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.stahl@allotropia.de>
This commit is contained in:
Regina Henschel
2022-02-24 11:43:51 +01:00
committed by Michael Stahl
parent cf2449aac0
commit c893c0e359
10 changed files with 108 additions and 7 deletions
+1
View File
@@ -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,
@@ -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"/>
+1
View File
@@ -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,
+66 -6
View File
@@ -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: */
+1
View File
@@ -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 ),
@@ -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 },
+20
View File
@@ -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,
+8 -1
View File
@@ -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,
+1
View File
@@ -2326,6 +2326,7 @@ extrusion-rotation-center
extrusion-shininess
extrusion-skew
extrusion-specularity
extrusion-specularity-loext
extrusion-projection-mode
extrusion-viewpoint
extrusion-origin