summaryrefslogtreecommitdiff
path: root/core/fpdfapi/render
diff options
context:
space:
mode:
Diffstat (limited to 'core/fpdfapi/render')
-rw-r--r--core/fpdfapi/render/cpdf_imagerenderer.cpp201
-rw-r--r--core/fpdfapi/render/cpdf_imagerenderer.h13
-rw-r--r--core/fpdfapi/render/cpdf_renderstatus.cpp11
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,