blob: 3ae7244552f6c8f347428c8bec069494d44cfaca [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
Dan Sinclair5f2d3812017-02-14 15:42:11 -05009#include <algorithm>
10
dsinclair488b7ad2016-10-04 11:55:50 -070011#include "core/fpdfapi/parser/cpdf_array.h"
12#include "core/fpdfapi/parser/cpdf_stream.h"
dan sinclair89e904b2016-03-23 19:29:15 -040013#include "fpdfsdk/pdfwindow/PWL_Utils.h"
14#include "fpdfsdk/pdfwindow/PWL_Wnd.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070015
thestig1cd352e2016-06-07 17:53:06 -070016CPWL_Image::CPWL_Image() : m_pPDFStream(nullptr) {}
Nico Weber9d8ec5a2015-08-04 13:00:21 -070017
18CPWL_Image::~CPWL_Image() {}
19
20CFX_ByteString CPWL_Image::GetImageAppStream() {
21 CFX_ByteTextBuf sAppStream;
22
23 CFX_ByteString sAlias = GetImageAlias();
Tom Sepez281a9ea2016-02-26 14:24:28 -080024 CFX_FloatRect rcPlate = GetClientRect();
Tom Sepez60d909e2015-12-10 15:34:55 -080025 CFX_Matrix mt;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070026 mt.SetReverse(GetImageMatrix());
27
Dan Sinclair05df0752017-03-14 14:43:42 -040028 float fHScale = 1.0f;
29 float fVScale = 1.0f;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070030 GetScale(fHScale, fVScale);
31
Dan Sinclair05df0752017-03-14 14:43:42 -040032 float fx = 0.0f;
33 float fy = 0.0f;
Nico Weber9d8ec5a2015-08-04 13:00:21 -070034 GetImageOffset(fx, fy);
35
36 if (m_pPDFStream && sAlias.GetLength() > 0) {
37 sAppStream << "q\n";
38 sAppStream << rcPlate.left << " " << rcPlate.bottom << " "
39 << rcPlate.right - rcPlate.left << " "
40 << rcPlate.top - rcPlate.bottom << " re W n\n";
41
42 sAppStream << fHScale << " 0 0 " << fVScale << " " << rcPlate.left + fx
43 << " " << rcPlate.bottom + fy << " cm\n";
Dan Sinclair687a79c2017-02-09 14:08:53 -050044 sAppStream << mt.a << " " << mt.b << " " << mt.c << " " << mt.d << " "
45 << mt.e << " " << mt.f << " cm\n";
Nico Weber9d8ec5a2015-08-04 13:00:21 -070046
tsepez4c3debb2016-04-08 12:20:38 -070047 sAppStream << "0 g 0 G 1 w /" << sAlias.AsStringC() << " Do\n"
Nico Weber9d8ec5a2015-08-04 13:00:21 -070048 << "Q\n";
49 }
50
tsepez71a452f2016-05-13 17:51:27 -070051 return sAppStream.MakeString();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070052}
53
Nico Weber9d8ec5a2015-08-04 13:00:21 -070054void CPWL_Image::SetPDFStream(CPDF_Stream* pStream) {
55 m_pPDFStream = pStream;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070056}
57
Nico Weber9d8ec5a2015-08-04 13:00:21 -070058CPDF_Stream* CPWL_Image::GetPDFStream() {
59 return m_pPDFStream;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070060}
61
Dan Sinclair05df0752017-03-14 14:43:42 -040062void CPWL_Image::GetImageSize(float& fWidth, float& fHeight) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070063 fWidth = 0.0f;
64 fHeight = 0.0f;
65
66 if (m_pPDFStream) {
67 if (CPDF_Dictionary* pDict = m_pPDFStream->GetDict()) {
dsinclair38fd8442016-09-15 10:15:32 -070068 CFX_FloatRect rect = pDict->GetRectFor("BBox");
Nico Weber9d8ec5a2015-08-04 13:00:21 -070069
70 fWidth = rect.right - rect.left;
71 fHeight = rect.top - rect.bottom;
72 }
73 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070074}
75
Tom Sepez60d909e2015-12-10 15:34:55 -080076CFX_Matrix CPWL_Image::GetImageMatrix() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -070077 if (m_pPDFStream) {
78 if (CPDF_Dictionary* pDict = m_pPDFStream->GetDict()) {
dsinclair38fd8442016-09-15 10:15:32 -070079 return pDict->GetMatrixFor("Matrix");
Nico Weber9d8ec5a2015-08-04 13:00:21 -070080 }
81 }
82
Tom Sepez60d909e2015-12-10 15:34:55 -080083 return CFX_Matrix();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070084}
85
Nico Weber9d8ec5a2015-08-04 13:00:21 -070086CFX_ByteString CPWL_Image::GetImageAlias() {
Lei Zhangc2fb35f2016-01-05 16:46:58 -080087 if (!m_sImageAlias.IsEmpty())
Nico Weber9d8ec5a2015-08-04 13:00:21 -070088 return m_sImageAlias;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070089
Lei Zhangc2fb35f2016-01-05 16:46:58 -080090 if (m_pPDFStream) {
91 if (CPDF_Dictionary* pDict = m_pPDFStream->GetDict()) {
dsinclair38fd8442016-09-15 10:15:32 -070092 return pDict->GetStringFor("Name");
Lei Zhangc2fb35f2016-01-05 16:46:58 -080093 }
94 }
95
Nico Weber9d8ec5a2015-08-04 13:00:21 -070096 return CFX_ByteString();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070097}
98
Dan Sinclair812e96c2017-03-13 16:43:37 -040099void CPWL_Image::SetImageAlias(const char* sImageAlias) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700100 m_sImageAlias = sImageAlias;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700101}
102
Dan Sinclair05df0752017-03-14 14:43:42 -0400103void CPWL_Image::GetScale(float& fHScale, float& fVScale) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700104 fHScale = 1.0f;
105 fVScale = 1.0f;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700106}
107
Dan Sinclair05df0752017-03-14 14:43:42 -0400108void CPWL_Image::GetImageOffset(float& x, float& y) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700109 x = 0.0f;
110 y = 0.0f;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700111}
112
thestig1cd352e2016-06-07 17:53:06 -0700113CPWL_Icon::CPWL_Icon() : m_pIconFit(nullptr) {}
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700114
115CPWL_Icon::~CPWL_Icon() {}
116
weili625ad662016-06-15 11:21:33 -0700117CPDF_IconFit* CPWL_Icon::GetIconFit() {
118 return m_pIconFit;
119}
120
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700121int32_t CPWL_Icon::GetScaleMethod() {
122 if (m_pIconFit)
123 return m_pIconFit->GetScaleMethod();
124
125 return 0;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700126}
127
tsepez4cf55152016-11-02 14:37:54 -0700128bool CPWL_Icon::IsProportionalScale() {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700129 if (m_pIconFit)
130 return m_pIconFit->IsProportionalScale();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700131
tsepez4cf55152016-11-02 14:37:54 -0700132 return false;
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700133}
134
Dan Sinclair05df0752017-03-14 14:43:42 -0400135void CPWL_Icon::GetIconPosition(float& fLeft, float& fBottom) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700136 if (m_pIconFit) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700137 fLeft = 0.0f;
138 fBottom = 0.0f;
thestig1cd352e2016-06-07 17:53:06 -0700139 CPDF_Array* pA = m_pIconFit->GetDict()
dsinclair38fd8442016-09-15 10:15:32 -0700140 ? m_pIconFit->GetDict()->GetArrayFor("A")
thestig1cd352e2016-06-07 17:53:06 -0700141 : nullptr;
Lei Zhang96660d62015-12-14 18:27:25 -0800142 if (pA) {
Wei Lie1aebd42016-04-11 10:02:09 -0700143 size_t dwCount = pA->GetCount();
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700144 if (dwCount > 0)
Wei Li9b761132016-01-29 15:44:20 -0800145 fLeft = pA->GetNumberAt(0);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700146 if (dwCount > 1)
Wei Li9b761132016-01-29 15:44:20 -0800147 fBottom = pA->GetNumberAt(1);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700148 }
149 } else {
150 fLeft = 0.0f;
151 fBottom = 0.0f;
152 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700153}
154
Dan Sinclair05df0752017-03-14 14:43:42 -0400155void CPWL_Icon::GetScale(float& fHScale, float& fVScale) {
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700156 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) {
Dan Sinclair05df0752017-03-14 14:43:42 -0400160 float fImageWidth, fImageHeight;
161 float fPlateWidth, fPlateHeight;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700162
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:
Dan Sinclair5f2d3812017-02-14 15:42:11 -0500174 fHScale = fPlateWidth / std::max(fImageWidth, 1.0f);
175 fVScale = fPlateHeight / std::max(fImageHeight, 1.0f);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700176 break;
177 case 1:
178 if (fPlateWidth < fImageWidth)
Dan Sinclair5f2d3812017-02-14 15:42:11 -0500179 fHScale = fPlateWidth / std::max(fImageWidth, 1.0f);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700180 if (fPlateHeight < fImageHeight)
Dan Sinclair5f2d3812017-02-14 15:42:11 -0500181 fVScale = fPlateHeight / std::max(fImageHeight, 1.0f);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700182 break;
183 case 2:
184 if (fPlateWidth > fImageWidth)
Dan Sinclair5f2d3812017-02-14 15:42:11 -0500185 fHScale = fPlateWidth / std::max(fImageWidth, 1.0f);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700186 if (fPlateHeight > fImageHeight)
Dan Sinclair5f2d3812017-02-14 15:42:11 -0500187 fVScale = fPlateHeight / std::max(fImageHeight, 1.0f);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700188 break;
189 case 3:
190 break;
191 }
192
Dan Sinclair05df0752017-03-14 14:43:42 -0400193 float fMinScale;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700194 if (IsProportionalScale()) {
Dan Sinclair5f2d3812017-02-14 15:42:11 -0500195 fMinScale = std::min(fHScale, fVScale);
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700196 fHScale = fMinScale;
197 fVScale = fMinScale;
198 }
199 }
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700200}
201
Dan Sinclair05df0752017-03-14 14:43:42 -0400202void CPWL_Icon::GetImageOffset(float& x, float& y) {
203 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
Dan Sinclair05df0752017-03-14 14:43:42 -0400209 float fImageWidth, fImageHeight;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700210 GetImageSize(fImageWidth, fImageHeight);
211
Dan Sinclair05df0752017-03-14 14:43:42 -0400212 float fHScale, fVScale;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700213 GetScale(fHScale, fVScale);
214
Dan Sinclair05df0752017-03-14 14:43:42 -0400215 float fImageFactWidth = fImageWidth * fHScale;
216 float fImageFactHeight = fImageHeight * fVScale;
Nico Weber9d8ec5a2015-08-04 13:00:21 -0700217
Dan Sinclair05df0752017-03-14 14:43:42 -0400218 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}