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 "core/fxcrt/fx_ext.h"
10
11CXFA_Measurement::CXFA_Measurement(const CFX_WideStringC& wsMeasure) {
12  Set(wsMeasure);
13}
14
15CXFA_Measurement::CXFA_Measurement() {
16  Set(-1, XFA_UNIT_Unknown);
17}
18
19CXFA_Measurement::CXFA_Measurement(FX_FLOAT fValue, XFA_UNIT eUnit) {
20  Set(fValue, eUnit);
21}
22
23void CXFA_Measurement::Set(const CFX_WideStringC& wsMeasure) {
24  if (wsMeasure.IsEmpty()) {
25    m_fValue = 0;
26    m_eUnit = XFA_UNIT_Unknown;
27    return;
28  }
29  int32_t iUsedLen = 0;
30  int32_t iOffset = (wsMeasure.GetAt(0) == L'=') ? 1 : 0;
31  FX_FLOAT fValue = FXSYS_wcstof(wsMeasure.c_str() + iOffset,
32                                 wsMeasure.GetLength() - iOffset, &iUsedLen);
33  XFA_UNIT eUnit = GetUnit(wsMeasure.Mid(iOffset + iUsedLen));
34  Set(fValue, eUnit);
35}
36
37bool CXFA_Measurement::ToString(CFX_WideString& wsMeasure) const {
38  switch (GetUnit()) {
39    case XFA_UNIT_Mm:
40      wsMeasure.Format(L"%.8gmm", GetValue());
41      return true;
42    case XFA_UNIT_Pt:
43      wsMeasure.Format(L"%.8gpt", GetValue());
44      return true;
45    case XFA_UNIT_In:
46      wsMeasure.Format(L"%.8gin", GetValue());
47      return true;
48    case XFA_UNIT_Cm:
49      wsMeasure.Format(L"%.8gcm", GetValue());
50      return true;
51    case XFA_UNIT_Mp:
52      wsMeasure.Format(L"%.8gmp", GetValue());
53      return true;
54    case XFA_UNIT_Pc:
55      wsMeasure.Format(L"%.8gpc", GetValue());
56      return true;
57    case XFA_UNIT_Em:
58      wsMeasure.Format(L"%.8gem", GetValue());
59      return true;
60    case XFA_UNIT_Percent:
61      wsMeasure.Format(L"%.8g%%", GetValue());
62      return true;
63    default:
64      wsMeasure.Format(L"%.8g", GetValue());
65      return false;
66  }
67}
68
69bool CXFA_Measurement::ToUnit(XFA_UNIT eUnit, FX_FLOAT& fValue) const {
70  fValue = GetValue();
71  XFA_UNIT eFrom = GetUnit();
72  if (eFrom == eUnit)
73    return true;
74
75  switch (eFrom) {
76    case XFA_UNIT_Pt:
77      break;
78    case XFA_UNIT_Mm:
79      fValue *= 72 / 2.54f / 10;
80      break;
81    case XFA_UNIT_In:
82      fValue *= 72;
83      break;
84    case XFA_UNIT_Cm:
85      fValue *= 72 / 2.54f;
86      break;
87    case XFA_UNIT_Mp:
88      fValue *= 0.001f;
89      break;
90    case XFA_UNIT_Pc:
91      fValue *= 12.0f;
92      break;
93    default:
94      fValue = 0;
95      return false;
96  }
97  switch (eUnit) {
98    case XFA_UNIT_Pt:
99      return true;
100    case XFA_UNIT_Mm:
101      fValue /= 72 / 2.54f / 10;
102      return true;
103    case XFA_UNIT_In:
104      fValue /= 72;
105      return true;
106    case XFA_UNIT_Cm:
107      fValue /= 72 / 2.54f;
108      return true;
109    case XFA_UNIT_Mp:
110      fValue /= 0.001f;
111      return true;
112    case XFA_UNIT_Pc:
113      fValue /= 12.0f;
114      return true;
115    default:
116      fValue = 0;
117      return false;
118  }
119}
120
121XFA_UNIT CXFA_Measurement::GetUnit(const CFX_WideStringC& wsUnit) {
122  if (wsUnit == L"mm")
123    return XFA_UNIT_Mm;
124  if (wsUnit == L"pt")
125    return XFA_UNIT_Pt;
126  if (wsUnit == L"in")
127    return XFA_UNIT_In;
128  if (wsUnit == L"cm")
129    return XFA_UNIT_Cm;
130  if (wsUnit == L"pc")
131    return XFA_UNIT_Pc;
132  if (wsUnit == L"mp")
133    return XFA_UNIT_Mp;
134  if (wsUnit == L"em")
135    return XFA_UNIT_Em;
136  if (wsUnit == L"%")
137    return XFA_UNIT_Percent;
138  return XFA_UNIT_Unknown;
139}
140