From 9484e8e7285f40129470bf1847aa2b74c559c3e9 Mon Sep 17 00:00:00 2001 From: Patrick Corless Date: Thu, 25 Feb 2021 23:51:04 -0700 Subject: [PATCH] GH-80 some encoding tweaks, still not correct but better. --- .../core/pobjects/fonts/zfont/Encoding.java | 3 +- .../fonts/zfont/TypeCidType2Font.java | 48 +++++++++---------- .../fonts/zfont/fontFiles/ZFontTrueType.java | 17 ++++++- .../fonts/zfont/fontFiles/ZFontType1C.java | 11 +++++ .../fonts/zfont/fontFiles/ZSimpleFont.java | 12 +++-- 5 files changed, 61 insertions(+), 30 deletions(-) diff --git a/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/Encoding.java b/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/Encoding.java index 409d08f13..fb190c826 100644 --- a/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/Encoding.java +++ b/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/Encoding.java @@ -132,7 +132,8 @@ public Character getChar(String name) { name = "Euro"; } // boolean isEuro = name.equalsIgnoreCase("euro"); - for (int i = 0, max = encodingMap.length; i < max; i++) { + for (int i = encodingMap.length - 1; i >= 0; i--) { +// for (int i = 0, max = encodingMap.length; i < max; i++) { if (name.equals(encodingMap[i])) { ch = (char) i; break; diff --git a/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/TypeCidType2Font.java b/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/TypeCidType2Font.java index 6fecf388b..efc2dfc2d 100644 --- a/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/TypeCidType2Font.java +++ b/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/TypeCidType2Font.java @@ -5,6 +5,7 @@ import org.icepdf.core.pobjects.fonts.ofont.CMap; import org.icepdf.core.pobjects.fonts.ofont.CMapIdentityH; import org.icepdf.core.pobjects.fonts.ofont.CMapReverse; +import org.icepdf.core.pobjects.fonts.zfont.fontFiles.ZFontTrueType; import org.icepdf.core.pobjects.fonts.zfont.fontFiles.ZFontType2; import org.icepdf.core.util.Library; @@ -23,6 +24,9 @@ public TypeCidType2Font(Library library, HashMap entries) { @Override public synchronized void init() { super.init(); + if (!(font instanceof ZFontType2)) { + font = new ZFontType2((ZFontTrueType) font); + } parseCidToGidMap(); inited = true; } @@ -44,35 +48,31 @@ protected void parseCidToGidMap() { Object gidMap = library.getObject(entries, CID_TO_GID_MAP_KEY); // ordering != null && ordering.startsWith("Identity")) || ((gidMap != null || !isFontSubstitution) - if (!isFontSubstitution) { +// if (!isFontSubstitution) { // CMap subfontToUnicodeCMap = toUnicodeCMap != null ? toUnicodeCMap : CMap.IDENTITY; - if (gidMap == null) { + if (gidMap == null) { // throw new Exception("null CID_TO_GID_MAP_KEY " + gidMap); // font = ((ZFontTrueType) font).deriveFont(CMap.IDENTITY, null);// subfontToUnicodeCMap); + } + if (gidMap instanceof Name) { + String mappingName = null; + mappingName = gidMap.toString(); + if (toUnicodeCMap instanceof CMapIdentityH) { + mappingName = toUnicodeCMap.toString(); + } + // mapping name will be null only in a few corner cases, but + // identity will be applied otherwise. + if (mappingName == null || mappingName.equals("Identity")) { + // subfontToUnicodeCMap + font = ((ZFontType2) font).deriveFont(CMap.IDENTITY, toUnicodeCMap); } - if (gidMap instanceof Name) { -// throw new Exception("gidMap name " + gidMap); - String mappingName = null; - if (gidMap != null) { - mappingName = gidMap.toString(); - } - if (toUnicodeCMap instanceof CMapIdentityH) { - mappingName = toUnicodeCMap.toString(); - } - // mapping name will be null only in a few corner cases, but - // identity will be applied otherwise. - if (mappingName == null || mappingName.equals("Identity")) { - // subfontToUnicodeCMap - font = ((ZFontType2) font).deriveFont(CMap.IDENTITY, null); - } - } else if (gidMap instanceof Stream) { - int[] cidToGidMap = CMap.parseCidToGidMap((Stream) gidMap); - CMap cidGidMap = new CMapReverse(cidToGidMap); - if (font instanceof ZFontType2) { - // todo unicode should already be setup, need to fix this signature. - font = ((ZFontType2) font).deriveFont(cidGidMap, null); - } + } else if (gidMap instanceof Stream) { + int[] cidToGidMap = CMap.parseCidToGidMap((Stream) gidMap); + CMap cidGidMap = new CMapReverse(cidToGidMap); + if (font instanceof ZFontType2) { + font = ((ZFontType2) font).deriveFont(cidGidMap, toUnicodeCMap); } } +// } } } \ No newline at end of file diff --git a/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/fontFiles/ZFontTrueType.java b/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/fontFiles/ZFontTrueType.java index f067301db..adbecd995 100644 --- a/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/fontFiles/ZFontTrueType.java +++ b/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/fontFiles/ZFontTrueType.java @@ -288,9 +288,22 @@ public int codeToGID(int code) { gid = cmapMacRoman.getGlyphId(macCode); } } - // 'post' table + // 'post' table - comment is incorrect but keeping it for now as the post table is an encoding + // that we can use. With this little hack we still have issue showing some glyphs correctly. + // likely looking at font substitutions corner cases. if (gid == 0) { - gid = code; + // still not happy with this, lots of mystery and deception that needs to be figured out. + if (encoding != null) { + if (encoding.getName().equals(org.icepdf.core.pobjects.fonts.zfont.Encoding.WIN_ANSI_ENCODING_NAME) && cmapWinUnicode != null) { + gid = cmapWinUnicode.getGlyphId(code); + } else if (encoding.getName().startsWith("Mac") && cmapMacRoman != null) { + gid = cmapMacRoman.getGlyphId(code); + } else { + gid = code; + } + } else { + gid = code; + } } } // symbolic diff --git a/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/fontFiles/ZFontType1C.java b/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/fontFiles/ZFontType1C.java index 8ea802268..e90cc1f6e 100644 --- a/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/fontFiles/ZFontType1C.java +++ b/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/fontFiles/ZFontType1C.java @@ -50,6 +50,17 @@ public Point2D echarAdvance(char ech) { return super.echarAdvance(ech); } + @Override + protected String codeToName(String estr) { + // might be able to blow this out out some point, but we're in the weeds at this point, not + // a lot of good examples. + if (org.icepdf.core.pobjects.fonts.zfont.Encoding.STANDARD_ENCODING_NAME.equals(encoding.getName())) { + return cffType1Font.getEncoding().getName(estr.charAt(0)); + } else { + return estr; + } + } + @Override public void drawEstring(Graphics2D g, String estr, float x, float y, long layout, int mode, Color strokeColor) { super.drawEstring(g, estr, x, y, layout, mode, strokeColor); diff --git a/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/fontFiles/ZSimpleFont.java b/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/fontFiles/ZSimpleFont.java index a5e295524..37450c792 100644 --- a/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/fontFiles/ZSimpleFont.java +++ b/core/core-awt/src/main/java/org/icepdf/core/pobjects/fonts/zfont/fontFiles/ZSimpleFont.java @@ -110,13 +110,19 @@ else if (missingWidth > 0) { } } + // allows sub classes to override the codeToName logic. + protected String codeToName(String estr) { + return estr; + } + @Override public void drawEstring(Graphics2D g, String estr, float x, float y, long layout, int mode, Color strokeColor) { try { AffineTransform af = g.getTransform(); - Shape outline = fontBoxFont.getPath(estr); - if (encoding != null && !fontBoxFont.hasGlyph(estr)) { - String name = encoding.getName(estr.charAt(0)); + String name = codeToName(estr); + Shape outline = fontBoxFont.getPath(name); + if (encoding != null && !fontBoxFont.hasGlyph(name)) { + name = encoding.getName(estr.charAt(0)); if (name != null) { outline = fontBoxFont.getPath(name); }