From 2ba9df23cd7fb81ba970ca6c89af60ca5630d443 Mon Sep 17 00:00:00 2001 From: Bertrand Delacretaz Date: Tue, 10 Oct 2006 13:00:05 +0000 Subject: [PATCH] Applied patch from bugzilla 5335, comment 10. Generates a ToUnicode table for embedded CID fonts. Patch provided by Adam Strzelecki, ono@java.pl. The patch contains code for the FOray project, used with permission (bugzilla 5335 comment #13). git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@454725 13f79535-47bb-0310-9956-ffa450edef68 --- src/java/org/apache/fop/fonts/CIDFont.java | 9 +++ .../org/apache/fop/fonts/MultiByteFont.java | 29 +++++++++- .../org/apache/fop/fonts/SingleByteFont.java | 5 +- src/java/org/apache/fop/pdf/PDFCMap.java | 57 +++++++++++++++++-- src/java/org/apache/fop/pdf/PDFFactory.java | 11 ++-- 5 files changed, 97 insertions(+), 14 deletions(-) diff --git a/src/java/org/apache/fop/fonts/CIDFont.java b/src/java/org/apache/fop/fonts/CIDFont.java index facfb9c88..dd12991c1 100644 --- a/src/java/org/apache/fop/fonts/CIDFont.java +++ b/src/java/org/apache/fop/fonts/CIDFont.java @@ -38,6 +38,11 @@ public abstract class CIDFont extends CustomFont { public Map usedGlyphsIndex = new java.util.HashMap(); public int usedGlyphsCount = 0; + /** + * usedCharsIndex contains new glyph, original char + */ + public Map usedCharsIndex = new java.util.HashMap(); + //private PDFWArray warray = new PDFWArray(); public int width[] = null; @@ -91,4 +96,8 @@ public abstract class CIDFont extends CustomFont { return true; } + /** + * Returns char[] array . + */ + public abstract char[] getCharsUsed(); } \ No newline at end of file diff --git a/src/java/org/apache/fop/fonts/MultiByteFont.java b/src/java/org/apache/fop/fonts/MultiByteFont.java index ed1bbd505..6db84b68d 100644 --- a/src/java/org/apache/fop/fonts/MultiByteFont.java +++ b/src/java/org/apache/fop/fonts/MultiByteFont.java @@ -126,7 +126,7 @@ public class MultiByteFont extends CIDFont { * @see org.apache.fop.fonts.FontDescriptor#isEmbeddable() */ public boolean isEmbeddable() { - return !(getEmbedFileName() == null && embedResourceName == null); + return !(getEmbedFileName() == null && embedResourceName == null); } /** @@ -199,8 +199,8 @@ public class MultiByteFont extends CIDFont { for (int i = 0; (i < bfentries.length) && retIdx == 0; i++) { if (bfentries[i].getUnicodeStart() <= idx && bfentries[i].getUnicodeEnd() >= idx) { - - retIdx = bfentries[i].getGlyphStartIndex() + + retIdx = bfentries[i].getGlyphStartIndex() + idx - bfentries[i].getUnicodeStart(); } @@ -223,6 +223,8 @@ public class MultiByteFont extends CIDFont { new Integer(usedGlyphsCount)); usedGlyphsIndex.put(new Integer(usedGlyphsCount), new Integer(retIdx)); + usedCharsIndex.put(new Integer(usedGlyphsCount), + new Integer((int) c)); retIdx = usedGlyphsCount; usedGlyphsCount++; } else { @@ -300,5 +302,26 @@ public class MultiByteFont extends CIDFont { return usedGlyphs; } + /** The invalid Unicode character, suitable as a return value in methods + * that need to return an invalid character. */ + public static final char INVALID_UNICODE_CHAR = 0xFFFF; + + public char[] getCharsUsed() { + if (! isEmbeddable()) { + return null; + } + char[] charArray = new char[usedGlyphsCount]; + for (int i = 0; i < usedGlyphsCount; i++) { + Integer mapValue = (Integer)usedCharsIndex.get(new Integer(i)); + if(mapValue != null) { + char arrayItem = (char) mapValue.intValue(); + charArray[i] = arrayItem; + } + else { + charArray[i] = INVALID_UNICODE_CHAR; + } + } + return charArray; + } } diff --git a/src/java/org/apache/fop/fonts/SingleByteFont.java b/src/java/org/apache/fop/fonts/SingleByteFont.java index a170514a9..99245fe28 100644 --- a/src/java/org/apache/fop/fonts/SingleByteFont.java +++ b/src/java/org/apache/fop/fonts/SingleByteFont.java @@ -95,7 +95,7 @@ public class SingleByteFont extends CustomFont { return '#'; } } - + /** * @see org.apache.fop.fonts.Typeface#hasChar(char) */ @@ -117,5 +117,8 @@ public class SingleByteFont extends CustomFont { this.width[index] = width; } + public char[] getCharsUsed() { + return null; + } } diff --git a/src/java/org/apache/fop/pdf/PDFCMap.java b/src/java/org/apache/fop/pdf/PDFCMap.java index 84d9f8359..d62e45d85 100644 --- a/src/java/org/apache/fop/pdf/PDFCMap.java +++ b/src/java/org/apache/fop/pdf/PDFCMap.java @@ -19,6 +19,9 @@ package org.apache.fop.pdf; +import java.io.IOException; +import java.io.OutputStream; + /** * Class representing the CMap encodings. * @@ -424,53 +427,91 @@ public class PDFCMap extends PDFStream { * @param p the string buffer to add the pdf data to */ public void fillInPDF(StringBuffer p) { + writePreStream(p); + writeStreamComments(p); + writeCIDInit(p); + writeCIDSystemInfo(p); + writeVersionTypeName(p); + writeCodeSpaceRange(p); + writeCIDRange(p); + writeBFEntries(p); + writeWrapUp(p); + writeStreamAfterComments(p); + writeUseCMap(p); + add(p.toString()); + } + + protected void writePreStream(StringBuffer p) { // p.append("/Type /CMap\n"); // p.append(sysInfo.toPDFString()); - // p.append("/CMapName /" + name); - // p.append("\n"); + // p.append("/CMapName /" + name + EOL); + } + + protected void writeStreamComments(StringBuffer p) { p.append("%!PS-Adobe-3.0 Resource-CMap\n"); p.append("%%DocumentNeededResources: ProcSet (CIDInit)\n"); p.append("%%IncludeResource: ProcSet (CIDInit)\n"); p.append("%%BeginResource: CMap (" + name + ")\n"); p.append("%%EndComments\n"); + } + protected void writeCIDInit(StringBuffer p) { p.append("/CIDInit /ProcSet findresource begin\n"); p.append("12 dict begin\n"); p.append("begincmap\n"); + } + protected void writeCIDSystemInfo(StringBuffer p) { p.append("/CIDSystemInfo 3 dict dup begin\n"); p.append(" /Registry (Adobe) def\n"); p.append(" /Ordering (Identity) def\n"); p.append(" /Supplement 0 def\n"); p.append("end def\n"); + } + protected void writeVersionTypeName(StringBuffer p) { p.append("/CMapVersion 1 def\n"); p.append("/CMapType 1 def\n"); p.append("/CMapName /" + name + " def\n"); + } + protected void writeCodeSpaceRange(StringBuffer p) { p.append("1 begincodespacerange\n"); p.append("<0000> \n"); p.append("endcodespacerange\n"); + } + + protected void writeCIDRange(StringBuffer p) { p.append("1 begincidrange\n"); p.append("<0000> 0\n"); p.append("endcidrange\n"); + } + protected void writeBFEntries(StringBuffer p) { // p.append("1 beginbfrange\n"); // p.append("<0020> <0100> <0000>\n"); // p.append("endbfrange\n"); + } + protected void writeWrapUp(StringBuffer p) { p.append("endcmap\n"); p.append("CMapName currentdict /CMap defineresource pop\n"); p.append("end\n"); p.append("end\n"); + } + + protected void writeStreamAfterComments(StringBuffer p) { p.append("%%EndResource\n"); p.append("%%EOF\n"); + } + + protected void writeUseCMap(StringBuffer p) { /* - * p.append(" /Type /CMap\n/CMapName /" + name); - * p.append("\n"); - * p.append("\n/WMode "); p.append(wMode); + * p.append(" /Type /CMap"); + * p.append("/CMapName /" + name + EOL); + * p.append("/WMode " + wMode + EOL); * if (base != null) { - * p.append("\n/UseCMap "); + * p.append("/UseCMap "); * if (base instanceof String) { * p.append("/"+base); * } else {// base instanceof PDFStream @@ -480,4 +521,8 @@ public class PDFCMap extends PDFStream { */ } + protected int output(OutputStream stream) throws IOException { + fillInPDF(new StringBuffer()); + return super.output(stream); + } } diff --git a/src/java/org/apache/fop/pdf/PDFFactory.java b/src/java/org/apache/fop/pdf/PDFFactory.java index 77c25bc89..4ab6ebd7b 100644 --- a/src/java/org/apache/fop/pdf/PDFFactory.java +++ b/src/java/org/apache/fop/pdf/PDFFactory.java @@ -32,9 +32,6 @@ import java.util.Map; import javax.xml.transform.Source; import javax.xml.transform.stream.StreamSource; -//W3C DOM -import org.w3c.dom.Document; - // Apache libs import org.apache.commons.io.IOUtils; import org.apache.commons.io.output.ByteArrayOutputStream; @@ -957,7 +954,7 @@ public class PDFFactory { * @return the new PDF outline object */ public PDFOutline makeOutline(PDFOutline parent, String label, - String destination, float yoffset, + String destination, float yoffset, boolean showSubItems) { String goToRef = getGoToReference(destination, yoffset); @@ -1060,6 +1057,12 @@ public class PDFFactory { (PDFCIDFontDescriptor)pdfdesc); getDocument().registerObject(cidFont); + PDFCMap cmap = new PDFToUnicodeCMap(cidMetrics, "fop-ucs-H", + new PDFCIDSystemInfo("Adobe", + "Identity", + 0)); + getDocument().registerObject(cmap); + ((PDFFontType0)font).setCMAP(cmap); ((PDFFontType0)font).setDescendantFonts(cidFont); } else { int firstChar = 0; -- 2.39.5