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