| OLD | NEW |
| 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 Loading... |
| 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 } | |
| OLD | NEW |