org.apache.fop.render.afp.AFPFontConfig Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of org.apache.fop Show documentation
Show all versions of org.apache.fop Show documentation
The core maven build properties
The newest version!
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* $Id$ */
package org.apache.fop.render.afp;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.fop.afp.AFPEventProducer;
import org.apache.fop.afp.fonts.AFPFont;
import org.apache.fop.afp.fonts.AFPFontInfo;
import org.apache.fop.afp.fonts.CharacterSet;
import org.apache.fop.afp.fonts.CharacterSetBuilder;
import org.apache.fop.afp.fonts.CharacterSetType;
import org.apache.fop.afp.fonts.DoubleByteFont;
import org.apache.fop.afp.fonts.OutlineFont;
import org.apache.fop.afp.fonts.RasterFont;
import org.apache.fop.afp.util.AFPResourceAccessor;
import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.io.InternalResourceResolver;
import org.apache.fop.configuration.Configuration;
import org.apache.fop.configuration.ConfigurationException;
import org.apache.fop.events.EventProducer;
import org.apache.fop.fonts.EmbedFontInfo;
import org.apache.fop.fonts.EmbeddingMode;
import org.apache.fop.fonts.EncodingMode;
import org.apache.fop.fonts.FontConfig;
import org.apache.fop.fonts.FontManager;
import org.apache.fop.fonts.FontManagerConfigurator;
import org.apache.fop.fonts.FontTriplet;
import org.apache.fop.fonts.FontTriplet.Matcher;
import org.apache.fop.fonts.FontType;
import org.apache.fop.fonts.FontUris;
import org.apache.fop.fonts.FontUtil;
import org.apache.fop.fonts.LazyFont;
import org.apache.fop.fonts.Typeface;
/**
* The config object for AFP fonts, these differ from the the more generic fonts (TTF and Type1).
*/
public final class AFPFontConfig implements FontConfig {
private static final Log LOG = LogFactory.getLog(AFPFontConfig.class);
private final List fontsConfig;
private AFPFontConfig() {
fontsConfig = new ArrayList();
}
/**
* Returns a list of AFP font configuration data.
* @return the AFP font config data
*/
public List getFontConfig() {
return fontsConfig;
}
/**
* The parser for AFP font data.
*/
static final class AFPFontInfoConfigParser implements FontConfigParser {
/** {@inheritDoc}} */
public AFPFontConfig parse(Configuration cfg, FontManager fontManager, boolean strict,
EventProducer eventProducer) throws FOPException {
try {
return new ParserHelper(cfg, fontManager, strict,
(AFPEventProducer) eventProducer).fontConfig;
} catch (ConfigurationException ce) {
throw new FOPException(ce);
}
}
AFPFontConfig getEmptyConfig() {
return new AFPFontConfig();
}
}
private static final class AggregateMatcher implements Matcher {
private final List matchers;
private AggregateMatcher(Matcher... matchers) {
this.matchers = new ArrayList();
for (Matcher matcher : matchers) {
if (matcher != null) {
this.matchers.add(matcher);
}
}
}
public boolean matches(FontTriplet triplet) {
for (Matcher matcher : matchers) {
if (matcher.matches(triplet)) {
return true;
}
}
return false;
}
}
private static final class ParserHelper {
private static final Log LOG = LogFactory.getLog(ParserHelper.class);
private final AFPFontConfig fontConfig;
private final Matcher matcher;
private ParserHelper(Configuration cfg, FontManager fontManager, boolean strict,
AFPEventProducer eventProducer) throws FOPException, ConfigurationException {
Configuration fonts = cfg.getChild("fonts");
Matcher localMatcher = null;
Configuration referencedFontsCfg = fonts.getChild("referenced-fonts", false);
if (referencedFontsCfg != null) {
localMatcher = FontManagerConfigurator.createFontsMatcher(referencedFontsCfg, strict);
}
matcher = new AggregateMatcher(fontManager.getReferencedFontsMatcher(), localMatcher);
fontConfig = new AFPFontConfig();
for (Configuration font : fonts.getChildren("font")) {
buildFont(font, eventProducer);
}
}
private void buildFont(Configuration fontCfg, AFPEventProducer eventProducer)
throws ConfigurationException {
//FontManager fontManager = this.userAgent.getFontManager();
Configuration[] triplets = fontCfg.getChildren("font-triplet");
List tripletList = new ArrayList();
if (triplets.length == 0) {
eventProducer.fontConfigMissing(this, " fontTriplets, String type, String codepage,
String encoding, Configuration cfg, AFPEventProducer eventProducer, String embedURI)
throws ConfigurationException {
AFPFontConfigData config = null;
if ("raster".equalsIgnoreCase(type)) {
config = getRasterFont(fontTriplets, type, codepage, encoding, cfg, eventProducer,
embedURI);
} else if ("outline".equalsIgnoreCase(type)) {
config = getOutlineFont(fontTriplets, type, codepage, encoding, cfg, eventProducer,
embedURI);
} else if ("CIDKeyed".equalsIgnoreCase(type)) {
config = getCIDKeyedFont(fontTriplets, type, codepage, encoding, cfg,
eventProducer, embedURI);
} else if ("truetype".equalsIgnoreCase(type)) {
config = getTruetypeFont(fontTriplets, type, codepage, encoding, cfg, eventProducer, embedURI);
} else {
LOG.error("No or incorrect type attribute: " + type);
}
if (config != null) {
fontConfig.fontsConfig.add(config);
}
}
private CIDKeyedFontConfig getCIDKeyedFont(List fontTriplets, String type,
String codepage, String encoding, Configuration cfg, AFPEventProducer eventProducer,
String uri) throws ConfigurationException {
String characterset = cfg.getAttribute("characterset");
if (characterset == null) {
eventProducer.fontConfigMissing(this, "characterset attribute",
cfg.getLocation());
return null;
}
String name = cfg.getAttribute("name", characterset);
CharacterSetType charsetType = cfg.getAttributeAsBoolean("ebcdic-dbcs", false)
? CharacterSetType.DOUBLE_BYTE_LINE_DATA : CharacterSetType.DOUBLE_BYTE;
return new CIDKeyedFontConfig(fontTriplets, type, codepage, encoding, characterset,
name, charsetType, isEmbbedable(fontTriplets), uri);
}
private OutlineFontConfig getOutlineFont(List fontTriplets, String type,
String codepage, String encoding, Configuration cfg,
AFPEventProducer eventProducer, String uri) throws ConfigurationException {
String characterset = cfg.getAttribute("characterset");
if (characterset == null) {
eventProducer.fontConfigMissing(this, "characterset attribute",
cfg.getLocation());
return null;
}
String name = cfg.getAttribute("name", characterset);
String base14 = cfg.getAttribute("base14-font", null);
return new OutlineFontConfig(fontTriplets, type, codepage, encoding, characterset,
name, base14, isEmbbedable(fontTriplets), uri);
}
private TrueTypeFontConfig getTruetypeFont(List fontTriplets, String type, String codepage,
String encoding, Configuration cfg, AFPEventProducer eventProducer,
String uri) throws ConfigurationException {
String name = cfg.getAttribute("name", null);
if (name == null) {
eventProducer.fontConfigMissing(this, "font name attribute", cfg.getLocation());
return null;
}
String subfont = cfg.getAttribute("sub-font", null);
boolean positionByChar = cfg.getAttributeAsBoolean("position-by-char", true);
return new TrueTypeFontConfig(fontTriplets, type, codepage, encoding, "",
name, subfont, isEmbbedable(fontTriplets), uri, positionByChar);
}
private RasterFontConfig getRasterFont(List triplets, String type,
String codepage, String encoding, Configuration cfg,
AFPEventProducer eventProducer, String uri)
throws ConfigurationException {
String name = cfg.getAttribute("name", "Unknown");
// Create a new font object
Configuration[] rasters = cfg.getChildren("afp-raster-font");
if (rasters.length == 0) {
eventProducer.fontConfigMissing(this, " charsetData = new ArrayList();
for (Configuration rasterCfg : rasters) {
String characterset = rasterCfg.getAttribute("characterset");
if (characterset == null) {
eventProducer.fontConfigMissing(this, "characterset attribute",
cfg.getLocation());
return null;
}
float size = rasterCfg.getAttributeAsFloat("size");
int sizeMpt = (int) (size * 1000);
String base14 = rasterCfg.getAttribute("base14-font", null);
charsetData.add(new RasterCharactersetData(characterset, sizeMpt, base14));
}
return new RasterFontConfig(triplets, type, codepage, encoding, null, name, uri, charsetData,
isEmbbedable(triplets));
}
private boolean isEmbbedable(List triplets) {
for (FontTriplet triplet : triplets) {
if (matcher.matches(triplet)) {
return false;
}
}
return true;
}
}
abstract static class AFPFontConfigData {
protected final List triplets;
private final String codePage;
private final String encoding;
private final String name;
private final boolean embeddable;
protected final String uri;
AFPFontConfigData(List triplets, String type, String codePage,
String encoding, String name, boolean embeddable, String uri) {
this.triplets = Collections.unmodifiableList(triplets);
this.codePage = codePage;
this.encoding = encoding;
this.name = name;
this.embeddable = embeddable;
this.uri = uri;
}
static AFPFontInfo getFontInfo(AFPFont font, AFPFontConfigData config) {
return font != null ? new AFPFontInfo(font, config.triplets) : null;
}
abstract AFPFontInfo getFontInfo(InternalResourceResolver resourceResolver,
AFPEventProducer eventProducer) throws IOException;
AFPResourceAccessor getAccessor(InternalResourceResolver resourceResolver) {
return new AFPResourceAccessor(resourceResolver, uri);
}
}
static final class CIDKeyedFontConfig extends AFPFontConfigData {
private final CharacterSetType charsetType;
private final String characterset;
private CIDKeyedFontConfig(List triplets, String type, String codePage, String encoding,
String characterset, String name, CharacterSetType charsetType, boolean embeddable, String uri) {
super(triplets, type, codePage, encoding, name, embeddable, uri);
this.characterset = characterset;
this.charsetType = charsetType;
}
@Override
AFPFontInfo getFontInfo(InternalResourceResolver resourceResolver, AFPEventProducer eventProducer)
throws IOException {
AFPResourceAccessor accessor = getAccessor(resourceResolver);
CharacterSet characterSet = CharacterSetBuilder.getDoubleByteInstance().buildDBCS(
characterset, super.codePage, super.encoding, charsetType, accessor, eventProducer);
return getFontInfo(new DoubleByteFont(super.codePage, super.embeddable, characterSet,
eventProducer), this);
}
}
static final class TrueTypeFontConfig extends AFPFontConfigData {
private String characterset;
private String subfont;
private String fontUri;
private boolean positionByChar;
private TrueTypeFontConfig(List triplets, String type, String codePage,
String encoding, String characterset, String name, String subfont,
boolean embeddable, String uri, boolean positionByChar) {
super(triplets, type, codePage, encoding, name, embeddable, null);
this.characterset = characterset;
this.subfont = subfont;
this.fontUri = uri;
this.positionByChar = positionByChar;
}
@Override
AFPFontInfo getFontInfo(InternalResourceResolver resourceResolver, AFPEventProducer eventProducer)
throws IOException {
try {
FontUris fontUris = new FontUris(new URI(fontUri), null);
EmbedFontInfo embedFontInfo = new EmbedFontInfo(fontUris, false, true, null, subfont, EncodingMode.AUTO,
EmbeddingMode.FULL, false, false, true);
Typeface tf = new LazyFont(embedFontInfo, resourceResolver, false).getRealFont();
AFPResourceAccessor accessor = getAccessor(resourceResolver);
CharacterSet characterSet = CharacterSetBuilder.getDoubleByteInstance().build(characterset,
super.codePage, super.encoding, tf, accessor, eventProducer);
OutlineFont font = new AFPTrueTypeFont(super.name, super.embeddable, characterSet,
eventProducer, subfont, new URI(fontUri), positionByChar);
return getFontInfo(font, this);
} catch (URISyntaxException e) {
throw new IOException(e);
}
}
}
public static class AFPTrueTypeFont extends OutlineFont {
private String ttc;
private URI uri;
private boolean positionByChar;
public AFPTrueTypeFont(String name, boolean embeddable, CharacterSet charSet, AFPEventProducer eventProducer,
String ttc, URI uri, boolean positionByChar) {
super(name, embeddable, charSet, eventProducer);
this.ttc = ttc;
this.uri = uri;
this.positionByChar = positionByChar;
}
public FontType getFontType() {
return FontType.TRUETYPE;
}
public String getTTC() {
return ttc;
}
public URI getUri() {
return uri;
}
public boolean isPositionByChar() {
return positionByChar;
}
}
static final class OutlineFontConfig extends AFPFontConfigData {
private final String base14;
private final String characterset;
private OutlineFontConfig(List triplets, String type, String codePage,
String encoding, String characterset, String name, String base14, boolean embeddable, String uri) {
super(triplets, type, codePage, encoding, name, embeddable, uri);
this.characterset = characterset;
this.base14 = base14;
}
@Override
AFPFontInfo getFontInfo(InternalResourceResolver resourceResolver, AFPEventProducer eventProducer)
throws IOException {
CharacterSet characterSet = null;
if (base14 != null) {
try {
Typeface tf = getTypeFace(base14);
characterSet = CharacterSetBuilder.getSingleByteInstance()
.build(characterset, super.codePage,
super.encoding, tf, eventProducer);
} catch (ClassNotFoundException cnfe) {
String msg = "The base 14 font class for " + characterset
+ " could not be found";
LOG.error(msg);
}
} else {
AFPResourceAccessor accessor = getAccessor(resourceResolver);
characterSet = CharacterSetBuilder.getSingleByteInstance().buildSBCS(
characterset, super.codePage, super.encoding, accessor, eventProducer);
}
return getFontInfo(new OutlineFont(super.name, super.embeddable, characterSet,
eventProducer), this);
}
}
private static Typeface getTypeFace(String base14Name) throws ClassNotFoundException {
try {
Class extends Typeface> clazz = Class.forName("org.apache.fop.fonts.base14."
+ base14Name).asSubclass(Typeface.class);
return clazz.getDeclaredConstructor().newInstance();
} catch (IllegalAccessException iae) {
LOG.error(iae.getMessage());
} catch (ClassNotFoundException cnfe) {
LOG.error(cnfe.getMessage());
} catch (InstantiationException ie) {
LOG.error(ie.getMessage());
} catch (NoSuchMethodException e) {
LOG.error(e.getMessage());
} catch (InvocationTargetException e) {
LOG.error(e.getMessage());
}
throw new ClassNotFoundException("Couldn't load file for AFP font with base14 name: "
+ base14Name);
}
static final class RasterFontConfig extends AFPFontConfigData {
private final List charsets;
private RasterFontConfig(List triplets, String type, String codePage,
String encoding, String characterset, String name, String uri,
List csetData, boolean embeddable) {
super(triplets, type, codePage, encoding, name, embeddable, uri);
this.charsets = Collections.unmodifiableList(csetData);
}
@Override
AFPFontInfo getFontInfo(InternalResourceResolver resourceResolver, AFPEventProducer eventProducer)
throws IOException {
RasterFont rasterFont = new RasterFont(super.name, super.embeddable);
for (RasterCharactersetData charset : charsets) {
if (charset.base14 != null) {
try {
Typeface tf = getTypeFace(charset.base14);
rasterFont.addCharacterSet(charset.size,
CharacterSetBuilder.getSingleByteInstance().build(
charset.characterset, super.codePage, super.encoding,
tf, eventProducer));
} catch (ClassNotFoundException cnfe) {
String msg = "The base 14 font class for " + charset.characterset
+ " could not be found";
LOG.error(msg);
} catch (IOException ie) {
String msg = "The base 14 font class " + charset.characterset
+ " could not be instantiated";
LOG.error(msg);
}
} else {
AFPResourceAccessor accessor = getAccessor(resourceResolver);
rasterFont.addCharacterSet(charset.size,
CharacterSetBuilder.getSingleByteInstance().buildSBCS(charset.characterset,
super.codePage, super.encoding, accessor, eventProducer));
}
}
return getFontInfo(rasterFont, this);
}
}
static final class RasterCharactersetData {
private final String characterset;
private final int size;
private final String base14;
private RasterCharactersetData(String characterset, int size, String base14) {
this.characterset = characterset;
this.size = size;
this.base14 = base14;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy