git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1204579 13f79535-47bb-0310-9956-ffa450edef68pull/18/head
@@ -39,8 +39,7 @@ public interface AFPEventProducer extends EventProducer { | |||
* @return the event producer | |||
*/ | |||
public static AFPEventProducer get(EventBroadcaster broadcaster) { | |||
return (AFPEventProducer)broadcaster.getEventProducerFor( | |||
AFPEventProducer.class); | |||
return (AFPEventProducer) broadcaster.getEventProducerFor(AFPEventProducer.class); | |||
} | |||
} | |||
@@ -81,4 +80,37 @@ public interface AFPEventProducer extends EventProducer { | |||
* @event.severity ERROR | |||
*/ | |||
void resourceEmbeddingError(Object source, String resourceName, Exception e); | |||
/** | |||
* A mandatory font configuration node is missing at location. | |||
* @param source the event source | |||
* @param missingConfig the expected configuration element | |||
* @param location the position of the missing element within the config file. | |||
* @event.severity ERROR | |||
*/ | |||
void fontConfigMissing(Object source, String missingConfig, String location); | |||
/** | |||
* The character set given has an invalid name. | |||
* @param source the event source | |||
* @param msg the error message | |||
* @event.severity ERROR | |||
*/ | |||
void characterSetNameInvalid(Object source, String msg); | |||
/** | |||
* The code page for an AFP font could not be found. | |||
* @param source the event source | |||
* @param e the original exception | |||
* @event.severity ERROR | |||
*/ | |||
void codePageNotFound(Object source, Exception e); | |||
/** | |||
* This is a generic event for invalid configuration errors. | |||
* @param source the event source | |||
* @param e the original exception | |||
* @event.severity ERROR | |||
*/ | |||
void invalidConfiguration(Object source, Exception e); | |||
} |
@@ -4,4 +4,8 @@ | |||
<message key="warnMissingDefaultFont">No AFP default "any", {style}, {weight} font configured.</message> | |||
<message key="characterSetEncodingError">An error occurred when attempting to encode character set {charSetName} with encoding scheme {encoding}.</message> | |||
<message key="resourceEmbeddingError">An error occurs while embedding the resource named "{resourceName}".[ Reason: {e}]</message> | |||
<message key="invalidConfiguration">There has been a configuration error.[ Reason: {e}]</message> | |||
<message key="fontConfigMissing">The mandatory configuation node: '{missingConfig}' was not found at {location}.</message> | |||
<message key="characterSetNameInvalid">The character set given has an invalid name. [ Reason: {msg} ]</message> | |||
<message key="codePageNotFound">The code page for an AFP font cannot be found.[ Reason: {e}]</message> | |||
</catalogue> |
@@ -19,6 +19,7 @@ | |||
package org.apache.fop.afp.fonts; | |||
import org.apache.fop.afp.AFPEventProducer; | |||
import org.apache.fop.fonts.Base14Font; | |||
import org.apache.fop.fonts.Font; | |||
import org.apache.fop.fonts.FontCollection; | |||
@@ -40,6 +41,12 @@ import org.apache.fop.fonts.base14.TimesRoman; | |||
*/ | |||
public class AFPBase12FontCollection implements FontCollection { | |||
private final AFPEventProducer eventProducer; | |||
public AFPBase12FontCollection(AFPEventProducer eventProducer) { | |||
this.eventProducer = eventProducer; | |||
} | |||
/** standard raster font sizes */ | |||
private static final int[] RASTER_SIZES = {6, 7, 8, 9, 10, 11, 12, 14, 16, 18, 20, 24, 30, 36}; | |||
@@ -52,7 +59,7 @@ public class AFPBase12FontCollection implements FontCollection { | |||
int size = RASTER_SIZES[i] * 1000; | |||
FopCharacterSet characterSet = new FopCharacterSet( | |||
CharacterSet.DEFAULT_CODEPAGE, CharacterSet.DEFAULT_ENCODING, | |||
charsetName + CHARSET_REF[i], base14); | |||
charsetName + CHARSET_REF[i], base14, eventProducer); | |||
font.addCharacterSet(size, characterSet); | |||
} | |||
} |
@@ -19,7 +19,6 @@ | |||
package org.apache.fop.afp.fonts; | |||
import java.util.Iterator; | |||
import java.util.List; | |||
import org.apache.fop.afp.AFPEventProducer; | |||
@@ -34,9 +33,9 @@ import org.apache.fop.fonts.FontTriplet; | |||
*/ | |||
public class AFPFontCollection implements FontCollection { | |||
private final EventBroadcaster eventBroadcaster; | |||
private final AFPEventProducer eventProducer; | |||
private final List/*<AFPFontInfo>*/ fontInfoList; | |||
private final List<AFPFontInfo> fontInfoList; | |||
/** | |||
* Main constructor | |||
@@ -44,49 +43,40 @@ public class AFPFontCollection implements FontCollection { | |||
* @param eventBroadcaster the event broadcaster | |||
* @param fontInfoList the font info list | |||
*/ | |||
public AFPFontCollection(EventBroadcaster eventBroadcaster, | |||
List/*<AFPFontInfo>*/ fontInfoList) { | |||
this.eventBroadcaster = eventBroadcaster; | |||
public AFPFontCollection(EventBroadcaster eventBroadcaster, List<AFPFontInfo> fontInfoList) { | |||
this.eventProducer = AFPEventProducer.Provider.get(eventBroadcaster); | |||
this.fontInfoList = fontInfoList; | |||
} | |||
/** {@inheritDoc} */ | |||
public int setup(int start, FontInfo fontInfo) { | |||
int num = 1; | |||
AFPEventProducer eventProducer = AFPEventProducer.Provider.get(eventBroadcaster); | |||
if (fontInfoList != null && fontInfoList.size() > 0) { | |||
for (Iterator it = fontInfoList.iterator(); it.hasNext();) { | |||
AFPFontInfo afpFontInfo = (AFPFontInfo)it.next(); | |||
for (AFPFontInfo afpFontInfo : fontInfoList) { | |||
AFPFont afpFont = afpFontInfo.getAFPFont(); | |||
List/*<FontTriplet>*/ tripletList = afpFontInfo.getFontTriplets(); | |||
for (Iterator it2 = tripletList.iterator(); it2.hasNext();) { | |||
FontTriplet triplet = (FontTriplet)it2.next(); | |||
List<FontTriplet> tripletList = afpFontInfo.getFontTriplets(); | |||
for (FontTriplet triplet : tripletList) { | |||
fontInfo.addMetrics("F" + num, afpFont); | |||
fontInfo.addFontProperties("F" + num, | |||
triplet.getName(), triplet.getStyle(), triplet.getWeight()); | |||
num++; | |||
} | |||
} | |||
checkDefaultFontAvailable(fontInfo, eventProducer, | |||
Font.STYLE_NORMAL, Font.WEIGHT_NORMAL); | |||
checkDefaultFontAvailable(fontInfo, eventProducer, | |||
Font.STYLE_ITALIC, Font.WEIGHT_NORMAL); | |||
checkDefaultFontAvailable(fontInfo, eventProducer, | |||
Font.STYLE_NORMAL, Font.WEIGHT_BOLD); | |||
checkDefaultFontAvailable(fontInfo, eventProducer, | |||
Font.STYLE_ITALIC, Font.WEIGHT_BOLD); | |||
checkDefaultFontAvailable(fontInfo, Font.STYLE_NORMAL, Font.WEIGHT_NORMAL); | |||
checkDefaultFontAvailable(fontInfo, Font.STYLE_ITALIC, Font.WEIGHT_NORMAL); | |||
checkDefaultFontAvailable(fontInfo, Font.STYLE_NORMAL, Font.WEIGHT_BOLD); | |||
checkDefaultFontAvailable(fontInfo, Font.STYLE_ITALIC, Font.WEIGHT_BOLD); | |||
} else { | |||
eventProducer.warnDefaultFontSetup(this); | |||
// Go with a default base 12 configuration for AFP environments | |||
FontCollection base12FontCollection = new AFPBase12FontCollection(); | |||
FontCollection base12FontCollection = new AFPBase12FontCollection(eventProducer); | |||
num = base12FontCollection.setup(num, fontInfo); | |||
} | |||
return num; | |||
} | |||
private void checkDefaultFontAvailable(FontInfo fontInfo, AFPEventProducer eventProducer, | |||
String style, int weight) { | |||
private void checkDefaultFontAvailable(FontInfo fontInfo, String style, int weight) { | |||
if (!fontInfo.hasFont("any", style, weight)) { | |||
eventProducer.warnMissingDefaultFont(this, style, weight); | |||
} |
@@ -19,17 +19,17 @@ | |||
package org.apache.fop.afp.fonts; | |||
import java.io.File; | |||
import java.io.UnsupportedEncodingException; | |||
import java.nio.charset.CharacterCodingException; | |||
import java.util.HashMap; | |||
import java.util.Map; | |||
import org.apache.commons.logging.Log; | |||
import org.apache.commons.logging.LogFactory; | |||
import org.apache.fop.afp.AFPConstants; | |||
import org.apache.fop.afp.AFPEventProducer; | |||
import org.apache.fop.afp.fonts.CharactersetEncoder.EncodedChars; | |||
import org.apache.fop.afp.util.ResourceAccessor; | |||
import org.apache.fop.afp.util.SimpleResourceAccessor; | |||
import org.apache.fop.afp.util.StringUtils; | |||
/** | |||
@@ -76,32 +76,16 @@ public class CharacterSet { | |||
protected final String name; | |||
/** The path to the installed fonts */ | |||
private ResourceAccessor accessor; | |||
private final ResourceAccessor accessor; | |||
/** The current orientation (currently only 0 is supported by FOP) */ | |||
private final String currentOrientation = "0"; | |||
/** The collection of objects for each orientation */ | |||
private Map characterSetOrientations = null; | |||
private final Map<String, CharacterSetOrientation> characterSetOrientations; | |||
/** The nominal vertical size (in millipoints) for bitmap fonts. 0 for outline fonts. */ | |||
private int nominalVerticalSize = 0; | |||
/** | |||
* Constructor for the CharacterSetMetric object, the character set is used | |||
* to load the font information from the actual AFP font. | |||
* | |||
* @param codePage the code page identifier | |||
* @param encoding the encoding of the font | |||
* @param name the character set name | |||
* @param path the path to the installed afp fonts | |||
* @deprecated Please use | |||
* {@link #CharacterSet(String, String, String, ResourceAccessor)} instead. | |||
*/ | |||
public CharacterSet(String codePage, String encoding, String name, String path) { | |||
this(codePage, encoding, false, name, | |||
new SimpleResourceAccessor(path != null ? new File(path) : null)); | |||
} | |||
private int nominalVerticalSize; | |||
/** | |||
* Constructor for the CharacterSetMetric object, the character set is used to load the font | |||
@@ -112,13 +96,14 @@ public class CharacterSet { | |||
* @param isEBDCS if this is an EBCDIC double byte character set. | |||
* @param name the character set name | |||
* @param accessor the resource accessor to load resource with | |||
* @param eventProducer for handling AFP related events | |||
*/ | |||
CharacterSet(String codePage, String encoding, boolean isEBDCS, String name, | |||
ResourceAccessor accessor) { | |||
ResourceAccessor accessor, AFPEventProducer eventProducer) { | |||
if (name.length() > MAX_NAME_LEN) { | |||
String msg = "Character set name '" + name + "' must be a maximum of " | |||
+ MAX_NAME_LEN + " characters"; | |||
LOG.error("Constructor:: " + msg); | |||
eventProducer.characterSetNameInvalid(this, msg); | |||
throw new IllegalArgumentException(msg); | |||
} | |||
@@ -132,7 +117,7 @@ public class CharacterSet { | |||
this.encoder = CharactersetEncoder.newInstance(encoding, isEBDCS); | |||
this.accessor = accessor; | |||
this.characterSetOrientations = new java.util.HashMap(4); | |||
this.characterSetOrientations = new HashMap<String, CharacterSetOrientation>(4); | |||
} | |||
/** | |||
@@ -141,9 +126,7 @@ public class CharacterSet { | |||
* @param cso the metrics for the orientation | |||
*/ | |||
public void addCharacterSetOrientation(CharacterSetOrientation cso) { | |||
characterSetOrientations.put( | |||
String.valueOf(cso.getOrientation()), | |||
cso); | |||
characterSetOrientations.put(String.valueOf(cso.getOrientation()), cso); | |||
} | |||
/** |
@@ -24,18 +24,23 @@ import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.net.URI; | |||
import java.net.URISyntaxException; | |||
import java.util.ArrayList; | |||
import java.util.Collections; | |||
import java.util.HashMap; | |||
import java.util.List; | |||
import java.util.Map; | |||
import java.util.WeakHashMap; | |||
import org.apache.commons.logging.Log; | |||
import org.apache.commons.logging.LogFactory; | |||
import org.apache.xmlgraphics.image.loader.util.SoftMapCache; | |||
import org.apache.fop.afp.AFPConstants; | |||
import org.apache.fop.afp.AFPEventProducer; | |||
import org.apache.fop.afp.util.ResourceAccessor; | |||
import org.apache.fop.afp.util.StructuredFieldReader; | |||
import org.apache.fop.fonts.Typeface; | |||
import org.apache.xmlgraphics.image.loader.util.SoftMapCache; | |||
/** | |||
* The CharacterSetBuilder is responsible building the a CharacterSet instance that holds | |||
@@ -109,7 +114,7 @@ public abstract class CharacterSetBuilder { | |||
private final SoftMapCache characterSetsCache = new SoftMapCache(true); | |||
/** Default constructor. */ | |||
protected CharacterSetBuilder() { | |||
private CharacterSetBuilder() { | |||
} | |||
/** | |||
@@ -134,11 +139,13 @@ public abstract class CharacterSetBuilder { | |||
* | |||
* * @param accessor the resource accessor | |||
* @param filename the file name | |||
* @param eventProducer for handling AFP related events | |||
* @return an inputStream | |||
* | |||
* @throws IOException in the event that an I/O exception of some sort has occurred | |||
*/ | |||
protected InputStream openInputStream(ResourceAccessor accessor, String filename) | |||
protected InputStream openInputStream(ResourceAccessor accessor, String filename, | |||
AFPEventProducer eventProducer) | |||
throws IOException { | |||
URI uri; | |||
try { | |||
@@ -174,17 +181,19 @@ public abstract class CharacterSetBuilder { | |||
/** | |||
* Load the font details and metrics into the CharacterSetMetric object, this will use the | |||
* actual afp code page and character set files to load the object with the necessary metrics. | |||
* | |||
* | |||
* @param characterSetName name of the characterset | |||
* @param codePageName name of the code page file | |||
* @param encoding encoding name | |||
* @param accessor used to load codepage and characterset | |||
* @param eventProducer for handling AFP related events | |||
* @return CharacterSet object | |||
* @throws IOException if an I/O error occurs | |||
*/ | |||
public CharacterSet build(String characterSetName, String codePageName, String encoding, | |||
ResourceAccessor accessor) throws IOException { | |||
return processFont(characterSetName, codePageName, encoding, false, accessor); | |||
ResourceAccessor accessor, AFPEventProducer eventProducer) throws IOException { | |||
return processFont(characterSetName, codePageName, encoding, false, accessor, | |||
eventProducer); | |||
} | |||
/** | |||
@@ -197,35 +206,41 @@ public abstract class CharacterSetBuilder { | |||
* @param encoding encoding name | |||
* @param isEDBCS if this is an EBCDIC double byte character set (DBCS) | |||
* @param accessor used to load codepage and characterset | |||
* @param eventProducer for handling AFP related events | |||
* @return CharacterSet object | |||
* @throws IOException if an I/O error occurs | |||
*/ | |||
public CharacterSet buildDBCS(String characterSetName, String codePageName, String encoding, | |||
boolean isEDBCS, ResourceAccessor accessor) throws IOException { | |||
return processFont(characterSetName, codePageName, encoding, isEDBCS, accessor); | |||
boolean isEDBCS, ResourceAccessor accessor, AFPEventProducer eventProducer) | |||
throws IOException { | |||
return processFont(characterSetName, codePageName, encoding, isEDBCS, accessor, | |||
eventProducer); | |||
} | |||
/** | |||
* Load the font details and metrics into the CharacterSetMetric object, this will use the | |||
* actual afp code page and character set files to load the object with the necessary metrics. | |||
* | |||
* | |||
* @param characterSetName the CharacterSetMetric object to populate | |||
* @param codePageName the name of the code page to use | |||
* @param encoding name of the encoding in use | |||
* @param typeface base14 font name | |||
* @param eventProducer for handling AFP related events | |||
* @return CharacterSet object | |||
* @throws IOException if an I/O error occurs | |||
*/ | |||
public CharacterSet build(String characterSetName, String codePageName, String encoding, | |||
Typeface typeface) throws IOException { | |||
return new FopCharacterSet(codePageName, encoding, characterSetName, typeface); | |||
Typeface typeface, AFPEventProducer eventProducer) throws IOException { | |||
return new FopCharacterSet(codePageName, encoding, characterSetName, typeface, | |||
eventProducer); | |||
} | |||
private CharacterSet processFont(String characterSetName, String codePageName, String encoding, | |||
boolean isEDBCS, ResourceAccessor accessor) throws IOException { | |||
boolean isEDBCS, ResourceAccessor accessor, AFPEventProducer eventProducer) | |||
throws IOException { | |||
// check for cached version of the characterset | |||
String descriptor = characterSetName + "_" + encoding + "_" + codePageName; | |||
CharacterSet characterSet = (CharacterSet)characterSetsCache.get(descriptor); | |||
CharacterSet characterSet = (CharacterSet) characterSetsCache.get(descriptor); | |||
if (characterSet != null) { | |||
return characterSet; | |||
@@ -233,7 +248,7 @@ public abstract class CharacterSetBuilder { | |||
// characterset not in the cache, so recreating | |||
characterSet = new CharacterSet(codePageName, encoding, isEDBCS, characterSetName, | |||
accessor); | |||
accessor, eventProducer); | |||
InputStream inputStream = null; | |||
@@ -249,12 +264,12 @@ public abstract class CharacterSetBuilder { | |||
codePage = codePagesCache.get(codePageName); | |||
if (codePage == null) { | |||
codePage = loadCodePage(codePageName, encoding, accessor); | |||
codePage = loadCodePage(codePageName, encoding, accessor, eventProducer); | |||
codePagesCache.put(codePageName, codePage); | |||
} | |||
} | |||
inputStream = openInputStream(accessor, characterSetName); | |||
inputStream = openInputStream(accessor, characterSetName, eventProducer); | |||
StructuredFieldReader structuredFieldReader = new StructuredFieldReader(inputStream); | |||
@@ -309,18 +324,19 @@ public abstract class CharacterSetBuilder { | |||
* @param encoding | |||
* the encoding to use for the character decoding | |||
* @param accessor the resource accessor | |||
* @param eventProducer for handling AFP related events | |||
* @return a code page mapping (key: GCGID, value: Unicode character) | |||
* @throws IOException if an I/O exception of some sort has occurred. | |||
*/ | |||
protected Map/*<String,String>*/ loadCodePage(String codePage, String encoding, | |||
ResourceAccessor accessor) throws IOException { | |||
protected Map<String, String> loadCodePage(String codePage, String encoding, | |||
ResourceAccessor accessor, AFPEventProducer eventProducer) throws IOException { | |||
// Create the HashMap to store code page information | |||
Map/*<String,String>*/ codePages = new java.util.HashMap/*<String,String>*/(); | |||
Map<String, String> codePages = new HashMap<String, String>(); | |||
InputStream inputStream = null; | |||
try { | |||
inputStream = openInputStream(accessor, codePage.trim()); | |||
inputStream = openInputStream(accessor, codePage.trim(), eventProducer); | |||
StructuredFieldReader structuredFieldReader = new StructuredFieldReader(inputStream); | |||
byte[] data = structuredFieldReader.getNext(CHARACTER_TABLE_SF); | |||
@@ -351,6 +367,8 @@ public abstract class CharacterSetBuilder { | |||
position++; | |||
} | |||
} | |||
} catch (FileNotFoundException e) { | |||
eventProducer.codePageNotFound(this, e); | |||
} finally { | |||
closeInputStream(inputStream); | |||
} | |||
@@ -421,7 +439,7 @@ public abstract class CharacterSetBuilder { | |||
int position = 0; | |||
byte[] fnoData = new byte[26]; | |||
List orientations = new java.util.ArrayList(); | |||
List<CharacterSetOrientation> orientations = new ArrayList<CharacterSetOrientation>(); | |||
// Read data, ignoring bytes 0 - 2 | |||
for (int index = 3; index < data.length; index++) { | |||
@@ -521,8 +539,8 @@ public abstract class CharacterSetBuilder { | |||
* @throws IOException if an I/O exception of some sort has occurred. | |||
*/ | |||
protected void processFontIndex(StructuredFieldReader structuredFieldReader, | |||
CharacterSetOrientation cso, Map/*<String,String>*/ codepage, | |||
double metricNormalizationFactor) | |||
CharacterSetOrientation cso, Map<String, String> codepage, | |||
double metricNormalizationFactor) | |||
throws IOException { | |||
byte[] data = structuredFieldReader.getNext(FONT_INDEX_SF); | |||
@@ -692,15 +710,15 @@ public abstract class CharacterSetBuilder { | |||
return INSTANCE; | |||
} | |||
protected Map/*<String,String>*/ loadCodePage(String codePage, String encoding, | |||
ResourceAccessor accessor) throws IOException { | |||
protected Map<String, String> loadCodePage(String codePage, String encoding, | |||
ResourceAccessor accessor, AFPEventProducer eventProducer) throws IOException { | |||
// Create the HashMap to store code page information | |||
Map/*<String,String>*/ codePages = new java.util.HashMap/*<String,String>*/(); | |||
Map<String, String> codePages = new HashMap<String, String>(); | |||
InputStream inputStream = null; | |||
try { | |||
inputStream = openInputStream(accessor, codePage.trim()); | |||
inputStream = openInputStream(accessor, codePage.trim(), eventProducer); | |||
StructuredFieldReader structuredFieldReader | |||
= new StructuredFieldReader(inputStream); | |||
@@ -737,6 +755,8 @@ public abstract class CharacterSetBuilder { | |||
} | |||
} | |||
} | |||
} catch (FileNotFoundException e) { | |||
eventProducer.codePageNotFound(this, e); | |||
} finally { | |||
closeInputStream(inputStream); | |||
} |
@@ -19,6 +19,7 @@ | |||
package org.apache.fop.afp.fonts; | |||
import org.apache.fop.afp.AFPEventProducer; | |||
import org.apache.fop.afp.util.ResourceAccessor; | |||
import org.apache.fop.fonts.Typeface; | |||
@@ -37,14 +38,11 @@ public class FopCharacterSet extends CharacterSet { | |||
* @param encoding the encoding of the font | |||
* @param name the character set name | |||
* @param charSet the fop character set | |||
* @param eventProducer for handling AFP related events | |||
*/ | |||
public FopCharacterSet( | |||
String codePage, | |||
String encoding, | |||
String name, | |||
Typeface charSet) { | |||
super(codePage, encoding, false, name, (ResourceAccessor) null); | |||
public FopCharacterSet(String codePage, String encoding, String name, Typeface charSet, | |||
AFPEventProducer eventProducer) { | |||
super(codePage, encoding, false, name, (ResourceAccessor) null, eventProducer); | |||
this.charSet = charSet; | |||
} | |||
@@ -29,6 +29,7 @@ import java.util.List; | |||
import org.apache.avalon.framework.configuration.Configuration; | |||
import org.apache.avalon.framework.configuration.ConfigurationException; | |||
import org.apache.fop.afp.AFPEventProducer; | |||
import org.apache.fop.afp.AFPResourceLevel; | |||
import org.apache.fop.afp.AFPResourceLevelDefaults; | |||
import org.apache.fop.afp.fonts.AFPFont; | |||
@@ -62,6 +63,8 @@ import org.apache.fop.util.LogUtil; | |||
public class AFPRendererConfigurator extends PrintRendererConfigurator | |||
implements IFDocumentHandlerConfigurator { | |||
private final AFPEventProducer eventProducer; | |||
/** | |||
* Default constructor | |||
* | |||
@@ -69,17 +72,17 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator | |||
*/ | |||
public AFPRendererConfigurator(FOUserAgent userAgent) { | |||
super(userAgent); | |||
eventProducer = AFPEventProducer.Provider.get(userAgent.getEventBroadcaster()); | |||
} | |||
private AFPFontInfo buildFont(Configuration fontCfg, String fontPath) | |||
throws ConfigurationException { | |||
FontManager fontManager = this.userAgent.getFactory().getFontManager(); | |||
Configuration[] triple = fontCfg.getChildren("font-triplet"); | |||
List<FontTriplet> tripletList = new java.util.ArrayList<FontTriplet>(); | |||
List<FontTriplet> tripletList = new ArrayList<FontTriplet>(); | |||
if (triple.length == 0) { | |||
log.error("Mandatory font configuration element '<font-triplet...' is missing"); | |||
eventProducer.fontConfigMissing(this, "<font-triplet...", fontCfg.getLocation()); | |||
return null; | |||
} | |||
for (Configuration config : triple) { | |||
@@ -91,11 +94,12 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator | |||
} | |||
//build the fonts | |||
Configuration afpFontCfg = fontCfg.getChild("afp-font"); | |||
if (afpFontCfg == null) { | |||
log.error("Mandatory font configuration element '<afp-font...' is missing"); | |||
Configuration[] config = fontCfg.getChildren("afp-font"); | |||
if (config.length == 0) { | |||
eventProducer.fontConfigMissing(this, "<afp-font...", fontCfg.getLocation()); | |||
return null; | |||
} | |||
Configuration afpFontCfg = config[0]; | |||
URI baseURI = null; | |||
String uri = afpFontCfg.getAttribute("base-uri", fontPath); | |||
@@ -110,7 +114,7 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator | |||
try { | |||
baseURI = new URI(uri); | |||
} catch (URISyntaxException e) { | |||
log.error("Invalid URI: " + e.getMessage()); | |||
eventProducer.invalidConfiguration(this, e); | |||
return null; | |||
} | |||
} | |||
@@ -119,25 +123,35 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator | |||
fontManager.getFontBaseURL(), | |||
baseURI); | |||
String type = afpFontCfg.getAttribute("type"); | |||
if (type == null) { | |||
log.error("Mandatory afp-font configuration attribute 'type=' is missing"); | |||
return null; | |||
} | |||
String codepage = afpFontCfg.getAttribute("codepage"); | |||
if (codepage == null) { | |||
log.error("Mandatory afp-font configuration attribute 'code=' is missing"); | |||
return null; | |||
} | |||
String encoding = afpFontCfg.getAttribute("encoding"); | |||
AFPFont font = null; | |||
try { | |||
String type = afpFontCfg.getAttribute("type"); | |||
if (type == null) { | |||
eventProducer.fontConfigMissing(this, "type attribute", fontCfg.getLocation()); | |||
return null; | |||
} | |||
String codepage = afpFontCfg.getAttribute("codepage"); | |||
if (codepage == null) { | |||
eventProducer.fontConfigMissing(this, "codepage attribute", | |||
fontCfg.getLocation()); | |||
return null; | |||
} | |||
String encoding = afpFontCfg.getAttribute("encoding"); | |||
if (encoding == null) { | |||
eventProducer.fontConfigMissing(this, "encoding attribute", | |||
fontCfg.getLocation()); | |||
return null; | |||
} | |||
if (encoding == null) { | |||
log.error("Mandatory afp-font configuration attribute 'encoding=' is missing"); | |||
return null; | |||
font = fontFromType(type, codepage, encoding, accessor, afpFontCfg); | |||
} catch (ConfigurationException ce) { | |||
eventProducer.invalidConfiguration(this, ce); | |||
} catch (IOException ioe) { | |||
eventProducer.invalidConfiguration(this, ioe); | |||
} catch (IllegalArgumentException iae) { | |||
eventProducer.invalidConfiguration(this, iae); | |||
} | |||
AFPFont font = fontFromType(type, codepage, encoding, accessor, afpFontCfg); | |||
return font != null ? new AFPFontInfo(font, tripletList) : null; | |||
} | |||
@@ -154,8 +168,8 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator | |||
* @throws ConfigurationException | |||
*/ | |||
private AFPFont fontFromType(String type, String codepage, String encoding, | |||
ResourceAccessor accessor, Configuration afpFontCfg) | |||
throws ConfigurationException { | |||
ResourceAccessor accessor, Configuration afpFontCfg) throws ConfigurationException, | |||
IOException { | |||
if ("raster".equalsIgnoreCase(type)) { | |||
@@ -166,21 +180,22 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator | |||
Configuration[] rasters = afpFontCfg.getChildren("afp-raster-font"); | |||
if (rasters.length == 0) { | |||
log.error("Mandatory font configuration elements '<afp-raster-font...'" | |||
+ " are missing at " + afpFontCfg.getLocation()); | |||
eventProducer.fontConfigMissing(this, "<afp-raster-font...", | |||
afpFontCfg.getLocation()); | |||
return null; | |||
} | |||
for (int j = 0; j < rasters.length; j++) { | |||
Configuration rasterCfg = rasters[j]; | |||
String characterset = rasterCfg.getAttribute("characterset"); | |||
if (characterset == null) { | |||
log.error( | |||
"Mandatory afp-raster-font configuration attribute 'characterset=' is missing"); | |||
eventProducer.fontConfigMissing(this, "characterset attribute", | |||
afpFontCfg.getLocation()); | |||
return null; | |||
} | |||
float size = rasterCfg.getAttributeAsFloat("size"); | |||
int sizeMpt = (int)(size * 1000); | |||
int sizeMpt = (int) (size * 1000); | |||
String base14 = rasterCfg.getAttribute("base14-font", null); | |||
if (base14 != null) { | |||
@@ -189,9 +204,8 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator | |||
"org.apache.fop.fonts.base14." + base14).asSubclass(Typeface.class); | |||
try { | |||
Typeface tf = clazz.newInstance(); | |||
font.addCharacterSet(sizeMpt, | |||
CharacterSetBuilder.getSingleByteInstance() | |||
.build(characterset, codepage, encoding, tf)); | |||
font.addCharacterSet(sizeMpt, CharacterSetBuilder.getSingleByteInstance() | |||
.build(characterset, codepage, encoding, tf, eventProducer)); | |||
} catch (Exception ie) { | |||
String msg = "The base 14 font class " + clazz.getName() | |||
+ " could not be instantiated"; | |||
@@ -203,12 +217,8 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator | |||
log.error(msg); | |||
} | |||
} else { | |||
try { | |||
font.addCharacterSet(sizeMpt, CharacterSetBuilder.getSingleByteInstance() | |||
.build(characterset, codepage, encoding, accessor)); | |||
} catch (IOException ioe) { | |||
toConfigurationException(codepage, characterset, ioe); | |||
} | |||
font.addCharacterSet(sizeMpt, CharacterSetBuilder.getSingleByteInstance() | |||
.build(characterset, codepage, encoding, accessor, eventProducer)); | |||
} | |||
} | |||
return font; | |||
@@ -216,7 +226,8 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator | |||
} else if ("outline".equalsIgnoreCase(type)) { | |||
String characterset = afpFontCfg.getAttribute("characterset"); | |||
if (characterset == null) { | |||
log.error("Mandatory afp-font configuration attribute 'characterset=' is missing"); | |||
eventProducer.fontConfigMissing(this, "characterset attribute", | |||
afpFontCfg.getLocation()); | |||
return null; | |||
} | |||
String name = afpFontCfg.getAttribute("name", characterset); | |||
@@ -229,7 +240,7 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator | |||
try { | |||
Typeface tf = clazz.newInstance(); | |||
characterSet = CharacterSetBuilder.getSingleByteInstance() | |||
.build(characterset, codepage, encoding, tf); | |||
.build(characterset, codepage, encoding, tf, eventProducer); | |||
} catch (Exception ie) { | |||
String msg = "The base 14 font class " + clazz.getName() | |||
+ " could not be instantiated"; | |||
@@ -241,12 +252,8 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator | |||
log.error(msg); | |||
} | |||
} else { | |||
try { | |||
characterSet = CharacterSetBuilder.getSingleByteInstance().build( | |||
characterset, codepage, encoding, accessor); | |||
} catch (IOException ioe) { | |||
toConfigurationException(codepage, characterset, ioe); | |||
} | |||
characterSet = CharacterSetBuilder.getSingleByteInstance().build( | |||
characterset, codepage, encoding, accessor, eventProducer); | |||
} | |||
// Return new font object | |||
return new OutlineFont(name, characterSet); | |||
@@ -254,19 +261,16 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator | |||
} else if ("CIDKeyed".equalsIgnoreCase(type)) { | |||
String characterset = afpFontCfg.getAttribute("characterset"); | |||
if (characterset == null) { | |||
log.error("Mandatory afp-font configuration attribute 'characterset=' is missing"); | |||
eventProducer.fontConfigMissing(this, "characterset attribute", | |||
afpFontCfg.getLocation()); | |||
return null; | |||
} | |||
String name = afpFontCfg.getAttribute("name", characterset); | |||
CharacterSet characterSet = null; | |||
boolean ebcdicDBCS = afpFontCfg.getAttributeAsBoolean("ebcdic-dbcs", false); | |||
try { | |||
characterSet = CharacterSetBuilder.getDoubleByteInstance().buildDBCS(characterset, | |||
codepage, encoding, ebcdicDBCS, accessor); | |||
} catch (IOException ioe) { | |||
toConfigurationException(codepage, characterset, ioe); | |||
} | |||
characterSet = CharacterSetBuilder.getDoubleByteInstance().buildDBCS(characterset, | |||
codepage, encoding, ebcdicDBCS, accessor, eventProducer); | |||
// Create a new font object | |||
DoubleByteFont font = new DoubleByteFont(name, characterSet); | |||
@@ -279,23 +283,16 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator | |||
return null; | |||
} | |||
private void toConfigurationException(String codepage, String characterset, IOException ioe) | |||
throws ConfigurationException { | |||
String msg = "Failed to load the character set metrics " + characterset | |||
+ " with code page " + codepage | |||
+ ". I/O error: " + ioe.getMessage(); | |||
throw new ConfigurationException(msg, ioe); | |||
} | |||
/** | |||
* Builds a list of AFPFontInfo objects for use with the setup() method. | |||
* | |||
* @param cfg Configuration object | |||
* @param eventProducer for AFP font related events | |||
* @return List the newly created list of fonts | |||
* @throws ConfigurationException if something's wrong with the config data | |||
*/ | |||
private List<AFPFontInfo> buildFontListFromConfiguration(Configuration cfg) | |||
throws FOPException, ConfigurationException { | |||
private List<AFPFontInfo> buildFontListFromConfiguration(Configuration cfg, | |||
AFPEventProducer eventProducer) throws FOPException, ConfigurationException { | |||
Configuration fonts = cfg.getChild("fonts"); | |||
FontManager fontManager = this.userAgent.getFactory().getFontManager(); | |||
@@ -490,7 +487,7 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator | |||
public void configure(IFDocumentHandler documentHandler) throws FOPException { | |||
Configuration cfg = super.getRendererConfig(documentHandler.getMimeType()); | |||
if (cfg != null) { | |||
AFPDocumentHandler afpDocumentHandler = (AFPDocumentHandler)documentHandler; | |||
AFPDocumentHandler afpDocumentHandler = (AFPDocumentHandler) documentHandler; | |||
configure(afpDocumentHandler, cfg); | |||
} | |||
} | |||
@@ -505,10 +502,11 @@ public class AFPRendererConfigurator extends PrintRendererConfigurator | |||
Configuration cfg = super.getRendererConfig(documentHandler.getMimeType()); | |||
if (cfg != null) { | |||
try { | |||
List<AFPFontInfo> fontList = buildFontListFromConfiguration(cfg); | |||
List<AFPFontInfo> fontList = buildFontListFromConfiguration(cfg, eventProducer); | |||
fontCollections.add(new AFPFontCollection( | |||
userAgent.getEventBroadcaster(), fontList)); | |||
} catch (ConfigurationException e) { | |||
eventProducer.invalidConfiguration(this, e); | |||
LogUtil.handleException(log, e, | |||
userAgent.getFactory().validateUserConfigStrictly()); | |||
} |
@@ -0,0 +1,16 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<fop version="1.0"> | |||
<base>.</base> | |||
<renderers> | |||
<renderer mime="application/x-afp"> | |||
<fonts> | |||
<font> | |||
<afp-font name="TEST" type="raster" codepage="codepage" encoding="Cp500"> | |||
<afp-raster-font size="36" characterset="C0N200Z0"/> | |||
</afp-font> | |||
<font-triplet name="TEST" style="normal" weight="normal"/> | |||
</font> | |||
</fonts> | |||
</renderer> | |||
</renderers> | |||
</fop> |
@@ -0,0 +1,13 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<fop version="1.0"> | |||
<base>.</base> | |||
<renderers> | |||
<renderer mime="application/x-afp"> | |||
<fonts> | |||
<font> | |||
<font-triplet name="TEST" style="normal" weight="normal"/> | |||
</font> | |||
</fonts> | |||
</renderer> | |||
</renderers> | |||
</fop> |
@@ -0,0 +1,16 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<fop version="1.0"> | |||
<base>.</base> | |||
<renderers> | |||
<renderer mime="application/x-afp"> | |||
<fonts> | |||
<font> | |||
<afp-font name="TEST" type="raster" codepage="T1V10500" encoding="Cp500" ebcdic-dbcs="true"> | |||
<afp-raster-font size="36" characterset="THIS NAME IS TOO LONG"/> | |||
</afp-font> | |||
<font-triplet name="TEST" style="normal" weight="normal"/> | |||
</font> | |||
</fonts> | |||
</renderer> | |||
</renderers> | |||
</fop> |
@@ -0,0 +1,16 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<fop version="1.0"> | |||
<base>.</base> | |||
<renderers> | |||
<renderer mime="application/x-afp"> | |||
<fonts> | |||
<font> | |||
<afp-font name="TEST" type="raster" codepage="T1V10500" encoding="Cp500"> | |||
<afp-raster-font size="36" characterset="C0N200Z0"/> | |||
</afp-font> | |||
<font-triplet name="TEST" style="normal" weight="normal"/> | |||
</font> | |||
</fonts> | |||
</renderer> | |||
</renderers> | |||
</fop> |
@@ -0,0 +1,16 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<fop version="1.0"> | |||
<base>.</base> | |||
<renderers> | |||
<renderer mime="application/x-afp"> | |||
<fonts> | |||
<font> | |||
<afp-font name="TEST" type="raster" codepage="bad:\\lkja" encoding="Cp500" ebcdic-dbcs="true"> | |||
<afp-raster-font size="36" characterset="C0N200Z0"/> | |||
</afp-font> | |||
<font-triplet name="TEST" style="normal" weight="normal"/> | |||
</font> | |||
</fonts> | |||
</renderer> | |||
</renderers> | |||
</fop> |
@@ -0,0 +1,15 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<fop version="1.0"> | |||
<base>.</base> | |||
<renderers> | |||
<renderer mime="application/x-afp"> | |||
<fonts> | |||
<font> | |||
<afp-font name="TEST" type="raster" codepage="T1V10500" encoding="Cp500"> | |||
</afp-font> | |||
<font-triplet name="TEST" style="normal" weight="normal"/> | |||
</font> | |||
</fonts> | |||
</renderer> | |||
</renderers> | |||
</fop> |
@@ -0,0 +1,15 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<fop version="1.0"> | |||
<base>.</base> | |||
<renderers> | |||
<renderer mime="application/x-afp"> | |||
<fonts> | |||
<font> | |||
<afp-font name="Times Roman" type="raster" codepage="T1V10500" encoding="Cp500"> | |||
<afp-raster-font size="36" characterset="C0N200Z0" base14-font="TimesRoman"/> | |||
</afp-font> | |||
</font> | |||
</fonts> | |||
</renderer> | |||
</renderers> | |||
</fop> |
@@ -0,0 +1,79 @@ | |||
/* | |||
* 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.afp; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import javax.xml.transform.TransformerException; | |||
import org.junit.Test; | |||
import org.xml.sax.SAXException; | |||
import org.apache.xmlgraphics.util.MimeConstants; | |||
import org.apache.fop.apps.FOPException; | |||
import org.apache.fop.events.EventProcessingTestCase; | |||
/** | |||
* A test class for testing AFP events. | |||
*/ | |||
public class AFPEventProcessingTestCase { | |||
private EventProcessingTestCase eventsTests = new EventProcessingTestCase(); | |||
private static final String CONFIG_BASE_DIR = EventProcessingTestCase.CONFIG_BASE_DIR; | |||
private void testInvalidConfigEvent(String xconf, String eventId) | |||
throws FOPException, TransformerException, IOException, SAXException { | |||
InputStream inStream = getClass().getResourceAsStream("simple.fo"); | |||
eventsTests.doTest(inStream, CONFIG_BASE_DIR + xconf, | |||
AFPEventProducer.class.getName() + eventId, MimeConstants.MIME_AFP); | |||
} | |||
@Test | |||
public void testMissingFontConfigurationElement() throws FOPException, TransformerException, | |||
IOException, SAXException { | |||
testInvalidConfigEvent("afp-font-missing.xconf", ".fontConfigMissing"); | |||
} | |||
@Test | |||
public void testInvalidCharactersetName() throws FOPException, TransformerException, | |||
IOException, SAXException { | |||
testInvalidConfigEvent("afp-invalid-characterset.xconf", ".characterSetNameInvalid"); | |||
} | |||
@Test | |||
public void testinvalidConfig() throws FOPException, TransformerException, IOException, | |||
SAXException { | |||
testInvalidConfigEvent("afp-invalid-config.xconf", ".invalidConfiguration"); | |||
} | |||
@Test | |||
public void testRasterFontElementMissing() throws FOPException, TransformerException, | |||
IOException, SAXException { | |||
testInvalidConfigEvent("afp-raster-font-missing.xconf", ".fontConfigMissing"); | |||
} | |||
@Test | |||
public void testTripletElementMissing() throws FOPException, TransformerException, | |||
IOException, SAXException { | |||
testInvalidConfigEvent("afp-triplet-missing.xconf", ".fontConfigMissing"); | |||
} | |||
} |
@@ -0,0 +1,14 @@ | |||
<?xml version="1.0" standalone="no"?> | |||
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> | |||
<fo:layout-master-set> | |||
<fo:simple-page-master master-name="page" | |||
page-height="420pt" page-width="320pt" margin="10pt"> | |||
<fo:region-body background-color="#F0F0F0"/> | |||
</fo:simple-page-master> | |||
</fo:layout-master-set> | |||
<fo:page-sequence master-reference="page"> | |||
<fo:flow flow-name="xsl-region-body"> | |||
<fo:block>This is a simple document.</fo:block> | |||
</fo:flow> | |||
</fo:page-sequence> | |||
</fo:root> |
@@ -60,7 +60,10 @@ public class EventProcessingTestCase { | |||
private static final String BASE_DIR = "test/events/"; | |||
public void doTest(InputStream inStream, String fopConf, String expectedEventID) | |||
/** The base directory of configuration files */ | |||
public static final String CONFIG_BASE_DIR = "test/config/"; | |||
public void doTest(InputStream inStream, String fopConf, String expectedEventID, String mimeType) | |||
throws FOPException, TransformerException, IOException, SAXException { | |||
EventChecker eventChecker = new EventChecker(expectedEventID); | |||
if (fopConf != null) { | |||
@@ -68,7 +71,7 @@ public class EventProcessingTestCase { | |||
} | |||
FOUserAgent userAgent = fopFactory.newFOUserAgent(); | |||
userAgent.getEventBroadcaster().addEventListener(eventChecker); | |||
Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, userAgent, new NullOutputStream()); | |||
Fop fop = fopFactory.newFop(mimeType, userAgent, new NullOutputStream()); | |||
Transformer transformer = tFactory.newTransformer(); | |||
Source src = new StreamSource(inStream); | |||
Result res = new SAXResult(fop.getDefaultHandler()); | |||
@@ -78,12 +81,8 @@ public class EventProcessingTestCase { | |||
public void doTest(String filename, String expectedEventID) throws | |||
FOPException, TransformerException, IOException, SAXException { | |||
doTest(filename, null, expectedEventID); | |||
} | |||
public void doTest(String filename, String fopConf, String expectedEventID) throws | |||
FOPException, TransformerException, IOException, SAXException { | |||
doTest(new FileInputStream(BASE_DIR + filename), fopConf, expectedEventID); | |||
doTest(new FileInputStream(BASE_DIR + filename), null, expectedEventID, | |||
MimeConstants.MIME_PDF); | |||
} | |||
@Test |
@@ -27,6 +27,8 @@ import javax.xml.transform.TransformerException; | |||
import org.junit.Test; | |||
import org.xml.sax.SAXException; | |||
import org.apache.xmlgraphics.util.MimeConstants; | |||
import org.apache.fop.apps.FOPException; | |||
import org.apache.fop.events.EventProcessingTestCase; | |||
@@ -37,17 +39,22 @@ public class FontEventProcessingTestCase { | |||
private EventProcessingTestCase eventsTests = new EventProcessingTestCase(); | |||
private static final String CONFIG_BASE_DIR = EventProcessingTestCase.CONFIG_BASE_DIR; | |||
@Test | |||
public void testFont() throws FOPException, TransformerException, IOException, SAXException { | |||
InputStream inStream = getClass().getResourceAsStream("substituted-font.fo"); | |||
eventsTests.doTest(inStream, null, FontEventProducer.class.getName() + ".fontSubstituted"); | |||
eventsTests.doTest(inStream, null, FontEventProducer.class.getName() + ".fontSubstituted", | |||
MimeConstants.MIME_PDF); | |||
} | |||
@Test | |||
public void testFontWithBadDirectory() throws FOPException, TransformerException, IOException, | |||
SAXException { | |||
InputStream inStream = getClass().getResourceAsStream("substituted-font.fo"); | |||
eventsTests.doTest(inStream, "test/config/test_fonts_directory_bad.xconf", | |||
FontEventProducer.class.getName() + ".fontDirectoryNotFound"); | |||
eventsTests.doTest(inStream, CONFIG_BASE_DIR + "test_fonts_directory_bad.xconf", | |||
FontEventProducer.class.getName() + ".fontDirectoryNotFound", | |||
MimeConstants.MIME_PDF); | |||
} | |||
} |