Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: src/ports/SkFontHost_win_dw.cpp

Issue 314193002: Split SkFontHost_win_dw. (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Remove unneeded includes. Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « gyp/ports.gyp ('k') | src/ports/SkFontMgr_win_dw.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2011 Google Inc. 2 * Copyright 2011 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "SkTypes.h" 8 #include "SkTypes.h"
9 #undef GetGlyphIndices 9 #undef GetGlyphIndices
10 10
11 #include "SkAdvancedTypefaceMetrics.h"
12 #include "SkColorFilter.h"
13 #include "SkDWrite.h" 11 #include "SkDWrite.h"
14 #include "SkDWriteFontFileStream.h"
15 #include "SkDWriteGeometrySink.h" 12 #include "SkDWriteGeometrySink.h"
16 #include "SkDescriptor.h"
17 #include "SkEndian.h" 13 #include "SkEndian.h"
18 #include "SkFontDescriptor.h"
19 #include "SkFontHost.h"
20 #include "SkFontMgr.h"
21 #include "SkFontStream.h"
22 #include "SkGlyph.h" 14 #include "SkGlyph.h"
23 #include "SkHRESULT.h" 15 #include "SkHRESULT.h"
24 #include "SkMaskGamma.h" 16 #include "SkMaskGamma.h"
25 #include "SkMatrix22.h" 17 #include "SkMatrix22.h"
26 #include "SkOnce.h"
27 #include "SkOTTable_EBLC.h" 18 #include "SkOTTable_EBLC.h"
28 #include "SkOTTable_EBSC.h" 19 #include "SkOTTable_EBSC.h"
29 #include "SkOTTable_head.h"
30 #include "SkOTTable_hhea.h"
31 #include "SkOTTable_OS_2.h"
32 #include "SkOTTable_post.h"
33 #include "SkPath.h" 20 #include "SkPath.h"
34 #include "SkStream.h" 21 #include "SkScalerContext.h"
35 #include "SkString.h" 22 #include "SkScalerContext_win_dw.h"
36 #include "SkTScopedComPtr.h" 23 #include "SkTScopedComPtr.h"
37 #include "SkThread.h" 24 #include "SkTypeface_win_dw.h"
38 #include "SkTypeface_win.h"
39 #include "SkTypefaceCache.h"
40 #include "SkUtils.h"
41 25
42 #include <dwrite.h> 26 #include <dwrite.h>
43 27
44 static bool isLCD(const SkScalerContext::Rec& rec) { 28 static bool isLCD(const SkScalerContext::Rec& rec) {
45 return SkMask::kLCD16_Format == rec.fMaskFormat || 29 return SkMask::kLCD16_Format == rec.fMaskFormat ||
46 SkMask::kLCD32_Format == rec.fMaskFormat; 30 SkMask::kLCD32_Format == rec.fMaskFormat;
47 } 31 }
48 32
49 ///////////////////////////////////////////////////////////////////////////////
50
51 class StreamFontFileLoader;
52
53 class SkFontMgr_DirectWrite : public SkFontMgr {
54 public:
55 /** localeNameLength must include the null terminator. */
56 SkFontMgr_DirectWrite(IDWriteFactory* factory, IDWriteFontCollection* fontCo llection,
57 WCHAR* localeName, int localeNameLength)
58 : fFactory(SkRefComPtr(factory))
59 , fFontCollection(SkRefComPtr(fontCollection))
60 , fLocaleName(localeNameLength)
61 {
62 memcpy(fLocaleName.get(), localeName, localeNameLength * sizeof(WCHAR));
63 }
64
65 /** Creates a typeface using a typeface cache. */
66 SkTypeface* createTypefaceFromDWriteFont(IDWriteFontFace* fontFace,
67 IDWriteFont* font,
68 IDWriteFontFamily* fontFamily) cons t;
69
70 protected:
71 virtual int onCountFamilies() const SK_OVERRIDE;
72 virtual void onGetFamilyName(int index, SkString* familyName) const SK_OVERR IDE;
73 virtual SkFontStyleSet* onCreateStyleSet(int index) const SK_OVERRIDE;
74 virtual SkFontStyleSet* onMatchFamily(const char familyName[]) const SK_OVER RIDE;
75 virtual SkTypeface* onMatchFamilyStyle(const char familyName[],
76 const SkFontStyle& fontstyle) const S K_OVERRIDE;
77 virtual SkTypeface* onMatchFaceStyle(const SkTypeface* familyMember,
78 const SkFontStyle& fontstyle) const SK_ OVERRIDE;
79 virtual SkTypeface* onCreateFromStream(SkStream* stream, int ttcIndex) const SK_OVERRIDE;
80 virtual SkTypeface* onCreateFromData(SkData* data, int ttcIndex) const SK_OV ERRIDE;
81 virtual SkTypeface* onCreateFromFile(const char path[], int ttcIndex) const SK_OVERRIDE;
82 virtual SkTypeface* onLegacyCreateTypeface(const char familyName[],
83 unsigned styleBits) const SK_OVER RIDE;
84
85 private:
86 HRESULT getByFamilyName(const WCHAR familyName[], IDWriteFontFamily** fontFa mily) const;
87 HRESULT getDefaultFontFamily(IDWriteFontFamily** fontFamily) const;
88
89 void Add(SkTypeface* face, SkTypeface::Style requestedStyle, bool strong) co nst {
90 SkAutoMutexAcquire ama(fTFCacheMutex);
91 fTFCache.add(face, requestedStyle, strong);
92 }
93
94 SkTypeface* FindByProcAndRef(SkTypefaceCache::FindProc proc, void* ctx) cons t {
95 SkAutoMutexAcquire ama(fTFCacheMutex);
96 SkTypeface* typeface = fTFCache.findByProcAndRef(proc, ctx);
97 return typeface;
98 }
99
100 SkTScopedComPtr<IDWriteFactory> fFactory;
101 SkTScopedComPtr<IDWriteFontCollection> fFontCollection;
102 SkSMallocWCHAR fLocaleName;
103 mutable SkMutex fTFCacheMutex;
104 mutable SkTypefaceCache fTFCache;
105
106 friend class SkFontStyleSet_DirectWrite;
107 };
108
109 class SkFontStyleSet_DirectWrite : public SkFontStyleSet {
110 public:
111 SkFontStyleSet_DirectWrite(const SkFontMgr_DirectWrite* fontMgr,
112 IDWriteFontFamily* fontFamily)
113 : fFontMgr(SkRef(fontMgr))
114 , fFontFamily(SkRefComPtr(fontFamily))
115 { }
116
117 virtual int count() SK_OVERRIDE;
118 virtual void getStyle(int index, SkFontStyle* fs, SkString* styleName) SK_OV ERRIDE;
119 virtual SkTypeface* createTypeface(int index) SK_OVERRIDE;
120 virtual SkTypeface* matchStyle(const SkFontStyle& pattern) SK_OVERRIDE;
121
122 private:
123 SkAutoTUnref<const SkFontMgr_DirectWrite> fFontMgr;
124 SkTScopedComPtr<IDWriteFontFamily> fFontFamily;
125 };
126
127 ///////////////////////////////////////////////////////////////////////////////
128
129 class StreamFontFileLoader : public IDWriteFontFileLoader {
130 public:
131 // IUnknown methods
132 virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObjec t);
133 virtual ULONG STDMETHODCALLTYPE AddRef();
134 virtual ULONG STDMETHODCALLTYPE Release();
135
136 // IDWriteFontFileLoader methods
137 virtual HRESULT STDMETHODCALLTYPE CreateStreamFromKey(
138 void const* fontFileReferenceKey,
139 UINT32 fontFileReferenceKeySize,
140 IDWriteFontFileStream** fontFileStream);
141
142 static HRESULT Create(SkStream* stream, StreamFontFileLoader** streamFontFil eLoader) {
143 *streamFontFileLoader = new StreamFontFileLoader(stream);
144 if (NULL == streamFontFileLoader) {
145 return E_OUTOFMEMORY;
146 }
147 return S_OK;
148 }
149
150 SkAutoTUnref<SkStream> fStream;
151
152 private:
153 StreamFontFileLoader(SkStream* stream) : fRefCount(1), fStream(SkRef(stream) ) { }
154
155 ULONG fRefCount;
156 };
157
158 HRESULT StreamFontFileLoader::QueryInterface(REFIID iid, void** ppvObject) {
159 if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileLoader)) {
160 *ppvObject = this;
161 AddRef();
162 return S_OK;
163 } else {
164 *ppvObject = NULL;
165 return E_NOINTERFACE;
166 }
167 }
168
169 ULONG StreamFontFileLoader::AddRef() {
170 return InterlockedIncrement(&fRefCount);
171 }
172
173 ULONG StreamFontFileLoader::Release() {
174 ULONG newCount = InterlockedDecrement(&fRefCount);
175 if (0 == newCount) {
176 delete this;
177 }
178 return newCount;
179 }
180
181 HRESULT StreamFontFileLoader::CreateStreamFromKey(
182 void const* fontFileReferenceKey,
183 UINT32 fontFileReferenceKeySize,
184 IDWriteFontFileStream** fontFileStream)
185 {
186 SkTScopedComPtr<SkDWriteFontFileStreamWrapper> stream;
187 HR(SkDWriteFontFileStreamWrapper::Create(fStream, &stream));
188 *fontFileStream = stream.release();
189 return S_OK;
190 }
191
192 class StreamFontFileEnumerator : public IDWriteFontFileEnumerator {
193 public:
194 // IUnknown methods
195 virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObjec t);
196 virtual ULONG STDMETHODCALLTYPE AddRef();
197 virtual ULONG STDMETHODCALLTYPE Release();
198
199 // IDWriteFontFileEnumerator methods
200 virtual HRESULT STDMETHODCALLTYPE MoveNext(BOOL* hasCurrentFile);
201 virtual HRESULT STDMETHODCALLTYPE GetCurrentFontFile(IDWriteFontFile** fontF ile);
202
203 static HRESULT Create(IDWriteFactory* factory, IDWriteFontFileLoader* fontFi leLoader,
204 StreamFontFileEnumerator** streamFontFileEnumerator) {
205 *streamFontFileEnumerator = new StreamFontFileEnumerator(factory, fontFi leLoader);
206 if (NULL == streamFontFileEnumerator) {
207 return E_OUTOFMEMORY;
208 }
209 return S_OK;
210 }
211 private:
212 StreamFontFileEnumerator(IDWriteFactory* factory, IDWriteFontFileLoader* fon tFileLoader);
213 ULONG fRefCount;
214
215 SkTScopedComPtr<IDWriteFactory> fFactory;
216 SkTScopedComPtr<IDWriteFontFile> fCurrentFile;
217 SkTScopedComPtr<IDWriteFontFileLoader> fFontFileLoader;
218 bool fHasNext;
219 };
220
221 StreamFontFileEnumerator::StreamFontFileEnumerator(IDWriteFactory* factory,
222 IDWriteFontFileLoader* fontFi leLoader)
223 : fRefCount(1)
224 , fFactory(SkRefComPtr(factory))
225 , fCurrentFile()
226 , fFontFileLoader(SkRefComPtr(fontFileLoader))
227 , fHasNext(true)
228 { }
229
230 HRESULT StreamFontFileEnumerator::QueryInterface(REFIID iid, void** ppvObject) {
231 if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileEnumerator)) {
232 *ppvObject = this;
233 AddRef();
234 return S_OK;
235 } else {
236 *ppvObject = NULL;
237 return E_NOINTERFACE;
238 }
239 }
240
241 ULONG StreamFontFileEnumerator::AddRef() {
242 return InterlockedIncrement(&fRefCount);
243 }
244
245 ULONG StreamFontFileEnumerator::Release() {
246 ULONG newCount = InterlockedDecrement(&fRefCount);
247 if (0 == newCount) {
248 delete this;
249 }
250 return newCount;
251 }
252
253 HRESULT StreamFontFileEnumerator::MoveNext(BOOL* hasCurrentFile) {
254 *hasCurrentFile = FALSE;
255
256 if (!fHasNext) {
257 return S_OK;
258 }
259 fHasNext = false;
260
261 UINT32 dummy = 0;
262 HR(fFactory->CreateCustomFontFileReference(
263 &dummy, //cannot be NULL
264 sizeof(dummy), //even if this is 0
265 fFontFileLoader.get(),
266 &fCurrentFile));
267
268 *hasCurrentFile = TRUE;
269 return S_OK;
270 }
271
272 HRESULT StreamFontFileEnumerator::GetCurrentFontFile(IDWriteFontFile** fontFile) {
273 if (fCurrentFile.get() == NULL) {
274 *fontFile = NULL;
275 return E_FAIL;
276 }
277
278 *fontFile = SkRefComPtr(fCurrentFile.get());
279 return S_OK;
280 }
281
282 class StreamFontCollectionLoader : public IDWriteFontCollectionLoader {
283 public:
284 // IUnknown methods
285 virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID iid, void** ppvObjec t);
286 virtual ULONG STDMETHODCALLTYPE AddRef();
287 virtual ULONG STDMETHODCALLTYPE Release();
288
289 // IDWriteFontCollectionLoader methods
290 virtual HRESULT STDMETHODCALLTYPE CreateEnumeratorFromKey(
291 IDWriteFactory* factory,
292 void const* collectionKey,
293 UINT32 collectionKeySize,
294 IDWriteFontFileEnumerator** fontFileEnumerator);
295
296 static HRESULT Create(IDWriteFontFileLoader* fontFileLoader,
297 StreamFontCollectionLoader** streamFontCollectionLoade r) {
298 *streamFontCollectionLoader = new StreamFontCollectionLoader(fontFileLoa der);
299 if (NULL == streamFontCollectionLoader) {
300 return E_OUTOFMEMORY;
301 }
302 return S_OK;
303 }
304 private:
305 StreamFontCollectionLoader(IDWriteFontFileLoader* fontFileLoader)
306 : fRefCount(1)
307 , fFontFileLoader(SkRefComPtr(fontFileLoader))
308 { }
309
310 ULONG fRefCount;
311 SkTScopedComPtr<IDWriteFontFileLoader> fFontFileLoader;
312 };
313
314 HRESULT StreamFontCollectionLoader::QueryInterface(REFIID iid, void** ppvObject) {
315 if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontCollectionLoader)) {
316 *ppvObject = this;
317 AddRef();
318 return S_OK;
319 } else {
320 *ppvObject = NULL;
321 return E_NOINTERFACE;
322 }
323 }
324
325 ULONG StreamFontCollectionLoader::AddRef() {
326 return InterlockedIncrement(&fRefCount);
327 }
328
329 ULONG StreamFontCollectionLoader::Release() {
330 ULONG newCount = InterlockedDecrement(&fRefCount);
331 if (0 == newCount) {
332 delete this;
333 }
334 return newCount;
335 }
336
337 HRESULT StreamFontCollectionLoader::CreateEnumeratorFromKey(
338 IDWriteFactory* factory,
339 void const* collectionKey,
340 UINT32 collectionKeySize,
341 IDWriteFontFileEnumerator** fontFileEnumerator)
342 {
343 SkTScopedComPtr<StreamFontFileEnumerator> enumerator;
344 HR(StreamFontFileEnumerator::Create(factory, fFontFileLoader.get(), &enumera tor));
345 *fontFileEnumerator = enumerator.release();
346 return S_OK;
347 }
348
349 ///////////////////////////////////////////////////////////////////////////////
350
351 static SkTypeface::Style get_style(IDWriteFont* font) {
352 int style = SkTypeface::kNormal;
353 DWRITE_FONT_WEIGHT weight = font->GetWeight();
354 if (DWRITE_FONT_WEIGHT_DEMI_BOLD <= weight) {
355 style |= SkTypeface::kBold;
356 }
357 DWRITE_FONT_STYLE angle = font->GetStyle();
358 if (DWRITE_FONT_STYLE_OBLIQUE == angle || DWRITE_FONT_STYLE_ITALIC == angle) {
359 style |= SkTypeface::kItalic;
360 }
361 return static_cast<SkTypeface::Style>(style);
362 }
363
364 class DWriteFontTypeface : public SkTypeface {
365 private:
366 DWriteFontTypeface(SkTypeface::Style style, SkFontID fontID,
367 IDWriteFactory* factory,
368 IDWriteFontFace* fontFace,
369 IDWriteFont* font,
370 IDWriteFontFamily* fontFamily,
371 StreamFontFileLoader* fontFileLoader = NULL,
372 IDWriteFontCollectionLoader* fontCollectionLoader = NULL)
373 : SkTypeface(style, fontID, false)
374 , fFactory(SkRefComPtr(factory))
375 , fDWriteFontCollectionLoader(SkSafeRefComPtr(fontCollectionLoader))
376 , fDWriteFontFileLoader(SkSafeRefComPtr(fontFileLoader))
377 , fDWriteFontFamily(SkRefComPtr(fontFamily))
378 , fDWriteFont(SkRefComPtr(font))
379 , fDWriteFontFace(SkRefComPtr(fontFace))
380 { }
381
382 public:
383 SkTScopedComPtr<IDWriteFactory> fFactory;
384 SkTScopedComPtr<IDWriteFontCollectionLoader> fDWriteFontCollectionLoader;
385 SkTScopedComPtr<StreamFontFileLoader> fDWriteFontFileLoader;
386 SkTScopedComPtr<IDWriteFontFamily> fDWriteFontFamily;
387 SkTScopedComPtr<IDWriteFont> fDWriteFont;
388 SkTScopedComPtr<IDWriteFontFace> fDWriteFontFace;
389
390 static DWriteFontTypeface* Create(IDWriteFactory* factory,
391 IDWriteFontFace* fontFace,
392 IDWriteFont* font,
393 IDWriteFontFamily* fontFamily,
394 StreamFontFileLoader* fontFileLoader = NUL L,
395 IDWriteFontCollectionLoader* fontCollectio nLoader = NULL) {
396 SkTypeface::Style style = get_style(font);
397 SkFontID fontID = SkTypefaceCache::NewFontID();
398 return SkNEW_ARGS(DWriteFontTypeface, (style, fontID,
399 factory, fontFace, font, fontFami ly,
400 fontFileLoader, fontCollectionLoa der));
401 }
402
403 protected:
404 virtual void weak_dispose() const SK_OVERRIDE {
405 if (fDWriteFontCollectionLoader.get()) {
406 HRV(fFactory->UnregisterFontCollectionLoader(fDWriteFontCollectionLo ader.get()));
407 }
408 if (fDWriteFontFileLoader.get()) {
409 HRV(fFactory->UnregisterFontFileLoader(fDWriteFontFileLoader.get())) ;
410 }
411
412 //SkTypefaceCache::Remove(this);
413 INHERITED::weak_dispose();
414 }
415
416 virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE;
417 virtual SkScalerContext* onCreateScalerContext(const SkDescriptor*) const SK _OVERRIDE;
418 virtual void onFilterRec(SkScalerContextRec*) const SK_OVERRIDE;
419 virtual SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics(
420 SkAdvancedTypefaceMetrics::PerGlyphInfo,
421 const uint32_t*, uint32_t) const SK_OVERRIDE;
422 virtual void onGetFontDescriptor(SkFontDescriptor*, bool*) const SK_OVERRIDE ;
423 virtual int onCharsToGlyphs(const void* chars, Encoding encoding,
424 uint16_t glyphs[], int glyphCount) const SK_OVER RIDE;
425 virtual int onCountGlyphs() const SK_OVERRIDE;
426 virtual int onGetUPEM() const SK_OVERRIDE;
427 virtual SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const SK_ OVERRIDE;
428 virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE;
429 virtual size_t onGetTableData(SkFontTableTag, size_t offset,
430 size_t length, void* data) const SK_OVERRIDE;
431
432 private:
433 typedef SkTypeface INHERITED;
434 };
435
436 class SkScalerContext_DW : public SkScalerContext {
437 public:
438 SkScalerContext_DW(DWriteFontTypeface*, const SkDescriptor* desc);
439 virtual ~SkScalerContext_DW();
440
441 protected:
442 virtual unsigned generateGlyphCount() SK_OVERRIDE;
443 virtual uint16_t generateCharToGlyph(SkUnichar uni) SK_OVERRIDE;
444 virtual void generateAdvance(SkGlyph* glyph) SK_OVERRIDE;
445 virtual void generateMetrics(SkGlyph* glyph) SK_OVERRIDE;
446 virtual void generateImage(const SkGlyph& glyph) SK_OVERRIDE;
447 virtual void generatePath(const SkGlyph& glyph, SkPath* path) SK_OVERRIDE;
448 virtual void generateFontMetrics(SkPaint::FontMetrics* mX,
449 SkPaint::FontMetrics* mY) SK_OVERRIDE;
450
451 private:
452 const void* drawDWMask(const SkGlyph& glyph);
453
454 SkTDArray<uint8_t> fBits;
455 /** The total matrix without the text height scale. */
456 SkMatrix fSkXform;
457 /** The total matrix without the text height scale. */
458 DWRITE_MATRIX fXform;
459 /** The non-rotational part of total matrix without the text height scale.
460 * This is used to find the magnitude of gdi compatible advances.
461 */
462 DWRITE_MATRIX fGsA;
463 /** The inverse of the rotational part of the total matrix.
464 * This is used to find the direction of gdi compatible advances.
465 */
466 SkMatrix fG_inv;
467 /** The text size to render with. */
468 SkScalar fTextSizeRender;
469 /** The text size to measure with. */
470 SkScalar fTextSizeMeasure;
471 SkAutoTUnref<DWriteFontTypeface> fTypeface;
472 int fGlyphCount;
473 DWRITE_RENDERING_MODE fRenderingMode;
474 DWRITE_TEXTURE_TYPE fTextureType;
475 DWRITE_MEASURING_MODE fMeasuringMode;
476 };
477
478 static bool are_same(IUnknown* a, IUnknown* b) {
479 SkTScopedComPtr<IUnknown> iunkA;
480 if (FAILED(a->QueryInterface(&iunkA))) {
481 return false;
482 }
483
484 SkTScopedComPtr<IUnknown> iunkB;
485 if (FAILED(b->QueryInterface(&iunkB))) {
486 return false;
487 }
488
489 return iunkA.get() == iunkB.get();
490 }
491 static bool FindByDWriteFont(SkTypeface* face, SkTypeface::Style requestedStyle, void* ctx) {
492 //Check to see if the two fonts are identical.
493 DWriteFontTypeface* dwFace = reinterpret_cast<DWriteFontTypeface*>(face);
494 IDWriteFont* dwFont = reinterpret_cast<IDWriteFont*>(ctx);
495 if (are_same(dwFace->fDWriteFont.get(), dwFont)) {
496 return true;
497 }
498
499 //Check if the two fonts share the same loader and have the same key.
500 SkTScopedComPtr<IDWriteFontFace> dwFaceFontFace;
501 SkTScopedComPtr<IDWriteFontFace> dwFontFace;
502 HRB(dwFace->fDWriteFont->CreateFontFace(&dwFaceFontFace));
503 HRB(dwFont->CreateFontFace(&dwFontFace));
504 if (are_same(dwFaceFontFace.get(), dwFontFace.get())) {
505 return true;
506 }
507
508 UINT32 dwFaceNumFiles;
509 UINT32 dwNumFiles;
510 HRB(dwFaceFontFace->GetFiles(&dwFaceNumFiles, NULL));
511 HRB(dwFontFace->GetFiles(&dwNumFiles, NULL));
512 if (dwFaceNumFiles != dwNumFiles) {
513 return false;
514 }
515
516 SkTScopedComPtr<IDWriteFontFile> dwFaceFontFile;
517 SkTScopedComPtr<IDWriteFontFile> dwFontFile;
518 HRB(dwFaceFontFace->GetFiles(&dwFaceNumFiles, &dwFaceFontFile));
519 HRB(dwFontFace->GetFiles(&dwNumFiles, &dwFontFile));
520
521 //for (each file) { //we currently only admit fonts from one file.
522 SkTScopedComPtr<IDWriteFontFileLoader> dwFaceFontFileLoader;
523 SkTScopedComPtr<IDWriteFontFileLoader> dwFontFileLoader;
524 HRB(dwFaceFontFile->GetLoader(&dwFaceFontFileLoader));
525 HRB(dwFontFile->GetLoader(&dwFontFileLoader));
526 if (!are_same(dwFaceFontFileLoader.get(), dwFontFileLoader.get())) {
527 return false;
528 }
529 //}
530
531 const void* dwFaceFontRefKey;
532 UINT32 dwFaceFontRefKeySize;
533 const void* dwFontRefKey;
534 UINT32 dwFontRefKeySize;
535 HRB(dwFaceFontFile->GetReferenceKey(&dwFaceFontRefKey, &dwFaceFontRefKeySize ));
536 HRB(dwFontFile->GetReferenceKey(&dwFontRefKey, &dwFontRefKeySize));
537 if (dwFaceFontRefKeySize != dwFontRefKeySize) {
538 return false;
539 }
540 if (0 != memcmp(dwFaceFontRefKey, dwFontRefKey, dwFontRefKeySize)) {
541 return false;
542 }
543
544 //TODO: better means than comparing name strings?
545 //NOTE: .tfc and fake bold/italic will end up here.
546 SkTScopedComPtr<IDWriteFontFamily> dwFaceFontFamily;
547 SkTScopedComPtr<IDWriteFontFamily> dwFontFamily;
548 HRB(dwFace->fDWriteFont->GetFontFamily(&dwFaceFontFamily));
549 HRB(dwFont->GetFontFamily(&dwFontFamily));
550
551 SkTScopedComPtr<IDWriteLocalizedStrings> dwFaceFontFamilyNames;
552 SkTScopedComPtr<IDWriteLocalizedStrings> dwFaceFontNames;
553 HRB(dwFaceFontFamily->GetFamilyNames(&dwFaceFontFamilyNames));
554 HRB(dwFace->fDWriteFont->GetFaceNames(&dwFaceFontNames));
555
556 SkTScopedComPtr<IDWriteLocalizedStrings> dwFontFamilyNames;
557 SkTScopedComPtr<IDWriteLocalizedStrings> dwFontNames;
558 HRB(dwFontFamily->GetFamilyNames(&dwFontFamilyNames));
559 HRB(dwFont->GetFaceNames(&dwFontNames));
560
561 UINT32 dwFaceFontFamilyNameLength;
562 UINT32 dwFaceFontNameLength;
563 HRB(dwFaceFontFamilyNames->GetStringLength(0, &dwFaceFontFamilyNameLength));
564 HRB(dwFaceFontNames->GetStringLength(0, &dwFaceFontNameLength));
565
566 UINT32 dwFontFamilyNameLength;
567 UINT32 dwFontNameLength;
568 HRB(dwFontFamilyNames->GetStringLength(0, &dwFontFamilyNameLength));
569 HRB(dwFontNames->GetStringLength(0, &dwFontNameLength));
570
571 if (dwFaceFontFamilyNameLength != dwFontFamilyNameLength ||
572 dwFaceFontNameLength != dwFontNameLength)
573 {
574 return false;
575 }
576
577 SkSMallocWCHAR dwFaceFontFamilyNameChar(dwFaceFontFamilyNameLength+1);
578 SkSMallocWCHAR dwFaceFontNameChar(dwFaceFontNameLength+1);
579 HRB(dwFaceFontFamilyNames->GetString(0, dwFaceFontFamilyNameChar.get(), dwFa ceFontFamilyNameLength+1));
580 HRB(dwFaceFontNames->GetString(0, dwFaceFontNameChar.get(), dwFaceFontNameLe ngth+1));
581
582 SkSMallocWCHAR dwFontFamilyNameChar(dwFontFamilyNameLength+1);
583 SkSMallocWCHAR dwFontNameChar(dwFontNameLength+1);
584 HRB(dwFontFamilyNames->GetString(0, dwFontFamilyNameChar.get(), dwFontFamily NameLength+1));
585 HRB(dwFontNames->GetString(0, dwFontNameChar.get(), dwFontNameLength+1));
586
587 return wcscmp(dwFaceFontFamilyNameChar.get(), dwFontFamilyNameChar.get()) == 0 &&
588 wcscmp(dwFaceFontNameChar.get(), dwFontNameChar.get()) == 0;
589 }
590
591 class AutoDWriteTable {
592 public:
593 AutoDWriteTable(IDWriteFontFace* fontFace, UINT32 beTag) : fFontFace(fontFac e), fExists(FALSE) {
594 // Any errors are ignored, user must check fExists anyway.
595 fontFace->TryGetFontTable(beTag,
596 reinterpret_cast<const void **>(&fData), &fSize, &fLock, &fExists);
597 }
598 ~AutoDWriteTable() {
599 if (fExists) {
600 fFontFace->ReleaseFontTable(fLock);
601 }
602 }
603
604 const uint8_t* fData;
605 UINT32 fSize;
606 BOOL fExists;
607 private:
608 // Borrowed reference, the user must ensure the fontFace stays alive.
609 IDWriteFontFace* fFontFace;
610 void* fLock;
611 };
612 template<typename T> class AutoTDWriteTable : public AutoDWriteTable {
613 public:
614 static const UINT32 tag = DWRITE_MAKE_OPENTYPE_TAG(T::TAG0, T::TAG1, T::TAG2 , T::TAG3);
615 AutoTDWriteTable(IDWriteFontFace* fontFace) : AutoDWriteTable(fontFace, tag) { }
616
617 const T* get() const { return reinterpret_cast<const T*>(fData); }
618 const T* operator->() const { return reinterpret_cast<const T*>(fData); }
619 };
620
621 static bool hasBitmapStrike(DWriteFontTypeface* typeface, int size) { 33 static bool hasBitmapStrike(DWriteFontTypeface* typeface, int size) {
622 { 34 {
623 AutoTDWriteTable<SkOTTableEmbeddedBitmapLocation> eblc(typeface->fDWrite FontFace.get()); 35 AutoTDWriteTable<SkOTTableEmbeddedBitmapLocation> eblc(typeface->fDWrite FontFace.get());
624 if (!eblc.fExists) { 36 if (!eblc.fExists) {
625 return false; 37 return false;
626 } 38 }
627 if (eblc.fSize < sizeof(SkOTTableEmbeddedBitmapLocation)) { 39 if (eblc.fSize < sizeof(SkOTTableEmbeddedBitmapLocation)) {
628 return false; 40 return false;
629 } 41 }
630 if (eblc->version != SkOTTableEmbeddedBitmapLocation::version_initial) { 42 if (eblc->version != SkOTTableEmbeddedBitmapLocation::version_initial) {
(...skipping 571 matching lines...) Expand 10 before | Expand all | Expand 10 after
1202 NULL, //advances 614 NULL, //advances
1203 NULL, //offsets 615 NULL, //offsets
1204 1, //num glyphs 616 1, //num glyphs
1205 FALSE, //sideways 617 FALSE, //sideways
1206 FALSE, //rtl 618 FALSE, //rtl
1207 geometryToPath.get()), 619 geometryToPath.get()),
1208 "Could not create glyph outline."); 620 "Could not create glyph outline.");
1209 621
1210 path->transform(fSkXform); 622 path->transform(fSkXform);
1211 } 623 }
1212
1213 void DWriteFontTypeface::onGetFontDescriptor(SkFontDescriptor* desc,
1214 bool* isLocalStream) const {
1215 // Get the family name.
1216 SkTScopedComPtr<IDWriteLocalizedStrings> dwFamilyNames;
1217 HRV(fDWriteFontFamily->GetFamilyNames(&dwFamilyNames));
1218
1219 UINT32 dwFamilyNamesLength;
1220 HRV(dwFamilyNames->GetStringLength(0, &dwFamilyNamesLength));
1221
1222 SkSMallocWCHAR dwFamilyNameChar(dwFamilyNamesLength+1);
1223 HRV(dwFamilyNames->GetString(0, dwFamilyNameChar.get(), dwFamilyNamesLength+ 1));
1224
1225 SkString utf8FamilyName;
1226 HRV(sk_wchar_to_skstring(dwFamilyNameChar.get(), &utf8FamilyName));
1227
1228 desc->setFamilyName(utf8FamilyName.c_str());
1229 *isLocalStream = SkToBool(fDWriteFontFileLoader.get());
1230 }
1231
1232 static SkUnichar next_utf8(const void** chars) {
1233 return SkUTF8_NextUnichar((const char**)chars);
1234 }
1235
1236 static SkUnichar next_utf16(const void** chars) {
1237 return SkUTF16_NextUnichar((const uint16_t**)chars);
1238 }
1239
1240 static SkUnichar next_utf32(const void** chars) {
1241 const SkUnichar** uniChars = (const SkUnichar**)chars;
1242 SkUnichar uni = **uniChars;
1243 *uniChars += 1;
1244 return uni;
1245 }
1246
1247 typedef SkUnichar (*EncodingProc)(const void**);
1248
1249 static EncodingProc find_encoding_proc(SkTypeface::Encoding enc) {
1250 static const EncodingProc gProcs[] = {
1251 next_utf8, next_utf16, next_utf32
1252 };
1253 SkASSERT((size_t)enc < SK_ARRAY_COUNT(gProcs));
1254 return gProcs[enc];
1255 }
1256
1257 int DWriteFontTypeface::onCharsToGlyphs(const void* chars, Encoding encoding,
1258 uint16_t glyphs[], int glyphCount) const
1259 {
1260 if (NULL == glyphs) {
1261 EncodingProc next_ucs4_proc = find_encoding_proc(encoding);
1262 for (int i = 0; i < glyphCount; ++i) {
1263 const SkUnichar c = next_ucs4_proc(&chars);
1264 BOOL exists;
1265 fDWriteFont->HasCharacter(c, &exists);
1266 if (!exists) {
1267 return i;
1268 }
1269 }
1270 return glyphCount;
1271 }
1272
1273 switch (encoding) {
1274 case SkTypeface::kUTF8_Encoding:
1275 case SkTypeface::kUTF16_Encoding: {
1276 static const int scratchCount = 256;
1277 UINT32 scratch[scratchCount];
1278 EncodingProc next_ucs4_proc = find_encoding_proc(encoding);
1279 for (int baseGlyph = 0; baseGlyph < glyphCount; baseGlyph += scratchCoun t) {
1280 int glyphsLeft = glyphCount - baseGlyph;
1281 int limit = SkTMin(glyphsLeft, scratchCount);
1282 for (int i = 0; i < limit; ++i) {
1283 scratch[i] = next_ucs4_proc(&chars);
1284 }
1285 fDWriteFontFace->GetGlyphIndices(scratch, limit, &glyphs[baseGlyph]) ;
1286 }
1287 break;
1288 }
1289 case SkTypeface::kUTF32_Encoding: {
1290 const UINT32* utf32 = reinterpret_cast<const UINT32*>(chars);
1291 fDWriteFontFace->GetGlyphIndices(utf32, glyphCount, glyphs);
1292 break;
1293 }
1294 default:
1295 SK_CRASH();
1296 }
1297
1298 for (int i = 0; i < glyphCount; ++i) {
1299 if (0 == glyphs[i]) {
1300 return i;
1301 }
1302 }
1303 return glyphCount;
1304 }
1305
1306 int DWriteFontTypeface::onCountGlyphs() const {
1307 return fDWriteFontFace->GetGlyphCount();
1308 }
1309
1310 int DWriteFontTypeface::onGetUPEM() const {
1311 DWRITE_FONT_METRICS metrics;
1312 fDWriteFontFace->GetMetrics(&metrics);
1313 return metrics.designUnitsPerEm;
1314 }
1315
1316 class LocalizedStrings_IDWriteLocalizedStrings : public SkTypeface::LocalizedStr ings {
1317 public:
1318 /** Takes ownership of the IDWriteLocalizedStrings. */
1319 explicit LocalizedStrings_IDWriteLocalizedStrings(IDWriteLocalizedStrings* s trings)
1320 : fIndex(0), fStrings(strings)
1321 { }
1322
1323 virtual bool next(SkTypeface::LocalizedString* localizedString) SK_OVERRIDE {
1324 if (fIndex >= fStrings->GetCount()) {
1325 return false;
1326 }
1327
1328 // String
1329 UINT32 stringLength;
1330 HRBM(fStrings->GetStringLength(fIndex, &stringLength), "Could not get st ring length.");
1331 stringLength += 1;
1332
1333 SkSMallocWCHAR wString(stringLength);
1334 HRBM(fStrings->GetString(fIndex, wString.get(), stringLength), "Could no t get string.");
1335
1336 HRB(sk_wchar_to_skstring(wString.get(), &localizedString->fString));
1337
1338 // Locale
1339 UINT32 localeLength;
1340 HRBM(fStrings->GetLocaleNameLength(fIndex, &localeLength), "Could not ge t locale length.");
1341 localeLength += 1;
1342
1343 SkSMallocWCHAR wLocale(localeLength);
1344 HRBM(fStrings->GetLocaleName(fIndex, wLocale.get(), localeLength), "Coul d not get locale.");
1345
1346 HRB(sk_wchar_to_skstring(wLocale.get(), &localizedString->fLanguage));
1347
1348 ++fIndex;
1349 return true;
1350 }
1351
1352 private:
1353 UINT32 fIndex;
1354 SkTScopedComPtr<IDWriteLocalizedStrings> fStrings;
1355 };
1356
1357 SkTypeface::LocalizedStrings* DWriteFontTypeface::onCreateFamilyNameIterator() c onst {
1358 SkTScopedComPtr<IDWriteLocalizedStrings> familyNames;
1359 HRNM(fDWriteFontFamily->GetFamilyNames(&familyNames), "Could not obtain fami ly names.");
1360
1361 return new LocalizedStrings_IDWriteLocalizedStrings(familyNames.release());
1362 }
1363
1364 int DWriteFontTypeface::onGetTableTags(SkFontTableTag tags[]) const {
1365 DWRITE_FONT_FACE_TYPE type = fDWriteFontFace->GetType();
1366 if (type != DWRITE_FONT_FACE_TYPE_CFF &&
1367 type != DWRITE_FONT_FACE_TYPE_TRUETYPE &&
1368 type != DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION)
1369 {
1370 return 0;
1371 }
1372
1373 int ttcIndex;
1374 SkAutoTUnref<SkStream> stream(this->openStream(&ttcIndex));
1375 return stream.get() ? SkFontStream::GetTableTags(stream, ttcIndex, tags) : 0 ;
1376 }
1377
1378 size_t DWriteFontTypeface::onGetTableData(SkFontTableTag tag, size_t offset,
1379 size_t length, void* data) const
1380 {
1381 AutoDWriteTable table(fDWriteFontFace.get(), SkEndian_SwapBE32(tag));
1382 if (!table.fExists) {
1383 return 0;
1384 }
1385
1386 if (offset > table.fSize) {
1387 return 0;
1388 }
1389 size_t size = SkTMin(length, table.fSize - offset);
1390 if (NULL != data) {
1391 memcpy(data, table.fData + offset, size);
1392 }
1393
1394 return size;
1395 }
1396
1397 template <typename T> class SkAutoIDWriteUnregister {
1398 public:
1399 SkAutoIDWriteUnregister(IDWriteFactory* factory, T* unregister)
1400 : fFactory(factory), fUnregister(unregister)
1401 { }
1402
1403 ~SkAutoIDWriteUnregister() {
1404 if (fUnregister) {
1405 unregister(fFactory, fUnregister);
1406 }
1407 }
1408
1409 T* detatch() {
1410 T* old = fUnregister;
1411 fUnregister = NULL;
1412 return old;
1413 }
1414
1415 private:
1416 HRESULT unregister(IDWriteFactory* factory, IDWriteFontFileLoader* unregiste r) {
1417 return factory->UnregisterFontFileLoader(unregister);
1418 }
1419
1420 HRESULT unregister(IDWriteFactory* factory, IDWriteFontCollectionLoader* unr egister) {
1421 return factory->UnregisterFontCollectionLoader(unregister);
1422 }
1423
1424 IDWriteFactory* fFactory;
1425 T* fUnregister;
1426 };
1427
1428 SkStream* DWriteFontTypeface::onOpenStream(int* ttcIndex) const {
1429 *ttcIndex = fDWriteFontFace->GetIndex();
1430
1431 UINT32 numFiles;
1432 HRNM(fDWriteFontFace->GetFiles(&numFiles, NULL),
1433 "Could not get number of font files.");
1434 if (numFiles != 1) {
1435 return NULL;
1436 }
1437
1438 SkTScopedComPtr<IDWriteFontFile> fontFile;
1439 HRNM(fDWriteFontFace->GetFiles(&numFiles, &fontFile), "Could not get font fi les.");
1440
1441 const void* fontFileKey;
1442 UINT32 fontFileKeySize;
1443 HRNM(fontFile->GetReferenceKey(&fontFileKey, &fontFileKeySize),
1444 "Could not get font file reference key.");
1445
1446 SkTScopedComPtr<IDWriteFontFileLoader> fontFileLoader;
1447 HRNM(fontFile->GetLoader(&fontFileLoader), "Could not get font file loader." );
1448
1449 SkTScopedComPtr<IDWriteFontFileStream> fontFileStream;
1450 HRNM(fontFileLoader->CreateStreamFromKey(fontFileKey, fontFileKeySize,
1451 &fontFileStream),
1452 "Could not create font file stream.");
1453
1454 return SkNEW_ARGS(SkDWriteFontFileStream, (fontFileStream.get()));
1455 }
1456
1457 SkScalerContext* DWriteFontTypeface::onCreateScalerContext(const SkDescriptor* d esc) const {
1458 return SkNEW_ARGS(SkScalerContext_DW, (const_cast<DWriteFontTypeface*>(this) , desc));
1459 }
1460
1461 void DWriteFontTypeface::onFilterRec(SkScalerContext::Rec* rec) const {
1462 if (rec->fFlags & SkScalerContext::kLCD_BGROrder_Flag ||
1463 rec->fFlags & SkScalerContext::kLCD_Vertical_Flag)
1464 {
1465 rec->fMaskFormat = SkMask::kA8_Format;
1466 }
1467
1468 unsigned flagsWeDontSupport = SkScalerContext::kDevKernText_Flag |
1469 SkScalerContext::kForceAutohinting_Flag |
1470 SkScalerContext::kEmbolden_Flag |
1471 SkScalerContext::kLCD_BGROrder_Flag |
1472 SkScalerContext::kLCD_Vertical_Flag;
1473 rec->fFlags &= ~flagsWeDontSupport;
1474
1475 SkPaint::Hinting h = rec->getHinting();
1476 // DirectWrite does not provide for hinting hints.
1477 h = SkPaint::kSlight_Hinting;
1478 rec->setHinting(h);
1479
1480 #if SK_FONT_HOST_USE_SYSTEM_SETTINGS
1481 IDWriteFactory* factory = get_dwrite_factory();
1482 if (factory != NULL) {
1483 SkTScopedComPtr<IDWriteRenderingParams> defaultRenderingParams;
1484 if (SUCCEEDED(factory->CreateRenderingParams(&defaultRenderingParams))) {
1485 float gamma = defaultRenderingParams->GetGamma();
1486 rec->setDeviceGamma(gamma);
1487 rec->setPaintGamma(gamma);
1488
1489 rec->setContrast(defaultRenderingParams->GetEnhancedContrast());
1490 }
1491 }
1492 #endif
1493 }
1494
1495 ///////////////////////////////////////////////////////////////////////////////
1496 //PDF Support
1497
1498 using namespace skia_advanced_typeface_metrics_utils;
1499
1500 // Construct Glyph to Unicode table.
1501 // Unicode code points that require conjugate pairs in utf16 are not
1502 // supported.
1503 // TODO(arthurhsu): Add support for conjugate pairs. It looks like that may
1504 // require parsing the TTF cmap table (platform 4, encoding 12) directly instead
1505 // of calling GetFontUnicodeRange().
1506 // TODO(bungeman): This never does what anyone wants.
1507 // What is really wanted is the text to glyphs mapping
1508 static void populate_glyph_to_unicode(IDWriteFontFace* fontFace,
1509 const unsigned glyphCount,
1510 SkTDArray<SkUnichar>* glyphToUnicode) {
1511 HRESULT hr = S_OK;
1512
1513 //Do this like free type instead
1514 UINT32 count = 0;
1515 for (UINT32 c = 0; c < 0x10FFFF; ++c) {
1516 UINT16 glyph;
1517 hr = fontFace->GetGlyphIndices(&c, 1, &glyph);
1518 if (glyph > 0) {
1519 ++count;
1520 }
1521 }
1522
1523 SkAutoTArray<UINT32> chars(count);
1524 count = 0;
1525 for (UINT32 c = 0; c < 0x10FFFF; ++c) {
1526 UINT16 glyph;
1527 hr = fontFace->GetGlyphIndices(&c, 1, &glyph);
1528 if (glyph > 0) {
1529 chars[count] = c;
1530 ++count;
1531 }
1532 }
1533
1534 SkAutoTArray<UINT16> glyph(count);
1535 fontFace->GetGlyphIndices(chars.get(), count, glyph.get());
1536
1537 USHORT maxGlyph = 0;
1538 for (USHORT j = 0; j < count; ++j) {
1539 if (glyph[j] > maxGlyph) maxGlyph = glyph[j];
1540 }
1541
1542 glyphToUnicode->setCount(maxGlyph+1);
1543 for (USHORT j = 0; j < maxGlyph+1u; ++j) {
1544 (*glyphToUnicode)[j] = 0;
1545 }
1546
1547 //'invert'
1548 for (USHORT j = 0; j < count; ++j) {
1549 if (glyph[j] < glyphCount && (*glyphToUnicode)[glyph[j]] == 0) {
1550 (*glyphToUnicode)[glyph[j]] = chars[j];
1551 }
1552 }
1553 }
1554
1555 static bool getWidthAdvance(IDWriteFontFace* fontFace, int gId, int16_t* advance ) {
1556 SkASSERT(advance);
1557
1558 UINT16 glyphId = gId;
1559 DWRITE_GLYPH_METRICS gm;
1560 HRESULT hr = fontFace->GetDesignGlyphMetrics(&glyphId, 1, &gm);
1561
1562 if (FAILED(hr)) {
1563 *advance = 0;
1564 return false;
1565 }
1566
1567 *advance = gm.advanceWidth;
1568 return true;
1569 }
1570
1571 SkAdvancedTypefaceMetrics* DWriteFontTypeface::onGetAdvancedTypefaceMetrics(
1572 SkAdvancedTypefaceMetrics::PerGlyphInfo perGlyphInfo,
1573 const uint32_t* glyphIDs,
1574 uint32_t glyphIDsCount) const {
1575
1576 SkAdvancedTypefaceMetrics* info = NULL;
1577
1578 HRESULT hr = S_OK;
1579
1580 const unsigned glyphCount = fDWriteFontFace->GetGlyphCount();
1581
1582 DWRITE_FONT_METRICS dwfm;
1583 fDWriteFontFace->GetMetrics(&dwfm);
1584
1585 info = new SkAdvancedTypefaceMetrics;
1586 info->fEmSize = dwfm.designUnitsPerEm;
1587 info->fMultiMaster = false;
1588 info->fLastGlyphID = SkToU16(glyphCount - 1);
1589 info->fStyle = 0;
1590
1591
1592 SkTScopedComPtr<IDWriteLocalizedStrings> familyNames;
1593 SkTScopedComPtr<IDWriteLocalizedStrings> faceNames;
1594 hr = fDWriteFontFamily->GetFamilyNames(&familyNames);
1595 hr = fDWriteFont->GetFaceNames(&faceNames);
1596
1597 UINT32 familyNameLength;
1598 hr = familyNames->GetStringLength(0, &familyNameLength);
1599
1600 UINT32 faceNameLength;
1601 hr = faceNames->GetStringLength(0, &faceNameLength);
1602
1603 UINT32 size = familyNameLength+1+faceNameLength+1;
1604 SkSMallocWCHAR wFamilyName(size);
1605 hr = familyNames->GetString(0, wFamilyName.get(), size);
1606 wFamilyName[familyNameLength] = L' ';
1607 hr = faceNames->GetString(0, &wFamilyName[familyNameLength+1], size - faceNa meLength + 1);
1608
1609 hr = sk_wchar_to_skstring(wFamilyName.get(), &info->fFontName);
1610
1611 if (perGlyphInfo & SkAdvancedTypefaceMetrics::kToUnicode_PerGlyphInfo) {
1612 populate_glyph_to_unicode(fDWriteFontFace.get(), glyphCount, &(info->fGl yphToUnicode));
1613 }
1614
1615 DWRITE_FONT_FACE_TYPE fontType = fDWriteFontFace->GetType();
1616 if (fontType == DWRITE_FONT_FACE_TYPE_TRUETYPE ||
1617 fontType == DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION) {
1618 info->fType = SkAdvancedTypefaceMetrics::kTrueType_Font;
1619 } else {
1620 info->fType = SkAdvancedTypefaceMetrics::kOther_Font;
1621 info->fItalicAngle = 0;
1622 info->fAscent = dwfm.ascent;;
1623 info->fDescent = dwfm.descent;
1624 info->fStemV = 0;
1625 info->fCapHeight = dwfm.capHeight;
1626 info->fBBox = SkIRect::MakeEmpty();
1627 return info;
1628 }
1629
1630 AutoTDWriteTable<SkOTTableHead> headTable(fDWriteFontFace.get());
1631 AutoTDWriteTable<SkOTTablePostScript> postTable(fDWriteFontFace.get());
1632 AutoTDWriteTable<SkOTTableHorizontalHeader> hheaTable(fDWriteFontFace.get()) ;
1633 AutoTDWriteTable<SkOTTableOS2> os2Table(fDWriteFontFace.get());
1634 if (!headTable.fExists || !postTable.fExists || !hheaTable.fExists || !os2Ta ble.fExists) {
1635 info->fItalicAngle = 0;
1636 info->fAscent = dwfm.ascent;;
1637 info->fDescent = dwfm.descent;
1638 info->fStemV = 0;
1639 info->fCapHeight = dwfm.capHeight;
1640 info->fBBox = SkIRect::MakeEmpty();
1641 return info;
1642 }
1643
1644 //There exist CJK fonts which set the IsFixedPitch and Monospace bits,
1645 //but have full width, latin half-width, and half-width kana.
1646 bool fixedWidth = (postTable->isFixedPitch &&
1647 (1 == SkEndian_SwapBE16(hheaTable->numberOfHMetrics)));
1648 //Monospace
1649 if (fixedWidth) {
1650 info->fStyle |= SkAdvancedTypefaceMetrics::kFixedPitch_Style;
1651 }
1652 //Italic
1653 if (os2Table->version.v0.fsSelection.field.Italic) {
1654 info->fStyle |= SkAdvancedTypefaceMetrics::kItalic_Style;
1655 }
1656 //Script
1657 if (SkPanose::FamilyType::Script == os2Table->version.v0.panose.bFamilyType. value) {
1658 info->fStyle |= SkAdvancedTypefaceMetrics::kScript_Style;
1659 //Serif
1660 } else if (SkPanose::FamilyType::TextAndDisplay == os2Table->version.v0.pano se.bFamilyType.value &&
1661 SkPanose::Data::TextAndDisplay::SerifStyle::Triangle <= os2Table- >version.v0.panose.data.textAndDisplay.bSerifStyle.value &&
1662 SkPanose::Data::TextAndDisplay::SerifStyle::NoFit != os2Table->ve rsion.v0.panose.data.textAndDisplay.bSerifStyle.value) {
1663 info->fStyle |= SkAdvancedTypefaceMetrics::kSerif_Style;
1664 }
1665
1666 info->fItalicAngle = SkEndian_SwapBE32(postTable->italicAngle) >> 16;
1667
1668 info->fAscent = SkToS16(dwfm.ascent);
1669 info->fDescent = SkToS16(dwfm.descent);
1670 info->fCapHeight = SkToS16(dwfm.capHeight);
1671
1672 info->fBBox = SkIRect::MakeLTRB((int32_t)SkEndian_SwapBE16((uint16_t)headTab le->xMin),
1673 (int32_t)SkEndian_SwapBE16((uint16_t)headTab le->yMax),
1674 (int32_t)SkEndian_SwapBE16((uint16_t)headTab le->xMax),
1675 (int32_t)SkEndian_SwapBE16((uint16_t)headTab le->yMin));
1676
1677 //TODO: is this even desired? It seems PDF only wants this value for Type1
1678 //fonts, and we only get here for TrueType fonts.
1679 info->fStemV = 0;
1680 /*
1681 // Figure out a good guess for StemV - Min width of i, I, !, 1.
1682 // This probably isn't very good with an italic font.
1683 int16_t min_width = SHRT_MAX;
1684 info->fStemV = 0;
1685 char stem_chars[] = {'i', 'I', '!', '1'};
1686 for (size_t i = 0; i < SK_ARRAY_COUNT(stem_chars); i++) {
1687 ABC abcWidths;
1688 if (GetCharABCWidths(hdc, stem_chars[i], stem_chars[i], &abcWidths)) {
1689 int16_t width = abcWidths.abcB;
1690 if (width > 0 && width < min_width) {
1691 min_width = width;
1692 info->fStemV = min_width;
1693 }
1694 }
1695 }
1696 */
1697
1698 // If Restricted, the font may not be embedded in a document.
1699 // If not Restricted, the font can be embedded.
1700 // If PreviewPrint, the embedding is read-only.
1701 if (os2Table->version.v0.fsType.field.Restricted) {
1702 info->fType = SkAdvancedTypefaceMetrics::kNotEmbeddable_Font;
1703 } else if (perGlyphInfo & SkAdvancedTypefaceMetrics::kHAdvance_PerGlyphInfo) {
1704 if (fixedWidth) {
1705 appendRange(&info->fGlyphWidths, 0);
1706 int16_t advance;
1707 getWidthAdvance(fDWriteFontFace.get(), 1, &advance);
1708 info->fGlyphWidths->fAdvance.append(1, &advance);
1709 finishRange(info->fGlyphWidths.get(), 0,
1710 SkAdvancedTypefaceMetrics::WidthRange::kDefault);
1711 } else {
1712 info->fGlyphWidths.reset(
1713 getAdvanceData(fDWriteFontFace.get(),
1714 glyphCount,
1715 glyphIDs,
1716 glyphIDsCount,
1717 getWidthAdvance));
1718 }
1719 }
1720
1721 return info;
1722 }
1723
1724 ///////////////////////////////////////////////////////////////////////////////
1725
1726 SkTypeface* SkFontMgr_DirectWrite::createTypefaceFromDWriteFont(
1727 IDWriteFontFace* fontFace,
1728 IDWriteFont* font,
1729 IDWriteFontFamily* fontFamily) const {
1730 SkTypeface* face = FindByProcAndRef(FindByDWriteFont, font);
1731 if (NULL == face) {
1732 face = DWriteFontTypeface::Create(fFactory.get(), fontFace, font, fontFa mily);
1733 if (face) {
1734 Add(face, get_style(font), true);
1735 }
1736 }
1737 return face;
1738 }
1739
1740 int SkFontMgr_DirectWrite::onCountFamilies() const {
1741 return fFontCollection->GetFontFamilyCount();
1742 }
1743
1744 void SkFontMgr_DirectWrite::onGetFamilyName(int index, SkString* familyName) con st {
1745 SkTScopedComPtr<IDWriteFontFamily> fontFamily;
1746 HRVM(fFontCollection->GetFontFamily(index, &fontFamily), "Could not get requ ested family.");
1747
1748 SkTScopedComPtr<IDWriteLocalizedStrings> familyNames;
1749 HRVM(fontFamily->GetFamilyNames(&familyNames), "Could not get family names." );
1750
1751 sk_get_locale_string(familyNames.get(), fLocaleName.get(), familyName);
1752 }
1753
1754 SkFontStyleSet* SkFontMgr_DirectWrite::onCreateStyleSet(int index) const {
1755 SkTScopedComPtr<IDWriteFontFamily> fontFamily;
1756 HRNM(fFontCollection->GetFontFamily(index, &fontFamily), "Could not get requ ested family.");
1757
1758 return SkNEW_ARGS(SkFontStyleSet_DirectWrite, (this, fontFamily.get()));
1759 }
1760
1761 SkFontStyleSet* SkFontMgr_DirectWrite::onMatchFamily(const char familyName[]) co nst {
1762 SkSMallocWCHAR dwFamilyName;
1763 HRN(sk_cstring_to_wchar(familyName, &dwFamilyName));
1764
1765 UINT32 index;
1766 BOOL exists;
1767 HRNM(fFontCollection->FindFamilyName(dwFamilyName.get(), &index, &exists),
1768 "Failed while finding family by name.");
1769 if (!exists) {
1770 return NULL;
1771 }
1772
1773 return this->onCreateStyleSet(index);
1774 }
1775
1776 SkTypeface* SkFontMgr_DirectWrite::onMatchFamilyStyle(const char familyName[],
1777 const SkFontStyle& fontsty le) const {
1778 SkAutoTUnref<SkFontStyleSet> sset(this->matchFamily(familyName));
1779 return sset->matchStyle(fontstyle);
1780 }
1781
1782 SkTypeface* SkFontMgr_DirectWrite::onMatchFaceStyle(const SkTypeface* familyMemb er,
1783 const SkFontStyle& fontstyle ) const {
1784 SkString familyName;
1785 SkFontStyleSet_DirectWrite sset(
1786 this, ((DWriteFontTypeface*)familyMember)->fDWriteFontFamily.get()
1787 );
1788 return sset.matchStyle(fontstyle);
1789 }
1790
1791 SkTypeface* SkFontMgr_DirectWrite::onCreateFromStream(SkStream* stream, int ttcI ndex) const {
1792 SkTScopedComPtr<StreamFontFileLoader> fontFileLoader;
1793 HRN(StreamFontFileLoader::Create(stream, &fontFileLoader));
1794 HRN(fFactory->RegisterFontFileLoader(fontFileLoader.get()));
1795 SkAutoIDWriteUnregister<StreamFontFileLoader> autoUnregisterFontFileLoader(
1796 fFactory.get(), fontFileLoader.get());
1797
1798 SkTScopedComPtr<StreamFontCollectionLoader> fontCollectionLoader;
1799 HRN(StreamFontCollectionLoader::Create(fontFileLoader.get(), &fontCollection Loader));
1800 HRN(fFactory->RegisterFontCollectionLoader(fontCollectionLoader.get()));
1801 SkAutoIDWriteUnregister<StreamFontCollectionLoader> autoUnregisterFontCollec tionLoader(
1802 fFactory.get(), fontCollectionLoader.get());
1803
1804 SkTScopedComPtr<IDWriteFontCollection> fontCollection;
1805 HRN(fFactory->CreateCustomFontCollection(fontCollectionLoader.get(), NULL, 0 , &fontCollection));
1806
1807 // Find the first non-simulated font which has the given ttc index.
1808 UINT32 familyCount = fontCollection->GetFontFamilyCount();
1809 for (UINT32 familyIndex = 0; familyIndex < familyCount; ++familyIndex) {
1810 SkTScopedComPtr<IDWriteFontFamily> fontFamily;
1811 HRN(fontCollection->GetFontFamily(familyIndex, &fontFamily));
1812
1813 UINT32 fontCount = fontFamily->GetFontCount();
1814 for (UINT32 fontIndex = 0; fontIndex < fontCount; ++fontIndex) {
1815 SkTScopedComPtr<IDWriteFont> font;
1816 HRN(fontFamily->GetFont(fontIndex, &font));
1817 if (font->GetSimulations() != DWRITE_FONT_SIMULATIONS_NONE) {
1818 continue;
1819 }
1820
1821 SkTScopedComPtr<IDWriteFontFace> fontFace;
1822 HRN(font->CreateFontFace(&fontFace));
1823
1824 UINT32 faceIndex = fontFace->GetIndex();
1825 if (faceIndex == ttcIndex) {
1826 return DWriteFontTypeface::Create(fFactory.get(),
1827 fontFace.get(), font.get(), fo ntFamily.get(),
1828 autoUnregisterFontFileLoader.d etatch(),
1829 autoUnregisterFontCollectionLo ader.detatch());
1830 }
1831 }
1832 }
1833
1834 return NULL;
1835 }
1836
1837 SkTypeface* SkFontMgr_DirectWrite::onCreateFromData(SkData* data, int ttcIndex) const {
1838 SkAutoTUnref<SkStream> stream(SkNEW_ARGS(SkMemoryStream, (data)));
1839 return this->createFromStream(stream, ttcIndex);
1840 }
1841
1842 SkTypeface* SkFontMgr_DirectWrite::onCreateFromFile(const char path[], int ttcIn dex) const {
1843 SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path));
1844 return this->createFromStream(stream, ttcIndex);
1845 }
1846
1847 HRESULT SkFontMgr_DirectWrite::getByFamilyName(const WCHAR wideFamilyName[],
1848 IDWriteFontFamily** fontFamily) c onst {
1849 UINT32 index;
1850 BOOL exists;
1851 HR(fFontCollection->FindFamilyName(wideFamilyName, &index, &exists));
1852
1853 if (exists) {
1854 HR(fFontCollection->GetFontFamily(index, fontFamily));
1855 }
1856 return S_OK;
1857 }
1858
1859 HRESULT SkFontMgr_DirectWrite::getDefaultFontFamily(IDWriteFontFamily** fontFami ly) const {
1860 NONCLIENTMETRICSW metrics;
1861 metrics.cbSize = sizeof(metrics);
1862 if (0 == SystemParametersInfoW(SPI_GETNONCLIENTMETRICS,
1863 sizeof(metrics),
1864 &metrics,
1865 0)) {
1866 return E_UNEXPECTED;
1867 }
1868 HRM(this->getByFamilyName(metrics.lfMessageFont.lfFaceName, fontFamily),
1869 "Could not create DWrite font family from LOGFONT.");
1870 return S_OK;
1871 }
1872
1873 SkTypeface* SkFontMgr_DirectWrite::onLegacyCreateTypeface(const char familyName[ ],
1874 unsigned styleBits) co nst {
1875 SkTScopedComPtr<IDWriteFontFamily> fontFamily;
1876 if (familyName) {
1877 SkSMallocWCHAR wideFamilyName;
1878 if (SUCCEEDED(sk_cstring_to_wchar(familyName, &wideFamilyName))) {
1879 this->getByFamilyName(wideFamilyName, &fontFamily);
1880 }
1881 }
1882
1883 if (NULL == fontFamily.get()) {
1884 // No family with given name, try default.
1885 HRNM(this->getDefaultFontFamily(&fontFamily), "Could not get default fon t family.");
1886 }
1887
1888 if (NULL == fontFamily.get()) {
1889 // Could not obtain the default font.
1890 HRNM(fFontCollection->GetFontFamily(0, &fontFamily),
1891 "Could not get default-default font family.");
1892 }
1893
1894 SkTScopedComPtr<IDWriteFont> font;
1895 DWRITE_FONT_WEIGHT weight = (styleBits & SkTypeface::kBold)
1896 ? DWRITE_FONT_WEIGHT_BOLD
1897 : DWRITE_FONT_WEIGHT_NORMAL;
1898 DWRITE_FONT_STRETCH stretch = DWRITE_FONT_STRETCH_NORMAL;
1899 DWRITE_FONT_STYLE italic = (styleBits & SkTypeface::kItalic)
1900 ? DWRITE_FONT_STYLE_ITALIC
1901 : DWRITE_FONT_STYLE_NORMAL;
1902 HRNM(fontFamily->GetFirstMatchingFont(weight, stretch, italic, &font),
1903 "Could not get matching font.");
1904
1905 SkTScopedComPtr<IDWriteFontFace> fontFace;
1906 HRNM(font->CreateFontFace(&fontFace), "Could not create font face.");
1907
1908 return this->createTypefaceFromDWriteFont(fontFace.get(), font.get(), fontFa mily.get());
1909 }
1910
1911 ///////////////////////////////////////////////////////////////////////////////
1912
1913 int SkFontStyleSet_DirectWrite::count() {
1914 return fFontFamily->GetFontCount();
1915 }
1916
1917 SkTypeface* SkFontStyleSet_DirectWrite::createTypeface(int index) {
1918 SkTScopedComPtr<IDWriteFont> font;
1919 HRNM(fFontFamily->GetFont(index, &font), "Could not get font.");
1920
1921 SkTScopedComPtr<IDWriteFontFace> fontFace;
1922 HRNM(font->CreateFontFace(&fontFace), "Could not create font face.");
1923
1924 return fFontMgr->createTypefaceFromDWriteFont(fontFace.get(), font.get(), fF ontFamily.get());
1925 }
1926
1927 void SkFontStyleSet_DirectWrite::getStyle(int index, SkFontStyle* fs, SkString* styleName) {
1928 SkTScopedComPtr<IDWriteFont> font;
1929 HRVM(fFontFamily->GetFont(index, &font), "Could not get font.");
1930
1931 if (fs) {
1932 SkFontStyle::Slant slant;
1933 switch (font->GetStyle()) {
1934 case DWRITE_FONT_STYLE_NORMAL:
1935 slant = SkFontStyle::kUpright_Slant;
1936 break;
1937 case DWRITE_FONT_STYLE_OBLIQUE:
1938 case DWRITE_FONT_STYLE_ITALIC:
1939 slant = SkFontStyle::kItalic_Slant;
1940 break;
1941 default:
1942 SkASSERT(false);
1943 }
1944
1945 int weight = font->GetWeight();
1946 int width = font->GetStretch();
1947
1948 *fs = SkFontStyle(weight, width, slant);
1949 }
1950
1951 if (styleName) {
1952 SkTScopedComPtr<IDWriteLocalizedStrings> faceNames;
1953 if (SUCCEEDED(font->GetFaceNames(&faceNames))) {
1954 sk_get_locale_string(faceNames.get(), fFontMgr->fLocaleName.get(), s tyleName);
1955 }
1956 }
1957 }
1958
1959 SkTypeface* SkFontStyleSet_DirectWrite::matchStyle(const SkFontStyle& pattern) {
1960 DWRITE_FONT_STYLE slant;
1961 switch (pattern.slant()) {
1962 case SkFontStyle::kUpright_Slant:
1963 slant = DWRITE_FONT_STYLE_NORMAL;
1964 break;
1965 case SkFontStyle::kItalic_Slant:
1966 slant = DWRITE_FONT_STYLE_ITALIC;
1967 break;
1968 default:
1969 SkASSERT(false);
1970 }
1971
1972 DWRITE_FONT_WEIGHT weight = (DWRITE_FONT_WEIGHT)pattern.weight();
1973 DWRITE_FONT_STRETCH width = (DWRITE_FONT_STRETCH)pattern.width();
1974
1975 SkTScopedComPtr<IDWriteFont> font;
1976 // TODO: perhaps use GetMatchingFonts and get the least simulated?
1977 HRNM(fFontFamily->GetFirstMatchingFont(weight, width, slant, &font),
1978 "Could not match font in family.");
1979
1980 SkTScopedComPtr<IDWriteFontFace> fontFace;
1981 HRNM(font->CreateFontFace(&fontFace), "Could not create font face.");
1982
1983 return fFontMgr->createTypefaceFromDWriteFont(fontFace.get(), font.get(),
1984 fFontFamily.get());
1985 }
1986
1987 ///////////////////////////////////////////////////////////////////////////////
1988
1989 SkFontMgr* SkFontMgr_New_DirectWrite(IDWriteFactory* factory) {
1990 if (NULL == factory) {
1991 factory = sk_get_dwrite_factory();
1992 if (NULL == factory) {
1993 return NULL;
1994 }
1995 }
1996
1997 SkTScopedComPtr<IDWriteFontCollection> sysFontCollection;
1998 HRNM(factory->GetSystemFontCollection(&sysFontCollection, FALSE),
1999 "Could not get system font collection.");
2000
2001 WCHAR localeNameStorage[LOCALE_NAME_MAX_LENGTH];
2002 WCHAR* localeName = NULL;
2003 int localeNameLen = 0;
2004
2005 // Dynamically load GetUserDefaultLocaleName function, as it is not availabl e on XP.
2006 SkGetUserDefaultLocaleNameProc getUserDefaultLocaleNameProc = NULL;
2007 HRESULT hr = SkGetGetUserDefaultLocaleNameProc(&getUserDefaultLocaleNameProc );
2008 if (NULL == getUserDefaultLocaleNameProc) {
2009 SK_TRACEHR(hr, "Could not get GetUserDefaultLocaleName.");
2010 } else {
2011 localeNameLen = getUserDefaultLocaleNameProc(localeNameStorage, LOCALE_N AME_MAX_LENGTH);
2012 if (localeNameLen) {
2013 localeName = localeNameStorage;
2014 };
2015 }
2016
2017 return SkNEW_ARGS(SkFontMgr_DirectWrite, (factory, sysFontCollection.get(),
2018 localeName, localeNameLen));
2019 }
2020
2021 #include "SkFontMgr_indirect.h"
2022 SkFontMgr* SkFontMgr_New_DirectWriteRenderer(SkRemotableFontMgr* proxy) {
2023 SkAutoTUnref<SkFontMgr> impl(SkFontMgr_New_DirectWrite());
2024 if (impl.get() == NULL) {
2025 return NULL;
2026 }
2027 return SkNEW_ARGS(SkFontMgr_Indirect, (impl.get(), proxy));
2028 }
OLDNEW
« no previous file with comments | « gyp/ports.gyp ('k') | src/ports/SkFontMgr_win_dw.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698