10#if defined(SK_ENABLE_SVG)
58TestSVGTypeface::TestSVGTypeface(
const char*
name,
const SkFontStyle& style,
64 , fFontMetrics(fontMetrics)
67 for (
size_t i = 0;
i <
data.size(); ++
i) {
68 const SkSVGTestTypefaceGlyphData& datum =
data[
i];
69 fCMap.set(datum.fUnicode,
i);
70 fGlyphs[
i].fAdvance = datum.fAdvance;
71 fGlyphs[
i].fOrigin = datum.fOrigin;
72 fGlyphs[
i].fResourcePath = datum.fSvgResourcePath;
77void TestSVGTypeface::Glyph::withSVG(Fn&& fn)
const {
97 if (
svg->containerSize().isEmpty()) {
101 fSvg = std::move(
svg);
123TestSVGTypeface::~TestSVGTypeface() {}
126TestSVGTypeface::Glyph::~Glyph() {}
129 glyphID = glyphID < fGlyphCount ? glyphID : 0;
130 return {fGlyphs[glyphID].fAdvance, 0};
133void TestSVGTypeface::getFontMetrics(
SkFontMetrics* metrics)
const { *metrics = fFontMetrics; }
139void TestSVGTypeface::getGlyphToUnicodeMap(
SkUnichar* glyphToUnicode)
const {
140 SkDEBUGCODE(
unsigned glyphCount = this->countGlyphs());
143 glyphToUnicode[g] = c;
147std::unique_ptr<SkAdvancedTypefaceMetrics> TestSVGTypeface::onGetAdvancedMetrics()
const {
155 desc->setStyle(this->fontStyle());
166void TestSVGTypeface::onGetFamilyName(
SkString* familyName)
const { *familyName =
fName; }
168bool TestSVGTypeface::onGetPostScriptName(
SkString*)
const {
return false; }
182 fRec.getSingleMatrix(&
fMatrix);
183 SkScalar upem = this->getTestSVGTypeface()->fUpem;
188 TestSVGTypeface* getTestSVGTypeface()
const {
189 return static_cast<TestSVGTypeface*
>(this->
getTypeface());
193 auto advance = this->getTestSVGTypeface()->getAdvance(glyphID);
199 glyphID = glyphID < this->getTestSVGTypeface()->fGlyphCount ? glyphID : 0;
202 mx.neverRequestPath =
true;
203 mx.advance = this->computeAdvance(glyph.
getGlyphID());
207 SkSize containerSize = glyphData.size();
209 -glyphData.fOrigin.fY,
222 glyphID = glyphID < this->getTestSVGTypeface()->fGlyphCount ? glyphID : 0;
239 canvas.
translate(glyphData.fOrigin.fX, -glyphData.fOrigin.fY);
241 glyphData.render(&canvas);
246 SK_ABORT(
"Path requested, but it should have been indicated that there isn't one.");
252 SkTestSVGScalerContext* fSelf;
254 SVGGlyphDrawable(SkTestSVGScalerContext*
self,
const SkGlyph& glyph)
255 : fSelf(
self), fGlyph(glyph) {}
256 SkRect onGetBounds()
override {
return fGlyph.
rect(); }
257 size_t onApproximateBytesUsed()
override {
return sizeof(SVGGlyphDrawable); }
259 void onDraw(
SkCanvas* canvas)
override {
261 glyphID = glyphID < fSelf->getTestSVGTypeface()->fGlyphCount ? glyphID : 0;
269 canvas->
concat(fSelf->fMatrix);
270 canvas->
translate(glyphData.fOrigin.fX, -glyphData.fOrigin.fY);
272 glyphData.render(canvas);
280 this->getTestSVGTypeface()->getFontMetrics(metrics);
288std::unique_ptr<SkScalerContext> TestSVGTypeface::onCreateScalerContext(
291 return std::make_unique<SkTestSVGScalerContext>(
296 using TestSVGTypeface::TestSVGTypeface;
308 static constexpr const char gHeaderString[] =
"SkTestSVGTypefaceDefault01";
311 std::unique_ptr<SkStreamAsset> onOpenStream(
int* ttcIndex)
const override {
325 return TestSVGTypeface::Default();
329 TestSVGTypeface::onGetFontDescriptor(
desc, serialize);
330 desc->setFactoryId(FactoryId);
338 constexpr const static SkSVGTestTypefaceGlyphData
glyphs[] = {
339 {
"fonts/svg/notdef.svg", {100, 800}, 800, 0x0},
340 {
"fonts/svg/empty.svg", {0, 0}, 800, 0x0020},
341 {
"fonts/svg/diamond.svg", {100, 800}, 800, 0x2662},
342 {
"fonts/svg/smile.svg", {0, 800}, 800, 0x1F600},
357 metrics.
fXMax = 1000;
370 using TestSVGTypeface::TestSVGTypeface;
378 static constexpr const char gHeaderString[] =
"SkTestSVGTypefacePlanet01";
381 std::unique_ptr<SkStreamAsset> onOpenStream(
int* ttcIndex)
const override {
395 return TestSVGTypeface::Planets();
399 TestSVGTypeface::onGetFontDescriptor(
desc, isLocal);
400 desc->setFactoryId(FactoryId);
408 constexpr const static SkSVGTestTypefaceGlyphData
glyphs[] = {
409 {
"fonts/svg/planets/pluto.svg", {0, 20}, 60, 0x0},
410 {
"fonts/svg/empty.svg", {0, 0}, 400, 0x0020},
411 {
"fonts/svg/planets/mercury.svg", {0, 45}, 120, 0x263F},
412 {
"fonts/svg/planets/venus.svg", {0, 100}, 240, 0x2640},
413 {
"fonts/svg/planets/earth.svg", {0, 100}, 240, 0x2641},
414 {
"fonts/svg/planets/mars.svg", {0, 50}, 130, 0x2642},
415 {
"fonts/svg/planets/jupiter.svg", {0, 1000}, 2200, 0x2643},
416 {
"fonts/svg/planets/saturn.svg", {-300, 1500}, 2600, 0x2644},
417 {
"fonts/svg/planets/uranus.svg", {0, 375}, 790, 0x2645},
418 {
"fonts/svg/planets/neptune.svg", {0, 350}, 740, 0x2646},
425 metrics.
fTop = -1500;
432 metrics.
fXMin = -300;
433 metrics.
fXMax = 2566;
448 int totalGlyphs = fGlyphCount;
449 out->writeText(
" <GlyphOrder>\n");
450 for (
int i = 0;
i < fGlyphCount; ++
i) {
451 out->writeText(
" <GlyphID name=\"glyf");
452 out->writeHexAsText(
i, 4);
453 out->writeText(
"\"/>\n");
456 for (
int i = 0;
i < fGlyphCount; ++
i) {
457 for (
int j = 0; j < (*glyfInfo)[
i].fLayers.size(); ++j) {
458 out->writeText(
" <GlyphID name=\"glyf");
459 out->writeHexAsText(
i, 4);
461 out->writeHexAsText(j, 4);
462 out->writeText(
"\"/>\n");
467 out->writeText(
" </GlyphOrder>\n");
469 out->writeText(
" <head>\n");
470 out->writeText(
" <tableVersion value=\"1.0\"/>\n");
471 out->writeText(
" <fontRevision value=\"1.0\"/>\n");
472 out->writeText(
" <checkSumAdjustment value=\"0xa9c3274\"/>\n");
473 out->writeText(
" <magicNumber value=\"0x5f0f3cf5\"/>\n");
474 out->writeText(
" <flags value=\"00000000 00011011\"/>\n");
475 out->writeText(
" <unitsPerEm value=\"");
476 out->writeDecAsText(fUpem);
477 out->writeText(
"\"/>\n");
478 out->writeText(
" <created value=\"Thu Feb 15 12:55:49 2018\"/>\n");
479 out->writeText(
" <modified value=\"Thu Feb 15 12:55:49 2018\"/>\n");
481 out->writeText(
" <xMin value=\"");
482 out->writeScalarAsText(fFontMetrics.fXMin);
483 out->writeText(
"\"/>\n");
484 out->writeText(
" <yMin value=\"");
485 out->writeScalarAsText(-fFontMetrics.fBottom);
486 out->writeText(
"\"/>\n");
487 out->writeText(
" <xMax value=\"");
488 out->writeScalarAsText(fFontMetrics.fXMax);
489 out->writeText(
"\"/>\n");
490 out->writeText(
" <yMax value=\"");
491 out->writeScalarAsText(-fFontMetrics.fTop);
492 out->writeText(
"\"/>\n");
494 char macStyle[16] = {
495 '0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0'};
497 macStyle[0xF - 0x0] =
'1';
499 switch (this->fontStyle().slant()) {
502 macStyle[0xF - 0x1] =
'1';
505 macStyle[0xF - 0x1] =
'1';
507 default:
SK_ABORT(
"Unknown slant.");
510 macStyle[0xF - 0x5] =
'1';
512 macStyle[0xF - 0x6] =
'1';
514 out->writeText(
" <macStyle value=\"");
515 out->write(macStyle, 8);
517 out->write(macStyle + 8, 8);
518 out->writeText(
"\"/>\n");
519 out->writeText(
" <lowestRecPPEM value=\"8\"/>\n");
520 out->writeText(
" <fontDirectionHint value=\"2\"/>\n");
521 out->writeText(
" <indexToLocFormat value=\"0\"/>\n");
522 out->writeText(
" <glyphDataFormat value=\"0\"/>\n");
523 out->writeText(
" </head>\n");
525 out->writeText(
" <hhea>\n");
526 out->writeText(
" <tableVersion value=\"0x00010000\"/>\n");
527 out->writeText(
" <ascent value=\"");
528 out->writeDecAsText(-fFontMetrics.fAscent);
529 out->writeText(
"\"/>\n");
530 out->writeText(
" <descent value=\"");
531 out->writeDecAsText(-fFontMetrics.fDescent);
532 out->writeText(
"\"/>\n");
533 out->writeText(
" <lineGap value=\"");
534 out->writeDecAsText(fFontMetrics.fLeading);
535 out->writeText(
"\"/>\n");
536 out->writeText(
" <advanceWidthMax value=\"0\"/>\n");
537 out->writeText(
" <minLeftSideBearing value=\"0\"/>\n");
538 out->writeText(
" <minRightSideBearing value=\"0\"/>\n");
539 out->writeText(
" <xMaxExtent value=\"");
540 out->writeScalarAsText(fFontMetrics.fXMax - fFontMetrics.fXMin);
541 out->writeText(
"\"/>\n");
542 out->writeText(
" <caretSlopeRise value=\"1\"/>\n");
543 out->writeText(
" <caretSlopeRun value=\"0\"/>\n");
544 out->writeText(
" <caretOffset value=\"0\"/>\n");
545 out->writeText(
" <reserved0 value=\"0\"/>\n");
546 out->writeText(
" <reserved1 value=\"0\"/>\n");
547 out->writeText(
" <reserved2 value=\"0\"/>\n");
548 out->writeText(
" <reserved3 value=\"0\"/>\n");
549 out->writeText(
" <metricDataFormat value=\"0\"/>\n");
550 out->writeText(
" <numberOfHMetrics value=\"0\"/>\n");
551 out->writeText(
" </hhea>\n");
554 out->writeText(
" <maxp>\n");
555 out->writeText(
" <tableVersion value=\"0x10000\"/>\n");
556 out->writeText(
" <numGlyphs value=\"");
557 out->writeDecAsText(totalGlyphs);
558 out->writeText(
"\"/>\n");
559 out->writeText(
" <maxPoints value=\"4\"/>\n");
560 out->writeText(
" <maxContours value=\"1\"/>\n");
561 out->writeText(
" <maxCompositePoints value=\"0\"/>\n");
562 out->writeText(
" <maxCompositeContours value=\"0\"/>\n");
563 out->writeText(
" <maxZones value=\"1\"/>\n");
564 out->writeText(
" <maxTwilightPoints value=\"0\"/>\n");
565 out->writeText(
" <maxStorage value=\"0\"/>\n");
566 out->writeText(
" <maxFunctionDefs value=\"10\"/>\n");
567 out->writeText(
" <maxInstructionDefs value=\"0\"/>\n");
568 out->writeText(
" <maxStackElements value=\"512\"/>\n");
569 out->writeText(
" <maxSizeOfInstructions value=\"24\"/>\n");
570 out->writeText(
" <maxComponentElements value=\"0\"/>\n");
571 out->writeText(
" <maxComponentDepth value=\"0\"/>\n");
572 out->writeText(
" </maxp>\n");
574 out->writeText(
" <OS_2>\n");
575 out->writeText(
" <version value=\"4\"/>\n");
576 out->writeText(
" <xAvgCharWidth value=\"");
577 out->writeScalarAsText(fFontMetrics.fAvgCharWidth);
578 out->writeText(
"\"/>\n");
579 out->writeText(
" <usWeightClass value=\"");
580 out->writeDecAsText(this->fontStyle().weight());
581 out->writeText(
"\"/>\n");
582 out->writeText(
" <usWidthClass value=\"");
583 out->writeDecAsText(this->fontStyle().
width());
584 out->writeText(
"\"/>\n");
585 out->writeText(
" <fsType value=\"00000000 00000000\"/>\n");
586 out->writeText(
" <ySubscriptXSize value=\"665\"/>\n");
587 out->writeText(
" <ySubscriptYSize value=\"716\"/>\n");
588 out->writeText(
" <ySubscriptXOffset value=\"0\"/>\n");
589 out->writeText(
" <ySubscriptYOffset value=\"143\"/>\n");
590 out->writeText(
" <ySuperscriptXSize value=\"665\"/>\n");
591 out->writeText(
" <ySuperscriptYSize value=\"716\"/>\n");
592 out->writeText(
" <ySuperscriptXOffset value=\"0\"/>\n");
593 out->writeText(
" <ySuperscriptYOffset value=\"491\"/>\n");
594 out->writeText(
" <yStrikeoutSize value=\"");
595 out->writeScalarAsText(fFontMetrics.fStrikeoutThickness);
596 out->writeText(
"\"/>\n");
597 out->writeText(
" <yStrikeoutPosition value=\"");
598 out->writeScalarAsText(-fFontMetrics.fStrikeoutPosition);
599 out->writeText(
"\"/>\n");
600 out->writeText(
" <sFamilyClass value=\"0\"/>\n");
601 out->writeText(
" <panose>\n");
602 out->writeText(
" <bFamilyType value=\"0\"/>\n");
603 out->writeText(
" <bSerifStyle value=\"0\"/>\n");
604 out->writeText(
" <bWeight value=\"0\"/>\n");
605 out->writeText(
" <bProportion value=\"0\"/>\n");
606 out->writeText(
" <bContrast value=\"0\"/>\n");
607 out->writeText(
" <bStrokeVariation value=\"0\"/>\n");
608 out->writeText(
" <bArmStyle value=\"0\"/>\n");
609 out->writeText(
" <bLetterForm value=\"0\"/>\n");
610 out->writeText(
" <bMidline value=\"0\"/>\n");
611 out->writeText(
" <bXHeight value=\"0\"/>\n");
612 out->writeText(
" </panose>\n");
613 out->writeText(
" <ulUnicodeRange1 value=\"00000000 00000000 00000000 00000001\"/>\n");
614 out->writeText(
" <ulUnicodeRange2 value=\"00010000 00000000 00000000 00000000\"/>\n");
615 out->writeText(
" <ulUnicodeRange3 value=\"00000000 00000000 00000000 00000000\"/>\n");
616 out->writeText(
" <ulUnicodeRange4 value=\"00000000 00000000 00000000 00000000\"/>\n");
617 out->writeText(
" <achVendID value=\"Skia\"/>\n");
618 char fsSelection[16] = {
619 '0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0',
'0'};
620 fsSelection[0xF - 0x7] =
'1';
622 fsSelection[0xF - 0x5] =
'1';
624 switch (this->fontStyle().slant()) {
627 fsSelection[0xF - 0x6] =
'1';
631 fsSelection[0xF - 0x0] =
'1';
634 fsSelection[0xF - 0x0] =
'1';
635 fsSelection[0xF - 0x9] =
'1';
637 default:
SK_ABORT(
"Unknown slant.");
639 out->writeText(
" <fsSelection value=\"");
640 out->write(fsSelection, 8);
642 out->write(fsSelection + 8, 8);
643 out->writeText(
"\"/>\n");
644 out->writeText(
" <usFirstCharIndex value=\"0\"/>\n");
645 out->writeText(
" <usLastCharIndex value=\"0\"/>\n");
646 out->writeText(
" <sTypoAscender value=\"");
647 out->writeScalarAsText(-fFontMetrics.fAscent);
648 out->writeText(
"\"/>\n");
649 out->writeText(
" <sTypoDescender value=\"");
650 out->writeScalarAsText(-fFontMetrics.fDescent);
651 out->writeText(
"\"/>\n");
652 out->writeText(
" <sTypoLineGap value=\"");
653 out->writeScalarAsText(fFontMetrics.fLeading);
654 out->writeText(
"\"/>\n");
655 out->writeText(
" <usWinAscent value=\"");
656 out->writeScalarAsText(-fFontMetrics.fAscent);
657 out->writeText(
"\"/>\n");
658 out->writeText(
" <usWinDescent value=\"");
659 out->writeScalarAsText(fFontMetrics.fDescent);
660 out->writeText(
"\"/>\n");
661 out->writeText(
" <ulCodePageRange1 value=\"00000000 00000000 00000000 00000000\"/>\n");
662 out->writeText(
" <ulCodePageRange2 value=\"00000000 00000000 00000000 00000000\"/>\n");
663 out->writeText(
" <sxHeight value=\"");
664 out->writeScalarAsText(fFontMetrics.fXHeight);
665 out->writeText(
"\"/>\n");
666 out->writeText(
" <sCapHeight value=\"");
667 out->writeScalarAsText(fFontMetrics.fCapHeight);
668 out->writeText(
"\"/>\n");
669 out->writeText(
" <usDefaultChar value=\"0\"/>\n");
670 out->writeText(
" <usBreakChar value=\"32\"/>\n");
671 out->writeText(
" <usMaxContext value=\"0\"/>\n");
672 out->writeText(
" </OS_2>\n");
674 out->writeText(
" <hmtx>\n");
675 for (
int i = 0;
i < fGlyphCount; ++
i) {
676 out->writeText(
" <mtx name=\"glyf");
677 out->writeHexAsText(
i, 4);
678 out->writeText(
"\" width=\"");
679 out->writeDecAsText(fGlyphs[
i].fAdvance);
680 out->writeText(
"\" lsb=\"");
681 int lsb = fGlyphs[
i].fOrigin.fX;
683 lsb += (*glyfInfo)[
i].fBounds.fLeft;
685 out->writeDecAsText(lsb);
686 out->writeText(
"\"/>\n");
689 for (
int i = 0;
i < fGlyphCount; ++
i) {
690 for (
int j = 0; j < (*glyfInfo)[
i].fLayers.size(); ++j) {
691 out->writeText(
" <mtx name=\"glyf");
692 out->writeHexAsText(
i, 4);
694 out->writeHexAsText(j, 4);
695 out->writeText(
"\" width=\"");
696 out->writeDecAsText(fGlyphs[
i].fAdvance);
697 out->writeText(
"\" lsb=\"");
698 int32_t lsb = fGlyphs[
i].fOrigin.fX + (*glyfInfo)[
i].fLayers[j].fBounds.fLeft;
699 out->writeDecAsText(lsb);
700 out->writeText(
"\"/>\n");
704 out->writeText(
" </hmtx>\n");
706 bool hasNonBMP =
false;
707 out->writeText(
" <cmap>\n");
708 out->writeText(
" <tableVersion version=\"0\"/>\n");
709 out->writeText(
" <cmap_format_4 platformID=\"3\" platEncID=\"1\" language=\"0\">\n");
715 out->writeText(
" <map code=\"0x");
716 out->writeHexAsText(c, 4);
717 out->writeText(
"\" name=\"glyf");
718 out->writeHexAsText(g, 4);
719 out->writeText(
"\"/>\n");
721 out->writeText(
" </cmap_format_4>\n");
724 " <cmap_format_12 platformID=\"3\" platEncID=\"10\" format=\"12\" "
725 "reserved=\"0\" length=\"1\" language=\"0\" nGroups=\"0\">\n");
727 out->writeText(
" <map code=\"0x");
728 out->writeHexAsText(c, 6);
729 out->writeText(
"\" name=\"glyf");
730 out->writeHexAsText(g, 4);
731 out->writeText(
"\"/>\n");
733 out->writeText(
" </cmap_format_12>\n");
735 out->writeText(
" </cmap>\n");
737 out->writeText(
" <name>\n");
739 " <namerecord nameID=\"1\" platformID=\"3\" platEncID=\"1\" langID=\"0x409\">\n");
744 out->writeText(
"\n");
745 out->writeText(
" </namerecord>\n");
747 " <namerecord nameID=\"2\" platformID=\"3\" platEncID=\"1\" langID=\"0x409\">\n");
748 out->writeText(
" Regular\n");
749 out->writeText(
" </namerecord>\n");
751 " <namerecord nameID=\"6\" platformID=\"3\" platEncID=\"1\" langID=\"0x409\">\n");
756 out->writeText(
"\n");
757 out->writeText(
" </namerecord>\n");
758 out->writeText(
" </name>\n");
760 out->writeText(
" <post>\n");
761 out->writeText(
" <formatType value=\"3.0\"/>\n");
762 out->writeText(
" <italicAngle value=\"0.0\"/>\n");
763 out->writeText(
" <underlinePosition value=\"");
764 out->writeScalarAsText(fFontMetrics.fUnderlinePosition);
765 out->writeText(
"\"/>\n");
766 out->writeText(
" <underlineThickness value=\"");
767 out->writeScalarAsText(fFontMetrics.fUnderlineThickness);
768 out->writeText(
"\"/>\n");
769 out->writeText(
" <isFixedPitch value=\"0\"/>\n");
770 out->writeText(
" <minMemType42 value=\"0\"/>\n");
771 out->writeText(
" <maxMemType42 value=\"0\"/>\n");
772 out->writeText(
" <minMemType1 value=\"0\"/>\n");
773 out->writeText(
" <maxMemType1 value=\"0\"/>\n");
774 out->writeText(
" </post>\n");
780 font.setTypeface(
sk_ref_sp(
const_cast<TestSVGTypeface*
>(
this)));
782 this->getFamilyName(&
name);
786 for (
size_t strikeIndex = 0; strikeIndex < strikeSizes.
size(); ++strikeIndex) {
787 font.setSize(strikeSizes[strikeIndex]);
791 font.getMetrics(&fm);
792 if (!SkTFitsIn<int8_t>((
int)(-fm.
fTop)) || !SkTFitsIn<int8_t>((
int)(-fm.
fBottom)) ||
793 !SkTFitsIn<uint8_t>((
int)(fm.
fXMax - fm.
fXMin))) {
794 SkDebugf(
"Metrics too big cbdt font size %f for %s.\n",
font.getSize(),
name.c_str());
799 auto exceedsCbdtLimits = [&]() {
800 for (
int i = 0;
i < fGlyphCount; ++
i) {
804 font.getWidthsBounds(&gid, 1, &advance, &
bounds,
nullptr);
806 if (!SkTFitsIn<int8_t>(ibounds.
fLeft) || !SkTFitsIn<int8_t>(ibounds.
fTop) ||
807 !SkTFitsIn<uint8_t>(ibounds.
width()) || !SkTFitsIn<uint8_t>(ibounds.
height()) ||
808 !SkTFitsIn<uint8_t>((
int)advance)) {
814 if (exceedsCbdtLimits()) {
815 SkDebugf(
"Glyphs too big cbdt font size %f for %s.\n",
font.getSize(),
name.c_str());
822 if (goodStrikeSizes.
empty()) {
823 SkDebugf(
"No strike size fit for cbdt font for %s.\n",
name.c_str());
827 out->writeText(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
828 out->writeText(
"<ttFont sfntVersion=\"\\x00\\x01\\x00\\x00\" ttLibVersion=\"3.19\">\n");
829 this->exportTtxCommon(
out,
"CBDT");
831 out->writeText(
" <CBDT>\n");
832 out->writeText(
" <header version=\"2.0\"/>\n");
833 for (
int strikeIndex = 0; strikeIndex < goodStrikeSizes.
size(); ++strikeIndex) {
834 font.setSize(goodStrikeSizes[strikeIndex]);
836 out->writeText(
" <strikedata index=\"");
837 out->writeDecAsText(strikeIndex);
838 out->writeText(
"\">\n");
839 for (
int i = 0;
i < fGlyphCount; ++
i) {
843 font.getWidthsBounds(&gid, 1, &advance, &
bounds,
nullptr);
866 out->writeText(
" <cbdt_bitmap_format_17 name=\"glyf");
867 out->writeHexAsText(
i, 4);
868 out->writeText(
"\">\n");
869 out->writeText(
" <SmallGlyphMetrics>\n");
870 out->writeText(
" <height value=\"");
872 out->writeText(
"\"/>\n");
873 out->writeText(
" <width value=\"");
875 out->writeText(
"\"/>\n");
876 out->writeText(
" <BearingX value=\"");
878 out->writeText(
"\"/>\n");
879 out->writeText(
" <BearingY value=\"");
880 out->writeDecAsText(-ibounds.
fTop);
881 out->writeText(
"\"/>\n");
882 out->writeText(
" <Advance value=\"");
883 out->writeDecAsText((
int)advance);
884 out->writeText(
"\"/>\n");
885 out->writeText(
" </SmallGlyphMetrics>\n");
886 out->writeText(
" <rawimagedata>");
887 uint8_t
const* bytes =
data->bytes();
888 for (
size_t j = 0; j <
data->size(); ++j) {
889 if ((j % 0x10) == 0x0) {
890 out->writeText(
"\n ");
891 }
else if (((j - 1) % 0x4) == 0x3) {
894 out->writeHexAsText(bytes[j], 2);
896 out->writeText(
"\n");
897 out->writeText(
" </rawimagedata>\n");
898 out->writeText(
" </cbdt_bitmap_format_17>\n");
900 out->writeText(
" </strikedata>\n");
902 out->writeText(
" </CBDT>\n");
905 out->writeText(
" <CBLC>\n");
906 out->writeText(
" <header version=\"2.0\"/>\n");
907 for (
int strikeIndex = 0; strikeIndex < goodStrikeSizes.
size(); ++strikeIndex) {
908 font.setSize(goodStrikeSizes[strikeIndex]);
909 font.getMetrics(&fm);
910 out->writeText(
" <strike index=\"");
911 out->writeDecAsText(strikeIndex);
912 out->writeText(
"\">\n");
913 out->writeText(
" <bitmapSizeTable>\n");
914 out->writeText(
" <sbitLineMetrics direction=\"hori\">\n");
915 out->writeText(
" <ascender value=\"");
916 out->writeDecAsText((
int)(-fm.
fTop));
917 out->writeText(
"\"/>\n");
918 out->writeText(
" <descender value=\"");
920 out->writeText(
"\"/>\n");
921 out->writeText(
" <widthMax value=\"");
923 out->writeText(
"\"/>\n");
924 out->writeText(
" <caretSlopeNumerator value=\"0\"/>\n");
925 out->writeText(
" <caretSlopeDenominator value=\"0\"/>\n");
926 out->writeText(
" <caretOffset value=\"0\"/>\n");
927 out->writeText(
" <minOriginSB value=\"0\"/>\n");
928 out->writeText(
" <minAdvanceSB value=\"0\"/>\n");
929 out->writeText(
" <maxBeforeBL value=\"0\"/>\n");
930 out->writeText(
" <minAfterBL value=\"0\"/>\n");
931 out->writeText(
" <pad1 value=\"0\"/>\n");
932 out->writeText(
" <pad2 value=\"0\"/>\n");
933 out->writeText(
" </sbitLineMetrics>\n");
934 out->writeText(
" <sbitLineMetrics direction=\"vert\">\n");
935 out->writeText(
" <ascender value=\"");
936 out->writeDecAsText((
int)(-fm.
fTop));
937 out->writeText(
"\"/>\n");
938 out->writeText(
" <descender value=\"");
940 out->writeText(
"\"/>\n");
941 out->writeText(
" <widthMax value=\"");
943 out->writeText(
"\"/>\n");
944 out->writeText(
" <caretSlopeNumerator value=\"0\"/>\n");
945 out->writeText(
" <caretSlopeDenominator value=\"0\"/>\n");
946 out->writeText(
" <caretOffset value=\"0\"/>\n");
947 out->writeText(
" <minOriginSB value=\"0\"/>\n");
948 out->writeText(
" <minAdvanceSB value=\"0\"/>\n");
949 out->writeText(
" <maxBeforeBL value=\"0\"/>\n");
950 out->writeText(
" <minAfterBL value=\"0\"/>\n");
951 out->writeText(
" <pad1 value=\"0\"/>\n");
952 out->writeText(
" <pad2 value=\"0\"/>\n");
953 out->writeText(
" </sbitLineMetrics>\n");
954 out->writeText(
" <colorRef value=\"0\"/>\n");
955 out->writeText(
" <startGlyphIndex value=\"1\"/>\n");
956 out->writeText(
" <endGlyphIndex value=\"1\"/>\n");
957 out->writeText(
" <ppemX value=\"");
958 out->writeDecAsText(goodStrikeSizes[strikeIndex]);
959 out->writeText(
"\"/>\n");
960 out->writeText(
" <ppemY value=\"");
961 out->writeDecAsText(goodStrikeSizes[strikeIndex]);
962 out->writeText(
"\"/>\n");
963 out->writeText(
" <bitDepth value=\"32\"/>\n");
964 out->writeText(
" <flags value=\"1\"/>\n");
965 out->writeText(
" </bitmapSizeTable>\n");
967 " <eblc_index_sub_table_1 imageFormat=\"17\" firstGlyphIndex=\"1\" "
968 "lastGlyphIndex=\"1\">\n");
969 for (
int i = 0;
i < fGlyphCount; ++
i) {
976 out->writeText(
" <glyphLoc name=\"glyf");
977 out->writeHexAsText(
i, 4);
978 out->writeText(
"\"/>\n");
980 out->writeText(
" </eblc_index_sub_table_1>\n");
981 out->writeText(
" </strike>\n");
983 out->writeText(
" </CBLC>\n");
985 out->writeText(
"</ttFont>\n");
1016 out->writeText(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
1017 out->writeText(
"<ttFont sfntVersion=\"\\x00\\x01\\x00\\x00\" ttLibVersion=\"3.19\">\n");
1018 this->exportTtxCommon(
out,
"sbix");
1022 font.setTypeface(
sk_ref_sp(
const_cast<TestSVGTypeface*
>(
this)));
1024 out->writeText(
" <glyf>\n");
1025 for (
int i = 0;
i < fGlyphCount; ++
i) {
1028 SkSize containerSize = glyphData.size();
1032 out->writeText(
" <TTGlyph name=\"glyf");
1033 out->writeHexAsText(
i, 4);
1034 out->writeText(
"\" xMin=\"");
1035 out->writeDecAsText(0);
1036 out->writeText(
"\" yMin=\"");
1038 out->writeText(
"\" xMax=\"");
1040 out->writeText(
"\" yMax=\"");
1041 out->writeDecAsText(-ibounds.
fTop);
1042 out->writeText(
"\">\n");
1043 out->writeText(
" <contour>\n");
1044 out->writeText(
" <pt x=\"");
1045 out->writeDecAsText(0);
1046 out->writeText(
"\" y=\"");
1048 out->writeText(
"\" on=\"1\"/>\n");
1049 out->writeText(
" </contour>\n");
1050 out->writeText(
" <contour>\n");
1051 out->writeText(
" <pt x=\"");
1053 out->writeText(
"\" y=\"");
1054 out->writeDecAsText(-ibounds.
fTop);
1055 out->writeText(
"\" on=\"1\"/>\n");
1056 out->writeText(
" </contour>\n");
1057 out->writeText(
" <instructions/>\n");
1058 out->writeText(
" </TTGlyph>\n");
1060 out->writeText(
" </glyf>\n");
1063 out->writeText(
" <loca/>\n");
1065 out->writeText(
" <sbix>\n");
1066 out->writeText(
" <version value=\"1\"/>\n");
1067 out->writeText(
" <flags value=\"00000000 00000001\"/>\n");
1068 for (
size_t strikeIndex = 0; strikeIndex < strikeSizes.
size(); ++strikeIndex) {
1069 font.setSize(strikeSizes[strikeIndex]);
1070 out->writeText(
" <strike>\n");
1071 out->writeText(
" <ppem value=\"");
1072 out->writeDecAsText(strikeSizes[strikeIndex]);
1073 out->writeText(
"\"/>\n");
1074 out->writeText(
" <resolution value=\"72\"/>\n");
1075 for (
int i = 0;
i < fGlyphCount; ++
i) {
1079 font.getWidthsBounds(&gid, 1, &advance, &
bounds,
nullptr);
1102 out->writeText(
" <glyph name=\"glyf");
1103 out->writeHexAsText(
i, 4);
1109 out->writeText(
"\" graphicType=\"png \" originOffsetX=\"0\" originOffsetY=\"0\">\n");
1111 out->writeText(
" <hexdata>");
1112 uint8_t
const* bytes =
data->bytes();
1113 for (
size_t j = 0; j <
data->size(); ++j) {
1114 if ((j % 0x10) == 0x0) {
1115 out->writeText(
"\n ");
1116 }
else if (((j - 1) % 0x4) == 0x3) {
1117 out->writeText(
" ");
1119 out->writeHexAsText(bytes[j], 2);
1121 out->writeText(
"\n");
1122 out->writeText(
" </hexdata>\n");
1123 out->writeText(
" </glyph>\n");
1125 out->writeText(
" </strike>\n");
1127 out->writeText(
" </sbix>\n");
1128 out->writeText(
"</ttFont>\n");
1133void convert_noninflect_cubic_to_quads(
const SkPoint p[4],
1158 static const int kMaxSubdivs = 10;
1160 ab.scale(kLengthScale);
1161 dc.
scale(kLengthScale);
1170 if (dSqd < toleranceSqd) {
1183 convert_noninflect_cubic_to_quads(choppedPts + 0, toleranceSqd, quads, sublevel + 1);
1184 convert_noninflect_cubic_to_quads(choppedPts + 3, toleranceSqd, quads, sublevel + 1);
1198 convert_noninflect_cubic_to_quads(
cubic, tolSqd, quads);
1212 quadPath->
quadTo(pts[1].fX, pts[1].fY, pts[2].fX, pts[2].fY);
1217 for (
int i = 0;
i < qPts.
size();
i += 3) {
1219 qPts[
i + 1].fX, qPts[
i + 1].fY, qPts[
i + 2].fX, qPts[
i + 2].fY);
1225 quadPath->
quadTo(quadPts[
i * 2 + 1].fX,
1226 quadPts[
i * 2 + 1].fY,
1227 quadPts[
i * 2 + 2].fX,
1228 quadPts[
i * 2 + 2].fY);
1238 SkCOLRCanvas(
SkRect glyphBounds,
1239 const TestSVGTypeface& typeface,
1241 TestSVGTypeface::GlyfInfo* glyf,
1245 , fBaselineOffset(glyphBounds.top())
1246 , fTypeface(typeface)
1254 fOut->writeText(
" <pt x=\"");
1256 fOut->writeText(
"\" y=\"");
1258 fOut->writeText(
"\" on=\"");
1259 fOut->write8(on ?
'1' :
'0');
1260 fOut->writeText(
"\"/>\n");
1265 path_to_quads(
path, &quads);
1270 fOut->writeText(
" <TTGlyph name=\"glyf");
1271 fOut->writeHexAsText(fGlyphId, 4);
1273 fOut->writeText(
"l");
1274 fOut->writeHexAsText(fLayerId, 4);
1276 fOut->writeText(
"\" xMin=\"");
1277 fOut->writeDecAsText(ibounds.
fLeft);
1278 fOut->writeText(
"\" yMin=\"");
1279 fOut->writeDecAsText(ibounds.
fTop);
1280 fOut->writeText(
"\" xMax=\"");
1281 fOut->writeDecAsText(ibounds.
fRight);
1282 fOut->writeText(
"\" yMax=\"");
1283 fOut->writeDecAsText(ibounds.
fBottom);
1284 fOut->writeText(
"\">\n");
1286 bool contourOpen =
false;
1291 fOut->writeText(
" </contour>\n");
1292 contourOpen =
false;
1297 fOut->writeText(
" <contour>\n");
1298 this->writePoint(pts[0].fX, pts[0].fY,
true);
1301 this->writePoint(pts[1].fX, pts[1].fY,
true);
1305 fOut->writeText(
" <contour>\n");
1306 this->writePoint(pts[0].fX, pts[0].fY,
true);
1309 this->writePoint(pts[1].fX, pts[1].fY,
false);
1310 this->writePoint(pts[2].fX, pts[2].fY,
true);
1314 fOut->writeText(
" </contour>\n");
1315 contourOpen =
false;
1322 fOut->writeText(
" </contour>\n");
1326 fOut->writeText(
" <instructions/>\n");
1327 fOut->writeText(
" </TTGlyph>\n");
1369 paint.setPathEffect(
nullptr);
1374 paint.setStrokeWidth(0);
1388 if (fTypeface.getPathOp(
color, &op)) {
1389 fBasePath.add(
path, op);
1397 constexpr SkColor currentColor = 0xFF2B0000;
1400 if (
color == currentColor) {
1401 colorIndex = 0xFFFF;
1403 int* colorIndexPtr = fColors->find(
color);
1404 if (colorIndexPtr) {
1405 colorIndex = *colorIndexPtr;
1407 colorIndex = fColors->count();
1408 fColors->set(
color, colorIndex);
1411 fGlyf->fLayers.emplace_back(colorIndex,
bounds);
1416 void finishGlyph() {
1418 fBasePath.resolve(&baseGlyph);
1419 fGlyf->fBounds = this->writePath(baseGlyph,
false);
1424 const TestSVGTypeface& fTypeface;
1426 TestSVGTypeface::GlyfInfo* fGlyf;
1435void TestSVGTypeface::exportTtxColr(
SkWStream*
out)
const {
1436 out->writeText(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
1437 out->writeText(
"<ttFont sfntVersion=\"\\x00\\x01\\x00\\x00\" ttLibVersion=\"3.19\">\n");
1445 for (
int i = 0;
i < fGlyphCount; ++
i) {
1448 SkSize containerSize = glyphData.size();
1450 -glyphData.fOrigin.fY,
1453 SkCOLRCanvas canvas(
bounds, *
this,
i, &glyfInfos.emplace_back(), &
colors, &glyfOut);
1454 glyphData.render(&canvas);
1455 canvas.finishGlyph();
1459 this->exportTtxCommon(
out,
"COLR", &glyfInfos);
1462 out->writeText(
" <loca/>\n");
1464 std::unique_ptr<SkStreamAsset> glyfStream = glyfOut.
detachAsStream();
1465 out->writeStream(glyfStream.get(), glyfStream->getLength());
1467 out->writeText(
" <COLR>\n");
1468 out->writeText(
" <version value=\"0\"/>\n");
1469 for (
int i = 0;
i < fGlyphCount; ++
i) {
1470 if (glyfInfos[
i].fLayers.empty()) {
1474 SkDebugf(
"Glyph %d is empty but has layers.\n",
i);
1476 out->writeText(
" <ColorGlyph name=\"glyf");
1477 out->writeHexAsText(
i, 4);
1478 out->writeText(
"\">\n");
1479 for (
int j = 0; j < glyfInfos[
i].fLayers.size(); ++j) {
1480 const int colorIndex = glyfInfos[
i].fLayers[j].fLayerColorIndex;
1481 out->writeText(
" <layer colorID=\"");
1482 out->writeDecAsText(colorIndex);
1483 out->writeText(
"\" name=\"glyf");
1484 out->writeHexAsText(
i, 4);
1485 out->writeText(
"l");
1486 out->writeHexAsText(j, 4);
1487 out->writeText(
"\"/>\n");
1489 out->writeText(
" </ColorGlyph>\n");
1491 out->writeText(
" </COLR>\n");
1495 colors.foreach ([&colorsInOrder](
const SkColor& c,
const int*
i) { colorsInOrder[*
i] = c; });
1496 out->writeText(
" <CPAL>\n");
1497 out->writeText(
" <version value=\"0\"/>\n");
1498 out->writeText(
" <numPaletteEntries value=\"");
1500 out->writeText(
"\"/>\n");
1501 out->writeText(
" <palette index=\"0\">\n");
1502 for (
int i = 0;
i <
colors.count(); ++
i) {
1504 out->writeText(
" <color index=\"");
1505 out->writeDecAsText(
i);
1506 out->writeText(
"\" value=\"#");
1511 out->writeText(
"\"/>\n");
1513 out->writeText(
" </palette>\n");
1514 out->writeText(
" </CPAL>\n");
1516 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)
SkDEBUGCODE(SK_SPI) SkThreadID SkGetThreadID()
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 SkArc &arc, 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)
std::unique_ptr< SkCodec > MakeFromStream(std::unique_ptr< SkStream > stream, SkCodec::SelectionPolicy selectionPolicy, SkCodec::Result *result)
SK_API bool Encode(SkWStream *dst, const SkPixmap &src, const Options &options)
Optional< SkRect > bounds
sk_sp< const SkImage > image
sk_sp< SkBlender > blender SkRect rect
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)
const CatchEntryMove ab[]
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
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.
def render(idl_node, indent_str=' ')
SK_API bool FillPathWithPaint(const SkPath &src, const SkPaint &paint, SkPath *dst, const SkRect *cullRect, SkScalar resScale=1)
static const char header[]
static SkArc Make(const SkRect &oval, SkScalar startAngleDegrees, SkScalar sweepAngleDegrees, Type type)
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()
std::shared_ptr< const fml::Mapping > data