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