include/xmloff/xmltoken.hxx                                 |    1 
 schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng |    9 +
 xmloff/inc/EnhancedCustomShapeToken.hxx                     |    1 
 xmloff/qa/unit/data/tdf147580_extrusion-specularity.doc     |binary
 xmloff/qa/unit/draw.cxx                                     |   72 +++++++++++-
 xmloff/source/core/xmltoken.cxx                             |    1 
 xmloff/source/draw/EnhancedCustomShapeToken.cxx             |    1 
 xmloff/source/draw/shapeexport.cxx                          |   20 +++
 xmloff/source/draw/ximpcustomshape.cxx                      |    9 +
 xmloff/source/token/tokens.txt                              |    1 
 10 files changed, 108 insertions(+), 7 deletions(-)

New commits:
commit c893c0e359b82be71107e064bd2266c6daff81d7
Author:     Regina Henschel <rb.hensc...@t-online.de>
AuthorDate: Mon Feb 21 23:08:10 2022 +0100
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Thu Feb 24 11:43:51 2022 +0100

    tdf#147580 use valid values for extrusion-specularity
    
    The fix for tdf#145700 has changed the internal handling so, that
    values larger than 100% from MS binary import are now kept und correctly
    used. But ODF 1.2 and 1.3 have the range restricted to
    zeroToHundredPercent.
    
    The patch writes values larger than 100% in extended namespace for our
    'ODF 1.3 extended'. It writes draw:extrusion-specularity in any case, so
    that older versions get a meaninful value, but clamps it to [0,100] if
    necessary to get valid files.
    
    Change-Id: I98298d5c3e3367ffe4a45cdc051be23679308119
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/130306
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>

diff --git a/include/xmloff/xmltoken.hxx b/include/xmloff/xmltoken.hxx
index 7e278b4cffc3..4f7cd7e148a4 100644
--- a/include/xmloff/xmltoken.hxx
+++ b/include/xmloff/xmltoken.hxx
@@ -2461,6 +2461,7 @@ namespace xmloff::token {
         XML_EXTRUSION_SHININESS,
         XML_EXTRUSION_SKEW,
         XML_EXTRUSION_SPECULARITY,
+        XML_EXTRUSION_SPECULARITY_LOEXT,
         XML_EXTRUSION_PROJECTION_MODE,
         XML_EXTRUSION_VIEWPOINT,
         XML_EXTRUSION_ORIGIN,
diff --git a/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng 
b/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng
index 2df8d41c5eb9..9698c0448bdf 100644
--- a/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng
+++ b/schema/libreoffice/OpenDocument-v1.3+libreoffice-schema.rng
@@ -2404,6 +2404,15 @@ 
xmlns:loext="urn:org:documentfoundation:names:experimental:office:xmlns:loext:1.
     </rng:optional>
   </rng:define>
 
+  <!-- https://issues.oasis-open.org/browse/OFFICE-4122 -->
+  <rng:define name="draw-enhanced-geometry-attlist" combine="interleave">
+    <rng:optional>
+      <rng:attribute name="loext:extrusion-specularity-loext">
+        <rng:ref name="percent"/>
+      </rng:attribute>
+    </rng:optional>
+  </rng:define>
+
   <!-- TODO no proposal -->
   <rng:define name="draw-custom-shape-attlist" combine="interleave">
     <rng:ref name="common-draw-rel-size-attlist"/>
diff --git a/xmloff/inc/EnhancedCustomShapeToken.hxx 
b/xmloff/inc/EnhancedCustomShapeToken.hxx
index 7fd86f5a5126..4438ba1260e5 100644
--- a/xmloff/inc/EnhancedCustomShapeToken.hxx
+++ b/xmloff/inc/EnhancedCustomShapeToken.hxx
@@ -54,6 +54,7 @@ namespace xmloff::EnhancedCustomShapeToken {
         EAS_extrusion_shininess,
         EAS_extrusion_skew,
         EAS_extrusion_specularity,
+        EAS_extrusion_specularity_loext,
         EAS_projection,
         EAS_extrusion_viewpoint,
         EAS_extrusion_origin,
diff --git a/xmloff/qa/unit/data/tdf147580_extrusion-specularity.doc 
b/xmloff/qa/unit/data/tdf147580_extrusion-specularity.doc
new file mode 100644
index 000000000000..9efe793d3d56
Binary files /dev/null and 
b/xmloff/qa/unit/data/tdf147580_extrusion-specularity.doc differ
diff --git a/xmloff/qa/unit/draw.cxx b/xmloff/qa/unit/draw.cxx
index 04c7178ca6bf..ac0801dce72b 100644
--- a/xmloff/qa/unit/draw.cxx
+++ b/xmloff/qa/unit/draw.cxx
@@ -296,9 +296,6 @@ CPPUNIT_TEST_FIXTURE(XmloffDrawTest, 
testExtrusionMetalTypeExtended)
 
     // Test, that new attribute is written with loext namespace. Adapt when 
attribute is added to ODF.
     utl::TempFile aTempFile;
-    // The file has set c3DSpecularAmt="65536" to prevent validation error in 
attribute
-    // draw:extrusion-specularity. The error, that 122% is written in case of 
c3DSpecularAmt="80000" is
-    // not yet fixed.
     save("writer8", aTempFile);
 
     // assert XML.
@@ -327,9 +324,6 @@ CPPUNIT_TEST_FIXTURE(XmloffDrawTest, 
testExtrusionMetalTypeStrict)
     // added to ODF.
     const SvtSaveOptions::ODFDefaultVersion 
nCurrentODFVersion(GetODFDefaultVersion());
     SetODFDefaultVersion(SvtSaveOptions::ODFVER_013);
-    // The file has set c3DSpecularAmt="65536" to prevent validation error in 
attribute
-    // draw:extrusion-specularity. The error, that 122% is written in case of 
c3DSpecularAmt="80000" is
-    // not yet fixed.
     utl::TempFile aTempFile;
     save("writer8", aTempFile);
 
@@ -342,6 +336,72 @@ CPPUNIT_TEST_FIXTURE(XmloffDrawTest, 
testExtrusionMetalTypeStrict)
     SetODFDefaultVersion(nCurrentODFVersion);
 }
 
+namespace
+{
+void lcl_assertSpecularityProperty(std::string_view sInfo, 
uno::Reference<drawing::XShape>& rxShape)
+{
+    uno::Reference<beans::XPropertySet> xShapeProps(rxShape, uno::UNO_QUERY);
+    uno::Sequence<beans::PropertyValue> aGeoPropSeq;
+    xShapeProps->getPropertyValue("CustomShapeGeometry") >>= aGeoPropSeq;
+    comphelper::SequenceAsHashMap aGeoPropMap(aGeoPropSeq);
+    uno::Sequence<beans::PropertyValue> aExtrusionSeq;
+    aGeoPropMap.getValue("Extrusion") >>= aExtrusionSeq;
+    comphelper::SequenceAsHashMap aExtrusionPropMap(aExtrusionSeq);
+
+    double fSpecularity(-1.0);
+    aExtrusionPropMap.getValue("Specularity") >>= fSpecularity;
+    OString sMsg = OString::Concat(sInfo) + "Specularity";
+    CPPUNIT_ASSERT_EQUAL_MESSAGE(sMsg.getStr(), 122.0703125, fSpecularity);
+}
+}
+
+CPPUNIT_TEST_FIXTURE(XmloffDrawTest, testExtrusionSpecularityExtended)
+{
+    // import
+    getComponent() = 
loadFromDesktop(m_directories.getURLFromSrc(DATA_DIRECTORY)
+                                         + 
"tdf147580_extrusion-specularity.doc",
+                                     "com.sun.star.text.TextDocument");
+    // verify property
+    uno::Reference<drawing::XShape> xShape(getShape(0));
+    lcl_assertSpecularityProperty("from doc", xShape);
+
+    // Test, that attribute is written in draw namespace with value 100% and 
in loext namespace with
+    // value 122.0703125%.
+    utl::TempFile aTempFile;
+    save("writer8", aTempFile);
+
+    // assert XML.
+    std::unique_ptr<SvStream> pStream = parseExportStream(aTempFile, 
"content.xml");
+    xmlDocUniquePtr pXmlDoc = parseXmlStream(pStream.get());
+    assertXPath(pXmlDoc, 
"//draw:enhanced-geometry[@draw:extrusion-specularity='100%']");
+    assertXPath(pXmlDoc,
+                
"//draw:enhanced-geometry[@loext:extrusion-specularity-loext='122.0703125%']");
+
+    // reload and verify, that the loext value is used
+    getComponent()->dispose();
+    getComponent() = loadFromDesktop(aTempFile.GetURL(), 
"com.sun.star.text.TextDocument");
+    // verify properties
+    uno::Reference<drawing::XShape> xShapeReload(getShape(0));
+    lcl_assertSpecularityProperty("from ODF 1.3 extended", xShapeReload);
+}
+
+CPPUNIT_TEST_FIXTURE(XmloffDrawTest, testExtrusionSpecularity)
+{
+    // import
+    getComponent() = 
loadFromDesktop(m_directories.getURLFromSrc(DATA_DIRECTORY)
+                                         + 
"tdf147580_extrusion-specularity.doc",
+                                     "com.sun.star.text.TextDocument");
+
+    // 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.
+    const SvtSaveOptions::ODFDefaultVersion 
nCurrentODFVersion(GetODFDefaultVersion());
+    SetODFDefaultVersion(SvtSaveOptions::ODFVER_013);
+    utl::TempFile aTempFile;
+    save("writer8", aTempFile);
+
+    SetODFDefaultVersion(nCurrentODFVersion);
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/core/xmltoken.cxx b/xmloff/source/core/xmltoken.cxx
index f3ae86566e43..c7db64b00174 100644
--- a/xmloff/source/core/xmltoken.cxx
+++ b/xmloff/source/core/xmltoken.cxx
@@ -2479,6 +2479,7 @@ namespace xmloff::token {
         TOKEN( "extrusion-shininess" ,                  
XML_EXTRUSION_SHININESS ),
         TOKEN( "extrusion-skew" ,                       XML_EXTRUSION_SKEW ),
         TOKEN( "extrusion-specularity" ,                
XML_EXTRUSION_SPECULARITY ),
+        TOKEN( "extrusion-specularity-loext",           
XML_EXTRUSION_SPECULARITY_LOEXT ),
         TOKEN( "extrusion-projection-mode" ,            
XML_EXTRUSION_PROJECTION_MODE ),
         TOKEN( "extrusion-viewpoint" ,                  
XML_EXTRUSION_VIEWPOINT ),
         TOKEN( "extrusion-origin" ,                 XML_EXTRUSION_ORIGIN ),
diff --git a/xmloff/source/draw/EnhancedCustomShapeToken.cxx 
b/xmloff/source/draw/EnhancedCustomShapeToken.cxx
index 700e29fc71fd..bd0613e9e4b4 100644
--- a/xmloff/source/draw/EnhancedCustomShapeToken.cxx
+++ b/xmloff/source/draw/EnhancedCustomShapeToken.cxx
@@ -66,6 +66,7 @@ const TokenTable pTokenTableArray[] =
     { "extrusion-shininess",                EAS_extrusion_shininess },
     { "extrusion-skew",                     EAS_extrusion_skew },
     { "extrusion-specularity",              EAS_extrusion_specularity },
+    { "extrusion-specularity-loext",        EAS_extrusion_specularity_loext },
     { "projection",                         EAS_projection },
     { "extrusion-viewpoint",                EAS_extrusion_viewpoint },
     { "extrusion-origin",                   EAS_extrusion_origin },
diff --git a/xmloff/source/draw/shapeexport.cxx 
b/xmloff/source/draw/shapeexport.cxx
index ea33330994b1..bc642d344e68 100644
--- a/xmloff/source/draw/shapeexport.cxx
+++ b/xmloff/source/draw/shapeexport.cxx
@@ -4556,6 +4556,26 @@ static void ImpExportEnhancedGeometry( SvXMLExport& 
rExport, const uno::Referenc
                                         double fExtrusionSpecularity = 0;
                                         if ( rProp.Value >>= 
fExtrusionSpecularity )
                                         {
+                                            
SvtSaveOptions::ODFSaneDefaultVersion eVersion = 
rExport.getSaneDefaultVersion();
+                                            if (fExtrusionSpecularity > 100.0 
&& eVersion >= SvtSaveOptions::ODFSVER_012
+                                                && (eVersion & 
SvtSaveOptions::ODFSVER_EXTENDED))
+                                            {
+                                                // tdf#147580 write values > 
100% in loext
+                                                
::sax::Converter::convertDouble(
+                                                    aStrBuffer,
+                                                    fExtrusionSpecularity,
+                                                    false,
+                                                    util::MeasureUnit::PERCENT,
+                                                    
util::MeasureUnit::PERCENT);
+                                                aStrBuffer.append( '%' );
+                                                aStr = 
aStrBuffer.makeStringAndClear();
+                                                rExport.AddAttribute( 
XML_NAMESPACE_LO_EXT, XML_EXTRUSION_SPECULARITY_LOEXT, aStr );
+                                            }
+                                            // tdf#147580 ODF 1 allows 
arbitrary percent, later versions not
+                                            if (eVersion >= 
SvtSaveOptions::ODFSVER_012)
+                                            {
+                                                fExtrusionSpecularity = 
std::clamp<double>(fExtrusionSpecularity, 0.0, 100.0);
+                                            }
                                             ::sax::Converter::convertDouble(
                                                 aStrBuffer,
                                                 fExtrusionSpecularity,
diff --git a/xmloff/source/draw/ximpcustomshape.cxx 
b/xmloff/source/draw/ximpcustomshape.cxx
index df86901b9635..ab567b6bd178 100644
--- a/xmloff/source/draw/ximpcustomshape.cxx
+++ b/xmloff/source/draw/ximpcustomshape.cxx
@@ -866,6 +866,7 @@ void XMLEnhancedCustomShapeContext::startFastElement(
     const css::uno::Reference< css::xml::sax::XFastAttributeList >& xAttrList )
 {
     sal_Int32               nAttrNumber;
+    std::optional<std::string_view> oSpecularityValue; // for postpone 
extrusion-specularity
     for( auto& aIter : sax_fastparser::castToFastAttributeList(xAttrList) )
     {
         switch( EASGet( aIter.getToken() ) )
@@ -1024,7 +1025,11 @@ void XMLEnhancedCustomShapeContext::startFastElement(
                 GetEnhancedParameterPair( maExtrusion, aIter.toString(), 
EAS_Skew );
             break;
             case EAS_extrusion_specularity :
-                GetDoublePercentage( maExtrusion, aIter.toView(), 
EAS_Specularity );
+                if (!oSpecularityValue)
+                    oSpecularityValue = aIter.toView();
+            break;
+            case EAS_extrusion_specularity_loext :
+                oSpecularityValue = aIter.toView();
             break;
             case EAS_projection :
             {
@@ -1125,6 +1130,8 @@ void XMLEnhancedCustomShapeContext::startFastElement(
                 break;
         }
     }
+    if (oSpecularityValue)
+        GetDoublePercentage( maExtrusion, *oSpecularityValue, EAS_Specularity 
);
 }
 
 static void SdXMLCustomShapePropertyMerge( std::vector< 
css::beans::PropertyValue >& rPropVec,
diff --git a/xmloff/source/token/tokens.txt b/xmloff/source/token/tokens.txt
index f610bfbff47e..ec591c072789 100644
--- a/xmloff/source/token/tokens.txt
+++ b/xmloff/source/token/tokens.txt
@@ -2326,6 +2326,7 @@ extrusion-rotation-center
 extrusion-shininess
 extrusion-skew
 extrusion-specularity
+extrusion-specularity-loext
 extrusion-projection-mode
 extrusion-viewpoint
 extrusion-origin

Reply via email to