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"
1451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#include "SkTScopedComPtr.h"
1551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#include "SkTypeface.h"
1651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#include "SkTypefaceCache.h"
1751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#include "SkTypes.h"
1851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
1951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#include <dwrite.h>
20f548444684b9c96f7717aebe645944af4f95d650bungeman#if SK_HAS_DWRITE_1_H
21f548444684b9c96f7717aebe645944af4f95d650bungeman#  include <dwrite_1.h>
22f548444684b9c96f7717aebe645944af4f95d650bungeman#endif
2351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
2451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanclass SkFontDescriptor;
2551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanstruct SkScalerContextRec;
2651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
2751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanstatic SkTypeface::Style get_style(IDWriteFont* font) {
2851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    int style = SkTypeface::kNormal;
2951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    DWRITE_FONT_WEIGHT weight = font->GetWeight();
3051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    if (DWRITE_FONT_WEIGHT_DEMI_BOLD <= weight) {
3151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        style |= SkTypeface::kBold;
3251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
3351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    DWRITE_FONT_STYLE angle = font->GetStyle();
3451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    if (DWRITE_FONT_STYLE_OBLIQUE == angle || DWRITE_FONT_STYLE_ITALIC == angle) {
3551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        style |= SkTypeface::kItalic;
3651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
3751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    return static_cast<SkTypeface::Style>(style);
3851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman}
3951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
4051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanclass DWriteFontTypeface : public SkTypeface {
4151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanprivate:
4251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    DWriteFontTypeface(SkTypeface::Style style, SkFontID fontID,
4351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                       IDWriteFactory* factory,
4451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                       IDWriteFontFace* fontFace,
4551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                       IDWriteFont* font,
4651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                       IDWriteFontFamily* fontFamily,
4751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                       IDWriteFontFileLoader* fontFileLoader = NULL,
4851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                       IDWriteFontCollectionLoader* fontCollectionLoader = NULL)
4951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        : SkTypeface(style, fontID, false)
5051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        , fFactory(SkRefComPtr(factory))
5151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        , fDWriteFontCollectionLoader(SkSafeRefComPtr(fontCollectionLoader))
5251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        , fDWriteFontFileLoader(SkSafeRefComPtr(fontFileLoader))
5351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        , fDWriteFontFamily(SkRefComPtr(fontFamily))
5451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        , fDWriteFont(SkRefComPtr(font))
5551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        , fDWriteFontFace(SkRefComPtr(fontFace))
56f73c237291bb1fc698f688d8a9b1cdd23838ed18bungeman    {
57f548444684b9c96f7717aebe645944af4f95d650bungeman#if SK_HAS_DWRITE_1_H
58f73c237291bb1fc698f688d8a9b1cdd23838ed18bungeman        if (!SUCCEEDED(fDWriteFontFace->QueryInterface(&fDWriteFontFace1))) {
59f73c237291bb1fc698f688d8a9b1cdd23838ed18bungeman            // IUnknown::QueryInterface states that if it fails, punk will be set to NULL.
60f73c237291bb1fc698f688d8a9b1cdd23838ed18bungeman            // http://blogs.msdn.com/b/oldnewthing/archive/2004/03/26/96777.aspx
61f73c237291bb1fc698f688d8a9b1cdd23838ed18bungeman            SK_ALWAYSBREAK(NULL == fDWriteFontFace1.get());
62f73c237291bb1fc698f688d8a9b1cdd23838ed18bungeman        }
63f548444684b9c96f7717aebe645944af4f95d650bungeman#endif
64f73c237291bb1fc698f688d8a9b1cdd23838ed18bungeman    }
6551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
6651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanpublic:
6751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    SkTScopedComPtr<IDWriteFactory> fFactory;
6851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    SkTScopedComPtr<IDWriteFontCollectionLoader> fDWriteFontCollectionLoader;
6951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    SkTScopedComPtr<IDWriteFontFileLoader> fDWriteFontFileLoader;
7051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    SkTScopedComPtr<IDWriteFontFamily> fDWriteFontFamily;
7151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    SkTScopedComPtr<IDWriteFont> fDWriteFont;
7251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    SkTScopedComPtr<IDWriteFontFace> fDWriteFontFace;
73f548444684b9c96f7717aebe645944af4f95d650bungeman#if SK_HAS_DWRITE_1_H
74f73c237291bb1fc698f688d8a9b1cdd23838ed18bungeman    SkTScopedComPtr<IDWriteFontFace1> fDWriteFontFace1;
75f548444684b9c96f7717aebe645944af4f95d650bungeman#endif
7651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
7751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    static DWriteFontTypeface* Create(IDWriteFactory* factory,
7851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                                      IDWriteFontFace* fontFace,
7951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                                      IDWriteFont* font,
8051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                                      IDWriteFontFamily* fontFamily,
8151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                                      IDWriteFontFileLoader* fontFileLoader = NULL,
8251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                                      IDWriteFontCollectionLoader* fontCollectionLoader = NULL) {
8351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        SkTypeface::Style style = get_style(font);
8451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        SkFontID fontID = SkTypefaceCache::NewFontID();
8551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        return SkNEW_ARGS(DWriteFontTypeface, (style, fontID,
8651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                                               factory, fontFace, font, fontFamily,
8751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                                               fontFileLoader, fontCollectionLoader));
8851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
8951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
9051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanprotected:
9151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    virtual void weak_dispose() const SK_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
10351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE;
10451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    virtual SkScalerContext* onCreateScalerContext(const SkDescriptor*) const SK_OVERRIDE;
10551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    virtual void onFilterRec(SkScalerContextRec*) const SK_OVERRIDE;
10651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    virtual SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics(
10751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                                SkAdvancedTypefaceMetrics::PerGlyphInfo,
10851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                                const uint32_t*, uint32_t) const SK_OVERRIDE;
10951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    virtual void onGetFontDescriptor(SkFontDescriptor*, bool*) const SK_OVERRIDE;
11051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    virtual int onCharsToGlyphs(const void* chars, Encoding encoding,
11151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                                uint16_t glyphs[], int glyphCount) const SK_OVERRIDE;
11251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    virtual int onCountGlyphs() const SK_OVERRIDE;
11351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    virtual int onGetUPEM() const SK_OVERRIDE;
114b374d6a62c0259387d90cad74753d8bad9ee1beabungeman    virtual void onGetFamilyName(SkString* familyName) const SK_OVERRIDE;
11551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    virtual SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const SK_OVERRIDE;
11651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE;
11751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    virtual size_t onGetTableData(SkFontTableTag, size_t offset,
11851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                                  size_t length, void* data) const SK_OVERRIDE;
11951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
12051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanprivate:
12151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    typedef SkTypeface INHERITED;
12251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman};
12351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
12451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#endif
125