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