52static inline const constexpr bool kSkShowTextBlitCoverage =
false;
53static inline const constexpr bool kSkScalerContextDumpRec =
false;
90 : fRec(PreprocessRec(*typeface, effects, *
desc))
91 , fTypeface(
std::move(typeface))
92 , fPathEffect(
sk_ref_sp(effects.fPathEffect))
93 , fMaskFilter(
sk_ref_sp(effects.fMaskFilter))
95 , fGenerateImageFromPath(fRec.fFrameWidth >= 0 || fPathEffect != nullptr)
99 if constexpr (kSkScalerContextDumpRec) {
100 SkDebugf(
"SkScalerContext checksum %x count %u length %u\n",
101 desc->getChecksum(),
desc->getCount(),
desc->getLength());
115 static SkMutex& mutex = *(
new SkMutex);
132 constexpr uint8_t contrast0 = InternalContrastFromExternal(0);
133 constexpr uint8_t gamma1 = InternalGammaFromExternal(1);
134 if (contrast0 == contrast && gamma1 == gamma) {
140 constexpr uint8_t defaultContrast = InternalContrastFromExternal(
SK_GAMMA_CONTRAST);
142 if (defaultContrast == contrast && defaultGamma == gamma) {
145 ExternalGammaFromInternal(gamma));
152 ExternalGammaFromInternal(gamma));
175 SkScalerContextRec::InternalContrastFromExternal(contrast),
176 SkScalerContextRec::InternalGammaFromExternal(deviceGamma));
179 size_t size = (*width)*(*height)*
sizeof(uint8_t);
187 SkScalerContextRec::InternalContrastFromExternal(contrast),
188 SkScalerContextRec::InternalGammaFromExternal(deviceGamma));
207 static_assert(std::is_integral_v<D>);
214 glyph->fLeft = sk_saturate_cast<int16_t>(r.fLeft);
215 glyph->fTop = sk_saturate_cast<int16_t>(r.fTop);
216 glyph->fWidth = sk_saturate_cast<uint16_t>(r.width());
217 glyph->fHeight = sk_saturate_cast<uint16_t>(r.height());
220 glyph->fLeft = sk_saturate_cast<int16_t>(r.
fLeft);
221 glyph->fTop = sk_saturate_cast<int16_t>(r.
fTop);
222 glyph->fWidth = sk_saturate_cast<uint16_t>(r.
width64());
223 glyph->fHeight = sk_saturate_cast<uint16_t>(r.
height64());
228 const bool verticalLCD,
const bool a8FromLCD,
const bool hairline)
243 const bool needExtraWidth = (fromLCD && !verticalLCD) || hairline;
244 const bool needExtraHeight = (fromLCD && verticalLCD) || hairline;
245 if (needExtraWidth) {
249 if (needExtraHeight) {
258 auto zeroBounds = [](
SkGlyph& glyph) {
266 glyph.fMaskFormat =
format;
268 SkASSERT(!mx.neverRequestPath || !mx.computeFromPath);
270 glyph.fAdvanceX = mx.advance.fX;
271 glyph.fAdvanceY = mx.advance.fY;
272 glyph.fMaskFormat = mx.maskFormat;
273 glyph.fScalerContextBits = mx.extraBits;
275 if (mx.computeFromPath || (fGenerateImageFromPath && !mx.neverRequestPath)) {
276 SkDEBUGCODE(glyph.fAdvancesBoundsFormatAndInitialPathDone =
true;)
277 this->internalGetPath(glyph, alloc);
282 const bool hairline = glyph.pathIsHairline();
287 if (mx.neverRequestPath) {
288 glyph.setPath(alloc,
nullptr,
false);
291 SkDEBUGCODE(glyph.fAdvancesBoundsFormatAndInitialPathDone =
true;)
294 if (0 == glyph.fWidth || 0 == glyph.fHeight) {
301 SkMask src(
nullptr, glyph.iRect(), glyph.rowBytes(), glyph.maskFormat());
308 if (
dst.fBounds.isEmpty()) {
314 glyph.fMaskFormat =
dst.fFormat;
334 const bool doBGR,
const bool doVert) {
335#define SAMPLES_PER_PIXEL 4
336#define LCD_PER_PIXEL 3
351 const int sample_width =
src.width();
354 uint8_t* dstImage =
dst.image();
355 size_t dstRB =
dst.fRowBytes;
379 { 0x03, 0x0b, 0x1c, 0x33, 0x40, 0x39, 0x24, 0x10, 0x05, 0x01, 0x00, 0x00, },
381 { 0x00, 0x02, 0x08, 0x16, 0x2b, 0x3d, 0x3d, 0x2b, 0x16, 0x08, 0x02, 0x00, },
383 { 0x00, 0x00, 0x01, 0x05, 0x10, 0x24, 0x39, 0x40, 0x33, 0x1c, 0x0b, 0x03, },
386 size_t dstPB = toA8 ?
sizeof(uint8_t) :
sizeof(uint16_t);
391 dstP = SkTAddOffset<uint8_t>(dstImage,
y * dstPB);
394 dstP = SkTAddOffset<uint8_t>(dstImage,
y * dstRB);
398 const uint8_t* srcP =
src.addr8(0,
y);
402 for (
int sample_x = -4; sample_x < sample_width + 4; sample_x += 4) {
404 for (
int sample_index =
std::max(0, sample_x - 4), coeff_index = sample_index - (sample_x - 4)
405 ; sample_index <
std::min(sample_x + 8, sample_width)
406 ; ++sample_index, ++coeff_index)
408 int sample_value = srcP[sample_index];
409 for (
int subpxl_index = 0; subpxl_index <
LCD_PER_PIXEL; ++subpxl_index) {
410 fir[subpxl_index] += coefficients[subpxl_index][coeff_index] * sample_value;
413 for (
int subpxl_index = 0; subpxl_index <
LCD_PER_PIXEL; ++subpxl_index) {
414 fir[subpxl_index] /= 0x100;
415 fir[subpxl_index] =
std::min(fir[subpxl_index], 255);
428 if constexpr (kSkShowTextBlitCoverage) {
436 a = maskPreBlend.
fG[
a];
441 r = maskPreBlend.
fR[r];
442 g = maskPreBlend.
fG[g];
443 b = maskPreBlend.
fB[
b];
447 dstP = SkTAddOffset<uint8_t>(dstP, dstPDelta);
459 for (
int i = 0;
i < 8; ++
i) {
469 const int octs =
width >> 3;
470 const int leftOverBits =
width & 7;
478 const size_t srcPad = srcRB -
width;
481 for (
int i = 0;
i < octs; ++
i) {
485 if (leftOverBits > 0) {
488 for (
int i = 0;
i < leftOverBits; ++
i, --shift) {
500 const bool doBGR,
const bool verticalLCD,
const bool a8FromLCD,
const bool hairline)
519 paint.setStroke(hairline);
557 if (intermediateDst) {
595 SkASSERT(origGlyph.fAdvancesBoundsFormatAndInitialPathDone);
597 const SkGlyph* unfilteredGlyph = &origGlyph;
602 SkSTArenaAlloc<
sizeof(SkGlyph::PathData)> tmpGlyphPathDataStorage;
607 fMaskFilter = std::move(mf);
610 if (tmpGlyph.fMaskFormat == origGlyph.fMaskFormat &&
613 tmpGlyph.fImage = origGlyph.fImage;
616 tmpGlyph.fImage = tmpGlyphImageStorage.
get();
618 unfilteredGlyph = &tmpGlyph;
621 if (!fGenerateImageFromPath) {
630 SkMaskBuilder mask(
static_cast<uint8_t*
>(unfilteredGlyph->fImage),
652 if (
as_MFB(fMaskFilter)->filterMask(&srcMask, unfilteredGlyph->
mask(),
m,
nullptr)) {
654 srcMaskOwnedImage.reset(srcMask.
image());
655 }
else if (unfilteredGlyph->fImage == tmpGlyphImageStorage.
get()) {
657 srcMask =
SkMaskBuilder(
static_cast<uint8_t*
>(unfilteredGlyph->fImage),
660 }
else if (origGlyph.
iRect() == unfilteredGlyph->
iRect()) {
665 srcMask =
SkMaskBuilder(
static_cast<uint8_t*
>(unfilteredGlyph->fImage),
668 size_t imageSize = unfilteredGlyph->
imageSize();
669 tmpGlyphImageStorage.
reset(imageSize);
670 srcMask.
image() =
static_cast<uint8_t*
>(tmpGlyphImageStorage.
get());
671 memcpy(srcMask.
image(), unfilteredGlyph->fImage, imageSize);
694 srcMask.
image() += leftDiff;
699 dstMask.
image() += leftDiff;
732 if (dstMask.
fBounds != origBounds) {
745 this->internalGetPath(glyph, alloc);
764 SkASSERT(glyph.fAdvancesBoundsFormatAndInitialPathDone);
772 bool hairline =
false;
800 if (!
matrix.invert(&inverse)) {
801 glyph.
setPath(alloc, &devPath, hairline);
803 path.transform(inverse, &localPath);
820 if (fPathEffect->
filterPath(&effectPath, localPath, &rec,
nullptr,
matrix)) {
821 localPath.
swap(effectPath);
825 if (rec.needToApply()) {
827 if (rec.applyToPath(&
strokePath, localPath)) {
833 if (rec.isHairlineStyle()) {
839 glyph.
setPath(alloc, &devPath, hairline);
859 m->postConcat(deviceMatrix);
876 bool skewedOrFlipped =
A.getSkewX() ||
A.getSkewY() ||
A.getScaleX() < 0 ||
A.getScaleY() < 0;
877 if (skewedOrFlipped) {
926 switch (preMatrixScale) {
940 if (intYScale == 0) {
950 if (!skewedOrFlipped && (
1020 switch (
font.getEdging()) {
1034#ifndef SK_MAX_SIZE_FOR_LCDTEXT
1035 #define SK_MAX_SIZE_FOR_LCDTEXT 48
1070 bool checkPost2x2 =
false;
1076 checkPost2x2 =
true;
1083 checkPost2x2 =
true;
1093 if (
font.isEmbolden()) {
1094#ifdef SK_USE_FREETYPE_EMBOLDEN
1124 rec->fStrokeJoin = 0;
1125 rec->fStrokeCap = 0;
1160 if (
font.isEmbeddedBitmaps()) {
1163 if (
font.isSubpixel()) {
1166 if (
font.isForceAutoHinting()) {
1169 if (
font.isLinearMetrics()) {
1172 if (
font.isBaselineSnap()) {
1175 if (typeface->glyphMaskNeedsCurrentColor()) {
1216 size_t descSize =
sizeof(rec);
1241 desc->computeChecksum();
1300 sk_bzero(metrics,
sizeof(*metrics));
1305 return std::make_unique<SkScalerContext_Empty>(std::move(typeface), effects,
desc);
static const int strokeWidth
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
sk_bzero(glyphs, sizeof(glyphs))
static constexpr T SkAlign8(T x)
#define SkASSERT_RELEASE(cond)
SkBlitter * SkA8Blitter_Choose(const SkPixmap &dst, const SkMatrix &ctm, const SkPaint &paint, SkArenaAlloc *alloc, bool drawCoverage, sk_sp< SkShader > clipShader, const SkSurfaceProps &)
static U8CPU SkComputeLuminance(U8CPU r, U8CPU g, U8CPU b)
static U16CPU SkPack888ToRGB16(U8CPU r, U8CPU g, U8CPU b)
@ kAlpha_8_SkColorType
pixel with alpha in 8-bit byte
#define SkColorGetR(color)
#define SkColorGetG(color)
#define SkColorSetRGB(r, g, b)
#define SkColorGetB(color)
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
#define SkFixedToScalar(x)
SkMaskFilterBase * as_MFB(SkMaskFilter *mf)
std::unique_ptr< uint8_t, SkFunctionObject< SkMaskBuilder::FreeImage > > SkAutoMaskFreeImage
void SkComputeGivensRotation(const SkVector &h, SkMatrix *G)
static SkPath clip(const SkPath &path, const SkHalfPlane &plane)
static void SkSafeUnref(T *obj)
sk_sp< T > sk_ref_sp(T *obj)
#define SkScalarInvert(x)
#define SK_ScalarNearlyZero
#define SkScalarRoundToScalar(x)
SkScalar SkScalarInterpFunc(SkScalar searchKey, const SkScalar keys[], const SkScalar values[], int length)
static int convert_8_to_1(unsigned byte)
static SkScalar sk_relax(SkScalar x)
static void generate_descriptor(const SkScalerContextRec &rec, const SkBinaryWriteBuffer &effectBuffer, SkDescriptor *desc)
static constexpr D sk_saturate_cast(S s)
#define SK_MAX_SIZE_FOR_LCDTEXT
static void applyLUTToA8Mask(SkMaskBuilder &mask, const uint8_t *lut)
static void pack4xHToMask(const SkPixmap &src, SkMaskBuilder &dst, const SkMaskGamma::PreBlend &maskPreBlend, const bool doBGR, const bool doVert)
static bool too_big_for_lcd(const SkScalerContextRec &rec, bool checkPost2x2)
static SkMaskGamma * gDefaultMaskGamma
const SkScalar gMaxSize2ForLCDText
static SkMutex & mask_gamma_cache_mutex()
static SkMask::Format compute_mask_format(const SkFont &font)
static size_t calculate_size_and_flatten(const SkScalerContextRec &rec, const SkScalerContextEffects &effects, SkBinaryWriteBuffer *effectBuffer)
static SkMaskGamma * gLinearMaskGamma
static uint8_t pack_8_to_1(const uint8_t alpha[8])
static void packA8ToA1(SkMaskBuilder &dstMask, const uint8_t *src, size_t srcRB)
#define SAMPLES_PER_PIXEL
static SkMaskGamma * gMaskGamma
SkTMaskGamma< 3, 3, 3 > SkMaskGamma
#define kRec_SkDescriptorTag
#define kEffects_SkDescriptorTag
@ kUnknown_SkPixelGeometry
static const SkScalar kStdFakeBoldInterpValues[]
static const int kStdFakeBoldInterpLength
static const SkScalar kStdFakeBoldInterpKeys[]
SkDEBUGCODE(SK_SPI) SkThreadID SkGetThreadID()
constexpr uint16_t SkToU16(S x)
static constexpr bool SkToBool(const T &x)
constexpr uint8_t SkToU8(S x)
#define SK_GAMMA_CONTRAST
#define SK_GAMMA_EXPONENT
static void draw(SkCanvas *canvas, SkRect &target, int x, int y)
SkDescriptor * getDesc() const
void * reset(size_t size=0, OnShrink shrink=kAlloc_OnShrink)
void writeFlattenable(const SkFlattenable *flattenable) override
size_t bytesWritten() const
void writeToMemory(void *dst) const
static std::unique_ptr< SkDescriptor > Alloc(size_t length)
static size_t ComputeOverhead(int entryCount)
static SkMatrix MakeTextMatrix(SkScalar size, SkScalar scaleX, SkScalar skewX)
@ kAntiAlias
may have transparent pixels on glyph edges
@ kAlias
no transparent pixels on glyph edges
@ kSubpixelAntiAlias
glyph positioned in pixel using transparency
bool setPathHasBeenCalled() const
const SkPath * path() const
SkMask::Format maskFormat() const
bool setPath(SkArenaAlloc *alloc, SkScalerContext *scalerContext)
bool pathIsHairline() const
SkPackedGlyphID getPackedID() const
static constexpr int kMScaleX
horizontal scale factor
static constexpr int kMTransY
vertical translation
SkScalar getSkewY() const
static constexpr int kMPersp1
input y perspective factor
SkMatrix & setAll(SkScalar scaleX, SkScalar skewX, SkScalar transX, SkScalar skewY, SkScalar scaleY, SkScalar transY, SkScalar persp0, SkScalar persp1, SkScalar persp2)
SkMatrix & setScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
SkScalar getSkewX() const
SkScalar getScaleX() const
SkMatrix & preConcat(const SkMatrix &other)
static constexpr int kMPersp0
input x perspective factor
SkScalar getScaleY() const
static constexpr int kMPersp2
perspective bias
static constexpr int kMTransX
horizontal translation
bool hasPerspective() const
static constexpr int kMSkewY
vertical skew factor
SkScalar get(int index) const
static constexpr int kMScaleY
vertical scale factor
static constexpr int kMSkewX
horizontal skew factor
SkMatrix & preScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
SkMatrix & setScaleX(SkScalar v)
@ kScale_Mask
scale SkMatrix
@ kAffine_Mask
skew or rotate SkMatrix
static SkColor ComputeLuminanceColor(const SkPaint &)
@ kButt_Cap
no stroke extension
@ kFill_Style
set to fill geometry
@ kStrokeAndFill_Style
sets to stroke and fill geometry
bool filterPath(SkPath *dst, const SkPath &src, SkStrokeRec *, const SkRect *cullR) const
const SkRect & getBounds() const
void transform(const SkMatrix &matrix, SkPath *dst, SkApplyPerspectiveClip pc=SkApplyPerspectiveClip::kYes) const
virtual void generateFontMetrics(SkFontMetrics *)=0
SkScalerContext(sk_sp< SkTypeface >, const SkScalerContextEffects &, const SkDescriptor *)
@ kEmbeddedBitmapText_Flag
@ kNeedsForegroundColor_Flag
@ kSubpixelPositioning_Flag
virtual void generateImage(const SkGlyph &glyph, void *imageBuffer)=0
static void GenerateImageFromPath(SkMaskBuilder &dst, const SkPath &path, const SkMaskGamma::PreBlend &maskPreBlend, bool doBGR, bool verticalLCD, bool a8FromLCD, bool hairline)
static void MakeRecAndEffects(const SkFont &font, const SkPaint &paint, const SkSurfaceProps &surfaceProps, SkScalerContextFlags scalerContextFlags, const SkMatrix &deviceMatrix, SkScalerContextRec *rec, SkScalerContextEffects *effects)
static std::unique_ptr< SkDescriptor > DescriptorGivenRecAndEffects(const SkScalerContextRec &rec, const SkScalerContextEffects &effects)
virtual GlyphMetrics generateMetrics(const SkGlyph &, SkArenaAlloc *)=0
virtual bool generatePath(const SkGlyph &, SkPath *)=0
void getPath(SkGlyph &, SkArenaAlloc *)
const SkMaskGamma::PreBlend fPreBlend
static SkMaskGamma::PreBlend GetMaskPreBlend(const SkScalerContextRec &rec)
static SkDescriptor * CreateDescriptorAndEffectsUsingPaint(const SkFont &, const SkPaint &, const SkSurfaceProps &, SkScalerContextFlags scalerContextFlags, const SkMatrix &deviceMatrix, SkAutoDescriptor *ad, SkScalerContextEffects *effects)
virtual sk_sp< SkDrawable > generateDrawable(const SkGlyph &)
static SkDescriptor * AutoDescriptorGivenRecAndEffects(const SkScalerContextRec &rec, const SkScalerContextEffects &effects, SkAutoDescriptor *ad)
static void GenerateMetricsFromPath(SkGlyph *glyph, const SkPath &path, SkMask::Format format, bool verticalLCD, bool a8FromLCD, bool hairline)
static bool CheckBufferSizeForRec(const SkScalerContextRec &rec, const SkScalerContextEffects &effects, size_t size)
static size_t GetGammaLUTSize(SkScalar contrast, SkScalar deviceGamma, int *width, int *height)
SkAxisAlignment computeAxisAlignmentForHText() const
sk_sp< SkDrawable > getDrawable(SkGlyph &)
static std::unique_ptr< SkScalerContext > MakeEmpty(sk_sp< SkTypeface > typeface, const SkScalerContextEffects &effects, const SkDescriptor *desc)
SkGlyph makeGlyph(SkPackedGlyphID, SkArenaAlloc *)
static void DescriptorBufferGiveRec(const SkScalerContextRec &rec, void *buffer)
virtual ~SkScalerContext()
void getFontMetrics(SkFontMetrics *)
static bool GetGammaLUTData(SkScalar contrast, SkScalar deviceGamma, uint8_t *data)
void getImage(const SkGlyph &)
static void SaturateGlyphBounds(SkGlyph *glyph, SkRect &&)
const char * c_str() const
void setStrokeStyle(SkScalar width, bool strokeAndFill=false)
bool applyToPath(SkPath *dst, const SkPath &src) const
void setStrokeParams(SkPaint::Cap cap, SkPaint::Join join, SkScalar miterLimit)
SkScalar textGamma() const
SkPixelGeometry pixelGeometry() const
SkScalar textContrast() const
void getGammaTableDimensions(int *tableWidth, int *numTables) const
PreBlend preBlend(SkColor color) const
static SkColor CanonicalColor(SkColor color)
const uint8_t * getGammaTables() const
bool isApplicable() const
SkTypefaceID uniqueID() const
virtual void onFilterRec(SkScalerContextRec *) const =0
FlutterSemanticsFlag flags
uint32_t uint32_t * format
static void strokePath(SkCanvas *canvas, const SkPath &path)
static float max(float r, float g, float b)
static float lum(float r, float g, float b)
static float min(float r, float g, float b)
unsigned useCenter Optional< SkMatrix > matrix
Optional< SkRect > bounds
skia_private::AutoTArray< sk_sp< SkImageFilter > > filters TypedMatrix matrix TypedMatrix matrix SkScalar dx
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 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 to the cache directory This is different from the persistent_cache_path in embedder which is used for Skia shader cache icu native lib Path to the library file that exports the ICU data vm service The hostname IP address on which the Dart VM Service should be served If not defaults to or::depending on whether ipv6 is specified vm service A custom Dart VM Service port The default is to pick a randomly available open port disable vm Disable the Dart VM Service The Dart VM Service is never available in release mode disable vm service Disable mDNS Dart VM Service publication Bind to the IPv6 localhost address for the Dart VM Service Ignored if vm service host is set endless trace buffer
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.
constexpr int64_t height64() const
int32_t fBottom
larger y-axis bounds
constexpr int32_t height() const
int32_t fTop
smaller y-axis bounds
constexpr int32_t width() const
constexpr int64_t width64() const
static constexpr SkIRect MakeWH(int32_t w, int32_t h)
int32_t fLeft
smaller x-axis bounds
int32_t fRight
larger x-axis bounds
static SkImageInfo MakeA8(int width, int height)
@ k3D_Format
3 8bit per pixl planes: alpha, mul, add
@ kA8_Format
8bits per pixel mask (e.g. antialiasing)
@ kLCD16_Format
565 alpha for r/g/b
@ kARGB32_Format
SkPMColor.
@ kBW_Format
1bit per pixel mask (e.g. monochrome)
uint8_t const *const fImage
size_t computeImageSize() const
SkFixed getSubXFixed() const
SkFixed getSubYFixed() const
static constexpr SkPoint Make(float x, float y)
SkPathEffect * fPathEffect
SkMaskFilter * fMaskFilter
void getSingleMatrix(SkMatrix *) const
uint32_t fForegroundColor
void getLocalMatrix(SkMatrix *) const
void setDeviceGamma(SkScalar g)
static const SkMaskGamma & CachedMaskGamma(uint8_t contrast, uint8_t gamma)
SkAxisAlignment computeAxisAlignmentForHText() const
SkMask::Format fMaskFormat
void setContrast(SkScalar c)
void getMatrixFrom2x2(SkMatrix *) const
bool computeMatrices(PreMatrixScale preMatrixScale, SkVector *scale, SkMatrix *remaining, SkMatrix *remainingWithoutRotation=nullptr, SkMatrix *remainingRotation=nullptr, SkMatrix *total=nullptr)
const SkMaskGamma & cachedMaskGamma() const
SkColor getLuminanceColor() const
void setHinting(SkFontHinting)
void setLuminanceColor(SkColor c)
std::shared_ptr< const fml::Mapping > data