diff options
Diffstat (limited to 'core/fpdfapi/render')
-rw-r--r-- | core/fpdfapi/render/cpdf_imagerenderer.cpp | 201 | ||||
-rw-r--r-- | core/fpdfapi/render/cpdf_imagerenderer.h | 13 | ||||
-rw-r--r-- | core/fpdfapi/render/cpdf_renderstatus.cpp | 11 |
3 files changed, 96 insertions, 129 deletions
diff --git a/core/fpdfapi/render/cpdf_imagerenderer.cpp b/core/fpdfapi/render/cpdf_imagerenderer.cpp index 6d951a8d39..bdcd2b3c65 100644 --- a/core/fpdfapi/render/cpdf_imagerenderer.cpp +++ b/core/fpdfapi/render/cpdf_imagerenderer.cpp @@ -6,6 +6,7 @@ #include "core/fpdfapi/render/cpdf_imagerenderer.h" +#include <algorithm> #include <memory> #include "core/fpdfapi/page/cpdf_docpagedata.h" @@ -56,12 +57,10 @@ bool CPDF_ImageRenderer::StartLoadDIBSource() { if (!image_rect.Valid()) return false; - int dest_width = image_rect.Width(); - int dest_height = image_rect.Height(); - if (m_ImageMatrix.a < 0) - dest_width = -dest_width; - if (m_ImageMatrix.d > 0) - dest_height = -dest_height; + int dest_width = + m_ImageMatrix.a >= 0 ? image_rect.Width() : -image_rect.Width(); + int dest_height = + m_ImageMatrix.d <= 0 ? image_rect.Height() : -image_rect.Height(); if (m_Loader.Start( m_pImageObject, m_pRenderStatus->m_pContext->GetPageCache(), m_bStdCS, m_pRenderStatus->m_GroupFamily, m_pRenderStatus->m_bLoadMask, @@ -225,21 +224,74 @@ bool CPDF_ImageRenderer::Start(CPDF_RenderStatus* pStatus, return StartDIBSource(); } +bool CPDF_ImageRenderer::NotDrawing() const { + return m_pRenderStatus->m_bPrint && + !(m_pRenderStatus->m_pDevice->GetRenderCaps() & FXRC_BLEND_MODE); +} + +FX_RECT CPDF_ImageRenderer::GetDrawRect() const { + FX_RECT rect = m_ImageMatrix.GetUnitRect().GetOuterRect(); + rect.Intersect(m_pRenderStatus->m_pDevice->GetClipBox()); + return rect; +} + +CFX_Matrix CPDF_ImageRenderer::GetDrawMatrix(const FX_RECT& rect) const { + CFX_Matrix new_matrix = m_ImageMatrix; + new_matrix.TranslateI(-rect.left, -rect.top); + return new_matrix; +} + +void CPDF_ImageRenderer::CalculateDrawImage(CFX_FxgeDevice* pBitmapDevice1, + CFX_FxgeDevice* pBitmapDevice2, + const CFX_DIBSource* pDIBSource, + CFX_Matrix* pNewMatrix, + const FX_RECT& rect) const { + CPDF_RenderStatus bitmap_render; + bitmap_render.Initialize(m_pRenderStatus->m_pContext, pBitmapDevice2, nullptr, + nullptr, nullptr, nullptr, nullptr, 0, + m_pRenderStatus->m_bDropObjects, nullptr, true); + CPDF_ImageRenderer image_render; + if (image_render.Start(&bitmap_render, pDIBSource, 0xffffffff, 255, + pNewMatrix, m_Flags, true, FXDIB_BLEND_NORMAL)) { + image_render.Continue(nullptr); + } + if (m_Loader.m_MatteColor == 0xffffffff) + return; + int matte_r = FXARGB_R(m_Loader.m_MatteColor); + int matte_g = FXARGB_G(m_Loader.m_MatteColor); + int matte_b = FXARGB_B(m_Loader.m_MatteColor); + for (int row = 0; row < rect.Height(); row++) { + uint8_t* dest_scan = + const_cast<uint8_t*>(pBitmapDevice1->GetBitmap()->GetScanline(row)); + const uint8_t* mask_scan = pBitmapDevice2->GetBitmap()->GetScanline(row); + for (int col = 0; col < rect.Width(); col++) { + int alpha = *mask_scan++; + if (!alpha) { + dest_scan += 4; + continue; + } + int orig = (*dest_scan - matte_b) * 255 / alpha + matte_b; + *dest_scan++ = std::min(std::max(orig, 0), 255); + orig = (*dest_scan - matte_g) * 255 / alpha + matte_g; + *dest_scan++ = std::min(std::max(orig, 0), 255); + orig = (*dest_scan - matte_r) * 255 / alpha + matte_r; + *dest_scan++ = std::min(std::max(orig, 0), 255); + dest_scan++; + } + } +} + bool CPDF_ImageRenderer::DrawPatternImage(const CFX_Matrix* pObj2Device) { - if (m_pRenderStatus->m_bPrint && - !(m_pRenderStatus->m_pDevice->GetRenderCaps() & FXRC_BLEND_MODE)) { + if (NotDrawing()) { m_Result = false; return false; } - FX_RECT rect = m_ImageMatrix.GetUnitRect().GetOuterRect(); - rect.Intersect(m_pRenderStatus->m_pDevice->GetClipBox()); + + FX_RECT rect = GetDrawRect(); if (rect.IsEmpty()) return false; - CFX_Matrix new_matrix = m_ImageMatrix; - new_matrix.TranslateI(-rect.left, -rect.top); - int width = rect.Width(); - int height = rect.Height(); + CFX_Matrix new_matrix = GetDrawMatrix(rect); CFX_FxgeDevice bitmap_device1; if (!bitmap_device1.Create(rect.Width(), rect.Height(), FXDIB_Rgb32, nullptr)) return true; @@ -267,51 +319,8 @@ bool CPDF_ImageRenderer::DrawPatternImage(const CFX_Matrix* pObj2Device) { return true; } bitmap_device2.GetBitmap()->Clear(0); - CPDF_RenderStatus bitmap_render2; - bitmap_render2.Initialize(m_pRenderStatus->m_pContext, &bitmap_device2, - nullptr, nullptr, nullptr, nullptr, nullptr, 0, - m_pRenderStatus->m_bDropObjects, nullptr, true); - CPDF_ImageRenderer image_render; - if (image_render.Start(&bitmap_render2, m_pDIBSource, 0xffffffff, 255, - &new_matrix, m_Flags, true, FXDIB_BLEND_NORMAL)) { - image_render.Continue(nullptr); - } - if (m_Loader.m_MatteColor != 0xffffffff) { - int matte_r = FXARGB_R(m_Loader.m_MatteColor); - int matte_g = FXARGB_G(m_Loader.m_MatteColor); - int matte_b = FXARGB_B(m_Loader.m_MatteColor); - for (int row = 0; row < height; row++) { - uint8_t* dest_scan = - (uint8_t*)bitmap_device1.GetBitmap()->GetScanline(row); - const uint8_t* mask_scan = bitmap_device2.GetBitmap()->GetScanline(row); - for (int col = 0; col < width; col++) { - int alpha = *mask_scan++; - if (!alpha) { - dest_scan += 4; - continue; - } - int orig = (*dest_scan - matte_b) * 255 / alpha + matte_b; - if (orig < 0) - orig = 0; - else if (orig > 255) - orig = 255; - *dest_scan++ = orig; - orig = (*dest_scan - matte_g) * 255 / alpha + matte_g; - if (orig < 0) - orig = 0; - else if (orig > 255) - orig = 255; - *dest_scan++ = orig; - orig = (*dest_scan - matte_r) * 255 / alpha + matte_r; - if (orig < 0) - orig = 0; - else if (orig > 255) - orig = 255; - *dest_scan++ = orig; - dest_scan++; - } - } - } + CalculateDrawImage(&bitmap_device1, &bitmap_device2, m_pDIBSource, + &new_matrix, rect); bitmap_device2.GetBitmap()->ConvertFormat(FXDIB_8bppMask); bitmap_device1.GetBitmap()->MultiplyAlpha(bitmap_device2.GetBitmap()); bitmap_device1.GetBitmap()->MultiplyAlpha(255); @@ -321,22 +330,18 @@ bool CPDF_ImageRenderer::DrawPatternImage(const CFX_Matrix* pObj2Device) { } bool CPDF_ImageRenderer::DrawMaskedImage() { - if (m_pRenderStatus->m_bPrint && - !(m_pRenderStatus->m_pDevice->GetRenderCaps() & FXRC_BLEND_MODE)) { + if (NotDrawing()) { m_Result = false; return false; } - FX_RECT rect = m_ImageMatrix.GetUnitRect().GetOuterRect(); - rect.Intersect(m_pRenderStatus->m_pDevice->GetClipBox()); + + FX_RECT rect = GetDrawRect(); if (rect.IsEmpty()) return false; - CFX_Matrix new_matrix = m_ImageMatrix; - new_matrix.TranslateI(-rect.left, -rect.top); - int width = rect.Width(); - int height = rect.Height(); + CFX_Matrix new_matrix = GetDrawMatrix(rect); CFX_FxgeDevice bitmap_device1; - if (!bitmap_device1.Create(width, height, FXDIB_Rgb32, nullptr)) + if (!bitmap_device1.Create(rect.Width(), rect.Height(), FXDIB_Rgb32, nullptr)) return true; #if defined _SKIA_SUPPORT_ @@ -354,7 +359,8 @@ bool CPDF_ImageRenderer::DrawMaskedImage() { image_render.Continue(nullptr); } CFX_FxgeDevice bitmap_device2; - if (!bitmap_device2.Create(width, height, FXDIB_8bppRgb, nullptr)) + if (!bitmap_device2.Create(rect.Width(), rect.Height(), FXDIB_8bppRgb, + nullptr)) return true; #if defined _SKIA_SUPPORT_ @@ -362,54 +368,8 @@ bool CPDF_ImageRenderer::DrawMaskedImage() { #else bitmap_device2.GetBitmap()->Clear(0); #endif - CPDF_RenderStatus bitmap_render2; - bitmap_render2.Initialize(m_pRenderStatus->m_pContext, &bitmap_device2, - nullptr, nullptr, nullptr, nullptr, nullptr, 0, - m_pRenderStatus->m_bDropObjects, nullptr, true); - CPDF_ImageRenderer image_render2; - if (image_render2.Start(&bitmap_render2, m_Loader.m_pMask, 0xffffffff, 255, - &new_matrix, m_Flags, true, FXDIB_BLEND_NORMAL)) { - image_render2.Continue(nullptr); - } - if (m_Loader.m_MatteColor != 0xffffffff) { - int matte_r = FXARGB_R(m_Loader.m_MatteColor); - int matte_g = FXARGB_G(m_Loader.m_MatteColor); - int matte_b = FXARGB_B(m_Loader.m_MatteColor); - for (int row = 0; row < height; row++) { - uint8_t* dest_scan = - (uint8_t*)bitmap_device1.GetBitmap()->GetScanline(row); - const uint8_t* mask_scan = bitmap_device2.GetBitmap()->GetScanline(row); - for (int col = 0; col < width; col++) { - int alpha = *mask_scan++; - if (alpha) { - int orig = (*dest_scan - matte_b) * 255 / alpha + matte_b; - if (orig < 0) { - orig = 0; - } else if (orig > 255) { - orig = 255; - } - *dest_scan++ = orig; - orig = (*dest_scan - matte_g) * 255 / alpha + matte_g; - if (orig < 0) { - orig = 0; - } else if (orig > 255) { - orig = 255; - } - *dest_scan++ = orig; - orig = (*dest_scan - matte_r) * 255 / alpha + matte_r; - if (orig < 0) { - orig = 0; - } else if (orig > 255) { - orig = 255; - } - *dest_scan++ = orig; - dest_scan++; - } else { - dest_scan += 4; - } - } - } - } + CalculateDrawImage(&bitmap_device1, &bitmap_device2, m_Loader.m_pMask, + &new_matrix, rect); #ifdef _SKIA_SUPPORT_ m_pRenderStatus->m_pDevice->SetBitsWithMask( bitmap_device1.GetBitmap(), bitmap_device2.GetBitmap(), rect.left, @@ -469,11 +429,11 @@ bool CPDF_ImageRenderer::StartDIBSource() { int dest_height = image_rect.Height(); if ((FXSYS_fabs(m_ImageMatrix.b) >= 0.5f || m_ImageMatrix.a == 0) || (FXSYS_fabs(m_ImageMatrix.c) >= 0.5f || m_ImageMatrix.d == 0)) { - if (m_pRenderStatus->m_bPrint && - !(m_pRenderStatus->m_pDevice->GetRenderCaps() & FXRC_BLEND_MODE)) { + if (NotDrawing()) { m_Result = false; return false; } + FX_RECT clip_box = m_pRenderStatus->m_pDevice->GetClipBox(); clip_box.Intersect(image_rect); m_Status = 2; @@ -506,8 +466,7 @@ bool CPDF_ImageRenderer::StartDIBSource() { return false; } } - if (m_pRenderStatus->m_bPrint && - !(m_pRenderStatus->m_pDevice->GetRenderCaps() & FXRC_BLEND_MODE)) { + if (NotDrawing()) { m_Result = false; return true; } diff --git a/core/fpdfapi/render/cpdf_imagerenderer.h b/core/fpdfapi/render/cpdf_imagerenderer.h index b0550e7441..d358716e9f 100644 --- a/core/fpdfapi/render/cpdf_imagerenderer.h +++ b/core/fpdfapi/render/cpdf_imagerenderer.h @@ -11,6 +11,7 @@ #include "core/fpdfapi/render/cpdf_imageloader.h" +class CFX_FxgeDevice; class CFX_ImageTransformer; class CPDF_ImageObject; class CPDF_PageObject; @@ -38,8 +39,7 @@ class CPDF_ImageRenderer { int blendType); bool Continue(IFX_Pause* pPause); - - bool m_Result; + bool GetResult() const { return m_Result; } private: bool StartBitmapAlpha(); @@ -48,6 +48,14 @@ class CPDF_ImageRenderer { bool StartLoadDIBSource(); bool DrawMaskedImage(); bool DrawPatternImage(const CFX_Matrix* pObj2Device); + bool NotDrawing() const; + FX_RECT GetDrawRect() const; + CFX_Matrix GetDrawMatrix(const FX_RECT& rect) const; + void CalculateDrawImage(CFX_FxgeDevice* bitmap_device1, + CFX_FxgeDevice* bitmap_device2, + const CFX_DIBSource* pDIBSource, + CFX_Matrix* pNewMatrix, + const FX_RECT& rect) const; CPDF_RenderStatus* m_pRenderStatus; CPDF_ImageObject* m_pImageObject; @@ -66,6 +74,7 @@ class CPDF_ImageRenderer { void* m_DeviceHandle; bool m_bStdCS; int m_BlendType; + bool m_Result; }; #endif // CORE_FPDFAPI_RENDER_CPDF_IMAGERENDERER_H_ diff --git a/core/fpdfapi/render/cpdf_renderstatus.cpp b/core/fpdfapi/render/cpdf_renderstatus.cpp index e0c1c654ff..efad9db4c4 100644 --- a/core/fpdfapi/render/cpdf_renderstatus.cpp +++ b/core/fpdfapi/render/cpdf_renderstatus.cpp @@ -1058,7 +1058,7 @@ bool CPDF_RenderStatus::ContinueSingleObject(CPDF_PageObject* pObj, if (m_pImageRenderer->Continue(pPause)) return true; - if (!m_pImageRenderer->m_Result) + if (!m_pImageRenderer->GetResult()) DrawObjWithBackground(pObj, pObj2Device); m_pImageRenderer.reset(); return false; @@ -1078,7 +1078,7 @@ bool CPDF_RenderStatus::ContinueSingleObject(CPDF_PageObject* pObj, m_pImageRenderer.reset(new CPDF_ImageRenderer); if (!m_pImageRenderer->Start(this, pObj, pObj2Device, false, FXDIB_BLEND_NORMAL)) { - if (!m_pImageRenderer->m_Result) + if (!m_pImageRenderer->GetResult()) DrawObjWithBackground(pObj, pObj2Device); m_pImageRenderer.reset(); return false; @@ -1900,7 +1900,7 @@ bool CPDF_RenderStatus::ProcessType3Text(CPDF_TextObject* textobj, &image_matrix, 0, false, FXDIB_BLEND_NORMAL)) { renderer.Continue(nullptr); } - if (!renderer.m_Result) + if (!renderer.GetResult()) return false; } } @@ -2375,10 +2375,9 @@ void CPDF_RenderStatus::ProcessPathPattern(CPDF_PathObject* pPathObj, bool CPDF_RenderStatus::ProcessImage(CPDF_ImageObject* pImageObj, const CFX_Matrix* pObj2Device) { CPDF_ImageRenderer render; - if (render.Start(this, pImageObj, pObj2Device, m_bStdCS, m_curBlend)) { + if (render.Start(this, pImageObj, pObj2Device, m_bStdCS, m_curBlend)) render.Continue(nullptr); - } - return render.m_Result; + return render.GetResult(); } void CPDF_RenderStatus::CompositeDIBitmap(CFX_DIBitmap* pDIBitmap, |