aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Ben Wagner <bungeman@google.com>2018-03-08 16:02:55 -0500
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2018-03-09 15:03:20 +0000
commit03cd6e6dec894b3447527f84e7591d62981df433 (patch)
tree2319502c438ba05cda2d8ce462b80484e4d3ef9f
parent74b429086122e19e82fe090fc999120ed48d3532 (diff)
Avoid serializing to 'typ1' on Mac.
CoreGraphics does not provide a means to get the original font data for a CGFont, only the tables. As a result, Skia pieces the font data back together when requested. The most awkward part of this is choosing the first four bytes, and the CTFont suggestion seems to often be wrong. This change doublechecks the selection of 'typ1', prefering to use 'OTTO' if there are no 'TYP1' or 'CID ' tables. These sorts of fonts are extremely old and unlikely to be in current use. It appears that CTFont may report that it has this format if it is an 'OTTO' font with very few glyphs. If Skia serializes such a font with 'typ1' as the first four bytes, CoreGraphics will not create a CGFont from the resulting font data. BUG=chromium:809763,skia:7630 Change-Id: I9979b9f0ebdd27c4ad0903e8ee6237241e755541 Reviewed-on: https://skia-review.googlesource.com/113306 Reviewed-by: Herb Derby <herb@google.com> Commit-Queue: Ben Wagner <bungeman@google.com>
-rw-r--r--resources/fonts/7630.otfbin0 -> 1168 bytes
-rw-r--r--src/ports/SkFontHost_mac.cpp17
-rw-r--r--tests/TypefaceTest.cpp15
3 files changed, 31 insertions, 1 deletions
diff --git a/resources/fonts/7630.otf b/resources/fonts/7630.otf
new file mode 100644
index 0000000000..355d0af275
--- /dev/null
+++ b/resources/fonts/7630.otf
Binary files differ
diff --git a/src/ports/SkFontHost_mac.cpp b/src/ports/SkFontHost_mac.cpp
index ae46664ff6..5d8723b95f 100644
--- a/src/ports/SkFontHost_mac.cpp
+++ b/src/ports/SkFontHost_mac.cpp
@@ -1629,15 +1629,30 @@ SkStreamAsset* SkTypeface_Mac::onOpenStream(int* ttcIndex) const {
tableTags.setCount(numTables);
this->getTableTags(tableTags.begin());
- // calc total size for font, save sizes
+ // 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', ' ');
+ // 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();
diff --git a/tests/TypefaceTest.cpp b/tests/TypefaceTest.cpp
index fc81e84926..b6b71aeb8c 100644
--- a/tests/TypefaceTest.cpp
+++ b/tests/TypefaceTest.cpp
@@ -94,6 +94,21 @@ DEF_TEST(TypefaceStyle, reporter) {
}
}
+DEF_TEST(TypefaceRoundTrip, reporter) {
+ sk_sp<SkTypeface> typeface(MakeResourceAsTypeface("fonts/7630.otf"));
+ if (!typeface) {
+ // Not all SkFontMgr can MakeFromStream().
+ return;
+ }
+
+ int fontIndex;
+ std::unique_ptr<SkStreamAsset> stream(typeface->openStream(&fontIndex));
+
+ sk_sp<SkFontMgr> fm = SkFontMgr::RefDefault();
+ sk_sp<SkTypeface> typeface2 = fm->makeFromStream(std::move(stream), fontIndex);
+ REPORTER_ASSERT(reporter, typeface2);
+}
+
DEF_TEST(TypefaceAxes, reporter) {
std::unique_ptr<SkStreamAsset> distortable(GetResourceAsStream("fonts/Distortable.ttf"));
if (!distortable) {