class SkArenaAlloc; class SkMatrix; class SkPaint; class SkShader; class SkSurfaceProps; struct SkMask; enumclass SkDrawCoverage : bool;
/** SkBlitter and its subclasses are responsible for actually writing pixels intomemory.Besidesefficiency,theyhandleclippingandantialiasing. ASkBlittersubclasscontainsallthecontextneededtogeneratepixels forthedestinationandhowsrc/generatedpixelsmaptothedestination. ThecoordinatespassedtotheblitXcallsareindestinationpixelspace.
*/ class SkBlitter {
public:
virtual ~SkBlitter();
SkBlitter() = default;
SkBlitter(const SkBlitter&) = delete;
SkBlitter(SkBlitter&&) = delete;
SkBlitter& operator=(const SkBlitter&) = delete;
SkBlitter& operator=(SkBlitter&&) = delete;
/// Blit a horizontal run of one or more pixels.
virtual void blitH(int x, int y, int width) = 0;
/// Blit a horizontal run of antialiased pixels; runs[] is a *sparse* /// zero-terminated run-length encoding of spans of constant alpha values. /// The runs[] and antialias[] work together to represent long runs of pixels with the same /// alphas. The runs[] contains the number of pixels with the same alpha, and antialias[] /// contain the coverage value for that number of pixels. The runs[] (and antialias[]) are /// encoded in a clever way. The runs array is zero terminated, and has enough entries for /// each pixel plus one, in most cases some of the entries will not contain valid data. An entry /// in the runs array contains the number of pixels (np) that have the same alpha value. The /// next np value is found np entries away. For example, if runs[0] = 7, then the next valid /// entry will by at runs[7]. The runs array and antialias[] are coupled by index. So, if the /// np entry is at runs[45] = 12 then the alpha value can be found at antialias[45] = 0x88. /// This would mean to use an alpha value of 0x88 for the next 12 pixels starting at pixel 45.
virtual void blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[]) = 0;
/// Blit a vertical run of pixels with a constant alpha value.
virtual void blitV(int x, int y, int height, SkAlpha alpha);
/// Blit a solid rectangle one or more pixels wide.
virtual void blitRect(int x, int y, int width, int height);
/** Blit a rectangle with one alpha-blended column on the left, width(zeroormore)opaquepixels,andonealpha-blendedcolumn ontheright. Theresultwillalwaysbeatleasttwopixelswide.
*/
virtual void blitAntiRect(int x, int y, int width, int height,
SkAlpha leftAlpha, SkAlpha rightAlpha);
// Blit a rect in AA with size at least 3 x 3 (small rect has too many edge cases...) void blitFatAntiRect(const SkRect& rect);
/// Blit a pattern of pixels defined by a rectangle-clipped mask; /// typically used for text.
virtual void blitMask(const SkMask&, const SkIRect& clip);
/** This blitter silently never draws anything.
*/ class SkNullBlitter final : public SkBlitter {
public: void blitH(int x, int y, int width) override {} void blitAntiH(int x, int y, const SkAlpha[], const int16_t runs[]) override {} void blitV(int x, int y, int height, SkAlpha alpha) override {} void blitRect(int x, int y, int width, int height) override {} void blitMask(const SkMask&, const SkIRect& clip) override {}
};
/** Wraps another (real) blitter, and ensures that the real blitter is only calledwithcoordinatesthathavebeenclippedbythespecifiedclipRect. Thismeansthecallerneednotperformtheclippingaheadoftime.
*/ class SkRectClipBlitter final : public SkBlitter {
public: void init(SkBlitter* blitter, const SkIRect& clipRect) {
SkASSERT(!clipRect.isEmpty());
fBlitter = blitter;
fClipRect = clipRect;
}
void blitH(int x, int y, int width) override; void blitAntiH(int x, int y, const SkAlpha[], const int16_t runs[]) override; void blitV(int x, int y, int height, SkAlpha alpha) override; void blitRect(int x, int y, int width, int height) override; void blitAntiRect(int x, int y, int width, int height,
SkAlpha leftAlpha, SkAlpha rightAlpha) override; void blitMask(const SkMask&, const SkIRect& clip) override;
int requestRowsPreserved() const override { return fBlitter->requestRowsPreserved();
}
/** Wraps another (real) blitter, and ensures that the real blitter is only calledwithcoordinatesthathavebeenclippedbythespecifiedclipRgn. Thismeansthecallerneednotperformtheclippingaheadoftime.
*/ class SkRgnClipBlitter final : public SkBlitter {
public: void init(SkBlitter* blitter, const SkRegion* clipRgn) {
SkASSERT(clipRgn && !clipRgn->isEmpty());
fBlitter = blitter;
fRgn = clipRgn;
}
void blitH(int x, int y, int width) override; void blitAntiH(int x, int y, const SkAlpha[], const int16_t runs[]) override; void blitV(int x, int y, int height, SkAlpha alpha) override; void blitRect(int x, int y, int width, int height) override; void blitAntiRect(int x, int y, int width, int height,
SkAlpha leftAlpha, SkAlpha rightAlpha) override; void blitMask(const SkMask&, const SkIRect& clip) override;
int requestRowsPreserved() const override { return fBlitter->requestRowsPreserved();
}
#ifdef SK_DEBUG class SkRectClipCheckBlitter final : public SkBlitter {
public: void init(SkBlitter* blitter, const SkIRect& clipRect) {
SkASSERT(blitter);
SkASSERT(!clipRect.isEmpty());
fBlitter = blitter;
fClipRect = clipRect;
}
void blitH(int x, int y, int width) override; void blitAntiH(int x, int y, const SkAlpha[], const int16_t runs[]) override; void blitV(int x, int y, int height, SkAlpha alpha) override; void blitRect(int x, int y, int width, int height) override; void blitAntiRect(int x, int y, int width, int height,
SkAlpha leftAlpha, SkAlpha rightAlpha) override; void blitMask(const SkMask&, const SkIRect& clip) override; void blitAntiH2(int x, int y, U8CPU a0, U8CPU a1) override; void blitAntiV2(int x, int y, U8CPU a0, U8CPU a1) override;
int requestRowsPreserved() const override { return fBlitter->requestRowsPreserved();
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.