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