summaryrefslogtreecommitdiff
path: root/xmloff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2021-09-09 13:04:01 +0200
committerMiklos Vajna <vmiklos@collabora.com>2021-09-09 14:27:52 +0200
commit7a8bb65e1b8dc7fdd7f89c8c546e71e4208da574 (patch)
treea7e3503c90395052a071b543f21be5303ddef947 /xmloff
parenta9cd44f8deeccbb8afc7209fdf86fbc26ea7a464 (diff)
ODT export: order <style:font-face> elements inside <office:font-face-decls>
This builds on top of commit 92471550b8c43d8ff0cef8b414884d697edf9e63 (ODF export: sort <style:font-face> elements based on the style:name attribute, 2021-03-11), the additional problem was that the style:name attribute already has number suffixes to have unique names for fonts where the style name would match. This means that even if we sort the container right before writing the elements, which font gets the number suffix depends on the insert order. Fix this by additionally sorting the font items before insertion, given that a single call-site does all the insertion, at least for Writer documents. This is required as SfxItemPool::GetItemSurrogates() exposes a container which is based on SfxPoolItemArray_Impl, which uses an o3tl::sorted_vector<> of pointers, so effectively unsorted, the order depends on the pointer address of the font items. Change-Id: I46569b40796243f7f95b92870504c2023b2ce943 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/121823 Reviewed-by: Miklos Vajna <vmiklos@collabora.com> Tested-by: Jenkins
Diffstat (limited to 'xmloff')
-rw-r--r--xmloff/qa/unit/style.cxx53
1 files changed, 47 insertions, 6 deletions
diff --git a/xmloff/qa/unit/style.cxx b/xmloff/qa/unit/style.cxx
index c6dd4ecd8bc2..1f63cbe1355a 100644
--- a/xmloff/qa/unit/style.cxx
+++ b/xmloff/qa/unit/style.cxx
@@ -25,6 +25,7 @@
#include <comphelper/propertysequence.hxx>
#include <unotools/tempfile.hxx>
#include <unotools/ucbstreamhelper.hxx>
+#include <rtl/character.hxx>
using namespace ::com::sun::star;
@@ -85,6 +86,25 @@ CPPUNIT_TEST_FIXTURE(XmloffStyleTest, testFillImageBase64)
CPPUNIT_ASSERT(xBitmaps->hasByName("libreoffice_0"));
}
+namespace
+{
+struct XmlFont
+{
+ OString aName;
+ OString aFontFamilyGeneric;
+ bool operator<(const XmlFont& rOther) const
+ {
+ sal_Int32 nRet = aName.compareTo(rOther.aName);
+ if (nRet != 0)
+ {
+ return nRet < 0;
+ }
+
+ return aFontFamilyGeneric.compareTo(rOther.aFontFamilyGeneric) < 0;
+ }
+};
+}
+
CPPUNIT_TEST_FIXTURE(XmloffStyleTest, testFontSorting)
{
// Given an empty document with default fonts (Liberation Sans, Lucida Sans, etc):
@@ -110,25 +130,46 @@ CPPUNIT_TEST_FIXTURE(XmloffStyleTest, testFontSorting)
= getXPathNode(pXmlDoc, "/office:document-content/office:font-face-decls/style:font-face");
xmlNodeSetPtr pXmlNodes = pXPath->nodesetval;
int nNodeCount = xmlXPathNodeSetGetLength(pXmlNodes);
- std::vector<OString> aXMLNames;
- std::set<OString> aSortedNames;
+ std::vector<XmlFont> aXMLFonts;
+ std::vector<XmlFont> aSortedFonts;
for (int i = 0; i < nNodeCount; ++i)
{
xmlNodePtr pXmlNode = pXmlNodes->nodeTab[i];
xmlChar* pName = xmlGetProp(pXmlNode, BAD_CAST("name"));
OString aName(reinterpret_cast<char const*>(pName));
- aXMLNames.push_back(aName);
- aSortedNames.insert(aName);
+
+ // Ignore numbers at the end, those are just appended to make all names unique.
+ while (rtl::isAsciiDigit(static_cast<sal_uInt32>(aName[aName.getLength() - 1])))
+ {
+ aName = aName.copy(0, aName.getLength() - 1);
+ }
+
+ xmlChar* pFontFamilyGeneric = xmlGetProp(pXmlNode, BAD_CAST("font-family-generic"));
+ OString aFontFamilyGeneric;
+ if (pFontFamilyGeneric)
+ {
+ aFontFamilyGeneric = OString(reinterpret_cast<char const*>(pFontFamilyGeneric));
+ }
+
+ aXMLFonts.push_back(XmlFont{ aName, aFontFamilyGeneric });
+ aSortedFonts.push_back(XmlFont{ aName, aFontFamilyGeneric });
xmlFree(pName);
}
+ std::sort(aSortedFonts.begin(), aSortedFonts.end());
size_t nIndex = 0;
- for (const auto& rName : aSortedNames)
+ for (const auto& rFont : aSortedFonts)
{
// Without the accompanying fix in place, this test would have failed with:
// - Expected: Liberation Sans
// - Actual : Lucida Sans1
// i.e. the output was not lexicographically sorted, "u" was before "i".
- CPPUNIT_ASSERT_EQUAL(rName, aXMLNames[nIndex]);
+ CPPUNIT_ASSERT_EQUAL(rFont.aName, aXMLFonts[nIndex].aName);
+ // Without the accompanying fix in place, this test would have failed with:
+ // - Expected: swiss
+ // - Actual : system
+ // i.e. the output was not lexicographically sorted when style:name was the same, but
+ // style:font-family-generic was not the same.
+ CPPUNIT_ASSERT_EQUAL(rFont.aFontFamilyGeneric, aXMLFonts[nIndex].aFontFamilyGeneric);
++nIndex;
}
xmlXPathFreeObject(pXPath);