blob: 877921d6e822bd089d188d11ed3ee0f0e8a21e69 [file] [log] [blame]
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001// Copyright 2014 PDFium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
Lei Zhanga6d9f0e2015-06-13 00:48:38 -07004
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07005// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
dan sinclair89e904b2016-03-23 19:29:15 -04007#include "fpdfsdk/pdfwindow/PWL_Icon.h"
Dan Sinclairaa403d32016-03-15 14:57:22 -04008
dsinclair488b7ad2016-10-04 11:55:50 -07009#include "core/fpdfapi/parser/cpdf_array.h"
10#include "core/fpdfapi/parser/cpdf_stream.h"
dan sinclair89e904b2016-03-23 19:29:15 -040011#include "fpdfsdk/pdfwindow/PWL_Utils.h"
12#include "fpdfsdk/pdfwindow/PWL_Wnd.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070013
thestig1cd352e2016-06-07 17:53:06 -070014CPWL_Image::CPWL_Image() : m_pPDFStream(nullptr) {}
Nico Weber9d8ec5a2015-08-04 13:00:21 -070015
16CPWL_Image::~CPWL_Image() {}
17
18CFX_ByteString CPWL_Image::GetImageAppStream() {
19 CFX_ByteTextBuf sAppStream;
20
21 CFX_ByteString sAlias = GetImageAlias();
Tom Sepez281a9ea2016-02-26 14:24:28 -080022 CFX_FloatRect rcPlate = GetClientRect();
Tom Sepez60d909e2015-12-10 15:34:55 -080023 CFX_Matrix mt;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070024 mt.SetReverse(GetImageMatrix());
25
26 FX_FLOAT fHScale = 1.0f;
27 FX_FLOAT fVScale = 1.0f;
28 GetScale(fHScale, fVScale);
29
30 FX_FLOAT fx = 0.0f;
31 FX_FLOAT fy = 0.0f;
32 GetImageOffset(fx, fy);
33
34 if (m_pPDFStream && sAlias.GetLength() > 0) {
35 sAppStream << "q\n";
36 sAppStream << rcPlate.left << " " << rcPlate.bottom << " "
37 << rcPlate.right - rcPlate.left << " "
38 << rcPlate.top - rcPlate.bottom << " re W n\n";
39
40 sAppStream << fHScale << " 0 0 " << fVScale << " " << rcPlate.left + fx
41 << " " << rcPlate.bottom + fy << " cm\n";
42 sAppStream << mt.GetA() << " " << mt.GetB() << " " << mt.GetC() << " "
43 << mt.GetD() << " " << mt.GetE() << " " << mt.GetF() << " cm\n";
44
tsepez4c3debb2016-04-08 12:20:38 -070045 sAppStream << "0 g 0 G 1 w /" << sAlias.AsStringC() << " Do\n"
Nico Weber9d8ec5a2015-08-04 13:00:21 -070046 << "Q\n";
47 }
48
tsepez71a452f2016-05-13 17:51:27 -070049 return sAppStream.MakeString();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070050}
51
Nico Weber9d8ec5a2015-08-04 13:00:21 -070052void CPWL_Image::SetPDFStream(CPDF_Stream* pStream) {
53 m_pPDFStream = pStream;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070054}
55
Nico Weber9d8ec5a2015-08-04 13:00:21 -070056CPDF_Stream* CPWL_Image::GetPDFStream() {
57 return m_pPDFStream;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070058}
59
Nico Weber9d8ec5a2015-08-04 13:00:21 -070060void CPWL_Image::GetImageSize(FX_FLOAT& fWidth, FX_FLOAT& fHeight) {
61 fWidth = 0.0f;
62 fHeight = 0.0f;
63
64 if (m_pPDFStream) {
65 if (CPDF_Dictionary* pDict = m_pPDFStream->GetDict()) {
dsinclair38fd8442016-09-15 10:15:32 -070066 CFX_FloatRect rect = pDict->GetRectFor("BBox");
Nico Weber9d8ec5a2015-08-04 13:00:21 -070067
68 fWidth = rect.right - rect.left;
69 fHeight = rect.top - rect.bottom;
70 }
71 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070072}
73
Tom Sepez60d909e2015-12-10 15:34:55 -080074CFX_Matrix CPWL_Image::GetImageMatrix() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070075 if (m_pPDFStream) {
76 if (CPDF_Dictionary* pDict = m_pPDFStream->GetDict()) {
dsinclair38fd8442016-09-15 10:15:32 -070077 return pDict->GetMatrixFor("Matrix");
Nico Weber9d8ec5a2015-08-04 13:00:21 -070078 }
79 }
80
Tom Sepez60d909e2015-12-10 15:34:55 -080081 return CFX_Matrix();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070082}
83
Nico Weber9d8ec5a2015-08-04 13:00:21 -070084CFX_ByteString CPWL_Image::GetImageAlias() {
Lei Zhangc2fb35f2016-01-05 16:46:58 -080085 if (!m_sImageAlias.IsEmpty())
Nico Weber9d8ec5a2015-08-04 13:00:21 -070086 return m_sImageAlias;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070087
Lei Zhangc2fb35f2016-01-05 16:46:58 -080088 if (m_pPDFStream) {
89 if (CPDF_Dictionary* pDict = m_pPDFStream->GetDict()) {
dsinclair38fd8442016-09-15 10:15:32 -070090 return pDict->GetStringFor("Name");
Lei Zhangc2fb35f2016-01-05 16:46:58 -080091 }
92 }
93
Nico Weber9d8ec5a2015-08-04 13:00:21 -070094 return CFX_ByteString();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070095}
96
Nico Weber9d8ec5a2015-08-04 13:00:21 -070097void CPWL_Image::SetImageAlias(const FX_CHAR* sImageAlias) {
98 m_sImageAlias = sImageAlias;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070099}
100
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700101void CPWL_Image::GetScale(FX_FLOAT& fHScale, FX_FLOAT& fVScale) {
102 fHScale = 1.0f;
103 fVScale = 1.0f;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700104}
105
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700106void CPWL_Image::GetImageOffset(FX_FLOAT& x, FX_FLOAT& y) {
107 x = 0.0f;
108 y = 0.0f;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700109}
110
thestig1cd352e2016-06-07 17:53:06 -0700111CPWL_Icon::CPWL_Icon() : m_pIconFit(nullptr) {}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700112
113CPWL_Icon::~CPWL_Icon() {}
114
weili625ad662016-06-15 11:21:33 -0700115CPDF_IconFit* CPWL_Icon::GetIconFit() {
116 return m_pIconFit;
117}
118
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700119int32_t CPWL_Icon::GetScaleMethod() {
120 if (m_pIconFit)
121 return m_pIconFit->GetScaleMethod();
122
123 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700124}
125
tsepez4cf55152016-11-02 14:37:54 -0700126bool CPWL_Icon::IsProportionalScale() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700127 if (m_pIconFit)
128 return m_pIconFit->IsProportionalScale();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700129
tsepez4cf55152016-11-02 14:37:54 -0700130 return false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700131}
132
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700133void CPWL_Icon::GetIconPosition(FX_FLOAT& fLeft, FX_FLOAT& fBottom) {
134 if (m_pIconFit) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700135 fLeft = 0.0f;
136 fBottom = 0.0f;
thestig1cd352e2016-06-07 17:53:06 -0700137 CPDF_Array* pA = m_pIconFit->GetDict()
dsinclair38fd8442016-09-15 10:15:32 -0700138 ? m_pIconFit->GetDict()->GetArrayFor("A")
thestig1cd352e2016-06-07 17:53:06 -0700139 : nullptr;
Lei Zhang96660d62015-12-14 18:27:25 -0800140 if (pA) {
Wei Lie1aebd42016-04-11 10:02:09 -0700141 size_t dwCount = pA->GetCount();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700142 if (dwCount > 0)
Wei Li9b761132016-01-29 15:44:20 -0800143 fLeft = pA->GetNumberAt(0);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700144 if (dwCount > 1)
Wei Li9b761132016-01-29 15:44:20 -0800145 fBottom = pA->GetNumberAt(1);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700146 }
147 } else {
148 fLeft = 0.0f;
149 fBottom = 0.0f;
150 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700151}
152
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700153void CPWL_Icon::GetScale(FX_FLOAT& fHScale, FX_FLOAT& fVScale) {
154 fHScale = 1.0f;
155 fVScale = 1.0f;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700156
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700157 if (m_pPDFStream) {
158 FX_FLOAT fImageWidth, fImageHeight;
159 FX_FLOAT fPlateWidth, fPlateHeight;
160
Tom Sepez281a9ea2016-02-26 14:24:28 -0800161 CFX_FloatRect rcPlate = GetClientRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700162 fPlateWidth = rcPlate.right - rcPlate.left;
163 fPlateHeight = rcPlate.top - rcPlate.bottom;
164
165 GetImageSize(fImageWidth, fImageHeight);
166
167 int32_t nScaleMethod = GetScaleMethod();
168
169 switch (nScaleMethod) {
170 default:
171 case 0:
172 fHScale = fPlateWidth / PWL_MAX(fImageWidth, 1.0f);
173 fVScale = fPlateHeight / PWL_MAX(fImageHeight, 1.0f);
174 break;
175 case 1:
176 if (fPlateWidth < fImageWidth)
177 fHScale = fPlateWidth / PWL_MAX(fImageWidth, 1.0f);
178 if (fPlateHeight < fImageHeight)
179 fVScale = fPlateHeight / PWL_MAX(fImageHeight, 1.0f);
180 break;
181 case 2:
182 if (fPlateWidth > fImageWidth)
183 fHScale = fPlateWidth / PWL_MAX(fImageWidth, 1.0f);
184 if (fPlateHeight > fImageHeight)
185 fVScale = fPlateHeight / PWL_MAX(fImageHeight, 1.0f);
186 break;
187 case 3:
188 break;
189 }
190
191 FX_FLOAT fMinScale;
192 if (IsProportionalScale()) {
193 fMinScale = PWL_MIN(fHScale, fVScale);
194 fHScale = fMinScale;
195 fVScale = fMinScale;
196 }
197 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700198}
199
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700200void CPWL_Icon::GetImageOffset(FX_FLOAT& x, FX_FLOAT& y) {
201 FX_FLOAT fLeft, fBottom;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700202
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700203 GetIconPosition(fLeft, fBottom);
204 x = 0.0f;
205 y = 0.0f;
206
207 FX_FLOAT fImageWidth, fImageHeight;
208 GetImageSize(fImageWidth, fImageHeight);
209
210 FX_FLOAT fHScale, fVScale;
211 GetScale(fHScale, fVScale);
212
213 FX_FLOAT fImageFactWidth = fImageWidth * fHScale;
214 FX_FLOAT fImageFactHeight = fImageHeight * fVScale;
215
216 FX_FLOAT fPlateWidth, fPlateHeight;
Tom Sepez281a9ea2016-02-26 14:24:28 -0800217 CFX_FloatRect rcPlate = GetClientRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700218 fPlateWidth = rcPlate.right - rcPlate.left;
219 fPlateHeight = rcPlate.top - rcPlate.bottom;
220
221 x = (fPlateWidth - fImageFactWidth) * fLeft;
222 y = (fPlateHeight - fImageFactHeight) * fBottom;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700223}