xref: /aosp_15_r20/external/pdfium/xfa/fxfa/parser/cxfa_measurement.cpp (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
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