blob: 08ba970225590ed710180d5b1aff82093e39a605 [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
9#include "core/fpdfapi/fpdf_parser/include/cpdf_array.h"
Dan Sinclair455a4192016-03-16 09:48:56 -040010#include "core/fpdfapi/fpdf_parser/include/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
Nico Weber9d8ec5a2015-08-04 13:00:21 -070014CPWL_Image::CPWL_Image() : m_pPDFStream(NULL) {}
15
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
tsepez8e4c5052016-04-14 13:42:44 -070049 return sAppStream.AsStringC();
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()) {
Tom Sepez281a9ea2016-02-26 14:24:28 -080066 CFX_FloatRect rect = pDict->GetRectBy("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()) {
Wei Li9b761132016-01-29 15:44:20 -080077 return pDict->GetMatrixBy("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()) {
Wei Li9b761132016-01-29 15:44:20 -080090 return pDict->GetStringBy("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
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700111CPWL_Icon::CPWL_Icon() : m_pIconFit(NULL) {}
112
113CPWL_Icon::~CPWL_Icon() {}
114
115int32_t CPWL_Icon::GetScaleMethod() {
116 if (m_pIconFit)
117 return m_pIconFit->GetScaleMethod();
118
119 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700120}
121
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700122FX_BOOL CPWL_Icon::IsProportionalScale() {
123 if (m_pIconFit)
124 return m_pIconFit->IsProportionalScale();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700125
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700126 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700127}
128
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700129void CPWL_Icon::GetIconPosition(FX_FLOAT& fLeft, FX_FLOAT& fBottom) {
130 if (m_pIconFit) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700131 fLeft = 0.0f;
132 fBottom = 0.0f;
133 CPDF_Array* pA =
Wei Li0fc6b252016-03-01 16:29:41 -0800134 m_pIconFit->GetDict() ? m_pIconFit->GetDict()->GetArrayBy("A") : NULL;
Lei Zhang96660d62015-12-14 18:27:25 -0800135 if (pA) {
Wei Lie1aebd42016-04-11 10:02:09 -0700136 size_t dwCount = pA->GetCount();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700137 if (dwCount > 0)
Wei Li9b761132016-01-29 15:44:20 -0800138 fLeft = pA->GetNumberAt(0);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700139 if (dwCount > 1)
Wei Li9b761132016-01-29 15:44:20 -0800140 fBottom = pA->GetNumberAt(1);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700141 }
142 } else {
143 fLeft = 0.0f;
144 fBottom = 0.0f;
145 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700146}
147
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700148FX_BOOL CPWL_Icon::GetFittingBounds() {
149 if (m_pIconFit)
150 return m_pIconFit->GetFittingBounds();
151
152 return FALSE;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700153}
154
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700155void CPWL_Icon::GetScale(FX_FLOAT& fHScale, FX_FLOAT& fVScale) {
156 fHScale = 1.0f;
157 fVScale = 1.0f;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700158
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700159 if (m_pPDFStream) {
160 FX_FLOAT fImageWidth, fImageHeight;
161 FX_FLOAT fPlateWidth, fPlateHeight;
162
Tom Sepez281a9ea2016-02-26 14:24:28 -0800163 CFX_FloatRect rcPlate = GetClientRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700164 fPlateWidth = rcPlate.right - rcPlate.left;
165 fPlateHeight = rcPlate.top - rcPlate.bottom;
166
167 GetImageSize(fImageWidth, fImageHeight);
168
169 int32_t nScaleMethod = GetScaleMethod();
170
171 switch (nScaleMethod) {
172 default:
173 case 0:
174 fHScale = fPlateWidth / PWL_MAX(fImageWidth, 1.0f);
175 fVScale = fPlateHeight / PWL_MAX(fImageHeight, 1.0f);
176 break;
177 case 1:
178 if (fPlateWidth < fImageWidth)
179 fHScale = fPlateWidth / PWL_MAX(fImageWidth, 1.0f);
180 if (fPlateHeight < fImageHeight)
181 fVScale = fPlateHeight / PWL_MAX(fImageHeight, 1.0f);
182 break;
183 case 2:
184 if (fPlateWidth > fImageWidth)
185 fHScale = fPlateWidth / PWL_MAX(fImageWidth, 1.0f);
186 if (fPlateHeight > fImageHeight)
187 fVScale = fPlateHeight / PWL_MAX(fImageHeight, 1.0f);
188 break;
189 case 3:
190 break;
191 }
192
193 FX_FLOAT fMinScale;
194 if (IsProportionalScale()) {
195 fMinScale = PWL_MIN(fHScale, fVScale);
196 fHScale = fMinScale;
197 fVScale = fMinScale;
198 }
199 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700200}
201
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700202void CPWL_Icon::GetImageOffset(FX_FLOAT& x, FX_FLOAT& y) {
203 FX_FLOAT fLeft, fBottom;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700204
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700205 GetIconPosition(fLeft, fBottom);
206 x = 0.0f;
207 y = 0.0f;
208
209 FX_FLOAT fImageWidth, fImageHeight;
210 GetImageSize(fImageWidth, fImageHeight);
211
212 FX_FLOAT fHScale, fVScale;
213 GetScale(fHScale, fVScale);
214
215 FX_FLOAT fImageFactWidth = fImageWidth * fHScale;
216 FX_FLOAT fImageFactHeight = fImageHeight * fVScale;
217
218 FX_FLOAT fPlateWidth, fPlateHeight;
Tom Sepez281a9ea2016-02-26 14:24:28 -0800219 CFX_FloatRect rcPlate = GetClientRect();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700220 fPlateWidth = rcPlate.right - rcPlate.left;
221 fPlateHeight = rcPlate.top - rcPlate.bottom;
222
223 x = (fPlateWidth - fImageFactWidth) * fLeft;
224 y = (fPlateHeight - fImageFactHeight) * fBottom;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700225}