27[[maybe_unused]]
static inline const constexpr bool kSkShowTextBlitCoverage =
false;
29sk_sp<SkData> streamToData(
const std::unique_ptr<SkStreamAsset>& font_data) {
37rust::Box<::fontations_ffi::BridgeFontRef> make_bridge_font_ref(
sk_sp<SkData> fontData,
39 rust::Slice<const uint8_t> slice{fontData->
bytes(), fontData->
size()};
40 return fontations_ffi::make_font_ref(slice, index);
43static_assert(
sizeof(fontations_ffi::SkiaDesignCoordinate) ==
45 sizeof(fontations_ffi::SkiaDesignCoordinate::axis) ==
49 offsetof(fontations_ffi::SkiaDesignCoordinate, axis) ==
51 offsetof(fontations_ffi::SkiaDesignCoordinate,
value) ==
53 "Struct fontations_ffi::SkiaDesignCoordinate must match "
54 "SkFontArguments::VariationPosition::Coordinate.");
56rust::Box<fontations_ffi::BridgeNormalizedCoords> make_normalized_coords(
57 fontations_ffi::BridgeFontRef
const& bridgeFontRef,
60 rust::Slice<const fontations_ffi::SkiaDesignCoordinate> coordinates(
61 reinterpret_cast<const fontations_ffi::SkiaDesignCoordinate*
>(
64 return resolve_into_normalized_coords(bridgeFontRef, coordinates);
95SkTypeface_Fontations::SkTypeface_Fontations(
99 rust::Box<fontations_ffi::BridgeFontRef>&& fontRef,
100 rust::Box<fontations_ffi::BridgeMappingIndex>&& mappingIndex,
101 rust::Box<fontations_ffi::BridgeNormalizedCoords>&& normalizedCoords,
102 rust::Box<fontations_ffi::BridgeOutlineCollection>&& outlines,
103 rust::Vec<uint32_t>&& palette)
105 , fFontData(
std::move(fontData))
106 , fTtcIndex(ttcIndex)
107 , fBridgeFontRef(
std::move(fontRef))
108 , fMappingIndex(
std::move(mappingIndex))
109 , fBridgeNormalizedCoords(
std::move(normalizedCoords))
110 , fOutlines(
std::move(outlines))
111 , fPalette(
std::move(palette)) {}
120 uint32_t ttcIndex =
args.getCollectionIndex();
121 rust::Box<fontations_ffi::BridgeFontRef> bridgeFontRef = make_bridge_font_ref(
data, ttcIndex);
122 if (!fontations_ffi::font_ref_is_valid(*bridgeFontRef)) {
126 rust::Box<fontations_ffi::BridgeMappingIndex> mappingIndex =
127 fontations_ffi::make_mapping_index(*bridgeFontRef);
130 std::unique_ptr<SkFontArguments::VariationPosition::Coordinate[]> concatenatedCoords =
nullptr;
136 if (
args.getCollectionIndex() & 0xFFFF0000) {
137 size_t numNamedInstanceCoords =
138 fontations_ffi::coordinates_for_shifted_named_instance_index(
140 args.getCollectionIndex(),
141 rust::cxxbridge1::Slice<fontations_ffi::SkiaDesignCoordinate>());
142 concatenatedCoords.reset(
146 rust::cxxbridge1::Slice<fontations_ffi::SkiaDesignCoordinate> targetSlice(
147 reinterpret_cast<fontations_ffi::SkiaDesignCoordinate*
>(concatenatedCoords.get()),
148 numNamedInstanceCoords);
149 size_t retrievedNamedInstanceCoords =
150 fontations_ffi::coordinates_for_shifted_named_instance_index(
151 *bridgeFontRef,
args.getCollectionIndex(), targetSlice);
152 if (numNamedInstanceCoords != retrievedNamedInstanceCoords) {
156 concatenatedCoords[numNamedInstanceCoords +
i] = variationPosition.
coordinates[
i];
159 variationPosition.
coordinates = concatenatedCoords.get();
162 rust::Box<fontations_ffi::BridgeNormalizedCoords> normalizedCoords =
163 make_normalized_coords(*bridgeFontRef, variationPosition);
165 fontations_ffi::BridgeFontStyle
fontStyle;
166 if (fontations_ffi::get_font_style(*bridgeFontRef, *normalizedCoords,
fontStyle)) {
171 rust::Box<fontations_ffi::BridgeOutlineCollection> outlines =
172 fontations_ffi::get_outline_collection(*bridgeFontRef);
174 rust::Slice<const fontations_ffi::PaletteOverride> paletteOverrides(
175 reinterpret_cast<const ::fontations_ffi::PaletteOverride*
>(
args.getPalette().overrides),
176 args.getPalette().overrideCount);
177 rust::Vec<uint32_t> palette =
178 resolve_palette(*bridgeFontRef,
args.getPalette().index, paletteOverrides);
183 std::move(bridgeFontRef),
184 std::move(mappingIndex),
185 std::move(normalizedCoords),
187 std::move(palette)));
193void PathGeometrySink::going_to(
SkPoint point) {
201bool PathGeometrySink::current_is_not(
SkPoint point) {
return fCurrent != point; }
213 if (current_is_not(pt0)) {
222 if (current_is_not(pt0) || current_is_not(pt1)) {
231 if (current_is_not(pt0) || current_is_not(pt1) || current_is_not(pt2)) {
242 : fAxisArray(axisArray), fAxisCount(axisCount) {}
245 size_t i, uint32_t axisTag,
float min,
float def,
float max,
bool hidden) {
246 if (
i >= fAxisCount) {
263 return fontations_ffi::units_per_em_or_zero(*fBridgeFontRef);
267 rust::String readFamilyName = fontations_ffi::family_name(*fBridgeFontRef);
268 *familyName =
SkString(readFamilyName.data(), readFamilyName.size());
272 rust::String readPsName;
273 if (fontations_ffi::postscript_name(*fBridgeFontRef, readPsName)) {
274 if (postscriptName) {
275 *postscriptName =
SkString(readPsName.data(), readPsName.size());
284 fGlyphMasksMayNeedCurrentColorOnce([
this] {
286 fGlyphMasksMayNeedCurrentColor = this->
getTableSize(COLRTag) > 0;
288 return fGlyphMasksMayNeedCurrentColor;
297 glyphs[
i] = fontations_ffi::lookup_glyph_or_zero(*fBridgeFontRef, *fMappingIndex, chars[
i]);
301 return fontations_ffi::num_glyphs(*fBridgeFontRef);
306 if (!codepointForGlyphMap) {
309 rust::Slice<uint32_t> codepointForGlyphSlice{
reinterpret_cast<uint32_t*
>(codepointForGlyphMap),
311 fontations_ffi::fill_glyph_to_unicode_map(*fBridgeFontRef, codepointForGlyphSlice);
332 rust::Box<::fontations_ffi::BridgeLocalizedStrings> bridge_localized_strings)
333 : fBridgeLocalizedStrings(
std::move(bridge_localized_strings)) {}
335 fontations_ffi::BridgeLocalizedName localizedName;
336 if (!fontations_ffi::localized_name_next(*fBridgeLocalizedStrings, localizedName)) {
340 SkString(localizedName.string.data(), localizedName.string.size());
342 SkString(localizedName.language.data(), localizedName.language.size());
347 rust::Box<::fontations_ffi::BridgeLocalizedStrings> fBridgeLocalizedStrings;
363 ->getBridgeNormalizedCoords())
377 fHintingInstance = fontations_ffi::no_hinting_instance();
378 fDoLinearMetrics =
true;
380 fHintingInstance = fontations_ffi::make_mono_hinting_instance(
381 fOutlines,
scale.fY, fBridgeNormalizedCoords);
382 fDoLinearMetrics =
false;
387 fHintingInstance = fontations_ffi::no_hinting_instance();
388 fDoLinearMetrics =
true;
392 fHintingInstance = fontations_ffi::make_hinting_instance(
395 fBridgeNormalizedCoords,
399 fDoLinearMetrics =
true;
403 fHintingInstance = fontations_ffi::make_hinting_instance(
406 fBridgeNormalizedCoords,
413 fHintingInstance = fontations_ffi::make_hinting_instance(
416 fBridgeNormalizedCoords,
434 const fontations_ffi::BridgeHintingInstance& hintingInstance) {
436 fontations_ffi::BridgeScalerMetrics scalerMetrics;
441 fBridgeNormalizedCoords,
447 *
path = std::move(pathWrapper).into_inner();
469 bool has_colrv1_glyph =
470 fontations_ffi::has_colrv1_glyph(fBridgeFontRef, glyph.
getGlyphID());
471 bool has_colrv0_glyph =
472 fontations_ffi::has_colrv0_glyph(fBridgeFontRef, glyph.
getGlyphID());
473 bool has_bitmap_glyph =
474 fontations_ffi::has_bitmap_glyph(fBridgeFontRef, glyph.
getGlyphID());
477 bool doLinearMetrics = fDoLinearMetrics;
479 if (has_bitmap_glyph) {
482 doLinearMetrics =
false;
484 if (has_colrv0_glyph || has_colrv1_glyph) {
486 doLinearMetrics =
true;
495 float x_advance = 0.0f;
496 x_advance = fontations_ffi::unhinted_advance_width_or_zero(
497 fBridgeFontRef,
scale.y(), fBridgeNormalizedCoords, glyph.
getGlyphID());
498 if (!doLinearMetrics) {
499 float hinted_advance = 0;
500 fontations_ffi::scaler_hinted_advance_width(
501 fOutlines, *fHintingInstance, glyph.
getGlyphID(), hinted_advance);
505 if (hinted_advance != x_advance && hinted_advance != 0) {
506 x_advance = hinted_advance;
511 if (has_colrv1_glyph || has_colrv0_glyph) {
516 fontations_ffi::ClipBox clipBox;
517 if (has_colrv1_glyph && fontations_ffi::get_colrv1_clip_box(fBridgeFontRef,
518 fBridgeNormalizedCoords,
524 clipBox.x_min, -clipBox.y_max, clipBox.x_max, -clipBox.y_min);
535 uint16_t upem = fontations_ffi::units_per_em_or_zero(fBridgeFontRef);
541 fullTransform.
preScale(1.f / upem, 1.f / upem);
544 bool result = fontations_ffi::draw_colr_glyph(fBridgeFontRef,
545 fBridgeNormalizedCoords,
555 }
else if (has_bitmap_glyph) {
560 rust::cxxbridge1::Box<fontations_ffi::BridgeBitmapGlyph> bitmap_glyph =
561 fontations_ffi::bitmap_glyph(fBridgeFontRef, glyph.
getGlyphID(),
scale.fY);
562 rust::cxxbridge1::Slice<const uint8_t> png_data =
563 fontations_ffi::png_data(*bitmap_glyph);
566 const fontations_ffi::BitmapMetrics bitmapMetrics =
567 fontations_ffi::bitmap_metrics(*bitmap_glyph);
585 float fontUnitsToSize =
scale.fY / fontations_ffi::units_per_em_or_zero(fBridgeFontRef);
589 matrix.preTranslate( bitmapMetrics.bearing_x * fontUnitsToSize,
590 -bitmapMetrics.bearing_y * fontUnitsToSize);
591 matrix.preScale(imageToSize, imageToSize);
592 matrix.preTranslate( bitmapMetrics.inner_bearing_x,
593 -bitmapMetrics.inner_bearing_y);
596 float heightAdjustment =
597 bitmapMetrics.placement_origin_bottom_left ?
bounds.height() : 0;
598 matrix.preTranslate(0, -heightAdjustment);
637 rust::cxxbridge1::Box<fontations_ffi::BridgeBitmapGlyph> bitmap_glyph =
638 fontations_ffi::bitmap_glyph(fBridgeFontRef, glyph.
getGlyphID(),
scale.fY);
639 rust::cxxbridge1::Slice<const uint8_t> png_data = fontations_ffi::png_data(*bitmap_glyph);
649 auto [glyph_image,
result] = codec->getImage();
655 canvas.
concat(remainingMatrix);
661 const fontations_ffi::BitmapMetrics bitmapMetrics =
662 fontations_ffi::bitmap_metrics(*bitmap_glyph);
668 float fontUnitsToSize =
scale.fY / fontations_ffi::units_per_em_or_zero(fBridgeFontRef);
669 canvas.
translate( bitmapMetrics.bearing_x * fontUnitsToSize,
670 -bitmapMetrics.bearing_y * fontUnitsToSize);
671 canvas.
scale(imageScaleFactor, imageScaleFactor);
672 canvas.
translate( bitmapMetrics.inner_bearing_x,
673 -bitmapMetrics.inner_bearing_y);
675 float heightAdjustment =
676 bitmapMetrics.placement_origin_bottom_left ? glyph_image->height() : 0;
710 if constexpr (kSkShowTextBlitCoverage) {
711 canvas.
clear(0x33FF0000);
740 *
path =
path->makeTransform(remainingMatrix);
745 uint16_t upem = fontations_ffi::units_per_em_or_zero(fBridgeFontRef);
757 canvas->
concat(scalerMatrix);
762 bool result = fontations_ffi::draw_colr_glyph(
763 fBridgeFontRef, fBridgeNormalizedCoords, glyph.
getGlyphID(), colorPainter);
772 : fSelf(
self), fGlyph(glyph) {}
773 SkRect onGetBounds()
override {
return fGlyph.
rect(); }
774 size_t onApproximateBytesUsed()
override {
return sizeof(GlyphDrawable); }
775 void maybeShowTextBlitCoverage(
SkCanvas* canvas) {
776 if constexpr (kSkShowTextBlitCoverage) {
778 paint.setColor(0x3300FF00);
784 struct ColrGlyphDrawable :
public GlyphDrawable {
785 using GlyphDrawable::GlyphDrawable;
786 void onDraw(
SkCanvas* canvas)
override {
787 this->maybeShowTextBlitCoverage(canvas);
788 fSelf->drawCOLRGlyph(fGlyph, fSelf->fRec.fForegroundColor, canvas);
803 fontations_ffi::Metrics metrics =
804 fontations_ffi::get_skia_metrics(fBridgeFontRef,
scale.fY, fBridgeNormalizedCoords);
805 out_metrics->
fTop = -metrics.top;
806 out_metrics->
fAscent = -metrics.ascent;
807 out_metrics->
fDescent = -metrics.descent;
808 out_metrics->
fBottom = -metrics.bottom;
809 out_metrics->
fLeading = metrics.leading;
812 out_metrics->
fXMin = metrics.x_min;
813 out_metrics->
fXMax = metrics.x_max;
814 out_metrics->
fXHeight = -metrics.x_height;
815 out_metrics->
fCapHeight = -metrics.cap_height;
817 if (fontations_ffi::table_data(fBridgeFontRef,
820 rust::Slice<uint8_t>())) {
823 auto setMetric = [](
float& dstMetric,
const float srcMetric,
826 if (std::isnan(srcMetric)) {
829 dstMetric = srcMetric;
847 const fontations_ffi::BridgeFontRef& fBridgeFontRef;
848 const fontations_ffi::BridgeNormalizedCoords& fBridgeNormalizedCoords;
849 const fontations_ffi::BridgeOutlineCollection& fOutlines;
851 rust::Box<fontations_ffi::BridgeHintingInstance> fHintingInstance;
852 bool fDoLinearMetrics =
false;
858 *ttcIndex = fTtcIndex;
859 return std::make_unique<SkMemoryStream>(fFontData);
864 if (fTtcIndex != SkTo<uint32_t>(
args.getCollectionIndex())) {
869 auto fusedDesignPosition =
870 std::make_unique<SkFontArguments::VariationPosition::Coordinate[]>(numAxes);
872 if (numAxes != retrievedAxes) {
878 for (
int i = 0;
i < numAxes; ++
i) {
891 rust::cxxbridge1::Box<fontations_ffi::BridgeNormalizedCoords> normalized_args =
894 if (!fontations_ffi::normalized_coords_equal(*normalized_args, *fBridgeNormalizedCoords)) {
899 rust::Slice<const fontations_ffi::PaletteOverride> argPaletteOverrides(
900 reinterpret_cast<const fontations_ffi::PaletteOverride*
>(
args.getPalette().overrides),
901 args.getPalette().overrideCount);
902 rust::Vec<uint32_t> newPalette =
903 resolve_palette(*fBridgeFontRef,
args.getPalette().index, argPaletteOverrides);
905 if (fPalette.size() != newPalette.size() ||
906 memcmp(fPalette.data(), newPalette.data(), fPalette.size() *
sizeof(fPalette[0]))) {
915 return std::make_unique<SkFontationsScalerContext>(
922 if (!fontations_ffi::is_embeddable(*fBridgeFontRef)) {
926 if (!fontations_ffi::is_subsettable(*fBridgeFontRef)) {
930 if (fontations_ffi::table_data(
931 *fBridgeFontRef,
SkSetFourByteTag(
'f',
'v',
'a',
'r'), 0, rust::Slice<uint8_t>())) {
936 fontations_ffi::Metrics metrics =
937 fontations_ffi::get_unscaled_metrics(*fBridgeFontRef, *fBridgeNormalizedCoords);
938 info->fAscent = metrics.ascent;
939 info->fDescent = metrics.descent;
940 info->fCapHeight = metrics.cap_height;
943 (int32_t)metrics.top,
944 (int32_t)metrics.x_max,
945 (int32_t)metrics.bottom);
948 if (fontations_ffi::is_fixed_pitch(*fBridgeFontRef)) {
952 fontations_ffi::BridgeFontStyle
fontStyle;
953 if (fontations_ffi::get_font_style(*fBridgeFontRef, *fBridgeNormalizedCoords,
fontStyle)) {
959 if (fontations_ffi::is_serif_style(*fBridgeFontRef)) {
961 }
else if (fontations_ffi::is_script_style(*fBridgeFontRef)) {
965 info->fItalicAngle = fontations_ffi::italic_angle(*fBridgeFontRef);
978 desc->setPaletteIndex(0);
981 size_t paletteOverrideCount = palette.
size();
982 auto overrides =
desc->setPaletteEntryOverrides(paletteOverrideCount);
983 for (
size_t i = 0;
i < paletteOverrideCount; ++
i) {
984 overrides[
i] = {(uint16_t)
i, palette[
i]};
994 rust::Slice<uint8_t> dataSlice;
996 dataSlice = rust::Slice<uint8_t>(
reinterpret_cast<uint8_t*
>(
data),
length);
998 size_t copied = fontations_ffi::table_data(*fBridgeFontRef, tag,
offset, dataSlice);
1004 uint16_t numTables = fontations_ffi::table_tags(*fBridgeFontRef, rust::Slice<uint32_t>());
1008 rust::Slice<uint32_t> copyToTags(tags, numTables);
1009 return fontations_ffi::table_tags(*fBridgeFontRef, copyToTags);
1014 rust::Slice<fontations_ffi::SkiaDesignCoordinate> copyToCoordinates;
1016 copyToCoordinates = rust::Slice<fontations_ffi::SkiaDesignCoordinate>(
1017 reinterpret_cast<fontations_ffi::SkiaDesignCoordinate*
>(coordinates),
1020 return fontations_ffi::variation_position(*fBridgeNormalizedCoords, copyToCoordinates);
1026 return fontations_ffi::populate_axes(*fBridgeFontRef, axisWrapper);
1033const uint16_t kForegroundColorPaletteIndex = 0xFFFF;
1035void populateStopsAndColors(std::vector<SkScalar>& dest_stops,
1036 std::vector<SkColor4f>& dest_colors,
1039 fontations_ffi::BridgeColorStops& color_stops) {
1042 size_t num_color_stops = fontations_ffi::num_color_stops(color_stops);
1043 dest_stops.reserve(num_color_stops);
1044 dest_colors.reserve(num_color_stops);
1046 fontations_ffi::ColorStop color_stop;
1047 while (fontations_ffi::next_color_stop(color_stops, color_stop)) {
1048 dest_stops.push_back(color_stop.stop);
1050 if (color_stop.palette_index == kForegroundColorPaletteIndex) {
1051 dest_color = SkColor4f::FromColor(foregroundColor);
1053 dest_color = SkColor4f::FromColor(palette[color_stop.palette_index]);
1055 dest_color.fA *= color_stop.alpha;
1056 dest_colors.push_back(dest_color);
1072 const auto c_4f = c0_4f + (c1_4f - c0_4f) * t;
1075 c_4f.store(l.vec());
1079enum TruncateStops { TruncateStart, TruncateEnd };
1083void truncateToStopInterpolating(
SkScalar zeroRadiusStop,
1084 std::vector<SkColor4f>&
colors,
1085 std::vector<SkScalar>& stops,
1086 TruncateStops truncateStops) {
1087 if (stops.size() <= 1u || zeroRadiusStop < stops.front() || stops.back() < zeroRadiusStop) {
1092 (truncateStops == TruncateStart)
1093 ? std::lower_bound(stops.begin(), stops.end(), zeroRadiusStop) - stops.begin()
1094 : std::upper_bound(stops.begin(), stops.end(), zeroRadiusStop) - stops.begin();
1097 (zeroRadiusStop - stops[afterIndex - 1]) / (stops[afterIndex] - stops[afterIndex - 1]);
1100 if (truncateStops == TruncateStart) {
1101 stops.erase(stops.begin(), stops.begin() + afterIndex);
1103 stops.insert(stops.begin(), 0);
1106 stops.erase(stops.begin() + afterIndex, stops.end());
1108 stops.insert(stops.end(), 1);
1114inline SkBlendMode ToSkBlendMode(uint16_t colrV1CompositeMode) {
1115 switch (colrV1CompositeMode) {
1177inline SkTileMode ToSkTileMode(uint8_t extendMode) {
1178 switch (extendMode) {
1195 : fScalerContext(scaler_context)
1198 , fForegroundColor(foregroundColor)
1199 , fAntialias(antialias)
1204 fCanvas.
concat(SkMatrixFromFontationsTransform(transform_arg));
1224void ColorPainter::configure_solid_paint(uint16_t palette_index,
float alpha,
SkPaint&
paint) {
1225 paint.setAntiAlias(fAntialias);
1227 if (palette_index == kForegroundColorPaletteIndex) {
1228 color = SkColor4f::FromColor(fForegroundColor);
1230 color = SkColor4f::FromColor(fPalette[palette_index]);
1233 paint.setShader(
nullptr);
1239 configure_solid_paint(palette_index, alpha,
paint);
1248 configure_solid_paint(palette_index, alpha,
paint);
1252void ColorPainter::configure_linear_paint(
const fontations_ffi::FillLinearParams& linear_params,
1253 fontations_ffi::BridgeColorStops& bridge_stops,
1257 paint.setAntiAlias(fAntialias);
1259 std::vector<SkScalar> stops;
1260 std::vector<SkColor4f>
colors;
1262 populateStopsAndColors(stops,
colors, fPalette, fForegroundColor, bridge_stops);
1264 if (stops.size() == 1) {
1282 SkGradientShader::Interpolation::ColorSpace::kSRGB,
1283 SkGradientShader::Interpolation::HueMethod::kShorter},
1289 paint.setShader(shader);
1293 fontations_ffi::BridgeColorStops& bridge_stops,
1304 const fontations_ffi::FillLinearParams& linear_params,
1305 fontations_ffi::BridgeColorStops& bridge_stops,
1312 configure_linear_paint(linear_params, bridge_stops,
extend_mode,
paint, &paintTransform);
1316void ColorPainter::configure_radial_paint(
1317 const fontations_ffi::FillRadialParams& fill_radial_params,
1318 fontations_ffi::BridgeColorStops& bridge_stops,
1322 paint.setAntiAlias(fAntialias);
1327 float startRadius = fill_radial_params.r0;
1328 float endRadius = fill_radial_params.r1;
1330 std::vector<SkScalar> stops;
1331 std::vector<SkColor4f>
colors;
1333 populateStopsAndColors(stops,
colors, fPalette, fForegroundColor, bridge_stops);
1336 if (stops.size() == 1) {
1349 if (startRadius < 0 || endRadius < 0) {
1350 if (startRadius == endRadius && startRadius < 0) {
1358 SkScalar radiusDiff = endRadius - startRadius;
1360 TruncateStops truncateSide = TruncateStart;
1361 if (startRadius < 0) {
1362 truncateSide = TruncateStart;
1369 zeroRadiusStop = -startRadius / (endRadius - startRadius);
1372 startEndDiff.
scale(zeroRadiusStop);
1376 if (endRadius < 0) {
1377 truncateSide = TruncateEnd;
1378 zeroRadiusStop = -startRadius / (endRadius - startRadius);
1381 startEndDiff.
scale(1 - zeroRadiusStop);
1382 end =
end - startEndDiff;
1385 if (!(startRadius == 0 && endRadius == 0)) {
1386 truncateToStopInterpolating(zeroRadiusStop,
colors, stops, truncateSide);
1391 if (radiusDiff > 0) {
1393 endRadius = radiusDiff;
1395 stops.erase(stops.begin(), stops.end() - 1);
1397 start -= startToEnd;
1398 startRadius = -radiusDiff;
1400 stops.erase(stops.begin() + 1, stops.end());
1404 if (startRadius < 0 || endRadius < 0) {
1406 int roundedMultiple = factorZeroCrossing > 0 ? ceilf(factorZeroCrossing)
1407 : floorf(factorZeroCrossing) - 1;
1409 roundedMultiple += roundedMultiple < 0 ? -1 : 1;
1411 return roundedMultiple;
1415 SkScalar radiusDiff = endRadius - startRadius;
1416 SkScalar factorZeroCrossing = (startRadius / (startRadius - endRadius));
1417 bool inRange = 0.f <= factorZeroCrossing && factorZeroCrossing <= 1.0f;
1418 SkScalar direction = inRange && radiusDiff < 0 ? -1.0f : 1.0f;
1420 roundIntegerMultiple(factorZeroCrossing * direction, tileMode);
1421 startToEnd.
scale(circleProjectionFactor);
1422 startRadius += circleProjectionFactor * radiusDiff;
1423 endRadius += circleProjectionFactor * radiusDiff;
1424 start += startToEnd;
1444 SkGradientShader::Interpolation::ColorSpace::kSRGB,
1445 SkGradientShader::Interpolation::HueMethod::kShorter},
1450 fontations_ffi::BridgeColorStops& bridge_stops,
1454 configure_radial_paint(fill_radial_params, bridge_stops,
extend_mode,
paint);
1461 const fontations_ffi::FillRadialParams& fill_radial_params,
1462 fontations_ffi::BridgeColorStops& bridge_stops,
1469 configure_radial_paint(fill_radial_params, bridge_stops,
extend_mode,
paint, &paintTransform);
1473void ColorPainter::configure_sweep_paint(
const fontations_ffi::FillSweepParams& sweep_params,
1474 fontations_ffi::BridgeColorStops& bridge_stops,
1478 paint.setAntiAlias(fAntialias);
1482 std::vector<SkScalar> stops;
1483 std::vector<SkColor4f>
colors;
1485 populateStopsAndColors(stops,
colors, fPalette, fForegroundColor, bridge_stops);
1487 if (stops.size() == 1) {
1506 sweep_params.start_angle,
1507 sweep_params.end_angle,
1509 SkGradientShader::Interpolation::ColorSpace::kSRGB,
1510 SkGradientShader::Interpolation::HueMethod::kShorter},
1515 fontations_ffi::BridgeColorStops& bridge_stops,
1526 const fontations_ffi::FillSweepParams& sweep_params,
1527 fontations_ffi::BridgeColorStops& bridge_stops,
1534 configure_sweep_paint(sweep_params, bridge_stops,
extend_mode,
paint, &paintTransform);
1540 paint.setBlendMode(ToSkBlendMode(compositeMode));
1549 : fScalerContext(scaler_context)
1550 , fCurrentTransform(initialTransfom)
1568 bool invertResult =
transform.invert(&fStackTopTransformInverse);
1572 fCurrentTransform.
preConcat(fStackTopTransformInverse);
1573 fStackTopTransformInverse =
SkMatrix();
1579 path.transform(fCurrentTransform);
1597 const fontations_ffi::FillRadialParams&,
1598 fontations_ffi::BridgeColorStops&,
1605 const fontations_ffi::FillLinearParams&,
1606 fontations_ffi::BridgeColorStops&,
1614 const fontations_ffi::FillSweepParams&,
1615 fontations_ffi::BridgeColorStops&,
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
sk_bzero(glyphs, sizeof(glyphs))
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
#define SK_ABORT(message,...)
#define SkASSERT_RELEASE(cond)
@ kExclusion
rc = s + d - two(s*d), ra = kSrcOver
@ kSaturation
saturation of source with hue and luminosity of destination
@ kColorBurn
darken destination to reflect source
@ kLighten
rc = s + d - min(s*da, d*sa), ra = kSrcOver
@ kHue
hue of source with saturation and luminosity of destination
@ kMultiply
r = s*(1-da) + d*(1-sa) + s*d
@ kColorDodge
brighten destination to reflect source
@ kSrcOver
r = s + (1-sa)*d
@ kXor
r = s*(1-da) + d*(1-sa)
@ kLuminosity
luminosity of source with hue and saturation of destination
@ kSoftLight
lighten or darken, depending on source
@ kDifference
rc = s + d - 2*(min(s*da, d*sa)), ra = kSrcOver
@ kOverlay
multiply or screen, depending on destination
@ kSrcATop
r = s*da + d*(1-sa)
@ kDstATop
r = d*sa + s*(1-da)
@ kDstOver
r = d + (1-da)*s
@ kColor
hue and saturation of source with luminosity of destination
@ kHardLight
multiply or screen, depending on source
@ kDarken
rc = s + d - max(s*da, d*sa), ra = kSrcOver
constexpr SkColor SK_ColorTRANSPARENT
constexpr SkColor SK_ColorRED
constexpr SkColor SK_ColorBLACK
#define SkFixedToScalar(x)
static bool SkIsFinite(T x, Pack... values)
static bool isLCD(const SkScalerContextRec &rec)
static bool bothZero(SkScalar a, SkScalar b)
static bool isAxisAligned(const SkScalerContextRec &rec)
@ 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_sp< T > sk_ref_sp(T *obj)
#define SkFloatToScalar(x)
constexpr size_t SkToSizeT(S x)
constexpr int SkToInt(S x)
static constexpr bool SkToBool(const T &x)
sk_sp< SkTypeface > SkTypeface_Make_Fontations(std::unique_ptr< SkStreamAsset > fontData, const SkFontArguments &args)
static constexpr SkFourByteTag SkSetFourByteTag(char a, char b, char c, char d)
void setPixels(void *pixels)
bool setInfo(const SkImageInfo &imageInfo, size_t rowBytes=0)
int saveLayer(const SkRect *bounds, const SkPaint *paint)
void drawRect(const SkRect &rect, const SkPaint &paint)
void clipRect(const SkRect &rect, SkClipOp op, bool doAntiAlias)
void translate(SkScalar dx, SkScalar dy)
void drawPaint(const SkPaint &paint)
void clear(SkColor color)
void clipPath(const SkPath &path, SkClipOp op, bool doAntiAlias)
void drawPath(const SkPath &path, const SkPaint &paint)
void scale(SkScalar sx, SkScalar sy)
void concat(const SkMatrix &matrix)
void drawImage(const SkImage *image, SkScalar left, SkScalar top)
static sk_sp< SkColorSpace > MakeSRGB()
static sk_sp< SkData > MakeWithoutCopy(const void *data, size_t length)
const uint8_t * bytes() const
static sk_sp< SkData > MakeFromStream(SkStream *, size_t size)
void setFactoryId(SkTypeface::FactoryId factoryId)
sk_sp< SkDrawable > generateDrawable(const SkGlyph &glyph) override
void generateImage(const SkGlyph &glyph, void *imageBuffer) override
bool drawCOLRGlyph(const SkGlyph &glyph, SkColor foregroundColor, SkCanvas *canvas)
void generatePngImage(const SkGlyph &glyph, void *imageBuffer)
SkFontationsScalerContext(sk_sp< SkTypeface_Fontations > face, const SkScalerContextEffects &effects, const SkDescriptor *desc)
void generateFontMetrics(SkFontMetrics *out_metrics) override
bool generateYScalePathForGlyphId(uint16_t glyphId, SkPath *path, float yScale, const fontations_ffi::BridgeHintingInstance &hintingInstance)
GlyphMetrics generateMetrics(const SkGlyph &glyph, SkArenaAlloc *) override
bool generatePath(const SkGlyph &glyph, SkPath *path) override
uint16_t extraBits() const
SkGlyphID getGlyphID() const
const SkPath * path() const
SkMask::Format maskFormat() const
bool pathIsHairline() const
SkFixed getSubYFixed() const
SkFixed getSubXFixed() const
static sk_sp< SkShader > MakeTwoPointConical(const SkPoint &start, SkScalar startRadius, const SkPoint &end, SkScalar endRadius, const SkColor colors[], const SkScalar pos[], int count, SkTileMode mode, uint32_t flags=0, const SkMatrix *localMatrix=nullptr)
static sk_sp< SkShader > MakeSweep(SkScalar cx, SkScalar cy, const SkColor colors[], const SkScalar pos[], int count, SkTileMode mode, SkScalar startAngle, SkScalar endAngle, uint32_t flags, const SkMatrix *localMatrix)
static sk_sp< SkShader > MakeLinear(const SkPoint pts[2], const SkColor colors[], const SkScalar pos[], int count, SkTileMode mode, uint32_t flags=0, const SkMatrix *localMatrix=nullptr)
static SkMatrix Scale(SkScalar sx, SkScalar sy)
SkMatrix & postTranslate(SkScalar dx, SkScalar dy)
static SkMatrix MakeAll(SkScalar scaleX, SkScalar skewX, SkScalar transX, SkScalar skewY, SkScalar scaleY, SkScalar transY, SkScalar pers0, SkScalar pers1, SkScalar pers2)
void mapXY(SkScalar x, SkScalar y, SkPoint *result) const
SkMatrix & preConcat(const SkMatrix &other)
SkMatrix & preScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
void setColor(SkColor color)
@ kFill_Style
set to fill geometry
static SkPath Rect(const SkRect &, SkPathDirection=SkPathDirection::kCW, unsigned startIndex=0)
SkPath & moveTo(SkScalar x, SkScalar y)
SkPath & lineTo(SkScalar x, SkScalar y)
SkPath & quadTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2)
const SkRect & getBounds() const
SkPath & cubicTo(SkScalar x1, SkScalar y1, SkScalar x2, SkScalar y2, SkScalar x3, SkScalar y3)
void transform(const SkMatrix &matrix, SkPath *dst, SkApplyPerspectiveClip pc=SkApplyPerspectiveClip::kYes) const
static void GenerateImageFromPath(SkMaskBuilder &dst, const SkPath &path, const SkMaskGamma::PreBlend &maskPreBlend, bool doBGR, bool verticalLCD, bool a8FromLCD, bool hairline)
const SkMaskGamma::PreBlend fPreBlend
SkTypeface * getTypeface() const
bool isLinearMetrics() const
constexpr size_t size() const
const char * c_str() const
void onGetFontDescriptor(SkFontDescriptor *, bool *) const override
int onGetVariationDesignPosition(SkFontArguments::VariationPosition::Coordinate coordinates[], int coordinateCount) const override
static sk_sp< SkTypeface > MakeFromStream(std::unique_ptr< SkStreamAsset >, const SkFontArguments &)
int onCountGlyphs() const override
SkSpan< const SkColor > getPalette() const
int onGetUPEM() const override
void onCharsToGlyphs(const SkUnichar *chars, int count, SkGlyphID glyphs[]) const override
std::unique_ptr< SkAdvancedTypefaceMetrics > onGetAdvancedMetrics() const override
bool onGlyphMaskNeedsCurrentColor() const override
int onGetVariationDesignParameters(SkFontParameters::Variation::Axis parameters[], int parameterCount) const override
sk_sp< SkTypeface > onMakeClone(const SkFontArguments &args) const override
void onFilterRec(SkScalerContextRec *) const override
int onGetTableTags(SkFontTableTag tags[]) const override
void getGlyphToUnicodeMap(SkUnichar *) const override
std::unique_ptr< SkScalerContext > onCreateScalerContext(const SkScalerContextEffects &effects, const SkDescriptor *desc) const override
void onGetFamilyName(SkString *familyName) const override
static sk_sp< SkTypeface > MakeFromData(sk_sp< SkData > fontData, const SkFontArguments &)
size_t onGetTableData(SkFontTableTag, size_t, size_t, void *) const override
std::unique_ptr< SkStreamAsset > onOpenStream(int *ttcIndex) const override
bool onGetPostScriptName(SkString *) const override
SkTypeface::LocalizedStrings * onCreateFamilyNameIterator() const override
SkFontStyle fontStyle() const
void serialize(SkWStream *, SerializeBehavior=SerializeBehavior::kIncludeDataIfLocal) const
size_t getTableSize(SkFontTableTag) const
SkrifaLocalizedStrings(rust::Box<::fontations_ffi::BridgeLocalizedStrings > bridge_localized_strings)
bool next(SkTypeface::LocalizedString *localized_string) override
size_t size() const override
bool populate_axis(size_t i, uint32_t axisTag, float min, float def, float max, bool hidden) override
virtual void fill_glyph_radial(uint16_t glyph_id, const fontations_ffi::Transform &, const fontations_ffi::FillRadialParams &, fontations_ffi::BridgeColorStops &, uint8_t) override
virtual void push_transform(const fontations_ffi::Transform &transform) override
virtual void push_clip_rectangle(float x_min, float y_min, float x_max, float y_max) override
virtual void fill_glyph_linear(uint16_t glyph_id, const fontations_ffi::Transform &, const fontations_ffi::FillLinearParams &, fontations_ffi::BridgeColorStops &, uint8_t) override
virtual void fill_glyph_sweep(uint16_t glyph_id, const fontations_ffi::Transform &, const fontations_ffi::FillSweepParams &, fontations_ffi::BridgeColorStops &, uint8_t) override
virtual void pop_clip() override
virtual void fill_glyph_solid(uint16_t glyph_id, uint16_t, float) override
virtual void push_clip_glyph(uint16_t glyph_id) override
virtual void pop_transform() override
virtual void fill_radial(const fontations_ffi::FillRadialParams &fill_radial_params, fontations_ffi::BridgeColorStops &, uint8_t extend_mode) override
virtual void fill_glyph_radial(uint16_t glyph_id, const fontations_ffi::Transform &transform, const fontations_ffi::FillRadialParams &fill_radial_params, fontations_ffi::BridgeColorStops &stops, uint8_t) override
virtual void pop_clip() override
virtual void fill_glyph_linear(uint16_t glyph_id, const fontations_ffi::Transform &transform, const fontations_ffi::FillLinearParams &fill_linear_params, fontations_ffi::BridgeColorStops &stops, uint8_t) override
virtual void fill_solid(uint16_t palette_index, float alpha) override
virtual void fill_glyph_sweep(uint16_t glyph_id, const fontations_ffi::Transform &transform, const fontations_ffi::FillSweepParams &fill_sweep_params, fontations_ffi::BridgeColorStops &stops, uint8_t) override
virtual void pop_layer() override
virtual void push_layer(uint8_t compositeMode) override
virtual void pop_transform() override
virtual void fill_sweep(const fontations_ffi::FillSweepParams &fill_sweep_params, fontations_ffi::BridgeColorStops &, uint8_t extend_mode) override
virtual void fill_linear(const fontations_ffi::FillLinearParams &fill_linear_params, fontations_ffi::BridgeColorStops &, uint8_t extend_mode) override
virtual void fill_glyph_solid(uint16_t glyph_id, uint16_t palette_index, float alpha) override
virtual void push_clip_rectangle(float x_min, float y_min, float x_max, float y_max) override
virtual void push_transform(const fontations_ffi::Transform &transform) override
virtual void push_clip_glyph(uint16_t glyph_id) override
void line_to(float x, float y) override
void move_to(float x, float y) override
void curve_to(float cx0, float cy0, float cx1, float cy1, float x, float y) override
void quad_to(float cx0, float cy0, float x, float y) override
FlutterSemanticsFlag flag
FlutterSemanticsFlag flags
G_BEGIN_DECLS G_MODULE_EXPORT FlValue * args
uint32_t uint32_t * format
static float max(float r, float g, float b)
static float min(float r, float g, float b)
SK_API std::unique_ptr< SkCodec > Decode(std::unique_ptr< SkStream >, SkCodec::Result *, SkCodecs::DecodeContext=nullptr)
unsigned useCenter Optional< SkMatrix > matrix
Optional< SkRect > bounds
clipRect(r.rect, r.opAA.op(), r.opAA.aa())) template<> void Draw
PODArray< SkColor > colors
SkSamplingOptions sampling
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
const uint32_t extend_mode[]
skgpu::graphite::Transform Transform
static SkColor4f transform(SkColor4f c, SkColorSpace *src, SkColorSpace *dst)
@ kNotEmbeddable_FontFlag
May not be embedded.
@ kNotSubsettable_FontFlag
May not be subset.
@ kVariable_FontFlag
May be true for Type1, CFF, or TrueType fonts.
const Coordinate * coordinates
SkFontArguments & setVariationDesignPosition(VariationPosition position)
SkFontArguments & setPalette(Palette palette)
VariationPosition getVariationDesignPosition() const
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 const constexpr value_type COLRv1
static const constexpr value_type PATH
static const constexpr value_type COLRv0
static const constexpr value_type BITMAP
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)
static constexpr SkPoint Make(float x, float y)
void scale(float scale, SkPoint *dst) const
static SkRect Make(const SkISize &size)
static constexpr SkRect MakeEmpty()
void roundOut(SkIRect *dst) const
void join(const SkRect &r)
static constexpr SkRect MakeLTRB(float l, float t, float r, float b)
void getSingleMatrix(SkMatrix *) 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
static SKVX_ALWAYS_INLINE Vec Load(const void *ptr)
std::shared_ptr< const fml::Mapping > data