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_extension.h" 10 11 namespace { 12 13 constexpr float kPtToInch = 72; 14 constexpr float kPtToCm = kPtToInch / 2.54f; 15 constexpr float kPtToMm = kPtToCm / 10; 16 constexpr float kPtToMp = 0.001f; 17 constexpr float kPtToPc = 12; 18 19 } // namespace 20 21 CXFA_Measurement::CXFA_Measurement(const WideStringView& wsMeasure) { 22 SetString(wsMeasure); 23 } 24 25 CXFA_Measurement::CXFA_Measurement() { 26 Set(-1, XFA_Unit::Unknown); 27 } 28 29 CXFA_Measurement::CXFA_Measurement(float fValue, XFA_Unit eUnit) { 30 Set(fValue, eUnit); 31 } 32 33 void CXFA_Measurement::SetString(const WideStringView& wsMeasure) { 34 if (wsMeasure.IsEmpty()) { 35 m_fValue = 0; 36 m_eUnit = XFA_Unit::Unknown; 37 return; 38 } 39 40 int32_t iUsedLen = 0; 41 int32_t iOffset = (wsMeasure[0] == L'=') ? 1 : 0; 42 float fValue = FXSYS_wcstof(wsMeasure.unterminated_c_str() + iOffset, 43 wsMeasure.GetLength() - iOffset, &iUsedLen); 44 XFA_Unit eUnit = GetUnitFromString( 45 wsMeasure.Right(wsMeasure.GetLength() - (iOffset + iUsedLen))); 46 Set(fValue, eUnit); 47 } 48 49 WideString CXFA_Measurement::ToString() const { 50 switch (GetUnit()) { 51 case XFA_Unit::Mm: 52 return WideString::Format(L"%.8gmm", GetValue()); 53 case XFA_Unit::Pt: 54 return WideString::Format(L"%.8gpt", GetValue()); 55 case XFA_Unit::In: 56 return WideString::Format(L"%.8gin", GetValue()); 57 case XFA_Unit::Cm: 58 return WideString::Format(L"%.8gcm", GetValue()); 59 case XFA_Unit::Mp: 60 return WideString::Format(L"%.8gmp", GetValue()); 61 case XFA_Unit::Pc: 62 return WideString::Format(L"%.8gpc", GetValue()); 63 case XFA_Unit::Em: 64 return WideString::Format(L"%.8gem", GetValue()); 65 case XFA_Unit::Percent: 66 return WideString::Format(L"%.8g%%", GetValue()); 67 default: 68 break; 69 } 70 return WideString::Format(L"%.8g", GetValue()); 71 } 72 73 float CXFA_Measurement::ToUnit(XFA_Unit eUnit) const { 74 float f; 75 return ToUnitInternal(eUnit, &f) ? f : 0; 76 } 77 78 bool CXFA_Measurement::ToUnitInternal(XFA_Unit eUnit, float* fValue) const { 79 *fValue = GetValue(); 80 XFA_Unit eFrom = GetUnit(); 81 if (eFrom == eUnit) 82 return true; 83 84 switch (eFrom) { 85 case XFA_Unit::Pt: 86 break; 87 case XFA_Unit::Mm: 88 *fValue *= kPtToMm; 89 break; 90 case XFA_Unit::In: 91 *fValue *= kPtToInch; 92 break; 93 case XFA_Unit::Cm: 94 *fValue *= kPtToCm; 95 break; 96 case XFA_Unit::Mp: 97 *fValue *= kPtToMp; 98 break; 99 case XFA_Unit::Pc: 100 *fValue *= kPtToPc; 101 break; 102 default: 103 *fValue = 0; 104 return false; 105 } 106 switch (eUnit) { 107 case XFA_Unit::Pt: 108 return true; 109 case XFA_Unit::Mm: 110 *fValue /= kPtToMm; 111 return true; 112 case XFA_Unit::In: 113 *fValue /= kPtToInch; 114 return true; 115 case XFA_Unit::Cm: 116 *fValue /= kPtToCm; 117 return true; 118 case XFA_Unit::Mp: 119 *fValue /= kPtToMp; 120 return true; 121 case XFA_Unit::Pc: 122 *fValue /= kPtToPc; 123 return true; 124 default: 125 NOTREACHED(); 126 return false; 127 } 128 } 129 130 // static 131 XFA_Unit CXFA_Measurement::GetUnitFromString(const WideStringView& wsUnit) { 132 if (wsUnit == L"mm") 133 return XFA_Unit::Mm; 134 if (wsUnit == L"pt") 135 return XFA_Unit::Pt; 136 if (wsUnit == L"in") 137 return XFA_Unit::In; 138 if (wsUnit == L"cm") 139 return XFA_Unit::Cm; 140 if (wsUnit == L"pc") 141 return XFA_Unit::Pc; 142 if (wsUnit == L"mp") 143 return XFA_Unit::Mp; 144 if (wsUnit == L"em") 145 return XFA_Unit::Em; 146 if (wsUnit == L"%") 147 return XFA_Unit::Percent; 148 return XFA_Unit::Unknown; 149 } 150