blob: 851f1db623c5df52da33366fd041494251052301 [file] [log] [blame]
dsinclair27053d82016-08-02 15:43:46 -07001// Copyright 2016 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
dsinclair1727aee2016-09-29 13:12:56 -07007#include "core/fpdfdoc/cpdf_iconfit.h"
dsinclair27053d82016-08-02 15:43:46 -07008
Lei Zhang59a1a912021-06-07 16:55:25 +00009#include <algorithm>
10
dsinclair488b7ad2016-10-04 11:55:50 -070011#include "core/fpdfapi/parser/cpdf_array.h"
12#include "core/fpdfapi/parser/cpdf_dictionary.h"
dsinclaira52ab742016-09-29 13:59:29 -070013#include "core/fxcrt/fx_string.h"
dsinclair27053d82016-08-02 15:43:46 -070014
Lei Zhang65b8db92018-10-10 17:50:31 +000015namespace {
16
17constexpr float kDefaultPosition = 0.5f;
18
19} // namespace
20
Tom Sepez797ca5c2017-05-25 12:03:18 -070021CPDF_IconFit::CPDF_IconFit(const CPDF_Dictionary* pDict) : m_pDict(pDict) {}
22
23CPDF_IconFit::CPDF_IconFit(const CPDF_IconFit& that) = default;
24
Lei Zhang65b8db92018-10-10 17:50:31 +000025CPDF_IconFit::~CPDF_IconFit() = default;
Tom Sepez797ca5c2017-05-25 12:03:18 -070026
Lei Zhang65b8db92018-10-10 17:50:31 +000027CPDF_IconFit::ScaleMethod CPDF_IconFit::GetScaleMethod() const {
dsinclair27053d82016-08-02 15:43:46 -070028 if (!m_pDict)
Lei Zhang55ae76d2020-06-23 01:12:41 +000029 return ScaleMethod::kAlways;
dsinclair27053d82016-08-02 15:43:46 -070030
Ryan Harrison275e2602017-09-18 14:23:18 -040031 ByteString csSW = m_pDict->GetStringFor("SW", "A");
dsinclair27053d82016-08-02 15:43:46 -070032 if (csSW == "B")
Lei Zhang55ae76d2020-06-23 01:12:41 +000033 return ScaleMethod::kBigger;
dsinclair27053d82016-08-02 15:43:46 -070034 if (csSW == "S")
Lei Zhang55ae76d2020-06-23 01:12:41 +000035 return ScaleMethod::kSmaller;
dsinclair27053d82016-08-02 15:43:46 -070036 if (csSW == "N")
Lei Zhang55ae76d2020-06-23 01:12:41 +000037 return ScaleMethod::kNever;
38 return ScaleMethod::kAlways;
dsinclair27053d82016-08-02 15:43:46 -070039}
40
Lei Zhang65b8db92018-10-10 17:50:31 +000041bool CPDF_IconFit::IsProportionalScale() const {
42 return !m_pDict || m_pDict->GetStringFor("S", "P") != "A";
dsinclair27053d82016-08-02 15:43:46 -070043}
44
Lei Zhang65b8db92018-10-10 17:50:31 +000045CFX_PointF CPDF_IconFit::GetIconBottomLeftPosition() const {
46 float fLeft = kDefaultPosition;
47 float fBottom = kDefaultPosition;
dsinclair27053d82016-08-02 15:43:46 -070048 if (!m_pDict)
Lei Zhang65b8db92018-10-10 17:50:31 +000049 return {fLeft, fBottom};
dsinclair27053d82016-08-02 15:43:46 -070050
Lei Zhangdbf13f62018-05-24 01:36:40 +000051 const CPDF_Array* pA = m_pDict->GetArrayFor("A");
Lei Zhang65b8db92018-10-10 17:50:31 +000052 if (!pA)
53 return {fLeft, fBottom};
54
Lei Zhangf40380f2018-10-12 18:31:51 +000055 size_t dwCount = pA->size();
Lei Zhang65b8db92018-10-10 17:50:31 +000056 if (dwCount > 0)
57 fLeft = pA->GetNumberAt(0);
58 if (dwCount > 1)
59 fBottom = pA->GetNumberAt(1);
60 return {fLeft, fBottom};
dsinclair27053d82016-08-02 15:43:46 -070061}
62
Lei Zhang65b8db92018-10-10 17:50:31 +000063bool CPDF_IconFit::GetFittingBounds() const {
Lei Zhang76ec9262018-10-09 23:32:10 +000064 return m_pDict && m_pDict->GetBooleanFor("FB", false);
dsinclair27053d82016-08-02 15:43:46 -070065}
Tom Sepezd49e0572019-12-18 00:04:16 +000066
67CFX_PointF CPDF_IconFit::GetIconPosition() const {
68 if (!m_pDict)
69 return CFX_PointF();
70
71 const CPDF_Array* pA = m_pDict->GetArrayFor("A");
72 if (!pA)
73 return CFX_PointF();
74
75 size_t dwCount = pA->size();
76 return {dwCount > 0 ? pA->GetNumberAt(0) : 0.0f,
77 dwCount > 1 ? pA->GetNumberAt(1) : 0.0f};
78}
Tom Sepeza043b722021-04-21 18:27:45 +000079
Tom Sepezaa5065c2021-04-21 21:48:39 +000080CFX_VectorF CPDF_IconFit::GetScale(const CFX_SizeF& image_size,
81 const CFX_FloatRect& rcPlate) const {
Tom Sepeza043b722021-04-21 18:27:45 +000082 float fHScale = 1.0f;
83 float fVScale = 1.0f;
Tom Sepez47a8cd02021-04-21 23:13:30 +000084 const float fPlateWidth = rcPlate.Width();
85 const float fPlateHeight = rcPlate.Height();
86 const float fImageWidth = image_size.width;
87 const float fImageHeight = image_size.height;
88 switch (GetScaleMethod()) {
Tom Sepeza043b722021-04-21 18:27:45 +000089 case CPDF_IconFit::ScaleMethod::kAlways:
90 fHScale = fPlateWidth / std::max(fImageWidth, 1.0f);
91 fVScale = fPlateHeight / std::max(fImageHeight, 1.0f);
92 break;
93 case CPDF_IconFit::ScaleMethod::kBigger:
94 if (fPlateWidth < fImageWidth)
95 fHScale = fPlateWidth / std::max(fImageWidth, 1.0f);
96 if (fPlateHeight < fImageHeight)
97 fVScale = fPlateHeight / std::max(fImageHeight, 1.0f);
98 break;
99 case CPDF_IconFit::ScaleMethod::kSmaller:
100 if (fPlateWidth > fImageWidth)
101 fHScale = fPlateWidth / std::max(fImageWidth, 1.0f);
102 if (fPlateHeight > fImageHeight)
103 fVScale = fPlateHeight / std::max(fImageHeight, 1.0f);
104 break;
105 case CPDF_IconFit::ScaleMethod::kNever:
106 break;
107 }
108
109 if (IsProportionalScale()) {
110 float min_scale = std::min(fHScale, fVScale);
111 fHScale = min_scale;
112 fVScale = min_scale;
113 }
114 return {fHScale, fVScale};
115}
116
Tom Sepezaa5065c2021-04-21 21:48:39 +0000117CFX_VectorF CPDF_IconFit::GetImageOffset(const CFX_SizeF& image_size,
Tom Sepez47a8cd02021-04-21 23:13:30 +0000118 const CFX_VectorF& scale,
Tom Sepezaa5065c2021-04-21 21:48:39 +0000119 const CFX_FloatRect& rcPlate) const {
Tom Sepez47a8cd02021-04-21 23:13:30 +0000120 const CFX_PointF icon_position = GetIconPosition();
121 const float fImageFactWidth = image_size.width * scale.x;
122 const float fImageFactHeight = image_size.height * scale.y;
123 return {(rcPlate.Width() - fImageFactWidth) * icon_position.x,
124 (rcPlate.Height() - fImageFactHeight) * icon_position.y};
Tom Sepeza043b722021-04-21 18:27:45 +0000125}