diff --git a/fontbox/src/main/java/org/apache/fontbox/cmap/CMap.java b/fontbox/src/main/java/org/apache/fontbox/cmap/CMap.java index 915256a8567..0ed19ed3758 100644 --- a/fontbox/src/main/java/org/apache/fontbox/cmap/CMap.java +++ b/fontbox/src/main/java/org/apache/fontbox/cmap/CMap.java @@ -332,25 +332,6 @@ private int toCIDFromRanges(byte[] code) return 0; } - /** - * Convert the given part of a byte array to an integer. - * - * @param data the byte array - * @param offset The offset into the byte array. - * @param length The length of the data we are getting. - * @return the resulting integer - */ - private int getCodeFromArray( byte[] data, int offset, int length ) - { - int code = 0; - for( int i=0; i twoByteMappings = new ArrayList<>(256 * 256); private static final List oneByteMappings = new ArrayList<>(256); + private static final List indexValues = new ArrayList<>(256 * 256); + private static final List oneByteValues = new ArrayList<>(256); + private static final List twoByteValues = new ArrayList<>(256 * 256); + static { // create all mappings when loading the class to avoid concurrency issues @@ -48,12 +52,15 @@ private static void fillMappings() { byte[] bytes = { (byte) i, (byte) j }; twoByteMappings.add(new String(bytes, StandardCharsets.UTF_16BE)); + twoByteValues.add(bytes); + indexValues.add((i * 256) + j); } } for (int i = 0; i < 256; i++) { byte[] bytes = { (byte) i }; oneByteMappings.add(new String(bytes, StandardCharsets.ISO_8859_1)); + oneByteValues.add(bytes); } } @@ -73,4 +80,39 @@ public static String getMapping(byte[] bytes) return bytes.length == 1 ? oneByteMappings.get(CMap.toInt(bytes)) : twoByteMappings.get(CMap.toInt(bytes)); } + + /** + * Get an Integer instance of the given combination of bytes. Each value is a singleton to avoid multiple instances + * for same value. The values are limited to one and two-byte sequences. Any longer byte sequence produces null as + * return value. + * + * @param bytes the given combination of bytes + * @return the Integer representation for the given combination of bytes + */ + public static Integer getIndexValue(byte[] bytes) + { + if (bytes.length > 2) + { + return null; + } + return indexValues.get(CMap.toInt(bytes)); + } + + /** + * Get a singleton instance of the given combination of bytes to avoid multiple instances for same value. The values + * are limited to one and two-byte sequences. Any longer byte sequence produces null as return value. + * + * @param bytes the given combination of bytes + * @return a singleton instance for the given combination of bytes + */ + public static byte[] getByteValue(byte[] bytes) + { + if (bytes.length > 2) + { + return null; + } + return bytes.length == 1 ? oneByteValues.get(CMap.toInt(bytes)) + : twoByteValues.get(CMap.toInt(bytes)); + } + }