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