blob: 51748b00e957594767c82c8d1219a8abd0026dc3 [file] [log] [blame]
epoger@google.comec3ed6a2011-07-28 14:26:00 +00001
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
reed@android.com8a1c16f2008-12-17 15:59:43 +00009
10#include "SkCoreBlitters.h"
11#include "SkColorPriv.h"
12#include "SkShader.h"
13#include "SkXfermode.h"
14
reed41e010c2015-06-09 12:16:53 -070015SkA8_Blitter::SkA8_Blitter(const SkPixmap& device, const SkPaint& paint) : INHERITED(device) {
mike@reedtribe.orgeadc8072011-04-09 19:28:43 +000016 fSrcA = paint.getAlpha();
reed@android.com8a1c16f2008-12-17 15:59:43 +000017}
18
reed41e010c2015-06-09 12:16:53 -070019const SkPixmap* SkA8_Blitter::justAnOpaqueColor(uint32_t* value) {
reed@google.com82065d62011-02-07 15:30:46 +000020 if (255 == fSrcA) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000021 *value = 255;
22 return &fDevice;
23 }
halcanary96fcdcc2015-08-27 07:41:13 -070024 return nullptr;
reed@android.com8a1c16f2008-12-17 15:59:43 +000025}
26
reed@google.com82065d62011-02-07 15:30:46 +000027void SkA8_Blitter::blitH(int x, int y, int width) {
28 SkASSERT(x >= 0 && y >= 0 &&
29 (unsigned)(x + width) <= (unsigned)fDevice.width());
reed@android.com8a1c16f2008-12-17 15:59:43 +000030
reed@google.com82065d62011-02-07 15:30:46 +000031 if (fSrcA == 0) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000032 return;
reed@google.com82065d62011-02-07 15:30:46 +000033 }
reed@android.com8a1c16f2008-12-17 15:59:43 +000034
reed41e010c2015-06-09 12:16:53 -070035 uint8_t* device = fDevice.writable_addr8(x, y);
reed@android.com8a1c16f2008-12-17 15:59:43 +000036
reed@google.com82065d62011-02-07 15:30:46 +000037 if (fSrcA == 255) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000038 memset(device, 0xFF, width);
reed@google.com82065d62011-02-07 15:30:46 +000039 } else {
reed@android.com8a1c16f2008-12-17 15:59:43 +000040 unsigned scale = 256 - SkAlpha255To256(fSrcA);
41 unsigned srcA = fSrcA;
42
reed@google.com82065d62011-02-07 15:30:46 +000043 for (int i = 0; i < width; i++) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000044 device[i] = SkToU8(srcA + SkAlphaMul(device[i], scale));
45 }
46 }
47}
48
reed@google.com82065d62011-02-07 15:30:46 +000049void SkA8_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[],
50 const int16_t runs[]) {
51 if (fSrcA == 0) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000052 return;
reed@google.com82065d62011-02-07 15:30:46 +000053 }
reed@android.com8a1c16f2008-12-17 15:59:43 +000054
reed41e010c2015-06-09 12:16:53 -070055 uint8_t* device = fDevice.writable_addr8(x, y);
reed@android.com8a1c16f2008-12-17 15:59:43 +000056 unsigned srcA = fSrcA;
57
reed@google.com82065d62011-02-07 15:30:46 +000058 for (;;) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000059 int count = runs[0];
60 SkASSERT(count >= 0);
reed@google.com82065d62011-02-07 15:30:46 +000061 if (count == 0) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000062 return;
reed@google.com82065d62011-02-07 15:30:46 +000063 }
reed@android.com8a1c16f2008-12-17 15:59:43 +000064 unsigned aa = antialias[0];
65
reed@google.com82065d62011-02-07 15:30:46 +000066 if (aa == 255 && srcA == 255) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000067 memset(device, 0xFF, count);
reed@google.com82065d62011-02-07 15:30:46 +000068 } else {
reed@android.com8a1c16f2008-12-17 15:59:43 +000069 unsigned sa = SkAlphaMul(srcA, SkAlpha255To256(aa));
70 unsigned scale = 256 - sa;
71
reed@google.com82065d62011-02-07 15:30:46 +000072 for (int i = 0; i < count; i++) {
reed@android.com8a1c16f2008-12-17 15:59:43 +000073 device[i] = SkToU8(sa + SkAlphaMul(device[i], scale));
74 }
75 }
76 runs += count;
77 antialias += count;
78 device += count;
79 }
80}
81
82/////////////////////////////////////////////////////////////////////////////////////
83
84#define solid_8_pixels(mask, dst) \
85 do { \
86 if (mask & 0x80) dst[0] = 0xFF; \
87 if (mask & 0x40) dst[1] = 0xFF; \
88 if (mask & 0x20) dst[2] = 0xFF; \
89 if (mask & 0x10) dst[3] = 0xFF; \
90 if (mask & 0x08) dst[4] = 0xFF; \
91 if (mask & 0x04) dst[5] = 0xFF; \
92 if (mask & 0x02) dst[6] = 0xFF; \
93 if (mask & 0x01) dst[7] = 0xFF; \
94 } while (0)
95
96#define SK_BLITBWMASK_NAME SkA8_BlitBW
reed@google.com82065d62011-02-07 15:30:46 +000097#define SK_BLITBWMASK_ARGS
reed@android.com8a1c16f2008-12-17 15:59:43 +000098#define SK_BLITBWMASK_BLIT8(mask, dst) solid_8_pixels(mask, dst)
reed41e010c2015-06-09 12:16:53 -070099#define SK_BLITBWMASK_GETADDR writable_addr8
reed@android.com8a1c16f2008-12-17 15:59:43 +0000100#define SK_BLITBWMASK_DEVTYPE uint8_t
101#include "SkBlitBWMaskTemplate.h"
102
reed@google.com82065d62011-02-07 15:30:46 +0000103static inline void blend_8_pixels(U8CPU bw, uint8_t dst[], U8CPU sa,
104 unsigned dst_scale) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000105 if (bw & 0x80) dst[0] = SkToU8(sa + SkAlphaMul(dst[0], dst_scale));
106 if (bw & 0x40) dst[1] = SkToU8(sa + SkAlphaMul(dst[1], dst_scale));
107 if (bw & 0x20) dst[2] = SkToU8(sa + SkAlphaMul(dst[2], dst_scale));
108 if (bw & 0x10) dst[3] = SkToU8(sa + SkAlphaMul(dst[3], dst_scale));
109 if (bw & 0x08) dst[4] = SkToU8(sa + SkAlphaMul(dst[4], dst_scale));
110 if (bw & 0x04) dst[5] = SkToU8(sa + SkAlphaMul(dst[5], dst_scale));
111 if (bw & 0x02) dst[6] = SkToU8(sa + SkAlphaMul(dst[6], dst_scale));
112 if (bw & 0x01) dst[7] = SkToU8(sa + SkAlphaMul(dst[7], dst_scale));
113}
114
115#define SK_BLITBWMASK_NAME SkA8_BlendBW
116#define SK_BLITBWMASK_ARGS , U8CPU sa, unsigned dst_scale
117#define SK_BLITBWMASK_BLIT8(mask, dst) blend_8_pixels(mask, dst, sa, dst_scale)
reed41e010c2015-06-09 12:16:53 -0700118#define SK_BLITBWMASK_GETADDR writable_addr8
reed@android.com8a1c16f2008-12-17 15:59:43 +0000119#define SK_BLITBWMASK_DEVTYPE uint8_t
120#include "SkBlitBWMaskTemplate.h"
121
reed@google.com82065d62011-02-07 15:30:46 +0000122void SkA8_Blitter::blitMask(const SkMask& mask, const SkIRect& clip) {
123 if (fSrcA == 0) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000124 return;
reed@google.com82065d62011-02-07 15:30:46 +0000125 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000126
reed@google.com82065d62011-02-07 15:30:46 +0000127 if (mask.fFormat == SkMask::kBW_Format) {
128 if (fSrcA == 0xFF) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000129 SkA8_BlitBW(fDevice, mask, clip);
reed@google.com82065d62011-02-07 15:30:46 +0000130 } else {
131 SkA8_BlendBW(fDevice, mask, clip, fSrcA,
132 SkAlpha255To256(255 - fSrcA));
133 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000134 return;
135 }
136
137 int x = clip.fLeft;
138 int y = clip.fTop;
139 int width = clip.width();
140 int height = clip.height();
reed41e010c2015-06-09 12:16:53 -0700141 uint8_t* device = fDevice.writable_addr8(x, y);
reed@google.com79891862011-10-18 15:44:57 +0000142 const uint8_t* alpha = mask.getAddr8(x, y);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000143 unsigned srcA = fSrcA;
144
reed@google.com82065d62011-02-07 15:30:46 +0000145 while (--height >= 0) {
146 for (int i = width - 1; i >= 0; --i) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000147 unsigned sa;
148 // scale our src by the alpha value
149 {
150 int aa = alpha[i];
reed@google.com82065d62011-02-07 15:30:46 +0000151 if (aa == 0) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000152 continue;
reed@google.com82065d62011-02-07 15:30:46 +0000153 }
154 if (aa == 255) {
155 if (srcA == 255) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000156 device[i] = 0xFF;
157 continue;
158 }
159 sa = srcA;
reed@google.com82065d62011-02-07 15:30:46 +0000160 } else {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000161 sa = SkAlphaMul(srcA, SkAlpha255To256(aa));
reed@google.com82065d62011-02-07 15:30:46 +0000162 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000163 }
164
165 int scale = 256 - SkAlpha255To256(sa);
166 device[i] = SkToU8(sa + SkAlphaMul(device[i], scale));
167 }
168 device += fDevice.rowBytes();
169 alpha += mask.fRowBytes;
170 }
171}
172
reed@google.com82065d62011-02-07 15:30:46 +0000173///////////////////////////////////////////////////////////////////////////////
reed@android.com8a1c16f2008-12-17 15:59:43 +0000174
reed@google.com82065d62011-02-07 15:30:46 +0000175void SkA8_Blitter::blitV(int x, int y, int height, SkAlpha alpha) {
176 if (fSrcA == 0) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000177 return;
reed@google.com82065d62011-02-07 15:30:46 +0000178 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000179
180 unsigned sa = SkAlphaMul(fSrcA, SkAlpha255To256(alpha));
reed41e010c2015-06-09 12:16:53 -0700181 uint8_t* device = fDevice.writable_addr8(x, y);
scroggo@google.come5f48242013-02-25 21:47:41 +0000182 size_t rowBytes = fDevice.rowBytes();
reed@android.com8a1c16f2008-12-17 15:59:43 +0000183
reed@google.com82065d62011-02-07 15:30:46 +0000184 if (sa == 0xFF) {
185 for (int i = 0; i < height; i++) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000186 *device = SkToU8(sa);
187 device += rowBytes;
188 }
reed@google.com82065d62011-02-07 15:30:46 +0000189 } else {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000190 unsigned scale = 256 - SkAlpha255To256(sa);
191
reed@google.com82065d62011-02-07 15:30:46 +0000192 for (int i = 0; i < height; i++) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000193 *device = SkToU8(sa + SkAlphaMul(*device, scale));
194 device += rowBytes;
195 }
196 }
197}
198
reed@google.com82065d62011-02-07 15:30:46 +0000199void SkA8_Blitter::blitRect(int x, int y, int width, int height) {
200 SkASSERT(x >= 0 && y >= 0 &&
201 (unsigned)(x + width) <= (unsigned)fDevice.width() &&
202 (unsigned)(y + height) <= (unsigned)fDevice.height());
reed@android.com8a1c16f2008-12-17 15:59:43 +0000203
reed@google.com82065d62011-02-07 15:30:46 +0000204 if (fSrcA == 0) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000205 return;
reed@google.com82065d62011-02-07 15:30:46 +0000206 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000207
reed41e010c2015-06-09 12:16:53 -0700208 uint8_t* device = fDevice.writable_addr8(x, y);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000209 unsigned srcA = fSrcA;
210
reed@google.com82065d62011-02-07 15:30:46 +0000211 if (srcA == 255) {
212 while (--height >= 0) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000213 memset(device, 0xFF, width);
214 device += fDevice.rowBytes();
215 }
reed@google.com82065d62011-02-07 15:30:46 +0000216 } else {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000217 unsigned scale = 256 - SkAlpha255To256(srcA);
218
reed@google.com82065d62011-02-07 15:30:46 +0000219 while (--height >= 0) {
220 for (int i = 0; i < width; i++) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000221 device[i] = SkToU8(srcA + SkAlphaMul(device[i], scale));
222 }
223 device += fDevice.rowBytes();
224 }
225 }
226}
227
228///////////////////////////////////////////////////////////////////////
229
reed41e010c2015-06-09 12:16:53 -0700230SkA8_Shader_Blitter::SkA8_Shader_Blitter(const SkPixmap& device, const SkPaint& paint,
commit-bot@chromium.org87fcd952014-04-23 19:10:51 +0000231 SkShader::Context* shaderContext)
reed41e010c2015-06-09 12:16:53 -0700232 : INHERITED(device, paint, shaderContext)
233{
halcanary96fcdcc2015-08-27 07:41:13 -0700234 if ((fXfermode = paint.getXfermode()) != nullptr) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000235 fXfermode->ref();
commit-bot@chromium.org87fcd952014-04-23 19:10:51 +0000236 SkASSERT(fShaderContext);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000237 }
238
239 int width = device.width();
240 fBuffer = (SkPMColor*)sk_malloc_throw(sizeof(SkPMColor) * (width + (SkAlign4(width) >> 2)));
241 fAAExpand = (uint8_t*)(fBuffer + width);
242}
243
reed@google.com82065d62011-02-07 15:30:46 +0000244SkA8_Shader_Blitter::~SkA8_Shader_Blitter() {
djsollen@google.com57f49692011-02-23 20:46:31 +0000245 if (fXfermode) SkSafeUnref(fXfermode);
reed@android.com8a1c16f2008-12-17 15:59:43 +0000246 sk_free(fBuffer);
247}
248
reed@google.com82065d62011-02-07 15:30:46 +0000249void SkA8_Shader_Blitter::blitH(int x, int y, int width) {
250 SkASSERT(x >= 0 && y >= 0 &&
251 (unsigned)(x + width) <= (unsigned)fDevice.width());
reed@android.com8a1c16f2008-12-17 15:59:43 +0000252
reed41e010c2015-06-09 12:16:53 -0700253 uint8_t* device = fDevice.writable_addr8(x, y);
commit-bot@chromium.org87fcd952014-04-23 19:10:51 +0000254 SkShader::Context* shaderContext = fShaderContext;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000255
commit-bot@chromium.org87fcd952014-04-23 19:10:51 +0000256 if ((shaderContext->getFlags() & SkShader::kOpaqueAlpha_Flag) && !fXfermode) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000257 memset(device, 0xFF, width);
reed@google.com82065d62011-02-07 15:30:46 +0000258 } else {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000259 SkPMColor* span = fBuffer;
260
commit-bot@chromium.org87fcd952014-04-23 19:10:51 +0000261 shaderContext->shadeSpan(x, y, span, width);
reed@google.com82065d62011-02-07 15:30:46 +0000262 if (fXfermode) {
halcanary96fcdcc2015-08-27 07:41:13 -0700263 fXfermode->xferA8(device, span, width, nullptr);
reed@google.com82065d62011-02-07 15:30:46 +0000264 } else {
265 for (int i = width - 1; i >= 0; --i) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000266 unsigned srcA = SkGetPackedA32(span[i]);
267 unsigned scale = 256 - SkAlpha255To256(srcA);
268
269 device[i] = SkToU8(srcA + SkAlphaMul(device[i], scale));
270 }
271 }
272 }
273}
274
reed@google.com82065d62011-02-07 15:30:46 +0000275static inline uint8_t aa_blend8(SkPMColor src, U8CPU da, int aa) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000276 SkASSERT((unsigned)aa <= 255);
277
278 int src_scale = SkAlpha255To256(aa);
279 int sa = SkGetPackedA32(src);
280 int dst_scale = 256 - SkAlphaMul(sa, src_scale);
281
282 return SkToU8((sa * src_scale + da * dst_scale) >> 8);
283}
284
reed@google.com82065d62011-02-07 15:30:46 +0000285void SkA8_Shader_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[],
286 const int16_t runs[]) {
commit-bot@chromium.org87fcd952014-04-23 19:10:51 +0000287 SkShader::Context* shaderContext = fShaderContext;
288 SkXfermode* mode = fXfermode;
289 uint8_t* aaExpand = fAAExpand;
290 SkPMColor* span = fBuffer;
reed41e010c2015-06-09 12:16:53 -0700291 uint8_t* device = fDevice.writable_addr8(x, y);
commit-bot@chromium.org87fcd952014-04-23 19:10:51 +0000292 int opaque = shaderContext->getFlags() & SkShader::kOpaqueAlpha_Flag;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000293
reed@google.com82065d62011-02-07 15:30:46 +0000294 for (;;) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000295 int count = *runs;
reed@google.com82065d62011-02-07 15:30:46 +0000296 if (count == 0) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000297 break;
reed@google.com82065d62011-02-07 15:30:46 +0000298 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000299 int aa = *antialias;
reed@google.com82065d62011-02-07 15:30:46 +0000300 if (aa) {
halcanary96fcdcc2015-08-27 07:41:13 -0700301 if (opaque && aa == 255 && mode == nullptr) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000302 memset(device, 0xFF, count);
reed@google.com82065d62011-02-07 15:30:46 +0000303 } else {
commit-bot@chromium.org87fcd952014-04-23 19:10:51 +0000304 shaderContext->shadeSpan(x, y, span, count);
reed@google.com82065d62011-02-07 15:30:46 +0000305 if (mode) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000306 memset(aaExpand, aa, count);
307 mode->xferA8(device, span, count, aaExpand);
reed@google.com82065d62011-02-07 15:30:46 +0000308 } else {
309 for (int i = count - 1; i >= 0; --i) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000310 device[i] = aa_blend8(span[i], device[i], aa);
reed@google.com82065d62011-02-07 15:30:46 +0000311 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000312 }
313 }
314 }
315 device += count;
316 runs += count;
317 antialias += count;
318 x += count;
reed@google.com82065d62011-02-07 15:30:46 +0000319 }
reed@android.com8a1c16f2008-12-17 15:59:43 +0000320}
321
reed@google.com82065d62011-02-07 15:30:46 +0000322void SkA8_Shader_Blitter::blitMask(const SkMask& mask, const SkIRect& clip) {
323 if (mask.fFormat == SkMask::kBW_Format) {
reed@android.com8a1c16f2008-12-17 15:59:43 +0000324 this->INHERITED::blitMask(mask, clip);
325 return;
326 }
reed@google.com82065d62011-02-07 15:30:46 +0000327
reed@android.com8a1c16f2008-12-17 15:59:43 +0000328 int x = clip.fLeft;
329 int y = clip.fTop;
330 int width = clip.width();
331 int height = clip.height();
reed41e010c2015-06-09 12:16:53 -0700332 uint8_t* device = fDevice.writable_addr8(x, y);
reed@google.com79891862011-10-18 15:44:57 +0000333 const uint8_t* alpha = mask.getAddr8(x, y);
commit-bot@chromium.org87fcd952014-04-23 19:10:51 +0000334 SkShader::Context* shaderContext = fShaderContext;
reed@android.com8a1c16f2008-12-17 15:59:43 +0000335
336 SkPMColor* span = fBuffer;
337
reed@google.com82065d62011-02-07 15:30:46 +0000338 while (--height >= 0) {
commit-bot@chromium.org87fcd952014-04-23 19:10:51 +0000339 shaderContext->shadeSpan(x, y, span, width);
djsollen@google.com57f49692011-02-23 20:46:31 +0000340 if (fXfermode) {
341 fXfermode->xferA8(device, span, width, alpha);
commit-bot@chromium.org96583db2013-08-15 18:16:07 +0000342 } else {
343 for (int i = width - 1; i >= 0; --i) {
344 device[i] = aa_blend8(span[i], device[i], alpha[i]);
345 }
djsollen@google.com57f49692011-02-23 20:46:31 +0000346 }
reed@google.com82065d62011-02-07 15:30:46 +0000347
reed@android.com8a1c16f2008-12-17 15:59:43 +0000348 y += 1;
349 device += fDevice.rowBytes();
350 alpha += mask.fRowBytes;
351 }
352}
reed@google.com126f7f52013-11-07 16:06:53 +0000353
354///////////////////////////////////////////////////////////////////////////////
355
reed41e010c2015-06-09 12:16:53 -0700356SkA8_Coverage_Blitter::SkA8_Coverage_Blitter(const SkPixmap& device,
reed@google.com126f7f52013-11-07 16:06:53 +0000357 const SkPaint& paint) : SkRasterBlitter(device) {
halcanary96fcdcc2015-08-27 07:41:13 -0700358 SkASSERT(nullptr == paint.getShader());
359 SkASSERT(nullptr == paint.getXfermode());
360 SkASSERT(nullptr == paint.getColorFilter());
reed@google.com126f7f52013-11-07 16:06:53 +0000361}
362
363void SkA8_Coverage_Blitter::blitAntiH(int x, int y, const SkAlpha antialias[],
364 const int16_t runs[]) {
reed41e010c2015-06-09 12:16:53 -0700365 uint8_t* device = fDevice.writable_addr8(x, y);
reed@google.com126f7f52013-11-07 16:06:53 +0000366 SkDEBUGCODE(int totalCount = 0;)
skia.committer@gmail.comab7442c2013-11-08 07:01:56 +0000367
reed@google.com126f7f52013-11-07 16:06:53 +0000368 for (;;) {
369 int count = runs[0];
370 SkASSERT(count >= 0);
371 if (count == 0) {
372 return;
373 }
reed@google.comb95d9f52013-11-08 17:50:14 +0000374 if (antialias[0]) {
reed@google.com126f7f52013-11-07 16:06:53 +0000375 memset(device, antialias[0], count);
376 }
377 runs += count;
378 antialias += count;
379 device += count;
380
381 SkDEBUGCODE(totalCount += count;)
382 }
383 SkASSERT(fDevice.width() == totalCount);
384}
385
386void SkA8_Coverage_Blitter::blitH(int x, int y, int width) {
reed41e010c2015-06-09 12:16:53 -0700387 memset(fDevice.writable_addr8(x, y), 0xFF, width);
reed@google.com126f7f52013-11-07 16:06:53 +0000388}
389
390void SkA8_Coverage_Blitter::blitV(int x, int y, int height, SkAlpha alpha) {
reed@google.com126f7f52013-11-07 16:06:53 +0000391 if (0 == alpha) {
392 return;
393 }
reed@google.comb95d9f52013-11-08 17:50:14 +0000394
reed41e010c2015-06-09 12:16:53 -0700395 uint8_t* dst = fDevice.writable_addr8(x, y);
reed@google.com126f7f52013-11-07 16:06:53 +0000396 const size_t dstRB = fDevice.rowBytes();
397 while (--height >= 0) {
398 *dst = alpha;
399 dst += dstRB;
400 }
401}
402
403void SkA8_Coverage_Blitter::blitRect(int x, int y, int width, int height) {
reed41e010c2015-06-09 12:16:53 -0700404 uint8_t* dst = fDevice.writable_addr8(x, y);
reed@google.com126f7f52013-11-07 16:06:53 +0000405 const size_t dstRB = fDevice.rowBytes();
406 while (--height >= 0) {
407 memset(dst, 0xFF, width);
408 dst += dstRB;
409 }
410}
411
412void SkA8_Coverage_Blitter::blitMask(const SkMask& mask, const SkIRect& clip) {
413 SkASSERT(SkMask::kA8_Format == mask.fFormat);
414
415 int x = clip.fLeft;
416 int y = clip.fTop;
417 int width = clip.width();
418 int height = clip.height();
419
reed41e010c2015-06-09 12:16:53 -0700420 uint8_t* dst = fDevice.writable_addr8(x, y);
reed@google.com126f7f52013-11-07 16:06:53 +0000421 const uint8_t* src = mask.getAddr8(x, y);
422 const size_t srcRB = mask.fRowBytes;
423 const size_t dstRB = fDevice.rowBytes();
skia.committer@gmail.comab7442c2013-11-08 07:01:56 +0000424
reed@google.com126f7f52013-11-07 16:06:53 +0000425 while (--height >= 0) {
426 memcpy(dst, src, width);
427 dst += dstRB;
428 src += srcRB;
429 }
430}
431
reed41e010c2015-06-09 12:16:53 -0700432const SkPixmap* SkA8_Coverage_Blitter::justAnOpaqueColor(uint32_t*) {
halcanary96fcdcc2015-08-27 07:41:13 -0700433 return nullptr;
reed@google.com126f7f52013-11-07 16:06:53 +0000434}