Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(53)

Side by Side Diff: skia/sgl/SkXfermode.cpp

Issue 113827: Remove the remainder of the skia source code from the Chromium repo.... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Created 11 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « skia/sgl/SkWriter32.cpp ('k') | skia/svg/SkSVG.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright (C) 2006 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "SkXfermode.h"
18 #include "SkColorPriv.h"
19
20 #define SkAlphaMulAlpha(a, b) SkMulDiv255Round(a, b)
21
22 static SkPMColor SkFourByteInterp(SkPMColor src, SkPMColor dst, U8CPU alpha) {
23 unsigned scale = SkAlpha255To256(alpha);
24
25 unsigned a = SkAlphaBlend(SkGetPackedA32(src), SkGetPackedA32(dst), scale);
26 unsigned r = SkAlphaBlend(SkGetPackedR32(src), SkGetPackedR32(dst), scale);
27 unsigned g = SkAlphaBlend(SkGetPackedG32(src), SkGetPackedG32(dst), scale);
28 unsigned b = SkAlphaBlend(SkGetPackedB32(src), SkGetPackedB32(dst), scale);
29
30 return SkPackARGB32(a, r, g, b);
31 }
32
33 // idea for higher precision blends in xfer procs (and slightly faster)
34 // see DstATop as a probable caller
35 static U8CPU mulmuldiv255round(U8CPU a, U8CPU b, U8CPU c, U8CPU d) {
36 SkASSERT(a <= 255);
37 SkASSERT(b <= 255);
38 SkASSERT(c <= 255);
39 SkASSERT(d <= 255);
40 unsigned prod = SkMulS16(a, b) + SkMulS16(c, d) + 128;
41 unsigned result = (prod + (prod >> 8)) >> 8;
42 SkASSERT(result <= 255);
43 return result;
44 }
45
46 static unsigned saturated_add(unsigned a, unsigned b) {
47 SkASSERT(a <= 255);
48 SkASSERT(b <= 255);
49 unsigned sum = a + b;
50 if (sum > 255) {
51 sum = 255;
52 }
53 return sum;
54 }
55
56 ///////////////////////////////////////////////////////////////////////////////
57
58 bool SkXfermode::asCoeff(Coeff* src, Coeff* dst) {
59 return false;
60 }
61
62 SkPMColor SkXfermode::xferColor(SkPMColor src, SkPMColor dst) {
63 // no-op. subclasses should override this
64 return dst;
65 }
66
67 void SkXfermode::xfer32(SK_RESTRICT SkPMColor dst[],
68 const SK_RESTRICT SkPMColor src[], int count,
69 const SK_RESTRICT SkAlpha aa[]) {
70 SkASSERT(dst && src && count >= 0);
71
72 if (NULL == aa) {
73 for (int i = count - 1; i >= 0; --i) {
74 dst[i] = this->xferColor(src[i], dst[i]);
75 }
76 } else {
77 for (int i = count - 1; i >= 0; --i) {
78 unsigned a = aa[i];
79 if (0 != a) {
80 SkPMColor dstC = dst[i];
81 SkPMColor C = this->xferColor(src[i], dstC);
82 if (0xFF != a) {
83 C = SkFourByteInterp(C, dstC, a);
84 }
85 dst[i] = C;
86 }
87 }
88 }
89 }
90
91 void SkXfermode::xfer16(SK_RESTRICT uint16_t dst[],
92 const SK_RESTRICT SkPMColor src[], int count,
93 const SK_RESTRICT SkAlpha aa[]) {
94 SkASSERT(dst && src && count >= 0);
95
96 if (NULL == aa) {
97 for (int i = count - 1; i >= 0; --i) {
98 SkPMColor dstC = SkPixel16ToPixel32(dst[i]);
99 dst[i] = SkPixel32ToPixel16_ToU16(this->xferColor(src[i], dstC));
100 }
101 } else {
102 for (int i = count - 1; i >= 0; --i) {
103 unsigned a = aa[i];
104 if (0 != a) {
105 SkPMColor dstC = SkPixel16ToPixel32(dst[i]);
106 SkPMColor C = this->xferColor(src[i], dstC);
107 if (0xFF != a) {
108 C = SkFourByteInterp(C, dstC, a);
109 }
110 dst[i] = SkPixel32ToPixel16_ToU16(C);
111 }
112 }
113 }
114 }
115
116 void SkXfermode::xfer4444(SK_RESTRICT SkPMColor16 dst[],
117 const SK_RESTRICT SkPMColor src[], int count,
118 const SK_RESTRICT SkAlpha aa[])
119 {
120 SkASSERT(dst && src && count >= 0);
121
122 if (NULL == aa) {
123 for (int i = count - 1; i >= 0; --i) {
124 SkPMColor dstC = SkPixel4444ToPixel32(dst[i]);
125 dst[i] = SkPixel32ToPixel4444(this->xferColor(src[i], dstC));
126 }
127 } else {
128 for (int i = count - 1; i >= 0; --i) {
129 unsigned a = aa[i];
130 if (0 != a) {
131 SkPMColor dstC = SkPixel4444ToPixel32(dst[i]);
132 SkPMColor C = this->xferColor(src[i], dstC);
133 if (0xFF != a) {
134 C = SkFourByteInterp(C, dstC, a);
135 }
136 dst[i] = SkPixel32ToPixel4444(C);
137 }
138 }
139 }
140 }
141
142 void SkXfermode::xferA8(SK_RESTRICT SkAlpha dst[],
143 const SkPMColor src[], int count,
144 const SK_RESTRICT SkAlpha aa[])
145 {
146 SkASSERT(dst && src && count >= 0);
147
148 if (NULL == aa) {
149 for (int i = count - 1; i >= 0; --i) {
150 SkPMColor res = this->xferColor(src[i], (dst[i] << SK_A32_SHIFT));
151 dst[i] = SkToU8(SkGetPackedA32(res));
152 }
153 } else {
154 for (int i = count - 1; i >= 0; --i) {
155 unsigned a = aa[i];
156 if (0 != a) {
157 SkAlpha dstA = dst[i];
158 unsigned A = SkGetPackedA32(this->xferColor(src[i],
159 (SkPMColor)(dstA << SK_A32_SHIFT)));
160 if (0xFF != a) {
161 A = SkAlphaBlend(A, dstA, SkAlpha255To256(a));
162 }
163 dst[i] = SkToU8(A);
164 }
165 }
166 }
167 }
168
169 ///////////////////////////////////////////////////////////////////////////////
170
171 void SkProcXfermode::xfer32(SK_RESTRICT SkPMColor dst[],
172 const SK_RESTRICT SkPMColor src[], int count,
173 const SK_RESTRICT SkAlpha aa[]) {
174 SkASSERT(dst && src && count >= 0);
175
176 SkXfermodeProc proc = fProc;
177
178 if (NULL != proc) {
179 if (NULL == aa) {
180 for (int i = count - 1; i >= 0; --i) {
181 dst[i] = proc(src[i], dst[i]);
182 }
183 } else {
184 for (int i = count - 1; i >= 0; --i) {
185 unsigned a = aa[i];
186 if (0 != a) {
187 SkPMColor dstC = dst[i];
188 SkPMColor C = proc(src[i], dstC);
189 if (a != 0xFF) {
190 C = SkFourByteInterp(C, dstC, a);
191 }
192 dst[i] = C;
193 }
194 }
195 }
196 }
197 }
198
199 void SkProcXfermode::xfer16(SK_RESTRICT uint16_t dst[],
200 const SK_RESTRICT SkPMColor src[], int count,
201 const SK_RESTRICT SkAlpha aa[]) {
202 SkASSERT(dst && src && count >= 0);
203
204 SkXfermodeProc proc = fProc;
205
206 if (NULL != proc) {
207 if (NULL == aa) {
208 for (int i = count - 1; i >= 0; --i) {
209 SkPMColor dstC = SkPixel16ToPixel32(dst[i]);
210 dst[i] = SkPixel32ToPixel16_ToU16(proc(src[i], dstC));
211 }
212 } else {
213 for (int i = count - 1; i >= 0; --i) {
214 unsigned a = aa[i];
215 if (0 != a) {
216 SkPMColor dstC = SkPixel16ToPixel32(dst[i]);
217 SkPMColor C = proc(src[i], dstC);
218 if (0xFF != a) {
219 C = SkFourByteInterp(C, dstC, a);
220 }
221 dst[i] = SkPixel32ToPixel16_ToU16(C);
222 }
223 }
224 }
225 }
226 }
227
228 void SkProcXfermode::xfer4444(SK_RESTRICT SkPMColor16 dst[],
229 const SK_RESTRICT SkPMColor src[], int count,
230 const SK_RESTRICT SkAlpha aa[]) {
231 SkASSERT(dst && src && count >= 0);
232
233 SkXfermodeProc proc = fProc;
234
235 if (NULL != proc) {
236 if (NULL == aa) {
237 for (int i = count - 1; i >= 0; --i) {
238 SkPMColor dstC = SkPixel4444ToPixel32(dst[i]);
239 dst[i] = SkPixel32ToPixel4444(proc(src[i], dstC));
240 }
241 } else {
242 for (int i = count - 1; i >= 0; --i) {
243 unsigned a = aa[i];
244 if (0 != a) {
245 SkPMColor dstC = SkPixel4444ToPixel32(dst[i]);
246 SkPMColor C = proc(src[i], dstC);
247 if (0xFF != a) {
248 C = SkFourByteInterp(C, dstC, a);
249 }
250 dst[i] = SkPixel32ToPixel4444(C);
251 }
252 }
253 }
254 }
255 }
256
257 void SkProcXfermode::xferA8(SK_RESTRICT SkAlpha dst[],
258 const SK_RESTRICT SkPMColor src[], int count,
259 const SK_RESTRICT SkAlpha aa[]) {
260 SkASSERT(dst && src && count >= 0);
261
262 SkXfermodeProc proc = fProc;
263
264 if (NULL != proc) {
265 if (NULL == aa) {
266 for (int i = count - 1; i >= 0; --i) {
267 SkPMColor res = proc(src[i], dst[i] << SK_A32_SHIFT);
268 dst[i] = SkToU8(SkGetPackedA32(res));
269 }
270 } else {
271 for (int i = count - 1; i >= 0; --i) {
272 unsigned a = aa[i];
273 if (0 != a) {
274 SkAlpha dstA = dst[i];
275 SkPMColor res = proc(src[i], dstA << SK_A32_SHIFT);
276 unsigned A = SkGetPackedA32(res);
277 if (0xFF != a) {
278 A = SkAlphaBlend(A, dstA, SkAlpha255To256(a));
279 }
280 dst[i] = SkToU8(A);
281 }
282 }
283 }
284 }
285 }
286
287 SkProcXfermode::SkProcXfermode(SkFlattenableReadBuffer& buffer)
288 : SkXfermode(buffer) {
289 fProc = (SkXfermodeProc)buffer.readFunctionPtr();
290 }
291
292 void SkProcXfermode::flatten(SkFlattenableWriteBuffer& buffer) {
293 buffer.writeFunctionPtr((void*)fProc);
294 }
295
296 ///////////////////////////////////////////////////////////////////////////////
297 ///////////////////////////////////////////////////////////////////////////////
298
299 class SkProcCoeffXfermode : public SkProcXfermode {
300 public:
301 SkProcCoeffXfermode(SkXfermodeProc proc, Coeff sc, Coeff dc)
302 : INHERITED(proc), fSrcCoeff(sc), fDstCoeff(dc) {
303 }
304
305 virtual bool asCoeff(Coeff* sc, Coeff* dc) {
306 if (sc) {
307 *sc = fSrcCoeff;
308 }
309 if (dc) {
310 *dc = fDstCoeff;
311 }
312 return true;
313 }
314
315 virtual Factory getFactory() { return CreateProc; }
316 virtual void flatten(SkFlattenableWriteBuffer& buffer) {
317 this->INHERITED::flatten(buffer);
318 buffer.write32(fSrcCoeff);
319 buffer.write32(fDstCoeff);
320 }
321
322 protected:
323 SkProcCoeffXfermode(SkFlattenableReadBuffer& buffer)
324 : INHERITED(buffer) {
325 fSrcCoeff = (Coeff)buffer.readU32();
326 fDstCoeff = (Coeff)buffer.readU32();
327 }
328
329 private:
330 Coeff fSrcCoeff, fDstCoeff;
331
332 static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
333 return SkNEW_ARGS(SkProcCoeffXfermode, (buffer)); }
334
335 typedef SkProcXfermode INHERITED;
336 };
337
338 ///////////////////////////////////////////////////////////////////////////////
339
340 // kClear_Mode, //!< [0, 0]
341 static SkPMColor clear_modeproc(SkPMColor src, SkPMColor dst) {
342 return 0;
343 }
344
345 // kSrc_Mode, //!< [Sa, Sc]
346 static SkPMColor src_modeproc(SkPMColor src, SkPMColor dst) {
347 return src;
348 }
349
350 // kDst_Mode, //!< [Da, Dc]
351 static SkPMColor dst_modeproc(SkPMColor src, SkPMColor dst) {
352 return dst;
353 }
354
355 // kSrcOver_Mode, //!< [Sa + (1 - Sa)*Da, Sc + (1 - Sa)*Dc]
356 static SkPMColor srcover_modeproc(SkPMColor src, SkPMColor dst) {
357 return src + SkAlphaMulQ(dst, SkAlpha255To256(255 - SkGetPackedA32(src)));
358 }
359
360 // kDstOver_Mode, //!< [Sa + (1 - Sa)*Da, Dc + (1 - Da)*Sc]
361 static SkPMColor dstover_modeproc(SkPMColor src, SkPMColor dst) {
362 unsigned sa = SkGetPackedA32(src);
363 unsigned da = SkGetPackedA32(dst);
364 unsigned ida = 255 - da;
365
366 return SkPackARGB32(sa + da - SkAlphaMulAlpha(sa, da),
367 SkGetPackedR32(dst) + SkAlphaMulAlpha(ida, SkGetPackedR32(src)),
368 SkGetPackedG32(dst) + SkAlphaMulAlpha(ida, SkGetPackedG32(src)),
369 SkGetPackedB32(dst) + SkAlphaMulAlpha(ida, SkGetPackedB32(src)));
370 }
371
372 // kSrcIn_Mode, //!< [Sa * Da, Sc * Da]
373 static SkPMColor srcin_modeproc(SkPMColor src, SkPMColor dst) {
374 return SkAlphaMulQ(src, SkAlpha255To256(SkGetPackedA32(dst)));
375 }
376
377 // kDstIn_Mode, //!< [Sa * Da, Sa * Dc]
378 static SkPMColor dstin_modeproc(SkPMColor src, SkPMColor dst) {
379 return SkAlphaMulQ(dst, SkAlpha255To256(SkGetPackedA32(src)));
380 }
381
382 // kSrcOut_Mode, //!< [Sa * (1 - Da), Sc * (1 - Da)]
383 static SkPMColor srcout_modeproc(SkPMColor src, SkPMColor dst) {
384 return SkAlphaMulQ(src, SkAlpha255To256(255 - SkGetPackedA32(dst)));
385 }
386
387 // kDstOut_Mode, //!< [Da * (1 - Sa), Dc * (1 - Sa)]
388 static SkPMColor dstout_modeproc(SkPMColor src, SkPMColor dst) {
389 return SkAlphaMulQ(dst, SkAlpha255To256(255 - SkGetPackedA32(src)));
390 }
391
392 // kSrcATop_Mode, //!< [Da, Sc * Da + (1 - Sa) * Dc]
393 static SkPMColor srcatop_modeproc(SkPMColor src, SkPMColor dst) {
394 unsigned sa = SkGetPackedA32(src);
395 unsigned da = SkGetPackedA32(dst);
396 unsigned isa = 255 - sa;
397
398 return SkPackARGB32(da,
399 SkAlphaMulAlpha(da, SkGetPackedR32(src)) +
400 SkAlphaMulAlpha(isa, SkGetPackedR32(dst)),
401 SkAlphaMulAlpha(da, SkGetPackedG32(src)) +
402 SkAlphaMulAlpha(isa, SkGetPackedG32(dst)),
403 SkAlphaMulAlpha(da, SkGetPackedB32(src)) +
404 SkAlphaMulAlpha(isa, SkGetPackedB32(dst)));
405 }
406
407 // kDstATop_Mode, //!< [Sa, Sa * Dc + Sc * (1 - Da)]
408 static SkPMColor dstatop_modeproc(SkPMColor src, SkPMColor dst) {
409 unsigned sa = SkGetPackedA32(src);
410 unsigned da = SkGetPackedA32(dst);
411 unsigned ida = 255 - da;
412
413 return SkPackARGB32(sa,
414 SkAlphaMulAlpha(ida, SkGetPackedR32(src)) +
415 SkAlphaMulAlpha(sa, SkGetPackedR32(dst)),
416 SkAlphaMulAlpha(ida, SkGetPackedG32(src)) +
417 SkAlphaMulAlpha(sa, SkGetPackedG32(dst)),
418 SkAlphaMulAlpha(ida, SkGetPackedB32(src)) +
419 SkAlphaMulAlpha(sa, SkGetPackedB32(dst)));
420 }
421
422 // kXor_Mode [Sa + Da - 2 * Sa * Da, Sc * (1 - Da) + (1 - Sa) * Dc]
423 static SkPMColor xor_modeproc(SkPMColor src, SkPMColor dst) {
424 unsigned sa = SkGetPackedA32(src);
425 unsigned da = SkGetPackedA32(dst);
426 unsigned isa = 255 - sa;
427 unsigned ida = 255 - da;
428
429 return SkPackARGB32(sa + da - (SkAlphaMulAlpha(sa, da) << 1),
430 SkAlphaMulAlpha(ida, SkGetPackedR32(src)) +
431 SkAlphaMulAlpha(isa, SkGetPackedR32(dst)),
432 SkAlphaMulAlpha(ida, SkGetPackedG32(src)) +
433 SkAlphaMulAlpha(isa, SkGetPackedG32(dst)),
434 SkAlphaMulAlpha(ida, SkGetPackedB32(src)) +
435 SkAlphaMulAlpha(isa, SkGetPackedB32(dst)));
436 }
437
438
439 // kDarken_Mode, [Sa + Da - Sa·Da, Sc·(1 - Da) + Dc·(1 - Sa) + min(Sc, Dc)]
440
441 static inline unsigned darken_p(unsigned src, unsigned dst,
442 unsigned src_mul, unsigned dst_mul) {
443 return ((dst_mul * src + src_mul * dst) >> 8) + SkMin32(src, dst);
444 }
445
446 static SkPMColor darken_modeproc(SkPMColor src, SkPMColor dst) {
447 unsigned sa = SkGetPackedA32(src);
448 unsigned da = SkGetPackedA32(dst);
449 unsigned src_scale = SkAlpha255To256(255 - sa);
450 unsigned dst_scale = SkAlpha255To256(255 - da);
451
452 unsigned ra = sa + da - SkAlphaMulAlpha(sa, da);
453 unsigned rr = darken_p(SkGetPackedR32(src), SkGetPackedR32(dst),
454 src_scale, dst_scale);
455 unsigned rg = darken_p(SkGetPackedG32(src), SkGetPackedG32(dst),
456 src_scale, dst_scale);
457 unsigned rb = darken_p(SkGetPackedB32(src), SkGetPackedB32(dst),
458 src_scale, dst_scale);
459
460 return SkPackARGB32(ra, SkFastMin32(rr, ra),
461 SkFastMin32(rg, ra), SkFastMin32(rb, ra));
462 }
463
464 // kLighten_Mode, [Sa + Da - Sa·Da, Sc·(1 - Da) + Dc·(1 - Sa) + max(Sc, Dc)]
465 static inline unsigned lighten_p(unsigned src, unsigned dst,
466 unsigned src_mul, unsigned dst_mul) {
467 return ((dst_mul * src + src_mul * dst) >> 8) + SkMax32(src, dst);
468 }
469
470 static SkPMColor lighten_modeproc(SkPMColor src, SkPMColor dst) {
471 unsigned sa = SkGetPackedA32(src);
472 unsigned da = SkGetPackedA32(dst);
473 unsigned src_scale = SkAlpha255To256(255 - sa);
474 unsigned dst_scale = SkAlpha255To256(255 - da);
475
476 unsigned ra = sa + da - SkAlphaMulAlpha(sa, da);
477 unsigned rr = lighten_p(SkGetPackedR32(src), SkGetPackedR32(dst),
478 src_scale, dst_scale);
479 unsigned rg = lighten_p(SkGetPackedG32(src), SkGetPackedG32(dst),
480 src_scale, dst_scale);
481 unsigned rb = lighten_p(SkGetPackedB32(src), SkGetPackedB32(dst),
482 src_scale, dst_scale);
483
484 return SkPackARGB32(ra, SkFastMin32(rr, ra),
485 SkFastMin32(rg, ra), SkFastMin32(rb, ra));
486 }
487
488 static SkPMColor mult_modeproc(SkPMColor src, SkPMColor dst) {
489 int a = SkAlphaMulAlpha(SkGetPackedA32(src), SkGetPackedA32(dst));
490 int r = SkAlphaMulAlpha(SkGetPackedR32(src), SkGetPackedR32(dst));
491 int g = SkAlphaMulAlpha(SkGetPackedG32(src), SkGetPackedG32(dst));
492 int b = SkAlphaMulAlpha(SkGetPackedB32(src), SkGetPackedB32(dst));
493 return SkPackARGB32(a, r, g, b);
494 }
495
496 static inline int screen_byte(int a, int b) {
497 return a + b - SkAlphaMulAlpha(a, b);
498 }
499
500 static SkPMColor screen_modeproc(SkPMColor src, SkPMColor dst) {
501 int a = screen_byte(SkGetPackedA32(src), SkGetPackedA32(dst));
502 int r = screen_byte(SkGetPackedR32(src), SkGetPackedR32(dst));
503 int g = screen_byte(SkGetPackedG32(src), SkGetPackedG32(dst));
504 int b = screen_byte(SkGetPackedB32(src), SkGetPackedB32(dst));
505 return SkPackARGB32(a, r, g, b);
506 }
507
508 static SkPMColor add_modeproc(SkPMColor src, SkPMColor dst) {
509 unsigned a = saturated_add(SkGetPackedA32(src), SkGetPackedA32(dst));
510 unsigned r = saturated_add(SkGetPackedR32(src), SkGetPackedR32(dst));
511 unsigned g = saturated_add(SkGetPackedG32(src), SkGetPackedG32(dst));
512 unsigned b = saturated_add(SkGetPackedB32(src), SkGetPackedB32(dst));
513 return SkPackARGB32(a, r, g, b);
514 }
515
516 ///////////////////////////////////////////////////////////////////////////////
517
518 class SkClearXfermode : public SkProcCoeffXfermode {
519 public:
520 SkClearXfermode() : SkProcCoeffXfermode(clear_modeproc,
521 kZero_Coeff, kZero_Coeff) {}
522
523 virtual void xfer32(SK_RESTRICT SkPMColor dst[],
524 const SK_RESTRICT SkPMColor[], int count,
525 const SK_RESTRICT SkAlpha aa[]) {
526 SkASSERT(dst && count >= 0);
527
528 if (NULL == aa) {
529 memset(dst, 0, count << 2);
530 } else {
531 for (int i = count - 1; i >= 0; --i) {
532 unsigned a = aa[i];
533 if (0xFF == a) {
534 dst[i] = 0;
535 } else if (a != 0) {
536 dst[i] = SkAlphaMulQ(dst[i], SkAlpha255To256(255 - a));
537 }
538 }
539 }
540 }
541 virtual void xferA8(SK_RESTRICT SkAlpha dst[],
542 const SK_RESTRICT SkPMColor[], int count,
543 const SK_RESTRICT SkAlpha aa[]) {
544 SkASSERT(dst && count >= 0);
545
546 if (NULL == aa) {
547 memset(dst, 0, count);
548 } else {
549 for (int i = count - 1; i >= 0; --i) {
550 unsigned a = aa[i];
551 if (0xFF == a) {
552 dst[i] = 0;
553 } else if (0 != a) {
554 dst[i] = SkAlphaMulAlpha(dst[i], 255 - a);
555 }
556 }
557 }
558 }
559
560 virtual Factory getFactory() { return CreateProc; }
561
562 private:
563 SkClearXfermode(SkFlattenableReadBuffer& buffer)
564 : SkProcCoeffXfermode(buffer) {}
565
566 static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
567 return SkNEW_ARGS(SkClearXfermode, (buffer));
568 }
569 };
570
571 ///////////////////////////////////////////////////////////////////////////////
572
573 class SkSrcXfermode : public SkProcCoeffXfermode {
574 public:
575 SkSrcXfermode() : SkProcCoeffXfermode(src_modeproc,
576 kOne_Coeff, kZero_Coeff) {}
577
578 virtual void xfer32(SK_RESTRICT SkPMColor dst[],
579 const SK_RESTRICT SkPMColor src[], int count,
580 const SK_RESTRICT SkAlpha aa[]) {
581 SkASSERT(dst && src && count >= 0);
582
583 if (NULL == aa) {
584 memcpy(dst, src, count << 2);
585 } else {
586 for (int i = count - 1; i >= 0; --i) {
587 unsigned a = aa[i];
588 if (a == 0xFF) {
589 dst[i] = src[i];
590 } else if (a != 0) {
591 dst[i] = SkFourByteInterp(src[i], dst[i], a);
592 }
593 }
594 }
595 }
596
597 virtual void xferA8(SK_RESTRICT SkAlpha dst[],
598 const SK_RESTRICT SkPMColor src[], int count,
599 const SK_RESTRICT SkAlpha aa[]) {
600 SkASSERT(dst && src && count >= 0);
601
602 if (NULL == aa) {
603 for (int i = count - 1; i >= 0; --i) {
604 dst[i] = SkToU8(SkGetPackedA32(src[i]));
605 }
606 } else {
607 for (int i = count - 1; i >= 0; --i) {
608 unsigned a = aa[i];
609 if (0 != a) {
610 unsigned srcA = SkGetPackedA32(src[i]);
611 if (a == 0xFF) {
612 dst[i] = SkToU8(srcA);
613 } else {
614 dst[i] = SkToU8(SkAlphaBlend(srcA, dst[i], a));
615 }
616 }
617 }
618 }
619 }
620
621 virtual Factory getFactory() { return CreateProc; }
622
623 private:
624 SkSrcXfermode(SkFlattenableReadBuffer& buffer)
625 : SkProcCoeffXfermode(buffer) {}
626
627 static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
628 return SkNEW_ARGS(SkSrcXfermode, (buffer));
629 }
630 };
631
632 class SkDstInXfermode : public SkProcCoeffXfermode {
633 public:
634 SkDstInXfermode() : SkProcCoeffXfermode(dstin_modeproc,
635 kZero_Coeff, kSA_Coeff) {}
636
637 virtual void xfer32(SK_RESTRICT SkPMColor dst[],
638 const SK_RESTRICT SkPMColor src[], int count,
639 const SK_RESTRICT SkAlpha aa[]) {
640 SkASSERT(dst && src);
641
642 if (count <= 0) {
643 return;
644 }
645 if (NULL != aa) {
646 return this->INHERITED::xfer32(dst, src, count, aa);
647 }
648
649 do {
650 unsigned a = SkGetPackedA32(*src);
651 *dst = SkAlphaMulQ(*dst, SkAlpha255To256(a));
652 dst++;
653 src++;
654 } while (--count != 0);
655 }
656
657 virtual Factory getFactory() { return CreateProc; }
658
659 private:
660 SkDstInXfermode(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {}
661
662 static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
663 return SkNEW_ARGS(SkDstInXfermode, (buffer));
664 }
665
666 typedef SkProcCoeffXfermode INHERITED;
667 };
668
669 class SkDstOutXfermode : public SkProcCoeffXfermode {
670 public:
671 SkDstOutXfermode() : SkProcCoeffXfermode(dstout_modeproc,
672 kZero_Coeff, kISA_Coeff) {}
673
674 virtual void xfer32(SK_RESTRICT SkPMColor dst[],
675 const SK_RESTRICT SkPMColor src[], int count,
676 const SK_RESTRICT SkAlpha aa[]) {
677 SkASSERT(dst && src);
678
679 if (count <= 0) {
680 return;
681 }
682 if (NULL != aa) {
683 return this->INHERITED::xfer32(dst, src, count, aa);
684 }
685
686 do {
687 unsigned a = SkGetPackedA32(*src);
688 *dst = SkAlphaMulQ(*dst, SkAlpha255To256(255 - a));
689 dst++;
690 src++;
691 } while (--count != 0);
692 }
693
694 virtual Factory getFactory() { return CreateProc; }
695
696 private:
697 SkDstOutXfermode(SkFlattenableReadBuffer& buffer)
698 : INHERITED(buffer) {}
699
700 static SkFlattenable* CreateProc(SkFlattenableReadBuffer& buffer) {
701 return SkNEW_ARGS(SkDstOutXfermode, (buffer));
702 }
703
704 typedef SkProcCoeffXfermode INHERITED;
705 };
706
707 ///////////////////////////////////////////////////////////////////////////////
708
709 #include "SkPorterDuff.h"
710
711 struct ProcCoeff {
712 SkXfermodeProc fProc;
713 SkXfermode::Coeff fSC;
714 SkXfermode::Coeff fDC;
715 };
716
717 #define CANNOT_USE_COEFF SkXfermode::Coeff(-1)
718
719 static const ProcCoeff gProcCoeffs[] = {
720 { clear_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kZero_Coeff },
721 { src_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kZero_Coeff },
722 { dst_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kOne_Coeff },
723 { srcover_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kISA_Coeff },
724 { dstover_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kOne_Coeff },
725 { srcin_modeproc, SkXfermode::kDA_Coeff, SkXfermode::kZero_Coeff },
726 { dstin_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kSA_Coeff },
727 { srcout_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kZero_Coeff },
728 { dstout_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kISA_Coeff },
729 { srcatop_modeproc, SkXfermode::kDA_Coeff, SkXfermode::kISA_Coeff },
730 { dstatop_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kSA_Coeff },
731 { xor_modeproc, SkXfermode::kIDA_Coeff, SkXfermode::kISA_Coeff },
732 { darken_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
733 { lighten_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF },
734 { mult_modeproc, SkXfermode::kZero_Coeff, SkXfermode::kSC_Coeff },
735 { screen_modeproc, SkXfermode::kOne_Coeff, SkXfermode::kISC_Coeff },
736 { add_modeproc, CANNOT_USE_COEFF, CANNOT_USE_COEFF }
737 };
738
739 SkXfermode* SkPorterDuff::CreateXfermode(SkPorterDuff::Mode mode) {
740 SkASSERT(SK_ARRAY_COUNT(gProcCoeffs) == SkPorterDuff::kModeCount);
741 SkASSERT((unsigned)mode < SkPorterDuff::kModeCount);
742
743 switch (mode) {
744 case kClear_Mode:
745 return SkNEW(SkClearXfermode);
746 case kSrc_Mode:
747 return SkNEW(SkSrcXfermode);
748 case kSrcOver_Mode:
749 return NULL;
750 case kDstIn_Mode:
751 return SkNEW(SkDstInXfermode);
752 case kDstOut_Mode:
753 return SkNEW(SkDstOutXfermode);
754 // these two can't be represented with Coeff
755 case kDarken_Mode:
756 return SkNEW_ARGS(SkProcXfermode, (darken_modeproc));
757 case kLighten_Mode:
758 return SkNEW_ARGS(SkProcXfermode, (lighten_modeproc));
759 // use the table
760 default: {
761 const ProcCoeff& rec = gProcCoeffs[mode];
762 SkASSERT((unsigned)rec.fSC < SkXfermode::kCoeffCount);
763 SkASSERT((unsigned)rec.fDC < SkXfermode::kCoeffCount);
764 return SkNEW_ARGS(SkProcCoeffXfermode, (rec.fProc,
765 rec.fSC, rec.fDC));
766 }
767 }
768 }
769
770 bool SkPorterDuff::IsMode(SkXfermode* xfer, Mode* mode) {
771 if (NULL == xfer) {
772 if (mode) {
773 *mode = kSrcOver_Mode;
774 }
775 return true;
776 }
777
778 SkXfermode::Coeff sc, dc;
779 if (xfer->asCoeff(&sc, &dc)) {
780 SkASSERT((unsigned)sc < (unsigned)SkXfermode::kCoeffCount);
781 SkASSERT((unsigned)dc < (unsigned)SkXfermode::kCoeffCount);
782
783 const ProcCoeff* rec = gProcCoeffs;
784 for (size_t i = 0; i < SK_ARRAY_COUNT(gProcCoeffs); i++) {
785 if (rec[i].fSC == sc && rec[i].fDC == dc) {
786 if (mode) {
787 *mode = SkPorterDuff::Mode(i);
788 }
789 return true;
790 }
791 }
792 }
793
794 // no coefficients, or not found in our table
795 return false;
796 }
797
798 ///////////////////////////////////////////////////////////////////////////////
799
800 #ifdef SK_DEBUG
801 static void unit_test() {
802 for (unsigned a = 0; a <= 255; a++) {
803 for (unsigned c = 0; c <= a; c++) {
804 SkPMColor pm = SkPackARGB32(a, c, c, c);
805 for (unsigned aa = 0; aa <= 255; aa++) {
806 for (unsigned cc = 0; cc <= aa; cc++) {
807 SkPMColor pm2 = SkPackARGB32(aa, cc, cc, cc);
808
809 const size_t N = SK_ARRAY_COUNT(gProcCoeffs);
810 for (size_t i = 0; i < N; i++) {
811 gProcCoeffs[i].fProc(pm, pm2);
812 }
813 }
814 }
815 }
816 }
817 }
818 #endif
819
820 SkXfermodeProc SkPorterDuff::GetXfermodeProc(Mode mode) {
821 #ifdef SK_DEBUGx
822 static bool gUnitTest;
823 if (!gUnitTest) {
824 gUnitTest = true;
825 unit_test();
826 }
827 #endif
828
829 SkXfermodeProc proc = NULL;
830
831 if ((unsigned)mode < SkPorterDuff::kModeCount) {
832 proc = gProcCoeffs[mode].fProc;
833 }
834 return proc;
835 }
836
837 ///////////////////////////////////////////////////////////////////////////////
838 //////////// 16bit xfermode procs
839
840 #ifdef SK_DEBUG
841 static bool require_255(SkPMColor src) { return SkGetPackedA32(src) == 0xFF; }
842 static bool require_0(SkPMColor src) { return SkGetPackedA32(src) == 0; }
843 #endif
844
845 static uint16_t src_modeproc16_255(SkPMColor src, uint16_t dst) {
846 SkASSERT(require_255(src));
847 return SkPixel32ToPixel16(src);
848 }
849
850 static uint16_t dst_modeproc16(SkPMColor src, uint16_t dst) {
851 return dst;
852 }
853
854 static uint16_t srcover_modeproc16_0(SkPMColor src, uint16_t dst) {
855 SkASSERT(require_0(src));
856 return dst;
857 }
858
859 static uint16_t srcover_modeproc16_255(SkPMColor src, uint16_t dst) {
860 SkASSERT(require_255(src));
861 return SkPixel32ToPixel16(src);
862 }
863
864 static uint16_t dstover_modeproc16_0(SkPMColor src, uint16_t dst) {
865 SkASSERT(require_0(src));
866 return dst;
867 }
868
869 static uint16_t dstover_modeproc16_255(SkPMColor src, uint16_t dst) {
870 SkASSERT(require_255(src));
871 return dst;
872 }
873
874 static uint16_t srcin_modeproc16_255(SkPMColor src, uint16_t dst) {
875 SkASSERT(require_255(src));
876 return SkPixel32ToPixel16(src);
877 }
878
879 static uint16_t dstin_modeproc16_255(SkPMColor src, uint16_t dst) {
880 SkASSERT(require_255(src));
881 return dst;
882 }
883
884 static uint16_t dstout_modeproc16_0(SkPMColor src, uint16_t dst) {
885 SkASSERT(require_0(src));
886 return dst;
887 }
888
889 static uint16_t srcatop_modeproc16(SkPMColor src, uint16_t dst) {
890 unsigned isa = 255 - SkGetPackedA32(src);
891
892 return SkPackRGB16(
893 SkPacked32ToR16(src) + SkAlphaMulAlpha(SkGetPackedR16(dst), isa),
894 SkPacked32ToG16(src) + SkAlphaMulAlpha(SkGetPackedG16(dst), isa),
895 SkPacked32ToB16(src) + SkAlphaMulAlpha(SkGetPackedB16(dst), isa));
896 }
897
898 static uint16_t srcatop_modeproc16_0(SkPMColor src, uint16_t dst) {
899 SkASSERT(require_0(src));
900 return dst;
901 }
902
903 static uint16_t srcatop_modeproc16_255(SkPMColor src, uint16_t dst) {
904 SkASSERT(require_255(src));
905 return SkPixel32ToPixel16(src);
906 }
907
908 static uint16_t dstatop_modeproc16_255(SkPMColor src, uint16_t dst) {
909 SkASSERT(require_255(src));
910 return dst;
911 }
912
913 /*********
914 darken and lighten boil down to this.
915
916 darken = (1 - Sa) * Dc + min(Sc, Dc)
917 lighten = (1 - Sa) * Dc + max(Sc, Dc)
918
919 if (Sa == 0) these become
920 darken = Dc + min(0, Dc) = 0
921 lighten = Dc + max(0, Dc) = Dc
922
923 if (Sa == 1) these become
924 darken = min(Sc, Dc)
925 lighten = max(Sc, Dc)
926 */
927
928 static uint16_t darken_modeproc16_0(SkPMColor src, uint16_t dst) {
929 SkASSERT(require_0(src));
930 return 0;
931 }
932
933 static uint16_t darken_modeproc16_255(SkPMColor src, uint16_t dst) {
934 SkASSERT(require_255(src));
935 unsigned r = SkFastMin32(SkPacked32ToR16(src), SkGetPackedR16(dst));
936 unsigned g = SkFastMin32(SkPacked32ToG16(src), SkGetPackedG16(dst));
937 unsigned b = SkFastMin32(SkPacked32ToB16(src), SkGetPackedB16(dst));
938 return SkPackRGB16(r, g, b);
939 }
940
941 static uint16_t lighten_modeproc16_0(SkPMColor src, uint16_t dst) {
942 SkASSERT(require_0(src));
943 return dst;
944 }
945
946 static uint16_t lighten_modeproc16_255(SkPMColor src, uint16_t dst) {
947 SkASSERT(require_255(src));
948 unsigned r = SkMax32(SkPacked32ToR16(src), SkGetPackedR16(dst));
949 unsigned g = SkMax32(SkPacked32ToG16(src), SkGetPackedG16(dst));
950 unsigned b = SkMax32(SkPacked32ToB16(src), SkGetPackedB16(dst));
951 return SkPackRGB16(r, g, b);
952 }
953
954 struct Proc16Rec {
955 SkXfermodeProc16 fProc16_0;
956 SkXfermodeProc16 fProc16_255;
957 SkXfermodeProc16 fProc16_General;
958 };
959
960 static const Proc16Rec gPorterDuffModeProcs16[] = {
961 { NULL, NULL, NULL }, // CLEAR
962 { NULL, src_modeproc16_255, NULL },
963 { dst_modeproc16, dst_modeproc16, dst_modeproc16 },
964 { srcover_modeproc16_0, srcover_modeproc16_255, NULL },
965 { dstover_modeproc16_0, dstover_modeproc16_255, NULL },
966 { NULL, srcin_modeproc16_255, NULL },
967 { NULL, dstin_modeproc16_255, NULL },
968 { NULL, NULL, NULL },// SRC_OUT
969 { dstout_modeproc16_0, NULL, NULL },
970 { srcatop_modeproc16_0, srcatop_modeproc16_255, srcatop_modeproc16 },
971 { NULL, dstatop_modeproc16_255, NULL },
972 { NULL, NULL, NULL }, // XOR
973 { darken_modeproc16_0, darken_modeproc16_255, NULL },
974 { lighten_modeproc16_0, lighten_modeproc16_255, NULL },
975 { NULL, NULL, NULL },//multiply
976 { NULL, NULL, NULL }// screen
977 };
978
979 SkXfermodeProc16 SkPorterDuff::GetXfermodeProc16(Mode mode, SkColor srcColor) {
980 SkXfermodeProc16 proc16 = NULL;
981
982 if ((unsigned)mode < SkPorterDuff::kModeCount) {
983 const Proc16Rec& rec = gPorterDuffModeProcs16[mode];
984
985 unsigned a = SkColorGetA(srcColor);
986
987 if (0 == a) {
988 proc16 = rec.fProc16_0;
989 } else if (255 == a) {
990 proc16 = rec.fProc16_255;
991 } else {
992 proc16 = rec.fProc16_General;
993 }
994 }
995 return proc16;
996 }
997
OLDNEW
« no previous file with comments | « skia/sgl/SkWriter32.cpp ('k') | skia/svg/SkSVG.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698