michael@0: michael@0: /* michael@0: * Copyright 2006 The Android Open Source Project michael@0: * michael@0: * Use of this source code is governed by a BSD-style license that can be michael@0: * found in the LICENSE file. michael@0: */ michael@0: michael@0: michael@0: #ifndef SkBlitter_DEFINED michael@0: #define SkBlitter_DEFINED michael@0: michael@0: #include "SkBitmap.h" michael@0: #include "SkBitmapProcShader.h" michael@0: #include "SkMask.h" michael@0: #include "SkMatrix.h" michael@0: #include "SkPaint.h" michael@0: #include "SkRefCnt.h" michael@0: #include "SkRegion.h" michael@0: #include "SkShader.h" michael@0: #include "SkSmallAllocator.h" michael@0: michael@0: /** SkBlitter and its subclasses are responsible for actually writing pixels michael@0: into memory. Besides efficiency, they handle clipping and antialiasing. michael@0: */ michael@0: class SkBlitter { michael@0: public: michael@0: virtual ~SkBlitter(); michael@0: michael@0: /// Blit a horizontal run of one or more pixels. michael@0: virtual void blitH(int x, int y, int width); michael@0: /// Blit a horizontal run of antialiased pixels; runs[] is a *sparse* michael@0: /// zero-terminated run-length encoding of spans of constant alpha values. michael@0: virtual void blitAntiH(int x, int y, const SkAlpha antialias[], michael@0: const int16_t runs[]); michael@0: /// Blit a vertical run of pixels with a constant alpha value. michael@0: virtual void blitV(int x, int y, int height, SkAlpha alpha); michael@0: /// Blit a solid rectangle one or more pixels wide. michael@0: virtual void blitRect(int x, int y, int width, int height); michael@0: /** Blit a rectangle with one alpha-blended column on the left, michael@0: width (zero or more) opaque pixels, and one alpha-blended column michael@0: on the right. michael@0: The result will always be at least two pixels wide. michael@0: */ michael@0: virtual void blitAntiRect(int x, int y, int width, int height, michael@0: SkAlpha leftAlpha, SkAlpha rightAlpha); michael@0: /// Blit a pattern of pixels defined by a rectangle-clipped mask; michael@0: /// typically used for text. michael@0: virtual void blitMask(const SkMask&, const SkIRect& clip); michael@0: michael@0: /** If the blitter just sets a single value for each pixel, return the michael@0: bitmap it draws into, and assign value. If not, return NULL and ignore michael@0: the value parameter. michael@0: */ michael@0: virtual const SkBitmap* justAnOpaqueColor(uint32_t* value); michael@0: michael@0: /** michael@0: * Special method just to identify the null blitter, which is returned michael@0: * from Choose() if the request cannot be fulfilled. Default impl michael@0: * returns false. michael@0: */ michael@0: virtual bool isNullBlitter() const; michael@0: michael@0: ///@name non-virtual helpers michael@0: void blitMaskRegion(const SkMask& mask, const SkRegion& clip); michael@0: void blitRectRegion(const SkIRect& rect, const SkRegion& clip); michael@0: void blitRegion(const SkRegion& clip); michael@0: ///@} michael@0: michael@0: /** @name Factories michael@0: Return the correct blitter to use given the specified context. michael@0: */ michael@0: static SkBlitter* Choose(const SkBitmap& device, michael@0: const SkMatrix& matrix, michael@0: const SkPaint& paint, michael@0: SkTBlitterAllocator*, michael@0: bool drawCoverage = false); michael@0: michael@0: static SkBlitter* ChooseSprite(const SkBitmap& device, michael@0: const SkPaint&, michael@0: const SkBitmap& src, michael@0: int left, int top, michael@0: SkTBlitterAllocator*); michael@0: ///@} michael@0: michael@0: private: michael@0: }; michael@0: michael@0: /** This blitter silently never draws anything. michael@0: */ michael@0: class SkNullBlitter : public SkBlitter { michael@0: public: michael@0: virtual void blitH(int x, int y, int width) SK_OVERRIDE; michael@0: virtual void blitAntiH(int x, int y, const SkAlpha[], michael@0: const int16_t runs[]) SK_OVERRIDE; michael@0: virtual void blitV(int x, int y, int height, SkAlpha alpha) SK_OVERRIDE; michael@0: virtual void blitRect(int x, int y, int width, int height) SK_OVERRIDE; michael@0: virtual void blitMask(const SkMask&, const SkIRect& clip) SK_OVERRIDE; michael@0: virtual const SkBitmap* justAnOpaqueColor(uint32_t* value) SK_OVERRIDE; michael@0: virtual bool isNullBlitter() const SK_OVERRIDE; michael@0: }; michael@0: michael@0: /** Wraps another (real) blitter, and ensures that the real blitter is only michael@0: called with coordinates that have been clipped by the specified clipRect. michael@0: This means the caller need not perform the clipping ahead of time. michael@0: */ michael@0: class SkRectClipBlitter : public SkBlitter { michael@0: public: michael@0: void init(SkBlitter* blitter, const SkIRect& clipRect) { michael@0: SkASSERT(!clipRect.isEmpty()); michael@0: fBlitter = blitter; michael@0: fClipRect = clipRect; michael@0: } michael@0: michael@0: virtual void blitH(int x, int y, int width) SK_OVERRIDE; michael@0: virtual void blitAntiH(int x, int y, const SkAlpha[], michael@0: const int16_t runs[]) SK_OVERRIDE; michael@0: virtual void blitV(int x, int y, int height, SkAlpha alpha) SK_OVERRIDE; michael@0: virtual void blitRect(int x, int y, int width, int height) SK_OVERRIDE; michael@0: virtual void blitAntiRect(int x, int y, int width, int height, michael@0: SkAlpha leftAlpha, SkAlpha rightAlpha) SK_OVERRIDE; michael@0: virtual void blitMask(const SkMask&, const SkIRect& clip) SK_OVERRIDE; michael@0: virtual const SkBitmap* justAnOpaqueColor(uint32_t* value) SK_OVERRIDE; michael@0: michael@0: private: michael@0: SkBlitter* fBlitter; michael@0: SkIRect fClipRect; michael@0: }; michael@0: michael@0: /** Wraps another (real) blitter, and ensures that the real blitter is only michael@0: called with coordinates that have been clipped by the specified clipRgn. michael@0: This means the caller need not perform the clipping ahead of time. michael@0: */ michael@0: class SkRgnClipBlitter : public SkBlitter { michael@0: public: michael@0: void init(SkBlitter* blitter, const SkRegion* clipRgn) { michael@0: SkASSERT(clipRgn && !clipRgn->isEmpty()); michael@0: fBlitter = blitter; michael@0: fRgn = clipRgn; michael@0: } michael@0: michael@0: virtual void blitH(int x, int y, int width) SK_OVERRIDE; michael@0: virtual void blitAntiH(int x, int y, const SkAlpha[], michael@0: const int16_t runs[]) SK_OVERRIDE; michael@0: virtual void blitV(int x, int y, int height, SkAlpha alpha) SK_OVERRIDE; michael@0: virtual void blitRect(int x, int y, int width, int height) SK_OVERRIDE; michael@0: virtual void blitAntiRect(int x, int y, int width, int height, michael@0: SkAlpha leftAlpha, SkAlpha rightAlpha) SK_OVERRIDE; michael@0: virtual void blitMask(const SkMask&, const SkIRect& clip) SK_OVERRIDE; michael@0: virtual const SkBitmap* justAnOpaqueColor(uint32_t* value) SK_OVERRIDE; michael@0: michael@0: private: michael@0: SkBlitter* fBlitter; michael@0: const SkRegion* fRgn; michael@0: }; michael@0: michael@0: /** Factory to set up the appropriate most-efficient wrapper blitter michael@0: to apply a clip. Returns a pointer to a member, so lifetime must michael@0: be managed carefully. michael@0: */ michael@0: class SkBlitterClipper { michael@0: public: michael@0: SkBlitter* apply(SkBlitter* blitter, const SkRegion* clip, michael@0: const SkIRect* bounds = NULL); michael@0: michael@0: private: michael@0: SkNullBlitter fNullBlitter; michael@0: SkRectClipBlitter fRectBlitter; michael@0: SkRgnClipBlitter fRgnBlitter; michael@0: }; michael@0: michael@0: #endif