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.
4 *
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 */
9
10 #include <mathmlattr.hxx>
11
12 #include <unordered_map>
13
ParseMathMLUnsignedNumber(const OUString & rStr,Fraction & rUN)14 static sal_Int32 ParseMathMLUnsignedNumber(const OUString& rStr, Fraction& rUN)
15 {
16 auto nLen = rStr.getLength();
17 sal_Int32 nDecimalPoint = -1;
18 sal_Int32 nIdx;
19 for (nIdx = 0; nIdx < nLen; nIdx++)
20 {
21 auto cD = rStr[nIdx];
22 if (cD == u'.')
23 {
24 if (nDecimalPoint >= 0)
25 return -1;
26 nDecimalPoint = nIdx;
27 continue;
28 }
29 if (cD < u'0' || u'9' < cD)
30 break;
31 }
32 if (nIdx == 0 || (nIdx == 1 && nDecimalPoint == 0))
33 return -1;
34
35 rUN = Fraction(rStr.copy(0, nIdx).toDouble());
36
37 return nIdx;
38 }
39
ParseMathMLNumber(const OUString & rStr,Fraction & rN)40 static sal_Int32 ParseMathMLNumber(const OUString& rStr, Fraction& rN)
41 {
42 if (rStr.isEmpty())
43 return -1;
44 bool bNegative = (rStr[0] == '-');
45 sal_Int32 nOffset = bNegative ? 1 : 0;
46 auto nIdx = ParseMathMLUnsignedNumber(rStr.copy(nOffset), rN);
47 if (nIdx <= 0 || !rN.IsValid())
48 return -1;
49 if (bNegative)
50 rN *= -1;
51 return nOffset + nIdx;
52 }
53
ParseMathMLAttributeLengthValue(const OUString & rStr,MathMLAttributeLengthValue & rV)54 sal_Int32 ParseMathMLAttributeLengthValue(const OUString& rStr, MathMLAttributeLengthValue& rV)
55 {
56 auto nIdx = ParseMathMLNumber(rStr, rV.aNumber);
57 if (nIdx <= 0)
58 return -1;
59 OUString sRest = rStr.copy(nIdx);
60 if (sRest.isEmpty())
61 {
62 rV.eUnit = MathMLLengthUnit::None;
63 return nIdx;
64 }
65 if (sRest.startsWith("em"))
66 {
67 rV.eUnit = MathMLLengthUnit::Em;
68 return nIdx + 2;
69 }
70 if (sRest.startsWith("ex"))
71 {
72 rV.eUnit = MathMLLengthUnit::Ex;
73 return nIdx + 2;
74 }
75 if (sRest.startsWith("px"))
76 {
77 rV.eUnit = MathMLLengthUnit::Px;
78 return nIdx + 2;
79 }
80 if (sRest.startsWith("in"))
81 {
82 rV.eUnit = MathMLLengthUnit::In;
83 return nIdx + 2;
84 }
85 if (sRest.startsWith("cm"))
86 {
87 rV.eUnit = MathMLLengthUnit::Cm;
88 return nIdx + 2;
89 }
90 if (sRest.startsWith("mm"))
91 {
92 rV.eUnit = MathMLLengthUnit::Mm;
93 return nIdx + 2;
94 }
95 if (sRest.startsWith("pt"))
96 {
97 rV.eUnit = MathMLLengthUnit::Pt;
98 return nIdx + 2;
99 }
100 if (sRest.startsWith("pc"))
101 {
102 rV.eUnit = MathMLLengthUnit::Pc;
103 return nIdx + 2;
104 }
105 if (sRest[0] == u'%')
106 {
107 rV.eUnit = MathMLLengthUnit::Percent;
108 return nIdx + 2;
109 }
110 return nIdx;
111 }
112
GetMathMLMathvariantValue(const OUString & rStr,MathMLMathvariantValue & rV)113 bool GetMathMLMathvariantValue(const OUString& rStr, MathMLMathvariantValue& rV)
114 {
115 static const std::unordered_map<OUString, MathMLMathvariantValue> aMap{
116 { "normal", MathMLMathvariantValue::Normal },
117 { "bold", MathMLMathvariantValue::Bold },
118 { "italic", MathMLMathvariantValue::Italic },
119 { "bold-italic", MathMLMathvariantValue::BoldItalic },
120 { "double-struck", MathMLMathvariantValue::DoubleStruck },
121 { "bold-fraktur", MathMLMathvariantValue::BoldFraktur },
122 { "script", MathMLMathvariantValue::Script },
123 { "bold-script", MathMLMathvariantValue::BoldScript },
124 { "fraktur", MathMLMathvariantValue::Fraktur },
125 { "sans-serif", MathMLMathvariantValue::SansSerif },
126 { "bold-sans-serif", MathMLMathvariantValue::BoldSansSerif },
127 { "sans-serif-italic", MathMLMathvariantValue::SansSerifItalic },
128 { "sans-serif-bold-italic", MathMLMathvariantValue::SansSerifBoldItalic },
129 { "monospace", MathMLMathvariantValue::Monospace },
130 { "initial", MathMLMathvariantValue::Initial },
131 { "tailed", MathMLMathvariantValue::Tailed },
132 { "looped", MathMLMathvariantValue::Looped },
133 { "stretched", MathMLMathvariantValue::Stretched }
134 };
135
136 auto it = aMap.find(rStr);
137 if (it != aMap.end())
138 {
139 rV = it->second;
140 return true;
141 }
142 return false;
143 }
144
145 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
146