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"
98f11d4dcafef4447fa68ea0ab28a72589241e9fdMike Klein#if defined(SK_BUILD_FOR_WIN)
101ee76510f5dbf632d30975fc3509ef4f609156d2mtklein
11df2ec358be78820550f334bc7224ae18e3d25390bungeman// SkTypes will include Windows.h, which will pull in all of the GDI defines.
12df2ec358be78820550f334bc7224ae18e3d25390bungeman// GDI #defines GetGlyphIndices to GetGlyphIndicesA or GetGlyphIndicesW, but
13df2ec358be78820550f334bc7224ae18e3d25390bungeman// IDWriteFontFace has a method called GetGlyphIndices. Since this file does
14df2ec358be78820550f334bc7224ae18e3d25390bungeman// not use GDI, undefing GetGlyphIndices makes things less confusing.
15df2ec358be78820550f334bc7224ae18e3d25390bungeman#undef GetGlyphIndices
16df2ec358be78820550f334bc7224ae18e3d25390bungeman
17b374d6a62c0259387d90cad74753d8bad9ee1beabungeman#include "SkDWrite.h"
1851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#include "SkDWriteFontFileStream.h"
1951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#include "SkFontDescriptor.h"
2051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#include "SkFontStream.h"
21f1bc5e8b78376e3b6509c8626623d3aae871daecBen Wagner#include "SkOTTable_fvar.h"
2251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#include "SkOTTable_head.h"
2351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#include "SkOTTable_hhea.h"
2451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#include "SkOTTable_OS_2.h"
2551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#include "SkOTTable_post.h"
26f05271581fc6204c2b7ccf146af5d02eec27e670bungeman#include "SkOTUtils.h"
2751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#include "SkScalerContext.h"
2851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#include "SkScalerContext_win_dw.h"
2951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#include "SkTypeface_win_dw.h"
3051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#include "SkUtils.h"
3151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
32b374d6a62c0259387d90cad74753d8bad9ee1beabungemanvoid DWriteFontTypeface::onGetFamilyName(SkString* familyName) const {
33b374d6a62c0259387d90cad74753d8bad9ee1beabungeman    SkTScopedComPtr<IDWriteLocalizedStrings> familyNames;
34b374d6a62c0259387d90cad74753d8bad9ee1beabungeman    HRV(fDWriteFontFamily->GetFamilyNames(&familyNames));
35b374d6a62c0259387d90cad74753d8bad9ee1beabungeman
3696fcdcc219d2a0d3579719b84b28bede76efba64halcanary    sk_get_locale_string(familyNames.get(), nullptr/*fMgr->fLocaleName.get()*/, familyName);
37b374d6a62c0259387d90cad74753d8bad9ee1beabungeman}
38b374d6a62c0259387d90cad74753d8bad9ee1beabungeman
3951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanvoid DWriteFontTypeface::onGetFontDescriptor(SkFontDescriptor* desc,
4051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                                             bool* isLocalStream) const {
4151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    // Get the family name.
425e7b4f967b37cc303a20b87617446605f26f1867bungeman    SkTScopedComPtr<IDWriteLocalizedStrings> familyNames;
435e7b4f967b37cc303a20b87617446605f26f1867bungeman    HRV(fDWriteFontFamily->GetFamilyNames(&familyNames));
4451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
4551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    SkString utf8FamilyName;
4696fcdcc219d2a0d3579719b84b28bede76efba64halcanary    sk_get_locale_string(familyNames.get(), nullptr/*fMgr->fLocaleName.get()*/, &utf8FamilyName);
4751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
4851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    desc->setFamilyName(utf8FamilyName.c_str());
49b8113780c3cfed640016b263194b7f1531d43312bungeman    desc->setStyle(this->fontStyle());
5051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    *isLocalStream = SkToBool(fDWriteFontFileLoader.get());
5151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman}
5251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
5351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanstatic SkUnichar next_utf8(const void** chars) {
5451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    return SkUTF8_NextUnichar((const char**)chars);
5551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman}
5651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
5751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanstatic SkUnichar next_utf16(const void** chars) {
5851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    return SkUTF16_NextUnichar((const uint16_t**)chars);
5951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman}
6051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
6151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanstatic SkUnichar next_utf32(const void** chars) {
6251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    const SkUnichar** uniChars = (const SkUnichar**)chars;
6351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    SkUnichar uni = **uniChars;
6451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    *uniChars += 1;
6551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    return uni;
6651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman}
6751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
6851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemantypedef SkUnichar (*EncodingProc)(const void**);
6951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
7051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanstatic EncodingProc find_encoding_proc(SkTypeface::Encoding enc) {
7151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    static const EncodingProc gProcs[] = {
7251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        next_utf8, next_utf16, next_utf32
7351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    };
7451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    SkASSERT((size_t)enc < SK_ARRAY_COUNT(gProcs));
7551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    return gProcs[enc];
7651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman}
7751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
7851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanint DWriteFontTypeface::onCharsToGlyphs(const void* chars, Encoding encoding,
7951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                                        uint16_t glyphs[], int glyphCount) const
8051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman{
8196fcdcc219d2a0d3579719b84b28bede76efba64halcanary    if (nullptr == glyphs) {
8251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        EncodingProc next_ucs4_proc = find_encoding_proc(encoding);
8351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        for (int i = 0; i < glyphCount; ++i) {
8451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman            const SkUnichar c = next_ucs4_proc(&chars);
8551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman            BOOL exists;
8651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman            fDWriteFont->HasCharacter(c, &exists);
8751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman            if (!exists) {
8851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                return i;
8951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman            }
9051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        }
9151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        return glyphCount;
9251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
9351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
9451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    switch (encoding) {
9551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    case SkTypeface::kUTF8_Encoding:
9651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    case SkTypeface::kUTF16_Encoding: {
9751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        static const int scratchCount = 256;
9851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        UINT32 scratch[scratchCount];
9951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        EncodingProc next_ucs4_proc = find_encoding_proc(encoding);
10051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        for (int baseGlyph = 0; baseGlyph < glyphCount; baseGlyph += scratchCount) {
10151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman            int glyphsLeft = glyphCount - baseGlyph;
10251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman            int limit = SkTMin(glyphsLeft, scratchCount);
10351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman            for (int i = 0; i < limit; ++i) {
10451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                scratch[i] = next_ucs4_proc(&chars);
10551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman            }
10651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman            fDWriteFontFace->GetGlyphIndices(scratch, limit, &glyphs[baseGlyph]);
10751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        }
10851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        break;
10951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
11051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    case SkTypeface::kUTF32_Encoding: {
11151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        const UINT32* utf32 = reinterpret_cast<const UINT32*>(chars);
11251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        fDWriteFontFace->GetGlyphIndices(utf32, glyphCount, glyphs);
11351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        break;
11451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
11551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    default:
116f2b340fc885ad2a12d2d73974eff9c8f4c94192cdjsollen        SK_ABORT("Invalid Text Encoding");
11751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
11851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
11951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    for (int i = 0; i < glyphCount; ++i) {
12051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        if (0 == glyphs[i]) {
12151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman            return i;
12251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        }
12351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
12451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    return glyphCount;
12551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman}
12651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
12751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanint DWriteFontTypeface::onCountGlyphs() const {
12851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    return fDWriteFontFace->GetGlyphCount();
12951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman}
13051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
13151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanint DWriteFontTypeface::onGetUPEM() const {
13251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    DWRITE_FONT_METRICS metrics;
13351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    fDWriteFontFace->GetMetrics(&metrics);
13451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    return metrics.designUnitsPerEm;
13551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman}
13651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
13751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanclass LocalizedStrings_IDWriteLocalizedStrings : public SkTypeface::LocalizedStrings {
13851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanpublic:
13951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    /** Takes ownership of the IDWriteLocalizedStrings. */
14051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    explicit LocalizedStrings_IDWriteLocalizedStrings(IDWriteLocalizedStrings* strings)
14151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        : fIndex(0), fStrings(strings)
14251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    { }
14351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
14436352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    bool next(SkTypeface::LocalizedString* localizedString) override {
14551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        if (fIndex >= fStrings->GetCount()) {
14651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman            return false;
14751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        }
14851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
14951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        // String
1505e7b4f967b37cc303a20b87617446605f26f1867bungeman        UINT32 stringLen;
1515e7b4f967b37cc303a20b87617446605f26f1867bungeman        HRBM(fStrings->GetStringLength(fIndex, &stringLen), "Could not get string length.");
15251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
1535e7b4f967b37cc303a20b87617446605f26f1867bungeman        SkSMallocWCHAR wString(stringLen+1);
1545e7b4f967b37cc303a20b87617446605f26f1867bungeman        HRBM(fStrings->GetString(fIndex, wString.get(), stringLen+1), "Could not get string.");
15551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
1565e7b4f967b37cc303a20b87617446605f26f1867bungeman        HRB(sk_wchar_to_skstring(wString.get(), stringLen, &localizedString->fString));
15751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
15851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        // Locale
1595e7b4f967b37cc303a20b87617446605f26f1867bungeman        UINT32 localeLen;
1605e7b4f967b37cc303a20b87617446605f26f1867bungeman        HRBM(fStrings->GetLocaleNameLength(fIndex, &localeLen), "Could not get locale length.");
16151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
1625e7b4f967b37cc303a20b87617446605f26f1867bungeman        SkSMallocWCHAR wLocale(localeLen+1);
1635e7b4f967b37cc303a20b87617446605f26f1867bungeman        HRBM(fStrings->GetLocaleName(fIndex, wLocale.get(), localeLen+1), "Could not get locale.");
16451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
1655e7b4f967b37cc303a20b87617446605f26f1867bungeman        HRB(sk_wchar_to_skstring(wLocale.get(), localeLen, &localizedString->fLanguage));
16651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
16751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        ++fIndex;
16851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        return true;
16951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
17051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
17151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanprivate:
17251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    UINT32 fIndex;
17351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    SkTScopedComPtr<IDWriteLocalizedStrings> fStrings;
17451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman};
17551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
17651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanSkTypeface::LocalizedStrings* DWriteFontTypeface::onCreateFamilyNameIterator() const {
177f05271581fc6204c2b7ccf146af5d02eec27e670bungeman    SkTypeface::LocalizedStrings* nameIter =
178f05271581fc6204c2b7ccf146af5d02eec27e670bungeman        SkOTUtils::LocalizedStrings_NameTable::CreateForFamilyNames(*this);
17996fcdcc219d2a0d3579719b84b28bede76efba64halcanary    if (nullptr == nameIter) {
180f05271581fc6204c2b7ccf146af5d02eec27e670bungeman        SkTScopedComPtr<IDWriteLocalizedStrings> familyNames;
181f05271581fc6204c2b7ccf146af5d02eec27e670bungeman        HRNM(fDWriteFontFamily->GetFamilyNames(&familyNames), "Could not obtain family names.");
182f05271581fc6204c2b7ccf146af5d02eec27e670bungeman        nameIter = new LocalizedStrings_IDWriteLocalizedStrings(familyNames.release());
183f05271581fc6204c2b7ccf146af5d02eec27e670bungeman    }
184f05271581fc6204c2b7ccf146af5d02eec27e670bungeman    return nameIter;
18551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman}
18651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
18751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanint DWriteFontTypeface::onGetTableTags(SkFontTableTag tags[]) const {
18851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    DWRITE_FONT_FACE_TYPE type = fDWriteFontFace->GetType();
18951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    if (type != DWRITE_FONT_FACE_TYPE_CFF &&
19051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        type != DWRITE_FONT_FACE_TYPE_TRUETYPE &&
19151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        type != DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION)
19251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    {
19351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        return 0;
19451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
19551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
19651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    int ttcIndex;
197145dbcd165d9d27298eb8888bc240e2d06a95464Ben Wagner    std::unique_ptr<SkStream> stream(this->openStream(&ttcIndex));
198145dbcd165d9d27298eb8888bc240e2d06a95464Ben Wagner    return stream.get() ? SkFontStream::GetTableTags(stream.get(), ttcIndex, tags) : 0;
19951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman}
20051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
20151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemansize_t DWriteFontTypeface::onGetTableData(SkFontTableTag tag, size_t offset,
20251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                                          size_t length, void* data) const
20351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman{
20451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    AutoDWriteTable table(fDWriteFontFace.get(), SkEndian_SwapBE32(tag));
20551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    if (!table.fExists) {
20651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        return 0;
20751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
20851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
20951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    if (offset > table.fSize) {
21051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        return 0;
21151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
21251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    size_t size = SkTMin(length, table.fSize - offset);
21349f085dddff10473b6ebf832a974288300224e60bsalomon    if (data) {
21451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        memcpy(data, table.fData + offset, size);
21551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
21651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
21751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    return size;
21851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman}
21951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
2205f213d9627d2eefa7da81cd97f36754f75eb4ae9bungemanSkStreamAsset* DWriteFontTypeface::onOpenStream(int* ttcIndex) const {
22151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    *ttcIndex = fDWriteFontFace->GetIndex();
22251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
22351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    UINT32 numFiles;
22496fcdcc219d2a0d3579719b84b28bede76efba64halcanary    HRNM(fDWriteFontFace->GetFiles(&numFiles, nullptr),
22551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman         "Could not get number of font files.");
22651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    if (numFiles != 1) {
22796fcdcc219d2a0d3579719b84b28bede76efba64halcanary        return nullptr;
22851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
22951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
23051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    SkTScopedComPtr<IDWriteFontFile> fontFile;
23151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    HRNM(fDWriteFontFace->GetFiles(&numFiles, &fontFile), "Could not get font files.");
23251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
23351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    const void* fontFileKey;
23451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    UINT32 fontFileKeySize;
23551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    HRNM(fontFile->GetReferenceKey(&fontFileKey, &fontFileKeySize),
23651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman         "Could not get font file reference key.");
23751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
23851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    SkTScopedComPtr<IDWriteFontFileLoader> fontFileLoader;
23951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    HRNM(fontFile->GetLoader(&fontFileLoader), "Could not get font file loader.");
24051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
24151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    SkTScopedComPtr<IDWriteFontFileStream> fontFileStream;
24251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    HRNM(fontFileLoader->CreateStreamFromKey(fontFileKey, fontFileKeySize,
24351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                                             &fontFileStream),
24451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman         "Could not create font file stream.");
24551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
246385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary    return new SkDWriteFontFileStream(fontFileStream.get());
24751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman}
24851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
249a9322c2d86aaef1085c267dfc43cf0747f170a86reedSkScalerContext* DWriteFontTypeface::onCreateScalerContext(const SkScalerContextEffects& effects,
250a9322c2d86aaef1085c267dfc43cf0747f170a86reed                                                           const SkDescriptor* desc) const {
2517cfd46aebda7b7d2b88e73621ed0d1be7244c2cabungeman    return new SkScalerContext_DW(sk_ref_sp(const_cast<DWriteFontTypeface*>(this)), effects, desc);
25251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman}
25351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
2543e45a2f48ed8dbf3a55e980c43d97d29afeb93a0Ben Wagnervoid DWriteFontTypeface::onFilterRec(SkScalerContextRec* rec) const {
25512f03121bb76214b71677ac0208d74c3c56c3b1fbungeman    if (rec->fFlags & SkScalerContext::kLCD_Vertical_Flag) {
25651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        rec->fMaskFormat = SkMask::kA8_Format;
25722253064ceee1dd9fcd26b7d6d69505cba76bb33Ben Wagner        rec->fFlags |= SkScalerContext::kGenA8FromLCD_Flag;
25851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
25951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
260410780677af260e32948b02c0725ef6ad761260cbungeman    unsigned flagsWeDontSupport = SkScalerContext::kVertical_Flag |
261410780677af260e32948b02c0725ef6ad761260cbungeman                                  SkScalerContext::kDevKernText_Flag |
26251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                                  SkScalerContext::kForceAutohinting_Flag |
26351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                                  SkScalerContext::kEmbolden_Flag |
26451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                                  SkScalerContext::kLCD_Vertical_Flag;
26551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    rec->fFlags &= ~flagsWeDontSupport;
26651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
26751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    SkPaint::Hinting h = rec->getHinting();
26822253064ceee1dd9fcd26b7d6d69505cba76bb33Ben Wagner    // DirectWrite2 allows for hinting to be turned off. Force everything else to normal.
26922253064ceee1dd9fcd26b7d6d69505cba76bb33Ben Wagner    if (h != SkPaint::kNo_Hinting || !fFactory2 || !fDWriteFontFace2) {
27022253064ceee1dd9fcd26b7d6d69505cba76bb33Ben Wagner        h = SkPaint::kNormal_Hinting;
27122253064ceee1dd9fcd26b7d6d69505cba76bb33Ben Wagner    }
27251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    rec->setHinting(h);
27351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
274b3ed65e53703221a7649571da17f0b54f5770073bungeman#if defined(SK_FONT_HOST_USE_SYSTEM_SETTINGS)
275b3ed65e53703221a7649571da17f0b54f5770073bungeman    IDWriteFactory* factory = sk_get_dwrite_factory();
27696fcdcc219d2a0d3579719b84b28bede76efba64halcanary    if (factory != nullptr) {
27751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        SkTScopedComPtr<IDWriteRenderingParams> defaultRenderingParams;
27851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        if (SUCCEEDED(factory->CreateRenderingParams(&defaultRenderingParams))) {
27951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman            float gamma = defaultRenderingParams->GetGamma();
28051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman            rec->setDeviceGamma(gamma);
28151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman            rec->setPaintGamma(gamma);
28251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
28351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman            rec->setContrast(defaultRenderingParams->GetEnhancedContrast());
28451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        }
28551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
28651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#endif
28751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman}
28851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
28951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman///////////////////////////////////////////////////////////////////////////////
29051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman//PDF Support
29151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
29251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman// Construct Glyph to Unicode table.
29351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman// Unicode code points that require conjugate pairs in utf16 are not
29451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman// supported.
29551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman// TODO(bungeman): This never does what anyone wants.
29651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman// What is really wanted is the text to glyphs mapping
29751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanstatic void populate_glyph_to_unicode(IDWriteFontFace* fontFace,
29851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                                      const unsigned glyphCount,
29951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                                      SkTDArray<SkUnichar>* glyphToUnicode) {
30051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    //Do this like free type instead
3013390cdfef8c0ad1f04810a4bb1e98a04e3d56a1aHal Canary    SkAutoTMalloc<SkUnichar> glyphToUni(
3023390cdfef8c0ad1f04810a4bb1e98a04e3d56a1aHal Canary            (SkUnichar*)sk_calloc_throw(sizeof(SkUnichar) * glyphCount));
303df2ec358be78820550f334bc7224ae18e3d25390bungeman    int maxGlyph = -1;
304266dcb05995e2c06544c4a1456264bd9b86180f8Hal Canary    unsigned remainingGlyphCount = glyphCount;
305266dcb05995e2c06544c4a1456264bd9b86180f8Hal Canary    for (UINT32 c = 0; c < 0x10FFFF && remainingGlyphCount != 0; ++c) {
306f7b54cda0d44cb1e7fd89586ff8ff3b78dfb823bwfh        UINT16 glyph = 0;
307f7b54cda0d44cb1e7fd89586ff8ff3b78dfb823bwfh        HRVM(fontFace->GetGlyphIndices(&c, 1, &glyph),
308f7b54cda0d44cb1e7fd89586ff8ff3b78dfb823bwfh             "Failed to get glyph index.");
309f7b54cda0d44cb1e7fd89586ff8ff3b78dfb823bwfh        // Intermittent DW bug on Windows 10. See crbug.com/470146.
310f7b54cda0d44cb1e7fd89586ff8ff3b78dfb823bwfh        if (glyph >= glyphCount) {
311f7b54cda0d44cb1e7fd89586ff8ff3b78dfb823bwfh          return;
312f7b54cda0d44cb1e7fd89586ff8ff3b78dfb823bwfh        }
313266dcb05995e2c06544c4a1456264bd9b86180f8Hal Canary        if (0 < glyph && glyphToUni[glyph] == 0) {
314df2ec358be78820550f334bc7224ae18e3d25390bungeman            maxGlyph = SkTMax(static_cast<int>(glyph), maxGlyph);
315266dcb05995e2c06544c4a1456264bd9b86180f8Hal Canary            glyphToUni[glyph] = c;  // Always use lowest-index unichar.
316266dcb05995e2c06544c4a1456264bd9b86180f8Hal Canary            --remainingGlyphCount;
31751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        }
31851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
319aace9976cddfa2f3e65f2ba263a5b66c7f0b923dbungeman    SkTDArray<SkUnichar>(glyphToUni, maxGlyph + 1).swap(*glyphToUnicode);
32051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman}
32151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
322209e4b1b70a5e9c2f504de15f038999ed9ee4ae5Hal Canarystd::unique_ptr<SkAdvancedTypefaceMetrics> DWriteFontTypeface::onGetAdvancedMetrics() const {
32351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
324209e4b1b70a5e9c2f504de15f038999ed9ee4ae5Hal Canary    std::unique_ptr<SkAdvancedTypefaceMetrics> info(nullptr);
32551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
32651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    HRESULT hr = S_OK;
32751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
32851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    const unsigned glyphCount = fDWriteFontFace->GetGlyphCount();
32951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
33051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    DWRITE_FONT_METRICS dwfm;
33151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    fDWriteFontFace->GetMetrics(&dwfm);
33251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
333209e4b1b70a5e9c2f504de15f038999ed9ee4ae5Hal Canary    info.reset(new SkAdvancedTypefaceMetrics);
33451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
3350b7758236ca81337aa465a9f61cf466f03718862bungeman    info->fAscent = SkToS16(dwfm.ascent);
3360b7758236ca81337aa465a9f61cf466f03718862bungeman    info->fDescent = SkToS16(dwfm.descent);
3370b7758236ca81337aa465a9f61cf466f03718862bungeman    info->fCapHeight = SkToS16(dwfm.capHeight);
3380b7758236ca81337aa465a9f61cf466f03718862bungeman
3396d867d494a0e619ebf445a7c0b8e35bb65d5f027bungeman    // SkAdvancedTypefaceMetrics::fFontName is in theory supposed to be
3406d867d494a0e619ebf445a7c0b8e35bb65d5f027bungeman    // the PostScript name of the font. However, due to the way it is currently
3416d867d494a0e619ebf445a7c0b8e35bb65d5f027bungeman    // used, it must actually be a family name.
34251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    SkTScopedComPtr<IDWriteLocalizedStrings> familyNames;
34351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    hr = fDWriteFontFamily->GetFamilyNames(&familyNames);
34451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
3455e7b4f967b37cc303a20b87617446605f26f1867bungeman    UINT32 familyNameLen;
3465e7b4f967b37cc303a20b87617446605f26f1867bungeman    hr = familyNames->GetStringLength(0, &familyNameLen);
34751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
3485e7b4f967b37cc303a20b87617446605f26f1867bungeman    SkSMallocWCHAR familyName(familyNameLen+1);
3495e7b4f967b37cc303a20b87617446605f26f1867bungeman    hr = familyNames->GetString(0, familyName.get(), familyNameLen+1);
35051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
3515e7b4f967b37cc303a20b87617446605f26f1867bungeman    hr = sk_wchar_to_skstring(familyName.get(), familyNameLen, &info->fFontName);
35251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
353209e4b1b70a5e9c2f504de15f038999ed9ee4ae5Hal Canary    populate_glyph_to_unicode(fDWriteFontFace.get(), glyphCount, &(info->fGlyphToUnicode));
35451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
35551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    DWRITE_FONT_FACE_TYPE fontType = fDWriteFontFace->GetType();
3560b7758236ca81337aa465a9f61cf466f03718862bungeman    if (fontType != DWRITE_FONT_FACE_TYPE_TRUETYPE &&
3570b7758236ca81337aa465a9f61cf466f03718862bungeman        fontType != DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION)
3580b7758236ca81337aa465a9f61cf466f03718862bungeman    {
35951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        return info;
36051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
36151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
3620b7758236ca81337aa465a9f61cf466f03718862bungeman    // Simulated fonts aren't really TrueType fonts.
3630b7758236ca81337aa465a9f61cf466f03718862bungeman    if (fDWriteFontFace->GetSimulations() == DWRITE_FONT_SIMULATIONS_NONE) {
3640b7758236ca81337aa465a9f61cf466f03718862bungeman        info->fType = SkAdvancedTypefaceMetrics::kTrueType_Font;
3650b7758236ca81337aa465a9f61cf466f03718862bungeman    }
3660b7758236ca81337aa465a9f61cf466f03718862bungeman
36751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    AutoTDWriteTable<SkOTTableHead> headTable(fDWriteFontFace.get());
36851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    AutoTDWriteTable<SkOTTablePostScript> postTable(fDWriteFontFace.get());
36951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    AutoTDWriteTable<SkOTTableHorizontalHeader> hheaTable(fDWriteFontFace.get());
37051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    AutoTDWriteTable<SkOTTableOS2> os2Table(fDWriteFontFace.get());
37151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    if (!headTable.fExists || !postTable.fExists || !hheaTable.fExists || !os2Table.fExists) {
37251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        return info;
37351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
37451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
375a865d25519b0805697c5809288dd2fb3f642c17dHal Canary    SkOTUtils::SetAdvancedTypefaceFlags(os2Table->version.v4.fsType, info.get());
3764a851ca334caac5e60606dbeb9ef6de77b34e24dHal Canary
377f1bc5e8b78376e3b6509c8626623d3aae871daecBen Wagner    // There are versions of DirectWrite which support named instances for system variation fonts,
378f1bc5e8b78376e3b6509c8626623d3aae871daecBen Wagner    // but no means to indicate that such a typeface is a variation.
379f1bc5e8b78376e3b6509c8626623d3aae871daecBen Wagner    AutoTDWriteTable<SkOTTableFontVariations> fvarTable(fDWriteFontFace.get());
380f1bc5e8b78376e3b6509c8626623d3aae871daecBen Wagner    if (fvarTable.fExists) {
381f1bc5e8b78376e3b6509c8626623d3aae871daecBen Wagner        info->fFlags |= SkAdvancedTypefaceMetrics::kMultiMaster_FontFlag;
382f1bc5e8b78376e3b6509c8626623d3aae871daecBen Wagner    }
383f1bc5e8b78376e3b6509c8626623d3aae871daecBen Wagner
38451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    //There exist CJK fonts which set the IsFixedPitch and Monospace bits,
38551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    //but have full width, latin half-width, and half-width kana.
38651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    bool fixedWidth = (postTable->isFixedPitch &&
38751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                      (1 == SkEndian_SwapBE16(hheaTable->numberOfHMetrics)));
38851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    //Monospace
38951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    if (fixedWidth) {
39051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        info->fStyle |= SkAdvancedTypefaceMetrics::kFixedPitch_Style;
39151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
39251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    //Italic
39351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    if (os2Table->version.v0.fsSelection.field.Italic) {
39451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        info->fStyle |= SkAdvancedTypefaceMetrics::kItalic_Style;
39551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
3964f81caf16995679adc05131823e209bf12844d3cbungeman    //Serif
3974f81caf16995679adc05131823e209bf12844d3cbungeman    using SerifStyle = SkPanose::Data::TextAndDisplay::SerifStyle;
3984f81caf16995679adc05131823e209bf12844d3cbungeman    SerifStyle serifStyle = os2Table->version.v0.panose.data.textAndDisplay.bSerifStyle;
3994f81caf16995679adc05131823e209bf12844d3cbungeman    if (SkPanose::FamilyType::TextAndDisplay == os2Table->version.v0.panose.bFamilyType) {
4004f81caf16995679adc05131823e209bf12844d3cbungeman        if (SerifStyle::Cove == serifStyle ||
4014f81caf16995679adc05131823e209bf12844d3cbungeman            SerifStyle::ObtuseCove == serifStyle ||
4024f81caf16995679adc05131823e209bf12844d3cbungeman            SerifStyle::SquareCove == serifStyle ||
4034f81caf16995679adc05131823e209bf12844d3cbungeman            SerifStyle::ObtuseSquareCove == serifStyle ||
4044f81caf16995679adc05131823e209bf12844d3cbungeman            SerifStyle::Square == serifStyle ||
4054f81caf16995679adc05131823e209bf12844d3cbungeman            SerifStyle::Thin == serifStyle ||
4064f81caf16995679adc05131823e209bf12844d3cbungeman            SerifStyle::Bone == serifStyle ||
4074f81caf16995679adc05131823e209bf12844d3cbungeman            SerifStyle::Exaggerated == serifStyle ||
4084f81caf16995679adc05131823e209bf12844d3cbungeman            SerifStyle::Triangle == serifStyle)
4094f81caf16995679adc05131823e209bf12844d3cbungeman        {
4104f81caf16995679adc05131823e209bf12844d3cbungeman            info->fStyle |= SkAdvancedTypefaceMetrics::kSerif_Style;
4114f81caf16995679adc05131823e209bf12844d3cbungeman        }
41251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    //Script
4134f81caf16995679adc05131823e209bf12844d3cbungeman    } else if (SkPanose::FamilyType::Script == os2Table->version.v0.panose.bFamilyType) {
41451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        info->fStyle |= SkAdvancedTypefaceMetrics::kScript_Style;
41551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
41651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
41751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    info->fItalicAngle = SkEndian_SwapBE32(postTable->italicAngle) >> 16;
41851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
41951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    info->fBBox = SkIRect::MakeLTRB((int32_t)SkEndian_SwapBE16((uint16_t)headTable->xMin),
42051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                                    (int32_t)SkEndian_SwapBE16((uint16_t)headTable->yMax),
42151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                                    (int32_t)SkEndian_SwapBE16((uint16_t)headTable->xMax),
42251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                                    (int32_t)SkEndian_SwapBE16((uint16_t)headTable->yMin));
42351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    return info;
42451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman}
4258f11d4dcafef4447fa68ea0ab28a72589241e9fdMike Klein#endif//defined(SK_BUILD_FOR_WIN)
426