SkBlitter.h revision 72c9faab45124e08c85f70ca38536914862d947c
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*/ 26class SkBlitter { 27public: 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 37 /// Blit a vertical run of pixels with a constant alpha value. 38 virtual void blitV(int x, int y, int height, SkAlpha alpha); 39 /// Blit a solid rectangle one or more pixels wide. 40 virtual void blitRect(int x, int y, int width, int height); 41 /** Blit a rectangle with one alpha-blended column on the left, 42 width (zero or more) opaque pixels, and one alpha-blended column 43 on the right. 44 The result will always be at least two pixels wide. 45 */ 46 virtual void blitAntiRect(int x, int y, int width, int height, 47 SkAlpha leftAlpha, SkAlpha rightAlpha); 48 /// Blit a pattern of pixels defined by a rectangle-clipped mask; 49 /// typically used for text. 50 virtual void blitMask(const SkMask&, const SkIRect& clip); 51 52 /** If the blitter just sets a single value for each pixel, return the 53 bitmap it draws into, and assign value. If not, return NULL and ignore 54 the value parameter. 55 */ 56 virtual const SkBitmap* justAnOpaqueColor(uint32_t* value); 57 58 /** 59 * Special method just to identify the null blitter, which is returned 60 * from Choose() if the request cannot be fulfilled. Default impl 61 * returns false. 62 */ 63 virtual bool isNullBlitter() const; 64 65 /** 66 * Special methods for SkShaderBlitter. On all other classes this is a no-op. 67 */ 68 virtual bool resetShaderContext(const SkShader::ContextRec&); 69 virtual SkShader::Context* getShaderContext() const; 70 71 /** 72 * Special methods for blitters that can blit more than one row at a time. 73 * This function returns the number of rows that this blitter could optimally 74 * process at a time. It is still required to support blitting one scanline 75 * at a time. 76 */ 77 virtual int requestRowsPreserved() const { return 1; } 78 79 /** 80 * This function allocates memory for the blitter that the blitter then owns. 81 * The memory can be used by the calling function at will, but it will be 82 * released when the blitter's destructor is called. This function returns 83 * NULL if no persistent memory is needed by the blitter. 84 */ 85 virtual void* allocBlitMemory(size_t sz) { 86 return fBlitMemory.reset(sz, SkAutoMalloc::kReuse_OnShrink); 87 } 88 89 ///@name non-virtual helpers 90 void blitMaskRegion(const SkMask& mask, const SkRegion& clip); 91 void blitRectRegion(const SkIRect& rect, const SkRegion& clip); 92 void blitRegion(const SkRegion& clip); 93 ///@} 94 95 /** @name Factories 96 Return the correct blitter to use given the specified context. 97 */ 98 static SkBlitter* Choose(const SkBitmap& device, 99 const SkMatrix& matrix, 100 const SkPaint& paint, 101 SkTBlitterAllocator*, 102 bool drawCoverage = false); 103 104 static SkBlitter* ChooseSprite(const SkBitmap& device, 105 const SkPaint&, 106 const SkBitmap& src, 107 int left, int top, 108 SkTBlitterAllocator*); 109 ///@} 110 111protected: 112 113 SkAutoMalloc fBlitMemory; 114 115private: 116}; 117 118/** This blitter silently never draws anything. 119*/ 120class SkNullBlitter : public SkBlitter { 121public: 122 void blitH(int x, int y, int width) SK_OVERRIDE; 123 virtual void blitAntiH(int x, int y, const SkAlpha[], 124 const int16_t runs[]) SK_OVERRIDE; 125 void blitV(int x, int y, int height, SkAlpha alpha) SK_OVERRIDE; 126 void blitRect(int x, int y, int width, int height) SK_OVERRIDE; 127 void blitMask(const SkMask&, const SkIRect& clip) SK_OVERRIDE; 128 const SkBitmap* justAnOpaqueColor(uint32_t* value) SK_OVERRIDE; 129 bool isNullBlitter() const SK_OVERRIDE; 130}; 131 132/** Wraps another (real) blitter, and ensures that the real blitter is only 133 called with coordinates that have been clipped by the specified clipRect. 134 This means the caller need not perform the clipping ahead of time. 135*/ 136class SkRectClipBlitter : public SkBlitter { 137public: 138 void init(SkBlitter* blitter, const SkIRect& clipRect) { 139 SkASSERT(!clipRect.isEmpty()); 140 fBlitter = blitter; 141 fClipRect = clipRect; 142 } 143 144 void blitH(int x, int y, int width) SK_OVERRIDE; 145 virtual void blitAntiH(int x, int y, const SkAlpha[], 146 const int16_t runs[]) SK_OVERRIDE; 147 void blitV(int x, int y, int height, SkAlpha alpha) SK_OVERRIDE; 148 void blitRect(int x, int y, int width, int height) SK_OVERRIDE; 149 virtual void blitAntiRect(int x, int y, int width, int height, 150 SkAlpha leftAlpha, SkAlpha rightAlpha) SK_OVERRIDE; 151 void blitMask(const SkMask&, const SkIRect& clip) SK_OVERRIDE; 152 const SkBitmap* justAnOpaqueColor(uint32_t* value) SK_OVERRIDE; 153 154 int requestRowsPreserved() const SK_OVERRIDE { 155 return fBlitter->requestRowsPreserved(); 156 } 157 158 void* allocBlitMemory(size_t sz) SK_OVERRIDE { 159 return fBlitter->allocBlitMemory(sz); 160 } 161 162private: 163 SkBlitter* fBlitter; 164 SkIRect fClipRect; 165}; 166 167/** Wraps another (real) blitter, and ensures that the real blitter is only 168 called with coordinates that have been clipped by the specified clipRgn. 169 This means the caller need not perform the clipping ahead of time. 170*/ 171class SkRgnClipBlitter : public SkBlitter { 172public: 173 void init(SkBlitter* blitter, const SkRegion* clipRgn) { 174 SkASSERT(clipRgn && !clipRgn->isEmpty()); 175 fBlitter = blitter; 176 fRgn = clipRgn; 177 } 178 179 void blitH(int x, int y, int width) SK_OVERRIDE; 180 virtual void blitAntiH(int x, int y, const SkAlpha[], 181 const int16_t runs[]) SK_OVERRIDE; 182 void blitV(int x, int y, int height, SkAlpha alpha) SK_OVERRIDE; 183 void blitRect(int x, int y, int width, int height) SK_OVERRIDE; 184 virtual void blitAntiRect(int x, int y, int width, int height, 185 SkAlpha leftAlpha, SkAlpha rightAlpha) SK_OVERRIDE; 186 void blitMask(const SkMask&, const SkIRect& clip) SK_OVERRIDE; 187 const SkBitmap* justAnOpaqueColor(uint32_t* value) SK_OVERRIDE; 188 189 int requestRowsPreserved() const SK_OVERRIDE { 190 return fBlitter->requestRowsPreserved(); 191 } 192 193 void* allocBlitMemory(size_t sz) SK_OVERRIDE { 194 return fBlitter->allocBlitMemory(sz); 195 } 196 197private: 198 SkBlitter* fBlitter; 199 const SkRegion* fRgn; 200}; 201 202/** Factory to set up the appropriate most-efficient wrapper blitter 203 to apply a clip. Returns a pointer to a member, so lifetime must 204 be managed carefully. 205*/ 206class SkBlitterClipper { 207public: 208 SkBlitter* apply(SkBlitter* blitter, const SkRegion* clip, 209 const SkIRect* bounds = NULL); 210 211private: 212 SkNullBlitter fNullBlitter; 213 SkRectClipBlitter fRectBlitter; 214 SkRgnClipBlitter fRgnBlitter; 215}; 216 217#endif 218