Home | History | Annotate | Download | only in ports
      1 /*
      2  * Copyright 2011 Google Inc.
      3  *
      4  * Use of this source code is governed by a BSD-style license that can be
      5  * found in the LICENSE file.
      6  */
      7 
      8 #include "SkTypes.h"
      9 #undef GetGlyphIndices
     10 
     11 #include "SkAdvancedTypefaceMetrics.h"
     12 #include "SkColorFilter.h"
     13 #include "SkDWriteFontFileStream.h"
     14 #include "SkDWriteGeometrySink.h"
     15 #include "SkDescriptor.h"
     16 #include "SkEndian.h"
     17 #include "SkFontDescriptor.h"
     18 #include "SkFontHost.h"
     19 #include "SkFontMgr.h"
     20 #include "SkFontStream.h"
     21 #include "SkGlyph.h"
     22 #include "SkHRESULT.h"
     23 #include "SkMaskGamma.h"
     24 #include "SkOnce.h"
     25 #include "SkOTTable_head.h"
     26 #include "SkOTTable_hhea.h"
     27 #include "SkOTTable_OS_2.h"
     28 #include "SkOTTable_post.h"
     29 #include "SkPath.h"
     30 #include "SkStream.h"
     31 #include "SkString.h"
     32 #include "SkTScopedComPtr.h"
     33 #include "SkThread.h"
     34 #include "SkTypeface_win.h"
     35 #include "SkTypefaceCache.h"
     36 #include "SkUtils.h"
     37 
     38 #include <dwrite.h>
     39 
     40 static bool isLCD(const SkScalerContext::Rec& rec) {
     41     return SkMask::kLCD16_Format == rec.fMaskFormat ||
     42            SkMask::kLCD32_Format == rec.fMaskFormat;
     43 }
     44 
     45 /** Prefer to use this type to prevent template proliferation. */
     46 typedef SkAutoSTMalloc<16, WCHAR> SkSMallocWCHAR;
     47 
     48 /** Converts a utf8 string to a WCHAR string. */
     49 static HRESULT cstring_to_wchar(const char* skname, SkSMallocWCHAR* name) {
     50     int wlen = MultiByteToWideChar(CP_UTF8, 0, skname, -1, NULL, 0);
     51     if (0 == wlen) {
     52         HRM(HRESULT_FROM_WIN32(GetLastError()),
     53             "Could not get length for wchar to utf-8 conversion.");
     54     }
     55     name->reset(wlen);
     56     wlen = MultiByteToWideChar(CP_UTF8, 0, skname, -1, name->get(), wlen);
     57     if (0 == wlen) {
     58         HRM(HRESULT_FROM_WIN32(GetLastError()), "Could not convert wchar to utf-8.");
     59     }
     60     return S_OK;
     61 }
     62 
     63 /** Converts a WCHAR string to a utf8 string. */
     64 static HRESULT wchar_to_skstring(WCHAR* name, SkString* skname) {
     65     int len = WideCharToMultiByte(CP_UTF8, 0, name, -1, NULL, 0, NULL, NULL);
     66     if (0 == len) {
     67         HRM(HRESULT_FROM_WIN32(GetLastError()),
     68             "Could not get length for utf-8 to wchar conversion.");
     69     }
     70     skname->resize(len - 1);
     71     len = WideCharToMultiByte(CP_UTF8, 0, name, -1, skname->writable_str(), len, NULL, NULL);
     72     if (0 == len) {
     73         HRM(HRESULT_FROM_WIN32(GetLastError()), "Could not convert utf-8 to wchar.");
     74     }
     75     return S_OK;
     76 }
     77 
     78 ///////////////////////////////////////////////////////////////////////////////
     79 
     80 static void create_dwrite_factory(IDWriteFactory** factory) {
     81     typedef decltype(DWriteCreateFactory)* DWriteCreateFactoryProc;
     82     DWriteCreateFactoryProc dWriteCreateFactoryProc = reinterpret_cast<DWriteCreateFactoryProc>(
     83         GetProcAddress(LoadLibraryW(L"dwrite.dll"), "DWriteCreateFactory"));
     84 
     85     if (!dWriteCreateFactoryProc) {
     86         HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
     87         if (!IS_ERROR(hr)) {
     88             hr = ERROR_PROC_NOT_FOUND;
     89         }
     90         HRVM(hr, "Could not get DWriteCreateFactory proc.");
     91     }
     92 
     93     HRVM(dWriteCreateFactoryProc(DWRITE_FACTORY_TYPE_SHARED,
     94                                  __uuidof(IDWriteFactory),
     95                                  reinterpret_cast<IUnknown**>(factory)),
     96          "Could not create DirectWrite factory.");
     97 }
     98 
     99 static IDWriteFactory* get_dwrite_factory() {
    100     static IDWriteFactory* gDWriteFactory = NULL;
    101     SK_DECLARE_STATIC_ONCE(once);
    102     SkOnce(&once, create_dwrite_factory, &gDWriteFactory);
    103 
    104     return gDWriteFactory;
    105 }
    106 
    107 ///////////////////////////////////////////////////////////////////////////////
    108 
    109 class StreamFontFileLoader;
    110 
    111 class SkFontMgr_DirectWrite : public SkFontMgr {
    112 public:
    113     /** localeNameLength must include the null terminator. */
    114     SkFontMgr_DirectWrite(IDWriteFontCollection* fontCollection,
    115                           WCHAR* localeName, int localeNameLength)
    116         : fFontCollection(SkRefComPtr(fontCollection))
    117         , fLocaleName(localeNameLength)
    118     {
    119         memcpy(fLocaleName.get(), localeName, localeNameLength * sizeof(WCHAR));
    120     }
    121 
    122     SkTypefaceCache* getTypefaceCache() { return &fTFCache; }
    123 
    124     SkTypeface* createTypefaceFromDWriteFont(IDWriteFontFace* fontFace,
    125                                              IDWriteFont* font,
    126                                              IDWriteFontFamily* fontFamily,
    127                                              StreamFontFileLoader* = NULL,
    128                                              IDWriteFontCollectionLoader* = NULL);
    129 
    130 protected:
    131     virtual int onCountFamilies() SK_OVERRIDE;
    132     virtual void onGetFamilyName(int index, SkString* familyName) SK_OVERRIDE;
    133     virtual SkFontStyleSet* onCreateStyleSet(int index) SK_OVERRIDE;
    134     virtual SkFontStyleSet* onMatchFamily(const char familyName[]) SK_OVERRIDE;
    135     virtual SkTypeface* onMatchFamilyStyle(const char familyName[],
    136                                            const SkFontStyle& fontstyle) SK_OVERRIDE;
    137     virtual SkTypeface* onMatchFaceStyle(const SkTypeface* familyMember,
    138                                          const SkFontStyle& fontstyle) SK_OVERRIDE;
    139     virtual SkTypeface* onCreateFromStream(SkStream* stream, int ttcIndex) SK_OVERRIDE;
    140     virtual SkTypeface* onCreateFromData(SkData* data, int ttcIndex) SK_OVERRIDE;
    141     virtual SkTypeface* onCreateFromFile(const char path[], int ttcIndex) SK_OVERRIDE;
    142     virtual SkTypeface* onLegacyCreateTypeface(const char familyName[],
    143                                                unsigned styleBits) SK_OVERRIDE;
    144 
    145 private:
    146     HRESULT getByFamilyName(const WCHAR familyName[], IDWriteFontFamily** fontFamily);
    147     HRESULT getDefaultFontFamily(IDWriteFontFamily** fontFamily);
    148 
    149     SkMutex fTFCacheMutex;
    150     void Add(SkTypeface* face, SkTypeface::Style requestedStyle, bool strong) {
    151         SkAutoMutexAcquire ama(fTFCacheMutex);
    152         fTFCache.add(face, requestedStyle, strong);
    153     }
    154 
    155     SkTypeface* FindByProcAndRef(SkTypefaceCache::FindProc proc, void* ctx) {
    156         SkAutoMutexAcquire ama(fTFCacheMutex);
    157         SkTypeface* typeface = fTFCache.findByProcAndRef(proc, ctx);
    158         return typeface;
    159     }
    160 
    161     friend class SkFontStyleSet_DirectWrite;
    162     SkTScopedComPtr<IDWriteFontCollection> fFontCollection;
    163     SkSMallocWCHAR fLocaleName;
    164     SkTypefaceCache fTFCache;
    165 };
    166 
    167 class SkFontStyleSet_DirectWrite : public SkFontStyleSet {
    168 public:
    169     SkFontStyleSet_DirectWrite(SkFontMgr_DirectWrite* fontMgr, IDWriteFontFamily* fontFamily)
    170         : fFontMgr(SkRef(fontMgr))
    171         , fFontFamily(SkRefComPtr(fontFamily))
    172     { }
    173 
    174     virtual int count() SK_OVERRIDE;
    175     virtual void getStyle(int index, SkFontStyle* fs, SkString* styleName) SK_OVERRIDE;
    176     virtual SkTypeface* createTypeface(int index) SK_OVERRIDE;
    177     virtual SkTypeface* matchStyle(const SkFontStyle& pattern) SK_OVERRIDE;
    178 
    179 private:
    180     SkAutoTUnref<SkFontMgr_DirectWrite> fFontMgr;
    181     SkTScopedComPtr<IDWriteFontFamily> fFontFamily;
    182 };
    183 
    184 ///////////////////////////////////////////////////////////////////////////////
    185 
    186 class DWriteOffscreen {
    187 public:
    188     DWriteOffscreen() : fWidth(0), fHeight(0) {
    189     }
    190 
    191     void init(IDWriteFontFace* fontFace, const DWRITE_MATRIX& xform, FLOAT fontSize) {
    192         fFontFace = fontFace;
    193         fFontSize = fontSize;
    194         fXform = xform;
    195     }
    196 
    197     const void* draw(const SkGlyph&, bool isBW);
    198 
    199 private:
    200     uint16_t fWidth;
    201     uint16_t fHeight;
    202     IDWriteFontFace* fFontFace;
    203     FLOAT fFontSize;
    204     DWRITE_MATRIX fXform;
    205     SkTDArray<uint8_t> fBits;
    206 };
    207 
    208 const void* DWriteOffscreen::draw(const SkGlyph& glyph, bool isBW) {
    209     IDWriteFactory* factory = get_dwrite_factory();
    210     SkASSERT(factory != NULL);
    211 
    212     if (fWidth < glyph.fWidth || fHeight < glyph.fHeight) {
    213         fWidth = SkMax32(fWidth, glyph.fWidth);
    214         fHeight = SkMax32(fHeight, glyph.fHeight);
    215 
    216         if (isBW) {
    217             fBits.setCount(fWidth * fHeight);
    218         } else {
    219             fBits.setCount(fWidth * fHeight * 3);
    220         }
    221     }
    222 
    223     // erase
    224     memset(fBits.begin(), 0, fBits.count());
    225 
    226     fXform.dx = SkFixedToFloat(glyph.getSubXFixed());
    227     fXform.dy = SkFixedToFloat(glyph.getSubYFixed());
    228 
    229     FLOAT advance = 0.0f;
    230 
    231     UINT16 index = glyph.getGlyphID();
    232 
    233     DWRITE_GLYPH_OFFSET offset;
    234     offset.advanceOffset = 0.0f;
    235     offset.ascenderOffset = 0.0f;
    236 
    237     DWRITE_GLYPH_RUN run;
    238     run.glyphCount = 1;
    239     run.glyphAdvances = &advance;
    240     run.fontFace = fFontFace;
    241     run.fontEmSize = fFontSize;
    242     run.bidiLevel = 0;
    243     run.glyphIndices = &index;
    244     run.isSideways = FALSE;
    245     run.glyphOffsets = &offset;
    246 
    247     DWRITE_RENDERING_MODE renderingMode;
    248     DWRITE_TEXTURE_TYPE textureType;
    249     if (isBW) {
    250         renderingMode = DWRITE_RENDERING_MODE_ALIASED;
    251         textureType = DWRITE_TEXTURE_ALIASED_1x1;
    252     } else {
    253         renderingMode = DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC;
    254         textureType = DWRITE_TEXTURE_CLEARTYPE_3x1;
    255     }
    256     SkTScopedComPtr<IDWriteGlyphRunAnalysis> glyphRunAnalysis;
    257     HRNM(factory->CreateGlyphRunAnalysis(&run,
    258                                          1.0f, // pixelsPerDip,
    259                                          &fXform,
    260                                          renderingMode,
    261                                          DWRITE_MEASURING_MODE_NATURAL,
    262                                          0.0f, // baselineOriginX,
    263                                          0.0f, // baselineOriginY,
    264                                          &glyphRunAnalysis),
    265          "Could not create glyph run analysis.");
    266 
    267     //NOTE: this assumes that the glyph has already been measured
    268     //with an exact same glyph run analysis.
    269     RECT bbox;
    270     bbox.left = glyph.fLeft;
    271     bbox.top = glyph.fTop;
    272     bbox.right = glyph.fLeft + glyph.fWidth;
    273     bbox.bottom = glyph.fTop + glyph.fHeight;
    274     HRNM(glyphRunAnalysis->CreateAlphaTexture(textureType,
    275                                               &bbox,
    276                                               fBits.begin(),
    277                                               fBits.count()),
    278          "Could not draw mask.");
    279     return fBits.begin();
    280 }
    281 
    282 ///////////////////////////////////////////////////////////////////////////////
    283 
    284 class StreamFontFileLoader : public IDWriteFontFileLoader {
    285 public:
    286     // IUnknown methods
    287     virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject);
    288     virtual ULONG STDMETHODCALLTYPE AddRef();
    289     virtual ULONG STDMETHODCALLTYPE Release();
    290 
    291     // IDWriteFontFileLoader methods
    292     virtual HRESULT STDMETHODCALLTYPE CreateStreamFromKey(
    293         void const* fontFileReferenceKey,
    294         UINT32 fontFileReferenceKeySize,
    295         IDWriteFontFileStream** fontFileStream);
    296 
    297     static HRESULT Create(SkStream* stream, StreamFontFileLoader** streamFontFileLoader) {
    298         *streamFontFileLoader = new StreamFontFileLoader(stream);
    299         if (NULL == streamFontFileLoader) {
    300             return E_OUTOFMEMORY;
    301         }
    302         return S_OK;
    303     }
    304 
    305     SkAutoTUnref<SkStream> fStream;
    306 
    307 private:
    308     StreamFontFileLoader(SkStream* stream) : fRefCount(1), fStream(SkRef(stream)) { }
    309 
    310     ULONG fRefCount;
    311 };
    312 
    313 HRESULT StreamFontFileLoader::QueryInterface(REFIID iid, void** ppvObject) {
    314     if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileLoader)) {
    315         *ppvObject = this;
    316         AddRef();
    317         return S_OK;
    318     } else {
    319         *ppvObject = NULL;
    320         return E_NOINTERFACE;
    321     }
    322 }
    323 
    324 ULONG StreamFontFileLoader::AddRef() {
    325     return InterlockedIncrement(&fRefCount);
    326 }
    327 
    328 ULONG StreamFontFileLoader::Release() {
    329     ULONG newCount = InterlockedDecrement(&fRefCount);
    330     if (0 == newCount) {
    331         delete this;
    332     }
    333     return newCount;
    334 }
    335 
    336 HRESULT StreamFontFileLoader::CreateStreamFromKey(
    337     void const* fontFileReferenceKey,
    338     UINT32 fontFileReferenceKeySize,
    339     IDWriteFontFileStream** fontFileStream)
    340 {
    341     SkTScopedComPtr<SkDWriteFontFileStreamWrapper> stream;
    342     HR(SkDWriteFontFileStreamWrapper::Create(fStream, &stream));
    343     *fontFileStream = stream.release();
    344     return S_OK;
    345 }
    346 
    347 class StreamFontFileEnumerator : public IDWriteFontFileEnumerator {
    348 public:
    349     // IUnknown methods
    350     virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject);
    351     virtual ULONG STDMETHODCALLTYPE AddRef();
    352     virtual ULONG STDMETHODCALLTYPE Release();
    353 
    354     // IDWriteFontFileEnumerator methods
    355     virtual HRESULT STDMETHODCALLTYPE MoveNext(BOOL* hasCurrentFile);
    356     virtual HRESULT STDMETHODCALLTYPE GetCurrentFontFile(IDWriteFontFile** fontFile);
    357 
    358     static HRESULT Create(IDWriteFactory* factory, IDWriteFontFileLoader* fontFileLoader,
    359                           StreamFontFileEnumerator** streamFontFileEnumerator) {
    360         *streamFontFileEnumerator = new StreamFontFileEnumerator(factory, fontFileLoader);
    361         if (NULL == streamFontFileEnumerator) {
    362             return E_OUTOFMEMORY;
    363         }
    364         return S_OK;
    365     }
    366 private:
    367     StreamFontFileEnumerator(IDWriteFactory* factory, IDWriteFontFileLoader* fontFileLoader);
    368     ULONG fRefCount;
    369 
    370     SkTScopedComPtr<IDWriteFactory> fFactory;
    371     SkTScopedComPtr<IDWriteFontFile> fCurrentFile;
    372     SkTScopedComPtr<IDWriteFontFileLoader> fFontFileLoader;
    373     bool fHasNext;
    374 };
    375 
    376 StreamFontFileEnumerator::StreamFontFileEnumerator(IDWriteFactory* factory,
    377                                                    IDWriteFontFileLoader* fontFileLoader)
    378     : fRefCount(1)
    379     , fFactory(SkRefComPtr(factory))
    380     , fCurrentFile()
    381     , fFontFileLoader(SkRefComPtr(fontFileLoader))
    382     , fHasNext(true)
    383 { }
    384 
    385 HRESULT StreamFontFileEnumerator::QueryInterface(REFIID iid, void** ppvObject) {
    386     if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileEnumerator)) {
    387         *ppvObject = this;
    388         AddRef();
    389         return S_OK;
    390     } else {
    391         *ppvObject = NULL;
    392         return E_NOINTERFACE;
    393     }
    394 }
    395 
    396 ULONG StreamFontFileEnumerator::AddRef() {
    397     return InterlockedIncrement(&fRefCount);
    398 }
    399 
    400 ULONG StreamFontFileEnumerator::Release() {
    401     ULONG newCount = InterlockedDecrement(&fRefCount);
    402     if (0 == newCount) {
    403         delete this;
    404     }
    405     return newCount;
    406 }
    407 
    408 HRESULT StreamFontFileEnumerator::MoveNext(BOOL* hasCurrentFile) {
    409     *hasCurrentFile = FALSE;
    410 
    411     if (!fHasNext) {
    412         return S_OK;
    413     }
    414     fHasNext = false;
    415 
    416     UINT32 dummy = 0;
    417     HR(fFactory->CreateCustomFontFileReference(
    418             &dummy, //cannot be NULL
    419             sizeof(dummy), //even if this is 0
    420             fFontFileLoader.get(),
    421             &fCurrentFile));
    422 
    423     *hasCurrentFile = TRUE;
    424     return S_OK;
    425 }
    426 
    427 HRESULT StreamFontFileEnumerator::GetCurrentFontFile(IDWriteFontFile** fontFile) {
    428     if (fCurrentFile.get() == NULL) {
    429         *fontFile = NULL;
    430         return E_FAIL;
    431     }
    432 
    433     *fontFile = SkRefComPtr(fCurrentFile.get());
    434     return  S_OK;
    435 }
    436 
    437 class StreamFontCollectionLoader : public IDWriteFontCollectionLoader {
    438 public:
    439     // IUnknown methods
    440     virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject);
    441     virtual ULONG STDMETHODCALLTYPE AddRef();
    442     virtual ULONG STDMETHODCALLTYPE Release();
    443 
    444     // IDWriteFontCollectionLoader methods
    445     virtual HRESULT STDMETHODCALLTYPE CreateEnumeratorFromKey(
    446         IDWriteFactory* factory,
    447         void const* collectionKey,
    448         UINT32 collectionKeySize,
    449         IDWriteFontFileEnumerator** fontFileEnumerator);
    450 
    451     static HRESULT Create(IDWriteFontFileLoader* fontFileLoader,
    452                           StreamFontCollectionLoader** streamFontCollectionLoader) {
    453         *streamFontCollectionLoader = new StreamFontCollectionLoader(fontFileLoader);
    454         if (NULL == streamFontCollectionLoader) {
    455             return E_OUTOFMEMORY;
    456         }
    457         return S_OK;
    458     }
    459 private:
    460     StreamFontCollectionLoader(IDWriteFontFileLoader* fontFileLoader)
    461         : fRefCount(1)
    462         , fFontFileLoader(SkRefComPtr(fontFileLoader))
    463     { }
    464 
    465     ULONG fRefCount;
    466     SkTScopedComPtr<IDWriteFontFileLoader> fFontFileLoader;
    467 };
    468 
    469 HRESULT StreamFontCollectionLoader::QueryInterface(REFIID iid, void** ppvObject) {
    470     if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontCollectionLoader)) {
    471         *ppvObject = this;
    472         AddRef();
    473         return S_OK;
    474     } else {
    475         *ppvObject = NULL;
    476         return E_NOINTERFACE;
    477     }
    478 }
    479 
    480 ULONG StreamFontCollectionLoader::AddRef() {
    481     return InterlockedIncrement(&fRefCount);
    482 }
    483 
    484 ULONG StreamFontCollectionLoader::Release() {
    485     ULONG newCount = InterlockedDecrement(&fRefCount);
    486     if (0 == newCount) {
    487         delete this;
    488     }
    489     return newCount;
    490 }
    491 
    492 HRESULT StreamFontCollectionLoader::CreateEnumeratorFromKey(
    493     IDWriteFactory* factory,
    494     void const* collectionKey,
    495     UINT32 collectionKeySize,
    496     IDWriteFontFileEnumerator** fontFileEnumerator)
    497 {
    498     SkTScopedComPtr<StreamFontFileEnumerator> enumerator;
    499     HR(StreamFontFileEnumerator::Create(factory, fFontFileLoader.get(), &enumerator));
    500     *fontFileEnumerator = enumerator.release();
    501     return S_OK;
    502 }
    503 
    504 ///////////////////////////////////////////////////////////////////////////////
    505 
    506 static SkTypeface::Style get_style(IDWriteFont* font) {
    507     int style = SkTypeface::kNormal;
    508     DWRITE_FONT_WEIGHT weight = font->GetWeight();
    509     if (DWRITE_FONT_WEIGHT_DEMI_BOLD <= weight) {
    510         style |= SkTypeface::kBold;
    511     }
    512     DWRITE_FONT_STYLE angle = font->GetStyle();
    513     if (DWRITE_FONT_STYLE_OBLIQUE == angle || DWRITE_FONT_STYLE_ITALIC == angle) {
    514         style |= SkTypeface::kItalic;
    515     }
    516     return static_cast<SkTypeface::Style>(style);
    517 }
    518 
    519 class DWriteFontTypeface : public SkTypeface {
    520 private:
    521     DWriteFontTypeface(SkTypeface::Style style, SkFontID fontID,
    522                        IDWriteFontFace* fontFace,
    523                        IDWriteFont* font,
    524                        IDWriteFontFamily* fontFamily,
    525                        StreamFontFileLoader* fontFileLoader = NULL,
    526                        IDWriteFontCollectionLoader* fontCollectionLoader = NULL)
    527         : SkTypeface(style, fontID, false)
    528         , fDWriteFontCollectionLoader(SkSafeRefComPtr(fontCollectionLoader))
    529         , fDWriteFontFileLoader(SkSafeRefComPtr(fontFileLoader))
    530         , fDWriteFontFamily(SkRefComPtr(fontFamily))
    531         , fDWriteFont(SkRefComPtr(font))
    532         , fDWriteFontFace(SkRefComPtr(fontFace))
    533     { }
    534 
    535 public:
    536     SkTScopedComPtr<IDWriteFontCollectionLoader> fDWriteFontCollectionLoader;
    537     SkTScopedComPtr<StreamFontFileLoader> fDWriteFontFileLoader;
    538     SkTScopedComPtr<IDWriteFontFamily> fDWriteFontFamily;
    539     SkTScopedComPtr<IDWriteFont> fDWriteFont;
    540     SkTScopedComPtr<IDWriteFontFace> fDWriteFontFace;
    541 
    542     static DWriteFontTypeface* Create(IDWriteFontFace* fontFace,
    543                                       IDWriteFont* font,
    544                                       IDWriteFontFamily* fontFamily,
    545                                       StreamFontFileLoader* fontFileLoader = NULL,
    546                                       IDWriteFontCollectionLoader* fontCollectionLoader = NULL) {
    547         SkTypeface::Style style = get_style(font);
    548         SkFontID fontID = SkTypefaceCache::NewFontID();
    549         return SkNEW_ARGS(DWriteFontTypeface, (style, fontID,
    550                                                fontFace, font, fontFamily,
    551                                                fontFileLoader, fontCollectionLoader));
    552     }
    553 
    554     ~DWriteFontTypeface() {
    555         if (fDWriteFontCollectionLoader.get() == NULL) return;
    556 
    557         IDWriteFactory* factory = get_dwrite_factory();
    558         SkASSERT(factory != NULL);
    559         HRV(factory->UnregisterFontCollectionLoader(fDWriteFontCollectionLoader.get()));
    560         HRV(factory->UnregisterFontFileLoader(fDWriteFontFileLoader.get()));
    561     }
    562 
    563 protected:
    564     virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE;
    565     virtual SkScalerContext* onCreateScalerContext(const SkDescriptor*) const SK_OVERRIDE;
    566     virtual void onFilterRec(SkScalerContextRec*) const SK_OVERRIDE;
    567     virtual SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics(
    568                                 SkAdvancedTypefaceMetrics::PerGlyphInfo,
    569                                 const uint32_t*, uint32_t) const SK_OVERRIDE;
    570     virtual void onGetFontDescriptor(SkFontDescriptor*, bool*) const SK_OVERRIDE;
    571     virtual int onCharsToGlyphs(const void* chars, Encoding encoding,
    572                                 uint16_t glyphs[], int glyphCount) const SK_OVERRIDE;
    573     virtual int onCountGlyphs() const SK_OVERRIDE;
    574     virtual int onGetUPEM() const SK_OVERRIDE;
    575     virtual SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const SK_OVERRIDE;
    576     virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE;
    577     virtual size_t onGetTableData(SkFontTableTag, size_t offset,
    578                                   size_t length, void* data) const SK_OVERRIDE;
    579 };
    580 
    581 class SkScalerContext_DW : public SkScalerContext {
    582 public:
    583     SkScalerContext_DW(DWriteFontTypeface*, const SkDescriptor* desc);
    584     virtual ~SkScalerContext_DW();
    585 
    586 protected:
    587     virtual unsigned generateGlyphCount() SK_OVERRIDE;
    588     virtual uint16_t generateCharToGlyph(SkUnichar uni) SK_OVERRIDE;
    589     virtual void generateAdvance(SkGlyph* glyph) SK_OVERRIDE;
    590     virtual void generateMetrics(SkGlyph* glyph) SK_OVERRIDE;
    591     virtual void generateImage(const SkGlyph& glyph) SK_OVERRIDE;
    592     virtual void generatePath(const SkGlyph& glyph, SkPath* path) SK_OVERRIDE;
    593     virtual void generateFontMetrics(SkPaint::FontMetrics* mX,
    594                                      SkPaint::FontMetrics* mY) SK_OVERRIDE;
    595 
    596 private:
    597     DWriteOffscreen fOffscreen;
    598     DWRITE_MATRIX fXform;
    599     SkAutoTUnref<DWriteFontTypeface> fTypeface;
    600     int fGlyphCount;
    601 };
    602 
    603 static bool are_same(IUnknown* a, IUnknown* b) {
    604     SkTScopedComPtr<IUnknown> iunkA;
    605     if (FAILED(a->QueryInterface(&iunkA))) {
    606         return false;
    607     }
    608 
    609     SkTScopedComPtr<IUnknown> iunkB;
    610     if (FAILED(b->QueryInterface(&iunkB))) {
    611         return false;
    612     }
    613 
    614     return iunkA.get() == iunkB.get();
    615 }
    616 static bool FindByDWriteFont(SkTypeface* face, SkTypeface::Style requestedStyle, void* ctx) {
    617     //Check to see if the two fonts are identical.
    618     DWriteFontTypeface* dwFace = reinterpret_cast<DWriteFontTypeface*>(face);
    619     IDWriteFont* dwFont = reinterpret_cast<IDWriteFont*>(ctx);
    620     if (are_same(dwFace->fDWriteFont.get(), dwFont)) {
    621         return true;
    622     }
    623 
    624     //Check if the two fonts share the same loader and have the same key.
    625     SkTScopedComPtr<IDWriteFontFace> dwFaceFontFace;
    626     SkTScopedComPtr<IDWriteFontFace> dwFontFace;
    627     HRB(dwFace->fDWriteFont->CreateFontFace(&dwFaceFontFace));
    628     HRB(dwFont->CreateFontFace(&dwFontFace));
    629     if (are_same(dwFaceFontFace.get(), dwFontFace.get())) {
    630         return true;
    631     }
    632 
    633     UINT32 dwFaceNumFiles;
    634     UINT32 dwNumFiles;
    635     HRB(dwFaceFontFace->GetFiles(&dwFaceNumFiles, NULL));
    636     HRB(dwFontFace->GetFiles(&dwNumFiles, NULL));
    637     if (dwFaceNumFiles != dwNumFiles) {
    638         return false;
    639     }
    640 
    641     SkTScopedComPtr<IDWriteFontFile> dwFaceFontFile;
    642     SkTScopedComPtr<IDWriteFontFile> dwFontFile;
    643     HRB(dwFaceFontFace->GetFiles(&dwFaceNumFiles, &dwFaceFontFile));
    644     HRB(dwFontFace->GetFiles(&dwNumFiles, &dwFontFile));
    645 
    646     //for (each file) { //we currently only admit fonts from one file.
    647     SkTScopedComPtr<IDWriteFontFileLoader> dwFaceFontFileLoader;
    648     SkTScopedComPtr<IDWriteFontFileLoader> dwFontFileLoader;
    649     HRB(dwFaceFontFile->GetLoader(&dwFaceFontFileLoader));
    650     HRB(dwFontFile->GetLoader(&dwFontFileLoader));
    651     if (!are_same(dwFaceFontFileLoader.get(), dwFontFileLoader.get())) {
    652         return false;
    653     }
    654     //}
    655 
    656     const void* dwFaceFontRefKey;
    657     UINT32 dwFaceFontRefKeySize;
    658     const void* dwFontRefKey;
    659     UINT32 dwFontRefKeySize;
    660     HRB(dwFaceFontFile->GetReferenceKey(&dwFaceFontRefKey, &dwFaceFontRefKeySize));
    661     HRB(dwFontFile->GetReferenceKey(&dwFontRefKey, &dwFontRefKeySize));
    662     if (dwFaceFontRefKeySize != dwFontRefKeySize) {
    663         return false;
    664     }
    665     if (0 != memcmp(dwFaceFontRefKey, dwFontRefKey, dwFontRefKeySize)) {
    666         return false;
    667     }
    668 
    669     //TODO: better means than comparing name strings?
    670     //NOTE: .tfc and fake bold/italic will end up here.
    671     SkTScopedComPtr<IDWriteFontFamily> dwFaceFontFamily;
    672     SkTScopedComPtr<IDWriteFontFamily> dwFontFamily;
    673     HRB(dwFace->fDWriteFont->GetFontFamily(&dwFaceFontFamily));
    674     HRB(dwFont->GetFontFamily(&dwFontFamily));
    675 
    676     SkTScopedComPtr<IDWriteLocalizedStrings> dwFaceFontFamilyNames;
    677     SkTScopedComPtr<IDWriteLocalizedStrings> dwFaceFontNames;
    678     HRB(dwFaceFontFamily->GetFamilyNames(&dwFaceFontFamilyNames));
    679     HRB(dwFace->fDWriteFont->GetFaceNames(&dwFaceFontNames));
    680 
    681     SkTScopedComPtr<IDWriteLocalizedStrings> dwFontFamilyNames;
    682     SkTScopedComPtr<IDWriteLocalizedStrings> dwFontNames;
    683     HRB(dwFontFamily->GetFamilyNames(&dwFontFamilyNames));
    684     HRB(dwFont->GetFaceNames(&dwFontNames));
    685 
    686     UINT32 dwFaceFontFamilyNameLength;
    687     UINT32 dwFaceFontNameLength;
    688     HRB(dwFaceFontFamilyNames->GetStringLength(0, &dwFaceFontFamilyNameLength));
    689     HRB(dwFaceFontNames->GetStringLength(0, &dwFaceFontNameLength));
    690 
    691     UINT32 dwFontFamilyNameLength;
    692     UINT32 dwFontNameLength;
    693     HRB(dwFontFamilyNames->GetStringLength(0, &dwFontFamilyNameLength));
    694     HRB(dwFontNames->GetStringLength(0, &dwFontNameLength));
    695 
    696     if (dwFaceFontFamilyNameLength != dwFontFamilyNameLength ||
    697         dwFaceFontNameLength != dwFontNameLength)
    698     {
    699         return false;
    700     }
    701 
    702     SkSMallocWCHAR dwFaceFontFamilyNameChar(dwFaceFontFamilyNameLength+1);
    703     SkSMallocWCHAR dwFaceFontNameChar(dwFaceFontNameLength+1);
    704     HRB(dwFaceFontFamilyNames->GetString(0, dwFaceFontFamilyNameChar.get(), dwFaceFontFamilyNameLength+1));
    705     HRB(dwFaceFontNames->GetString(0, dwFaceFontNameChar.get(), dwFaceFontNameLength+1));
    706 
    707     SkSMallocWCHAR dwFontFamilyNameChar(dwFontFamilyNameLength+1);
    708     SkSMallocWCHAR dwFontNameChar(dwFontNameLength+1);
    709     HRB(dwFontFamilyNames->GetString(0, dwFontFamilyNameChar.get(), dwFontFamilyNameLength+1));
    710     HRB(dwFontNames->GetString(0, dwFontNameChar.get(), dwFontNameLength+1));
    711 
    712     return wcscmp(dwFaceFontFamilyNameChar.get(), dwFontFamilyNameChar.get()) == 0 &&
    713            wcscmp(dwFaceFontNameChar.get(), dwFontNameChar.get()) == 0;
    714 }
    715 
    716 SkScalerContext_DW::SkScalerContext_DW(DWriteFontTypeface* typeface,
    717                                                  const SkDescriptor* desc)
    718         : SkScalerContext(typeface, desc)
    719         , fTypeface(SkRef(typeface))
    720         , fGlyphCount(-1) {
    721 
    722     fXform.m11 = SkScalarToFloat(fRec.fPost2x2[0][0]);
    723     fXform.m12 = SkScalarToFloat(fRec.fPost2x2[1][0]);
    724     fXform.m21 = SkScalarToFloat(fRec.fPost2x2[0][1]);
    725     fXform.m22 = SkScalarToFloat(fRec.fPost2x2[1][1]);
    726     fXform.dx = 0;
    727     fXform.dy = 0;
    728 
    729     fOffscreen.init(fTypeface->fDWriteFontFace.get(), fXform, SkScalarToFloat(fRec.fTextSize));
    730 }
    731 
    732 SkScalerContext_DW::~SkScalerContext_DW() {
    733 }
    734 
    735 unsigned SkScalerContext_DW::generateGlyphCount() {
    736     if (fGlyphCount < 0) {
    737         fGlyphCount = fTypeface->fDWriteFontFace->GetGlyphCount();
    738     }
    739     return fGlyphCount;
    740 }
    741 
    742 uint16_t SkScalerContext_DW::generateCharToGlyph(SkUnichar uni) {
    743     uint16_t index = 0;
    744     fTypeface->fDWriteFontFace->GetGlyphIndices(reinterpret_cast<UINT32*>(&uni), 1, &index);
    745     return index;
    746 }
    747 
    748 void SkScalerContext_DW::generateAdvance(SkGlyph* glyph) {
    749     //Delta is the difference between the right/left side bearing metric
    750     //and where the right/left side bearing ends up after hinting.
    751     //DirectWrite does not provide this information.
    752     glyph->fRsbDelta = 0;
    753     glyph->fLsbDelta = 0;
    754 
    755     glyph->fAdvanceX = 0;
    756     glyph->fAdvanceY = 0;
    757 
    758     uint16_t glyphId = glyph->getGlyphID();
    759     DWRITE_GLYPH_METRICS gm;
    760     HRVM(fTypeface->fDWriteFontFace->GetDesignGlyphMetrics(&glyphId, 1, &gm),
    761          "Could not get design metrics.");
    762 
    763     DWRITE_FONT_METRICS dwfm;
    764     fTypeface->fDWriteFontFace->GetMetrics(&dwfm);
    765 
    766     SkScalar advanceX = SkScalarMulDiv(fRec.fTextSize,
    767                                        SkIntToScalar(gm.advanceWidth),
    768                                        SkIntToScalar(dwfm.designUnitsPerEm));
    769 
    770     if (!(fRec.fFlags & kSubpixelPositioning_Flag)) {
    771         advanceX = SkScalarRoundToScalar(advanceX);
    772     }
    773 
    774     SkVector vecs[1] = { { advanceX, 0 } };
    775     SkMatrix mat;
    776     fRec.getMatrixFrom2x2(&mat);
    777     mat.mapVectors(vecs, SK_ARRAY_COUNT(vecs));
    778 
    779     glyph->fAdvanceX = SkScalarToFixed(vecs[0].fX);
    780     glyph->fAdvanceY = SkScalarToFixed(vecs[0].fY);
    781 }
    782 
    783 void SkScalerContext_DW::generateMetrics(SkGlyph* glyph) {
    784     glyph->fWidth = 0;
    785 
    786     this->generateAdvance(glyph);
    787 
    788     //Measure raster size.
    789     fXform.dx = SkFixedToFloat(glyph->getSubXFixed());
    790     fXform.dy = SkFixedToFloat(glyph->getSubYFixed());
    791 
    792     FLOAT advance = 0;
    793 
    794     UINT16 glyphId = glyph->getGlyphID();
    795 
    796     DWRITE_GLYPH_OFFSET offset;
    797     offset.advanceOffset = 0.0f;
    798     offset.ascenderOffset = 0.0f;
    799 
    800     DWRITE_GLYPH_RUN run;
    801     run.glyphCount = 1;
    802     run.glyphAdvances = &advance;
    803     run.fontFace = fTypeface->fDWriteFontFace.get();
    804     run.fontEmSize = SkScalarToFloat(fRec.fTextSize);
    805     run.bidiLevel = 0;
    806     run.glyphIndices = &glyphId;
    807     run.isSideways = FALSE;
    808     run.glyphOffsets = &offset;
    809 
    810     IDWriteFactory* factory = get_dwrite_factory();
    811     SkASSERT(factory != NULL);
    812 
    813     const bool isBW = SkMask::kBW_Format == fRec.fMaskFormat;
    814     DWRITE_RENDERING_MODE renderingMode;
    815     DWRITE_TEXTURE_TYPE textureType;
    816     if (isBW) {
    817         renderingMode = DWRITE_RENDERING_MODE_ALIASED;
    818         textureType = DWRITE_TEXTURE_ALIASED_1x1;
    819     } else {
    820         renderingMode = DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC;
    821         textureType = DWRITE_TEXTURE_CLEARTYPE_3x1;
    822     }
    823 
    824     SkTScopedComPtr<IDWriteGlyphRunAnalysis> glyphRunAnalysis;
    825     HRVM(factory->CreateGlyphRunAnalysis(&run,
    826                                          1.0f, // pixelsPerDip,
    827                                          &fXform,
    828                                          renderingMode,
    829                                          DWRITE_MEASURING_MODE_NATURAL,
    830                                          0.0f, // baselineOriginX,
    831                                          0.0f, // baselineOriginY,
    832                                          &glyphRunAnalysis),
    833          "Could not create glyph run analysis.");
    834 
    835     RECT bbox;
    836     HRVM(glyphRunAnalysis->GetAlphaTextureBounds(textureType, &bbox),
    837          "Could not get texture bounds.");
    838 
    839     glyph->fWidth = SkToU16(bbox.right - bbox.left);
    840     glyph->fHeight = SkToU16(bbox.bottom - bbox.top);
    841     glyph->fLeft = SkToS16(bbox.left);
    842     glyph->fTop = SkToS16(bbox.top);
    843 }
    844 
    845 void SkScalerContext_DW::generateFontMetrics(SkPaint::FontMetrics* mx,
    846                                                   SkPaint::FontMetrics* my) {
    847     if (!(mx || my))
    848       return;
    849 
    850     if (mx) {
    851         sk_bzero(mx, sizeof(*mx));
    852     }
    853     if (my) {
    854         sk_bzero(my, sizeof(*my));
    855     }
    856 
    857     DWRITE_FONT_METRICS dwfm;
    858     fTypeface->fDWriteFontFace->GetMetrics(&dwfm);
    859 
    860     SkScalar upem = SkIntToScalar(dwfm.designUnitsPerEm);
    861     if (mx) {
    862         mx->fTop = -fRec.fTextSize * SkIntToScalar(dwfm.ascent) / upem;
    863         mx->fAscent = mx->fTop;
    864         mx->fDescent = fRec.fTextSize * SkIntToScalar(dwfm.descent) / upem;
    865         mx->fBottom = mx->fDescent;
    866         mx->fLeading = fRec.fTextSize * SkIntToScalar(dwfm.lineGap) / upem;
    867         mx->fXHeight = fRec.fTextSize * SkIntToScalar(dwfm.xHeight) / upem;
    868     }
    869 
    870     if (my) {
    871         my->fTop = -fRec.fTextSize * SkIntToScalar(dwfm.ascent) / upem;
    872         my->fAscent = my->fTop;
    873         my->fDescent = fRec.fTextSize * SkIntToScalar(dwfm.descent) / upem;
    874         my->fBottom = my->fDescent;
    875         my->fLeading = fRec.fTextSize * SkIntToScalar(dwfm.lineGap) / upem;
    876         my->fXHeight = fRec.fTextSize * SkIntToScalar(dwfm.xHeight) / upem;
    877     }
    878 }
    879 
    880 ///////////////////////////////////////////////////////////////////////////////
    881 
    882 #include "SkColorPriv.h"
    883 
    884 static void bilevel_to_bw(const uint8_t* SK_RESTRICT src, const SkGlyph& glyph) {
    885     const int width = glyph.fWidth;
    886     const size_t dstRB = (width + 7) >> 3;
    887     uint8_t* SK_RESTRICT dst = static_cast<uint8_t*>(glyph.fImage);
    888 
    889     int byteCount = width >> 3;
    890     int bitCount = width & 7;
    891 
    892     for (int y = 0; y < glyph.fHeight; ++y) {
    893         if (byteCount > 0) {
    894             for (int i = 0; i < byteCount; ++i) {
    895                 unsigned byte = 0;
    896                 byte |= src[0] & (1 << 7);
    897                 byte |= src[1] & (1 << 6);
    898                 byte |= src[2] & (1 << 5);
    899                 byte |= src[3] & (1 << 4);
    900                 byte |= src[4] & (1 << 3);
    901                 byte |= src[5] & (1 << 2);
    902                 byte |= src[6] & (1 << 1);
    903                 byte |= src[7] & (1 << 0);
    904                 dst[i] = byte;
    905                 src += 8;
    906             }
    907         }
    908         if (bitCount > 0) {
    909             unsigned byte = 0;
    910             unsigned mask = 0x80;
    911             for (int i = 0; i < bitCount; i++) {
    912                 byte |= (src[i]) & mask;
    913                 mask >>= 1;
    914             }
    915             dst[byteCount] = byte;
    916         }
    917         src += bitCount;
    918         dst += dstRB;
    919     }
    920 }
    921 
    922 template<bool APPLY_PREBLEND>
    923 static void rgb_to_a8(const uint8_t* SK_RESTRICT src, const SkGlyph& glyph, const uint8_t* table8) {
    924     const size_t dstRB = glyph.rowBytes();
    925     const U16CPU width = glyph.fWidth;
    926     uint8_t* SK_RESTRICT dst = static_cast<uint8_t*>(glyph.fImage);
    927 
    928     for (U16CPU y = 0; y < glyph.fHeight; y++) {
    929         for (U16CPU i = 0; i < width; i++) {
    930             U8CPU r = *(src++);
    931             U8CPU g = *(src++);
    932             U8CPU b = *(src++);
    933             dst[i] = sk_apply_lut_if<APPLY_PREBLEND>((r + g + b) / 3, table8);
    934         }
    935         dst = (uint8_t*)((char*)dst + dstRB);
    936     }
    937 }
    938 
    939 template<bool APPLY_PREBLEND>
    940 static void rgb_to_lcd16(const uint8_t* SK_RESTRICT src, const SkGlyph& glyph,
    941                          const uint8_t* tableR, const uint8_t* tableG, const uint8_t* tableB) {
    942     const size_t dstRB = glyph.rowBytes();
    943     const U16CPU width = glyph.fWidth;
    944     uint16_t* SK_RESTRICT dst = static_cast<uint16_t*>(glyph.fImage);
    945 
    946     for (U16CPU y = 0; y < glyph.fHeight; y++) {
    947         for (U16CPU i = 0; i < width; i++) {
    948             U8CPU r = sk_apply_lut_if<APPLY_PREBLEND>(*(src++), tableR);
    949             U8CPU g = sk_apply_lut_if<APPLY_PREBLEND>(*(src++), tableG);
    950             U8CPU b = sk_apply_lut_if<APPLY_PREBLEND>(*(src++), tableB);
    951             dst[i] = SkPack888ToRGB16(r, g, b);
    952         }
    953         dst = (uint16_t*)((char*)dst + dstRB);
    954     }
    955 }
    956 
    957 template<bool APPLY_PREBLEND>
    958 static void rgb_to_lcd32(const uint8_t* SK_RESTRICT src, const SkGlyph& glyph,
    959                          const uint8_t* tableR, const uint8_t* tableG, const uint8_t* tableB) {
    960     const size_t dstRB = glyph.rowBytes();
    961     const U16CPU width = glyph.fWidth;
    962     SkPMColor* SK_RESTRICT dst = static_cast<SkPMColor*>(glyph.fImage);
    963 
    964     for (U16CPU y = 0; y < glyph.fHeight; y++) {
    965         for (U16CPU i = 0; i < width; i++) {
    966             U8CPU r = sk_apply_lut_if<APPLY_PREBLEND>(*(src++), tableR);
    967             U8CPU g = sk_apply_lut_if<APPLY_PREBLEND>(*(src++), tableG);
    968             U8CPU b = sk_apply_lut_if<APPLY_PREBLEND>(*(src++), tableB);
    969             dst[i] = SkPackARGB32(0xFF, r, g, b);
    970         }
    971         dst = (SkPMColor*)((char*)dst + dstRB);
    972     }
    973 }
    974 
    975 void SkScalerContext_DW::generateImage(const SkGlyph& glyph) {
    976     const bool isBW = SkMask::kBW_Format == fRec.fMaskFormat;
    977     const bool isAA = !isLCD(fRec);
    978 
    979     //Create the mask.
    980     const void* bits = fOffscreen.draw(glyph, isBW);
    981     if (!bits) {
    982         sk_bzero(glyph.fImage, glyph.computeImageSize());
    983         return;
    984     }
    985 
    986     //Copy the mask into the glyph.
    987     const uint8_t* src = (const uint8_t*)bits;
    988     if (isBW) {
    989         bilevel_to_bw(src, glyph);
    990     } else if (isAA) {
    991         if (fPreBlend.isApplicable()) {
    992             rgb_to_a8<true>(src, glyph, fPreBlend.fG);
    993         } else {
    994             rgb_to_a8<false>(src, glyph, fPreBlend.fG);
    995         }
    996     } else if (SkMask::kLCD16_Format == glyph.fMaskFormat) {
    997         if (fPreBlend.isApplicable()) {
    998             rgb_to_lcd16<true>(src, glyph, fPreBlend.fR, fPreBlend.fG, fPreBlend.fB);
    999         } else {
   1000             rgb_to_lcd16<false>(src, glyph, fPreBlend.fR, fPreBlend.fG, fPreBlend.fB);
   1001         }
   1002     } else {
   1003         SkASSERT(SkMask::kLCD32_Format == glyph.fMaskFormat);
   1004         if (fPreBlend.isApplicable()) {
   1005             rgb_to_lcd32<true>(src, glyph, fPreBlend.fR, fPreBlend.fG, fPreBlend.fB);
   1006         } else {
   1007             rgb_to_lcd32<false>(src, glyph, fPreBlend.fR, fPreBlend.fG, fPreBlend.fB);
   1008         }
   1009     }
   1010 }
   1011 
   1012 void SkScalerContext_DW::generatePath(const SkGlyph& glyph, SkPath* path) {
   1013     SkASSERT(&glyph && path);
   1014 
   1015     path->reset();
   1016 
   1017     SkTScopedComPtr<IDWriteGeometrySink> geometryToPath;
   1018     HRVM(SkDWriteGeometrySink::Create(path, &geometryToPath),
   1019          "Could not create geometry to path converter.");
   1020     uint16_t glyphId = glyph.getGlyphID();
   1021     //TODO: convert to<->from DIUs? This would make a difference if hinting.
   1022     //It may not be needed, it appears that DirectWrite only hints at em size.
   1023     HRVM(fTypeface->fDWriteFontFace->GetGlyphRunOutline(SkScalarToFloat(fRec.fTextSize),
   1024                                        &glyphId,
   1025                                        NULL, //advances
   1026                                        NULL, //offsets
   1027                                        1, //num glyphs
   1028                                        FALSE, //sideways
   1029                                        FALSE, //rtl
   1030                                        geometryToPath.get()),
   1031          "Could not create glyph outline.");
   1032 
   1033     SkMatrix mat;
   1034     fRec.getMatrixFrom2x2(&mat);
   1035     path->transform(mat);
   1036 }
   1037 
   1038 void DWriteFontTypeface::onGetFontDescriptor(SkFontDescriptor* desc,
   1039                                              bool* isLocalStream) const {
   1040     // Get the family name.
   1041     SkTScopedComPtr<IDWriteLocalizedStrings> dwFamilyNames;
   1042     HRV(fDWriteFontFamily->GetFamilyNames(&dwFamilyNames));
   1043 
   1044     UINT32 dwFamilyNamesLength;
   1045     HRV(dwFamilyNames->GetStringLength(0, &dwFamilyNamesLength));
   1046 
   1047     SkSMallocWCHAR dwFamilyNameChar(dwFamilyNamesLength+1);
   1048     HRV(dwFamilyNames->GetString(0, dwFamilyNameChar.get(), dwFamilyNamesLength+1));
   1049 
   1050     SkString utf8FamilyName;
   1051     HRV(wchar_to_skstring(dwFamilyNameChar.get(), &utf8FamilyName));
   1052 
   1053     desc->setFamilyName(utf8FamilyName.c_str());
   1054     *isLocalStream = SkToBool(fDWriteFontFileLoader.get());
   1055 }
   1056 
   1057 static SkUnichar next_utf8(const void** chars) {
   1058     return SkUTF8_NextUnichar((const char**)chars);
   1059 }
   1060 
   1061 static SkUnichar next_utf16(const void** chars) {
   1062     return SkUTF16_NextUnichar((const uint16_t**)chars);
   1063 }
   1064 
   1065 static SkUnichar next_utf32(const void** chars) {
   1066     const SkUnichar** uniChars = (const SkUnichar**)chars;
   1067     SkUnichar uni = **uniChars;
   1068     *uniChars += 1;
   1069     return uni;
   1070 }
   1071 
   1072 typedef SkUnichar (*EncodingProc)(const void**);
   1073 
   1074 static EncodingProc find_encoding_proc(SkTypeface::Encoding enc) {
   1075     static const EncodingProc gProcs[] = {
   1076         next_utf8, next_utf16, next_utf32
   1077     };
   1078     SkASSERT((size_t)enc < SK_ARRAY_COUNT(gProcs));
   1079     return gProcs[enc];
   1080 }
   1081 
   1082 int DWriteFontTypeface::onCharsToGlyphs(const void* chars, Encoding encoding,
   1083                                         uint16_t glyphs[], int glyphCount) const
   1084 {
   1085     if (NULL == glyphs) {
   1086         EncodingProc next_ucs4_proc = find_encoding_proc(encoding);
   1087         for (int i = 0; i < glyphCount; ++i) {
   1088             const SkUnichar c = next_ucs4_proc(&chars);
   1089             BOOL exists;
   1090             fDWriteFont->HasCharacter(c, &exists);
   1091             if (!exists) {
   1092                 return i;
   1093             }
   1094         }
   1095         return glyphCount;
   1096     }
   1097 
   1098     switch (encoding) {
   1099     case SkTypeface::kUTF8_Encoding:
   1100     case SkTypeface::kUTF16_Encoding: {
   1101         static const int scratchCount = 256;
   1102         UINT32 scratch[scratchCount];
   1103         EncodingProc next_ucs4_proc = find_encoding_proc(encoding);
   1104         for (int baseGlyph = 0; baseGlyph < glyphCount; baseGlyph += scratchCount) {
   1105             int glyphsLeft = glyphCount - baseGlyph;
   1106             int limit = SkTMin(glyphsLeft, scratchCount);
   1107             for (int i = 0; i < limit; ++i) {
   1108                 scratch[i] = next_ucs4_proc(&chars);
   1109             }
   1110             fDWriteFontFace->GetGlyphIndices(scratch, limit, &glyphs[baseGlyph]);
   1111         }
   1112         break;
   1113     }
   1114     case SkTypeface::kUTF32_Encoding: {
   1115         const UINT32* utf32 = reinterpret_cast<const UINT32*>(chars);
   1116         fDWriteFontFace->GetGlyphIndices(utf32, glyphCount, glyphs);
   1117         break;
   1118     }
   1119     default:
   1120         SK_CRASH();
   1121     }
   1122 
   1123     for (int i = 0; i < glyphCount; ++i) {
   1124         if (0 == glyphs[i]) {
   1125             return i;
   1126         }
   1127     }
   1128     return glyphCount;
   1129 }
   1130 
   1131 int DWriteFontTypeface::onCountGlyphs() const {
   1132     return fDWriteFontFace->GetGlyphCount();
   1133 }
   1134 
   1135 int DWriteFontTypeface::onGetUPEM() const {
   1136     DWRITE_FONT_METRICS metrics;
   1137     fDWriteFontFace->GetMetrics(&metrics);
   1138     return metrics.designUnitsPerEm;
   1139 }
   1140 
   1141 class LocalizedStrings_IDWriteLocalizedStrings : public SkTypeface::LocalizedStrings {
   1142 public:
   1143     /** Takes ownership of the IDWriteLocalizedStrings. */
   1144     explicit LocalizedStrings_IDWriteLocalizedStrings(IDWriteLocalizedStrings* strings)
   1145         : fIndex(0), fStrings(strings)
   1146     { }
   1147 
   1148     virtual bool next(SkTypeface::LocalizedString* localizedString) SK_OVERRIDE {
   1149         if (fIndex >= fStrings->GetCount()) {
   1150             return false;
   1151         }
   1152 
   1153         // String
   1154         UINT32 stringLength;
   1155         HRBM(fStrings->GetStringLength(fIndex, &stringLength), "Could not get string length.");
   1156         stringLength += 1;
   1157 
   1158         SkSMallocWCHAR wString(stringLength);
   1159         HRBM(fStrings->GetString(fIndex, wString.get(), stringLength), "Could not get string.");
   1160 
   1161         HRB(wchar_to_skstring(wString.get(), &localizedString->fString));
   1162 
   1163         // Locale
   1164         UINT32 localeLength;
   1165         HRBM(fStrings->GetLocaleNameLength(fIndex, &localeLength), "Could not get locale length.");
   1166         localeLength += 1;
   1167 
   1168         SkSMallocWCHAR wLocale(localeLength);
   1169         HRBM(fStrings->GetLocaleName(fIndex, wLocale.get(), localeLength), "Could not get locale.");
   1170 
   1171         HRB(wchar_to_skstring(wLocale.get(), &localizedString->fLanguage));
   1172 
   1173         ++fIndex;
   1174         return true;
   1175     }
   1176 
   1177 private:
   1178     UINT32 fIndex;
   1179     SkTScopedComPtr<IDWriteLocalizedStrings> fStrings;
   1180 };
   1181 
   1182 SkTypeface::LocalizedStrings* DWriteFontTypeface::onCreateFamilyNameIterator() const {
   1183     SkTScopedComPtr<IDWriteLocalizedStrings> familyNames;
   1184     HRNM(fDWriteFontFamily->GetFamilyNames(&familyNames), "Could not obtain family names.");
   1185 
   1186     return new LocalizedStrings_IDWriteLocalizedStrings(familyNames.release());
   1187 }
   1188 
   1189 int DWriteFontTypeface::onGetTableTags(SkFontTableTag tags[]) const {
   1190     DWRITE_FONT_FACE_TYPE type = fDWriteFontFace->GetType();
   1191     if (type != DWRITE_FONT_FACE_TYPE_CFF &&
   1192         type != DWRITE_FONT_FACE_TYPE_TRUETYPE &&
   1193         type != DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION)
   1194     {
   1195         return 0;
   1196     }
   1197 
   1198     int ttcIndex;
   1199     SkAutoTUnref<SkStream> stream(this->openStream(&ttcIndex));
   1200     return stream.get() ? SkFontStream::GetTableTags(stream, ttcIndex, tags) : 0;
   1201 }
   1202 
   1203 class AutoDWriteTable {
   1204 public:
   1205     AutoDWriteTable(IDWriteFontFace* fontFace, UINT32 beTag) : fFontFace(fontFace), fExists(FALSE) {
   1206         // Any errors are ignored, user must check fExists anyway.
   1207         fontFace->TryGetFontTable(beTag,
   1208             reinterpret_cast<const void **>(&fData), &fSize, &fLock, &fExists);
   1209     }
   1210     ~AutoDWriteTable() {
   1211         if (fExists) {
   1212             fFontFace->ReleaseFontTable(fLock);
   1213         }
   1214     }
   1215 
   1216     const uint8_t* fData;
   1217     UINT32 fSize;
   1218     BOOL fExists;
   1219 private:
   1220     // Borrowed reference, the user must ensure the fontFace stays alive.
   1221     IDWriteFontFace* fFontFace;
   1222     void* fLock;
   1223 };
   1224 
   1225 size_t DWriteFontTypeface::onGetTableData(SkFontTableTag tag, size_t offset,
   1226                                           size_t length, void* data) const
   1227 {
   1228     AutoDWriteTable table(fDWriteFontFace.get(), SkEndian_SwapBE32(tag));
   1229     if (!table.fExists) {
   1230         return 0;
   1231     }
   1232 
   1233     if (offset > table.fSize) {
   1234         return 0;
   1235     }
   1236     size_t size = SkTMin(length, table.fSize - offset);
   1237     if (NULL != data) {
   1238         memcpy(data, table.fData + offset, size);
   1239     }
   1240 
   1241     return size;
   1242 }
   1243 
   1244 template <typename T> class SkAutoIDWriteUnregister {
   1245 public:
   1246     SkAutoIDWriteUnregister(IDWriteFactory* factory, T* unregister)
   1247         : fFactory(factory), fUnregister(unregister)
   1248     { }
   1249 
   1250     ~SkAutoIDWriteUnregister() {
   1251         if (fUnregister) {
   1252             unregister(fFactory, fUnregister);
   1253         }
   1254     }
   1255 
   1256     T* detatch() {
   1257         T* old = fUnregister;
   1258         fUnregister = NULL;
   1259         return old;
   1260     }
   1261 
   1262 private:
   1263     HRESULT unregister(IDWriteFactory* factory, IDWriteFontFileLoader* unregister) {
   1264         return factory->UnregisterFontFileLoader(unregister);
   1265     }
   1266 
   1267     HRESULT unregister(IDWriteFactory* factory, IDWriteFontCollectionLoader* unregister) {
   1268         return factory->UnregisterFontCollectionLoader(unregister);
   1269     }
   1270 
   1271     IDWriteFactory* fFactory;
   1272     T* fUnregister;
   1273 };
   1274 
   1275 static SkTypeface* create_from_stream(SkStream* stream, int ttcIndex) {
   1276     IDWriteFactory* factory = get_dwrite_factory();
   1277     if (NULL == factory) {
   1278         return NULL;
   1279     }
   1280 
   1281     SkTScopedComPtr<StreamFontFileLoader> fontFileLoader;
   1282     HRN(StreamFontFileLoader::Create(stream, &fontFileLoader));
   1283     HRN(factory->RegisterFontFileLoader(fontFileLoader.get()));
   1284     SkAutoIDWriteUnregister<StreamFontFileLoader> autoUnregisterFontFileLoader(
   1285         factory, fontFileLoader.get());
   1286 
   1287     SkTScopedComPtr<StreamFontCollectionLoader> fontCollectionLoader;
   1288     HRN(StreamFontCollectionLoader::Create(fontFileLoader.get(), &fontCollectionLoader));
   1289     HRN(factory->RegisterFontCollectionLoader(fontCollectionLoader.get()));
   1290     SkAutoIDWriteUnregister<StreamFontCollectionLoader> autoUnregisterFontCollectionLoader(
   1291         factory, fontCollectionLoader.get());
   1292 
   1293     SkTScopedComPtr<IDWriteFontCollection> fontCollection;
   1294     HRN(factory->CreateCustomFontCollection(fontCollectionLoader.get(), NULL, 0, &fontCollection));
   1295 
   1296     // Find the first non-simulated font which has the given ttc index.
   1297     UINT32 familyCount = fontCollection->GetFontFamilyCount();
   1298     for (UINT32 familyIndex = 0; familyIndex < familyCount; ++familyIndex) {
   1299         SkTScopedComPtr<IDWriteFontFamily> fontFamily;
   1300         HRN(fontCollection->GetFontFamily(familyIndex, &fontFamily));
   1301 
   1302         UINT32 fontCount = fontFamily->GetFontCount();
   1303         for (UINT32 fontIndex = 0; fontIndex < fontCount; ++fontIndex) {
   1304             SkTScopedComPtr<IDWriteFont> font;
   1305             HRN(fontFamily->GetFont(fontIndex, &font));
   1306             if (font->GetSimulations() != DWRITE_FONT_SIMULATIONS_NONE) {
   1307                 continue;
   1308             }
   1309 
   1310             SkTScopedComPtr<IDWriteFontFace> fontFace;
   1311             HRN(font->CreateFontFace(&fontFace));
   1312 
   1313             UINT32 faceIndex = fontFace->GetIndex();
   1314             if (faceIndex == ttcIndex) {
   1315                 return DWriteFontTypeface::Create(fontFace.get(), font.get(), fontFamily.get(),
   1316                                                   autoUnregisterFontFileLoader.detatch(),
   1317                                                   autoUnregisterFontCollectionLoader.detatch());
   1318             }
   1319         }
   1320     }
   1321 
   1322     return NULL;
   1323 }
   1324 
   1325 SkStream* DWriteFontTypeface::onOpenStream(int* ttcIndex) const {
   1326     *ttcIndex = fDWriteFontFace->GetIndex();
   1327 
   1328     UINT32 numFiles;
   1329     HRNM(fDWriteFontFace->GetFiles(&numFiles, NULL),
   1330          "Could not get number of font files.");
   1331     if (numFiles != 1) {
   1332         return NULL;
   1333     }
   1334 
   1335     SkTScopedComPtr<IDWriteFontFile> fontFile;
   1336     HRNM(fDWriteFontFace->GetFiles(&numFiles, &fontFile), "Could not get font files.");
   1337 
   1338     const void* fontFileKey;
   1339     UINT32 fontFileKeySize;
   1340     HRNM(fontFile->GetReferenceKey(&fontFileKey, &fontFileKeySize),
   1341          "Could not get font file reference key.");
   1342 
   1343     SkTScopedComPtr<IDWriteFontFileLoader> fontFileLoader;
   1344     HRNM(fontFile->GetLoader(&fontFileLoader), "Could not get font file loader.");
   1345 
   1346     SkTScopedComPtr<IDWriteFontFileStream> fontFileStream;
   1347     HRNM(fontFileLoader->CreateStreamFromKey(fontFileKey, fontFileKeySize,
   1348                                              &fontFileStream),
   1349          "Could not create font file stream.");
   1350 
   1351     return SkNEW_ARGS(SkDWriteFontFileStream, (fontFileStream.get()));
   1352 }
   1353 
   1354 SkScalerContext* DWriteFontTypeface::onCreateScalerContext(const SkDescriptor* desc) const {
   1355     return SkNEW_ARGS(SkScalerContext_DW, (const_cast<DWriteFontTypeface*>(this), desc));
   1356 }
   1357 
   1358 void DWriteFontTypeface::onFilterRec(SkScalerContext::Rec* rec) const {
   1359     if (rec->fFlags & SkScalerContext::kLCD_BGROrder_Flag ||
   1360         rec->fFlags & SkScalerContext::kLCD_Vertical_Flag)
   1361     {
   1362         rec->fMaskFormat = SkMask::kA8_Format;
   1363     }
   1364 
   1365     unsigned flagsWeDontSupport = SkScalerContext::kDevKernText_Flag |
   1366                                   SkScalerContext::kAutohinting_Flag |
   1367                                   SkScalerContext::kEmbeddedBitmapText_Flag |
   1368                                   SkScalerContext::kEmbolden_Flag |
   1369                                   SkScalerContext::kLCD_BGROrder_Flag |
   1370                                   SkScalerContext::kLCD_Vertical_Flag;
   1371     rec->fFlags &= ~flagsWeDontSupport;
   1372 
   1373     SkPaint::Hinting h = rec->getHinting();
   1374     // DirectWrite does not provide for hinting hints.
   1375     h = SkPaint::kSlight_Hinting;
   1376     rec->setHinting(h);
   1377 
   1378 #if SK_FONT_HOST_USE_SYSTEM_SETTINGS
   1379     IDWriteFactory* factory = get_dwrite_factory();
   1380     if (factory != NULL) {
   1381         SkTScopedComPtr<IDWriteRenderingParams> defaultRenderingParams;
   1382         if (SUCCEEDED(factory->CreateRenderingParams(&defaultRenderingParams))) {
   1383             float gamma = defaultRenderingParams->GetGamma();
   1384             rec->setDeviceGamma(gamma);
   1385             rec->setPaintGamma(gamma);
   1386 
   1387             rec->setContrast(defaultRenderingParams->GetEnhancedContrast());
   1388         }
   1389     }
   1390 #endif
   1391 }
   1392 
   1393 ///////////////////////////////////////////////////////////////////////////////
   1394 //PDF Support
   1395 
   1396 using namespace skia_advanced_typeface_metrics_utils;
   1397 
   1398 // Construct Glyph to Unicode table.
   1399 // Unicode code points that require conjugate pairs in utf16 are not
   1400 // supported.
   1401 // TODO(arthurhsu): Add support for conjugate pairs. It looks like that may
   1402 // require parsing the TTF cmap table (platform 4, encoding 12) directly instead
   1403 // of calling GetFontUnicodeRange().
   1404 // TODO(bungeman): This never does what anyone wants.
   1405 // What is really wanted is the text to glyphs mapping
   1406 static void populate_glyph_to_unicode(IDWriteFontFace* fontFace,
   1407                                       const unsigned glyphCount,
   1408                                       SkTDArray<SkUnichar>* glyphToUnicode) {
   1409     HRESULT hr = S_OK;
   1410 
   1411     //Do this like free type instead
   1412     UINT32 count = 0;
   1413     for (UINT32 c = 0; c < 0x10FFFF; ++c) {
   1414         UINT16 glyph;
   1415         hr = fontFace->GetGlyphIndices(&c, 1, &glyph);
   1416         if (glyph > 0) {
   1417             ++count;
   1418         }
   1419     }
   1420 
   1421     SkAutoTArray<UINT32> chars(count);
   1422     count = 0;
   1423     for (UINT32 c = 0; c < 0x10FFFF; ++c) {
   1424         UINT16 glyph;
   1425         hr = fontFace->GetGlyphIndices(&c, 1, &glyph);
   1426         if (glyph > 0) {
   1427             chars[count] = c;
   1428             ++count;
   1429         }
   1430     }
   1431 
   1432     SkAutoTArray<UINT16> glyph(count);
   1433     fontFace->GetGlyphIndices(chars.get(), count, glyph.get());
   1434 
   1435     USHORT maxGlyph = 0;
   1436     for (USHORT j = 0; j < count; ++j) {
   1437         if (glyph[j] > maxGlyph) maxGlyph = glyph[j];
   1438     }
   1439 
   1440     glyphToUnicode->setCount(maxGlyph+1);
   1441     for (USHORT j = 0; j < maxGlyph+1u; ++j) {
   1442         (*glyphToUnicode)[j] = 0;
   1443     }
   1444 
   1445     //'invert'
   1446     for (USHORT j = 0; j < count; ++j) {
   1447         if (glyph[j] < glyphCount && (*glyphToUnicode)[glyph[j]] == 0) {
   1448             (*glyphToUnicode)[glyph[j]] = chars[j];
   1449         }
   1450     }
   1451 }
   1452 
   1453 static bool getWidthAdvance(IDWriteFontFace* fontFace, int gId, int16_t* advance) {
   1454     SkASSERT(advance);
   1455 
   1456     UINT16 glyphId = gId;
   1457     DWRITE_GLYPH_METRICS gm;
   1458     HRESULT hr = fontFace->GetDesignGlyphMetrics(&glyphId, 1, &gm);
   1459 
   1460     if (FAILED(hr)) {
   1461         *advance = 0;
   1462         return false;
   1463     }
   1464 
   1465     *advance = gm.advanceWidth;
   1466     return true;
   1467 }
   1468 
   1469 template<typename T> class AutoTDWriteTable : public AutoDWriteTable {
   1470 public:
   1471     static const UINT32 tag = DWRITE_MAKE_OPENTYPE_TAG(T::TAG0, T::TAG1, T::TAG2, T::TAG3);
   1472     AutoTDWriteTable(IDWriteFontFace* fontFace) : AutoDWriteTable(fontFace, tag) { }
   1473 
   1474     const T* operator->() const { return reinterpret_cast<const T*>(fData); }
   1475 };
   1476 
   1477 SkAdvancedTypefaceMetrics* DWriteFontTypeface::onGetAdvancedTypefaceMetrics(
   1478         SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo,
   1479         const uint32_t* glyphIDs,
   1480         uint32_t glyphIDsCount) const {
   1481 
   1482     SkAdvancedTypefaceMetrics* info = NULL;
   1483 
   1484     HRESULT hr = S_OK;
   1485 
   1486     const unsigned glyphCount = fDWriteFontFace->GetGlyphCount();
   1487 
   1488     DWRITE_FONT_METRICS dwfm;
   1489     fDWriteFontFace->GetMetrics(&dwfm);
   1490 
   1491     info = new SkAdvancedTypefaceMetrics;
   1492     info->fEmSize = dwfm.designUnitsPerEm;
   1493     info->fMultiMaster = false;
   1494     info->fLastGlyphID = SkToU16(glyphCount - 1);
   1495     info->fStyle = 0;
   1496 
   1497 
   1498     SkTScopedComPtr<IDWriteLocalizedStrings> familyNames;
   1499     SkTScopedComPtr<IDWriteLocalizedStrings> faceNames;
   1500     hr = fDWriteFontFamily->GetFamilyNames(&familyNames);
   1501     hr = fDWriteFont->GetFaceNames(&faceNames);
   1502 
   1503     UINT32 familyNameLength;
   1504     hr = familyNames->GetStringLength(0, &familyNameLength);
   1505 
   1506     UINT32 faceNameLength;
   1507     hr = faceNames->GetStringLength(0, &faceNameLength);
   1508 
   1509     UINT32 size = familyNameLength+1+faceNameLength+1;
   1510     SkSMallocWCHAR wFamilyName(size);
   1511     hr = familyNames->GetString(0, wFamilyName.get(), size);
   1512     wFamilyName[familyNameLength] = L' ';
   1513     hr = faceNames->GetString(0, &wFamilyName[familyNameLength+1], size - faceNameLength + 1);
   1514 
   1515     hr = wchar_to_skstring(wFamilyName.get(), &info->fFontName);
   1516 
   1517     if (perGlyphInfo & SkAdvancedTypefaceMetrics::kToUnicode_PerGlyphInfo) {
   1518         populate_glyph_to_unicode(fDWriteFontFace.get(), glyphCount, &(info->fGlyphToUnicode));
   1519     }
   1520 
   1521     DWRITE_FONT_FACE_TYPE fontType = fDWriteFontFace->GetType();
   1522     if (fontType == DWRITE_FONT_FACE_TYPE_TRUETYPE ||
   1523         fontType == DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION) {
   1524         info->fType = SkAdvancedTypefaceMetrics::kTrueType_Font;
   1525     } else {
   1526         info->fType = SkAdvancedTypefaceMetrics::kOther_Font;
   1527         info->fItalicAngle = 0;
   1528         info->fAscent = dwfm.ascent;;
   1529         info->fDescent = dwfm.descent;
   1530         info->fStemV = 0;
   1531         info->fCapHeight = dwfm.capHeight;
   1532         info->fBBox = SkIRect::MakeEmpty();
   1533         return info;
   1534     }
   1535 
   1536     AutoTDWriteTable<SkOTTableHead> headTable(fDWriteFontFace.get());
   1537     AutoTDWriteTable<SkOTTablePostScript> postTable(fDWriteFontFace.get());
   1538     AutoTDWriteTable<SkOTTableHorizontalHeader> hheaTable(fDWriteFontFace.get());
   1539     AutoTDWriteTable<SkOTTableOS2> os2Table(fDWriteFontFace.get());
   1540     if (!headTable.fExists || !postTable.fExists || !hheaTable.fExists || !os2Table.fExists) {
   1541         info->fItalicAngle = 0;
   1542         info->fAscent = dwfm.ascent;;
   1543         info->fDescent = dwfm.descent;
   1544         info->fStemV = 0;
   1545         info->fCapHeight = dwfm.capHeight;
   1546         info->fBBox = SkIRect::MakeEmpty();
   1547         return info;
   1548     }
   1549 
   1550     //There exist CJK fonts which set the IsFixedPitch and Monospace bits,
   1551     //but have full width, latin half-width, and half-width kana.
   1552     bool fixedWidth = (postTable->isFixedPitch &&
   1553                       (1 == SkEndian_SwapBE16(hheaTable->numberOfHMetrics)));
   1554     //Monospace
   1555     if (fixedWidth) {
   1556         info->fStyle |= SkAdvancedTypefaceMetrics::kFixedPitch_Style;
   1557     }
   1558     //Italic
   1559     if (os2Table->version.v0.fsSelection.field.Italic) {
   1560         info->fStyle |= SkAdvancedTypefaceMetrics::kItalic_Style;
   1561     }
   1562     //Script
   1563     if (SkPanose::FamilyType::Script == os2Table->version.v0.panose.bFamilyType.value) {
   1564         info->fStyle |= SkAdvancedTypefaceMetrics::kScript_Style;
   1565     //Serif
   1566     } else if (SkPanose::FamilyType::TextAndDisplay == os2Table->version.v0.panose.bFamilyType.value &&
   1567                SkPanose::Data::TextAndDisplay::SerifStyle::Triangle <= os2Table->version.v0.panose.data.textAndDisplay.bSerifStyle.value &&
   1568                SkPanose::Data::TextAndDisplay::SerifStyle::NoFit != os2Table->version.v0.panose.data.textAndDisplay.bSerifStyle.value) {
   1569         info->fStyle |= SkAdvancedTypefaceMetrics::kSerif_Style;
   1570     }
   1571 
   1572     info->fItalicAngle = SkEndian_SwapBE32(postTable->italicAngle) >> 16;
   1573 
   1574     info->fAscent = SkToS16(dwfm.ascent);
   1575     info->fDescent = SkToS16(dwfm.descent);
   1576     info->fCapHeight = SkToS16(dwfm.capHeight);
   1577 
   1578     info->fBBox = SkIRect::MakeLTRB((int32_t)SkEndian_SwapBE16((uint16_t)headTable->xMin),
   1579                                     (int32_t)SkEndian_SwapBE16((uint16_t)headTable->yMax),
   1580                                     (int32_t)SkEndian_SwapBE16((uint16_t)headTable->xMax),
   1581                                     (int32_t)SkEndian_SwapBE16((uint16_t)headTable->yMin));
   1582 
   1583     //TODO: is this even desired? It seems PDF only wants this value for Type1
   1584     //fonts, and we only get here for TrueType fonts.
   1585     info->fStemV = 0;
   1586     /*
   1587     // Figure out a good guess for StemV - Min width of i, I, !, 1.
   1588     // This probably isn't very good with an italic font.
   1589     int16_t min_width = SHRT_MAX;
   1590     info->fStemV = 0;
   1591     char stem_chars[] = {'i', 'I', '!', '1'};
   1592     for (size_t i = 0; i < SK_ARRAY_COUNT(stem_chars); i++) {
   1593         ABC abcWidths;
   1594         if (GetCharABCWidths(hdc, stem_chars[i], stem_chars[i], &abcWidths)) {
   1595             int16_t width = abcWidths.abcB;
   1596             if (width > 0 && width < min_width) {
   1597                 min_width = width;
   1598                 info->fStemV = min_width;
   1599             }
   1600         }
   1601     }
   1602     */
   1603 
   1604     // If Restricted, the font may not be embedded in a document.
   1605     // If not Restricted, the font can be embedded.
   1606     // If PreviewPrint, the embedding is read-only.
   1607     if (os2Table->version.v0.fsType.field.Restricted) {
   1608         info->fType = SkAdvancedTypefaceMetrics::kNotEmbeddable_Font;
   1609     } else if (perGlyphInfo & SkAdvancedTypefaceMetrics::kHAdvance_PerGlyphInfo) {
   1610         if (fixedWidth) {
   1611             appendRange(&info->fGlyphWidths, 0);
   1612             int16_t advance;
   1613             getWidthAdvance(fDWriteFontFace.get(), 1, &advance);
   1614             info->fGlyphWidths->fAdvance.append(1, &advance);
   1615             finishRange(info->fGlyphWidths.get(), 0,
   1616                         SkAdvancedTypefaceMetrics::WidthRange::kDefault);
   1617         } else {
   1618             info->fGlyphWidths.reset(
   1619                 getAdvanceData(fDWriteFontFace.get(),
   1620                                glyphCount,
   1621                                glyphIDs,
   1622                                glyphIDsCount,
   1623                                getWidthAdvance));
   1624         }
   1625     }
   1626 
   1627     return info;
   1628 }
   1629 
   1630 ///////////////////////////////////////////////////////////////////////////////
   1631 
   1632 static void get_locale_string(IDWriteLocalizedStrings* names, const WCHAR* preferedLocale,
   1633                               SkString* skname) {
   1634     UINT32 nameIndex = 0;
   1635     if (preferedLocale) {
   1636         // Ignore any errors and continue with index 0 if there is a problem.
   1637         BOOL nameExists;
   1638         names->FindLocaleName(preferedLocale, &nameIndex, &nameExists);
   1639         if (!nameExists) {
   1640             nameIndex = 0;
   1641         }
   1642     }
   1643 
   1644     UINT32 nameLength;
   1645     HRVM(names->GetStringLength(nameIndex, &nameLength), "Could not get name length.");
   1646     nameLength += 1;
   1647 
   1648     SkSMallocWCHAR name(nameLength);
   1649     HRVM(names->GetString(nameIndex, name.get(), nameLength), "Could not get string.");
   1650 
   1651     HRV(wchar_to_skstring(name.get(), skname));
   1652 }
   1653 
   1654 SkTypeface* SkFontMgr_DirectWrite::createTypefaceFromDWriteFont(
   1655                                            IDWriteFontFace* fontFace,
   1656                                            IDWriteFont* font,
   1657                                            IDWriteFontFamily* fontFamily,
   1658                                            StreamFontFileLoader* fontFileLoader,
   1659                                            IDWriteFontCollectionLoader* fontCollectionLoader) {
   1660     SkTypeface* face = FindByProcAndRef(FindByDWriteFont, font);
   1661     if (NULL == face) {
   1662         face = DWriteFontTypeface::Create(fontFace, font, fontFamily,
   1663                                           fontFileLoader, fontCollectionLoader);
   1664         if (face) {
   1665             Add(face, get_style(font), fontCollectionLoader != NULL);
   1666         }
   1667     }
   1668     return face;
   1669 }
   1670 
   1671 int SkFontMgr_DirectWrite::onCountFamilies() {
   1672     return fFontCollection->GetFontFamilyCount();
   1673 }
   1674 
   1675 void SkFontMgr_DirectWrite::onGetFamilyName(int index, SkString* familyName) {
   1676     SkTScopedComPtr<IDWriteFontFamily> fontFamily;
   1677     HRVM(fFontCollection->GetFontFamily(index, &fontFamily), "Could not get requested family.");
   1678 
   1679     SkTScopedComPtr<IDWriteLocalizedStrings> familyNames;
   1680     HRVM(fontFamily->GetFamilyNames(&familyNames), "Could not get family names.");
   1681 
   1682     get_locale_string(familyNames.get(), fLocaleName.get(), familyName);
   1683 }
   1684 
   1685 SkFontStyleSet* SkFontMgr_DirectWrite::onCreateStyleSet(int index) {
   1686     SkTScopedComPtr<IDWriteFontFamily> fontFamily;
   1687     HRNM(fFontCollection->GetFontFamily(index, &fontFamily), "Could not get requested family.");
   1688 
   1689     return SkNEW_ARGS(SkFontStyleSet_DirectWrite, (this, fontFamily.get()));
   1690 }
   1691 
   1692 SkFontStyleSet* SkFontMgr_DirectWrite::onMatchFamily(const char familyName[]) {
   1693     SkSMallocWCHAR dwFamilyName;
   1694     HRN(cstring_to_wchar(familyName, &dwFamilyName));
   1695 
   1696     UINT32 index;
   1697     BOOL exists;
   1698     HRNM(fFontCollection->FindFamilyName(dwFamilyName.get(), &index, &exists),
   1699             "Failed while finding family by name.");
   1700     if (!exists) {
   1701         return NULL;
   1702     }
   1703 
   1704     return this->onCreateStyleSet(index);
   1705 }
   1706 
   1707 SkTypeface* SkFontMgr_DirectWrite::onMatchFamilyStyle(const char familyName[],
   1708                                                       const SkFontStyle& fontstyle) {
   1709     SkAutoTUnref<SkFontStyleSet> sset(this->matchFamily(familyName));
   1710     return sset->matchStyle(fontstyle);
   1711 }
   1712 
   1713 SkTypeface* SkFontMgr_DirectWrite::onMatchFaceStyle(const SkTypeface* familyMember,
   1714                                                     const SkFontStyle& fontstyle) {
   1715     SkString familyName;
   1716     SkFontStyleSet_DirectWrite sset(
   1717         this, ((DWriteFontTypeface*)familyMember)->fDWriteFontFamily.get()
   1718     );
   1719     return sset.matchStyle(fontstyle);
   1720 }
   1721 
   1722 SkTypeface* SkFontMgr_DirectWrite::onCreateFromStream(SkStream* stream, int ttcIndex) {
   1723     return create_from_stream(stream, ttcIndex);
   1724 }
   1725 
   1726 SkTypeface* SkFontMgr_DirectWrite::onCreateFromData(SkData* data, int ttcIndex) {
   1727     SkAutoTUnref<SkStream> stream(SkNEW_ARGS(SkMemoryStream, (data)));
   1728     return this->createFromStream(stream, ttcIndex);
   1729 }
   1730 
   1731 SkTypeface* SkFontMgr_DirectWrite::onCreateFromFile(const char path[], int ttcIndex) {
   1732     SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path));
   1733     return this->createFromStream(stream, ttcIndex);
   1734 }
   1735 
   1736 HRESULT SkFontMgr_DirectWrite::getByFamilyName(const WCHAR wideFamilyName[],
   1737                                                IDWriteFontFamily** fontFamily) {
   1738     UINT32 index;
   1739     BOOL exists;
   1740     HR(fFontCollection->FindFamilyName(wideFamilyName, &index, &exists));
   1741 
   1742     if (exists) {
   1743         HR(fFontCollection->GetFontFamily(index, fontFamily));
   1744         return S_OK;
   1745     }
   1746     return S_FALSE;
   1747 }
   1748 
   1749 HRESULT SkFontMgr_DirectWrite::getDefaultFontFamily(IDWriteFontFamily** fontFamily) {
   1750     NONCLIENTMETRICSW metrics;
   1751     metrics.cbSize = sizeof(metrics);
   1752     if (0 == SystemParametersInfoW(SPI_GETNONCLIENTMETRICS,
   1753                                    sizeof(metrics),
   1754                                    &metrics,
   1755                                    0)) {
   1756         return E_UNEXPECTED;
   1757     }
   1758     HRM(this->getByFamilyName(metrics.lfMessageFont.lfFaceName, fontFamily),
   1759         "Could not create DWrite font family from LOGFONT.");
   1760 
   1761     return S_OK;
   1762 }
   1763 
   1764 SkTypeface* SkFontMgr_DirectWrite::onLegacyCreateTypeface(const char familyName[],
   1765                                                           unsigned styleBits) {
   1766     SkTScopedComPtr<IDWriteFontFamily> fontFamily;
   1767     if (familyName) {
   1768         SkSMallocWCHAR wideFamilyName;
   1769         if (SUCCEEDED(cstring_to_wchar(familyName, &wideFamilyName))) {
   1770             this->getByFamilyName(wideFamilyName, &fontFamily);
   1771         }
   1772     }
   1773 
   1774     if (NULL == fontFamily.get()) {
   1775         // No family with given name, try default.
   1776         HRNM(this->getDefaultFontFamily(&fontFamily), "Could not get default font family.");
   1777     }
   1778 
   1779     SkTScopedComPtr<IDWriteFont> font;
   1780     DWRITE_FONT_WEIGHT weight = (styleBits & SkTypeface::kBold)
   1781                               ? DWRITE_FONT_WEIGHT_BOLD
   1782                               : DWRITE_FONT_WEIGHT_NORMAL;
   1783     DWRITE_FONT_STRETCH stretch = DWRITE_FONT_STRETCH_UNDEFINED;
   1784     DWRITE_FONT_STYLE italic = (styleBits & SkTypeface::kItalic)
   1785                              ? DWRITE_FONT_STYLE_ITALIC
   1786                              : DWRITE_FONT_STYLE_NORMAL;
   1787     HRNM(fontFamily->GetFirstMatchingFont(weight, stretch, italic, &font),
   1788          "Could not get matching font.");
   1789 
   1790     SkTScopedComPtr<IDWriteFontFace> fontFace;
   1791     HRNM(font->CreateFontFace(&fontFace), "Could not create font face.");
   1792 
   1793     return this->createTypefaceFromDWriteFont(fontFace.get(), font.get(), fontFamily.get());
   1794 }
   1795 
   1796 ///////////////////////////////////////////////////////////////////////////////
   1797 
   1798 int SkFontStyleSet_DirectWrite::count() {
   1799     return fFontFamily->GetFontCount();
   1800 }
   1801 
   1802 SkTypeface* SkFontStyleSet_DirectWrite::createTypeface(int index) {
   1803     SkTScopedComPtr<IDWriteFont> font;
   1804     HRNM(fFontFamily->GetFont(index, &font), "Could not get font.");
   1805 
   1806     SkTScopedComPtr<IDWriteFontFace> fontFace;
   1807     HRNM(font->CreateFontFace(&fontFace), "Could not create font face.");
   1808 
   1809     return fFontMgr->createTypefaceFromDWriteFont(fontFace.get(), font.get(), fFontFamily.get());
   1810 }
   1811 
   1812 void SkFontStyleSet_DirectWrite::getStyle(int index, SkFontStyle* fs, SkString* styleName) {
   1813     SkTScopedComPtr<IDWriteFont> font;
   1814     HRVM(fFontFamily->GetFont(index, &font), "Could not get font.");
   1815 
   1816     SkFontStyle::Slant slant;
   1817     switch (font->GetStyle()) {
   1818     case DWRITE_FONT_STYLE_NORMAL:
   1819         slant = SkFontStyle::kUpright_Slant;
   1820         break;
   1821     case DWRITE_FONT_STYLE_OBLIQUE:
   1822     case DWRITE_FONT_STYLE_ITALIC:
   1823         slant = SkFontStyle::kItalic_Slant;
   1824         break;
   1825     default:
   1826         SkASSERT(false);
   1827     }
   1828 
   1829     int weight = font->GetWeight();
   1830     int width = font->GetStretch();
   1831 
   1832     *fs = SkFontStyle(weight, width, slant);
   1833 
   1834     SkTScopedComPtr<IDWriteLocalizedStrings> faceNames;
   1835     if (SUCCEEDED(font->GetFaceNames(&faceNames))) {
   1836         get_locale_string(faceNames.get(), fFontMgr->fLocaleName.get(), styleName);
   1837     }
   1838 }
   1839 
   1840 SkTypeface* SkFontStyleSet_DirectWrite::matchStyle(const SkFontStyle& pattern) {
   1841     DWRITE_FONT_STYLE slant;
   1842     switch (pattern.slant()) {
   1843     case SkFontStyle::kUpright_Slant:
   1844         slant = DWRITE_FONT_STYLE_NORMAL;
   1845         break;
   1846     case SkFontStyle::kItalic_Slant:
   1847         slant = DWRITE_FONT_STYLE_ITALIC;
   1848         break;
   1849     default:
   1850         SkASSERT(false);
   1851     }
   1852 
   1853     DWRITE_FONT_WEIGHT weight = (DWRITE_FONT_WEIGHT)pattern.weight();
   1854     DWRITE_FONT_STRETCH width = (DWRITE_FONT_STRETCH)pattern.width();
   1855 
   1856     SkTScopedComPtr<IDWriteFont> font;
   1857     // TODO: perhaps use GetMatchingFonts and get the least simulated?
   1858     HRNM(fFontFamily->GetFirstMatchingFont(weight, width, slant, &font),
   1859             "Could not match font in family.");
   1860 
   1861     SkTScopedComPtr<IDWriteFontFace> fontFace;
   1862     HRNM(font->CreateFontFace(&fontFace), "Could not create font face.");
   1863 
   1864     return fFontMgr->createTypefaceFromDWriteFont(fontFace.get(), font.get(),
   1865                                                   fFontFamily.get());
   1866 }
   1867 
   1868 ///////////////////////////////////////////////////////////////////////////////
   1869 
   1870 typedef decltype(GetUserDefaultLocaleName)* GetUserDefaultLocaleNameProc;
   1871 static HRESULT GetGetUserDefaultLocaleNameProc(GetUserDefaultLocaleNameProc* proc) {
   1872     *proc = reinterpret_cast<GetUserDefaultLocaleNameProc>(
   1873         GetProcAddress(LoadLibraryW(L"Kernel32.dll"), "GetUserDefaultLocaleName")
   1874     );
   1875     if (!*proc) {
   1876         HRESULT hr = HRESULT_FROM_WIN32(GetLastError());
   1877         if (!IS_ERROR(hr)) {
   1878             hr = ERROR_PROC_NOT_FOUND;
   1879         }
   1880         return hr;
   1881     }
   1882     return S_OK;
   1883 }
   1884 
   1885 SkFontMgr* SkFontMgr_New_DirectWrite() {
   1886     IDWriteFactory* factory = get_dwrite_factory();
   1887     if (NULL == factory) {
   1888         return NULL;
   1889     }
   1890 
   1891     SkTScopedComPtr<IDWriteFontCollection> sysFontCollection;
   1892     HRNM(factory->GetSystemFontCollection(&sysFontCollection, FALSE),
   1893          "Could not get system font collection.");
   1894 
   1895     WCHAR localeNameStorage[LOCALE_NAME_MAX_LENGTH];
   1896     WCHAR* localeName = NULL;
   1897     int localeNameLen = 0;
   1898 
   1899     // Dynamically load GetUserDefaultLocaleName function, as it is not available on XP.
   1900     GetUserDefaultLocaleNameProc getUserDefaultLocaleNameProc = NULL;
   1901     HRESULT hr = GetGetUserDefaultLocaleNameProc(&getUserDefaultLocaleNameProc);
   1902     if (NULL == getUserDefaultLocaleNameProc) {
   1903         SK_TRACEHR(hr, "Could not get GetUserDefaultLocaleName.");
   1904     } else {
   1905         localeNameLen = getUserDefaultLocaleNameProc(localeNameStorage, LOCALE_NAME_MAX_LENGTH);
   1906         if (localeNameLen) {
   1907             localeName = localeNameStorage;
   1908         };
   1909     }
   1910 
   1911     return SkNEW_ARGS(SkFontMgr_DirectWrite, (sysFontCollection.get(), localeName, localeNameLen));
   1912 }
   1913