Bug 1228799 - Part 1 - Move GetTableFromFontData to gfxFontUtils as a static function, and expose FindTableDirEntry helper method. r=emk

This commit is contained in:
Jonathan Kew 2016-08-19 13:57:05 +01:00
parent 86b32617f9
commit 17a2101b23
7 changed files with 60 additions and 66 deletions

View File

@ -544,7 +544,8 @@ FT2FontEntry::GetFontTable(uint32_t aTableTag)
FTUserFontData *userFontData = static_cast<FTUserFontData*>(
cairo_font_face_get_user_data(mFontFace, &sFTUserFontDataKey));
if (userFontData && userFontData->FontData()) {
return GetTableFromFontData(userFontData->FontData(), aTableTag);
return gfxFontUtils::GetTableFromFontData(userFontData->FontData(),
aTableTag);
}
}

View File

@ -422,7 +422,7 @@ gfxFontconfigFontEntry::GetFontTable(uint32_t aTableTag)
{
// for data fonts, read directly from the font data
if (mFontData) {
return GetTableFromFontData(mFontData, aTableTag);
return gfxFontUtils::GetTableFromFontData(mFontData, aTableTag);
}
return gfxFontEntry::GetFontTable(aTableTag);

View File

@ -674,33 +674,6 @@ gfxFontEntry::ShareFontTableAndGetBlob(uint32_t aTag,
return entry->ShareTableAndGetBlob(Move(*aBuffer), mFontTableCache.get());
}
static int
DirEntryCmp(const void* aKey, const void* aItem)
{
int32_t tag = *static_cast<const int32_t*>(aKey);
const TableDirEntry* entry = static_cast<const TableDirEntry*>(aItem);
return tag - int32_t(entry->tag);
}
hb_blob_t*
gfxFontEntry::GetTableFromFontData(const void* aFontData, uint32_t aTableTag)
{
const SFNTHeader* header =
reinterpret_cast<const SFNTHeader*>(aFontData);
const TableDirEntry* dir =
reinterpret_cast<const TableDirEntry*>(header + 1);
dir = static_cast<const TableDirEntry*>
(bsearch(&aTableTag, dir, uint16_t(header->numTables),
sizeof(TableDirEntry), DirEntryCmp));
if (dir) {
return hb_blob_create(reinterpret_cast<const char*>(aFontData) +
dir->offset, dir->length,
HB_MEMORY_MODE_READONLY, nullptr, nullptr);
}
return nullptr;
}
already_AddRefed<gfxCharacterMap>
gfxFontEntry::GetCMAPFromFontInfo(FontInfoData *aFontInfoData,
uint32_t& aUVSOffset,

View File

@ -484,14 +484,6 @@ protected:
return NS_ERROR_FAILURE;
}
// Return a blob that wraps a table found within a buffer of font data.
// The blob does NOT own its data; caller guarantees that the buffer
// will remain valid at least as long as the blob.
// Returns null if the specified table is not found.
// This method assumes aFontData is valid 'sfnt' data; before using this,
// caller is responsible to do any sanitization/validation necessary.
hb_blob_t* GetTableFromFontData(const void* aFontData, uint32_t aTableTag);
// lookup the cmap in cached font data
virtual already_AddRefed<gfxCharacterMap>
GetCMAPFromFontInfo(FontInfoData *aFontInfoData,

View File

@ -962,6 +962,41 @@ gfxFontUtils::DetermineFontDataType(const uint8_t *aFontData, uint32_t aFontData
return GFX_USERFONT_UNKNOWN;
}
static int
DirEntryCmp(const void* aKey, const void* aItem)
{
int32_t tag = *static_cast<const int32_t*>(aKey);
const TableDirEntry* entry = static_cast<const TableDirEntry*>(aItem);
return tag - int32_t(entry->tag);
}
/* static */
TableDirEntry*
gfxFontUtils::FindTableDirEntry(const void* aFontData, uint32_t aTableTag)
{
const SFNTHeader* header =
reinterpret_cast<const SFNTHeader*>(aFontData);
const TableDirEntry* dir =
reinterpret_cast<const TableDirEntry*>(header + 1);
return static_cast<TableDirEntry*>
(bsearch(&aTableTag, dir, uint16_t(header->numTables),
sizeof(TableDirEntry), DirEntryCmp));
}
/* static */
hb_blob_t*
gfxFontUtils::GetTableFromFontData(const void* aFontData, uint32_t aTableTag)
{
const TableDirEntry* dir = FindTableDirEntry(aFontData, aTableTag);
if (dir) {
return hb_blob_create(reinterpret_cast<const char*>(aFontData) +
dir->offset, dir->length,
HB_MEMORY_MODE_READONLY, nullptr, nullptr);
}
return nullptr;
}
nsresult
gfxFontUtils::RenameFont(const nsAString& aName, const uint8_t *aFontData,
uint32_t aFontDataLength, FallibleTArray<uint8_t> *aNewFont)
@ -1045,21 +1080,14 @@ gfxFontUtils::RenameFont(const nsAString& aName, const uint8_t *aFontData,
SFNTHeader *sfntHeader = reinterpret_cast<SFNTHeader*>(newFontData);
// table directory entries begin immediately following SFNT header
TableDirEntry *dirEntry =
reinterpret_cast<TableDirEntry*>(newFontData + sizeof(SFNTHeader));
TableDirEntry *dirEntry =
FindTableDirEntry(newFontData, TRUETYPE_TAG('n','a','m','e'));
// function only called if font validates, so this should always be true
MOZ_ASSERT(dirEntry, "attempt to rename font with no name table");
uint32_t numTables = sfntHeader->numTables;
for (i = 0; i < numTables; i++, dirEntry++) {
if (dirEntry->tag == TRUETYPE_TAG('n','a','m','e')) {
break;
}
}
// function only called if font validates, so this should always be true
NS_ASSERTION(i < numTables, "attempt to rename font with no name table");
// note: dirEntry now points to name record
// note: dirEntry now points to 'name' table record
// recalculate name table checksum
uint32_t checkSum = 0;
@ -1116,25 +1144,11 @@ gfxFontUtils::GetFullNameFromSFNT(const uint8_t* aFontData, uint32_t aLength,
{
aFullName.AssignLiteral("(MISSING NAME)"); // should always get replaced
NS_ENSURE_TRUE(aLength >= sizeof(SFNTHeader), NS_ERROR_UNEXPECTED);
const SFNTHeader *sfntHeader =
reinterpret_cast<const SFNTHeader*>(aFontData);
const TableDirEntry *dirEntry =
reinterpret_cast<const TableDirEntry*>(aFontData + sizeof(SFNTHeader));
uint32_t numTables = sfntHeader->numTables;
NS_ENSURE_TRUE(aLength >=
sizeof(SFNTHeader) + numTables * sizeof(TableDirEntry),
NS_ERROR_UNEXPECTED);
bool foundName = false;
for (uint32_t i = 0; i < numTables; i++, dirEntry++) {
if (dirEntry->tag == TRUETYPE_TAG('n','a','m','e')) {
foundName = true;
break;
}
}
FindTableDirEntry(aFontData, TRUETYPE_TAG('n','a','m','e'));
// should never fail, as we're only called after font validation succeeded
NS_ENSURE_TRUE(foundName, NS_ERROR_NOT_AVAILABLE);
NS_ENSURE_TRUE(dirEntry, NS_ERROR_NOT_AVAILABLE);
uint32_t len = dirEntry->length;
NS_ENSURE_TRUE(aLength > len && aLength - len >= dirEntry->offset,

View File

@ -858,6 +858,20 @@ public:
GetFamilyNameFromTable(hb_blob_t *aNameTable,
nsAString& aFamilyName);
// Find the table directory entry for a given table tag, in a (validated)
// buffer of 'sfnt' data. Returns null if the tag is not present.
static mozilla::TableDirEntry*
FindTableDirEntry(const void* aFontData, uint32_t aTableTag);
// Return a blob that wraps a table found within a buffer of font data.
// The blob does NOT own its data; caller guarantees that the buffer
// will remain valid at least as long as the blob.
// Returns null if the specified table is not found.
// This method assumes aFontData is valid 'sfnt' data; before using this,
// caller is responsible to do any sanitization/validation necessary.
static hb_blob_t*
GetTableFromFontData(const void* aFontData, uint32_t aTableTag);
// create a new name table and build a new font with that name table
// appended on the end, returns true on success
static nsresult

View File

@ -652,7 +652,7 @@ gfxDownloadedFcFontEntry::GetFontTable(uint32_t aTableTag)
// so we can just return a blob that "wraps" the appropriate chunk of it.
// The blob should not attempt to free its data, as the entire sfnt data
// will be freed when the font entry is deleted.
return GetTableFromFontData(mFontData, aTableTag);
return gfxFontUtils::GetTableFromFontData(mFontData, aTableTag);
}
/*