diff options
author | bungeman <bungeman@google.com> | 2016-07-22 11:19:24 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-07-22 11:19:24 -0700 |
commit | f1491693527a70919de5d624a049cae38384474e (patch) | |
tree | 1e1076f385b14c7905ff739508182517f0f78dc1 /src | |
parent | 9a5c47f4effba3b48a9a8c7c144b72b532d06efe (diff) |
Correct advances for 'monospace' fonts in PDF.
FT_IS_FIXED_WIDTH, kCTFontMonoSpaceTrait, and TMPF_FIXED_PITCH
are style bits, they do not imply that all advances are the same.
BUG=skia:5537
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2162023002
Review-Url: https://codereview.chromium.org/2162023002
Diffstat (limited to 'src')
-rw-r--r-- | src/ports/SkFontHost_FreeType.cpp | 121 | ||||
-rw-r--r-- | src/ports/SkFontHost_mac.cpp | 38 | ||||
-rw-r--r-- | src/ports/SkFontHost_win.cpp | 48 |
3 files changed, 80 insertions, 127 deletions
diff --git a/src/ports/SkFontHost_FreeType.cpp b/src/ports/SkFontHost_FreeType.cpp index 2780a32d09..4a1f12babe 100644 --- a/src/ports/SkFontHost_FreeType.cpp +++ b/src/ports/SkFontHost_FreeType.cpp @@ -482,21 +482,17 @@ SkAdvancedTypefaceMetrics* SkTypeface_FreeType::onGetAdvancedTypefaceMetrics( info->fLastGlyphID = face->num_glyphs - 1; info->fEmSize = 1000; - bool cid = false; const char* fontType = FT_Get_X11_Font_Format(face); if (strcmp(fontType, "Type 1") == 0) { info->fType = SkAdvancedTypefaceMetrics::kType1_Font; } else if (strcmp(fontType, "CID Type 1") == 0) { info->fType = SkAdvancedTypefaceMetrics::kType1CID_Font; - cid = true; } else if (strcmp(fontType, "CFF") == 0) { info->fType = SkAdvancedTypefaceMetrics::kCFF_Font; } else if (strcmp(fontType, "TrueType") == 0) { info->fType = SkAdvancedTypefaceMetrics::kTrueType_Font; - cid = true; TT_Header* ttHeader; - if ((ttHeader = (TT_Header*)FT_Get_Sfnt_Table(face, - ft_sfnt_head)) != nullptr) { + if ((ttHeader = (TT_Header*)FT_Get_Sfnt_Table(face, ft_sfnt_head)) != nullptr) { info->fEmSize = ttHeader->Units_Per_EM; } } else { @@ -504,19 +500,19 @@ SkAdvancedTypefaceMetrics* SkTypeface_FreeType::onGetAdvancedTypefaceMetrics( } info->fStyle = 0; - if (FT_IS_FIXED_WIDTH(face)) + if (FT_IS_FIXED_WIDTH(face)) { info->fStyle |= SkAdvancedTypefaceMetrics::kFixedPitch_Style; - if (face->style_flags & FT_STYLE_FLAG_ITALIC) + } + if (face->style_flags & FT_STYLE_FLAG_ITALIC) { info->fStyle |= SkAdvancedTypefaceMetrics::kItalic_Style; + } - PS_FontInfoRec ps_info; - TT_Postscript* tt_info; - if (FT_Get_PS_Font_Info(face, &ps_info) == 0) { - info->fItalicAngle = ps_info.italic_angle; - } else if ((tt_info = - (TT_Postscript*)FT_Get_Sfnt_Table(face, - ft_sfnt_post)) != nullptr) { - info->fItalicAngle = SkFixedToScalar(tt_info->italicAngle); + PS_FontInfoRec psFontInfo; + TT_Postscript* postTable; + if (FT_Get_PS_Font_Info(face, &psFontInfo) == 0) { + info->fItalicAngle = psFontInfo.italic_angle; + } else if ((postTable = (TT_Postscript*)FT_Get_Sfnt_Table(face, ft_sfnt_post)) != nullptr) { + info->fItalicAngle = SkFixedToScalar(postTable->italicAngle); } else { info->fItalicAngle = 0; } @@ -540,20 +536,22 @@ SkAdvancedTypefaceMetrics* SkTypeface_FreeType::onGetAdvancedTypefaceMetrics( } } - TT_PCLT* pclt_info; - TT_OS2* os2_table; - if ((pclt_info = (TT_PCLT*)FT_Get_Sfnt_Table(face, ft_sfnt_pclt)) != nullptr) { - info->fCapHeight = pclt_info->CapHeight; - uint8_t serif_style = pclt_info->SerifStyle & 0x3F; - if (serif_style >= 2 && serif_style <= 6) + TT_PCLT* pcltTable; + TT_OS2* os2Table; + if ((pcltTable = (TT_PCLT*)FT_Get_Sfnt_Table(face, ft_sfnt_pclt)) != nullptr) { + info->fCapHeight = pcltTable->CapHeight; + uint8_t serif_style = pcltTable->SerifStyle & 0x3F; + if (2 <= serif_style && serif_style <= 6) { info->fStyle |= SkAdvancedTypefaceMetrics::kSerif_Style; - else if (serif_style >= 9 && serif_style <= 12) + } else if (9 <= serif_style && serif_style <= 12) { info->fStyle |= SkAdvancedTypefaceMetrics::kScript_Style; - } else if (((os2_table = (TT_OS2*)FT_Get_Sfnt_Table(face, ft_sfnt_os2)) != nullptr) && + } + } else if (((os2Table = (TT_OS2*)FT_Get_Sfnt_Table(face, ft_sfnt_os2)) != nullptr) && // sCapHeight is available only when version 2 or later. - os2_table->version != 0xFFFF && - os2_table->version >= 2) { - info->fCapHeight = os2_table->sCapHeight; + os2Table->version != 0xFFFF && + os2Table->version >= 2) + { + info->fCapHeight = os2Table->sCapHeight; } else { // Figure out a good guess for CapHeight: average the height of M and X. FT_BBox m_bbox, x_bbox; @@ -561,8 +559,7 @@ SkAdvancedTypefaceMetrics* SkTypeface_FreeType::onGetAdvancedTypefaceMetrics( got_m = GetLetterCBox(face, 'M', &m_bbox); got_x = GetLetterCBox(face, 'X', &x_bbox); if (got_m && got_x) { - info->fCapHeight = (m_bbox.yMax - m_bbox.yMin + x_bbox.yMax - - x_bbox.yMin) / 2; + info->fCapHeight = ((m_bbox.yMax - m_bbox.yMin) + (x_bbox.yMax - x_bbox.yMin)) / 2; } else if (got_m && !got_x) { info->fCapHeight = m_bbox.yMax - m_bbox.yMin; } else if (!got_m && got_x) { @@ -581,62 +578,33 @@ SkAdvancedTypefaceMetrics* SkTypeface_FreeType::onGetAdvancedTypefaceMetrics( } if (perGlyphInfo & kHAdvance_PerGlyphInfo) { - if (FT_IS_FIXED_WIDTH(face)) { - SkAdvancedTypefaceMetrics::WidthRange range(0); - int16_t advance = face->max_advance_width; - range.fAdvance.append(1, &advance); - SkAdvancedTypefaceMetrics::FinishRange( - &range, 0, SkAdvancedTypefaceMetrics::WidthRange::kDefault); - info->fGlyphWidths.emplace_back(std::move(range)); - } else if (!cid) { - SkAdvancedTypefaceMetrics::WidthRange range(0); - // So as to not blow out the stack, get advances in batches. - for (int gID = 0; gID < face->num_glyphs; gID += 128) { - FT_Fixed advances[128]; - int advanceCount = 128; - if (gID + advanceCount > face->num_glyphs) { - advanceCount = face->num_glyphs - gID; - } - FT_Get_Advances(face, gID, advanceCount, FT_LOAD_NO_SCALE, advances); - for (int i = 0; i < advanceCount; i++) { - int16_t advance = advances[i]; - range.fAdvance.append(1, &advance); + info->setGlyphWidths( + face->num_glyphs, + glyphIDs, + glyphIDsCount, + SkAdvancedTypefaceMetrics::GetAdvance([face](int gId, int16_t* data) { + FT_Fixed advance = 0; + if (FT_Get_Advances(face, gId, 1, FT_LOAD_NO_SCALE, &advance)) { + return false; } - } - SkAdvancedTypefaceMetrics::FinishRange( - &range, face->num_glyphs - 1, - SkAdvancedTypefaceMetrics::WidthRange::kRange); - info->fGlyphWidths.emplace_back(std::move(range)); - } else { - info->setGlyphWidths( - face->num_glyphs, - glyphIDs, - glyphIDsCount, - SkAdvancedTypefaceMetrics::GetAdvance([face](int gId, int16_t* data) { - FT_Fixed advance = 0; - if (FT_Get_Advances(face, gId, 1, FT_LOAD_NO_SCALE, &advance)) { - return false; - } - SkASSERT(data); - *data = advance; - return true; - }) - ); - } + SkASSERT(data); + *data = advance; + return true; + }) + ); } - if (perGlyphInfo & kVAdvance_PerGlyphInfo && - FT_HAS_VERTICAL(face)) { + if (perGlyphInfo & kVAdvance_PerGlyphInfo && FT_HAS_VERTICAL(face)) { SkASSERT(false); // Not implemented yet. } if (perGlyphInfo & kGlyphNames_PerGlyphInfo && - info->fType == SkAdvancedTypefaceMetrics::kType1_Font) { + info->fType == SkAdvancedTypefaceMetrics::kType1_Font) + { // Postscript fonts may contain more than 255 glyphs, so we end up // using multiple font descriptions with a glyph ordering. Record // the name of each glyph. - info->fGlyphNames.reset( - new SkAutoTArray<SkString>(face->num_glyphs)); + info->fGlyphNames.reset(new SkAutoTArray<SkString>(face->num_glyphs)); for (int gID = 0; gID < face->num_glyphs; gID++) { char glyphName[128]; // PS limit for names is 127 bytes. FT_Get_Glyph_Name(face, gID, glyphName, 128); @@ -645,8 +613,9 @@ SkAdvancedTypefaceMetrics* SkTypeface_FreeType::onGetAdvancedTypefaceMetrics( } if (perGlyphInfo & kToUnicode_PerGlyphInfo && - info->fType != SkAdvancedTypefaceMetrics::kType1_Font && - face->num_charmaps) { + info->fType != SkAdvancedTypefaceMetrics::kType1_Font && + face->num_charmaps) + { populate_glyph_to_unicode(face, &(info->fGlyphToUnicode)); } diff --git a/src/ports/SkFontHost_mac.cpp b/src/ports/SkFontHost_mac.cpp index 55eec33502..68668c248e 100644 --- a/src/ports/SkFontHost_mac.cpp +++ b/src/ports/SkFontHost_mac.cpp @@ -1610,29 +1610,21 @@ SkAdvancedTypefaceMetrics* SkTypeface_Mac::onGetAdvancedTypefaceMetrics( } if (perGlyphInfo & kHAdvance_PerGlyphInfo) { - if (info->fStyle & SkAdvancedTypefaceMetrics::kFixedPitch_Style) { - SkAdvancedTypefaceMetrics::WidthRange range(0); - range.fAdvance.append(1, &min_width); - SkAdvancedTypefaceMetrics::FinishRange( - &range, 0, SkAdvancedTypefaceMetrics::WidthRange::kDefault); - info->fGlyphWidths.emplace_back(std::move(range)); - } else { - CTFontRef borrowedCTFont = ctFont.get(); - info->setGlyphWidths( - SkToInt(glyphCount), - glyphIDs, - glyphIDsCount, - SkAdvancedTypefaceMetrics::GetAdvance([borrowedCTFont](int gId, int16_t* data) { - CGSize advance; - advance.width = 0; - CGGlyph glyph = gId; - CTFontGetAdvancesForGlyphs(borrowedCTFont, kCTFontHorizontalOrientation, - &glyph, &advance, 1); - *data = sk_float_round2int(advance.width); - return true; - }) - ); - } + CTFontRef borrowedCTFont = ctFont.get(); + info->setGlyphWidths( + SkToInt(glyphCount), + glyphIDs, + glyphIDsCount, + SkAdvancedTypefaceMetrics::GetAdvance([borrowedCTFont](int gId, int16_t* data) { + CGSize advance; + advance.width = 0; + CGGlyph glyph = gId; + CTFontGetAdvancesForGlyphs(borrowedCTFont, kCTFontHorizontalOrientation, + &glyph, &advance, 1); + *data = sk_float_round2int(advance.width); + return true; + }) + ); } return info; } diff --git a/src/ports/SkFontHost_win.cpp b/src/ports/SkFontHost_win.cpp index 34d05068f5..22262a5b71 100644 --- a/src/ports/SkFontHost_win.cpp +++ b/src/ports/SkFontHost_win.cpp @@ -1818,34 +1818,26 @@ SkAdvancedTypefaceMetrics* LogFontTypeface::onGetAdvancedTypefaceMetrics( } if (perGlyphInfo & kHAdvance_PerGlyphInfo) { - if (info->fStyle & SkAdvancedTypefaceMetrics::kFixedPitch_Style) { - SkAdvancedTypefaceMetrics::WidthRange range(0); - range.fAdvance.append(1, &min_width); - SkAdvancedTypefaceMetrics::FinishRange( - &range, 0, SkAdvancedTypefaceMetrics::WidthRange::kDefault); - info->fGlyphWidths.emplace_back(std::move(range)); - } else { - info->setGlyphWidths( - glyphCount, - glyphIDs, - glyphIDsCount, - SkAdvancedTypefaceMetrics::GetAdvance([hdc](int gId, int16_t* advance) { - // Initialize the MAT2 structure to - // the identify transformation matrix. - static const MAT2 mat2 = { - SkScalarToFIXED(1), SkScalarToFIXED(0), - SkScalarToFIXED(0), SkScalarToFIXED(1)}; - int flags = GGO_METRICS | GGO_GLYPH_INDEX; - GLYPHMETRICS gm; - if (GDI_ERROR == GetGlyphOutline(hdc, gId, flags, &gm, 0, nullptr, &mat2)) { - return false; - } - SkASSERT(advance); - *advance = gm.gmCellIncX; - return true; - }) - ); - } + info->setGlyphWidths( + glyphCount, + glyphIDs, + glyphIDsCount, + SkAdvancedTypefaceMetrics::GetAdvance([hdc](int gId, int16_t* advance) { + // Initialize the MAT2 structure to + // the identify transformation matrix. + static const MAT2 mat2 = { + SkScalarToFIXED(1), SkScalarToFIXED(0), + SkScalarToFIXED(0), SkScalarToFIXED(1)}; + int flags = GGO_METRICS | GGO_GLYPH_INDEX; + GLYPHMETRICS gm; + if (GDI_ERROR == GetGlyphOutline(hdc, gId, flags, &gm, 0, nullptr, &mat2)) { + return false; + } + SkASSERT(advance); + *advance = gm.gmCellIncX; + return true; + }) + ); } Error: |