• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
HardClip(FX_FLOAT & x,FX_FLOAT & y)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 
BuildPath(const CFX_PathData * pPathData,const CFX_Matrix * pObject2Device)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;
renderer_scanline_aa_offset(base_ren_type & ren,unsigned left,unsigned top)79   renderer_scanline_aa_offset(base_ren_type& ren, unsigned left, unsigned top)
80       : m_ren(&ren), m_left(left), m_top(top) {}
color(const color_type & c)81   void color(const color_type& c) { m_color = c; }
color() const82   const color_type& color() const { return m_color; }
prepare(unsigned)83   void prepare(unsigned) {}
84   template <class Scanline>
render(const Scanline & sl)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 
RasterizeStroke(agg::rasterizer_scanline_aa & rasterizer,agg::path_storage & path_data,const CFX_Matrix * pObject2Device,const CFX_GraphStateData * pGraphState,FX_FLOAT scale=1.0f,FX_BOOL bStrokeAdjust=FALSE,FX_BOOL bTextMode=FALSE)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 }
CreateFxgeDriver(CFX_DIBitmap * pBitmap,FX_BOOL bRgbByteOrder,CFX_DIBitmap * pOriDevice,FX_BOOL bGroupKnockout)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 }
CFX_AggDeviceDriver(CFX_DIBitmap * pBitmap,int dither_bits,FX_BOOL bRgbByteOrder,CFX_DIBitmap * pOriDevice,FX_BOOL bGroupKnockout)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 }
~CFX_AggDeviceDriver()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_
InitPlatform()218 void CFX_AggDeviceDriver::InitPlatform() {}
DestroyPlatform()219 void CFX_AggDeviceDriver::DestroyPlatform() {}
DrawDeviceText(int nChars,const FXTEXT_CHARPOS * pCharPos,CFX_Font * pFont,CFX_FontCache * pCache,const CFX_Matrix * pObject2Device,FX_FLOAT font_size,FX_DWORD color,int alpha_flag,void * pIccTransform)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
GetDeviceCaps(int caps_id)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 }
SaveState()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 }
RestoreState(FX_BOOL bKeepSaved)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 }
SetClipMask(agg::rasterizer_scanline_aa & rasterizer)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 }
SetClip_PathFill(const CFX_PathData * pPathData,const CFX_Matrix * pObject2Device,int fill_mode)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 }
SetClip_PathStroke(const CFX_PathData * pPathData,const CFX_Matrix * pObject2Device,const CFX_GraphStateData * pGraphState)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:
prepare(unsigned)389   void prepare(unsigned) {}
CompositeSpan(uint8_t * dest_scan,uint8_t * ori_scan,int Bpp,FX_BOOL bDestAlpha,int span_left,int span_len,uint8_t * cover_scan,int clip_left,int clip_right,uint8_t * clip_scan)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   }
CompositeSpan1bpp(uint8_t * dest_scan,int Bpp,int span_left,int span_len,uint8_t * cover_scan,int clip_left,int clip_right,uint8_t * clip_scan,uint8_t * dest_extra_alpha_scan)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   }
CompositeSpanGray(uint8_t * dest_scan,int Bpp,int span_left,int span_len,uint8_t * cover_scan,int clip_left,int clip_right,uint8_t * clip_scan,uint8_t * dest_extra_alpha_scan)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   }
CompositeSpanARGB(uint8_t * dest_scan,int Bpp,int span_left,int span_len,uint8_t * cover_scan,int clip_left,int clip_right,uint8_t * clip_scan,uint8_t * dest_extra_alpha_scan)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   }
CompositeSpanRGB(uint8_t * dest_scan,int Bpp,int span_left,int span_len,uint8_t * cover_scan,int clip_left,int clip_right,uint8_t * clip_scan,uint8_t * dest_extra_alpha_scan)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   }
CompositeSpanCMYK(uint8_t * dest_scan,int Bpp,int span_left,int span_len,uint8_t * cover_scan,int clip_left,int clip_right,uint8_t * clip_scan,uint8_t * dest_extra_alpha_scan)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>
render(const Scanline & sl)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 
Init(CFX_DIBitmap * pDevice,CFX_DIBitmap * pOriDevice,const CFX_ClipRgn * pClipRgn,FX_DWORD color,FX_BOOL bFullCover,FX_BOOL bRgbByteOrder,int alpha_flag=0,void * pIccTransform=NULL)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 };
RenderRasterizer(agg::rasterizer_scanline_aa & rasterizer,FX_DWORD color,FX_BOOL bFullCover,FX_BOOL bGroupKnockout,int alpha_flag,void * pIccTransform)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 }
DrawPath(const CFX_PathData * pPathData,const CFX_Matrix * pObject2Device,const CFX_GraphStateData * pGraphState,FX_DWORD fill_color,FX_DWORD stroke_color,int fill_mode,int alpha_flag,void * pIccTransform,int blend_type)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 }
RgbByteOrderSetPixel(CFX_DIBitmap * pBitmap,int x,int y,FX_DWORD argb)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 }
RgbByteOrderCompositeRect(CFX_DIBitmap * pBitmap,int left,int top,int width,int height,FX_ARGB argb)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 }
RgbByteOrderTransferBitmap(CFX_DIBitmap * pBitmap,int dest_left,int dest_top,int width,int height,const CFX_DIBSource * pSrcBitmap,int src_left,int src_top)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 }
_DefaultCMYK2ARGB(FX_CMYK cmyk,uint8_t alpha)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 }
_DibSetPixel(CFX_DIBitmap * pDevice,int x,int y,FX_DWORD color,int alpha_flag,void * pIccTransform)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 }
SetPixel(int x,int y,FX_DWORD color,int alpha_flag,void * pIccTransform)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 }
FillRect(const FX_RECT * pRect,FX_DWORD fill_color,int alpha_flag,void * pIccTransform,int blend_type)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 }
GetClipBox(FX_RECT * pRect)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 }
GetDIBits(CFX_DIBitmap * pBitmap,int left,int top,void * pIccTransform,FX_BOOL bDEdge)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 }
SetDIBits(const CFX_DIBSource * pBitmap,FX_DWORD argb,const FX_RECT * pSrcRect,int left,int top,int blend_type,int alpha_flag,void * pIccTransform)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 }
StretchDIBits(const CFX_DIBSource * pSource,FX_DWORD argb,int dest_left,int dest_top,int dest_width,int dest_height,const FX_RECT * pClipRect,FX_DWORD flags,int alpha_flag,void * pIccTransform,int blend_type)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 }
StartDIBits(const CFX_DIBSource * pSource,int bitmap_alpha,FX_DWORD argb,const CFX_Matrix * pMatrix,FX_DWORD render_flags,void * & handle,int alpha_flag,void * pIccTransform,int blend_type)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 }
ContinueDIBits(void * pHandle,IFX_Pause * pPause)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 }
CancelDIBits(void * pHandle)1751 void CFX_AggDeviceDriver::CancelDIBits(void* pHandle) {
1752   if (!m_pBitmap->GetBuffer()) {
1753     return;
1754   }
1755   delete (CFX_ImageRenderer*)pHandle;
1756 }
CFX_FxgeDevice()1757 CFX_FxgeDevice::CFX_FxgeDevice() {
1758   m_bOwnedBitmap = FALSE;
1759 }
Attach(CFX_DIBitmap * pBitmap,int dither_bits,FX_BOOL bRgbByteOrder,CFX_DIBitmap * pOriDevice,FX_BOOL bGroupKnockout)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 }
Create(int width,int height,FXDIB_Format format,int dither_bits,CFX_DIBitmap * pOriDevice)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 }
~CFX_FxgeDevice()1791 CFX_FxgeDevice::~CFX_FxgeDevice() {
1792   if (m_bOwnedBitmap) {
1793     delete GetBitmap();
1794   }
1795 }
1796