tdf#143213: Fix reading math font settings from file

The order of reading the settings is significant, e.g. if font italic
was read first then font name, font name would set a new font
overriding the italic setting.

We now collect all font settings and apply them at once.

Change-Id: Idb32d7d416607011bc325eff0b73c03b2d12e7d3
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/156352
Tested-by: Jenkins
Reviewed-by: خالد حسني <khaled@libreoffice.org>
This commit is contained in:
Khaled Hosny 2023-08-31 14:54:52 +03:00 committed by خالد حسني
parent 5b205d2b39
commit 626d17a8ec
5 changed files with 136 additions and 17 deletions

View file

@ -19,6 +19,7 @@ $(eval $(call gb_CppunitTest_use_external,starmath_import,boost_headers))
$(eval $(call gb_CppunitTest_use_sdk_api,starmath_import))
$(eval $(call gb_CppunitTest_add_exception_objects,starmath_import,\
starmath/qa/cppunit/test_import \
starmath/qa/extras/mmlimport-test \
))

View file

@ -27,6 +27,8 @@
#include <vcl/print.hxx>
#include <oox/mathml/imexport.hxx>
#include "format.hxx"
inline constexpr OUStringLiteral PRTUIOPT_TITLE_ROW = u"TitleRow";
inline constexpr OUStringLiteral PRTUIOPT_FORMULA_TEXT = u"FormulaText";
inline constexpr OUStringLiteral PRTUIOPT_BORDER = u"Border";
@ -48,6 +50,8 @@ class SmModel final : public SfxBaseModel,
{
std::unique_ptr<SmPrintUIOptions> m_pPrintUIOptions;
SmFace maFonts[FNT_END + 1];
virtual void _setPropertyValues( const comphelper::PropertyMapEntry** ppEntries, const css::uno::Any* pValues ) override;
virtual void _getPropertyValues( const comphelper::PropertyMapEntry** ppEntries, css::uno::Any* pValue ) override;
public:

Binary file not shown.

View file

@ -0,0 +1,91 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* 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 <sal/config.h>
#include <test/unoapi_test.hxx>
#include <sfx2/sfxbasemodel.hxx>
#include <document.hxx>
#include <smdll.hxx>
using namespace ::com::sun::star;
namespace
{
class Test : public UnoApiTest
{
public:
Test()
: UnoApiTest("starmath/qa/cppunit/data/")
{
}
void testFontStyles();
CPPUNIT_TEST_SUITE(Test);
CPPUNIT_TEST(testFontStyles);
CPPUNIT_TEST_SUITE_END();
};
void Test::testFontStyles()
{
// tdf#143213
loadFromURL(u"font-styles.odf");
SfxBaseModel* pModel = dynamic_cast<SfxBaseModel*>(mxComponent.get());
SmDocShell* pDocShell = static_cast<SmDocShell*>(pModel->GetObjectShell());
const SmFormat& aFormat = pDocShell->GetFormat();
CPPUNIT_ASSERT_EQUAL(ITALIC_NORMAL, aFormat.GetFont(FNT_MATH).GetItalic());
CPPUNIT_ASSERT_EQUAL(WEIGHT_BOLD, aFormat.GetFont(FNT_MATH).GetWeight());
CPPUNIT_ASSERT_EQUAL(aFormat.GetBaseSize().Height(),
aFormat.GetFont(FNT_MATH).GetFontSize().Height());
CPPUNIT_ASSERT_EQUAL(ITALIC_NORMAL, aFormat.GetFont(FNT_VARIABLE).GetItalic());
CPPUNIT_ASSERT_EQUAL(WEIGHT_BOLD, aFormat.GetFont(FNT_VARIABLE).GetWeight());
CPPUNIT_ASSERT_EQUAL(aFormat.GetBaseSize().Height(),
aFormat.GetFont(FNT_VARIABLE).GetFontSize().Height());
CPPUNIT_ASSERT_EQUAL(ITALIC_NORMAL, aFormat.GetFont(FNT_FUNCTION).GetItalic());
CPPUNIT_ASSERT_EQUAL(WEIGHT_BOLD, aFormat.GetFont(FNT_FUNCTION).GetWeight());
CPPUNIT_ASSERT_EQUAL(aFormat.GetBaseSize().Height(),
aFormat.GetFont(FNT_FUNCTION).GetFontSize().Height());
CPPUNIT_ASSERT_EQUAL(ITALIC_NORMAL, aFormat.GetFont(FNT_NUMBER).GetItalic());
CPPUNIT_ASSERT_EQUAL(WEIGHT_BOLD, aFormat.GetFont(FNT_NUMBER).GetWeight());
CPPUNIT_ASSERT_EQUAL(aFormat.GetBaseSize().Height(),
aFormat.GetFont(FNT_NUMBER).GetFontSize().Height());
CPPUNIT_ASSERT_EQUAL(ITALIC_NORMAL, aFormat.GetFont(FNT_TEXT).GetItalic());
CPPUNIT_ASSERT_EQUAL(WEIGHT_BOLD, aFormat.GetFont(FNT_TEXT).GetWeight());
CPPUNIT_ASSERT_EQUAL(aFormat.GetBaseSize().Height(),
aFormat.GetFont(FNT_TEXT).GetFontSize().Height());
CPPUNIT_ASSERT_EQUAL(ITALIC_NONE, aFormat.GetFont(FNT_SERIF).GetItalic());
CPPUNIT_ASSERT_EQUAL(WEIGHT_NORMAL, aFormat.GetFont(FNT_SERIF).GetWeight());
CPPUNIT_ASSERT_EQUAL(aFormat.GetBaseSize().Height(),
aFormat.GetFont(FNT_SERIF).GetFontSize().Height());
CPPUNIT_ASSERT_EQUAL(ITALIC_NONE, aFormat.GetFont(FNT_SANS).GetItalic());
CPPUNIT_ASSERT_EQUAL(WEIGHT_NORMAL, aFormat.GetFont(FNT_SANS).GetWeight());
CPPUNIT_ASSERT_EQUAL(aFormat.GetBaseSize().Height(),
aFormat.GetFont(FNT_SANS).GetFontSize().Height());
CPPUNIT_ASSERT_EQUAL(ITALIC_NONE, aFormat.GetFont(FNT_FIXED).GetItalic());
CPPUNIT_ASSERT_EQUAL(WEIGHT_NORMAL, aFormat.GetFont(FNT_FIXED).GetWeight());
CPPUNIT_ASSERT_EQUAL(aFormat.GetBaseSize().Height(),
aFormat.GetFont(FNT_FIXED).GetFontSize().Height());
}
CPPUNIT_TEST_SUITE_REGISTRATION(Test);
} // namespace
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View file

@ -434,16 +434,7 @@ void SmModel::_setPropertyValues(const PropertyMapEntry** ppEntries, const Any*
*pValues >>= sFontName;
if(sFontName.isEmpty())
throw IllegalArgumentException();
if(aFormat.GetFont((*ppEntries)->mnMemberId).GetFamilyName() != sFontName)
{
const SmFace rOld = aFormat.GetFont((*ppEntries)->mnMemberId);
SmFace aSet( sFontName, rOld.GetFontSize() );
aSet.SetBorderWidth( rOld.GetBorderWidth() );
aSet.SetAlignment( ALIGN_BASELINE );
aFormat.SetFont( (*ppEntries)->mnMemberId, aSet );
}
maFonts[(*ppEntries)->mnMemberId].SetFamilyName(sFontName);
}
break;
case HANDLE_CUSTOM_FONT_FIXED_POSTURE:
@ -458,9 +449,7 @@ void SmModel::_setPropertyValues(const PropertyMapEntry** ppEntries, const Any*
std::optional<const bool> bVal = o3tl::tryAccess<bool>(*pValues);
if(!bVal.has_value())
throw IllegalArgumentException();
vcl::Font aNewFont(aFormat.GetFont((*ppEntries)->mnMemberId));
aNewFont.SetItalic(*bVal ? ITALIC_NORMAL : ITALIC_NONE);
aFormat.SetFont((*ppEntries)->mnMemberId, aNewFont);
maFonts[(*ppEntries)->mnMemberId].SetItalic(*bVal ? ITALIC_NORMAL : ITALIC_NONE);
}
break;
case HANDLE_CUSTOM_FONT_FIXED_WEIGHT :
@ -475,9 +464,7 @@ void SmModel::_setPropertyValues(const PropertyMapEntry** ppEntries, const Any*
std::optional<const bool> bVal = o3tl::tryAccess<bool>(*pValues);
if(!bVal.has_value())
throw IllegalArgumentException();
vcl::Font aNewFont(aFormat.GetFont((*ppEntries)->mnMemberId));
aNewFont.SetWeight(*bVal ? WEIGHT_BOLD : WEIGHT_NORMAL);
aFormat.SetFont((*ppEntries)->mnMemberId, aNewFont);
maFonts[(*ppEntries)->mnMemberId].SetWeight(*bVal ? WEIGHT_BOLD : WEIGHT_NORMAL);
}
break;
case HANDLE_BASE_FONT_HEIGHT :
@ -493,7 +480,7 @@ void SmModel::_setPropertyValues(const PropertyMapEntry** ppEntries, const Any*
// apply base size to fonts
const Size aTmp( aFormat.GetBaseSize() );
for (sal_uInt16 i = FNT_BEGIN; i <= FNT_END; i++)
aFormat.SetFontSize(i, aTmp);
maFonts[i].SetSize(aTmp);
}
break;
case HANDLE_RELATIVE_FONT_HEIGHT_TEXT :
@ -674,6 +661,42 @@ void SmModel::_setPropertyValues(const PropertyMapEntry** ppEntries, const Any*
}
}
// tdf#143213
// Collect all font settings and apply them at the end, since the font name change can be seen
// after italic or bold settings and would then override them.
for (sal_uInt16 nFontDesc = FNT_BEGIN; nFontDesc <= FNT_END; ++nFontDesc)
{
const SmFace& rFont = maFonts[nFontDesc];
if (aFormat.GetFont(nFontDesc).GetFamilyName() != rFont.GetFamilyName())
{
const SmFace rOld = aFormat.GetFont(nFontDesc);
SmFace aSet(rFont.GetFamilyName(), rOld.GetFontSize());
aSet.SetBorderWidth(rOld.GetBorderWidth());
aSet.SetAlignment(ALIGN_BASELINE);
aFormat.SetFont(nFontDesc, aSet);
}
if (aFormat.GetFont(nFontDesc).GetItalic() != rFont.GetItalic())
{
vcl::Font aNewFont(aFormat.GetFont(nFontDesc));
aNewFont.SetItalic(rFont.GetItalic());
aFormat.SetFont(nFontDesc, aNewFont);
}
if (aFormat.GetFont(nFontDesc).GetWeight() != rFont.GetWeight())
{
vcl::Font aNewFont(aFormat.GetFont(nFontDesc));
aNewFont.SetWeight(rFont.GetWeight());
aFormat.SetFont(nFontDesc, aNewFont);
}
if (aFormat.GetFont(nFontDesc).GetFontSize() != rFont.GetFontSize())
{
aFormat.SetFontSize(nFontDesc, rFont.GetFontSize());
}
}
pDocSh->SetFormat( aFormat );
// #i67283# since about all of the above changes are likely to change