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