Home | History | Annotate | Download | only in src
      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 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
      6 
      7 #include "core/src/fxge/agg/include/fx_agg_driver.h"
      8 
      9 #include <algorithm>
     10 
     11 #include "core/include/fxcodec/fx_codec.h"
     12 #include "core/include/fxge/fx_ge.h"
     13 #include "core/src/fxge/dib/dib_int.h"
     14 #include "core/src/fxge/ge/text_int.h"
     15 #include "third_party/agg23/agg_conv_dash.h"
     16 #include "third_party/agg23/agg_conv_stroke.h"
     17 #include "third_party/agg23/agg_curves.h"
     18 #include "third_party/agg23/agg_path_storage.h"
     19 #include "third_party/agg23/agg_pixfmt_gray.h"
     20 #include "third_party/agg23/agg_rasterizer_scanline_aa.h"
     21 #include "third_party/agg23/agg_renderer_scanline.h"
     22 #include "third_party/agg23/agg_scanline_u.h"
     23 
     24 namespace {
     25 
     26 void HardClip(FX_FLOAT& x, FX_FLOAT& y) {
     27   x = std::max(std::min(x, 50000.0f), -50000.0f);
     28   y = std::max(std::min(y, 50000.0f), -50000.0f);
     29 }
     30 
     31 }  // namespace
     32 
     33 void CAgg_PathData::BuildPath(const CFX_PathData* pPathData,
     34                               const CFX_Matrix* pObject2Device) {
     35   int nPoints = pPathData->GetPointCount();
     36   FX_PATHPOINT* pPoints = pPathData->GetPoints();
     37   for (int i = 0; i < nPoints; i++) {
     38     FX_FLOAT x = pPoints[i].m_PointX, y = pPoints[i].m_PointY;
     39     if (pObject2Device) {
     40       pObject2Device->Transform(x, y);
     41     }
     42     HardClip(x, y);
     43     int point_type = pPoints[i].m_Flag & FXPT_TYPE;
     44     if (point_type == FXPT_MOVETO) {
     45       m_PathData.move_to(x, y);
     46     } else if (point_type == FXPT_LINETO) {
     47       if (pPoints[i - 1].m_Flag == FXPT_MOVETO &&
     48           (i == nPoints - 1 || pPoints[i + 1].m_Flag == FXPT_MOVETO) &&
     49           pPoints[i].m_PointX == pPoints[i - 1].m_PointX &&
     50           pPoints[i].m_PointY == pPoints[i - 1].m_PointY) {
     51         x += 1;
     52       }
     53       m_PathData.line_to(x, y);
     54     } else if (point_type == FXPT_BEZIERTO) {
     55       FX_FLOAT x0 = pPoints[i - 1].m_PointX, y0 = pPoints[i - 1].m_PointY;
     56       FX_FLOAT x2 = pPoints[i + 1].m_PointX, y2 = pPoints[i + 1].m_PointY;
     57       FX_FLOAT x3 = pPoints[i + 2].m_PointX, y3 = pPoints[i + 2].m_PointY;
     58       if (pObject2Device) {
     59         pObject2Device->Transform(x0, y0);
     60         pObject2Device->Transform(x2, y2);
     61         pObject2Device->Transform(x3, y3);
     62       }
     63       agg::curve4 curve(x0, y0, x, y, x2, y2, x3, y3);
     64       i += 2;
     65       m_PathData.add_path_curve(curve);
     66     }
     67     if (pPoints[i].m_Flag & FXPT_CLOSEFIGURE) {
     68       m_PathData.end_poly();
     69     }
     70   }
     71 }
     72 namespace agg {
     73 
     74 template <class BaseRenderer>
     75 class renderer_scanline_aa_offset {
     76  public:
     77   typedef BaseRenderer base_ren_type;
     78   typedef typename base_ren_type::color_type color_type;
     79   renderer_scanline_aa_offset(base_ren_type& ren, unsigned left, unsigned top)
     80       : m_ren(&ren), m_left(left), m_top(top) {}
     81   void color(const color_type& c) { m_color = c; }
     82   const color_type& color() const { return m_color; }
     83   void prepare(unsigned) {}
     84   template <class Scanline>
     85   void render(const Scanline& sl) {
     86     int y = sl.y();
     87     unsigned num_spans = sl.num_spans();
     88     typename Scanline::const_iterator span = sl.begin();
     89     for (;;) {
     90       int x = span->x;
     91       if (span->len > 0) {
     92         m_ren->blend_solid_hspan(x - m_left, y - m_top, (unsigned)span->len,
     93                                  m_color, span->covers);
     94       } else {
     95         m_ren->blend_hline(x - m_left, y - m_top, (unsigned)(x - span->len - 1),
     96                            m_color, *(span->covers));
     97       }
     98       if (--num_spans == 0) {
     99         break;
    100       }
    101       ++span;
    102     }
    103   }
    104 
    105  private:
    106   base_ren_type* m_ren;
    107   color_type m_color;
    108   unsigned m_left, m_top;
    109 };
    110 
    111 }  // namespace agg
    112 
    113 static void RasterizeStroke(agg::rasterizer_scanline_aa& rasterizer,
    114                             agg::path_storage& path_data,
    115                             const CFX_Matrix* pObject2Device,
    116                             const CFX_GraphStateData* pGraphState,
    117                             FX_FLOAT scale = 1.0f,
    118                             FX_BOOL bStrokeAdjust = FALSE,
    119                             FX_BOOL bTextMode = FALSE) {
    120   agg::line_cap_e cap;
    121   switch (pGraphState->m_LineCap) {
    122     case CFX_GraphStateData::LineCapRound:
    123       cap = agg::round_cap;
    124       break;
    125     case CFX_GraphStateData::LineCapSquare:
    126       cap = agg::square_cap;
    127       break;
    128     default:
    129       cap = agg::butt_cap;
    130       break;
    131   }
    132   agg::line_join_e join;
    133   switch (pGraphState->m_LineJoin) {
    134     case CFX_GraphStateData::LineJoinRound:
    135       join = agg::round_join;
    136       break;
    137     case CFX_GraphStateData::LineJoinBevel:
    138       join = agg::bevel_join;
    139       break;
    140     default:
    141       join = agg::miter_join_revert;
    142       break;
    143   }
    144   FX_FLOAT width = pGraphState->m_LineWidth * scale;
    145   FX_FLOAT unit = 1.f;
    146   if (pObject2Device) {
    147     unit = FXSYS_Div(
    148         1.0f, (pObject2Device->GetXUnit() + pObject2Device->GetYUnit()) / 2);
    149   }
    150   if (width < unit) {
    151     width = unit;
    152   }
    153   if (pGraphState->m_DashArray) {
    154     typedef agg::conv_dash<agg::path_storage> dash_converter;
    155     dash_converter dash(path_data);
    156     for (int i = 0; i < (pGraphState->m_DashCount + 1) / 2; i++) {
    157       FX_FLOAT on = pGraphState->m_DashArray[i * 2];
    158       if (on <= 0.000001f) {
    159         on = 1.0f / 10;
    160       }
    161       FX_FLOAT off = i * 2 + 1 == pGraphState->m_DashCount
    162                          ? on
    163                          : pGraphState->m_DashArray[i * 2 + 1];
    164       if (off < 0) {
    165         off = 0;
    166       }
    167       dash.add_dash(on * scale, off * scale);
    168     }
    169     dash.dash_start(pGraphState->m_DashPhase * scale);
    170     typedef agg::conv_stroke<dash_converter> dash_stroke;
    171     dash_stroke stroke(dash);
    172     stroke.line_join(join);
    173     stroke.line_cap(cap);
    174     stroke.miter_limit(pGraphState->m_MiterLimit);
    175     stroke.width(width);
    176     rasterizer.add_path_transformed(stroke, pObject2Device);
    177   } else {
    178     agg::conv_stroke<agg::path_storage> stroke(path_data);
    179     stroke.line_join(join);
    180     stroke.line_cap(cap);
    181     stroke.miter_limit(pGraphState->m_MiterLimit);
    182     stroke.width(width);
    183     rasterizer.add_path_transformed(stroke, pObject2Device);
    184   }
    185 }
    186 IFX_RenderDeviceDriver* IFX_RenderDeviceDriver::CreateFxgeDriver(
    187     CFX_DIBitmap* pBitmap,
    188     FX_BOOL bRgbByteOrder,
    189     CFX_DIBitmap* pOriDevice,
    190     FX_BOOL bGroupKnockout) {
    191   return new CFX_AggDeviceDriver(pBitmap, 0, bRgbByteOrder, pOriDevice,
    192                                  bGroupKnockout);
    193 }
    194 CFX_AggDeviceDriver::CFX_AggDeviceDriver(CFX_DIBitmap* pBitmap,
    195                                          int dither_bits,
    196                                          FX_BOOL bRgbByteOrder,
    197                                          CFX_DIBitmap* pOriDevice,
    198                                          FX_BOOL bGroupKnockout) {
    199   m_pBitmap = pBitmap;
    200   m_DitherBits = dither_bits;
    201   m_pClipRgn = NULL;
    202   m_pPlatformBitmap = NULL;
    203   m_pPlatformGraphics = NULL;
    204   m_pDwRenderTartget = NULL;
    205   m_bRgbByteOrder = bRgbByteOrder;
    206   m_pOriDevice = pOriDevice;
    207   m_bGroupKnockout = bGroupKnockout;
    208   m_FillFlags = 0;
    209   InitPlatform();
    210 }
    211 CFX_AggDeviceDriver::~CFX_AggDeviceDriver() {
    212   delete m_pClipRgn;
    213   for (int i = 0; i < m_StateStack.GetSize(); i++)
    214     delete m_StateStack[i];
    215   DestroyPlatform();
    216 }
    217 #if _FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_
    218 void CFX_AggDeviceDriver::InitPlatform() {}
    219 void CFX_AggDeviceDriver::DestroyPlatform() {}
    220 FX_BOOL CFX_AggDeviceDriver::DrawDeviceText(int nChars,
    221                                             const FXTEXT_CHARPOS* pCharPos,
    222                                             CFX_Font* pFont,
    223                                             CFX_FontCache* pCache,
    224                                             const CFX_Matrix* pObject2Device,
    225                                             FX_FLOAT font_size,
    226                                             FX_DWORD color,
    227                                             int alpha_flag,
    228                                             void* pIccTransform) {
    229   return FALSE;
    230 }
    231 #endif
    232 int CFX_AggDeviceDriver::GetDeviceCaps(int caps_id) {
    233   switch (caps_id) {
    234     case FXDC_DEVICE_CLASS:
    235       return FXDC_DISPLAY;
    236     case FXDC_PIXEL_WIDTH:
    237       return m_pBitmap->GetWidth();
    238     case FXDC_PIXEL_HEIGHT:
    239       return m_pBitmap->GetHeight();
    240     case FXDC_BITS_PIXEL:
    241       return m_pBitmap->GetBPP();
    242     case FXDC_HORZ_SIZE:
    243     case FXDC_VERT_SIZE:
    244       return 0;
    245     case FXDC_RENDER_CAPS: {
    246       int flags = FXRC_GET_BITS | FXRC_ALPHA_PATH | FXRC_ALPHA_IMAGE |
    247                   FXRC_BLEND_MODE | FXRC_SOFT_CLIP;
    248       if (m_pBitmap->HasAlpha()) {
    249         flags |= FXRC_ALPHA_OUTPUT;
    250       } else if (m_pBitmap->IsAlphaMask()) {
    251         if (m_pBitmap->GetBPP() == 1) {
    252           flags |= FXRC_BITMASK_OUTPUT;
    253         } else {
    254           flags |= FXRC_BYTEMASK_OUTPUT;
    255         }
    256       }
    257       if (m_pBitmap->IsCmykImage()) {
    258         flags |= FXRC_CMYK_OUTPUT;
    259       }
    260       return flags;
    261     }
    262     case FXDC_DITHER_BITS:
    263       return m_DitherBits;
    264   }
    265   return 0;
    266 }
    267 void CFX_AggDeviceDriver::SaveState() {
    268   CFX_ClipRgn* pClip = NULL;
    269   if (m_pClipRgn) {
    270     pClip = new CFX_ClipRgn(*m_pClipRgn);
    271   }
    272   m_StateStack.Add(pClip);
    273 }
    274 void CFX_AggDeviceDriver::RestoreState(FX_BOOL bKeepSaved) {
    275   if (m_StateStack.GetSize() == 0) {
    276     delete m_pClipRgn;
    277     m_pClipRgn = NULL;
    278     return;
    279   }
    280   CFX_ClipRgn* pSavedClip = m_StateStack[m_StateStack.GetSize() - 1];
    281   delete m_pClipRgn;
    282   m_pClipRgn = NULL;
    283   if (bKeepSaved) {
    284     if (pSavedClip) {
    285       m_pClipRgn = new CFX_ClipRgn(*pSavedClip);
    286     }
    287   } else {
    288     m_StateStack.RemoveAt(m_StateStack.GetSize() - 1);
    289     m_pClipRgn = pSavedClip;
    290   }
    291 }
    292 void CFX_AggDeviceDriver::SetClipMask(agg::rasterizer_scanline_aa& rasterizer) {
    293   FX_RECT path_rect(rasterizer.min_x(), rasterizer.min_y(),
    294                     rasterizer.max_x() + 1, rasterizer.max_y() + 1);
    295   path_rect.Intersect(m_pClipRgn->GetBox());
    296   CFX_DIBitmapRef mask;
    297   CFX_DIBitmap* pThisLayer = mask.New();
    298   if (!pThisLayer) {
    299     return;
    300   }
    301   pThisLayer->Create(path_rect.Width(), path_rect.Height(), FXDIB_8bppMask);
    302   pThisLayer->Clear(0);
    303   agg::rendering_buffer raw_buf(pThisLayer->GetBuffer(), pThisLayer->GetWidth(),
    304                                 pThisLayer->GetHeight(),
    305                                 pThisLayer->GetPitch());
    306   agg::pixfmt_gray8 pixel_buf(raw_buf);
    307   agg::renderer_base<agg::pixfmt_gray8> base_buf(pixel_buf);
    308   agg::renderer_scanline_aa_offset<agg::renderer_base<agg::pixfmt_gray8> >
    309       final_render(base_buf, path_rect.left, path_rect.top);
    310   final_render.color(agg::gray8(255));
    311   agg::scanline_u8 scanline;
    312   agg::render_scanlines(rasterizer, scanline, final_render,
    313                         (m_FillFlags & FXFILL_NOPATHSMOOTH) != 0);
    314   m_pClipRgn->IntersectMaskF(path_rect.left, path_rect.top, mask);
    315 }
    316 FX_BOOL CFX_AggDeviceDriver::SetClip_PathFill(const CFX_PathData* pPathData,
    317                                               const CFX_Matrix* pObject2Device,
    318                                               int fill_mode) {
    319   m_FillFlags = fill_mode;
    320   if (!m_pClipRgn) {
    321     m_pClipRgn = new CFX_ClipRgn(GetDeviceCaps(FXDC_PIXEL_WIDTH),
    322                                  GetDeviceCaps(FXDC_PIXEL_HEIGHT));
    323   }
    324   if (pPathData->GetPointCount() == 5 || pPathData->GetPointCount() == 4) {
    325     CFX_FloatRect rectf;
    326     if (pPathData->IsRect(pObject2Device, &rectf)) {
    327       rectf.Intersect(
    328           CFX_FloatRect(0, 0, (FX_FLOAT)GetDeviceCaps(FXDC_PIXEL_WIDTH),
    329                         (FX_FLOAT)GetDeviceCaps(FXDC_PIXEL_HEIGHT)));
    330       FX_RECT rect = rectf.GetOutterRect();
    331       m_pClipRgn->IntersectRect(rect);
    332       return TRUE;
    333     }
    334   }
    335   CAgg_PathData path_data;
    336   path_data.BuildPath(pPathData, pObject2Device);
    337   path_data.m_PathData.end_poly();
    338   agg::rasterizer_scanline_aa rasterizer;
    339   rasterizer.clip_box(0.0f, 0.0f, (FX_FLOAT)(GetDeviceCaps(FXDC_PIXEL_WIDTH)),
    340                       (FX_FLOAT)(GetDeviceCaps(FXDC_PIXEL_HEIGHT)));
    341   rasterizer.add_path(path_data.m_PathData);
    342   rasterizer.filling_rule((fill_mode & 3) == FXFILL_WINDING
    343                               ? agg::fill_non_zero
    344                               : agg::fill_even_odd);
    345   SetClipMask(rasterizer);
    346   return TRUE;
    347 }
    348 FX_BOOL CFX_AggDeviceDriver::SetClip_PathStroke(
    349     const CFX_PathData* pPathData,
    350     const CFX_Matrix* pObject2Device,
    351     const CFX_GraphStateData* pGraphState) {
    352   if (!m_pClipRgn) {
    353     m_pClipRgn = new CFX_ClipRgn(GetDeviceCaps(FXDC_PIXEL_WIDTH),
    354                                  GetDeviceCaps(FXDC_PIXEL_HEIGHT));
    355   }
    356   CAgg_PathData path_data;
    357   path_data.BuildPath(pPathData, NULL);
    358   agg::rasterizer_scanline_aa rasterizer;
    359   rasterizer.clip_box(0.0f, 0.0f, (FX_FLOAT)(GetDeviceCaps(FXDC_PIXEL_WIDTH)),
    360                       (FX_FLOAT)(GetDeviceCaps(FXDC_PIXEL_HEIGHT)));
    361   RasterizeStroke(rasterizer, path_data.m_PathData, pObject2Device,
    362                   pGraphState);
    363   rasterizer.filling_rule(agg::fill_non_zero);
    364   SetClipMask(rasterizer);
    365   return TRUE;
    366 }
    367 class CFX_Renderer {
    368  private:
    369   int m_Alpha, m_Red, m_Green, m_Blue, m_Gray;
    370   FX_DWORD m_Color;
    371   FX_BOOL m_bFullCover;
    372   FX_BOOL m_bRgbByteOrder;
    373   CFX_DIBitmap* m_pOriDevice;
    374   FX_RECT m_ClipBox;
    375   const CFX_DIBitmap* m_pClipMask;
    376   CFX_DIBitmap* m_pDevice;
    377   const CFX_ClipRgn* m_pClipRgn;
    378   void (CFX_Renderer::*composite_span)(uint8_t*,
    379                                        int,
    380                                        int,
    381                                        int,
    382                                        uint8_t*,
    383                                        int,
    384                                        int,
    385                                        uint8_t*,
    386                                        uint8_t*);
    387 
    388  public:
    389   void prepare(unsigned) {}
    390   void CompositeSpan(uint8_t* dest_scan,
    391                      uint8_t* ori_scan,
    392                      int Bpp,
    393                      FX_BOOL bDestAlpha,
    394                      int span_left,
    395                      int span_len,
    396                      uint8_t* cover_scan,
    397                      int clip_left,
    398                      int clip_right,
    399                      uint8_t* clip_scan) {
    400     ASSERT(!m_pDevice->IsCmykImage());
    401     int col_start = span_left < clip_left ? clip_left - span_left : 0;
    402     int col_end = (span_left + span_len) < clip_right
    403                       ? span_len
    404                       : (clip_right - span_left);
    405     if (Bpp) {
    406       dest_scan += col_start * Bpp;
    407       ori_scan += col_start * Bpp;
    408     } else {
    409       dest_scan += col_start / 8;
    410       ori_scan += col_start / 8;
    411     }
    412     if (m_bRgbByteOrder) {
    413       if (Bpp == 4 && bDestAlpha) {
    414         for (int col = col_start; col < col_end; col++) {
    415           int src_alpha;
    416           if (clip_scan) {
    417             src_alpha = m_Alpha * clip_scan[col] / 255;
    418           } else {
    419             src_alpha = m_Alpha;
    420           }
    421           uint8_t dest_alpha =
    422               ori_scan[3] + src_alpha - ori_scan[3] * src_alpha / 255;
    423           dest_scan[3] = dest_alpha;
    424           int alpha_ratio = src_alpha * 255 / dest_alpha;
    425           if (m_bFullCover) {
    426             *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Red, alpha_ratio);
    427             *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, alpha_ratio);
    428             *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, alpha_ratio);
    429             dest_scan++;
    430             ori_scan++;
    431           } else {
    432             int r = FXDIB_ALPHA_MERGE(*ori_scan++, m_Red, alpha_ratio);
    433             int g = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, alpha_ratio);
    434             int b = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, alpha_ratio);
    435             ori_scan++;
    436             *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, r, cover_scan[col]);
    437             dest_scan++;
    438             *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, g, cover_scan[col]);
    439             dest_scan++;
    440             *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, b, cover_scan[col]);
    441             dest_scan += 2;
    442           }
    443         }
    444         return;
    445       }
    446       if (Bpp == 3 || Bpp == 4) {
    447         for (int col = col_start; col < col_end; col++) {
    448           int src_alpha;
    449           if (clip_scan) {
    450             src_alpha = m_Alpha * clip_scan[col] / 255;
    451           } else {
    452             src_alpha = m_Alpha;
    453           }
    454           int r = FXDIB_ALPHA_MERGE(*ori_scan++, m_Red, src_alpha);
    455           int g = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, src_alpha);
    456           int b = FXDIB_ALPHA_MERGE(*ori_scan, m_Blue, src_alpha);
    457           ori_scan += Bpp - 2;
    458           *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, r, cover_scan[col]);
    459           dest_scan++;
    460           *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, g, cover_scan[col]);
    461           dest_scan++;
    462           *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, b, cover_scan[col]);
    463           dest_scan += Bpp - 2;
    464         }
    465       }
    466       return;
    467     }
    468     if (Bpp == 4 && bDestAlpha) {
    469       for (int col = col_start; col < col_end; col++) {
    470         int src_alpha;
    471         if (clip_scan) {
    472           src_alpha = m_Alpha * clip_scan[col] / 255;
    473         } else {
    474           src_alpha = m_Alpha;
    475         }
    476         int src_alpha_covered = src_alpha * cover_scan[col] / 255;
    477         if (src_alpha_covered == 0) {
    478           dest_scan += 4;
    479           continue;
    480         }
    481         if (cover_scan[col] == 255) {
    482           dest_scan[3] = src_alpha_covered;
    483           *dest_scan++ = m_Blue;
    484           *dest_scan++ = m_Green;
    485           *dest_scan = m_Red;
    486           dest_scan += 2;
    487           continue;
    488         } else {
    489           if (dest_scan[3] == 0) {
    490             dest_scan[3] = src_alpha_covered;
    491             *dest_scan++ = m_Blue;
    492             *dest_scan++ = m_Green;
    493             *dest_scan = m_Red;
    494             dest_scan += 2;
    495             continue;
    496           }
    497           uint8_t cover = cover_scan[col];
    498           dest_scan[3] = FXDIB_ALPHA_MERGE(dest_scan[3], src_alpha, cover);
    499           *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, cover);
    500           dest_scan++;
    501           *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, cover);
    502           dest_scan++;
    503           *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, cover);
    504           dest_scan += 2;
    505         }
    506       }
    507       return;
    508     }
    509     if (Bpp == 3 || Bpp == 4) {
    510       for (int col = col_start; col < col_end; col++) {
    511         int src_alpha;
    512         if (clip_scan) {
    513           src_alpha = m_Alpha * clip_scan[col] / 255;
    514         } else {
    515           src_alpha = m_Alpha;
    516         }
    517         if (m_bFullCover) {
    518           *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, src_alpha);
    519           *dest_scan++ = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, src_alpha);
    520           *dest_scan = FXDIB_ALPHA_MERGE(*ori_scan, m_Red, src_alpha);
    521           dest_scan += Bpp - 2;
    522           ori_scan += Bpp - 2;
    523           continue;
    524         }
    525         int b = FXDIB_ALPHA_MERGE(*ori_scan++, m_Blue, src_alpha);
    526         int g = FXDIB_ALPHA_MERGE(*ori_scan++, m_Green, src_alpha);
    527         int r = FXDIB_ALPHA_MERGE(*ori_scan, m_Red, src_alpha);
    528         ori_scan += Bpp - 2;
    529         *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, b, cover_scan[col]);
    530         dest_scan++;
    531         *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, g, cover_scan[col]);
    532         dest_scan++;
    533         *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, r, cover_scan[col]);
    534         dest_scan += Bpp - 2;
    535         continue;
    536       }
    537       return;
    538     }
    539     if (Bpp == 1) {
    540       for (int col = col_start; col < col_end; col++) {
    541         int src_alpha;
    542         if (clip_scan) {
    543           src_alpha = m_Alpha * clip_scan[col] / 255;
    544         } else {
    545           src_alpha = m_Alpha;
    546         }
    547         if (m_bFullCover) {
    548           *dest_scan = FXDIB_ALPHA_MERGE(*ori_scan++, m_Gray, src_alpha);
    549         } else {
    550           int gray = FXDIB_ALPHA_MERGE(*ori_scan++, m_Gray, src_alpha);
    551           *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, gray, cover_scan[col]);
    552           dest_scan++;
    553         }
    554       }
    555     } else {
    556       int index = 0;
    557       if (m_pDevice->GetPalette()) {
    558         for (int i = 0; i < 2; i++) {
    559           if (FXARGB_TODIB(m_pDevice->GetPalette()[i]) == m_Color) {
    560             index = i;
    561           }
    562         }
    563       } else {
    564         index = ((uint8_t)m_Color == 0xff) ? 1 : 0;
    565       }
    566       uint8_t* dest_scan1 = dest_scan;
    567       for (int col = col_start; col < col_end; col++) {
    568         int src_alpha;
    569         if (clip_scan) {
    570           src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255;
    571         } else {
    572           src_alpha = m_Alpha * cover_scan[col] / 255;
    573         }
    574         if (src_alpha) {
    575           if (!index) {
    576             *dest_scan1 &= ~(1 << (7 - (col + span_left) % 8));
    577           } else {
    578             *dest_scan1 |= 1 << (7 - (col + span_left) % 8);
    579           }
    580         }
    581         dest_scan1 = dest_scan + (span_left % 8 + col - col_start + 1) / 8;
    582       }
    583     }
    584   }
    585   void CompositeSpan1bpp(uint8_t* dest_scan,
    586                          int Bpp,
    587                          int span_left,
    588                          int span_len,
    589                          uint8_t* cover_scan,
    590                          int clip_left,
    591                          int clip_right,
    592                          uint8_t* clip_scan,
    593                          uint8_t* dest_extra_alpha_scan) {
    594     ASSERT(!m_bRgbByteOrder);
    595     ASSERT(!m_pDevice->IsCmykImage());
    596     int col_start = span_left < clip_left ? clip_left - span_left : 0;
    597     int col_end = (span_left + span_len) < clip_right
    598                       ? span_len
    599                       : (clip_right - span_left);
    600     dest_scan += col_start / 8;
    601     int index = 0;
    602     if (m_pDevice->GetPalette()) {
    603       for (int i = 0; i < 2; i++) {
    604         if (FXARGB_TODIB(m_pDevice->GetPalette()[i]) == m_Color) {
    605           index = i;
    606         }
    607       }
    608     } else {
    609       index = ((uint8_t)m_Color == 0xff) ? 1 : 0;
    610     }
    611     uint8_t* dest_scan1 = dest_scan;
    612     for (int col = col_start; col < col_end; col++) {
    613       int src_alpha;
    614       if (clip_scan) {
    615         src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255;
    616       } else {
    617         src_alpha = m_Alpha * cover_scan[col] / 255;
    618       }
    619       if (src_alpha) {
    620         if (!index) {
    621           *dest_scan1 &= ~(1 << (7 - (col + span_left) % 8));
    622         } else {
    623           *dest_scan1 |= 1 << (7 - (col + span_left) % 8);
    624         }
    625       }
    626       dest_scan1 = dest_scan + (span_left % 8 + col - col_start + 1) / 8;
    627     }
    628   }
    629   void CompositeSpanGray(uint8_t* dest_scan,
    630                          int Bpp,
    631                          int span_left,
    632                          int span_len,
    633                          uint8_t* cover_scan,
    634                          int clip_left,
    635                          int clip_right,
    636                          uint8_t* clip_scan,
    637                          uint8_t* dest_extra_alpha_scan) {
    638     ASSERT(!m_bRgbByteOrder);
    639     int col_start = span_left < clip_left ? clip_left - span_left : 0;
    640     int col_end = (span_left + span_len) < clip_right
    641                       ? span_len
    642                       : (clip_right - span_left);
    643     dest_scan += col_start;
    644     if (dest_extra_alpha_scan) {
    645       for (int col = col_start; col < col_end; col++) {
    646         int src_alpha;
    647         if (m_bFullCover) {
    648           if (clip_scan) {
    649             src_alpha = m_Alpha * clip_scan[col] / 255;
    650           } else {
    651             src_alpha = m_Alpha;
    652           }
    653         } else {
    654           if (clip_scan) {
    655             src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255;
    656           } else {
    657             src_alpha = m_Alpha * cover_scan[col] / 255;
    658           }
    659         }
    660         if (src_alpha) {
    661           if (src_alpha == 255) {
    662             *dest_scan = m_Gray;
    663             *dest_extra_alpha_scan = m_Alpha;
    664           } else {
    665             uint8_t dest_alpha = (*dest_extra_alpha_scan) + src_alpha -
    666                                  (*dest_extra_alpha_scan) * src_alpha / 255;
    667             *dest_extra_alpha_scan++ = dest_alpha;
    668             int alpha_ratio = src_alpha * 255 / dest_alpha;
    669             *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Gray, alpha_ratio);
    670             dest_scan++;
    671             continue;
    672           }
    673         }
    674         dest_extra_alpha_scan++;
    675         dest_scan++;
    676       }
    677     } else {
    678       for (int col = col_start; col < col_end; col++) {
    679         int src_alpha;
    680         if (clip_scan) {
    681           src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255;
    682         } else {
    683           src_alpha = m_Alpha * cover_scan[col] / 255;
    684         }
    685         if (src_alpha) {
    686           if (src_alpha == 255) {
    687             *dest_scan = m_Gray;
    688           } else {
    689             *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Gray, src_alpha);
    690           }
    691         }
    692         dest_scan++;
    693       }
    694     }
    695   }
    696   void CompositeSpanARGB(uint8_t* dest_scan,
    697                          int Bpp,
    698                          int span_left,
    699                          int span_len,
    700                          uint8_t* cover_scan,
    701                          int clip_left,
    702                          int clip_right,
    703                          uint8_t* clip_scan,
    704                          uint8_t* dest_extra_alpha_scan) {
    705     int col_start = span_left < clip_left ? clip_left - span_left : 0;
    706     int col_end = (span_left + span_len) < clip_right
    707                       ? span_len
    708                       : (clip_right - span_left);
    709     dest_scan += col_start * Bpp;
    710     if (m_bRgbByteOrder) {
    711       for (int col = col_start; col < col_end; col++) {
    712         int src_alpha;
    713         if (m_bFullCover) {
    714           if (clip_scan) {
    715             src_alpha = m_Alpha * clip_scan[col] / 255;
    716           } else {
    717             src_alpha = m_Alpha;
    718           }
    719         } else {
    720           if (clip_scan) {
    721             src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255;
    722           } else {
    723             src_alpha = m_Alpha * cover_scan[col] / 255;
    724           }
    725         }
    726         if (src_alpha) {
    727           if (src_alpha == 255) {
    728             *(FX_DWORD*)dest_scan = m_Color;
    729           } else {
    730             uint8_t dest_alpha =
    731                 dest_scan[3] + src_alpha - dest_scan[3] * src_alpha / 255;
    732             dest_scan[3] = dest_alpha;
    733             int alpha_ratio = src_alpha * 255 / dest_alpha;
    734             *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio);
    735             dest_scan++;
    736             *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio);
    737             dest_scan++;
    738             *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio);
    739             dest_scan += 2;
    740             continue;
    741           }
    742         }
    743         dest_scan += 4;
    744       }
    745       return;
    746     }
    747     for (int col = col_start; col < col_end; col++) {
    748       int src_alpha;
    749       if (m_bFullCover) {
    750         if (clip_scan) {
    751           src_alpha = m_Alpha * clip_scan[col] / 255;
    752         } else {
    753           src_alpha = m_Alpha;
    754         }
    755       } else {
    756         if (clip_scan) {
    757           src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255;
    758         } else {
    759           src_alpha = m_Alpha * cover_scan[col] / 255;
    760         }
    761       }
    762       if (src_alpha) {
    763         if (src_alpha == 255) {
    764           *(FX_DWORD*)dest_scan = m_Color;
    765         } else {
    766           if (dest_scan[3] == 0) {
    767             dest_scan[3] = src_alpha;
    768             *dest_scan++ = m_Blue;
    769             *dest_scan++ = m_Green;
    770             *dest_scan = m_Red;
    771             dest_scan += 2;
    772             continue;
    773           }
    774           uint8_t dest_alpha =
    775               dest_scan[3] + src_alpha - dest_scan[3] * src_alpha / 255;
    776           dest_scan[3] = dest_alpha;
    777           int alpha_ratio = src_alpha * 255 / dest_alpha;
    778           *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio);
    779           dest_scan++;
    780           *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio);
    781           dest_scan++;
    782           *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio);
    783           dest_scan += 2;
    784           continue;
    785         }
    786       }
    787       dest_scan += Bpp;
    788     }
    789   }
    790   void CompositeSpanRGB(uint8_t* dest_scan,
    791                         int Bpp,
    792                         int span_left,
    793                         int span_len,
    794                         uint8_t* cover_scan,
    795                         int clip_left,
    796                         int clip_right,
    797                         uint8_t* clip_scan,
    798                         uint8_t* dest_extra_alpha_scan) {
    799     int col_start = span_left < clip_left ? clip_left - span_left : 0;
    800     int col_end = (span_left + span_len) < clip_right
    801                       ? span_len
    802                       : (clip_right - span_left);
    803     dest_scan += col_start * Bpp;
    804     if (m_bRgbByteOrder) {
    805       for (int col = col_start; col < col_end; col++) {
    806         int src_alpha;
    807         if (clip_scan) {
    808           src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255;
    809         } else {
    810           src_alpha = m_Alpha * cover_scan[col] / 255;
    811         }
    812         if (src_alpha) {
    813           if (src_alpha == 255) {
    814             if (Bpp == 4) {
    815               *(FX_DWORD*)dest_scan = m_Color;
    816             } else if (Bpp == 3) {
    817               *dest_scan++ = m_Red;
    818               *dest_scan++ = m_Green;
    819               *dest_scan++ = m_Blue;
    820               continue;
    821             }
    822           } else {
    823             *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha);
    824             dest_scan++;
    825             *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha);
    826             dest_scan++;
    827             *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha);
    828             dest_scan += Bpp - 2;
    829             continue;
    830           }
    831         }
    832         dest_scan += Bpp;
    833       }
    834       return;
    835     }
    836     if (Bpp == 3 && dest_extra_alpha_scan) {
    837       for (int col = col_start; col < col_end; col++) {
    838         int src_alpha;
    839         if (m_bFullCover) {
    840           if (clip_scan) {
    841             src_alpha = m_Alpha * clip_scan[col] / 255;
    842           } else {
    843             src_alpha = m_Alpha;
    844           }
    845         } else {
    846           if (clip_scan) {
    847             src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255;
    848           } else {
    849             src_alpha = m_Alpha * cover_scan[col] / 255;
    850           }
    851         }
    852         if (src_alpha) {
    853           if (src_alpha == 255) {
    854             *dest_scan++ = (uint8_t)m_Blue;
    855             *dest_scan++ = (uint8_t)m_Green;
    856             *dest_scan++ = (uint8_t)m_Red;
    857             *dest_extra_alpha_scan++ = (uint8_t)m_Alpha;
    858             continue;
    859           } else {
    860             uint8_t dest_alpha = (*dest_extra_alpha_scan) + src_alpha -
    861                                  (*dest_extra_alpha_scan) * src_alpha / 255;
    862             *dest_extra_alpha_scan++ = dest_alpha;
    863             int alpha_ratio = src_alpha * 255 / dest_alpha;
    864             *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio);
    865             dest_scan++;
    866             *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio);
    867             dest_scan++;
    868             *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio);
    869             dest_scan++;
    870             continue;
    871           }
    872         }
    873         dest_extra_alpha_scan++;
    874         dest_scan += Bpp;
    875       }
    876     } else {
    877       for (int col = col_start; col < col_end; col++) {
    878         int src_alpha;
    879         if (m_bFullCover) {
    880           if (clip_scan) {
    881             src_alpha = m_Alpha * clip_scan[col] / 255;
    882           } else {
    883             src_alpha = m_Alpha;
    884           }
    885         } else {
    886           if (clip_scan) {
    887             src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255;
    888           } else {
    889             src_alpha = m_Alpha * cover_scan[col] / 255;
    890           }
    891         }
    892         if (src_alpha) {
    893           if (src_alpha == 255) {
    894             if (Bpp == 4) {
    895               *(FX_DWORD*)dest_scan = m_Color;
    896             } else if (Bpp == 3) {
    897               *dest_scan++ = m_Blue;
    898               *dest_scan++ = m_Green;
    899               *dest_scan++ = m_Red;
    900               continue;
    901             }
    902           } else {
    903             *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha);
    904             dest_scan++;
    905             *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha);
    906             dest_scan++;
    907             *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha);
    908             dest_scan += Bpp - 2;
    909             continue;
    910           }
    911         }
    912         dest_scan += Bpp;
    913       }
    914     }
    915   }
    916   void CompositeSpanCMYK(uint8_t* dest_scan,
    917                          int Bpp,
    918                          int span_left,
    919                          int span_len,
    920                          uint8_t* cover_scan,
    921                          int clip_left,
    922                          int clip_right,
    923                          uint8_t* clip_scan,
    924                          uint8_t* dest_extra_alpha_scan) {
    925     ASSERT(!m_bRgbByteOrder);
    926     int col_start = span_left < clip_left ? clip_left - span_left : 0;
    927     int col_end = (span_left + span_len) < clip_right
    928                       ? span_len
    929                       : (clip_right - span_left);
    930     dest_scan += col_start * 4;
    931     if (dest_extra_alpha_scan) {
    932       for (int col = col_start; col < col_end; col++) {
    933         int src_alpha;
    934         if (m_bFullCover) {
    935           if (clip_scan) {
    936             src_alpha = m_Alpha * clip_scan[col] / 255;
    937           } else {
    938             src_alpha = m_Alpha;
    939           }
    940         } else {
    941           if (clip_scan) {
    942             src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255;
    943           } else {
    944             src_alpha = m_Alpha * cover_scan[col] / 255;
    945           }
    946         }
    947         if (src_alpha) {
    948           if (src_alpha == 255) {
    949             *(FX_CMYK*)dest_scan = m_Color;
    950             *dest_extra_alpha_scan = (uint8_t)m_Alpha;
    951           } else {
    952             uint8_t dest_alpha = (*dest_extra_alpha_scan) + src_alpha -
    953                                  (*dest_extra_alpha_scan) * src_alpha / 255;
    954             *dest_extra_alpha_scan++ = dest_alpha;
    955             int alpha_ratio = src_alpha * 255 / dest_alpha;
    956             *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, alpha_ratio);
    957             dest_scan++;
    958             *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, alpha_ratio);
    959             dest_scan++;
    960             *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, alpha_ratio);
    961             dest_scan++;
    962             *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Gray, alpha_ratio);
    963             dest_scan++;
    964             continue;
    965           }
    966         }
    967         dest_extra_alpha_scan++;
    968         dest_scan += 4;
    969       }
    970     } else {
    971       for (int col = col_start; col < col_end; col++) {
    972         int src_alpha;
    973         if (clip_scan) {
    974           src_alpha = m_Alpha * cover_scan[col] * clip_scan[col] / 255 / 255;
    975         } else {
    976           src_alpha = m_Alpha * cover_scan[col] / 255;
    977         }
    978         if (src_alpha) {
    979           if (src_alpha == 255) {
    980             *(FX_CMYK*)dest_scan = m_Color;
    981           } else {
    982             *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Red, src_alpha);
    983             dest_scan++;
    984             *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Green, src_alpha);
    985             dest_scan++;
    986             *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Blue, src_alpha);
    987             dest_scan++;
    988             *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, m_Gray, src_alpha);
    989             dest_scan++;
    990             continue;
    991           }
    992         }
    993         dest_scan += 4;
    994       }
    995     }
    996   }
    997   template <class Scanline>
    998   void render(const Scanline& sl) {
    999     if (!m_pOriDevice && !composite_span) {
   1000       return;
   1001     }
   1002     int y = sl.y();
   1003     if (y < m_ClipBox.top || y >= m_ClipBox.bottom) {
   1004       return;
   1005     }
   1006     uint8_t* dest_scan = m_pDevice->GetBuffer() + m_pDevice->GetPitch() * y;
   1007     uint8_t* dest_scan_extra_alpha = NULL;
   1008     CFX_DIBitmap* pAlphaMask = m_pDevice->m_pAlphaMask;
   1009     if (pAlphaMask) {
   1010       dest_scan_extra_alpha =
   1011           pAlphaMask->GetBuffer() + pAlphaMask->GetPitch() * y;
   1012     }
   1013     uint8_t* ori_scan = NULL;
   1014     if (m_pOriDevice) {
   1015       ori_scan = m_pOriDevice->GetBuffer() + m_pOriDevice->GetPitch() * y;
   1016     }
   1017     int Bpp = m_pDevice->GetBPP() / 8;
   1018     FX_BOOL bDestAlpha = m_pDevice->HasAlpha() || m_pDevice->IsAlphaMask();
   1019     unsigned num_spans = sl.num_spans();
   1020     typename Scanline::const_iterator span = sl.begin();
   1021     while (1) {
   1022       int x = span->x;
   1023       ASSERT(span->len > 0);
   1024       uint8_t* dest_pos = NULL;
   1025       uint8_t* dest_extra_alpha_pos = NULL;
   1026       uint8_t* ori_pos = NULL;
   1027       if (Bpp) {
   1028         ori_pos = ori_scan ? ori_scan + x * Bpp : NULL;
   1029         dest_pos = dest_scan + x * Bpp;
   1030         dest_extra_alpha_pos =
   1031             dest_scan_extra_alpha ? dest_scan_extra_alpha + x : NULL;
   1032       } else {
   1033         dest_pos = dest_scan + x / 8;
   1034         ori_pos = ori_scan ? ori_scan + x / 8 : NULL;
   1035       }
   1036       uint8_t* clip_pos = NULL;
   1037       if (m_pClipMask) {
   1038         clip_pos = m_pClipMask->GetBuffer() +
   1039                    (y - m_ClipBox.top) * m_pClipMask->GetPitch() + x -
   1040                    m_ClipBox.left;
   1041       }
   1042       if (ori_pos) {
   1043         CompositeSpan(dest_pos, ori_pos, Bpp, bDestAlpha, x, span->len,
   1044                       span->covers, m_ClipBox.left, m_ClipBox.right, clip_pos);
   1045       } else {
   1046         (this->*composite_span)(dest_pos, Bpp, x, span->len, span->covers,
   1047                                 m_ClipBox.left, m_ClipBox.right, clip_pos,
   1048                                 dest_extra_alpha_pos);
   1049       }
   1050       if (--num_spans == 0) {
   1051         break;
   1052       }
   1053       ++span;
   1054     }
   1055   }
   1056 
   1057   FX_BOOL Init(CFX_DIBitmap* pDevice,
   1058                CFX_DIBitmap* pOriDevice,
   1059                const CFX_ClipRgn* pClipRgn,
   1060                FX_DWORD color,
   1061                FX_BOOL bFullCover,
   1062                FX_BOOL bRgbByteOrder,
   1063                int alpha_flag = 0,
   1064                void* pIccTransform = NULL) {
   1065     m_pDevice = pDevice;
   1066     m_pClipRgn = pClipRgn;
   1067     composite_span = NULL;
   1068     m_bRgbByteOrder = bRgbByteOrder;
   1069     m_pOriDevice = pOriDevice;
   1070     if (m_pClipRgn) {
   1071       m_ClipBox = m_pClipRgn->GetBox();
   1072     } else {
   1073       m_ClipBox.left = m_ClipBox.top = 0;
   1074       m_ClipBox.right = m_pDevice->GetWidth();
   1075       m_ClipBox.bottom = m_pDevice->GetHeight();
   1076     }
   1077     m_pClipMask = NULL;
   1078     if (m_pClipRgn && m_pClipRgn->GetType() == CFX_ClipRgn::MaskF) {
   1079       m_pClipMask = m_pClipRgn->GetMask();
   1080     }
   1081     m_bFullCover = bFullCover;
   1082     FX_BOOL bObjectCMYK = FXGETFLAG_COLORTYPE(alpha_flag);
   1083     FX_BOOL bDeviceCMYK = pDevice->IsCmykImage();
   1084     m_Alpha = bObjectCMYK ? FXGETFLAG_ALPHA_FILL(alpha_flag) : FXARGB_A(color);
   1085     ICodec_IccModule* pIccModule = NULL;
   1086     if (!CFX_GEModule::Get()->GetCodecModule() ||
   1087         !CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) {
   1088       pIccTransform = NULL;
   1089     } else {
   1090       pIccModule = CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
   1091     }
   1092     if (m_pDevice->GetBPP() == 8) {
   1093       ASSERT(!m_bRgbByteOrder);
   1094       composite_span = &CFX_Renderer::CompositeSpanGray;
   1095       if (m_pDevice->IsAlphaMask()) {
   1096         m_Gray = 255;
   1097       } else {
   1098         if (pIccTransform) {
   1099           uint8_t gray;
   1100           color = bObjectCMYK ? FXCMYK_TODIB(color) : FXARGB_TODIB(color);
   1101           pIccModule->TranslateScanline(pIccTransform, &gray,
   1102                                         (const uint8_t*)&color, 1);
   1103           m_Gray = gray;
   1104         } else {
   1105           if (bObjectCMYK) {
   1106             uint8_t r, g, b;
   1107             AdobeCMYK_to_sRGB1(FXSYS_GetCValue(color), FXSYS_GetMValue(color),
   1108                                FXSYS_GetYValue(color), FXSYS_GetKValue(color),
   1109                                r, g, b);
   1110             m_Gray = FXRGB2GRAY(r, g, b);
   1111           } else {
   1112             m_Gray =
   1113                 FXRGB2GRAY(FXARGB_R(color), FXARGB_G(color), FXARGB_B(color));
   1114           }
   1115         }
   1116       }
   1117       return TRUE;
   1118     }
   1119     if (bDeviceCMYK) {
   1120       ASSERT(!m_bRgbByteOrder);
   1121       composite_span = &CFX_Renderer::CompositeSpanCMYK;
   1122       if (bObjectCMYK) {
   1123         m_Color = FXCMYK_TODIB(color);
   1124         if (pIccTransform) {
   1125           pIccModule->TranslateScanline(pIccTransform, (uint8_t*)&m_Color,
   1126                                         (const uint8_t*)&m_Color, 1);
   1127         }
   1128       } else {
   1129         if (!pIccTransform) {
   1130           return FALSE;
   1131         }
   1132         color = FXARGB_TODIB(color);
   1133         pIccModule->TranslateScanline(pIccTransform, (uint8_t*)&m_Color,
   1134                                       (const uint8_t*)&color, 1);
   1135       }
   1136       m_Red = ((uint8_t*)&m_Color)[0];
   1137       m_Green = ((uint8_t*)&m_Color)[1];
   1138       m_Blue = ((uint8_t*)&m_Color)[2];
   1139       m_Gray = ((uint8_t*)&m_Color)[3];
   1140     } else {
   1141       composite_span = (pDevice->GetFormat() == FXDIB_Argb)
   1142                            ? &CFX_Renderer::CompositeSpanARGB
   1143                            : &CFX_Renderer::CompositeSpanRGB;
   1144       if (pIccTransform) {
   1145         color = bObjectCMYK ? FXCMYK_TODIB(color) : FXARGB_TODIB(color);
   1146         pIccModule->TranslateScanline(pIccTransform, (uint8_t*)&m_Color,
   1147                                       (const uint8_t*)&color, 1);
   1148         ((uint8_t*)&m_Color)[3] = m_Alpha;
   1149         m_Red = ((uint8_t*)&m_Color)[2];
   1150         m_Green = ((uint8_t*)&m_Color)[1];
   1151         m_Blue = ((uint8_t*)&m_Color)[0];
   1152         if (m_bRgbByteOrder) {
   1153           m_Color = FXARGB_TODIB(m_Color);
   1154           m_Color = FXARGB_TOBGRORDERDIB(m_Color);
   1155         }
   1156       } else {
   1157         if (bObjectCMYK) {
   1158           uint8_t r, g, b;
   1159           AdobeCMYK_to_sRGB1(FXSYS_GetCValue(color), FXSYS_GetMValue(color),
   1160                              FXSYS_GetYValue(color), FXSYS_GetKValue(color), r,
   1161                              g, b);
   1162           m_Color = FXARGB_MAKE(m_Alpha, r, g, b);
   1163           if (m_bRgbByteOrder) {
   1164             m_Color = FXARGB_TOBGRORDERDIB(m_Color);
   1165           } else {
   1166             m_Color = FXARGB_TODIB(m_Color);
   1167           }
   1168           m_Red = r;
   1169           m_Green = g;
   1170           m_Blue = b;
   1171         } else {
   1172           if (m_bRgbByteOrder) {
   1173             m_Color = FXARGB_TOBGRORDERDIB(color);
   1174           } else {
   1175             m_Color = FXARGB_TODIB(color);
   1176           }
   1177           ArgbDecode(color, m_Alpha, m_Red, m_Green, m_Blue);
   1178         }
   1179       }
   1180     }
   1181     if (m_pDevice->GetBPP() == 1) {
   1182       composite_span = &CFX_Renderer::CompositeSpan1bpp;
   1183     }
   1184     return TRUE;
   1185   }
   1186 };
   1187 FX_BOOL CFX_AggDeviceDriver::RenderRasterizer(
   1188     agg::rasterizer_scanline_aa& rasterizer,
   1189     FX_DWORD color,
   1190     FX_BOOL bFullCover,
   1191     FX_BOOL bGroupKnockout,
   1192     int alpha_flag,
   1193     void* pIccTransform) {
   1194   CFX_DIBitmap* pt = bGroupKnockout ? m_pOriDevice : NULL;
   1195   CFX_Renderer render;
   1196   if (!render.Init(m_pBitmap, pt, m_pClipRgn, color, bFullCover,
   1197                    m_bRgbByteOrder, alpha_flag, pIccTransform)) {
   1198     return FALSE;
   1199   }
   1200   agg::scanline_u8 scanline;
   1201   agg::render_scanlines(rasterizer, scanline, render,
   1202                         (m_FillFlags & FXFILL_NOPATHSMOOTH) != 0);
   1203   return TRUE;
   1204 }
   1205 FX_BOOL CFX_AggDeviceDriver::DrawPath(const CFX_PathData* pPathData,
   1206                                       const CFX_Matrix* pObject2Device,
   1207                                       const CFX_GraphStateData* pGraphState,
   1208                                       FX_DWORD fill_color,
   1209                                       FX_DWORD stroke_color,
   1210                                       int fill_mode,
   1211                                       int alpha_flag,
   1212                                       void* pIccTransform,
   1213                                       int blend_type) {
   1214   if (blend_type != FXDIB_BLEND_NORMAL) {
   1215     return FALSE;
   1216   }
   1217   if (!GetBuffer()) {
   1218     return TRUE;
   1219   }
   1220   m_FillFlags = fill_mode;
   1221   if ((fill_mode & 3) && fill_color) {
   1222     CAgg_PathData path_data;
   1223     path_data.BuildPath(pPathData, pObject2Device);
   1224     agg::rasterizer_scanline_aa rasterizer;
   1225     rasterizer.clip_box(0.0f, 0.0f, (FX_FLOAT)(GetDeviceCaps(FXDC_PIXEL_WIDTH)),
   1226                         (FX_FLOAT)(GetDeviceCaps(FXDC_PIXEL_HEIGHT)));
   1227     rasterizer.add_path(path_data.m_PathData);
   1228     rasterizer.filling_rule((fill_mode & 3) == FXFILL_WINDING
   1229                                 ? agg::fill_non_zero
   1230                                 : agg::fill_even_odd);
   1231     if (!RenderRasterizer(rasterizer, fill_color, fill_mode & FXFILL_FULLCOVER,
   1232                           FALSE, alpha_flag, pIccTransform)) {
   1233       return FALSE;
   1234     }
   1235   }
   1236   int stroke_alpha = FXGETFLAG_COLORTYPE(alpha_flag)
   1237                          ? FXGETFLAG_ALPHA_STROKE(alpha_flag)
   1238                          : FXARGB_A(stroke_color);
   1239   if (pGraphState && stroke_alpha) {
   1240     if (fill_mode & FX_ZEROAREA_FILL) {
   1241       CAgg_PathData path_data;
   1242       path_data.BuildPath(pPathData, pObject2Device);
   1243       agg::rasterizer_scanline_aa rasterizer;
   1244       rasterizer.clip_box(0.0f, 0.0f,
   1245                           (FX_FLOAT)(GetDeviceCaps(FXDC_PIXEL_WIDTH)),
   1246                           (FX_FLOAT)(GetDeviceCaps(FXDC_PIXEL_HEIGHT)));
   1247       RasterizeStroke(rasterizer, path_data.m_PathData, NULL, pGraphState, 1,
   1248                       FALSE, fill_mode & FX_STROKE_TEXT_MODE);
   1249       int fill_flag = FXGETFLAG_COLORTYPE(alpha_flag) << 8 |
   1250                       FXGETFLAG_ALPHA_STROKE(alpha_flag);
   1251       if (!RenderRasterizer(rasterizer, stroke_color,
   1252                             fill_mode & FXFILL_FULLCOVER, m_bGroupKnockout,
   1253                             fill_flag, pIccTransform)) {
   1254         return FALSE;
   1255       }
   1256       return TRUE;
   1257     }
   1258     CFX_Matrix matrix1, matrix2;
   1259     if (pObject2Device) {
   1260       matrix1.a = std::max(FXSYS_fabs(pObject2Device->a),
   1261                            FXSYS_fabs(pObject2Device->b));
   1262       matrix1.d = matrix1.a;
   1263       matrix2.Set(pObject2Device->a / matrix1.a, pObject2Device->b / matrix1.a,
   1264                   pObject2Device->c / matrix1.d, pObject2Device->d / matrix1.d,
   1265                   0, 0);
   1266       CFX_Matrix mtRervese;
   1267       mtRervese.SetReverse(matrix2);
   1268       matrix1 = *pObject2Device;
   1269       matrix1.Concat(mtRervese);
   1270     }
   1271     CAgg_PathData path_data;
   1272     path_data.BuildPath(pPathData, &matrix1);
   1273     agg::rasterizer_scanline_aa rasterizer;
   1274     rasterizer.clip_box(0.0f, 0.0f, (FX_FLOAT)(GetDeviceCaps(FXDC_PIXEL_WIDTH)),
   1275                         (FX_FLOAT)(GetDeviceCaps(FXDC_PIXEL_HEIGHT)));
   1276     RasterizeStroke(rasterizer, path_data.m_PathData, &matrix2, pGraphState,
   1277                     matrix1.a, FALSE, fill_mode & FX_STROKE_TEXT_MODE);
   1278     int fill_flag = FXGETFLAG_COLORTYPE(alpha_flag) << 8 |
   1279                     FXGETFLAG_ALPHA_STROKE(alpha_flag);
   1280     if (!RenderRasterizer(rasterizer, stroke_color,
   1281                           fill_mode & FXFILL_FULLCOVER, m_bGroupKnockout,
   1282                           fill_flag, pIccTransform)) {
   1283       return FALSE;
   1284     }
   1285   }
   1286   return TRUE;
   1287 }
   1288 void RgbByteOrderSetPixel(CFX_DIBitmap* pBitmap, int x, int y, FX_DWORD argb) {
   1289   if (x < 0 || x >= pBitmap->GetWidth() || y < 0 || y >= pBitmap->GetHeight()) {
   1290     return;
   1291   }
   1292   uint8_t* pos = (uint8_t*)pBitmap->GetBuffer() + y * pBitmap->GetPitch() +
   1293                  x * pBitmap->GetBPP() / 8;
   1294   if (pBitmap->GetFormat() == FXDIB_Argb) {
   1295     FXARGB_SETRGBORDERDIB(pos, ArgbGamma(argb));
   1296   } else {
   1297     int alpha = FXARGB_A(argb);
   1298     pos[0] = (FXARGB_R(argb) * alpha + pos[0] * (255 - alpha)) / 255;
   1299     pos[1] = (FXARGB_G(argb) * alpha + pos[1] * (255 - alpha)) / 255;
   1300     pos[2] = (FXARGB_B(argb) * alpha + pos[2] * (255 - alpha)) / 255;
   1301   }
   1302 }
   1303 void RgbByteOrderCompositeRect(CFX_DIBitmap* pBitmap,
   1304                                int left,
   1305                                int top,
   1306                                int width,
   1307                                int height,
   1308                                FX_ARGB argb) {
   1309   int src_alpha = FXARGB_A(argb);
   1310   if (src_alpha == 0) {
   1311     return;
   1312   }
   1313   FX_RECT rect(left, top, left + width, top + height);
   1314   rect.Intersect(0, 0, pBitmap->GetWidth(), pBitmap->GetHeight());
   1315   width = rect.Width();
   1316   int src_r = FXARGB_R(argb), src_g = FXARGB_G(argb), src_b = FXARGB_B(argb);
   1317   int Bpp = pBitmap->GetBPP() / 8;
   1318   FX_BOOL bAlpha = pBitmap->HasAlpha();
   1319   int dib_argb = FXARGB_TOBGRORDERDIB(argb);
   1320   uint8_t* pBuffer = pBitmap->GetBuffer();
   1321   if (src_alpha == 255) {
   1322     for (int row = rect.top; row < rect.bottom; row++) {
   1323       uint8_t* dest_scan =
   1324           pBuffer + row * pBitmap->GetPitch() + rect.left * Bpp;
   1325       if (Bpp == 4) {
   1326         FX_DWORD* scan = (FX_DWORD*)dest_scan;
   1327         for (int col = 0; col < width; col++) {
   1328           *scan++ = dib_argb;
   1329         }
   1330       } else {
   1331         for (int col = 0; col < width; col++) {
   1332           *dest_scan++ = src_r;
   1333           *dest_scan++ = src_g;
   1334           *dest_scan++ = src_b;
   1335         }
   1336       }
   1337     }
   1338     return;
   1339   }
   1340   src_r = FX_GAMMA(src_r);
   1341   src_g = FX_GAMMA(src_g);
   1342   src_b = FX_GAMMA(src_b);
   1343   for (int row = rect.top; row < rect.bottom; row++) {
   1344     uint8_t* dest_scan = pBuffer + row * pBitmap->GetPitch() + rect.left * Bpp;
   1345     if (bAlpha) {
   1346       for (int col = 0; col < width; col++) {
   1347         uint8_t back_alpha = dest_scan[3];
   1348         if (back_alpha == 0) {
   1349           FXARGB_SETRGBORDERDIB(dest_scan,
   1350                                 FXARGB_MAKE(src_alpha, src_r, src_g, src_b));
   1351           dest_scan += 4;
   1352           continue;
   1353         }
   1354         uint8_t dest_alpha =
   1355             back_alpha + src_alpha - back_alpha * src_alpha / 255;
   1356         dest_scan[3] = dest_alpha;
   1357         int alpha_ratio = src_alpha * 255 / dest_alpha;
   1358         *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_r, alpha_ratio);
   1359         dest_scan++;
   1360         *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_g, alpha_ratio);
   1361         dest_scan++;
   1362         *dest_scan = FXDIB_ALPHA_MERGE(*dest_scan, src_b, alpha_ratio);
   1363         dest_scan += 2;
   1364       }
   1365     } else {
   1366       for (int col = 0; col < width; col++) {
   1367         *dest_scan = FX_GAMMA_INVERSE(
   1368             FXDIB_ALPHA_MERGE(FX_GAMMA(*dest_scan), src_r, src_alpha));
   1369         dest_scan++;
   1370         *dest_scan = FX_GAMMA_INVERSE(
   1371             FXDIB_ALPHA_MERGE(FX_GAMMA(*dest_scan), src_g, src_alpha));
   1372         dest_scan++;
   1373         *dest_scan = FX_GAMMA_INVERSE(
   1374             FXDIB_ALPHA_MERGE(FX_GAMMA(*dest_scan), src_b, src_alpha));
   1375         dest_scan++;
   1376         if (Bpp == 4) {
   1377           dest_scan++;
   1378         }
   1379       }
   1380     }
   1381   }
   1382 }
   1383 void RgbByteOrderTransferBitmap(CFX_DIBitmap* pBitmap,
   1384                                 int dest_left,
   1385                                 int dest_top,
   1386                                 int width,
   1387                                 int height,
   1388                                 const CFX_DIBSource* pSrcBitmap,
   1389                                 int src_left,
   1390                                 int src_top) {
   1391   if (!pBitmap) {
   1392     return;
   1393   }
   1394   pBitmap->GetOverlapRect(dest_left, dest_top, width, height,
   1395                           pSrcBitmap->GetWidth(), pSrcBitmap->GetHeight(),
   1396                           src_left, src_top, NULL);
   1397   if (width == 0 || height == 0) {
   1398     return;
   1399   }
   1400   int Bpp = pBitmap->GetBPP() / 8;
   1401   FXDIB_Format dest_format = pBitmap->GetFormat();
   1402   FXDIB_Format src_format = pSrcBitmap->GetFormat();
   1403   int pitch = pBitmap->GetPitch();
   1404   uint8_t* buffer = pBitmap->GetBuffer();
   1405   if (dest_format == src_format) {
   1406     for (int row = 0; row < height; row++) {
   1407       uint8_t* dest_scan = buffer + (dest_top + row) * pitch + dest_left * Bpp;
   1408       uint8_t* src_scan =
   1409           (uint8_t*)pSrcBitmap->GetScanline(src_top + row) + src_left * Bpp;
   1410       if (Bpp == 4) {
   1411         for (int col = 0; col < width; col++) {
   1412           FXARGB_SETDIB(dest_scan, FXARGB_MAKE(src_scan[3], src_scan[0],
   1413                                                src_scan[1], src_scan[2]));
   1414           dest_scan += 4;
   1415           src_scan += 4;
   1416         }
   1417       } else {
   1418         for (int col = 0; col < width; col++) {
   1419           *dest_scan++ = src_scan[2];
   1420           *dest_scan++ = src_scan[1];
   1421           *dest_scan++ = src_scan[0];
   1422           src_scan += 3;
   1423         }
   1424       }
   1425     }
   1426     return;
   1427   }
   1428   uint8_t* dest_buf = buffer + dest_top * pitch + dest_left * Bpp;
   1429   if (dest_format == FXDIB_Rgb) {
   1430     if (src_format == FXDIB_Rgb32) {
   1431       for (int row = 0; row < height; row++) {
   1432         uint8_t* dest_scan = dest_buf + row * pitch;
   1433         uint8_t* src_scan =
   1434             (uint8_t*)pSrcBitmap->GetScanline(src_top + row) + src_left * 4;
   1435         for (int col = 0; col < width; col++) {
   1436           *dest_scan++ = src_scan[2];
   1437           *dest_scan++ = src_scan[1];
   1438           *dest_scan++ = src_scan[0];
   1439           src_scan += 4;
   1440         }
   1441       }
   1442     } else {
   1443       ASSERT(FALSE);
   1444     }
   1445   } else if (dest_format == FXDIB_Argb || dest_format == FXDIB_Rgb32) {
   1446     if (src_format == FXDIB_Rgb) {
   1447       for (int row = 0; row < height; row++) {
   1448         uint8_t* dest_scan = (uint8_t*)(dest_buf + row * pitch);
   1449         uint8_t* src_scan =
   1450             (uint8_t*)pSrcBitmap->GetScanline(src_top + row) + src_left * 3;
   1451         if (src_format == FXDIB_Argb) {
   1452           for (int col = 0; col < width; col++) {
   1453             FXARGB_SETDIB(dest_scan, FXARGB_MAKE(0xff, FX_GAMMA(src_scan[0]),
   1454                                                  FX_GAMMA(src_scan[1]),
   1455                                                  FX_GAMMA(src_scan[2])));
   1456             dest_scan += 4;
   1457             src_scan += 3;
   1458           }
   1459         } else {
   1460           for (int col = 0; col < width; col++) {
   1461             FXARGB_SETDIB(dest_scan, FXARGB_MAKE(0xff, src_scan[0], src_scan[1],
   1462                                                  src_scan[2]));
   1463             dest_scan += 4;
   1464             src_scan += 3;
   1465           }
   1466         }
   1467       }
   1468     } else if (src_format == FXDIB_Rgb32) {
   1469       ASSERT(dest_format == FXDIB_Argb);
   1470       for (int row = 0; row < height; row++) {
   1471         uint8_t* dest_scan = dest_buf + row * pitch;
   1472         uint8_t* src_scan =
   1473             (uint8_t*)(pSrcBitmap->GetScanline(src_top + row) + src_left * 4);
   1474         for (int col = 0; col < width; col++) {
   1475           FXARGB_SETDIB(dest_scan, FXARGB_MAKE(0xff, src_scan[0], src_scan[1],
   1476                                                src_scan[2]));
   1477           src_scan += 4;
   1478           dest_scan += 4;
   1479         }
   1480       }
   1481     }
   1482   } else {
   1483     ASSERT(FALSE);
   1484   }
   1485 }
   1486 FX_ARGB _DefaultCMYK2ARGB(FX_CMYK cmyk, uint8_t alpha) {
   1487   uint8_t r, g, b;
   1488   AdobeCMYK_to_sRGB1(FXSYS_GetCValue(cmyk), FXSYS_GetMValue(cmyk),
   1489                      FXSYS_GetYValue(cmyk), FXSYS_GetKValue(cmyk), r, g, b);
   1490   return ArgbEncode(alpha, r, g, b);
   1491 }
   1492 FX_BOOL _DibSetPixel(CFX_DIBitmap* pDevice,
   1493                      int x,
   1494                      int y,
   1495                      FX_DWORD color,
   1496                      int alpha_flag,
   1497                      void* pIccTransform) {
   1498   FX_BOOL bObjCMYK = FXGETFLAG_COLORTYPE(alpha_flag);
   1499   int alpha = bObjCMYK ? FXGETFLAG_ALPHA_FILL(alpha_flag) : FXARGB_A(color);
   1500   if (pIccTransform) {
   1501     ICodec_IccModule* pIccModule =
   1502         CFX_GEModule::Get()->GetCodecModule()->GetIccModule();
   1503     color = bObjCMYK ? FXCMYK_TODIB(color) : FXARGB_TODIB(color);
   1504     pIccModule->TranslateScanline(pIccTransform, (uint8_t*)&color,
   1505                                   (uint8_t*)&color, 1);
   1506     color = bObjCMYK ? FXCMYK_TODIB(color) : FXARGB_TODIB(color);
   1507     if (!pDevice->IsCmykImage()) {
   1508       color = (color & 0xffffff) | (alpha << 24);
   1509     }
   1510   } else {
   1511     if (pDevice->IsCmykImage()) {
   1512       if (!bObjCMYK) {
   1513         return FALSE;
   1514       }
   1515     } else {
   1516       if (bObjCMYK) {
   1517         color = _DefaultCMYK2ARGB(color, alpha);
   1518       }
   1519     }
   1520   }
   1521   pDevice->SetPixel(x, y, color);
   1522   if (pDevice->m_pAlphaMask) {
   1523     pDevice->m_pAlphaMask->SetPixel(x, y, alpha << 24);
   1524   }
   1525   return TRUE;
   1526 }
   1527 FX_BOOL CFX_AggDeviceDriver::SetPixel(int x,
   1528                                       int y,
   1529                                       FX_DWORD color,
   1530                                       int alpha_flag,
   1531                                       void* pIccTransform) {
   1532   if (!m_pBitmap->GetBuffer()) {
   1533     return TRUE;
   1534   }
   1535   if (!CFX_GEModule::Get()->GetCodecModule() ||
   1536       !CFX_GEModule::Get()->GetCodecModule()->GetIccModule()) {
   1537     pIccTransform = NULL;
   1538   }
   1539   if (!m_pClipRgn) {
   1540     if (m_bRgbByteOrder) {
   1541       RgbByteOrderSetPixel(m_pBitmap, x, y, color);
   1542     } else {
   1543       return _DibSetPixel(m_pBitmap, x, y, color, alpha_flag, pIccTransform);
   1544     }
   1545   } else if (m_pClipRgn->GetBox().Contains(x, y)) {
   1546     if (m_pClipRgn->GetType() == CFX_ClipRgn::RectI) {
   1547       if (m_bRgbByteOrder) {
   1548         RgbByteOrderSetPixel(m_pBitmap, x, y, color);
   1549       } else {
   1550         return _DibSetPixel(m_pBitmap, x, y, color, alpha_flag, pIccTransform);
   1551       }
   1552     } else if (m_pClipRgn->GetType() == CFX_ClipRgn::MaskF) {
   1553       const CFX_DIBitmap* pMask = m_pClipRgn->GetMask();
   1554       FX_BOOL bCMYK = FXGETFLAG_COLORTYPE(alpha_flag);
   1555       int new_alpha =
   1556           bCMYK ? FXGETFLAG_ALPHA_FILL(alpha_flag) : FXARGB_A(color);
   1557       new_alpha = new_alpha * pMask->GetScanline(y)[x] / 255;
   1558       if (m_bRgbByteOrder) {
   1559         RgbByteOrderSetPixel(m_pBitmap, x, y,
   1560                              (color & 0xffffff) | (new_alpha << 24));
   1561         return TRUE;
   1562       }
   1563       if (bCMYK) {
   1564         FXSETFLAG_ALPHA_FILL(alpha_flag, new_alpha);
   1565       } else {
   1566         color = (color & 0xffffff) | (new_alpha << 24);
   1567       }
   1568       return _DibSetPixel(m_pBitmap, x, y, color, alpha_flag, pIccTransform);
   1569     }
   1570   }
   1571   return TRUE;
   1572 }
   1573 FX_BOOL CFX_AggDeviceDriver::FillRect(const FX_RECT* pRect,
   1574                                       FX_DWORD fill_color,
   1575                                       int alpha_flag,
   1576                                       void* pIccTransform,
   1577                                       int blend_type) {
   1578   if (blend_type != FXDIB_BLEND_NORMAL) {
   1579     return FALSE;
   1580   }
   1581   if (!m_pBitmap->GetBuffer()) {
   1582     return TRUE;
   1583   }
   1584   FX_RECT clip_rect;
   1585   GetClipBox(&clip_rect);
   1586   FX_RECT draw_rect = clip_rect;
   1587   if (pRect) {
   1588     draw_rect.Intersect(*pRect);
   1589   }
   1590   if (draw_rect.IsEmpty()) {
   1591     return TRUE;
   1592   }
   1593   if (!m_pClipRgn || m_pClipRgn->GetType() == CFX_ClipRgn::RectI) {
   1594     if (m_bRgbByteOrder) {
   1595       RgbByteOrderCompositeRect(m_pBitmap, draw_rect.left, draw_rect.top,
   1596                                 draw_rect.Width(), draw_rect.Height(),
   1597                                 fill_color);
   1598     } else {
   1599       m_pBitmap->CompositeRect(draw_rect.left, draw_rect.top, draw_rect.Width(),
   1600                                draw_rect.Height(), fill_color, alpha_flag,
   1601                                pIccTransform);
   1602     }
   1603     return TRUE;
   1604   }
   1605   m_pBitmap->CompositeMask(
   1606       draw_rect.left, draw_rect.top, draw_rect.Width(), draw_rect.Height(),
   1607       (const CFX_DIBitmap*)m_pClipRgn->GetMask(), fill_color,
   1608       draw_rect.left - clip_rect.left, draw_rect.top - clip_rect.top,
   1609       FXDIB_BLEND_NORMAL, NULL, m_bRgbByteOrder, alpha_flag, pIccTransform);
   1610   return TRUE;
   1611 }
   1612 FX_BOOL CFX_AggDeviceDriver::GetClipBox(FX_RECT* pRect) {
   1613   if (!m_pClipRgn) {
   1614     pRect->left = pRect->top = 0;
   1615     pRect->right = GetDeviceCaps(FXDC_PIXEL_WIDTH);
   1616     pRect->bottom = GetDeviceCaps(FXDC_PIXEL_HEIGHT);
   1617     return TRUE;
   1618   }
   1619   *pRect = m_pClipRgn->GetBox();
   1620   return TRUE;
   1621 }
   1622 FX_BOOL CFX_AggDeviceDriver::GetDIBits(CFX_DIBitmap* pBitmap,
   1623                                        int left,
   1624                                        int top,
   1625                                        void* pIccTransform,
   1626                                        FX_BOOL bDEdge) {
   1627   if (!m_pBitmap->GetBuffer()) {
   1628     return TRUE;
   1629   }
   1630   if (bDEdge) {
   1631     if (m_bRgbByteOrder) {
   1632       RgbByteOrderTransferBitmap(pBitmap, 0, 0, pBitmap->GetWidth(),
   1633                                  pBitmap->GetHeight(), m_pBitmap, left, top);
   1634     } else {
   1635       return pBitmap->TransferBitmap(0, 0, pBitmap->GetWidth(),
   1636                                      pBitmap->GetHeight(), m_pBitmap, left, top,
   1637                                      pIccTransform);
   1638     }
   1639     return TRUE;
   1640   }
   1641   FX_RECT rect(left, top, left + pBitmap->GetWidth(),
   1642                top + pBitmap->GetHeight());
   1643   CFX_DIBitmap* pBack = NULL;
   1644   if (m_pOriDevice) {
   1645     pBack = m_pOriDevice->Clone(&rect);
   1646     if (!pBack) {
   1647       return TRUE;
   1648     }
   1649     pBack->CompositeBitmap(0, 0, pBack->GetWidth(), pBack->GetHeight(),
   1650                            m_pBitmap, 0, 0);
   1651   } else {
   1652     pBack = m_pBitmap->Clone(&rect);
   1653   }
   1654   if (!pBack) {
   1655     return TRUE;
   1656   }
   1657   FX_BOOL bRet = TRUE;
   1658   left = left >= 0 ? 0 : left;
   1659   top = top >= 0 ? 0 : top;
   1660   if (m_bRgbByteOrder) {
   1661     RgbByteOrderTransferBitmap(pBitmap, 0, 0, rect.Width(), rect.Height(),
   1662                                pBack, left, top);
   1663   } else {
   1664     bRet = pBitmap->TransferBitmap(0, 0, rect.Width(), rect.Height(), pBack,
   1665                                    left, top, pIccTransform);
   1666   }
   1667   delete pBack;
   1668   return bRet;
   1669 }
   1670 FX_BOOL CFX_AggDeviceDriver::SetDIBits(const CFX_DIBSource* pBitmap,
   1671                                        FX_DWORD argb,
   1672                                        const FX_RECT* pSrcRect,
   1673                                        int left,
   1674                                        int top,
   1675                                        int blend_type,
   1676                                        int alpha_flag,
   1677                                        void* pIccTransform) {
   1678   if (!m_pBitmap->GetBuffer()) {
   1679     return TRUE;
   1680   }
   1681   if (pBitmap->IsAlphaMask())
   1682     return m_pBitmap->CompositeMask(
   1683         left, top, pSrcRect->Width(), pSrcRect->Height(), pBitmap, argb,
   1684         pSrcRect->left, pSrcRect->top, blend_type, m_pClipRgn, m_bRgbByteOrder,
   1685         alpha_flag, pIccTransform);
   1686   return m_pBitmap->CompositeBitmap(
   1687       left, top, pSrcRect->Width(), pSrcRect->Height(), pBitmap, pSrcRect->left,
   1688       pSrcRect->top, blend_type, m_pClipRgn, m_bRgbByteOrder, pIccTransform);
   1689 }
   1690 FX_BOOL CFX_AggDeviceDriver::StretchDIBits(const CFX_DIBSource* pSource,
   1691                                            FX_DWORD argb,
   1692                                            int dest_left,
   1693                                            int dest_top,
   1694                                            int dest_width,
   1695                                            int dest_height,
   1696                                            const FX_RECT* pClipRect,
   1697                                            FX_DWORD flags,
   1698                                            int alpha_flag,
   1699                                            void* pIccTransform,
   1700                                            int blend_type) {
   1701   if (!m_pBitmap->GetBuffer()) {
   1702     return TRUE;
   1703   }
   1704   if (dest_width == pSource->GetWidth() &&
   1705       dest_height == pSource->GetHeight()) {
   1706     FX_RECT rect(0, 0, dest_width, dest_height);
   1707     return SetDIBits(pSource, argb, &rect, dest_left, dest_top, blend_type,
   1708                      alpha_flag, pIccTransform);
   1709   }
   1710   FX_RECT dest_rect(dest_left, dest_top, dest_left + dest_width,
   1711                     dest_top + dest_height);
   1712   dest_rect.Normalize();
   1713   FX_RECT dest_clip = dest_rect;
   1714   dest_clip.Intersect(*pClipRect);
   1715   CFX_BitmapComposer composer;
   1716   composer.Compose(m_pBitmap, m_pClipRgn, 255, argb, dest_clip, FALSE, FALSE,
   1717                    FALSE, m_bRgbByteOrder, alpha_flag, pIccTransform,
   1718                    blend_type);
   1719   dest_clip.Offset(-dest_rect.left, -dest_rect.top);
   1720   CFX_ImageStretcher stretcher;
   1721   if (stretcher.Start(&composer, pSource, dest_width, dest_height, dest_clip,
   1722                       flags)) {
   1723     stretcher.Continue(NULL);
   1724   }
   1725   return TRUE;
   1726 }
   1727 FX_BOOL CFX_AggDeviceDriver::StartDIBits(const CFX_DIBSource* pSource,
   1728                                          int bitmap_alpha,
   1729                                          FX_DWORD argb,
   1730                                          const CFX_Matrix* pMatrix,
   1731                                          FX_DWORD render_flags,
   1732                                          void*& handle,
   1733                                          int alpha_flag,
   1734                                          void* pIccTransform,
   1735                                          int blend_type) {
   1736   if (!m_pBitmap->GetBuffer()) {
   1737     return TRUE;
   1738   }
   1739   CFX_ImageRenderer* pRenderer = new CFX_ImageRenderer;
   1740   pRenderer->Start(m_pBitmap, m_pClipRgn, pSource, bitmap_alpha, argb, pMatrix,
   1741                    render_flags, m_bRgbByteOrder, alpha_flag, pIccTransform);
   1742   handle = pRenderer;
   1743   return TRUE;
   1744 }
   1745 FX_BOOL CFX_AggDeviceDriver::ContinueDIBits(void* pHandle, IFX_Pause* pPause) {
   1746   if (!m_pBitmap->GetBuffer()) {
   1747     return TRUE;
   1748   }
   1749   return ((CFX_ImageRenderer*)pHandle)->Continue(pPause);
   1750 }
   1751 void CFX_AggDeviceDriver::CancelDIBits(void* pHandle) {
   1752   if (!m_pBitmap->GetBuffer()) {
   1753     return;
   1754   }
   1755   delete (CFX_ImageRenderer*)pHandle;
   1756 }
   1757 CFX_FxgeDevice::CFX_FxgeDevice() {
   1758   m_bOwnedBitmap = FALSE;
   1759 }
   1760 FX_BOOL CFX_FxgeDevice::Attach(CFX_DIBitmap* pBitmap,
   1761                                int dither_bits,
   1762                                FX_BOOL bRgbByteOrder,
   1763                                CFX_DIBitmap* pOriDevice,
   1764                                FX_BOOL bGroupKnockout) {
   1765   if (!pBitmap) {
   1766     return FALSE;
   1767   }
   1768   SetBitmap(pBitmap);
   1769   IFX_RenderDeviceDriver* pDriver = new CFX_AggDeviceDriver(
   1770       pBitmap, dither_bits, bRgbByteOrder, pOriDevice, bGroupKnockout);
   1771   SetDeviceDriver(pDriver);
   1772   return TRUE;
   1773 }
   1774 FX_BOOL CFX_FxgeDevice::Create(int width,
   1775                                int height,
   1776                                FXDIB_Format format,
   1777                                int dither_bits,
   1778                                CFX_DIBitmap* pOriDevice) {
   1779   m_bOwnedBitmap = TRUE;
   1780   CFX_DIBitmap* pBitmap = new CFX_DIBitmap;
   1781   if (!pBitmap->Create(width, height, format)) {
   1782     delete pBitmap;
   1783     return FALSE;
   1784   }
   1785   SetBitmap(pBitmap);
   1786   IFX_RenderDeviceDriver* pDriver =
   1787       new CFX_AggDeviceDriver(pBitmap, dither_bits, FALSE, pOriDevice, FALSE);
   1788   SetDeviceDriver(pDriver);
   1789   return TRUE;
   1790 }
   1791 CFX_FxgeDevice::~CFX_FxgeDevice() {
   1792   if (m_bOwnedBitmap) {
   1793     delete GetBitmap();
   1794   }
   1795 }
   1796