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