Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
cfx_imagerenderer.cpp
Go to the documentation of this file.
1// Copyright 2017 The PDFium Authors
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/fxge/dib/cfx_imagerenderer.h"
8
9#include <math.h>
10
11#include <memory>
12#include <utility>
13
14#include "core/fxcrt/fx_system.h"
15#include "core/fxge/cfx_cliprgn.h"
16#include "core/fxge/dib/cfx_dibitmap.h"
17#include "core/fxge/dib/cfx_imagestretcher.h"
18#include "core/fxge/dib/cfx_imagetransformer.h"
19
20CFX_ImageRenderer::CFX_ImageRenderer(const RetainPtr<CFX_DIBitmap>& pDevice,
21 const CFX_ClipRgn* pClipRgn,
22 RetainPtr<const CFX_DIBBase> source,
23 float alpha,
24 uint32_t mask_color,
25 const CFX_Matrix& matrix,
26 const FXDIB_ResampleOptions& options,
27 bool bRgbByteOrder)
30 m_Matrix(matrix),
31 m_Alpha(alpha),
32 m_MaskColor(mask_color),
33 m_bRgbByteOrder(bRgbByteOrder) {
34 FX_RECT image_rect = m_Matrix.GetUnitRect().GetOuterRect();
35 m_ClipBox = pClipRgn
36 ? pClipRgn->GetBox()
37 : FX_RECT(0, 0, pDevice->GetWidth(), pDevice->GetHeight());
38 m_ClipBox.Intersect(image_rect);
39 if (m_ClipBox.IsEmpty())
40 return;
41
42 if ((fabs(m_Matrix.b) >= 0.5f || m_Matrix.a == 0) ||
43 (fabs(m_Matrix.c) >= 0.5f || m_Matrix.d == 0)) {
44 if (fabs(m_Matrix.a) < fabs(m_Matrix.b) / 20 &&
45 fabs(m_Matrix.d) < fabs(m_Matrix.c) / 20 && fabs(m_Matrix.a) < 0.5f &&
46 fabs(m_Matrix.d) < 0.5f) {
47 int dest_width = image_rect.Width();
48 int dest_height = image_rect.Height();
49 FX_RECT bitmap_clip = m_ClipBox;
50 bitmap_clip.Offset(-image_rect.left, -image_rect.top);
51 bitmap_clip = bitmap_clip.SwappedClipBox(dest_width, dest_height,
52 m_Matrix.c > 0, m_Matrix.b < 0);
53 const bool flip_x = m_Matrix.c > 0;
54 const bool flip_y = m_Matrix.b < 0;
55 m_Composer.Compose(pDevice, pClipRgn, alpha, mask_color, m_ClipBox,
56 /*bVertical=*/true, flip_x, flip_y, m_bRgbByteOrder,
57 BlendMode::kNormal);
58 m_Stretcher = std::make_unique<CFX_ImageStretcher>(
59 &m_Composer, std::move(source), dest_height, dest_width, bitmap_clip,
60 options);
61 if (m_Stretcher->Start())
62 m_State = State::kStretching;
63 return;
64 }
65 m_State = State::kTransforming;
66 m_pTransformer = std::make_unique<CFX_ImageTransformer>(
67 std::move(source), m_Matrix, options, &m_ClipBox);
68 return;
69 }
70
71 int dest_width = image_rect.Width();
72 if (m_Matrix.a < 0)
73 dest_width = -dest_width;
74
75 int dest_height = image_rect.Height();
76 if (m_Matrix.d > 0)
77 dest_height = -dest_height;
78
79 if (dest_width == 0 || dest_height == 0)
80 return;
81
82 FX_RECT bitmap_clip = m_ClipBox;
83 bitmap_clip.Offset(-image_rect.left, -image_rect.top);
84 m_Composer.Compose(pDevice, pClipRgn, alpha, mask_color, m_ClipBox,
85 /*bVertical=*/false, /*bFlipX=*/false, /*bFlipY=*/false,
86 m_bRgbByteOrder, BlendMode::kNormal);
87 m_State = State::kStretching;
88 m_Stretcher = std::make_unique<CFX_ImageStretcher>(
89 &m_Composer, std::move(source), dest_width, dest_height, bitmap_clip,
90 options);
91 m_Stretcher->Start();
92}
93
95
97 if (m_State == State::kStretching)
98 return m_Stretcher->Continue(pPause);
99 if (m_State != State::kTransforming)
100 return false;
101 if (m_pTransformer->Continue(pPause))
102 return true;
103
104 RetainPtr<CFX_DIBitmap> pBitmap = m_pTransformer->DetachBitmap();
105 if (!pBitmap || pBitmap->GetBuffer().empty())
106 return false;
107
108 if (pBitmap->IsMaskFormat()) {
109 if (m_Alpha != 1.0f) {
110 m_MaskColor = FXARGB_MUL_ALPHA(m_MaskColor, FXSYS_roundf(m_Alpha * 255));
111 }
112 m_pDevice->CompositeMask(m_pTransformer->result().left,
113 m_pTransformer->result().top, pBitmap->GetWidth(),
114 pBitmap->GetHeight(), pBitmap, m_MaskColor, 0, 0,
115 BlendMode::kNormal, m_pClipRgn, m_bRgbByteOrder);
116 } else {
117 pBitmap->MultiplyAlpha(m_Alpha);
118 m_pDevice->CompositeBitmap(
119 m_pTransformer->result().left, m_pTransformer->result().top,
120 pBitmap->GetWidth(), pBitmap->GetHeight(), pBitmap, 0, 0,
121 BlendMode::kNormal, m_pClipRgn, m_bRgbByteOrder);
122 }
123 return false;
124}
FX_RECT GetOuterRect() const
bool Continue(PauseIndicatorIface *pPause)
CFX_ImageRenderer(const RetainPtr< CFX_DIBitmap > &pDevice, const CFX_ClipRgn *pClipRgn, RetainPtr< const CFX_DIBBase > source, float alpha, uint32_t mask_color, const CFX_Matrix &matrix, const FXDIB_ResampleOptions &options, bool bRgbByteOrder)
CFX_FloatRect GetUnitRect() const
CFX_Matrix(const CFX_Matrix &other)=default
#define FXARGB_MUL_ALPHA(argb, alpha)
Definition fx_dib.h:128
int FXSYS_roundf(float f)
Definition fx_system.cpp:92
void Offset(int dx, int dy)
FX_RECT & operator=(const FX_RECT &that)=default
int Height() const
int Width() const
int32_t top
FX_RECT SwappedClipBox(int width, int height, bool bFlipX, bool bFlipY) const
int32_t left
void Intersect(const FX_RECT &src)
bool IsEmpty() const