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