@Override public int getGlyphId(int characterCode) { int gid = cmap.getGlyphId(characterCode); String[] scriptTags = OpenTypeScript.getScriptTags(characterCode); return gsub.getSubstitution(gid, scriptTags, enabledFeatures); }
@Override public String toString() { return "{" + getPlatformId() + " " + getPlatformEncodingId() + "}"; }
/** * This will read the required data from the stream. * * @param ttf The font that is being read. * @param data The stream to read the data from. * @throws IOException If there is an error reading the data. */ @Override public void read(TrueTypeFont ttf, TTFDataStream data) throws IOException { @SuppressWarnings({"unused", "squid:S1854", "squid:S1481"}) int version = data.readUnsignedShort(); int numberOfTables = data.readUnsignedShort(); cmaps = new CmapSubtable[numberOfTables]; for (int i = 0; i < numberOfTables; i++) { CmapSubtable cmap = new CmapSubtable(); cmap.initData(data); cmaps[i] = cmap; } for (int i = 0; i < numberOfTables; i++) { cmaps[i].initSubtable(this, ttf.getNumberOfGlyphs(), data); } initialized = true; }
/** * Initialize the CMapEntry when it is a subtype 0. * * @param data the data stream of the to be parsed ttf font * @throws IOException If there is an error parsing the true type font. */ protected void processSubtype0(TTFDataStream data) throws IOException { byte[] glyphMapping = data.read(256); glyphIdToCharacterCode = newGlyphIdToCharacterCode(256); characterCodeToGlyphId = new HashMap<>(glyphMapping.length); for (int i = 0; i < glyphMapping.length; i++) { int glyphIndex = glyphMapping[i] & 0xFF; glyphIdToCharacterCode[glyphIndex] = i; characterCodeToGlyphId.put(i, glyphIndex); } }
/** * Reads a format 6 subtable. * * @param data the data stream of the to be parsed ttf font * @param numGlyphs number of glyphs to be read * @throws IOException If there is an error parsing the true type font. */ protected void processSubtype6(TTFDataStream data, int numGlyphs) throws IOException { int firstCode = data.readUnsignedShort(); int entryCount = data.readUnsignedShort(); // skip emtpy tables if (entryCount == 0) { return; } characterCodeToGlyphId = new HashMap<>(numGlyphs); int[] glyphIdArray = data.readUnsignedShortArray(entryCount); int maxGlyphId = 0; for (int i = 0; i < entryCount; i++) { maxGlyphId = Math.max(maxGlyphId, glyphIdArray[i]); characterCodeToGlyphId.put(firstCode + i, glyphIdArray[i]); } buildGlyphIdToCharacterCodeLookup(maxGlyphId); }
/** * Returns the character code for the given GID, or null if there is none. * * @param gid glyph id * @return character code * * @deprecated the mapping may be ambiguous, see {@link #getCharCodes(int)}. The first mapped value is returned by * default. */ public Integer getCharacterCode(int gid) { int code = getCharCode(gid); if (code == -1) { return null; } // ambiguous mapping if (code == Integer.MIN_VALUE) { List<Integer> mappedValues = glyphIdToCharacterCodeMultiple.get(gid); if (mappedValues != null) { // use the first mapping return mappedValues.get(0); } } return code; }
@Override public List<Integer> getCharCodes(int gid) { return cmap.getCharCodes(gsub.getUnsubstitution(gid)); } }
private void buildGlyphIdToCharacterCodeLookup(int maxGlyphId) { glyphIdToCharacterCode = newGlyphIdToCharacterCode(maxGlyphId + 1); for (Entry<Integer, Integer> entry : characterCodeToGlyphId.entrySet()) { if (glyphIdToCharacterCode[entry.getValue()] == -1) { // add new value to the array glyphIdToCharacterCode[entry.getValue()] = entry.getKey(); } else { // there is already a mapping for the given glyphId List<Integer> mappedValues = glyphIdToCharacterCodeMultiple.get(entry.getValue()); if (mappedValues == null) { mappedValues = new ArrayList<>(); glyphIdToCharacterCodeMultiple.put(entry.getValue(), mappedValues); mappedValues.add(glyphIdToCharacterCode[entry.getValue()]); // mark value as multiple mapping glyphIdToCharacterCode[entry.getValue()] = Integer.MIN_VALUE; } mappedValues.add(entry.getKey()); } } }
return; buildGlyphIdToCharacterCodeLookup(maxGlyphId);
public List<Integer> getCharCodes(int gid) int code = getCharCode(gid); if (code == -1)
@Override public List<Integer> getCharCodes(int gid) { return cmap.getCharCodes(gsub.getUnsubstitution(gid)); } }
/** * Returns the subtable, if any, for the given platform and encoding. */ public CmapSubtable getSubtable(int platformId, int platformEncodingId) { for (CmapSubtable cmap : cmaps) { if (cmap.getPlatformId() == platformId && cmap.getPlatformEncodingId() == platformEncodingId) { return cmap; } } return null; } }
gid = cmapWinUnicode.getGlyphId(uni); if (macCode != null) gid = cmapMacRoman.getGlyphId(macCode); gid = cmapWinSymbol.getGlyphId(code); if (code >= 0 && code <= 0xFF) gid = cmapWinSymbol.getGlyphId(code + START_RANGE_F000); gid = cmapWinSymbol.getGlyphId(code + START_RANGE_F100); gid = cmapWinSymbol.getGlyphId(code + START_RANGE_F200); gid = cmapMacRoman.getGlyphId(code); gid = cmapWinUnicode.getGlyphId(uni);
/** * This will read the required data from the stream. * * @param ttf The font that is being read. * @param data The stream to read the data from. * @throws IOException If there is an error reading the data. */ public void read(TrueTypeFont ttf, TTFDataStream data) throws IOException { int version = data.readUnsignedShort(); int numberOfTables = data.readUnsignedShort(); cmaps = new CmapSubtable[numberOfTables]; for (int i = 0; i < numberOfTables; i++) { CmapSubtable cmap = new CmapSubtable(); cmap.initData(data); cmaps[i] = cmap; } for (int i = 0; i < numberOfTables; i++) { cmaps[i].initSubtable(this, ttf.getNumberOfGlyphs(), data); } initialized = true; }
glyphIdToCharacterCode = newGlyphIdToCharacterCode(numGlyphs); characterCodeToGlyphId = new HashMap<>(numGlyphs); for (long i = 0; i < nbGroups; ++i)
/** * Reads a format 6 subtable. * * @param data the data stream of the to be parsed ttf font * @param numGlyphs number of glyphs to be read * @throws IOException If there is an error parsing the true type font. */ protected void processSubtype6(TTFDataStream data, int numGlyphs) throws IOException { int firstCode = data.readUnsignedShort(); int entryCount = data.readUnsignedShort(); // skip emtpy tables if (entryCount == 0) { return; } characterCodeToGlyphId = new HashMap<Integer, Integer>(numGlyphs); int[] glyphIdArray = data.readUnsignedShortArray(entryCount); int maxGlyphId = 0; for (int i = 0; i < entryCount; i++) { maxGlyphId = Math.max(maxGlyphId, glyphIdArray[i]); characterCodeToGlyphId.put(firstCode + i, glyphIdArray[i]); } buildGlyphIdToCharacterCodeLookup(maxGlyphId); }
/** * Returns the character code for the given GID, or null if there is none. * * @param gid glyph id * @return character code * * @deprecated the mapping may be ambiguous, see {@link #getCharCodes(int)}. The first mapped value is returned by * default. */ public Integer getCharacterCode(int gid) { int code = getCharCode(gid); if (code == -1) { return null; } // ambiguous mapping if (code == Integer.MIN_VALUE) { List<Integer> mappedValues = glyphIdToCharacterCodeMultiple.get(gid); if (mappedValues != null) { // use the first mapping return mappedValues.get(0); } } return code; }
List<Integer> codes = cmap.getCharCodes(cid); // old GID -> Unicode if (codes != null)
for (CmapSubtable cmap : cmaps) if (CmapTable.PLATFORM_WINDOWS == cmap.getPlatformId()) if (CmapTable.ENCODING_WIN_UNICODE_BMP == cmap.getPlatformEncodingId()) else if (CmapTable.ENCODING_WIN_SYMBOL == cmap.getPlatformEncodingId()) else if (CmapTable.PLATFORM_MACINTOSH == cmap.getPlatformId() && CmapTable.ENCODING_MAC_ROMAN == cmap.getPlatformEncodingId())
/** * Add the given character code to the subset. * * @param unicode character code */ public void add(int unicode) { int gid = unicodeCmap.getGlyphId(unicode); if (gid != 0) { uniToGID.put(unicode, gid); glyphIds.add(gid); } }