static CMap createCMap(Buffer buffer, int offset) { /* First do a sanity check that this cmap subtable is contained * within the cmap table. */ int subtableFormat = buffer.getChar(offset); switch (subtableFormat) { case 0: return new CMapFormat0(buffer, offset); case 2: return new CMapFormat2(buffer, offset); case 4: return new CMapFormat4(buffer, offset); case 6: return new CMapFormat6(buffer, offset); case 8: return new CMapFormat8(buffer, offset); case 10: return new CMapFormat10(buffer, offset); case 12: return new CMapFormat12(buffer, offset); default: throw new RuntimeException("Cmap format unimplemented: " + (int) buffer.getChar(offset)); } }
CMapFormat6(Buffer buffer, int offset) { buffer.position(offset + 6); firstCode = buffer.getChar(); entryCount = buffer.getChar(); glyphIdArray = new char[entryCount]; for (int i = 0; i < entryCount; i++) { glyphIdArray[i] = buffer.getChar(); } }
CMapFormat0(Buffer buffer, int offset) { /* skip 6 bytes of format, length, and version */ int len = buffer.getChar(offset + 2); cmap = new byte[len - 6]; buffer.get(offset + 6, cmap, 0, len - 6); }
CMapFormat2(Buffer buffer, int offset) { int tableLen = buffer.getChar(offset + 2); buffer.position(offset + 6); char maxSubHeader = 0; for (int i = 0; i < 256; i++) { subHeaderKey[i] = buffer.getChar(); if (subHeaderKey[i] > maxSubHeader) { maxSubHeader = subHeaderKey[i]; } } /* The value of the subHeaderKey is 8 * the subHeader index, * so the number of subHeaders can be obtained by dividing * this value bv 8 and adding 1. */ int numSubHeaders = (maxSubHeader >> 3) + 1; firstCodeArray = new char[numSubHeaders]; entryCountArray = new char[numSubHeaders]; idDeltaArray = new short[numSubHeaders]; idRangeOffSetArray = new char[numSubHeaders]; for (int i = 0; i < numSubHeaders; i++) { firstCodeArray[i] = buffer.getChar(); entryCountArray[i] = buffer.getChar(); idDeltaArray[i] = (short) buffer.getChar(); idRangeOffSetArray[i] = buffer.getChar(); } int glyphIndexArrSize = (tableLen - 518 - numSubHeaders * 8) / 2; glyphIndexArray = new char[glyphIndexArrSize]; for (int i = 0; i < glyphIndexArrSize; i++) { glyphIndexArray[i] = buffer.getChar(); } }
CMapFormat10(Buffer buffer, int offset) { buffer.position(offset + 12); startCharCode = buffer.getInt() & INTMASK; numChars = buffer.getInt() & INTMASK; glyphIdArray = new char[numChars]; for (int i = 0; i < numChars; i++) { glyphIdArray[i] = buffer.getChar(); } }
CMapFormat4(Buffer buffer, int offset) { buffer.position(offset); buffer.getChar(); // skip, we already know format=4 int subtableLength = buffer.getChar(); /* Try to recover from some bad fonts which specify a subtable * length that would overflow the byte buffer holding the whole * cmap table. If this isn't a recoverable situation an exception * may be thrown which is caught higher up the call stack. * Whilst this may seem lenient, in practice, unless the "bad" * subtable we are using is the last one in the cmap table we * would have no way of knowing about this problem anyway. */ if (offset + subtableLength > buffer.capacity()) { subtableLength = buffer.capacity() - offset; } buffer.getChar(); // skip language segCount = buffer.getChar() / 2; buffer.getChar(); // skip searchRange entrySelector = buffer.getChar(); rangeShift = buffer.getChar() / 2; startCount = new char[segCount]; endCount = new char[segCount]; idDelta = new short[segCount]; idRangeOffset = new char[segCount]; for (int i = 0; i < segCount; i++) { endCount[i] = buffer.getChar(); } buffer.getChar(); // 2 bytes for reserved pad for (int i = 0; i < segCount; i++) { startCount[i] = buffer.getChar(); } for (int i = 0; i < segCount; i++) { idDelta[i] = (short) buffer.getChar(); } for (int i = 0; i < segCount; i++) { char ctmp = buffer.getChar(); idRangeOffset[i] = (char) ((ctmp >> 1) & 0xffff); } /* Can calculate the number of glyph IDs by subtracting * "pos" from the length of the cmap */ int pos = (segCount * 8 + 16) / 2; buffer.position(pos * 2 + offset); // * 2 for chars int numGlyphIds = (subtableLength / 2 - pos); glyphIds = new char[numGlyphIds]; for (int i = 0; i < numGlyphIds; i++) { glyphIds[i] = buffer.getChar(); } }