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