diff options
-rw-r--r-- | editeng/source/items/textitem.cxx | 48 | ||||
-rw-r--r-- | include/editeng/fontitem.hxx | 1 | ||||
-rw-r--r-- | sw/source/filter/xml/xmlfonte.cxx | 18 | ||||
-rw-r--r-- | xmloff/qa/unit/style.cxx | 53 |
4 files changed, 108 insertions, 12 deletions
diff --git a/editeng/source/items/textitem.cxx b/editeng/source/items/textitem.cxx index 64236dd542f1..22c86e4cabd1 100644 --- a/editeng/source/items/textitem.cxx +++ b/editeng/source/items/textitem.cxx @@ -153,6 +153,24 @@ bool SvxFontListItem::GetPresentation // class SvxFontItem ----------------------------------------------------- +namespace +{ +sal_Int32 CompareTo(sal_Int32 nA, sal_Int32 nB) +{ + if (nA < nB) + { + return -1; + } + + if (nA > nB) + { + return 1; + } + + return 0; +} +} + SvxFontItem::SvxFontItem( const sal_uInt16 nId ) : SfxPoolItem( nId ) { @@ -290,6 +308,36 @@ bool SvxFontItem::operator==( const SfxPoolItem& rAttr ) const return bRet; } +bool SvxFontItem::operator<(const SfxPoolItem& rCmp) const +{ + const auto& rOther = static_cast<const SvxFontItem&>(rCmp); + sal_Int32 nRet = GetFamilyName().compareTo(rOther.GetFamilyName()); + if (nRet != 0) + { + return nRet < 0; + } + + nRet = GetStyleName().compareTo(rOther.GetStyleName()); + if (nRet != 0) + { + return nRet < 0; + } + + nRet = CompareTo(GetFamily(), rOther.GetFamily()); + if (nRet != 0) + { + return nRet < 0; + } + + nRet = CompareTo(GetPitch(), rOther.GetPitch()); + if (nRet != 0) + { + return nRet < 0; + } + + return GetCharSet() < rOther.GetCharSet(); +} + SvxFontItem* SvxFontItem::Clone( SfxItemPool * ) const { return new SvxFontItem( *this ); diff --git a/include/editeng/fontitem.hxx b/include/editeng/fontitem.hxx index 9a73a051f79e..2ccaade20121 100644 --- a/include/editeng/fontitem.hxx +++ b/include/editeng/fontitem.hxx @@ -46,6 +46,7 @@ public: // "pure virtual Methods" from SfxPoolItem virtual bool operator==(const SfxPoolItem& rItem) const override; + bool operator<(const SfxPoolItem& rCmp) const override; virtual SvxFontItem* Clone(SfxItemPool *pPool = nullptr) const override; virtual bool QueryValue(css::uno::Any& rVal, sal_uInt8 nMemberId = 0) const override; virtual bool PutValue(const css::uno::Any& rVal, sal_uInt8 nMemberId) override; diff --git a/sw/source/filter/xml/xmlfonte.cxx b/sw/source/filter/xml/xmlfonte.cxx index ce415aeb41e5..b8c0f7730d57 100644 --- a/sw/source/filter/xml/xmlfonte.cxx +++ b/sw/source/filter/xml/xmlfonte.cxx @@ -46,21 +46,27 @@ SwXMLFontAutoStylePool_Impl::SwXMLFontAutoStylePool_Impl(SwXMLExport& _rExport, RES_CHRATR_CTL_FONT }; const SfxItemPool& rPool = _rExport.getDoc()->GetAttrPool(); + std::vector<const SvxFontItem *> aFonts; for(sal_uInt16 nWhichId : aWhichIds) { const SvxFontItem& rFont = static_cast<const SvxFontItem&>(rPool.GetDefaultItem( nWhichId )); - Add( rFont.GetFamilyName(), rFont.GetStyleName(), - rFont.GetFamily(), rFont.GetPitch(), - rFont.GetCharSet() ); + aFonts.push_back(&rFont); for (const SfxPoolItem* pItem : rPool.GetItemSurrogates(nWhichId)) { auto pFont = static_cast<const SvxFontItem *>(pItem); - Add( pFont->GetFamilyName(), pFont->GetStyleName(), - pFont->GetFamily(), pFont->GetPitch(), - pFont->GetCharSet() ); + aFonts.push_back(pFont); } } + + std::sort(aFonts.begin(), aFonts.end(), + [](const SvxFontItem* pA, const SvxFontItem* pB) -> bool { return *pA < *pB; }); + for (const auto& pFont : aFonts) + { + Add(pFont->GetFamilyName(), pFont->GetStyleName(), pFont->GetFamily(), pFont->GetPitch(), + pFont->GetCharSet()); + } + auto const & pDocument = _rExport.getDoc(); m_bEmbedUsedOnly = pDocument->getIDocumentSettingAccess().get(DocumentSettingId::EMBED_USED_FONTS); 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); |