cURL: follow redirects
[LibreOffice.git] / starmath / source / mathmlattr.cxx
blob262609f1875dfc1e44bf201cce9fed53f60559ab
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
10 #include "mathmlattr.hxx"
12 #include <cassert>
14 namespace {
16 sal_Int32 lcl_GetPowerOf10(sal_Int32 nPower)
18 assert(nPower > 0);
19 sal_Int32 nResult = 1;
20 while (nPower--)
21 nResult *= 10;
22 return nResult;
27 sal_Int32 ParseMathMLUnsignedNumber(const OUString &rStr, Fraction *pUN)
29 assert(pUN);
30 auto nLen = rStr.getLength();
31 sal_Int32 nDecimalPoint = -1;
32 sal_Int32 nIdx;
33 for (nIdx = 0; nIdx < nLen; nIdx++)
35 auto cD = rStr[nIdx];
36 if (cD == sal_Unicode('.'))
38 if (nDecimalPoint >= 0)
39 return -1;
40 nDecimalPoint = nIdx;
41 continue;
43 if (cD < sal_Unicode('0') || sal_Unicode('9') < cD)
44 break;
46 if (nIdx == 0 || (nIdx == 1 && nDecimalPoint == 0))
47 return -1;
48 if (nDecimalPoint == -1)
50 assert(nIdx > 0);
51 *pUN = Fraction(rStr.copy(0, nIdx).toInt32(), 1);
52 return nIdx;
54 if (nDecimalPoint == 0)
56 assert(nIdx > 1);
57 *pUN = Fraction(rStr.copy(1, nIdx-1).toInt32(), lcl_GetPowerOf10(nIdx-1));
58 return nIdx;
60 assert(0 < nDecimalPoint);
61 assert(nDecimalPoint < nIdx);
62 *pUN = Fraction(rStr.copy(0, nDecimalPoint).toInt32(), 1);
63 if (++nDecimalPoint < nIdx)
64 *pUN += Fraction(rStr.copy(nDecimalPoint, nIdx-nDecimalPoint).toInt32(),
65 lcl_GetPowerOf10(nIdx-nDecimalPoint));
66 return nIdx;
69 sal_Int32 ParseMathMLNumber(const OUString &rStr, Fraction *pN)
71 assert(pN);
72 if (rStr.isEmpty())
73 return -1;
74 bool bNegative = (rStr[0] == sal_Unicode('-'));
75 sal_Int32 nOffset = bNegative ? 1 : 0;
76 Fraction aF;
77 auto nIdx = ParseMathMLUnsignedNumber(rStr.copy(nOffset), &aF);
78 if (nIdx <= 0)
79 return -1;
80 if (bNegative)
81 *pN = Fraction(aF.GetNumerator(), aF.GetDenominator());
82 else
83 *pN = aF;
84 return nOffset + nIdx;
87 sal_Int32 ParseMathMLAttributeLengthValue(const OUString &rStr, MathMLAttributeLengthValue *pV)
89 assert(pV);
90 auto nIdx = ParseMathMLNumber(rStr, &pV->aNumber);
91 if (nIdx <= 0)
92 return -1;
93 OUString sRest = rStr.copy(nIdx);
94 if (sRest.isEmpty())
96 pV->eUnit = MathMLLengthUnit::None;
97 return nIdx;
99 if (sRest.startsWith("em"))
101 pV->eUnit = MathMLLengthUnit::Em;
102 return nIdx + 2;
104 if (sRest.startsWith("ex"))
106 pV->eUnit = MathMLLengthUnit::Ex;
107 return nIdx + 2;
109 if (sRest.startsWith("px"))
111 pV->eUnit = MathMLLengthUnit::Px;
112 return nIdx + 2;
114 if (sRest.startsWith("in"))
116 pV->eUnit = MathMLLengthUnit::In;
117 return nIdx + 2;
119 if (sRest.startsWith("cm"))
121 pV->eUnit = MathMLLengthUnit::Cm;
122 return nIdx + 2;
124 if (sRest.startsWith("mm"))
126 pV->eUnit = MathMLLengthUnit::Mm;
127 return nIdx + 2;
129 if (sRest.startsWith("pt"))
131 pV->eUnit = MathMLLengthUnit::Pt;
132 return nIdx + 2;
134 if (sRest.startsWith("pc"))
136 pV->eUnit = MathMLLengthUnit::Pc;
137 return nIdx + 2;
139 if (sRest[0] == sal_Unicode('%'))
141 pV->eUnit = MathMLLengthUnit::Percent;
142 return nIdx + 2;
144 return nIdx;
147 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */