151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman/*
251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman * Copyright 2014 Google Inc.
351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman *
451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman * Use of this source code is governed by a BSD-style license that can be
551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman * found in the LICENSE file.
651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman */
751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
8df2ec358be78820550f334bc7224ae18e3d25390bungeman#include "SkTypes.h"
9df2ec358be78820550f334bc7224ae18e3d25390bungeman// SkTypes will include Windows.h, which will pull in all of the GDI defines.
10df2ec358be78820550f334bc7224ae18e3d25390bungeman// GDI #defines GetGlyphIndices to GetGlyphIndicesA or GetGlyphIndicesW, but
11df2ec358be78820550f334bc7224ae18e3d25390bungeman// IDWriteFontFace has a method called GetGlyphIndices. Since this file does
12df2ec358be78820550f334bc7224ae18e3d25390bungeman// not use GDI, undefing GetGlyphIndices makes things less confusing.
13df2ec358be78820550f334bc7224ae18e3d25390bungeman#undef GetGlyphIndices
14df2ec358be78820550f334bc7224ae18e3d25390bungeman
15b374d6a62c0259387d90cad74753d8bad9ee1beabungeman#include "SkDWrite.h"
1651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#include "SkDWriteFontFileStream.h"
1751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#include "SkFontDescriptor.h"
1851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#include "SkFontStream.h"
1951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#include "SkOTTable_head.h"
2051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#include "SkOTTable_hhea.h"
2151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#include "SkOTTable_OS_2.h"
2251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#include "SkOTTable_post.h"
2351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#include "SkScalerContext.h"
2451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#include "SkScalerContext_win_dw.h"
2551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#include "SkTypeface_win_dw.h"
2651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#include "SkUtils.h"
2751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
28b374d6a62c0259387d90cad74753d8bad9ee1beabungemanvoid DWriteFontTypeface::onGetFamilyName(SkString* familyName) const {
29b374d6a62c0259387d90cad74753d8bad9ee1beabungeman    SkTScopedComPtr<IDWriteLocalizedStrings> familyNames;
30b374d6a62c0259387d90cad74753d8bad9ee1beabungeman    HRV(fDWriteFontFamily->GetFamilyNames(&familyNames));
31b374d6a62c0259387d90cad74753d8bad9ee1beabungeman
32b374d6a62c0259387d90cad74753d8bad9ee1beabungeman    sk_get_locale_string(familyNames.get(), NULL/*fMgr->fLocaleName.get()*/, familyName);
33b374d6a62c0259387d90cad74753d8bad9ee1beabungeman}
34b374d6a62c0259387d90cad74753d8bad9ee1beabungeman
3551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanvoid DWriteFontTypeface::onGetFontDescriptor(SkFontDescriptor* desc,
3651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                                             bool* isLocalStream) const {
3751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    // Get the family name.
385e7b4f967b37cc303a20b87617446605f26f1867bungeman    SkTScopedComPtr<IDWriteLocalizedStrings> familyNames;
395e7b4f967b37cc303a20b87617446605f26f1867bungeman    HRV(fDWriteFontFamily->GetFamilyNames(&familyNames));
4051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
4151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    SkString utf8FamilyName;
42b374d6a62c0259387d90cad74753d8bad9ee1beabungeman    sk_get_locale_string(familyNames.get(), NULL/*fMgr->fLocaleName.get()*/, &utf8FamilyName);
4351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
4451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    desc->setFamilyName(utf8FamilyName.c_str());
45d71b75757335393d9643a5b7a0f2769b6ba52fb6bungeman    desc->setFontIndex(fDWriteFontFace->GetIndex());
4651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    *isLocalStream = SkToBool(fDWriteFontFileLoader.get());
4751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman}
4851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
4951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanstatic SkUnichar next_utf8(const void** chars) {
5051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    return SkUTF8_NextUnichar((const char**)chars);
5151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman}
5251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
5351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanstatic SkUnichar next_utf16(const void** chars) {
5451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    return SkUTF16_NextUnichar((const uint16_t**)chars);
5551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman}
5651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
5751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanstatic SkUnichar next_utf32(const void** chars) {
5851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    const SkUnichar** uniChars = (const SkUnichar**)chars;
5951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    SkUnichar uni = **uniChars;
6051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    *uniChars += 1;
6151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    return uni;
6251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman}
6351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
6451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemantypedef SkUnichar (*EncodingProc)(const void**);
6551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
6651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanstatic EncodingProc find_encoding_proc(SkTypeface::Encoding enc) {
6751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    static const EncodingProc gProcs[] = {
6851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        next_utf8, next_utf16, next_utf32
6951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    };
7051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    SkASSERT((size_t)enc < SK_ARRAY_COUNT(gProcs));
7151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    return gProcs[enc];
7251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman}
7351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
7451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanint DWriteFontTypeface::onCharsToGlyphs(const void* chars, Encoding encoding,
7551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                                        uint16_t glyphs[], int glyphCount) const
7651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman{
7751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    if (NULL == glyphs) {
7851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        EncodingProc next_ucs4_proc = find_encoding_proc(encoding);
7951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        for (int i = 0; i < glyphCount; ++i) {
8051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman            const SkUnichar c = next_ucs4_proc(&chars);
8151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman            BOOL exists;
8251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman            fDWriteFont->HasCharacter(c, &exists);
8351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman            if (!exists) {
8451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                return i;
8551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman            }
8651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        }
8751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        return glyphCount;
8851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
8951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
9051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    switch (encoding) {
9151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    case SkTypeface::kUTF8_Encoding:
9251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    case SkTypeface::kUTF16_Encoding: {
9351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        static const int scratchCount = 256;
9451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        UINT32 scratch[scratchCount];
9551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        EncodingProc next_ucs4_proc = find_encoding_proc(encoding);
9651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        for (int baseGlyph = 0; baseGlyph < glyphCount; baseGlyph += scratchCount) {
9751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman            int glyphsLeft = glyphCount - baseGlyph;
9851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman            int limit = SkTMin(glyphsLeft, scratchCount);
9951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman            for (int i = 0; i < limit; ++i) {
10051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                scratch[i] = next_ucs4_proc(&chars);
10151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman            }
10251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman            fDWriteFontFace->GetGlyphIndices(scratch, limit, &glyphs[baseGlyph]);
10351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        }
10451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        break;
10551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
10651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    case SkTypeface::kUTF32_Encoding: {
10751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        const UINT32* utf32 = reinterpret_cast<const UINT32*>(chars);
10851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        fDWriteFontFace->GetGlyphIndices(utf32, glyphCount, glyphs);
10951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        break;
11051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
11151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    default:
11251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        SK_CRASH();
11351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
11451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
11551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    for (int i = 0; i < glyphCount; ++i) {
11651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        if (0 == glyphs[i]) {
11751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman            return i;
11851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        }
11951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
12051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    return glyphCount;
12151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman}
12251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
12351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanint DWriteFontTypeface::onCountGlyphs() const {
12451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    return fDWriteFontFace->GetGlyphCount();
12551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman}
12651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
12751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanint DWriteFontTypeface::onGetUPEM() const {
12851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    DWRITE_FONT_METRICS metrics;
12951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    fDWriteFontFace->GetMetrics(&metrics);
13051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    return metrics.designUnitsPerEm;
13151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman}
13251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
13351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanclass LocalizedStrings_IDWriteLocalizedStrings : public SkTypeface::LocalizedStrings {
13451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanpublic:
13551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    /** Takes ownership of the IDWriteLocalizedStrings. */
13651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    explicit LocalizedStrings_IDWriteLocalizedStrings(IDWriteLocalizedStrings* strings)
13751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        : fIndex(0), fStrings(strings)
13851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    { }
13951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
14051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    virtual bool next(SkTypeface::LocalizedString* localizedString) SK_OVERRIDE {
14151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        if (fIndex >= fStrings->GetCount()) {
14251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman            return false;
14351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        }
14451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
14551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        // String
1465e7b4f967b37cc303a20b87617446605f26f1867bungeman        UINT32 stringLen;
1475e7b4f967b37cc303a20b87617446605f26f1867bungeman        HRBM(fStrings->GetStringLength(fIndex, &stringLen), "Could not get string length.");
14851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
1495e7b4f967b37cc303a20b87617446605f26f1867bungeman        SkSMallocWCHAR wString(stringLen+1);
1505e7b4f967b37cc303a20b87617446605f26f1867bungeman        HRBM(fStrings->GetString(fIndex, wString.get(), stringLen+1), "Could not get string.");
15151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
1525e7b4f967b37cc303a20b87617446605f26f1867bungeman        HRB(sk_wchar_to_skstring(wString.get(), stringLen, &localizedString->fString));
15351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
15451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        // Locale
1555e7b4f967b37cc303a20b87617446605f26f1867bungeman        UINT32 localeLen;
1565e7b4f967b37cc303a20b87617446605f26f1867bungeman        HRBM(fStrings->GetLocaleNameLength(fIndex, &localeLen), "Could not get locale length.");
15751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
1585e7b4f967b37cc303a20b87617446605f26f1867bungeman        SkSMallocWCHAR wLocale(localeLen+1);
1595e7b4f967b37cc303a20b87617446605f26f1867bungeman        HRBM(fStrings->GetLocaleName(fIndex, wLocale.get(), localeLen+1), "Could not get locale.");
16051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
1615e7b4f967b37cc303a20b87617446605f26f1867bungeman        HRB(sk_wchar_to_skstring(wLocale.get(), localeLen, &localizedString->fLanguage));
16251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
16351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        ++fIndex;
16451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        return true;
16551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
16651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
16751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanprivate:
16851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    UINT32 fIndex;
16951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    SkTScopedComPtr<IDWriteLocalizedStrings> fStrings;
17051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman};
17151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
17251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanSkTypeface::LocalizedStrings* DWriteFontTypeface::onCreateFamilyNameIterator() const {
17351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    SkTScopedComPtr<IDWriteLocalizedStrings> familyNames;
17451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    HRNM(fDWriteFontFamily->GetFamilyNames(&familyNames), "Could not obtain family names.");
17551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
17651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    return new LocalizedStrings_IDWriteLocalizedStrings(familyNames.release());
17751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman}
17851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
17951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanint DWriteFontTypeface::onGetTableTags(SkFontTableTag tags[]) const {
18051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    DWRITE_FONT_FACE_TYPE type = fDWriteFontFace->GetType();
18151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    if (type != DWRITE_FONT_FACE_TYPE_CFF &&
18251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        type != DWRITE_FONT_FACE_TYPE_TRUETYPE &&
18351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        type != DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION)
18451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    {
18551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        return 0;
18651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
18751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
18851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    int ttcIndex;
18951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    SkAutoTUnref<SkStream> stream(this->openStream(&ttcIndex));
19051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    return stream.get() ? SkFontStream::GetTableTags(stream, ttcIndex, tags) : 0;
19151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman}
19251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
19351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemansize_t DWriteFontTypeface::onGetTableData(SkFontTableTag tag, size_t offset,
19451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                                          size_t length, void* data) const
19551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman{
19651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    AutoDWriteTable table(fDWriteFontFace.get(), SkEndian_SwapBE32(tag));
19751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    if (!table.fExists) {
19851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        return 0;
19951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
20051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
20151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    if (offset > table.fSize) {
20251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        return 0;
20351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
20451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    size_t size = SkTMin(length, table.fSize - offset);
20549f085dddff10473b6ebf832a974288300224e60bsalomon    if (data) {
20651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        memcpy(data, table.fData + offset, size);
20751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
20851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
20951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    return size;
21051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman}
21151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
21251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanSkStream* DWriteFontTypeface::onOpenStream(int* ttcIndex) const {
21351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    *ttcIndex = fDWriteFontFace->GetIndex();
21451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
21551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    UINT32 numFiles;
21651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    HRNM(fDWriteFontFace->GetFiles(&numFiles, NULL),
21751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman         "Could not get number of font files.");
21851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    if (numFiles != 1) {
21951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        return NULL;
22051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
22151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
22251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    SkTScopedComPtr<IDWriteFontFile> fontFile;
22351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    HRNM(fDWriteFontFace->GetFiles(&numFiles, &fontFile), "Could not get font files.");
22451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
22551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    const void* fontFileKey;
22651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    UINT32 fontFileKeySize;
22751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    HRNM(fontFile->GetReferenceKey(&fontFileKey, &fontFileKeySize),
22851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman         "Could not get font file reference key.");
22951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
23051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    SkTScopedComPtr<IDWriteFontFileLoader> fontFileLoader;
23151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    HRNM(fontFile->GetLoader(&fontFileLoader), "Could not get font file loader.");
23251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
23351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    SkTScopedComPtr<IDWriteFontFileStream> fontFileStream;
23451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    HRNM(fontFileLoader->CreateStreamFromKey(fontFileKey, fontFileKeySize,
23551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                                             &fontFileStream),
23651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman         "Could not create font file stream.");
23751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
23851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    return SkNEW_ARGS(SkDWriteFontFileStream, (fontFileStream.get()));
23951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman}
24051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
24151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanSkScalerContext* DWriteFontTypeface::onCreateScalerContext(const SkDescriptor* desc) const {
24251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    return SkNEW_ARGS(SkScalerContext_DW, (const_cast<DWriteFontTypeface*>(this), desc));
24351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman}
24451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
24551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanvoid DWriteFontTypeface::onFilterRec(SkScalerContext::Rec* rec) const {
24651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    if (rec->fFlags & SkScalerContext::kLCD_BGROrder_Flag ||
24751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        rec->fFlags & SkScalerContext::kLCD_Vertical_Flag)
24851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    {
24951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        rec->fMaskFormat = SkMask::kA8_Format;
25051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
25151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
252410780677af260e32948b02c0725ef6ad761260cbungeman    unsigned flagsWeDontSupport = SkScalerContext::kVertical_Flag |
253410780677af260e32948b02c0725ef6ad761260cbungeman                                  SkScalerContext::kDevKernText_Flag |
25451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                                  SkScalerContext::kForceAutohinting_Flag |
25551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                                  SkScalerContext::kEmbolden_Flag |
25651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                                  SkScalerContext::kLCD_BGROrder_Flag |
25751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                                  SkScalerContext::kLCD_Vertical_Flag;
25851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    rec->fFlags &= ~flagsWeDontSupport;
25951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
26051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    SkPaint::Hinting h = rec->getHinting();
26151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    // DirectWrite does not provide for hinting hints.
26251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    h = SkPaint::kSlight_Hinting;
26351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    rec->setHinting(h);
26451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
26551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#if SK_FONT_HOST_USE_SYSTEM_SETTINGS
26651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    IDWriteFactory* factory = get_dwrite_factory();
26751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    if (factory != NULL) {
26851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        SkTScopedComPtr<IDWriteRenderingParams> defaultRenderingParams;
26951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        if (SUCCEEDED(factory->CreateRenderingParams(&defaultRenderingParams))) {
27051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman            float gamma = defaultRenderingParams->GetGamma();
27151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman            rec->setDeviceGamma(gamma);
27251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman            rec->setPaintGamma(gamma);
27351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
27451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman            rec->setContrast(defaultRenderingParams->GetEnhancedContrast());
27551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        }
27651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
27751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#endif
27851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman}
27951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
28051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman///////////////////////////////////////////////////////////////////////////////
28151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman//PDF Support
28251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
28351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanusing namespace skia_advanced_typeface_metrics_utils;
28451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
28551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman// Construct Glyph to Unicode table.
28651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman// Unicode code points that require conjugate pairs in utf16 are not
28751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman// supported.
28851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman// TODO(bungeman): This never does what anyone wants.
28951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman// What is really wanted is the text to glyphs mapping
29051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanstatic void populate_glyph_to_unicode(IDWriteFontFace* fontFace,
29151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                                      const unsigned glyphCount,
29251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                                      SkTDArray<SkUnichar>* glyphToUnicode) {
29351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    HRESULT hr = S_OK;
29451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
29551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    //Do this like free type instead
296df2ec358be78820550f334bc7224ae18e3d25390bungeman    SkAutoTMalloc<SkUnichar> glyphToUni(glyphCount);
297df2ec358be78820550f334bc7224ae18e3d25390bungeman    int maxGlyph = -1;
29851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    for (UINT32 c = 0; c < 0x10FFFF; ++c) {
29951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        UINT16 glyph;
30051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        hr = fontFace->GetGlyphIndices(&c, 1, &glyph);
301df2ec358be78820550f334bc7224ae18e3d25390bungeman        SkASSERT(glyph < glyphCount);
302df2ec358be78820550f334bc7224ae18e3d25390bungeman        if (0 < glyph) {
303df2ec358be78820550f334bc7224ae18e3d25390bungeman            maxGlyph = SkTMax(static_cast<int>(glyph), maxGlyph);
304df2ec358be78820550f334bc7224ae18e3d25390bungeman            glyphToUni[glyph] = c;
30551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        }
30651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
30751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
308aace9976cddfa2f3e65f2ba263a5b66c7f0b923dbungeman    SkTDArray<SkUnichar>(glyphToUni, maxGlyph + 1).swap(*glyphToUnicode);
30951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman}
31051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
31151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanstatic bool getWidthAdvance(IDWriteFontFace* fontFace, int gId, int16_t* advance) {
31251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    SkASSERT(advance);
31351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
31451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    UINT16 glyphId = gId;
31551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    DWRITE_GLYPH_METRICS gm;
31651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    HRESULT hr = fontFace->GetDesignGlyphMetrics(&glyphId, 1, &gm);
31751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
31851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    if (FAILED(hr)) {
31951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        *advance = 0;
32051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        return false;
32151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
32251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
32351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    *advance = gm.advanceWidth;
32451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    return true;
32551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman}
32651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
32751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanSkAdvancedTypefaceMetrics* DWriteFontTypeface::onGetAdvancedTypefaceMetrics(
32851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo,
32951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        const uint32_t* glyphIDs,
33051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        uint32_t glyphIDsCount) const {
33151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
33251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    SkAdvancedTypefaceMetrics* info = NULL;
33351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
33451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    HRESULT hr = S_OK;
33551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
33651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    const unsigned glyphCount = fDWriteFontFace->GetGlyphCount();
33751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
33851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    DWRITE_FONT_METRICS dwfm;
33951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    fDWriteFontFace->GetMetrics(&dwfm);
34051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
34151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    info = new SkAdvancedTypefaceMetrics;
34251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    info->fEmSize = dwfm.designUnitsPerEm;
34351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    info->fLastGlyphID = SkToU16(glyphCount - 1);
34451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    info->fStyle = 0;
3450f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo    info->fFlags = SkAdvancedTypefaceMetrics::kEmpty_FontFlag;
34651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
3476d867d494a0e619ebf445a7c0b8e35bb65d5f027bungeman    // SkAdvancedTypefaceMetrics::fFontName is in theory supposed to be
3486d867d494a0e619ebf445a7c0b8e35bb65d5f027bungeman    // the PostScript name of the font. However, due to the way it is currently
3496d867d494a0e619ebf445a7c0b8e35bb65d5f027bungeman    // used, it must actually be a family name.
35051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    SkTScopedComPtr<IDWriteLocalizedStrings> familyNames;
35151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    hr = fDWriteFontFamily->GetFamilyNames(&familyNames);
35251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
3535e7b4f967b37cc303a20b87617446605f26f1867bungeman    UINT32 familyNameLen;
3545e7b4f967b37cc303a20b87617446605f26f1867bungeman    hr = familyNames->GetStringLength(0, &familyNameLen);
35551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
3565e7b4f967b37cc303a20b87617446605f26f1867bungeman    SkSMallocWCHAR familyName(familyNameLen+1);
3575e7b4f967b37cc303a20b87617446605f26f1867bungeman    hr = familyNames->GetString(0, familyName.get(), familyNameLen+1);
35851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
3595e7b4f967b37cc303a20b87617446605f26f1867bungeman    hr = sk_wchar_to_skstring(familyName.get(), familyNameLen, &info->fFontName);
36051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
36151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    if (perGlyphInfo & SkAdvancedTypefaceMetrics::kToUnicode_PerGlyphInfo) {
36251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        populate_glyph_to_unicode(fDWriteFontFace.get(), glyphCount, &(info->fGlyphToUnicode));
36351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
36451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
36551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    DWRITE_FONT_FACE_TYPE fontType = fDWriteFontFace->GetType();
36651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    if (fontType == DWRITE_FONT_FACE_TYPE_TRUETYPE ||
36751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        fontType == DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION) {
36851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        info->fType = SkAdvancedTypefaceMetrics::kTrueType_Font;
36951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    } else {
37051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        info->fType = SkAdvancedTypefaceMetrics::kOther_Font;
37151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        info->fItalicAngle = 0;
37251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        info->fAscent = dwfm.ascent;;
37351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        info->fDescent = dwfm.descent;
37451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        info->fStemV = 0;
37551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        info->fCapHeight = dwfm.capHeight;
37651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        info->fBBox = SkIRect::MakeEmpty();
37751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        return info;
37851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
37951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
38051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    AutoTDWriteTable<SkOTTableHead> headTable(fDWriteFontFace.get());
38151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    AutoTDWriteTable<SkOTTablePostScript> postTable(fDWriteFontFace.get());
38251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    AutoTDWriteTable<SkOTTableHorizontalHeader> hheaTable(fDWriteFontFace.get());
38351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    AutoTDWriteTable<SkOTTableOS2> os2Table(fDWriteFontFace.get());
38451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    if (!headTable.fExists || !postTable.fExists || !hheaTable.fExists || !os2Table.fExists) {
38551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        info->fItalicAngle = 0;
38651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        info->fAscent = dwfm.ascent;;
38751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        info->fDescent = dwfm.descent;
38851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        info->fStemV = 0;
38951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        info->fCapHeight = dwfm.capHeight;
39051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        info->fBBox = SkIRect::MakeEmpty();
39151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        return info;
39251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
39351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
39451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    //There exist CJK fonts which set the IsFixedPitch and Monospace bits,
39551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    //but have full width, latin half-width, and half-width kana.
39651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    bool fixedWidth = (postTable->isFixedPitch &&
39751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                      (1 == SkEndian_SwapBE16(hheaTable->numberOfHMetrics)));
39851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    //Monospace
39951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    if (fixedWidth) {
40051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        info->fStyle |= SkAdvancedTypefaceMetrics::kFixedPitch_Style;
40151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
40251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    //Italic
40351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    if (os2Table->version.v0.fsSelection.field.Italic) {
40451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        info->fStyle |= SkAdvancedTypefaceMetrics::kItalic_Style;
40551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
40651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    //Script
40751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    if (SkPanose::FamilyType::Script == os2Table->version.v0.panose.bFamilyType.value) {
40851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        info->fStyle |= SkAdvancedTypefaceMetrics::kScript_Style;
40951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    //Serif
41051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    } else if (SkPanose::FamilyType::TextAndDisplay == os2Table->version.v0.panose.bFamilyType.value &&
41151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman               SkPanose::Data::TextAndDisplay::SerifStyle::Triangle <= os2Table->version.v0.panose.data.textAndDisplay.bSerifStyle.value &&
41251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman               SkPanose::Data::TextAndDisplay::SerifStyle::NoFit != os2Table->version.v0.panose.data.textAndDisplay.bSerifStyle.value) {
41351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        info->fStyle |= SkAdvancedTypefaceMetrics::kSerif_Style;
41451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
41551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
41651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    info->fItalicAngle = SkEndian_SwapBE32(postTable->italicAngle) >> 16;
41751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
41851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    info->fAscent = SkToS16(dwfm.ascent);
41951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    info->fDescent = SkToS16(dwfm.descent);
42051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    info->fCapHeight = SkToS16(dwfm.capHeight);
42151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
42251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    info->fBBox = SkIRect::MakeLTRB((int32_t)SkEndian_SwapBE16((uint16_t)headTable->xMin),
42351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                                    (int32_t)SkEndian_SwapBE16((uint16_t)headTable->yMax),
42451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                                    (int32_t)SkEndian_SwapBE16((uint16_t)headTable->xMax),
42551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                                    (int32_t)SkEndian_SwapBE16((uint16_t)headTable->yMin));
42651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
42751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    //TODO: is this even desired? It seems PDF only wants this value for Type1
42851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    //fonts, and we only get here for TrueType fonts.
42951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    info->fStemV = 0;
43051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    /*
43151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    // Figure out a good guess for StemV - Min width of i, I, !, 1.
43251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    // This probably isn't very good with an italic font.
43351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    int16_t min_width = SHRT_MAX;
43451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    info->fStemV = 0;
43551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    char stem_chars[] = {'i', 'I', '!', '1'};
43651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    for (size_t i = 0; i < SK_ARRAY_COUNT(stem_chars); i++) {
43751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        ABC abcWidths;
43851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        if (GetCharABCWidths(hdc, stem_chars[i], stem_chars[i], &abcWidths)) {
43951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman            int16_t width = abcWidths.abcB;
44051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman            if (width > 0 && width < min_width) {
44151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                min_width = width;
44251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                info->fStemV = min_width;
44351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman            }
44451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        }
44551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
44651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    */
44751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
4480f9bad01b0e7ad592ffb342dcf1d238b15329be1vandebo    if (perGlyphInfo & SkAdvancedTypefaceMetrics::kHAdvance_PerGlyphInfo) {
44951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        if (fixedWidth) {
45051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman            appendRange(&info->fGlyphWidths, 0);
45151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman            int16_t advance;
45251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman            getWidthAdvance(fDWriteFontFace.get(), 1, &advance);
45351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman            info->fGlyphWidths->fAdvance.append(1, &advance);
45451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman            finishRange(info->fGlyphWidths.get(), 0,
45551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                        SkAdvancedTypefaceMetrics::WidthRange::kDefault);
45651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        } else {
45751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman            info->fGlyphWidths.reset(
45851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                getAdvanceData(fDWriteFontFace.get(),
45951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                               glyphCount,
46051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                               glyphIDs,
46151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                               glyphIDsCount,
46251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                               getWidthAdvance));
46351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        }
46451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
46551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
46651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    return info;
46751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman}
468