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 "../../../include/fxcodec/fx_codec.h" 9 #include "../../../include/fpdfapi/fpdf_module.h" 10 #include "../../../include/fpdfapi/fpdf_render.h" 11 #include "../../../include/fpdfapi/fpdf_pageobj.h" 12 #include "../../fxcrt/fx_safe_types.h" 13 #include "../fpdf_page/pageint.h" 14 #include "render_int.h" 15 FX_BOOL CPDF_RenderStatus::ProcessImage(CPDF_ImageObject* pImageObj, const CFX_AffineMatrix* pObj2Device) 16 { 17 CPDF_ImageRenderer render; 18 if (render.Start(this, pImageObj, pObj2Device, m_bStdCS, m_curBlend)) { 19 render.Continue(NULL); 20 } 21 return render.m_Result; 22 } 23 void CPDF_RenderStatus::CompositeDIBitmap(CFX_DIBitmap* pDIBitmap, int left, int top, FX_ARGB mask_argb, 24 int bitmap_alpha, int blend_mode, int Transparency) 25 { 26 if (pDIBitmap == NULL) { 27 return; 28 } 29 FX_BOOL bIsolated = Transparency & PDFTRANS_ISOLATED; 30 FX_BOOL bGroup = Transparency & PDFTRANS_GROUP; 31 if (blend_mode == FXDIB_BLEND_NORMAL) { 32 if (!pDIBitmap->IsAlphaMask()) { 33 if (bitmap_alpha < 255) { 34 pDIBitmap->MultiplyAlpha(bitmap_alpha); 35 } 36 if (m_pDevice->SetDIBits(pDIBitmap, left, top)) { 37 return; 38 } 39 } else { 40 FX_DWORD fill_argb = m_Options.TranslateColor(mask_argb); 41 if (bitmap_alpha < 255) { 42 ((FX_BYTE*)&fill_argb)[3] = ((FX_BYTE*)&fill_argb)[3] * bitmap_alpha / 255; 43 } 44 if (m_pDevice->SetBitMask(pDIBitmap, left, top, fill_argb)) { 45 return; 46 } 47 } 48 } 49 FX_BOOL bBackAlphaRequired = blend_mode && bIsolated && !m_bDropObjects; 50 FX_BOOL bGetBackGround = ((m_pDevice->GetRenderCaps() & FXRC_ALPHA_OUTPUT)) || 51 (!(m_pDevice->GetRenderCaps() & FXRC_ALPHA_OUTPUT) && (m_pDevice->GetRenderCaps() 52 & FXRC_GET_BITS) && !bBackAlphaRequired); 53 if (bGetBackGround) { 54 if (bIsolated || !bGroup) { 55 if (pDIBitmap->IsAlphaMask()) { 56 return; 57 } 58 m_pDevice->SetDIBits(pDIBitmap, left, top, blend_mode); 59 } else { 60 FX_RECT rect(left, top, left + pDIBitmap->GetWidth(), top + pDIBitmap->GetHeight()); 61 rect.Intersect(m_pDevice->GetClipBox()); 62 CFX_DIBitmap* pClone = NULL; 63 FX_BOOL bClone = FALSE; 64 if (m_pDevice->GetBackDrop() && m_pDevice->GetBitmap()) { 65 bClone = TRUE; 66 pClone = m_pDevice->GetBackDrop()->Clone(&rect); 67 CFX_DIBitmap *pForeBitmap = m_pDevice->GetBitmap(); 68 pClone->CompositeBitmap(0, 0, pClone->GetWidth(), pClone->GetHeight(), pForeBitmap, rect.left, rect.top); 69 left = left >= 0 ? 0 : left; 70 top = top >= 0 ? 0 : top; 71 if (!pDIBitmap->IsAlphaMask()) 72 pClone->CompositeBitmap(0, 0, pClone->GetWidth(), pClone->GetHeight(), pDIBitmap, 73 left, top, blend_mode); 74 else 75 pClone->CompositeMask(0, 0, pClone->GetWidth(), pClone->GetHeight(), pDIBitmap, 76 mask_argb, left, top, blend_mode); 77 } else { 78 pClone = pDIBitmap; 79 } 80 if (m_pDevice->GetBackDrop()) { 81 m_pDevice->SetDIBits(pClone, rect.left, rect.top); 82 } else { 83 if (pDIBitmap->IsAlphaMask()) { 84 return; 85 } 86 m_pDevice->SetDIBits(pDIBitmap, rect.left, rect.top, blend_mode); 87 } 88 if (bClone) { 89 delete pClone; 90 } 91 } 92 return; 93 } 94 int back_left, back_top; 95 FX_RECT rect(left, top, left + pDIBitmap->GetWidth(), top + pDIBitmap->GetHeight()); 96 CFX_DIBitmap* pBackdrop = GetBackdrop(m_pCurObj, rect, back_left, back_top, blend_mode > FXDIB_BLEND_NORMAL && bIsolated); 97 if (!pBackdrop) { 98 return; 99 } 100 if (!pDIBitmap->IsAlphaMask()) 101 pBackdrop->CompositeBitmap(left - back_left, top - back_top, pDIBitmap->GetWidth(), pDIBitmap->GetHeight(), pDIBitmap, 102 0, 0, blend_mode); 103 else 104 pBackdrop->CompositeMask(left - back_left, top - back_top, pDIBitmap->GetWidth(), pDIBitmap->GetHeight(), pDIBitmap, 105 mask_argb, 0, 0, blend_mode); 106 CFX_DIBitmap* pBackdrop1 = new CFX_DIBitmap; 107 pBackdrop1->Create(pBackdrop->GetWidth(), pBackdrop->GetHeight(), FXDIB_Rgb32); 108 pBackdrop1->Clear((FX_DWORD) - 1); 109 pBackdrop1->CompositeBitmap(0, 0, pBackdrop->GetWidth(), pBackdrop->GetHeight(), pBackdrop, 0, 0); 110 delete pBackdrop; 111 pBackdrop = pBackdrop1; 112 m_pDevice->SetDIBits(pBackdrop, back_left, back_top); 113 delete pBackdrop; 114 } 115 FX_COLORREF CPDF_TransferFunc::TranslateColor(FX_COLORREF rgb) 116 { 117 return FXSYS_RGB(m_Samples[FXSYS_GetRValue(rgb)], m_Samples[256 + FXSYS_GetGValue(rgb)], 118 m_Samples[512 + FXSYS_GetBValue(rgb)]); 119 } 120 CFX_DIBSource* CPDF_TransferFunc::TranslateImage(const CFX_DIBSource* pSrc, FX_BOOL bAutoDropSrc) 121 { 122 CPDF_DIBTransferFunc* pDest = new CPDF_DIBTransferFunc(this); 123 pDest->LoadSrc(pSrc, bAutoDropSrc); 124 return pDest; 125 } 126 FXDIB_Format CPDF_DIBTransferFunc::GetDestFormat() 127 { 128 if (m_pSrc->IsAlphaMask()) { 129 return FXDIB_8bppMask; 130 } 131 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ 132 return (m_pSrc->HasAlpha()) ? FXDIB_Argb : FXDIB_Rgb32; 133 #else 134 return (m_pSrc->HasAlpha()) ? FXDIB_Argb : FXDIB_Rgb; 135 #endif 136 } 137 CPDF_DIBTransferFunc::CPDF_DIBTransferFunc(const CPDF_TransferFunc* pTransferFunc) 138 { 139 m_RampR = pTransferFunc->m_Samples; 140 m_RampG = &pTransferFunc->m_Samples[256]; 141 m_RampB = &pTransferFunc->m_Samples[512]; 142 } 143 void CPDF_DIBTransferFunc::TranslateScanline(FX_LPBYTE dest_buf, FX_LPCBYTE src_buf) const 144 { 145 int i; 146 FX_BOOL bSkip = FALSE; 147 switch (m_pSrc->GetFormat()) { 148 case FXDIB_1bppRgb: { 149 int r0 = m_RampR[0], g0 = m_RampG[0], b0 = m_RampB[0]; 150 int r1 = m_RampR[255], g1 = m_RampG[255], b1 = m_RampB[255]; 151 for (i = 0; i < m_Width; i ++) { 152 if (src_buf[i / 8] & (1 << (7 - i % 8))) { 153 *dest_buf++ = b1; 154 *dest_buf++ = g1; 155 *dest_buf++ = r1; 156 } else { 157 *dest_buf++ = b0; 158 *dest_buf++ = g0; 159 *dest_buf++ = r0; 160 } 161 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ 162 dest_buf++; 163 #endif 164 } 165 break; 166 } 167 case FXDIB_1bppMask: { 168 int m0 = m_RampR[0], m1 = m_RampR[255]; 169 for (i = 0; i < m_Width; i ++) { 170 if (src_buf[i / 8] & (1 << (7 - i % 8))) { 171 *dest_buf++ = m1; 172 } else { 173 *dest_buf++ = m0; 174 } 175 } 176 break; 177 } 178 case FXDIB_8bppRgb: { 179 FX_ARGB* pPal = m_pSrc->GetPalette(); 180 for (i = 0; i < m_Width; i ++) { 181 if (pPal) { 182 FX_ARGB src_argb = pPal[*src_buf]; 183 *dest_buf++ = m_RampB[FXARGB_R(src_argb)]; 184 *dest_buf++ = m_RampG[FXARGB_G(src_argb)]; 185 *dest_buf++ = m_RampR[FXARGB_B(src_argb)]; 186 } else { 187 FX_DWORD src_byte = *src_buf; 188 *dest_buf++ = m_RampB[src_byte]; 189 *dest_buf++ = m_RampG[src_byte]; 190 *dest_buf++ = m_RampR[src_byte]; 191 } 192 src_buf ++; 193 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ 194 dest_buf++; 195 #endif 196 } 197 break; 198 } 199 case FXDIB_8bppMask: 200 for (i = 0; i < m_Width; i ++) { 201 *dest_buf++ = m_RampR[*(src_buf++)]; 202 } 203 break; 204 case FXDIB_Rgb: 205 for (i = 0; i < m_Width; i ++) { 206 *dest_buf++ = m_RampB[*(src_buf++)]; 207 *dest_buf++ = m_RampG[*(src_buf++)]; 208 *dest_buf++ = m_RampR[*(src_buf++)]; 209 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ 210 dest_buf++; 211 #endif 212 } 213 break; 214 case FXDIB_Rgb32: 215 bSkip = TRUE; 216 case FXDIB_Argb: 217 for (i = 0; i < m_Width; i ++) { 218 *dest_buf++ = m_RampB[*(src_buf++)]; 219 *dest_buf++ = m_RampG[*(src_buf++)]; 220 *dest_buf++ = m_RampR[*(src_buf++)]; 221 if (!bSkip) { 222 *dest_buf++ = *src_buf; 223 } 224 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ 225 else { 226 dest_buf++; 227 } 228 #endif 229 src_buf ++; 230 } 231 break; 232 default: 233 break; 234 } 235 } 236 void CPDF_DIBTransferFunc::TranslateDownSamples(FX_LPBYTE dest_buf, FX_LPCBYTE src_buf, int pixels, int Bpp) const 237 { 238 if (Bpp == 8) { 239 for (int i = 0; i < pixels; i ++) { 240 *dest_buf++ = m_RampR[*(src_buf++)]; 241 } 242 } else if (Bpp == 24) { 243 for (int i = 0; i < pixels; i ++) { 244 *dest_buf++ = m_RampB[*(src_buf++)]; 245 *dest_buf++ = m_RampG[*(src_buf++)]; 246 *dest_buf++ = m_RampR[*(src_buf++)]; 247 } 248 } else { 249 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ 250 if (!m_pSrc->HasAlpha()) { 251 for (int i = 0; i < pixels; i ++) { 252 *dest_buf++ = m_RampB[*(src_buf++)]; 253 *dest_buf++ = m_RampG[*(src_buf++)]; 254 *dest_buf++ = m_RampR[*(src_buf++)]; 255 dest_buf++; 256 src_buf++; 257 } 258 } else 259 #endif 260 for (int i = 0; i < pixels; i ++) { 261 *dest_buf++ = m_RampB[*(src_buf++)]; 262 *dest_buf++ = m_RampG[*(src_buf++)]; 263 *dest_buf++ = m_RampR[*(src_buf++)]; 264 *dest_buf++ = *(src_buf++); 265 } 266 } 267 } 268 static FX_BOOL _IsSupported(CPDF_ColorSpace* pCS) 269 { 270 if (pCS->GetFamily() == PDFCS_DEVICERGB || pCS->GetFamily() == PDFCS_DEVICEGRAY || 271 pCS->GetFamily() == PDFCS_DEVICECMYK || pCS->GetFamily() == PDFCS_CALGRAY || 272 pCS->GetFamily() == PDFCS_CALRGB) { 273 return TRUE; 274 } 275 if (pCS->GetFamily() == PDFCS_INDEXED && _IsSupported(pCS->GetBaseCS())) { 276 return TRUE; 277 } 278 return FALSE; 279 } 280 CPDF_ImageRenderer::CPDF_ImageRenderer() 281 { 282 m_pRenderStatus = NULL; 283 m_pImageObject = NULL; 284 m_Result = TRUE; 285 m_Status = 0; 286 m_pQuickStretcher = NULL; 287 m_pTransformer = NULL; 288 m_DeviceHandle = NULL; 289 m_LoadHandle = NULL; 290 m_pClone = NULL; 291 m_bStdCS = FALSE; 292 m_bPatternColor = FALSE; 293 m_BlendType = FXDIB_BLEND_NORMAL; 294 m_pPattern = NULL; 295 m_pObj2Device = NULL; 296 } 297 CPDF_ImageRenderer::~CPDF_ImageRenderer() 298 { 299 if (m_pQuickStretcher) { 300 delete m_pQuickStretcher; 301 } 302 if (m_pTransformer) { 303 delete m_pTransformer; 304 } 305 if (m_DeviceHandle) { 306 m_pRenderStatus->m_pDevice->CancelDIBits(m_DeviceHandle); 307 } 308 if (m_LoadHandle) { 309 delete (CPDF_ProgressiveImageLoaderHandle*)m_LoadHandle; 310 } 311 if (m_pClone) { 312 delete m_pClone; 313 } 314 } 315 FX_BOOL CPDF_ImageRenderer::StartLoadDIBSource() 316 { 317 CFX_FloatRect image_rect_f = m_ImageMatrix.GetUnitRect(); 318 FX_RECT image_rect = image_rect_f.GetOutterRect(); 319 int dest_width = image_rect.Width(); 320 int dest_height = image_rect.Height(); 321 if (m_ImageMatrix.a < 0) { 322 dest_width = -dest_width; 323 } 324 if (m_ImageMatrix.d > 0) { 325 dest_height = -dest_height; 326 } 327 if (m_Loader.StartLoadImage(m_pImageObject, m_pRenderStatus->m_pContext->m_pPageCache, m_LoadHandle, m_bStdCS, 328 m_pRenderStatus->m_GroupFamily, m_pRenderStatus->m_bLoadMask, m_pRenderStatus, dest_width, dest_height)) { 329 if (m_LoadHandle != NULL) { 330 m_Status = 4; 331 return TRUE; 332 } 333 return FALSE; 334 } 335 return FALSE; 336 } 337 FX_BOOL CPDF_ImageRenderer::StartRenderDIBSource() 338 { 339 if (m_Loader.m_pBitmap == NULL) { 340 return FALSE; 341 } 342 m_BitmapAlpha = 255; 343 const CPDF_GeneralStateData* pGeneralState = m_pImageObject->m_GeneralState; 344 if (pGeneralState) { 345 m_BitmapAlpha = FXSYS_round(pGeneralState->m_FillAlpha * 255); 346 } 347 m_pDIBSource = m_Loader.m_pBitmap; 348 if (m_pRenderStatus->m_Options.m_ColorMode == RENDER_COLOR_ALPHA && m_Loader.m_pMask == NULL) { 349 return StartBitmapAlpha(); 350 } 351 if (pGeneralState && pGeneralState->m_pTR) { 352 if (!pGeneralState->m_pTransferFunc) { 353 ((CPDF_GeneralStateData*)pGeneralState)->m_pTransferFunc = m_pRenderStatus->GetTransferFunc(pGeneralState->m_pTR); 354 } 355 if (pGeneralState->m_pTransferFunc && !pGeneralState->m_pTransferFunc->m_bIdentity) { 356 m_pDIBSource = m_Loader.m_pBitmap = pGeneralState->m_pTransferFunc->TranslateImage(m_Loader.m_pBitmap, !m_Loader.m_bCached); 357 if (m_Loader.m_bCached && m_Loader.m_pMask) { 358 m_Loader.m_pMask = m_Loader.m_pMask->Clone(); 359 } 360 m_Loader.m_bCached = FALSE; 361 } 362 } 363 m_FillArgb = 0; 364 m_bPatternColor = FALSE; 365 m_pPattern = NULL; 366 if (m_pDIBSource->IsAlphaMask()) { 367 CPDF_Color* pColor = m_pImageObject->m_ColorState.GetFillColor(); 368 if (pColor && pColor->IsPattern()) { 369 m_pPattern = pColor->GetPattern(); 370 if (m_pPattern != NULL) { 371 m_bPatternColor = TRUE; 372 } 373 } 374 m_FillArgb = m_pRenderStatus->GetFillArgb(m_pImageObject); 375 } else if (m_pRenderStatus->m_Options.m_ColorMode == RENDER_COLOR_GRAY) { 376 m_pClone = m_pDIBSource->Clone(); 377 m_pClone->ConvertColorScale(m_pRenderStatus->m_Options.m_BackColor, m_pRenderStatus->m_Options.m_ForeColor); 378 m_pDIBSource = m_pClone; 379 } 380 m_Flags = 0; 381 if (m_pRenderStatus->m_Options.m_Flags & RENDER_FORCE_DOWNSAMPLE) { 382 m_Flags |= RENDER_FORCE_DOWNSAMPLE; 383 } else if (m_pRenderStatus->m_Options.m_Flags & RENDER_FORCE_HALFTONE) { 384 m_Flags |= RENDER_FORCE_HALFTONE; 385 } 386 if (m_pRenderStatus->m_pDevice->GetDeviceClass() != FXDC_DISPLAY) { 387 CPDF_Object* pFilters = m_pImageObject->m_pImage->GetStream()->GetDict()->GetElementValue(FX_BSTRC("Filter")); 388 if (pFilters) { 389 if (pFilters->GetType() == PDFOBJ_NAME) { 390 CFX_ByteStringC bsDecodeType = pFilters->GetConstString(); 391 if (bsDecodeType == FX_BSTRC("DCTDecode") || bsDecodeType == FX_BSTRC("JPXDecode")) { 392 m_Flags |= FXRENDER_IMAGE_LOSSY; 393 } 394 } else if (pFilters->GetType() == PDFOBJ_ARRAY) { 395 CPDF_Array* pArray = (CPDF_Array*)pFilters; 396 for (FX_DWORD i = 0; i < pArray->GetCount(); i ++) { 397 CFX_ByteStringC bsDecodeType = pArray->GetConstString(i); 398 if (bsDecodeType == FX_BSTRC("DCTDecode") || bsDecodeType == FX_BSTRC("JPXDecode")) { 399 m_Flags |= FXRENDER_IMAGE_LOSSY; 400 break; 401 } 402 } 403 } 404 } 405 } 406 if (m_pRenderStatus->m_Options.m_Flags & RENDER_NOIMAGESMOOTH) { 407 m_Flags |= FXDIB_NOSMOOTH; 408 } else if (m_pImageObject->m_pImage->IsInterpol()) { 409 m_Flags |= FXDIB_INTERPOL; 410 } 411 if (m_Loader.m_pMask) { 412 return DrawMaskedImage(); 413 } 414 if (m_bPatternColor) { 415 return DrawPatternImage(m_pObj2Device); 416 } 417 if (m_BitmapAlpha == 255 && pGeneralState && pGeneralState->m_FillOP && 418 pGeneralState->m_OPMode == 0 && pGeneralState->m_BlendType == FXDIB_BLEND_NORMAL && pGeneralState->m_StrokeAlpha == 1 && pGeneralState->m_FillAlpha == 1) { 419 CPDF_Document* pDocument = NULL; 420 CPDF_Page* pPage = NULL; 421 if (m_pRenderStatus->m_pContext->m_pPageCache) { 422 pPage = m_pRenderStatus->m_pContext->m_pPageCache->GetPage(); 423 pDocument = pPage->m_pDocument; 424 } else { 425 pDocument = m_pImageObject->m_pImage->GetDocument(); 426 } 427 CPDF_Dictionary* pPageResources = pPage ? pPage->m_pPageResources : NULL; 428 CPDF_Object* pCSObj = m_pImageObject->m_pImage->GetStream()->GetDict()->GetElementValue(FX_BSTRC("ColorSpace")); 429 CPDF_ColorSpace* pColorSpace = pDocument->LoadColorSpace(pCSObj, pPageResources); 430 if (pColorSpace) { 431 int format = pColorSpace->GetFamily(); 432 if (format == PDFCS_DEVICECMYK || format == PDFCS_SEPARATION || format == PDFCS_DEVICEN) { 433 m_BlendType = FXDIB_BLEND_DARKEN; 434 } 435 pDocument->GetPageData()->ReleaseColorSpace(pCSObj); 436 } 437 } 438 return StartDIBSource(); 439 } 440 FX_BOOL CPDF_ImageRenderer::Start(CPDF_RenderStatus* pStatus, const CPDF_PageObject* pObj, const CFX_AffineMatrix* pObj2Device, FX_BOOL bStdCS, int blendType) 441 { 442 m_pRenderStatus = pStatus; 443 m_bStdCS = bStdCS; 444 m_pImageObject = (CPDF_ImageObject*)pObj; 445 m_BlendType = blendType; 446 m_pObj2Device = pObj2Device; 447 CPDF_Dictionary* pOC = m_pImageObject->m_pImage->GetOC(); 448 if (pOC && m_pRenderStatus->m_Options.m_pOCContext && !m_pRenderStatus->m_Options.m_pOCContext->CheckOCGVisible(pOC)) { 449 return FALSE; 450 } 451 m_ImageMatrix = m_pImageObject->m_Matrix; 452 m_ImageMatrix.Concat(*pObj2Device); 453 if (StartLoadDIBSource()) { 454 return TRUE; 455 } 456 return StartRenderDIBSource(); 457 } 458 FX_BOOL CPDF_ImageRenderer::Start(CPDF_RenderStatus* pStatus, const CFX_DIBSource* pDIBSource, FX_ARGB bitmap_argb, 459 int bitmap_alpha, const CFX_AffineMatrix* pImage2Device, FX_DWORD flags, FX_BOOL bStdCS, int blendType) 460 { 461 m_pRenderStatus = pStatus; 462 m_pDIBSource = pDIBSource; 463 m_FillArgb = bitmap_argb; 464 m_BitmapAlpha = bitmap_alpha; 465 m_ImageMatrix = *pImage2Device; 466 m_Flags = flags; 467 m_bStdCS = bStdCS; 468 m_BlendType = blendType; 469 return StartDIBSource(); 470 } 471 FX_BOOL CPDF_ImageRenderer::DrawPatternImage(const CFX_Matrix* pObj2Device) 472 { 473 if (m_pRenderStatus->m_bPrint && !(m_pRenderStatus->m_pDevice->GetRenderCaps() & FXRC_BLEND_MODE)) { 474 m_Result = FALSE; 475 return FALSE; 476 } 477 FX_RECT rect = m_ImageMatrix.GetUnitRect().GetOutterRect(); 478 rect.Intersect(m_pRenderStatus->m_pDevice->GetClipBox()); 479 if (rect.IsEmpty()) { 480 return FALSE; 481 } 482 CFX_AffineMatrix new_matrix = m_ImageMatrix; 483 new_matrix.TranslateI(-rect.left, -rect.top); 484 int width = rect.Width(); 485 int height = rect.Height(); 486 CFX_FxgeDevice bitmap_device1; 487 if (!bitmap_device1.Create(rect.Width(), rect.Height(), FXDIB_Rgb32)) { 488 return TRUE; 489 } 490 bitmap_device1.GetBitmap()->Clear(0xffffff); 491 { 492 CPDF_RenderStatus bitmap_render; 493 bitmap_render.Initialize(m_pRenderStatus->m_pContext, &bitmap_device1, NULL, NULL, 494 NULL, NULL, &m_pRenderStatus->m_Options, 0, m_pRenderStatus->m_bDropObjects, NULL, TRUE); 495 CFX_Matrix patternDevice = *pObj2Device; 496 patternDevice.Translate((FX_FLOAT) - rect.left, (FX_FLOAT) - rect.top); 497 if(m_pPattern->m_PatternType == PATTERN_TILING) { 498 bitmap_render.DrawTilingPattern((CPDF_TilingPattern*)m_pPattern, m_pImageObject, &patternDevice, FALSE); 499 } else { 500 bitmap_render.DrawShadingPattern((CPDF_ShadingPattern*)m_pPattern, m_pImageObject, &patternDevice, FALSE); 501 } 502 } 503 { 504 CFX_FxgeDevice bitmap_device2; 505 if (!bitmap_device2.Create(rect.Width(), rect.Height(), FXDIB_8bppRgb)) { 506 return TRUE; 507 } 508 bitmap_device2.GetBitmap()->Clear(0); 509 CPDF_RenderStatus bitmap_render; 510 bitmap_render.Initialize(m_pRenderStatus->m_pContext, &bitmap_device2, NULL, NULL, 511 NULL, NULL, NULL, 0, m_pRenderStatus->m_bDropObjects, NULL, TRUE); 512 CPDF_ImageRenderer image_render; 513 if (image_render.Start(&bitmap_render, m_pDIBSource, 0xffffffff, 255, &new_matrix, m_Flags, TRUE)) { 514 image_render.Continue(NULL); 515 } 516 if (m_Loader.m_MatteColor != 0xffffffff) { 517 int matte_r = FXARGB_R(m_Loader.m_MatteColor); 518 int matte_g = FXARGB_G(m_Loader.m_MatteColor); 519 int matte_b = FXARGB_B(m_Loader.m_MatteColor); 520 for (int row = 0; row < height; row ++) { 521 FX_LPBYTE dest_scan = (FX_LPBYTE)bitmap_device1.GetBitmap()->GetScanline(row); 522 FX_LPCBYTE mask_scan = bitmap_device2.GetBitmap()->GetScanline(row); 523 for (int col = 0; col < width; col ++) { 524 int alpha = *mask_scan ++; 525 if (alpha) { 526 int orig = (*dest_scan - matte_b) * 255 / alpha + matte_b; 527 if (orig < 0) { 528 orig = 0; 529 } else if (orig > 255) { 530 orig = 255; 531 } 532 *dest_scan++ = orig; 533 orig = (*dest_scan - matte_g) * 255 / alpha + matte_g; 534 if (orig < 0) { 535 orig = 0; 536 } else if (orig > 255) { 537 orig = 255; 538 } 539 *dest_scan++ = orig; 540 orig = (*dest_scan - matte_r) * 255 / alpha + matte_r; 541 if (orig < 0) { 542 orig = 0; 543 } else if (orig > 255) { 544 orig = 255; 545 } 546 *dest_scan++ = orig; 547 dest_scan ++; 548 } else { 549 dest_scan += 4; 550 } 551 } 552 } 553 } 554 bitmap_device2.GetBitmap()->ConvertFormat(FXDIB_8bppMask); 555 bitmap_device1.GetBitmap()->MultiplyAlpha(bitmap_device2.GetBitmap()); 556 bitmap_device1.GetBitmap()->MultiplyAlpha(255); 557 } 558 m_pRenderStatus->m_pDevice->SetDIBits(bitmap_device1.GetBitmap(), rect.left, rect.top, m_BlendType); 559 return FALSE; 560 } 561 FX_BOOL CPDF_ImageRenderer::DrawMaskedImage() 562 { 563 if (m_pRenderStatus->m_bPrint && !(m_pRenderStatus->m_pDevice->GetRenderCaps() & FXRC_BLEND_MODE)) { 564 m_Result = FALSE; 565 return FALSE; 566 } 567 FX_RECT rect = m_ImageMatrix.GetUnitRect().GetOutterRect(); 568 rect.Intersect(m_pRenderStatus->m_pDevice->GetClipBox()); 569 if (rect.IsEmpty()) { 570 return FALSE; 571 } 572 CFX_AffineMatrix new_matrix = m_ImageMatrix; 573 new_matrix.TranslateI(-rect.left, -rect.top); 574 int width = rect.Width(); 575 int height = rect.Height(); 576 CFX_FxgeDevice bitmap_device1; 577 if (!bitmap_device1.Create(width, height, FXDIB_Rgb32)) { 578 return TRUE; 579 } 580 bitmap_device1.GetBitmap()->Clear(0xffffff); 581 { 582 CPDF_RenderStatus bitmap_render; 583 bitmap_render.Initialize(m_pRenderStatus->m_pContext, &bitmap_device1, NULL, NULL, 584 NULL, NULL, NULL, 0, m_pRenderStatus->m_bDropObjects, NULL, TRUE); 585 CPDF_ImageRenderer image_render; 586 if (image_render.Start(&bitmap_render, m_pDIBSource, 0, 255, &new_matrix, m_Flags, TRUE)) { 587 image_render.Continue(NULL); 588 } 589 } 590 { 591 CFX_FxgeDevice bitmap_device2; 592 if (!bitmap_device2.Create(width, height, FXDIB_8bppRgb)) { 593 return TRUE; 594 } 595 bitmap_device2.GetBitmap()->Clear(0); 596 CPDF_RenderStatus bitmap_render; 597 bitmap_render.Initialize(m_pRenderStatus->m_pContext, &bitmap_device2, NULL, NULL, 598 NULL, NULL, NULL, 0, m_pRenderStatus->m_bDropObjects, NULL, TRUE); 599 CPDF_ImageRenderer image_render; 600 if (image_render.Start(&bitmap_render, m_Loader.m_pMask, 0xffffffff, 255, &new_matrix, m_Flags, TRUE)) { 601 image_render.Continue(NULL); 602 } 603 if (m_Loader.m_MatteColor != 0xffffffff) { 604 int matte_r = FXARGB_R(m_Loader.m_MatteColor); 605 int matte_g = FXARGB_G(m_Loader.m_MatteColor); 606 int matte_b = FXARGB_B(m_Loader.m_MatteColor); 607 for (int row = 0; row < height; row ++) { 608 FX_LPBYTE dest_scan = (FX_LPBYTE)bitmap_device1.GetBitmap()->GetScanline(row); 609 FX_LPCBYTE mask_scan = bitmap_device2.GetBitmap()->GetScanline(row); 610 for (int col = 0; col < width; col ++) { 611 int alpha = *mask_scan ++; 612 if (alpha) { 613 int orig = (*dest_scan - matte_b) * 255 / alpha + matte_b; 614 if (orig < 0) { 615 orig = 0; 616 } else if (orig > 255) { 617 orig = 255; 618 } 619 *dest_scan++ = orig; 620 orig = (*dest_scan - matte_g) * 255 / alpha + matte_g; 621 if (orig < 0) { 622 orig = 0; 623 } else if (orig > 255) { 624 orig = 255; 625 } 626 *dest_scan++ = orig; 627 orig = (*dest_scan - matte_r) * 255 / alpha + matte_r; 628 if (orig < 0) { 629 orig = 0; 630 } else if (orig > 255) { 631 orig = 255; 632 } 633 *dest_scan++ = orig; 634 dest_scan ++; 635 } else { 636 dest_scan += 4; 637 } 638 } 639 } 640 } 641 bitmap_device2.GetBitmap()->ConvertFormat(FXDIB_8bppMask); 642 bitmap_device1.GetBitmap()->MultiplyAlpha(bitmap_device2.GetBitmap()); 643 if (m_BitmapAlpha < 255) { 644 bitmap_device1.GetBitmap()->MultiplyAlpha(m_BitmapAlpha); 645 } 646 } 647 m_pRenderStatus->m_pDevice->SetDIBits(bitmap_device1.GetBitmap(), rect.left, rect.top, m_BlendType); 648 return FALSE; 649 } 650 FX_BOOL CPDF_ImageRenderer::StartDIBSource() 651 { 652 if (!(m_Flags & RENDER_FORCE_DOWNSAMPLE) && m_pDIBSource->GetBPP() > 1) { 653 int image_size = m_pDIBSource->GetBPP() / 8 * m_pDIBSource->GetWidth() * m_pDIBSource->GetHeight(); 654 if (image_size > FPDF_HUGE_IMAGE_SIZE && !(m_Flags & RENDER_FORCE_HALFTONE)) { 655 m_Flags |= RENDER_FORCE_DOWNSAMPLE; 656 } 657 } 658 if (m_pRenderStatus->m_pDevice->StartDIBits(m_pDIBSource, m_BitmapAlpha, m_FillArgb, 659 &m_ImageMatrix, m_Flags, m_DeviceHandle, 0, NULL, m_BlendType)) { 660 if (m_DeviceHandle != NULL) { 661 m_Status = 3; 662 return TRUE; 663 } 664 return FALSE; 665 } 666 CFX_FloatRect image_rect_f = m_ImageMatrix.GetUnitRect(); 667 FX_RECT image_rect = image_rect_f.GetOutterRect(); 668 int dest_width = image_rect.Width(); 669 int dest_height = image_rect.Height(); 670 if ((FXSYS_fabs(m_ImageMatrix.b) >= 0.5f || m_ImageMatrix.a == 0) || 671 (FXSYS_fabs(m_ImageMatrix.c) >= 0.5f || m_ImageMatrix.d == 0) ) { 672 if (m_pRenderStatus->m_bPrint && !(m_pRenderStatus->m_pDevice->GetRenderCaps() & FXRC_BLEND_MODE)) { 673 m_Result = FALSE; 674 return FALSE; 675 } 676 FX_RECT clip_box = m_pRenderStatus->m_pDevice->GetClipBox(); 677 clip_box.Intersect(image_rect); 678 m_Status = 2; 679 m_pTransformer = new CFX_ImageTransformer; 680 m_pTransformer->Start(m_pDIBSource, &m_ImageMatrix, m_Flags, &clip_box); 681 return TRUE; 682 } 683 if (m_ImageMatrix.a < 0) { 684 dest_width = -dest_width; 685 } 686 if (m_ImageMatrix.d > 0) { 687 dest_height = -dest_height; 688 } 689 int dest_left, dest_top; 690 dest_left = dest_width > 0 ? image_rect.left : image_rect.right; 691 dest_top = dest_height > 0 ? image_rect.top : image_rect.bottom; 692 if (m_pDIBSource->IsOpaqueImage() && m_BitmapAlpha == 255) { 693 if (m_pRenderStatus->m_pDevice->StretchDIBits(m_pDIBSource, dest_left, dest_top, 694 dest_width, dest_height, m_Flags, NULL, m_BlendType)) { 695 return FALSE; 696 } 697 } 698 if (m_pDIBSource->IsAlphaMask()) { 699 if (m_BitmapAlpha != 255) { 700 m_FillArgb = FXARGB_MUL_ALPHA(m_FillArgb, m_BitmapAlpha); 701 } 702 if (m_pRenderStatus->m_pDevice->StretchBitMask(m_pDIBSource, dest_left, dest_top, dest_width, dest_height, m_FillArgb, m_Flags)) { 703 return FALSE; 704 } 705 } 706 if (m_pRenderStatus->m_bPrint && !(m_pRenderStatus->m_pDevice->GetRenderCaps() & FXRC_BLEND_MODE)) { 707 m_Result = FALSE; 708 return TRUE; 709 } 710 FX_RECT clip_box = m_pRenderStatus->m_pDevice->GetClipBox(); 711 FX_RECT dest_rect = clip_box; 712 dest_rect.Intersect(image_rect); 713 FX_RECT dest_clip(dest_rect.left - image_rect.left, dest_rect.top - image_rect.top, 714 dest_rect.right - image_rect.left, dest_rect.bottom - image_rect.top); 715 CFX_DIBitmap* pStretched = m_pDIBSource->StretchTo(dest_width, dest_height, m_Flags, &dest_clip); 716 if (pStretched) { 717 m_pRenderStatus->CompositeDIBitmap(pStretched, dest_rect.left, dest_rect.top, m_FillArgb, 718 m_BitmapAlpha, m_BlendType, FALSE); 719 delete pStretched; 720 pStretched = NULL; 721 } 722 return FALSE; 723 } 724 FX_BOOL CPDF_ImageRenderer::StartBitmapAlpha() 725 { 726 if (m_pDIBSource->IsOpaqueImage()) { 727 CFX_PathData path; 728 path.AppendRect(0, 0, 1, 1); 729 path.Transform(&m_ImageMatrix); 730 FX_DWORD fill_color = ArgbEncode(0xff, m_BitmapAlpha, m_BitmapAlpha, m_BitmapAlpha); 731 m_pRenderStatus->m_pDevice->DrawPath(&path, NULL, NULL, fill_color, 0, FXFILL_WINDING); 732 } else { 733 const CFX_DIBSource* pAlphaMask = m_pDIBSource->IsAlphaMask() ? m_pDIBSource : m_pDIBSource->GetAlphaMask(); 734 if (FXSYS_fabs(m_ImageMatrix.b) >= 0.5f || FXSYS_fabs(m_ImageMatrix.c) >= 0.5f) { 735 int left, top; 736 CFX_DIBitmap* pTransformed = pAlphaMask->TransformTo(&m_ImageMatrix, left, top); 737 if (pTransformed == NULL) { 738 return TRUE; 739 } 740 m_pRenderStatus->m_pDevice->SetBitMask(pTransformed, left, top, ArgbEncode(0xff, m_BitmapAlpha, m_BitmapAlpha, m_BitmapAlpha)); 741 delete pTransformed; 742 } else { 743 CFX_FloatRect image_rect_f = m_ImageMatrix.GetUnitRect(); 744 FX_RECT image_rect = image_rect_f.GetOutterRect(); 745 int dest_width = m_ImageMatrix.a > 0 ? image_rect.Width() : -image_rect.Width(); 746 int dest_height = m_ImageMatrix.d > 0 ? -image_rect.Height() : image_rect.Height(); 747 int left = dest_width > 0 ? image_rect.left : image_rect.right; 748 int top = dest_height > 0 ? image_rect.top : image_rect.bottom; 749 m_pRenderStatus->m_pDevice->StretchBitMask(pAlphaMask, left, top, dest_width, dest_height, 750 ArgbEncode(0xff, m_BitmapAlpha, m_BitmapAlpha, m_BitmapAlpha)); 751 } 752 if (m_pDIBSource != pAlphaMask) { 753 delete pAlphaMask; 754 } 755 } 756 return FALSE; 757 } 758 FX_BOOL CPDF_ImageRenderer::Continue(IFX_Pause* pPause) 759 { 760 if (m_Status == 1) { 761 if (m_pQuickStretcher->Continue(pPause)) { 762 return TRUE; 763 } 764 if (m_pQuickStretcher->m_pBitmap->IsAlphaMask()) 765 m_pRenderStatus->m_pDevice->SetBitMask(m_pQuickStretcher->m_pBitmap, m_pQuickStretcher->m_ResultLeft, 766 m_pQuickStretcher->m_ResultTop, m_FillArgb); 767 else 768 m_pRenderStatus->m_pDevice->SetDIBits(m_pQuickStretcher->m_pBitmap, m_pQuickStretcher->m_ResultLeft, 769 m_pQuickStretcher->m_ResultTop, m_BlendType); 770 return FALSE; 771 } else if (m_Status == 2) { 772 if (m_pTransformer->Continue(pPause)) { 773 return TRUE; 774 } 775 CFX_DIBitmap* pBitmap = m_pTransformer->m_Storer.Detach(); 776 if (pBitmap == NULL) { 777 return FALSE; 778 } 779 if (pBitmap->IsAlphaMask()) { 780 if (m_BitmapAlpha != 255) { 781 m_FillArgb = FXARGB_MUL_ALPHA(m_FillArgb, m_BitmapAlpha); 782 } 783 m_Result = m_pRenderStatus->m_pDevice->SetBitMask(pBitmap, 784 m_pTransformer->m_ResultLeft, m_pTransformer->m_ResultTop, m_FillArgb); 785 } else { 786 if (m_BitmapAlpha != 255) { 787 pBitmap->MultiplyAlpha(m_BitmapAlpha); 788 } 789 m_Result = m_pRenderStatus->m_pDevice->SetDIBits(pBitmap, 790 m_pTransformer->m_ResultLeft, m_pTransformer->m_ResultTop, m_BlendType); 791 } 792 delete pBitmap; 793 return FALSE; 794 } else if (m_Status == 3) { 795 return m_pRenderStatus->m_pDevice->ContinueDIBits(m_DeviceHandle, pPause); 796 } else if (m_Status == 4) { 797 if (m_Loader.Continue(m_LoadHandle, pPause)) { 798 return TRUE; 799 } 800 if (StartRenderDIBSource()) { 801 return Continue(pPause); 802 } 803 return FALSE; 804 } 805 return FALSE; 806 } 807 CPDF_QuickStretcher::CPDF_QuickStretcher() 808 { 809 m_pBitmap = NULL; 810 m_pDecoder = NULL; 811 m_pCS = NULL; 812 } 813 CPDF_QuickStretcher::~CPDF_QuickStretcher() 814 { 815 if (m_pBitmap) { 816 delete m_pBitmap; 817 } 818 if (m_pCS) { 819 m_pCS->ReleaseCS(); 820 } 821 if (m_pDecoder) { 822 delete m_pDecoder; 823 } 824 } 825 ICodec_ScanlineDecoder* FPDFAPI_CreateFlateDecoder(FX_LPCBYTE src_buf, FX_DWORD src_size, int width, int height, 826 int nComps, int bpc, const CPDF_Dictionary* pParams); 827 FX_BOOL CPDF_QuickStretcher::Start(CPDF_ImageObject* pImageObj, CFX_AffineMatrix* pImage2Device, const FX_RECT* pClipBox) 828 { 829 if (FXSYS_fabs(pImage2Device->a) < FXSYS_fabs(pImage2Device->b) * 10 && FXSYS_fabs(pImage2Device->d) < FXSYS_fabs(pImage2Device->c) * 10) { 830 return FALSE; 831 } 832 CFX_FloatRect image_rect_f = pImage2Device->GetUnitRect(); 833 FX_RECT image_rect = image_rect_f.GetOutterRect(); 834 m_DestWidth = image_rect.Width(); 835 m_DestHeight = image_rect.Height(); 836 m_bFlipX = pImage2Device->a < 0; 837 m_bFlipY = pImage2Device->d > 0; 838 FX_RECT result_rect = *pClipBox; 839 result_rect.Intersect(image_rect); 840 if (result_rect.IsEmpty()) { 841 return FALSE; 842 } 843 m_ResultWidth = result_rect.Width(); 844 m_ResultHeight = result_rect.Height(); 845 m_ResultLeft = result_rect.left; 846 m_ResultTop = result_rect.top; 847 m_ClipLeft = result_rect.left - image_rect.left; 848 m_ClipTop = result_rect.top - image_rect.top; 849 CPDF_Dictionary* pDict = pImageObj->m_pImage->GetDict(); 850 if (pDict->GetInteger(FX_BSTRC("BitsPerComponent")) != 8) { 851 return FALSE; 852 } 853 if (pDict->KeyExist(FX_BSTRC("SMask")) || pDict->KeyExist(FX_BSTRC("Mask"))) { 854 return FALSE; 855 } 856 m_SrcWidth = pDict->GetInteger(FX_BSTRC("Width")); 857 m_SrcHeight = pDict->GetInteger(FX_BSTRC("Height")); 858 m_pCS = NULL; 859 m_Bpp = 3; 860 CPDF_Object* pCSObj = pDict->GetElementValue(FX_BSTRC("ColorSpace")); 861 if (pCSObj == NULL) { 862 return FALSE; 863 } 864 m_pCS = CPDF_ColorSpace::Load(pImageObj->m_pImage->GetDocument(), pCSObj); 865 if (m_pCS == NULL) { 866 return FALSE; 867 } 868 if (!_IsSupported(m_pCS)) { 869 return FALSE; 870 } 871 m_Bpp = m_pCS->CountComponents(); 872 if (m_pCS->sRGB()) { 873 m_pCS->ReleaseCS(); 874 m_pCS = NULL; 875 } 876 CPDF_Stream* pStream = pImageObj->m_pImage->GetStream(); 877 m_StreamAcc.LoadAllData(pStream, FALSE, m_SrcWidth * m_SrcHeight * m_Bpp, TRUE); 878 m_pDecoder = NULL; 879 if (!m_StreamAcc.GetImageDecoder().IsEmpty()) { 880 if (m_StreamAcc.GetImageDecoder() == FX_BSTRC("DCTDecode")) { 881 const CPDF_Dictionary* pParam = m_StreamAcc.GetImageParam(); 882 m_pDecoder = CPDF_ModuleMgr::Get()->GetJpegModule()->CreateDecoder( 883 m_StreamAcc.GetData(), m_StreamAcc.GetSize(), m_SrcWidth, m_SrcHeight, m_Bpp, 884 pParam ? pParam->GetInteger(FX_BSTRC("ColorTransform"), 1) : 1); 885 } else if (m_StreamAcc.GetImageDecoder() == FX_BSTRC("FlateDecode")) { 886 m_pDecoder = FPDFAPI_CreateFlateDecoder( 887 m_StreamAcc.GetData(), m_StreamAcc.GetSize(), m_SrcWidth, m_SrcHeight, m_Bpp, 8, 888 m_StreamAcc.GetImageParam()); 889 } else { 890 return FALSE; 891 } 892 m_pDecoder->DownScale(m_DestWidth, m_DestHeight); 893 } 894 m_pBitmap = new CFX_DIBitmap; 895 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ 896 m_pBitmap->Create(m_ResultWidth, m_ResultHeight, FXDIB_Rgb32); 897 #else 898 m_pBitmap->Create(m_ResultWidth, m_ResultHeight, FXDIB_Rgb); 899 #endif 900 m_LineIndex = 0; 901 return TRUE; 902 } 903 FX_BOOL CPDF_QuickStretcher::Continue(IFX_Pause* pPause) 904 { 905 FX_LPBYTE result_buf = m_pBitmap->GetBuffer(); 906 int src_width = m_pDecoder ? m_pDecoder->GetWidth() : m_SrcWidth; 907 int src_height = m_pDecoder ? m_pDecoder->GetHeight() : m_SrcHeight; 908 int src_pitch = src_width * m_Bpp; 909 while (m_LineIndex < m_ResultHeight) { 910 int dest_y, src_y; 911 if (m_bFlipY) { 912 dest_y = m_ResultHeight - m_LineIndex - 1; 913 src_y = (m_DestHeight - (dest_y + m_ClipTop) - 1) * src_height / m_DestHeight; 914 } else { 915 dest_y = m_LineIndex; 916 src_y = (dest_y + m_ClipTop) * src_height / m_DestHeight; 917 } 918 FX_LPCBYTE src_scan; 919 if (m_pDecoder) { 920 src_scan = m_pDecoder->GetScanline(src_y); 921 if (src_scan == NULL) { 922 break; 923 } 924 } else { 925 src_scan = m_StreamAcc.GetData(); 926 if (src_scan == NULL) { 927 break; 928 } 929 src_scan += src_y * src_pitch; 930 } 931 FX_LPBYTE result_scan = result_buf + dest_y * m_pBitmap->GetPitch(); 932 for (int x = 0; x < m_ResultWidth; x ++) { 933 int dest_x = m_ClipLeft + x; 934 int src_x = (m_bFlipX ? (m_DestWidth - dest_x - 1) : dest_x) * src_width / m_DestWidth; 935 FX_LPCBYTE src_pixel = src_scan + src_x * m_Bpp; 936 if (m_pCS == NULL) { 937 *result_scan = src_pixel[2]; 938 result_scan ++; 939 *result_scan = src_pixel[1]; 940 result_scan ++; 941 *result_scan = src_pixel[0]; 942 result_scan ++; 943 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ 944 result_scan ++; 945 #endif 946 } else { 947 m_pCS->TranslateImageLine(result_scan, src_pixel, 1, 0, 0); 948 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ 949 result_scan += 4; 950 #else 951 result_scan += 3; 952 #endif 953 } 954 } 955 m_LineIndex ++; 956 if (pPause && pPause->NeedToPauseNow()) { 957 return TRUE; 958 } 959 } 960 return FALSE; 961 } 962 CFX_DIBitmap* CPDF_RenderStatus::LoadSMask(CPDF_Dictionary* pSMaskDict, 963 FX_RECT* pClipRect, const CFX_AffineMatrix* pMatrix) 964 { 965 if (pSMaskDict == NULL) { 966 return NULL; 967 } 968 CFX_DIBitmap* pMask = NULL; 969 int width = pClipRect->right - pClipRect->left; 970 int height = pClipRect->bottom - pClipRect->top; 971 FX_BOOL bLuminosity = FALSE; 972 bLuminosity = pSMaskDict->GetConstString(FX_BSTRC("S")) != FX_BSTRC("Alpha"); 973 CPDF_Stream* pGroup = pSMaskDict->GetStream(FX_BSTRC("G")); 974 if (pGroup == NULL) { 975 return NULL; 976 } 977 CPDF_Function* pFunc = NULL; 978 CPDF_Object* pFuncObj = pSMaskDict->GetElementValue(FX_BSTRC("TR")); 979 if (pFuncObj && (pFuncObj->GetType() == PDFOBJ_DICTIONARY || pFuncObj->GetType() == PDFOBJ_STREAM)) { 980 pFunc = CPDF_Function::Load(pFuncObj); 981 } 982 CFX_AffineMatrix matrix = *pMatrix; 983 matrix.TranslateI(-pClipRect->left, -pClipRect->top); 984 CPDF_Form form(m_pContext->m_pDocument, m_pContext->m_pPageResources, pGroup); 985 form.ParseContent(NULL, NULL, NULL, NULL); 986 CFX_FxgeDevice bitmap_device; 987 #if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ 988 if (!bitmap_device.Create(width, height, bLuminosity ? FXDIB_Rgb32 : FXDIB_8bppMask)) { 989 return NULL; 990 } 991 #else 992 if (!bitmap_device.Create(width, height, bLuminosity ? FXDIB_Rgb : FXDIB_8bppMask)) { 993 return NULL; 994 } 995 #endif 996 CFX_DIBitmap& bitmap = *bitmap_device.GetBitmap(); 997 CPDF_Object* pCSObj = NULL; 998 CPDF_ColorSpace* pCS = NULL; 999 if (bLuminosity) { 1000 CPDF_Array* pBC = pSMaskDict->GetArray(FX_BSTRC("BC")); 1001 FX_ARGB back_color = 0xff000000; 1002 if (pBC) { 1003 CPDF_Dictionary* pDict = pGroup->GetDict(); 1004 if (pDict && pDict->GetDict(FX_BSTRC("Group"))) 1005 pCSObj = pDict->GetDict(FX_BSTRC("Group"))->GetElementValue(FX_BSTRC("CS")); 1006 else 1007 pCSObj = NULL; 1008 pCS = m_pContext->m_pDocument->LoadColorSpace(pCSObj); 1009 if (pCS) { 1010 FX_FLOAT R, G, B; 1011 FX_DWORD comps = 8; 1012 if (pCS->CountComponents() > static_cast<FX_INT32>(comps)) { 1013 comps = (FX_DWORD)pCS->CountComponents(); 1014 } 1015 CFX_FixedBufGrow<FX_FLOAT, 8> float_array(comps); 1016 FX_FLOAT* pFloats = float_array; 1017 FX_SAFE_DWORD num_floats = comps; 1018 num_floats *= sizeof(FX_FLOAT); 1019 if (!num_floats.IsValid()) { 1020 return NULL; 1021 } 1022 FXSYS_memset32(pFloats, 0, num_floats.ValueOrDie()); 1023 int count = pBC->GetCount() > 8 ? 8 : pBC->GetCount(); 1024 for (int i = 0; i < count; i ++) { 1025 pFloats[i] = pBC->GetNumber(i); 1026 } 1027 pCS->GetRGB(pFloats, R, G, B); 1028 back_color = 0xff000000 | ((FX_INT32)(R * 255) << 16) | ((FX_INT32)(G * 255) << 8) | (FX_INT32)(B * 255); 1029 m_pContext->m_pDocument->GetPageData()->ReleaseColorSpace(pCSObj); 1030 } 1031 } 1032 bitmap.Clear(back_color); 1033 } else { 1034 bitmap.Clear(0); 1035 } 1036 CPDF_Dictionary* pFormResource = NULL; 1037 if (form.m_pFormDict) { 1038 pFormResource = form.m_pFormDict->GetDict(FX_BSTRC("Resources")); 1039 } 1040 CPDF_RenderOptions options; 1041 options.m_ColorMode = bLuminosity ? RENDER_COLOR_NORMAL : RENDER_COLOR_ALPHA; 1042 CPDF_RenderStatus status; 1043 status.Initialize(m_pContext, &bitmap_device, NULL, NULL, NULL, NULL, 1044 &options, 0, m_bDropObjects, pFormResource, TRUE, NULL, 0, pCS ? pCS->GetFamily() : 0, bLuminosity); 1045 status.RenderObjectList(&form, &matrix); 1046 pMask = new CFX_DIBitmap; 1047 if (!pMask->Create(width, height, FXDIB_8bppMask)) { 1048 delete pMask; 1049 return NULL; 1050 } 1051 FX_LPBYTE dest_buf = pMask->GetBuffer(); 1052 int dest_pitch = pMask->GetPitch(); 1053 FX_LPBYTE src_buf = bitmap.GetBuffer(); 1054 int src_pitch = bitmap.GetPitch(); 1055 FX_LPBYTE pTransfer = FX_Alloc(FX_BYTE, 256); 1056 if (pFunc) { 1057 CFX_FixedBufGrow<FX_FLOAT, 16> results(pFunc->CountOutputs()); 1058 for (int i = 0; i < 256; i ++) { 1059 FX_FLOAT input = (FX_FLOAT)i / 255.0f; 1060 int nresult; 1061 pFunc->Call(&input, 1, results, nresult); 1062 pTransfer[i] = FXSYS_round(results[0] * 255); 1063 } 1064 } else { 1065 for (int i = 0; i < 256; i ++) { 1066 pTransfer[i] = i; 1067 } 1068 } 1069 if (bLuminosity) { 1070 int Bpp = bitmap.GetBPP() / 8; 1071 for (int row = 0; row < height; row ++) { 1072 FX_LPBYTE dest_pos = dest_buf + row * dest_pitch; 1073 FX_LPBYTE src_pos = src_buf + row * src_pitch; 1074 for (int col = 0; col < width; col ++) { 1075 *dest_pos ++ = pTransfer[FXRGB2GRAY(src_pos[2], src_pos[1], *src_pos)]; 1076 src_pos += Bpp; 1077 } 1078 } 1079 } else if (pFunc) { 1080 int size = dest_pitch * height; 1081 for (int i = 0; i < size; i ++) { 1082 dest_buf[i] = pTransfer[src_buf[i]]; 1083 } 1084 } else { 1085 FXSYS_memcpy32(dest_buf, src_buf, dest_pitch * height); 1086 } 1087 if (pFunc) { 1088 delete pFunc; 1089 } 1090 FX_Free(pTransfer); 1091 return pMask; 1092 } 1093