1 // 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.
4
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6
7 #include "fpdfsdk/pwl/cpwl_icon.h"
8
9 #include <algorithm>
10 #include <sstream>
11
12 #include "core/fpdfapi/parser/cpdf_array.h"
13 #include "core/fpdfapi/parser/cpdf_stream.h"
14 #include "fpdfsdk/pwl/cpwl_wnd.h"
15
CPWL_Icon()16 CPWL_Icon::CPWL_Icon() : m_pPDFStream(nullptr), m_pIconFit(nullptr) {}
17
~CPWL_Icon()18 CPWL_Icon::~CPWL_Icon() {}
19
GetImageSize()20 std::pair<float, float> CPWL_Icon::GetImageSize() {
21 if (!m_pPDFStream)
22 return {0.0f, 0.0f};
23
24 CPDF_Dictionary* pDict = m_pPDFStream->GetDict();
25 if (!pDict)
26 return {0.0f, 0.0f};
27
28 CFX_FloatRect rect = pDict->GetRectFor("BBox");
29 return {rect.right - rect.left, rect.top - rect.bottom};
30 }
31
GetImageMatrix()32 CFX_Matrix CPWL_Icon::GetImageMatrix() {
33 if (!m_pPDFStream)
34 return CFX_Matrix();
35 if (CPDF_Dictionary* pDict = m_pPDFStream->GetDict())
36 return pDict->GetMatrixFor("Matrix");
37 return CFX_Matrix();
38 }
39
GetImageAlias()40 ByteString CPWL_Icon::GetImageAlias() {
41 if (!m_pPDFStream)
42 return ByteString();
43 if (CPDF_Dictionary* pDict = m_pPDFStream->GetDict())
44 return pDict->GetStringFor("Name");
45 return ByteString();
46 }
47
GetIconPosition()48 std::pair<float, float> CPWL_Icon::GetIconPosition() {
49 if (!m_pIconFit)
50 return {0.0f, 0.0f};
51
52 CPDF_Array* pA =
53 m_pIconFit->GetDict() ? m_pIconFit->GetDict()->GetArrayFor("A") : nullptr;
54 if (!pA)
55 return {0.0f, 0.0f};
56
57 size_t dwCount = pA->GetCount();
58 return {dwCount > 0 ? pA->GetNumberAt(0) : 0.0f,
59 dwCount > 1 ? pA->GetNumberAt(1) : 0.0f};
60 }
61
GetScale()62 std::pair<float, float> CPWL_Icon::GetScale() {
63 float fHScale = 1.0f;
64 float fVScale = 1.0f;
65
66 if (!m_pPDFStream)
67 return {fHScale, fVScale};
68
69 CFX_FloatRect rcPlate = GetClientRect();
70 float fPlateWidth = rcPlate.right - rcPlate.left;
71 float fPlateHeight = rcPlate.top - rcPlate.bottom;
72
73 float fImageWidth;
74 float fImageHeight;
75 std::tie(fImageWidth, fImageHeight) = GetImageSize();
76
77 int32_t nScaleMethod = m_pIconFit ? m_pIconFit->GetScaleMethod() : 0;
78
79 switch (nScaleMethod) {
80 default:
81 case 0:
82 fHScale = fPlateWidth / std::max(fImageWidth, 1.0f);
83 fVScale = fPlateHeight / std::max(fImageHeight, 1.0f);
84 break;
85 case 1:
86 if (fPlateWidth < fImageWidth)
87 fHScale = fPlateWidth / std::max(fImageWidth, 1.0f);
88 if (fPlateHeight < fImageHeight)
89 fVScale = fPlateHeight / std::max(fImageHeight, 1.0f);
90 break;
91 case 2:
92 if (fPlateWidth > fImageWidth)
93 fHScale = fPlateWidth / std::max(fImageWidth, 1.0f);
94 if (fPlateHeight > fImageHeight)
95 fVScale = fPlateHeight / std::max(fImageHeight, 1.0f);
96 break;
97 case 3:
98 break;
99 }
100
101 float fMinScale;
102 if (m_pIconFit && m_pIconFit->IsProportionalScale()) {
103 fMinScale = std::min(fHScale, fVScale);
104 fHScale = fMinScale;
105 fVScale = fMinScale;
106 }
107 return {fHScale, fVScale};
108 }
109
GetImageOffset()110 std::pair<float, float> CPWL_Icon::GetImageOffset() {
111 float fLeft;
112 float fBottom;
113 std::tie(fLeft, fBottom) = GetIconPosition();
114
115 float fImageWidth;
116 float fImageHeight;
117 std::tie(fImageWidth, fImageHeight) = GetImageSize();
118
119 float fHScale, fVScale;
120 std::tie(fHScale, fVScale) = GetScale();
121
122 float fImageFactWidth = fImageWidth * fHScale;
123 float fImageFactHeight = fImageHeight * fVScale;
124
125 CFX_FloatRect rcPlate = GetClientRect();
126 float fPlateWidth = rcPlate.right - rcPlate.left;
127 float fPlateHeight = rcPlate.top - rcPlate.bottom;
128
129 return {(fPlateWidth - fImageFactWidth) * fLeft,
130 (fPlateHeight - fImageFactHeight) * fBottom};
131 }
132