diff options
18 files changed, 258 insertions, 132 deletions
@@ -482,7 +482,7 @@ list of possible build targets. need to be defined even if no jdk 14 is available. --> <mkdir dir="${build.dir}/temp"/> <retroweaver srcdir="${build.classes.dir}" destdir="${build.dir}/temp" - classpathref="verify-classpath" lazy="false" + classpath="${toString:verify-classpath}" lazy="false" verify="true" target="1.4" /> </target> <target name="retro" depends="retro-avail,retro-unavail,compile"> @@ -1125,23 +1125,28 @@ NOTE: </taskdef> <pmd shortFilenames="true" targetjdk="${javac.target}"> <ruleset>basic</ruleset> - <ruleset>braces</ruleset> - <ruleset>codesize</ruleset> - <ruleset>clone</ruleset> - <ruleset>design</ruleset> - <ruleset>finalizers</ruleset> - <ruleset>imports</ruleset> - <ruleset>strings</ruleset> <ruleset>rulesets/migrating_to_14.xml</ruleset> - <ruleset>optimizations</ruleset> <ruleset>sunsecure</ruleset> - <ruleset>unusedcode</ruleset> <formatter type="html" toFile="${build.dir}/report_pmd.html"/> <fileset dir="${src.java.dir}"> <include name="**/*.java"/> </fileset> </pmd> </target> + + <target name="cpd" depends="init" description="Runs PMD/CDP for a code quality report"> + <taskdef name="cpd" classname="net.sourceforge.pmd.cpd.CPDTask"> + <classpath> + <path refid="libs-build-classpath"/> + <path refid="libs-build-tools-classpath"/> + </classpath> + </taskdef> + <cpd minimumTokenCount="100" outputFile="${build.dir}/report_cpd.txt"> + <fileset dir="${src.java.dir}"> + <include name="**/*.java"/> + </fileset> + </cpd> + </target> <!-- =================================================================== --> <!-- Findbugs --> <!-- =================================================================== --> @@ -1164,7 +1169,7 @@ NOTE: <!-- =================================================================== --> <!-- Creates the reports --> <!-- =================================================================== --> - <target name="reports" depends="checkstyle, pmd, findbugs" description="Runs all configured code quality reports"/> + <target name="reports" depends="checkstyle, pmd, cpd, findbugs" description="Runs all configured code quality reports"/> <!-- =================================================================== --> <!-- Creates the documentation --> <!-- =================================================================== --> diff --git a/lib/build/pmd-4.2.5.jar b/lib/build/pmd-4.2.5.jar Binary files differnew file mode 100644 index 000000000..986ad2010 --- /dev/null +++ b/lib/build/pmd-4.2.5.jar diff --git a/lib/build/pmd14-4.2.2.jar b/lib/build/pmd14-4.2.2.jar Binary files differdeleted file mode 100644 index 6321a18ae..000000000 --- a/lib/build/pmd14-4.2.2.jar +++ /dev/null diff --git a/src/documentation/content/xdocs/trunk/fonts.xml b/src/documentation/content/xdocs/trunk/fonts.xml index 165487e73..429c86a51 100644 --- a/src/documentation/content/xdocs/trunk/fonts.xml +++ b/src/documentation/content/xdocs/trunk/fonts.xml @@ -474,7 +474,9 @@ This is helpful with older versions of Acrobat Reader that preferred installed fonts over embedded fonts.</li> <li>When embedding PostScript fonts, the entire font is always embedded.</li> <li>When embedding TrueType fonts (ttf) or TrueType Collections (ttc), a subset of the - original font, containing only the glyphs used, is embedded in the output document.</li> + original font, containing only the glyphs used, is embedded in the output document. + That's the default, but if you specify encoding-mode="single-byte" (see above), the + complete font is embedded.</li> </ul> </section> <section id="substitution"> diff --git a/src/java/org/apache/fop/afp/fonts/AFPFontReader.java b/src/java/org/apache/fop/afp/fonts/AFPFontReader.java index 07fafecd1..d1e8bd8db 100644 --- a/src/java/org/apache/fop/afp/fonts/AFPFontReader.java +++ b/src/java/org/apache/fop/afp/fonts/AFPFontReader.java @@ -73,6 +73,10 @@ public final class AFPFontReader { private static final byte[] CHARACTER_TABLE_SF = new byte[] { (byte) 0xD3, (byte) 0x8C, (byte) 0x87}; + /** Font descriptor MO:DCA structured field. */ + private static final byte[] FONT_DESCRIPTOR_SF = new byte[] { + (byte) 0xD3, (byte) 0xA6, (byte) 0x89 }; + /** Font control MO:DCA structured field. */ private static final byte[] FONT_CONTROL_SF = new byte[] { (byte) 0xD3, (byte) 0xA7, (byte) 0x89 }; @@ -90,26 +94,6 @@ public final class AFPFontReader { (byte) 0xD3, (byte) 0x8C, (byte) 0x89 }; /** - * The conversion factor to millipoints for 240 dpi - */ - private static final int FOP_100_DPI_FACTOR = 1; - - /** - * The conversion factor to millipoints for 240 dpi - */ - private static final int FOP_240_DPI_FACTOR = 300000; - - /** - * The conversion factor to millipoints for 300 dpi - */ - private static final int FOP_300_DPI_FACTOR = 240000; - - /** - * The encoding to use to convert from EBCIDIC to ASCII - */ - private static final String ASCII_ENCODING = "UTF8"; - - /** * The collection of code pages */ private final Map/*<String, Map<String, String>>*/ codePages @@ -242,6 +226,9 @@ public final class AFPFontReader { StructuredFieldReader structuredFieldReader = new StructuredFieldReader(inputStream); + // Process D3A689 Font Descriptor + int pointSize = processFontDescriptor(structuredFieldReader); + // Process D3A789 Font Control FontControl fontControl = processFontControl(structuredFieldReader); @@ -251,14 +238,20 @@ public final class AFPFontReader { = processFontOrientation(structuredFieldReader); int dpi = fontControl.getDpi(); + int metricNormalizationFactor = 0; + if (fontControl.isRelative()) { + metricNormalizationFactor = 1; + } else { + metricNormalizationFactor = 72000 / dpi / pointSize; + } //process D3AC89 Font Position - processFontPosition(structuredFieldReader, characterSetOrientations, dpi); + processFontPosition(structuredFieldReader, characterSetOrientations, metricNormalizationFactor); //process D38C89 Font Index (per orientation) for (int i = 0; i < characterSetOrientations.length; i++) { processFontIndex(structuredFieldReader, - characterSetOrientations[i], codePage, dpi); + characterSetOrientations[i], codePage, metricNormalizationFactor); characterSet.addCharacterSetOrientation(characterSetOrientations[i]); } } else { @@ -313,7 +306,6 @@ public final class AFPFontReader { String gcgiString = new String(gcgiBytes, AFPConstants.EBCIDIC_ENCODING); String charString = new String(charBytes, encoding); -// int value = charString.charAt(0); codePages.put(gcgiString, charString); } else { position++; @@ -327,6 +319,21 @@ public final class AFPFontReader { } /** + * Process the font descriptor details using the structured field reader. + * + * @param structuredFieldReader the structured field reader + * @return the nominal size of the font (in points) + */ + private static int processFontDescriptor(StructuredFieldReader structuredFieldReader) + throws IOException { + + byte[] fndData = structuredFieldReader.getNext(FONT_DESCRIPTOR_SF); + + int nominalPointSize = (((fndData[39] & 0xFF) << 8) + (fndData[40] & 0xFF)) / 10; + return nominalPointSize; + } + + /** * Process the font control details using the structured field reader. * * @param structuredFieldReader @@ -337,7 +344,6 @@ public final class AFPFontReader { byte[] fncData = structuredFieldReader.getNext(FONT_CONTROL_SF); -// int position = 0; FontControl fontControl = null; if (fncData != null) { fontControl = new FontControl(); @@ -345,10 +351,8 @@ public final class AFPFontReader { if (fncData[7] == (byte) 0x02) { fontControl.setRelative(true); } - - int dpi = (((fncData[9] & 0xFF) << 8) + (fncData[10] & 0xFF)) / 10; - - fontControl.setDpi(dpi); + int metricResolution = (((fncData[9] & 0xFF) << 8) + (fncData[10] & 0xFF)) / 10; + fontControl.setDpi(metricResolution); } return fontControl; } @@ -418,9 +422,12 @@ public final class AFPFontReader { * the structured field reader * @param characterSetOrientations * the array of CharacterSetOrientation objects + * @param metricNormalizationFactor factor to apply to the metrics to get normalized + * font metric values */ private void processFontPosition(StructuredFieldReader structuredFieldReader, - CharacterSetOrientation[] characterSetOrientations, int dpi) throws IOException { + CharacterSetOrientation[] characterSetOrientations, int metricNormalizationFactor) + throws IOException { byte[] data = structuredFieldReader.getNext(FONT_POSITION_SF); @@ -428,52 +435,32 @@ public final class AFPFontReader { byte[] fpData = new byte[26]; int characterSetOrientationIndex = 0; - int fopFactor = 0; - - switch (dpi) { - case 100: - fopFactor = FOP_100_DPI_FACTOR; - break; - case 240: - fopFactor = FOP_240_DPI_FACTOR; - break; - case 300: - fopFactor = FOP_300_DPI_FACTOR; - break; - default: - String msg = "Unsupported font resolution of " + dpi + " dpi."; - log.error(msg); - throw new IOException(msg); - } // Read data, ignoring bytes 0 - 2 for (int index = 3; index < data.length; index++) { if (position < 22) { // Build the font orientation record fpData[position] = data[index]; - } else if (position == 22) { - - position = 0; - - CharacterSetOrientation characterSetOrientation - = characterSetOrientations[characterSetOrientationIndex]; - - int xHeight = ((fpData[2] & 0xFF) << 8) + (fpData[3] & 0xFF); - int capHeight = ((fpData[4] & 0xFF) << 8) + (fpData[5] & 0xFF); - int ascHeight = ((fpData[6] & 0xFF) << 8) + (fpData[7] & 0xFF); - int dscHeight = ((fpData[8] & 0xFF) << 8) + (fpData[9] & 0xFF); + if (position == 9) { + CharacterSetOrientation characterSetOrientation + = characterSetOrientations[characterSetOrientationIndex]; - dscHeight = dscHeight * -1; + int xHeight = ((fpData[2] & 0xFF) << 8) + (fpData[3] & 0xFF); + int capHeight = ((fpData[4] & 0xFF) << 8) + (fpData[5] & 0xFF); + int ascHeight = ((fpData[6] & 0xFF) << 8) + (fpData[7] & 0xFF); + int dscHeight = ((fpData[8] & 0xFF) << 8) + (fpData[9] & 0xFF); - characterSetOrientation.setXHeight(xHeight * fopFactor); - characterSetOrientation.setCapHeight(capHeight * fopFactor); - characterSetOrientation.setAscender(ascHeight * fopFactor); - characterSetOrientation.setDescender(dscHeight * fopFactor); + dscHeight = dscHeight * -1; + characterSetOrientation.setXHeight(xHeight * metricNormalizationFactor); + characterSetOrientation.setCapHeight(capHeight * metricNormalizationFactor); + characterSetOrientation.setAscender(ascHeight * metricNormalizationFactor); + characterSetOrientation.setDescender(dscHeight * metricNormalizationFactor); + } + } else if (position == 22) { + position = 0; characterSetOrientationIndex++; - fpData[position] = data[index]; - } position++; @@ -484,37 +471,18 @@ public final class AFPFontReader { /** * Process the font index details for the character set orientation. * - * @param structuredFieldReader - * the structured field reader - * @param cso - * the CharacterSetOrientation object to populate - * @param codepage - * the map of code pages + * @param structuredFieldReader the structured field reader + * @param cso the CharacterSetOrientation object to populate + * @param codepage the map of code pages + * @param metricNormalizationFactor factor to apply to the metrics to get normalized + * font metric values */ private void processFontIndex(StructuredFieldReader structuredFieldReader, - CharacterSetOrientation cso, Map/*<String,String>*/ codepage, int dpi) + CharacterSetOrientation cso, Map/*<String,String>*/ codepage, int metricNormalizationFactor) throws IOException { byte[] data = structuredFieldReader.getNext(FONT_INDEX_SF); - int fopFactor = 0; - - switch (dpi) { - case 100: - fopFactor = FOP_100_DPI_FACTOR; - break; - case 240: - fopFactor = FOP_240_DPI_FACTOR; - break; - case 300: - fopFactor = FOP_300_DPI_FACTOR; - break; - default: - String msg = "Unsupported font resolution of " + dpi + " dpi."; - log.error(msg); - throw new IOException(msg); - } - int position = 0; byte[] gcgid = new byte[8]; @@ -554,7 +522,7 @@ public final class AFPFontReader { highest = cidx; } - int a = (width * fopFactor); + int a = (width * metricNormalizationFactor); cso.setWidth(cidx, a); diff --git a/src/java/org/apache/fop/fonts/FontCache.java b/src/java/org/apache/fop/fonts/FontCache.java index fceeacb7b..9d5eff010 100644 --- a/src/java/org/apache/fop/fonts/FontCache.java +++ b/src/java/org/apache/fop/fonts/FontCache.java @@ -81,11 +81,18 @@ public final class FontCache implements Serializable { } private static File getUserHome() { - String s = System.getProperty("user.home"); - if (s != null) { - File userDir = new File(s); - if (userDir.exists()) { - return userDir; + return toDirectory(System.getProperty("user.home")); + } + + private static File getTempDirectory() { + return toDirectory(System.getProperty("java.io.tmpdir")); + } + + private static File toDirectory(String path) { + if (path != null) { + File dir = new File(path); + if (dir.exists()) { + return dir; } } return null; @@ -101,7 +108,15 @@ public final class FontCache implements Serializable { if (userHome != null) { File fopUserDir = new File(userHome, FOP_USER_DIR); if (forWriting) { - fopUserDir.mkdir(); + boolean writable = fopUserDir.canWrite(); + if (!fopUserDir.exists()) { + writable = fopUserDir.mkdir(); + } + if (!writable) { + userHome = getTempDirectory(); + fopUserDir = new File(userHome, FOP_USER_DIR); + fopUserDir.mkdir(); + } } return new File(fopUserDir, DEFAULT_CACHE_FILENAME); } diff --git a/src/java/org/apache/fop/fonts/SingleByteFont.java b/src/java/org/apache/fop/fonts/SingleByteFont.java index 92e7c0547..8739b42a4 100644 --- a/src/java/org/apache/fop/fonts/SingleByteFont.java +++ b/src/java/org/apache/fop/fonts/SingleByteFont.java @@ -19,8 +19,10 @@ package org.apache.fop.fonts; +import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Set; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -34,6 +36,7 @@ public class SingleByteFont extends CustomFont { private static Log log = LogFactory.getLog(SingleByteFont.class); private SingleByteEncoding mapping; + private boolean useNativeEncoding = false; private int[] width = null; @@ -41,6 +44,7 @@ public class SingleByteFont extends CustomFont { //Map<Character, UnencodedCharacter> private List additionalEncodings; + /** * Main constructor. */ @@ -190,6 +194,24 @@ public class SingleByteFont extends CustomFont { } /** + * Controls whether the font is configured to use its native encoding or if it + * may need to be re-encoded for the target format. + * @param value true indicates that the configured encoding is the font's native encoding + */ + public void setUseNativeEncoding(boolean value) { + this.useNativeEncoding = value; + } + + /** + * Indicates whether this font is configured to use its native encoding. This + * method is used to determine whether the font needs to be re-encoded. + * @return true if the font uses its native encoding. + */ + public boolean isUsingNativeEncoding() { + return this.useNativeEncoding; + } + + /** * Sets a width for a character. * @param index index of the character * @param w the width of the character @@ -219,6 +241,24 @@ public class SingleByteFont extends CustomFont { } /** + * Makes all unencoded characters available through additional encodings. This method + * is used in cases where the fonts need to be encoded in the target format before + * all text of the document is processed (for example in PostScript when resource optimization + * is disabled). + */ + public void encodeAllUnencodedCharacters() { + if (this.unencodedCharacters != null) { + Set sortedKeys = new java.util.TreeSet(this.unencodedCharacters.keySet()); + Iterator iter = sortedKeys.iterator(); + while (iter.hasNext()) { + Character ch = (Character)iter.next(); + char mapped = mapChar(ch.charValue()); + assert mapped != Typeface.NOT_FOUND; + } + } + } + + /** * Indicates whether the encoding has additional encodings besides the primary encoding. * @return true if there are additional encodings. */ diff --git a/src/java/org/apache/fop/fonts/type1/Type1FontLoader.java b/src/java/org/apache/fop/fonts/type1/Type1FontLoader.java index 1d0c75605..4979ba2bb 100644 --- a/src/java/org/apache/fop/fonts/type1/Type1FontLoader.java +++ b/src/java/org/apache/fop/fonts/type1/Type1FontLoader.java @@ -140,6 +140,7 @@ public class Type1FontLoader extends FontLoader { //Encoding if (afm != null) { String encoding = afm.getEncodingScheme(); + singleFont.setUseNativeEncoding(true); if ("AdobeStandardEncoding".equals(encoding)) { singleFont.setEncoding(CodePointMapping.STANDARD_ENCODING); } else { diff --git a/src/java/org/apache/fop/pdf/AbstractPDFFontStream.java b/src/java/org/apache/fop/pdf/AbstractPDFFontStream.java new file mode 100644 index 000000000..f3d005bd3 --- /dev/null +++ b/src/java/org/apache/fop/pdf/AbstractPDFFontStream.java @@ -0,0 +1,41 @@ +/* + * 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.pdf; + + +/** + * Base class for PDF font streams. + */ +public abstract class AbstractPDFFontStream extends AbstractPDFStream { + + /** + * Main constructor. + */ + public AbstractPDFFontStream() { + super(); + } + + /** {@inheritDoc} */ + protected void setupFilterList() { + addDefaultFilter(PDFFilterList.FONT_FILTER); + super.setupFilterList(); + } + +} diff --git a/src/java/org/apache/fop/pdf/AbstractPDFStream.java b/src/java/org/apache/fop/pdf/AbstractPDFStream.java index 1e1f1f259..fc853b512 100644 --- a/src/java/org/apache/fop/pdf/AbstractPDFStream.java +++ b/src/java/org/apache/fop/pdf/AbstractPDFStream.java @@ -47,13 +47,21 @@ public abstract class AbstractPDFStream extends PDFDictionary { * from outside. */ protected void setupFilterList() { + addDefaultFilter(PDFFilterList.DEFAULT_FILTER); + prepareImplicitFilters(); + getDocument().applyEncryption(this); + } + + /** + * Adds the default filter to the filter list if the filter list hasn't been initialized, yet. + * @param filterName the name of the default filter to use + */ + protected void addDefaultFilter(String filterName) { if (!getFilterList().isInitialized()) { getFilterList().addDefaultFilters( getDocumentSafely().getFilterMap(), - PDFFilterList.DEFAULT_FILTER); + filterName); } - prepareImplicitFilters(); - getDocument().applyEncryption(this); } /** diff --git a/src/java/org/apache/fop/pdf/PDFFactory.java b/src/java/org/apache/fop/pdf/PDFFactory.java index b820e12fe..0a4516ce6 100644 --- a/src/java/org/apache/fop/pdf/PDFFactory.java +++ b/src/java/org/apache/fop/pdf/PDFFactory.java @@ -955,7 +955,7 @@ public class PDFFactory { PDFGoTo gt = new PDFGoTo(page); gt.setDestination(dest); - getDocument().addTrailerObject(gt); + getDocument().registerObject(gt); PDFInternalLink internalLink = new PDFInternalLink(gt.referencePDF()); link.setAction(internalLink); diff --git a/src/java/org/apache/fop/pdf/PDFImageXObject.java b/src/java/org/apache/fop/pdf/PDFImageXObject.java index 7104422e7..a69d9e8de 100644 --- a/src/java/org/apache/fop/pdf/PDFImageXObject.java +++ b/src/java/org/apache/fop/pdf/PDFImageXObject.java @@ -164,11 +164,7 @@ public class PDFImageXObject extends PDFXObject { * {@inheritDoc} */ protected void setupFilterList() { - if (!getFilterList().isInitialized()) { - getFilterList().addDefaultFilters( - getDocumentSafely().getFilterMap(), - pdfimage.getFilterHint()); - } + addDefaultFilter(pdfimage.getFilterHint()); super.setupFilterList(); } diff --git a/src/java/org/apache/fop/pdf/PDFMetadata.java b/src/java/org/apache/fop/pdf/PDFMetadata.java index 6d15a67d4..5008183ef 100644 --- a/src/java/org/apache/fop/pdf/PDFMetadata.java +++ b/src/java/org/apache/fop/pdf/PDFMetadata.java @@ -60,11 +60,7 @@ public class PDFMetadata extends PDFStream { /** {@inheritDoc} */ protected void setupFilterList() { - if (!getFilterList().isInitialized()) { - getFilterList().addDefaultFilters( - getDocumentSafely().getFilterMap(), - PDFFilterList.METADATA_FILTER); - } + addDefaultFilter(PDFFilterList.METADATA_FILTER); super.setupFilterList(); } diff --git a/src/java/org/apache/fop/pdf/PDFT1Stream.java b/src/java/org/apache/fop/pdf/PDFT1Stream.java index 8181287b5..d723625eb 100644 --- a/src/java/org/apache/fop/pdf/PDFT1Stream.java +++ b/src/java/org/apache/fop/pdf/PDFT1Stream.java @@ -28,13 +28,11 @@ import org.apache.fop.fonts.type1.PFBData; /** * Special PDFStream for embedding Type 1 fonts. */ -public class PDFT1Stream extends AbstractPDFStream { +public class PDFT1Stream extends AbstractPDFFontStream { private PFBData pfb; - /** - * {@inheritDoc} - */ + /** {@inheritDoc} */ protected int getSizeHint() throws IOException { if (this.pfb != null) { return pfb.getLength(); diff --git a/src/java/org/apache/fop/pdf/PDFTTFStream.java b/src/java/org/apache/fop/pdf/PDFTTFStream.java index 6c68ea8bf..643ddb1e8 100644 --- a/src/java/org/apache/fop/pdf/PDFTTFStream.java +++ b/src/java/org/apache/fop/pdf/PDFTTFStream.java @@ -20,13 +20,15 @@ package org.apache.fop.pdf; import java.io.IOException; +import java.io.OutputStream; /** * Special PDFStream for embeddable TrueType fonts. */ -public class PDFTTFStream extends PDFStream { +public class PDFTTFStream extends AbstractPDFFontStream { private int origLength; + private byte[] ttfData; /** * Main constructor @@ -37,6 +39,15 @@ public class PDFTTFStream extends PDFStream { origLength = len; } + /** {@inheritDoc} */ + protected int getSizeHint() throws IOException { + if (this.ttfData != null) { + return ttfData.length; + } else { + return 0; //no hint available + } + } + /** * Overload the base object method so we don't have to copy * byte arrays around so much @@ -54,6 +65,11 @@ public class PDFTTFStream extends PDFStream { } /** {@inheritDoc} */ + protected void outputRawStreamData(OutputStream out) throws IOException { + out.write(this.ttfData); + } + + /** {@inheritDoc} */ protected void populateStreamDict(Object lengthEntry) { put("Length1", origLength); super.populateStreamDict(lengthEntry); @@ -66,8 +82,8 @@ public class PDFTTFStream extends PDFStream { * @throws IOException in case of an I/O problem */ public void setData(byte[] data, int size) throws IOException { - this.data.clear(); - getBufferOutputStream().write(data, 0, size); + this.ttfData = new byte[size]; + System.arraycopy(data, 0, this.ttfData, 0, size); } } diff --git a/src/java/org/apache/fop/render/ps/PSFontUtils.java b/src/java/org/apache/fop/render/ps/PSFontUtils.java index 6bb1f294b..a29210b41 100644 --- a/src/java/org/apache/fop/render/ps/PSFontUtils.java +++ b/src/java/org/apache/fop/render/ps/PSFontUtils.java @@ -57,7 +57,9 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils { protected static Log log = LogFactory.getLog(PSFontUtils.class); /** - * Generates the PostScript code for the font dictionary. + * Generates the PostScript code for the font dictionary. This method should only be + * used if no "resource optimization" is performed, i.e. when the fonts are not embedded + * in a second pass. * @param gen PostScript generator to use for output * @param fontInfo available fonts * @return a Map of PSResource instances representing all defined fonts (key: font key) @@ -65,11 +67,13 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils { */ public static Map writeFontDict(PSGenerator gen, FontInfo fontInfo) throws IOException { - return writeFontDict(gen, fontInfo, fontInfo.getFonts()); + return writeFontDict(gen, fontInfo, fontInfo.getFonts(), true); } /** - * Generates the PostScript code for the font dictionary. + * Generates the PostScript code for the font dictionary. This method assumes all used + * fonts and characters are known, i.e. when PostScript is generated with resource + * optimization turned on. * @param gen PostScript generator to use for output * @param fontInfo available fonts * @param fonts the set of fonts to work with @@ -78,6 +82,21 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils { */ public static Map writeFontDict(PSGenerator gen, FontInfo fontInfo, Map fonts) throws IOException { + return writeFontDict(gen, fontInfo, fonts, false); + } + + /** + * Generates the PostScript code for the font dictionary. + * @param gen PostScript generator to use for output + * @param fontInfo available fonts + * @param fonts the set of fonts to work with + * @param encodeAllCharacters true if all characters shall be encoded using additional, + * generated encodings. + * @return a Map of PSResource instances representing all defined fonts (key: font key) + * @throws IOException in case of an I/O problem + */ + private static Map writeFontDict(PSGenerator gen, FontInfo fontInfo, Map fonts, + boolean encodeAllCharacters) throws IOException { gen.commentln("%FOPBeginFontDict"); Map fontResources = new java.util.HashMap(); @@ -91,6 +110,11 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils { if (tf instanceof SingleByteFont) { SingleByteFont sbf = (SingleByteFont)tf; + + if (encodeAllCharacters) { + sbf.encodeAllUnencodedCharacters(); + } + for (int i = 0, c = sbf.getAdditionalEncodingCount(); i < c; i++) { SingleByteEncoding encoding = sbf.getAdditionalEncoding(i); defineEncoding(gen, encoding); @@ -110,6 +134,7 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils { ResourceTracker tracker = gen.getResourceTracker(); if (!tracker.isResourceSupplied(WINANSI_ENCODING_RESOURCE)) { + //Only out Base 14 fonts still use that defineWinAnsiEncoding(gen); } gen.commentln("%FOPBeginFontReencode"); @@ -135,6 +160,12 @@ public class PSFontUtils extends org.apache.xmlgraphics.ps.PSFontUtils { if (tf instanceof Base14Font) { //Our Base 14 fonts don't use the default encoding redefineFontEncoding(gen, tf.getFontName(), tf.getEncodingName()); + } else if (tf instanceof SingleByteFont) { + SingleByteFont sbf = (SingleByteFont)tf; + if (!sbf.isUsingNativeEncoding()) { + //Font has been configured to use an encoding other than the default one + redefineFontEncoding(gen, tf.getFontName(), tf.getEncodingName()); + } } } } diff --git a/src/java/org/apache/fop/render/ps/ResourceHandler.java b/src/java/org/apache/fop/render/ps/ResourceHandler.java index 0b2f174f5..1590363a1 100644 --- a/src/java/org/apache/fop/render/ps/ResourceHandler.java +++ b/src/java/org/apache/fop/render/ps/ResourceHandler.java @@ -249,6 +249,7 @@ public class ResourceHandler implements DSCParserConstants, PSSupportedFlavors { DSCEvent event = parser.nextEvent(); event.generate(gen); } + gen.flush(); } private static void reportInvalidDSC() throws DSCException { diff --git a/status.xml b/status.xml index f4d479c42..74393873d 100644 --- a/status.xml +++ b/status.xml @@ -58,6 +58,14 @@ documents. Example: the fix of marks layering will be such a case when it's done. --> <release version="FOP Trunk" date="TBD"> + <action context="Fonts" dev="JM" type="fix" fixes-bug="46686" due-to="Alok Singh"> + Use temporary directory for the font cache if the user home directory is not + write-accessible. + </action> + <action context="Renderers" dev="JM" type="fix" fixes-bug="45342" due-to="Emil Maskovsky"> + AFP Fonts: Fixed interpretation of metric for fonts with fixed metrics and made sure + all repeating groups in FNP (Font Position) are processed. + </action> <action context="Renderers" dev="JM" type="add"> AFP Output: Added a configuration option to override the resource level defaults in the code. |