From 1b7bdc29559caba53fb3de9820110c633bf00a27 Mon Sep 17 00:00:00 2001 From: Regina Henschel Date: Thu, 7 Nov 2024 19:24:03 +0100 Subject: [PATCH] tdf#162686 tdf#162687 ODF 1.4 extrusion-metal-type and extrusion-specularity. In ODF strict always value 'draw:MetalODF' was written. Changed the logic to write 'loext:MetalMSCompatible' too, depending on eMetalType. Using a QName as value requires a namespace declaration for the prefix 'loext'. That is now written directly at the element, not as global declaration, to restrict its scope to the element. A global declaration would hide when attributes or elements are accidentially written in 'loext' namespace. The pattern for nonNegativePercent had missed the percent sign. The export is adapted to write the percent sign. Validation is skipped for save to ODF 1.3, because currently the implicit validation uses always latest ODF version, see tdf#163806. Tests are extended to cover ODF 1.4 and value draw:MetalODF. Change-Id: I836d11b9cd327b9772e800d9797e04e1613ab2f9 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/176246 Tested-by: Jenkins Reviewed-by: Regina Henschel --- .../OpenDocument-v1.4+libreoffice-schema.rng | 18 - schema/odf1.4/OpenDocument-v1.4-schema.rng | 2 +- .../data/tdf162686_3D_metal_type_ODF.fods | 337 ++++++++++++++++++ xmloff/qa/unit/draw.cxx | 118 +++++- xmloff/source/draw/shapeexport.cxx | 37 +- 5 files changed, 466 insertions(+), 46 deletions(-) create mode 100644 xmloff/qa/unit/data/tdf162686_3D_metal_type_ODF.fods diff --git a/schema/libreoffice/OpenDocument-v1.4+libreoffice-schema.rng b/schema/libreoffice/OpenDocument-v1.4+libreoffice-schema.rng index d24889bce097..1dd70cfdbe26 100644 --- a/schema/libreoffice/OpenDocument-v1.4+libreoffice-schema.rng +++ b/schema/libreoffice/OpenDocument-v1.4+libreoffice-schema.rng @@ -2951,24 +2951,6 @@ xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1. - - - - - - - - - - - - - - - - - - diff --git a/schema/odf1.4/OpenDocument-v1.4-schema.rng b/schema/odf1.4/OpenDocument-v1.4-schema.rng index 169c5c8f6cd4..c444dd15e52c 100644 --- a/schema/odf1.4/OpenDocument-v1.4-schema.rng +++ b/schema/odf1.4/OpenDocument-v1.4-schema.rng @@ -7075,7 +7075,7 @@ - ([0-9]+(\.[0-9]*)?|\.[0-9]+) + ([0-9]+(\.[0-9]*)?|\.[0-9]+)% diff --git a/xmloff/qa/unit/data/tdf162686_3D_metal_type_ODF.fods b/xmloff/qa/unit/data/tdf162686_3D_metal_type_ODF.fods new file mode 100644 index 000000000000..3ed0abf15667 --- /dev/null +++ b/xmloff/qa/unit/data/tdf162686_3D_metal_type_ODF.fods @@ -0,0 +1,337 @@ + + + + + LibreOfficeDev/25.2.0.0.alpha0$Windows_X86_64 LibreOffice_project/957fea5f3d554c870903687d56e49d4777b69ef8 + + + + + + 0 + 0 + 9031 + 4064 + + + view1 + + + 5 + 6 + 2 + 0 + 0 + 0 + 0 + 0 + 100 + 60 + true + false + false + false + false + + + Sheet1 + 991 + 0 + 100 + 60 + false + true + true + true + false + true + 12632256 + 1 + true + true + true + false + false + false + 1000 + 1000 + 1 + 1 + true + false + false + false + false + + + + + true + true + true + true + false + true + 12632256 + true + false + 3 + true + true + true + true + false + false + 1000 + 1000 + 1 + 1 + true + true + true + 0 + false + true + 0 + false + true + true + false + false + false + false + true + 7 + + + Sheet1 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ??? + + + + + Page 1 + + + + + + + + ???(???) + + + 00.00.0000, 00:00:00 + + + + + + Page 1/ 99 + + + + + + + + + + + + + + + + + + Dummy + + + + + + + \ No newline at end of file diff --git a/xmloff/qa/unit/draw.cxx b/xmloff/qa/unit/draw.cxx index 198173350d73..c72bf57c7e9c 100644 --- a/xmloff/qa/unit/draw.cxx +++ b/xmloff/qa/unit/draw.cxx @@ -497,9 +497,11 @@ CPPUNIT_TEST_FIXTURE(XmloffDrawTest, testTableInShape) } // Tests for save/load of new (LO 7.4) attribute loext:extrusion-metal-type +// Since ODF 1.4 it is available as draw:extrusion-metal-type in the standard. namespace { -void lcl_assertMetalProperties(std::string_view sInfo, uno::Reference& rxShape) +void lcl_assertMetalProperties(std::string_view sInfo, uno::Reference& rxShape, + sal_Int16 nExpectedMetalType) { uno::Reference xShapeProps(rxShape, uno::UNO_QUERY); uno::Sequence aGeoPropSeq; @@ -517,8 +519,7 @@ void lcl_assertMetalProperties(std::string_view sInfo, uno::Reference>= nMetalType; sMsg = OString::Concat(sInfo) + " MetalType"; - CPPUNIT_ASSERT_EQUAL_MESSAGE( - sMsg.getStr(), css::drawing::EnhancedCustomShapeMetalType::MetalMSCompatible, nMetalType); + CPPUNIT_ASSERT_EQUAL_MESSAGE(sMsg.getStr(), nExpectedMetalType, nMetalType); } } @@ -528,34 +529,108 @@ CPPUNIT_TEST_FIXTURE(XmloffDrawTest, testExtrusionMetalTypeExtended) loadFromFile(u"tdf145700_3D_metal_type_MSCompatible.doc"); // verify properties uno::Reference xShape(getShape(0)); - lcl_assertMetalProperties("from doc", xShape); + lcl_assertMetalProperties("from doc", xShape, + css::drawing::EnhancedCustomShapeMetalType::MetalMSCompatible); - // Test, that new attribute is written with loext namespace. Adapt when attribute is added to ODF. - SetODFDefaultVersion(SvtSaveOptions::ODFVER_013_EXTENDED); + // Test, that attribute is written with 'draw' namespace in ODF version LATEST saveAndReload(u"writer8"_ustr); // assert XML. xmlDocUniquePtr pXmlDoc = parseExport(u"content.xml"_ustr); assertXPath(pXmlDoc, "//draw:enhanced-geometry", "extrusion-metal", u"true"); assertXPath(pXmlDoc, - "//draw:enhanced-geometry[@loext:extrusion-metal-type='loext:MetalMSCompatible']"); + "//draw:enhanced-geometry[@draw:extrusion-metal-type='loext:MetalMSCompatible']"); // verify properties uno::Reference xShapeReload(getShape(0)); - lcl_assertMetalProperties("from ODF 1.3 extended", xShapeReload); + lcl_assertMetalProperties("from LATEST", xShapeReload, + css::drawing::EnhancedCustomShapeMetalType::MetalMSCompatible); + + // Test, that attribute is written with 'loext' namespace in extended version before ODF 1.4 + SetODFDefaultVersion(SvtSaveOptions::ODFVER_013_EXTENDED); + // As of Nov 2024, validating against a version other than LATEST is not implemented. + skipValidation(); + saveAndReload(u"writer8"_ustr); + + // assert XML. + pXmlDoc = parseExport(u"content.xml"_ustr); + assertXPath(pXmlDoc, "//draw:enhanced-geometry", "extrusion-metal", u"true"); + assertXPath(pXmlDoc, + "//draw:enhanced-geometry[@loext:extrusion-metal-type='loext:MetalMSCompatible']"); + + // verify properties + uno::Reference xShapeReload2(getShape(0)); + lcl_assertMetalProperties("from ODF 1.3 extended", xShapeReload2, + css::drawing::EnhancedCustomShapeMetalType::MetalMSCompatible); } CPPUNIT_TEST_FIXTURE(XmloffDrawTest, testExtrusionMetalTypeStrict) { + Resetter resetter([]() { SetODFDefaultVersion(SvtSaveOptions::ODFVER_LATEST); }); loadFromFile(u"tdf145700_3D_metal_type_MSCompatible.doc"); - // save ODF 1.4 strict and test that new attribute is written. + // save in ODF 1.4 strict and test that new attribute is written. + SetODFDefaultVersion(SvtSaveOptions::ODFVER_014); save(u"writer8"_ustr); + xmlDocUniquePtr pXmlDoc = parseExport(u"content.xml"_ustr); + assertXPath(pXmlDoc, "//draw:enhanced-geometry", "extrusion-metal", u"true"); + assertXPath(pXmlDoc, + "//draw:enhanced-geometry[@draw:extrusion-metal-type='loext:MetalMSCompatible']"); + + // save in ODF 1.3 strict and test that new attribute is not written. + SetODFDefaultVersion(SvtSaveOptions::ODFVER_013); + save(u"writer8"_ustr); + pXmlDoc = parseExport(u"content.xml"_ustr); + assertXPath(pXmlDoc, "//draw:enhanced-geometry", "extrusion-metal", u"true"); + assertXPathNoAttribute(pXmlDoc, "//draw:enhanced-geometry", "extrusion-metal-type"); +} + +CPPUNIT_TEST_FIXTURE(XmloffDrawTest, testExtrusionMetalTypeODF) +{ + Resetter resetter([]() { SetODFDefaultVersion(SvtSaveOptions::ODFVER_LATEST); }); + loadFromFile(u"tdf162686_3D_metal_type_ODF.fods"); + // verify properties + uno::Reference xShape(getShape(0)); + lcl_assertMetalProperties("from doc", xShape, + css::drawing::EnhancedCustomShapeMetalType::MetalODF); + + // Test, that attribute is written with 'draw' namespace in ODF version LATEST + saveAndReload(u"calc8"_ustr); // assert XML. xmlDocUniquePtr pXmlDoc = parseExport(u"content.xml"_ustr); assertXPath(pXmlDoc, "//draw:enhanced-geometry", "extrusion-metal", u"true"); - assertXPath(pXmlDoc, "//draw:enhanced-geometry[@draw:extrusion-metal-type]", 1); + assertXPath(pXmlDoc, "//draw:enhanced-geometry[@draw:extrusion-metal-type='draw:MetalODF']"); + + // verify properties + uno::Reference xShapeReload(getShape(0)); + lcl_assertMetalProperties("from LATEST", xShapeReload, + css::drawing::EnhancedCustomShapeMetalType::MetalODF); + + // Test, that export in ODFVER_014 is valid. Needs adaption, when ODF 1.5 comes out. + SetODFDefaultVersion(SvtSaveOptions::ODFVER_014); + saveAndReload(u"calc8"_ustr); + + // Test, that attribute is written with 'loext' namespace in extended version before ODF 1.4 + SetODFDefaultVersion(SvtSaveOptions::ODFVER_013_EXTENDED); + // As of Nov 2024, validating against a version other than LATEST is not implemented. + skipValidation(); + saveAndReload(u"calc8"_ustr); + + // assert XML. + pXmlDoc = parseExport(u"content.xml"_ustr); + assertXPath(pXmlDoc, "//draw:enhanced-geometry[@loext:extrusion-metal-type='draw:MetalODF']"); + + // verify properties + uno::Reference xShapeReload2(getShape(0)); + lcl_assertMetalProperties("from ODF 1.3 extended", xShapeReload2, + css::drawing::EnhancedCustomShapeMetalType::MetalODF); + + // Test, that attribute is not written at all in strict version before ODF 1.4 + SetODFDefaultVersion(SvtSaveOptions::ODFVER_013); + save(u"calc8"_ustr); + pXmlDoc = parseExport(u"content.xml"_ustr); + assertXPathNoAttribute(pXmlDoc, "//draw:enhanced-geometry", "extrusion-metal-type"); } namespace @@ -588,11 +663,13 @@ CPPUNIT_TEST_FIXTURE(XmloffDrawTest, testExtrusionSpecularityExtended) // Test, that attribute is written in draw namespace with value 100% and in loext namespace with // value 122.0703125%. SetODFDefaultVersion(SvtSaveOptions::ODFVER_013_EXTENDED); + // As of Nov 2024, validating against a version other than LATEST is not implemented. + skipValidation(); saveAndReload(u"writer8"_ustr); // assert XML. xmlDocUniquePtr pXmlDoc = parseExport(u"content.xml"_ustr); - assertXPath(pXmlDoc, "//draw:enhanced-geometry[@draw:extrusion-specularity='100']"); + assertXPath(pXmlDoc, "//draw:enhanced-geometry[@draw:extrusion-specularity='100%']"); assertXPath(pXmlDoc, "//draw:enhanced-geometry[@loext:extrusion-specularity-loext='122.0703125%']"); @@ -601,7 +678,7 @@ CPPUNIT_TEST_FIXTURE(XmloffDrawTest, testExtrusionSpecularityExtended) lcl_assertSpecularityProperty("from ODF 1.3 extended", xShapeReload); } -CPPUNIT_TEST_FIXTURE(XmloffDrawTest, testExtrusionSpecularityStrict) +CPPUNIT_TEST_FIXTURE(XmloffDrawTest, testExtrusionSpecularity) { loadFromFile(u"tdf147580_extrusion-specularity.doc"); // verify property @@ -612,22 +689,33 @@ CPPUNIT_TEST_FIXTURE(XmloffDrawTest, testExtrusionSpecularityStrict) // assert XML. xmlDocUniquePtr pXmlDoc = parseExport(u"content.xml"_ustr); - assertXPath(pXmlDoc, "//draw:enhanced-geometry[@draw:extrusion-specularity='122.0703125']"); + assertXPath(pXmlDoc, "//draw:enhanced-geometry[@draw:extrusion-specularity='122.0703125%']"); // verify properties uno::Reference xShapeReload(getShape(0)); lcl_assertSpecularityProperty("from ODF 1.4", xShapeReload); } -CPPUNIT_TEST_FIXTURE(XmloffDrawTest, testExtrusionSpecularity) +CPPUNIT_TEST_FIXTURE(XmloffDrawTest, testExtrusionSpecularityStrict) { Resetter resetter([]() { SetODFDefaultVersion(SvtSaveOptions::ODFVER_LATEST); }); loadFromFile(u"tdf147580_extrusion-specularity.doc"); // The file has c3DSpecularAmt="80000" which results internally in specularity=122%. - // Save to ODF 1.3 strict and make sure it does not produce a validation error. + SetODFDefaultVersion(SvtSaveOptions::ODFVER_014); + save(u"writer8"_ustr); + xmlDocUniquePtr pXmlDoc = parseExport(u"content.xml"_ustr); + assertXPath(pXmlDoc, "//draw:enhanced-geometry[@draw:extrusion-specularity='122.0703125%']"); + + // Save to ODF 1.3 strict and make sure draw:extrusion-specularity="100%" is written and + // loext:extrusion-specularity is not written. + // As of Nov 2024, validating against a version other than LATEST is not implemented. + skipValidation(); SetODFDefaultVersion(SvtSaveOptions::ODFVER_013); save(u"writer8"_ustr); + pXmlDoc = parseExport(u"content.xml"_ustr); + assertXPath(pXmlDoc, "//draw:enhanced-geometry[@loext:extrusion-specularity]", 0); + assertXPath(pXmlDoc, "//draw:enhanced-geometry[@draw:extrusion-specularity='100%']"); } namespace diff --git a/xmloff/source/draw/shapeexport.cxx b/xmloff/source/draw/shapeexport.cxx index 5af74d7fc93a..81e83550c82f 100644 --- a/xmloff/source/draw/shapeexport.cxx +++ b/xmloff/source/draw/shapeexport.cxx @@ -4599,22 +4599,26 @@ static void ImpExportEnhancedGeometry( SvXMLExport& rExport, const uno::Referenc break; case EAS_MetalType : { - // export only if ODF extensions are enabled + // In ODF since ODF 1.4. Before 1.4, export only in extended. sal_Int16 eMetalType; if (rProp.Value >>= eMetalType) { + // LibreOffice had used the same values as later specified in ODF 1.4 + if (eMetalType == drawing::EnhancedCustomShapeMetalType::MetalMSCompatible) + aStr = "loext:MetalMSCompatible"; + else + aStr = "draw:MetalODF"; + SvtSaveOptions::ODFSaneDefaultVersion eVersion = rExport.getSaneDefaultVersion(); if (eVersion >= SvtSaveOptions::ODFSVER_014) { - aStr = "draw:MetalODF"; + if (!(eVersion & SvtSaveOptions::ODFSVER_EXTENDED) + && eMetalType == drawing::EnhancedCustomShapeMetalType::MetalMSCompatible) + rExport.AddAttribute(XML_NAMESPACE_XMLNS, XML_NP_LO_EXT, XML_N_LO_EXT); rExport.AddAttribute(XML_NAMESPACE_DRAW, XML_EXTRUSION_METAL_TYPE, aStr); } else if (eVersion & SvtSaveOptions::ODFSVER_EXTENDED) { - if (eMetalType == drawing::EnhancedCustomShapeMetalType::MetalMSCompatible) - aStr = "loext:MetalMSCompatible"; - else - aStr = "draw:MetalODF"; rExport.AddAttribute(XML_NAMESPACE_LO_EXT, XML_EXTRUSION_METAL_TYPE, aStr); } } @@ -4703,8 +4707,11 @@ static void ImpExportEnhancedGeometry( SvXMLExport& rExport, const uno::Referenc double fExtrusionSpecularity = 0; if ( rProp.Value >>= fExtrusionSpecularity ) { + // ODF 1.0/1.1 allow arbitrary percent, ODF 1.2/1.3 restrict it to 0%-100%, + // ODF 1.4 restricts it to non negative percent. SvtSaveOptions::ODFSaneDefaultVersion eVersion = rExport.getSaneDefaultVersion(); - if (fExtrusionSpecularity > 100.0 && eVersion & SvtSaveOptions::ODFSVER_EXTENDED) + if (fExtrusionSpecularity > 100.0 && eVersion & SvtSaveOptions::ODFSVER_EXTENDED + && eVersion >= SvtSaveOptions::ODFSVER_012 && eVersion < SvtSaveOptions::ODFSVER_014) { // tdf#147580 write values > 100% in loext ::sax::Converter::convertDouble( @@ -4717,14 +4724,20 @@ static void ImpExportEnhancedGeometry( SvXMLExport& rExport, const uno::Referenc aStr = aStrBuffer.makeStringAndClear(); rExport.AddAttribute( XML_NAMESPACE_LO_EXT, XML_EXTRUSION_SPECULARITY_LOEXT, aStr ); } - // tdf#147580 ODF 1 allows arbitrary percent, later versions not + // clamp fExtrusionSpecularity to allowed values if (eVersion >= SvtSaveOptions::ODFSVER_012 && eVersion < SvtSaveOptions::ODFSVER_014) - { fExtrusionSpecularity = std::clamp(fExtrusionSpecularity, 0.0, 100.0); - } - ::sax::Converter::convertDouble( aStrBuffer, fExtrusionSpecularity ); + else if (eVersion >= SvtSaveOptions::ODFSVER_014) + fExtrusionSpecularity = std::max(0.0, fExtrusionSpecularity); + // write percent + ::sax::Converter::convertDouble( + aStrBuffer, + fExtrusionSpecularity, + false, + util::MeasureUnit::PERCENT, + util::MeasureUnit::PERCENT); + aStrBuffer.append( '%' ); aStr = aStrBuffer.makeStringAndClear(); - rExport.AddAttribute( XML_NAMESPACE_DRAW, XML_EXTRUSION_SPECULARITY, aStr ); } }