49#include <freetype/ftadvanc.h>
50#include <freetype/ftimage.h>
51#include <freetype/ftbitmap.h>
53# include <freetype/ftcolor.h>
55#include <freetype/freetype.h>
56#include <freetype/ftlcdfil.h>
57#include <freetype/ftmodapi.h>
58#include <freetype/ftmm.h>
59#include <freetype/ftoutln.h>
60#include <freetype/ftsizes.h>
61#include <freetype/ftsystem.h>
62#include <freetype/tttables.h>
63#include <freetype/t1tables.h>
64#include <freetype/ftfntfmt.h>
69[[maybe_unused]]
static inline const constexpr bool kSkShowTextBlitCoverage =
false;
71using SkUniqueFTFace = std::unique_ptr<FT_FaceRec, SkFunctionObject<FT_Done_Face>>;
72using SkUniqueFTSize = std::unique_ptr<FT_SizeRec, SkFunctionObject<FT_Done_Size>>;
77#define SK_FREETYPE_DLOPEN (0x1)
78#ifndef SK_FREETYPE_MINIMUM_RUNTIME_VERSION
79# if defined(SK_BUILD_FOR_ANDROID_FRAMEWORK) || \
80 defined(SK_BUILD_FOR_GOOGLE3) || \
81 defined(SK_FREETYPE_MINIMUM_RUNTIME_VERSION_IS_BUILD_VERSION)
82# define SK_FREETYPE_MINIMUM_RUNTIME_VERSION (((FREETYPE_MAJOR) << 24) | ((FREETYPE_MINOR) << 16) | ((FREETYPE_PATCH) << 8))
84# define SK_FREETYPE_MINIMUM_RUNTIME_VERSION ((2 << 24) | (8 << 16) | (1 << 8) | (SK_FREETYPE_DLOPEN))
87#if SK_FREETYPE_MINIMUM_RUNTIME_VERSION & SK_FREETYPE_DLOPEN
91#ifdef TT_SUPPORT_COLRV1
98#if (((FREETYPE_MAJOR) < 2) || \
99 ((FREETYPE_MAJOR) == 2 && (FREETYPE_MINOR) < 11) || \
100 ((FREETYPE_MAJOR) == 2 && (FREETYPE_MINOR) == 11 && (FREETYPE_PATCH) < 1)) && \
101 !defined(FT_STATIC_CAST)
102# undef TT_SUPPORT_COLRV1
112 #define LOG_INFO(...)
114 #define LOG_INFO SkDEBUGF
148 if (FT_New_Library(&
gFTMemory, &fLibrary)) {
151 FT_Add_Default_Modules(fLibrary);
152 FT_Set_Default_Properties(fLibrary);
157 FT_Library_SetLcdFilter(fLibrary, FT_LCD_FILTER_DEFAULT);
161 FT_Done_Library(fLibrary);
194 static SkMutex& mutex = *(
new SkMutex);
222 static bool ref_ft_library() {
235 static void unref_ft_library() {
247int SkTypeface_FreeType::FaceRec::gFTCount;
269SkTypeface_FreeType::FaceRec::FaceRec(std::unique_ptr<SkStreamAsset>
stream)
272 sk_bzero(&fFTStream,
sizeof(fFTStream));
273 fFTStream.size = fSkStream->getLength();
274 fFTStream.descriptor.pointer = fSkStream.get();
288void SkTypeface_FreeType::FaceRec::setupAxes(
const SkFontData&
data) {
289 if (!(fFace->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS)) {
294 if (
data.getIndex() > 0xFFFF) {
299 FT_MM_Var* variations =
nullptr;
300 if (FT_Get_MM_Var(fFace.get(), &variations)) {
301 LOG_INFO(
"INFO: font %s claims variations, but none found.\n",
302 rec->fFace->family_name);
307 if (
static_cast<FT_UInt
>(
data.getAxisCount()) != variations->num_axis) {
308 LOG_INFO(
"INFO: font %s has %d variations, but %d were specified.\n",
309 rec->fFace->family_name, variations->num_axis, data.getAxisCount());
315 for (
int i = 0;
i <
data.getAxisCount(); ++
i) {
316 coords[
i] =
data.getAxis()[
i];
318 if (FT_Set_Var_Design_Coordinates(fFace.get(),
data.getAxisCount(), coords.get())) {
319 LOG_INFO(
"INFO: font %s has variations, but specified variations could not be set.\n",
320 rec->fFace->family_name);
325void SkTypeface_FreeType::FaceRec::setupPalette(
const SkFontData&
data) {
327 FT_Palette_Data paletteData;
328 if (FT_Palette_Data_Get(fFace.get(), &paletteData)) {
334 FT_UShort basePaletteIndex = 0;
335 if (SkTFitsIn<FT_UShort>(
data.getPaletteIndex()) &&
336 SkTo<FT_UShort>(
data.getPaletteIndex()) < paletteData.num_palettes)
338 basePaletteIndex =
data.getPaletteIndex();
341 FT_Color* ftPalette =
nullptr;
342 if (FT_Palette_Select(fFace.get(), basePaletteIndex, &ftPalette)) {
345 fFTPaletteEntryCount = paletteData.num_palette_entries;
347 for (
int i = 0;
i <
data.getPaletteOverrideCount(); ++
i) {
349 if (paletteOverride.
index < fFTPaletteEntryCount) {
351 FT_Color& ftColor = ftPalette[paletteOverride.
index];
359 fSkPalette.reset(
new SkColor[fFTPaletteEntryCount]);
360 for (
int i = 0;
i < fFTPaletteEntryCount; ++
i) {
371std::unique_ptr<SkTypeface_FreeType::FaceRec>
376 if (
nullptr ==
data || !
data->hasStream()) {
380 std::unique_ptr<FaceRec> rec(
new FaceRec(
data->detachStream()));
384 const void* memoryBase = rec->fSkStream->getMemoryBase();
386 args.flags = FT_OPEN_MEMORY;
387 args.memory_base = (
const FT_Byte*)memoryBase;
388 args.memory_size = rec->fSkStream->getLength();
390 args.flags = FT_OPEN_STREAM;
391 args.stream = &rec->fFTStream;
401 rec->fFace.reset(rawFace);
405 rec->setupAxes(*
data);
406 rec->setupPalette(*
data);
414 if (!rec->fFace->charmap) {
415 FT_Select_Charmap(rec->fFace.get(), FT_ENCODING_MS_SYMBOL);
432 FT_Face face() {
return fFaceRec ? fFaceRec->fFace.get() :
nullptr; }
448 return fFTSize !=
nullptr && fFace !=
nullptr;
453 void generateImage(
const SkGlyph&,
void*)
override;
459 struct ScalerContextBits {
460 static const constexpr uint32_t COLRv0 = 1;
461 static const constexpr uint32_t COLRv1 = 2;
462 static const constexpr uint32_t SVG = 3;
467 static const FT_Pos kBitmapEmboldenStrength = 1 << 6;
486 uint32_t fLoadGlyphFlags;
487 bool fDoLinearMetrics;
490 FT_Error setupSize();
492 static bool getBoundsOfCurrentOutlineGlyph(FT_GlyphSlot glyph,
SkRect*
bounds);
494 bool getCBoxForLetter(
char letter,
FT_BBox* bbox);
496 void updateGlyphBoundsIfLCD(GlyphMetrics* mx);
506 FT_UShort fsType = FT_Get_FSType_Flags(face);
507 return (fsType & (FT_FSTYPE_RESTRICTED_LICENSE_EMBEDDING |
508 FT_FSTYPE_BITMAP_EMBEDDING_ONLY)) == 0;
512 FT_UShort fsType = FT_Get_FSType_Flags(face);
513 return (fsType & FT_FSTYPE_NO_SUBSETTING) == 0;
517 const char* fontType = FT_Get_X11_Font_Format(face);
524 for(
const auto& v :
values) {
if (strcmp(fontType, v.s) == 0) {
return v.t; } }
557 info->fPostScriptName.set(FT_Get_Postscript_Name(face));
559 if (FT_HAS_MULTIPLE_MASTERS(face)) {
578 if (FT_IS_FIXED_WIDTH(face)) {
581 if (face->style_flags & FT_STYLE_FLAG_ITALIC) {
585 PS_FontInfoRec psFontInfo;
586 TT_Postscript* postTable;
587 if (FT_Get_PS_Font_Info(face, &psFontInfo) == 0) {
588 info->fItalicAngle = psFontInfo.italic_angle;
589 }
else if ((postTable = (TT_Postscript*)FT_Get_Sfnt_Table(face, ft_sfnt_post)) !=
nullptr) {
592 info->fItalicAngle = 0;
595 info->fAscent = face->ascender;
596 info->fDescent = face->descender;
600 if ((pcltTable = (TT_PCLT*)FT_Get_Sfnt_Table(face, ft_sfnt_pclt)) !=
nullptr) {
601 info->fCapHeight = pcltTable->CapHeight;
602 uint8_t serif_style = pcltTable->SerifStyle & 0x3F;
603 if (2 <= serif_style && serif_style <= 6) {
605 }
else if (9 <= serif_style && serif_style <= 12) {
608 }
else if (((os2Table = (TT_OS2*)FT_Get_Sfnt_Table(face, ft_sfnt_os2)) !=
nullptr) &&
610 os2Table->version != 0xFFFF &&
611 os2Table->version >= 2)
613 info->fCapHeight = os2Table->sCapHeight;
616 face->bbox.xMax, face->bbox.yMin);
627 FT_Long numGlyphs = face->num_glyphs;
628 if (!dstArray) {
SkASSERT(numGlyphs == 0); }
632 SkUnichar charCode = FT_Get_First_Char(face, &glyphIndex);
636 if (0 == dstArray[glyphIndex]) {
637 dstArray[glyphIndex] = charCode;
639 charCode = FT_Get_Next_Char(face, charCode, &glyphIndex);
650 FT_Long numGlyphs = face->num_glyphs;
651 if (!dstArray) {
SkASSERT(numGlyphs == 0); }
653 if (FT_HAS_GLYPH_NAMES(face)) {
654 for (
int gID = 0; gID < numGlyphs; ++gID) {
656 FT_Get_Glyph_Name(face, gID, glyphName, 128);
657 dstArray[gID] = glyphName;
669 const char* ftPostScriptName = FT_Get_Postscript_Name(face);
670 if (!ftPostScriptName) {
673 if (skPostScriptName) {
674 *skPostScriptName = ftPostScriptName;
682 return 0 ==
a && 0 ==
b;
695 auto c = std::make_unique<SkScalerContext_FreeType>(
723 if (!(face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS)) {
727 FT_MM_Var* variations =
nullptr;
728 if (FT_Get_MM_Var(face, &variations)) {
733 if (!coordinates || coordinateCount <
SkToInt(variations->num_axis)) {
734 return variations->num_axis;
738 if (FT_Get_Var_Design_Coordinates(face, variations->num_axis, coords.
get())) {
741 for (FT_UInt
i = 0;
i < variations->num_axis; ++
i) {
742 coordinates[
i].
axis = variations->axis[
i].tag;
746 return variations->num_axis;
761 int axisCount = axisDefinitions.
size();
770 args.getVariationDesignPosition(),
773 currentAxisCount == axisCount ? currentPosition.
get() :
nullptr);
778 return std::make_unique<SkFontData>(std::move(
stream),
780 args.getPalette().index,
783 args.getPalette().overrides,
784 args.getPalette().overrideCount);
809#ifndef SK_GAMMA_APPLY_TO_A8
823 TT_Header* ttHeader = (TT_Header*)FT_Get_Sfnt_Table(face, ft_sfnt_head);
841 int count, int32_t adjustments[])
const {
844 if (!face || !FT_HAS_KERNING(face)) {
848 for (
int i = 0;
i <
count - 1; ++
i) {
851 FT_KERNING_UNSCALED, &
delta);
862 if (face ==
nullptr) {
863 LOG_INFO(
"chooseBitmapStrike aborted due to nullptr face.\n");
867 FT_Pos requestedPPEM = scaleY;
868 FT_Int chosenStrikeIndex = -1;
870 for (FT_Int strikeIndex = 0; strikeIndex < face->num_fixed_sizes; ++strikeIndex) {
871 FT_Pos strikePPEM = face->available_sizes[strikeIndex].y_ppem;
872 if (strikePPEM == requestedPPEM) {
875 }
else if (chosenPPEM < requestedPPEM) {
877 if (chosenPPEM < strikePPEM) {
878 chosenPPEM = strikePPEM;
879 chosenStrikeIndex = strikeIndex;
883 if (requestedPPEM < strikePPEM && strikePPEM < chosenPPEM) {
884 chosenPPEM = strikePPEM;
885 chosenStrikeIndex = strikeIndex;
889 return chosenStrikeIndex;
904 if (
nullptr == fFaceRec) {
905 LOG_INFO(
"Could not create FT_Face.\n");
914 FT_Int32 loadFlags = FT_LOAD_DEFAULT;
918 loadFlags = FT_LOAD_TARGET_MONO;
920 loadFlags |= FT_LOAD_NO_HINTING;
921 linearMetrics =
true;
926 loadFlags = FT_LOAD_NO_HINTING;
927 linearMetrics =
true;
930 loadFlags = FT_LOAD_TARGET_LIGHT;
931 linearMetrics =
true;
934 loadFlags = FT_LOAD_TARGET_NORMAL;
937 loadFlags = FT_LOAD_TARGET_NORMAL;
940 loadFlags = FT_LOAD_TARGET_LCD_V;
942 loadFlags = FT_LOAD_TARGET_LCD;
953 loadFlags |= FT_LOAD_FORCE_AUTOHINT;
954#ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
956 loadFlags |= FT_LOAD_NO_AUTOHINT;
961 loadFlags |= FT_LOAD_NO_BITMAP;
967 loadFlags |= FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH;
971 loadFlags |= FT_LOAD_VERTICAL_LAYOUT;
974 fLoadGlyphFlags = loadFlags;
977 SkUniqueFTSize ftSize([
this]() -> FT_Size {
979 FT_Error err = FT_New_Size(fFaceRec->
fFace.get(), &
size);
986 if (
nullptr == ftSize) {
987 LOG_INFO(
"Could not create FT_Size.\n");
991 FT_Error err = FT_Activate_Size(ftSize.get());
993 SK_TRACEFTR(err,
"FT_Activate_Size(%s) failed.", fFaceRec->
fFace->family_name);
1001 if (FT_IS_SCALABLE(fFaceRec->
fFace)) {
1002 err = FT_Set_Char_Size(fFaceRec->
fFace.get(), scaleX, scaleY, 72, 72);
1004 SK_TRACEFTR(err,
"FT_Set_CharSize(%s, %f, %f) failed.",
1005 fFaceRec->
fFace->family_name, fScale.
fX, fScale.
fY);
1012 if (fScale.
fX < 1 || fScale.
fY < 1) {
1014 FT_Size_Metrics& ftmetrics = fFaceRec->
fFace->size->metrics;
1017 fMatrix22Scalar.
preScale(fScale.
x() / x_ppem, fScale.
y() / y_ppem);
1022#if defined(FT_CONFIG_OPTION_SVG)
1027 }
else if (FT_HAS_FIXED_SIZES(fFaceRec->
fFace)) {
1029 if (fStrikeIndex == -1) {
1030 LOG_INFO(
"No glyphs for font \"%s\" size %f.\n",
1031 fFaceRec->
fFace->family_name, fScale.
fY);
1035 err = FT_Select_Size(fFaceRec->
fFace.get(), fStrikeIndex);
1037 SK_TRACEFTR(err,
"FT_Select_Size(%s, %d) failed.",
1038 fFaceRec->
fFace->family_name, fStrikeIndex);
1045 fMatrix22Scalar.
preScale(fScale.
x() / fFaceRec->
fFace->size->metrics.x_ppem,
1046 fScale.
y() / fFaceRec->
fFace->size->metrics.y_ppem);
1049 linearMetrics =
false;
1057 fLoadGlyphFlags &= ~FT_LOAD_NO_BITMAP;
1062 LOG_INFO(
"Unknown kind of font \"%s\" size %f.\n", fFaceRec->
fFace->family_name, fScale.
fY);
1071 fFTSize = ftSize.release();
1072 fFace = fFaceRec->
fFace.get();
1073 fDoLinearMetrics = linearMetrics;
1080 if (fFTSize !=
nullptr) {
1081 FT_Done_Size(fFTSize);
1090FT_Error SkScalerContext_FreeType::setupSize() {
1092 FT_Error err = FT_Activate_Size(fFTSize);
1096 FT_Set_Transform(fFace, &fMatrix22,
nullptr);
1100bool SkScalerContext_FreeType::getBoundsOfCurrentOutlineGlyph(FT_GlyphSlot glyph,
SkRect*
bounds) {
1101 if (glyph->format != FT_GLYPH_FORMAT_OUTLINE) {
1105 if (0 == glyph->outline.n_contours) {
1110 FT_Outline_Get_CBox(&glyph->outline, &bbox);
1116bool SkScalerContext_FreeType::getCBoxForLetter(
char letter,
FT_BBox* bbox) {
1117 const FT_UInt glyph_id = FT_Get_Char_Index(fFace, letter);
1121 if (FT_Load_Glyph(fFace, glyph_id, fLoadGlyphFlags)) {
1124 if (fFace->glyph->format != FT_GLYPH_FORMAT_OUTLINE) {
1127 emboldenIfNeeded(fFace, fFace->glyph, SkTo<SkGlyphID>(glyph_id));
1128 FT_Outline_Get_CBox(&fFace->glyph->outline, bbox);
1132void SkScalerContext_FreeType::updateGlyphBoundsIfSubpixel(
const SkGlyph& glyph,
SkRect*
bounds,
1134 if (subpixel && !
bounds->isEmpty()) {
1140void SkScalerContext_FreeType::updateGlyphBoundsIfLCD(GlyphMetrics* mx) {
1142 mx->bounds.roundOut(&mx->bounds);
1144 mx->bounds.fBottom += 1;
1145 mx->bounds.fTop -= 1;
1147 mx->bounds.fRight += 1;
1148 mx->bounds.fLeft -= 1;
1155 bool mechanism = fFace->glyph->format == FT_GLYPH_FORMAT_BITMAP &&
1164 bool policy = !FT_IS_SCALABLE(fFace) || !
matrix.isIdentity();
1166 return mechanism &&
policy;
1175 if (this->setupSize()) {
1179 FT_Bool haveLayers =
false;
1182 if (FT_IS_SCALABLE(fFace)) {
1184#ifdef TT_SUPPORT_COLRV1
1185 FT_OpaquePaint opaqueLayerPaint{
nullptr, 1};
1186 if (FT_Get_Color_Glyph_Paint(fFace, glyph.
getGlyphID(),
1187 FT_COLOR_INCLUDE_ROOT_TRANSFORM, &opaqueLayerPaint)) {
1189 mx.
extraBits = ScalerContextBits::COLRv1;
1193 if (FT_Get_Color_Glyph_ClipBox(fFace, glyph.
getGlyphID(), &clipBox)) {
1196 bbox.xMin = clipBox.bottom_left.x;
1197 bbox.xMax = clipBox.bottom_left.x;
1198 bbox.yMin = clipBox.bottom_left.y;
1199 bbox.yMax = clipBox.bottom_left.y;
1200 for (
auto& corner : {clipBox.top_left, clipBox.top_right, clipBox.bottom_right}) {
1201 bbox.xMin =
std::min(bbox.xMin, corner.x);
1202 bbox.yMin =
std::min(bbox.yMin, corner.y);
1203 bbox.xMax =
std::max(bbox.xMax, corner.x);
1204 bbox.yMax =
std::max(bbox.yMax, corner.y);
1224 FT_LayerIterator layerIterator = { 0, 0,
nullptr };
1225 FT_UInt layerGlyphIndex;
1226 FT_UInt layerColorIndex;
1227 FT_Int32
flags = fLoadGlyphFlags;
1228 flags |= FT_LOAD_BITMAP_METRICS_ONLY;
1229 flags |= FT_LOAD_NO_BITMAP;
1230 flags &= ~FT_LOAD_RENDER;
1231 flags &= ~FT_LOAD_COLOR;
1233 while (FT_Get_Color_Glyph_Layer(fFace, glyph.
getGlyphID(), &layerGlyphIndex,
1234 &layerColorIndex, &layerIterator)) {
1236 if (FT_Load_Glyph(fFace, layerGlyphIndex,
flags)) {
1241 if (getBoundsOfCurrentOutlineGlyph(fFace->glyph, ¤tBounds)) {
1242 bounds.join(currentBounds);
1246 mx.
extraBits = ScalerContextBits::COLRv0;
1260 if (FT_Load_Glyph(fFace, glyph.
getGlyphID(), fLoadGlyphFlags | FT_LOAD_BITMAP_METRICS_ONLY)) {
1265 emboldenIfNeeded(fFace, fFace->glyph, glyph.
getGlyphID());
1267 if (fFace->glyph->format == FT_GLYPH_FORMAT_OUTLINE) {
1268 getBoundsOfCurrentOutlineGlyph(fFace->glyph, &mx.
bounds);
1269 updateGlyphBoundsIfSubpixel(glyph, &mx.
bounds, this->isSubpixel());
1270 updateGlyphBoundsIfLCD(&mx);
1272 }
else if (fFace->glyph->format == FT_GLYPH_FORMAT_BITMAP) {
1277 vector.x = fFace->glyph->metrics.vertBearingX - fFace->glyph->metrics.horiBearingX;
1278 vector.y = -fFace->glyph->metrics.vertBearingY - fFace->glyph->metrics.horiBearingY;
1279 FT_Vector_Transform(&vector, &fMatrix22);
1293 updateGlyphBoundsIfSubpixel(glyph, &mx.
bounds,
1294 this->shouldSubpixelBitmap(glyph, fMatrix22Scalar));
1296#if defined(FT_CONFIG_OPTION_SVG)
1297 }
else if (fFace->glyph->format == FT_GLYPH_FORMAT_SVG) {
1308 if (!fUtils.
drawSVGGlyph(fFace, glyph, fLoadGlyphFlags, palette, recordingCanvas)) {
1324 if (fDoLinearMetrics) {
1333 if (fDoLinearMetrics) {
1343#ifdef ENABLE_GLYPH_SPEW
1352 if (this->setupSize()) {
1357 if (glyph.
extraBits() == ScalerContextBits::COLRv0 ||
1358 glyph.
extraBits() == ScalerContextBits::COLRv1 ||
1359 glyph.
extraBits() == ScalerContextBits::SVG )
1371 if constexpr (kSkShowTextBlitCoverage) {
1372 canvas.
clear(0x33FF0000);
1379 if (glyph.
extraBits() == ScalerContextBits::COLRv0) {
1381 fUtils.
drawCOLRv0Glyph(fFace, glyph, fLoadGlyphFlags, palette, &canvas);
1383 }
else if (glyph.
extraBits() == ScalerContextBits::COLRv1) {
1384#ifdef TT_SUPPORT_COLRV1
1385 fUtils.
drawCOLRv1Glyph(fFace, glyph, fLoadGlyphFlags, palette, &canvas);
1387 }
else if (glyph.
extraBits() == ScalerContextBits::SVG) {
1388#if defined(FT_CONFIG_OPTION_SVG)
1389 if (FT_Load_Glyph(fFace, glyph.
getGlyphID(), fLoadGlyphFlags)) {
1392 fUtils.
drawSVGGlyph(fFace, glyph, fLoadGlyphFlags, palette, &canvas);
1398 if (FT_Load_Glyph(fFace, glyph.
getGlyphID(), fLoadGlyphFlags)) {
1402 emboldenIfNeeded(fFace, fFace->glyph, glyph.
getGlyphID());
1404 SkMatrix* bitmapMatrix = &fMatrix22Scalar;
1406 if (this->shouldSubpixelBitmap(glyph, *bitmapMatrix)) {
1407 subpixelBitmapMatrix = fMatrix22Scalar;
1410 bitmapMatrix = &subpixelBitmapMatrix;
1425 if (this->setupSize()) {
1429#if defined(FT_COLOR_H) || defined(TT_SUPPORT_COLRV1) || defined(FT_CONFIG_OPTION_SVG)
1430 if (glyph.
extraBits() == ScalerContextBits::COLRv0 ||
1431 glyph.
extraBits() == ScalerContextBits::COLRv1 ||
1432 glyph.
extraBits() == ScalerContextBits::SVG )
1437 if (glyph.
extraBits() == ScalerContextBits::COLRv0) {
1439 if (!fUtils.
drawCOLRv0Glyph(fFace, glyph, fLoadGlyphFlags, palette, recordingCanvas)) {
1445 }
else if (glyph.
extraBits() == ScalerContextBits::COLRv1) {
1446#ifdef TT_SUPPORT_COLRV1
1447 if (!fUtils.
drawCOLRv1Glyph(fFace, glyph, fLoadGlyphFlags, palette, recordingCanvas)) {
1453 }
else if (glyph.
extraBits() == ScalerContextBits::SVG) {
1454#if defined(FT_CONFIG_OPTION_SVG)
1455 if (FT_Load_Glyph(fFace, glyph.
getGlyphID(), fLoadGlyphFlags)) {
1458 if (!fUtils.
drawSVGGlyph(fFace, glyph, fLoadGlyphFlags, palette, recordingCanvas)) {
1478 if (!FT_IS_SCALABLE(fFace) || this->setupSize()) {
1483 uint32_t
flags = fLoadGlyphFlags;
1484 flags |= FT_LOAD_NO_BITMAP;
1485 flags &= ~FT_LOAD_RENDER;
1487 FT_Error err = FT_Load_Glyph(fFace, glyphID,
flags);
1488 if (err != 0 || fFace->glyph->format != FT_GLYPH_FORMAT_OUTLINE) {
1492 emboldenIfNeeded(fFace, fFace->glyph, glyphID);
1503 vector.x = fFace->glyph->metrics.vertBearingX - fFace->glyph->metrics.horiBearingX;
1504 vector.y = -fFace->glyph->metrics.vertBearingY - fFace->glyph->metrics.horiBearingY;
1505 FT_Vector_Transform(&vector, &fMatrix22);
1512 if (
nullptr == metrics) {
1518 if (this->setupSize()) {
1519 sk_bzero(metrics,
sizeof(*metrics));
1532 SkScalar strikeoutThickness = 0.0f, strikeoutPosition = 0.0f;
1533 TT_OS2* os2 = (TT_OS2*) FT_Get_Sfnt_Table(face, ft_sfnt_os2);
1537 strikeoutThickness =
SkIntToScalar(os2->yStrikeoutSize) / upem;
1538 strikeoutPosition = -
SkIntToScalar(os2->yStrikeoutPosition) / upem;
1541 if (os2->version != 0xFFFF && os2->version >= 2) {
1548 SkScalar underlineThickness, underlinePosition;
1549 if (face->face_flags & FT_FACE_FLAG_SCALABLE) {
1554 static const int kUseTypoMetricsMask = (1 << 7);
1555 if (os2 && os2->version != 0xFFFF && (os2->fsSelection & kUseTypoMetricsMask)) {
1562 leading =
SkIntToScalar(face->height + (face->descender - face->ascender)) / upem;
1568 underlineThickness =
SkIntToScalar(face->underline_thickness) / upem;
1569 underlinePosition = -
SkIntToScalar(face->underline_position +
1570 face->underline_thickness / 2) / upem;
1578 if (getCBoxForLetter(
'x', &bbox)) {
1584 if (getCBoxForLetter(
'H', &bbox)) {
1588 }
else if (fStrikeIndex != -1) {
1596 xmax =
SkIntToScalar(face->available_sizes[fStrikeIndex].width) / xppem;
1602 underlineThickness = 0;
1603 underlinePosition = 0;
1607 TT_Postscript* post = (TT_Postscript*) FT_Get_Sfnt_Table(face, ft_sfnt_post);
1609 underlineThickness =
SkIntToScalar(post->underlineThickness) / upem;
1610 underlinePosition = -
SkIntToScalar(post->underlinePosition) / upem;
1615 sk_bzero(metrics,
sizeof(*metrics));
1621 x_height = -
ascent * fScale.
y();
1623 if (!avgCharWidth) {
1624 avgCharWidth = xmax - xmin;
1627 cap_height = -
ascent * fScale.
y();
1631 if (leading < 0.0f) {
1635 metrics->
fTop = ymax * fScale.
y();
1638 metrics->
fBottom = ymin * fScale.
y();
1639 metrics->
fLeading = leading * fScale.
y();
1641 metrics->
fXMin = xmin * fScale.
y();
1642 metrics->
fXMax = xmax * fScale.
y();
1651 if (face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS
1652#
if defined(FT_CONFIG_OPTION_SVG)
1653 || face->face_flags & FT_FACE_FLAG_SVG
1667#ifndef SK_OUTLINE_EMBOLDEN_DIVISOR
1668 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
1669 #define SK_OUTLINE_EMBOLDEN_DIVISOR 34
1671 #define SK_OUTLINE_EMBOLDEN_DIVISOR 24
1677void SkScalerContext_FreeType::emboldenIfNeeded(
FT_Face face, FT_GlyphSlot glyph,
SkGlyphID gid) {
1683 switch (glyph->format) {
1684 case FT_GLYPH_FORMAT_OUTLINE:
1686 strength = FT_MulFix(face->units_per_EM, face->size->metrics.y_scale)
1688 FT_Outline_Embolden(&glyph->outline, strength);
1690 case FT_GLYPH_FORMAT_BITMAP:
1691 if (!fFace->glyph->bitmap.buffer) {
1692 FT_Load_Glyph(fFace, gid, fLoadGlyphFlags);
1694 FT_GlyphSlot_Own_Bitmap(glyph);
1695 FT_Bitmap_Embolden(glyph->library, &glyph->bitmap, kBitmapEmboldenStrength, 0);
1771 return face ? face->num_glyphs : 0;
1781 nameIter = sk_make_sp<SkOTUtils::LocalizedStrings_SingleName>(familyName, language);
1787 fGlyphMasksMayNeedCurrentColorOnce([
this]{
1789 fGlyphMasksMayNeedCurrentColor = this->
getTableSize(COLRTag) > 0;
1790#if defined(FT_CONFIG_OPTION_SVG)
1792 fGlyphMasksMayNeedCurrentColor |= this->
getTableSize(SVGTag) > 0 ;
1795 return fGlyphMasksMayNeedCurrentColor;
1814 if (!(face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS)) {
1818 FT_MM_Var* variations =
nullptr;
1819 if (FT_Get_MM_Var(face, &variations)) {
1824 if (!parameters || parameterCount <
SkToInt(variations->num_axis)) {
1825 return variations->num_axis;
1828 for (FT_UInt
i = 0;
i < variations->num_axis; ++
i) {
1829 parameters[
i].
tag = variations->axis[
i].tag;
1834 bool hidden = !FT_Get_Var_Axis_Flags(variations,
i, &
flags) &&
1835 (
flags & FT_VAR_AXIS_FLAG_HIDDEN);
1839 return variations->num_axis;
1849 FT_ULong tableCount = 0;
1853 error = FT_Sfnt_Table_Info(face, 0,
nullptr, &tableCount);
1859 for (FT_ULong tableIndex = 0; tableIndex < tableCount; ++tableIndex) {
1861 FT_ULong tablelength;
1862 error = FT_Sfnt_Table_Info(face, tableIndex, &tableTag, &tablelength);
1881 FT_ULong tableLength = 0;
1885 error = FT_Load_Sfnt_Table(face, tag, 0,
nullptr, &tableLength);
1890 if (
offset > tableLength) {
1911 FT_ULong tableLength = 0;
1915 error = FT_Load_Sfnt_Table(face, tag, 0,
nullptr, &tableLength);
1922 error = FT_Load_Sfnt_Table(face, tag, 0,
1923 reinterpret_cast<FT_Byte*
>(
data->writable_data()), &tableLength);
1934 return fFaceRec.get();
1945 auto overrides =
desc->setPaletteEntryOverrides(paletteOverrideCount);
1946 for (
int i = 0;
i < paletteOverrideCount; ++
i) {
1958 , fFamilyName(
std::move(familyName))
1959 , fData(
std::move(fontData))
1965 *familyName = fFamilyName;
1969 *ttcIndex = fData->getIndex();
1970 return fData->getStream()->duplicate();
1974 return std::make_unique<SkFontData>(*fData);
1987 return sk_make_sp<SkTypeface_FreeTypeStream>(
1992 desc->setFamilyName(fFamilyName.
c_str());
2015 auto data = std::make_unique<SkFontData>(
2016 std::move(
stream),
args.getCollectionIndex(),
args.getPalette().index,
2017 axisValues.
get(), axisDefinitions.
size(),
2018 args.getPalette().overrides,
args.getPalette().overrideCount);
2023 if (FT_New_Library(&
gFTMemory, &fLibrary)) {
2026 FT_Add_Default_Modules(fLibrary);
2027 FT_Set_Default_Properties(fLibrary);
2032 FT_Done_Library(fLibrary);
2039 if (fLibrary ==
nullptr ||
stream ==
nullptr) {
2046 const void* memoryBase =
stream->getMemoryBase();
2049 args.flags = FT_OPEN_MEMORY;
2050 args.memory_base = (
const FT_Byte*)memoryBase;
2053 memset(ftStream, 0,
sizeof(*ftStream));
2054 ftStream->size =
stream->getLength();
2055 ftStream->descriptor.pointer =
stream;
2059 args.flags = FT_OPEN_STREAM;
2060 args.stream = ftStream;
2064 if (FT_Open_Face(fLibrary, &
args, ttcIndex, &face)) {
2073 FT_StreamRec streamRec;
2074 SkUniqueFTFace face(this->openFace(
stream, -1, &streamRec));
2079 *numFaces = face->num_faces;
2085 int* numInstances)
const {
2088 FT_StreamRec streamRec;
2089 SkUniqueFTFace face(this->openFace(
stream, -(faceIndex + 1), &streamRec));
2094 *numInstances = face->style_flags >> 16;
2108 FT_StreamRec streamRec;
2109 SkUniqueFTFace face(this->openFace(
stream, (instanceIndex << 16) + faceIndex, &streamRec));
2117 if (face->style_flags & FT_STYLE_FLAG_BOLD) {
2120 if (face->style_flags & FT_STYLE_FLAG_ITALIC) {
2124 bool hasAxes = face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS;
2125 TT_OS2* os2 =
static_cast<TT_OS2*
>(FT_Get_Sfnt_Table(face.get(), ft_sfnt_os2));
2126 bool hasOs2 = os2 && os2->version != 0xffff;
2128 PS_FontInfoRec psFontInfo;
2131 weight = os2->usWeightClass;
2132 width = os2->usWidthClass;
2135 if (
SkToBool(os2->fsSelection & (1u << 9))) {
2143 if (
GetAxes(face.get(), &axisDefinitions)) {
2144 size_t numAxes = axisDefinitions.
size();
2148 std::optional<size_t> wghtIndex;
2149 std::optional<size_t> wdthIndex;
2150 std::optional<size_t> slntIndex;
2151 for(
size_t i = 0;
i < numAxes; ++
i) {
2152 if (axisDefinitions[
i].fTag == wghtTag) {
2154 SkScalar wghtRange = axisDefinitions[
i].fMaximum - axisDefinitions[
i].fMinimum;
2155 if (wghtRange > 5 && wghtRange <= 1000 && axisDefinitions[
i].fMaximum <= 1000) {
2159 if (axisDefinitions[
i].fTag == wdthTag) {
2161 SkScalar wdthRange = axisDefinitions[
i].fMaximum - axisDefinitions[
i].fMinimum;
2162 if (wdthRange > 0 && wdthRange <= 500 && axisDefinitions[
i].fMaximum <= 500) {
2166 if (axisDefinitions[
i].fTag == slntTag) {
2171 if ((wghtIndex || wdthIndex || slntIndex) &&
2172 !FT_Get_Var_Design_Coordinates(face.get(), numAxes, coords.
get())) {
2196 if (!hasOs2 && !hasAxes && 0 == FT_Get_PS_Font_Info(face.get(), &psFontInfo) && psFontInfo.weight) {
2197 static const struct {
2198 char const *
const name;
2200 } commonWeights [] = {
2229 psFontInfo.weight,
sizeof(commonWeights[0]));
2231 weight = commonWeights[index].weight;
2233 LOG_INFO(
"Do not know weight for: %s (%s) \n", face->family_name, psFontInfo.weight);
2237 if (
name !=
nullptr) {
2238 name->set(face->family_name);
2240 if (style !=
nullptr) {
2243 if (isFixedPitch !=
nullptr) {
2244 *isFixedPitch = FT_IS_FIXED_WIDTH(face);
2247 if (axes !=
nullptr && !
GetAxes(face.get(), axes)) {
2255 if (face->face_flags & FT_FACE_FLAG_MULTIPLE_MASTERS) {
2256 FT_MM_Var* variations =
nullptr;
2257 FT_Error err = FT_Get_MM_Var(face, &variations);
2259 LOG_INFO(
"INFO: font %s claims to have variations, but none found.\n",
2265 axes->
reset(variations->num_axis);
2266 for (FT_UInt
i = 0;
i < variations->num_axis; ++
i) {
2267 const FT_Var_Axis& ftAxis = variations->axis[
i];
2268 (*axes)[
i].fTag = ftAxis.tag;
2292 weight = style->
weight();
2294 slant = style->
slant();
2297 for (
int i = 0;
i < axisDefinitions.
size(); ++
i) {
2307 for (
int j = 0; j < axisDefinitions.
size(); ++j) {
2308 const auto& coordinate = current[j];
2309 if (axisDefinition.
fTag == coordinate.axis) {
2310 const SkScalar axisValue =
SkTPin(coordinate.value, axisMin, axisMax);
2322 if (axisDefinition.
fTag == coordinate.axis) {
2323 const SkScalar axisValue =
SkTPin(coordinate.value, axisMin, axisMax);
2324 if (coordinate.value != axisValue) {
2325 LOG_INFO(
"Requested font axis value out of range: "
2326 "%s '%c%c%c%c' %f; pinned to %f.\n",
2328 (axisDefinition.
fTag >> 24) & 0xFF,
2329 (axisDefinition.
fTag >> 16) & 0xFF,
2330 (axisDefinition.
fTag >> 8) & 0xFF,
2331 (axisDefinition.
fTag ) & 0xFF,
2341 if (axisDefinition.
fTag == wghtTag) {
2343 SkScalar wghtRange = axisMax - axisMin;
2344 if (wghtRange > 5 && wghtRange <= 1000 && axisMax <= 1000) {
2348 if (axisDefinition.
fTag == wdthTag) {
2350 SkScalar wdthRange = axisMax - axisMin;
2351 if (wdthRange > 0 && wdthRange <= 500 && axisMax <= 500) {
2361 if (axisValues[
i] == 0) {
2380 for (
int j = 0; j < axisDefinitions.
size(); ++j) {
2381 if (skTag == axisDefinitions[j].fTag) {
2387 LOG_INFO(
"Requested font axis not found: %s '%c%c%c%c'\n",
2389 (skTag >> 24) & 0xFF,
2390 (skTag >> 16) & 0xFF,
2391 (skTag >> 8) & 0xFF,
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
sk_bzero(glyphs, sizeof(glyphs))
for(const auto glyph :glyphs)
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
#define SkDEBUGFAIL(message)
#define SkColorGetR(color)
#define SkColorGetG(color)
constexpr SkColor SK_ColorTRANSPARENT
static constexpr SkColor SkColorSetARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b)
#define SkColorGetA(color)
#define SkColorGetB(color)
#define SkEndian_SwapBE32(n)
#define SkFDot6ToScalar(x)
#define SkScalarToFDot6(x)
#define SkScalarToFixed(x)
#define SkFixedToScalar(x)
#define SkFixedFloorToInt(x)
#define SkFixedRoundToInt(x)
static void sk_ft_free(FT_Memory, void *block)
static SkAdvancedTypefaceMetrics::FontType get_font_type(FT_Face face)
static bool is_opentype_font_data_standard_format(const SkTypeface &typeface)
static bool canEmbed(FT_Face face)
static int GetVariationDesignPosition(AutoFTAccess &fta, SkFontArguments::VariationPosition::Coordinate coordinates[], int coordinateCount)
static FreeTypeLibrary * gFTLibrary
SkCallableTraits< FT_Alloc_Func >::argument< 1 >::type FT_Alloc_size_t
static bool isLCD(const SkScalerContextRec &rec)
static bool bothZero(SkScalar a, SkScalar b)
static void sk_ft_stream_close(FT_Stream)
static FT_Int chooseBitmapStrike(FT_Face face, FT_F26Dot6 scaleY)
static void * sk_ft_realloc(FT_Memory, FT_Alloc_size_t cur_size, FT_Alloc_size_t new_size, void *block)
static SkMutex & f_t_mutex()
static bool canSubset(FT_Face face)
static bool isAxisAligned(const SkScalerContextRec &rec)
constexpr int kMaxC2GCacheCount
static SkScalar SkFT_FixedToScalar(FT_Fixed x)
static unsigned long sk_ft_stream_io(FT_Stream ftStream, unsigned long offset, unsigned char *buffer, unsigned long count)
#define SK_OUTLINE_EMBOLDEN_DIVISOR
static void * sk_ft_alloc(FT_Memory, FT_Alloc_size_t size)
#define FT_PIXEL_MODE_BGRA
#define SK_TRACEFTR(ERR,...)
struct FT_FaceRec_ * FT_Face
@ kNormal
glyph outlines modified to improve constrast
@ kNone
glyph outlines unchanged
@ kSlight
minimal modification to improve constrast
@ kFull
modifies glyph outlines for maximum constrast
SK_API void sk_free(void *)
static void * sk_malloc_canfail(size_t size)
SK_API void * sk_realloc_throw(void *buffer, size_t size)
sk_sp< T > sk_ref_sp(T *obj)
#define SkScalarToDouble(x)
#define SK_ScalarInfinity
static constexpr const T & SkTPin(const T &x, const T &lo, const T &hi)
int SkStrLCSearch(const char *const *base, int count, const char target[], size_t len, size_t elemSize)
SkDEBUGCODE(SK_SPI) SkThreadID SkGetThreadID()
constexpr uint16_t SkToU16(S x)
constexpr int SkToInt(S x)
static constexpr bool SkToBool(const T &x)
constexpr unsigned SkToUInt(S x)
struct FT_StreamRec_ * FT_Stream
struct FT_LibraryRec_ * FT_Library
static constexpr SkFourByteTag SkSetFourByteTag(char a, char b, char c, char d)
AutoFTAccess(const SkTypeface_FreeType *tf)
void setPixels(void *pixels)
bool setInfo(const SkImageInfo &imageInfo, size_t rowBytes=0)
void translate(SkScalar dx, SkScalar dy)
void clear(SkColor color)
int findGlyphIndex(SkUnichar c) const
void insertCharAndGlyph(int index, SkUnichar, SkGlyphID)
static sk_sp< SkData > MakeUninitialized(size_t length)
const SkFontArguments::Palette::Override * getPaletteOverrides() const
int getPaletteIndex() const
int getPaletteOverrideCount() const
static SkFontStyle::Width SkFontStyleWidthForWidthAxisValue(SkScalar width)
void setFactoryId(SkTypeface::FactoryId factoryId)
static bool GetAxes(FT_Face face, AxisDefinitions *axes)
bool scanFace(SkStreamAsset *stream, int faceIndex, int *numInstances) const override
static void computeAxisValues(AxisDefinitions axisDefinitions, const SkFontArguments::VariationPosition position, SkFixed *axisValues, const SkString &name, SkFontStyle *style, const SkFontArguments::VariationPosition::Coordinate *currentPosition=nullptr)
~SkFontScanner_FreeType() override
bool scanInstance(SkStreamAsset *stream, int faceIndex, int instanceIndex, SkString *name, SkFontStyle *style, bool *isFixedPitch, AxisDefinitions *axes) const override
bool scanFile(SkStreamAsset *stream, int *numFaces) const override
uint16_t extraBits() const
SkGlyphID getGlyphID() const
SkMask::Format maskFormat() const
SkFixed getSubYFixed() const
SkFixed getSubXFixed() const
static OpenTypeSVGDecoderFactory GetOpenTypeSVGDecoderFactory()
SkMatrix & postTranslate(SkScalar dx, SkScalar dy)
SkScalar getSkewY() const
SkScalar getSkewX() const
SkScalar getScaleX() 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
SkCanvas * beginRecording(const SkRect &bounds, sk_sp< SkBBoxHierarchy > bbh)
sk_sp< SkPicture > finishRecordingAsPicture()
sk_sp< SkDrawable > finishRecordingAsDrawable()
virtual SkRect cullRect() const =0
bool generatePath(const SkGlyph &glyph, SkPath *path) override
GlyphMetrics generateMetrics(const SkGlyph &, SkArenaAlloc *) override
SkScalerContext_FreeType(sk_sp< SkTypeface_FreeType >, const SkScalerContextEffects &, const SkDescriptor *desc)
~SkScalerContext_FreeType() override
void generateFontMetrics(SkFontMetrics *) override
void generateImage(const SkGlyph &, void *) override
sk_sp< SkDrawable > generateDrawable(const SkGlyph &) override
@ kEmbeddedBitmapText_Flag
const SkMaskGamma::PreBlend fPreBlend
SkTypeface * getTypeface() const
static std::unique_ptr< SkScalerContext > MakeEmpty(sk_sp< SkTypeface > typeface, const SkScalerContextEffects &effects, const SkDescriptor *desc)
bool isLinearMetrics() const
const char * c_str() const
sk_sp< SkTypeface > onMakeClone(const SkFontArguments &) const override
void onGetFamilyName(SkString *familyName) const override
void onGetFontDescriptor(SkFontDescriptor *, bool *serialize) const override
~SkTypeface_FreeTypeStream() override
SkTypeface_FreeTypeStream(std::unique_ptr< SkFontData > fontData, const SkString familyName, const SkFontStyle &style, bool isFixedPitch)
std::unique_ptr< SkStreamAsset > onOpenStream(int *ttcIndex) const override
std::unique_ptr< SkFontData > onMakeFontData() const override
static std::unique_ptr< FaceRec > Make(const SkTypeface_FreeType *typeface)
FT_UShort fFTPaletteEntryCount
std::unique_ptr< SkStreamAsset > fSkStream
std::unique_ptr< SkColor[]> fSkPalette
void getPostScriptGlyphNames(SkString *dstArray) const override
sk_sp< SkData > onCopyTableData(SkFontTableTag) const override
std::unique_ptr< SkAdvancedTypefaceMetrics > onGetAdvancedMetrics() const override
void onCharsToGlyphs(const SkUnichar uni[], int count, SkGlyphID glyphs[]) const override
std::unique_ptr< SkScalerContext > onCreateScalerContext(const SkScalerContextEffects &, const SkDescriptor *) const override
int onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[], int coordinateCount) const override
bool onGetKerningPairAdjustments(const uint16_t glyphs[], int count, int32_t adjustments[]) const override
int onGetUPEM() const override
int onGetTableTags(SkFontTableTag tags[]) const override
bool onGlyphMaskNeedsCurrentColor() const override
int onGetVariationDesignParameters(SkFontParameters::Variation::Axis parameters[], int parameterCount) const override
std::unique_ptr< SkFontData > makeFontData() const
std::unique_ptr< SkFontData > cloneFontData(const SkFontArguments &, SkFontStyle *style) const
virtual std::unique_ptr< SkFontData > onMakeFontData() const =0
size_t onGetTableData(SkFontTableTag, size_t offset, size_t length, void *data) const override
void onFilterRec(SkScalerContextRec *) const override
int onCountGlyphs() const override
SkTypeface_FreeType(const SkFontStyle &style, bool isFixedPitch)
~SkTypeface_FreeType() override
LocalizedStrings * onCreateFamilyNameIterator() const override
FaceRec * getFaceRec() const
static sk_sp< SkTypeface > MakeFromStream(std::unique_ptr< SkStreamAsset >, const SkFontArguments &)
static void FontDataPaletteToDescriptorPalette(const SkFontData &, SkFontDescriptor *)
static int GetUnitsPerEm(FT_Face face)
void getGlyphToUnicodeMap(SkUnichar *) const override
bool onGetPostScriptName(SkString *) const override
SkTypefaceID uniqueID() const
void getFamilyName(SkString *name) const
SkFontStyle fontStyle() const
void serialize(SkWStream *, SerializeBehavior=SerializeBehavior::kIncludeDataIfLocal) const
bool isFixedPitch() const
size_t getTableSize(SkFontTableTag) const
std::unique_ptr< SkStreamAsset > openStream(int *ttcIndex) const
FlutterSemanticsFlag flags
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
const uint8_t uint32_t uint32_t GError ** error
static float max(float r, float g, float b)
static float min(float r, float g, float b)
unsigned useCenter Optional< SkMatrix > matrix
Optional< SkRect > bounds
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 policy
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
std::unique_ptr< void, SkOverloadedFunctionObject< void(void *), sk_free > > UniqueVoidPtr
@ kNotEmbeddable_FontFlag
May not be embedded.
@ kAltDataFormat_FontFlag
Data compressed. Table access may still work.
@ kNotSubsettable_FontFlag
May not be subset.
@ kVariable_FontFlag
May be true for Type1, CFF, or TrueType fonts.
const Coordinate * coordinates
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
@ kBoundsInvalid_Flag
set if fTop, fBottom, fXMin, fXMax invalid
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...
void setHidden(bool hidden)
static constexpr SkIRect MakeLTRB(int32_t l, int32_t t, int32_t r, int32_t b)
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)
@ kLCD16_Format
565 alpha for r/g/b
@ kARGB32_Format
SkPMColor.
@ kBW_Format
1bit per pixel mask (e.g. monochrome)
constexpr float y() const
constexpr float x() const
static SkRect Make(const SkISize &size)
static constexpr SkRect MakeEmpty()
static constexpr SkRect MakeXYWH(float x, float y, float w, float h)
static constexpr SkRect MakeLTRB(float l, float t, float r, float b)
bool drawCOLRv1Glyph(FT_Face, const SkGlyph &, LoadGlyphFlags, SkSpan< SkColor > palette, SkCanvas *) const
bool drawSVGGlyph(FT_Face, const SkGlyph &, LoadGlyphFlags, SkSpan< SkColor > palette, SkCanvas *) const
static bool computeColrV1GlyphBoundingBox(FT_Face, SkGlyphID, SkRect *bounds)
void generateGlyphImage(FT_Face, const SkGlyph &, void *, const SkMatrix &bitmapTransform, const SkMaskGamma::PreBlend &) const
bool generateGlyphPath(FT_Face, SkPath *) const
void init(SkColor fgColor, SkScalerContext::Flags)
bool drawCOLRv0Glyph(FT_Face, const SkGlyph &, LoadGlyphFlags, SkSpan< SkColor > palette, SkCanvas *) const
uint32_t fForegroundColor
SkMask::Format fMaskFormat
bool computeMatrices(PreMatrixScale preMatrixScale, SkVector *scale, SkMatrix *remaining, SkMatrix *remainingWithoutRotation=nullptr, SkMatrix *remainingRotation=nullptr, SkMatrix *total=nullptr)
SkFontHinting getHinting() const
void setHinting(SkFontHinting)
SkMask::Format maskFormat
std::shared_ptr< const fml::Mapping > data