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 "SkGlyph.h"
     20 #include "SkHRESULT.h"
     21 #include "SkMaskGamma.h"
     22 #include "SkOTTable_head.h"
     23 #include "SkOTTable_hhea.h"
     24 #include "SkOTTable_OS_2.h"
     25 #include "SkOTTable_post.h"
     26 #include "SkPath.h"
     27 #include "SkStream.h"
     28 #include "SkString.h"
     29 #include "SkTScopedComPtr.h"
     30 #include "SkThread.h"
     31 #include "SkTypeface_win.h"
     32 #include "SkTypefaceCache.h"
     33 #include "SkUtils.h"
     34 
     35 #include <dwrite.h>
     36 
     37 SK_DECLARE_STATIC_MUTEX(gFTMutex);
     38 
     39 static bool isLCD(const SkScalerContext::Rec& rec) {
     40     return SkMask::kLCD16_Format == rec.fMaskFormat ||
     41            SkMask::kLCD32_Format == rec.fMaskFormat;
     42 }
     43 
     44 SkFontID SkFontHost::NextLogicalFont(SkFontID currFontID, SkFontID origFontID) {
     45   // Zero means that we don't have any fallback fonts for this fontID.
     46   // This function is implemented on Android, but doesn't have much
     47   // meaning here.
     48   return 0;
     49 }
     50 
     51 ///////////////////////////////////////////////////////////////////////////////
     52 
     53 class DWriteOffscreen {
     54 public:
     55     DWriteOffscreen() : fWidth(0), fHeight(0) {
     56     }
     57 
     58     void init(IDWriteFontFace* fontFace, const DWRITE_MATRIX& xform, FLOAT fontSize) {
     59         fFontFace = fontFace;
     60         fFontSize = fontSize;
     61         fXform = xform;
     62     }
     63 
     64     const void* draw(const SkGlyph&, bool isBW);
     65 
     66 private:
     67     uint16_t fWidth;
     68     uint16_t fHeight;
     69     IDWriteFontFace* fFontFace;
     70     FLOAT fFontSize;
     71     DWRITE_MATRIX fXform;
     72     SkTDArray<uint8_t> fBits;
     73 };
     74 
     75 typedef HRESULT (WINAPI *DWriteCreateFactoryProc)(
     76     __in DWRITE_FACTORY_TYPE factoryType,
     77     __in REFIID iid,
     78     __out IUnknown **factory
     79 );
     80 
     81 static HRESULT get_dwrite_factory(IDWriteFactory** factory) {
     82     static IDWriteFactory* gDWriteFactory = NULL;
     83 
     84     if (gDWriteFactory != NULL) {
     85         *factory = gDWriteFactory;
     86         return S_OK;
     87     }
     88 
     89     DWriteCreateFactoryProc dWriteCreateFactoryProc =
     90         reinterpret_cast<DWriteCreateFactoryProc>(
     91             GetProcAddress(LoadLibraryW(L"dwrite.dll"), "DWriteCreateFactory")
     92         )
     93     ;
     94 
     95     if (!dWriteCreateFactoryProc) {
     96         return E_UNEXPECTED;
     97     }
     98 
     99     HRM(dWriteCreateFactoryProc(DWRITE_FACTORY_TYPE_SHARED,
    100                                 __uuidof(IDWriteFactory),
    101                                 reinterpret_cast<IUnknown**>(&gDWriteFactory)),
    102         "Could not create DirectWrite factory.");
    103 
    104     *factory = gDWriteFactory;
    105     return S_OK;
    106 }
    107 
    108 const void* DWriteOffscreen::draw(const SkGlyph& glyph, bool isBW) {
    109     IDWriteFactory* factory;
    110     HRNM(get_dwrite_factory(&factory), "Could not get factory.");
    111 
    112     if (fWidth < glyph.fWidth || fHeight < glyph.fHeight) {
    113         fWidth = SkMax32(fWidth, glyph.fWidth);
    114         fHeight = SkMax32(fHeight, glyph.fHeight);
    115 
    116         if (isBW) {
    117             fBits.setCount(fWidth * fHeight);
    118         } else {
    119             fBits.setCount(fWidth * fHeight * 3);
    120         }
    121     }
    122 
    123     // erase
    124     memset(fBits.begin(), 0, fBits.count());
    125 
    126     fXform.dx = SkFixedToFloat(glyph.getSubXFixed());
    127     fXform.dy = SkFixedToFloat(glyph.getSubYFixed());
    128 
    129     FLOAT advance = 0.0f;
    130 
    131     UINT16 index = glyph.getGlyphID();
    132 
    133     DWRITE_GLYPH_OFFSET offset;
    134     offset.advanceOffset = 0.0f;
    135     offset.ascenderOffset = 0.0f;
    136 
    137     DWRITE_GLYPH_RUN run;
    138     run.glyphCount = 1;
    139     run.glyphAdvances = &advance;
    140     run.fontFace = fFontFace;
    141     run.fontEmSize = fFontSize;
    142     run.bidiLevel = 0;
    143     run.glyphIndices = &index;
    144     run.isSideways = FALSE;
    145     run.glyphOffsets = &offset;
    146 
    147     DWRITE_RENDERING_MODE renderingMode;
    148     DWRITE_TEXTURE_TYPE textureType;
    149     if (isBW) {
    150         renderingMode = DWRITE_RENDERING_MODE_ALIASED;
    151         textureType = DWRITE_TEXTURE_ALIASED_1x1;
    152     } else {
    153         renderingMode = DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC;
    154         textureType = DWRITE_TEXTURE_CLEARTYPE_3x1;
    155     }
    156     SkTScopedComPtr<IDWriteGlyphRunAnalysis> glyphRunAnalysis;
    157     HRNM(factory->CreateGlyphRunAnalysis(&run,
    158                                          1.0f, // pixelsPerDip,
    159                                          &fXform,
    160                                          renderingMode,
    161                                          DWRITE_MEASURING_MODE_NATURAL,
    162                                          0.0f, // baselineOriginX,
    163                                          0.0f, // baselineOriginY,
    164                                          &glyphRunAnalysis),
    165          "Could not create glyph run analysis.");
    166 
    167     //NOTE: this assumes that the glyph has already been measured
    168     //with an exact same glyph run analysis.
    169     RECT bbox;
    170     bbox.left = glyph.fLeft;
    171     bbox.top = glyph.fTop;
    172     bbox.right = glyph.fLeft + glyph.fWidth;
    173     bbox.bottom = glyph.fTop + glyph.fHeight;
    174     HRNM(glyphRunAnalysis->CreateAlphaTexture(textureType,
    175                                               &bbox,
    176                                               fBits.begin(),
    177                                               fBits.count()),
    178          "Could not draw mask.");
    179     return fBits.begin();
    180 }
    181 
    182 ///////////////////////////////////////////////////////////////////////////////
    183 
    184 class StreamFontFileLoader : public IDWriteFontFileLoader {
    185 public:
    186     // IUnknown methods
    187     virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject);
    188     virtual ULONG STDMETHODCALLTYPE AddRef();
    189     virtual ULONG STDMETHODCALLTYPE Release();
    190 
    191     // IDWriteFontFileLoader methods
    192     virtual HRESULT STDMETHODCALLTYPE CreateStreamFromKey(
    193         void const* fontFileReferenceKey,
    194         UINT32 fontFileReferenceKeySize,
    195         IDWriteFontFileStream** fontFileStream);
    196 
    197     static HRESULT Create(SkStream* stream, StreamFontFileLoader** streamFontFileLoader) {
    198         *streamFontFileLoader = new StreamFontFileLoader(stream);
    199         if (NULL == streamFontFileLoader) {
    200             return E_OUTOFMEMORY;
    201         }
    202         return S_OK;
    203     }
    204 
    205     SkAutoTUnref<SkStream> fStream;
    206 
    207 private:
    208     StreamFontFileLoader(SkStream* stream) : fRefCount(1), fStream(stream) {
    209         stream->ref();
    210     }
    211 
    212     ULONG fRefCount;
    213 };
    214 
    215 HRESULT StreamFontFileLoader::QueryInterface(REFIID iid, void** ppvObject) {
    216     if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileLoader)) {
    217         *ppvObject = this;
    218         AddRef();
    219         return S_OK;
    220     } else {
    221         *ppvObject = NULL;
    222         return E_NOINTERFACE;
    223     }
    224 }
    225 
    226 ULONG StreamFontFileLoader::AddRef() {
    227     return InterlockedIncrement(&fRefCount);
    228 }
    229 
    230 ULONG StreamFontFileLoader::Release() {
    231     ULONG newCount = InterlockedDecrement(&fRefCount);
    232     if (0 == newCount) {
    233         delete this;
    234     }
    235     return newCount;
    236 }
    237 
    238 HRESULT StreamFontFileLoader::CreateStreamFromKey(
    239     void const* fontFileReferenceKey,
    240     UINT32 fontFileReferenceKeySize,
    241     IDWriteFontFileStream** fontFileStream)
    242 {
    243     SkTScopedComPtr<SkDWriteFontFileStreamWrapper> stream;
    244     HR(SkDWriteFontFileStreamWrapper::Create(fStream, &stream));
    245     *fontFileStream = stream.release();
    246     return S_OK;
    247 }
    248 
    249 class StreamFontFileEnumerator : public IDWriteFontFileEnumerator {
    250 public:
    251     // IUnknown methods
    252     virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject);
    253     virtual ULONG STDMETHODCALLTYPE AddRef();
    254     virtual ULONG STDMETHODCALLTYPE Release();
    255 
    256     // IDWriteFontFileEnumerator methods
    257     virtual HRESULT STDMETHODCALLTYPE MoveNext(BOOL* hasCurrentFile);
    258     virtual HRESULT STDMETHODCALLTYPE GetCurrentFontFile(IDWriteFontFile** fontFile);
    259 
    260     static HRESULT Create(IDWriteFactory* factory, IDWriteFontFileLoader* fontFileLoader,
    261                           StreamFontFileEnumerator** streamFontFileEnumerator) {
    262         *streamFontFileEnumerator = new StreamFontFileEnumerator(factory, fontFileLoader);
    263         if (NULL == streamFontFileEnumerator) {
    264             return E_OUTOFMEMORY;
    265         }
    266         return S_OK;
    267     }
    268 private:
    269     StreamFontFileEnumerator(IDWriteFactory* factory, IDWriteFontFileLoader* fontFileLoader);
    270     ULONG fRefCount;
    271 
    272     SkTScopedComPtr<IDWriteFactory> fFactory;
    273     SkTScopedComPtr<IDWriteFontFile> fCurrentFile;
    274     SkTScopedComPtr<IDWriteFontFileLoader> fFontFileLoader;
    275     bool fHasNext;
    276 };
    277 
    278 StreamFontFileEnumerator::StreamFontFileEnumerator(IDWriteFactory* factory,
    279                                                    IDWriteFontFileLoader* fontFileLoader)
    280     : fRefCount(1)
    281     , fFactory(factory)
    282     , fCurrentFile()
    283     , fFontFileLoader(fontFileLoader)
    284     , fHasNext(true)
    285 {
    286     factory->AddRef();
    287     fontFileLoader->AddRef();
    288 }
    289 
    290 HRESULT StreamFontFileEnumerator::QueryInterface(REFIID iid, void** ppvObject) {
    291     if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileEnumerator)) {
    292         *ppvObject = this;
    293         AddRef();
    294         return S_OK;
    295     } else {
    296         *ppvObject = NULL;
    297         return E_NOINTERFACE;
    298     }
    299 }
    300 
    301 ULONG StreamFontFileEnumerator::AddRef() {
    302     return InterlockedIncrement(&fRefCount);
    303 }
    304 
    305 ULONG StreamFontFileEnumerator::Release() {
    306     ULONG newCount = InterlockedDecrement(&fRefCount);
    307     if (0 == newCount) {
    308         delete this;
    309     }
    310     return newCount;
    311 }
    312 
    313 HRESULT StreamFontFileEnumerator::MoveNext(BOOL* hasCurrentFile) {
    314     *hasCurrentFile = FALSE;
    315 
    316     if (!fHasNext) {
    317         return S_OK;
    318     }
    319     fHasNext = false;
    320 
    321     UINT32 dummy = 0;
    322     HR(fFactory->CreateCustomFontFileReference(
    323             &dummy, //cannot be NULL
    324             sizeof(dummy), //even if this is 0
    325             fFontFileLoader.get(),
    326             &fCurrentFile));
    327 
    328     *hasCurrentFile = TRUE;
    329     return S_OK;
    330 }
    331 
    332 HRESULT StreamFontFileEnumerator::GetCurrentFontFile(IDWriteFontFile** fontFile) {
    333     if (fCurrentFile.get() == NULL) {
    334         *fontFile = NULL;
    335         return E_FAIL;
    336     }
    337 
    338     fCurrentFile.get()->AddRef();
    339     *fontFile = fCurrentFile.get();
    340     return  S_OK;
    341 }
    342 
    343 class StreamFontCollectionLoader : public IDWriteFontCollectionLoader {
    344 public:
    345     // IUnknown methods
    346     virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObject);
    347     virtual ULONG STDMETHODCALLTYPE AddRef();
    348     virtual ULONG STDMETHODCALLTYPE Release();
    349 
    350     // IDWriteFontCollectionLoader methods
    351     virtual HRESULT STDMETHODCALLTYPE CreateEnumeratorFromKey(
    352         IDWriteFactory* factory,
    353         void const* collectionKey,
    354         UINT32 collectionKeySize,
    355         IDWriteFontFileEnumerator** fontFileEnumerator);
    356 
    357     static HRESULT Create(IDWriteFontFileLoader* fontFileLoader,
    358                           StreamFontCollectionLoader** streamFontCollectionLoader) {
    359         *streamFontCollectionLoader = new StreamFontCollectionLoader(fontFileLoader);
    360         if (NULL == streamFontCollectionLoader) {
    361             return E_OUTOFMEMORY;
    362         }
    363         return S_OK;
    364     }
    365 private:
    366     StreamFontCollectionLoader(IDWriteFontFileLoader* fontFileLoader)
    367         : fRefCount(1)
    368         , fFontFileLoader(fontFileLoader)
    369     {
    370         fontFileLoader->AddRef();
    371     }
    372 
    373     ULONG fRefCount;
    374     SkTScopedComPtr<IDWriteFontFileLoader> fFontFileLoader;
    375 };
    376 
    377 HRESULT StreamFontCollectionLoader::QueryInterface(REFIID iid, void** ppvObject) {
    378     if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontCollectionLoader)) {
    379         *ppvObject = this;
    380         AddRef();
    381         return S_OK;
    382     } else {
    383         *ppvObject = NULL;
    384         return E_NOINTERFACE;
    385     }
    386 }
    387 
    388 ULONG StreamFontCollectionLoader::AddRef() {
    389     return InterlockedIncrement(&fRefCount);
    390 }
    391 
    392 ULONG StreamFontCollectionLoader::Release() {
    393     ULONG newCount = InterlockedDecrement(&fRefCount);
    394     if (0 == newCount) {
    395         delete this;
    396     }
    397     return newCount;
    398 }
    399 
    400 HRESULT StreamFontCollectionLoader::CreateEnumeratorFromKey(
    401     IDWriteFactory* factory,
    402     void const* collectionKey,
    403     UINT32 collectionKeySize,
    404     IDWriteFontFileEnumerator** fontFileEnumerator)
    405 {
    406     SkTScopedComPtr<StreamFontFileEnumerator> enumerator;
    407     HR(StreamFontFileEnumerator::Create(factory, fFontFileLoader.get(), &enumerator));
    408     *fontFileEnumerator = enumerator.release();
    409     return S_OK;
    410 }
    411 
    412 ///////////////////////////////////////////////////////////////////////////////
    413 
    414 static SkTypeface::Style get_style(IDWriteFont* font) {
    415     int style = SkTypeface::kNormal;
    416     DWRITE_FONT_WEIGHT weight = font->GetWeight();
    417     if (DWRITE_FONT_WEIGHT_DEMI_BOLD <= weight) {
    418         style |= SkTypeface::kBold;
    419     }
    420     DWRITE_FONT_STYLE angle = font->GetStyle();
    421     if (DWRITE_FONT_STYLE_OBLIQUE == angle || DWRITE_FONT_STYLE_ITALIC == angle) {
    422         style |= SkTypeface::kItalic;
    423     }
    424     return static_cast<SkTypeface::Style>(style);
    425 }
    426 
    427 class DWriteFontTypeface : public SkTypeface {
    428 private:
    429     DWriteFontTypeface(SkTypeface::Style style, SkFontID fontID,
    430                        IDWriteFontFace* fontFace,
    431                        IDWriteFont* font,
    432                        IDWriteFontFamily* fontFamily,
    433                        StreamFontFileLoader* fontFileLoader = NULL,
    434                        IDWriteFontCollectionLoader* fontCollectionLoader = NULL)
    435         : SkTypeface(style, fontID, false)
    436         , fDWriteFontCollectionLoader(fontCollectionLoader)
    437         , fDWriteFontFileLoader(fontFileLoader)
    438         , fDWriteFontFamily(fontFamily)
    439         , fDWriteFont(font)
    440         , fDWriteFontFace(fontFace) {
    441 
    442         if (fontCollectionLoader != NULL) {
    443             fontCollectionLoader->AddRef();
    444         }
    445         if (fontFileLoader != NULL) {
    446             fontFileLoader->AddRef();
    447         }
    448         fontFamily->AddRef();
    449         font->AddRef();
    450         fontFace->AddRef();
    451     }
    452 
    453 public:
    454     SkTScopedComPtr<IDWriteFontCollectionLoader> fDWriteFontCollectionLoader;
    455     SkTScopedComPtr<StreamFontFileLoader> fDWriteFontFileLoader;
    456     SkTScopedComPtr<IDWriteFontFamily> fDWriteFontFamily;
    457     SkTScopedComPtr<IDWriteFont> fDWriteFont;
    458     SkTScopedComPtr<IDWriteFontFace> fDWriteFontFace;
    459 
    460     static DWriteFontTypeface* Create(IDWriteFontFace* fontFace,
    461                                       IDWriteFont* font,
    462                                       IDWriteFontFamily* fontFamily,
    463                                       StreamFontFileLoader* fontFileLoader = NULL,
    464                                       IDWriteFontCollectionLoader* fontCollectionLoader = NULL) {
    465         SkTypeface::Style style = get_style(font);
    466         SkFontID fontID = SkTypefaceCache::NewFontID();
    467         return SkNEW_ARGS(DWriteFontTypeface, (style, fontID,
    468                                                fontFace, font, fontFamily,
    469                                                fontFileLoader, fontCollectionLoader));
    470     }
    471 
    472     ~DWriteFontTypeface() {
    473         if (fDWriteFontCollectionLoader.get() == NULL) return;
    474 
    475         IDWriteFactory* factory;
    476         HRVM(get_dwrite_factory(&factory), "Could not get factory.");
    477         HRV(factory->UnregisterFontCollectionLoader(fDWriteFontCollectionLoader.get()));
    478         HRV(factory->UnregisterFontFileLoader(fDWriteFontFileLoader.get()));
    479     }
    480 };
    481 
    482 class SkScalerContext_Windows : public SkScalerContext {
    483 public:
    484     SkScalerContext_Windows(const SkDescriptor* desc);
    485     virtual ~SkScalerContext_Windows();
    486 
    487 protected:
    488     virtual unsigned generateGlyphCount() SK_OVERRIDE;
    489     virtual uint16_t generateCharToGlyph(SkUnichar uni) SK_OVERRIDE;
    490     virtual void generateAdvance(SkGlyph* glyph) SK_OVERRIDE;
    491     virtual void generateMetrics(SkGlyph* glyph) SK_OVERRIDE;
    492     virtual void generateImage(const SkGlyph& glyph) SK_OVERRIDE;
    493     virtual void generatePath(const SkGlyph& glyph, SkPath* path) SK_OVERRIDE;
    494     virtual void generateFontMetrics(SkPaint::FontMetrics* mX,
    495                                      SkPaint::FontMetrics* mY) SK_OVERRIDE;
    496 
    497 private:
    498     DWriteOffscreen fOffscreen;
    499     DWRITE_MATRIX fXform;
    500     SkAutoTUnref<DWriteFontTypeface> fTypeface;
    501     int fGlyphCount;
    502 };
    503 
    504 #define SK_DWRITE_DEFAULT_FONT_NAMED 1
    505 #define SK_DWRITE_DEFAULT_FONT_MESSAGE 2
    506 #define SK_DWRITE_DEFAULT_FONT_THEME 3
    507 #define SK_DWRITE_DEFAULT_FONT_SHELLDLG 4
    508 #define SK_DWRITE_DEFAULT_FONT_GDI 5
    509 #define SK_DWRITE_DEFAULT_FONT_STRATEGY SK_DWRITE_DEFAULT_FONT_MESSAGE
    510 
    511 static HRESULT get_default_font(IDWriteFont** font) {
    512     IDWriteFactory* factory;
    513     HRM(get_dwrite_factory(&factory), "Could not get factory.");
    514 
    515 #if SK_DWRITE_DEFAULT_FONT_STRATEGY == SK_DWRITE_DEFAULT_FONT_NAMED
    516     SkTScopedComPtr<IDWriteFontCollection> sysFonts;
    517     HRM(factory->GetSystemFontCollection(&sysFonts, false),
    518         "Could not get system font collection.");
    519 
    520     UINT32 index;
    521     BOOL exists;
    522     //hr = sysFonts->FindFamilyName(L"Georgia", &index, &exists);
    523     HRM(sysFonts->FindFamilyName(L"Microsoft Sans Serif", &index, &exists),
    524         "Could not access family names.");
    525 
    526     if (!exists) {
    527         SkDEBUGF(("The hard coded font family does not exist."));
    528         return E_UNEXPECTED;
    529     }
    530 
    531     SkTScopedComPtr<IDWriteFontFamily> fontFamily;
    532     HRM(sysFonts->GetFontFamily(index, &fontFamily),
    533         "Could not load the requested font family.");
    534 
    535     HRM(fontFamily->GetFont(0, font), "Could not get first font from family.");
    536 
    537 #elif SK_DWRITE_DEFAULT_FONT_STRATEGY == SK_DWRITE_DEFAULT_FONT_MESSAGE
    538     SkTScopedComPtr<IDWriteGdiInterop> gdi;
    539     HRM(factory->GetGdiInterop(&gdi), "Could not get GDI interop.");
    540 
    541     NONCLIENTMETRICSW metrics;
    542     metrics.cbSize = sizeof(metrics);
    543     if (0 == SystemParametersInfoW(SPI_GETNONCLIENTMETRICS,
    544                                    sizeof(metrics),
    545                                    &metrics,
    546                                    0)) {
    547         return E_UNEXPECTED;
    548     }
    549     HRM(gdi->CreateFontFromLOGFONT(&metrics.lfMessageFont, font),
    550         "Could not create DWrite font from LOGFONT.");
    551 
    552 #elif SK_DWRITE_DEFAULT_FONT_STRATEGY == SK_DWRITE_DEFAULT_FONT_THEME
    553     //Theme body font?
    554 
    555 #elif SK_DWRITE_DEFAULT_FONT_STRATEGY == SK_DWRITE_DEFAULT_FONT_SHELLDLG
    556     //"MS Shell Dlg" or "MS Shell Dlg 2"?
    557 
    558 #elif SK_DWRITE_DEFAULT_FONT_STRATEGY == SK_DWRITE_DEFAULT_FONT_GDI
    559     //Never works.
    560     SkTScopedComPtr<IDWriteGdiInterop> gdi;
    561     HRM(factory->GetGdiInterop(&gdi), "Could not get GDI interop.");
    562 
    563     static LOGFONTW gDefaultFont = {};
    564     gDefaultFont.lfFaceName
    565     HRM(gdi->CreateFontFromLOGFONT(&gDefaultFont, font),
    566         "Could not create DWrite font from LOGFONT.";
    567 #endif
    568     return S_OK;
    569 }
    570 
    571 static bool are_same(IUnknown* a, IUnknown* b) {
    572     SkTScopedComPtr<IUnknown> iunkA;
    573     if (FAILED(a->QueryInterface(&iunkA))) {
    574         return false;
    575     }
    576 
    577     SkTScopedComPtr<IUnknown> iunkB;
    578     if (FAILED(b->QueryInterface(&iunkB))) {
    579         return false;
    580     }
    581 
    582     return iunkA.get() == iunkB.get();
    583 }
    584 static bool FindByDWriteFont(SkTypeface* face, SkTypeface::Style requestedStyle, void* ctx) {
    585     //Check to see if the two fonts are identical.
    586     DWriteFontTypeface* dwFace = reinterpret_cast<DWriteFontTypeface*>(face);
    587     IDWriteFont* dwFont = reinterpret_cast<IDWriteFont*>(ctx);
    588     if (are_same(dwFace->fDWriteFont.get(), dwFont)) {
    589         return true;
    590     }
    591 
    592     //Check if the two fonts share the same loader and have the same key.
    593     SkTScopedComPtr<IDWriteFontFace> dwFaceFontFace;
    594     SkTScopedComPtr<IDWriteFontFace> dwFontFace;
    595     HRB(dwFace->fDWriteFont->CreateFontFace(&dwFaceFontFace));
    596     HRB(dwFont->CreateFontFace(&dwFontFace));
    597     if (are_same(dwFaceFontFace.get(), dwFontFace.get())) {
    598         return true;
    599     }
    600 
    601     UINT32 dwFaceNumFiles;
    602     UINT32 dwNumFiles;
    603     HRB(dwFaceFontFace->GetFiles(&dwFaceNumFiles, NULL));
    604     HRB(dwFontFace->GetFiles(&dwNumFiles, NULL));
    605     if (dwFaceNumFiles != dwNumFiles) {
    606         return false;
    607     }
    608 
    609     SkTScopedComPtr<IDWriteFontFile> dwFaceFontFile;
    610     SkTScopedComPtr<IDWriteFontFile> dwFontFile;
    611     HRB(dwFaceFontFace->GetFiles(&dwFaceNumFiles, &dwFaceFontFile));
    612     HRB(dwFontFace->GetFiles(&dwNumFiles, &dwFontFile));
    613 
    614     //for (each file) { //we currently only admit fonts from one file.
    615     SkTScopedComPtr<IDWriteFontFileLoader> dwFaceFontFileLoader;
    616     SkTScopedComPtr<IDWriteFontFileLoader> dwFontFileLoader;
    617     HRB(dwFaceFontFile->GetLoader(&dwFaceFontFileLoader));
    618     HRB(dwFontFile->GetLoader(&dwFontFileLoader));
    619     if (!are_same(dwFaceFontFileLoader.get(), dwFontFileLoader.get())) {
    620         return false;
    621     }
    622     //}
    623 
    624     const void* dwFaceFontRefKey;
    625     UINT32 dwFaceFontRefKeySize;
    626     const void* dwFontRefKey;
    627     UINT32 dwFontRefKeySize;
    628     HRB(dwFaceFontFile->GetReferenceKey(&dwFaceFontRefKey, &dwFaceFontRefKeySize));
    629     HRB(dwFontFile->GetReferenceKey(&dwFontRefKey, &dwFontRefKeySize));
    630     if (dwFaceFontRefKeySize != dwFontRefKeySize) {
    631         return false;
    632     }
    633     if (0 != memcmp(dwFaceFontRefKey, dwFontRefKey, dwFontRefKeySize)) {
    634         return false;
    635     }
    636 
    637     //TODO: better means than comparing name strings?
    638     //NOTE: .tfc and fake bold/italic will end up here.
    639     SkTScopedComPtr<IDWriteFontFamily> dwFaceFontFamily;
    640     SkTScopedComPtr<IDWriteFontFamily> dwFontFamily;
    641     HRB(dwFace->fDWriteFont->GetFontFamily(&dwFaceFontFamily));
    642     HRB(dwFont->GetFontFamily(&dwFontFamily));
    643 
    644     SkTScopedComPtr<IDWriteLocalizedStrings> dwFaceFontFamilyNames;
    645     SkTScopedComPtr<IDWriteLocalizedStrings> dwFaceFontNames;
    646     HRB(dwFaceFontFamily->GetFamilyNames(&dwFaceFontFamilyNames));
    647     HRB(dwFace->fDWriteFont->GetFaceNames(&dwFaceFontNames));
    648 
    649     SkTScopedComPtr<IDWriteLocalizedStrings> dwFontFamilyNames;
    650     SkTScopedComPtr<IDWriteLocalizedStrings> dwFontNames;
    651     HRB(dwFontFamily->GetFamilyNames(&dwFontFamilyNames));
    652     HRB(dwFont->GetFaceNames(&dwFontNames));
    653 
    654     UINT32 dwFaceFontFamilyNameLength;
    655     UINT32 dwFaceFontNameLength;
    656     HRB(dwFaceFontFamilyNames->GetStringLength(0, &dwFaceFontFamilyNameLength));
    657     HRB(dwFaceFontNames->GetStringLength(0, &dwFaceFontNameLength));
    658 
    659     UINT32 dwFontFamilyNameLength;
    660     UINT32 dwFontNameLength;
    661     HRB(dwFontFamilyNames->GetStringLength(0, &dwFontFamilyNameLength));
    662     HRB(dwFontNames->GetStringLength(0, &dwFontNameLength));
    663 
    664     if (dwFaceFontFamilyNameLength != dwFontFamilyNameLength ||
    665         dwFaceFontNameLength != dwFontNameLength)
    666     {
    667         return false;
    668     }
    669 
    670     SkTDArray<wchar_t> dwFaceFontFamilyNameChar(new wchar_t[dwFaceFontFamilyNameLength+1], dwFaceFontFamilyNameLength+1);
    671     SkTDArray<wchar_t> dwFaceFontNameChar(new wchar_t[dwFaceFontNameLength+1], dwFaceFontNameLength+1);
    672     HRB(dwFaceFontFamilyNames->GetString(0, dwFaceFontFamilyNameChar.begin(), dwFaceFontFamilyNameChar.count()));
    673     HRB(dwFaceFontNames->GetString(0, dwFaceFontNameChar.begin(), dwFaceFontNameChar.count()));
    674 
    675     SkTDArray<wchar_t> dwFontFamilyNameChar(new wchar_t[dwFontFamilyNameLength+1], dwFontFamilyNameLength+1);
    676     SkTDArray<wchar_t> dwFontNameChar(new wchar_t[dwFontNameLength+1], dwFontNameLength+1);
    677     HRB(dwFontFamilyNames->GetString(0, dwFontFamilyNameChar.begin(), dwFontFamilyNameChar.count()));
    678     HRB(dwFontNames->GetString(0, dwFontNameChar.begin(), dwFontNameChar.count()));
    679 
    680     return wcscmp(dwFaceFontFamilyNameChar.begin(), dwFontFamilyNameChar.begin()) == 0 &&
    681            wcscmp(dwFaceFontNameChar.begin(), dwFontNameChar.begin()) == 0;
    682 }
    683 
    684 SkTypeface* SkCreateTypefaceFromDWriteFont(IDWriteFontFace* fontFace,
    685                                            IDWriteFont* font,
    686                                            IDWriteFontFamily* fontFamily,
    687                                            StreamFontFileLoader* fontFileLoader = NULL,
    688                                            IDWriteFontCollectionLoader* fontCollectionLoader = NULL) {
    689     SkTypeface* face = SkTypefaceCache::FindByProcAndRef(FindByDWriteFont, font);
    690     if (NULL == face) {
    691         face = DWriteFontTypeface::Create(fontFace, font, fontFamily,
    692                                           fontFileLoader, fontCollectionLoader);
    693         SkTypefaceCache::Add(face, get_style(font), fontCollectionLoader != NULL);
    694     }
    695     return face;
    696 }
    697 
    698 void SkDWriteFontFromTypeface(const SkTypeface* face, IDWriteFont** font) {
    699     if (NULL == face) {
    700         HRVM(get_default_font(font), "Could not get default font.");
    701     } else {
    702         *font = static_cast<const DWriteFontTypeface*>(face)->fDWriteFont.get();
    703         (*font)->AddRef();
    704     }
    705 }
    706 static DWriteFontTypeface* GetDWriteFontByID(SkFontID fontID) {
    707     return static_cast<DWriteFontTypeface*>(SkTypefaceCache::FindByID(fontID));
    708 }
    709 
    710 SkScalerContext_Windows::SkScalerContext_Windows(const SkDescriptor* desc)
    711         : SkScalerContext(desc)
    712         , fGlyphCount(-1) {
    713     SkAutoMutexAcquire ac(gFTMutex);
    714 
    715     fXform.m11 = SkScalarToFloat(fRec.fPost2x2[0][0]);
    716     fXform.m12 = SkScalarToFloat(fRec.fPost2x2[1][0]);
    717     fXform.m21 = SkScalarToFloat(fRec.fPost2x2[0][1]);
    718     fXform.m22 = SkScalarToFloat(fRec.fPost2x2[1][1]);
    719     fXform.dx = 0;
    720     fXform.dy = 0;
    721 
    722     fTypeface.reset(GetDWriteFontByID(fRec.fFontID));
    723     fTypeface.get()->ref();
    724 
    725     fOffscreen.init(fTypeface->fDWriteFontFace.get(), fXform, SkScalarToFloat(fRec.fTextSize));
    726 }
    727 
    728 SkScalerContext_Windows::~SkScalerContext_Windows() {
    729 }
    730 
    731 unsigned SkScalerContext_Windows::generateGlyphCount() {
    732     if (fGlyphCount < 0) {
    733         fGlyphCount = fTypeface->fDWriteFontFace->GetGlyphCount();
    734     }
    735     return fGlyphCount;
    736 }
    737 
    738 uint16_t SkScalerContext_Windows::generateCharToGlyph(SkUnichar uni) {
    739     uint16_t index = 0;
    740     fTypeface->fDWriteFontFace->GetGlyphIndices(reinterpret_cast<UINT32*>(&uni), 1, &index);
    741     return index;
    742 }
    743 
    744 void SkScalerContext_Windows::generateAdvance(SkGlyph* glyph) {
    745     //Delta is the difference between the right/left side bearing metric
    746     //and where the right/left side bearing ends up after hinting.
    747     //DirectWrite does not provide this information.
    748     glyph->fRsbDelta = 0;
    749     glyph->fLsbDelta = 0;
    750 
    751     glyph->fAdvanceX = 0;
    752     glyph->fAdvanceY = 0;
    753 
    754     uint16_t glyphId = glyph->getGlyphID();
    755     DWRITE_GLYPH_METRICS gm;
    756     HRVM(fTypeface->fDWriteFontFace->GetDesignGlyphMetrics(&glyphId, 1, &gm),
    757          "Could not get design metrics.");
    758 
    759     DWRITE_FONT_METRICS dwfm;
    760     fTypeface->fDWriteFontFace->GetMetrics(&dwfm);
    761 
    762     SkScalar advanceX = SkScalarMulDiv(fRec.fTextSize,
    763                                        SkIntToScalar(gm.advanceWidth),
    764                                        SkIntToScalar(dwfm.designUnitsPerEm));
    765 
    766     if (!(fRec.fFlags & kSubpixelPositioning_Flag)) {
    767         advanceX = SkScalarRoundToScalar(advanceX);
    768     }
    769 
    770     SkVector vecs[1] = { { advanceX, 0 } };
    771     SkMatrix mat;
    772     fRec.getMatrixFrom2x2(&mat);
    773     mat.mapVectors(vecs, SK_ARRAY_COUNT(vecs));
    774 
    775     glyph->fAdvanceX = SkScalarToFixed(vecs[0].fX);
    776     glyph->fAdvanceY = SkScalarToFixed(vecs[0].fY);
    777 }
    778 
    779 void SkScalerContext_Windows::generateMetrics(SkGlyph* glyph) {
    780     glyph->fWidth = 0;
    781 
    782     this->generateAdvance(glyph);
    783 
    784     //Measure raster size.
    785     fXform.dx = SkFixedToFloat(glyph->getSubXFixed());
    786     fXform.dy = SkFixedToFloat(glyph->getSubYFixed());
    787 
    788     FLOAT advance = 0;
    789 
    790     UINT16 glyphId = glyph->getGlyphID();
    791 
    792     DWRITE_GLYPH_OFFSET offset;
    793     offset.advanceOffset = 0.0f;
    794     offset.ascenderOffset = 0.0f;
    795 
    796     DWRITE_GLYPH_RUN run;
    797     run.glyphCount = 1;
    798     run.glyphAdvances = &advance;
    799     run.fontFace = fTypeface->fDWriteFontFace.get();
    800     run.fontEmSize = SkScalarToFloat(fRec.fTextSize);
    801     run.bidiLevel = 0;
    802     run.glyphIndices = &glyphId;
    803     run.isSideways = FALSE;
    804     run.glyphOffsets = &offset;
    805 
    806     IDWriteFactory* factory;
    807     HRVM(get_dwrite_factory(&factory), "Could not get factory.");
    808 
    809     const bool isBW = SkMask::kBW_Format == fRec.fMaskFormat;
    810     DWRITE_RENDERING_MODE renderingMode;
    811     DWRITE_TEXTURE_TYPE textureType;
    812     if (isBW) {
    813         renderingMode = DWRITE_RENDERING_MODE_ALIASED;
    814         textureType = DWRITE_TEXTURE_ALIASED_1x1;
    815     } else {
    816         renderingMode = DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC;
    817         textureType = DWRITE_TEXTURE_CLEARTYPE_3x1;
    818     }
    819 
    820     SkTScopedComPtr<IDWriteGlyphRunAnalysis> glyphRunAnalysis;
    821     HRVM(factory->CreateGlyphRunAnalysis(&run,
    822                                          1.0f, // pixelsPerDip,
    823                                          &fXform,
    824                                          renderingMode,
    825                                          DWRITE_MEASURING_MODE_NATURAL,
    826                                          0.0f, // baselineOriginX,
    827                                          0.0f, // baselineOriginY,
    828                                          &glyphRunAnalysis),
    829          "Could not create glyph run analysis.");
    830 
    831     RECT bbox;
    832     HRVM(glyphRunAnalysis->GetAlphaTextureBounds(textureType, &bbox),
    833          "Could not get texture bounds.");
    834 
    835     glyph->fWidth = SkToU16(bbox.right - bbox.left);
    836     glyph->fHeight = SkToU16(bbox.bottom - bbox.top);
    837     glyph->fLeft = SkToS16(bbox.left);
    838     glyph->fTop = SkToS16(bbox.top);
    839 }
    840 
    841 void SkScalerContext_Windows::generateFontMetrics(SkPaint::FontMetrics* mx,
    842                                                   SkPaint::FontMetrics* my) {
    843     if (!(mx || my))
    844       return;
    845 
    846     DWRITE_FONT_METRICS dwfm;
    847     fTypeface->fDWriteFontFace->GetMetrics(&dwfm);
    848 
    849     if (mx) {
    850         mx->fTop = SkScalarMulDiv(-fRec.fTextSize,
    851                                   SkIntToScalar(dwfm.ascent),
    852                                   SkIntToScalar(dwfm.designUnitsPerEm));
    853         mx->fAscent = mx->fTop;
    854         mx->fDescent = SkScalarMulDiv(fRec.fTextSize,
    855                                       SkIntToScalar(dwfm.descent),
    856                                       SkIntToScalar(dwfm.designUnitsPerEm));
    857         mx->fBottom = mx->fDescent;
    858         //TODO, can be less than zero
    859         mx->fLeading = SkScalarMulDiv(fRec.fTextSize,
    860                                       SkIntToScalar(dwfm.lineGap),
    861                                       SkIntToScalar(dwfm.designUnitsPerEm));
    862     }
    863 
    864     if (my) {
    865         my->fTop = SkScalarMulDiv(-fRec.fTextSize,
    866                                   SkIntToScalar(dwfm.ascent),
    867                                   SkIntToScalar(dwfm.designUnitsPerEm));
    868         my->fAscent = my->fTop;
    869         my->fDescent = SkScalarMulDiv(fRec.fTextSize,
    870                                       SkIntToScalar(dwfm.descent),
    871                                       SkIntToScalar(dwfm.designUnitsPerEm));
    872         my->fBottom = my->fDescent;
    873         //TODO, can be less than zero
    874         my->fLeading = SkScalarMulDiv(fRec.fTextSize,
    875                                       SkIntToScalar(dwfm.lineGap),
    876                                       SkIntToScalar(dwfm.designUnitsPerEm));
    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_Windows::generateImage(const SkGlyph& glyph) {
    976     SkAutoMutexAcquire ac(gFTMutex);
    977 
    978     const bool isBW = SkMask::kBW_Format == fRec.fMaskFormat;
    979     const bool isAA = !isLCD(fRec);
    980 
    981     //Create the mask.
    982     const void* bits = fOffscreen.draw(glyph, isBW);
    983     if (!bits) {
    984         sk_bzero(glyph.fImage, glyph.computeImageSize());
    985         return;
    986     }
    987 
    988     //Copy the mask into the glyph.
    989     int width = glyph.fWidth;
    990     size_t dstRB = glyph.rowBytes();
    991     const uint8_t* src = (const uint8_t*)bits;
    992     if (isBW) {
    993         bilevel_to_bw(src, glyph);
    994     } else if (isAA) {
    995         if (fPreBlend.isApplicable()) {
    996             rgb_to_a8<true>(src, glyph, fPreBlend.fG);
    997         } else {
    998             rgb_to_a8<false>(src, glyph, fPreBlend.fG);
    999         }
   1000     } else if (SkMask::kLCD16_Format == glyph.fMaskFormat) {
   1001         if (fPreBlend.isApplicable()) {
   1002             rgb_to_lcd16<true>(src, glyph, fPreBlend.fR, fPreBlend.fG, fPreBlend.fB);
   1003         } else {
   1004             rgb_to_lcd16<false>(src, glyph, fPreBlend.fR, fPreBlend.fG, fPreBlend.fB);
   1005         }
   1006     } else {
   1007         SkASSERT(SkMask::kLCD32_Format == glyph.fMaskFormat);
   1008         if (fPreBlend.isApplicable()) {
   1009             rgb_to_lcd32<true>(src, glyph, fPreBlend.fR, fPreBlend.fG, fPreBlend.fB);
   1010         } else {
   1011             rgb_to_lcd32<false>(src, glyph, fPreBlend.fR, fPreBlend.fG, fPreBlend.fB);
   1012         }
   1013     }
   1014 }
   1015 
   1016 void SkScalerContext_Windows::generatePath(const SkGlyph& glyph, SkPath* path) {
   1017     SkAutoMutexAcquire ac(gFTMutex);
   1018 
   1019     SkASSERT(&glyph && path);
   1020 
   1021     path->reset();
   1022 
   1023     SkTScopedComPtr<IDWriteGeometrySink> geometryToPath;
   1024     HRVM(SkDWriteGeometrySink::Create(path, &geometryToPath),
   1025          "Could not create geometry to path converter.");
   1026     uint16_t glyphId = glyph.getGlyphID();
   1027     //TODO: convert to<->from DIUs? This would make a difference if hinting.
   1028     //It may not be needed, it appears that DirectWrite only hints at em size.
   1029     HRVM(fTypeface->fDWriteFontFace->GetGlyphRunOutline(SkScalarToFloat(fRec.fTextSize),
   1030                                        &glyphId,
   1031                                        NULL, //advances
   1032                                        NULL, //offsets
   1033                                        1, //num glyphs
   1034                                        FALSE, //sideways
   1035                                        FALSE, //rtl
   1036                                        geometryToPath.get()),
   1037          "Could not create glyph outline.");
   1038 
   1039     SkMatrix mat;
   1040     fRec.getMatrixFrom2x2(&mat);
   1041     path->transform(mat);
   1042 }
   1043 
   1044 void SkFontHost::Serialize(const SkTypeface* rawFace, SkWStream* stream) {
   1045     const DWriteFontTypeface* face = static_cast<const DWriteFontTypeface*>(rawFace);
   1046     SkFontDescriptor descriptor(face->style());
   1047 
   1048     // Get the family name.
   1049     SkTScopedComPtr<IDWriteLocalizedStrings> dwFamilyNames;
   1050     HRV(face->fDWriteFontFamily->GetFamilyNames(&dwFamilyNames));
   1051 
   1052     UINT32 dwFamilyNamesLength;
   1053     HRV(dwFamilyNames->GetStringLength(0, &dwFamilyNamesLength));
   1054 
   1055     SkTDArray<wchar_t> dwFamilyNameChar(new wchar_t[dwFamilyNamesLength+1], dwFamilyNamesLength+1);
   1056     HRV(dwFamilyNames->GetString(0, dwFamilyNameChar.begin(), dwFamilyNameChar.count()));
   1057 
   1058     // Convert the family name to utf8.
   1059     // Get the buffer size needed first.
   1060     int str_len = WideCharToMultiByte(CP_UTF8, 0, dwFamilyNameChar.begin(), -1,
   1061                                       NULL, 0, NULL, NULL);
   1062     // Allocate a buffer (str_len already has terminating null accounted for).
   1063     SkTDArray<char> utf8FamilyName(new char[str_len], str_len);
   1064     // Now actually convert the string.
   1065     str_len = WideCharToMultiByte(CP_UTF8, 0, dwFamilyNameChar.begin(), -1,
   1066                                   utf8FamilyName.begin(), str_len, NULL, NULL);
   1067 
   1068     descriptor.setFamilyName(utf8FamilyName.begin());
   1069     //TODO: FileName and PostScriptName currently unsupported.
   1070 
   1071     descriptor.serialize(stream);
   1072 
   1073     if (NULL != face->fDWriteFontFileLoader.get()) {
   1074         // store the entire font in the fontData
   1075         SkStream* fontStream = face->fDWriteFontFileLoader->fStream.get();
   1076         const uint32_t length = fontStream->getLength();
   1077 
   1078         stream->writePackedUInt(length);
   1079         stream->writeStream(fontStream, length);
   1080     } else {
   1081         stream->writePackedUInt(0);
   1082     }
   1083 }
   1084 
   1085 SkTypeface* SkFontHost::Deserialize(SkStream* stream) {
   1086     SkFontDescriptor descriptor(stream);
   1087 
   1088     const uint32_t customFontDataLength = stream->readPackedUInt();
   1089     if (customFontDataLength > 0) {
   1090         // generate a new stream to store the custom typeface
   1091         SkAutoTUnref<SkMemoryStream> fontStream(SkNEW_ARGS(SkMemoryStream, (customFontDataLength - 1)));
   1092         stream->read((void*)fontStream->getMemoryBase(), customFontDataLength - 1);
   1093 
   1094         return CreateTypefaceFromStream(fontStream.get());
   1095     }
   1096 
   1097     return SkFontHost::CreateTypeface(NULL, descriptor.getFamilyName(), descriptor.getStyle());
   1098 }
   1099 
   1100 SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) {
   1101     IDWriteFactory* factory;
   1102     HRN(get_dwrite_factory(&factory));
   1103 
   1104     SkTScopedComPtr<StreamFontFileLoader> fontFileLoader;
   1105     HRN(StreamFontFileLoader::Create(stream, &fontFileLoader));
   1106     HRN(factory->RegisterFontFileLoader(fontFileLoader.get()));
   1107 
   1108     SkTScopedComPtr<StreamFontCollectionLoader> streamFontCollectionLoader;
   1109     HRN(StreamFontCollectionLoader::Create(fontFileLoader.get(), &streamFontCollectionLoader));
   1110     HRN(factory->RegisterFontCollectionLoader(streamFontCollectionLoader.get()));
   1111 
   1112     SkTScopedComPtr<IDWriteFontCollection> streamFontCollection;
   1113     HRN(factory->CreateCustomFontCollection(streamFontCollectionLoader.get(), NULL, 0,
   1114                                             &streamFontCollection));
   1115 
   1116     SkTScopedComPtr<IDWriteFontFamily> fontFamily;
   1117     HRN(streamFontCollection->GetFontFamily(0, &fontFamily));
   1118 
   1119     SkTScopedComPtr<IDWriteFont> font;
   1120     HRN(fontFamily->GetFont(0, &font));
   1121 
   1122     SkTScopedComPtr<IDWriteFontFace> fontFace;
   1123     HRN(font->CreateFontFace(&fontFace));
   1124 
   1125     return SkCreateTypefaceFromDWriteFont(fontFace.get(), font.get(), fontFamily.get(),
   1126                                           fontFileLoader.get(), streamFontCollectionLoader.get());
   1127 }
   1128 
   1129 SkStream* SkFontHost::OpenStream(SkFontID uniqueID) {
   1130     DWriteFontTypeface* typeface = GetDWriteFontByID(uniqueID);
   1131     if (NULL == typeface) {
   1132         return NULL;
   1133     }
   1134 
   1135     UINT32 numFiles;
   1136     HRNM(typeface->fDWriteFontFace->GetFiles(&numFiles, NULL),
   1137          "Could not get number of font files.");
   1138     if (numFiles != 1) {
   1139         return NULL;
   1140     }
   1141 
   1142     SkTScopedComPtr<IDWriteFontFile> fontFile;
   1143     HRNM(typeface->fDWriteFontFace->GetFiles(&numFiles, &fontFile), "Could not get font files.");
   1144 
   1145     const void* fontFileKey;
   1146     UINT32 fontFileKeySize;
   1147     HRNM(fontFile->GetReferenceKey(&fontFileKey, &fontFileKeySize),
   1148          "Could not get font file reference key.");
   1149 
   1150     SkTScopedComPtr<IDWriteFontFileLoader> fontFileLoader;
   1151     HRNM(fontFile->GetLoader(&fontFileLoader), "Could not get font file loader.");
   1152 
   1153     SkTScopedComPtr<IDWriteFontFileStream> fontFileStream;
   1154     HRNM(fontFileLoader->CreateStreamFromKey(fontFileKey, fontFileKeySize,
   1155                                              &fontFileStream),
   1156          "Could not create font file stream.");
   1157 
   1158     return SkNEW_ARGS(SkDWriteFontFileStream, (fontFileStream.get()));
   1159 }
   1160 
   1161 SkScalerContext* SkFontHost::CreateScalerContext(const SkDescriptor* desc) {
   1162     return SkNEW_ARGS(SkScalerContext_Windows, (desc));
   1163 }
   1164 
   1165 static HRESULT get_by_family_name(const char familyName[], IDWriteFontFamily** fontFamily) {
   1166     IDWriteFactory* factory;
   1167     HR(get_dwrite_factory(&factory));
   1168 
   1169     SkTScopedComPtr<IDWriteFontCollection> sysFontCollection;
   1170     HR(factory->GetSystemFontCollection(&sysFontCollection, FALSE));
   1171 
   1172     // Get the buffer size needed first.
   1173     int wlen = ::MultiByteToWideChar(CP_UTF8, 0, familyName,-1, NULL, 0);
   1174     if (0 == wlen) {
   1175         return HRESULT_FROM_WIN32(GetLastError());
   1176     }
   1177     // Allocate a buffer
   1178     SkTDArray<wchar_t> wideFamilyName(new wchar_t[wlen], wlen);
   1179     // Now actually convert the string.
   1180     wlen = ::MultiByteToWideChar(CP_UTF8, 0, familyName, -1,
   1181                                     wideFamilyName.begin(), wlen);
   1182     if (0 == wlen) {
   1183         return HRESULT_FROM_WIN32(GetLastError());
   1184     }
   1185 
   1186     UINT32 index;
   1187     BOOL exists;
   1188     HR(sysFontCollection->FindFamilyName(wideFamilyName.begin(), &index, &exists));
   1189 
   1190     if (exists) {
   1191         HR(sysFontCollection->GetFontFamily(index, fontFamily));
   1192         return S_OK;
   1193     }
   1194     return S_FALSE;
   1195 }
   1196 
   1197 /** Return the closest matching typeface given either an existing family
   1198  (specified by a typeface in that family) or by a familyName, and a
   1199  requested style.
   1200  1) If familyFace is null, use familyName.
   1201  2) If familyName is null, use familyFace.
   1202  3) If both are null, return the default font that best matches style
   1203  This MUST not return NULL.
   1204  */
   1205 SkTypeface* SkFontHost::CreateTypeface(const SkTypeface* familyFace,
   1206                                        const char familyName[],
   1207                                        SkTypeface::Style style) {
   1208     HRESULT hr;
   1209     SkTScopedComPtr<IDWriteFontFamily> fontFamily;
   1210     SkTScopedComPtr<IDWriteFontCollectionLoader> fontCollectionLoader;
   1211     SkTScopedComPtr<IDWriteFontFileLoader> fontFileLoader;
   1212     if (familyFace) {
   1213         const DWriteFontTypeface* face = static_cast<const DWriteFontTypeface*>(familyFace);
   1214         face->fDWriteFontFamily.get()->AddRef();
   1215         *(&fontFamily) = face->fDWriteFontFamily.get();
   1216 
   1217         if (face->fDWriteFontCollectionLoader.get() != NULL) {
   1218             face->fDWriteFontCollectionLoader.get()->AddRef();
   1219             *(&fontCollectionLoader) = face->fDWriteFontCollectionLoader.get();
   1220 
   1221             face->fDWriteFontFileLoader.get()->AddRef();
   1222             *(&fontFileLoader) = face->fDWriteFontFileLoader.get();
   1223         }
   1224 
   1225     } else if (familyName) {
   1226         hr = get_by_family_name(familyName, &fontFamily);
   1227     }
   1228 
   1229     if (NULL == fontFamily.get()) {
   1230         //No good family found, go with default.
   1231         SkTScopedComPtr<IDWriteFont> font;
   1232         hr = get_default_font(&font);
   1233         hr = font->GetFontFamily(&fontFamily);
   1234     }
   1235 
   1236     SkTScopedComPtr<IDWriteFont> font;
   1237     DWRITE_FONT_WEIGHT weight = (style & SkTypeface::kBold)
   1238                                  ? DWRITE_FONT_WEIGHT_BOLD
   1239                                  : DWRITE_FONT_WEIGHT_NORMAL;
   1240     DWRITE_FONT_STRETCH stretch = DWRITE_FONT_STRETCH_UNDEFINED;
   1241     DWRITE_FONT_STYLE italic = (style & SkTypeface::kItalic)
   1242                                 ? DWRITE_FONT_STYLE_ITALIC
   1243                                 : DWRITE_FONT_STYLE_NORMAL;
   1244     hr = fontFamily->GetFirstMatchingFont(weight, stretch, italic, &font);
   1245 
   1246     SkTScopedComPtr<IDWriteFontFace> fontFace;
   1247     hr = font->CreateFontFace(&fontFace);
   1248 
   1249     return SkCreateTypefaceFromDWriteFont(fontFace.get(), font.get(), fontFamily.get());
   1250 }
   1251 
   1252 SkTypeface* SkFontHost::CreateTypefaceFromFile(const char path[]) {
   1253     printf("SkFontHost::CreateTypefaceFromFile unimplemented");
   1254     return NULL;
   1255 }
   1256 
   1257 void SkFontHost::FilterRec(SkScalerContext::Rec* rec, SkTypeface*) {
   1258     unsigned flagsWeDontSupport = SkScalerContext::kDevKernText_Flag |
   1259                                   SkScalerContext::kAutohinting_Flag |
   1260                                   SkScalerContext::kEmbeddedBitmapText_Flag |
   1261                                   SkScalerContext::kEmbolden_Flag |
   1262                                   SkScalerContext::kLCD_BGROrder_Flag |
   1263                                   SkScalerContext::kLCD_Vertical_Flag;
   1264     rec->fFlags &= ~flagsWeDontSupport;
   1265 
   1266     SkPaint::Hinting h = rec->getHinting();
   1267     // DirectWrite does not provide for hinting hints.
   1268     h = SkPaint::kSlight_Hinting;
   1269     rec->setHinting(h);
   1270 
   1271 #if SK_FONT_HOST_USE_SYSTEM_SETTINGS
   1272     IDWriteFactory* factory;
   1273     if (SUCCEEDED(get_dwrite_factory(&factory))) {
   1274         SkTScopedComPtr<IDWriteRenderingParams> defaultRenderingParams;
   1275         if (SUCCEEDED(factory->CreateRenderingParams(&defaultRenderingParams))) {
   1276             float gamma = defaultRenderingParams->GetGamma();
   1277             rec->setDeviceGamma(SkFloatToScalar(gamma));
   1278             rec->setPaintGamma(SkFloatToScalar(gamma));
   1279 
   1280             rec->setContrast(SkFloatToScalar(defaultRenderingParams->GetEnhancedContrast()));
   1281         }
   1282     }
   1283 #endif
   1284 }
   1285 
   1286 ///////////////////////////////////////////////////////////////////////////////
   1287 //PDF Support
   1288 
   1289 using namespace skia_advanced_typeface_metrics_utils;
   1290 
   1291 // Construct Glyph to Unicode table.
   1292 // Unicode code points that require conjugate pairs in utf16 are not
   1293 // supported.
   1294 // TODO(arthurhsu): Add support for conjugate pairs. It looks like that may
   1295 // require parsing the TTF cmap table (platform 4, encoding 12) directly instead
   1296 // of calling GetFontUnicodeRange().
   1297 // TODO(bungeman): This never does what anyone wants.
   1298 // What is really wanted is the text to glyphs mapping
   1299 static void populate_glyph_to_unicode(IDWriteFontFace* fontFace,
   1300                                       const unsigned glyphCount,
   1301                                       SkTDArray<SkUnichar>* glyphToUnicode) {
   1302     HRESULT hr = S_OK;
   1303 
   1304     //Do this like free type instead
   1305     UINT32 count = 0;
   1306     for (UINT32 c = 0; c < 0x10FFFF; ++c) {
   1307         UINT16 glyph;
   1308         hr = fontFace->GetGlyphIndices(&c, 1, &glyph);
   1309         if (glyph > 0) {
   1310             ++count;
   1311         }
   1312     }
   1313 
   1314     SkAutoTArray<UINT32> chars(count);
   1315     count = 0;
   1316     for (UINT32 c = 0; c < 0x10FFFF; ++c) {
   1317         UINT16 glyph;
   1318         hr = fontFace->GetGlyphIndices(&c, 1, &glyph);
   1319         if (glyph > 0) {
   1320             chars[count] = c;
   1321             ++count;
   1322         }
   1323     }
   1324 
   1325     SkAutoTArray<UINT16> glyph(count);
   1326     fontFace->GetGlyphIndices(chars.get(), count, glyph.get());
   1327 
   1328     USHORT maxGlyph = 0;
   1329     for (USHORT j = 0; j < count; ++j) {
   1330         if (glyph[j] > maxGlyph) maxGlyph = glyph[j];
   1331     }
   1332 
   1333     glyphToUnicode->setCount(maxGlyph+1);
   1334     for (size_t j = 0; j < maxGlyph+1u; ++j) {
   1335         (*glyphToUnicode)[j] = 0;
   1336     }
   1337 
   1338     //'invert'
   1339     for (USHORT j = 0; j < count; ++j) {
   1340         if (glyph[j] < glyphCount && (*glyphToUnicode)[glyph[j]] == 0) {
   1341             (*glyphToUnicode)[glyph[j]] = chars[j];
   1342         }
   1343     }
   1344 }
   1345 
   1346 static bool getWidthAdvance(IDWriteFontFace* fontFace, int gId, int16_t* advance) {
   1347     SkASSERT(advance);
   1348 
   1349     UINT16 glyphId = gId;
   1350     DWRITE_GLYPH_METRICS gm;
   1351     HRESULT hr = fontFace->GetDesignGlyphMetrics(&glyphId, 1, &gm);
   1352 
   1353     if (FAILED(hr)) {
   1354         *advance = 0;
   1355         return false;
   1356     }
   1357 
   1358     *advance = gm.advanceWidth;
   1359     return true;
   1360 }
   1361 
   1362 template<typename T>
   1363 class AutoDWriteTable {
   1364 public:
   1365     AutoDWriteTable(IDWriteFontFace* fontFace)
   1366         : fFontFace(fontFace)
   1367         , fExists(FALSE) {
   1368 
   1369         //fontFace->AddRef();
   1370         const UINT32 tag = DWRITE_MAKE_OPENTYPE_TAG(T::TAG0,
   1371                                                     T::TAG1,
   1372                                                     T::TAG2,
   1373                                                     T::TAG3);
   1374         HRESULT hr = fontFace->TryGetFontTable(tag,
   1375             reinterpret_cast<const void **>(&fData), &fSize, &fLock, &fExists);
   1376     }
   1377     ~AutoDWriteTable() {
   1378         if (fExists) {
   1379             fFontFace->ReleaseFontTable(fLock);
   1380         }
   1381     }
   1382     const T* operator->() const { return fData; }
   1383 
   1384     const T* fData;
   1385     UINT32 fSize;
   1386     BOOL fExists;
   1387 private:
   1388     //SkTScopedComPtr<IDWriteFontFace> fFontFace;
   1389     IDWriteFontFace* fFontFace;
   1390     void* fLock;
   1391 };
   1392 
   1393 // static
   1394 SkAdvancedTypefaceMetrics* SkFontHost::GetAdvancedTypefaceMetrics(
   1395         uint32_t fontID,
   1396         SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo,
   1397         const uint32_t* glyphIDs,
   1398         uint32_t glyphIDsCount) {
   1399 
   1400     SkAdvancedTypefaceMetrics* info = NULL;
   1401 
   1402     HRESULT hr = S_OK;
   1403 
   1404     DWriteFontTypeface* typeface = GetDWriteFontByID(fontID);
   1405 
   1406     const unsigned glyphCount = typeface->fDWriteFontFace->GetGlyphCount();
   1407 
   1408     DWRITE_FONT_METRICS dwfm;
   1409     typeface->fDWriteFontFace->GetMetrics(&dwfm);
   1410 
   1411     info = new SkAdvancedTypefaceMetrics;
   1412     info->fEmSize = dwfm.designUnitsPerEm;
   1413     info->fMultiMaster = false;
   1414     info->fLastGlyphID = SkToU16(glyphCount - 1);
   1415     info->fStyle = 0;
   1416 
   1417 
   1418     SkTScopedComPtr<IDWriteLocalizedStrings> familyNames;
   1419     SkTScopedComPtr<IDWriteLocalizedStrings> faceNames;
   1420     hr = typeface->fDWriteFontFamily->GetFamilyNames(&familyNames);
   1421     hr = typeface->fDWriteFont->GetFaceNames(&faceNames);
   1422 
   1423     UINT32 familyNameLength;
   1424     hr = familyNames->GetStringLength(0, &familyNameLength);
   1425 
   1426     UINT32 faceNameLength;
   1427     hr = faceNames->GetStringLength(0, &faceNameLength);
   1428 
   1429     size_t size = familyNameLength+1+faceNameLength+1;
   1430     SkTDArray<wchar_t> wFamilyName(new wchar_t[size], size);
   1431     hr = familyNames->GetString(0, wFamilyName.begin(), size);
   1432     wFamilyName[familyNameLength] = L' ';
   1433     hr = faceNames->GetString(0, &wFamilyName[familyNameLength+1], size - faceNameLength + 1);
   1434 
   1435     size_t str_len = WideCharToMultiByte(CP_UTF8, 0, wFamilyName.begin(), -1, NULL, 0, NULL, NULL);
   1436     if (0 == str_len) {
   1437         //TODO: error
   1438     }
   1439     SkTDArray<char> familyName(new char[str_len], str_len);
   1440     str_len = WideCharToMultiByte(CP_UTF8, 0, wFamilyName.begin(), -1, familyName.begin(), str_len, NULL, NULL);
   1441     if (0 == str_len) {
   1442         //TODO: error
   1443     }
   1444     info->fFontName.set(familyName.begin(), str_len);
   1445 
   1446     if (perGlyphInfo & SkAdvancedTypefaceMetrics::kToUnicode_PerGlyphInfo) {
   1447         populate_glyph_to_unicode(typeface->fDWriteFontFace.get(), glyphCount, &(info->fGlyphToUnicode));
   1448     }
   1449 
   1450     DWRITE_FONT_FACE_TYPE fontType = typeface->fDWriteFontFace->GetType();
   1451     if (fontType == DWRITE_FONT_FACE_TYPE_TRUETYPE ||
   1452         fontType == DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION) {
   1453         info->fType = SkAdvancedTypefaceMetrics::kTrueType_Font;
   1454     } else {
   1455         info->fType = SkAdvancedTypefaceMetrics::kOther_Font;
   1456         info->fItalicAngle = 0;
   1457         info->fAscent = dwfm.ascent;;
   1458         info->fDescent = dwfm.descent;
   1459         info->fStemV = 0;
   1460         info->fCapHeight = dwfm.capHeight;
   1461         info->fBBox = SkIRect::MakeEmpty();
   1462         return info;
   1463     }
   1464 
   1465     AutoDWriteTable<SkOTTableHead> headTable(typeface->fDWriteFontFace.get());
   1466     AutoDWriteTable<SkOTTablePostScript> postTable(typeface->fDWriteFontFace.get());
   1467     AutoDWriteTable<SkOTTableHorizontalHeader> hheaTable(typeface->fDWriteFontFace.get());
   1468     AutoDWriteTable<SkOTTableOS2> os2Table(typeface->fDWriteFontFace.get());
   1469     if (!headTable.fExists || !postTable.fExists || !hheaTable.fExists || !os2Table.fExists) {
   1470         info->fItalicAngle = 0;
   1471         info->fAscent = dwfm.ascent;;
   1472         info->fDescent = dwfm.descent;
   1473         info->fStemV = 0;
   1474         info->fCapHeight = dwfm.capHeight;
   1475         info->fBBox = SkIRect::MakeEmpty();
   1476         return info;
   1477     }
   1478 
   1479     //There exist CJK fonts which set the IsFixedPitch and Monospace bits,
   1480     //but have full width, latin half-width, and half-width kana.
   1481     bool fixedWidth = (postTable->isFixedPitch &&
   1482                       (1 == SkEndian_SwapBE16(hheaTable->numberOfHMetrics)));
   1483     //Monospace
   1484     if (fixedWidth) {
   1485         info->fStyle |= SkAdvancedTypefaceMetrics::kFixedPitch_Style;
   1486     }
   1487     //Italic
   1488     if (os2Table->version.v0.fsSelection.field.Italic) {
   1489         info->fStyle |= SkAdvancedTypefaceMetrics::kItalic_Style;
   1490     }
   1491     //Symbolic (uses more than base latin).
   1492     info->fStyle |= SkAdvancedTypefaceMetrics::kSymbolic_Style;
   1493     //Script
   1494     if (SkPanose::FamilyType::Script == os2Table->version.v0.panose.bFamilyType.value) {
   1495         info->fStyle |= SkAdvancedTypefaceMetrics::kScript_Style;
   1496     //Serif
   1497     } else if (SkPanose::FamilyType::TextAndDisplay == os2Table->version.v0.panose.bFamilyType.value &&
   1498                SkPanose::Data::TextAndDisplay::SerifStyle::Triangle <= os2Table->version.v0.panose.data.textAndDisplay.bSerifStyle.value &&
   1499                SkPanose::Data::TextAndDisplay::SerifStyle::NoFit != os2Table->version.v0.panose.data.textAndDisplay.bSerifStyle.value) {
   1500         info->fStyle |= SkAdvancedTypefaceMetrics::kSerif_Style;
   1501     }
   1502 
   1503     info->fItalicAngle = SkEndian_SwapBE32(postTable->italicAngle) >> 16;
   1504 
   1505     info->fAscent = SkToS16(dwfm.ascent);
   1506     info->fDescent = SkToS16(dwfm.descent);
   1507     info->fCapHeight = SkToS16(dwfm.capHeight);
   1508 
   1509     info->fBBox = SkIRect::MakeLTRB((int32_t)SkEndian_SwapBE16((uint16_t)headTable->xMin),
   1510                                     (int32_t)SkEndian_SwapBE16((uint16_t)headTable->yMax),
   1511                                     (int32_t)SkEndian_SwapBE16((uint16_t)headTable->xMax),
   1512                                     (int32_t)SkEndian_SwapBE16((uint16_t)headTable->yMin));
   1513 
   1514     //TODO: is this even desired? It seems PDF only wants this value for Type1
   1515     //fonts, and we only get here for TrueType fonts.
   1516     info->fStemV = 0;
   1517     /*
   1518     // Figure out a good guess for StemV - Min width of i, I, !, 1.
   1519     // This probably isn't very good with an italic font.
   1520     int16_t min_width = SHRT_MAX;
   1521     info->fStemV = 0;
   1522     char stem_chars[] = {'i', 'I', '!', '1'};
   1523     for (size_t i = 0; i < SK_ARRAY_COUNT(stem_chars); i++) {
   1524         ABC abcWidths;
   1525         if (GetCharABCWidths(hdc, stem_chars[i], stem_chars[i], &abcWidths)) {
   1526             int16_t width = abcWidths.abcB;
   1527             if (width > 0 && width < min_width) {
   1528                 min_width = width;
   1529                 info->fStemV = min_width;
   1530             }
   1531         }
   1532     }
   1533     */
   1534 
   1535     // If Restricted, the font may not be embedded in a document.
   1536     // If not Restricted, the font can be embedded.
   1537     // If PreviewPrint, the embedding is read-only.
   1538     if (os2Table->version.v0.fsType.field.Restricted) {
   1539         info->fType = SkAdvancedTypefaceMetrics::kNotEmbeddable_Font;
   1540     } else if (perGlyphInfo & SkAdvancedTypefaceMetrics::kHAdvance_PerGlyphInfo) {
   1541         if (fixedWidth) {
   1542             appendRange(&info->fGlyphWidths, 0);
   1543             int16_t advance;
   1544             getWidthAdvance(typeface->fDWriteFontFace.get(), 1, &advance);
   1545             info->fGlyphWidths->fAdvance.append(1, &advance);
   1546             finishRange(info->fGlyphWidths.get(), 0,
   1547                         SkAdvancedTypefaceMetrics::WidthRange::kDefault);
   1548         } else {
   1549             info->fGlyphWidths.reset(
   1550                 getAdvanceData(typeface->fDWriteFontFace.get(),
   1551                                glyphCount,
   1552                                glyphIDs,
   1553                                glyphIDsCount,
   1554                                getWidthAdvance));
   1555         }
   1556     }
   1557 
   1558     return info;
   1559 }
   1560