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