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 |
(...skipping 23 matching lines...) Expand all Loading... |
34 | 34 |
35 #include <dwrite.h> | 35 #include <dwrite.h> |
36 | 36 |
37 SK_DECLARE_STATIC_MUTEX(gFTMutex); | 37 SK_DECLARE_STATIC_MUTEX(gFTMutex); |
38 | 38 |
39 static bool isLCD(const SkScalerContext::Rec& rec) { | 39 static bool isLCD(const SkScalerContext::Rec& rec) { |
40 return SkMask::kLCD16_Format == rec.fMaskFormat || | 40 return SkMask::kLCD16_Format == rec.fMaskFormat || |
41 SkMask::kLCD32_Format == rec.fMaskFormat; | 41 SkMask::kLCD32_Format == rec.fMaskFormat; |
42 } | 42 } |
43 | 43 |
| 44 /** Prefer to use this type to prevent template proliferation. */ |
| 45 typedef SkAutoSTMalloc<16, WCHAR> SkSMallocWCHAR; |
| 46 |
| 47 static HRESULT cstring_to_wchar(const char* skname, SkSMallocWCHAR* name) { |
| 48 int wlen = MultiByteToWideChar(CP_UTF8, 0, skname, -1, NULL, 0); |
| 49 if (0 == wlen) { |
| 50 HRM(HRESULT_FROM_WIN32(GetLastError()), |
| 51 "Could not get length for wchar to utf-8 conversion."); |
| 52 } |
| 53 name->reset(wlen); |
| 54 wlen = MultiByteToWideChar(CP_UTF8, 0, skname, -1, name->get(), wlen); |
| 55 if (0 == wlen) { |
| 56 HRM(HRESULT_FROM_WIN32(GetLastError()), "Could not convert wchar to utf-
8."); |
| 57 } |
| 58 return S_OK; |
| 59 } |
| 60 |
| 61 static HRESULT wchar_to_skstring(WCHAR* name, SkString* skname) { |
| 62 int len = WideCharToMultiByte(CP_UTF8, 0, name, -1, NULL, 0, NULL, NULL); |
| 63 if (0 == len) { |
| 64 HRM(HRESULT_FROM_WIN32(GetLastError()), |
| 65 "Could not get length for utf-8 to wchar conversion."); |
| 66 } |
| 67 skname->resize(len - 1); |
| 68 len = WideCharToMultiByte(CP_UTF8, 0, name, -1, skname->writable_str(), len,
NULL, NULL); |
| 69 if (0 == len) { |
| 70 HRM(HRESULT_FROM_WIN32(GetLastError()), "Could not convert utf-8 to wcha
r."); |
| 71 } |
| 72 return S_OK; |
| 73 } |
| 74 |
44 /////////////////////////////////////////////////////////////////////////////// | 75 /////////////////////////////////////////////////////////////////////////////// |
45 | 76 |
46 class DWriteOffscreen { | 77 class DWriteOffscreen { |
47 public: | 78 public: |
48 DWriteOffscreen() : fWidth(0), fHeight(0) { | 79 DWriteOffscreen() : fWidth(0), fHeight(0) { |
49 } | 80 } |
50 | 81 |
51 void init(IDWriteFontFace* fontFace, const DWRITE_MATRIX& xform, FLOAT fontS
ize) { | 82 void init(IDWriteFontFace* fontFace, const DWRITE_MATRIX& xform, FLOAT fontS
ize) { |
52 fFontFace = fontFace; | 83 fFontFace = fontFace; |
53 fFontSize = fontSize; | 84 fFontSize = fontSize; |
(...skipping 608 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
662 UINT32 dwFontNameLength; | 693 UINT32 dwFontNameLength; |
663 HRB(dwFontFamilyNames->GetStringLength(0, &dwFontFamilyNameLength)); | 694 HRB(dwFontFamilyNames->GetStringLength(0, &dwFontFamilyNameLength)); |
664 HRB(dwFontNames->GetStringLength(0, &dwFontNameLength)); | 695 HRB(dwFontNames->GetStringLength(0, &dwFontNameLength)); |
665 | 696 |
666 if (dwFaceFontFamilyNameLength != dwFontFamilyNameLength || | 697 if (dwFaceFontFamilyNameLength != dwFontFamilyNameLength || |
667 dwFaceFontNameLength != dwFontNameLength) | 698 dwFaceFontNameLength != dwFontNameLength) |
668 { | 699 { |
669 return false; | 700 return false; |
670 } | 701 } |
671 | 702 |
672 SkTDArray<wchar_t> dwFaceFontFamilyNameChar(new wchar_t[dwFaceFontFamilyName
Length+1], dwFaceFontFamilyNameLength+1); | 703 SkSMallocWCHAR dwFaceFontFamilyNameChar(dwFaceFontFamilyNameLength+1); |
673 SkTDArray<wchar_t> dwFaceFontNameChar(new wchar_t[dwFaceFontNameLength+1], d
wFaceFontNameLength+1); | 704 SkSMallocWCHAR dwFaceFontNameChar(dwFaceFontNameLength+1); |
674 HRB(dwFaceFontFamilyNames->GetString(0, dwFaceFontFamilyNameChar.begin(), dw
FaceFontFamilyNameChar.count())); | 705 HRB(dwFaceFontFamilyNames->GetString(0, dwFaceFontFamilyNameChar.get(), dwFa
ceFontFamilyNameLength+1)); |
675 HRB(dwFaceFontNames->GetString(0, dwFaceFontNameChar.begin(), dwFaceFontName
Char.count())); | 706 HRB(dwFaceFontNames->GetString(0, dwFaceFontNameChar.get(), dwFaceFontNameLe
ngth+1)); |
676 | 707 |
677 SkTDArray<wchar_t> dwFontFamilyNameChar(new wchar_t[dwFontFamilyNameLength+1
], dwFontFamilyNameLength+1); | 708 SkSMallocWCHAR dwFontFamilyNameChar(dwFontFamilyNameLength+1); |
678 SkTDArray<wchar_t> dwFontNameChar(new wchar_t[dwFontNameLength+1], dwFontNam
eLength+1); | 709 SkSMallocWCHAR dwFontNameChar(dwFontNameLength+1); |
679 HRB(dwFontFamilyNames->GetString(0, dwFontFamilyNameChar.begin(), dwFontFami
lyNameChar.count())); | 710 HRB(dwFontFamilyNames->GetString(0, dwFontFamilyNameChar.get(), dwFontFamily
NameLength+1)); |
680 HRB(dwFontNames->GetString(0, dwFontNameChar.begin(), dwFontNameChar.count()
)); | 711 HRB(dwFontNames->GetString(0, dwFontNameChar.get(), dwFontNameLength+1)); |
681 | 712 |
682 return wcscmp(dwFaceFontFamilyNameChar.begin(), dwFontFamilyNameChar.begin()
) == 0 && | 713 return wcscmp(dwFaceFontFamilyNameChar.get(), dwFontFamilyNameChar.get()) ==
0 && |
683 wcscmp(dwFaceFontNameChar.begin(), dwFontNameChar.begin()) == 0; | 714 wcscmp(dwFaceFontNameChar.get(), dwFontNameChar.get()) == 0; |
684 } | 715 } |
685 | 716 |
686 SkTypeface* SkCreateTypefaceFromDWriteFont(IDWriteFontFace* fontFace, | 717 SkTypeface* SkCreateTypefaceFromDWriteFont(IDWriteFontFace* fontFace, |
687 IDWriteFont* font, | 718 IDWriteFont* font, |
688 IDWriteFontFamily* fontFamily, | 719 IDWriteFontFamily* fontFamily, |
689 StreamFontFileLoader* fontFileLoader
= NULL, | 720 StreamFontFileLoader* fontFileLoader
= NULL, |
690 IDWriteFontCollectionLoader* fontColl
ectionLoader = NULL) { | 721 IDWriteFontCollectionLoader* fontColl
ectionLoader = NULL) { |
691 SkTypeface* face = SkTypefaceCache::FindByProcAndRef(FindByDWriteFont, font)
; | 722 SkTypeface* face = SkTypefaceCache::FindByProcAndRef(FindByDWriteFont, font)
; |
692 if (NULL == face) { | 723 if (NULL == face) { |
693 face = DWriteFontTypeface::Create(fontFace, font, fontFamily, | 724 face = DWriteFontTypeface::Create(fontFace, font, fontFamily, |
(...skipping 348 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1042 | 1073 |
1043 void DWriteFontTypeface::onGetFontDescriptor(SkFontDescriptor* desc, | 1074 void DWriteFontTypeface::onGetFontDescriptor(SkFontDescriptor* desc, |
1044 bool* isLocalStream) const { | 1075 bool* isLocalStream) const { |
1045 // Get the family name. | 1076 // Get the family name. |
1046 SkTScopedComPtr<IDWriteLocalizedStrings> dwFamilyNames; | 1077 SkTScopedComPtr<IDWriteLocalizedStrings> dwFamilyNames; |
1047 HRV(fDWriteFontFamily->GetFamilyNames(&dwFamilyNames)); | 1078 HRV(fDWriteFontFamily->GetFamilyNames(&dwFamilyNames)); |
1048 | 1079 |
1049 UINT32 dwFamilyNamesLength; | 1080 UINT32 dwFamilyNamesLength; |
1050 HRV(dwFamilyNames->GetStringLength(0, &dwFamilyNamesLength)); | 1081 HRV(dwFamilyNames->GetStringLength(0, &dwFamilyNamesLength)); |
1051 | 1082 |
1052 SkTDArray<wchar_t> dwFamilyNameChar(new wchar_t[dwFamilyNamesLength+1], dwFa
milyNamesLength+1); | 1083 SkSMallocWCHAR dwFamilyNameChar(dwFamilyNamesLength+1); |
1053 HRV(dwFamilyNames->GetString(0, dwFamilyNameChar.begin(), dwFamilyNameChar.c
ount())); | 1084 HRV(dwFamilyNames->GetString(0, dwFamilyNameChar.get(), dwFamilyNamesLength+
1)); |
1054 | 1085 |
1055 // Convert the family name to utf8. | 1086 SkString utf8FamilyName; |
1056 // Get the buffer size needed first. | 1087 HRV(wchar_to_skstring(dwFamilyNameChar.get(), &utf8FamilyName)); |
1057 int str_len = WideCharToMultiByte(CP_UTF8, 0, dwFamilyNameChar.begin(), -1, | |
1058 NULL, 0, NULL, NULL); | |
1059 // Allocate a buffer (str_len already has terminating null accounted for). | |
1060 SkTDArray<char> utf8FamilyName(new char[str_len], str_len); | |
1061 // Now actually convert the string. | |
1062 str_len = WideCharToMultiByte(CP_UTF8, 0, dwFamilyNameChar.begin(), -1, | |
1063 utf8FamilyName.begin(), str_len, NULL, NULL); | |
1064 | 1088 |
1065 desc->setFamilyName(utf8FamilyName.begin()); | 1089 desc->setFamilyName(utf8FamilyName.c_str()); |
1066 *isLocalStream = SkToBool(fDWriteFontFileLoader.get()); | 1090 *isLocalStream = SkToBool(fDWriteFontFileLoader.get()); |
1067 } | 1091 } |
1068 | 1092 |
1069 SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) { | 1093 static SkTypeface* create_from_stream(SkStream* stream) { |
1070 IDWriteFactory* factory; | 1094 IDWriteFactory* factory; |
1071 HRN(get_dwrite_factory(&factory)); | 1095 HRN(get_dwrite_factory(&factory)); |
1072 | 1096 |
1073 SkTScopedComPtr<StreamFontFileLoader> fontFileLoader; | 1097 SkTScopedComPtr<StreamFontFileLoader> fontFileLoader; |
1074 HRN(StreamFontFileLoader::Create(stream, &fontFileLoader)); | 1098 HRN(StreamFontFileLoader::Create(stream, &fontFileLoader)); |
1075 HRN(factory->RegisterFontFileLoader(fontFileLoader.get())); | 1099 HRN(factory->RegisterFontFileLoader(fontFileLoader.get())); |
1076 | 1100 |
1077 SkTScopedComPtr<StreamFontCollectionLoader> streamFontCollectionLoader; | 1101 SkTScopedComPtr<StreamFontCollectionLoader> streamFontCollectionLoader; |
1078 HRN(StreamFontCollectionLoader::Create(fontFileLoader.get(), &streamFontColl
ectionLoader)); | 1102 HRN(StreamFontCollectionLoader::Create(fontFileLoader.get(), &streamFontColl
ectionLoader)); |
1079 HRN(factory->RegisterFontCollectionLoader(streamFontCollectionLoader.get()))
; | 1103 HRN(factory->RegisterFontCollectionLoader(streamFontCollectionLoader.get()))
; |
1080 | 1104 |
1081 SkTScopedComPtr<IDWriteFontCollection> streamFontCollection; | 1105 SkTScopedComPtr<IDWriteFontCollection> streamFontCollection; |
1082 HRN(factory->CreateCustomFontCollection(streamFontCollectionLoader.get(), NU
LL, 0, | 1106 HRN(factory->CreateCustomFontCollection(streamFontCollectionLoader.get(), NU
LL, 0, |
1083 &streamFontCollection)); | 1107 &streamFontCollection)); |
1084 | 1108 |
1085 SkTScopedComPtr<IDWriteFontFamily> fontFamily; | 1109 SkTScopedComPtr<IDWriteFontFamily> fontFamily; |
1086 HRN(streamFontCollection->GetFontFamily(0, &fontFamily)); | 1110 HRN(streamFontCollection->GetFontFamily(0, &fontFamily)); |
1087 | 1111 |
1088 SkTScopedComPtr<IDWriteFont> font; | 1112 SkTScopedComPtr<IDWriteFont> font; |
1089 HRN(fontFamily->GetFont(0, &font)); | 1113 HRN(fontFamily->GetFont(0, &font)); |
1090 | 1114 |
1091 SkTScopedComPtr<IDWriteFontFace> fontFace; | 1115 SkTScopedComPtr<IDWriteFontFace> fontFace; |
1092 HRN(font->CreateFontFace(&fontFace)); | 1116 HRN(font->CreateFontFace(&fontFace)); |
1093 | 1117 |
1094 return SkCreateTypefaceFromDWriteFont(fontFace.get(), font.get(), fontFamily
.get(), | 1118 return SkCreateTypefaceFromDWriteFont(fontFace.get(), font.get(), fontFamily
.get(), |
1095 fontFileLoader.get(), streamFontCollec
tionLoader.get()); | 1119 fontFileLoader.get(), streamFontCollec
tionLoader.get()); |
1096 } | 1120 } |
1097 | 1121 |
| 1122 SkTypeface* SkFontHost::CreateTypefaceFromStream(SkStream* stream) { |
| 1123 return create_from_stream(stream); |
| 1124 } |
| 1125 |
1098 SkStream* DWriteFontTypeface::onOpenStream(int* ttcIndex) const { | 1126 SkStream* DWriteFontTypeface::onOpenStream(int* ttcIndex) const { |
1099 *ttcIndex = 0; | 1127 *ttcIndex = 0; |
1100 | 1128 |
1101 UINT32 numFiles; | 1129 UINT32 numFiles; |
1102 HRNM(fDWriteFontFace->GetFiles(&numFiles, NULL), | 1130 HRNM(fDWriteFontFace->GetFiles(&numFiles, NULL), |
1103 "Could not get number of font files."); | 1131 "Could not get number of font files."); |
1104 if (numFiles != 1) { | 1132 if (numFiles != 1) { |
1105 return NULL; | 1133 return NULL; |
1106 } | 1134 } |
1107 | 1135 |
(...skipping 20 matching lines...) Expand all Loading... |
1128 return SkNEW_ARGS(SkScalerContext_Windows, (const_cast<DWriteFontTypeface*>(
this), desc)); | 1156 return SkNEW_ARGS(SkScalerContext_Windows, (const_cast<DWriteFontTypeface*>(
this), desc)); |
1129 } | 1157 } |
1130 | 1158 |
1131 static HRESULT get_by_family_name(const char familyName[], IDWriteFontFamily** f
ontFamily) { | 1159 static HRESULT get_by_family_name(const char familyName[], IDWriteFontFamily** f
ontFamily) { |
1132 IDWriteFactory* factory; | 1160 IDWriteFactory* factory; |
1133 HR(get_dwrite_factory(&factory)); | 1161 HR(get_dwrite_factory(&factory)); |
1134 | 1162 |
1135 SkTScopedComPtr<IDWriteFontCollection> sysFontCollection; | 1163 SkTScopedComPtr<IDWriteFontCollection> sysFontCollection; |
1136 HR(factory->GetSystemFontCollection(&sysFontCollection, FALSE)); | 1164 HR(factory->GetSystemFontCollection(&sysFontCollection, FALSE)); |
1137 | 1165 |
1138 // Get the buffer size needed first. | 1166 SkSMallocWCHAR wideFamilyName; |
1139 int wlen = ::MultiByteToWideChar(CP_UTF8, 0, familyName,-1, NULL, 0); | 1167 HR(cstring_to_wchar(familyName, &wideFamilyName)); |
1140 if (0 == wlen) { | |
1141 return HRESULT_FROM_WIN32(GetLastError()); | |
1142 } | |
1143 // Allocate a buffer | |
1144 SkTDArray<wchar_t> wideFamilyName(new wchar_t[wlen], wlen); | |
1145 // Now actually convert the string. | |
1146 wlen = ::MultiByteToWideChar(CP_UTF8, 0, familyName, -1, | |
1147 wideFamilyName.begin(), wlen); | |
1148 if (0 == wlen) { | |
1149 return HRESULT_FROM_WIN32(GetLastError()); | |
1150 } | |
1151 | 1168 |
1152 UINT32 index; | 1169 UINT32 index; |
1153 BOOL exists; | 1170 BOOL exists; |
1154 HR(sysFontCollection->FindFamilyName(wideFamilyName.begin(), &index, &exists
)); | 1171 HR(sysFontCollection->FindFamilyName(wideFamilyName.get(), &index, &exists))
; |
1155 | 1172 |
1156 if (exists) { | 1173 if (exists) { |
1157 HR(sysFontCollection->GetFontFamily(index, fontFamily)); | 1174 HR(sysFontCollection->GetFontFamily(index, fontFamily)); |
1158 return S_OK; | 1175 return S_OK; |
1159 } | 1176 } |
1160 return S_FALSE; | 1177 return S_FALSE; |
1161 } | 1178 } |
1162 | 1179 |
1163 /** Return the closest matching typeface given either an existing family | 1180 /** Return the closest matching typeface given either an existing family |
1164 (specified by a typeface in that family) or by a familyName, and a | 1181 (specified by a typeface in that family) or by a familyName, and a |
(...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1382 SkTScopedComPtr<IDWriteLocalizedStrings> faceNames; | 1399 SkTScopedComPtr<IDWriteLocalizedStrings> faceNames; |
1383 hr = fDWriteFontFamily->GetFamilyNames(&familyNames); | 1400 hr = fDWriteFontFamily->GetFamilyNames(&familyNames); |
1384 hr = fDWriteFont->GetFaceNames(&faceNames); | 1401 hr = fDWriteFont->GetFaceNames(&faceNames); |
1385 | 1402 |
1386 UINT32 familyNameLength; | 1403 UINT32 familyNameLength; |
1387 hr = familyNames->GetStringLength(0, &familyNameLength); | 1404 hr = familyNames->GetStringLength(0, &familyNameLength); |
1388 | 1405 |
1389 UINT32 faceNameLength; | 1406 UINT32 faceNameLength; |
1390 hr = faceNames->GetStringLength(0, &faceNameLength); | 1407 hr = faceNames->GetStringLength(0, &faceNameLength); |
1391 | 1408 |
1392 size_t size = familyNameLength+1+faceNameLength+1; | 1409 UINT32 size = familyNameLength+1+faceNameLength+1; |
1393 SkTDArray<wchar_t> wFamilyName(new wchar_t[size], size); | 1410 SkSMallocWCHAR wFamilyName(size); |
1394 hr = familyNames->GetString(0, wFamilyName.begin(), size); | 1411 hr = familyNames->GetString(0, wFamilyName.get(), size); |
1395 wFamilyName[familyNameLength] = L' '; | 1412 wFamilyName[familyNameLength] = L' '; |
1396 hr = faceNames->GetString(0, &wFamilyName[familyNameLength+1], size - faceNa
meLength + 1); | 1413 hr = faceNames->GetString(0, &wFamilyName[familyNameLength+1], size - faceNa
meLength + 1); |
1397 | 1414 |
1398 size_t str_len = WideCharToMultiByte(CP_UTF8, 0, wFamilyName.begin(), -1, NU
LL, 0, NULL, NULL); | 1415 hr = wchar_to_skstring(wFamilyName.get(), &info->fFontName); |
1399 if (0 == str_len) { | |
1400 //TODO: error | |
1401 } | |
1402 SkTDArray<char> familyName(new char[str_len], str_len); | |
1403 str_len = WideCharToMultiByte(CP_UTF8, 0, wFamilyName.begin(), -1, familyNam
e.begin(), str_len, NULL, NULL); | |
1404 if (0 == str_len) { | |
1405 //TODO: error | |
1406 } | |
1407 info->fFontName.set(familyName.begin(), str_len); | |
1408 | 1416 |
1409 if (perGlyphInfo & SkAdvancedTypefaceMetrics::kToUnicode_PerGlyphInfo) { | 1417 if (perGlyphInfo & SkAdvancedTypefaceMetrics::kToUnicode_PerGlyphInfo) { |
1410 populate_glyph_to_unicode(fDWriteFontFace.get(), glyphCount, &(info->fGl
yphToUnicode)); | 1418 populate_glyph_to_unicode(fDWriteFontFace.get(), glyphCount, &(info->fGl
yphToUnicode)); |
1411 } | 1419 } |
1412 | 1420 |
1413 DWRITE_FONT_FACE_TYPE fontType = fDWriteFontFace->GetType(); | 1421 DWRITE_FONT_FACE_TYPE fontType = fDWriteFontFace->GetType(); |
1414 if (fontType == DWRITE_FONT_FACE_TYPE_TRUETYPE || | 1422 if (fontType == DWRITE_FONT_FACE_TYPE_TRUETYPE || |
1415 fontType == DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION) { | 1423 fontType == DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION) { |
1416 info->fType = SkAdvancedTypefaceMetrics::kTrueType_Font; | 1424 info->fType = SkAdvancedTypefaceMetrics::kTrueType_Font; |
1417 } else { | 1425 } else { |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1516 } | 1524 } |
1517 } | 1525 } |
1518 | 1526 |
1519 return info; | 1527 return info; |
1520 } | 1528 } |
1521 | 1529 |
1522 /////////////////////////////////////////////////////////////////////////////// | 1530 /////////////////////////////////////////////////////////////////////////////// |
1523 | 1531 |
1524 #include "SkFontMgr.h" | 1532 #include "SkFontMgr.h" |
1525 | 1533 |
| 1534 static void get_locale_string(IDWriteLocalizedStrings* names, const WCHAR* prefe
redLocale, |
| 1535 SkString* skname) { |
| 1536 UINT32 nameIndex = 0; |
| 1537 if (preferedLocale) { |
| 1538 // Ignore any errors and continue with index 0 if there is a problem. |
| 1539 BOOL nameExists; |
| 1540 names->FindLocaleName(preferedLocale, &nameIndex, &nameExists); |
| 1541 if (!nameExists) { |
| 1542 nameIndex = 0; |
| 1543 } |
| 1544 } |
| 1545 |
| 1546 UINT32 nameLength; |
| 1547 HRVM(names->GetStringLength(nameIndex, &nameLength), "Could not get name len
gth."); |
| 1548 nameLength += 1; |
| 1549 |
| 1550 SkSMallocWCHAR name(nameLength); |
| 1551 HRVM(names->GetString(nameIndex, name.get(), nameLength), "Could not get str
ing."); |
| 1552 |
| 1553 HRV(wchar_to_skstring(name.get(), skname)); |
| 1554 } |
| 1555 |
| 1556 class SkFontMgr_DirectWrite; |
| 1557 |
| 1558 class SkFontStyleSet_DirectWrite : public SkFontStyleSet { |
| 1559 public: |
| 1560 SkFontStyleSet_DirectWrite(const SkFontMgr_DirectWrite* fontMgr, IDWriteFont
Family* fontFamily) |
| 1561 : fFontMgr(SkRef(fontMgr)) |
| 1562 , fFontFamily(SkRefComPtr(fontFamily)) |
| 1563 { } |
| 1564 |
| 1565 virtual int count() SK_OVERRIDE { |
| 1566 return fFontFamily->GetFontCount(); |
| 1567 } |
| 1568 |
| 1569 virtual void getStyle(int index, SkFontStyle* fs, SkString* styleName); |
| 1570 |
| 1571 virtual SkTypeface* createTypeface(int index) SK_OVERRIDE { |
| 1572 SkTScopedComPtr<IDWriteFont> font; |
| 1573 HRNM(fFontFamily->GetFont(index, &font), "Could not get font."); |
| 1574 |
| 1575 SkTScopedComPtr<IDWriteFontFace> fontFace; |
| 1576 HRNM(font->CreateFontFace(&fontFace), "Could not create font face."); |
| 1577 |
| 1578 return SkCreateTypefaceFromDWriteFont(fontFace.get(), font.get(), fFontF
amily.get()); |
| 1579 } |
| 1580 |
| 1581 virtual SkTypeface* matchStyle(const SkFontStyle& pattern) SK_OVERRIDE { |
| 1582 DWRITE_FONT_STYLE slant; |
| 1583 switch (pattern.slant()) { |
| 1584 case SkFontStyle::kUpright_Slant: |
| 1585 slant = DWRITE_FONT_STYLE_NORMAL; |
| 1586 break; |
| 1587 case SkFontStyle::kItalic_Slant: |
| 1588 slant = DWRITE_FONT_STYLE_ITALIC; |
| 1589 break; |
| 1590 default: |
| 1591 SkASSERT(false); |
| 1592 } |
| 1593 |
| 1594 DWRITE_FONT_WEIGHT weight = (DWRITE_FONT_WEIGHT)pattern.weight(); |
| 1595 DWRITE_FONT_STRETCH width = (DWRITE_FONT_STRETCH)pattern.width(); |
| 1596 |
| 1597 SkTScopedComPtr<IDWriteFont> font; |
| 1598 HRNM(fFontFamily->GetFirstMatchingFont(weight, width, slant, &font), |
| 1599 "Could not match font in family."); |
| 1600 |
| 1601 SkTScopedComPtr<IDWriteFontFace> fontFace; |
| 1602 HRNM(font->CreateFontFace(&fontFace), "Could not create font face."); |
| 1603 |
| 1604 return SkCreateTypefaceFromDWriteFont(fontFace.get(), font.get(), fFontF
amily.get()); |
| 1605 } |
| 1606 |
| 1607 private: |
| 1608 SkAutoTUnref<const SkFontMgr_DirectWrite> fFontMgr; |
| 1609 SkTScopedComPtr<IDWriteFontFamily> fFontFamily; |
| 1610 }; |
| 1611 |
| 1612 class SkFontMgr_DirectWrite : public SkFontMgr { |
| 1613 public: |
| 1614 /** localeNameLength must include the null terminator. */ |
| 1615 SkFontMgr_DirectWrite(IDWriteFontCollection* fontCollection, |
| 1616 WCHAR* localeName, int localeNameLength) |
| 1617 : fFontCollection(SkRefComPtr(fontCollection)) |
| 1618 , fLocaleName(localeNameLength) |
| 1619 { |
| 1620 memcpy(fLocaleName.get(), localeName, localeNameLength * sizeof(WCHAR)); |
| 1621 } |
| 1622 |
| 1623 private: |
| 1624 friend class SkFontStyleSet_DirectWrite; |
| 1625 SkTScopedComPtr<IDWriteFontCollection> fFontCollection; |
| 1626 SkSMallocWCHAR fLocaleName; |
| 1627 |
| 1628 protected: |
| 1629 virtual int onCountFamilies() SK_OVERRIDE { |
| 1630 return fFontCollection->GetFontFamilyCount(); |
| 1631 } |
| 1632 virtual void onGetFamilyName(int index, SkString* familyName) SK_OVERRIDE { |
| 1633 SkTScopedComPtr<IDWriteFontFamily> fontFamily; |
| 1634 HRVM(fFontCollection->GetFontFamily(index, &fontFamily), "Could not get
requested family."); |
| 1635 |
| 1636 SkTScopedComPtr<IDWriteLocalizedStrings> familyNames; |
| 1637 HRVM(fontFamily->GetFamilyNames(&familyNames), "Could not get family nam
es."); |
| 1638 |
| 1639 get_locale_string(familyNames.get(), fLocaleName.get(), familyName); |
| 1640 } |
| 1641 virtual SkFontStyleSet* onCreateStyleSet(int index) SK_OVERRIDE { |
| 1642 SkTScopedComPtr<IDWriteFontFamily> fontFamily; |
| 1643 HRNM(fFontCollection->GetFontFamily(index, &fontFamily), "Could not get
requested family."); |
| 1644 |
| 1645 return SkNEW_ARGS(SkFontStyleSet_DirectWrite, (this, fontFamily.get())); |
| 1646 } |
| 1647 virtual SkFontStyleSet* onMatchFamily(const char familyName[]) SK_OVERRIDE { |
| 1648 SkSMallocWCHAR dwFamilyName; |
| 1649 HRN(cstring_to_wchar(familyName, &dwFamilyName)); |
| 1650 |
| 1651 UINT32 index; |
| 1652 BOOL exists; |
| 1653 HRNM(fFontCollection->FindFamilyName(dwFamilyName.get(), &index, &exists
), |
| 1654 "Failed while finding family by name."); |
| 1655 if (!exists) { |
| 1656 return NULL; |
| 1657 } |
| 1658 |
| 1659 return this->onCreateStyleSet(index); |
| 1660 } |
| 1661 |
| 1662 virtual SkTypeface* onMatchFamilyStyle(const char familyName[], |
| 1663 const SkFontStyle& fontstyle) SK_OVER
RIDE { |
| 1664 SkAutoTUnref<SkFontStyleSet> sset(this->matchFamily(familyName)); |
| 1665 return sset->matchStyle(fontstyle); |
| 1666 } |
| 1667 virtual SkTypeface* onMatchFaceStyle(const SkTypeface* familyMember, |
| 1668 const SkFontStyle& fontstyle) SK_OVERRI
DE { |
| 1669 SkString familyName; |
| 1670 SkFontStyleSet_DirectWrite sset( |
| 1671 this, ((DWriteFontTypeface*)familyMember)->fDWriteFontFamily.get() |
| 1672 ); |
| 1673 return sset.matchStyle(fontstyle); |
| 1674 } |
| 1675 virtual SkTypeface* onCreateFromStream(SkStream* stream, int ttcIndex) SK_OV
ERRIDE { |
| 1676 return create_from_stream(stream); |
| 1677 } |
| 1678 virtual SkTypeface* onCreateFromData(SkData* data, int ttcIndex) SK_OVERRIDE
{ |
| 1679 SkAutoTUnref<SkStream> stream(SkNEW_ARGS(SkMemoryStream, (data))); |
| 1680 return this->createFromStream(stream, ttcIndex); |
| 1681 } |
| 1682 virtual SkTypeface* onCreateFromFile(const char path[], int ttcIndex) SK_OVE
RRIDE { |
| 1683 SkAutoTUnref<SkStream> stream(SkStream::NewFromFile(path)); |
| 1684 return this->createFromStream(stream, ttcIndex); |
| 1685 } |
| 1686 }; |
| 1687 |
| 1688 void SkFontStyleSet_DirectWrite::getStyle(int index, SkFontStyle* fs, SkString*
styleName) { |
| 1689 SkTScopedComPtr<IDWriteFont> font; |
| 1690 HRVM(fFontFamily->GetFont(index, &font), "Could not get font."); |
| 1691 |
| 1692 SkFontStyle::Slant slant; |
| 1693 switch (font->GetStyle()) { |
| 1694 case DWRITE_FONT_STYLE_NORMAL: |
| 1695 slant = SkFontStyle::kUpright_Slant; |
| 1696 break; |
| 1697 case DWRITE_FONT_STYLE_OBLIQUE: |
| 1698 case DWRITE_FONT_STYLE_ITALIC: |
| 1699 slant = SkFontStyle::kItalic_Slant; |
| 1700 break; |
| 1701 default: |
| 1702 SkASSERT(false); |
| 1703 } |
| 1704 |
| 1705 int weight = font->GetWeight(); |
| 1706 int width = font->GetStretch(); |
| 1707 |
| 1708 *fs = SkFontStyle(weight, width, slant); |
| 1709 |
| 1710 SkTScopedComPtr<IDWriteLocalizedStrings> faceNames; |
| 1711 if (SUCCEEDED(font->GetFaceNames(&faceNames))) { |
| 1712 get_locale_string(faceNames.get(), fFontMgr->fLocaleName.get(), styleNam
e); |
| 1713 } |
| 1714 } |
| 1715 |
1526 SkFontMgr* SkFontMgr::Factory() { | 1716 SkFontMgr* SkFontMgr::Factory() { |
1527 // todo | 1717 IDWriteFactory* factory; |
1528 return NULL; | 1718 HRNM(get_dwrite_factory(&factory), "Could not get factory."); |
| 1719 |
| 1720 SkTScopedComPtr<IDWriteFontCollection> sysFontCollection; |
| 1721 HRNM(factory->GetSystemFontCollection(&sysFontCollection, FALSE), |
| 1722 "Could not get system font collection."); |
| 1723 |
| 1724 WCHAR localeNameStorage[LOCALE_NAME_MAX_LENGTH]; |
| 1725 WCHAR* localeName = NULL; |
| 1726 int localeNameLen = GetUserDefaultLocaleName(localeNameStorage, LOCALE_NAME_
MAX_LENGTH); |
| 1727 if (localeNameLen) { |
| 1728 localeName = localeNameStorage; |
| 1729 }; |
| 1730 |
| 1731 return SkNEW_ARGS(SkFontMgr_DirectWrite, (sysFontCollection.get(), localeNam
e, localeNameLen)); |
1529 } | 1732 } |
OLD | NEW |