diff options
author | Hal Canary <halcanary@google.com> | 2018-05-09 11:50:34 -0400 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2018-05-09 18:00:35 +0000 |
commit | 46cc3dabaff7daa6b57e3c33997153d986219579 (patch) | |
tree | 809ca0d62fddcbd3b378d0a4d330692ebd58748d /src/ports | |
parent | 06d374694a515d064a26e6c5391bce9a0c5c8aa0 (diff) |
Revert "Revert "SkAdvancedTypefaceMetrics: factor out GlyphToUnicode""
This reverts commit 97c1108607584b6050a6880d6ce22846e4913a92.
Change-Id: Ic3c6addc64ced39766bbee3e10b4d88faf61ba2f
Reviewed-on: https://skia-review.googlesource.com/127021
Reviewed-by: Hal Canary <halcanary@google.com>
Commit-Queue: Hal Canary <halcanary@google.com>
Diffstat (limited to 'src/ports')
-rw-r--r-- | src/ports/SkFontHost_FreeType.cpp | 42 | ||||
-rw-r--r-- | src/ports/SkFontHost_FreeType_common.h | 1 | ||||
-rw-r--r-- | src/ports/SkFontHost_mac.cpp | 26 | ||||
-rw-r--r-- | src/ports/SkFontHost_win.cpp | 30 | ||||
-rw-r--r-- | src/ports/SkTypeface_win_dw.cpp | 30 | ||||
-rw-r--r-- | src/ports/SkTypeface_win_dw.h | 1 |
6 files changed, 63 insertions, 67 deletions
diff --git a/src/ports/SkFontHost_FreeType.cpp b/src/ports/SkFontHost_FreeType.cpp index f1c1b555f2..3e8e9576dd 100644 --- a/src/ports/SkFontHost_FreeType.cpp +++ b/src/ports/SkFontHost_FreeType.cpp @@ -511,23 +511,6 @@ static bool canSubset(FT_Face face) { return (fsType & FT_FSTYPE_NO_SUBSETTING) == 0; } -static void populate_glyph_to_unicode(FT_Face& face, SkTDArray<SkUnichar>* glyphToUnicode) { - FT_Long numGlyphs = face->num_glyphs; - glyphToUnicode->setCount(SkToInt(numGlyphs)); - sk_bzero(glyphToUnicode->begin(), sizeof((*glyphToUnicode)[0]) * numGlyphs); - - FT_UInt glyphIndex; - SkUnichar charCode = FT_Get_First_Char(face, &glyphIndex); - while (glyphIndex) { - SkASSERT(glyphIndex < SkToUInt(numGlyphs)); - // Use the first character that maps to this glyphID. https://crbug.com/359065 - if (0 == (*glyphToUnicode)[glyphIndex]) { - (*glyphToUnicode)[glyphIndex] = charCode; - } - charCode = FT_Get_Next_Char(face, charCode, &glyphIndex); - } -} - static SkAdvancedTypefaceMetrics::FontType get_font_type(FT_Face face) { const char* fontType = FT_Get_X11_Font_Format(face); static struct { const char* s; SkAdvancedTypefaceMetrics::FontType t; } values[] = { @@ -602,17 +585,26 @@ std::unique_ptr<SkAdvancedTypefaceMetrics> SkTypeface_FreeType::onGetAdvancedMet } info->fBBox = SkIRect::MakeLTRB(face->bbox.xMin, face->bbox.yMax, face->bbox.xMax, face->bbox.yMin); + return info; +} - bool perGlyphInfo = FT_IS_SCALABLE(face); +void SkTypeface_FreeType::getGlyphToUnicodeMap(SkUnichar* dstArray) const { + SkASSERT(dstArray); + AutoFTAccess fta(this); + FT_Face face = fta.face(); + FT_Long numGlyphs = face->num_glyphs; + sk_bzero(dstArray, sizeof(SkUnichar) * numGlyphs); - if (perGlyphInfo && - info->fType != SkAdvancedTypefaceMetrics::kType1_Font && - face->num_charmaps) - { - populate_glyph_to_unicode(face, &(info->fGlyphToUnicode)); + FT_UInt glyphIndex; + SkUnichar charCode = FT_Get_First_Char(face, &glyphIndex); + while (glyphIndex) { + SkASSERT(glyphIndex < SkToUInt(numGlyphs)); + // Use the first character that maps to this glyphID. https://crbug.com/359065 + if (0 == dstArray[glyphIndex]) { + dstArray[glyphIndex] = charCode; + } + charCode = FT_Get_Next_Char(face, charCode, &glyphIndex); } - - return info; } void SkTypeface_FreeType::getPostScriptGlyphNames(SkString* dstArray) const { diff --git a/src/ports/SkFontHost_FreeType_common.h b/src/ports/SkFontHost_FreeType_common.h index 3aabdde250..eacce04ca1 100644 --- a/src/ports/SkFontHost_FreeType_common.h +++ b/src/ports/SkFontHost_FreeType_common.h @@ -91,6 +91,7 @@ protected: virtual SkScalerContext* onCreateScalerContext(const SkScalerContextEffects&, const SkDescriptor*) const override; void onFilterRec(SkScalerContextRec*) const override; + void getGlyphToUnicodeMap(SkUnichar*) const override; std::unique_ptr<SkAdvancedTypefaceMetrics> onGetAdvancedMetrics() const override; void getPostScriptGlyphNames(SkString* dstArray) const override; int onGetUPEM() const override; diff --git a/src/ports/SkFontHost_mac.cpp b/src/ports/SkFontHost_mac.cpp index 8047c4352f..3cc51d43f6 100644 --- a/src/ports/SkFontHost_mac.cpp +++ b/src/ports/SkFontHost_mac.cpp @@ -719,6 +719,7 @@ protected: const SkDescriptor*) const override; void onFilterRec(SkScalerContextRec*) const override; void onGetFontDescriptor(SkFontDescriptor*, bool*) const override; + void getGlyphToUnicodeMap(SkUnichar*) const override; std::unique_ptr<SkAdvancedTypefaceMetrics> onGetAdvancedMetrics() const override; int onCharsToGlyphs(const void* chars, Encoding, uint16_t glyphs[], int glyphCount) const override; @@ -1605,9 +1606,7 @@ static sk_sp<SkTypeface> create_from_dataProvider(UniqueCFRef<CGDataProviderRef> // Iterate through the font in this case. The existing caller caches the result, // so the performance impact isn't too bad. static void populate_glyph_to_unicode_slow(CTFontRef ctFont, CFIndex glyphCount, - SkTDArray<SkUnichar>* glyphToUnicode) { - glyphToUnicode->setCount(SkToInt(glyphCount)); - SkUnichar* out = glyphToUnicode->begin(); + SkUnichar* out) { sk_bzero(out, glyphCount * sizeof(SkUnichar)); UniChar unichar = 0; while (glyphCount > 0) { @@ -1628,7 +1627,8 @@ static void populate_glyph_to_unicode_slow(CTFontRef ctFont, CFIndex glyphCount, // Unicode code points that require conjugate pairs in utf16 are not // supported. static void populate_glyph_to_unicode(CTFontRef ctFont, CFIndex glyphCount, - SkTDArray<SkUnichar>* glyphToUnicode) { + SkUnichar* glyphToUnicode) { + sk_bzero(glyphToUnicode, sizeof(SkUnichar) * glyphCount); UniqueCFRef<CFCharacterSetRef> charSet(CTFontCopyCharacterSet(ctFont)); if (!charSet) { populate_glyph_to_unicode_slow(ctFont, glyphCount, glyphToUnicode); @@ -1651,9 +1651,7 @@ static void populate_glyph_to_unicode(CTFontRef ctFont, CFIndex glyphCount, length = 8192; } const UInt8* bits = CFDataGetBytePtr(bitmap.get()); - glyphToUnicode->setCount(SkToInt(glyphCount)); - SkUnichar* out = glyphToUnicode->begin(); - sk_bzero(out, glyphCount * sizeof(SkUnichar)); + sk_bzero(glyphToUnicode, glyphCount * sizeof(SkUnichar)); for (int i = 0; i < length; i++) { int mask = bits[i]; if (!mask) { @@ -1663,7 +1661,7 @@ static void populate_glyph_to_unicode(CTFontRef ctFont, CFIndex glyphCount, CGGlyph glyph; UniChar unichar = static_cast<UniChar>((i << 3) + j); if (mask & (1 << j) && CTFontGetGlyphsForCharacters(ctFont, &unichar, &glyph, 1)) { - out[glyph] = unichar; + glyphToUnicode[glyph] = unichar; } } } @@ -1681,6 +1679,14 @@ static void CFStringToSkString(CFStringRef src, SkString* dst) { dst->resize(strlen(dst->c_str())); } +void SkTypeface_Mac::getGlyphToUnicodeMap(SkUnichar* dstArray) const { + AUTO_CG_LOCK(); + UniqueCFRef<CTFontRef> ctFont = + ctfont_create_exact_copy(fFontRef.get(), CTFontGetUnitsPerEm(fFontRef.get()), nullptr); + CFIndex glyphCount = CTFontGetGlyphCount(ctFont.get()); + populate_glyph_to_unicode(ctFont.get(), glyphCount, dstArray); +} + std::unique_ptr<SkAdvancedTypefaceMetrics> SkTypeface_Mac::onGetAdvancedMetrics() const { AUTO_CG_LOCK(); @@ -1710,10 +1716,6 @@ std::unique_ptr<SkAdvancedTypefaceMetrics> SkTypeface_Mac::onGetAdvancedMetrics( } } - CFIndex glyphCount = CTFontGetGlyphCount(ctFont.get()); - - populate_glyph_to_unicode(ctFont.get(), glyphCount, &info->fGlyphToUnicode); - SkOTTableOS2_V4::Type fsType; if (sizeof(fsType) == this->getTableData(SkTEndian_SwapBE32(SkOTTableOS2::TAG), offsetof(SkOTTableOS2_V4, fsType), diff --git a/src/ports/SkFontHost_win.cpp b/src/ports/SkFontHost_win.cpp index 35a0a74b22..f1da8053f2 100644 --- a/src/ports/SkFontHost_win.cpp +++ b/src/ports/SkFontHost_win.cpp @@ -261,6 +261,7 @@ protected: SkScalerContext* onCreateScalerContext(const SkScalerContextEffects&, const SkDescriptor*) const override; void onFilterRec(SkScalerContextRec*) const override; + void getGlyphToUnicodeMap(SkUnichar*) const override; std::unique_ptr<SkAdvancedTypefaceMetrics> onGetAdvancedMetrics() const override; void onGetFontDescriptor(SkFontDescriptor*, bool*) const override; int onCharsToGlyphs(const void* chars, Encoding encoding, @@ -362,7 +363,8 @@ void SkLOGFONTFromTypeface(const SkTypeface* face, LOGFONT* lf) { // require parsing the TTF cmap table (platform 4, encoding 12) directly instead // of calling GetFontUnicodeRange(). static void populate_glyph_to_unicode(HDC fontHdc, const unsigned glyphCount, - SkTDArray<SkUnichar>* glyphToUnicode) { + SkUnichar* glyphToUnicode) { + sk_bzero(glyphToUnicode, sizeof(SkUnichar) * glyphCount); DWORD glyphSetBufferSize = GetFontUnicodeRanges(fontHdc, nullptr); if (!glyphSetBufferSize) { return; @@ -375,8 +377,6 @@ static void populate_glyph_to_unicode(HDC fontHdc, const unsigned glyphCount, return; } - glyphToUnicode->setCount(glyphCount); - memset(glyphToUnicode->begin(), 0, glyphCount * sizeof(SkUnichar)); for (DWORD i = 0; i < glyphSet->cRanges; ++i) { // There is no guarantee that within a Unicode range, the corresponding // glyph id in a font file are continuous. So, even if we have ranges, @@ -399,9 +399,8 @@ static void populate_glyph_to_unicode(HDC fontHdc, const unsigned glyphCount, // unlikely to have collisions since glyph reuse happens mostly for // different Unicode pages. for (USHORT j = 0; j < count; ++j) { - if (glyph[j] != 0xffff && glyph[j] < glyphCount && - (*glyphToUnicode)[glyph[j]] == 0) { - (*glyphToUnicode)[glyph[j]] = chars[j]; + if (glyph[j] != 0xFFFF && glyph[j] < glyphCount && glyphToUnicode[glyph[j]] == 0) { + glyphToUnicode[glyph[j]] = chars[j]; } } } @@ -1707,6 +1706,23 @@ void LogFontTypeface::onGetFontDescriptor(SkFontDescriptor* desc, *isLocalStream = this->fSerializeAsStream; } +void LogFontTypeface::getGlyphToUnicodeMap(SkUnichar* dstArray) const { + HDC hdc = ::CreateCompatibleDC(nullptr); + HFONT font = CreateFontIndirect(&fLogFont); + HFONT savefont = (HFONT)SelectObject(hdc, font); + LOGFONT lf = fLogFont; + HFONT designFont = CreateFontIndirect(&lf); + SelectObject(hdc, designFont); + + unsigned int glyphCount = calculateGlyphCount(hdc, fLogFont); + populate_glyph_to_unicode(hdc, glyphCount, dstArray); + + SelectObject(hdc, savefont); + DeleteObject(designFont); + DeleteObject(font); + DeleteDC(hdc); +} + std::unique_ptr<SkAdvancedTypefaceMetrics> LogFontTypeface::onGetAdvancedMetrics() const { LOGFONT lf = fLogFont; std::unique_ptr<SkAdvancedTypefaceMetrics> info(nullptr); @@ -1757,8 +1773,6 @@ std::unique_ptr<SkAdvancedTypefaceMetrics> LogFontTypeface::onGetAdvancedMetrics } } - populate_glyph_to_unicode(hdc, glyphCount, &(info->fGlyphToUnicode)); - if (glyphCount > 0 && (otm.otmTextMetrics.tmPitchAndFamily & TMPF_TRUETYPE)) { info->fType = SkAdvancedTypefaceMetrics::kTrueType_Font; diff --git a/src/ports/SkTypeface_win_dw.cpp b/src/ports/SkTypeface_win_dw.cpp index 69bf7ff034..38e68dccca 100644 --- a/src/ports/SkTypeface_win_dw.cpp +++ b/src/ports/SkTypeface_win_dw.cpp @@ -288,42 +288,31 @@ void DWriteFontTypeface::onFilterRec(SkScalerContextRec* rec) const { /////////////////////////////////////////////////////////////////////////////// //PDF Support -// Construct Glyph to Unicode table. -// Unicode code points that require conjugate pairs in utf16 are not -// supported. -// TODO(bungeman): This never does what anyone wants. -// What is really wanted is the text to glyphs mapping -static void populate_glyph_to_unicode(IDWriteFontFace* fontFace, - const unsigned glyphCount, - SkTDArray<SkUnichar>* glyphToUnicode) { - //Do this like free type instead - SkAutoTMalloc<SkUnichar> glyphToUni( - (SkUnichar*)sk_calloc_throw(sizeof(SkUnichar) * glyphCount)); +void DWriteFontTypeface::getGlyphToUnicodeMap(SkUnichar* glyphToUnicode) const { + unsigned glyphCount = fDWriteFontFace->GetGlyphCount(); + sk_bzero(glyphToUnicode, sizeof(SkUnichar) * glyphCount); + IDWriteFontFace* fontFace = fDWriteFontFace.get(); int maxGlyph = -1; unsigned remainingGlyphCount = glyphCount; for (UINT32 c = 0; c < 0x10FFFF && remainingGlyphCount != 0; ++c) { UINT16 glyph = 0; - HRVM(fontFace->GetGlyphIndices(&c, 1, &glyph), - "Failed to get glyph index."); + HRVM(fontFace->GetGlyphIndices(&c, 1, &glyph), "Failed to get glyph index."); // Intermittent DW bug on Windows 10. See crbug.com/470146. if (glyph >= glyphCount) { - return; + return; } - if (0 < glyph && glyphToUni[glyph] == 0) { + if (0 < glyph && glyphToUnicode[glyph] == 0) { maxGlyph = SkTMax(static_cast<int>(glyph), maxGlyph); - glyphToUni[glyph] = c; // Always use lowest-index unichar. + glyphToUnicode[glyph] = c; // Always use lowest-index unichar. --remainingGlyphCount; } } - SkTDArray<SkUnichar>(glyphToUni, maxGlyph + 1).swap(*glyphToUnicode); } std::unique_ptr<SkAdvancedTypefaceMetrics> DWriteFontTypeface::onGetAdvancedMetrics() const { std::unique_ptr<SkAdvancedTypefaceMetrics> info(nullptr); - const unsigned glyphCount = fDWriteFontFace->GetGlyphCount(); - DWRITE_FONT_METRICS dwfm; fDWriteFontFace->GetMetrics(&dwfm); @@ -358,9 +347,6 @@ std::unique_ptr<SkAdvancedTypefaceMetrics> DWriteFontTypeface::onGetAdvancedMetr info->fPostScriptName = info->fFontName; } - - populate_glyph_to_unicode(fDWriteFontFace.get(), glyphCount, &(info->fGlyphToUnicode)); - DWRITE_FONT_FACE_TYPE fontType = fDWriteFontFace->GetType(); if (fontType != DWRITE_FONT_FACE_TYPE_TRUETYPE && fontType != DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION) diff --git a/src/ports/SkTypeface_win_dw.h b/src/ports/SkTypeface_win_dw.h index 7abbde55aa..75be040fd4 100644 --- a/src/ports/SkTypeface_win_dw.h +++ b/src/ports/SkTypeface_win_dw.h @@ -104,6 +104,7 @@ protected: SkScalerContext* onCreateScalerContext(const SkScalerContextEffects&, const SkDescriptor*) const override; void onFilterRec(SkScalerContextRec*) const override; + void getGlyphToUnicodeMap(SkUnichar* glyphToUnicode) const override; std::unique_ptr<SkAdvancedTypefaceMetrics> onGetAdvancedMetrics() const override; void onGetFontDescriptor(SkFontDescriptor*, bool*) const override; int onCharsToGlyphs(const void* chars, Encoding encoding, |