summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Steiner <ssteiner@apache.org>2020-10-30 15:06:49 +0000
committerSimon Steiner <ssteiner@apache.org>2020-10-30 15:06:49 +0000
commit3bd145534c2f6d1755835eb071a13298db7be850 (patch)
tree7e4eea996c8b327bba39b9b39851e6caea5bad6e
parente92a71fbd66bb441984f45d91227c3cedfa94f75 (diff)
downloadxmlgraphics-fop-3bd145534c2f6d1755835eb071a13298db7be850.tar.gz
xmlgraphics-fop-3bd145534c2f6d1755835eb071a13298db7be850.zip
FOP-2981: Convert CFF CID to Type1
git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@1882997 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--fop-core/src/main/java/org/apache/fop/fonts/CFFToType1Font.java11
-rw-r--r--fop-core/src/main/java/org/apache/fop/render/ps/Type1FontFormatter.java54
-rw-r--r--fop-core/src/test/java/org/apache/fop/fonts/truetype/OTFToType1TestCase.java15
-rw-r--r--fop/test/resources/fonts/otf/AlexBrush-Regular-cid.otfbin0 -> 23240 bytes
4 files changed, 58 insertions, 22 deletions
diff --git a/fop-core/src/main/java/org/apache/fop/fonts/CFFToType1Font.java b/fop-core/src/main/java/org/apache/fop/fonts/CFFToType1Font.java
index a1b523811..3ef9b6e33 100644
--- a/fop-core/src/main/java/org/apache/fop/fonts/CFFToType1Font.java
+++ b/fop-core/src/main/java/org/apache/fop/fonts/CFFToType1Font.java
@@ -30,7 +30,6 @@ import java.util.Map;
import org.apache.commons.io.IOUtils;
import org.apache.fontbox.cff.CFFFont;
import org.apache.fontbox.cff.CFFParser;
-import org.apache.fontbox.cff.CFFType1Font;
import org.apache.fop.apps.io.InternalResourceResolver;
import org.apache.fop.fonts.type1.PFBData;
@@ -57,9 +56,6 @@ public class CFFToType1Font extends MultiByteFont {
private List<InputStream> convertOTFToType1(InputStream in) throws IOException {
CFFFont f = new CFFParser().parse(IOUtils.toByteArray(in)).get(0);
- if (!(f instanceof CFFType1Font)) {
- throw new IOException(getEmbedFileURI() + ": only OTF CFF Type1 font can be converted to Type1");
- }
List<InputStream> fonts = new ArrayList<InputStream>();
Map<Integer, Integer> glyphs = cidSet.getGlyphs();
int i = 0;
@@ -88,9 +84,10 @@ public class CFFToType1Font extends MultiByteFont {
return allGlyphs;
}
- private InputStream convertOTFToType1(Map<Integer, Integer> glyphs, CFFFont f, String i) throws IOException {
- byte[] t1 = new Type1FontFormatter(glyphs).format((CFFType1Font) f, i);
- PFBData pfb = new PFBParser().parsePFB(new ByteArrayInputStream(t1));
+ private InputStream convertOTFToType1(Map<Integer, Integer> glyphs, CFFFont cffFont, String splitGlyphsId)
+ throws IOException {
+ byte[] type1Bytes = new Type1FontFormatter(glyphs).format(cffFont, splitGlyphsId);
+ PFBData pfb = new PFBParser().parsePFB(new ByteArrayInputStream(type1Bytes));
ByteArrayOutputStream s1 = new ByteArrayOutputStream();
s1.write(pfb.getHeaderSegment());
ByteArrayOutputStream s2 = new ByteArrayOutputStream();
diff --git a/fop-core/src/main/java/org/apache/fop/render/ps/Type1FontFormatter.java b/fop-core/src/main/java/org/apache/fop/render/ps/Type1FontFormatter.java
index 0d1936702..776d410f9 100644
--- a/fop-core/src/main/java/org/apache/fop/render/ps/Type1FontFormatter.java
+++ b/fop-core/src/main/java/org/apache/fop/render/ps/Type1FontFormatter.java
@@ -24,6 +24,8 @@ import java.util.Collection;
import java.util.Locale;
import java.util.Map;
+import org.apache.fontbox.cff.CFFCIDFont;
+import org.apache.fontbox.cff.CFFFont;
import org.apache.fontbox.cff.CFFType1Font;
import org.apache.fontbox.cff.DataOutput;
import org.apache.fontbox.cff.Type1FontUtil;
@@ -47,13 +49,13 @@ public final class Type1FontFormatter {
* @return the Type1 font
* @throws IOException if an error occurs during reading the given font
*/
- public byte[] format(CFFType1Font font, String i) throws IOException {
+ public byte[] format(CFFFont font, String i) throws IOException {
DataOutput output = new DataOutput();
printFont(font, output, i);
return output.getBytes();
}
- private void printFont(CFFType1Font font, DataOutput output, String iStr)
+ private void printFont(CFFFont font, DataOutput output, String iStr)
throws IOException {
output.println("%!FontType1-1.0 " + font.getName() + iStr + " "
+ font.getTopDict().get("version"));
@@ -73,7 +75,7 @@ public final class Type1FontFormatter {
output.println("cleartomark");
}
- private void printFontDictionary(CFFType1Font font, DataOutput output, String iStr)
+ private void printFontDictionary(CFFFont font, DataOutput output, String iStr)
throws IOException {
output.println("10 dict begin");
output.println("/FontInfo 10 dict dup begin");
@@ -112,7 +114,13 @@ public final class Type1FontFormatter {
int max = 0;
StringBuilder sb = new StringBuilder();
for (Map.Entry<Integer, Integer> gid : gids.entrySet()) {
- String name = font.getCharset().getNameForGID(gid.getKey());
+ String name = "gid_" + gid.getKey();
+ if (gid.getKey() == 0) {
+ name = ".notdef";
+ }
+ if (font instanceof CFFType1Font) {
+ name = font.getCharset().getNameForGID(gid.getKey());
+ }
sb.append(String.format("dup %d /%s put", gid.getValue(), name)).append('\n');
max = Math.max(max, gid.getValue());
}
@@ -133,32 +141,48 @@ public final class Type1FontFormatter {
output.write(eexecBytes);
}
- private void printEexecFontDictionary(CFFType1Font font, DataOutput output)
+ private void printEexecFontDictionary(CFFFont font, DataOutput output)
throws IOException {
output.println("dup /Private 15 dict dup begin");
output.println("/RD {string currentfile exch readstring pop} executeonly def");
output.println("/ND {noaccess def} executeonly def");
output.println("/NP {noaccess put} executeonly def");
+ Map<String, Object> privDict;
+ if (font instanceof CFFCIDFont) {
+ privDict = ((CFFCIDFont)font).getPrivDicts().get(0);
+ } else {
+ privDict = ((CFFType1Font)font).getPrivateDict();
+ }
output.println("/BlueValues "
- + formatArray(font.getPrivateDict().get("BlueValues"), true) + " ND");
+ + formatArray(privDict.get("BlueValues"), true) + " ND");
output.println("/OtherBlues "
- + formatArray(font.getPrivateDict().get("OtherBlues"), true) + " ND");
- output.println("/BlueScale " + font.getPrivateDict().get("BlueScale") + " def");
- output.println("/BlueShift " + font.getPrivateDict().get("BlueShift") + " def");
- output.println("/BlueFuzz " + font.getPrivateDict().get("BlueFuzz") + " def");
- output.println("/StdHW " + formatArray(font.getPrivateDict().get("StdHW"), true)
+ + formatArray(privDict.get("OtherBlues"), true) + " ND");
+ output.println("/BlueScale " + privDict.get("BlueScale") + " def");
+ output.println("/BlueShift " + privDict.get("BlueShift") + " def");
+ output.println("/BlueFuzz " + privDict.get("BlueFuzz") + " def");
+ output.println("/StdHW " + formatArray(privDict.get("StdHW"), true)
+ " ND");
- output.println("/StdVW " + formatArray(font.getPrivateDict().get("StdVW"), true)
+ output.println("/StdVW " + formatArray(privDict.get("StdVW"), true)
+ " ND");
- output.println("/ForceBold " + font.getPrivateDict().get("ForceBold") + " def");
+ output.println("/ForceBold " + privDict.get("ForceBold") + " def");
output.println("/MinFeature {16 16} def");
output.println("/password 5839 def");
output.println("2 index /CharStrings " + gids.size() + " dict dup begin");
Type1CharStringFormatter formatter = new Type1CharStringFormatter();
for (int gid : gids.keySet()) {
- String mapping = font.getCharset().getNameForGID(gid);
- byte[] type1Bytes = formatter.format(font.getType1CharString(mapping).getType1Sequence());
+ String mapping = "gid_" + gid;
+ if (gid == 0) {
+ mapping = ".notdef";
+ }
+ byte[] type1Bytes;
+ if (font instanceof CFFCIDFont) {
+ int cid = font.getCharset().getCIDForGID(gid);
+ type1Bytes = formatter.format(((CFFCIDFont)font).getType2CharString(cid).getType1Sequence());
+ } else {
+ mapping = font.getCharset().getNameForGID(gid);
+ type1Bytes = formatter.format(((CFFType1Font)font).getType1CharString(mapping).getType1Sequence());
+ }
byte[] charstringBytes = Type1FontUtil.charstringEncrypt(type1Bytes, 4);
output.print("/" + mapping + " " + charstringBytes.length + " RD ");
output.write(charstringBytes);
diff --git a/fop-core/src/test/java/org/apache/fop/fonts/truetype/OTFToType1TestCase.java b/fop-core/src/test/java/org/apache/fop/fonts/truetype/OTFToType1TestCase.java
index adea1d128..9194d16c7 100644
--- a/fop-core/src/test/java/org/apache/fop/fonts/truetype/OTFToType1TestCase.java
+++ b/fop-core/src/test/java/org/apache/fop/fonts/truetype/OTFToType1TestCase.java
@@ -21,6 +21,7 @@ package org.apache.fop.fonts.truetype;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
+import java.util.List;
import org.junit.Assert;
import org.junit.Test;
@@ -54,6 +55,20 @@ public class OTFToType1TestCase {
Assert.assertEquals(t1.getFontType(), FontType.TYPE1);
}
+ @Test
+ public void testCIDFont() throws IOException {
+ CFFToType1Font realFont = (CFFToType1Font)getRealFont("test/resources/fonts/otf/AlexBrush-Regular-cid.otf");
+ for (int i = 0; i < 10240; i++) {
+ realFont.mapChar((char) i);
+ }
+ List<InputStream> fonts = realFont.getInputStreams();
+ InputStream is = fonts.get(0);
+ Type1Font t1 = Type1Font.createWithPFB(is);
+ Assert.assertEquals(t1.getFontName(), "AlexBrush-Regular.0");
+ Assert.assertTrue(t1.getCharStringsDict().keySet().contains(".notdef"));
+ Assert.assertTrue(t1.getCharStringsDict().keySet().contains("gid_1"));
+ }
+
private Type1Font getFont(String s) throws IOException {
InputStream is = ((CFFToType1Font)getRealFont(s)).getInputStreams().get(0);
return Type1Font.createWithPFB(is);
diff --git a/fop/test/resources/fonts/otf/AlexBrush-Regular-cid.otf b/fop/test/resources/fonts/otf/AlexBrush-Regular-cid.otf
new file mode 100644
index 000000000..4b015be8c
--- /dev/null
+++ b/fop/test/resources/fonts/otf/AlexBrush-Regular-cid.otf
Binary files differ