Author: lehmi Date: Sun Sep 12 16:21:15 2021 New Revision: 1893283 URL: http://svn.apache.org/viewvc?rev=1893283&view=rev Log: PDFBOX-5143: replace class with enum to reduce memory footprint
Modified: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CharStringCommand.java pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type1CharString.java pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type1CharStringParser.java pdfbox/trunk/fontbox/src/test/java/org/apache/fontbox/cff/CharStringCommandTest.java Modified: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CharStringCommand.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CharStringCommand.java?rev=1893283&r1=1893282&r2=1893283&view=diff ============================================================================== --- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CharStringCommand.java (original) +++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/CharStringCommand.java Sun Sep 12 16:21:15 2021 @@ -16,7 +16,6 @@ */ package org.apache.fontbox.cff; -import java.util.Arrays; import java.util.HashMap; import java.util.Map; @@ -27,8 +26,8 @@ import java.util.Map; */ public class CharStringCommand { - - private final Key commandKey; + private final Type1KeyWord type1KeyWord; + private final Type2KeyWord type2KeyWord; /** * Constructor with one value. @@ -37,7 +36,8 @@ public class CharStringCommand */ public CharStringCommand(int b0) { - commandKey = new Key(b0); + type1KeyWord = Type1KeyWord.valueOfKey(b0); + type2KeyWord = Type2KeyWord.valueOfKey(b0); } /** @@ -48,7 +48,8 @@ public class CharStringCommand */ public CharStringCommand(int b0, int b1) { - commandKey = new Key(b0, b1); + type1KeyWord = Type1KeyWord.valueOfKey(b0, b1); + type2KeyWord = Type2KeyWord.valueOfKey(b0, b1); } /** @@ -58,26 +59,31 @@ public class CharStringCommand */ public CharStringCommand(int[] values) { - commandKey = new Key(values); - } - - /** - * The key of the CharStringCommand. - * @return the key - */ - public Key getKey() - { - return commandKey; + if (values.length == 1) + { + type1KeyWord = Type1KeyWord.valueOfKey(values[0]); + type2KeyWord = Type2KeyWord.valueOfKey(values[0]); + } + else if (values.length == 2) + { + type1KeyWord = Type1KeyWord.valueOfKey(values[0], values[1]); + type2KeyWord = Type2KeyWord.valueOfKey(values[0], values[1]); + } + else + { + type1KeyWord = null; + type2KeyWord = null; + } } public Type1KeyWord getType1KeyWord() { - return Type1KeyWord.valueOfKey(commandKey); + return type1KeyWord; } public Type2KeyWord getType2KeyWord() { - return Type2KeyWord.valueOfKey(commandKey); + return type2KeyWord; } /** @@ -87,22 +93,17 @@ public class CharStringCommand public String toString() { String str = null; - Type2KeyWord type2KeyWord = getType2KeyWord(); if (type2KeyWord != null) { str = type2KeyWord.toString(); } - else + else if (type1KeyWord != null) { - Type1KeyWord type1KeyWord = getType1KeyWord(); - if (type1KeyWord != null) - { - str = type1KeyWord.toString(); - } + str = type1KeyWord.toString(); } - if (str == null) + else { - str = getKey().toString(); + str = "unknown command"; } return str + '|'; } @@ -113,7 +114,15 @@ public class CharStringCommand @Override public int hashCode() { - return getKey().hashCode(); + if (type1KeyWord != null) + { + return type1KeyWord.key.hashCode(); + } + if (type2KeyWord != null) + { + return type2KeyWord.key.hashCode(); + } + return 0; } /** @@ -125,182 +134,172 @@ public class CharStringCommand if (object instanceof CharStringCommand) { CharStringCommand that = (CharStringCommand) object; - return getKey().equals(that.getKey()); + if (type1KeyWord != null && type1KeyWord.equals(that.getType1KeyWord())) + { + return true; + } + if (type2KeyWord != null && type2KeyWord.equals(that.getType2KeyWord())) + { + return true; + } + if (type1KeyWord == null && type2KeyWord == null) + { + return true; + } } return false; } /** - * A static class to hold one or more int values as key. + * Enum of all valid type1 key words */ - public static class Key + public static enum Type1KeyWord { + HSTEM(Key.HSTEM), VSTEM(Key.VSTEM), VMOVETO(Key.VMOVETO), RLINETO(Key.RLINETO), // + HLINETO(Key.HLINETO), VLINETO(Key.VLINETO), RRCURVETO(Key.RRCURVETO), // + CLOSEPATH(Key.CLOSEPATH), CALLSUBR(Key.CALLSUBR), RET(Key.RET), // + ESCAPE(Key.ESCAPE), DOTSECTION(Key.DOTSECTION), // + VSTEM3(Key.VSTEM3), HSTEM3(Key.HSTEM3), SEAC(Key.SEAC), SBW(Key.SBW), // + DIV(Key.DIV), CALLOTHERSUBR(Key.CALLOTHERSUBR), POP(Key.POP), // + SETCURRENTPOINT(Key.SETCURRENTPOINT), HSBW(Key.HSBW), ENDCHAR(Key.ENDCHAR), // + RMOVETO(Key.RMOVETO), HMOVETO(Key.HMOVETO), VHCURVETO(Key.VHCURVETO), // + HVCURVETO(Key.HVCURVETO); - private final int[] keyValues; - - /** - * Constructor with one value. - * - * @param b0 value - */ - public Key(int b0) - { - keyValues = new int[] { b0 }; - } + final Key key; - /** - * Constructor with two values. - * - * @param b0 value1 - * @param b1 value2 - */ - public Key(int b0, int b1) + private Type1KeyWord(Key key) { - keyValues = new int[] { b0, b1 }; + this.key = key; } - /** - * Constructor with an array as values. - * - * @param values array of values - */ - public Key(int[] values) + private static final Map<Key, Type1KeyWord> BY_KEY = new HashMap<>(); + + static { - keyValues = values; + for (Type1KeyWord e : values()) + { + BY_KEY.put(e.key, e); + } } - /** - * Array the with the values. - * - * @return array with the values - */ - public int[] getValue() + public static Type1KeyWord valueOfKey(int b0) { - return keyValues; + return BY_KEY.get(Key.valueOfKey(b0)); } - /** - * {@inheritDoc} - */ - @Override - public String toString() + public static Type1KeyWord valueOfKey(int b0, int b1) { - return Arrays.toString(getValue()); + return BY_KEY.get(Key.valueOfKey(b0, b1)); } - /** - * {@inheritDoc} - */ - @Override - public int hashCode() + public static Type1KeyWord valueOfKey(Key key) { - if (keyValues[0] == 12 && keyValues.length > 1) - { - return keyValues[0] ^ keyValues[1]; - } - return keyValues[0]; + return BY_KEY.get(key); } - /** - * {@inheritDoc} - */ - @Override - public boolean equals(Object object) - { - if (object instanceof Key) - { - Key that = (Key) object; - if (keyValues[0] == 12 && that.keyValues[0] == 12) - { - if (keyValues.length > 1 && that.keyValues.length > 1) - { - return keyValues[1] == that.keyValues[1]; - } - return keyValues.length == that.keyValues.length; - } - return keyValues[0] == that.keyValues[0]; - } - return false; - } } /** - * Enum of all valid type1 key words + * Enum of all valid type2 key words */ - public enum Type1KeyWord + public static enum Type2KeyWord { - HSTEM(new Key(1)), VSTEM(new Key(3)), VMOVETO(new Key(4)), RLINETO(new Key(5)), // - HLINETO(new Key(6)), VLINETO(new Key(7)), RRCURVETO(new Key(8)), CLOSEPATH(new Key(9)), // - CALLSUBR(new Key(10)), RET(new Key(11)), ESCAPE(new Key(12)), DOTSECTION(new Key(12, 0)), // - VSTEM3(new Key(12, 1)), HSTEM3(new Key(12, 2)), SEAC(new Key(12, 6)), SBW(new Key(12, 7)), // - DIV(new Key(12, 12)), CALLOTHERSUBR(new Key(12, 16)), POP(new Key(12, 17)), // - SETCURRENTPOINT(new Key(12, 33)), HSBW(new Key(13)), ENDCHAR(new Key(14)), // - RMOVETO(new Key(21)), HMOVETO(new Key(22)), VHCURVETO(new Key(30)), HVCURVETO(new Key(31)); + HSTEM(Key.HSTEM), VSTEM(Key.VSTEM), VMOVETO(Key.VMOVETO), RLINETO(Key.RLINETO), // + HLINETO(Key.HLINETO), VLINETO(Key.VLINETO), RRCURVETO(Key.RRCURVETO), CALLSUBR(Key.CALLSUBR), // + RET(Key.RET), ESCAPE(Key.ESCAPE), AND(Key.AND), OR(Key.OR), // + NOT(Key.NOT), ABS(Key.ABS), ADD(Key.ADD), SUB(Key.SUB), // + DIV(Key.DIV), NEG(Key.NEG), EQ(Key.EQ), DROP(Key.DROP), // + PUT(Key.PUT), GET(Key.GET), IFELSE(Key.IFELSE), // + RANDOM(Key.RANDOM), MUL(Key.MUL), SQRT(Key.SQRT), DUP(Key.DUP), // + EXCH(Key.EXCH), INDEX(Key.INDEX), ROLL(Key.ROLL), // + HFLEX(Key.HFLEX), FLEX(Key.FLEX), HFLEX1(Key.HFLEX1), // + FLEX1(Key.FLEX1), ENDCHAR(Key.ENDCHAR), HSTEMHM(Key.HSTEMHM), HINTMASK(Key.HINTMASK), // + CNTRMASK(Key.CNTRMASK), RMOVETO(Key.RMOVETO), HMOVETO(Key.HMOVETO), VSTEMHM(Key.VSTEMHM), // + RCURVELINE(Key.RCURVELINE), RLINECURVE(Key.RLINECURVE), VVCURVETO(Key.VVCURVETO), // + HHCURVETO(Key.HHCURVETO), SHORTINT(Key.SHORTINT), CALLGSUBR(Key.CALLGSUBR), // + VHCURVETO(Key.VHCURVETO), HVCURVETO(Key.HVCURVETO); final Key key; - private Type1KeyWord(Key key) + private Type2KeyWord(Key key) { this.key = key; } - private static final Map<Key, Type1KeyWord> BY_KEY = new HashMap<>(); + private static final Map<Key, Type2KeyWord> BY_KEY = new HashMap<>(); static { - for (Type1KeyWord e : values()) + for (Type2KeyWord e : values()) { BY_KEY.put(e.key, e); } } - - public static Type1KeyWord valueOfKey(Key key) + + public static Type2KeyWord valueOfKey(int b0) { - return BY_KEY.get(key); + return BY_KEY.get(Key.valueOfKey(b0)); } + public static Type2KeyWord valueOfKey(int b0, int b1) + { + return BY_KEY.get(Key.valueOfKey(b0, b1)); + } + + public static Type2KeyWord valueOfKey(Key key) + { + return BY_KEY.get(key); + } } - /** - * Enum of all valid type2 key words - */ - public enum Type2KeyWord + public static enum Key { - HSTEM(new Key(1)), VSTEM(new Key(3)), VMOVETO(new Key(4)), RLINETO(new Key(5)), // - HLINETO(new Key(6)), VLINETO(new Key(7)), RRCURVETO(new Key(8)), CALLSUBR(new Key(10)), // - RET(new Key(11)), ESCAPE(new Key(12)), AND(new Key(12, 3)), OR(new Key(12, 4)), // - NOT(new Key(12, 5)), ABS(new Key(12, 9)), ADD(new Key(12, 10)), SUB(new Key(12, 11)), // - DIV(new Key(12, 12)), NEG(new Key(12, 14)), EQ(new Key(12, 15)), DROP(new Key(12, 18)), // - PUT(new Key(12, 20)), GET(new Key(12, 21)), IFELSE(new Key(12, 22)), // - RANDOM(new Key(12, 23)), MUL(new Key(12, 24)), SQRT(new Key(12, 26)), DUP(new Key(12, 27)), // - EXCH(new Key(12, 28)), INDEX(new Key(12, 29)), ROLL(new Key(12, 30)), // - HFLEX(new Key(12, 34)), FLEX(new Key(12, 35)), HFLEX1(new Key(12, 36)), // - FLEX1(new Key(12, 37)), ENDCHAR(new Key(14)), HSTEMHM(new Key(18)), HINTMASK(new Key(19)), // - CNTRMASK(new Key(20)), RMOVETO(new Key(21)), HMOVETO(new Key(22)), VSTEMHM(new Key(23)), // - RCURVELINE(new Key(24)), RLINECURVE(new Key(25)), VVCURVETO(new Key(26)), // - HHCURVETO(new Key(27)), SHORTINT(new Key(28)), CALLGSUBR(new Key(29)), // - VHCURVETO(new Key(30)), HVCURVETO(new Key(31)); + HSTEM(1), VSTEM(3), VMOVETO(4), RLINETO(5), // + HLINETO(6), VLINETO(7), RRCURVETO(8), CLOSEPATH(9), CALLSUBR(10), // + RET(11), ESCAPE(12), DOTSECTION(12, 0), VSTEM3(12, 1), HSTEM3(12, 2), // + AND(12, 3), OR(12, 4), NOT(12, 5), SEAC(12, 6), SBW(12, 7), // + ABS(12, 9), ADD(12, 10), SUB(12, 11), DIV(12, 12), NEG(12, 14), EQ(12, 15), // + CALLOTHERSUBR(12, 16), POP(12, 17), DROP(12, 18), // + PUT(12, 20), GET(12, 21), IFELSE(12, 22), // + RANDOM(12, 23), MUL(12, 24), SQRT(12, 26), DUP(12, 27), // + EXCH(12, 28), INDEX(12, 29), ROLL(12, 30), SETCURRENTPOINT(12, 33), // + HFLEX(12, 34), FLEX(12, 35), HFLEX1(12, 36), FLEX1(12, 37), // + HSBW(13), ENDCHAR(14), HSTEMHM(18), HINTMASK(19), // + CNTRMASK(20), RMOVETO(21), HMOVETO(22), VSTEMHM(23), // + RCURVELINE(24), RLINECURVE(25), VVCURVETO(26), // + HHCURVETO(27), SHORTINT(28), CALLGSUBR(29), // + VHCURVETO(30), HVCURVETO(31); - final Key key; + private final int hashValue; - private Type2KeyWord(Key key) + private Key(int b0) { - this.key = key; + hashValue = b0; } - private static final Map<Key, Type2KeyWord> BY_KEY = new HashMap<>(); - + private Key(int b0, int b1) + { + hashValue = (b0 << 4) + b1; + } + + private static final Map<Integer, Key> BY_KEY = new HashMap<>(); + static { - for (Type2KeyWord e : values()) + for (Key e : values()) { - BY_KEY.put(e.key, e); + BY_KEY.put(e.hashValue, e); } } - - public static Type2KeyWord valueOfKey(Key key) + + public static Key valueOfKey(int b0) { - return BY_KEY.get(key); + return BY_KEY.get(b0); + } + + public static Key valueOfKey(int b0, int b1) + { + return BY_KEY.get((b0 << 4) + b1); } } } Modified: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type1CharString.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type1CharString.java?rev=1893283&r1=1893282&r2=1893283&view=diff ============================================================================== --- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type1CharString.java (original) +++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type1CharString.java Sun Sep 12 16:21:15 2021 @@ -165,8 +165,7 @@ public class Type1CharString if (type1KeyWord == null) { // indicates an invalid charstring - LOG.warn("Unknown charstring command: " + command.getKey() + " in glyph " + glyphName - + " of font " + fontName); + LOG.warn("Unknown charstring command in glyph " + glyphName + " of font " + fontName); return Collections.emptyList(); } switch(type1KeyWord) @@ -311,8 +310,8 @@ public class Type1CharString break; case RET: // indicates an invalid charstring - LOG.warn("Unexpected charstring command: " + command.getKey() + " in glyph " + - glyphName + " of font " + fontName); + LOG.warn("Unexpected charstring command: RET in glyph " + glyphName + " of font " + + fontName); break; default: // indicates a PDFBox bug Modified: pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type1CharStringParser.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type1CharStringParser.java?rev=1893283&r1=1893282&r2=1893283&view=diff ============================================================================== --- pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type1CharStringParser.java (original) +++ pdfbox/trunk/fontbox/src/main/java/org/apache/fontbox/cff/Type1CharStringParser.java Sun Sep 12 16:21:15 2021 @@ -210,7 +210,7 @@ public class Type1CharStringParser int b = (Integer) sequence.remove(sequence.size() - 1); return b / a; } - throw new IOException("Unexpected char string command: " + command.getKey()); + throw new IOException("Unexpected char string command: " + command.getType1KeyWord()); } private CharStringCommand readCommand(DataInput input, int b0) throws IOException Modified: pdfbox/trunk/fontbox/src/test/java/org/apache/fontbox/cff/CharStringCommandTest.java URL: http://svn.apache.org/viewvc/pdfbox/trunk/fontbox/src/test/java/org/apache/fontbox/cff/CharStringCommandTest.java?rev=1893283&r1=1893282&r2=1893283&view=diff ============================================================================== --- pdfbox/trunk/fontbox/src/test/java/org/apache/fontbox/cff/CharStringCommandTest.java (original) +++ pdfbox/trunk/fontbox/src/test/java/org/apache/fontbox/cff/CharStringCommandTest.java Sun Sep 12 16:21:15 2021 @@ -34,73 +34,39 @@ class CharStringCommandTest @Test void testKey() { - Key key1 = new Key(1); - int[] value1 = key1.getValue(); - assertEquals(1, value1.length); - assertEquals(1, value1[0]); - assertEquals(1, key1.hashCode()); - assertEquals(Arrays.toString(new int[] { 1 }), key1.toString()); - - Key key12_0 = new Key(12, 0); - int[] value12_0 = key12_0.getValue(); - assertEquals(2, value12_0.length); - assertEquals(12, value12_0[0]); - assertEquals(0, value12_0[1]); - assertEquals(12 ^ 0, key12_0.hashCode()); - assertEquals(Arrays.toString(new int[] { 12, 0 }), key12_0.toString()); - - int[] keyValues12_3 = new int[] { 12, 3 }; - Key key12_3 = new Key(keyValues12_3); - int[] value12_3 = key12_3.getValue(); - assertEquals(2, value12_3.length); - assertEquals(12, value12_3[0]); - assertEquals(3, value12_3[1]); - assertEquals(12 ^ 3, key12_3.hashCode()); - - assertEquals(Type1KeyWord.HSTEM.key, key1); - assertNotEquals(key1, key12_0); - assertNotEquals(key12_0, key1); - assertNotEquals(key12_0, key12_3); - assertNotEquals(key12_0, new Key(new int[] { 12, 3, 0 })); + assertEquals(Key.HSTEM, Key.valueOfKey(1)); + assertEquals(Key.ESCAPE, Key.valueOfKey(12)); + assertEquals(Key.DOTSECTION, Key.valueOfKey(12, 0)); + assertEquals(Key.AND, Key.valueOfKey(12, 3)); + assertEquals(Key.HSBW, Key.valueOfKey(13)); } @Test void testCharStringCommand() { CharStringCommand charStringCommand1 = new CharStringCommand(1); - assertEquals(1, charStringCommand1.getKey().getValue()[0]); assertEquals(Type1KeyWord.HSTEM, charStringCommand1.getType1KeyWord()); assertEquals(Type2KeyWord.HSTEM, charStringCommand1.getType2KeyWord()); - assertEquals(1, charStringCommand1.hashCode()); assertEquals("HSTEM|", charStringCommand1.toString()); CharStringCommand charStringCommand12_0 = new CharStringCommand(12, 0); - assertEquals(12, charStringCommand12_0.getKey().getValue()[0]); - assertEquals(0, charStringCommand12_0.getKey().getValue()[1]); assertEquals(Type1KeyWord.DOTSECTION, charStringCommand12_0.getType1KeyWord()); assertNull(charStringCommand12_0.getType2KeyWord()); - assertEquals(12 ^ 0, charStringCommand12_0.hashCode()); assertEquals("DOTSECTION|", charStringCommand12_0.toString()); int[] values12_3 = new int[] { 12, 3 }; CharStringCommand charStringCommand12_3 = new CharStringCommand(values12_3); - assertEquals(12, charStringCommand12_3.getKey().getValue()[0]); - assertEquals(3, charStringCommand12_3.getKey().getValue()[1]); assertNull(charStringCommand12_3.getType1KeyWord()); assertEquals(Type2KeyWord.AND, charStringCommand12_3.getType2KeyWord()); - assertEquals(12 ^ 3, charStringCommand12_3.hashCode()); assertEquals("AND|", charStringCommand12_3.toString()); - assertNotEquals(charStringCommand1, charStringCommand12_0); - assertNotEquals(charStringCommand12_0, charStringCommand12_3); } @Test void testUnknownCharStringCommand() { CharStringCommand charStringCommandUnknown = new CharStringCommand(99); - assertEquals(99, charStringCommandUnknown.getKey().getValue()[0]); - assertEquals("[99]|", charStringCommandUnknown.toString()); + assertEquals("unknown command|", charStringCommandUnknown.toString()); } }