diff options
author | Ben Wagner <bungeman@google.com> | 2018-04-05 11:57:17 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-04-05 19:38:48 +0000 |
commit | 93e4ea52f66320685d3bcd1d613d6cf36de5e080 (patch) | |
tree | 9703e712f6713c73f70020054c3b6c30ee2bacef /src/ports/SkFontHost_mac.cpp | |
parent | 87f852d1a30f040cfa0e9567b17ec236e14a0f41 (diff) |
Mac to better serialize OTTO fonts.
Sometimes CoreText just gives up on filling out kCTFontFormatAttribute
properly, in which case we need a simple fallback for format detection
which isn't so reluctant to determine the type. The strategy prior to this
change is to use the most common type (WindowsTrueType), but apparently
if a font is actually an OpenType CFF font but has a WindowsTrueType tag
as the first few bytes, CoreGraphics gives up and won't load the font. So
check if there are any CFF tables and, if so, mark the font as
OpenTypeCFF.
BUG=skia:7630
Change-Id: Ie974e6db031db13628d5a19962e23ce2bf127367
Reviewed-on: https://skia-review.googlesource.com/118887
Commit-Queue: Mike Klein <mtklein@google.com>
Reviewed-by: Mike Klein <mtklein@google.com>
Diffstat (limited to 'src/ports/SkFontHost_mac.cpp')
-rw-r--r-- | src/ports/SkFontHost_mac.cpp | 66 |
1 files changed, 41 insertions, 25 deletions
diff --git a/src/ports/SkFontHost_mac.cpp b/src/ports/SkFontHost_mac.cpp index cd77b2f491..fa39d74704 100644 --- a/src/ports/SkFontHost_mac.cpp +++ b/src/ports/SkFontHost_mac.cpp @@ -1780,8 +1780,7 @@ std::unique_ptr<SkAdvancedTypefaceMetrics> SkTypeface_Mac::onGetAdvancedMetrics( /////////////////////////////////////////////////////////////////////////////// -static SK_SFNT_ULONG get_font_type_tag(const SkTypeface_Mac* typeface) { - CTFontRef ctFont = typeface->fFontRef.get(); +static SK_SFNT_ULONG get_font_type_tag(CTFontRef ctFont) { UniqueCFRef<CFNumberRef> fontFormatRef( static_cast<CFNumberRef>(CTFontCopyAttribute(ctFont, kCTFontFormatAttribute))); if (!fontFormatRef) { @@ -1806,18 +1805,12 @@ static SK_SFNT_ULONG get_font_type_tag(const SkTypeface_Mac* typeface) { return SkSFNTHeader::fontType_MacTrueType::TAG; case kCTFontFormatUnrecognized: default: - //CT seems to be unreliable in being able to obtain the type, - //even if all we want is the first four bytes of the font resource. - //Just the presence of the FontForge 'FFTM' table seems to throw it off. - return SkSFNTHeader::fontType_WindowsTrueType::TAG; + return 0; } } SkStreamAsset* SkTypeface_Mac::onOpenStream(int* ttcIndex) const { - SK_SFNT_ULONG fontType = get_font_type_tag(this); - if (0 == fontType) { - return nullptr; - } + SK_SFNT_ULONG fontType = get_font_type_tag(fFontRef.get()); // get table tags int numTables = this->countTables(); @@ -1825,30 +1818,53 @@ SkStreamAsset* SkTypeface_Mac::onOpenStream(int* ttcIndex) const { tableTags.setCount(numTables); this->getTableTags(tableTags.begin()); - // see if there are any required 'typ1' tables (see Adobe Technical Note #5180) - bool couldBeTyp1 = false; - constexpr SkFontTableTag TYPE1Tag = SkSetFourByteTag('T', 'Y', 'P', '1'); - constexpr SkFontTableTag CIDTag = SkSetFourByteTag('C', 'I', 'D', ' '); + // CT seems to be unreliable in being able to obtain the type, + // even if all we want is the first four bytes of the font resource. + // Just the presence of the FontForge 'FFTM' table seems to throw it off. + if (fontType == 0) { + fontType = SkSFNTHeader::fontType_WindowsTrueType::TAG; + + // see https://skbug.com/7630#c7 + bool couldBeCFF = false; + constexpr SkFontTableTag CFFTag = SkSetFourByteTag('C', 'F', 'F', ' '); + constexpr SkFontTableTag CFF2Tag = SkSetFourByteTag('C', 'F', 'F', '2'); + for (int tableIndex = 0; tableIndex < numTables; ++tableIndex) { + if (CFFTag == tableTags[tableIndex] || CFF2Tag == tableTags[tableIndex]) { + couldBeCFF = true; + } + } + if (couldBeCFF) { + fontType = SkSFNTHeader::fontType_OpenTypeCFF::TAG; + } + } + + // Sometimes CoreGraphics incorrectly thinks a font is kCTFontFormatPostScript. + // It is exceedingly unlikely that this is the case, so double check + // (see https://crbug.com/809763 ). + if (fontType == SkSFNTHeader::fontType_PostScript::TAG) { + // see if there are any required 'typ1' tables (see Adobe Technical Note #5180) + bool couldBeTyp1 = false; + constexpr SkFontTableTag TYPE1Tag = SkSetFourByteTag('T', 'Y', 'P', '1'); + constexpr SkFontTableTag CIDTag = SkSetFourByteTag('C', 'I', 'D', ' '); + for (int tableIndex = 0; tableIndex < numTables; ++tableIndex) { + if (TYPE1Tag == tableTags[tableIndex] || CIDTag == tableTags[tableIndex]) { + couldBeTyp1 = true; + } + } + if (!couldBeTyp1) { + fontType = SkSFNTHeader::fontType_OpenTypeCFF::TAG; + } + } + // get the table sizes and accumulate the total size of the font SkTDArray<size_t> tableSizes; size_t totalSize = sizeof(SkSFNTHeader) + sizeof(SkSFNTHeader::TableDirectoryEntry) * numTables; for (int tableIndex = 0; tableIndex < numTables; ++tableIndex) { - if (TYPE1Tag == tableTags[tableIndex] || CIDTag == tableTags[tableIndex]) { - couldBeTyp1 = true; - } - size_t tableSize = this->getTableSize(tableTags[tableIndex]); totalSize += (tableSize + 3) & ~3; *tableSizes.append() = tableSize; } - // sometimes CoreGraphics incorrectly thinks a font is kCTFontFormatPostScript - // it is exceedingly unlikely that this is the case, so double check - // see https://crbug.com/809763 - if (fontType == SkSFNTHeader::fontType_PostScript::TAG && !couldBeTyp1) { - fontType = SkSFNTHeader::fontType_OpenTypeCFF::TAG; - } - // reserve memory for stream, and zero it (tables must be zero padded) SkMemoryStream* stream = new SkMemoryStream(totalSize); char* dataStart = (char*)stream->getMemoryBase(); |