by emulating it with SmFontNode. In case of <mo>, current implementation supports only the one named with an alphabet. Change-Id: I827a7e80f5aa94e243098a6e50eb758cf915c282 Reviewed-on: https://gerrit.libreoffice.org/31240 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Takeshi Abe <tabe@fixedpoint.jp>
183 lines
5.1 KiB
C++
183 lines
5.1 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
|
|
/*
|
|
* This file is part of the LibreOffice project.
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*/
|
|
|
|
#include "mathmlattr.hxx"
|
|
|
|
#include <cassert>
|
|
#include <unordered_map>
|
|
|
|
namespace {
|
|
|
|
sal_Int32 lcl_GetPowerOf10(sal_Int32 nPower)
|
|
{
|
|
assert(nPower > 0);
|
|
sal_Int32 nResult = 1;
|
|
while (nPower--)
|
|
nResult *= 10;
|
|
return nResult;
|
|
}
|
|
|
|
}
|
|
|
|
sal_Int32 ParseMathMLUnsignedNumber(const OUString &rStr, Fraction *pUN)
|
|
{
|
|
assert(pUN);
|
|
auto nLen = rStr.getLength();
|
|
sal_Int32 nDecimalPoint = -1;
|
|
sal_Int32 nIdx;
|
|
for (nIdx = 0; nIdx < nLen; nIdx++)
|
|
{
|
|
auto cD = rStr[nIdx];
|
|
if (cD == sal_Unicode('.'))
|
|
{
|
|
if (nDecimalPoint >= 0)
|
|
return -1;
|
|
nDecimalPoint = nIdx;
|
|
continue;
|
|
}
|
|
if (cD < sal_Unicode('0') || sal_Unicode('9') < cD)
|
|
break;
|
|
}
|
|
if (nIdx == 0 || (nIdx == 1 && nDecimalPoint == 0))
|
|
return -1;
|
|
if (nDecimalPoint == -1)
|
|
{
|
|
assert(nIdx > 0);
|
|
*pUN = Fraction(rStr.copy(0, nIdx).toInt32(), 1);
|
|
return nIdx;
|
|
}
|
|
if (nDecimalPoint == 0)
|
|
{
|
|
assert(nIdx > 1);
|
|
*pUN = Fraction(rStr.copy(1, nIdx-1).toInt32(), lcl_GetPowerOf10(nIdx-1));
|
|
return nIdx;
|
|
}
|
|
assert(0 < nDecimalPoint);
|
|
assert(nDecimalPoint < nIdx);
|
|
*pUN = Fraction(rStr.copy(0, nDecimalPoint).toInt32(), 1);
|
|
if (++nDecimalPoint < nIdx)
|
|
*pUN += Fraction(rStr.copy(nDecimalPoint, nIdx-nDecimalPoint).toInt32(),
|
|
lcl_GetPowerOf10(nIdx-nDecimalPoint));
|
|
return nIdx;
|
|
}
|
|
|
|
sal_Int32 ParseMathMLNumber(const OUString &rStr, Fraction *pN)
|
|
{
|
|
assert(pN);
|
|
if (rStr.isEmpty())
|
|
return -1;
|
|
bool bNegative = (rStr[0] == sal_Unicode('-'));
|
|
sal_Int32 nOffset = bNegative ? 1 : 0;
|
|
Fraction aF;
|
|
auto nIdx = ParseMathMLUnsignedNumber(rStr.copy(nOffset), &aF);
|
|
if (nIdx <= 0)
|
|
return -1;
|
|
if (bNegative)
|
|
*pN = Fraction(aF.GetNumerator(), aF.GetDenominator());
|
|
else
|
|
*pN = aF;
|
|
return nOffset + nIdx;
|
|
}
|
|
|
|
sal_Int32 ParseMathMLAttributeLengthValue(const OUString &rStr, MathMLAttributeLengthValue *pV)
|
|
{
|
|
assert(pV);
|
|
auto nIdx = ParseMathMLNumber(rStr, &pV->aNumber);
|
|
if (nIdx <= 0)
|
|
return -1;
|
|
OUString sRest = rStr.copy(nIdx);
|
|
if (sRest.isEmpty())
|
|
{
|
|
pV->eUnit = MathMLLengthUnit::None;
|
|
return nIdx;
|
|
}
|
|
if (sRest.startsWith("em"))
|
|
{
|
|
pV->eUnit = MathMLLengthUnit::Em;
|
|
return nIdx + 2;
|
|
}
|
|
if (sRest.startsWith("ex"))
|
|
{
|
|
pV->eUnit = MathMLLengthUnit::Ex;
|
|
return nIdx + 2;
|
|
}
|
|
if (sRest.startsWith("px"))
|
|
{
|
|
pV->eUnit = MathMLLengthUnit::Px;
|
|
return nIdx + 2;
|
|
}
|
|
if (sRest.startsWith("in"))
|
|
{
|
|
pV->eUnit = MathMLLengthUnit::In;
|
|
return nIdx + 2;
|
|
}
|
|
if (sRest.startsWith("cm"))
|
|
{
|
|
pV->eUnit = MathMLLengthUnit::Cm;
|
|
return nIdx + 2;
|
|
}
|
|
if (sRest.startsWith("mm"))
|
|
{
|
|
pV->eUnit = MathMLLengthUnit::Mm;
|
|
return nIdx + 2;
|
|
}
|
|
if (sRest.startsWith("pt"))
|
|
{
|
|
pV->eUnit = MathMLLengthUnit::Pt;
|
|
return nIdx + 2;
|
|
}
|
|
if (sRest.startsWith("pc"))
|
|
{
|
|
pV->eUnit = MathMLLengthUnit::Pc;
|
|
return nIdx + 2;
|
|
}
|
|
if (sRest[0] == sal_Unicode('%'))
|
|
{
|
|
pV->eUnit = MathMLLengthUnit::Percent;
|
|
return nIdx + 2;
|
|
}
|
|
return nIdx;
|
|
}
|
|
|
|
|
|
bool GetMathMLMathvariantValue(const OUString &rStr, MathMLMathvariantValue *pV)
|
|
{
|
|
static const std::unordered_map<OUString, MathMLMathvariantValue, OUStringHash> aMap{
|
|
{"normal", MathMLMathvariantValue::Normal},
|
|
{"bold", MathMLMathvariantValue::Bold},
|
|
{"italic", MathMLMathvariantValue::Italic},
|
|
{"bold-italic", MathMLMathvariantValue::BoldItalic},
|
|
{"double-struck", MathMLMathvariantValue::DoubleStruck},
|
|
{"bold-fraktur", MathMLMathvariantValue::BoldFraktur},
|
|
{"script", MathMLMathvariantValue::Script},
|
|
{"bold-script", MathMLMathvariantValue::BoldScript},
|
|
{"fraktur", MathMLMathvariantValue::Fraktur},
|
|
{"sans-serif", MathMLMathvariantValue::SansSerif},
|
|
{"bold-sans-serif", MathMLMathvariantValue::BoldSansSerif},
|
|
{"sans-serif-italic", MathMLMathvariantValue::SansSerifItalic},
|
|
{"sans-serif-bold-italic", MathMLMathvariantValue::SansSerifBoldItalic},
|
|
{"monospace", MathMLMathvariantValue::Monospace},
|
|
{"initial", MathMLMathvariantValue::Initial},
|
|
{"tailed", MathMLMathvariantValue::Tailed},
|
|
{"looped", MathMLMathvariantValue::Looped},
|
|
{"stretched", MathMLMathvariantValue::Stretched}
|
|
};
|
|
|
|
assert(pV);
|
|
auto it = aMap.find(rStr);
|
|
if (it != aMap.end())
|
|
{
|
|
*pV = it->second;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
|