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