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