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
851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#ifndef SkTypeface_win_dw_DEFINED
951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#define SkTypeface_win_dw_DEFINED
1051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
1151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#include "SkAdvancedTypefaceMetrics.h"
1251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#include "SkDWrite.h"
1351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#include "SkHRESULT.h"
144dbbd04314cc0606f8d3bafe515c97e52c180f73halcanary#include "SkLeanWindows.h"
1551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#include "SkTScopedComPtr.h"
1651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#include "SkTypeface.h"
1751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#include "SkTypefaceCache.h"
1851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
1951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#include <dwrite.h>
20e0c9e00cd5ed17a45a988b8b57fa9c09f3574921Ben Wagner#include <dwrite_1.h>
2122253064ceee1dd9fcd26b7d6d69505cba76bb33Ben Wagner#include <dwrite_2.h>
2251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
2351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanclass SkFontDescriptor;
2451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanstruct SkScalerContextRec;
2551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
26a4c4a2d8cd65abb1e5ac20813831cdb9ace6c7eebungemanstatic SkFontStyle get_style(IDWriteFont* font) {
27b4bb7d825566042ed64697be49457dbac060e6c4bungeman    int weight = font->GetWeight();
28b4bb7d825566042ed64697be49457dbac060e6c4bungeman    int width = font->GetStretch();
29b4bb7d825566042ed64697be49457dbac060e6c4bungeman    SkFontStyle::Slant slant = SkFontStyle::kUpright_Slant;
30b4bb7d825566042ed64697be49457dbac060e6c4bungeman    switch (font->GetStyle()) {
31b4bb7d825566042ed64697be49457dbac060e6c4bungeman        case DWRITE_FONT_STYLE_NORMAL: slant = SkFontStyle::kUpright_Slant; break;
32b4bb7d825566042ed64697be49457dbac060e6c4bungeman        case DWRITE_FONT_STYLE_OBLIQUE: slant = SkFontStyle::kOblique_Slant; break;
33b4bb7d825566042ed64697be49457dbac060e6c4bungeman        case DWRITE_FONT_STYLE_ITALIC: slant = SkFontStyle::kItalic_Slant; break;
34b4bb7d825566042ed64697be49457dbac060e6c4bungeman        default: SkASSERT(false); break;
35b4bb7d825566042ed64697be49457dbac060e6c4bungeman    }
36b4bb7d825566042ed64697be49457dbac060e6c4bungeman    return SkFontStyle(weight, width, slant);
3751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman}
3851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
3951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanclass DWriteFontTypeface : public SkTypeface {
4051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanprivate:
41e3aea10428d1597838fd563c92340beaf969a9b4bungeman    DWriteFontTypeface(const SkFontStyle& style,
4251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                       IDWriteFactory* factory,
4351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                       IDWriteFontFace* fontFace,
4451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                       IDWriteFont* font,
4551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                       IDWriteFontFamily* fontFamily,
4696fcdcc219d2a0d3579719b84b28bede76efba64halcanary                       IDWriteFontFileLoader* fontFileLoader = nullptr,
4796fcdcc219d2a0d3579719b84b28bede76efba64halcanary                       IDWriteFontCollectionLoader* fontCollectionLoader = nullptr)
48e3aea10428d1597838fd563c92340beaf969a9b4bungeman        : SkTypeface(style, false)
4951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        , fFactory(SkRefComPtr(factory))
5051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        , fDWriteFontCollectionLoader(SkSafeRefComPtr(fontCollectionLoader))
5151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        , fDWriteFontFileLoader(SkSafeRefComPtr(fontFileLoader))
5251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        , fDWriteFontFamily(SkRefComPtr(fontFamily))
5351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        , fDWriteFont(SkRefComPtr(font))
5451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        , fDWriteFontFace(SkRefComPtr(fontFace))
55f73c237291bb1fc698f688d8a9b1cdd23838ed18bungeman    {
56f73c237291bb1fc698f688d8a9b1cdd23838ed18bungeman        if (!SUCCEEDED(fDWriteFontFace->QueryInterface(&fDWriteFontFace1))) {
5796fcdcc219d2a0d3579719b84b28bede76efba64halcanary            // IUnknown::QueryInterface states that if it fails, punk will be set to nullptr.
58f73c237291bb1fc698f688d8a9b1cdd23838ed18bungeman            // http://blogs.msdn.com/b/oldnewthing/archive/2004/03/26/96777.aspx
59f2b340fc885ad2a12d2d73974eff9c8f4c94192cdjsollen            SkASSERT_RELEASE(nullptr == fDWriteFontFace1.get());
60f73c237291bb1fc698f688d8a9b1cdd23838ed18bungeman        }
6122253064ceee1dd9fcd26b7d6d69505cba76bb33Ben Wagner        if (!SUCCEEDED(fDWriteFontFace->QueryInterface(&fDWriteFontFace2))) {
6222253064ceee1dd9fcd26b7d6d69505cba76bb33Ben Wagner            SkASSERT_RELEASE(nullptr == fDWriteFontFace2.get());
6322253064ceee1dd9fcd26b7d6d69505cba76bb33Ben Wagner        }
6422253064ceee1dd9fcd26b7d6d69505cba76bb33Ben Wagner        if (!SUCCEEDED(fFactory->QueryInterface(&fFactory2))) {
6522253064ceee1dd9fcd26b7d6d69505cba76bb33Ben Wagner            SkASSERT_RELEASE(nullptr == fFactory2.get());
6622253064ceee1dd9fcd26b7d6d69505cba76bb33Ben Wagner        }
67f73c237291bb1fc698f688d8a9b1cdd23838ed18bungeman    }
6851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
6951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanpublic:
7051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    SkTScopedComPtr<IDWriteFactory> fFactory;
7122253064ceee1dd9fcd26b7d6d69505cba76bb33Ben Wagner    SkTScopedComPtr<IDWriteFactory2> fFactory2;
7251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    SkTScopedComPtr<IDWriteFontCollectionLoader> fDWriteFontCollectionLoader;
7351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    SkTScopedComPtr<IDWriteFontFileLoader> fDWriteFontFileLoader;
7451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    SkTScopedComPtr<IDWriteFontFamily> fDWriteFontFamily;
7551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    SkTScopedComPtr<IDWriteFont> fDWriteFont;
7651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    SkTScopedComPtr<IDWriteFontFace> fDWriteFontFace;
77f73c237291bb1fc698f688d8a9b1cdd23838ed18bungeman    SkTScopedComPtr<IDWriteFontFace1> fDWriteFontFace1;
7822253064ceee1dd9fcd26b7d6d69505cba76bb33Ben Wagner    SkTScopedComPtr<IDWriteFontFace2> fDWriteFontFace2;
7951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
8051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    static DWriteFontTypeface* Create(IDWriteFactory* factory,
8151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                                      IDWriteFontFace* fontFace,
8251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                                      IDWriteFont* font,
8351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                                      IDWriteFontFamily* fontFamily,
8496fcdcc219d2a0d3579719b84b28bede76efba64halcanary                                      IDWriteFontFileLoader* fontFileLoader = nullptr,
8596fcdcc219d2a0d3579719b84b28bede76efba64halcanary                                      IDWriteFontCollectionLoader* fontCollectionLoader = nullptr) {
86e3aea10428d1597838fd563c92340beaf969a9b4bungeman        return new DWriteFontTypeface(get_style(font), factory, fontFace, font, fontFamily,
87385fe4d4b62d7d1dd76116dd570df3290a2f487bhalcanary                                      fontFileLoader, fontCollectionLoader);
8851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
8951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
9051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanprotected:
9136352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void weak_dispose() const override {
9251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        if (fDWriteFontCollectionLoader.get()) {
9351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman            HRV(fFactory->UnregisterFontCollectionLoader(fDWriteFontCollectionLoader.get()));
9451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        }
9551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        if (fDWriteFontFileLoader.get()) {
9651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman            HRV(fFactory->UnregisterFontFileLoader(fDWriteFontFileLoader.get()));
9751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        }
9851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
9951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        //SkTypefaceCache::Remove(this);
10051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        INHERITED::weak_dispose();
10151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
10251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
10336352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    SkStreamAsset* onOpenStream(int* ttcIndex) const override;
104a9322c2d86aaef1085c267dfc43cf0747f170a86reed    SkScalerContext* onCreateScalerContext(const SkScalerContextEffects&,
105a9322c2d86aaef1085c267dfc43cf0747f170a86reed                                           const SkDescriptor*) const override;
10636352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void onFilterRec(SkScalerContextRec*) const override;
107209e4b1b70a5e9c2f504de15f038999ed9ee4ae5Hal Canary    std::unique_ptr<SkAdvancedTypefaceMetrics> onGetAdvancedMetrics() const override;
10836352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void onGetFontDescriptor(SkFontDescriptor*, bool*) const override;
109fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner    int onCharsToGlyphs(const void* chars, Encoding encoding,
110fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner                        uint16_t glyphs[], int glyphCount) const override;
11136352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    int onCountGlyphs() const override;
11236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    int onGetUPEM() const override;
11336352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void onGetFamilyName(SkString* familyName) const override;
11436352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const override;
115fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner    int onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[],
116fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner                                     int coordinateCount) const override
117fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner    {
118fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner        return -1;
119fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner    }
12036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    int onGetTableTags(SkFontTableTag tags[]) const override;
121fc497343cbcbd526f77da913ae2feca0e1b1b866Ben Wagner    size_t onGetTableData(SkFontTableTag, size_t offset, size_t length, void* data) const override;
12251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
12351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanprivate:
12451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    typedef SkTypeface INHERITED;
12551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman};
12651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
12751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#endif
128