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>
204e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger#include <dwrite_1.h>
2151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
2251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanclass SkFontDescriptor;
2351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanstruct SkScalerContextRec;
2451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
2551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanstatic SkTypeface::Style get_style(IDWriteFont* font) {
2651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    int style = SkTypeface::kNormal;
2751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    DWRITE_FONT_WEIGHT weight = font->GetWeight();
2851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    if (DWRITE_FONT_WEIGHT_DEMI_BOLD <= weight) {
2951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        style |= SkTypeface::kBold;
3051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
3151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    DWRITE_FONT_STYLE angle = font->GetStyle();
3251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    if (DWRITE_FONT_STYLE_OBLIQUE == angle || DWRITE_FONT_STYLE_ITALIC == angle) {
3351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        style |= SkTypeface::kItalic;
3451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
3551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    return static_cast<SkTypeface::Style>(style);
3651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman}
3751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
3851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanclass DWriteFontTypeface : public SkTypeface {
3951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanprivate:
4051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    DWriteFontTypeface(SkTypeface::Style style, SkFontID fontID,
4151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                       IDWriteFactory* factory,
4251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                       IDWriteFontFace* fontFace,
4351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                       IDWriteFont* font,
4451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                       IDWriteFontFamily* fontFamily,
4551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                       IDWriteFontFileLoader* fontFileLoader = NULL,
4651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                       IDWriteFontCollectionLoader* fontCollectionLoader = NULL)
4751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        : SkTypeface(style, fontID, false)
4851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        , fFactory(SkRefComPtr(factory))
4951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        , fDWriteFontCollectionLoader(SkSafeRefComPtr(fontCollectionLoader))
5051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        , fDWriteFontFileLoader(SkSafeRefComPtr(fontFileLoader))
5151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        , fDWriteFontFamily(SkRefComPtr(fontFamily))
5251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        , fDWriteFont(SkRefComPtr(font))
5351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        , fDWriteFontFace(SkRefComPtr(fontFace))
544e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger    {
554e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger        if (!SUCCEEDED(fDWriteFontFace->QueryInterface(&fDWriteFontFace1))) {
564e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger            // IUnknown::QueryInterface states that if it fails, punk will be set to NULL.
574e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger            // http://blogs.msdn.com/b/oldnewthing/archive/2004/03/26/96777.aspx
584e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger            SK_ALWAYSBREAK(NULL == fDWriteFontFace1.get());
594e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger        }
604e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger    }
6151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
6251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanpublic:
6351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    SkTScopedComPtr<IDWriteFactory> fFactory;
6451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    SkTScopedComPtr<IDWriteFontCollectionLoader> fDWriteFontCollectionLoader;
6551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    SkTScopedComPtr<IDWriteFontFileLoader> fDWriteFontFileLoader;
6651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    SkTScopedComPtr<IDWriteFontFamily> fDWriteFontFamily;
6751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    SkTScopedComPtr<IDWriteFont> fDWriteFont;
6851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    SkTScopedComPtr<IDWriteFontFace> fDWriteFontFace;
694e4a89dab47d74874d6a79c4b34d89ffbfb386afDerek Sollenberger    SkTScopedComPtr<IDWriteFontFace1> fDWriteFontFace1;
7051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
7151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    static DWriteFontTypeface* Create(IDWriteFactory* factory,
7251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                                      IDWriteFontFace* fontFace,
7351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                                      IDWriteFont* font,
7451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                                      IDWriteFontFamily* fontFamily,
7551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                                      IDWriteFontFileLoader* fontFileLoader = NULL,
7651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                                      IDWriteFontCollectionLoader* fontCollectionLoader = NULL) {
7751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        SkTypeface::Style style = get_style(font);
7851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        SkFontID fontID = SkTypefaceCache::NewFontID();
7951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        return SkNEW_ARGS(DWriteFontTypeface, (style, fontID,
8051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                                               factory, fontFace, font, fontFamily,
8151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                                               fontFileLoader, fontCollectionLoader));
8251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
8351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
8451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanprotected:
8551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    virtual void weak_dispose() const SK_OVERRIDE {
8651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        if (fDWriteFontCollectionLoader.get()) {
8751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman            HRV(fFactory->UnregisterFontCollectionLoader(fDWriteFontCollectionLoader.get()));
8851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        }
8951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        if (fDWriteFontFileLoader.get()) {
9051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman            HRV(fFactory->UnregisterFontFileLoader(fDWriteFontFileLoader.get()));
9151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        }
9251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
9351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        //SkTypefaceCache::Remove(this);
9451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman        INHERITED::weak_dispose();
9551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    }
9651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
9751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE;
9851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    virtual SkScalerContext* onCreateScalerContext(const SkDescriptor*) const SK_OVERRIDE;
9951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    virtual void onFilterRec(SkScalerContextRec*) const SK_OVERRIDE;
10051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    virtual SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics(
10151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                                SkAdvancedTypefaceMetrics::PerGlyphInfo,
10251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                                const uint32_t*, uint32_t) const SK_OVERRIDE;
10351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    virtual void onGetFontDescriptor(SkFontDescriptor*, bool*) const SK_OVERRIDE;
10451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    virtual int onCharsToGlyphs(const void* chars, Encoding encoding,
10551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                                uint16_t glyphs[], int glyphCount) const SK_OVERRIDE;
10651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    virtual int onCountGlyphs() const SK_OVERRIDE;
10751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    virtual int onGetUPEM() const SK_OVERRIDE;
10851daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    virtual SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const SK_OVERRIDE;
10951daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE;
11051daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    virtual size_t onGetTableData(SkFontTableTag, size_t offset,
11151daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman                                  size_t length, void* data) const SK_OVERRIDE;
11251daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
11351daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungemanprivate:
11451daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman    typedef SkTypeface INHERITED;
11551daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman};
11651daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman
11751daa25a2b16bca578e78b7ea1e5815b9abb8b0bbungeman#endif
118