git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/branches/Temp_AreaTreeNewDesign@744946 13f79535-47bb-0310-9956-ffa450edef68tags/fop-1_0
@@ -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 --> | |||
<!-- =================================================================== --> |
@@ -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"> |
@@ -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 }; | |||
@@ -89,26 +93,6 @@ public final class AFPFontReader { | |||
private static final byte[] FONT_INDEX_SF = new byte[] { | |||
(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 | |||
*/ | |||
@@ -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++; | |||
@@ -326,6 +318,21 @@ public final class AFPFontReader { | |||
return codePages; | |||
} | |||
/** | |||
* 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. | |||
* | |||
@@ -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); | |||
@@ -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); | |||
} |
@@ -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. | |||
*/ | |||
@@ -189,6 +193,24 @@ public class SingleByteFont extends CustomFont { | |||
this.mapping = encoding; | |||
} | |||
/** | |||
* 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 | |||
@@ -218,6 +240,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. |
@@ -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 { |
@@ -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(); | |||
} | |||
} |
@@ -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); | |||
} | |||
/** |
@@ -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); | |||
@@ -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(); | |||
} | |||
@@ -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(); | |||
} | |||
@@ -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(); |
@@ -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 | |||
@@ -53,6 +64,11 @@ public class PDFTTFStream extends PDFStream { | |||
return length; | |||
} | |||
/** {@inheritDoc} */ | |||
protected void outputRawStreamData(OutputStream out) throws IOException { | |||
out.write(this.ttfData); | |||
} | |||
/** {@inheritDoc} */ | |||
protected void populateStreamDict(Object lengthEntry) { | |||
put("Length1", origLength); | |||
@@ -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); | |||
} | |||
} |
@@ -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()); | |||
} | |||
} | |||
} | |||
} |
@@ -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 { |
@@ -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. |