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