| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2011 Google Inc. | 2 * Copyright 2011 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkTypes.h" | 8 #include "SkTypes.h" |
| 9 #undef GetGlyphIndices | 9 #undef GetGlyphIndices |
| 10 | 10 |
| 11 #include "SkAdvancedTypefaceMetrics.h" | 11 #include "SkAdvancedTypefaceMetrics.h" |
| 12 #include "SkColorFilter.h" | 12 #include "SkColorFilter.h" |
| 13 #include "SkDWrite.h" |
| 13 #include "SkDWriteFontFileStream.h" | 14 #include "SkDWriteFontFileStream.h" |
| 14 #include "SkDWriteGeometrySink.h" | 15 #include "SkDWriteGeometrySink.h" |
| 15 #include "SkDescriptor.h" | 16 #include "SkDescriptor.h" |
| 16 #include "SkEndian.h" | 17 #include "SkEndian.h" |
| 17 #include "SkFontDescriptor.h" | 18 #include "SkFontDescriptor.h" |
| 18 #include "SkFontHost.h" | 19 #include "SkFontHost.h" |
| 19 #include "SkFontMgr.h" | 20 #include "SkFontMgr.h" |
| 20 #include "SkFontStream.h" | 21 #include "SkFontStream.h" |
| 21 #include "SkGlyph.h" | 22 #include "SkGlyph.h" |
| 22 #include "SkHRESULT.h" | 23 #include "SkHRESULT.h" |
| (...skipping 12 matching lines...) Expand all Loading... |
| 35 #include "SkTypefaceCache.h" | 36 #include "SkTypefaceCache.h" |
| 36 #include "SkUtils.h" | 37 #include "SkUtils.h" |
| 37 | 38 |
| 38 #include <dwrite.h> | 39 #include <dwrite.h> |
| 39 | 40 |
| 40 static bool isLCD(const SkScalerContext::Rec& rec) { | 41 static bool isLCD(const SkScalerContext::Rec& rec) { |
| 41 return SkMask::kLCD16_Format == rec.fMaskFormat || | 42 return SkMask::kLCD16_Format == rec.fMaskFormat || |
| 42 SkMask::kLCD32_Format == rec.fMaskFormat; | 43 SkMask::kLCD32_Format == rec.fMaskFormat; |
| 43 } | 44 } |
| 44 | 45 |
| 45 /** Prefer to use this type to prevent template proliferation. */ | |
| 46 typedef SkAutoSTMalloc<16, WCHAR> SkSMallocWCHAR; | |
| 47 | |
| 48 /** Converts a utf8 string to a WCHAR string. */ | |
| 49 static 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. */ | |
| 64 static 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 | |
| 72 // TODO: remove after https://code.google.com/p/skia/issues/detail?id=1989 i
s fixed. | |
| 73 // If we resize to 0 then the skname points to gEmptyRec (the unique empty S
kString::Rec). | |
| 74 // gEmptyRec is static const and on Windows this means the value is in a rea
d only page. | |
| 75 // Writing to it in the following call to WideCharToMultiByte will cause an
access violation. | |
| 76 if (1 == len) { | |
| 77 return S_OK; | |
| 78 } | |
| 79 | |
| 80 len = WideCharToMultiByte(CP_UTF8, 0, name, -1, skname->writable_str(), len,
NULL, NULL); | |
| 81 if (0 == len) { | |
| 82 HRM(HRESULT_FROM_WIN32(GetLastError()), "Could not convert utf-8 to wcha
r."); | |
| 83 } | |
| 84 return S_OK; | |
| 85 } | |
| 86 | |
| 87 /////////////////////////////////////////////////////////////////////////////// | |
| 88 | |
| 89 static void create_dwrite_factory(IDWriteFactory** factory) { | |
| 90 typedef decltype(DWriteCreateFactory)* DWriteCreateFactoryProc; | |
| 91 DWriteCreateFactoryProc dWriteCreateFactoryProc = reinterpret_cast<DWriteCre
ateFactoryProc>( | |
| 92 GetProcAddress(LoadLibraryW(L"dwrite.dll"), "DWriteCreateFactory")); | |
| 93 | |
| 94 if (!dWriteCreateFactoryProc) { | |
| 95 HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); | |
| 96 if (!IS_ERROR(hr)) { | |
| 97 hr = ERROR_PROC_NOT_FOUND; | |
| 98 } | |
| 99 HRVM(hr, "Could not get DWriteCreateFactory proc."); | |
| 100 } | |
| 101 | |
| 102 HRVM(dWriteCreateFactoryProc(DWRITE_FACTORY_TYPE_SHARED, | |
| 103 __uuidof(IDWriteFactory), | |
| 104 reinterpret_cast<IUnknown**>(factory)), | |
| 105 "Could not create DirectWrite factory."); | |
| 106 } | |
| 107 | |
| 108 static IDWriteFactory* get_dwrite_factory() { | |
| 109 static IDWriteFactory* gDWriteFactory = NULL; | |
| 110 SK_DECLARE_STATIC_ONCE(once); | |
| 111 SkOnce(&once, create_dwrite_factory, &gDWriteFactory); | |
| 112 | |
| 113 return gDWriteFactory; | |
| 114 } | |
| 115 | |
| 116 /////////////////////////////////////////////////////////////////////////////// | 46 /////////////////////////////////////////////////////////////////////////////// |
| 117 | 47 |
| 118 class StreamFontFileLoader; | 48 class StreamFontFileLoader; |
| 119 | 49 |
| 120 class SkFontMgr_DirectWrite : public SkFontMgr { | 50 class SkFontMgr_DirectWrite : public SkFontMgr { |
| 121 public: | 51 public: |
| 122 /** localeNameLength must include the null terminator. */ | 52 /** localeNameLength must include the null terminator. */ |
| 123 SkFontMgr_DirectWrite(IDWriteFontCollection* fontCollection, | 53 SkFontMgr_DirectWrite(IDWriteFontCollection* fontCollection, |
| 124 WCHAR* localeName, int localeNameLength) | 54 WCHAR* localeName, int localeNameLength) |
| 125 : fFontCollection(SkRefComPtr(fontCollection)) | 55 : fFontCollection(SkRefComPtr(fontCollection)) |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 208 private: | 138 private: |
| 209 uint16_t fWidth; | 139 uint16_t fWidth; |
| 210 uint16_t fHeight; | 140 uint16_t fHeight; |
| 211 IDWriteFontFace* fFontFace; | 141 IDWriteFontFace* fFontFace; |
| 212 FLOAT fFontSize; | 142 FLOAT fFontSize; |
| 213 DWRITE_MATRIX fXform; | 143 DWRITE_MATRIX fXform; |
| 214 SkTDArray<uint8_t> fBits; | 144 SkTDArray<uint8_t> fBits; |
| 215 }; | 145 }; |
| 216 | 146 |
| 217 const void* DWriteOffscreen::draw(const SkGlyph& glyph, bool isBW) { | 147 const void* DWriteOffscreen::draw(const SkGlyph& glyph, bool isBW) { |
| 218 IDWriteFactory* factory = get_dwrite_factory(); | 148 IDWriteFactory* factory = sk_get_dwrite_factory(); |
| 219 SkASSERT(factory != NULL); | 149 SkASSERT(factory != NULL); |
| 220 | 150 |
| 221 if (fWidth < glyph.fWidth || fHeight < glyph.fHeight) { | 151 if (fWidth < glyph.fWidth || fHeight < glyph.fHeight) { |
| 222 fWidth = SkMax32(fWidth, glyph.fWidth); | 152 fWidth = SkMax32(fWidth, glyph.fWidth); |
| 223 fHeight = SkMax32(fHeight, glyph.fHeight); | 153 fHeight = SkMax32(fHeight, glyph.fHeight); |
| 224 | 154 |
| 225 if (isBW) { | 155 if (isBW) { |
| 226 fBits.setCount(fWidth * fHeight); | 156 fBits.setCount(fWidth * fHeight); |
| 227 } else { | 157 } else { |
| 228 fBits.setCount(fWidth * fHeight * 3); | 158 fBits.setCount(fWidth * fHeight * 3); |
| (...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 553 IDWriteFontFamily* fontFamily, | 483 IDWriteFontFamily* fontFamily, |
| 554 StreamFontFileLoader* fontFileLoader = NUL
L, | 484 StreamFontFileLoader* fontFileLoader = NUL
L, |
| 555 IDWriteFontCollectionLoader* fontCollectio
nLoader = NULL) { | 485 IDWriteFontCollectionLoader* fontCollectio
nLoader = NULL) { |
| 556 SkTypeface::Style style = get_style(font); | 486 SkTypeface::Style style = get_style(font); |
| 557 SkFontID fontID = SkTypefaceCache::NewFontID(); | 487 SkFontID fontID = SkTypefaceCache::NewFontID(); |
| 558 return SkNEW_ARGS(DWriteFontTypeface, (style, fontID, | 488 return SkNEW_ARGS(DWriteFontTypeface, (style, fontID, |
| 559 fontFace, font, fontFamily, | 489 fontFace, font, fontFamily, |
| 560 fontFileLoader, fontCollectionLoa
der)); | 490 fontFileLoader, fontCollectionLoa
der)); |
| 561 } | 491 } |
| 562 | 492 |
| 563 ~DWriteFontTypeface() { | 493 protected: |
| 494 virtual void weak_dispose() const SK_OVERRIDE { |
| 564 if (fDWriteFontCollectionLoader.get() == NULL) return; | 495 if (fDWriteFontCollectionLoader.get() == NULL) return; |
| 565 | 496 |
| 566 IDWriteFactory* factory = get_dwrite_factory(); | 497 IDWriteFactory* factory = sk_get_dwrite_factory(); |
| 567 SkASSERT(factory != NULL); | 498 SkASSERT(factory != NULL); |
| 568 HRV(factory->UnregisterFontCollectionLoader(fDWriteFontCollectionLoader.
get())); | 499 HRV(factory->UnregisterFontCollectionLoader(fDWriteFontCollectionLoader.
get())); |
| 569 HRV(factory->UnregisterFontFileLoader(fDWriteFontFileLoader.get())); | 500 HRV(factory->UnregisterFontFileLoader(fDWriteFontFileLoader.get())); |
| 501 |
| 502 //SkTypefaceCache::Remove(this); |
| 503 INHERITED::weak_dispose(); |
| 570 } | 504 } |
| 571 | 505 |
| 572 protected: | |
| 573 virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE; | 506 virtual SkStream* onOpenStream(int* ttcIndex) const SK_OVERRIDE; |
| 574 virtual SkScalerContext* onCreateScalerContext(const SkDescriptor*) const SK
_OVERRIDE; | 507 virtual SkScalerContext* onCreateScalerContext(const SkDescriptor*) const SK
_OVERRIDE; |
| 575 virtual void onFilterRec(SkScalerContextRec*) const SK_OVERRIDE; | 508 virtual void onFilterRec(SkScalerContextRec*) const SK_OVERRIDE; |
| 576 virtual SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics( | 509 virtual SkAdvancedTypefaceMetrics* onGetAdvancedTypefaceMetrics( |
| 577 SkAdvancedTypefaceMetrics::PerGlyphInfo, | 510 SkAdvancedTypefaceMetrics::PerGlyphInfo, |
| 578 const uint32_t*, uint32_t) const SK_OVERRIDE; | 511 const uint32_t*, uint32_t) const SK_OVERRIDE; |
| 579 virtual void onGetFontDescriptor(SkFontDescriptor*, bool*) const SK_OVERRIDE
; | 512 virtual void onGetFontDescriptor(SkFontDescriptor*, bool*) const SK_OVERRIDE
; |
| 580 virtual int onCharsToGlyphs(const void* chars, Encoding encoding, | 513 virtual int onCharsToGlyphs(const void* chars, Encoding encoding, |
| 581 uint16_t glyphs[], int glyphCount) const SK_OVER
RIDE; | 514 uint16_t glyphs[], int glyphCount) const SK_OVER
RIDE; |
| 582 virtual int onCountGlyphs() const SK_OVERRIDE; | 515 virtual int onCountGlyphs() const SK_OVERRIDE; |
| 583 virtual int onGetUPEM() const SK_OVERRIDE; | 516 virtual int onGetUPEM() const SK_OVERRIDE; |
| 584 virtual SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const SK_
OVERRIDE; | 517 virtual SkTypeface::LocalizedStrings* onCreateFamilyNameIterator() const SK_
OVERRIDE; |
| 585 virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE; | 518 virtual int onGetTableTags(SkFontTableTag tags[]) const SK_OVERRIDE; |
| 586 virtual size_t onGetTableData(SkFontTableTag, size_t offset, | 519 virtual size_t onGetTableData(SkFontTableTag, size_t offset, |
| 587 size_t length, void* data) const SK_OVERRIDE; | 520 size_t length, void* data) const SK_OVERRIDE; |
| 521 |
| 522 private: |
| 523 typedef SkTypeface INHERITED; |
| 588 }; | 524 }; |
| 589 | 525 |
| 590 class SkScalerContext_DW : public SkScalerContext { | 526 class SkScalerContext_DW : public SkScalerContext { |
| 591 public: | 527 public: |
| 592 SkScalerContext_DW(DWriteFontTypeface*, const SkDescriptor* desc); | 528 SkScalerContext_DW(DWriteFontTypeface*, const SkDescriptor* desc); |
| 593 virtual ~SkScalerContext_DW(); | 529 virtual ~SkScalerContext_DW(); |
| 594 | 530 |
| 595 protected: | 531 protected: |
| 596 virtual unsigned generateGlyphCount() SK_OVERRIDE; | 532 virtual unsigned generateGlyphCount() SK_OVERRIDE; |
| 597 virtual uint16_t generateCharToGlyph(SkUnichar uni) SK_OVERRIDE; | 533 virtual uint16_t generateCharToGlyph(SkUnichar uni) SK_OVERRIDE; |
| (...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 809 DWRITE_GLYPH_RUN run; | 745 DWRITE_GLYPH_RUN run; |
| 810 run.glyphCount = 1; | 746 run.glyphCount = 1; |
| 811 run.glyphAdvances = &advance; | 747 run.glyphAdvances = &advance; |
| 812 run.fontFace = fTypeface->fDWriteFontFace.get(); | 748 run.fontFace = fTypeface->fDWriteFontFace.get(); |
| 813 run.fontEmSize = SkScalarToFloat(fRec.fTextSize); | 749 run.fontEmSize = SkScalarToFloat(fRec.fTextSize); |
| 814 run.bidiLevel = 0; | 750 run.bidiLevel = 0; |
| 815 run.glyphIndices = &glyphId; | 751 run.glyphIndices = &glyphId; |
| 816 run.isSideways = FALSE; | 752 run.isSideways = FALSE; |
| 817 run.glyphOffsets = &offset; | 753 run.glyphOffsets = &offset; |
| 818 | 754 |
| 819 IDWriteFactory* factory = get_dwrite_factory(); | 755 IDWriteFactory* factory = sk_get_dwrite_factory(); |
| 820 SkASSERT(factory != NULL); | 756 SkASSERT(factory != NULL); |
| 821 | 757 |
| 822 const bool isBW = SkMask::kBW_Format == fRec.fMaskFormat; | 758 const bool isBW = SkMask::kBW_Format == fRec.fMaskFormat; |
| 823 DWRITE_RENDERING_MODE renderingMode; | 759 DWRITE_RENDERING_MODE renderingMode; |
| 824 DWRITE_TEXTURE_TYPE textureType; | 760 DWRITE_TEXTURE_TYPE textureType; |
| 825 if (isBW) { | 761 if (isBW) { |
| 826 renderingMode = DWRITE_RENDERING_MODE_ALIASED; | 762 renderingMode = DWRITE_RENDERING_MODE_ALIASED; |
| 827 textureType = DWRITE_TEXTURE_ALIASED_1x1; | 763 textureType = DWRITE_TEXTURE_ALIASED_1x1; |
| 828 } else { | 764 } else { |
| 829 renderingMode = DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC; | 765 renderingMode = DWRITE_RENDERING_MODE_CLEARTYPE_NATURAL_SYMMETRIC; |
| (...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1060 SkTScopedComPtr<IDWriteLocalizedStrings> dwFamilyNames; | 996 SkTScopedComPtr<IDWriteLocalizedStrings> dwFamilyNames; |
| 1061 HRV(fDWriteFontFamily->GetFamilyNames(&dwFamilyNames)); | 997 HRV(fDWriteFontFamily->GetFamilyNames(&dwFamilyNames)); |
| 1062 | 998 |
| 1063 UINT32 dwFamilyNamesLength; | 999 UINT32 dwFamilyNamesLength; |
| 1064 HRV(dwFamilyNames->GetStringLength(0, &dwFamilyNamesLength)); | 1000 HRV(dwFamilyNames->GetStringLength(0, &dwFamilyNamesLength)); |
| 1065 | 1001 |
| 1066 SkSMallocWCHAR dwFamilyNameChar(dwFamilyNamesLength+1); | 1002 SkSMallocWCHAR dwFamilyNameChar(dwFamilyNamesLength+1); |
| 1067 HRV(dwFamilyNames->GetString(0, dwFamilyNameChar.get(), dwFamilyNamesLength+
1)); | 1003 HRV(dwFamilyNames->GetString(0, dwFamilyNameChar.get(), dwFamilyNamesLength+
1)); |
| 1068 | 1004 |
| 1069 SkString utf8FamilyName; | 1005 SkString utf8FamilyName; |
| 1070 HRV(wchar_to_skstring(dwFamilyNameChar.get(), &utf8FamilyName)); | 1006 HRV(sk_wchar_to_skstring(dwFamilyNameChar.get(), &utf8FamilyName)); |
| 1071 | 1007 |
| 1072 desc->setFamilyName(utf8FamilyName.c_str()); | 1008 desc->setFamilyName(utf8FamilyName.c_str()); |
| 1073 *isLocalStream = SkToBool(fDWriteFontFileLoader.get()); | 1009 *isLocalStream = SkToBool(fDWriteFontFileLoader.get()); |
| 1074 } | 1010 } |
| 1075 | 1011 |
| 1076 static SkUnichar next_utf8(const void** chars) { | 1012 static SkUnichar next_utf8(const void** chars) { |
| 1077 return SkUTF8_NextUnichar((const char**)chars); | 1013 return SkUTF8_NextUnichar((const char**)chars); |
| 1078 } | 1014 } |
| 1079 | 1015 |
| 1080 static SkUnichar next_utf16(const void** chars) { | 1016 static SkUnichar next_utf16(const void** chars) { |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1170 } | 1106 } |
| 1171 | 1107 |
| 1172 // String | 1108 // String |
| 1173 UINT32 stringLength; | 1109 UINT32 stringLength; |
| 1174 HRBM(fStrings->GetStringLength(fIndex, &stringLength), "Could not get st
ring length."); | 1110 HRBM(fStrings->GetStringLength(fIndex, &stringLength), "Could not get st
ring length."); |
| 1175 stringLength += 1; | 1111 stringLength += 1; |
| 1176 | 1112 |
| 1177 SkSMallocWCHAR wString(stringLength); | 1113 SkSMallocWCHAR wString(stringLength); |
| 1178 HRBM(fStrings->GetString(fIndex, wString.get(), stringLength), "Could no
t get string."); | 1114 HRBM(fStrings->GetString(fIndex, wString.get(), stringLength), "Could no
t get string."); |
| 1179 | 1115 |
| 1180 HRB(wchar_to_skstring(wString.get(), &localizedString->fString)); | 1116 HRB(sk_wchar_to_skstring(wString.get(), &localizedString->fString)); |
| 1181 | 1117 |
| 1182 // Locale | 1118 // Locale |
| 1183 UINT32 localeLength; | 1119 UINT32 localeLength; |
| 1184 HRBM(fStrings->GetLocaleNameLength(fIndex, &localeLength), "Could not ge
t locale length."); | 1120 HRBM(fStrings->GetLocaleNameLength(fIndex, &localeLength), "Could not ge
t locale length."); |
| 1185 localeLength += 1; | 1121 localeLength += 1; |
| 1186 | 1122 |
| 1187 SkSMallocWCHAR wLocale(localeLength); | 1123 SkSMallocWCHAR wLocale(localeLength); |
| 1188 HRBM(fStrings->GetLocaleName(fIndex, wLocale.get(), localeLength), "Coul
d not get locale."); | 1124 HRBM(fStrings->GetLocaleName(fIndex, wLocale.get(), localeLength), "Coul
d not get locale."); |
| 1189 | 1125 |
| 1190 HRB(wchar_to_skstring(wLocale.get(), &localizedString->fLanguage)); | 1126 HRB(sk_wchar_to_skstring(wLocale.get(), &localizedString->fLanguage)); |
| 1191 | 1127 |
| 1192 ++fIndex; | 1128 ++fIndex; |
| 1193 return true; | 1129 return true; |
| 1194 } | 1130 } |
| 1195 | 1131 |
| 1196 private: | 1132 private: |
| 1197 UINT32 fIndex; | 1133 UINT32 fIndex; |
| 1198 SkTScopedComPtr<IDWriteLocalizedStrings> fStrings; | 1134 SkTScopedComPtr<IDWriteLocalizedStrings> fStrings; |
| 1199 }; | 1135 }; |
| 1200 | 1136 |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1285 | 1221 |
| 1286 HRESULT unregister(IDWriteFactory* factory, IDWriteFontCollectionLoader* unr
egister) { | 1222 HRESULT unregister(IDWriteFactory* factory, IDWriteFontCollectionLoader* unr
egister) { |
| 1287 return factory->UnregisterFontCollectionLoader(unregister); | 1223 return factory->UnregisterFontCollectionLoader(unregister); |
| 1288 } | 1224 } |
| 1289 | 1225 |
| 1290 IDWriteFactory* fFactory; | 1226 IDWriteFactory* fFactory; |
| 1291 T* fUnregister; | 1227 T* fUnregister; |
| 1292 }; | 1228 }; |
| 1293 | 1229 |
| 1294 static SkTypeface* create_from_stream(SkStream* stream, int ttcIndex) { | 1230 static SkTypeface* create_from_stream(SkStream* stream, int ttcIndex) { |
| 1295 IDWriteFactory* factory = get_dwrite_factory(); | 1231 IDWriteFactory* factory = sk_get_dwrite_factory(); |
| 1296 if (NULL == factory) { | 1232 if (NULL == factory) { |
| 1297 return NULL; | 1233 return NULL; |
| 1298 } | 1234 } |
| 1299 | 1235 |
| 1300 SkTScopedComPtr<StreamFontFileLoader> fontFileLoader; | 1236 SkTScopedComPtr<StreamFontFileLoader> fontFileLoader; |
| 1301 HRN(StreamFontFileLoader::Create(stream, &fontFileLoader)); | 1237 HRN(StreamFontFileLoader::Create(stream, &fontFileLoader)); |
| 1302 HRN(factory->RegisterFontFileLoader(fontFileLoader.get())); | 1238 HRN(factory->RegisterFontFileLoader(fontFileLoader.get())); |
| 1303 SkAutoIDWriteUnregister<StreamFontFileLoader> autoUnregisterFontFileLoader( | 1239 SkAutoIDWriteUnregister<StreamFontFileLoader> autoUnregisterFontFileLoader( |
| 1304 factory, fontFileLoader.get()); | 1240 factory, fontFileLoader.get()); |
| 1305 | 1241 |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1524 | 1460 |
| 1525 UINT32 faceNameLength; | 1461 UINT32 faceNameLength; |
| 1526 hr = faceNames->GetStringLength(0, &faceNameLength); | 1462 hr = faceNames->GetStringLength(0, &faceNameLength); |
| 1527 | 1463 |
| 1528 UINT32 size = familyNameLength+1+faceNameLength+1; | 1464 UINT32 size = familyNameLength+1+faceNameLength+1; |
| 1529 SkSMallocWCHAR wFamilyName(size); | 1465 SkSMallocWCHAR wFamilyName(size); |
| 1530 hr = familyNames->GetString(0, wFamilyName.get(), size); | 1466 hr = familyNames->GetString(0, wFamilyName.get(), size); |
| 1531 wFamilyName[familyNameLength] = L' '; | 1467 wFamilyName[familyNameLength] = L' '; |
| 1532 hr = faceNames->GetString(0, &wFamilyName[familyNameLength+1], size - faceNa
meLength + 1); | 1468 hr = faceNames->GetString(0, &wFamilyName[familyNameLength+1], size - faceNa
meLength + 1); |
| 1533 | 1469 |
| 1534 hr = wchar_to_skstring(wFamilyName.get(), &info->fFontName); | 1470 hr = sk_wchar_to_skstring(wFamilyName.get(), &info->fFontName); |
| 1535 | 1471 |
| 1536 if (perGlyphInfo & SkAdvancedTypefaceMetrics::kToUnicode_PerGlyphInfo) { | 1472 if (perGlyphInfo & SkAdvancedTypefaceMetrics::kToUnicode_PerGlyphInfo) { |
| 1537 populate_glyph_to_unicode(fDWriteFontFace.get(), glyphCount, &(info->fGl
yphToUnicode)); | 1473 populate_glyph_to_unicode(fDWriteFontFace.get(), glyphCount, &(info->fGl
yphToUnicode)); |
| 1538 } | 1474 } |
| 1539 | 1475 |
| 1540 DWRITE_FONT_FACE_TYPE fontType = fDWriteFontFace->GetType(); | 1476 DWRITE_FONT_FACE_TYPE fontType = fDWriteFontFace->GetType(); |
| 1541 if (fontType == DWRITE_FONT_FACE_TYPE_TRUETYPE || | 1477 if (fontType == DWRITE_FONT_FACE_TYPE_TRUETYPE || |
| 1542 fontType == DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION) { | 1478 fontType == DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION) { |
| 1543 info->fType = SkAdvancedTypefaceMetrics::kTrueType_Font; | 1479 info->fType = SkAdvancedTypefaceMetrics::kTrueType_Font; |
| 1544 } else { | 1480 } else { |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1641 glyphIDsCount, | 1577 glyphIDsCount, |
| 1642 getWidthAdvance)); | 1578 getWidthAdvance)); |
| 1643 } | 1579 } |
| 1644 } | 1580 } |
| 1645 | 1581 |
| 1646 return info; | 1582 return info; |
| 1647 } | 1583 } |
| 1648 | 1584 |
| 1649 /////////////////////////////////////////////////////////////////////////////// | 1585 /////////////////////////////////////////////////////////////////////////////// |
| 1650 | 1586 |
| 1651 static void get_locale_string(IDWriteLocalizedStrings* names, const WCHAR* prefe
redLocale, | |
| 1652 SkString* skname) { | |
| 1653 UINT32 nameIndex = 0; | |
| 1654 if (preferedLocale) { | |
| 1655 // Ignore any errors and continue with index 0 if there is a problem. | |
| 1656 BOOL nameExists; | |
| 1657 names->FindLocaleName(preferedLocale, &nameIndex, &nameExists); | |
| 1658 if (!nameExists) { | |
| 1659 nameIndex = 0; | |
| 1660 } | |
| 1661 } | |
| 1662 | |
| 1663 UINT32 nameLength; | |
| 1664 HRVM(names->GetStringLength(nameIndex, &nameLength), "Could not get name len
gth."); | |
| 1665 nameLength += 1; | |
| 1666 | |
| 1667 SkSMallocWCHAR name(nameLength); | |
| 1668 HRVM(names->GetString(nameIndex, name.get(), nameLength), "Could not get str
ing."); | |
| 1669 | |
| 1670 HRV(wchar_to_skstring(name.get(), skname)); | |
| 1671 } | |
| 1672 | |
| 1673 SkTypeface* SkFontMgr_DirectWrite::createTypefaceFromDWriteFont( | 1587 SkTypeface* SkFontMgr_DirectWrite::createTypefaceFromDWriteFont( |
| 1674 IDWriteFontFace* fontFace, | 1588 IDWriteFontFace* fontFace, |
| 1675 IDWriteFont* font, | 1589 IDWriteFont* font, |
| 1676 IDWriteFontFamily* fontFamily, | 1590 IDWriteFontFamily* fontFamily, |
| 1677 StreamFontFileLoader* fontFileLoader, | 1591 StreamFontFileLoader* fontFileLoader, |
| 1678 IDWriteFontCollectionLoader* fontCollectionLoader) const { | 1592 IDWriteFontCollectionLoader* fontCollectionLoader) const { |
| 1679 SkTypeface* face = FindByProcAndRef(FindByDWriteFont, font); | 1593 SkTypeface* face = FindByProcAndRef(FindByDWriteFont, font); |
| 1680 if (NULL == face) { | 1594 if (NULL == face) { |
| 1681 face = DWriteFontTypeface::Create(fontFace, font, fontFamily, | 1595 face = DWriteFontTypeface::Create(fontFace, font, fontFamily, |
| 1682 fontFileLoader, fontCollectionLoader); | 1596 fontFileLoader, fontCollectionLoader); |
| 1683 if (face) { | 1597 if (face) { |
| 1684 Add(face, get_style(font), fontCollectionLoader != NULL); | 1598 Add(face, get_style(font), fontCollectionLoader != NULL); |
| 1685 } | 1599 } |
| 1686 } | 1600 } |
| 1687 return face; | 1601 return face; |
| 1688 } | 1602 } |
| 1689 | 1603 |
| 1690 int SkFontMgr_DirectWrite::onCountFamilies() const { | 1604 int SkFontMgr_DirectWrite::onCountFamilies() const { |
| 1691 return fFontCollection->GetFontFamilyCount(); | 1605 return fFontCollection->GetFontFamilyCount(); |
| 1692 } | 1606 } |
| 1693 | 1607 |
| 1694 void SkFontMgr_DirectWrite::onGetFamilyName(int index, SkString* familyName) con
st { | 1608 void SkFontMgr_DirectWrite::onGetFamilyName(int index, SkString* familyName) con
st { |
| 1695 SkTScopedComPtr<IDWriteFontFamily> fontFamily; | 1609 SkTScopedComPtr<IDWriteFontFamily> fontFamily; |
| 1696 HRVM(fFontCollection->GetFontFamily(index, &fontFamily), "Could not get requ
ested family."); | 1610 HRVM(fFontCollection->GetFontFamily(index, &fontFamily), "Could not get requ
ested family."); |
| 1697 | 1611 |
| 1698 SkTScopedComPtr<IDWriteLocalizedStrings> familyNames; | 1612 SkTScopedComPtr<IDWriteLocalizedStrings> familyNames; |
| 1699 HRVM(fontFamily->GetFamilyNames(&familyNames), "Could not get family names."
); | 1613 HRVM(fontFamily->GetFamilyNames(&familyNames), "Could not get family names."
); |
| 1700 | 1614 |
| 1701 get_locale_string(familyNames.get(), fLocaleName.get(), familyName); | 1615 sk_get_locale_string(familyNames.get(), fLocaleName.get(), familyName); |
| 1702 } | 1616 } |
| 1703 | 1617 |
| 1704 SkFontStyleSet* SkFontMgr_DirectWrite::onCreateStyleSet(int index) const { | 1618 SkFontStyleSet* SkFontMgr_DirectWrite::onCreateStyleSet(int index) const { |
| 1705 SkTScopedComPtr<IDWriteFontFamily> fontFamily; | 1619 SkTScopedComPtr<IDWriteFontFamily> fontFamily; |
| 1706 HRNM(fFontCollection->GetFontFamily(index, &fontFamily), "Could not get requ
ested family."); | 1620 HRNM(fFontCollection->GetFontFamily(index, &fontFamily), "Could not get requ
ested family."); |
| 1707 | 1621 |
| 1708 return SkNEW_ARGS(SkFontStyleSet_DirectWrite, (this, fontFamily.get())); | 1622 return SkNEW_ARGS(SkFontStyleSet_DirectWrite, (this, fontFamily.get())); |
| 1709 } | 1623 } |
| 1710 | 1624 |
| 1711 SkFontStyleSet* SkFontMgr_DirectWrite::onMatchFamily(const char familyName[]) co
nst { | 1625 SkFontStyleSet* SkFontMgr_DirectWrite::onMatchFamily(const char familyName[]) co
nst { |
| 1712 SkSMallocWCHAR dwFamilyName; | 1626 SkSMallocWCHAR dwFamilyName; |
| 1713 HRN(cstring_to_wchar(familyName, &dwFamilyName)); | 1627 HRN(sk_cstring_to_wchar(familyName, &dwFamilyName)); |
| 1714 | 1628 |
| 1715 UINT32 index; | 1629 UINT32 index; |
| 1716 BOOL exists; | 1630 BOOL exists; |
| 1717 HRNM(fFontCollection->FindFamilyName(dwFamilyName.get(), &index, &exists), | 1631 HRNM(fFontCollection->FindFamilyName(dwFamilyName.get(), &index, &exists), |
| 1718 "Failed while finding family by name."); | 1632 "Failed while finding family by name."); |
| 1719 if (!exists) { | 1633 if (!exists) { |
| 1720 return NULL; | 1634 return NULL; |
| 1721 } | 1635 } |
| 1722 | 1636 |
| 1723 return this->onCreateStyleSet(index); | 1637 return this->onCreateStyleSet(index); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1778 "Could not create DWrite font family from LOGFONT."); | 1692 "Could not create DWrite font family from LOGFONT."); |
| 1779 | 1693 |
| 1780 return S_OK; | 1694 return S_OK; |
| 1781 } | 1695 } |
| 1782 | 1696 |
| 1783 SkTypeface* SkFontMgr_DirectWrite::onLegacyCreateTypeface(const char familyName[
], | 1697 SkTypeface* SkFontMgr_DirectWrite::onLegacyCreateTypeface(const char familyName[
], |
| 1784 unsigned styleBits) co
nst { | 1698 unsigned styleBits) co
nst { |
| 1785 SkTScopedComPtr<IDWriteFontFamily> fontFamily; | 1699 SkTScopedComPtr<IDWriteFontFamily> fontFamily; |
| 1786 if (familyName) { | 1700 if (familyName) { |
| 1787 SkSMallocWCHAR wideFamilyName; | 1701 SkSMallocWCHAR wideFamilyName; |
| 1788 if (SUCCEEDED(cstring_to_wchar(familyName, &wideFamilyName))) { | 1702 if (SUCCEEDED(sk_cstring_to_wchar(familyName, &wideFamilyName))) { |
| 1789 this->getByFamilyName(wideFamilyName, &fontFamily); | 1703 this->getByFamilyName(wideFamilyName, &fontFamily); |
| 1790 } | 1704 } |
| 1791 } | 1705 } |
| 1792 | 1706 |
| 1793 if (NULL == fontFamily.get()) { | 1707 if (NULL == fontFamily.get()) { |
| 1794 // No family with given name, try default. | 1708 // No family with given name, try default. |
| 1795 HRNM(this->getDefaultFontFamily(&fontFamily), "Could not get default fon
t family."); | 1709 HRNM(this->getDefaultFontFamily(&fontFamily), "Could not get default fon
t family."); |
| 1796 } | 1710 } |
| 1797 | 1711 |
| 1798 SkTScopedComPtr<IDWriteFont> font; | 1712 SkTScopedComPtr<IDWriteFont> font; |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1848 | 1762 |
| 1849 int weight = font->GetWeight(); | 1763 int weight = font->GetWeight(); |
| 1850 int width = font->GetStretch(); | 1764 int width = font->GetStretch(); |
| 1851 | 1765 |
| 1852 *fs = SkFontStyle(weight, width, slant); | 1766 *fs = SkFontStyle(weight, width, slant); |
| 1853 } | 1767 } |
| 1854 | 1768 |
| 1855 if (styleName) { | 1769 if (styleName) { |
| 1856 SkTScopedComPtr<IDWriteLocalizedStrings> faceNames; | 1770 SkTScopedComPtr<IDWriteLocalizedStrings> faceNames; |
| 1857 if (SUCCEEDED(font->GetFaceNames(&faceNames))) { | 1771 if (SUCCEEDED(font->GetFaceNames(&faceNames))) { |
| 1858 get_locale_string(faceNames.get(), fFontMgr->fLocaleName.get(), styl
eName); | 1772 sk_get_locale_string(faceNames.get(), fFontMgr->fLocaleName.get(), s
tyleName); |
| 1859 } | 1773 } |
| 1860 } | 1774 } |
| 1861 } | 1775 } |
| 1862 | 1776 |
| 1863 SkTypeface* SkFontStyleSet_DirectWrite::matchStyle(const SkFontStyle& pattern) { | 1777 SkTypeface* SkFontStyleSet_DirectWrite::matchStyle(const SkFontStyle& pattern) { |
| 1864 DWRITE_FONT_STYLE slant; | 1778 DWRITE_FONT_STYLE slant; |
| 1865 switch (pattern.slant()) { | 1779 switch (pattern.slant()) { |
| 1866 case SkFontStyle::kUpright_Slant: | 1780 case SkFontStyle::kUpright_Slant: |
| 1867 slant = DWRITE_FONT_STYLE_NORMAL; | 1781 slant = DWRITE_FONT_STYLE_NORMAL; |
| 1868 break; | 1782 break; |
| 1869 case SkFontStyle::kItalic_Slant: | 1783 case SkFontStyle::kItalic_Slant: |
| 1870 slant = DWRITE_FONT_STYLE_ITALIC; | 1784 slant = DWRITE_FONT_STYLE_ITALIC; |
| 1871 break; | 1785 break; |
| 1872 default: | 1786 default: |
| 1873 SkASSERT(false); | 1787 SkASSERT(false); |
| 1874 } | 1788 } |
| 1875 | 1789 |
| 1876 DWRITE_FONT_WEIGHT weight = (DWRITE_FONT_WEIGHT)pattern.weight(); | 1790 DWRITE_FONT_WEIGHT weight = (DWRITE_FONT_WEIGHT)pattern.weight(); |
| 1877 DWRITE_FONT_STRETCH width = (DWRITE_FONT_STRETCH)pattern.width(); | 1791 DWRITE_FONT_STRETCH width = (DWRITE_FONT_STRETCH)pattern.width(); |
| 1878 | 1792 |
| 1879 SkTScopedComPtr<IDWriteFont> font; | 1793 SkTScopedComPtr<IDWriteFont> font; |
| 1880 // TODO: perhaps use GetMatchingFonts and get the least simulated? | 1794 // TODO: perhaps use GetMatchingFonts and get the least simulated? |
| 1881 HRNM(fFontFamily->GetFirstMatchingFont(weight, width, slant, &font), | 1795 HRNM(fFontFamily->GetFirstMatchingFont(weight, width, slant, &font), |
| 1882 "Could not match font in family."); | 1796 "Could not match font in family."); |
| 1883 | 1797 |
| 1884 SkTScopedComPtr<IDWriteFontFace> fontFace; | 1798 SkTScopedComPtr<IDWriteFontFace> fontFace; |
| 1885 HRNM(font->CreateFontFace(&fontFace), "Could not create font face."); | 1799 HRNM(font->CreateFontFace(&fontFace), "Could not create font face."); |
| 1886 | 1800 |
| 1887 return fFontMgr->createTypefaceFromDWriteFont(fontFace.get(), font.get(), | 1801 return fFontMgr->createTypefaceFromDWriteFont(fontFace.get(), font.get(), |
| 1888 fFontFamily.get()); | 1802 fFontFamily.get()); |
| 1889 } | 1803 } |
| 1890 | 1804 |
| 1891 /////////////////////////////////////////////////////////////////////////////// | 1805 /////////////////////////////////////////////////////////////////////////////// |
| 1892 | 1806 |
| 1893 typedef decltype(GetUserDefaultLocaleName)* GetUserDefaultLocaleNameProc; | |
| 1894 static HRESULT GetGetUserDefaultLocaleNameProc(GetUserDefaultLocaleNameProc* pro
c) { | |
| 1895 *proc = reinterpret_cast<GetUserDefaultLocaleNameProc>( | |
| 1896 GetProcAddress(LoadLibraryW(L"Kernel32.dll"), "GetUserDefaultLocaleName"
) | |
| 1897 ); | |
| 1898 if (!*proc) { | |
| 1899 HRESULT hr = HRESULT_FROM_WIN32(GetLastError()); | |
| 1900 if (!IS_ERROR(hr)) { | |
| 1901 hr = ERROR_PROC_NOT_FOUND; | |
| 1902 } | |
| 1903 return hr; | |
| 1904 } | |
| 1905 return S_OK; | |
| 1906 } | |
| 1907 | |
| 1908 SkFontMgr* SkFontMgr_New_DirectWrite() { | 1807 SkFontMgr* SkFontMgr_New_DirectWrite() { |
| 1909 IDWriteFactory* factory = get_dwrite_factory(); | 1808 IDWriteFactory* factory = sk_get_dwrite_factory(); |
| 1910 if (NULL == factory) { | 1809 if (NULL == factory) { |
| 1911 return NULL; | 1810 return NULL; |
| 1912 } | 1811 } |
| 1913 | 1812 |
| 1914 SkTScopedComPtr<IDWriteFontCollection> sysFontCollection; | 1813 SkTScopedComPtr<IDWriteFontCollection> sysFontCollection; |
| 1915 HRNM(factory->GetSystemFontCollection(&sysFontCollection, FALSE), | 1814 HRNM(factory->GetSystemFontCollection(&sysFontCollection, FALSE), |
| 1916 "Could not get system font collection."); | 1815 "Could not get system font collection."); |
| 1917 | 1816 |
| 1918 WCHAR localeNameStorage[LOCALE_NAME_MAX_LENGTH]; | 1817 WCHAR localeNameStorage[LOCALE_NAME_MAX_LENGTH]; |
| 1919 WCHAR* localeName = NULL; | 1818 WCHAR* localeName = NULL; |
| 1920 int localeNameLen = 0; | 1819 int localeNameLen = 0; |
| 1921 | 1820 |
| 1922 // Dynamically load GetUserDefaultLocaleName function, as it is not availabl
e on XP. | 1821 // Dynamically load GetUserDefaultLocaleName function, as it is not availabl
e on XP. |
| 1923 GetUserDefaultLocaleNameProc getUserDefaultLocaleNameProc = NULL; | 1822 SkGetUserDefaultLocaleNameProc getUserDefaultLocaleNameProc = NULL; |
| 1924 HRESULT hr = GetGetUserDefaultLocaleNameProc(&getUserDefaultLocaleNameProc); | 1823 HRESULT hr = SkGetGetUserDefaultLocaleNameProc(&getUserDefaultLocaleNameProc
); |
| 1925 if (NULL == getUserDefaultLocaleNameProc) { | 1824 if (NULL == getUserDefaultLocaleNameProc) { |
| 1926 SK_TRACEHR(hr, "Could not get GetUserDefaultLocaleName."); | 1825 SK_TRACEHR(hr, "Could not get GetUserDefaultLocaleName."); |
| 1927 } else { | 1826 } else { |
| 1928 localeNameLen = getUserDefaultLocaleNameProc(localeNameStorage, LOCALE_N
AME_MAX_LENGTH); | 1827 localeNameLen = getUserDefaultLocaleNameProc(localeNameStorage, LOCALE_N
AME_MAX_LENGTH); |
| 1929 if (localeNameLen) { | 1828 if (localeNameLen) { |
| 1930 localeName = localeNameStorage; | 1829 localeName = localeNameStorage; |
| 1931 }; | 1830 }; |
| 1932 } | 1831 } |
| 1933 | 1832 |
| 1934 return SkNEW_ARGS(SkFontMgr_DirectWrite, (sysFontCollection.get(), localeNam
e, localeNameLen)); | 1833 return SkNEW_ARGS(SkFontMgr_DirectWrite, (sysFontCollection.get(), localeNam
e, localeNameLen)); |
| 1935 } | 1834 } |
| 1835 |
| 1836 #include "SkFontMgr_indirect.h" |
| 1837 SkFontMgr* SkFontMgr_New_DirectWriteRenderer(SkRemotableFontMgr* proxy) { |
| 1838 SkAutoTUnref<SkFontMgr> impl(SkFontMgr_New_DirectWrite()); |
| 1839 if (impl.get() == NULL) { |
| 1840 return NULL; |
| 1841 } |
| 1842 return SkNEW_ARGS(SkFontMgr_Indirect, (impl.get(), proxy)); |
| 1843 } |
| OLD | NEW |