static String parseNameRecord (MemoryInputStream& input, const NameRecord& nameRecord, const int64 directoryOffset, const int64 offsetOfStringStorage) { String result; const int64 oldPos = input.getPosition(); input.setPosition (directoryOffset + offsetOfStringStorage + ByteOrder::swapIfLittleEndian (nameRecord.offsetFromStorageArea)); const int stringLength = (int) ByteOrder::swapIfLittleEndian (nameRecord.stringLength); const int platformID = ByteOrder::swapIfLittleEndian (nameRecord.platformID); if (platformID == 0 || platformID == 3) { const int numChars = stringLength / 2 + 1; HeapBlock<uint16> buffer; buffer.calloc (numChars + 1); input.read (buffer, stringLength); for (int i = 0; i < numChars; ++i) buffer[i] = ByteOrder::swapIfLittleEndian (buffer[i]); static_jassert (sizeof (CharPointer_UTF16::CharType) == sizeof (uint16)); result = CharPointer_UTF16 ((CharPointer_UTF16::CharType*) buffer.getData()); } else { HeapBlock<char> buffer; buffer.calloc (stringLength + 1); input.read (buffer, stringLength); result = CharPointer_UTF8 (buffer.getData()); } input.setPosition (oldPos); return result; }
static String getTypefaceNameFromFile (MemoryInputStream& input) { OffsetTable offsetTable = { 0 }; input.read (&offsetTable, sizeof (offsetTable)); for (int i = 0; i < (int) ByteOrder::swapIfLittleEndian (offsetTable.numTables); ++i) { TableDirectory tableDirectory; zerostruct (tableDirectory); input.read (&tableDirectory, sizeof (tableDirectory)); if (String (tableDirectory.tag, sizeof (tableDirectory.tag)).equalsIgnoreCase ("name")) return parseNameTable (input, ByteOrder::swapIfLittleEndian (tableDirectory.offset)); } return {}; }
static String parseNameTable (MemoryInputStream& input, int64 directoryOffset) { input.setPosition (directoryOffset); NamingTable namingTable = { 0 }; input.read (&namingTable, sizeof (namingTable)); for (int i = 0; i < (int) ByteOrder::swapIfLittleEndian (namingTable.numberOfNameRecords); ++i) { NameRecord nameRecord = { 0 }; input.read (&nameRecord, sizeof (nameRecord)); if (ByteOrder::swapIfLittleEndian (nameRecord.nameID) == 4) { const String result (parseNameRecord (input, nameRecord, directoryOffset, ByteOrder::swapIfLittleEndian (namingTable.offsetStartOfStringStorage))); if (result.isNotEmpty()) return result; } } return String(); }