xref: /aosp_15_r20/external/pdfium/xfa/fxfa/parser/cxfa_measurement.cpp (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
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_NORETURN();
131   }
132 }
133 
134 // static
GetUnitFromString(WideStringView wsUnit)135 XFA_Unit CXFA_Measurement::GetUnitFromString(WideStringView wsUnit) {
136   if (wsUnit.EqualsASCII("mm"))
137     return XFA_Unit::Mm;
138   if (wsUnit.EqualsASCII("pt"))
139     return XFA_Unit::Pt;
140   if (wsUnit.EqualsASCII("in"))
141     return XFA_Unit::In;
142   if (wsUnit.EqualsASCII("cm"))
143     return XFA_Unit::Cm;
144   if (wsUnit.EqualsASCII("pc"))
145     return XFA_Unit::Pc;
146   if (wsUnit.EqualsASCII("mp"))
147     return XFA_Unit::Mp;
148   if (wsUnit.EqualsASCII("em"))
149     return XFA_Unit::Em;
150   if (wsUnit.EqualsASCII("%"))
151     return XFA_Unit::Percent;
152   return XFA_Unit::Unknown;
153 }
154