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