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-ffa450edef68tags/fop-0_93
@@ -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(); | |||
} |
@@ -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; | |||
} | |||
} | |||
@@ -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; | |||
} | |||
} | |||
@@ -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> <FFFF>\n"); | |||
p.append("endcodespacerange\n"); | |||
} | |||
protected void writeCIDRange(StringBuffer p) { | |||
p.append("1 begincidrange\n"); | |||
p.append("<0000> <FFFF> 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); | |||
} | |||
} |
@@ -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; |