Kaydet (Commit) 89879b00 authored tarafından Szymon Kłos's avatar Szymon Kłos

tdf#112088 gradient stop map -> multimap

When two gradientstops were set to position 50%
only one was stored and the exported file was
detected as broken by MSO.

Change-Id: I5fd1acde6051f734a5f3e4cff9bde01b675e1984
Reviewed-on: https://gerrit.libreoffice.org/42210Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarSzymon Kłos <szymon.klos@collabora.com>
üst 0f3b52bc
......@@ -48,7 +48,7 @@ class ShapePropertyMap;
struct GradientFillProperties
{
typedef ::std::map< double, Color > GradientStopMap;
typedef ::std::multimap< double, Color > GradientStopMap;
GradientStopMap maGradientStops; /// Gradient stops (colors/transparence).
OptValue< css::geometry::IntegerRectangle2D > moFillToRect;
......
......@@ -379,18 +379,20 @@ void FillProperties::pushToPropMap( ShapePropertyMap& rPropMap,
// Add a fake gradient stop at 0% and 100% if necessary, so that the gradient always starts
// at 0% and ends at 100%, to make following logic clearer (?).
if( aGradientStops.find(0.0) == aGradientStops.end() )
auto a0 = aGradientStops.find( 0.0 );
if( a0 == aGradientStops.end() )
{
// temp variable required
Color aFirstColor(aGradientStops.begin()->second);
aGradientStops[0.0] = aFirstColor;
aGradientStops.emplace( 0.0, aFirstColor );
}
if( aGradientStops.find(1.0) == aGradientStops.end() )
auto a1 = aGradientStops.find( 1.0 );
if( a1 == aGradientStops.end() )
{
// ditto
Color aLastColor(aGradientStops.rbegin()->second);
aGradientStops[1.0] = aLastColor;
aGradientStops.emplace( 1.0, aLastColor );
}
// Check if the gradient is symmetric, which we will emulate with an "axial" gradient.
......@@ -421,7 +423,12 @@ void FillProperties::pushToPropMap( ShapePropertyMap& rPropMap,
if( aItA->first != aItZ->first )
{
Color aMiddleColor = aItZ->second;
aGradientStops[0.5] = aMiddleColor;
auto a05 = aGradientStops.find( 0.5 );
if( a05 != aGradientStops.end() )
a05->second = aMiddleColor;
else
aGradientStops.emplace( 0.5, aMiddleColor );
}
// Drop the rest of the stops
while( aGradientStops.rbegin()->first > 0.5 )
......
......@@ -63,7 +63,8 @@ ContextHandlerRef GradientFillContext::onCreateContext(
if( rAttribs.hasAttribute( XML_pos ) )
{
double fPosition = getLimitedValue< double >( rAttribs.getDouble( XML_pos, 0.0 ) / 100000.0, 0.0, 1.0 );
return new ColorContext( *this, mrGradientProps.maGradientStops[ fPosition ] );
auto aElement = mrGradientProps.maGradientStops.emplace( fPosition, Color() );
return new ColorContext( *this, aElement->second );
}
break;
......
......@@ -999,7 +999,7 @@ Reference< XShape > const & Shape::createAndInsert(
if( aShapeProps.hasProperty( PROP_FillGradient ) )
{
std::vector<beans::PropertyValue> aGradientStops;
::std::map< double, Color >::iterator aIt = aFillProperties.maGradientProps.maGradientStops.begin();
auto aIt = aFillProperties.maGradientProps.maGradientStops.begin();
for( size_t i = 0; i < aFillProperties.maGradientProps.maGradientStops.size(); ++i )
{ // for each stop in the gradient definition:
......
......@@ -708,6 +708,15 @@ void FillModel::assignUsed( const FillModel& rSource )
moRotate.assignIfUsed( rSource.moRotate );
}
void lcl_setGradientStop( std::multimap< double, Color >& rMap, const double fKey, const Color& rValue ) {
auto aElement = rMap.find( fKey );
if (aElement != rMap.end())
aElement->second = rValue;
else
rMap.emplace( fKey, rValue );
}
void FillModel::pushToPropMap( ShapePropertyMap& rPropMap, const GraphicHelper& rGraphicHelper ) const
{
/* Convert VML fill formatting to DrawingML fill formatting and let the
......@@ -749,8 +758,10 @@ void FillModel::pushToPropMap( ShapePropertyMap& rPropMap, const GraphicHelper&
// simulate axial gradient by 3-step DrawingML gradient
const Color& rOuterColor = bOuterToInner ? aColor1 : aColor2;
const Color& rInnerColor = bOuterToInner ? aColor2 : aColor1;
aFillProps.maGradientProps.maGradientStops[ 0.0 ] = aFillProps.maGradientProps.maGradientStops[ 1.0 ] = rOuterColor;
aFillProps.maGradientProps.maGradientStops[ 0.5 ] = rInnerColor;
lcl_setGradientStop( aFillProps.maGradientProps.maGradientStops, 0.0, rOuterColor);
lcl_setGradientStop( aFillProps.maGradientProps.maGradientStops, 1.0, rOuterColor);
lcl_setGradientStop( aFillProps.maGradientProps.maGradientStops, 0.5, rInnerColor );
}
else // focus of -100%, 0%, and 100% is linear gradient
{
......@@ -762,8 +773,8 @@ void FillModel::pushToPropMap( ShapePropertyMap& rPropMap, const GraphicHelper&
if( fFocus < -0.5 || fFocus > 0.5 )
(nVmlAngle += 180) %= 360;
// set the start and stop colors
aFillProps.maGradientProps.maGradientStops[ 0.0 ] = aColor1;
aFillProps.maGradientProps.maGradientStops[ 1.0 ] = aColor2;
lcl_setGradientStop( aFillProps.maGradientProps.maGradientStops, 0.0, aColor1 );
lcl_setGradientStop( aFillProps.maGradientProps.maGradientStops, 1.0, aColor2 );
}
// VML counts counterclockwise from bottom, DrawingML clockwise from left
......@@ -788,8 +799,8 @@ void FillModel::pushToPropMap( ShapePropertyMap& rPropMap, const GraphicHelper&
// set the start and stop colors (focus of 0% means outer-to-inner)
bool bOuterToInner = (-0.5 <= fFocus) && (fFocus <= 0.5);
aFillProps.maGradientProps.maGradientStops[ 0.0 ] = bOuterToInner ? aColor2 : aColor1;
aFillProps.maGradientProps.maGradientStops[ 1.0 ] = bOuterToInner ? aColor1 : aColor2;
lcl_setGradientStop( aFillProps.maGradientProps.maGradientStops, 0.0, bOuterToInner ? aColor2 : aColor1 );
lcl_setGradientStop( aFillProps.maGradientProps.maGradientStops, 1.0, bOuterToInner ? aColor1 : aColor2 );
}
}
break;
......
......@@ -106,6 +106,7 @@ public:
void testRotateFlip();
void testTdf106867();
void testTdf112280();
void testTdf112088();
CPPUNIT_TEST_SUITE(SdOOXMLExportTest2);
......@@ -139,6 +140,7 @@ public:
CPPUNIT_TEST(testRotateFlip);
CPPUNIT_TEST(testTdf106867);
CPPUNIT_TEST(testTdf112280);
CPPUNIT_TEST(testTdf112088);
CPPUNIT_TEST_SUITE_END();
......@@ -1039,6 +1041,18 @@ void SdOOXMLExportTest2::testTdf112280()
"by", "21600000");
}
void SdOOXMLExportTest2::testTdf112088()
{
::sd::DrawDocShellRef xDocShRef = loadURL(m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf112088.pptx"), PPTX);
utl::TempFile tempFile;
xDocShRef = saveAndReload(xDocShRef.get(), PPTX, &tempFile);
xDocShRef->DoClose();
// check gradient stops
xmlDocPtr pXmlDocContent = parseExport(tempFile, "ppt/slides/slide1.xml");
assertXPathChildren(pXmlDocContent, "/p:sld/p:cSld/p:spTree/p:sp[3]/p:spPr/a:gradFill/a:gsLst", 2);
}
CPPUNIT_TEST_SUITE_REGISTRATION(SdOOXMLExportTest2);
CPPUNIT_PLUGIN_IMPLEMENT();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment