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
cxfa_imagerenderer.cpp
Go to the documentation of this file.
1// Copyright 2018 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 "xfa/fxfa/cxfa_imagerenderer.h"
8
9#include <math.h>
10
11#include "core/fxge/cfx_renderdevice.h"
12#include "core/fxge/dib/cfx_dibbase.h"
13#include "core/fxge/dib/cfx_dibitmap.h"
14#include "core/fxge/dib/cfx_imagerenderer.h"
15#include "core/fxge/dib/cfx_imagetransformer.h"
16
18 const RetainPtr<CFX_DIBBase>& pDIBBase,
19 const CFX_Matrix& pImage2Device)
20 : m_ImageMatrix(pImage2Device), m_pDevice(pDevice), m_pDIBBase(pDIBBase) {}
21
23
26 options.bInterpolateBilinear = true;
27 if (m_pDevice->StartDIBits(m_pDIBBase, /*alpha=*/1.0f, /*argb=*/0,
28 m_ImageMatrix, options, &m_DeviceHandle)) {
29 if (m_DeviceHandle) {
30 m_State = State::kStarted;
31 return true;
32 }
33 return false;
34 }
35 CFX_FloatRect image_rect_f = m_ImageMatrix.GetUnitRect();
36 FX_RECT image_rect = image_rect_f.GetOuterRect();
37 int dest_width = image_rect.Width();
38 int dest_height = image_rect.Height();
39 if ((fabs(m_ImageMatrix.b) >= 0.5f || m_ImageMatrix.a == 0) ||
40 (fabs(m_ImageMatrix.c) >= 0.5f || m_ImageMatrix.d == 0)) {
41 RetainPtr<CFX_DIBBase> pDib = m_pDIBBase;
42 if (m_pDIBBase->IsAlphaFormat() &&
43 !(m_pDevice->GetRenderCaps() & FXRC_ALPHA_IMAGE) &&
44 !(m_pDevice->GetRenderCaps() & FXRC_GET_BITS)) {
45 m_pCloneConvert = m_pDIBBase->ConvertTo(FXDIB_Format::kRgb);
46 if (!m_pCloneConvert)
47 return false;
48
49 pDib = m_pCloneConvert;
50 }
51 FX_RECT clip_box = m_pDevice->GetClipBox();
52 clip_box.Intersect(image_rect);
53 m_State = State::kTransforming;
54 m_pTransformer = std::make_unique<CFX_ImageTransformer>(pDib, m_ImageMatrix,
55 options, &clip_box);
56 return true;
57 }
58 if (m_ImageMatrix.a < 0)
59 dest_width = -dest_width;
60 if (m_ImageMatrix.d > 0)
61 dest_height = -dest_height;
62 int dest_left = dest_width > 0 ? image_rect.left : image_rect.right;
63 int dest_top = dest_height > 0 ? image_rect.top : image_rect.bottom;
64 if (m_pDIBBase->IsOpaqueImage()) {
65 if (m_pDevice->StretchDIBitsWithFlagsAndBlend(
66 m_pDIBBase, dest_left, dest_top, dest_width, dest_height, options,
67 BlendMode::kNormal)) {
68 return false;
69 }
70 }
71 if (m_pDIBBase->IsMaskFormat()) {
72 if (m_pDevice->StretchBitMaskWithFlags(m_pDIBBase, dest_left, dest_top,
73 dest_width, dest_height, 0,
74 options)) {
75 return false;
76 }
77 }
78
79 FX_RECT clip_box = m_pDevice->GetClipBox();
80 FX_RECT dest_rect = clip_box;
81 dest_rect.Intersect(image_rect);
82 FX_RECT dest_clip(
83 dest_rect.left - image_rect.left, dest_rect.top - image_rect.top,
84 dest_rect.right - image_rect.left, dest_rect.bottom - image_rect.top);
85 RetainPtr<CFX_DIBitmap> pStretched =
86 m_pDIBBase->StretchTo(dest_width, dest_height, options, &dest_clip);
87 if (pStretched)
88 CompositeDIBitmap(pStretched, dest_rect.left, dest_rect.top);
89
90 return false;
91}
92
94 if (m_State == State::kTransforming) {
95 if (m_pTransformer->Continue(nullptr))
96 return true;
97
98 RetainPtr<CFX_DIBitmap> pBitmap = m_pTransformer->DetachBitmap();
99 if (!pBitmap)
100 return false;
101
102 if (pBitmap->IsMaskFormat()) {
103 m_pDevice->SetBitMask(pBitmap, m_pTransformer->result().left,
104 m_pTransformer->result().top, 0);
105 } else {
106 m_pDevice->SetDIBitsWithBlend(pBitmap, m_pTransformer->result().left,
107 m_pTransformer->result().top,
108 BlendMode::kNormal);
109 }
110 return false;
111 }
112 if (m_State == State::kStarted)
113 return m_pDevice->ContinueDIBits(m_DeviceHandle.get(), nullptr);
114
115 return false;
116}
117
118void CXFA_ImageRenderer::CompositeDIBitmap(
119 const RetainPtr<CFX_DIBitmap>& pDIBitmap,
120 int left,
121 int top) {
122 if (!pDIBitmap)
123 return;
124
125 if (!pDIBitmap->IsMaskFormat()) {
126 if (m_pDevice->SetDIBits(pDIBitmap, left, top))
127 return;
128 } else if (m_pDevice->SetBitMask(pDIBitmap, left, top, 0)) {
129 return;
130 }
131
132 bool bGetBackGround = ((m_pDevice->GetRenderCaps() & FXRC_ALPHA_OUTPUT)) ||
133 (!(m_pDevice->GetRenderCaps() & FXRC_ALPHA_OUTPUT) &&
134 (m_pDevice->GetRenderCaps() & FXRC_GET_BITS));
135 if (bGetBackGround) {
136 if (pDIBitmap->IsMaskFormat())
137 return;
138
139 m_pDevice->SetDIBitsWithBlend(pDIBitmap, left, top, BlendMode::kNormal);
140 return;
141 }
142 if (!pDIBitmap->IsAlphaFormat() ||
143 (m_pDevice->GetRenderCaps() & FXRC_ALPHA_IMAGE)) {
144 return;
145 }
146
147 RetainPtr<CFX_DIBitmap> pConverted = pDIBitmap->ConvertTo(FXDIB_Format::kRgb);
148 if (!pConverted)
149 return;
150
151 CXFA_ImageRenderer imageRender(m_pDevice, pConverted, m_ImageMatrix);
152 if (!imageRender.Start())
153 return;
154
155 while (imageRender.Continue())
156 continue;
157}
FX_RECT GetOuterRect() const
CFX_FloatRect GetUnitRect() const
CFX_Matrix(const CFX_Matrix &other)=default
CXFA_ImageRenderer(CFX_RenderDevice *pDevice, const RetainPtr< CFX_DIBBase > &pDIBBase, const CFX_Matrix &mtImage2Device)
#define FXRC_ALPHA_OUTPUT
#define FXRC_ALPHA_IMAGE
#define FXRC_GET_BITS
bool bInterpolateBilinear
Definition fx_dib.h:41
int Height() const
int32_t bottom
int32_t right
int Width() const
int32_t top
int32_t left
void Intersect(const FX_RECT &src)
constexpr FX_RECT(int l, int t, int r, int b)