1*3ac0a46fSAndroid Build Coastguard Worker // Copyright 2016 The PDFium Authors
2*3ac0a46fSAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*3ac0a46fSAndroid Build Coastguard Worker // found in the LICENSE file.
4*3ac0a46fSAndroid Build Coastguard Worker
5*3ac0a46fSAndroid Build Coastguard Worker // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6*3ac0a46fSAndroid Build Coastguard Worker
7*3ac0a46fSAndroid Build Coastguard Worker #include "xfa/fxfa/parser/cxfa_measurement.h"
8*3ac0a46fSAndroid Build Coastguard Worker
9*3ac0a46fSAndroid Build Coastguard Worker #include <math.h>
10*3ac0a46fSAndroid Build Coastguard Worker
11*3ac0a46fSAndroid Build Coastguard Worker #include "core/fxcrt/fx_extension.h"
12*3ac0a46fSAndroid Build Coastguard Worker #include "third_party/base/notreached.h"
13*3ac0a46fSAndroid Build Coastguard Worker
14*3ac0a46fSAndroid Build Coastguard Worker namespace {
15*3ac0a46fSAndroid Build Coastguard Worker
16*3ac0a46fSAndroid Build Coastguard Worker constexpr float kPtToInch = 72;
17*3ac0a46fSAndroid Build Coastguard Worker constexpr float kPtToCm = kPtToInch / 2.54f;
18*3ac0a46fSAndroid Build Coastguard Worker constexpr float kPtToMm = kPtToCm / 10;
19*3ac0a46fSAndroid Build Coastguard Worker constexpr float kPtToMp = 0.001f;
20*3ac0a46fSAndroid Build Coastguard Worker constexpr float kPtToPc = 12;
21*3ac0a46fSAndroid Build Coastguard Worker
22*3ac0a46fSAndroid Build Coastguard Worker } // namespace
23*3ac0a46fSAndroid Build Coastguard Worker
CXFA_Measurement(WideStringView wsMeasure)24*3ac0a46fSAndroid Build Coastguard Worker CXFA_Measurement::CXFA_Measurement(WideStringView wsMeasure) {
25*3ac0a46fSAndroid Build Coastguard Worker SetString(wsMeasure);
26*3ac0a46fSAndroid Build Coastguard Worker }
27*3ac0a46fSAndroid Build Coastguard Worker
CXFA_Measurement()28*3ac0a46fSAndroid Build Coastguard Worker CXFA_Measurement::CXFA_Measurement() {
29*3ac0a46fSAndroid Build Coastguard Worker Set(-1, XFA_Unit::Unknown);
30*3ac0a46fSAndroid Build Coastguard Worker }
31*3ac0a46fSAndroid Build Coastguard Worker
CXFA_Measurement(float fValue,XFA_Unit eUnit)32*3ac0a46fSAndroid Build Coastguard Worker CXFA_Measurement::CXFA_Measurement(float fValue, XFA_Unit eUnit) {
33*3ac0a46fSAndroid Build Coastguard Worker Set(fValue, eUnit);
34*3ac0a46fSAndroid Build Coastguard Worker }
35*3ac0a46fSAndroid Build Coastguard Worker
SetString(WideStringView wsMeasure)36*3ac0a46fSAndroid Build Coastguard Worker void CXFA_Measurement::SetString(WideStringView wsMeasure) {
37*3ac0a46fSAndroid Build Coastguard Worker if (wsMeasure.Front() == L'=')
38*3ac0a46fSAndroid Build Coastguard Worker wsMeasure = wsMeasure.Substr(1);
39*3ac0a46fSAndroid Build Coastguard Worker
40*3ac0a46fSAndroid Build Coastguard Worker if (wsMeasure.IsEmpty()) {
41*3ac0a46fSAndroid Build Coastguard Worker Set(0, XFA_Unit::Unknown);
42*3ac0a46fSAndroid Build Coastguard Worker return;
43*3ac0a46fSAndroid Build Coastguard Worker }
44*3ac0a46fSAndroid Build Coastguard Worker
45*3ac0a46fSAndroid Build Coastguard Worker size_t nUsedLen = 0;
46*3ac0a46fSAndroid Build Coastguard Worker float fValue = FXSYS_wcstof(wsMeasure.unterminated_c_str(),
47*3ac0a46fSAndroid Build Coastguard Worker wsMeasure.GetLength(), &nUsedLen);
48*3ac0a46fSAndroid Build Coastguard Worker if (!isfinite(fValue))
49*3ac0a46fSAndroid Build Coastguard Worker fValue = 0.0f;
50*3ac0a46fSAndroid Build Coastguard Worker
51*3ac0a46fSAndroid Build Coastguard Worker Set(fValue, GetUnitFromString(wsMeasure.Substr(nUsedLen)));
52*3ac0a46fSAndroid Build Coastguard Worker }
53*3ac0a46fSAndroid Build Coastguard Worker
ToString() const54*3ac0a46fSAndroid Build Coastguard Worker WideString CXFA_Measurement::ToString() const {
55*3ac0a46fSAndroid Build Coastguard Worker switch (GetUnit()) {
56*3ac0a46fSAndroid Build Coastguard Worker case XFA_Unit::Mm:
57*3ac0a46fSAndroid Build Coastguard Worker return WideString::Format(L"%.8gmm", GetValue());
58*3ac0a46fSAndroid Build Coastguard Worker case XFA_Unit::Pt:
59*3ac0a46fSAndroid Build Coastguard Worker return WideString::Format(L"%.8gpt", GetValue());
60*3ac0a46fSAndroid Build Coastguard Worker case XFA_Unit::In:
61*3ac0a46fSAndroid Build Coastguard Worker return WideString::Format(L"%.8gin", GetValue());
62*3ac0a46fSAndroid Build Coastguard Worker case XFA_Unit::Cm:
63*3ac0a46fSAndroid Build Coastguard Worker return WideString::Format(L"%.8gcm", GetValue());
64*3ac0a46fSAndroid Build Coastguard Worker case XFA_Unit::Mp:
65*3ac0a46fSAndroid Build Coastguard Worker return WideString::Format(L"%.8gmp", GetValue());
66*3ac0a46fSAndroid Build Coastguard Worker case XFA_Unit::Pc:
67*3ac0a46fSAndroid Build Coastguard Worker return WideString::Format(L"%.8gpc", GetValue());
68*3ac0a46fSAndroid Build Coastguard Worker case XFA_Unit::Em:
69*3ac0a46fSAndroid Build Coastguard Worker return WideString::Format(L"%.8gem", GetValue());
70*3ac0a46fSAndroid Build Coastguard Worker case XFA_Unit::Percent:
71*3ac0a46fSAndroid Build Coastguard Worker return WideString::Format(L"%.8g%%", GetValue());
72*3ac0a46fSAndroid Build Coastguard Worker default:
73*3ac0a46fSAndroid Build Coastguard Worker break;
74*3ac0a46fSAndroid Build Coastguard Worker }
75*3ac0a46fSAndroid Build Coastguard Worker return WideString::Format(L"%.8g", GetValue());
76*3ac0a46fSAndroid Build Coastguard Worker }
77*3ac0a46fSAndroid Build Coastguard Worker
ToUnit(XFA_Unit eUnit) const78*3ac0a46fSAndroid Build Coastguard Worker float CXFA_Measurement::ToUnit(XFA_Unit eUnit) const {
79*3ac0a46fSAndroid Build Coastguard Worker float f;
80*3ac0a46fSAndroid Build Coastguard Worker return ToUnitInternal(eUnit, &f) ? f : 0;
81*3ac0a46fSAndroid Build Coastguard Worker }
82*3ac0a46fSAndroid Build Coastguard Worker
ToUnitInternal(XFA_Unit eUnit,float * fValue) const83*3ac0a46fSAndroid Build Coastguard Worker bool CXFA_Measurement::ToUnitInternal(XFA_Unit eUnit, float* fValue) const {
84*3ac0a46fSAndroid Build Coastguard Worker *fValue = GetValue();
85*3ac0a46fSAndroid Build Coastguard Worker XFA_Unit eFrom = GetUnit();
86*3ac0a46fSAndroid Build Coastguard Worker if (eFrom == eUnit)
87*3ac0a46fSAndroid Build Coastguard Worker return true;
88*3ac0a46fSAndroid Build Coastguard Worker
89*3ac0a46fSAndroid Build Coastguard Worker switch (eFrom) {
90*3ac0a46fSAndroid Build Coastguard Worker case XFA_Unit::Pt:
91*3ac0a46fSAndroid Build Coastguard Worker break;
92*3ac0a46fSAndroid Build Coastguard Worker case XFA_Unit::Mm:
93*3ac0a46fSAndroid Build Coastguard Worker *fValue *= kPtToMm;
94*3ac0a46fSAndroid Build Coastguard Worker break;
95*3ac0a46fSAndroid Build Coastguard Worker case XFA_Unit::In:
96*3ac0a46fSAndroid Build Coastguard Worker *fValue *= kPtToInch;
97*3ac0a46fSAndroid Build Coastguard Worker break;
98*3ac0a46fSAndroid Build Coastguard Worker case XFA_Unit::Cm:
99*3ac0a46fSAndroid Build Coastguard Worker *fValue *= kPtToCm;
100*3ac0a46fSAndroid Build Coastguard Worker break;
101*3ac0a46fSAndroid Build Coastguard Worker case XFA_Unit::Mp:
102*3ac0a46fSAndroid Build Coastguard Worker *fValue *= kPtToMp;
103*3ac0a46fSAndroid Build Coastguard Worker break;
104*3ac0a46fSAndroid Build Coastguard Worker case XFA_Unit::Pc:
105*3ac0a46fSAndroid Build Coastguard Worker *fValue *= kPtToPc;
106*3ac0a46fSAndroid Build Coastguard Worker break;
107*3ac0a46fSAndroid Build Coastguard Worker default:
108*3ac0a46fSAndroid Build Coastguard Worker *fValue = 0;
109*3ac0a46fSAndroid Build Coastguard Worker return false;
110*3ac0a46fSAndroid Build Coastguard Worker }
111*3ac0a46fSAndroid Build Coastguard Worker switch (eUnit) {
112*3ac0a46fSAndroid Build Coastguard Worker case XFA_Unit::Pt:
113*3ac0a46fSAndroid Build Coastguard Worker return true;
114*3ac0a46fSAndroid Build Coastguard Worker case XFA_Unit::Mm:
115*3ac0a46fSAndroid Build Coastguard Worker *fValue /= kPtToMm;
116*3ac0a46fSAndroid Build Coastguard Worker return true;
117*3ac0a46fSAndroid Build Coastguard Worker case XFA_Unit::In:
118*3ac0a46fSAndroid Build Coastguard Worker *fValue /= kPtToInch;
119*3ac0a46fSAndroid Build Coastguard Worker return true;
120*3ac0a46fSAndroid Build Coastguard Worker case XFA_Unit::Cm:
121*3ac0a46fSAndroid Build Coastguard Worker *fValue /= kPtToCm;
122*3ac0a46fSAndroid Build Coastguard Worker return true;
123*3ac0a46fSAndroid Build Coastguard Worker case XFA_Unit::Mp:
124*3ac0a46fSAndroid Build Coastguard Worker *fValue /= kPtToMp;
125*3ac0a46fSAndroid Build Coastguard Worker return true;
126*3ac0a46fSAndroid Build Coastguard Worker case XFA_Unit::Pc:
127*3ac0a46fSAndroid Build Coastguard Worker *fValue /= kPtToPc;
128*3ac0a46fSAndroid Build Coastguard Worker return true;
129*3ac0a46fSAndroid Build Coastguard Worker default:
130*3ac0a46fSAndroid Build Coastguard Worker NOTREACHED_NORETURN();
131*3ac0a46fSAndroid Build Coastguard Worker }
132*3ac0a46fSAndroid Build Coastguard Worker }
133*3ac0a46fSAndroid Build Coastguard Worker
134*3ac0a46fSAndroid Build Coastguard Worker // static
GetUnitFromString(WideStringView wsUnit)135*3ac0a46fSAndroid Build Coastguard Worker XFA_Unit CXFA_Measurement::GetUnitFromString(WideStringView wsUnit) {
136*3ac0a46fSAndroid Build Coastguard Worker if (wsUnit.EqualsASCII("mm"))
137*3ac0a46fSAndroid Build Coastguard Worker return XFA_Unit::Mm;
138*3ac0a46fSAndroid Build Coastguard Worker if (wsUnit.EqualsASCII("pt"))
139*3ac0a46fSAndroid Build Coastguard Worker return XFA_Unit::Pt;
140*3ac0a46fSAndroid Build Coastguard Worker if (wsUnit.EqualsASCII("in"))
141*3ac0a46fSAndroid Build Coastguard Worker return XFA_Unit::In;
142*3ac0a46fSAndroid Build Coastguard Worker if (wsUnit.EqualsASCII("cm"))
143*3ac0a46fSAndroid Build Coastguard Worker return XFA_Unit::Cm;
144*3ac0a46fSAndroid Build Coastguard Worker if (wsUnit.EqualsASCII("pc"))
145*3ac0a46fSAndroid Build Coastguard Worker return XFA_Unit::Pc;
146*3ac0a46fSAndroid Build Coastguard Worker if (wsUnit.EqualsASCII("mp"))
147*3ac0a46fSAndroid Build Coastguard Worker return XFA_Unit::Mp;
148*3ac0a46fSAndroid Build Coastguard Worker if (wsUnit.EqualsASCII("em"))
149*3ac0a46fSAndroid Build Coastguard Worker return XFA_Unit::Em;
150*3ac0a46fSAndroid Build Coastguard Worker if (wsUnit.EqualsASCII("%"))
151*3ac0a46fSAndroid Build Coastguard Worker return XFA_Unit::Percent;
152*3ac0a46fSAndroid Build Coastguard Worker return XFA_Unit::Unknown;
153*3ac0a46fSAndroid Build Coastguard Worker }
154