Skip to content

Commit

Permalink
GH-80 toUnicode work and some cleanup towards disabling ofont.
Browse files Browse the repository at this point in the history
  • Loading branch information
Patrick Corless committed Mar 18, 2021
1 parent 1a45b7d commit 40ad5a2
Show file tree
Hide file tree
Showing 18 changed files with 82 additions and 129 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ public interface CMap {

Name TYPE = new Name("CMap");

void init();

/**
* Maps the character id to an underlying unicode value if available.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
import org.icepdf.core.pobjects.Dictionary;
import org.icepdf.core.pobjects.Name;
import org.icepdf.core.pobjects.Resources;
import org.icepdf.core.pobjects.fonts.ofont.CMap;
import org.icepdf.core.util.Library;

import java.util.HashMap;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,11 @@

import org.icepdf.core.pobjects.Name;
import org.icepdf.core.pobjects.Stream;
import org.icepdf.core.pobjects.fonts.ofont.OFont;
import org.icepdf.core.pobjects.fonts.zfont.*;
import org.icepdf.core.pobjects.fonts.zfont.fontFiles.*;
import org.icepdf.core.util.Defs;
import org.icepdf.core.util.Library;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.logging.Level;
Expand All @@ -41,19 +37,6 @@ public class FontFactory {
private static final Logger logger =
Logger.getLogger(FontFactory.class.toString());

// allow scaling of large images to improve clarity on screen
private static final boolean awtFontLoading;

// dynamic property to switch between font engine and awt font substitution.
private static boolean awtFontSubstitution;

static {
// turn on font file loading using awt, can cause the jvm to crash
// if the font file is corrupt.
awtFontLoading =
Defs.sysPropertyBoolean("org.icepdf.core.awtFontLoading", true);
}

public static final int FONT_OPEN_TYPE = 5;
public static final int FONT_TRUE_TYPE = java.awt.Font.TRUETYPE_FONT;
public static final int FONT_TYPE_0 = 6;
Expand Down Expand Up @@ -128,9 +111,6 @@ else if (FONT_SUBTYPE_CID_FONT_TYPE_0.equals(subtype)) {
return font;
}

// todo the whole font.derive font sort of indicates an element of reuse
// maybe we should have base cash which does all the base parsing and then we'd save some time with the derive.
// as it would onlys setup encoding, widths and sizes as needed. food for thought
public FontFile createFontFile(Stream fontStream, int fontType, Name fontSubType) {
FontFile fontFile = null;
try {
Expand All @@ -152,36 +132,6 @@ public FontFile createFontFile(Stream fontStream, int fontType, Name fontSubType
} catch (Throwable e) {
logger.log(Level.WARNING, "Error reading font file type " + FONT_OPEN_TYPE, e);
}
// todo make a call about using the fontManager to load a substitution.
if (fontFile == null && awtFontLoading) {
// see if the font file can be loaded with Java Fonts
InputStream in = null;
try {
in = fontStream.getDecodedByteArrayInputStream();
// make sure we try to load open type fonts as well, done as true type.
if (fontType == FONT_OPEN_TYPE) fontType = FONT_TRUE_TYPE;
java.awt.Font javaFont = java.awt.Font.createFont(fontType, in);
if (javaFont != null) {
// create instance of OFont.
fontFile = new OFont(javaFont);
if (logger.isLoggable(Level.FINE)) {
logger.fine("Successfully created embedded OFont: " + fontTypeToString(fontType));
}
try {
in.close();
} catch (IOException e) {
logger.log(Level.FINE, "Error closing font stream.", e);
}
}
} catch (Throwable e) {
logger.log(Level.FINE, "Error reading font file with ", e);
try {
if (in != null) in.close();
} catch (Throwable e1) {
logger.log(Level.FINE, "Error closing font stream.", e);
}
}
}
return fontFile;
}

Expand All @@ -206,41 +156,9 @@ public FontFile createFontFile(URL url, int fontType, String fontSubType) {
// logging and error handling needs to be addressed
e.printStackTrace();
}
// todo, we may no longer needs this but no harm having it around for now.
if (fontFile == null) {
// see if the font file can be loaded with Java Fonts
try {
// make sure we try to load open type fonts as well, done as true type.
if (fontType == FONT_OPEN_TYPE) fontType = FONT_TRUE_TYPE;
java.awt.Font javaFont = java.awt.Font.createFont(fontType, url.openStream());
if (javaFont != null) {

// create instance of OFont.
fontFile = new OFont(javaFont);

if (logger.isLoggable(Level.FINE)) {
logger.fine("Successfully loaded OFont: " + url);
}
}
} catch (Throwable e) {
logger.log(Level.FINE, "Error reading font file with ", e);
}
}
return fontFile;
}

public boolean isAwtFontSubstitution() {
return awtFontSubstitution;
}

public void setAwtFontSubstitution(boolean awtFontSubstitution) {
FontFactory.awtFontSubstitution = awtFontSubstitution;
}

public void toggleAwtFontSubstitution() {
FontFactory.awtFontSubstitution = !FontFactory.awtFontSubstitution;
}

private String fontTypeToString(int fontType) {

if (fontType == FONT_OPEN_TYPE) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ FontFile deriveFont(Map<Integer, Float> widths, int firstCh, float missingWidth,

float getSize();

AffineTransform getFontTransform();

/**
* Returns maximum ascent glyphs above baseline.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,9 @@ public String toUnicode(char ch) {
}
}
}
if (codeSpaceRange != null && codeSpaceRange[0] != null && ch < codeSpaceRange[0].length - 1) {
return Character.toString(codeSpaceRange[0][ch]);
}
return String.valueOf(ch);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -428,4 +428,9 @@ public Shape getEstringOutline(String displayText, float x, float y) {
public URL getSource() {
return null;
}

@Override
public AffineTransform getFontTransform() {
return null;
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package org.icepdf.core.pobjects.fonts.zfont;

import org.icepdf.core.pobjects.fonts.Encoding;
import org.icepdf.core.pobjects.fonts.ofont.CMap;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
Expand Down Expand Up @@ -28,8 +31,7 @@ private GlyphList(String fileName, int size) {
}

public String toUnicode(String name) {
String unicode = nameToUnicode.get(name);
return unicode;
return nameToUnicode.get(name);
}

public static GlyphList getAdobeGlyphList() {
Expand All @@ -40,6 +42,29 @@ public static GlyphList getZapfDingBatsGlyphList() {
return zapfDingBatsGlyphList;
}

public static CMap guessToUnicode(Encoding encoding) {
int[] toUnicode = new int[256];
String unicode;
for (int i = 0; i < 256; i++) {
unicode = adobeGlyphList.toUnicode(encoding.getName((char) i));
if (unicode != null) {
toUnicode[i] = unicode.codePointAt(0);
}
}
boolean properMap = true;
int codePoint;
String name;
for (int i = 0; i < 256; i++) {
codePoint = toUnicode[i];
name = encoding.getName(i);
if (codePoint != i && name != null && name.equals(".notdef")) {
properMap = false;
break;
}
}
return properMap ? new CMap(toUnicode) : CMap.IDENTITY;
}

private static void initializeAdobeGlyphList() {
adobeGlyphList = new GlyphList("glyphlist.txt", 4281);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,13 @@ protected void parseEncoding() {
} else if (encodingValue instanceof Name) {
setBaseEncoding((Name) encodingValue);
}
if (toUnicodeCMap == null) {
if (encoding != null) {
toUnicodeCMap = GlyphList.guessToUnicode(encoding);
} else {
toUnicodeCMap = CMap.IDENTITY;
}
}
font = font.deriveFont(encoding, toUnicodeCMap);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package org.icepdf.core.pobjects.fonts.zfont;

import org.icepdf.core.pobjects.fonts.AFM;
import org.icepdf.core.pobjects.fonts.ofont.CMap;
import org.icepdf.core.util.Library;

import java.util.HashMap;
Expand Down Expand Up @@ -35,6 +36,13 @@ public synchronized void init() {
if (encoding == null) {
encoding = Encoding.standardEncoding;
font = font.deriveFont(encoding, toUnicodeCMap);
if (toUnicodeCMap == null) {
if (encoding != null) {
toUnicodeCMap = GlyphList.guessToUnicode(encoding);
} else {
toUnicodeCMap = CMap.IDENTITY;
}
}
}

inited = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import org.icepdf.core.pobjects.Name;
import org.icepdf.core.pobjects.Stream;
import org.icepdf.core.pobjects.fonts.ofont.CMap;
import org.icepdf.core.pobjects.fonts.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;
Expand Down Expand Up @@ -49,8 +49,8 @@ protected void parseCidToGidMap() {

// ordering != null && ordering.startsWith("Identity")) || ((gidMap != null || !isFontSubstitution)
if (gidMap == null && !isFontSubstitution) {
CMap subfontToUnicodeCMap = toUnicodeCMap != null ? toUnicodeCMap : CMap.IDENTITY;
font = ((ZFontType2) font).deriveFont(CMap.IDENTITY, subfontToUnicodeCMap);
CMap subfontToUnicodeCMap = toUnicodeCMap != null ? toUnicodeCMap : org.icepdf.core.pobjects.fonts.ofont.CMap.IDENTITY;
font = ((ZFontType2) font).deriveFont(org.icepdf.core.pobjects.fonts.ofont.CMap.IDENTITY, subfontToUnicodeCMap);
}
if (gidMap instanceof Name) {
String mappingName = null;
Expand All @@ -62,10 +62,10 @@ protected void parseCidToGidMap() {
// identity will be applied otherwise.
if (mappingName == null || mappingName.equals("Identity")) {
// subfontToUnicodeCMap
font = ((ZFontType2) font).deriveFont(CMap.IDENTITY, toUnicodeCMap);
font = ((ZFontType2) font).deriveFont(org.icepdf.core.pobjects.fonts.ofont.CMap.IDENTITY, toUnicodeCMap);
}
} else if (gidMap instanceof Stream) {
int[] cidToGidMap = CMap.parseCidToGidMap((Stream) gidMap);
int[] cidToGidMap = org.icepdf.core.pobjects.fonts.ofont.CMap.parseCidToGidMap((Stream) gidMap);
CMap cidGidMap = new CMapReverse(cidToGidMap);
if (font instanceof ZFontType2) {
font = ((ZFontType2) font).deriveFont(cidGidMap, toUnicodeCMap);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,13 +185,7 @@ public FontFile deriveFont(Encoding encoding, CMap toUnicode) {
if (encoding != null) {
font.encoding = encoding;
}
if (toUnicode != null) {
font.toUnicode = toUnicode;
}
if (font.toUnicode == null) {
font.toUnicode = org.icepdf.core.pobjects.fonts.ofont.CMap.IDENTITY;
}

font.toUnicode = deriveToUnicode(encoding, toUnicode);
return font;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,7 @@ public FontFile deriveFont(float pointSize) {
public FontFile deriveFont(Encoding encoding, CMap toUnicode) {
ZFontType0 font = new ZFontType0(this);
font.encoding = encoding;
font.toUnicode = toUnicode;
font.toUnicode = deriveToUnicode(encoding, toUnicode);
return font;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ public FontFile deriveFont(float pointSize) {
public FontFile deriveFont(Encoding encoding, CMap toUnicode) {
ZFontType1 font = new ZFontType1(this);
font.encoding = encoding;
font.toUnicode = toUnicode;
font.toUnicode = deriveToUnicode(encoding, toUnicode);
return font;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ public FontFile deriveFont(float pointSize) {
public FontFile deriveFont(Encoding encoding, CMap toUnicode) {
ZFontType1C font = new ZFontType1C(this);
font.encoding = encoding;
font.toUnicode = toUnicode;
font.toUnicode = deriveToUnicode(encoding, toUnicode);
return font;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ public FontFile deriveFont(float pointSize) {
public FontFile deriveFont(Encoding encoding, CMap toUnicode) {
ZFontType2 font = new ZFontType2(this);
font.encoding = encoding;
font.toUnicode = toUnicode;
font.toUnicode = deriveToUnicode(encoding, toUnicode);
return font;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ public ZFontType3(Library library, HashMap properties) {
public FontFile deriveFont(Encoding encoding, CMap toUnicode) {
ZFontType3 font = (ZFontType3) deriveFont(this.size);
font.encoding = encoding;
font.toUnicode = deriveToUnicode(encoding, toUnicode);
return font;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import org.icepdf.core.pobjects.fonts.CMap;
import org.icepdf.core.pobjects.fonts.Encoding;
import org.icepdf.core.pobjects.fonts.FontFile;
import org.icepdf.core.pobjects.fonts.zfont.GlyphList;
import org.icepdf.core.pobjects.graphics.TextState;

import java.awt.*;
Expand Down Expand Up @@ -117,6 +118,17 @@ protected String codeToName(String estr) {
return estr;
}

protected CMap deriveToUnicode(org.icepdf.core.pobjects.fonts.Encoding encoding, CMap toUnicode) {
if (toUnicode != null) {
return toUnicode;
}
// try and guess the encoding
if (encoding != null) {
return GlyphList.guessToUnicode(encoding);
}
return org.icepdf.core.pobjects.fonts.ofont.CMap.IDENTITY;
}

@Override
public void drawEstring(Graphics2D g, String estr, float x, float y, long layout, int mode, Color strokeColor) {
try {
Expand Down Expand Up @@ -276,6 +288,11 @@ public void setIsCid() {

}

@Override
public AffineTransform getFontTransform() {
return fontTransform;
}

public boolean isDamaged() {
return isDamaged;
}
Expand Down
Loading

0 comments on commit 40ad5a2

Please sign in to comment.