summaryrefslogtreecommitdiff
path: root/core/fxge/dib/cfx_imagerenderer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'core/fxge/dib/cfx_imagerenderer.cpp')
-rw-r--r--core/fxge/dib/cfx_imagerenderer.cpp143
1 files changed, 143 insertions, 0 deletions
diff --git a/core/fxge/dib/cfx_imagerenderer.cpp b/core/fxge/dib/cfx_imagerenderer.cpp
new file mode 100644
index 0000000000..9eea474352
--- /dev/null
+++ b/core/fxge/dib/cfx_imagerenderer.cpp
@@ -0,0 +1,143 @@
+// Copyright 2017 PDFium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
+
+#include "core/fxge/dib/cfx_imagerenderer.h"
+
+#include <memory>
+
+#include "core/fxge/dib/cfx_imagetransformer.h"
+#include "core/fxge/dib/dib_int.h"
+#include "core/fxge/ge/cfx_cliprgn.h"
+#include "third_party/base/ptr_util.h"
+
+CFX_ImageRenderer::CFX_ImageRenderer()
+ : m_Status(0),
+ m_pIccTransform(nullptr),
+ m_bRgbByteOrder(false),
+ m_BlendType(FXDIB_BLEND_NORMAL) {}
+
+CFX_ImageRenderer::~CFX_ImageRenderer() {}
+
+bool CFX_ImageRenderer::Start(const CFX_RetainPtr<CFX_DIBitmap>& pDevice,
+ const CFX_ClipRgn* pClipRgn,
+ const CFX_RetainPtr<CFX_DIBSource>& pSource,
+ int bitmap_alpha,
+ uint32_t mask_color,
+ const CFX_Matrix* pMatrix,
+ uint32_t dib_flags,
+ bool bRgbByteOrder,
+ int alpha_flag,
+ void* pIccTransform,
+ int blend_type) {
+ m_Matrix = *pMatrix;
+ CFX_FloatRect image_rect_f = m_Matrix.GetUnitRect();
+ FX_RECT image_rect = image_rect_f.GetOuterRect();
+ m_ClipBox = pClipRgn ? pClipRgn->GetBox() : FX_RECT(0, 0, pDevice->GetWidth(),
+ pDevice->GetHeight());
+ m_ClipBox.Intersect(image_rect);
+ if (m_ClipBox.IsEmpty())
+ return false;
+
+ m_pDevice = pDevice;
+ m_pClipRgn = pClipRgn;
+ m_MaskColor = mask_color;
+ m_BitmapAlpha = bitmap_alpha;
+ m_Matrix = *pMatrix;
+ m_Flags = dib_flags;
+ m_AlphaFlag = alpha_flag;
+ m_pIccTransform = pIccTransform;
+ m_bRgbByteOrder = bRgbByteOrder;
+ m_BlendType = blend_type;
+
+ if ((FXSYS_fabs(m_Matrix.b) >= 0.5f || m_Matrix.a == 0) ||
+ (FXSYS_fabs(m_Matrix.c) >= 0.5f || m_Matrix.d == 0)) {
+ if (FXSYS_fabs(m_Matrix.a) < FXSYS_fabs(m_Matrix.b) / 20 &&
+ FXSYS_fabs(m_Matrix.d) < FXSYS_fabs(m_Matrix.c) / 20 &&
+ FXSYS_fabs(m_Matrix.a) < 0.5f && FXSYS_fabs(m_Matrix.d) < 0.5f) {
+ int dest_width = image_rect.Width();
+ int dest_height = image_rect.Height();
+ FX_RECT bitmap_clip = m_ClipBox;
+ bitmap_clip.Offset(-image_rect.left, -image_rect.top);
+ bitmap_clip = FXDIB_SwapClipBox(bitmap_clip, dest_width, dest_height,
+ m_Matrix.c > 0, m_Matrix.b < 0);
+ m_Composer.Compose(pDevice, pClipRgn, bitmap_alpha, mask_color, m_ClipBox,
+ true, m_Matrix.c > 0, m_Matrix.b < 0, m_bRgbByteOrder,
+ alpha_flag, pIccTransform, m_BlendType);
+ m_Stretcher = pdfium::MakeUnique<CFX_ImageStretcher>(
+ &m_Composer, pSource, dest_height, dest_width, bitmap_clip,
+ dib_flags);
+ if (!m_Stretcher->Start())
+ return false;
+
+ m_Status = 1;
+ return true;
+ }
+ m_Status = 2;
+ m_pTransformer = pdfium::MakeUnique<CFX_ImageTransformer>(
+ pSource, &m_Matrix, dib_flags, &m_ClipBox);
+ m_pTransformer->Start();
+ return true;
+ }
+
+ int dest_width = image_rect.Width();
+ if (m_Matrix.a < 0)
+ dest_width = -dest_width;
+
+ int dest_height = image_rect.Height();
+ if (m_Matrix.d > 0)
+ dest_height = -dest_height;
+
+ if (dest_width == 0 || dest_height == 0)
+ return false;
+
+ FX_RECT bitmap_clip = m_ClipBox;
+ bitmap_clip.Offset(-image_rect.left, -image_rect.top);
+ m_Composer.Compose(pDevice, pClipRgn, bitmap_alpha, mask_color, m_ClipBox,
+ false, false, false, m_bRgbByteOrder, alpha_flag,
+ pIccTransform, m_BlendType);
+ m_Status = 1;
+ m_Stretcher = pdfium::MakeUnique<CFX_ImageStretcher>(
+ &m_Composer, pSource, dest_width, dest_height, bitmap_clip, dib_flags);
+ return m_Stretcher->Start();
+}
+
+bool CFX_ImageRenderer::Continue(IFX_Pause* pPause) {
+ if (m_Status == 1)
+ return m_Stretcher->Continue(pPause);
+
+ if (m_Status != 2)
+ return false;
+
+ if (m_pTransformer->Continue(pPause))
+ return true;
+
+ CFX_RetainPtr<CFX_DIBitmap> pBitmap = m_pTransformer->DetachBitmap();
+ if (!pBitmap || !pBitmap->GetBuffer())
+ return false;
+
+ if (pBitmap->IsAlphaMask()) {
+ if (m_BitmapAlpha != 255) {
+ if (m_AlphaFlag >> 8) {
+ m_AlphaFlag = (((uint8_t)((m_AlphaFlag & 0xff) * m_BitmapAlpha / 255)) |
+ ((m_AlphaFlag >> 8) << 8));
+ } else {
+ m_MaskColor = FXARGB_MUL_ALPHA(m_MaskColor, m_BitmapAlpha);
+ }
+ }
+ m_pDevice->CompositeMask(
+ m_pTransformer->result().left, m_pTransformer->result().top,
+ pBitmap->GetWidth(), pBitmap->GetHeight(), pBitmap, m_MaskColor, 0, 0,
+ m_BlendType, m_pClipRgn, m_bRgbByteOrder, m_AlphaFlag, m_pIccTransform);
+ } else {
+ if (m_BitmapAlpha != 255)
+ pBitmap->MultiplyAlpha(m_BitmapAlpha);
+ m_pDevice->CompositeBitmap(
+ m_pTransformer->result().left, m_pTransformer->result().top,
+ pBitmap->GetWidth(), pBitmap->GetHeight(), pBitmap, 0, 0, m_BlendType,
+ m_pClipRgn, m_bRgbByteOrder, m_pIccTransform);
+ }
+ return false;
+}