Index: core/fpdfapi/render/cpdf_imagerenderer.cpp |
diff --git a/core/fpdfapi/render/cpdf_imagerenderer.cpp b/core/fpdfapi/render/cpdf_imagerenderer.cpp |
index 6d951a8d39ef988594597a1015342aaf1e6dd721..8a15f0bb624318ad66e19f273a0006eb006668ba 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,75 @@ bool CPDF_ImageRenderer::Start(CPDF_RenderStatus* pStatus, |
return StartDIBSource(); |
} |
-bool CPDF_ImageRenderer::DrawPatternImage(const CFX_Matrix* pObj2Device) { |
- if (m_pRenderStatus->m_bPrint && |
- !(m_pRenderStatus->m_pDevice->GetRenderCaps() & FXRC_BLEND_MODE)) { |
+bool CPDF_ImageRenderer::NotDrawing() { |
+ bool bRet = m_pRenderStatus->m_bPrint && |
+ !(m_pRenderStatus->m_pDevice->GetRenderCaps() & FXRC_BLEND_MODE); |
+ if (bRet) |
m_Result = false; |
Tom Sepez
2016/11/28 18:42:53
I'd prefer to make this a const method, and make t
npm
2016/11/28 20:51:30
Done.
|
- return false; |
- } |
+ return bRet; |
+} |
+ |
+FX_RECT CPDF_ImageRenderer::GetDrawRect() { |
FX_RECT rect = m_ImageMatrix.GetUnitRect().GetOuterRect(); |
rect.Intersect(m_pRenderStatus->m_pDevice->GetClipBox()); |
- if (rect.IsEmpty()) |
- return false; |
+ return rect; |
+} |
+CFX_Matrix CPDF_ImageRenderer::GetDrawMatrix(const FX_RECT& rect) { |
CFX_Matrix new_matrix = m_ImageMatrix; |
new_matrix.TranslateI(-rect.left, -rect.top); |
- int width = rect.Width(); |
- int height = rect.Height(); |
+ return new_matrix; |
+} |
+ |
+void CPDF_ImageRenderer::CalculateDrawImage(CFX_FxgeDevice* pBitmapDevice1, |
+ CFX_FxgeDevice* pBitmapDevice2, |
+ const CFX_DIBSource* pDIBSource, |
+ CFX_Matrix* pNewMatrix, |
+ const FX_RECT& rect) { |
+ 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 = |
+ (uint8_t*)pBitmapDevice1->GetBitmap()->GetScanline(row); |
Tom Sepez
2016/11/28 18:42:53
nit: const_cast<uint8_t*>() so that we know that i
npm
2016/11/28 20:51:30
Done.
|
+ 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 (NotDrawing()) |
+ return false; |
+ |
+ FX_RECT rect = GetDrawRect(); |
+ if (rect.IsEmpty()) |
+ return false; |
+ |
+ 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 +320,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 +331,16 @@ 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)) { |
- m_Result = false; |
+ if (NotDrawing()) |
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 +358,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 +367,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 +428,9 @@ 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)) { |
- m_Result = false; |
+ if (NotDrawing()) |
return false; |
- } |
+ |
FX_RECT clip_box = m_pRenderStatus->m_pDevice->GetClipBox(); |
clip_box.Intersect(image_rect); |
m_Status = 2; |
@@ -506,11 +463,8 @@ bool CPDF_ImageRenderer::StartDIBSource() { |
return false; |
} |
} |
- if (m_pRenderStatus->m_bPrint && |
- !(m_pRenderStatus->m_pDevice->GetRenderCaps() & FXRC_BLEND_MODE)) { |
- m_Result = false; |
+ if (NotDrawing()) |
return true; |
- } |
FX_RECT clip_box = m_pRenderStatus->m_pDevice->GetClipBox(); |
FX_RECT dest_rect = clip_box; |
@@ -606,3 +560,7 @@ bool CPDF_ImageRenderer::Continue(IFX_Pause* pPause) { |
} |
return false; |
} |
+ |
+bool CPDF_ImageRenderer::GetResult() { |
Tom Sepez
2016/11/28 18:42:53
nit: a one-liner like this can go in the header.
npm
2016/11/28 20:51:30
Done.
|
+ return m_Result; |
+} |