summaryrefslogtreecommitdiff
path: root/sd
diff options
context:
space:
mode:
authorTomaž Vajngerl <tomaz.vajngerl@collabora.co.uk>2023-03-23 11:37:40 +0900
committerTomaž Vajngerl <quikee@gmail.com>2023-04-24 23:49:57 +0200
commitc3f7720ff13c34b9cf2c90d9c9b6dcc3d8f4c7a5 (patch)
tree98b24e4e90c0d858307b58bcd09c9b2d590893e8 /sd
parent09cdcb5f37bb4e42da7b28db6e757b9f2affed14 (diff)
oox: extend ThemeExport to export font and format scheme of a theme
Also use the ThemeExport when exporting PPTX documents and remove all the hard-coded theme bits. Change-Id: I03791e23d6ac4023748b5a553e4824b72ed63a93 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149363 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <quikee@gmail.com>
Diffstat (limited to 'sd')
-rw-r--r--sd/qa/filter/eppt/eppt.cxx85
-rw-r--r--sd/source/filter/eppt/epptooxml.hxx7
-rw-r--r--sd/source/filter/eppt/pptx-epptooxml.cxx316
3 files changed, 58 insertions, 350 deletions
diff --git a/sd/qa/filter/eppt/eppt.cxx b/sd/qa/filter/eppt/eppt.cxx
index 32d9b330a1dc..f5420a637751 100644
--- a/sd/qa/filter/eppt/eppt.cxx
+++ b/sd/qa/filter/eppt/eppt.cxx
@@ -12,6 +12,8 @@
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/drawing/XDrawPagesSupplier.hpp>
#include <com/sun/star/drawing/XMasterPageTarget.hpp>
+#include <com/sun/star/util/Color.hpp>
+#include <com/sun/star/util/XTheme.hpp>
#include <test/xmldocptr.hxx>
#include <docmodel/uno/UnoTheme.hxx>
@@ -56,40 +58,57 @@ CPPUNIT_TEST_FIXTURE(Test, testThemeExport)
{
// Given a document with a master slide and a theme, lt1 is set to 0x000002:
mxComponent = loadFromDesktop("private:factory/simpress");
- uno::Reference<drawing::XDrawPagesSupplier> xDrawPagesSupplier(mxComponent, uno::UNO_QUERY);
- uno::Reference<drawing::XMasterPageTarget> xDrawPage(
- xDrawPagesSupplier->getDrawPages()->getByIndex(0), uno::UNO_QUERY);
- uno::Reference<beans::XPropertySet> xMasterPage(xDrawPage->getMasterPage(), uno::UNO_QUERY);
-
- auto pTheme = std::make_shared<model::Theme>("mytheme");
- std::unique_ptr<model::ColorSet> pColorSet(new model::ColorSet("mycolorscheme"));
- pColorSet->add(model::ThemeColorType::Dark1, 0x1);
- pColorSet->add(model::ThemeColorType::Light1, 0x2);
- pColorSet->add(model::ThemeColorType::Dark2, 0x3);
- pColorSet->add(model::ThemeColorType::Light2, 0x4);
- pColorSet->add(model::ThemeColorType::Accent1, 0x5);
- pColorSet->add(model::ThemeColorType::Accent2, 0x6);
- pColorSet->add(model::ThemeColorType::Accent3, 0x7);
- pColorSet->add(model::ThemeColorType::Accent4, 0x8);
- pColorSet->add(model::ThemeColorType::Accent5, 0x9);
- pColorSet->add(model::ThemeColorType::Accent6, 0xa);
- pColorSet->add(model::ThemeColorType::Hyperlink, 0xb);
- pColorSet->add(model::ThemeColorType::FollowedHyperlink, 0xc);
- pTheme->SetColorSet(std::move(pColorSet));
-
- xMasterPage->setPropertyValue("Theme", uno::Any(model::theme::createXTheme(pTheme)));
-
- // When exporting to PPTX:
- save("Impress Office Open XML");
-
- // Then verify that this color is not lost:
+ {
+ uno::Reference<drawing::XDrawPagesSupplier> xDrawPagesSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<drawing::XMasterPageTarget> xDrawPage(
+ xDrawPagesSupplier->getDrawPages()->getByIndex(0), uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xMasterPage(xDrawPage->getMasterPage(), uno::UNO_QUERY);
+
+ auto pTheme = std::make_shared<model::Theme>("mytheme");
+ std::unique_ptr<model::ColorSet> pColorSet(new model::ColorSet("mycolorscheme"));
+ pColorSet->add(model::ThemeColorType::Dark1, 0x111111);
+ pColorSet->add(model::ThemeColorType::Light1, 0x222222);
+ pColorSet->add(model::ThemeColorType::Dark2, 0x333333);
+ pColorSet->add(model::ThemeColorType::Light2, 0x444444);
+ pColorSet->add(model::ThemeColorType::Accent1, 0x555555);
+ pColorSet->add(model::ThemeColorType::Accent2, 0x666666);
+ pColorSet->add(model::ThemeColorType::Accent3, 0x777777);
+ pColorSet->add(model::ThemeColorType::Accent4, 0x888888);
+ pColorSet->add(model::ThemeColorType::Accent5, 0x999999);
+ pColorSet->add(model::ThemeColorType::Accent6, 0xaaaaaa);
+ pColorSet->add(model::ThemeColorType::Hyperlink, 0xbbbbbb);
+ pColorSet->add(model::ThemeColorType::FollowedHyperlink, 0xcccccc);
+ pTheme->SetColorSet(std::move(pColorSet));
+
+ xMasterPage->setPropertyValue("Theme", uno::Any(model::theme::createXTheme(pTheme)));
+ }
+
+ // Export to PPTX and load again:
+ saveAndReload("Impress Office Open XML");
+
+ // Verify that this color is not lost:
xmlDocUniquePtr pXmlDoc = parseExport("ppt/theme/theme1.xml");
- assertXPath(pXmlDoc, "//a:clrScheme/a:lt1/a:srgbClr", "val", "000002");
- // Without the fix in place, this test would have failed with:
- // - Expected: 1
- // - Actual : 0
- // - XPath '//a:clrScheme/a:lt1/a:srgbClr' number of nodes is incorrect
- // i.e. the RGB color was lost on export.
+ assertXPath(pXmlDoc, "//a:clrScheme/a:lt1/a:srgbClr", "val",
+ "222222"); // expected color 22-22-22
+
+ // Check the theme after loading again
+ {
+ uno::Reference<drawing::XDrawPagesSupplier> xDrawPagesSupplier(mxComponent, uno::UNO_QUERY);
+ uno::Reference<drawing::XMasterPageTarget> xDrawPage(
+ xDrawPagesSupplier->getDrawPages()->getByIndex(0), uno::UNO_QUERY);
+ uno::Reference<beans::XPropertySet> xMasterPage(xDrawPage->getMasterPage(), uno::UNO_QUERY);
+ uno::Reference<util::XTheme> xTheme(xMasterPage->getPropertyValue("Theme"), uno::UNO_QUERY);
+ CPPUNIT_ASSERT_EQUAL(true, xTheme.is());
+
+ auto* pUnoTheme = dynamic_cast<UnoTheme*>(xTheme.get());
+ CPPUNIT_ASSERT(pUnoTheme);
+ auto pTheme = pUnoTheme->getTheme();
+
+ CPPUNIT_ASSERT_EQUAL(OUString("mytheme"), pTheme->GetName());
+ CPPUNIT_ASSERT_EQUAL(OUString("mycolorscheme"), pTheme->GetColorSet()->getName());
+ CPPUNIT_ASSERT_EQUAL(OUString("Office"), pTheme->getFontScheme().getName());
+ CPPUNIT_ASSERT_EQUAL(OUString(""), pTheme->getFormatScheme().getName());
+ }
}
CPPUNIT_TEST_FIXTURE(Test, testLoopingFromAnimation)
diff --git a/sd/source/filter/eppt/epptooxml.hxx b/sd/source/filter/eppt/epptooxml.hxx
index 48c928d60abb..0c7644c72b3d 100644
--- a/sd/source/filter/eppt/epptooxml.hxx
+++ b/sd/source/filter/eppt/epptooxml.hxx
@@ -90,13 +90,6 @@ private:
virtual void ImplWriteNotes( sal_uInt32 nPageNum ) override;
virtual void ImplWriteSlideMaster( sal_uInt32 nPageNum, css::uno::Reference< css::beans::XPropertySet > const & aXBackgroundPropSet ) override;
void ImplWritePPTXLayout( sal_Int32 nOffset, sal_uInt32 nMasterNum );
-
- /// Export the color set part of a theme.
- static bool WriteColorSets(const FSHelperPtr& pFS, model::Theme* pTheme);
-
- /// Same as WriteColorSets(), but works from a grab-bag.
- bool WriteColorSchemes(const FSHelperPtr& pFS, const OUString& rThemePath);
-
static void WriteDefaultColorSchemes(const FSHelperPtr& pFS);
void WriteTheme( sal_Int32 nThemeNum, model::Theme* pTheme );
diff --git a/sd/source/filter/eppt/pptx-epptooxml.cxx b/sd/source/filter/eppt/pptx-epptooxml.cxx
index c0215ecca162..9e207baf1be6 100644
--- a/sd/source/filter/eppt/pptx-epptooxml.cxx
+++ b/sd/source/filter/eppt/pptx-epptooxml.cxx
@@ -56,6 +56,7 @@
#include <comphelper/diagnose_ex.hxx>
#include <oox/export/utils.hxx>
+#include <oox/export/ThemeExport.hxx>
#include <docmodel/theme/Theme.hxx>
#include "pptx-animations.hxx"
@@ -1938,172 +1939,6 @@ ShapeExport& PowerPointShapeExport::WritePlaceholderReferenceTextBody(
return *this;
}
-#define SYS_COLOR_SCHEMES " <a:dk1>\
- <a:sysClr val=\"windowText\" lastClr=\"000000\"/>\
- </a:dk1>\
- <a:lt1>\
- <a:sysClr val=\"window\" lastClr=\"FFFFFF\"/>\
- </a:lt1>"
-
-#define MINIMAL_THEME " <a:fontScheme name=\"Office\">\
- <a:majorFont>\
- <a:latin typeface=\"Arial\"/>\
- <a:ea typeface=\"DejaVu Sans\"/>\
- <a:cs typeface=\"DejaVu Sans\"/>\
- </a:majorFont>\
- <a:minorFont>\
- <a:latin typeface=\"Arial\"/>\
- <a:ea typeface=\"DejaVu Sans\"/>\
- <a:cs typeface=\"DejaVu Sans\"/>\
- </a:minorFont>\
- </a:fontScheme>\
- <a:fmtScheme name=\"Office\">\
- <a:fillStyleLst>\
- <a:solidFill>\
- <a:schemeClr val=\"phClr\"/>\
- </a:solidFill>\
- <a:gradFill rotWithShape=\"1\">\
- <a:gsLst>\
- <a:gs pos=\"0\">\
- <a:schemeClr val=\"phClr\">\
- <a:tint val=\"50000\"/>\
- <a:satMod val=\"300000\"/>\
- </a:schemeClr>\
- </a:gs>\
- <a:gs pos=\"35000\">\
- <a:schemeClr val=\"phClr\">\
- <a:tint val=\"37000\"/>\
- <a:satMod val=\"300000\"/>\
- </a:schemeClr>\
- </a:gs>\
- <a:gs pos=\"100000\">\
- <a:schemeClr val=\"phClr\">\
- <a:tint val=\"15000\"/>\
- <a:satMod val=\"350000\"/>\
- </a:schemeClr>\
- </a:gs>\
- </a:gsLst>\
- <a:lin ang=\"16200000\" scaled=\"1\"/>\
- </a:gradFill>\
- <a:gradFill rotWithShape=\"1\">\
- <a:gsLst>\
- <a:gs pos=\"0\">\
- <a:schemeClr val=\"phClr\">\
- <a:shade val=\"51000\"/>\
- <a:satMod val=\"130000\"/>\
- </a:schemeClr>\
- </a:gs>\
- <a:gs pos=\"80000\">\
- <a:schemeClr val=\"phClr\">\
- <a:shade val=\"93000\"/>\
- <a:satMod val=\"130000\"/>\
- </a:schemeClr>\
- </a:gs>\
- <a:gs pos=\"100000\">\
- <a:schemeClr val=\"phClr\">\
- <a:shade val=\"94000\"/>\
- <a:satMod val=\"135000\"/>\
- </a:schemeClr>\
- </a:gs>\
- </a:gsLst>\
- <a:lin ang=\"16200000\" scaled=\"0\"/>\
- </a:gradFill>\
- </a:fillStyleLst>\
- <a:lnStyleLst>\
- <a:ln w=\"6350\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\">\
- <a:solidFill>\
- <a:schemeClr val=\"phClr\">\
- <a:shade val=\"95000\"/>\
- <a:satMod val=\"105000\"/>\
- </a:schemeClr>\
- </a:solidFill>\
- <a:prstDash val=\"solid\"/>\
- <a:miter/>\
- </a:ln>\
- <a:ln w=\"12700\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\">\
- <a:solidFill>\
- <a:schemeClr val=\"phClr\"/>\
- </a:solidFill>\
- <a:prstDash val=\"solid\"/>\
- <a:miter/>\
- </a:ln>\
- <a:ln w=\"19050\" cap=\"flat\" cmpd=\"sng\" algn=\"ctr\">\
- <a:solidFill>\
- <a:schemeClr val=\"phClr\"/>\
- </a:solidFill>\
- <a:prstDash val=\"solid\"/>\
- <a:miter/>\
- </a:ln>\
- </a:lnStyleLst>\
- <a:effectStyleLst>\
- <a:effectStyle>\
- <a:effectLst/>\
- </a:effectStyle>\
- <a:effectStyle>\
- <a:effectLst/>\
- </a:effectStyle>\
- <a:effectStyle>\
- <a:effectLst>\
- <a:outerShdw blurRad=\"40000\" dist=\"23000\" dir=\"5400000\" rotWithShape=\"0\">\
- <a:srgbClr val=\"000000\">\
- <a:alpha val=\"35000\"/>\
- </a:srgbClr>\
- </a:outerShdw>\
- </a:effectLst>\
- </a:effectStyle>\
- </a:effectStyleLst>\
- <a:bgFillStyleLst>\
- <a:solidFill>\
- <a:schemeClr val=\"phClr\"/>\
- </a:solidFill>\
- <a:gradFill rotWithShape=\"1\">\
- <a:gsLst>\
- <a:gs pos=\"0\">\
- <a:schemeClr val=\"phClr\">\
- <a:tint val=\"40000\"/>\
- <a:satMod val=\"350000\"/>\
- </a:schemeClr>\
- </a:gs>\
- <a:gs pos=\"40000\">\
- <a:schemeClr val=\"phClr\">\
- <a:tint val=\"45000\"/>\
- <a:shade val=\"99000\"/>\
- <a:satMod val=\"350000\"/>\
- </a:schemeClr>\
- </a:gs>\
- <a:gs pos=\"100000\">\
- <a:schemeClr val=\"phClr\">\
- <a:shade val=\"20000\"/>\
- <a:satMod val=\"255000\"/>\
- </a:schemeClr>\
- </a:gs>\
- </a:gsLst>\
- <a:path path=\"circle\">\
- <a:fillToRect l=\"50000\" t=\"-80000\" r=\"50000\" b=\"180000\"/>\
- </a:path>\
- </a:gradFill>\
- <a:gradFill rotWithShape=\"1\">\
- <a:gsLst>\
- <a:gs pos=\"0\">\
- <a:schemeClr val=\"phClr\">\
- <a:tint val=\"80000\"/>\
- <a:satMod val=\"300000\"/>\
- </a:schemeClr>\
- </a:gs>\
- <a:gs pos=\"100000\">\
- <a:schemeClr val=\"phClr\">\
- <a:shade val=\"30000\"/>\
- <a:satMod val=\"200000\"/>\
- </a:schemeClr>\
- </a:gs>\
- </a:gsLst>\
- <a:path path=\"circle\">\
- <a:fillToRect l=\"50000\" t=\"50000\" r=\"50000\" b=\"50000\"/>\
- </a:path>\
- </a:gradFill>\
- </a:bgFillStyleLst>\
- </a:fmtScheme>"
-
void PowerPointExport::WriteDefaultColorSchemes(const FSHelperPtr& pFS)
{
for (int nId = PredefinedClrSchemeId::dk2; nId != PredefinedClrSchemeId::Count; nId++)
@@ -2155,155 +1990,15 @@ void PowerPointExport::WriteDefaultColorSchemes(const FSHelperPtr& pFS)
}
}
-bool PowerPointExport::WriteColorSets(const FSHelperPtr& pFS, model::Theme* pTheme)
-{
- static std::map<PredefinedClrSchemeId, sal_Int32> aPredefinedClrTokens =
- {
- { dk1, XML_dk1 },
- { lt1, XML_lt1 },
- { dk2, XML_dk2 },
- { lt2, XML_lt2 },
- { accent1, XML_accent1 },
- { accent2, XML_accent2 },
- { accent3, XML_accent3 },
- { accent4, XML_accent4 },
- { accent5, XML_accent5 },
- { accent6, XML_accent6 },
- { hlink, XML_hlink },
- { folHlink, XML_folHlink }
- };
-
- if (!pTheme)
- {
- return false;
- }
-
- model::ColorSet* pColorSet = pTheme->GetColorSet();
- if (!pColorSet)
- {
- return false;
- }
-
- for (int nId = PredefinedClrSchemeId::dk1; nId < PredefinedClrSchemeId::Count; nId++)
- {
- sal_Int32 nToken = aPredefinedClrTokens[static_cast<PredefinedClrSchemeId>(nId)];
- pFS->startElementNS(XML_a, nToken);
- model::ThemeColorType eType = model::convertToThemeColorType(nId);
- pFS->singleElementNS(XML_a, XML_srgbClr, XML_val, I32SHEX(static_cast<sal_Int32>(pColorSet->getColor(eType))));
- pFS->endElementNS(XML_a, nToken);
- }
-
- return true;
-}
-
-bool PowerPointExport::WriteColorSchemes(const FSHelperPtr& pFS, const OUString& rThemePath)
-{
- try
- {
- uno::Reference<beans::XPropertySet> xDocProps(getModel(), uno::UNO_QUERY);
- if (xDocProps.is())
- {
- uno::Reference<beans::XPropertySetInfo> xPropsInfo = xDocProps->getPropertySetInfo();
-
- static const OUStringLiteral aGrabBagPropName = u"InteropGrabBag";
- if (xPropsInfo.is() && xPropsInfo->hasPropertyByName(aGrabBagPropName))
- {
- comphelper::SequenceAsHashMap aGrabBag(xDocProps->getPropertyValue(aGrabBagPropName));
- uno::Sequence<beans::PropertyValue> aCurrentTheme;
-
- aGrabBag.getValue(rThemePath) >>= aCurrentTheme;
-
- if (!aCurrentTheme.hasElements())
- return false;
-
- // Order is important
- for (int nId = PredefinedClrSchemeId::dk2; nId != PredefinedClrSchemeId::Count; nId++)
- {
- OUString sName = PredefinedClrNames[static_cast<PredefinedClrSchemeId>(nId)];
- sal_Int32 nColor = 0;
-
- for (auto aIt = std::cbegin(aCurrentTheme); aIt != std::cend(aCurrentTheme); aIt++)
- {
- if (aIt->Name == sName)
- {
- aIt->Value >>= nColor;
- break;
- }
- }
-
- OUString sOpenColorScheme ="<a:" + sName + ">";
- pFS->write(sOpenColorScheme);
-
- pFS->singleElementNS(XML_a, XML_srgbClr, XML_val, I32SHEX(nColor));
-
- OUString sCloseColorScheme = "</a:" + sName + ">";
- pFS->write(sCloseColorScheme);
- }
-
- // TODO: write complete color schemes & only if successful, protection against partial export
- return true;
- }
- }
- }
- catch (const uno::Exception&)
- {
- SAL_WARN("writerfilter", "Failed to save documents grab bag");
- }
-
- return false;
-}
-
void PowerPointExport::WriteTheme(sal_Int32 nThemeNum, model::Theme* pTheme)
{
+ if (!pTheme)
+ return;
OUString sThemePath = "ppt/theme/theme" + OUString::number(nThemeNum + 1) + ".xml";
- FSHelperPtr pFS = openFragmentStreamWithSerializer(sThemePath,
- "application/vnd.openxmlformats-officedocument.theme+xml");
-
- OUString aThemeName("Office Theme");
- if (pTheme)
- {
- aThemeName = pTheme->GetName();
- }
- pFS->startElementNS(XML_a, XML_theme,
- FSNS(XML_xmlns, XML_a), this->getNamespaceURL(OOX_NS(dml)),
- XML_name, aThemeName);
-
- pFS->startElementNS(XML_a, XML_themeElements);
- OUString aColorSchemeName("Office");
- if (pTheme)
- {
- model::ColorSet* pColorSet = pTheme->GetColorSet();
- if (pColorSet)
- {
- aColorSchemeName = pColorSet->getName();
- }
- }
- pFS->startElementNS(XML_a, XML_clrScheme, XML_name, aColorSchemeName);
+ oox::ThemeExport aThemeExport(this);
- if (!WriteColorSets(pFS, pTheme))
- {
- pFS->write(SYS_COLOR_SCHEMES);
- if (!WriteColorSchemes(pFS, sThemePath))
- {
- // if style is not defined, try to use first one
- if (!WriteColorSchemes(pFS, "ppt/theme/theme1.xml"))
- {
- // color schemes are required - use default values
- WriteDefaultColorSchemes(pFS);
- }
- }
- }
-
- pFS->endElementNS(XML_a, XML_clrScheme);
-
- // export remaining part
- pFS->write(MINIMAL_THEME);
-
- pFS->endElementNS(XML_a, XML_themeElements);
- pFS->endElementNS(XML_a, XML_theme);
-
- pFS->endDocument();
+ aThemeExport.write(sThemePath, *pTheme);
}
bool PowerPointExport::ImplCreateDocument()
@@ -2344,6 +2039,7 @@ void PowerPointExport::WriteNotesMaster()
openFragmentStreamWithSerializer("ppt/notesMasters/notesMaster1.xml",
"application/vnd.openxmlformats-officedocument.presentationml.notesMaster+xml");
// write theme per master
+
WriteTheme(mnMasterPages, nullptr);
// add implicit relation to the presentation theme