input.setPosition(fontDictOffset); byte[][] fdIndex = readIndexData(input); CFFDataInput fontDictInput = new CFFDataInput(bytes); DictData fontDict = readDictData(fontDictInput); input.setPosition(privateOffset); int privateSize = privateEntry.getNumber(0).intValue(); DictData privateDict = readDictData(input, privateSize); if (localSubrOffset > 0) input.setPosition(privateOffset + localSubrOffset); privDict.put("Subrs", readIndexData(input)); input.setPosition(fdSelectPos); FDSelect fdSelect = readFDSelect(input, nrOfcharStrings, font);
private static DictData readDictData(CFFDataInput input, int dictSize) throws IOException { DictData dict = new DictData(); int endPosition = input.getPosition() + dictSize; while (input.getPosition() < endPosition) { dict.add(readEntry(input)); } return dict; }
private static String readTagName(CFFDataInput input) throws IOException { byte[] b = input.readBytes(4); return new String(b, Charsets.ISO_8859_1); }
private static Header readHeader(CFFDataInput input) throws IOException { Header cffHeader = new Header(); cffHeader.major = input.readCard8(); cffHeader.minor = input.readCard8(); cffHeader.hdrSize = input.readCard8(); cffHeader.offSize = input.readOffSize(); return cffHeader; }
private static int[] readIndexDataOffsets(CFFDataInput input) throws IOException { int count = input.readCard16(); if (count == 0) { return null; } int offSize = input.readOffSize(); int[] offsets = new int[count+1]; for (int i = 0; i <= count; i++) { int offset = input.readOffset(offSize); if (offset > input.length()) { throw new IOException("illegal offset value " + offset + " in CFF font"); } offsets[i] = offset; } return offsets; }
private static Integer readIntegerNumber(CFFDataInput input, int b0) throws IOException { if (b0 == 28) { return (int) input.readShort(); } else if (b0 == 29) { return input.readInt(); } else if (b0 >= 32 && b0 <= 246) { return b0 - 139; } else if (b0 >= 247 && b0 <= 250) { int b1 = input.readUnsignedByte(); return (b0 - 247) * 256 + b1 + 108; } else if (b0 >= 251 && b0 <= 254) { int b1 = input.readUnsignedByte(); return -(b0 - 251) * 256 - b1 - 108; } else { throw new IllegalArgumentException(); } }
setNumObjects(cffData.readCard16()); setOffSize(cffData.readOffSize()); int[] offsets = new int[getNumObjects() + 1]; byte[] bytes; switch (getOffSize()) { case 1: offsets[i] = cffData.readCard8(); break; case 2: offsets[i] = cffData.readCard16(); break; case 3: bytes = cffData.readBytes(3); offsets[i] = ((bytes[0] & 0xFF) << 16) + ((bytes[1] & 0xFF) << 8) + (bytes[2] & 0xFF); break; case 4: bytes = cffData.readBytes(4); offsets[i] = ((bytes[0] & 0xFF) << 24) + ((bytes[1] & 0xFF) << 16) + ((bytes[2] & 0xFF) << 8) + (bytes[3] & 0xFF); int position = cffData.getPosition(); int dataSize = offsets[offsets.length - 1] - offsets[0]; cffData.setPosition(cffData.getPosition() + dataSize); setData(position, dataSize);
/** * Retrieves data from the index data * @param index The index position of the data to retrieve * @return Returns the byte data for the given index * @throws IOException Throws an IO Exception if an error occurs */ public byte[] getValue(int index) throws IOException { int oldPos = cffData.getPosition(); try { cffData.setPosition(dataLocation.getDataPosition() + (offsets[index] - 1)); return cffData.readBytes(offsets[index + 1] - offsets[index]); } finally { cffData.setPosition(oldPos); } }
/** * Retrieves the SID for the given GID object * @param charsetOffset The offset of the charset data * @param gid The GID for which to retrieve the SID * @return Returns the SID as an integer */ public int getSIDFromGID(int charsetOffset, int gid) throws IOException { if (gid == 0) { return 0; } cffData.setPosition(charsetOffset); int charsetFormat = cffData.readCard8(); switch (charsetFormat) { case 0: //Adjust for .notdef character cffData.setPosition(cffData.getPosition() + (--gid * 2)); return cffData.readSID(); case 1: return getSIDFromGIDFormat(gid, 1); case 2: return getSIDFromGIDFormat(gid, 2); default: return 0; } }
private void readSupplement(CFFDataInput dataInput, CFFBuiltInEncoding encoding) throws IOException { encoding.nSups = dataInput.readCard8(); encoding.supplement = new CFFBuiltInEncoding.Supplement[encoding.nSups]; for (int i = 0; i < encoding.supplement.length; i++) { CFFBuiltInEncoding.Supplement supplement = new CFFBuiltInEncoding.Supplement(); supplement.code = dataInput.readCard8(); supplement.sid = dataInput.readSID(); supplement.name = readString(supplement.sid); encoding.supplement[i] = supplement; encoding.add(supplement.code, supplement.sid, readString(supplement.sid)); } }
/** * Read the Format 0 of the FDSelect data structure. * @param dataInput * @param format * @param nGlyphs * @param ros * @return the Format 0 of the FDSelect data * @throws IOException */ private static Format0FDSelect readFormat0FDSelect(CFFDataInput dataInput, int format, int nGlyphs, CFFCIDFont ros) throws IOException { Format0FDSelect fdselect = new Format0FDSelect(ros); fdselect.format = format; fdselect.fds = new int[nGlyphs]; for (int i = 0; i < fdselect.fds.length; i++) { fdselect.fds[i] = dataInput.readCard8(); } return fdselect; }
private int getSIDFromGIDFormat(int gid, int format) throws IOException { int glyphCount = 0; while (true) { int oldGlyphCount = glyphCount; int start = cffData.readSID(); glyphCount += ((format == 1) ? cffData.readCard8() : cffData.readCard16()) + 1; if (gid <= glyphCount) { return start + (gid - oldGlyphCount) - 1; } } }
/** * Read the Format 3 of the FDSelect data structure. * * @param dataInput * @param format * @param nGlyphs * @param ros * @return the Format 3 of the FDSelect data * @throws IOException */ private static Format3FDSelect readFormat3FDSelect(CFFDataInput dataInput, int format, int nGlyphs, CFFCIDFont ros) throws IOException { Format3FDSelect fdselect = new Format3FDSelect(ros); fdselect.format = format; fdselect.nbRanges = dataInput.readCard16(); fdselect.range3 = new Range3[fdselect.nbRanges]; for (int i = 0; i < fdselect.nbRanges; i++) { Range3 r3 = new Range3(); r3.first = dataInput.readCard16(); r3.fd = dataInput.readCard8(); fdselect.range3[i] = r3; } fdselect.sentinel = dataInput.readCard16(); return fdselect; }
/** * Reads the CFFData from a given font file * @param fontFile The font file being read * @return The byte data found in the CFF table */ public static byte[] getCFFData(FontFileReader fontFile) throws IOException { byte[] cff = fontFile.getAllBytes(); CFFDataInput input = new CFFDataInput(fontFile.getAllBytes()); input.readBytes(4); //OTTO short numTables = input.readShort(); input.readShort(); //searchRange input.readShort(); //entrySelector input.readShort(); //rangeShift for (int q = 0; q < numTables; q++) { String tagName = new String(input.readBytes(4)); readLong(input); //Checksum long offset = readLong(input); long length = readLong(input); if (tagName.equals("CFF ")) { cff = new byte[(int)length]; System.arraycopy(fontFile.getAllBytes(), (int)offset, cff, 0, cff.length); break; } } return cff; }
private CFFDataInput createTaggedCFFDataInput(CFFDataInput input, byte[] bytes) throws IOException { // this is OpenType font containing CFF data // so find CFF tag short numTables = input.readShort(); @SuppressWarnings({"unused", "squid:S1854"}) short searchRange = input.readShort(); @SuppressWarnings({"unused", "squid:S1854"}) short entrySelector = input.readShort(); @SuppressWarnings({"unused", "squid:S1854"}) short rangeShift = input.readShort(); for (int q = 0; q < numTables; q++) { String tagName = readTagName(input); @SuppressWarnings("unused") long checksum = readLong(input); long offset = readLong(input); long length = readLong(input); if ("CFF ".equals(tagName)) { byte[] bytes2 = Arrays.copyOfRange(bytes, (int) offset, (int) (offset + length)); return new CFFDataInput(bytes2); } } throw new IOException("CFF tag not found in this OpenType font."); }
int first = dataInput.readSID(); int nLeft = dataInput.readCard16(); if (!isCIDFont)
/** * Retrieves a number of bytes from the CFF data stream * @param offset The offset of the bytes to retrieve * @param length The number of bytes to retrieve * @return Returns a byte array of requested bytes * @throws IOException Throws an IO Exception if an error occurs */ private byte[] getCFFOffsetBytes(int offset, int length) throws IOException { cffData.setPosition(offset); return cffData.readBytes(length); }
private FDSelect readFDSelect() throws IOException { FDSelect fdSelect = null; DICTEntry fdSelectEntry = topDict.get("FDSelect"); if (fdSelectEntry != null) { int fdOffset = fdSelectEntry.getOperands().get(0).intValue(); cffData.setPosition(fdOffset); int format = cffData.readCard8(); switch (format) { case 0: fdSelect = readFormat0FDSelect(); break; case 3: fdSelect = readFormat3FDSelect(); break; default: } } return fdSelect; }
break; default: input.setPosition(encodingId); encoding = readEncoding(input, charset); break; input.setPosition(privateOffset); int privateSize = privateEntry.getNumber(0).intValue(); DictData privateDict = readDictData(input, privateSize); if (localSubrOffset > 0) input.setPosition(privateOffset + localSubrOffset); font.addToPrivateDict("Subrs", readIndexData(input));
private static long readLong(CFFDataInput input) throws IOException { return (input.readCard16() << 16) | input.readCard16(); }