Home | History | Annotate | Download | only in parser
      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