Remove trailing whitespaces in core.
[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                         } else {
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                 }
1430                 // Get palette transparency selector
1431                 m_ProcessFilter = (m_pOriDevice? 1 : 0) /* has Ori Device flag */
1432                                                 + (m_pDevice->GetBPP() >= 8 ? 2 : 0)    /* bpp flag */
1433                                                 + (m_pClipMask? 4 : 0)                                  /* has clip region flag */
1434                                                 + (m_pDevice->m_pAlphaMask? 8 : 0);             /* has Alpha Mask chanel flag */
1435                 switch(m_ProcessFilter) {
1436                         case 0:
1437                                 composite_span = &CFX_SkiaRenderer::CompositeSpan1bpp_0;
1438                                 break;
1439                         case 2:
1440                                 {
1441                                         if (m_pDevice->GetBPP() == 8)
1442                                                 composite_span = &CFX_SkiaRenderer::CompositeSpanGray_2;
1443                                         else if (m_pDevice->GetBPP() == 24)
1444                                                 composite_span = &CFX_SkiaRenderer::CompositeSpanRGB24_2;
1445                                         else
1446                                                 composite_span = m_pDevice->HasAlpha()?&CFX_SkiaRenderer::CompositeSpanARGB_2 : &CFX_SkiaRenderer::CompositeSpanRGB32_2;
1447                                 }
1448                                 break;
1449                         case 3:
1450                                 {
1451                                         if (m_pDevice->GetBPP() == 8)
1452                                                 composite_span = &CFX_SkiaRenderer::CompositeSpanGray_3;
1453                                         else if (m_pDevice->GetBPP() == 24)
1454                                                 composite_span = &CFX_SkiaRenderer::CompositeSpanRGB24_3;
1455                                         else
1456                                                 composite_span = m_pDevice->HasAlpha()?&CFX_SkiaRenderer::CompositeSpanARGB_3 : &CFX_SkiaRenderer::CompositeSpanRGB32_3;
1457                                 }
1458                                 break;
1459                         case 4:
1460                                 composite_span = &CFX_SkiaRenderer::CompositeSpan1bpp_4;
1461                                 break;
1462                         case 6:
1463                                 {
1464                                         if (m_pDevice->GetBPP() == 8)
1465                                                 composite_span = &CFX_SkiaRenderer::CompositeSpanGray_6;
1466                                         else if (m_pDevice->GetBPP() == 24)
1467                                                 composite_span = &CFX_SkiaRenderer::CompositeSpanRGB24_6;
1468                                         else
1469                                                 composite_span = m_pDevice->HasAlpha()?&CFX_SkiaRenderer::CompositeSpanARGB_6 : &CFX_SkiaRenderer::CompositeSpanRGB32_6;
1470                                 }
1471                                 break;
1472                         case 7:
1473                                 {
1474                                         if (m_pDevice->GetBPP() == 8)
1475                                                 composite_span = &CFX_SkiaRenderer::CompositeSpanGray_7;
1476                                         else if (m_pDevice->GetBPP() == 24)
1477                                                 composite_span = &CFX_SkiaRenderer::CompositeSpanRGB24_7;
1478                                         else
1479                                                 composite_span = m_pDevice->HasAlpha()?&CFX_SkiaRenderer::CompositeSpanARGB_7 : &CFX_SkiaRenderer::CompositeSpanRGB32_7;
1480                                 }
1481                                 break;
1482                         case 1:
1483                         case 5:
1484                         case 8:
1485                         case 9:
1486                         case 11:
1487                         case 12:
1488                         case 13:
1489                         case 15:
1490                                 //TODO...
1491                                 break;
1492                         case 10:
1493                                 composite_span = &CFX_SkiaRenderer::CompositeSpanRGB24_10;
1494                                 break;
1495                         case 14:
1496                                 composite_span = &CFX_SkiaRenderer::CompositeSpanRGB24_14;
1497                                 break;
1498                 }
1499                 if (composite_span == NULL)
1500                         return FALSE;
1501                 return TRUE;
1502         }
1503
1504         /*----------------------------------------------------------------------------------------------------*/
1505         void CFX_SkiaA8Renderer::blitAntiH(int x, int y, const SkAlpha antialias[], const int16_t runs[])
1506         {
1507                 FXSYS_assert(m_pDevice);
1508                 int dst_y = y - m_Top;
1509                 if (dst_y < 0 || dst_y >=  m_pDevice->GetHeight())
1510                         return;
1511
1512                 uint8_t* dest_scan = m_pDevice->GetBuffer() + m_pDevice->GetPitch() * dst_y;
1513                 uint8_t* dest_pos = dest_scan;
1514                 while (1)
1515                 {
1516                         if (x >= m_dstWidth)
1517                                 return;
1518                         int width = runs[0];
1519                         SkASSERT(width >= 0);
1520                         if (width <= 0)
1521                                 return;
1522                         unsigned aa = antialias[0];
1523                         if (aa) {
1524                                 int col_start = x < m_Left ? 0 : x - m_Left;
1525                                 int col_end = x + width;
1526                                 col_end = col_end < m_dstWidth ? col_end - m_Left: m_pDevice->GetWidth();
1527                                 int result = col_end - col_start;
1528                                 if (result > 0) {
1529                                         dest_pos = dest_scan + col_start;
1530                                         if (result >= 4)
1531                                                 FXSYS_memset(dest_pos, FXARGB_MAKE(aa, aa, aa, aa),result);
1532                                         else
1533                                                 FXSYS_memset(dest_pos,aa,result);
1534                                 }
1535                         }
1536                         runs += width;
1537                         antialias += width;
1538                         x += width;
1539                 }
1540         }
1541         void CFX_SkiaA8Renderer::blitH(int x, int y, int width)
1542         {
1543                 FXSYS_assert(m_pDevice);
1544                 int dst_y = y - m_Top;
1545                 if (dst_y < 0 || dst_y >=  m_pDevice->GetHeight())
1546                         return;
1547                 if (x >= m_dstWidth)
1548                         return;
1549                 uint8_t* dest_scan = m_pDevice->GetBuffer() + m_pDevice->GetPitch() * dst_y;
1550                 int col_start = x < m_Left ? 0 : x - m_Left;
1551                 int col_end = x + width;
1552                 col_end = col_end < m_dstWidth ? col_end - m_Left: m_pDevice->GetWidth();
1553                 int result = col_end - col_start;
1554                 if (result > 0) {
1555                         uint8_t* dest_pos = dest_scan + col_start;
1556                         if (result >= 4)
1557                                 FXSYS_memset(dest_pos, 0xffffffff,result);
1558                         else
1559                                 FXSYS_memset(dest_pos,255,result);
1560                 }
1561         }
1562         void CFX_SkiaA8Renderer::blitV(int x, int y, int height, SkAlpha alpha)
1563         {
1564                 FXSYS_assert(alpha);
1565                 if (alpha == 255) {
1566                         blitRect(x, y, 1, height);
1567                 } else {
1568                         int16_t runs[2];
1569                         runs[0] = 1;
1570                         runs[1] = 0;
1571                         while (--height >= 0) {
1572                                 if (y >= m_dstHeight)
1573                                         return;
1574                                 blitAntiH(x, y ++, &alpha, runs);
1575                         }
1576                 }
1577         }
1578         void CFX_SkiaA8Renderer::blitRect(int x, int y, int width, int height)
1579         {
1580                 FXSYS_assert(m_pDevice);
1581                 while (--height >= 0) {
1582                         if (y >= m_dstHeight)
1583                                 return;
1584                         blitH(x , y ++, width);
1585                 }
1586         }
1587
1588         void CFX_SkiaA8Renderer::blitAntiRect(int x, int y, int width, int height,
1589                              SkAlpha leftAlpha, SkAlpha rightAlpha)
1590         {
1591                 blitV(x++, y, height, leftAlpha);
1592                 if (width > 0) {
1593                         blitRect(x, y, width, height);
1594                         x += width;
1595                 }
1596                 blitV(x, y, height, rightAlpha);
1597         }
1598
1599         FX_BOOL CFX_SkiaA8Renderer::Init(CFX_DIBitmap* pDevice, int Left, int Top)
1600         {
1601                 m_pDevice = pDevice;
1602                 m_Left = Left;
1603                 m_Top = Top;
1604                 if (pDevice){
1605                         m_dstWidth = m_Left + pDevice->GetWidth();
1606                         m_dstHeight = m_Top + pDevice->GetHeight();
1607                 }
1608                 return TRUE;
1609         }
1610 #endif