• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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