git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1175754 13f79535-47bb-0310-9956-ffa450edef68tags/fop-1_1rc1old
@@ -86,5 +86,10 @@ public interface FontDescriptor extends FontMetrics { | |||
*/ | |||
boolean isEmbeddable(); | |||
/** | |||
* Indicates whether this font is subset embedded. | |||
* @return true if this font is subset embedded | |||
*/ | |||
boolean isSubsetEmbedded(); | |||
} |
@@ -27,12 +27,10 @@ import java.util.Set; | |||
import javax.xml.transform.Source; | |||
import javax.xml.transform.stream.StreamSource; | |||
import org.xml.sax.InputSource; | |||
import org.apache.commons.logging.Log; | |||
import org.apache.commons.logging.LogFactory; | |||
import org.apache.fop.apps.FOPException; | |||
import org.xml.sax.InputSource; | |||
/** | |||
* This class is used to defer the loading of a font until it is really used. | |||
@@ -375,5 +373,13 @@ public class LazyFont extends Typeface implements FontDescriptor { | |||
return realFontDescriptor.isEmbeddable(); | |||
} | |||
/** | |||
* {@inheritDoc} | |||
*/ | |||
public boolean isSubsetEmbedded() { | |||
load(true); | |||
return realFont.isMultiByte(); | |||
} | |||
} | |||
@@ -20,7 +20,6 @@ | |||
package org.apache.fop.fonts; | |||
//Java | |||
import java.text.DecimalFormat; | |||
import java.util.Map; | |||
@@ -29,16 +28,12 @@ import java.util.Map; | |||
*/ | |||
public class MultiByteFont extends CIDFont { | |||
private static int uniqueCounter = -1; | |||
private String ttcName = null; | |||
private String encoding = "Identity-H"; | |||
private int defaultWidth = 0; | |||
private CIDFontType cidType = CIDFontType.CIDTYPE2; | |||
private String namePrefix = null; // Quasi unique prefix | |||
private CIDSubset subset = new CIDSubset(); | |||
/** A map from Unicode indices to glyph indices */ | |||
@@ -49,31 +44,11 @@ public class MultiByteFont extends CIDFont { | |||
*/ | |||
public MultiByteFont() { | |||
subset.setupFirstGlyph(); | |||
// Create a quasiunique prefix for fontname | |||
synchronized (this.getClass()) { | |||
uniqueCounter++; | |||
if (uniqueCounter > 99999 || uniqueCounter < 0) { | |||
uniqueCounter = 0; //We need maximum 5 character then we start again | |||
} | |||
} | |||
DecimalFormat counterFormat = new DecimalFormat("00000"); | |||
String cntString = counterFormat.format(uniqueCounter); | |||
//Subset prefix as described in chapter 5.5.3 of PDF 1.4 | |||
StringBuffer sb = new StringBuffer("E"); | |||
for (int i = 0, c = cntString.length(); i < c; i++) { | |||
//translate numbers to uppercase characters | |||
sb.append((char)(cntString.charAt(i) + (65 - 48))); | |||
} | |||
sb.append("+"); | |||
namePrefix = sb.toString(); | |||
setFontType(FontType.TYPE0); | |||
} | |||
/** {@inheritDoc} */ | |||
public int getDefaultWidth() { | |||
/** {@inheritdoc} */ | |||
public int getdefaultwidth() { | |||
return defaultWidth; | |||
} | |||
@@ -105,14 +80,10 @@ public class MultiByteFont extends CIDFont { | |||
this.cidType = cidType; | |||
} | |||
private String getPrefixedFontName() { | |||
return namePrefix + FontUtil.stripWhiteSpace(super.getFontName()); | |||
} | |||
/** {@inheritDoc} */ | |||
public String getEmbedFontName() { | |||
if (isEmbeddable()) { | |||
return getPrefixedFontName(); | |||
return FontUtil.stripWhiteSpace(super.getFontName()); | |||
} else { | |||
return super.getFontName(); | |||
} | |||
@@ -123,6 +94,11 @@ public class MultiByteFont extends CIDFont { | |||
return !(getEmbedFileName() == null && getEmbedResourceName() == null); | |||
} | |||
/** {@inheritDoc} */ | |||
public boolean isSubsetEmbedded() { | |||
return true; | |||
} | |||
/** {@inheritDoc} */ | |||
public CIDSubset getCIDSubset() { | |||
return this.subset; |
@@ -63,7 +63,11 @@ public class SingleByteFont extends CustomFont { | |||
} | |||
/** {@inheritDoc} */ | |||
@Override | |||
public boolean isSubsetEmbedded() { | |||
return false; | |||
} | |||
/** {@inheritDoc} */ | |||
public String getEncodingName() { | |||
return this.mapping.getName(); | |||
} |
@@ -27,6 +27,7 @@ import java.io.FileNotFoundException; | |||
import java.io.IOException; | |||
import java.io.InputStream; | |||
import java.net.MalformedURLException; | |||
import java.text.DecimalFormat; | |||
import java.util.ArrayList; | |||
import java.util.Arrays; | |||
import java.util.BitSet; | |||
@@ -63,6 +64,7 @@ import org.apache.fop.fonts.truetype.FontFileReader; | |||
import org.apache.fop.fonts.truetype.TTFSubSetFile; | |||
import org.apache.fop.fonts.type1.PFBData; | |||
import org.apache.fop.fonts.type1.PFBParser; | |||
import org.apache.xmlgraphics.xmp.Metadata; | |||
/** | |||
* This class provides method to create and register PDF objects. | |||
@@ -76,6 +78,8 @@ public class PDFFactory { | |||
private Log log = LogFactory.getLog(PDFFactory.class); | |||
private int subsetFontCounter = -1; | |||
/** | |||
* Creates a new PDFFactory. | |||
* @param document the parent PDFDocument needed to register the generated | |||
@@ -1377,10 +1381,15 @@ public class PDFFactory { | |||
} else { | |||
FontType fonttype = metrics.getFontType(); | |||
PDFFontDescriptor pdfdesc = makeFontDescriptor(descriptor); | |||
String fontPrefix = descriptor.isSubsetEmbedded() ? createSubsetFontPrefix() : ""; | |||
String subsetFontName = fontPrefix + basefont; | |||
PDFFontDescriptor pdfdesc = makeFontDescriptor(descriptor, fontPrefix); | |||
PDFFont font = null; | |||
font = PDFFont.createFont(fontname, fonttype, basefont, null); | |||
font = PDFFont.createFont(fontname, fonttype, subsetFontName, null); | |||
getDocument().registerObject(font); | |||
if (fonttype == FontType.TYPE0) { | |||
@@ -1395,8 +1404,7 @@ public class PDFFactory { | |||
= new PDFCIDSystemInfo(cidMetrics.getRegistry(), | |||
cidMetrics.getOrdering(), | |||
cidMetrics.getSupplement()); | |||
PDFCIDFont cidFont | |||
= new PDFCIDFont(basefont, | |||
PDFCIDFont cidFont = new PDFCIDFont(subsetFontName, | |||
cidMetrics.getCIDType(), | |||
cidMetrics.getDefaultWidth(), | |||
getSubsetWidths(cidMetrics), sysInfo, | |||
@@ -1550,18 +1558,35 @@ public class PDFFactory { | |||
return warray; | |||
} | |||
private String createSubsetFontPrefix() { | |||
subsetFontCounter++; | |||
DecimalFormat counterFormat = new DecimalFormat("00000"); | |||
String counterString = counterFormat.format(subsetFontCounter); | |||
// Subset prefix as described in chapter 5.5.3 of PDF 1.4 | |||
StringBuffer sb = new StringBuffer("E"); | |||
for (char c : counterString.toCharArray()) { | |||
// translate numbers to uppercase characters | |||
sb.append((char) (c + ('A' - '0'))); | |||
} | |||
sb.append("+"); | |||
return sb.toString(); | |||
} | |||
/** | |||
* make a /FontDescriptor object | |||
* | |||
* @param desc the font descriptor | |||
* @param fontPrefix the String with which to prefix the font name | |||
* @return the new PDF font descriptor | |||
*/ | |||
public PDFFontDescriptor makeFontDescriptor(FontDescriptor desc) { | |||
private PDFFontDescriptor makeFontDescriptor(FontDescriptor desc, String fontPrefix) { | |||
PDFFontDescriptor descriptor = null; | |||
if (desc.getFontType() == FontType.TYPE0) { | |||
// CID Font | |||
descriptor = new PDFCIDFontDescriptor(desc.getEmbedFontName(), | |||
descriptor = new PDFCIDFontDescriptor(fontPrefix + desc.getEmbedFontName(), | |||
desc.getFontBBox(), | |||
desc.getCapHeight(), | |||
desc.getFlags(), |
@@ -60,6 +60,9 @@ | |||
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="PH" type="fix" fixes-bug="51759" due-to="Mehdi Houshmand"> | |||
PDFFactory responsible for asdigning name to a subset font. | |||
</action> | |||
<action context="Fonts" dev="PH" type="fix" fixes-bug="51530" due-to="Mehdi Houshmand"> | |||
Improved support for EBCDIC encoded double byte fonts fo AFP. | |||
</action> |
@@ -25,6 +25,7 @@ import junit.framework.TestSuite; | |||
import org.apache.fop.events.BasicEventTestCase; | |||
import org.apache.fop.pdf.FileIDGeneratorTestCase; | |||
import org.apache.fop.pdf.PDFEncryptionJCETestCase; | |||
import org.apache.fop.pdf.PDFFactoryTestCase; | |||
import org.apache.fop.pdf.PDFObjectTestCase; | |||
import org.apache.fop.traits.BorderPropsTestCase; | |||
import org.apache.fop.util.BitmapImageUtilTestCase; | |||
@@ -49,6 +50,7 @@ public class UtilityCodeTestSuite { | |||
suite.addTest(new TestSuite(PDFNumberTestCase.class)); | |||
suite.addTest(new TestSuite(PDFObjectTestCase.class)); | |||
suite.addTest(FileIDGeneratorTestCase.suite()); | |||
suite.addTest(new TestSuite(PDFFactoryTestCase.class)); | |||
suite.addTest(new TestSuite(ColorUtilTestCase.class)); | |||
suite.addTest(new TestSuite(BorderPropsTestCase.class)); | |||
suite.addTest(new TestSuite(ElementListUtilsTestCase.class)); |
@@ -0,0 +1,58 @@ | |||
/* | |||
* 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; | |||
import junit.framework.TestCase; | |||
import org.apache.fop.fonts.CIDSubset; | |||
import org.apache.fop.fonts.MultiByteFont; | |||
/** | |||
* Test case for {@link PDFFactory}. | |||
*/ | |||
public class PDFFactoryTestCase extends TestCase { | |||
/** | |||
* This tests that when a font is subset embedded in a PDF, the font name is prefixed with a | |||
* pseudo-random tag as per the PDF spec. | |||
*/ | |||
public void testSubsetFontNamePrefix() { | |||
class MockedFont extends MultiByteFont { | |||
@Override | |||
public int[] getWidths() { | |||
return new int[] { 0 }; | |||
} | |||
@Override | |||
public CIDSubset getCIDSubset() { | |||
return new CIDSubset(); | |||
} | |||
} | |||
PDFDocument doc = new PDFDocument("Test"); | |||
PDFFactory pdfFactory = new PDFFactory(doc); | |||
MockedFont font = new MockedFont(); | |||
PDFFont pdfDejaVu = pdfFactory.makeFont("DejaVu", "DejaVu", "TTF", font, font); | |||
assertEquals("/EAAAAA+DejaVu", pdfDejaVu.getBaseFont().toString()); | |||
PDFFont pdfArial = pdfFactory.makeFont("Arial", "Arial", "TTF", font, font); | |||
assertEquals("/EAAAAB+Arial", pdfArial.getBaseFont().toString()); | |||
} | |||
} |