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