OLD | NEW |
| (Empty) |
1 // Copyright 2014 PDFium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "core/include/fxge/fx_ge.h" | |
6 | |
7 #if defined(_SKIA_SUPPORT_) | |
8 #include "SkBlitter.h" | |
9 #include "core/include/fxcodec/fx_codec.h" | |
10 #include "core/src/fxge/skia/fx_skia_blitter_new.h" | |
11 | |
12 // We use our own renderer here to make it simple | |
13 void CFX_SkiaRenderer::blitAntiH(int x, | |
14 int y, | |
15 const SkAlpha antialias[], | |
16 const int16_t runs[]) { | |
17 FXSYS_assert(m_Alpha); | |
18 if (!m_pOriDevice && !composite_span) | |
19 return; | |
20 if (y < m_ClipBox.top || y >= m_ClipBox.bottom) | |
21 return; | |
22 while (1) { | |
23 int width = runs[0]; | |
24 SkASSERT(width >= 0); | |
25 if (width <= 0) | |
26 return; | |
27 unsigned aa = antialias[0]; | |
28 if (aa) | |
29 (*composite_span)(m_pDestScan, m_pOriScan, 0, x, width, y, aa, | |
30 m_ClipBox.top, m_ClipBox.left, m_ClipBox.right, | |
31 m_pClipScan, m_pDestExtraAlphaScan); | |
32 runs += width; | |
33 antialias += width; | |
34 x += width; | |
35 } | |
36 } | |
37 | |
38 void CFX_SkiaRenderer::blitH(int x, int y, int width) { | |
39 FXSYS_assert(m_Alpha && width); | |
40 if (y < m_ClipBox.top || y >= m_ClipBox.bottom) | |
41 return; | |
42 (*composite_span)(m_pDestScan, m_pOriScan, 0, x, width, y, 255, m_ClipBox.top, | |
43 m_ClipBox.left, m_ClipBox.right, m_pClipScan, | |
44 m_pDestExtraAlphaScan); | |
45 } | |
46 | |
47 void CFX_SkiaRenderer::blitV(int x, int y, int height, SkAlpha alpha) { | |
48 FXSYS_assert(m_Alpha && alpha); | |
49 if (alpha == 255) { | |
50 blitRect(x, y, 1, height); | |
51 } else { | |
52 int16_t runs[2]; | |
53 runs[0] = 1; | |
54 runs[1] = 0; | |
55 while (--height >= 0) { | |
56 if (y >= m_ClipBox.bottom) | |
57 return; | |
58 blitAntiH(x, y++, &alpha, runs); | |
59 } | |
60 } | |
61 } | |
62 void CFX_SkiaRenderer::blitRect(int x, int y, int width, int height) { | |
63 FXSYS_assert(m_Alpha && width); | |
64 while (--height >= 0) { | |
65 if (y >= m_ClipBox.bottom) | |
66 return; | |
67 blitH(x, y++, width); | |
68 } | |
69 } | |
70 | |
71 void CFX_SkiaRenderer::blitAntiRect(int x, | |
72 int y, | |
73 int width, | |
74 int height, | |
75 SkAlpha leftAlpha, | |
76 SkAlpha rightAlpha) { | |
77 blitV(x++, y, height, leftAlpha); | |
78 if (width > 0) { | |
79 blitRect(x, y, width, height); | |
80 x += width; | |
81 } | |
82 blitV(x, y, height, rightAlpha); | |
83 } | |
84 /*------------------------------------------------------------------------------
---------------------*/ | |
85 void CFX_SkiaRenderer::CompositeSpan1bpp_0(uint8_t* dest_scan, | |
86 uint8_t* ori_scan, | |
87 int Bpp, | |
88 int span_left, | |
89 int span_len, | |
90 int span_top, | |
91 uint8_t cover_scan, | |
92 int clip_top, | |
93 int clip_left, | |
94 int clip_right, | |
95 uint8_t* clip_scan, | |
96 uint8_t* dest_extra_alpha_scan) { | |
97 ASSERT(!m_bRgbByteOrder); | |
98 ASSERT(!m_pDevice->IsCmykImage()); | |
99 dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + span_left / 8; | |
100 int col_start = span_left < clip_left ? clip_left - span_left : 0; | |
101 int col_end = | |
102 (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); | |
103 if (col_end < col_start) | |
104 return; // do nothing. | |
105 dest_scan += col_start / 8; | |
106 | |
107 int index = 0; | |
108 if (m_pDevice->GetPalette()) { | |
109 for (int i = 0; i < 2; i++) { | |
110 if (FXARGB_TODIB(m_pDevice->GetPalette()[i]) == m_Color) | |
111 index = i; | |
112 } | |
113 } else { | |
114 index = ((uint8_t)m_Color == 0xff) ? 1 : 0; | |
115 } | |
116 uint8_t* dest_scan1 = dest_scan; | |
117 int src_alpha = m_Alpha * cover_scan / 255; | |
118 for (int col = col_start; col < col_end; col++) { | |
119 if (src_alpha) { | |
120 if (!index) | |
121 *dest_scan1 &= ~(1 << (7 - (col + span_left) % 8)); | |
122 else | |
123 *dest_scan1 |= 1 << (7 - (col + span_left) % 8); | |
124 } | |
125 dest_scan1 = dest_scan + (span_left % 8 + col - col_start + 1) / 8; | |
126 } | |
127 } | |
128 void CFX_SkiaRenderer::CompositeSpan1bpp_4(uint8_t* dest_scan, | |
129 uint8_t* ori_scan, | |
130 int Bpp, | |
131 int span_left, | |
132 int span_len, | |
133 int span_top, | |
134 uint8_t cover_scan, | |
135 int clip_top, | |
136 int clip_left, | |
137 int clip_right, | |
138 uint8_t* clip_scan, | |
139 uint8_t* dest_extra_alpha_scan) { | |
140 ASSERT(!m_bRgbByteOrder); | |
141 ASSERT(!m_pDevice->IsCmykImage()); | |
142 dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + span_left / 8; | |
143 clip_scan = (uint8_t*)m_pClipMask->GetScanline(span_top - clip_top) - | |
144 clip_left + span_left; | |
145 int col_start = span_left < clip_left ? clip_left - span_left : 0; | |
146 int col_end = | |
147 (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); | |
148 if (col_end < col_start) | |
149 return; // do nothing. | |
150 dest_scan += col_start / 8; | |
151 | |
152 int index = 0; | |
153 if (m_pDevice->GetPalette()) { | |
154 for (int i = 0; i < 2; i++) { | |
155 if (FXARGB_TODIB(m_pDevice->GetPalette()[i]) == m_Color) | |
156 index = i; | |
157 } | |
158 } else { | |
159 index = ((uint8_t)m_Color == 0xff) ? 1 : 0; | |
160 } | |
161 uint8_t* dest_scan1 = dest_scan; | |
162 int src_alpha = m_Alpha * cover_scan / 255; | |
163 for (int col = col_start; col < col_end; col++) { | |
164 int src_alpha1 = src_alpha * clip_scan[col] / 255; | |
165 if (src_alpha1) { | |
166 if (!index) | |
167 *dest_scan1 &= ~(1 << (7 - (col + span_left) % 8)); | |
168 else | |
169 *dest_scan1 |= 1 << (7 - (col + span_left) % 8); | |
170 } | |
171 dest_scan1 = dest_scan + (span_left % 8 + col - col_start + 1) / 8; | |
172 } | |
173 } | |
174 /*------------------------------------------------------------------------------
-----------------------*/ | |
175 void CFX_SkiaRenderer::CompositeSpanGray_2(uint8_t* dest_scan, | |
176 uint8_t* ori_scan, | |
177 int Bpp, | |
178 int span_left, | |
179 int span_len, | |
180 int span_top, | |
181 uint8_t cover_scan, | |
182 int clip_top, | |
183 int clip_left, | |
184 int clip_right, | |
185 uint8_t* clip_scan, | |
186 uint8_t* dest_extra_alpha_scan) { | |
187 ASSERT(!m_pDevice->IsCmykImage()); | |
188 ASSERT(!m_bRgbByteOrder); | |
189 dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + span_left; | |
190 int col_start = span_left < clip_left ? clip_left - span_left : 0; | |
191 int col_end = | |
192 (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); | |
193 if (col_end < col_start) | |
194 return; // do nothing. | |
195 dest_scan += col_start; | |
196 if (cover_scan == 255 && m_Alpha == 255) { | |
197 FXSYS_memset(dest_scan, FXARGB_MAKE(m_Gray, m_Gray, m_Gray, m_Gray), | |
198 col_end - col_start); | |
199 return; | |
200 } | |
201 int src_alpha = m_Alpha * cover_scan / 255; | |
202 for (int col = col_start; col < col_end; col++) { | |
203 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Gray, src_alpha); | |
204 dest_scan++; | |
205 } | |
206 } | |
207 void CFX_SkiaRenderer::CompositeSpanGray_3(uint8_t* dest_scan, | |
208 uint8_t* ori_scan, | |
209 int Bpp, | |
210 int span_left, | |
211 int span_len, | |
212 int span_top, | |
213 uint8_t cover_scan, | |
214 int clip_top, | |
215 int clip_left, | |
216 int clip_right, | |
217 uint8_t* clip_scan, | |
218 uint8_t* dest_extra_alpha_scan) { | |
219 ASSERT(!m_pDevice->IsCmykImage()); | |
220 ASSERT(!m_bRgbByteOrder); | |
221 dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + span_left; | |
222 ori_scan = (uint8_t*)m_pOriDevice->GetScanline(span_top) + span_left; | |
223 int col_start = span_left < clip_left ? clip_left - span_left : 0; | |
224 int col_end = | |
225 (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); | |
226 if (col_end < col_start) | |
227 return; // do nothing. | |
228 dest_scan += col_start; | |
229 ori_scan += col_start; | |
230 if (m_Alpha == 255 && cover_scan == 255) { | |
231 FXSYS_memset(dest_scan, FXARGB_MAKE(m_Gray, m_Gray, m_Gray, m_Gray), | |
232 col_end - col_start); | |
233 } else { | |
234 int src_alpha = m_Alpha; | |
235 #if 1 | |
236 for (int col = col_start; col < col_end; col++) { | |
237 int gray = FXDIB_ALPHA_MERGE(*ori_scan++, m_Gray, src_alpha); | |
238 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, cover_scan); | |
239 dest_scan++; | |
240 } | |
241 #else | |
242 if (m_bFullCover) { | |
243 if (src_alpha == 255) { | |
244 FXSYS_memset(dest_scan, FXARGB_MAKE(m_Gray, m_Gray, m_Gray, m_Gray), | |
245 col_end - col_start); | |
246 return; | |
247 } | |
248 for (int col = col_start; col < col_end; col++) | |
249 *dest_scan = FXDIB_ALPHA_MERGE(*ori_scan++, m_Gray, src_alpha); | |
250 } else { | |
251 for (int col = col_start; col < col_end; col++) { | |
252 int gray = FXDIB_ALPHA_MERGE(*ori_scan++, m_Gray, src_alpha); | |
253 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, cover_scan); | |
254 dest_scan++; | |
255 } | |
256 } | |
257 #endif | |
258 } | |
259 } | |
260 | |
261 void CFX_SkiaRenderer::CompositeSpanGray_6(uint8_t* dest_scan, | |
262 uint8_t* ori_scan, | |
263 int Bpp, | |
264 int span_left, | |
265 int span_len, | |
266 int span_top, | |
267 uint8_t cover_scan, | |
268 int clip_top, | |
269 int clip_left, | |
270 int clip_right, | |
271 uint8_t* clip_scan, | |
272 uint8_t* dest_extra_alpha_scan) { | |
273 ASSERT(!m_bRgbByteOrder); | |
274 dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + span_left; | |
275 clip_scan = (uint8_t*)m_pClipMask->GetScanline(span_top - clip_top) - | |
276 clip_left + span_left; | |
277 int col_start = span_left < clip_left ? clip_left - span_left : 0; | |
278 int col_end = | |
279 (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); | |
280 if (col_end < col_start) | |
281 return; // do nothing. | |
282 dest_scan += col_start; | |
283 int src_alpha = m_Alpha * cover_scan / 255; | |
284 for (int col = col_start; col < col_end; col++) { | |
285 int src_alpha1 = src_alpha * clip_scan[col] / 255; | |
286 if (!src_alpha1) { | |
287 dest_scan++; | |
288 continue; | |
289 } | |
290 if (src_alpha1 == 255) { | |
291 *dest_scan++ = m_Gray; | |
292 } else { | |
293 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Gray, src_alpha1); | |
294 dest_scan++; | |
295 } | |
296 } | |
297 } | |
298 | |
299 void CFX_SkiaRenderer::CompositeSpanGray_7(uint8_t* dest_scan, | |
300 uint8_t* ori_scan, | |
301 int Bpp, | |
302 int span_left, | |
303 int span_len, | |
304 int span_top, | |
305 uint8_t cover_scan, | |
306 int clip_top, | |
307 int clip_left, | |
308 int clip_right, | |
309 uint8_t* clip_scan, | |
310 uint8_t* dest_extra_alpha_scan) { | |
311 ASSERT(!m_pDevice->IsCmykImage()); | |
312 dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + span_left; | |
313 ori_scan = (uint8_t*)m_pOriDevice->GetScanline(span_top) + span_left; | |
314 clip_scan = (uint8_t*)m_pClipMask->GetScanline(span_top - clip_top) - | |
315 clip_left + span_left; | |
316 int col_start = span_left < clip_left ? clip_left - span_left : 0; | |
317 int col_end = | |
318 (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); | |
319 if (col_end < col_start) | |
320 return; // do nothing. | |
321 dest_scan += col_start; | |
322 ori_scan += col_start; | |
323 #if 1 | |
324 for (int col = col_start; col < col_end; col++) { | |
325 int src_alpha = m_Alpha * clip_scan[col] / 255; | |
326 if (src_alpha == 255 && cover_scan == 255) { | |
327 *dest_scan++ = m_Gray; | |
328 ori_scan++; | |
329 continue; | |
330 } | |
331 int gray = FXDIB_ALPHA_MERGE(*ori_scan++, m_Gray, src_alpha); | |
332 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, cover_scan); | |
333 dest_scan++; | |
334 } | |
335 | |
336 #else | |
337 if (m_bFullCover) { | |
338 for (int col = col_start; col < col_end; col++) { | |
339 int src_alpha = m_Alpha * clip_scan[col] / 255; | |
340 if (!src_alpha) { | |
341 dest_scan++; | |
342 ori_scan++; | |
343 continue; | |
344 } | |
345 if (src_alpha == 255) { | |
346 *dest_scan++ = m_Gray; | |
347 ori_scan++; | |
348 continue; | |
349 } | |
350 *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Gray, src_alpha); | |
351 } | |
352 } else { | |
353 for (int col = col_start; col < col_end; col++) { | |
354 int src_alpha = m_Alpha * clip_scan[col] / 255; | |
355 if (src_alpha == 255 && cover_scan == 255) { | |
356 *dest_scan++ = m_Gray; | |
357 ori_scan++; | |
358 continue; | |
359 } | |
360 int gray = FXDIB_ALPHA_MERGE(*ori_scan++, m_Gray, src_alpha); | |
361 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, cover_scan); | |
362 dest_scan++; | |
363 } | |
364 } | |
365 #endif | |
366 } | |
367 /*------------------------------------------------------------------------------
--------------------*/ | |
368 | |
369 void CFX_SkiaRenderer::CompositeSpanARGB_2(uint8_t* dest_scan, | |
370 uint8_t* ori_scan, | |
371 int Bpp, | |
372 int span_left, | |
373 int span_len, | |
374 int span_top, | |
375 uint8_t cover_scan, | |
376 int clip_top, | |
377 int clip_left, | |
378 int clip_right, | |
379 uint8_t* clip_scan, | |
380 uint8_t* dest_extra_alpha_scan) { | |
381 dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + (span_left << 2); | |
382 int col_start = span_left < clip_left ? clip_left - span_left : 0; | |
383 int col_end = | |
384 (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); | |
385 if (col_end < col_start) | |
386 return; // do nothing. | |
387 dest_scan += col_start << 2; | |
388 if (m_Alpha == 255 && cover_scan == 255) { | |
389 FXSYS_memset(dest_scan, m_Color, (col_end - col_start) << 2); | |
390 return; | |
391 } | |
392 int src_alpha = m_Alpha * cover_scan / 255; | |
393 for (int col = col_start; col < col_end; col++) { | |
394 // Dest format: Argb | |
395 // calculate destination alpha (it's union of source and dest alpha) | |
396 if (dest_scan[3] == 0) { | |
397 dest_scan[3] = src_alpha; | |
398 *dest_scan++ = m_Blue; | |
399 *dest_scan++ = m_Green; | |
400 *dest_scan = m_Red; | |
401 dest_scan += 2; | |
402 continue; | |
403 } | |
404 uint8_t dest_alpha = | |
405 dest_scan[3] + src_alpha - dest_scan[3] * src_alpha / 255; | |
406 dest_scan[3] = dest_alpha; | |
407 int alpha_ratio = src_alpha * 255 / dest_alpha; | |
408 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); | |
409 dest_scan++; | |
410 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); | |
411 dest_scan++; | |
412 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); | |
413 dest_scan += 2; | |
414 } | |
415 } | |
416 | |
417 void CFX_SkiaRenderer::CompositeSpanARGB_3(uint8_t* dest_scan, | |
418 uint8_t* ori_scan, | |
419 int Bpp, | |
420 int span_left, | |
421 int span_len, | |
422 int span_top, | |
423 uint8_t cover_scan, | |
424 int clip_top, | |
425 int clip_left, | |
426 int clip_right, | |
427 uint8_t* clip_scan, | |
428 uint8_t* dest_extra_alpha_scan) { | |
429 ASSERT(!m_pDevice->IsCmykImage()); | |
430 dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + (span_left << 2); | |
431 // ori_scan = (uint8_t*)m_pOriDevice->GetScanline(span_top) + (span_left<<2); | |
432 int col_start = span_left < clip_left ? clip_left - span_left : 0; | |
433 int col_end = | |
434 (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); | |
435 if (col_end < col_start) | |
436 return; // do nothing. | |
437 dest_scan += col_start << 2; | |
438 // ori_scan += col_start << 2; | |
439 | |
440 if (m_Alpha == 255 && cover_scan == 255) { | |
441 FXSYS_memset(dest_scan, m_Color, (col_end - col_start) << 2); | |
442 return; | |
443 } | |
444 if (cover_scan == 255) { | |
445 int dst_color = (0x00ffffff & m_Color) | (m_Alpha << 24); | |
446 FXSYS_memset(dest_scan, dst_color, (col_end - col_start) << 2); | |
447 return; | |
448 } | |
449 // Do not need origin bitmap, because of merge in pure transparent background | |
450 int src_alpha_covered = m_Alpha * cover_scan / 255; | |
451 for (int col = col_start; col < col_end; col++) { | |
452 // shortcut | |
453 if (dest_scan[3] == 0) { | |
454 dest_scan[3] = src_alpha_covered; | |
455 *dest_scan++ = m_Blue; | |
456 *dest_scan++ = m_Green; | |
457 *dest_scan = m_Red; | |
458 dest_scan += 2; | |
459 continue; | |
460 } | |
461 // We should do alpha transition and color transition | |
462 // alpha fg color fg | |
463 // alpha bg color bg | |
464 // alpha cover color cover | |
465 dest_scan[3] = FXDIB_ALPHA_MERGE(dest_scan[3], m_Alpha, cover_scan); | |
466 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, cover_scan); | |
467 dest_scan++; | |
468 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, cover_scan); | |
469 dest_scan++; | |
470 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, cover_scan); | |
471 dest_scan += 2; | |
472 } | |
473 } | |
474 void CFX_SkiaRenderer::CompositeSpanARGB_6(uint8_t* dest_scan, | |
475 uint8_t* ori_scan, | |
476 int Bpp, | |
477 int span_left, | |
478 int span_len, | |
479 int span_top, | |
480 uint8_t cover_scan, | |
481 int clip_top, | |
482 int clip_left, | |
483 int clip_right, | |
484 uint8_t* clip_scan, | |
485 uint8_t* dest_extra_alpha_scan) { | |
486 dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + (span_left << 2); | |
487 clip_scan = (uint8_t*)m_pClipMask->GetScanline(span_top - clip_top) - | |
488 clip_left + span_left; | |
489 int col_start = span_left < clip_left ? clip_left - span_left : 0; | |
490 int col_end = | |
491 (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); | |
492 if (col_end < col_start) | |
493 return; // do nothing. | |
494 dest_scan += col_start << 2; | |
495 #if 1 | |
496 int src_alpha = m_Alpha * cover_scan / 255; | |
497 for (int col = col_start; col < col_end; col++) { | |
498 int src_alpha1 = src_alpha * clip_scan[col] / 255; | |
499 if (!src_alpha1) { | |
500 dest_scan += 4; | |
501 continue; | |
502 } | |
503 if (src_alpha1 == 255) { | |
504 *(FX_DWORD*)dest_scan = m_Color; | |
505 dest_scan += 4; | |
506 } else { | |
507 // Dest format: Argb | |
508 // calculate destination alpha (it's union of source and dest alpha) | |
509 if (dest_scan[3] == 0) { | |
510 dest_scan[3] = src_alpha1; | |
511 *dest_scan++ = m_Blue; | |
512 *dest_scan++ = m_Green; | |
513 *dest_scan = m_Red; | |
514 dest_scan += 2; | |
515 continue; | |
516 } | |
517 uint8_t dest_alpha = | |
518 dest_scan[3] + src_alpha1 - dest_scan[3] * src_alpha1 / 255; | |
519 dest_scan[3] = dest_alpha; | |
520 int alpha_ratio = src_alpha1 * 255 / dest_alpha; | |
521 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); | |
522 dest_scan++; | |
523 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); | |
524 dest_scan++; | |
525 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); | |
526 dest_scan += 2; | |
527 } | |
528 } | |
529 #else | |
530 if (m_bFullCover) { | |
531 for (int col = col_start; col < col_end; col++) { | |
532 int src_alpha = m_Alpha * clip_scan[col] / 255; | |
533 if (!src_alpha) { | |
534 dest_scan += 4; | |
535 continue; | |
536 } | |
537 if (src_alpha == 255) { | |
538 *(FX_DWORD*)dest_scan = m_Color; | |
539 dest_scan += 4; | |
540 continue; | |
541 } else { | |
542 // Dest format: Argb | |
543 // calculate destination alpha (it's union of source and dest alpha) | |
544 if (dest_scan[3] == 0) { | |
545 dest_scan[3] = src_alpha; | |
546 *dest_scan++ = m_Blue; | |
547 *dest_scan++ = m_Green; | |
548 *dest_scan = m_Red; | |
549 dest_scan += 2; | |
550 continue; | |
551 } | |
552 uint8_t dest_alpha = | |
553 dest_scan[3] + src_alpha - dest_scan[3] * src_alpha / 255; | |
554 dest_scan[3] = dest_alpha; | |
555 int alpha_ratio = src_alpha * 255 / dest_alpha; | |
556 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); | |
557 dest_scan++; | |
558 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); | |
559 dest_scan++; | |
560 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); | |
561 dest_scan += 2; | |
562 } | |
563 } | |
564 } else { | |
565 int src_alpha = m_Alpha * cover_scan / 255; | |
566 for (int col = col_start; col < col_end; col++) { | |
567 int src_alpha1 = src_alpha * clip_scan[col] / 255; | |
568 if (!src_alpha1) { | |
569 dest_scan += 4; | |
570 continue; | |
571 } | |
572 if (src_alpha1 == 255) { | |
573 *(FX_DWORD*)dest_scan = m_Color; | |
574 dest_scan += 4; | |
575 } else { | |
576 // Dest format: Argb | |
577 // calculate destination alpha (it's union of source and dest alpha) | |
578 if (dest_scan[3] == 0) { | |
579 dest_scan[3] = src_alpha1; | |
580 *dest_scan++ = m_Blue; | |
581 *dest_scan++ = m_Green; | |
582 *dest_scan = m_Red; | |
583 dest_scan += 2; | |
584 continue; | |
585 } | |
586 uint8_t dest_alpha = | |
587 dest_scan[3] + src_alpha1 - dest_scan[3] * src_alpha1 / 255; | |
588 dest_scan[3] = dest_alpha; | |
589 int alpha_ratio = src_alpha1 * 255 / dest_alpha; | |
590 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); | |
591 dest_scan++; | |
592 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); | |
593 dest_scan++; | |
594 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); | |
595 dest_scan += 2; | |
596 } | |
597 } | |
598 } | |
599 #endif | |
600 } | |
601 | |
602 void CFX_SkiaRenderer::CompositeSpanARGB_7(uint8_t* dest_scan, | |
603 uint8_t* ori_scan, | |
604 int Bpp, | |
605 int span_left, | |
606 int span_len, | |
607 int span_top, | |
608 uint8_t cover_scan, | |
609 int clip_top, | |
610 int clip_left, | |
611 int clip_right, | |
612 uint8_t* clip_scan, | |
613 uint8_t* dest_extra_alpha_scan) { | |
614 ASSERT(!m_pDevice->IsCmykImage()); | |
615 dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + (span_left << 2); | |
616 // ori_scan = (uint8_t*)m_pOriDevice->GetScanline(span_top) + (span_left<<2); | |
617 clip_scan = (uint8_t*)m_pClipMask->GetScanline(span_top - clip_top) - | |
618 clip_left + span_left; | |
619 int col_start = span_left < clip_left ? clip_left - span_left : 0; | |
620 int col_end = | |
621 (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); | |
622 if (col_end < col_start) | |
623 return; // do nothing. | |
624 dest_scan += col_start << 2; | |
625 // ori_scan += col_start << 2; | |
626 // Do not need origin bitmap, because of merge in pure transparent background | |
627 for (int col = col_start; col < col_end; col++) { | |
628 int src_alpha = m_Alpha * clip_scan[col] / 255; | |
629 int src_alpha_covered = src_alpha * cover_scan / 255; | |
630 // shortcut | |
631 if (src_alpha_covered == 0) { | |
632 dest_scan += 4; | |
633 continue; | |
634 } | |
635 // shortcut | |
636 if (cover_scan == 255 || dest_scan[3] == 0) { | |
637 // origin alpha always zero, just get src alpha | |
638 dest_scan[3] = src_alpha_covered; | |
639 *dest_scan++ = m_Blue; | |
640 *dest_scan++ = m_Green; | |
641 *dest_scan = m_Red; | |
642 dest_scan += 2; | |
643 continue; | |
644 } | |
645 // We should do alpha transition and color transition | |
646 // alpha fg color fg | |
647 // alpha bg color bg | |
648 // alpha cover color cover | |
649 dest_scan[3] = FXDIB_ALPHA_MERGE(dest_scan[3], src_alpha, cover_scan); | |
650 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, cover_scan); | |
651 dest_scan++; | |
652 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, cover_scan); | |
653 dest_scan++; | |
654 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, cover_scan); | |
655 dest_scan += 2; | |
656 } | |
657 } | |
658 | |
659 /*------------------------------------------------------------------------------
-----------------------------*/ | |
660 void CFX_SkiaRenderer::CompositeSpanRGB32_2(uint8_t* dest_scan, | |
661 uint8_t* ori_scan, | |
662 int Bpp, | |
663 int span_left, | |
664 int span_len, | |
665 int span_top, | |
666 uint8_t cover_scan, | |
667 int clip_top, | |
668 int clip_left, | |
669 int clip_right, | |
670 uint8_t* clip_scan, | |
671 uint8_t* dest_extra_alpha_scan) { | |
672 dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + (span_left << 2); | |
673 int col_start = span_left < clip_left ? clip_left - span_left : 0; | |
674 int col_end = | |
675 (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); | |
676 if (col_end < col_start) | |
677 return; // do nothing. | |
678 dest_scan += (col_start << 2); | |
679 if (m_Alpha == 255 && cover_scan == 255) { | |
680 FXSYS_memset(dest_scan, m_Color, (col_end - col_start) << 2); | |
681 return; | |
682 } | |
683 int src_alpha = m_Alpha * cover_scan / 255; | |
684 for (int col = col_start; col < col_end; col++) { | |
685 // Dest format: Rgb32 | |
686 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha); | |
687 dest_scan++; | |
688 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha); | |
689 dest_scan++; | |
690 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha); | |
691 dest_scan += 2; | |
692 } | |
693 } | |
694 void CFX_SkiaRenderer::CompositeSpanRGB32_3(uint8_t* dest_scan, | |
695 uint8_t* ori_scan, | |
696 int Bpp, | |
697 int span_left, | |
698 int span_len, | |
699 int span_top, | |
700 uint8_t cover_scan, | |
701 int clip_top, | |
702 int clip_left, | |
703 int clip_right, | |
704 uint8_t* clip_scan, | |
705 uint8_t* dest_extra_alpha_scan) { | |
706 dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + (span_left << 2); | |
707 ori_scan = (uint8_t*)m_pOriDevice->GetScanline(span_top) + (span_left << 2); | |
708 int col_start = span_left < clip_left ? clip_left - span_left : 0; | |
709 int col_end = | |
710 (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); | |
711 if (col_end < col_start) | |
712 return; // do nothing. | |
713 dest_scan += col_start << 2; | |
714 ori_scan += col_start << 2; | |
715 if (m_Alpha == 255 && cover_scan == 255) { | |
716 FXSYS_memset(dest_scan, m_Color, (col_end - col_start) << 2); | |
717 return; | |
718 } | |
719 int src_alpha = m_Alpha; | |
720 for (int col = col_start; col < col_end; col++) { | |
721 int b = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, src_alpha); | |
722 int g = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, src_alpha); | |
723 int r = FXDIB_ALPHA_MERGE(*ori_scan, m_Red, src_alpha); | |
724 ori_scan += 2; | |
725 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, b, cover_scan); | |
726 dest_scan++; | |
727 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, g, cover_scan); | |
728 dest_scan++; | |
729 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, r, cover_scan); | |
730 dest_scan += 2; | |
731 } | |
732 } | |
733 void CFX_SkiaRenderer::CompositeSpanRGB32_6(uint8_t* dest_scan, | |
734 uint8_t* ori_scan, | |
735 int Bpp, | |
736 int span_left, | |
737 int span_len, | |
738 int span_top, | |
739 uint8_t cover_scan, | |
740 int clip_top, | |
741 int clip_left, | |
742 int clip_right, | |
743 uint8_t* clip_scan, | |
744 uint8_t* dest_extra_alpha_scan) { | |
745 dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + (span_left << 2); | |
746 clip_scan = (uint8_t*)m_pClipMask->GetScanline(span_top - clip_top) - | |
747 clip_left + span_left; | |
748 int col_start = span_left < clip_left ? clip_left - span_left : 0; | |
749 int col_end = | |
750 (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); | |
751 if (col_end < col_start) | |
752 return; // do nothing. | |
753 dest_scan += col_start << 2; | |
754 #if 1 | |
755 int src_alpha = m_Alpha * cover_scan / 255; | |
756 for (int col = col_start; col < col_end; col++) { | |
757 int src_alpha1 = src_alpha * clip_scan[col] / 255; | |
758 if (!src_alpha1) { | |
759 dest_scan += 4; | |
760 continue; | |
761 } | |
762 if (src_alpha1 == 255) { | |
763 *(FX_DWORD*)dest_scan = m_Color; | |
764 dest_scan += 4; | |
765 } else { | |
766 // Dest format: Rgb or Rgb32 | |
767 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha1); | |
768 dest_scan++; | |
769 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha1); | |
770 dest_scan++; | |
771 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha1); | |
772 dest_scan += 2; | |
773 } | |
774 } | |
775 #else | |
776 if (m_bFullCover) { | |
777 for (int col = col_start; col < col_end; col++) { | |
778 int src_alpha = m_Alpha * clip_scan[col] / 255; | |
779 if (!src_alpha) { | |
780 dest_scan += 4; | |
781 continue; | |
782 } | |
783 if (src_alpha == 255) { | |
784 *(FX_DWORD*)dest_scan = m_Color; | |
785 dest_scan += 4; | |
786 } else { | |
787 // Dest format: Rgb or Rgb32 | |
788 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha); | |
789 dest_scan++; | |
790 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha); | |
791 dest_scan++; | |
792 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha); | |
793 dest_scan += 2; | |
794 } | |
795 } | |
796 } else { | |
797 // Rgb32 | |
798 int src_alpha = m_Alpha * cover_scan / 255; | |
799 for (int col = col_start; col < col_end; col++) { | |
800 int src_alpha1 = src_alpha * clip_scan[col] / 255; | |
801 if (!src_alpha1) { | |
802 dest_scan += 4; | |
803 continue; | |
804 } | |
805 if (src_alpha1 == 255) { | |
806 *(FX_DWORD*)dest_scan = m_Color; | |
807 dest_scan += 4; | |
808 } else { | |
809 // Dest format: Rgb or Rgb32 | |
810 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha1); | |
811 dest_scan++; | |
812 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha1); | |
813 dest_scan++; | |
814 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha1); | |
815 dest_scan += 2; | |
816 } | |
817 } | |
818 } | |
819 #endif | |
820 } | |
821 void CFX_SkiaRenderer::CompositeSpanRGB32_7(uint8_t* dest_scan, | |
822 uint8_t* ori_scan, | |
823 int Bpp, | |
824 int span_left, | |
825 int span_len, | |
826 int span_top, | |
827 uint8_t cover_scan, | |
828 int clip_top, | |
829 int clip_left, | |
830 int clip_right, | |
831 uint8_t* clip_scan, | |
832 uint8_t* dest_extra_alpha_scan) { | |
833 ASSERT(!m_pDevice->IsCmykImage()); | |
834 dest_scan = (uint8_t*)m_pDevice->GetScanline(span_top) + (span_left << 2); | |
835 ori_scan = (uint8_t*)m_pOriDevice->GetScanline(span_top) + (span_left << 2); | |
836 clip_scan = (uint8_t*)m_pClipMask->GetScanline(span_top - clip_top) - | |
837 clip_left + span_left; | |
838 int col_start = span_left < clip_left ? clip_left - span_left : 0; | |
839 int col_end = | |
840 (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); | |
841 if (col_end < col_start) | |
842 return; // do nothing. | |
843 dest_scan += col_start << 2; | |
844 ori_scan += col_start << 2; | |
845 #if 1 | |
846 for (int col = col_start; col < col_end; col++) { | |
847 int src_alpha = m_Alpha * clip_scan[col] / 255; | |
848 if (src_alpha == 255 && cover_scan == 255) { | |
849 *(FX_DWORD*)dest_scan = m_Color; | |
850 dest_scan += 4; | |
851 ori_scan += 4; | |
852 continue; | |
853 } | |
854 int b = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, src_alpha); | |
855 int g = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, src_alpha); | |
856 int r = FXDIB_ALPHA_MERGE(*ori_scan, m_Red, src_alpha); | |
857 ori_scan += 2; | |
858 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, b, cover_scan); | |
859 dest_scan++; | |
860 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, g, cover_scan); | |
861 dest_scan++; | |
862 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, r, cover_scan); | |
863 dest_scan += 2; | |
864 } | |
865 #else | |
866 if (m_bFullCover) { | |
867 for (int col = col_start; col < col_end; col++) { | |
868 int src_alpha = m_Alpha * clip_scan[col] / 255; | |
869 if (!src_alpha) { | |
870 *(FX_DWORD*)dest_scan = *(FX_DWORD*)ori_scan; | |
871 dest_scan += 4; | |
872 ori_scan += 4; | |
873 continue; | |
874 } | |
875 if (src_alpha == 255) { | |
876 *(FX_DWORD*)dest_scan = m_Color; | |
877 dest_scan += 4; | |
878 ori_scan += 4; | |
879 continue; | |
880 } | |
881 *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, src_alpha); | |
882 *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, src_alpha); | |
883 *dest_scan = FXDIB_ALPHA_MERGE(*ori_scan, m_Red, src_alpha); | |
884 dest_scan += 2; | |
885 ori_scan += 2; | |
886 } | |
887 } else { | |
888 for (int col = col_start; col < col_end; col++) { | |
889 int src_alpha = m_Alpha * clip_scan[col] / 255; | |
890 if (src_alpha == 255 && cover_scan == 255) { | |
891 *(FX_DWORD*)dest_scan = m_Color; | |
892 dest_scan += 4; | |
893 ori_scan += 4; | |
894 continue; | |
895 } | |
896 int b = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, src_alpha); | |
897 int g = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, src_alpha); | |
898 int r = FXDIB_ALPHA_MERGE(*ori_scan, m_Red, src_alpha); | |
899 ori_scan += 2; | |
900 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, b, cover_scan); | |
901 dest_scan++; | |
902 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, g, cover_scan); | |
903 dest_scan++; | |
904 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, r, cover_scan); | |
905 dest_scan += 2; | |
906 } | |
907 } | |
908 #endif | |
909 } | |
910 /*------------------------------------------------------------------------------
-----------------------*/ | |
911 void CFX_SkiaRenderer::CompositeSpanRGB24_2(uint8_t* dest_scan, | |
912 uint8_t* ori_scan, | |
913 int Bpp, | |
914 int span_left, | |
915 int span_len, | |
916 int span_top, | |
917 uint8_t cover_scan, | |
918 int clip_top, | |
919 int clip_left, | |
920 int clip_right, | |
921 uint8_t* clip_scan, | |
922 uint8_t* dest_extra_alpha_scan) { | |
923 dest_scan = | |
924 (uint8_t*)m_pDevice->GetScanline(span_top) + span_left + (span_left << 1); | |
925 int col_start = span_left < clip_left ? clip_left - span_left : 0; | |
926 int col_end = | |
927 (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); | |
928 if (col_end < col_start) | |
929 return; // do nothing. | |
930 dest_scan += (col_start << 1) + col_start; | |
931 int src_alpha = m_Alpha * cover_scan / 255; | |
932 if (src_alpha == 255) { | |
933 for (int col = col_start; col < col_end; col++) { | |
934 *dest_scan++ = m_Blue; | |
935 *dest_scan++ = m_Green; | |
936 *dest_scan++ = m_Red; | |
937 } | |
938 return; | |
939 } | |
940 for (int col = col_start; col < col_end; col++) { | |
941 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha); | |
942 dest_scan++; | |
943 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha); | |
944 dest_scan++; | |
945 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha); | |
946 dest_scan++; | |
947 } | |
948 } | |
949 void CFX_SkiaRenderer::CompositeSpanRGB24_3(uint8_t* dest_scan, | |
950 uint8_t* ori_scan, | |
951 int Bpp, | |
952 int span_left, | |
953 int span_len, | |
954 int span_top, | |
955 uint8_t cover_scan, | |
956 int clip_top, | |
957 int clip_left, | |
958 int clip_right, | |
959 uint8_t* clip_scan, | |
960 uint8_t* dest_extra_alpha_scan) { | |
961 ASSERT(!m_pDevice->IsCmykImage()); | |
962 dest_scan = | |
963 (uint8_t*)m_pDevice->GetScanline(span_top) + span_left + (span_left << 1); | |
964 ori_scan = (uint8_t*)m_pOriDevice->GetScanline(span_top) + span_left + | |
965 (span_left << 1); | |
966 int col_start = span_left < clip_left ? clip_left - span_left : 0; | |
967 int col_end = | |
968 (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); | |
969 if (col_end < col_start) | |
970 return; // do nothing. | |
971 dest_scan += (col_start << 1) + col_start; | |
972 ori_scan += (col_start << 1) + col_start; | |
973 if (m_Alpha == 255 && cover_scan == 255) { | |
974 for (int col = col_start; col < col_end; col++) { | |
975 *dest_scan++ = m_Blue; | |
976 *dest_scan++ = m_Green; | |
977 *dest_scan++ = m_Red; | |
978 } | |
979 return; | |
980 } | |
981 for (int col = col_start; col < col_end; col++) { | |
982 int b = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, m_Alpha); | |
983 int g = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, m_Alpha); | |
984 int r = FXDIB_ALPHA_MERGE(*ori_scan++, m_Red, m_Alpha); | |
985 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, b, cover_scan); | |
986 dest_scan++; | |
987 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, g, cover_scan); | |
988 dest_scan++; | |
989 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, r, cover_scan); | |
990 dest_scan++; | |
991 } | |
992 } | |
993 void CFX_SkiaRenderer::CompositeSpanRGB24_6(uint8_t* dest_scan, | |
994 uint8_t* ori_scan, | |
995 int Bpp, | |
996 int span_left, | |
997 int span_len, | |
998 int span_top, | |
999 uint8_t cover_scan, | |
1000 int clip_top, | |
1001 int clip_left, | |
1002 int clip_right, | |
1003 uint8_t* clip_scan, | |
1004 uint8_t* dest_extra_alpha_scan) { | |
1005 dest_scan = | |
1006 (uint8_t*)m_pDevice->GetScanline(span_top) + span_left + (span_left << 1); | |
1007 clip_scan = (uint8_t*)m_pClipMask->GetScanline(span_top - clip_top) - | |
1008 clip_left + span_left; | |
1009 int col_start = span_left < clip_left ? clip_left - span_left : 0; | |
1010 int col_end = | |
1011 (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); | |
1012 if (col_end < col_start) | |
1013 return; // do nothing. | |
1014 dest_scan += col_start + (col_start << 1); | |
1015 #if 1 | |
1016 int src_alpha = m_Alpha * cover_scan / 255; | |
1017 for (int col = col_start; col < col_end; col++) { | |
1018 int src_alpha1 = src_alpha * clip_scan[col] / 255; | |
1019 if (!src_alpha1) { | |
1020 dest_scan += 3; | |
1021 continue; | |
1022 } | |
1023 if (src_alpha1 == 255) { | |
1024 *dest_scan++ = m_Blue; | |
1025 *dest_scan++ = m_Green; | |
1026 *dest_scan++ = m_Red; | |
1027 } else { | |
1028 // Dest format: Rgb | |
1029 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha1); | |
1030 dest_scan++; | |
1031 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha1); | |
1032 dest_scan++; | |
1033 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha1); | |
1034 dest_scan++; | |
1035 } | |
1036 } | |
1037 #else | |
1038 if (m_bFullCover) { | |
1039 for (int col = col_start; col < col_end; col++) { | |
1040 int src_alpha = m_Alpha * clip_scan[col] / 255; | |
1041 if (!src_alpha) { | |
1042 dest_scan += 3; | |
1043 continue; | |
1044 } | |
1045 if (src_alpha == 255) { | |
1046 *dest_scan++ = m_Blue; | |
1047 *dest_scan++ = m_Green; | |
1048 *dest_scan++ = m_Red; | |
1049 } else { | |
1050 // Dest format: Rgb | |
1051 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha); | |
1052 dest_scan++; | |
1053 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha); | |
1054 dest_scan++; | |
1055 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha); | |
1056 dest_scan++; | |
1057 } | |
1058 } | |
1059 } else { | |
1060 int src_alpha = m_Alpha * cover_scan / 255; | |
1061 for (int col = col_start; col < col_end; col++) { | |
1062 int src_alpha1 = src_alpha * clip_scan[col] / 255; | |
1063 if (!src_alpha1) { | |
1064 dest_scan += 3; | |
1065 continue; | |
1066 } | |
1067 if (src_alpha1 == 255) { | |
1068 *dest_scan++ = m_Blue; | |
1069 *dest_scan++ = m_Green; | |
1070 *dest_scan++ = m_Red; | |
1071 } else { | |
1072 // Dest format: Rgb | |
1073 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha1); | |
1074 dest_scan++; | |
1075 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha1); | |
1076 dest_scan++; | |
1077 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha1); | |
1078 dest_scan++; | |
1079 } | |
1080 } | |
1081 } | |
1082 #endif | |
1083 } | |
1084 void CFX_SkiaRenderer::CompositeSpanRGB24_7(uint8_t* dest_scan, | |
1085 uint8_t* ori_scan, | |
1086 int Bpp, | |
1087 int span_left, | |
1088 int span_len, | |
1089 int span_top, | |
1090 uint8_t cover_scan, | |
1091 int clip_top, | |
1092 int clip_left, | |
1093 int clip_right, | |
1094 uint8_t* clip_scan, | |
1095 uint8_t* dest_extra_alpha_scan) { | |
1096 ASSERT(!m_pDevice->IsCmykImage()); | |
1097 dest_scan = | |
1098 (uint8_t*)m_pDevice->GetScanline(span_top) + span_left + (span_left << 1); | |
1099 ori_scan = (uint8_t*)m_pOriDevice->GetScanline(span_top) + span_left + | |
1100 (span_left << 1); | |
1101 clip_scan = (uint8_t*)m_pClipMask->GetScanline(span_top - clip_top) - | |
1102 clip_left + span_left; | |
1103 int col_start = span_left < clip_left ? clip_left - span_left : 0; | |
1104 int col_end = | |
1105 (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); | |
1106 if (col_end < col_start) | |
1107 return; // do nothing. | |
1108 dest_scan += col_start + (col_start << 1); | |
1109 ori_scan += col_start + (col_start << 1); | |
1110 #if 1 | |
1111 for (int col = col_start; col < col_end; col++) { | |
1112 int src_alpha = m_Alpha * clip_scan[col] / 255; | |
1113 if (src_alpha == 255 && cover_scan == 255) { | |
1114 *dest_scan++ = m_Blue; | |
1115 *dest_scan++ = m_Green; | |
1116 *dest_scan++ = m_Red; | |
1117 ori_scan += 3; | |
1118 continue; | |
1119 } | |
1120 int b = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, src_alpha); | |
1121 int g = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, src_alpha); | |
1122 int r = FXDIB_ALPHA_MERGE(*ori_scan++, m_Red, src_alpha); | |
1123 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, b, cover_scan); | |
1124 dest_scan++; | |
1125 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, g, cover_scan); | |
1126 dest_scan++; | |
1127 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, r, cover_scan); | |
1128 dest_scan++; | |
1129 } | |
1130 #else | |
1131 if (m_bFullCover) { | |
1132 for (int col = col_start; col < col_end; col++) { | |
1133 int src_alpha = m_Alpha * clip_scan[col] / 255; | |
1134 if (!src_alpha) { | |
1135 *dest_scan++ = *ori_scan++; | |
1136 *dest_scan++ = *ori_scan++; | |
1137 *dest_scan++ = *ori_scan++; | |
1138 continue; | |
1139 } | |
1140 if (src_alpha == 255) { | |
1141 *dest_scan++ = m_Blue; | |
1142 *dest_scan++ = m_Green; | |
1143 *dest_scan++ = m_Red; | |
1144 ori_scan += 3; | |
1145 continue; | |
1146 } | |
1147 *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, src_alpha); | |
1148 *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, src_alpha); | |
1149 *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Red, src_alpha); | |
1150 } | |
1151 } else { | |
1152 for (int col = col_start; col < col_end; col++) { | |
1153 int src_alpha = m_Alpha * clip_scan[col] / 255; | |
1154 if (src_alpha == 255 && cover_scan == 255) { | |
1155 *dest_scan++ = m_Blue; | |
1156 *dest_scan++ = m_Green; | |
1157 *dest_scan++ = m_Red; | |
1158 ori_scan += 3; | |
1159 continue; | |
1160 } | |
1161 int b = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, src_alpha); | |
1162 int g = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, src_alpha); | |
1163 int r = FXDIB_ALPHA_MERGE(*ori_scan++, m_Red, src_alpha); | |
1164 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, b, cover_scan); | |
1165 dest_scan++; | |
1166 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, g, cover_scan); | |
1167 dest_scan++; | |
1168 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, r, cover_scan); | |
1169 dest_scan++; | |
1170 } | |
1171 } | |
1172 #endif | |
1173 } | |
1174 void CFX_SkiaRenderer::CompositeSpanRGB24_10(uint8_t* dest_scan, | |
1175 uint8_t* ori_scan, | |
1176 int Bpp, | |
1177 int span_left, | |
1178 int span_len, | |
1179 int span_top, | |
1180 uint8_t cover_scan, | |
1181 int clip_top, | |
1182 int clip_left, | |
1183 int clip_right, | |
1184 uint8_t* clip_scan, | |
1185 uint8_t* dest_extra_alpha_scan) { | |
1186 dest_scan = | |
1187 (uint8_t*)m_pDevice->GetScanline(span_top) + span_left + (span_left << 1); | |
1188 dest_extra_alpha_scan = | |
1189 (uint8_t*)m_pDevice->m_pAlphaMask->GetScanline(span_top) + span_left; | |
1190 int col_start = span_left < clip_left ? clip_left - span_left : 0; | |
1191 int col_end = | |
1192 (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); | |
1193 if (col_end < col_start) | |
1194 return; // do nothing. | |
1195 dest_scan += col_start + (col_start << 1); | |
1196 #if 1 | |
1197 if (m_Alpha == 255 && cover_scan == 255) { | |
1198 for (int col = col_start; col < col_end; col++) { | |
1199 *dest_scan++ = (uint8_t)m_Blue; | |
1200 *dest_scan++ = (uint8_t)m_Green; | |
1201 *dest_scan++ = (uint8_t)m_Red; | |
1202 *dest_extra_alpha_scan++ = 255; | |
1203 } | |
1204 return; | |
1205 } | |
1206 int src_alpha = m_Alpha * cover_scan / 255; | |
1207 for (int col = col_start; col < col_end; col++) { | |
1208 // Dest format: Rgba | |
1209 // calculate destination alpha (it's union of source and dest alpha) | |
1210 uint8_t dest_alpha = (*dest_extra_alpha_scan) + src_alpha - | |
1211 (*dest_extra_alpha_scan) * src_alpha / 255; | |
1212 *dest_extra_alpha_scan++ = dest_alpha; | |
1213 int alpha_ratio = src_alpha * 255 / dest_alpha; | |
1214 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); | |
1215 dest_scan++; | |
1216 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); | |
1217 dest_scan++; | |
1218 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); | |
1219 dest_scan++; | |
1220 } | |
1221 #else | |
1222 if (m_bFullCover) { | |
1223 if (m_Alpha == 255) { | |
1224 for (int col = col_start; col < col_end; col++) { | |
1225 *dest_scan++ = (uint8_t)m_Blue; | |
1226 *dest_scan++ = (uint8_t)m_Green; | |
1227 *dest_scan++ = (uint8_t)m_Red; | |
1228 *dest_extra_alpha_scan++ = 255; | |
1229 } | |
1230 return; | |
1231 } | |
1232 for (int col = col_start; col < col_end; col++) { | |
1233 // Dest format: Rgba | |
1234 // calculate destination alpha (it's union of source and dest alpha) | |
1235 uint8_t dest_alpha = (*dest_extra_alpha_scan) + m_Alpha - | |
1236 (*dest_extra_alpha_scan) * m_Alpha / 255; | |
1237 *dest_extra_alpha_scan++ = dest_alpha; | |
1238 int alpha_ratio = m_Alpha * 255 / dest_alpha; | |
1239 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); | |
1240 dest_scan++; | |
1241 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); | |
1242 dest_scan++; | |
1243 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); | |
1244 dest_scan++; | |
1245 } | |
1246 } else { | |
1247 if (m_Alpha == 255 && cover_scan == 255) { | |
1248 for (int col = col_start; col < col_end; col++) { | |
1249 *dest_scan++ = (uint8_t)m_Blue; | |
1250 *dest_scan++ = (uint8_t)m_Green; | |
1251 *dest_scan++ = (uint8_t)m_Red; | |
1252 *dest_extra_alpha_scan++ = 255; | |
1253 } | |
1254 return; | |
1255 } | |
1256 int src_alpha = m_Alpha * cover_scan / 255; | |
1257 for (int col = col_start; col < col_end; col++) { | |
1258 // Dest format: Rgba | |
1259 // calculate destination alpha (it's union of source and dest alpha) | |
1260 uint8_t dest_alpha = (*dest_extra_alpha_scan) + src_alpha - | |
1261 (*dest_extra_alpha_scan) * src_alpha / 255; | |
1262 *dest_extra_alpha_scan++ = dest_alpha; | |
1263 int alpha_ratio = src_alpha * 255 / dest_alpha; | |
1264 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); | |
1265 dest_scan++; | |
1266 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); | |
1267 dest_scan++; | |
1268 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); | |
1269 dest_scan++; | |
1270 } | |
1271 } | |
1272 #endif | |
1273 } | |
1274 void CFX_SkiaRenderer::CompositeSpanRGB24_14(uint8_t* dest_scan, | |
1275 uint8_t* ori_scan, | |
1276 int Bpp, | |
1277 int span_left, | |
1278 int span_len, | |
1279 int span_top, | |
1280 uint8_t cover_scan, | |
1281 int clip_top, | |
1282 int clip_left, | |
1283 int clip_right, | |
1284 uint8_t* clip_scan, | |
1285 uint8_t* dest_extra_alpha_scan) { | |
1286 dest_scan = | |
1287 (uint8_t*)m_pDevice->GetScanline(span_top) + span_left + (span_left << 1); | |
1288 dest_extra_alpha_scan = | |
1289 (uint8_t*)m_pDevice->m_pAlphaMask->GetScanline(span_top) + span_left; | |
1290 clip_scan = (uint8_t*)m_pClipMask->GetScanline(span_top - clip_top) - | |
1291 clip_left + span_left; | |
1292 int col_start = span_left < clip_left ? clip_left - span_left : 0; | |
1293 int col_end = | |
1294 (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); | |
1295 if (col_end < col_start) | |
1296 return; // do nothing. | |
1297 dest_scan += col_start + (col_start << 1); | |
1298 #if 1 | |
1299 int src_alpha = m_Alpha * cover_scan / 255; | |
1300 for (int col = col_start; col < col_end; col++) { | |
1301 int src_alpha1 = src_alpha * clip_scan[col] / 255; | |
1302 if (!src_alpha1) { | |
1303 dest_extra_alpha_scan++; | |
1304 dest_scan += 3; | |
1305 continue; | |
1306 } | |
1307 if (src_alpha1 == 255) { | |
1308 *dest_scan++ = (uint8_t)m_Blue; | |
1309 *dest_scan++ = (uint8_t)m_Green; | |
1310 *dest_scan++ = (uint8_t)m_Red; | |
1311 *dest_extra_alpha_scan++ = (uint8_t)m_Alpha; | |
1312 } else { | |
1313 // Dest format: Rgba | |
1314 // calculate destination alpha (it's union of source and dest alpha) | |
1315 uint8_t dest_alpha = (*dest_extra_alpha_scan) + src_alpha1 - | |
1316 (*dest_extra_alpha_scan) * src_alpha1 / 255; | |
1317 *dest_extra_alpha_scan++ = dest_alpha; | |
1318 int alpha_ratio = src_alpha1 * 255 / dest_alpha; | |
1319 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); | |
1320 dest_scan++; | |
1321 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); | |
1322 dest_scan++; | |
1323 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); | |
1324 dest_scan++; | |
1325 } | |
1326 } | |
1327 #else | |
1328 if (m_bFullCover) { | |
1329 for (int col = col_start; col < col_end; col++) { | |
1330 int src_alpha = m_Alpha * clip_scan[col] / 255; | |
1331 if (!src_alpha) { | |
1332 dest_extra_alpha_scan++; | |
1333 dest_scan += 3; | |
1334 continue; | |
1335 } | |
1336 if (src_alpha == 255) { | |
1337 *dest_scan++ = (uint8_t)m_Blue; | |
1338 *dest_scan++ = (uint8_t)m_Green; | |
1339 *dest_scan++ = (uint8_t)m_Red; | |
1340 *dest_extra_alpha_scan++ = (uint8_t)m_Alpha; | |
1341 } else { | |
1342 // Dest format: Rgba | |
1343 // calculate destination alpha (it's union of source and dest alpha) | |
1344 uint8_t dest_alpha = (*dest_extra_alpha_scan) + src_alpha - | |
1345 (*dest_extra_alpha_scan) * src_alpha / 255; | |
1346 *dest_extra_alpha_scan++ = dest_alpha; | |
1347 int alpha_ratio = src_alpha * 255 / dest_alpha; | |
1348 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); | |
1349 dest_scan++; | |
1350 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); | |
1351 dest_scan++; | |
1352 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); | |
1353 dest_scan++; | |
1354 } | |
1355 } | |
1356 } else { | |
1357 int src_alpha = m_Alpha * cover_scan / 255; | |
1358 for (int col = col_start; col < col_end; col++) { | |
1359 int src_alpha1 = m_Alpha * cover_scan * clip_scan[col] / 255; | |
1360 if (!src_alpha1) { | |
1361 dest_extra_alpha_scan++; | |
1362 dest_scan += 3; | |
1363 continue; | |
1364 } | |
1365 if (src_alpha1 == 255) { | |
1366 *dest_scan++ = (uint8_t)m_Blue; | |
1367 *dest_scan++ = (uint8_t)m_Green; | |
1368 *dest_scan++ = (uint8_t)m_Red; | |
1369 *dest_extra_alpha_scan++ = (uint8_t)m_Alpha; | |
1370 } else { | |
1371 // Dest format: Rgba | |
1372 // calculate destination alpha (it's union of source and dest alpha) | |
1373 uint8_t dest_alpha = (*dest_extra_alpha_scan) + src_alpha1 - | |
1374 (*dest_extra_alpha_scan) * src_alpha1 / 255; | |
1375 *dest_extra_alpha_scan++ = dest_alpha; | |
1376 int alpha_ratio = src_alpha1 * 255 / dest_alpha; | |
1377 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); | |
1378 dest_scan++; | |
1379 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); | |
1380 dest_scan++; | |
1381 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); | |
1382 dest_scan++; | |
1383 } | |
1384 } | |
1385 } | |
1386 #endif | |
1387 } | |
1388 /*------------------------------------------------------------------------------
-----------------------*/ | |
1389 | |
1390 // A general alpha merge function (with clipping mask). Cmyka/Cmyk device. | |
1391 void CFX_SkiaRenderer::CompositeSpanCMYK(uint8_t* dest_scan, | |
1392 uint8_t* ori_scan, | |
1393 int Bpp, | |
1394 int span_left, | |
1395 int span_len, | |
1396 int span_top, | |
1397 uint8_t cover_scan, | |
1398 int clip_top, | |
1399 int clip_left, | |
1400 int clip_right, | |
1401 uint8_t* clip_scan, | |
1402 uint8_t* dest_extra_alpha_scan) { | |
1403 ASSERT(!m_bRgbByteOrder); | |
1404 // Cmyk(a) | |
1405 int col_start = span_left < clip_left ? clip_left - span_left : 0; | |
1406 int col_end = | |
1407 (span_left + span_len) < clip_right ? span_len : (clip_right - span_left); | |
1408 if (col_end < col_start) | |
1409 return; // do nothing. | |
1410 dest_scan += col_start * 4; | |
1411 Bpp; // for avoid compile warning. | |
1412 | |
1413 if (dest_extra_alpha_scan) { | |
1414 // CMYKa | |
1415 for (int col = col_start; col < col_end; col++) { | |
1416 int src_alpha; | |
1417 if (m_bFullCover) { | |
1418 if (clip_scan) | |
1419 src_alpha = m_Alpha * clip_scan[col] / 255; | |
1420 else | |
1421 src_alpha = m_Alpha; | |
1422 } else { | |
1423 if (clip_scan) | |
1424 src_alpha = m_Alpha * cover_scan * clip_scan[col] / 255 / 255; | |
1425 else | |
1426 src_alpha = m_Alpha * cover_scan / 255; | |
1427 } | |
1428 | |
1429 if (src_alpha) { | |
1430 if (src_alpha == 255) { | |
1431 *(FX_CMYK*)dest_scan = m_Color; | |
1432 *dest_extra_alpha_scan = (uint8_t)m_Alpha; | |
1433 } else { | |
1434 // Dest format: Cmyka | |
1435 // calculate destination alpha (it's union of source and dest alpha) | |
1436 uint8_t dest_alpha = (*dest_extra_alpha_scan) + src_alpha - | |
1437 (*dest_extra_alpha_scan) * src_alpha / 255; | |
1438 *dest_extra_alpha_scan++ = dest_alpha; | |
1439 int alpha_ratio = src_alpha * 255 / dest_alpha; | |
1440 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio); | |
1441 dest_scan++; | |
1442 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio); | |
1443 dest_scan++; | |
1444 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio); | |
1445 dest_scan++; | |
1446 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Gray, alpha_ratio); | |
1447 dest_scan++; | |
1448 continue; | |
1449 } | |
1450 } | |
1451 dest_extra_alpha_scan++; | |
1452 dest_scan += 4; | |
1453 } | |
1454 } else { | |
1455 // CMYK | |
1456 for (int col = col_start; col < col_end; col++) { | |
1457 int src_alpha; | |
1458 if (clip_scan) | |
1459 src_alpha = m_Alpha * cover_scan * clip_scan[col] / 255 / 255; | |
1460 else | |
1461 src_alpha = m_Alpha * cover_scan / 255; | |
1462 | |
1463 if (src_alpha) { | |
1464 if (src_alpha == 255) { | |
1465 *(FX_CMYK*)dest_scan = m_Color; | |
1466 } else { | |
1467 // Dest format: cmyk | |
1468 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha); | |
1469 dest_scan++; | |
1470 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha); | |
1471 dest_scan++; | |
1472 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha); | |
1473 dest_scan++; | |
1474 *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Gray, src_alpha); | |
1475 dest_scan++; | |
1476 continue; | |
1477 } | |
1478 } | |
1479 dest_scan += 4; | |
1480 } | |
1481 } | |
1482 } | |
1483 | |
1484 //-------------------------------------------------------------------- | |
1485 FX_BOOL CFX_SkiaRenderer::Init( | |
1486 CFX_DIBitmap* pDevice, | |
1487 CFX_DIBitmap* pOriDevice, | |
1488 const CFX_ClipRgn* pClipRgn, | |
1489 FX_DWORD color, | |
1490 FX_BOOL bFullCover, | |
1491 FX_BOOL bRgbByteOrder, | |
1492 int alpha_flag, | |
1493 void* pIccTransform) { // The alpha flag must be fill_flag if exist. | |
1494 m_pDevice = pDevice; | |
1495 m_pClipRgn = pClipRgn; | |
1496 m_bRgbByteOrder = bRgbByteOrder; | |
1497 m_pOriDevice = pOriDevice; | |
1498 m_pDestScan = NULL; | |
1499 m_pDestExtraAlphaScan = NULL; | |
1500 m_pOriScan = NULL; | |
1501 m_pClipScan = NULL; | |
1502 composite_span = NULL; | |
1503 if (m_pClipRgn) { | |
1504 m_ClipBox = m_pClipRgn->GetBox(); | |
1505 } else { | |
1506 m_ClipBox.left = m_ClipBox.top = 0; | |
1507 m_ClipBox.right = m_pDevice->GetWidth(); | |
1508 m_ClipBox.bottom = m_pDevice->GetHeight(); | |
1509 } | |
1510 m_pClipMask = NULL; | |
1511 if (m_pClipRgn && m_pClipRgn->GetType() == CFX_ClipRgn::MaskF) { | |
1512 m_pClipMask = m_pClipRgn->GetMask(); | |
1513 m_pClipScan = m_pClipMask->GetBuffer(); | |
1514 } | |
1515 if (m_pDevice->m_pAlphaMask) | |
1516 m_pDestExtraAlphaScan = m_pDevice->m_pAlphaMask->GetBuffer(); | |
1517 if (m_pOriDevice) | |
1518 m_pOriScan = m_pOriDevice->GetBuffer(); | |
1519 m_pDestScan = m_pDevice->GetBuffer(); | |
1520 | |
1521 m_bFullCover = bFullCover; | |
1522 | |
1523 FX_BOOL bObjectCMYK = FXGETFLAG_COLORTYPE(alpha_flag); | |
1524 FX_BOOL bDeviceCMYK = pDevice->IsCmykImage(); | |
1525 | |
1526 m_Alpha = bObjectCMYK ? FXGETFLAG_ALPHA_FILL(alpha_flag) : FXARGB_A(color); | |
1527 | |
1528 ICodec_IccModule* pIccModule = NULL; | |
1529 // No lcms engine, we skip the transform | |
1530 if (!CFX_GEModule::Get()->GetCodecModule() || | |
1531 !CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) | |
1532 pIccTransform = NULL; | |
1533 else | |
1534 pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule(); | |
1535 | |
1536 if (m_pDevice->GetBPP() == 8) { // Gray(a) device | |
1537 ASSERT(!m_bRgbByteOrder); | |
1538 if (m_pDevice->IsAlphaMask()) { | |
1539 // Alpha Mask | |
1540 m_Gray = 255; | |
1541 } else { | |
1542 // Gray(a) device | |
1543 if (pIccTransform) { | |
1544 uint8_t gray; | |
1545 color = bObjectCMYK ? FXCMYK_TODIB(color) : FXARGB_TODIB(color); | |
1546 pIccModule->TranslateScanline(pIccTransform, &gray, | |
1547 (const uint8_t*)&color, 1); | |
1548 m_Gray = gray; | |
1549 } else { | |
1550 if (bObjectCMYK) { | |
1551 uint8_t r, g, b; | |
1552 AdobeCMYK_to_sRGB1(FXSYS_GetCValue(color), FXSYS_GetMValue(color), | |
1553 FXSYS_GetYValue(color), FXSYS_GetKValue(color), r, | |
1554 g, b); | |
1555 m_Gray = FXRGB2GRAY(r, g, b); | |
1556 } else { | |
1557 m_Gray = | |
1558 FXRGB2GRAY(FXARGB_R(color), FXARGB_G(color), FXARGB_B(color)); | |
1559 } | |
1560 } | |
1561 } | |
1562 } else { | |
1563 if (bDeviceCMYK) { // Cmyk(a) Device | |
1564 ASSERT(!m_bRgbByteOrder); | |
1565 // TODO ... opt for cmyk | |
1566 composite_span = &CFX_SkiaRenderer::CompositeSpanCMYK; | |
1567 if (bObjectCMYK) { | |
1568 m_Color = FXCMYK_TODIB(color); | |
1569 if (pIccTransform) | |
1570 pIccModule->TranslateScanline(pIccTransform, (uint8_t*)&m_Color, | |
1571 (const uint8_t*)&m_Color, 1); | |
1572 } else { // Object RGB | |
1573 if (!pIccTransform) | |
1574 return FALSE; | |
1575 color = FXARGB_TODIB(color); | |
1576 pIccModule->TranslateScanline(pIccTransform, (uint8_t*)&m_Color, | |
1577 (const uint8_t*)&color, 1); | |
1578 } | |
1579 m_Red = ((uint8_t*)&m_Color)[0]; | |
1580 m_Green = ((uint8_t*)&m_Color)[1]; | |
1581 m_Blue = ((uint8_t*)&m_Color)[2]; | |
1582 m_Gray = ((uint8_t*)&m_Color)[3]; | |
1583 return TRUE; | |
1584 } | |
1585 if (pIccTransform) { | |
1586 color = bObjectCMYK ? FXCMYK_TODIB(color) : FXARGB_TODIB(color); | |
1587 pIccModule->TranslateScanline(pIccTransform, (uint8_t*)&m_Color, | |
1588 (const uint8_t*)&color, 1); | |
1589 ((uint8_t*)&m_Color)[3] = m_Alpha; | |
1590 m_Red = ((uint8_t*)&m_Color)[2]; | |
1591 m_Green = ((uint8_t*)&m_Color)[1]; | |
1592 m_Blue = ((uint8_t*)&m_Color)[0]; | |
1593 // Need Johnson to improvement it. | |
1594 if (m_bRgbByteOrder) { | |
1595 // swap | |
1596 m_Red = ((uint8_t*)&m_Color)[0]; | |
1597 m_Blue = ((uint8_t*)&m_Color)[2]; | |
1598 m_Color = FXARGB_TODIB(m_Color); | |
1599 m_Color = FXARGB_TOBGRORDERDIB(m_Color); | |
1600 } | |
1601 } else { | |
1602 if (bObjectCMYK) { | |
1603 uint8_t r, g, b; | |
1604 AdobeCMYK_to_sRGB1(FXSYS_GetCValue(color), FXSYS_GetMValue(color), | |
1605 FXSYS_GetYValue(color), FXSYS_GetKValue(color), r, g, | |
1606 b); | |
1607 m_Color = FXARGB_MAKE(m_Alpha, r, g, b); | |
1608 if (m_bRgbByteOrder) { | |
1609 m_Color = FXARGB_TOBGRORDERDIB(m_Color); | |
1610 m_Red = b; | |
1611 m_Green = g; | |
1612 m_Blue = r; // | |
1613 } else { | |
1614 m_Color = FXARGB_TODIB(m_Color); | |
1615 m_Red = r; | |
1616 m_Green = g; | |
1617 m_Blue = b; // | |
1618 } | |
1619 } else { | |
1620 if (m_bRgbByteOrder) { | |
1621 m_Color = FXARGB_TOBGRORDERDIB(color); | |
1622 ArgbDecode(color, m_Alpha, m_Blue, m_Green, m_Red); // | |
1623 } else { | |
1624 m_Color = FXARGB_TODIB(color); | |
1625 ArgbDecode(color, m_Alpha, m_Red, m_Green, m_Blue); | |
1626 } | |
1627 } | |
1628 } | |
1629 } | |
1630 // Get palette transparency selector | |
1631 m_ProcessFilter = | |
1632 (m_pOriDevice ? 1 : 0) /* has Ori Device flag */ | |
1633 + (m_pDevice->GetBPP() >= 8 ? 2 : 0) /* bpp flag */ | |
1634 + (m_pClipMask ? 4 : 0) /* has clip region flag */ | |
1635 + (m_pDevice->m_pAlphaMask ? 8 : 0); /* has Alpha Mask chanel flag */ | |
1636 switch (m_ProcessFilter) { | |
1637 case 0: | |
1638 composite_span = &CFX_SkiaRenderer::CompositeSpan1bpp_0; | |
1639 break; | |
1640 case 2: { | |
1641 if (m_pDevice->GetBPP() == 8) | |
1642 composite_span = &CFX_SkiaRenderer::CompositeSpanGray_2; | |
1643 else if (m_pDevice->GetBPP() == 24) | |
1644 composite_span = &CFX_SkiaRenderer::CompositeSpanRGB24_2; | |
1645 else | |
1646 composite_span = m_pDevice->HasAlpha() | |
1647 ? &CFX_SkiaRenderer::CompositeSpanARGB_2 | |
1648 : &CFX_SkiaRenderer::CompositeSpanRGB32_2; | |
1649 } break; | |
1650 case 3: { | |
1651 if (m_pDevice->GetBPP() == 8) | |
1652 composite_span = &CFX_SkiaRenderer::CompositeSpanGray_3; | |
1653 else if (m_pDevice->GetBPP() == 24) | |
1654 composite_span = &CFX_SkiaRenderer::CompositeSpanRGB24_3; | |
1655 else | |
1656 composite_span = m_pDevice->HasAlpha() | |
1657 ? &CFX_SkiaRenderer::CompositeSpanARGB_3 | |
1658 : &CFX_SkiaRenderer::CompositeSpanRGB32_3; | |
1659 } break; | |
1660 case 4: | |
1661 composite_span = &CFX_SkiaRenderer::CompositeSpan1bpp_4; | |
1662 break; | |
1663 case 6: { | |
1664 if (m_pDevice->GetBPP() == 8) | |
1665 composite_span = &CFX_SkiaRenderer::CompositeSpanGray_6; | |
1666 else if (m_pDevice->GetBPP() == 24) | |
1667 composite_span = &CFX_SkiaRenderer::CompositeSpanRGB24_6; | |
1668 else | |
1669 composite_span = m_pDevice->HasAlpha() | |
1670 ? &CFX_SkiaRenderer::CompositeSpanARGB_6 | |
1671 : &CFX_SkiaRenderer::CompositeSpanRGB32_6; | |
1672 } break; | |
1673 case 7: { | |
1674 if (m_pDevice->GetBPP() == 8) | |
1675 composite_span = &CFX_SkiaRenderer::CompositeSpanGray_7; | |
1676 else if (m_pDevice->GetBPP() == 24) | |
1677 composite_span = &CFX_SkiaRenderer::CompositeSpanRGB24_7; | |
1678 else | |
1679 composite_span = m_pDevice->HasAlpha() | |
1680 ? &CFX_SkiaRenderer::CompositeSpanARGB_7 | |
1681 : &CFX_SkiaRenderer::CompositeSpanRGB32_7; | |
1682 } break; | |
1683 case 1: | |
1684 case 5: | |
1685 case 8: | |
1686 case 9: | |
1687 case 11: | |
1688 case 12: | |
1689 case 13: | |
1690 case 15: | |
1691 // TODO ... | |
1692 break; | |
1693 case 10: | |
1694 composite_span = &CFX_SkiaRenderer::CompositeSpanRGB24_10; | |
1695 break; | |
1696 case 14: | |
1697 composite_span = &CFX_SkiaRenderer::CompositeSpanRGB24_14; | |
1698 break; | |
1699 } | |
1700 return !!composite_span; | |
1701 } | |
1702 | |
1703 /*------------------------------------------------------------------------------
----------------------*/ | |
1704 void CFX_SkiaA8Renderer::blitAntiH(int x, | |
1705 int y, | |
1706 const SkAlpha antialias[], | |
1707 const int16_t runs[]) { | |
1708 FXSYS_assert(m_pDevice); | |
1709 int dst_y = y - m_Top; | |
1710 if (dst_y < 0 || dst_y >= m_pDevice->GetHeight()) | |
1711 return; | |
1712 | |
1713 uint8_t* dest_scan = m_pDevice->GetBuffer() + m_pDevice->GetPitch() * dst_y; | |
1714 uint8_t* dest_pos = dest_scan; | |
1715 while (1) { | |
1716 if (x >= m_dstWidth) | |
1717 return; | |
1718 int width = runs[0]; | |
1719 SkASSERT(width >= 0); | |
1720 if (width <= 0) | |
1721 return; | |
1722 unsigned aa = antialias[0]; | |
1723 if (aa) { | |
1724 int col_start = x < m_Left ? 0 : x - m_Left; | |
1725 int col_end = x + width; | |
1726 col_end = col_end < m_dstWidth ? col_end - m_Left : m_pDevice->GetWidth(); | |
1727 int result = col_end - col_start; | |
1728 if (result > 0) { | |
1729 dest_pos = dest_scan + col_start; | |
1730 if (result >= 4) | |
1731 FXSYS_memset(dest_pos, FXARGB_MAKE(aa, aa, aa, aa), result); | |
1732 else | |
1733 FXSYS_memset(dest_pos, aa, result); | |
1734 } | |
1735 } | |
1736 runs += width; | |
1737 antialias += width; | |
1738 x += width; | |
1739 } | |
1740 } | |
1741 void CFX_SkiaA8Renderer::blitH(int x, int y, int width) { | |
1742 FXSYS_assert(m_pDevice); | |
1743 int dst_y = y - m_Top; | |
1744 if (dst_y < 0 || dst_y >= m_pDevice->GetHeight()) | |
1745 return; | |
1746 if (x >= m_dstWidth) | |
1747 return; | |
1748 uint8_t* dest_scan = m_pDevice->GetBuffer() + m_pDevice->GetPitch() * dst_y; | |
1749 int col_start = x < m_Left ? 0 : x - m_Left; | |
1750 int col_end = x + width; | |
1751 col_end = col_end < m_dstWidth ? col_end - m_Left : m_pDevice->GetWidth(); | |
1752 int result = col_end - col_start; | |
1753 if (result > 0) { | |
1754 uint8_t* dest_pos = dest_scan + col_start; | |
1755 if (result >= 4) | |
1756 FXSYS_memset(dest_pos, 0xffffffff, result); | |
1757 else | |
1758 FXSYS_memset(dest_pos, 255, result); | |
1759 } | |
1760 } | |
1761 void CFX_SkiaA8Renderer::blitV(int x, int y, int height, SkAlpha alpha) { | |
1762 FXSYS_assert(alpha); | |
1763 if (alpha == 255) { | |
1764 blitRect(x, y, 1, height); | |
1765 } else { | |
1766 int16_t runs[2]; | |
1767 runs[0] = 1; | |
1768 runs[1] = 0; | |
1769 while (--height >= 0) { | |
1770 if (y >= m_dstHeight) | |
1771 return; | |
1772 blitAntiH(x, y++, &alpha, runs); | |
1773 } | |
1774 } | |
1775 } | |
1776 void CFX_SkiaA8Renderer::blitRect(int x, int y, int width, int height) { | |
1777 FXSYS_assert(m_pDevice); | |
1778 while (--height >= 0) { | |
1779 if (y >= m_dstHeight) | |
1780 return; | |
1781 blitH(x, y++, width); | |
1782 } | |
1783 } | |
1784 | |
1785 void CFX_SkiaA8Renderer::blitAntiRect(int x, | |
1786 int y, | |
1787 int width, | |
1788 int height, | |
1789 SkAlpha leftAlpha, | |
1790 SkAlpha rightAlpha) { | |
1791 blitV(x++, y, height, leftAlpha); | |
1792 if (width > 0) { | |
1793 blitRect(x, y, width, height); | |
1794 x += width; | |
1795 } | |
1796 blitV(x, y, height, rightAlpha); | |
1797 } | |
1798 | |
1799 FX_BOOL CFX_SkiaA8Renderer::Init(CFX_DIBitmap* pDevice, int Left, int Top) { | |
1800 m_pDevice = pDevice; | |
1801 m_Left = Left; | |
1802 m_Top = Top; | |
1803 if (pDevice) { | |
1804 m_dstWidth = m_Left + pDevice->GetWidth(); | |
1805 m_dstHeight = m_Top + pDevice->GetHeight(); | |
1806 } | |
1807 return TRUE; | |
1808 } | |
1809 #endif | |
OLD | NEW |