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" 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 } 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; 79 renderer_scanline_aa_offset(base_ren_type& ren, unsigned left, unsigned top) : 80 m_ren(&ren), m_left(left), m_top(top) 81 {} 82 void color(const color_type& c) 83 { 84 m_color = c; 85 } 86 const color_type& color() const 87 { 88 return m_color; 89 } 90 void prepare(unsigned) {} 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 } 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 } 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 } 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 } 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_)) 218 void CFX_AggDeviceDriver::InitPlatform() 219 { 220 } 221 void CFX_AggDeviceDriver::DestroyPlatform() 222 { 223 } 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 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 } 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 } 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 } 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 } 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 } 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: 390 void prepare(unsigned) {} 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 } 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 } 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 } 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 } 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 } 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 } 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 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 }; 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 1585 void CFX_AggDeviceDriver::CancelDIBits(FX_LPVOID pHandle) 1586 { 1587 if (m_pBitmap->GetBuffer() == NULL) { 1588 return; 1589 } 1590 delete (CFX_ImageRenderer*)pHandle; 1591 } 1592 CFX_FxgeDevice::CFX_FxgeDevice() 1593 { 1594 m_bOwnedBitmap = FALSE; 1595 } 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 } 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 } 1628 CFX_FxgeDevice::~CFX_FxgeDevice() 1629 { 1630 if (m_bOwnedBitmap && GetBitmap()) { 1631 delete GetBitmap(); 1632 } 1633 } 1634