diff --git a/fontbox/src/main/java/org/apache/fontbox/cff/CFFCharset.java b/fontbox/src/main/java/org/apache/fontbox/cff/CFFCharset.java index 2768dde7e45..70b54959135 100644 --- a/fontbox/src/main/java/org/apache/fontbox/cff/CFFCharset.java +++ b/fontbox/src/main/java/org/apache/fontbox/cff/CFFCharset.java @@ -16,46 +16,19 @@ */ package org.apache.fontbox.cff; -import java.util.HashMap; -import java.util.Map; - /** * A CFF charset. A charset is an array of SIDs/CIDs for all glyphs in the font. * - * todo: split this into two? CFFCharsetType1 and CFFCharsetCID ? - * * @author John Hewson */ public abstract class CFFCharset { - private final boolean isCIDFont; - private final Map sidOrCidToGid = new HashMap<>(250); - private final Map gidToSid = new HashMap<>(250); - private final Map nameToSid = new HashMap<>(250); - - // inverse - private final Map gidToCid = new HashMap<>(); - private final Map gidToName = new HashMap<>(250); - - /** - * Package-private constructor for use by subclasses. - * - * @param isCIDFont true if the parent font is a CIDFont - */ - CFFCharset(boolean isCIDFont) - { - this.isCIDFont = isCIDFont; - } - /** * Indicates if the charset belongs to a CID font. * * @return true for CID fonts */ - public boolean isCIDFont() - { - return isCIDFont; - } + public abstract boolean isCIDFont(); /** * Adds a new GID/SID/name combination to the charset. @@ -63,17 +36,7 @@ public boolean isCIDFont() * @param gid GID * @param sid SID */ - public void addSID(int gid, int sid, String name) - { - if (isCIDFont) - { - throw new IllegalStateException("Not a Type 1-equivalent font"); - } - sidOrCidToGid.put(sid, gid); - gidToSid.put(gid, sid); - nameToSid.put(name, sid); - gidToName.put(gid, name); - } + public abstract void addSID(int gid, int sid, String name); /** * Adds a new GID/CID combination to the charset. @@ -81,15 +44,7 @@ public void addSID(int gid, int sid, String name) * @param gid GID * @param cid CID */ - public void addCID(int gid, int cid) - { - if (!isCIDFont) - { - throw new IllegalStateException("Not a CIDFont"); - } - sidOrCidToGid.put(cid, gid); - gidToCid.put(gid, cid); - } + public abstract void addCID(int gid, int cid); /** * Returns the SID for a given GID. SIDs are internal to the font and are not public. @@ -97,19 +52,7 @@ public void addCID(int gid, int cid) * @param sid SID * @return GID */ - int getSIDForGID(int sid) - { - if (isCIDFont) - { - throw new IllegalStateException("Not a Type 1-equivalent font"); - } - Integer gid = gidToSid.get(sid); - if (gid == null) - { - return 0; - } - return gid; - } + abstract int getSIDForGID(int sid); /** * Returns the GID for the given SID. SIDs are internal to the font and are not public. @@ -117,19 +60,7 @@ int getSIDForGID(int sid) * @param sid SID * @return GID */ - int getGIDForSID(int sid) - { - if (isCIDFont) - { - throw new IllegalStateException("Not a Type 1-equivalent font"); - } - Integer gid = sidOrCidToGid.get(sid); - if (gid == null) - { - return 0; - } - return gid; - } + abstract int getGIDForSID(int sid); /** * Returns the GID for a given CID. Returns 0 if the CID is missing. @@ -137,19 +68,7 @@ int getGIDForSID(int sid) * @param cid CID * @return GID */ - public int getGIDForCID(int cid) - { - if (!isCIDFont) - { - throw new IllegalStateException("Not a CIDFont"); - } - Integer gid = sidOrCidToGid.get(cid); - if (gid == null) - { - return 0; - } - return gid; - } + public abstract int getGIDForCID(int cid); /** * Returns the SID for a given PostScript name, you would think this is not needed, @@ -158,19 +77,7 @@ public int getGIDForCID(int cid) * @param name PostScript glyph name * @return SID */ - int getSID(String name) - { - if (isCIDFont) - { - throw new IllegalStateException("Not a Type 1-equivalent font"); - } - Integer sid = nameToSid.get(name); - if (sid == null) - { - return 0; - } - return sid; - } + abstract int getSID(String name); /** * Returns the PostScript glyph name for the given GID. @@ -178,14 +85,7 @@ int getSID(String name) * @param gid GID * @return PostScript glyph name */ - public String getNameForGID(int gid) - { - if (isCIDFont) - { - throw new IllegalStateException("Not a Type 1-equivalent font"); - } - return gidToName.get(gid); - } + public abstract String getNameForGID(int gid); /** * Returns the CID for the given GID. @@ -193,18 +93,5 @@ public String getNameForGID(int gid) * @param gid GID * @return CID */ - public int getCIDForGID(int gid) - { - if (!isCIDFont) - { - throw new IllegalStateException("Not a CIDFont"); - } - - Integer cid = gidToCid.get(gid); - if (cid != null) - { - return cid; - } - return 0; - } + public abstract int getCIDForGID(int gid); } diff --git a/fontbox/src/main/java/org/apache/fontbox/cff/CFFCharsetCID.java b/fontbox/src/main/java/org/apache/fontbox/cff/CFFCharsetCID.java new file mode 100644 index 00000000000..a7f10cffded --- /dev/null +++ b/fontbox/src/main/java/org/apache/fontbox/cff/CFFCharsetCID.java @@ -0,0 +1,136 @@ +package org.apache.fontbox.cff; + +import java.util.HashMap; +import java.util.Map; + +/** + * A CFF charset. A charset is an array of CIDs for all glyphs in the font. + * + * @author Valery Bokov + */ +class CFFCharsetCID extends CFFCharset +{ + private final Map sidOrCidToGid = new HashMap<>(250); + + // inverse + private final Map gidToCid = new HashMap<>(); + + /** + * Indicates if the charset belongs to a CID font. + * + * @return true for CID fonts + */ + @Override + public boolean isCIDFont() + { + return true; + } + + /** + * Adds a new GID/SID/name combination to the charset. + * + * @param gid GID + * @param sid SID + */ + @Override + public void addSID(int gid, int sid, String name) + { + throw new IllegalStateException("Not a Type 1-equivalent font"); + } + + /** + * Adds a new GID/CID combination to the charset. + * + * @param gid GID + * @param cid CID + */ + @Override + public void addCID(int gid, int cid) + { + sidOrCidToGid.put(cid, gid); + gidToCid.put(gid, cid); + } + + /** + * Returns the SID for a given GID. SIDs are internal to the font and are not public. + * + * @param sid SID + * @return GID + */ + @Override + int getSIDForGID(int sid) + { + throw new IllegalStateException("Not a Type 1-equivalent font"); + } + + /** + * Returns the GID for the given SID. SIDs are internal to the font and are not public. + * + * @param sid SID + * @return GID + */ + @Override + int getGIDForSID(int sid) + { + throw new IllegalStateException("Not a Type 1-equivalent font"); + } + + /** + * Returns the GID for a given CID. Returns 0 if the CID is missing. + * + * @param cid CID + * @return GID + */ + @Override + public int getGIDForCID(int cid) + { + Integer gid = sidOrCidToGid.get(cid); + if (gid == null) + { + return 0; + } + return gid; + } + + /** + * Returns the SID for a given PostScript name, you would think this is not needed, + * but some fonts have glyphs beyond their encoding with charset SID names. + * + * @param name PostScript glyph name + * @return SID + */ + @Override + int getSID(String name) + { + throw new IllegalStateException("Not a Type 1-equivalent font"); + } + + /** + * Returns the PostScript glyph name for the given GID. + * + * @param gid GID + * @return PostScript glyph name + */ + @Override + public String getNameForGID(int gid) + { + throw new IllegalStateException("Not a Type 1-equivalent font"); + } + + /** + * Returns the CID for the given GID. + * + * @param gid GID + * @return CID + */ + @Override + public int getCIDForGID(int gid) + { + Integer cid = gidToCid.get(gid); + if (cid != null) + { + return cid; + } + return 0; + } +} diff --git a/fontbox/src/main/java/org/apache/fontbox/cff/CFFCharsetType1.java b/fontbox/src/main/java/org/apache/fontbox/cff/CFFCharsetType1.java new file mode 100644 index 00000000000..85c0bf81be1 --- /dev/null +++ b/fontbox/src/main/java/org/apache/fontbox/cff/CFFCharsetType1.java @@ -0,0 +1,143 @@ +package org.apache.fontbox.cff; + +import java.util.HashMap; +import java.util.Map; +/** + * A CFF charset. A charset is an array of CIDs for all glyphs in the font. + * + * @author Valery Bokov + */ +class CFFCharsetType1 extends CFFCharset +{ + private final Map sidOrCidToGid = new HashMap<>(250); + private final Map gidToSid = new HashMap<>(250); + private final Map nameToSid = new HashMap<>(250); + // inverse + private final Map gidToName = new HashMap<>(250); + + /** + * Indicates if the charset belongs to a CID font. + * + * @return true for CID fonts + */ + @Override + public boolean isCIDFont() + { + return false; + } + + /** + * Adds a new GID/SID/name combination to the charset. + * + * @param gid GID + * @param sid SID + */ + @Override + public void addSID(int gid, int sid, String name) + { + sidOrCidToGid.put(sid, gid); + gidToSid.put(gid, sid); + nameToSid.put(name, sid); + gidToName.put(gid, name); + } + + /** + * Adds a new GID/CID combination to the charset. + * + * @param gid GID + * @param cid CID + */ + @Override + public void addCID(int gid, int cid) + { + throw new IllegalStateException("Not a CIDFont"); + } + + /** + * Returns the SID for a given GID. SIDs are internal to the font and are not public. + * + * @param sid SID + * @return GID + */ + @Override + int getSIDForGID(int sid) + { + Integer gid = gidToSid.get(sid); + if (gid == null) + { + return 0; + } + return gid; + } + + /** + * Returns the GID for the given SID. SIDs are internal to the font and are not public. + * + * @param sid SID + * @return GID + */ + @Override + int getGIDForSID(int sid) + { + Integer gid = sidOrCidToGid.get(sid); + if (gid == null) + { + return 0; + } + return gid; + } + + /** + * Returns the GID for a given CID. Returns 0 if the CID is missing. + * + * @param cid CID + * @return GID + */ + @Override + public int getGIDForCID(int cid) + { + throw new IllegalStateException("Not a CIDFont"); + } + + /** + * Returns the SID for a given PostScript name, you would think this is not needed, + * but some fonts have glyphs beyond their encoding with charset SID names. + * + * @param name PostScript glyph name + * @return SID + */ + @Override + int getSID(String name) + { + Integer sid = nameToSid.get(name); + if (sid == null) + { + return 0; + } + return sid; + } + + /** + * Returns the PostScript glyph name for the given GID. + * + * @param gid GID + * @return PostScript glyph name + */ + @Override + public String getNameForGID(int gid) + { + return gidToName.get(gid); + } + + /** + * Returns the CID for the given GID. + * + * @param gid GID + * @return CID + */ + @Override + public int getCIDForGID(int gid) + { + throw new IllegalStateException("Not a CIDFont"); + } +} \ No newline at end of file diff --git a/fontbox/src/main/java/org/apache/fontbox/cff/CFFExpertCharset.java b/fontbox/src/main/java/org/apache/fontbox/cff/CFFExpertCharset.java index 2d9af866203..e825b019960 100644 --- a/fontbox/src/main/java/org/apache/fontbox/cff/CFFExpertCharset.java +++ b/fontbox/src/main/java/org/apache/fontbox/cff/CFFExpertCharset.java @@ -21,7 +21,7 @@ * * @author Villu Ruusmann */ -public final class CFFExpertCharset extends CFFCharset +public final class CFFExpertCharset extends CFFCharsetType1 { private static final int CHAR_CODE = 0; private static final int CHAR_NAME = 1; @@ -200,7 +200,7 @@ public final class CFFExpertCharset extends CFFCharset private CFFExpertCharset() { - super(false); + //empty } /** diff --git a/fontbox/src/main/java/org/apache/fontbox/cff/CFFExpertSubsetCharset.java b/fontbox/src/main/java/org/apache/fontbox/cff/CFFExpertSubsetCharset.java index 63c4638a789..e385a88ca01 100644 --- a/fontbox/src/main/java/org/apache/fontbox/cff/CFFExpertSubsetCharset.java +++ b/fontbox/src/main/java/org/apache/fontbox/cff/CFFExpertSubsetCharset.java @@ -22,9 +22,8 @@ * * @author Villu Ruusmann */ -public final class CFFExpertSubsetCharset extends CFFCharset +public final class CFFExpertSubsetCharset extends CFFCharsetType1 { - private static final int CHAR_CODE = 0; private static final int CHAR_NAME = 1; @@ -123,7 +122,7 @@ public final class CFFExpertSubsetCharset extends CFFCharset private CFFExpertSubsetCharset() { - super(false); + //empty } /** diff --git a/fontbox/src/main/java/org/apache/fontbox/cff/CFFISOAdobeCharset.java b/fontbox/src/main/java/org/apache/fontbox/cff/CFFISOAdobeCharset.java index 1a810e3f748..8d44600df3a 100644 --- a/fontbox/src/main/java/org/apache/fontbox/cff/CFFISOAdobeCharset.java +++ b/fontbox/src/main/java/org/apache/fontbox/cff/CFFISOAdobeCharset.java @@ -22,7 +22,7 @@ * * @author Villu Ruusmann */ -public final class CFFISOAdobeCharset extends CFFCharset +public final class CFFISOAdobeCharset extends CFFCharsetType1 { private static final int CHAR_CODE = 0; private static final int CHAR_NAME = 1; @@ -264,7 +264,7 @@ public final class CFFISOAdobeCharset extends CFFCharset private CFFISOAdobeCharset() { - super(false); + //empty } /** diff --git a/fontbox/src/main/java/org/apache/fontbox/cff/CFFParser.java b/fontbox/src/main/java/org/apache/fontbox/cff/CFFParser.java index 90b8ab29260..a2699f35339 100644 --- a/fontbox/src/main/java/org/apache/fontbox/cff/CFFParser.java +++ b/fontbox/src/main/java/org/apache/fontbox/cff/CFFParser.java @@ -1358,17 +1358,6 @@ public String toString() } } - /** - * Inner class representing an embedded CFF charset. - */ - abstract static class EmbeddedCharset extends CFFCharset - { - protected EmbeddedCharset(boolean isCIDFont) - { - super(isCIDFont); - } - } - /** * An empty charset in a malformed CID font. */ @@ -1394,7 +1383,7 @@ public String toString() } /** - * Inner class representing a Format0 charset. + * Inner class representing a Format0 charset. */ private static class Format0Charset extends EmbeddedCharset { @@ -1461,21 +1450,20 @@ public int getGIDForCID(int cid) } /** - * Inner class representing a Format2 charset. + * Inner class representing a Format2 charset for CID. */ private static class Format2Charset extends EmbeddedCharset { - private final List rangesCID2GID; - + private final List rangesCID2GID = new ArrayList<>(); + private Format2Charset(boolean isCIDFont) { super(isCIDFont); - rangesCID2GID = new ArrayList<>(); } /** * Add the given range mapping. - * + * * @param rangeMapping the range mapping to be added. */ public void addRangeMapping(RangeMapping rangeMapping) @@ -1495,7 +1483,7 @@ public int getCIDForGID(int gid) } return super.getCIDForGID(gid); } - + @Override public int getGIDForCID(int cid) { @@ -1511,7 +1499,7 @@ public int getGIDForCID(int cid) } /** - * Inner class representing a rang mapping for a CID charset. + * Inner class representing a rang mapping for a CID charset. */ private static final class RangeMapping { @@ -1527,12 +1515,12 @@ private RangeMapping(int startGID, int first, int nLeft) this.startMappedValue = first; endMappedValue = startMappedValue + nLeft; } - + boolean isInRange(int value) { return value >= startValue && value <= endValue; } - + boolean isInReverseRange(int value) { return value >= startMappedValue && value <= endMappedValue; diff --git a/fontbox/src/main/java/org/apache/fontbox/cff/EmbeddedCharset.java b/fontbox/src/main/java/org/apache/fontbox/cff/EmbeddedCharset.java new file mode 100644 index 00000000000..123f2e91a58 --- /dev/null +++ b/fontbox/src/main/java/org/apache/fontbox/cff/EmbeddedCharset.java @@ -0,0 +1,65 @@ +package org.apache.fontbox.cff; + +class EmbeddedCharset extends CFFCharset +{ + private final CFFCharset font; + + EmbeddedCharset(boolean isCIDFont) + { + font = isCIDFont ? new CFFCharsetCID() : new CFFCharsetType1(); + } + + @Override + public int getCIDForGID(int gid) + { + return font.getCIDForGID(gid); + } + + @Override + public boolean isCIDFont() + { + return font.isCIDFont(); + } + + @Override + public void addSID(int gid, int sid, String name) + { + font.addSID(gid, sid, name); + } + + @Override + public void addCID(int gid, int cid) + { + font.addCID(gid, cid); + } + + @Override + int getSIDForGID(int sid) + { + return font.getSIDForGID(sid); + } + + @Override + int getGIDForSID(int sid) + { + return font.getGIDForSID(sid); + } + + @Override + public int getGIDForCID(int cid) + { + return font.getGIDForCID(cid); + } + + @Override + int getSID(String name) + { + return font.getSID(name); + } + + @Override + public String getNameForGID(int gid) + { + return font.getNameForGID(gid); + } +}