| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkData.h" | 8 #include "SkData.h" |
| 9 #include "SkEndian.h" | 9 #include "SkEndian.h" |
| 10 #include "SkSFNTHeader.h" | 10 #include "SkSFNTHeader.h" |
| (...skipping 20 matching lines...) Expand all Loading... |
| 31 sum += SkEndian_SwapBE32(*data); | 31 sum += SkEndian_SwapBE32(*data); |
| 32 } | 32 } |
| 33 return sum; | 33 return sum; |
| 34 } | 34 } |
| 35 | 35 |
| 36 SkData* SkOTUtils::RenameFont(SkStreamAsset* fontData, const char* fontName, int
fontNameLen) { | 36 SkData* SkOTUtils::RenameFont(SkStreamAsset* fontData, const char* fontName, int
fontNameLen) { |
| 37 | 37 |
| 38 // Get the sfnt header. | 38 // Get the sfnt header. |
| 39 SkSFNTHeader sfntHeader; | 39 SkSFNTHeader sfntHeader; |
| 40 if (fontData->read(&sfntHeader, sizeof(sfntHeader)) < sizeof(sfntHeader)) { | 40 if (fontData->read(&sfntHeader, sizeof(sfntHeader)) < sizeof(sfntHeader)) { |
| 41 return NULL; | 41 return nullptr; |
| 42 } | 42 } |
| 43 | 43 |
| 44 // Find the existing 'name' table. | 44 // Find the existing 'name' table. |
| 45 int tableIndex; | 45 int tableIndex; |
| 46 SkSFNTHeader::TableDirectoryEntry tableEntry; | 46 SkSFNTHeader::TableDirectoryEntry tableEntry; |
| 47 int numTables = SkEndian_SwapBE16(sfntHeader.numTables); | 47 int numTables = SkEndian_SwapBE16(sfntHeader.numTables); |
| 48 for (tableIndex = 0; tableIndex < numTables; ++tableIndex) { | 48 for (tableIndex = 0; tableIndex < numTables; ++tableIndex) { |
| 49 if (fontData->read(&tableEntry, sizeof(tableEntry)) < sizeof(tableEntry)
) { | 49 if (fontData->read(&tableEntry, sizeof(tableEntry)) < sizeof(tableEntry)
) { |
| 50 return NULL; | 50 return nullptr; |
| 51 } | 51 } |
| 52 if (SkOTTableName::TAG == tableEntry.tag) { | 52 if (SkOTTableName::TAG == tableEntry.tag) { |
| 53 break; | 53 break; |
| 54 } | 54 } |
| 55 } | 55 } |
| 56 if (tableIndex == numTables) { | 56 if (tableIndex == numTables) { |
| 57 return NULL; | 57 return nullptr; |
| 58 } | 58 } |
| 59 | 59 |
| 60 if (!fontData->rewind()) { | 60 if (!fontData->rewind()) { |
| 61 return NULL; | 61 return nullptr; |
| 62 } | 62 } |
| 63 | 63 |
| 64 // The required 'name' record types: Family, Style, Unique, Full and PostScr
ipt. | 64 // The required 'name' record types: Family, Style, Unique, Full and PostScr
ipt. |
| 65 const SkOTTableName::Record::NameID::Predefined::Value namesToCreate[] = { | 65 const SkOTTableName::Record::NameID::Predefined::Value namesToCreate[] = { |
| 66 SkOTTableName::Record::NameID::Predefined::FontFamilyName, | 66 SkOTTableName::Record::NameID::Predefined::FontFamilyName, |
| 67 SkOTTableName::Record::NameID::Predefined::FontSubfamilyName, | 67 SkOTTableName::Record::NameID::Predefined::FontSubfamilyName, |
| 68 SkOTTableName::Record::NameID::Predefined::UniqueFontIdentifier, | 68 SkOTTableName::Record::NameID::Predefined::UniqueFontIdentifier, |
| 69 SkOTTableName::Record::NameID::Predefined::FullFontName, | 69 SkOTTableName::Record::NameID::Predefined::FullFontName, |
| 70 SkOTTableName::Record::NameID::Predefined::PostscriptName, | 70 SkOTTableName::Record::NameID::Predefined::PostscriptName, |
| 71 }; | 71 }; |
| 72 const int namesCount = SK_ARRAY_COUNT(namesToCreate); | 72 const int namesCount = SK_ARRAY_COUNT(namesToCreate); |
| 73 | 73 |
| 74 // Copy the data, leaving out the old name table. | 74 // Copy the data, leaving out the old name table. |
| 75 // In theory, we could also remove the DSIG table if it exists. | 75 // In theory, we could also remove the DSIG table if it exists. |
| 76 size_t nameTableLogicalSize = sizeof(SkOTTableName) + (namesCount * sizeof(S
kOTTableName::Record)) + (fontNameLen * sizeof(wchar_t)); | 76 size_t nameTableLogicalSize = sizeof(SkOTTableName) + (namesCount * sizeof(S
kOTTableName::Record)) + (fontNameLen * sizeof(wchar_t)); |
| 77 size_t nameTablePhysicalSize = (nameTableLogicalSize + 3) & ~3; // Rounded u
p to a multiple of 4. | 77 size_t nameTablePhysicalSize = (nameTableLogicalSize + 3) & ~3; // Rounded u
p to a multiple of 4. |
| 78 | 78 |
| 79 size_t oldNameTablePhysicalSize = (SkEndian_SwapBE32(tableEntry.logicalLengt
h) + 3) & ~3; // Rounded up to a multiple of 4. | 79 size_t oldNameTablePhysicalSize = (SkEndian_SwapBE32(tableEntry.logicalLengt
h) + 3) & ~3; // Rounded up to a multiple of 4. |
| 80 size_t oldNameTableOffset = SkEndian_SwapBE32(tableEntry.offset); | 80 size_t oldNameTableOffset = SkEndian_SwapBE32(tableEntry.offset); |
| 81 | 81 |
| 82 //originalDataSize is the size of the original data without the name table. | 82 //originalDataSize is the size of the original data without the name table. |
| 83 size_t originalDataSize = fontData->getLength() - oldNameTablePhysicalSize; | 83 size_t originalDataSize = fontData->getLength() - oldNameTablePhysicalSize; |
| 84 size_t newDataSize = originalDataSize + nameTablePhysicalSize; | 84 size_t newDataSize = originalDataSize + nameTablePhysicalSize; |
| 85 | 85 |
| 86 SkAutoTUnref<SkData> rewrittenFontData(SkData::NewUninitialized(newDataSize)
); | 86 SkAutoTUnref<SkData> rewrittenFontData(SkData::NewUninitialized(newDataSize)
); |
| 87 SK_OT_BYTE* data = static_cast<SK_OT_BYTE*>(rewrittenFontData->writable_data
()); | 87 SK_OT_BYTE* data = static_cast<SK_OT_BYTE*>(rewrittenFontData->writable_data
()); |
| 88 | 88 |
| 89 if (fontData->read(data, oldNameTableOffset) < oldNameTableOffset) { | 89 if (fontData->read(data, oldNameTableOffset) < oldNameTableOffset) { |
| 90 return NULL; | 90 return nullptr; |
| 91 } | 91 } |
| 92 if (fontData->skip(oldNameTablePhysicalSize) < oldNameTablePhysicalSize) { | 92 if (fontData->skip(oldNameTablePhysicalSize) < oldNameTablePhysicalSize) { |
| 93 return NULL; | 93 return nullptr; |
| 94 } | 94 } |
| 95 if (fontData->read(data + oldNameTableOffset, originalDataSize - oldNameTabl
eOffset) < originalDataSize - oldNameTableOffset) { | 95 if (fontData->read(data + oldNameTableOffset, originalDataSize - oldNameTabl
eOffset) < originalDataSize - oldNameTableOffset) { |
| 96 return NULL; | 96 return nullptr; |
| 97 } | 97 } |
| 98 | 98 |
| 99 //Fix up the offsets of the directory entries after the old 'name' table ent
ry. | 99 //Fix up the offsets of the directory entries after the old 'name' table ent
ry. |
| 100 SkSFNTHeader::TableDirectoryEntry* currentEntry = reinterpret_cast<SkSFNTHea
der::TableDirectoryEntry*>(data + sizeof(SkSFNTHeader)); | 100 SkSFNTHeader::TableDirectoryEntry* currentEntry = reinterpret_cast<SkSFNTHea
der::TableDirectoryEntry*>(data + sizeof(SkSFNTHeader)); |
| 101 SkSFNTHeader::TableDirectoryEntry* endEntry = currentEntry + numTables; | 101 SkSFNTHeader::TableDirectoryEntry* endEntry = currentEntry + numTables; |
| 102 SkSFNTHeader::TableDirectoryEntry* headTableEntry = NULL; | 102 SkSFNTHeader::TableDirectoryEntry* headTableEntry = nullptr; |
| 103 for (; currentEntry < endEntry; ++currentEntry) { | 103 for (; currentEntry < endEntry; ++currentEntry) { |
| 104 uint32_t oldOffset = SkEndian_SwapBE32(currentEntry->offset); | 104 uint32_t oldOffset = SkEndian_SwapBE32(currentEntry->offset); |
| 105 if (oldOffset > oldNameTableOffset) { | 105 if (oldOffset > oldNameTableOffset) { |
| 106 currentEntry->offset = SkEndian_SwapBE32(SkToU32(oldOffset - oldName
TablePhysicalSize)); | 106 currentEntry->offset = SkEndian_SwapBE32(SkToU32(oldOffset - oldName
TablePhysicalSize)); |
| 107 } | 107 } |
| 108 if (SkOTTableHead::TAG == currentEntry->tag) { | 108 if (SkOTTableHead::TAG == currentEntry->tag) { |
| 109 headTableEntry = currentEntry; | 109 headTableEntry = currentEntry; |
| 110 } | 110 } |
| 111 } | 111 } |
| 112 | 112 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 159 | 159 |
| 160 return rewrittenFontData.detach(); | 160 return rewrittenFontData.detach(); |
| 161 } | 161 } |
| 162 | 162 |
| 163 | 163 |
| 164 SkOTUtils::LocalizedStrings_NameTable* | 164 SkOTUtils::LocalizedStrings_NameTable* |
| 165 SkOTUtils::LocalizedStrings_NameTable::CreateForFamilyNames(const SkTypeface& ty
peface) { | 165 SkOTUtils::LocalizedStrings_NameTable::CreateForFamilyNames(const SkTypeface& ty
peface) { |
| 166 static const SkFontTableTag nameTag = SkSetFourByteTag('n','a','m','e'); | 166 static const SkFontTableTag nameTag = SkSetFourByteTag('n','a','m','e'); |
| 167 size_t nameTableSize = typeface.getTableSize(nameTag); | 167 size_t nameTableSize = typeface.getTableSize(nameTag); |
| 168 if (0 == nameTableSize) { | 168 if (0 == nameTableSize) { |
| 169 return NULL; | 169 return nullptr; |
| 170 } | 170 } |
| 171 SkAutoTDeleteArray<uint8_t> nameTableData(new uint8_t[nameTableSize]); | 171 SkAutoTDeleteArray<uint8_t> nameTableData(new uint8_t[nameTableSize]); |
| 172 size_t copied = typeface.getTableData(nameTag, 0, nameTableSize, nameTableDa
ta.get()); | 172 size_t copied = typeface.getTableData(nameTag, 0, nameTableSize, nameTableDa
ta.get()); |
| 173 if (copied != nameTableSize) { | 173 if (copied != nameTableSize) { |
| 174 return NULL; | 174 return nullptr; |
| 175 } | 175 } |
| 176 | 176 |
| 177 return new SkOTUtils::LocalizedStrings_NameTable((SkOTTableName*)nameTableDa
ta.detach(), | 177 return new SkOTUtils::LocalizedStrings_NameTable((SkOTTableName*)nameTableDa
ta.detach(), |
| 178 SkOTUtils::LocalizedStrings_NameTable::familyNameTypes, | 178 SkOTUtils::LocalizedStrings_NameTable::familyNameTypes, |
| 179 SK_ARRAY_COUNT(SkOTUtils::LocalizedStrings_NameTable::familyNameTypes)); | 179 SK_ARRAY_COUNT(SkOTUtils::LocalizedStrings_NameTable::familyNameTypes)); |
| 180 } | 180 } |
| 181 | 181 |
| 182 bool SkOTUtils::LocalizedStrings_NameTable::next(SkTypeface::LocalizedString* lo
calizedString) { | 182 bool SkOTUtils::LocalizedStrings_NameTable::next(SkTypeface::LocalizedString* lo
calizedString) { |
| 183 do { | 183 do { |
| 184 SkOTTableName::Iterator::Record record; | 184 SkOTTableName::Iterator::Record record; |
| 185 if (fFamilyNameIter.next(record)) { | 185 if (fFamilyNameIter.next(record)) { |
| 186 localizedString->fString = record.name; | 186 localizedString->fString = record.name; |
| 187 localizedString->fLanguage = record.language; | 187 localizedString->fLanguage = record.language; |
| 188 return true; | 188 return true; |
| 189 } | 189 } |
| 190 if (fTypesCount == fTypesIndex + 1) { | 190 if (fTypesCount == fTypesIndex + 1) { |
| 191 return false; | 191 return false; |
| 192 } | 192 } |
| 193 ++fTypesIndex; | 193 ++fTypesIndex; |
| 194 fFamilyNameIter.reset(fTypes[fTypesIndex]); | 194 fFamilyNameIter.reset(fTypes[fTypesIndex]); |
| 195 } while (true); | 195 } while (true); |
| 196 } | 196 } |
| 197 | 197 |
| 198 SkOTTableName::Record::NameID::Predefined::Value | 198 SkOTTableName::Record::NameID::Predefined::Value |
| 199 SkOTUtils::LocalizedStrings_NameTable::familyNameTypes[3] = { | 199 SkOTUtils::LocalizedStrings_NameTable::familyNameTypes[3] = { |
| 200 SkOTTableName::Record::NameID::Predefined::FontFamilyName, | 200 SkOTTableName::Record::NameID::Predefined::FontFamilyName, |
| 201 SkOTTableName::Record::NameID::Predefined::PreferredFamily, | 201 SkOTTableName::Record::NameID::Predefined::PreferredFamily, |
| 202 SkOTTableName::Record::NameID::Predefined::WWSFamilyName, | 202 SkOTTableName::Record::NameID::Predefined::WWSFamilyName, |
| 203 }; | 203 }; |
| OLD | NEW |