1 // Copyright 2016 The PDFium Authors
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 <math.h>
10
11 #include "core/fxcrt/fx_extension.h"
12 #include "third_party/base/notreached.h"
13
14 namespace {
15
16 constexpr float kPtToInch = 72;
17 constexpr float kPtToCm = kPtToInch / 2.54f;
18 constexpr float kPtToMm = kPtToCm / 10;
19 constexpr float kPtToMp = 0.001f;
20 constexpr float kPtToPc = 12;
21
22 } // namespace
23
CXFA_Measurement(WideStringView wsMeasure)24 CXFA_Measurement::CXFA_Measurement(WideStringView wsMeasure) {
25 SetString(wsMeasure);
26 }
27
CXFA_Measurement()28 CXFA_Measurement::CXFA_Measurement() {
29 Set(-1, XFA_Unit::Unknown);
30 }
31
CXFA_Measurement(float fValue,XFA_Unit eUnit)32 CXFA_Measurement::CXFA_Measurement(float fValue, XFA_Unit eUnit) {
33 Set(fValue, eUnit);
34 }
35
SetString(WideStringView wsMeasure)36 void CXFA_Measurement::SetString(WideStringView wsMeasure) {
37 if (wsMeasure.Front() == L'=')
38 wsMeasure = wsMeasure.Substr(1);
39
40 if (wsMeasure.IsEmpty()) {
41 Set(0, XFA_Unit::Unknown);
42 return;
43 }
44
45 size_t nUsedLen = 0;
46 float fValue = FXSYS_wcstof(wsMeasure.unterminated_c_str(),
47 wsMeasure.GetLength(), &nUsedLen);
48 if (!isfinite(fValue))
49 fValue = 0.0f;
50
51 Set(fValue, GetUnitFromString(wsMeasure.Substr(nUsedLen)));
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