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