1 // 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
7 #include "xfa/fxfa/parser/cxfa_measurement.h"
8
9 #include <cmath>
10
11 #include "core/fxcrt/fx_extension.h"
12
13 namespace {
14
15 constexpr float kPtToInch = 72;
16 constexpr float kPtToCm = kPtToInch / 2.54f;
17 constexpr float kPtToMm = kPtToCm / 10;
18 constexpr float kPtToMp = 0.001f;
19 constexpr float kPtToPc = 12;
20
21 } // namespace
22
CXFA_Measurement(WideStringView wsMeasure)23 CXFA_Measurement::CXFA_Measurement(WideStringView wsMeasure) {
24 SetString(wsMeasure);
25 }
26
CXFA_Measurement()27 CXFA_Measurement::CXFA_Measurement() {
28 Set(-1, XFA_Unit::Unknown);
29 }
30
CXFA_Measurement(float fValue,XFA_Unit eUnit)31 CXFA_Measurement::CXFA_Measurement(float fValue, XFA_Unit eUnit) {
32 Set(fValue, eUnit);
33 }
34
SetString(WideStringView wsMeasure)35 void CXFA_Measurement::SetString(WideStringView wsMeasure) {
36 if (wsMeasure.IsEmpty()) {
37 Set(0, XFA_Unit::Unknown);
38 return;
39 }
40
41 if (wsMeasure[0] == L'=')
42 wsMeasure = wsMeasure.Last(wsMeasure.GetLength() - 1);
43
44 int32_t iUsedLen = 0;
45 float fValue = FXSYS_wcstof(wsMeasure.unterminated_c_str(),
46 wsMeasure.GetLength(), &iUsedLen);
47 if (!std::isfinite(fValue))
48 fValue = 0.0f;
49
50 wsMeasure = wsMeasure.Last(wsMeasure.GetLength() - iUsedLen);
51 Set(fValue, GetUnitFromString(wsMeasure));
52 }
53
ToString() const54 WideString CXFA_Measurement::ToString() const {
55 switch (GetUnit()) {
56 case XFA_Unit::Mm:
57 return WideString::Format(L"%.8gmm", GetValue());
58 case XFA_Unit::Pt:
59 return WideString::Format(L"%.8gpt", GetValue());
60 case XFA_Unit::In:
61 return WideString::Format(L"%.8gin", GetValue());
62 case XFA_Unit::Cm:
63 return WideString::Format(L"%.8gcm", GetValue());
64 case XFA_Unit::Mp:
65 return WideString::Format(L"%.8gmp", GetValue());
66 case XFA_Unit::Pc:
67 return WideString::Format(L"%.8gpc", GetValue());
68 case XFA_Unit::Em:
69 return WideString::Format(L"%.8gem", GetValue());
70 case XFA_Unit::Percent:
71 return WideString::Format(L"%.8g%%", GetValue());
72 default:
73 break;
74 }
75 return WideString::Format(L"%.8g", GetValue());
76 }
77
ToUnit(XFA_Unit eUnit) const78 float CXFA_Measurement::ToUnit(XFA_Unit eUnit) const {
79 float f;
80 return ToUnitInternal(eUnit, &f) ? f : 0;
81 }
82
ToUnitInternal(XFA_Unit eUnit,float * fValue) const83 bool CXFA_Measurement::ToUnitInternal(XFA_Unit eUnit, float* fValue) const {
84 *fValue = GetValue();
85 XFA_Unit eFrom = GetUnit();
86 if (eFrom == eUnit)
87 return true;
88
89 switch (eFrom) {
90 case XFA_Unit::Pt:
91 break;
92 case XFA_Unit::Mm:
93 *fValue *= kPtToMm;
94 break;
95 case XFA_Unit::In:
96 *fValue *= kPtToInch;
97 break;
98 case XFA_Unit::Cm:
99 *fValue *= kPtToCm;
100 break;
101 case XFA_Unit::Mp:
102 *fValue *= kPtToMp;
103 break;
104 case XFA_Unit::Pc:
105 *fValue *= kPtToPc;
106 break;
107 default:
108 *fValue = 0;
109 return false;
110 }
111 switch (eUnit) {
112 case XFA_Unit::Pt:
113 return true;
114 case XFA_Unit::Mm:
115 *fValue /= kPtToMm;
116 return true;
117 case XFA_Unit::In:
118 *fValue /= kPtToInch;
119 return true;
120 case XFA_Unit::Cm:
121 *fValue /= kPtToCm;
122 return true;
123 case XFA_Unit::Mp:
124 *fValue /= kPtToMp;
125 return true;
126 case XFA_Unit::Pc:
127 *fValue /= kPtToPc;
128 return true;
129 default:
130 NOTREACHED();
131 return false;
132 }
133 }
134
135 // static
GetUnitFromString(WideStringView wsUnit)136 XFA_Unit CXFA_Measurement::GetUnitFromString(WideStringView wsUnit) {
137 if (wsUnit.EqualsASCII("mm"))
138 return XFA_Unit::Mm;
139 if (wsUnit.EqualsASCII("pt"))
140 return XFA_Unit::Pt;
141 if (wsUnit.EqualsASCII("in"))
142 return XFA_Unit::In;
143 if (wsUnit.EqualsASCII("cm"))
144 return XFA_Unit::Cm;
145 if (wsUnit.EqualsASCII("pc"))
146 return XFA_Unit::Pc;
147 if (wsUnit.EqualsASCII("mp"))
148 return XFA_Unit::Mp;
149 if (wsUnit.EqualsASCII("em"))
150 return XFA_Unit::Em;
151 if (wsUnit.EqualsASCII("%"))
152 return XFA_Unit::Percent;
153 return XFA_Unit::Unknown;
154 }
155