1 2 /* 3 * Copyright 2006 The Android Open Source Project 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9 10 #ifndef SkBlitter_DEFINED 11 #define SkBlitter_DEFINED 12 13 #include "SkBitmap.h" 14 #include "SkBitmapProcShader.h" 15 #include "SkMask.h" 16 #include "SkMatrix.h" 17 #include "SkPaint.h" 18 #include "SkRefCnt.h" 19 #include "SkRegion.h" 20 #include "SkShader.h" 21 #include "SkSmallAllocator.h" 22 23 /** SkBlitter and its subclasses are responsible for actually writing pixels 24 into memory. Besides efficiency, they handle clipping and antialiasing. 25 */ 26 class SkBlitter { 27 public: 28 virtual ~SkBlitter(); 29 30 /// Blit a horizontal run of one or more pixels. 31 virtual void blitH(int x, int y, int width); 32 /// Blit a horizontal run of antialiased pixels; runs[] is a *sparse* 33 /// zero-terminated run-length encoding of spans of constant alpha values. 34 virtual void blitAntiH(int x, int y, const SkAlpha antialias[], 35 const int16_t runs[]); 36 /// Blit a vertical run of pixels with a constant alpha value. 37 virtual void blitV(int x, int y, int height, SkAlpha alpha); 38 /// Blit a solid rectangle one or more pixels wide. 39 virtual void blitRect(int x, int y, int width, int height); 40 /** Blit a rectangle with one alpha-blended column on the left, 41 width (zero or more) opaque pixels, and one alpha-blended column 42 on the right. 43 The result will always be at least two pixels wide. 44 */ 45 virtual void blitAntiRect(int x, int y, int width, int height, 46 SkAlpha leftAlpha, SkAlpha rightAlpha); 47 /// Blit a pattern of pixels defined by a rectangle-clipped mask; 48 /// typically used for text. 49 virtual void blitMask(const SkMask&, const SkIRect& clip); 50 51 /** If the blitter just sets a single value for each pixel, return the 52 bitmap it draws into, and assign value. If not, return NULL and ignore 53 the value parameter. 54 */ 55 virtual const SkBitmap* justAnOpaqueColor(uint32_t* value); 56 57 /** 58 * Special method just to identify the null blitter, which is returned 59 * from Choose() if the request cannot be fulfilled. Default impl 60 * returns false. 61 */ 62 virtual bool isNullBlitter() const; 63 64 /** 65 * Special methods for SkShaderBlitter. On all other classes this is a no-op. 66 */ 67 virtual bool resetShaderContext(const SkShader::ContextRec&); 68 virtual SkShader::Context* getShaderContext() const; 69 70 ///@name non-virtual helpers 71 void blitMaskRegion(const SkMask& mask, const SkRegion& clip); 72 void blitRectRegion(const SkIRect& rect, const SkRegion& clip); 73 void blitRegion(const SkRegion& clip); 74 ///@} 75 76 /** @name Factories 77 Return the correct blitter to use given the specified context. 78 */ 79 static SkBlitter* Choose(const SkBitmap& device, 80 const SkMatrix& matrix, 81 const SkPaint& paint, 82 SkTBlitterAllocator*, 83 bool drawCoverage = false); 84 85 static SkBlitter* ChooseSprite(const SkBitmap& device, 86 const SkPaint&, 87 const SkBitmap& src, 88 int left, int top, 89 SkTBlitterAllocator*); 90 ///@} 91 92 private: 93 }; 94 95 /** This blitter silently never draws anything. 96 */ 97 class SkNullBlitter : public SkBlitter { 98 public: 99 virtual void blitH(int x, int y, int width) SK_OVERRIDE; 100 virtual void blitAntiH(int x, int y, const SkAlpha[], 101 const int16_t runs[]) SK_OVERRIDE; 102 virtual void blitV(int x, int y, int height, SkAlpha alpha) SK_OVERRIDE; 103 virtual void blitRect(int x, int y, int width, int height) SK_OVERRIDE; 104 virtual void blitMask(const SkMask&, const SkIRect& clip) SK_OVERRIDE; 105 virtual const SkBitmap* justAnOpaqueColor(uint32_t* value) SK_OVERRIDE; 106 virtual bool isNullBlitter() const SK_OVERRIDE; 107 }; 108 109 /** Wraps another (real) blitter, and ensures that the real blitter is only 110 called with coordinates that have been clipped by the specified clipRect. 111 This means the caller need not perform the clipping ahead of time. 112 */ 113 class SkRectClipBlitter : public SkBlitter { 114 public: init(SkBlitter * blitter,const SkIRect & clipRect)115 void init(SkBlitter* blitter, const SkIRect& clipRect) { 116 SkASSERT(!clipRect.isEmpty()); 117 fBlitter = blitter; 118 fClipRect = clipRect; 119 } 120 121 virtual void blitH(int x, int y, int width) SK_OVERRIDE; 122 virtual void blitAntiH(int x, int y, const SkAlpha[], 123 const int16_t runs[]) SK_OVERRIDE; 124 virtual void blitV(int x, int y, int height, SkAlpha alpha) SK_OVERRIDE; 125 virtual void blitRect(int x, int y, int width, int height) SK_OVERRIDE; 126 virtual void blitAntiRect(int x, int y, int width, int height, 127 SkAlpha leftAlpha, SkAlpha rightAlpha) SK_OVERRIDE; 128 virtual void blitMask(const SkMask&, const SkIRect& clip) SK_OVERRIDE; 129 virtual const SkBitmap* justAnOpaqueColor(uint32_t* value) SK_OVERRIDE; 130 131 private: 132 SkBlitter* fBlitter; 133 SkIRect fClipRect; 134 }; 135 136 /** Wraps another (real) blitter, and ensures that the real blitter is only 137 called with coordinates that have been clipped by the specified clipRgn. 138 This means the caller need not perform the clipping ahead of time. 139 */ 140 class SkRgnClipBlitter : public SkBlitter { 141 public: init(SkBlitter * blitter,const SkRegion * clipRgn)142 void init(SkBlitter* blitter, const SkRegion* clipRgn) { 143 SkASSERT(clipRgn && !clipRgn->isEmpty()); 144 fBlitter = blitter; 145 fRgn = clipRgn; 146 } 147 148 virtual void blitH(int x, int y, int width) SK_OVERRIDE; 149 virtual void blitAntiH(int x, int y, const SkAlpha[], 150 const int16_t runs[]) SK_OVERRIDE; 151 virtual void blitV(int x, int y, int height, SkAlpha alpha) SK_OVERRIDE; 152 virtual void blitRect(int x, int y, int width, int height) SK_OVERRIDE; 153 virtual void blitAntiRect(int x, int y, int width, int height, 154 SkAlpha leftAlpha, SkAlpha rightAlpha) SK_OVERRIDE; 155 virtual void blitMask(const SkMask&, const SkIRect& clip) SK_OVERRIDE; 156 virtual const SkBitmap* justAnOpaqueColor(uint32_t* value) SK_OVERRIDE; 157 158 private: 159 SkBlitter* fBlitter; 160 const SkRegion* fRgn; 161 }; 162 163 /** Factory to set up the appropriate most-efficient wrapper blitter 164 to apply a clip. Returns a pointer to a member, so lifetime must 165 be managed carefully. 166 */ 167 class SkBlitterClipper { 168 public: 169 SkBlitter* apply(SkBlitter* blitter, const SkRegion* clip, 170 const SkIRect* bounds = NULL); 171 172 private: 173 SkNullBlitter fNullBlitter; 174 SkRectClipBlitter fRectBlitter; 175 SkRgnClipBlitter fRgnBlitter; 176 }; 177 178 #endif 179