int FontPlatformData::emSizeInFontUnits() const
{
    if (m_emSizeInFontUnits)
        return m_emSizeInFontUnits;

    SkAdvancedTypefaceMetrics* metrics = m_typeface->getAdvancedTypefaceMetrics(SkAdvancedTypefaceMetrics::kNo_PerGlyphInfo);
    m_emSizeInFontUnits = metrics->fEmSize;
    metrics->unref();
    return m_emSizeInFontUnits;
}
示例#2
0
int FontPlatformData::emSizeInFontUnits() const
{
    if (mEmSizeInFontUnits)
        return mEmSizeInFontUnits;

    SkAdvancedTypefaceMetrics* metrics = 0;
    if (mTypeface)
        metrics = mTypeface->getAdvancedTypefaceMetrics(SkAdvancedTypefaceMetrics::kNo_PerGlyphInfo);
    if (metrics) {
        mEmSizeInFontUnits = metrics->fEmSize;
        metrics->unref();
    } else
        mEmSizeInFontUnits = 1000;  // default value copied from Skia.
    return mEmSizeInFontUnits;
}
示例#3
0
    void runTest(skiatest::Reporter* reporter) {
        SkAdvancedTypefaceMetrics metrics;
        metrics.setGlyphWidths(
                fAdvancesLen, fSubset, fSubsetLen,
                std::function<bool(int, int16_t*)>([this](int gId, int16_t* advance) {
                            if (gId >= 0 && gId < fAdvancesLen) {
                                *advance = fAdvances[gId];
                                return true;
                            }
                            return false;
                        }));

        SkString stringResult = stringify_advance_data(metrics.fGlyphWidths);
        if (!stringResult.equals(fExpected)) {
            ERRORF(reporter, "Expected: %s\n  Result: %s\n", fExpected, stringResult.c_str());
        }
    }
int FontPlatformData::emSizeInFontUnits() const
{
    if (m_emSizeInFontUnits)
        return m_emSizeInFontUnits;

    // FIXME: Switch to the SkTypeface::GetUnitsPerEm API once this becomes available.
    // https://bugs.webkit.org/show_bug.cgi?id=75961
#if OS(ANDROID)
    // Android doesn't currently support Skia's getAdvancedTypefaceMetrics(),
    // but it has access to another method to replace this functionality.
    m_emSizeInFontUnits = SkFontHost::GetUnitsPerEm(m_typeface->uniqueID());
#else
    SkAdvancedTypefaceMetrics* metrics = m_typeface->getAdvancedTypefaceMetrics(SkAdvancedTypefaceMetrics::kNo_PerGlyphInfo);
    m_emSizeInFontUnits = metrics->fEmSize;
    metrics->unref();
#endif
    return m_emSizeInFontUnits;
}
示例#5
0
SkAdvancedTypefaceMetrics* DWriteFontTypeface::onGetAdvancedTypefaceMetrics(
        PerGlyphInfo perGlyphInfo,
        const uint32_t* glyphIDs,
        uint32_t glyphIDsCount) const {

    SkAdvancedTypefaceMetrics* info = nullptr;

    HRESULT hr = S_OK;

    const unsigned glyphCount = fDWriteFontFace->GetGlyphCount();

    DWRITE_FONT_METRICS dwfm;
    fDWriteFontFace->GetMetrics(&dwfm);

    info = new SkAdvancedTypefaceMetrics;
    info->fEmSize = dwfm.designUnitsPerEm;
    info->fLastGlyphID = SkToU16(glyphCount - 1);

    // SkAdvancedTypefaceMetrics::fFontName is in theory supposed to be
    // the PostScript name of the font. However, due to the way it is currently
    // used, it must actually be a family name.
    SkTScopedComPtr<IDWriteLocalizedStrings> familyNames;
    hr = fDWriteFontFamily->GetFamilyNames(&familyNames);

    UINT32 familyNameLen;
    hr = familyNames->GetStringLength(0, &familyNameLen);

    SkSMallocWCHAR familyName(familyNameLen+1);
    hr = familyNames->GetString(0, familyName.get(), familyNameLen+1);

    hr = sk_wchar_to_skstring(familyName.get(), familyNameLen, &info->fFontName);

    if (perGlyphInfo & kToUnicode_PerGlyphInfo) {
        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) {
        info->fType = SkAdvancedTypefaceMetrics::kTrueType_Font;
    } else {
        info->fAscent = dwfm.ascent;
        info->fDescent = dwfm.descent;
        info->fCapHeight = dwfm.capHeight;
        return info;
    }

    AutoTDWriteTable<SkOTTableHead> headTable(fDWriteFontFace.get());
    AutoTDWriteTable<SkOTTablePostScript> postTable(fDWriteFontFace.get());
    AutoTDWriteTable<SkOTTableHorizontalHeader> hheaTable(fDWriteFontFace.get());
    AutoTDWriteTable<SkOTTableOS2> os2Table(fDWriteFontFace.get());
    if (!headTable.fExists || !postTable.fExists || !hheaTable.fExists || !os2Table.fExists) {
        info->fAscent = dwfm.ascent;
        info->fDescent = dwfm.descent;
        info->fCapHeight = dwfm.capHeight;
        return info;
    }

    //There exist CJK fonts which set the IsFixedPitch and Monospace bits,
    //but have full width, latin half-width, and half-width kana.
    bool fixedWidth = (postTable->isFixedPitch &&
                      (1 == SkEndian_SwapBE16(hheaTable->numberOfHMetrics)));
    //Monospace
    if (fixedWidth) {
        info->fStyle |= SkAdvancedTypefaceMetrics::kFixedPitch_Style;
    }
    //Italic
    if (os2Table->version.v0.fsSelection.field.Italic) {
        info->fStyle |= SkAdvancedTypefaceMetrics::kItalic_Style;
    }
    //Script
    if (SkPanose::FamilyType::Script == os2Table->version.v0.panose.bFamilyType.value) {
        info->fStyle |= SkAdvancedTypefaceMetrics::kScript_Style;
    //Serif
    } else if (SkPanose::FamilyType::TextAndDisplay == os2Table->version.v0.panose.bFamilyType.value &&
               SkPanose::Data::TextAndDisplay::SerifStyle::Triangle <= os2Table->version.v0.panose.data.textAndDisplay.bSerifStyle.value &&
               SkPanose::Data::TextAndDisplay::SerifStyle::NoFit != os2Table->version.v0.panose.data.textAndDisplay.bSerifStyle.value) {
        info->fStyle |= SkAdvancedTypefaceMetrics::kSerif_Style;
    }

    info->fItalicAngle = SkEndian_SwapBE32(postTable->italicAngle) >> 16;

    info->fAscent = SkToS16(dwfm.ascent);
    info->fDescent = SkToS16(dwfm.descent);
    info->fCapHeight = SkToS16(dwfm.capHeight);

    info->fBBox = SkIRect::MakeLTRB((int32_t)SkEndian_SwapBE16((uint16_t)headTable->xMin),
                                    (int32_t)SkEndian_SwapBE16((uint16_t)headTable->yMax),
                                    (int32_t)SkEndian_SwapBE16((uint16_t)headTable->xMax),
                                    (int32_t)SkEndian_SwapBE16((uint16_t)headTable->yMin));

    //TODO: is this even desired? It seems PDF only wants this value for Type1
    //fonts, and we only get here for TrueType fonts.
    info->fStemV = 0;
    /*
    // Figure out a good guess for StemV - Min width of i, I, !, 1.
    // This probably isn't very good with an italic font.
    int16_t min_width = SHRT_MAX;
    info->fStemV = 0;
    char stem_chars[] = {'i', 'I', '!', '1'};
    for (size_t i = 0; i < SK_ARRAY_COUNT(stem_chars); i++) {
        ABC abcWidths;
        if (GetCharABCWidths(hdc, stem_chars[i], stem_chars[i], &abcWidths)) {
            int16_t width = abcWidths.abcB;
            if (width > 0 && width < min_width) {
                min_width = width;
                info->fStemV = min_width;
            }
        }
    }
    */

    if (perGlyphInfo & kHAdvance_PerGlyphInfo) {
        if (fixedWidth) {
            SkAdvancedTypefaceMetrics::WidthRange range(0);
            int16_t advance;
            getWidthAdvance(fDWriteFontFace.get(), 1, &advance);
            range.fAdvance.append(1, &advance);
            SkAdvancedTypefaceMetrics::FinishRange(
                    &range, 0, SkAdvancedTypefaceMetrics::WidthRange::kDefault);
            info->fGlyphWidths.emplace_back(std::move(range));
        } else {
            IDWriteFontFace* borrowedFontFace = fDWriteFontFace.get();
            info->setGlyphWidths(
                glyphCount,
                glyphIDs,
                glyphIDsCount,
                SkAdvancedTypefaceMetrics::GetAdvance([borrowedFontFace](int gId, int16_t* data) {
                    return getWidthAdvance(borrowedFontFace, gId, data);
                })
            );
        }
    }

    return info;
}