10#if defined(SK_ENABLE_SVG)
57TestSVGTypeface::TestSVGTypeface(
const char*
name,
65 , fFontMetrics(fontMetrics)
68 for (
size_t i = 0; i <
data.size(); ++i) {
69 const SkSVGTestTypefaceGlyphData& datum =
data[i];
70 fCMap.set(datum.fUnicode, i);
71 fGlyphs[i].fAdvance = datum.fAdvance;
72 fGlyphs[i].fOrigin = datum.fOrigin;
73 fGlyphs[i].fResourcePath = datum.fSvgResourcePath;
78void TestSVGTypeface::Glyph::withSVG(Fn&& fn)
const {
98 if (
svg->containerSize().isEmpty()) {
102 fSvg = std::move(
svg);
110SkSize TestSVGTypeface::Glyph::size()
const {
118void TestSVGTypeface::Glyph::render(
SkCanvas* canvas)
const {
124TestSVGTypeface::~TestSVGTypeface() {}
126TestSVGTypeface::Glyph::Glyph() : fOrigin{0, 0}, fAdvance(0) {}
127TestSVGTypeface::Glyph::~Glyph() {}
130 glyphID = glyphID < fGlyphCount ? glyphID : 0;
131 return {fGlyphs[glyphID].fAdvance, 0};
134void TestSVGTypeface::getFontMetrics(
SkFontMetrics* metrics)
const { *metrics = fFontMetrics; }
140void TestSVGTypeface::getGlyphToUnicodeMap(
SkUnichar* glyphToUnicode)
const {
141 SkDEBUGCODE(
unsigned glyphCount = this->countGlyphs());
144 glyphToUnicode[g] = c;
148std::unique_ptr<SkAdvancedTypefaceMetrics> TestSVGTypeface::onGetAdvancedMetrics()
const {
154void TestSVGTypeface::onGetFontDescriptor(
SkFontDescriptor* desc,
bool* serialize)
const {
156 desc->setStyle(this->fontStyle());
161 for (
int i = 0; i <
count; i++) {
167void TestSVGTypeface::onGetFamilyName(
SkString* familyName)
const { *familyName =
fName; }
169bool TestSVGTypeface::onGetPostScriptName(
SkString*)
const {
return false; }
183 fRec.getSingleMatrix(&fMatrix);
184 SkScalar upem = this->getTestSVGTypeface()->fUpem;
185 fMatrix.
preScale(1.f / upem, 1.f / upem);
189 TestSVGTypeface* getTestSVGTypeface()
const {
190 return static_cast<TestSVGTypeface*
>(this->
getTypeface());
194 auto advance = this->getTestSVGTypeface()->getAdvance(glyphID);
195 return fMatrix.
mapXY(advance.fX, advance.fY);
200 glyphID = glyphID < this->getTestSVGTypeface()->fGlyphCount ? glyphID : 0;
203 mx.neverRequestPath =
true;
204 mx.advance = this->computeAdvance(glyph.
getGlyphID());
206 TestSVGTypeface::Glyph& glyphData = this->getTestSVGTypeface()->fGlyphs[glyphID];
208 SkSize containerSize = glyphData.size();
210 -glyphData.fOrigin.fY,
223 glyphID = glyphID < this->getTestSVGTypeface()->fGlyphCount ? glyphID : 0;
231 TestSVGTypeface::Glyph& glyphData = this->getTestSVGTypeface()->fGlyphs[glyphID];
240 canvas.
translate(glyphData.fOrigin.fX, -glyphData.fOrigin.fY);
242 glyphData.render(&canvas);
247 SK_ABORT(
"Path requested, but it should have been indicated that there isn't one.");
253 SkTestSVGScalerContext* fSelf;
255 SVGGlyphDrawable(SkTestSVGScalerContext*
self,
const SkGlyph& glyph)
256 : fSelf(
self), fGlyph(glyph) {}
257 SkRect onGetBounds()
override {
return fGlyph.
rect(); }
258 size_t onApproximateBytesUsed()
override {
return sizeof(SVGGlyphDrawable); }
260 void onDraw(
SkCanvas* canvas)
override {
262 glyphID = glyphID < fSelf->getTestSVGTypeface()->fGlyphCount ? glyphID : 0;
264 TestSVGTypeface::Glyph& glyphData = fSelf->getTestSVGTypeface()->fGlyphs[glyphID];
270 canvas->
concat(fSelf->fMatrix);
271 canvas->
translate(glyphData.fOrigin.fX, -glyphData.fOrigin.fY);
273 glyphData.render(canvas);
281 this->getTestSVGTypeface()->getFontMetrics(metrics);
289std::unique_ptr<SkScalerContext> TestSVGTypeface::onCreateScalerContext(
292 return std::make_unique<SkTestSVGScalerContext>(
293 sk_ref_sp(
const_cast<TestSVGTypeface*
>(
this)), e, desc);
297 using TestSVGTypeface::TestSVGTypeface;
309 static constexpr const char gHeaderString[] =
"SkTestSVGTypefaceDefault01";
312 std::unique_ptr<SkStreamAsset> onOpenStream(
int* ttcIndex)
const override {
326 return TestSVGTypeface::Default();
329 void onGetFontDescriptor(
SkFontDescriptor* desc,
bool* serialize)
const override {
330 TestSVGTypeface::onGetFontDescriptor(desc, serialize);
331 desc->setFactoryId(FactoryId);
336static DefaultTypeface::Register defaultTypefaceRegister;
339 constexpr const static SkSVGTestTypefaceGlyphData
glyphs[] = {
340 {
"fonts/svg/notdef.svg", {100, 800}, 800, 0x0},
341 {
"fonts/svg/empty.svg", {0, 0}, 800, 0x0020},
342 {
"fonts/svg/diamond.svg", {100, 800}, 800, 0x2662},
343 {
"fonts/svg/smile.svg", {0, 800}, 800, 0x1F600},
358 metrics.
fXMax = 1000;
371 using TestSVGTypeface::TestSVGTypeface;
379 static constexpr const char gHeaderString[] =
"SkTestSVGTypefacePlanet01";
382 std::unique_ptr<SkStreamAsset> onOpenStream(
int* ttcIndex)
const override {
396 return TestSVGTypeface::Planets();
399 void onGetFontDescriptor(
SkFontDescriptor* desc,
bool* isLocal)
const override {
400 TestSVGTypeface::onGetFontDescriptor(desc, isLocal);
401 desc->setFactoryId(FactoryId);
406static PlanetTypeface::Register planetTypefaceRegister;
409 constexpr const static SkSVGTestTypefaceGlyphData
glyphs[] = {
410 {
"fonts/svg/planets/pluto.svg", {0, 20}, 60, 0x0},
411 {
"fonts/svg/empty.svg", {0, 0}, 400, 0x0020},
412 {
"fonts/svg/planets/mercury.svg", {0, 45}, 120, 0x263F},
413 {
"fonts/svg/planets/venus.svg", {0, 100}, 240, 0x2640},
414 {
"fonts/svg/planets/earth.svg", {0, 100}, 240, 0x2641},
415 {
"fonts/svg/planets/mars.svg", {0, 50}, 130, 0x2642},
416 {
"fonts/svg/planets/jupiter.svg", {0, 1000}, 2200, 0x2643},
417 {
"fonts/svg/planets/saturn.svg", {-300, 1500}, 2600, 0x2644},
418 {
"fonts/svg/planets/uranus.svg", {0, 375}, 790, 0x2645},
419 {
"fonts/svg/planets/neptune.svg", {0, 350}, 740, 0x2646},
426 metrics.
fTop = -1500;
433 metrics.
fXMin = -300;
434 metrics.
fXMax = 2566;
446void TestSVGTypeface::exportTtxCommon(
SkWStream* out,
449 int totalGlyphs = fGlyphCount;
450 out->writeText(
" <GlyphOrder>\n");
451 for (
int i = 0; i < fGlyphCount; ++i) {
452 out->writeText(
" <GlyphID name=\"glyf");
453 out->writeHexAsText(i, 4);
454 out->writeText(
"\"/>\n");
457 for (
int i = 0; i < fGlyphCount; ++i) {
458 for (
int j = 0; j < (*glyfInfo)[i].fLayers.size(); ++j) {
459 out->writeText(
" <GlyphID name=\"glyf");
460 out->writeHexAsText(i, 4);
462 out->writeHexAsText(j, 4);
463 out->writeText(
"\"/>\n");
468 out->writeText(
" </GlyphOrder>\n");
470 out->writeText(
" <head>\n");
471 out->writeText(
" <tableVersion value=\"1.0\"/>\n");
472 out->writeText(
" <fontRevision value=\"1.0\"/>\n");
473 out->writeText(
" <checkSumAdjustment value=\"0xa9c3274\"/>\n");
474 out->writeText(
" <magicNumber value=\"0x5f0f3cf5\"/>\n");
475 out->writeText(
" <flags value=\"00000000 00011011\"/>\n");
476 out->writeText(
" <unitsPerEm value=\"");
477 out->writeDecAsText(fUpem);
478 out->writeText(
"\"/>\n");
479 out->writeText(
" <created value=\"Thu Feb 15 12:55:49 2018\"/>\n");
480 out->writeText(
" <modified value=\"Thu Feb 15 12:55:49 2018\"/>\n");
482 out->writeText(
" <xMin value=\"");
483 out->writeScalarAsText(fFontMetrics.fXMin);
484 out->writeText(
"\"/>\n");
485 out->writeText(
" <yMin value=\"");
486 out->writeScalarAsText(-fFontMetrics.fBottom);
487 out->writeText(
"\"/>\n");
488 out->writeText(
" <xMax value=\"");
489 out->writeScalarAsText(fFontMetrics.fXMax);
490 out->writeText(
"\"/>\n");
491 out->writeText(
" <yMax value=\"");
492 out->writeScalarAsText(-fFontMetrics.fTop);
493 out->writeText(
"\"/>\n");
495 char macStyle[16] = {
496 '0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0'};
498 macStyle[0xF - 0x0] =
'1';
500 switch (this->fontStyle().slant()) {
503 macStyle[0xF - 0x1] =
'1';
506 macStyle[0xF - 0x1] =
'1';
508 default:
SK_ABORT(
"Unknown slant.");
511 macStyle[0xF - 0x5] =
'1';
513 macStyle[0xF - 0x6] =
'1';
515 out->writeText(
" <macStyle value=\"");
516 out->write(macStyle, 8);
518 out->write(macStyle + 8, 8);
519 out->writeText(
"\"/>\n");
520 out->writeText(
" <lowestRecPPEM value=\"8\"/>\n");
521 out->writeText(
" <fontDirectionHint value=\"2\"/>\n");
522 out->writeText(
" <indexToLocFormat value=\"0\"/>\n");
523 out->writeText(
" <glyphDataFormat value=\"0\"/>\n");
524 out->writeText(
" </head>\n");
526 out->writeText(
" <hhea>\n");
527 out->writeText(
" <tableVersion value=\"0x00010000\"/>\n");
528 out->writeText(
" <ascent value=\"");
529 out->writeDecAsText(-fFontMetrics.fAscent);
530 out->writeText(
"\"/>\n");
531 out->writeText(
" <descent value=\"");
532 out->writeDecAsText(-fFontMetrics.fDescent);
533 out->writeText(
"\"/>\n");
534 out->writeText(
" <lineGap value=\"");
535 out->writeDecAsText(fFontMetrics.fLeading);
536 out->writeText(
"\"/>\n");
537 out->writeText(
" <advanceWidthMax value=\"0\"/>\n");
538 out->writeText(
" <minLeftSideBearing value=\"0\"/>\n");
539 out->writeText(
" <minRightSideBearing value=\"0\"/>\n");
540 out->writeText(
" <xMaxExtent value=\"");
541 out->writeScalarAsText(fFontMetrics.fXMax - fFontMetrics.fXMin);
542 out->writeText(
"\"/>\n");
543 out->writeText(
" <caretSlopeRise value=\"1\"/>\n");
544 out->writeText(
" <caretSlopeRun value=\"0\"/>\n");
545 out->writeText(
" <caretOffset value=\"0\"/>\n");
546 out->writeText(
" <reserved0 value=\"0\"/>\n");
547 out->writeText(
" <reserved1 value=\"0\"/>\n");
548 out->writeText(
" <reserved2 value=\"0\"/>\n");
549 out->writeText(
" <reserved3 value=\"0\"/>\n");
550 out->writeText(
" <metricDataFormat value=\"0\"/>\n");
551 out->writeText(
" <numberOfHMetrics value=\"0\"/>\n");
552 out->writeText(
" </hhea>\n");
555 out->writeText(
" <maxp>\n");
556 out->writeText(
" <tableVersion value=\"0x10000\"/>\n");
557 out->writeText(
" <numGlyphs value=\"");
558 out->writeDecAsText(totalGlyphs);
559 out->writeText(
"\"/>\n");
560 out->writeText(
" <maxPoints value=\"4\"/>\n");
561 out->writeText(
" <maxContours value=\"1\"/>\n");
562 out->writeText(
" <maxCompositePoints value=\"0\"/>\n");
563 out->writeText(
" <maxCompositeContours value=\"0\"/>\n");
564 out->writeText(
" <maxZones value=\"1\"/>\n");
565 out->writeText(
" <maxTwilightPoints value=\"0\"/>\n");
566 out->writeText(
" <maxStorage value=\"0\"/>\n");
567 out->writeText(
" <maxFunctionDefs value=\"10\"/>\n");
568 out->writeText(
" <maxInstructionDefs value=\"0\"/>\n");
569 out->writeText(
" <maxStackElements value=\"512\"/>\n");
570 out->writeText(
" <maxSizeOfInstructions value=\"24\"/>\n");
571 out->writeText(
" <maxComponentElements value=\"0\"/>\n");
572 out->writeText(
" <maxComponentDepth value=\"0\"/>\n");
573 out->writeText(
" </maxp>\n");
575 out->writeText(
" <OS_2>\n");
576 out->writeText(
" <version value=\"4\"/>\n");
577 out->writeText(
" <xAvgCharWidth value=\"");
578 out->writeScalarAsText(fFontMetrics.fAvgCharWidth);
579 out->writeText(
"\"/>\n");
580 out->writeText(
" <usWeightClass value=\"");
581 out->writeDecAsText(this->fontStyle().weight());
582 out->writeText(
"\"/>\n");
583 out->writeText(
" <usWidthClass value=\"");
584 out->writeDecAsText(this->fontStyle().
width());
585 out->writeText(
"\"/>\n");
586 out->writeText(
" <fsType value=\"00000000 00000000\"/>\n");
587 out->writeText(
" <ySubscriptXSize value=\"665\"/>\n");
588 out->writeText(
" <ySubscriptYSize value=\"716\"/>\n");
589 out->writeText(
" <ySubscriptXOffset value=\"0\"/>\n");
590 out->writeText(
" <ySubscriptYOffset value=\"143\"/>\n");
591 out->writeText(
" <ySuperscriptXSize value=\"665\"/>\n");
592 out->writeText(
" <ySuperscriptYSize value=\"716\"/>\n");
593 out->writeText(
" <ySuperscriptXOffset value=\"0\"/>\n");
594 out->writeText(
" <ySuperscriptYOffset value=\"491\"/>\n");
595 out->writeText(
" <yStrikeoutSize value=\"");
596 out->writeScalarAsText(fFontMetrics.fStrikeoutThickness);
597 out->writeText(
"\"/>\n");
598 out->writeText(
" <yStrikeoutPosition value=\"");
599 out->writeScalarAsText(-fFontMetrics.fStrikeoutPosition);
600 out->writeText(
"\"/>\n");
601 out->writeText(
" <sFamilyClass value=\"0\"/>\n");
602 out->writeText(
" <panose>\n");
603 out->writeText(
" <bFamilyType value=\"0\"/>\n");
604 out->writeText(
" <bSerifStyle value=\"0\"/>\n");
605 out->writeText(
" <bWeight value=\"0\"/>\n");
606 out->writeText(
" <bProportion value=\"0\"/>\n");
607 out->writeText(
" <bContrast value=\"0\"/>\n");
608 out->writeText(
" <bStrokeVariation value=\"0\"/>\n");
609 out->writeText(
" <bArmStyle value=\"0\"/>\n");
610 out->writeText(
" <bLetterForm value=\"0\"/>\n");
611 out->writeText(
" <bMidline value=\"0\"/>\n");
612 out->writeText(
" <bXHeight value=\"0\"/>\n");
613 out->writeText(
" </panose>\n");
614 out->writeText(
" <ulUnicodeRange1 value=\"00000000 00000000 00000000 00000001\"/>\n");
615 out->writeText(
" <ulUnicodeRange2 value=\"00010000 00000000 00000000 00000000\"/>\n");
616 out->writeText(
" <ulUnicodeRange3 value=\"00000000 00000000 00000000 00000000\"/>\n");
617 out->writeText(
" <ulUnicodeRange4 value=\"00000000 00000000 00000000 00000000\"/>\n");
618 out->writeText(
" <achVendID value=\"Skia\"/>\n");
619 char fsSelection[16] = {
620 '0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0'};
621 fsSelection[0xF - 0x7] =
'1';
623 fsSelection[0xF - 0x5] =
'1';
625 switch (this->fontStyle().slant()) {
628 fsSelection[0xF - 0x6] =
'1';
632 fsSelection[0xF - 0x0] =
'1';
635 fsSelection[0xF - 0x0] =
'1';
636 fsSelection[0xF - 0x9] =
'1';
638 default:
SK_ABORT(
"Unknown slant.");
640 out->writeText(
" <fsSelection value=\"");
641 out->write(fsSelection, 8);
643 out->write(fsSelection + 8, 8);
644 out->writeText(
"\"/>\n");
645 out->writeText(
" <usFirstCharIndex value=\"0\"/>\n");
646 out->writeText(
" <usLastCharIndex value=\"0\"/>\n");
647 out->writeText(
" <sTypoAscender value=\"");
648 out->writeScalarAsText(-fFontMetrics.fAscent);
649 out->writeText(
"\"/>\n");
650 out->writeText(
" <sTypoDescender value=\"");
651 out->writeScalarAsText(-fFontMetrics.fDescent);
652 out->writeText(
"\"/>\n");
653 out->writeText(
" <sTypoLineGap value=\"");
654 out->writeScalarAsText(fFontMetrics.fLeading);
655 out->writeText(
"\"/>\n");
656 out->writeText(
" <usWinAscent value=\"");
657 out->writeScalarAsText(-fFontMetrics.fAscent);
658 out->writeText(
"\"/>\n");
659 out->writeText(
" <usWinDescent value=\"");
660 out->writeScalarAsText(fFontMetrics.fDescent);
661 out->writeText(
"\"/>\n");
662 out->writeText(
" <ulCodePageRange1 value=\"00000000 00000000 00000000 00000000\"/>\n");
663 out->writeText(
" <ulCodePageRange2 value=\"00000000 00000000 00000000 00000000\"/>\n");
664 out->writeText(
" <sxHeight value=\"");
665 out->writeScalarAsText(fFontMetrics.fXHeight);
666 out->writeText(
"\"/>\n");
667 out->writeText(
" <sCapHeight value=\"");
668 out->writeScalarAsText(fFontMetrics.fCapHeight);
669 out->writeText(
"\"/>\n");
670 out->writeText(
" <usDefaultChar value=\"0\"/>\n");
671 out->writeText(
" <usBreakChar value=\"32\"/>\n");
672 out->writeText(
" <usMaxContext value=\"0\"/>\n");
673 out->writeText(
" </OS_2>\n");
675 out->writeText(
" <hmtx>\n");
676 for (
int i = 0; i < fGlyphCount; ++i) {
677 out->writeText(
" <mtx name=\"glyf");
678 out->writeHexAsText(i, 4);
679 out->writeText(
"\" width=\"");
680 out->writeDecAsText(fGlyphs[i].fAdvance);
681 out->writeText(
"\" lsb=\"");
682 int lsb = fGlyphs[i].fOrigin.fX;
684 lsb += (*glyfInfo)[i].fBounds.fLeft;
686 out->writeDecAsText(lsb);
687 out->writeText(
"\"/>\n");
690 for (
int i = 0; i < fGlyphCount; ++i) {
691 for (
int j = 0; j < (*glyfInfo)[i].fLayers.size(); ++j) {
692 out->writeText(
" <mtx name=\"glyf");
693 out->writeHexAsText(i, 4);
695 out->writeHexAsText(j, 4);
696 out->writeText(
"\" width=\"");
697 out->writeDecAsText(fGlyphs[i].fAdvance);
698 out->writeText(
"\" lsb=\"");
699 int32_t lsb = fGlyphs[i].fOrigin.fX + (*glyfInfo)[i].fLayers[j].fBounds.fLeft;
700 out->writeDecAsText(lsb);
701 out->writeText(
"\"/>\n");
705 out->writeText(
" </hmtx>\n");
707 bool hasNonBMP =
false;
708 out->writeText(
" <cmap>\n");
709 out->writeText(
" <tableVersion version=\"0\"/>\n");
710 out->writeText(
" <cmap_format_4 platformID=\"3\" platEncID=\"1\" language=\"0\">\n");
716 out->writeText(
" <map code=\"0x");
717 out->writeHexAsText(c, 4);
718 out->writeText(
"\" name=\"glyf");
719 out->writeHexAsText(g, 4);
720 out->writeText(
"\"/>\n");
722 out->writeText(
" </cmap_format_4>\n");
725 " <cmap_format_12 platformID=\"3\" platEncID=\"10\" format=\"12\" "
726 "reserved=\"0\" length=\"1\" language=\"0\" nGroups=\"0\">\n");
728 out->writeText(
" <map code=\"0x");
729 out->writeHexAsText(c, 6);
730 out->writeText(
"\" name=\"glyf");
731 out->writeHexAsText(g, 4);
732 out->writeText(
"\"/>\n");
734 out->writeText(
" </cmap_format_12>\n");
736 out->writeText(
" </cmap>\n");
738 out->writeText(
" <name>\n");
740 " <namerecord nameID=\"1\" platformID=\"3\" platEncID=\"1\" langID=\"0x409\">\n");
745 out->writeText(
"\n");
746 out->writeText(
" </namerecord>\n");
748 " <namerecord nameID=\"2\" platformID=\"3\" platEncID=\"1\" langID=\"0x409\">\n");
749 out->writeText(
" Regular\n");
750 out->writeText(
" </namerecord>\n");
751 out->writeText(
" </name>\n");
753 out->writeText(
" <post>\n");
754 out->writeText(
" <formatType value=\"3.0\"/>\n");
755 out->writeText(
" <italicAngle value=\"0.0\"/>\n");
756 out->writeText(
" <underlinePosition value=\"");
757 out->writeScalarAsText(fFontMetrics.fUnderlinePosition);
758 out->writeText(
"\"/>\n");
759 out->writeText(
" <underlineThickness value=\"");
760 out->writeScalarAsText(fFontMetrics.fUnderlineThickness);
761 out->writeText(
"\"/>\n");
762 out->writeText(
" <isFixedPitch value=\"0\"/>\n");
763 out->writeText(
" <minMemType42 value=\"0\"/>\n");
764 out->writeText(
" <maxMemType42 value=\"0\"/>\n");
765 out->writeText(
" <minMemType1 value=\"0\"/>\n");
766 out->writeText(
" <maxMemType1 value=\"0\"/>\n");
767 out->writeText(
" </post>\n");
773 font.setTypeface(
sk_ref_sp(
const_cast<TestSVGTypeface*
>(
this)));
775 this->getFamilyName(&
name);
779 for (
size_t strikeIndex = 0; strikeIndex < strikeSizes.
size(); ++strikeIndex) {
780 font.setSize(strikeSizes[strikeIndex]);
784 font.getMetrics(&fm);
785 if (!SkTFitsIn<int8_t>((
int)(-fm.
fTop)) || !SkTFitsIn<int8_t>((
int)(-fm.
fBottom)) ||
786 !SkTFitsIn<uint8_t>((
int)(fm.
fXMax - fm.
fXMin))) {
787 SkDebugf(
"Metrics too big cbdt font size %f for %s.\n",
font.getSize(),
name.c_str());
792 auto exceedsCbdtLimits = [&]() {
793 for (
int i = 0; i < fGlyphCount; ++i) {
797 font.getWidthsBounds(&gid, 1, &advance, &bounds,
nullptr);
799 if (!SkTFitsIn<int8_t>(ibounds.
fLeft) || !SkTFitsIn<int8_t>(ibounds.
fTop) ||
800 !SkTFitsIn<uint8_t>(ibounds.
width()) || !SkTFitsIn<uint8_t>(ibounds.
height()) ||
801 !SkTFitsIn<uint8_t>((
int)advance)) {
807 if (exceedsCbdtLimits()) {
808 SkDebugf(
"Glyphs too big cbdt font size %f for %s.\n",
font.getSize(),
name.c_str());
815 if (goodStrikeSizes.
empty()) {
816 SkDebugf(
"No strike size fit for cbdt font for %s.\n",
name.c_str());
820 out->writeText(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
821 out->writeText(
"<ttFont sfntVersion=\"\\x00\\x01\\x00\\x00\" ttLibVersion=\"3.19\">\n");
822 this->exportTtxCommon(out,
"CBDT");
824 out->writeText(
" <CBDT>\n");
825 out->writeText(
" <header version=\"2.0\"/>\n");
826 for (
int strikeIndex = 0; strikeIndex < goodStrikeSizes.
size(); ++strikeIndex) {
827 font.setSize(goodStrikeSizes[strikeIndex]);
829 out->writeText(
" <strikedata index=\"");
830 out->writeDecAsText(strikeIndex);
831 out->writeText(
"\">\n");
832 for (
int i = 0; i < fGlyphCount; ++i) {
836 font.getWidthsBounds(&gid, 1, &advance, &bounds,
nullptr);
859 out->writeText(
" <cbdt_bitmap_format_17 name=\"glyf");
860 out->writeHexAsText(i, 4);
861 out->writeText(
"\">\n");
862 out->writeText(
" <SmallGlyphMetrics>\n");
863 out->writeText(
" <height value=\"");
865 out->writeText(
"\"/>\n");
866 out->writeText(
" <width value=\"");
868 out->writeText(
"\"/>\n");
869 out->writeText(
" <BearingX value=\"");
871 out->writeText(
"\"/>\n");
872 out->writeText(
" <BearingY value=\"");
873 out->writeDecAsText(-ibounds.
fTop);
874 out->writeText(
"\"/>\n");
875 out->writeText(
" <Advance value=\"");
876 out->writeDecAsText((
int)advance);
877 out->writeText(
"\"/>\n");
878 out->writeText(
" </SmallGlyphMetrics>\n");
879 out->writeText(
" <rawimagedata>");
880 uint8_t
const* bytes =
data->bytes();
881 for (
size_t j = 0; j <
data->size(); ++j) {
882 if ((j % 0x10) == 0x0) {
883 out->writeText(
"\n ");
884 }
else if (((j - 1) % 0x4) == 0x3) {
887 out->writeHexAsText(bytes[j], 2);
889 out->writeText(
"\n");
890 out->writeText(
" </rawimagedata>\n");
891 out->writeText(
" </cbdt_bitmap_format_17>\n");
893 out->writeText(
" </strikedata>\n");
895 out->writeText(
" </CBDT>\n");
898 out->writeText(
" <CBLC>\n");
899 out->writeText(
" <header version=\"2.0\"/>\n");
900 for (
int strikeIndex = 0; strikeIndex < goodStrikeSizes.
size(); ++strikeIndex) {
901 font.setSize(goodStrikeSizes[strikeIndex]);
902 font.getMetrics(&fm);
903 out->writeText(
" <strike index=\"");
904 out->writeDecAsText(strikeIndex);
905 out->writeText(
"\">\n");
906 out->writeText(
" <bitmapSizeTable>\n");
907 out->writeText(
" <sbitLineMetrics direction=\"hori\">\n");
908 out->writeText(
" <ascender value=\"");
909 out->writeDecAsText((
int)(-fm.
fTop));
910 out->writeText(
"\"/>\n");
911 out->writeText(
" <descender value=\"");
913 out->writeText(
"\"/>\n");
914 out->writeText(
" <widthMax value=\"");
916 out->writeText(
"\"/>\n");
917 out->writeText(
" <caretSlopeNumerator value=\"0\"/>\n");
918 out->writeText(
" <caretSlopeDenominator value=\"0\"/>\n");
919 out->writeText(
" <caretOffset value=\"0\"/>\n");
920 out->writeText(
" <minOriginSB value=\"0\"/>\n");
921 out->writeText(
" <minAdvanceSB value=\"0\"/>\n");
922 out->writeText(
" <maxBeforeBL value=\"0\"/>\n");
923 out->writeText(
" <minAfterBL value=\"0\"/>\n");
924 out->writeText(
" <pad1 value=\"0\"/>\n");
925 out->writeText(
" <pad2 value=\"0\"/>\n");
926 out->writeText(
" </sbitLineMetrics>\n");
927 out->writeText(
" <sbitLineMetrics direction=\"vert\">\n");
928 out->writeText(
" <ascender value=\"");
929 out->writeDecAsText((
int)(-fm.
fTop));
930 out->writeText(
"\"/>\n");
931 out->writeText(
" <descender value=\"");
933 out->writeText(
"\"/>\n");
934 out->writeText(
" <widthMax value=\"");
936 out->writeText(
"\"/>\n");
937 out->writeText(
" <caretSlopeNumerator value=\"0\"/>\n");
938 out->writeText(
" <caretSlopeDenominator value=\"0\"/>\n");
939 out->writeText(
" <caretOffset value=\"0\"/>\n");
940 out->writeText(
" <minOriginSB value=\"0\"/>\n");
941 out->writeText(
" <minAdvanceSB value=\"0\"/>\n");
942 out->writeText(
" <maxBeforeBL value=\"0\"/>\n");
943 out->writeText(
" <minAfterBL value=\"0\"/>\n");
944 out->writeText(
" <pad1 value=\"0\"/>\n");
945 out->writeText(
" <pad2 value=\"0\"/>\n");
946 out->writeText(
" </sbitLineMetrics>\n");
947 out->writeText(
" <colorRef value=\"0\"/>\n");
948 out->writeText(
" <startGlyphIndex value=\"1\"/>\n");
949 out->writeText(
" <endGlyphIndex value=\"1\"/>\n");
950 out->writeText(
" <ppemX value=\"");
951 out->writeDecAsText(goodStrikeSizes[strikeIndex]);
952 out->writeText(
"\"/>\n");
953 out->writeText(
" <ppemY value=\"");
954 out->writeDecAsText(goodStrikeSizes[strikeIndex]);
955 out->writeText(
"\"/>\n");
956 out->writeText(
" <bitDepth value=\"32\"/>\n");
957 out->writeText(
" <flags value=\"1\"/>\n");
958 out->writeText(
" </bitmapSizeTable>\n");
960 " <eblc_index_sub_table_1 imageFormat=\"17\" firstGlyphIndex=\"1\" "
961 "lastGlyphIndex=\"1\">\n");
962 for (
int i = 0; i < fGlyphCount; ++i) {
965 font.getBounds(&gid, 1, &bounds,
nullptr);
969 out->writeText(
" <glyphLoc name=\"glyf");
970 out->writeHexAsText(i, 4);
971 out->writeText(
"\"/>\n");
973 out->writeText(
" </eblc_index_sub_table_1>\n");
974 out->writeText(
" </strike>\n");
976 out->writeText(
" </CBLC>\n");
978 out->writeText(
"</ttFont>\n");
993 out->writeText(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
994 out->writeText(
"<ttFont sfntVersion=\"\\x00\\x01\\x00\\x00\" ttLibVersion=\"3.19\">\n");
995 this->exportTtxCommon(out,
"sbix");
999 font.setTypeface(
sk_ref_sp(
const_cast<TestSVGTypeface*
>(
this)));
1001 out->writeText(
" <glyf>\n");
1002 for (
int i = 0; i < fGlyphCount; ++i) {
1003 const TestSVGTypeface::Glyph& glyphData = this->fGlyphs[i];
1005 SkSize containerSize = glyphData.size();
1007 -glyphData.fOrigin.fY,
1011 out->writeText(
" <TTGlyph name=\"glyf");
1012 out->writeHexAsText(i, 4);
1013 out->writeText(
"\" xMin=\"");
1014 out->writeDecAsText(ibounds.
fLeft);
1015 out->writeText(
"\" yMin=\"");
1017 out->writeText(
"\" xMax=\"");
1019 out->writeText(
"\" yMax=\"");
1020 out->writeDecAsText(-ibounds.
fTop);
1021 out->writeText(
"\">\n");
1022 out->writeText(
" <contour>\n");
1023 out->writeText(
" <pt x=\"");
1024 out->writeDecAsText(ibounds.
fLeft);
1025 out->writeText(
"\" y=\"");
1027 out->writeText(
"\" on=\"1\"/>\n");
1028 out->writeText(
" </contour>\n");
1029 out->writeText(
" <contour>\n");
1030 out->writeText(
" <pt x=\"");
1032 out->writeText(
"\" y=\"");
1033 out->writeDecAsText(-ibounds.
fTop);
1034 out->writeText(
"\" on=\"1\"/>\n");
1035 out->writeText(
" </contour>\n");
1036 out->writeText(
" <instructions/>\n");
1037 out->writeText(
" </TTGlyph>\n");
1039 out->writeText(
" </glyf>\n");
1042 out->writeText(
" <loca/>\n");
1044 out->writeText(
" <sbix>\n");
1045 out->writeText(
" <version value=\"1\"/>\n");
1046 out->writeText(
" <flags value=\"00000000 00000001\"/>\n");
1047 for (
size_t strikeIndex = 0; strikeIndex < strikeSizes.
size(); ++strikeIndex) {
1048 font.setSize(strikeSizes[strikeIndex]);
1049 out->writeText(
" <strike>\n");
1050 out->writeText(
" <ppem value=\"");
1051 out->writeDecAsText(strikeSizes[strikeIndex]);
1052 out->writeText(
"\"/>\n");
1053 out->writeText(
" <resolution value=\"72\"/>\n");
1054 for (
int i = 0; i < fGlyphCount; ++i) {
1058 font.getWidthsBounds(&gid, 1, &advance, &bounds,
nullptr);
1087 out->writeText(
" <glyph name=\"glyf");
1088 out->writeHexAsText(i, 4);
1089 out->writeText(
"\" graphicType=\"png \" originOffsetX=\"");
1090#if defined(SK_SBIX_LIKE_FT) || defined(SK_SBIX_LIKE_DW)
1093 out->writeDecAsText(0);
1098 out->writeText(
"\" originOffsetY=\"");
1099#if defined(SK_SBIX_LIKE_FT)
1101#elif defined(SK_SBIX_LIKE_DW)
1102 out->writeScalarAsText(-
bounds.fBottom);
1104 out->writeDecAsText(0);
1106 out->writeText(
"\">\n");
1108 out->writeText(
" <hexdata>");
1109 uint8_t
const* bytes =
data->bytes();
1110 for (
size_t j = 0; j <
data->size(); ++j) {
1111 if ((j % 0x10) == 0x0) {
1112 out->writeText(
"\n ");
1113 }
else if (((j - 1) % 0x4) == 0x3) {
1114 out->writeText(
" ");
1116 out->writeHexAsText(bytes[j], 2);
1118 out->writeText(
"\n");
1119 out->writeText(
" </hexdata>\n");
1120 out->writeText(
" </glyph>\n");
1122 out->writeText(
" </strike>\n");
1124 out->writeText(
" </sbix>\n");
1125 out->writeText(
"</ttFont>\n");
1130void convert_noninflect_cubic_to_quads(
const SkPoint p[4],
1155 static const int kMaxSubdivs = 10;
1157 ab.scale(kLengthScale);
1158 dc.
scale(kLengthScale);
1167 if (dSqd < toleranceSqd) {
1180 convert_noninflect_cubic_to_quads(choppedPts + 0, toleranceSqd, quads, sublevel + 1);
1181 convert_noninflect_cubic_to_quads(choppedPts + 3, toleranceSqd, quads, sublevel + 1);
1193 for (
int i = 0; i <
count; ++i) {
1195 convert_noninflect_cubic_to_quads(cubic, tolSqd, quads);
1199void path_to_quads(
const SkPath& path,
SkPath* quadPath) {
1209 quadPath->
quadTo(pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY);
1214 for (
int i = 0; i < qPts.
size(); i += 3) {
1216 qPts[i + 1].fX, qPts[i + 1].fY, qPts[i + 2].fX, qPts[i + 2].fY);
1221 for (
int i = 0; i <
converter.countQuads(); ++i) {
1222 quadPath->
quadTo(quadPts[i * 2 + 1].fX,
1223 quadPts[i * 2 + 1].fY,
1224 quadPts[i * 2 + 2].fX,
1225 quadPts[i * 2 + 2].fY);
1235 SkCOLRCanvas(
SkRect glyphBounds,
1236 const TestSVGTypeface& typeface,
1238 TestSVGTypeface::GlyfInfo* glyf,
1242 , fBaselineOffset(glyphBounds.top())
1243 , fTypeface(typeface)
1251 fOut->writeText(
" <pt x=\"");
1253 fOut->writeText(
"\" y=\"");
1255 fOut->writeText(
"\" on=\"");
1256 fOut->write8(on ?
'1' :
'0');
1257 fOut->writeText(
"\"/>\n");
1262 path_to_quads(path, &quads);
1267 fOut->writeText(
" <TTGlyph name=\"glyf");
1268 fOut->writeHexAsText(fGlyphId, 4);
1270 fOut->writeText(
"l");
1271 fOut->writeHexAsText(fLayerId, 4);
1273 fOut->writeText(
"\" xMin=\"");
1274 fOut->writeDecAsText(ibounds.
fLeft);
1275 fOut->writeText(
"\" yMin=\"");
1276 fOut->writeDecAsText(ibounds.
fTop);
1277 fOut->writeText(
"\" xMax=\"");
1278 fOut->writeDecAsText(ibounds.
fRight);
1279 fOut->writeText(
"\" yMax=\"");
1280 fOut->writeDecAsText(ibounds.
fBottom);
1281 fOut->writeText(
"\">\n");
1283 bool contourOpen =
false;
1284 for (
auto [verb, pts,
w] :
SkPathPriv::Iterate(quads)) {
1288 fOut->writeText(
" </contour>\n");
1289 contourOpen =
false;
1294 fOut->writeText(
" <contour>\n");
1295 this->writePoint(pts[0].fX, pts[0].fY,
true);
1298 this->writePoint(pts[1].fX, pts[1].fY,
true);
1302 fOut->writeText(
" <contour>\n");
1303 this->writePoint(pts[0].fX, pts[0].fY,
true);
1306 this->writePoint(pts[1].fX, pts[1].fY,
false);
1307 this->writePoint(pts[2].fX, pts[2].fY,
true);
1311 fOut->writeText(
" </contour>\n");
1312 contourOpen =
false;
1319 fOut->writeText(
" </contour>\n");
1323 fOut->writeText(
" <instructions/>\n");
1324 fOut->writeText(
" </TTGlyph>\n");
1348 &path, oval, startAngle, sweepAngle, useCenter, fillNoPathEffect);
1354 path.addRRect(rrect);
1366 paint.setPathEffect(
nullptr);
1371 paint.setStrokeWidth(0);
1385 if (fTypeface.getPathOp(
color, &op)) {
1386 fBasePath.add(path, op);
1394 constexpr SkColor currentColor = 0xFF2B0000;
1397 if (
color == currentColor) {
1398 colorIndex = 0xFFFF;
1400 int* colorIndexPtr = fColors->find(
color);
1401 if (colorIndexPtr) {
1402 colorIndex = *colorIndexPtr;
1404 colorIndex = fColors->count();
1405 fColors->set(
color, colorIndex);
1408 fGlyf->fLayers.emplace_back(colorIndex, bounds);
1413 void finishGlyph() {
1415 fBasePath.resolve(&baseGlyph);
1416 fGlyf->fBounds = this->writePath(baseGlyph,
false);
1421 const TestSVGTypeface& fTypeface;
1423 TestSVGTypeface::GlyfInfo* fGlyf;
1432void TestSVGTypeface::exportTtxColr(
SkWStream* out)
const {
1433 out->writeText(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
1434 out->writeText(
"<ttFont sfntVersion=\"\\x00\\x01\\x00\\x00\" ttLibVersion=\"3.19\">\n");
1442 for (
int i = 0; i < fGlyphCount; ++i) {
1443 const TestSVGTypeface::Glyph& glyphData = this->fGlyphs[i];
1445 SkSize containerSize = glyphData.size();
1447 -glyphData.fOrigin.fY,
1450 SkCOLRCanvas canvas(bounds, *
this, i, &glyfInfos.emplace_back(), &colors, &glyfOut);
1451 glyphData.render(&canvas);
1452 canvas.finishGlyph();
1456 this->exportTtxCommon(out,
"COLR", &glyfInfos);
1459 out->writeText(
" <loca/>\n");
1461 std::unique_ptr<SkStreamAsset> glyfStream = glyfOut.
detachAsStream();
1462 out->writeStream(glyfStream.get(), glyfStream->getLength());
1464 out->writeText(
" <COLR>\n");
1465 out->writeText(
" <version value=\"0\"/>\n");
1466 for (
int i = 0; i < fGlyphCount; ++i) {
1467 if (glyfInfos[i].fLayers.empty()) {
1471 SkDebugf(
"Glyph %d is empty but has layers.\n", i);
1473 out->writeText(
" <ColorGlyph name=\"glyf");
1474 out->writeHexAsText(i, 4);
1475 out->writeText(
"\">\n");
1476 for (
int j = 0; j < glyfInfos[i].fLayers.size(); ++j) {
1477 const int colorIndex = glyfInfos[i].fLayers[j].fLayerColorIndex;
1478 out->writeText(
" <layer colorID=\"");
1479 out->writeDecAsText(colorIndex);
1480 out->writeText(
"\" name=\"glyf");
1481 out->writeHexAsText(i, 4);
1482 out->writeText(
"l");
1483 out->writeHexAsText(j, 4);
1484 out->writeText(
"\"/>\n");
1486 out->writeText(
" </ColorGlyph>\n");
1488 out->writeText(
" </COLR>\n");
1492 colors.foreach ([&colorsInOrder](
const SkColor& c,
const int* i) { colorsInOrder[*i] = c; });
1493 out->writeText(
" <CPAL>\n");
1494 out->writeText(
" <version value=\"0\"/>\n");
1495 out->writeText(
" <numPaletteEntries value=\"");
1497 out->writeText(
"\"/>\n");
1498 out->writeText(
" <palette index=\"0\">\n");
1499 for (
int i = 0; i <
colors.count(); ++i) {
1501 out->writeText(
" <color index=\"");
1502 out->writeDecAsText(i);
1503 out->writeText(
"\" value=\"#");
1508 out->writeText(
"\"/>\n");
1510 out->writeText(
" </palette>\n");
1511 out->writeText(
" </CPAL>\n");
1513 out->writeText(
"</ttFont>\n");
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
static bool isFinite(const SkRect &r)
std::unique_ptr< SkStreamAsset > GetResourceAsStream(const char *resource, bool useFileStream)
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
#define SkDEBUGFAIL(message)
#define SK_ABORT(message,...)
#define SkColorGetR(color)
#define SkColorGetG(color)
#define SkColorGetA(color)
#define SkColorGetB(color)
static const char gHeaderString[]
static constexpr size_t kHeaderSize
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
#define SkFixedToScalar(x)
@ kNone
glyph outlines unchanged
@ kGlyphID
uses two byte words to represent glyph indices
void SkChopCubicAtHalf(const SkPoint src[4], SkPoint dst[7])
int SkChopCubicAtInflections(const SkPoint src[4], SkPoint dst[10])
@ kDifference_SkPathOp
subtract the op path from the first path
@ kUnion_SkPathOp
union (inclusive-or) the two paths
@ kClose
SkPath::RawIter returns 0 points.
@ kCubic
SkPath::RawIter returns 4 points.
@ kConic
SkPath::RawIter returns 3 points + 1 weight.
@ kQuad
SkPath::RawIter returns 3 points.
@ kMove
SkPath::RawIter returns 1 point.
@ kLine
SkPath::RawIter returns 2 points.
sk_sp< T > sk_ref_sp(T *obj)
#define SkScalarRoundToInt(x)
#define SK_ScalarNearlyZero
static SkScalar SkScalarSquare(SkScalar x)
static constexpr SkFourByteTag SkSetFourByteTag(char a, char b, char c, char d)
bool installPixels(const SkImageInfo &info, void *pixels, size_t rowBytes, void(*releaseProc)(void *addr, void *context), void *context)
void eraseColor(SkColor4f) const
void drawSimpleText(const void *text, size_t byteLength, SkTextEncoding encoding, SkScalar x, SkScalar y, const SkFont &font, const SkPaint &paint)
void translate(SkScalar dx, SkScalar dy)
void clear(SkColor color)
SkMatrix getTotalMatrix() const
void drawPath(const SkPath &path, const SkPaint &paint)
void concat(const SkMatrix &matrix)
std::unique_ptr< SkStreamAsset > detachAsStream()
bool write(const void *buffer, size_t size) override
static void ScaleFontMetrics(SkFontMetrics *, SkScalar)
static constexpr SkFontStyle Bold()
static constexpr SkFontStyle Normal()
SkGlyphID getGlyphID() const
SkFixed getSubYFixed() const
SkFixed getSubXFixed() const
SkMatrix & postTranslate(SkScalar dx, SkScalar dy)
void mapXY(SkScalar x, SkScalar y, SkPoint *result) const
SkScalar getScaleY() const
SkMatrix & preScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
bool mapRect(SkRect *dst, const SkRect &src, SkApplyPerspectiveClip pc=SkApplyPerspectiveClip::kYes) const
void onDrawArc(const SkRect &, SkScalar, SkScalar, bool, const SkPaint &) override
void onDrawRRect(const SkRRect &, const SkPaint &) override
void onDrawRect(const SkRect &, const SkPaint &) override
void onDrawOval(const SkRect &, const SkPaint &) override
void onDrawPath(const SkPath &, const SkPaint &) override
@ kStroke_Style
set to stroke geometry
@ kFill_Style
set to fill geometry
static void CreateDrawArcPath(SkPath *path, const SkRect &oval, SkScalar startAngle, SkScalar sweepAngle, bool useCenter, bool isFillNoPathEffect)
SkPath & moveTo(SkScalar x, SkScalar y)
SkPath & lineTo(SkScalar x, SkScalar y)
SkRect computeTightBounds() const
SkPath & quadTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2)
static SkScalar LengthSqd(const SkPoint &pt)
static SkScalar DistanceToSqd(const SkPoint &pt, const SkPoint &a)
static sk_sp< SkSVGDOM > MakeFromStream(SkStream &str)
virtual void generateImage(const SkGlyph &glyph, void *imageBuffer)=0
virtual GlyphMetrics generateMetrics(const SkGlyph &, SkArenaAlloc *)=0
virtual bool generatePath(const SkGlyph &, SkPath *)=0
SkTypeface * getTypeface() const
constexpr size_t size() const
static void Register(FactoryId id, sk_sp< SkTypeface >(*make)(std::unique_ptr< SkStreamAsset >, const SkFontArguments &))
bool writeText(const char text[])
T & emplace_back(Args &&... args)
void convertCubicToQuads(const SkPoint p[4], SkScalar tolScale, skia_private::TArray< SkPoint, true > *quads)
SK_API bool Encode(SkWStream *dst, const SkPixmap &src, const Options &options)
Optional< SkRect > bounds
PODArray< SkColor > colors
skia_private::AutoTArray< sk_sp< SkImageFilter > > filters TypedMatrix matrix TypedMatrix matrix SkScalar dx
SK_API sk_sp< SkSurface > Raster(const SkImageInfo &imageInfo, size_t rowBytes, const SkSurfaceProps *surfaceProps)
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot The VM snapshot data that will be memory mapped as read only SnapshotAssetPath must be present isolate snapshot The isolate snapshot data that will be memory mapped as read only SnapshotAssetPath must be present cache dir path
DEF_SWITCHES_START aot vmservice shared library Name of the *so containing AOT compiled Dart assets for launching the service isolate vm snapshot data
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
font
Font Metadata and Metrics.
SK_API bool FillPathWithPaint(const SkPath &src, const SkPaint &paint, SkPath *dst, const SkRect *cullRect, SkScalar resScale=1)
static const char header[]
SkScalar fTop
greatest extent above origin of any glyph bounding box, typically negative; deprecated with variable ...
SkScalar fLeading
distance to add between lines, typically positive or zero
SkScalar fAvgCharWidth
average character width, zero if unknown
SkScalar fStrikeoutPosition
distance from baseline to bottom of stroke, typically negative
SkScalar fStrikeoutThickness
strikeout thickness
SkScalar fMaxCharWidth
maximum character width, zero if unknown
SkScalar fBottom
greatest extent below origin of any glyph bounding box, typically positive; deprecated with variable ...
uint32_t fFlags
FontMetricsFlags indicating which metrics are valid.
SkScalar fAscent
distance to reserve above baseline, typically negative
SkScalar fXHeight
height of lower-case 'x', zero if unknown, typically negative
SkScalar fUnderlineThickness
underline thickness
@ kStrikeoutPositionIsValid_Flag
set if fStrikeoutPosition is valid
@ kStrikeoutThicknessIsValid_Flag
set if fStrikeoutThickness is valid
@ kUnderlinePositionIsValid_Flag
set if fUnderlinePosition is valid
@ kUnderlineThicknessIsValid_Flag
set if fUnderlineThickness is valid
SkScalar fDescent
distance to reserve below baseline, typically positive
SkScalar fCapHeight
height of an upper-case letter, zero if unknown, typically negative
SkScalar fXMin
greatest extent to left of origin of any glyph bounding box, typically negative; deprecated with vari...
SkScalar fUnderlinePosition
distance from baseline to top of stroke, typically positive
SkScalar fXMax
greatest extent to right of origin of any glyph bounding box, typically positive; deprecated with var...
int32_t fBottom
larger y-axis bounds
constexpr int32_t height() const
int32_t fTop
smaller y-axis bounds
constexpr int32_t width() const
int32_t fLeft
smaller x-axis bounds
int32_t fRight
larger x-axis bounds
static SkImageInfo MakeN32Premul(int width, int height)
static SkImageInfo MakeN32(int width, int height, SkAlphaType at)
@ kARGB32_Format
SkPMColor.
void scale(float scale, SkPoint *dst) const
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
void roundOut(SkIRect *dst) const
void offset(float dx, float dy)
void setHinting(SkFontHinting)
static constexpr SkSize MakeEmpty()