Flutter Engine
The Flutter Engine
Classes | Public Member Functions | Protected Member Functions | Friends | List of all members
SkFontationsScalerContext Class Reference
Inheritance diagram for SkFontationsScalerContext:
SkScalerContext

Classes

struct  ScalerContextBits
 

Public Member Functions

 SkFontationsScalerContext (sk_sp< SkTypeface_Fontations > face, const SkScalerContextEffects &effects, const SkDescriptor *desc)
 
bool generateYScalePathForGlyphId (uint16_t glyphId, SkPath *path, float yScale, const fontations_ffi::BridgeHintingInstance &hintingInstance)
 
- Public Member Functions inherited from SkScalerContext
 SkScalerContext (sk_sp< SkTypeface >, const SkScalerContextEffects &, const SkDescriptor *)
 
virtual ~SkScalerContext ()
 
SkTypefacegetTypeface () const
 
SkMask::Format getMaskFormat () const
 
bool isSubpixel () const
 
bool isLinearMetrics () const
 
bool isVertical () const
 
SkGlyph makeGlyph (SkPackedGlyphID, SkArenaAlloc *)
 
void getImage (const SkGlyph &)
 
void getPath (SkGlyph &, SkArenaAlloc *)
 
sk_sp< SkDrawablegetDrawable (SkGlyph &)
 
void getFontMetrics (SkFontMetrics *)
 
const SkScalerContextRecgetRec () const
 
SkScalerContextEffects getEffects () const
 
SkAxisAlignment computeAxisAlignmentForHText () const
 

Protected Member Functions

GlyphMetrics generateMetrics (const SkGlyph &glyph, SkArenaAlloc *) override
 
void generatePngImage (const SkGlyph &glyph, void *imageBuffer)
 
void generateImage (const SkGlyph &glyph, void *imageBuffer) override
 
bool generatePath (const SkGlyph &glyph, SkPath *path) override
 
bool drawCOLRGlyph (const SkGlyph &glyph, SkColor foregroundColor, SkCanvas *canvas)
 
sk_sp< SkDrawablegenerateDrawable (const SkGlyph &glyph) override
 
void generateFontMetrics (SkFontMetrics *out_metrics) override
 
- Protected Member Functions inherited from SkScalerContext
virtual GlyphMetrics generateMetrics (const SkGlyph &, SkArenaAlloc *)=0
 
virtual void generateImage (const SkGlyph &glyph, void *imageBuffer)=0
 
virtual bool generatePath (const SkGlyph &, SkPath *)=0
 
virtual sk_sp< SkDrawablegenerateDrawable (const SkGlyph &)
 
virtual void generateFontMetrics (SkFontMetrics *)=0
 
void forceGenerateImageFromPath ()
 
void forceOffGenerateImageFromPath ()
 

Friends

class sk_fontations::ColorPainter
 

Additional Inherited Members

- Public Types inherited from SkScalerContext
enum  Flags {
  kFrameAndFill_Flag = 0x0001 , kUnused = 0x0002 , kEmbeddedBitmapText_Flag = 0x0004 , kEmbolden_Flag = 0x0008 ,
  kSubpixelPositioning_Flag = 0x0010 , kForceAutohinting_Flag = 0x0020 , kHinting_Shift = 7 , kHintingBit1_Flag = 0x0080 ,
  kHintingBit2_Flag = 0x0100 , kLCD_Vertical_Flag = 0x0200 , kLCD_BGROrder_Flag = 0x0400 , kGenA8FromLCD_Flag = 0x0800 ,
  kLinearMetrics_Flag = 0x1000 , kBaselineSnap_Flag = 0x2000 , kNeedsForegroundColor_Flag = 0x4000
}
 
enum  { kHinting_Mask = kHintingBit1_Flag | kHintingBit2_Flag }
 
- Static Public Member Functions inherited from SkScalerContext
static size_t GetGammaLUTSize (SkScalar contrast, SkScalar deviceGamma, int *width, int *height)
 
static bool GetGammaLUTData (SkScalar contrast, SkScalar deviceGamma, uint8_t *data)
 
static void MakeRecAndEffects (const SkFont &font, const SkPaint &paint, const SkSurfaceProps &surfaceProps, SkScalerContextFlags scalerContextFlags, const SkMatrix &deviceMatrix, SkScalerContextRec *rec, SkScalerContextEffects *effects)
 
static void MakeRecAndEffectsFromFont (const SkFont &font, SkScalerContextRec *rec, SkScalerContextEffects *effects)
 
static std::unique_ptr< SkScalerContextMakeEmpty (sk_sp< SkTypeface > typeface, const SkScalerContextEffects &effects, const SkDescriptor *desc)
 
static SkDescriptorAutoDescriptorGivenRecAndEffects (const SkScalerContextRec &rec, const SkScalerContextEffects &effects, SkAutoDescriptor *ad)
 
static std::unique_ptr< SkDescriptorDescriptorGivenRecAndEffects (const SkScalerContextRec &rec, const SkScalerContextEffects &effects)
 
static void DescriptorBufferGiveRec (const SkScalerContextRec &rec, void *buffer)
 
static bool CheckBufferSizeForRec (const SkScalerContextRec &rec, const SkScalerContextEffects &effects, size_t size)
 
static SkMaskGamma::PreBlend GetMaskPreBlend (const SkScalerContextRec &rec)
 
static SkDescriptorCreateDescriptorAndEffectsUsingPaint (const SkFont &, const SkPaint &, const SkSurfaceProps &, SkScalerContextFlags scalerContextFlags, const SkMatrix &deviceMatrix, SkAutoDescriptor *ad, SkScalerContextEffects *effects)
 
- Static Protected Member Functions inherited from SkScalerContext
static void GenerateMetricsFromPath (SkGlyph *glyph, const SkPath &path, SkMask::Format format, bool verticalLCD, bool a8FromLCD, bool hairline)
 
static void SaturateGlyphBounds (SkGlyph *glyph, SkRect &&)
 
static void SaturateGlyphBounds (SkGlyph *glyph, SkIRect const &)
 
static void GenerateImageFromPath (SkMaskBuilder &dst, const SkPath &path, const SkMaskGamma::PreBlend &maskPreBlend, bool doBGR, bool verticalLCD, bool a8FromLCD, bool hairline)
 
- Protected Attributes inherited from SkScalerContext
SkScalerContextRec fRec
 
const SkMaskGamma::PreBlend fPreBlend
 

Detailed Description

Definition at line 354 of file SkTypeface_fontations.cpp.

Constructor & Destructor Documentation

◆ SkFontationsScalerContext()

SkFontationsScalerContext::SkFontationsScalerContext ( sk_sp< SkTypeface_Fontations face,
const SkScalerContextEffects effects,
const SkDescriptor desc 
)
inline

Definition at line 356 of file SkTypeface_fontations.cpp.

359 : SkScalerContext(face, effects, desc)
360 , fBridgeFontRef(
361 static_cast<SkTypeface_Fontations*>(this->getTypeface())->getBridgeFontRef())
362 , fBridgeNormalizedCoords(static_cast<SkTypeface_Fontations*>(this->getTypeface())
363 ->getBridgeNormalizedCoords())
364 , fOutlines(static_cast<SkTypeface_Fontations*>(this->getTypeface())->getOutlines())
365 , fPalette(static_cast<SkTypeface_Fontations*>(this->getTypeface())->getPalette())
366 , fHintingInstance(fontations_ffi::no_hinting_instance()) {
367 fRec.getSingleMatrix(&fMatrix);
368
370 SkMatrix remainingMatrix;
373
374 fDoLinearMetrics = this->isLinearMetrics();
377 fHintingInstance = fontations_ffi::no_hinting_instance();
378 fDoLinearMetrics = true;
379 } else {
380 fHintingInstance = fontations_ffi::make_mono_hinting_instance(
381 fOutlines, scale.fY, fBridgeNormalizedCoords);
382 fDoLinearMetrics = false;
383 }
384 } else {
385 switch (fRec.getHinting()) {
387 fHintingInstance = fontations_ffi::no_hinting_instance();
388 fDoLinearMetrics = true;
389 break;
391 // Unhinted metrics.
392 fHintingInstance = fontations_ffi::make_hinting_instance(
393 fOutlines,
394 scale.fY,
395 fBridgeNormalizedCoords,
396 false /* do_lcd_antialiasing */,
397 false /* lcd_orientation_vertical */,
398 true /* preserve_linear_metrics */);
399 fDoLinearMetrics = true;
400 break;
402 // No hinting to subpixel coordinates.
403 fHintingInstance = fontations_ffi::make_hinting_instance(
404 fOutlines,
405 scale.fY,
406 fBridgeNormalizedCoords,
407 false /* do_lcd_antialiasing */,
408 false /* lcd_orientation_vertical */,
409 fDoLinearMetrics /* preserve_linear_metrics */);
410 break;
412 // Attempt to make use of hinting to subpixel coordinates.
413 fHintingInstance = fontations_ffi::make_hinting_instance(
414 fOutlines,
415 scale.fY,
416 fBridgeNormalizedCoords,
417 isLCD(fRec) /* do_lcd_antialiasing */,
420 kLCD_Vertical_Flag) /* lcd_orientation_vertical */,
421 fDoLinearMetrics /* preserve_linear_metrics */);
422 }
423 }
424 }
static bool isLCD(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
static constexpr bool SkToBool(const T &x)
Definition: SkTo.h:35
SkScalerContext(sk_sp< SkTypeface >, const SkScalerContextEffects &, const SkDescriptor *)
SkScalerContextRec fRec
SkTypeface * getTypeface() const
bool isLinearMetrics() const
const Scalar scale
@ kBW_Format
1bit per pixel mask (e.g. monochrome)
Definition: SkMask.h:27
void getSingleMatrix(SkMatrix *) const
SkMask::Format fMaskFormat
bool computeMatrices(PreMatrixScale preMatrixScale, SkVector *scale, SkMatrix *remaining, SkMatrix *remainingWithoutRotation=nullptr, SkMatrix *remainingRotation=nullptr, SkMatrix *total=nullptr)
SkFontHinting getHinting() const

Member Function Documentation

◆ drawCOLRGlyph()

bool SkFontationsScalerContext::drawCOLRGlyph ( const SkGlyph glyph,
SkColor  foregroundColor,
SkCanvas canvas 
)
inlineprotected

Definition at line 744 of file SkTypeface_fontations.cpp.

744 {
745 uint16_t upem = fontations_ffi::units_per_em_or_zero(fBridgeFontRef);
746 if (upem == 0) {
747 return false;
748 }
749
750 SkMatrix scalerMatrix;
751 fRec.getSingleMatrix(&scalerMatrix);
752 SkAutoCanvasRestore autoRestore(canvas, true /* doSave */);
753
754 // Scale down so that COLR operations can happen in glyph coordinates.
755 SkMatrix upemToPpem = SkMatrix::Scale(1.f / upem, 1.f / upem);
756 scalerMatrix.preConcat(upemToPpem);
757 canvas->concat(scalerMatrix);
758 SkPaint defaultPaint;
759 defaultPaint.setColor(SK_ColorRED);
760 sk_fontations::ColorPainter colorPainter(*this, *canvas, fPalette, foregroundColor,
762 bool result = fontations_ffi::draw_colr_glyph(
763 fBridgeFontRef, fBridgeNormalizedCoords, glyph.getGlyphID(), colorPainter);
764 return result;
765 }
constexpr SkColor SK_ColorRED
Definition: SkColor.h:126
void concat(const SkMatrix &matrix)
Definition: SkCanvas.cpp:1318
SkGlyphID getGlyphID() const
Definition: SkGlyph.h:429
static SkMatrix Scale(SkScalar sx, SkScalar sy)
Definition: SkMatrix.h:75
SkMatrix & preConcat(const SkMatrix &other)
Definition: SkMatrix.cpp:674
void setColor(SkColor color)
Definition: SkPaint.cpp:119
GAsyncResult * result

◆ generateDrawable()

sk_sp< SkDrawable > SkFontationsScalerContext::generateDrawable ( const SkGlyph )
inlineoverrideprotectedvirtual

Returns the drawable for the glyph (if any).

The generated drawable will be lifetime scoped to the lifetime of this scaler context. This means the drawable may refer to the scaler context and associated font data.

The drawable does not need to be flattenable (e.g. implement getFactory and getTypeName). Any necessary serialization will be done with makePictureSnapshot.

Reimplemented from SkScalerContext.

Definition at line 767 of file SkTypeface_fontations.cpp.

767 {
768 struct GlyphDrawable : public SkDrawable {
770 SkGlyph fGlyph;
771 GlyphDrawable(SkFontationsScalerContext* self, const SkGlyph& glyph)
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);
779 paint.setStyle(SkPaint::kFill_Style);
780 canvas->drawRect(this->onGetBounds(), paint);
781 }
782 }
783 };
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);
789 }
790 };
791 ScalerContextBits::value_type format = glyph.extraBits();
793 return sk_sp<SkDrawable>(new ColrGlyphDrawable(this, glyph));
794 }
795 return nullptr;
796 }
void drawRect(const SkRect &rect, const SkPaint &paint)
Definition: SkCanvas.cpp:1673
bool drawCOLRGlyph(const SkGlyph &glyph, SkColor foregroundColor, SkCanvas *canvas)
SkRect rect() const
Definition: SkGlyph.h:506
@ kFill_Style
set to fill geometry
Definition: SkPaint.h:193
const Paint & paint
Definition: color_source.cc:38
uint32_t uint32_t * format

◆ generateFontMetrics()

void SkFontationsScalerContext::generateFontMetrics ( SkFontMetrics )
inlineoverrideprotectedvirtual

Retrieves font metrics.

Implements SkScalerContext.

Definition at line 798 of file SkTypeface_fontations.cpp.

798 {
800 SkMatrix remainingMatrix;
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;
810 out_metrics->fAvgCharWidth = metrics.avg_char_width;
811 out_metrics->fMaxCharWidth = metrics.max_char_width;
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;
816 out_metrics->fFlags = 0;
817 if (fontations_ffi::table_data(fBridgeFontRef,
818 SkSetFourByteTag('f', 'v', 'a', 'r'),
819 0,
820 rust::Slice<uint8_t>())) {
821 out_metrics->fFlags |= SkFontMetrics::kBoundsInvalid_Flag;
822 }
823 auto setMetric = [](float& dstMetric, const float srcMetric,
825 {
826 if (std::isnan(srcMetric)) {
827 dstMetric = 0;
828 } else {
829 dstMetric = srcMetric;
830 flags |= flag;
831 }
832 };
833 setMetric(out_metrics->fUnderlinePosition, -metrics.underline_position,
835 setMetric(out_metrics->fUnderlineThickness, metrics.underline_thickness,
837
838 setMetric(out_metrics->fStrikeoutPosition, -metrics.strikeout_position,
840 setMetric(out_metrics->fStrikeoutThickness, metrics.strikeout_thickness,
842 }
static constexpr SkFourByteTag SkSetFourByteTag(char a, char b, char c, char d)
Definition: SkTypes.h:167
FlutterSemanticsFlag flag
FlutterSemanticsFlag flags
@ kStrikeoutPositionIsValid_Flag
set if fStrikeoutPosition is valid
Definition: SkFontMetrics.h:48
@ kStrikeoutThicknessIsValid_Flag
set if fStrikeoutThickness is valid
Definition: SkFontMetrics.h:47
@ kUnderlinePositionIsValid_Flag
set if fUnderlinePosition is valid
Definition: SkFontMetrics.h:46
@ kUnderlineThicknessIsValid_Flag
set if fUnderlineThickness is valid
Definition: SkFontMetrics.h:45
@ kBoundsInvalid_Flag
set if fTop, fBottom, fXMin, fXMax invalid
Definition: SkFontMetrics.h:49

◆ generateImage()

void SkFontationsScalerContext::generateImage ( const SkGlyph glyph,
void *  imageBuffer 
)
inlineoverrideprotectedvirtual

Generates the contents of glyph.fImage. When called, glyph.fImage will be pointing to a pre-allocated, uninitialized region of memory of size glyph.imageSize(). This method may not change glyph.fMaskFormat.

Because glyph.imageSize() will determine the size of fImage, generateMetrics will be called before generateImage.

Implements SkScalerContext.

Definition at line 684 of file SkTypeface_fontations.cpp.

684 {
687 const SkPath* devPath = glyph.path();
688 SkASSERT_RELEASE(devPath);
689 SkMaskBuilder mask(static_cast<uint8_t*>(imageBuffer),
690 glyph.iRect(),
691 glyph.rowBytes(),
692 glyph.maskFormat());
693 SkASSERT(SkMask::kARGB32_Format != mask.fFormat);
697 const bool hairline = glyph.pathIsHairline();
698 GenerateImageFromPath(mask, *devPath, fPreBlend, doBGR, doVert, a8LCD, hairline);
699
702 SkBitmap dstBitmap;
703 dstBitmap.setInfo(
705 glyph.width(), glyph.height(), kN32_SkColorType, kPremul_SkAlphaType),
706 glyph.rowBytes());
707 dstBitmap.setPixels(imageBuffer);
708
709 SkCanvas canvas(dstBitmap);
710 if constexpr (kSkShowTextBlitCoverage) {
711 canvas.clear(0x33FF0000);
712 } else {
713 canvas.clear(SK_ColorTRANSPARENT);
714 }
715 canvas.translate(-glyph.left(), -glyph.top());
716
717 drawCOLRGlyph(glyph, fRec.fForegroundColor, &canvas);
718 } else if (format == ScalerContextBits::BITMAP) {
719 generatePngImage(glyph, imageBuffer);
720 } else {
721 SK_ABORT("Bad format");
722 }
723 }
@ kPremul_SkAlphaType
pixel components are premultiplied by alpha
Definition: SkAlphaType.h:29
#define SK_ABORT(message,...)
Definition: SkAssert.h:70
#define SkASSERT_RELEASE(cond)
Definition: SkAssert.h:100
#define SkASSERT(cond)
Definition: SkAssert.h:116
constexpr SkColor SK_ColorTRANSPARENT
Definition: SkColor.h:99
void setPixels(void *pixels)
Definition: SkBitmap.cpp:207
bool setInfo(const SkImageInfo &imageInfo, size_t rowBytes=0)
Definition: SkBitmap.cpp:114
void generatePngImage(const SkGlyph &glyph, void *imageBuffer)
int top() const
Definition: SkGlyph.h:511
size_t rowBytes() const
Definition: SkGlyph.cpp:233
uint16_t extraBits() const
Definition: SkGlyph.h:519
const SkPath * path() const
Definition: SkGlyph.cpp:284
SkMask::Format maskFormat() const
Definition: SkGlyph.h:500
bool pathIsHairline() const
Definition: SkGlyph.cpp:293
int height() const
Definition: SkGlyph.h:513
SkIRect iRect() const
Definition: SkGlyph.h:505
int width() const
Definition: SkGlyph.h:512
int left() const
Definition: SkGlyph.h:510
Definition: SkPath.h:59
static void GenerateImageFromPath(SkMaskBuilder &dst, const SkPath &path, const SkMaskGamma::PreBlend &maskPreBlend, bool doBGR, bool verticalLCD, bool a8FromLCD, bool hairline)
const SkMaskGamma::PreBlend fPreBlend
static SkImageInfo Make(int width, int height, SkColorType ct, SkAlphaType at)
@ kARGB32_Format
SkPMColor.
Definition: SkMask.h:30

◆ generateMetrics()

GlyphMetrics SkFontationsScalerContext::generateMetrics ( const SkGlyph glyph,
SkArenaAlloc  
)
inlineoverrideprotectedvirtual

Implements SkScalerContext.

Definition at line 466 of file SkTypeface_fontations.cpp.

466 {
467 GlyphMetrics mx(glyph.maskFormat());
468
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());
475
476 // Local overrides for color fonts etc. may alter the request for linear metrics.
477 bool doLinearMetrics = fDoLinearMetrics;
478
479 if (has_bitmap_glyph) {
480 // Bitmap advance metrics can originate from different strike sizes in the bitmap
481 // font and are thus not linearly scaling with font size.
482 doLinearMetrics = false;
483 }
484 if (has_colrv0_glyph || has_colrv1_glyph) {
485 // We prefer color vector glyphs, and hinting is disabled for those.
486 doLinearMetrics = true;
487 }
488
490 SkMatrix remainingMatrix;
493 return mx;
494 }
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);
502 // TODO(drott): Remove this workaround for fontations returning 0
503 // for a space glyph without contours, compare
504 // https://github.com/googlefonts/fontations/issues/905
505 if (hinted_advance != x_advance && hinted_advance != 0) {
506 x_advance = hinted_advance;
507 }
508 }
509 mx.advance = remainingMatrix.mapXY(x_advance, SkFloatToScalar(0.f));
510
511 if (has_colrv1_glyph || has_colrv0_glyph) {
512 mx.extraBits = has_colrv1_glyph ? ScalerContextBits::COLRv1 : ScalerContextBits::COLRv0;
513 mx.maskFormat = SkMask::kARGB32_Format;
514 mx.neverRequestPath = true;
515
516 fontations_ffi::ClipBox clipBox;
517 if (has_colrv1_glyph && fontations_ffi::get_colrv1_clip_box(fBridgeFontRef,
518 fBridgeNormalizedCoords,
519 glyph.getGlyphID(),
520 scale.y(),
521 clipBox)) {
522 // Flip y.
523 SkRect boundsRect = SkRect::MakeLTRB(
524 clipBox.x_min, -clipBox.y_max, clipBox.x_max, -clipBox.y_min);
525
526 if (!remainingMatrix.isIdentity()) {
527 SkPath boundsPath = SkPath::Rect(boundsRect);
528 boundsPath.transform(remainingMatrix);
529 boundsRect = boundsPath.getBounds();
530 }
531
532 boundsRect.roundOut(&mx.bounds);
533
534 } else {
535 uint16_t upem = fontations_ffi::units_per_em_or_zero(fBridgeFontRef);
536 if (upem == 0) {
537 mx.bounds = SkRect::MakeEmpty();
538 } else {
539 SkMatrix fullTransform;
540 fRec.getSingleMatrix(&fullTransform);
541 fullTransform.preScale(1.f / upem, 1.f / upem);
542
543 sk_fontations::BoundsPainter boundsPainter(*this, fullTransform, upem);
544 bool result = fontations_ffi::draw_colr_glyph(fBridgeFontRef,
545 fBridgeNormalizedCoords,
546 glyph.getGlyphID(),
547 boundsPainter);
548 if (result) {
549 boundsPainter.getBoundingBox().roundOut(&mx.bounds);
550 } else {
551 mx.bounds = SkRect::MakeEmpty();
552 }
553 }
554 }
555 } else if (has_bitmap_glyph) {
556 mx.maskFormat = SkMask::kARGB32_Format;
557 mx.neverRequestPath = true;
558 mx.extraBits = ScalerContextBits::BITMAP;
559
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);
564 SkASSERT(png_data.size());
565
566 const fontations_ffi::BitmapMetrics bitmapMetrics =
567 fontations_ffi::bitmap_metrics(*bitmap_glyph);
568
569 std::unique_ptr<SkCodec> codec = SkPngDecoder::Decode(
570 SkData::MakeWithoutCopy(png_data.data(), png_data.size()), nullptr);
571 if (!codec) {
572 return mx;
573 }
574
575 SkImageInfo info = codec->getInfo();
576
577 SkRect bounds = SkRect::Make(info.bounds());
578 SkMatrix matrix = remainingMatrix;
579
580 // We deal with two scale factors here: Scaling from font units to
581 // device pixels, and scaling the embedded PNG from its number of
582 // rows to a specific size, depending on the ppem values in the
583 // bitmap glyph information.
584 SkScalar imageToSize = scale.fY / bitmapMetrics.ppem_y;
585 float fontUnitsToSize = scale.fY / fontations_ffi::units_per_em_or_zero(fBridgeFontRef);
586
587 // The offset from origin is given in font units, so requires a
588 // different scale factor than the scaling of the image.
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);
594
595 // For sbix bitmap glyphs, the origin is the bottom left of the image.
596 float heightAdjustment =
597 bitmapMetrics.placement_origin_bottom_left ? bounds.height() : 0;
598 matrix.preTranslate(0, -heightAdjustment);
599
600 if (this->isSubpixel()) {
603 }
604 matrix.mapRect(&bounds);
605 mx.bounds = SkRect::Make(bounds.roundOut());
606
607 if (SkIsFinite(bitmapMetrics.advance)) {
608 mx.advance = matrix.mapVector(bitmapMetrics.advance, 0);
609 }
610 } else {
611 mx.extraBits = ScalerContextBits::PATH;
612 mx.computeFromPath = true;
613 }
614 return mx;
615 }
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
Definition: DM.cpp:213
#define SkFixedToScalar(x)
Definition: SkFixed.h:124
static bool SkIsFinite(T x, Pack... values)
#define SkFloatToScalar(x)
Definition: SkScalar.h:62
static sk_sp< SkData > MakeWithoutCopy(const void *data, size_t length)
Definition: SkData.h:116
SkFixed getSubYFixed() const
Definition: SkGlyph.h:432
SkFixed getSubXFixed() const
Definition: SkGlyph.h:431
SkMatrix & postTranslate(SkScalar dx, SkScalar dy)
Definition: SkMatrix.cpp:281
void mapXY(SkScalar x, SkScalar y, SkPoint *result) const
Definition: SkMatrix.cpp:777
SkMatrix & preScale(SkScalar sx, SkScalar sy, SkScalar px, SkScalar py)
Definition: SkMatrix.cpp:315
bool isIdentity() const
Definition: SkMatrix.h:223
static SkPath Rect(const SkRect &, SkPathDirection=SkPathDirection::kCW, unsigned startIndex=0)
Definition: SkPath.cpp:3586
const SkRect & getBounds() const
Definition: SkPath.cpp:430
void transform(const SkMatrix &matrix, SkPath *dst, SkApplyPerspectiveClip pc=SkApplyPerspectiveClip::kYes) const
Definition: SkPath.cpp:1711
bool isSubpixel() const
float SkScalar
Definition: extension.cpp:12
SK_API std::unique_ptr< SkCodec > Decode(std::unique_ptr< SkStream >, SkCodec::Result *, SkCodecs::DecodeContext=nullptr)
unsigned useCenter Optional< SkMatrix > matrix
Definition: SkRecords.h:258
Optional< SkRect > bounds
Definition: SkRecords.h:189
static SkRect Make(const SkISize &size)
Definition: SkRect.h:669
static constexpr SkRect MakeEmpty()
Definition: SkRect.h:595
void roundOut(SkIRect *dst) const
Definition: SkRect.h:1241
static constexpr SkRect MakeLTRB(float l, float t, float r, float b)
Definition: SkRect.h:646

◆ generatePath()

bool SkFontationsScalerContext::generatePath ( const SkGlyph ,
SkPath  
)
inlineoverrideprotectedvirtual

Sets the passed path to the glyph outline. If this cannot be done the path is set to empty; Does not apply subpixel positioning to the path.

Returns
false if this glyph does not have any path.

Implements SkScalerContext.

Definition at line 725 of file SkTypeface_fontations.cpp.

725 {
726 SkASSERT(glyph.extraBits() == ScalerContextBits::PATH);
727
729 SkMatrix remainingMatrix;
732 return false;
733 }
735 glyph.getGlyphID(), path, scale.y(), *fHintingInstance);
736 if (!result) {
737 return false;
738 }
739
740 *path = path->makeTransform(remainingMatrix);
741 return true;
742 }
bool generateYScalePathForGlyphId(uint16_t glyphId, SkPath *path, float yScale, const fontations_ffi::BridgeHintingInstance &hintingInstance)
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
Definition: switches.h:57

◆ generatePngImage()

void SkFontationsScalerContext::generatePngImage ( const SkGlyph glyph,
void *  imageBuffer 
)
inlineprotected

Definition at line 617 of file SkTypeface_fontations.cpp.

617 {
619 SkBitmap dstBitmap;
620 dstBitmap.setInfo(
622 glyph.width(), glyph.height(), kN32_SkColorType, kPremul_SkAlphaType),
623 glyph.rowBytes());
624 dstBitmap.setPixels(imageBuffer);
625
626 SkCanvas canvas(dstBitmap);
627
628 canvas.translate(-glyph.left(), -glyph.top());
629
631 SkMatrix remainingMatrix;
634 return;
635 }
636
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);
640 SkASSERT(png_data.size());
641
642 std::unique_ptr<SkCodec> codec = SkPngDecoder::Decode(
643 SkData::MakeWithoutCopy(png_data.data(), png_data.size()), nullptr);
644
645 if (!codec) {
646 return;
647 }
648
649 auto [glyph_image, result] = codec->getImage();
651 return;
652 }
653
654 canvas.clear(SK_ColorTRANSPARENT);
655 canvas.concat(remainingMatrix);
656
657 if (this->isSubpixel()) {
658 canvas.translate(SkFixedToScalar(glyph.getSubXFixed()),
660 }
661 const fontations_ffi::BitmapMetrics bitmapMetrics =
662 fontations_ffi::bitmap_metrics(*bitmap_glyph);
663
664 // We need two different scale factors here, one for font units to size,
665 // one for scaling the embedded PNG, see generateMetrics() for details.
666 SkScalar imageScaleFactor = scale.fY / bitmapMetrics.ppem_y;
667
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);
674
675 float heightAdjustment =
676 bitmapMetrics.placement_origin_bottom_left ? glyph_image->height() : 0;
677
678 canvas.translate(0, -heightAdjustment);
679
681 canvas.drawImage(glyph_image, 0, 0, sampling);
682 }
@ kSuccess
Definition: embedder.h:73
SkSamplingOptions sampling
Definition: SkRecords.h:337

◆ generateYScalePathForGlyphId()

bool SkFontationsScalerContext::generateYScalePathForGlyphId ( uint16_t  glyphId,
SkPath path,
float  yScale,
const fontations_ffi::BridgeHintingInstance &  hintingInstance 
)
inline

Definition at line 430 of file SkTypeface_fontations.cpp.

434 {
436 fontations_ffi::BridgeScalerMetrics scalerMetrics;
437
438 if (!fontations_ffi::get_path(fOutlines,
439 glyphId,
440 yScale,
441 fBridgeNormalizedCoords,
442 hintingInstance,
443 pathWrapper,
444 scalerMetrics)) {
445 return false;
446 }
447 *path = std::move(pathWrapper).into_inner();
448
449 // See https://issues.skia.org/345178242 for details:
450 // The FreeType backend performs a path simplification here based on the
451 // equivalent of what we have here as scalerMetrics.has_overlaps
452 // Since PathOps::Simplify fails or at times produces incorrect simplified
453 // contours, skip that step here.
454 return true;
455 }
static SkPath get_path()
Definition: bug12866.cpp:14

Friends And Related Function Documentation

◆ sk_fontations::ColorPainter

friend class sk_fontations::ColorPainter
friend

Definition at line 854 of file SkTypeface_fontations.cpp.


The documentation for this class was generated from the following file: