Flutter Engine
The Flutter Engine
SkTypeface_win_dw.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2014 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 */
8
10#if defined(SK_BUILD_FOR_WIN)
11
13
14// SkLeanWindows will include Windows.h, which will pull in all of the GDI defines.
15// GDI #defines GetGlyphIndices to GetGlyphIndicesA or GetGlyphIndicesW, but
16// IDWriteFontFace has a method called GetGlyphIndices. Since this file does
17// not use GDI, undefing GetGlyphIndices makes things less confusing.
18#undef GetGlyphIndices
19
20#include "include/core/SkData.h"
33#include "src/sfnt/SkOTUtils.h"
36
37using namespace skia_private;
38
39SkFontStyle DWriteFontTypeface::GetStyle(IDWriteFont* font, IDWriteFontFace* fontFace) {
40 int weight = font->GetWeight();
41 int width = font->GetStretch();
43 switch (font->GetStyle()) {
44 case DWRITE_FONT_STYLE_NORMAL: slant = SkFontStyle::kUpright_Slant; break;
45 case DWRITE_FONT_STYLE_OBLIQUE: slant = SkFontStyle::kOblique_Slant; break;
46 case DWRITE_FONT_STYLE_ITALIC: slant = SkFontStyle::kItalic_Slant; break;
47 default: SkASSERT(false); break;
48 }
49
50#if defined(NTDDI_WIN10_RS3) && NTDDI_VERSION >= NTDDI_WIN10_RS3
51 [&weight, &width, &slant, fontFace]() -> void {
52 SkTScopedComPtr<IDWriteFontFace5> fontFace5;
53 if (FAILED(fontFace->QueryInterface(&fontFace5))) {
54 return;
55 }
56 if (!fontFace5->HasVariations()) {
57 return;
58 }
59
60 UINT32 fontAxisCount = fontFace5->GetFontAxisValueCount();
61 SkTScopedComPtr<IDWriteFontResource> fontResource;
62 HRV(fontFace5->GetFontResource(&fontResource));
63
64 AutoSTMalloc<8, DWRITE_FONT_AXIS_VALUE> fontAxisValue(fontAxisCount);
65 HRV(fontFace5->GetFontAxisValues(fontAxisValue.get(), fontAxisCount));
66 for (UINT32 axisIndex = 0; axisIndex < fontAxisCount; ++axisIndex) {
67 if (fontAxisValue[axisIndex].axisTag == DWRITE_FONT_AXIS_TAG_WEIGHT) {
68 weight = fontAxisValue[axisIndex].value;
69 }
70 if (fontAxisValue[axisIndex].axisTag == DWRITE_FONT_AXIS_TAG_WIDTH) {
71 SkScalar wdthValue = fontAxisValue[axisIndex].value;
73 }
74 if (fontAxisValue[axisIndex].axisTag == DWRITE_FONT_AXIS_TAG_SLANT &&
76 {
77 if (fontAxisValue[axisIndex].value == 0) {
79 } else {
81 }
82 }
83 }
84 }();
85#endif
86 return SkFontStyle(weight, width, slant);
87}
88
90 IDWriteFactory* factory,
91 IDWriteFontFace* fontFace,
92 IDWriteFont* font,
93 IDWriteFontFamily* fontFamily,
94 sk_sp<Loaders> loaders,
95 const SkFontArguments::Palette& palette)
96{
98 GetStyle(font, fontFace), factory, fontFace, font, fontFamily, std::move(loaders), palette));
99}
100
101HRESULT DWriteFontTypeface::initializePalette() {
102 if (!fIsColorFont) {
103 return S_OK;
104 }
105
106 UINT32 dwPaletteCount = fDWriteFontFace2->GetColorPaletteCount();
107 if (dwPaletteCount == 0) {
108 return S_OK;
109 }
110
111 // Treat out of range palette index values as 0. Still apply overrides.
112 // https://www.w3.org/TR/css-fonts-4/#base-palette-desc
113 UINT32 basePaletteIndex = 0;
114 if (SkTFitsIn<UINT32>(fRequestedPalette.index) &&
115 SkTo<UINT32>(fRequestedPalette.index) < dwPaletteCount)
116 {
117 basePaletteIndex = fRequestedPalette.index;
118 }
119
120 UINT32 dwPaletteEntryCount = fDWriteFontFace2->GetPaletteEntryCount();
121 AutoSTMalloc<8, DWRITE_COLOR_F> dwPaletteEntry(dwPaletteEntryCount);
122 HRM(fDWriteFontFace2->GetPaletteEntries(basePaletteIndex,
123 0, dwPaletteEntryCount,
124 dwPaletteEntry),
125 "Could not retrieve palette entries.");
126
127 fPalette.reset(new SkColor[dwPaletteEntryCount]);
128 fDWPalette.reset(new DWRITE_COLOR_F[dwPaletteEntryCount]);
129 for (UINT32 i = 0; i < dwPaletteEntryCount; ++i) {
130 fPalette[i] = SkColorSetARGB(sk_float_round2int(dwPaletteEntry[i].a * 255),
131 sk_float_round2int(dwPaletteEntry[i].r * 255),
132 sk_float_round2int(dwPaletteEntry[i].g * 255),
133 sk_float_round2int(dwPaletteEntry[i].b * 255));
134 fDWPalette[i] = dwPaletteEntry[i];
135 }
136
137 for (int i = 0; i < fRequestedPalette.overrideCount; ++i) {
139 if (SkTFitsIn<UINT32>(paletteOverride.index) &&
140 SkTo<UINT32>(paletteOverride.index) < dwPaletteEntryCount)
141 {
142 fPalette[paletteOverride.index] = paletteOverride.color;
143
144 // Avoid brace initialization as DWRITE_COLOR_F can be defined as four floats
145 // (dxgitype.h, d3d9types.h) or four unions of two floats (dwrite_2.h, d3dtypes.h).
146 // The type changed in Direct3D 10, but the change does not appear to be documented.
147 const SkColor4f skColor = SkColor4f::FromColor(paletteOverride.color);
148 DWRITE_COLOR_F& dwColor = fDWPalette[paletteOverride.index];
149 dwColor.r = skColor.fR;
150 dwColor.g = skColor.fG;
151 dwColor.b = skColor.fB;
152 dwColor.a = skColor.fA;
153 }
154 }
155 fPaletteEntryCount = dwPaletteEntryCount;
156
157 return S_OK;
158}
159
160DWriteFontTypeface::DWriteFontTypeface(const SkFontStyle& style,
161 IDWriteFactory* factory,
162 IDWriteFontFace* fontFace,
163 IDWriteFont* font,
164 IDWriteFontFamily* fontFamily,
165 sk_sp<Loaders> loaders,
166 const SkFontArguments::Palette& palette)
167 : SkTypeface(style, false)
168 , fFactory(SkRefComPtr(factory))
169 , fDWriteFontFamily(SkRefComPtr(fontFamily))
170 , fDWriteFont(SkRefComPtr(font))
171 , fDWriteFontFace(SkRefComPtr(fontFace))
172 , fRequestedPaletteEntryOverrides(palette.overrideCount
173 ? (SkFontArguments::Palette::Override*)memcpy(
174 new SkFontArguments::Palette::Override[palette.overrideCount],
175 palette.overrides,
176 palette.overrideCount * sizeof(palette.overrides[0]))
177 : nullptr)
178 , fRequestedPalette{palette.index,
179 fRequestedPaletteEntryOverrides.get(), palette.overrideCount }
180 , fPaletteEntryCount(0)
181 , fLoaders(std::move(loaders))
182{
183 if (!SUCCEEDED(fDWriteFontFace->QueryInterface(&fDWriteFontFace1))) {
184 // IUnknown::QueryInterface states that if it fails, punk will be set to nullptr.
185 // http://blogs.msdn.com/b/oldnewthing/archive/2004/03/26/96777.aspx
186 SkASSERT_RELEASE(nullptr == fDWriteFontFace1.get());
187 }
188 if (!SUCCEEDED(fDWriteFontFace->QueryInterface(&fDWriteFontFace2))) {
189 SkASSERT_RELEASE(nullptr == fDWriteFontFace2.get());
190 }
191 if (!SUCCEEDED(fDWriteFontFace->QueryInterface(&fDWriteFontFace4))) {
192 SkASSERT_RELEASE(nullptr == fDWriteFontFace4.get());
193 }
194#if DWRITE_CORE || (defined(NTDDI_WIN11_ZN) && NTDDI_VERSION >= NTDDI_WIN11_ZN)
195 if (!SUCCEEDED(fDWriteFontFace->QueryInterface(&fDWriteFontFace7))) {
196 SkASSERT_RELEASE(nullptr == fDWriteFontFace7/*.get()*/);
197 }
198#endif
199 if (!SUCCEEDED(fFactory->QueryInterface(&fFactory2))) {
200 SkASSERT_RELEASE(nullptr == fFactory2.get());
201 }
202
203 if (fDWriteFontFace1 && fDWriteFontFace1->IsMonospacedFont()) {
204 this->setIsFixedPitch(true);
205 }
206
207 fIsColorFont = fFactory2 && fDWriteFontFace2 && fDWriteFontFace2->IsColorFont();
208 this->initializePalette();
209}
210
212#if DWRITE_CORE || (defined(NTDDI_WIN11_ZN) && NTDDI_VERSION >= NTDDI_WIN11_ZN)
213 if (fDWriteFontFace7) {
214 fDWriteFontFace7->Release();
215 }
216#endif
217}
218
220 // Don't return if any fail, just keep going to free up as much as possible.
221 HRESULT hr;
222
223 hr = fFactory->UnregisterFontCollectionLoader(fDWriteFontCollectionLoader.get());
224 if (FAILED(hr)) {
225 SK_TRACEHR(hr, "FontCollectionLoader");
226 }
227
228 hr = fFactory->UnregisterFontFileLoader(fDWriteFontFileLoader.get());
229 if (FAILED(hr)) {
230 SK_TRACEHR(hr, "FontFileLoader");
231 }
232}
233
234void DWriteFontTypeface::onGetFamilyName(SkString* familyName) const {
235 SkTScopedComPtr<IDWriteLocalizedStrings> familyNames;
236 HRV(fDWriteFontFamily->GetFamilyNames(&familyNames));
237
238 sk_get_locale_string(familyNames.get(), nullptr/*fMgr->fLocaleName.get()*/, familyName);
239}
240
241bool DWriteFontTypeface::onGetPostScriptName(SkString* skPostScriptName) const {
242 SkString localSkPostScriptName;
243 SkTScopedComPtr<IDWriteLocalizedStrings> postScriptNames;
244 BOOL exists = FALSE;
245 if (FAILED(fDWriteFont->GetInformationalStrings(
246 DWRITE_INFORMATIONAL_STRING_POSTSCRIPT_NAME,
247 &postScriptNames,
248 &exists)) ||
249 !exists ||
250 FAILED(sk_get_locale_string(postScriptNames.get(), nullptr, &localSkPostScriptName)))
251 {
252 return false;
253 }
254 if (skPostScriptName) {
255 *skPostScriptName = localSkPostScriptName;
256 }
257 return true;
258}
259
261 bool* serialize) const {
262 // Get the family name.
263 SkTScopedComPtr<IDWriteLocalizedStrings> familyNames;
264 HRV(fDWriteFontFamily->GetFamilyNames(&familyNames));
265
266 SkString utf8FamilyName;
267 sk_get_locale_string(familyNames.get(), nullptr/*fMgr->fLocaleName.get()*/, &utf8FamilyName);
268
269 desc->setFamilyName(utf8FamilyName.c_str());
270 desc->setStyle(this->fontStyle());
271
273 sk_careful_memcpy(desc->setPaletteEntryOverrides(fRequestedPalette.overrideCount),
276
277 desc->setFactoryId(FactoryId);
278 *serialize = SkToBool(fLoaders);
279}
280
282 SkGlyphID glyphs[]) const {
283 fDWriteFontFace->GetGlyphIndices((const UINT32*)uni, count, glyphs);
284}
285
287 return fDWriteFontFace->GetGlyphCount();
288}
289
291
293 DWRITE_FONT_METRICS metrics;
294 fDWriteFontFace->GetMetrics(&metrics);
295 return metrics.designUnitsPerEm;
296}
297
298class LocalizedStrings_IDWriteLocalizedStrings : public SkTypeface::LocalizedStrings {
299public:
300 /** Takes ownership of the IDWriteLocalizedStrings. */
301 explicit LocalizedStrings_IDWriteLocalizedStrings(IDWriteLocalizedStrings* strings)
302 : fIndex(0), fStrings(strings)
303 { }
304
305 bool next(SkTypeface::LocalizedString* localizedString) override {
306 if (fIndex >= fStrings->GetCount()) {
307 return false;
308 }
309
310 // String
311 UINT32 stringLen;
312 HRBM(fStrings->GetStringLength(fIndex, &stringLen), "Could not get string length.");
313
314 SkSMallocWCHAR wString(static_cast<size_t>(stringLen)+1);
315 HRBM(fStrings->GetString(fIndex, wString.get(), stringLen+1), "Could not get string.");
316
317 HRB(sk_wchar_to_skstring(wString.get(), stringLen, &localizedString->fString));
318
319 // Locale
320 UINT32 localeLen;
321 HRBM(fStrings->GetLocaleNameLength(fIndex, &localeLen), "Could not get locale length.");
322
323 SkSMallocWCHAR wLocale(static_cast<size_t>(localeLen)+1);
324 HRBM(fStrings->GetLocaleName(fIndex, wLocale.get(), localeLen+1), "Could not get locale.");
325
326 HRB(sk_wchar_to_skstring(wLocale.get(), localeLen, &localizedString->fLanguage));
327
328 ++fIndex;
329 return true;
330 }
331
332private:
333 UINT32 fIndex;
334 SkTScopedComPtr<IDWriteLocalizedStrings> fStrings;
335};
336
340 if (!nameIter) {
341 SkTScopedComPtr<IDWriteLocalizedStrings> familyNames;
342 HRNM(fDWriteFontFamily->GetFamilyNames(&familyNames), "Could not obtain family names.");
343 nameIter = sk_make_sp<LocalizedStrings_IDWriteLocalizedStrings>(familyNames.release());
344 }
345 return nameIter.release();
346}
347
349 return fDWriteFontFace2 && fDWriteFontFace2->GetColorPaletteCount() > 0;
350}
351
353 SkFontArguments::VariationPosition::Coordinate coordinates[], int coordinateCount) const
354{
355
356#if defined(NTDDI_WIN10_RS3) && NTDDI_VERSION >= NTDDI_WIN10_RS3
357
358 SkTScopedComPtr<IDWriteFontFace5> fontFace5;
359 if (FAILED(fDWriteFontFace->QueryInterface(&fontFace5))) {
360 return -1;
361 }
362
363 // Return 0 if the font is not variable font.
364 if (!fontFace5->HasVariations()) {
365 return 0;
366 }
367
368 UINT32 fontAxisCount = fontFace5->GetFontAxisValueCount();
369 SkTScopedComPtr<IDWriteFontResource> fontResource;
370 HR_GENERAL(fontFace5->GetFontResource(&fontResource), nullptr, -1);
371 UINT32 variableAxisCount = 0;
372 for (UINT32 i = 0; i < fontAxisCount; ++i) {
373 if (fontResource->GetFontAxisAttributes(i) & DWRITE_FONT_AXIS_ATTRIBUTES_VARIABLE) {
374 ++variableAxisCount;
375 }
376 }
377
378 if (!coordinates || coordinateCount < 0 || (unsigned)coordinateCount < variableAxisCount) {
379 return SkTo<int>(variableAxisCount);
380 }
381
382 AutoSTMalloc<8, DWRITE_FONT_AXIS_VALUE> fontAxisValue(fontAxisCount);
383 HR_GENERAL(fontFace5->GetFontAxisValues(fontAxisValue.get(), fontAxisCount), nullptr, -1);
384 UINT32 coordIndex = 0;
385 for (UINT32 axisIndex = 0; axisIndex < fontAxisCount; ++axisIndex) {
386 if (fontResource->GetFontAxisAttributes(axisIndex) & DWRITE_FONT_AXIS_ATTRIBUTES_VARIABLE) {
387 coordinates[coordIndex].axis = SkEndian_SwapBE32(fontAxisValue[axisIndex].axisTag);
388 coordinates[coordIndex].value = fontAxisValue[axisIndex].value;
389 ++coordIndex;
390 }
391 }
392
393 SkASSERT(coordIndex == variableAxisCount);
394 return SkTo<int>(variableAxisCount);
395
396#else
397 return -1;
398#endif
399}
400
402 SkFontParameters::Variation::Axis parameters[], int parameterCount) const
403{
404
405#if defined(NTDDI_WIN10_RS3) && NTDDI_VERSION >= NTDDI_WIN10_RS3
406
407 SkTScopedComPtr<IDWriteFontFace5> fontFace5;
408 if (FAILED(fDWriteFontFace->QueryInterface(&fontFace5))) {
409 return -1;
410 }
411
412 // Return 0 if the font is not variable font.
413 if (!fontFace5->HasVariations()) {
414 return 0;
415 }
416
417 UINT32 fontAxisCount = fontFace5->GetFontAxisValueCount();
418 SkTScopedComPtr<IDWriteFontResource> fontResource;
419 HR_GENERAL(fontFace5->GetFontResource(&fontResource), nullptr, -1);
420 int variableAxisCount = 0;
421 for (UINT32 i = 0; i < fontAxisCount; ++i) {
422 if (fontResource->GetFontAxisAttributes(i) & DWRITE_FONT_AXIS_ATTRIBUTES_VARIABLE) {
423 variableAxisCount++;
424 }
425 }
426
427 if (!parameters || parameterCount < variableAxisCount) {
428 return variableAxisCount;
429 }
430
431 AutoSTMalloc<8, DWRITE_FONT_AXIS_RANGE> fontAxisRange(fontAxisCount);
432 HR_GENERAL(fontResource->GetFontAxisRanges(fontAxisRange.get(), fontAxisCount), nullptr, -1);
433 AutoSTMalloc<8, DWRITE_FONT_AXIS_VALUE> fontAxisDefaultValue(fontAxisCount);
434 HR_GENERAL(fontResource->GetDefaultFontAxisValues(fontAxisDefaultValue.get(), fontAxisCount),
435 nullptr, -1);
436 UINT32 coordIndex = 0;
437
438 for (UINT32 axisIndex = 0; axisIndex < fontAxisCount; ++axisIndex) {
439 if (fontResource->GetFontAxisAttributes(axisIndex) & DWRITE_FONT_AXIS_ATTRIBUTES_VARIABLE) {
440 parameters[coordIndex].tag = SkEndian_SwapBE32(fontAxisDefaultValue[axisIndex].axisTag);
441 parameters[coordIndex].min = fontAxisRange[axisIndex].minValue;
442 parameters[coordIndex].def = fontAxisDefaultValue[axisIndex].value;
443 parameters[coordIndex].max = fontAxisRange[axisIndex].maxValue;
444 parameters[coordIndex].setHidden(fontResource->GetFontAxisAttributes(axisIndex) &
445 DWRITE_FONT_AXIS_ATTRIBUTES_HIDDEN);
446 ++coordIndex;
447 }
448 }
449
450 return variableAxisCount;
451
452#else
453 return -1;
454#endif
455}
456
458 DWRITE_FONT_FACE_TYPE type = fDWriteFontFace->GetType();
459 if (type != DWRITE_FONT_FACE_TYPE_CFF &&
460 type != DWRITE_FONT_FACE_TYPE_TRUETYPE &&
461 type != DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION)
462 {
463 return 0;
464 }
465
466 int ttcIndex;
467 std::unique_ptr<SkStreamAsset> stream = this->openStream(&ttcIndex);
468 return stream.get() ? SkFontStream::GetTableTags(stream.get(), ttcIndex, tags) : 0;
469}
470
472 size_t length, void* data) const
473{
475 if (!table.fExists) {
476 return 0;
477 }
478
479 if (offset > table.fSize) {
480 return 0;
481 }
482 size_t size = std::min(length, table.fSize - offset);
483 if (data) {
484 memcpy(data, table.fData + offset, size);
485 }
486
487 return size;
488}
489
491 const uint8_t* data;
492 UINT32 size;
493 void* lock;
494 BOOL exists;
495 fDWriteFontFace->TryGetFontTable(SkEndian_SwapBE32(tag),
496 reinterpret_cast<const void **>(&data), &size, &lock, &exists);
497 if (!exists) {
498 return nullptr;
499 }
500 struct Context {
501 Context(void* lock, IDWriteFontFace* face) : fLock(lock), fFontFace(SkRefComPtr(face)) {}
502 ~Context() { fFontFace->ReleaseFontTable(fLock); }
503 void* fLock;
504 SkTScopedComPtr<IDWriteFontFace> fFontFace;
505 };
507 [](const void*, void* ctx) { delete (Context*)ctx; },
508 new Context(lock, fDWriteFontFace.get()));
509}
510
512 // Skip if the current face index does not match the ttcIndex
513 if (fDWriteFontFace->GetIndex() != SkTo<UINT32>(args.getCollectionIndex())) {
514 return sk_ref_sp(this);
515 }
516
517#if defined(NTDDI_WIN10_RS3) && NTDDI_VERSION >= NTDDI_WIN10_RS3
518
519 SkTScopedComPtr<IDWriteFontFace5> fontFace5;
520
521 if (SUCCEEDED(fDWriteFontFace->QueryInterface(&fontFace5)) && fontFace5->HasVariations()) {
522 UINT32 fontAxisCount = fontFace5->GetFontAxisValueCount();
523 UINT32 argsCoordCount = args.getVariationDesignPosition().coordinateCount;
524 AutoSTMalloc<8, DWRITE_FONT_AXIS_VALUE> fontAxisValue(fontAxisCount);
525 HRN(fontFace5->GetFontAxisValues(fontAxisValue.get(), fontAxisCount));
526
527 for (UINT32 fontIndex = 0; fontIndex < fontAxisCount; ++fontIndex) {
528 for (UINT32 argsIndex = 0; argsIndex < argsCoordCount; ++argsIndex) {
529 if (SkEndian_SwapBE32(fontAxisValue[fontIndex].axisTag) ==
530 args.getVariationDesignPosition().coordinates[argsIndex].axis) {
531 fontAxisValue[fontIndex].value =
532 args.getVariationDesignPosition().coordinates[argsIndex].value;
533 }
534 }
535 }
536 SkTScopedComPtr<IDWriteFontResource> fontResource;
537 HRN(fontFace5->GetFontResource(&fontResource));
538 SkTScopedComPtr<IDWriteFontFace5> newFontFace5;
539 HRN(fontResource->CreateFontFace(fDWriteFont->GetSimulations(),
540 fontAxisValue.get(),
541 fontAxisCount,
542 &newFontFace5));
543
544 SkTScopedComPtr<IDWriteFontFace> newFontFace;
545 HRN(newFontFace5->QueryInterface(&newFontFace));
547 newFontFace.get(),
548 fDWriteFont.get(),
549 fDWriteFontFamily.get(),
550 fLoaders,
551 args.getPalette());
552 }
553
554#endif
555
556 // If the palette args have changed, a new font will need to be created.
557 if (args.getPalette().index != fRequestedPalette.index ||
558 args.getPalette().overrideCount != fRequestedPalette.overrideCount ||
559 memcmp(args.getPalette().overrides, fRequestedPalette.overrides,
561 {
563 fDWriteFontFace.get(),
564 fDWriteFont.get(),
565 fDWriteFontFamily.get(),
566 fLoaders,
567 args.getPalette());
568 }
569
570 return sk_ref_sp(this);
571}
572
573std::unique_ptr<SkStreamAsset> DWriteFontTypeface::onOpenStream(int* ttcIndex) const {
574 *ttcIndex = fDWriteFontFace->GetIndex();
575
576 UINT32 numFiles = 0;
577 HRNM(fDWriteFontFace->GetFiles(&numFiles, nullptr),
578 "Could not get number of font files.");
579 if (numFiles != 1) {
580 return nullptr;
581 }
582
583 SkTScopedComPtr<IDWriteFontFile> fontFile;
584 HRNM(fDWriteFontFace->GetFiles(&numFiles, &fontFile), "Could not get font files.");
585
586 const void* fontFileKey;
587 UINT32 fontFileKeySize;
588 HRNM(fontFile->GetReferenceKey(&fontFileKey, &fontFileKeySize),
589 "Could not get font file reference key.");
590
591 SkTScopedComPtr<IDWriteFontFileLoader> fontFileLoader;
592 HRNM(fontFile->GetLoader(&fontFileLoader), "Could not get font file loader.");
593
594 SkTScopedComPtr<IDWriteFontFileStream> fontFileStream;
595 HRNM(fontFileLoader->CreateStreamFromKey(fontFileKey, fontFileKeySize,
596 &fontFileStream),
597 "Could not create font file stream.");
598
599 return std::unique_ptr<SkStreamAsset>(new SkDWriteFontFileStream(fontFileStream.get()));
600}
601
602std::unique_ptr<SkScalerContext> DWriteFontTypeface::onCreateScalerContext(
603 const SkScalerContextEffects& effects, const SkDescriptor* desc) const
604{
605 return std::make_unique<SkScalerContext_DW>(
606 sk_ref_sp(const_cast<DWriteFontTypeface*>(this)), effects, desc);
607}
608
613 }
614
615 unsigned flagsWeDontSupport = SkScalerContext::kForceAutohinting_Flag |
618 rec->fFlags &= ~flagsWeDontSupport;
619
620 SkFontHinting h = rec->getHinting();
621 // DirectWrite2 allows for hinting to be turned off. Force everything else to normal.
624 }
625 rec->setHinting(h);
626
627#if defined(SK_FONT_HOST_USE_SYSTEM_SETTINGS)
628 IDWriteFactory* factory = sk_get_dwrite_factory();
629 if (factory != nullptr) {
630 SkTScopedComPtr<IDWriteRenderingParams> defaultRenderingParams;
631 if (SUCCEEDED(factory->CreateRenderingParams(&defaultRenderingParams))) {
632 float gamma = defaultRenderingParams->GetGamma();
633 rec->setDeviceGamma(gamma);
634 rec->setPaintGamma(gamma);
635
636 rec->setContrast(defaultRenderingParams->GetEnhancedContrast());
637 }
638 }
639#endif
640}
641
642///////////////////////////////////////////////////////////////////////////////
643//PDF Support
644
645static void glyph_to_unicode_map(IDWriteFontFace* fontFace, DWRITE_UNICODE_RANGE range,
646 UINT32* remainingGlyphCount, UINT32 numGlyphs,
647 SkUnichar* glyphToUnicode)
648{
649 constexpr const int batchSize = 128;
650 UINT32 codepoints[batchSize];
651 UINT16 glyphs[batchSize];
652 for (UINT32 c = range.first; c <= range.last && *remainingGlyphCount != 0; c += batchSize) {
653 UINT32 numBatchedCodePoints = std::min<UINT32>(range.last - c + 1, batchSize);
654 for (UINT32 i = 0; i < numBatchedCodePoints; ++i) {
655 codepoints[i] = c + i;
656 }
657 HRVM(fontFace->GetGlyphIndices(codepoints, numBatchedCodePoints, glyphs),
658 "Failed to get glyph indexes.");
659 for (UINT32 i = 0; i < numBatchedCodePoints; ++i) {
660 UINT16 glyph = glyphs[i];
661 // Intermittent DW bug on Windows 10. See crbug.com/470146.
662 if (glyph >= numGlyphs) {
663 return;
664 }
665 if (0 < glyph && glyphToUnicode[glyph] == 0) {
666 glyphToUnicode[glyph] = c + i; // Always use lowest-index unichar.
667 --*remainingGlyphCount;
668 }
669 }
670 }
671}
672
673void DWriteFontTypeface::getGlyphToUnicodeMap(SkUnichar* glyphToUnicode) const {
674 IDWriteFontFace* face = fDWriteFontFace.get();
675 UINT32 numGlyphs = face->GetGlyphCount();
676 sk_bzero(glyphToUnicode, sizeof(SkUnichar) * numGlyphs);
677 UINT32 remainingGlyphCount = numGlyphs;
678
679 if (fDWriteFontFace1) {
680 IDWriteFontFace1* face1 = fDWriteFontFace1.get();
681 UINT32 numRanges = 0;
682 HRESULT hr = face1->GetUnicodeRanges(0, nullptr, &numRanges);
683 if (hr != E_NOT_SUFFICIENT_BUFFER && FAILED(hr)) {
684 HRVM(hr, "Failed to get number of ranges.");
685 }
686 std::unique_ptr<DWRITE_UNICODE_RANGE[]> ranges(new DWRITE_UNICODE_RANGE[numRanges]);
687 HRVM(face1->GetUnicodeRanges(numRanges, ranges.get(), &numRanges), "Failed to get ranges.");
688 for (UINT32 i = 0; i < numRanges; ++i) {
689 glyph_to_unicode_map(face1, ranges[i], &remainingGlyphCount, numGlyphs, glyphToUnicode);
690 }
691 } else {
692 glyph_to_unicode_map(face, {0, 0x10FFFF}, &remainingGlyphCount, numGlyphs, glyphToUnicode);
693 }
694}
695
696std::unique_ptr<SkAdvancedTypefaceMetrics> DWriteFontTypeface::onGetAdvancedMetrics() const {
697
698 std::unique_ptr<SkAdvancedTypefaceMetrics> info(nullptr);
699
700 DWRITE_FONT_METRICS dwfm;
701 fDWriteFontFace->GetMetrics(&dwfm);
702
704
705 info->fAscent = SkToS16(dwfm.ascent);
706 info->fDescent = SkToS16(dwfm.descent);
707 info->fCapHeight = SkToS16(dwfm.capHeight);
708
709 {
710 SkTScopedComPtr<IDWriteLocalizedStrings> postScriptNames;
711 BOOL exists = FALSE;
712 if (FAILED(fDWriteFont->GetInformationalStrings(
713 DWRITE_INFORMATIONAL_STRING_POSTSCRIPT_NAME,
714 &postScriptNames,
715 &exists)) ||
716 !exists ||
717 FAILED(sk_get_locale_string(postScriptNames.get(), nullptr, &info->fPostScriptName)))
718 {
719 SkDEBUGF("Unable to get postscript name for typeface %p\n", this);
720 }
721 }
722
723 DWRITE_FONT_FACE_TYPE fontType = fDWriteFontFace->GetType();
724 if (fontType == DWRITE_FONT_FACE_TYPE_TRUETYPE ||
725 fontType == DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION)
726 {
728 } else if (fontType == DWRITE_FONT_FACE_TYPE_CFF ||
729 fontType == DWRITE_FONT_FACE_TYPE_OPENTYPE_COLLECTION)
730 {
732 } else {
733 return info;
734 }
735
736 // Simulated fonts aren't really OpenType fonts.
737 if (fDWriteFontFace->GetSimulations() != DWRITE_FONT_SIMULATIONS_NONE) {
739 }
740
745 if (!headTable.fExists || !postTable.fExists || !hheaTable.fExists || !os2Table.fExists) {
746 return info;
747 }
748
749 SkOTUtils::SetAdvancedTypefaceFlags(os2Table->version.v4.fsType, info.get());
750
751 // There are versions of DirectWrite which support named instances for system variation fonts,
752 // but no means to indicate that such a typeface is a variation.
754 if (fvarTable.fExists) {
756 }
757
758 //There exist CJK fonts which set the IsFixedPitch and Monospace bits,
759 //but have full width, latin half-width, and half-width kana.
760 bool fixedWidth = (postTable->isFixedPitch &&
761 (1 == SkEndian_SwapBE16(hheaTable->numberOfHMetrics)));
762 //Monospace
763 if (fixedWidth) {
765 }
766 //Italic
767 if (os2Table->version.v0.fsSelection.field.Italic) {
769 }
770 //Serif
772 SerifStyle serifStyle = os2Table->version.v0.panose.data.textAndDisplay.bSerifStyle;
773 if (SkPanose::FamilyType::TextAndDisplay == os2Table->version.v0.panose.bFamilyType) {
774 if (SerifStyle::Cove == serifStyle ||
775 SerifStyle::ObtuseCove == serifStyle ||
776 SerifStyle::SquareCove == serifStyle ||
777 SerifStyle::ObtuseSquareCove == serifStyle ||
778 SerifStyle::Square == serifStyle ||
779 SerifStyle::Thin == serifStyle ||
780 SerifStyle::Bone == serifStyle ||
781 SerifStyle::Exaggerated == serifStyle ||
782 SerifStyle::Triangle == serifStyle)
783 {
785 }
786 //Script
787 } else if (SkPanose::FamilyType::Script == os2Table->version.v0.panose.bFamilyType) {
789 }
790
791 info->fItalicAngle = SkEndian_SwapBE32(postTable->italicAngle) >> 16;
792
793 info->fBBox = SkIRect::MakeLTRB((int32_t)SkEndian_SwapBE16((uint16_t)headTable->xMin),
794 (int32_t)SkEndian_SwapBE16((uint16_t)headTable->yMax),
795 (int32_t)SkEndian_SwapBE16((uint16_t)headTable->xMax),
796 (int32_t)SkEndian_SwapBE16((uint16_t)headTable->yMin));
797 return info;
798}
799
800class StreamFontFileLoader : public IDWriteFontFileLoader {
801public:
802 // IUnknown methods
803 SK_STDMETHODIMP QueryInterface(REFIID iid, void** ppvObject) override;
804 SK_STDMETHODIMP_(ULONG) AddRef() override;
805 SK_STDMETHODIMP_(ULONG) Release() override;
806
807 // IDWriteFontFileLoader methods
808 SK_STDMETHODIMP CreateStreamFromKey(
809 void const* fontFileReferenceKey,
810 UINT32 fontFileReferenceKeySize,
811 IDWriteFontFileStream** fontFileStream) override;
812
813 // Takes ownership of stream.
814 static HRESULT Create(std::unique_ptr<SkStreamAsset> stream,
815 StreamFontFileLoader** streamFontFileLoader) {
816 *streamFontFileLoader = new StreamFontFileLoader(std::move(stream));
817 if (nullptr == *streamFontFileLoader) {
818 return E_OUTOFMEMORY;
819 }
820 return S_OK;
821 }
822
823private:
824 StreamFontFileLoader(std::unique_ptr<SkStreamAsset> stream)
825 : fStream(std::move(stream)), fRefCount(1)
826 {}
827 virtual ~StreamFontFileLoader() { }
828
829 std::unique_ptr<SkStreamAsset> fStream;
830 ULONG fRefCount;
831};
832
833SK_STDMETHODIMP StreamFontFileLoader::QueryInterface(REFIID iid, void** ppvObject) {
834 if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileLoader)) {
835 *ppvObject = this;
836 AddRef();
837 return S_OK;
838 } else {
839 *ppvObject = nullptr;
840 return E_NOINTERFACE;
841 }
842}
843
844SK_STDMETHODIMP_(ULONG) StreamFontFileLoader::AddRef() {
845 return InterlockedIncrement(&fRefCount);
846}
847
848SK_STDMETHODIMP_(ULONG) StreamFontFileLoader::Release() {
849 ULONG newCount = InterlockedDecrement(&fRefCount);
850 if (0 == newCount) {
851 delete this;
852 }
853 return newCount;
854}
855
856SK_STDMETHODIMP StreamFontFileLoader::CreateStreamFromKey(
857 void const* fontFileReferenceKey,
858 UINT32 fontFileReferenceKeySize,
859 IDWriteFontFileStream** fontFileStream)
860{
861 SkTScopedComPtr<SkDWriteFontFileStreamWrapper> stream;
862 HR(SkDWriteFontFileStreamWrapper::Create(fStream->duplicate().release(), &stream));
863 *fontFileStream = stream.release();
864 return S_OK;
865}
866
867class StreamFontFileEnumerator : public IDWriteFontFileEnumerator {
868public:
869 // IUnknown methods
870 SK_STDMETHODIMP QueryInterface(REFIID iid, void** ppvObject) override;
871 SK_STDMETHODIMP_(ULONG) AddRef() override;
872 SK_STDMETHODIMP_(ULONG) Release() override;
873
874 // IDWriteFontFileEnumerator methods
875 SK_STDMETHODIMP MoveNext(BOOL* hasCurrentFile) override;
876 SK_STDMETHODIMP GetCurrentFontFile(IDWriteFontFile** fontFile) override;
877
878 static HRESULT Create(IDWriteFactory* factory, IDWriteFontFileLoader* fontFileLoader,
879 StreamFontFileEnumerator** streamFontFileEnumerator) {
880 *streamFontFileEnumerator = new StreamFontFileEnumerator(factory, fontFileLoader);
881 if (nullptr == *streamFontFileEnumerator) {
882 return E_OUTOFMEMORY;
883 }
884 return S_OK;
885 }
886private:
887 StreamFontFileEnumerator(IDWriteFactory* factory, IDWriteFontFileLoader* fontFileLoader);
888 virtual ~StreamFontFileEnumerator() { }
889
890 ULONG fRefCount;
891
892 SkTScopedComPtr<IDWriteFactory> fFactory;
893 SkTScopedComPtr<IDWriteFontFile> fCurrentFile;
894 SkTScopedComPtr<IDWriteFontFileLoader> fFontFileLoader;
895 bool fHasNext;
896};
897
898StreamFontFileEnumerator::StreamFontFileEnumerator(IDWriteFactory* factory,
899 IDWriteFontFileLoader* fontFileLoader)
900 : fRefCount(1)
901 , fFactory(SkRefComPtr(factory))
902 , fCurrentFile()
903 , fFontFileLoader(SkRefComPtr(fontFileLoader))
904 , fHasNext(true)
905{ }
906
907SK_STDMETHODIMP StreamFontFileEnumerator::QueryInterface(REFIID iid, void** ppvObject) {
908 if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontFileEnumerator)) {
909 *ppvObject = this;
910 AddRef();
911 return S_OK;
912 } else {
913 *ppvObject = nullptr;
914 return E_NOINTERFACE;
915 }
916}
917
918SK_STDMETHODIMP_(ULONG) StreamFontFileEnumerator::AddRef() {
919 return InterlockedIncrement(&fRefCount);
920}
921
922SK_STDMETHODIMP_(ULONG) StreamFontFileEnumerator::Release() {
923 ULONG newCount = InterlockedDecrement(&fRefCount);
924 if (0 == newCount) {
925 delete this;
926 }
927 return newCount;
928}
929
930SK_STDMETHODIMP StreamFontFileEnumerator::MoveNext(BOOL* hasCurrentFile) {
931 *hasCurrentFile = FALSE;
932
933 if (!fHasNext) {
934 return S_OK;
935 }
936 fHasNext = false;
937
938 UINT32 fontFileReferenceKey = 0;
939 HR(fFactory->CreateCustomFontFileReference(
940 &fontFileReferenceKey, //cannot be nullptr
941 sizeof(fontFileReferenceKey), //even if this is 0
942 fFontFileLoader.get(),
943 &fCurrentFile));
944
945 *hasCurrentFile = TRUE;
946 return S_OK;
947}
948
949SK_STDMETHODIMP StreamFontFileEnumerator::GetCurrentFontFile(IDWriteFontFile** fontFile) {
950 if (fCurrentFile.get() == nullptr) {
951 *fontFile = nullptr;
952 return E_FAIL;
953 }
954
955 *fontFile = SkRefComPtr(fCurrentFile.get());
956 return S_OK;
957}
958
959class StreamFontCollectionLoader : public IDWriteFontCollectionLoader {
960public:
961 // IUnknown methods
962 SK_STDMETHODIMP QueryInterface(REFIID iid, void** ppvObject) override;
963 SK_STDMETHODIMP_(ULONG) AddRef() override;
964 SK_STDMETHODIMP_(ULONG) Release() override;
965
966 // IDWriteFontCollectionLoader methods
967 SK_STDMETHODIMP CreateEnumeratorFromKey(
968 IDWriteFactory* factory,
969 void const* collectionKey,
970 UINT32 collectionKeySize,
971 IDWriteFontFileEnumerator** fontFileEnumerator) override;
972
973 static HRESULT Create(IDWriteFontFileLoader* fontFileLoader,
974 StreamFontCollectionLoader** streamFontCollectionLoader) {
975 *streamFontCollectionLoader = new StreamFontCollectionLoader(fontFileLoader);
976 if (nullptr == *streamFontCollectionLoader) {
977 return E_OUTOFMEMORY;
978 }
979 return S_OK;
980 }
981private:
982 StreamFontCollectionLoader(IDWriteFontFileLoader* fontFileLoader)
983 : fRefCount(1)
984 , fFontFileLoader(SkRefComPtr(fontFileLoader))
985 { }
986 virtual ~StreamFontCollectionLoader() { }
987
988 ULONG fRefCount;
989 SkTScopedComPtr<IDWriteFontFileLoader> fFontFileLoader;
990};
991
992SK_STDMETHODIMP StreamFontCollectionLoader::QueryInterface(REFIID iid, void** ppvObject) {
993 if (iid == IID_IUnknown || iid == __uuidof(IDWriteFontCollectionLoader)) {
994 *ppvObject = this;
995 AddRef();
996 return S_OK;
997 } else {
998 *ppvObject = nullptr;
999 return E_NOINTERFACE;
1000 }
1001}
1002
1003SK_STDMETHODIMP_(ULONG) StreamFontCollectionLoader::AddRef() {
1004 return InterlockedIncrement(&fRefCount);
1005}
1006
1007SK_STDMETHODIMP_(ULONG) StreamFontCollectionLoader::Release() {
1008 ULONG newCount = InterlockedDecrement(&fRefCount);
1009 if (0 == newCount) {
1010 delete this;
1011 }
1012 return newCount;
1013}
1014
1015template <typename T> class SkAutoIDWriteUnregister {
1016public:
1017 SkAutoIDWriteUnregister(IDWriteFactory* factory, T* unregister)
1018 : fFactory(factory), fUnregister(unregister)
1019 { }
1020 SkAutoIDWriteUnregister(const SkAutoIDWriteUnregister&) = delete;
1021 SkAutoIDWriteUnregister& operator=(const SkAutoIDWriteUnregister&) = delete;
1022 SkAutoIDWriteUnregister(SkAutoIDWriteUnregister&&) = delete;
1023 SkAutoIDWriteUnregister& operator=(SkAutoIDWriteUnregister&&) = delete;
1024
1025 ~SkAutoIDWriteUnregister() {
1026 if (fUnregister) {
1027 unregister(fFactory, fUnregister);
1028 }
1029 }
1030
1031 T* detatch() {
1032 T* old = fUnregister;
1033 fUnregister = nullptr;
1034 return old;
1035 }
1036
1037private:
1038 HRESULT unregister(IDWriteFactory* factory, IDWriteFontFileLoader* unregister) {
1039 return factory->UnregisterFontFileLoader(unregister);
1040 }
1041
1042 HRESULT unregister(IDWriteFactory* factory, IDWriteFontCollectionLoader* unregister) {
1043 return factory->UnregisterFontCollectionLoader(unregister);
1044 }
1045
1046 IDWriteFactory* fFactory;
1047 T* fUnregister;
1048};
1049
1050SK_STDMETHODIMP StreamFontCollectionLoader::CreateEnumeratorFromKey(
1051 IDWriteFactory* factory,
1052 void const* collectionKey,
1053 UINT32 collectionKeySize,
1054 IDWriteFontFileEnumerator** fontFileEnumerator)
1055{
1056 SkTScopedComPtr<StreamFontFileEnumerator> enumerator;
1057 HR(StreamFontFileEnumerator::Create(factory, fFontFileLoader.get(), &enumerator));
1058 *fontFileEnumerator = enumerator.release();
1059 return S_OK;
1060}
1061
1062static HRESULT apply_fontargument_variation(SkTScopedComPtr<IDWriteFontFace>& fontFace,
1063 const SkFontArguments& args)
1064{
1065#if defined(NTDDI_WIN10_RS3) && NTDDI_VERSION >= NTDDI_WIN10_RS3
1066
1067 SkTScopedComPtr<IDWriteFontFace5> fontFace5;
1068 if (FAILED(fontFace->QueryInterface(&fontFace5)) || !fontFace5->HasVariations()) {
1069 return S_OK;
1070 }
1071
1072 UINT32 fontAxisCount = fontFace5->GetFontAxisValueCount();
1073 UINT32 argsCoordCount = args.getVariationDesignPosition().coordinateCount;
1074 AutoSTMalloc<8, DWRITE_FONT_AXIS_VALUE> variation(fontAxisCount);
1075 SkTScopedComPtr<IDWriteFontResource> fontResource;
1076 HR(fontFace5->GetFontResource(&fontResource));
1077 HR(fontResource->GetDefaultFontAxisValues(variation, fontAxisCount));
1078
1079 for (UINT32 fontAxisIndex = 0; fontAxisIndex < fontAxisCount; ++fontAxisIndex) {
1080 DWRITE_FONT_AXIS_VALUE& fontCoordinate = variation[fontAxisIndex];
1081
1082 for (UINT32 argsCoordIndex = argsCoordCount; argsCoordIndex --> 0;) {
1084 args.getVariationDesignPosition().coordinates[argsCoordIndex];
1085 if (SkEndian_SwapBE32(fontCoordinate.axisTag) == argsCoordinate.axis) {
1086 fontCoordinate.value = argsCoordinate.value;
1087 break;
1088 }
1089 }
1090 }
1091
1092 SkTScopedComPtr<IDWriteFontFace5> fontFace5_Out;
1093 HR(fontResource->CreateFontFace(DWRITE_FONT_SIMULATIONS_NONE,
1094 variation.get(), fontAxisCount,
1095 &fontFace5_Out));
1096 fontFace.reset();
1097 HR(fontFace5_Out->QueryInterface(&fontFace));
1098#endif
1099 return S_OK;
1100}
1101
1102sk_sp<SkTypeface> DWriteFontTypeface::MakeFromStream(std::unique_ptr<SkStreamAsset> stream,
1103 const SkFontArguments& args) {
1104 // TODO: do we need to use some user provided factory?
1105 IDWriteFactory* factory = sk_get_dwrite_factory();
1106 if (nullptr == factory) {
1107 return nullptr;
1108 }
1109
1110 SkTScopedComPtr<StreamFontFileLoader> fontFileLoader;
1111 HRN(StreamFontFileLoader::Create(std::move(stream), &fontFileLoader));
1112 HRN(factory->RegisterFontFileLoader(fontFileLoader.get()));
1113 SkAutoIDWriteUnregister<StreamFontFileLoader> autoUnregisterFontFileLoader(
1114 factory, fontFileLoader.get());
1115
1116 SkTScopedComPtr<StreamFontCollectionLoader> fontCollectionLoader;
1117 HRN(StreamFontCollectionLoader::Create(fontFileLoader.get(), &fontCollectionLoader));
1118 HRN(factory->RegisterFontCollectionLoader(fontCollectionLoader.get()));
1119 SkAutoIDWriteUnregister<StreamFontCollectionLoader> autoUnregisterFontCollectionLoader(
1120 factory, fontCollectionLoader.get());
1121
1122 SkTScopedComPtr<IDWriteFontCollection> fontCollection;
1123 HRN(factory->CreateCustomFontCollection(fontCollectionLoader.get(), nullptr, 0,
1124 &fontCollection));
1125
1126 // Find the first non-simulated font which has the given ttc index.
1127 UINT32 familyCount = fontCollection->GetFontFamilyCount();
1128 for (UINT32 familyIndex = 0; familyIndex < familyCount; ++familyIndex) {
1129 SkTScopedComPtr<IDWriteFontFamily> fontFamily;
1130 HRN(fontCollection->GetFontFamily(familyIndex, &fontFamily));
1131
1132 UINT32 fontCount = fontFamily->GetFontCount();
1133 for (UINT32 fontIndex = 0; fontIndex < fontCount; ++fontIndex) {
1134 SkTScopedComPtr<IDWriteFont> font;
1135 HRN(fontFamily->GetFont(fontIndex, &font));
1136
1137 // Skip if the current font is simulated
1138 if (font->GetSimulations() != DWRITE_FONT_SIMULATIONS_NONE) {
1139 continue;
1140 }
1141 SkTScopedComPtr<IDWriteFontFace> fontFace;
1142 HRN(font->CreateFontFace(&fontFace));
1143 int faceIndex = fontFace->GetIndex();
1144 int ttcIndex = args.getCollectionIndex();
1145
1146 // Skip if the current face index does not match the ttcIndex
1147 if (faceIndex != ttcIndex) {
1148 continue;
1149 }
1150
1151 apply_fontargument_variation(fontFace, args);
1152
1154 factory, fontFace.get(), font.get(), fontFamily.get(),
1155 sk_make_sp<DWriteFontTypeface::Loaders>(
1156 factory,
1157 autoUnregisterFontFileLoader.detatch(),
1158 autoUnregisterFontCollectionLoader.detatch()),
1159 args.getPalette());
1160 }
1161 }
1162
1163 return nullptr;
1164}
1165
1166#endif//defined(SK_BUILD_FOR_WIN)
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
sk_bzero(glyphs, sizeof(glyphs))
uint16_t glyphs[5]
Definition: FontMgrTest.cpp:46
int count
Definition: FontMgrTest.cpp:50
static float next(float f)
static sk_sp< Effect > Create()
Definition: RefCntTest.cpp:117
#define SkASSERT_RELEASE(cond)
Definition: SkAssert.h:100
#define SkASSERT(cond)
Definition: SkAssert.h:116
uint32_t SkColor
Definition: SkColor.h:37
static constexpr SkColor SkColorSetARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
Definition: SkColor.h:49
HRESULT sk_wchar_to_skstring(WCHAR *name, int nameLen, SkString *skname)
HRESULT sk_get_locale_string(IDWriteLocalizedStrings *names, const WCHAR *preferedLocale, SkString *skname)
IDWriteFactory * sk_get_dwrite_factory()
#define SkDEBUGF(...)
Definition: SkDebug.h:24
#define SkEndian_SwapBE32(n)
Definition: SkEndian.h:136
#define SkEndian_SwapBE16(n)
Definition: SkEndian.h:135
#define sk_float_round2int(x)
SkFontHinting
Definition: SkFontTypes.h:18
@ kNormal
glyph outlines modified to improve constrast
@ kNone
glyph outlines unchanged
static void * sk_careful_memcpy(void *dst, const void *src, size_t len)
Definition: SkMalloc.h:125
#define SK_STDMETHODIMP_(type)
Definition: SkObjBase.h:23
#define SK_STDMETHODIMP
Definition: SkObjBase.h:22
sk_sp< T > sk_ref_sp(T *obj)
Definition: SkRefCnt.h:381
static constexpr bool SkToBool(const T &x)
Definition: SkTo.h:35
constexpr int16_t SkToS16(S x)
Definition: SkTo.h:23
uint32_t SkFontTableTag
Definition: SkTypeface.h:41
int32_t SkUnichar
Definition: SkTypes.h:175
uint16_t SkGlyphID
Definition: SkTypes.h:179
SI F table(const skcms_Curve *curve, F v)
GLenum type
int onGetVariationDesignParameters(SkFontParameters::Variation::Axis parameters[], int parameterCount) const override
int onGetUPEM() const override
SkTScopedComPtr< IDWriteFontFace2 > fDWriteFontFace2
std::unique_ptr< SkScalerContext > onCreateScalerContext(const SkScalerContextEffects &, const SkDescriptor *) const override
static sk_sp< SkTypeface > SK_SPI MakeFromStream(std::unique_ptr< SkStreamAsset >, const SkFontArguments &)
SkTypeface::LocalizedStrings * onCreateFamilyNameIterator() const override
SkTScopedComPtr< IDWriteFactory2 > fFactory2
SkTScopedComPtr< IDWriteFactory > fFactory
SkFontArguments::Palette fRequestedPalette
void onFilterRec(SkScalerContextRec *) const override
void getGlyphToUnicodeMap(SkUnichar *glyphToUnicode) const override
size_t onGetTableData(SkFontTableTag, size_t offset, size_t length, void *data) const override
static SkFontStyle GetStyle(IDWriteFont *font, IDWriteFontFace *fontFace)
std::unique_ptr< SkAdvancedTypefaceMetrics > onGetAdvancedMetrics() const override
void onCharsToGlyphs(const SkUnichar *chars, int count, SkGlyphID glyphs[]) const override
std::unique_ptr< SkColor[]> fPalette
~DWriteFontTypeface() override
IDWriteFontFace7 * fDWriteFontFace7
SkTScopedComPtr< IDWriteFontFamily > fDWriteFontFamily
SkTScopedComPtr< IDWriteFontFace1 > fDWriteFontFace1
std::unique_ptr< SkStreamAsset > onOpenStream(int *ttcIndex) const override
int onGetTableTags(SkFontTableTag tags[]) const override
std::unique_ptr< DWRITE_COLOR_F[]> fDWPalette
int onCountGlyphs() const override
bool onGetPostScriptName(SkString *) const override
void getPostScriptGlyphNames(SkString *) const override
bool onGlyphMaskNeedsCurrentColor() const override
sk_sp< SkData > onCopyTableData(SkFontTableTag) const override
void onGetFamilyName(SkString *familyName) const override
static constexpr SkTypeface::FactoryId FactoryId
SkTScopedComPtr< IDWriteFontFace > fDWriteFontFace
SkTScopedComPtr< IDWriteFont > fDWriteFont
int onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[], int coordinateCount) const override
static sk_sp< DWriteFontTypeface > Make(IDWriteFactory *factory, IDWriteFontFace *fontFace, IDWriteFont *font, IDWriteFontFamily *fontFamily, sk_sp< Loaders > loaders, const SkFontArguments::Palette &palette)
sk_sp< SkTypeface > onMakeClone(const SkFontArguments &) const override
void onGetFontDescriptor(SkFontDescriptor *, bool *) const override
static HRESULT Create(SkStreamAsset *stream, SkDWriteFontFileStreamWrapper **streamFontFileStream)
static sk_sp< SkData > MakeWithProc(const void *ptr, size_t length, ReleaseProc proc, void *ctx)
Definition: SkData.cpp:128
static SkFontStyle::Width SkFontStyleWidthForWidthAxisValue(SkScalar width)
void setPaletteIndex(int paletteIndex)
static int GetTableTags(SkStream *, int ttcIndex, SkFontTableTag tags[])
static sk_sp< LocalizedStrings_NameTable > MakeForFamilyNames(const SkTypeface &typeface)
Definition: SkOTUtils.cpp:191
const char * c_str() const
Definition: SkString.h:133
SkFontStyle fontStyle() const
Definition: SkTypeface.h:55
void serialize(SkWStream *, SerializeBehavior=SerializeBehavior::kIncludeDataIfLocal) const
Definition: SkTypeface.cpp:202
std::unique_ptr< SkStreamAsset > openStream(int *ttcIndex) const
Definition: SkTypeface.cpp:332
T * release()
Definition: SkRefCnt.h:324
float SkScalar
Definition: extension.cpp:12
static bool b
struct MyStruct a[10]
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
uint8_t value
static float min(float r, float g, float b)
Definition: hsl.cpp:48
size_t length
return FALSE
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
Definition: switches.h:259
font
Font Metadata and Metrics.
const myers::Point & get(const myers::Segment &)
Definition: ref_ptr.h:256
SkScalar h
#define T
Definition: precompiler.cc:65
int32_t width
SeparatedVector2 offset
SkTScopedComPtr< IDWriteFactory > fFactory
SkTScopedComPtr< IDWriteFontFileLoader > fDWriteFontFileLoader
SkTScopedComPtr< IDWriteFontCollectionLoader > fDWriteFontCollectionLoader
@ kVariable_FontFlag
May be true for Type1, CFF, or TrueType fonts.
const Override * overrides
static constexpr SkIRect MakeLTRB(int32_t l, int32_t t, int32_t r, int32_t b)
Definition: SkRect.h:91
@ kA8_Format
8bits per pixel mask (e.g. antialiasing)
Definition: SkMask.h:28
static void SetAdvancedTypefaceFlags(SkOTTableOS2_V4::Type fsType, SkAdvancedTypefaceMetrics *info)
Definition: SkOTUtils.cpp:219
void setDeviceGamma(SkScalar g)
SkMask::Format fMaskFormat
void setContrast(SkScalar c)
SkFontHinting getHinting() const
void setHinting(SkFontHinting)
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63
int BOOL
Definition: windows_types.h:37
#define SUCCEEDED(hr)
DWORD ULONG
Definition: windows_types.h:40
#define FAILED(hr)