summaryrefslogtreecommitdiff
path: root/oox
diff options
context:
space:
mode:
authorAdam Co <rattles2013@gmail.com>2014-06-08 16:35:32 +0300
committerTomaž Vajngerl <tomaz.vajngerl@collabora.com>2014-09-09 23:20:56 +0200
commit1af3d8a211852da5a1f130aa22e00ab329301ee7 (patch)
treebb5369af24677709d0853cefbb6d434cd9a98b3f /oox
parentc4c11a1b9e7b9c88dc7f64bfb5eb5d316c7b5366 (diff)
Rewrite import and export of custom dashes in ooxml filter (fix)
The import mechanism of custom-dash (a:custDash) was wrong, and imported wrong values, which causes that if you would import-export-import-export - you would get inflated values, which might cause a corruption. The attributes for custom-dash nodes (a:ds) are of type 'PositivePercentage'. Office will read percentages formatted with a trailing percent sign or formatted as 1000th of a percent without a trailing percent sign, but only write percentages as 1000th's of a percent without a trailing percent sign. During import - LO did not check if it was in '%' format or in '1000th of a percent' format. So that was fixed. Also - when exporting - it always exports now in '1000th of a percent' format. Reviewed-on: https://gerrit.libreoffice.org/9681 Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk> Tested-by: Miklos Vajna <vmiklos@collabora.co.uk> (cherry picked from commit 2211a67cc5e577f8abdcc96c9c63865be5fb988d) Conflicts: oox/source/export/drawingml.cxx Change-Id: I6bd74df26951974f85173227c832386c70034afb
Diffstat (limited to 'oox')
-rw-r--r--oox/source/drawingml/lineproperties.cxx15
-rw-r--r--oox/source/drawingml/linepropertiescontext.cxx46
-rw-r--r--oox/source/export/drawingml.cxx49
3 files changed, 92 insertions, 18 deletions
diff --git a/oox/source/drawingml/lineproperties.cxx b/oox/source/drawingml/lineproperties.cxx
index 2044095c484b..372740b36006 100644
--- a/oox/source/drawingml/lineproperties.cxx
+++ b/oox/source/drawingml/lineproperties.cxx
@@ -107,19 +107,26 @@ void lclConvertCustomDash( LineDash& orLineDash, const LineProperties::DashStopV
sal_Int16 nDashes = 0;
sal_Int32 nDashLen = 0;
sal_Int32 nDistance = 0;
+ sal_Int32 nConvertedLen = 0;
+ sal_Int32 nConvertedDistance = 0;
for( LineProperties::DashStopVector::const_iterator aIt = rCustomDash.begin(), aEnd = rCustomDash.end(); aIt != aEnd; ++aIt )
{
- if( aIt->first <= 2 )
+ // Get from "1000th of percent" ==> percent ==> multiplier
+ nConvertedLen = aIt->first / 1000 / 100;
+ nConvertedDistance = aIt->second / 1000 / 100;
+
+ // Check if it is a dot (100% = dot)
+ if( nConvertedLen == 1 )
{
++nDots;
- nDotLen += aIt->first;
+ nDotLen += nConvertedLen;
}
else
{
++nDashes;
- nDashLen += aIt->first;
+ nDashLen += nConvertedLen;
}
- nDistance += aIt->second;
+ nDistance += nConvertedDistance;
}
orLineDash.DotLen = (nDots > 0) ? ::std::max< sal_Int32 >( nDotLen / nDots, 1 ) : 0;
orLineDash.Dots = nDots;
diff --git a/oox/source/drawingml/linepropertiescontext.cxx b/oox/source/drawingml/linepropertiescontext.cxx
index 3195e569881b..ee49fbaddbb5 100644
--- a/oox/source/drawingml/linepropertiescontext.cxx
+++ b/oox/source/drawingml/linepropertiescontext.cxx
@@ -66,8 +66,50 @@ ContextHandlerRef LinePropertiesContext::onCreateContext( sal_Int32 nElement, co
return this;
break;
case A_TOKEN( ds ):
- mrLineProperties.maCustomDash.push_back( LineProperties::DashStop(
- rAttribs.getInteger( XML_d, 0 ), rAttribs.getInteger( XML_sp, 0 ) ) );
+ {
+ // 'a:ds' has 2 attributes : 'd' and 'sp'
+ // both are of type 'a:ST_PositivePercentage'
+ // according to the specs Office will read percentages formatted with a trailing percent sign
+ // or formatted as 1000th of a percent without a trailing percent sign, but only write percentages
+ // as 1000th's of a percent without a trailing percent sign.
+ // The code below takes care of both scenarios by converting to '1000th of a percent' always
+ OUString aStr;
+ sal_Int32 nDash = 0;
+ aStr = rAttribs.getString( XML_d, "" );
+ if ( aStr.endsWith("%") )
+ {
+ // Ends with a '%'
+ aStr = aStr.copy(0, aStr.getLength() - 1);
+ aStr = aStr.trim();
+ nDash = aStr.toInt32();
+
+ // Convert to 1000th of a percent
+ nDash *= 1000;
+ }
+ else
+ {
+ nDash = rAttribs.getInteger( XML_d, 0 );
+ }
+
+ sal_Int32 nSp = 0;
+ aStr = rAttribs.getString( XML_sp, "" );
+ if ( aStr.endsWith("%") )
+ {
+ // Ends with a '%'
+ aStr = aStr.copy(0, aStr.getLength() - 1);
+ aStr = aStr.trim();
+ nSp = aStr.toInt32();
+
+ // Convert to 1000th of a percent
+ nSp *= 1000;
+ }
+ else
+ {
+ nSp = rAttribs.getInteger( XML_sp, 0 );
+ }
+
+ mrLineProperties.maCustomDash.push_back( LineProperties::DashStop( nDash, nSp ) );
+ }
break;
// LineJoinPropertiesGroup
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
index 2ef0d1fa6928..641cb4daec84 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -626,19 +626,44 @@ void DrawingML::WriteOutline( Reference< XPropertySet > rXPropSet )
if( bDashSet && aStyleLineStyle != drawing::LineStyle_DASH ) {
// line style is a dash and it was not set by the shape style
- // TODO: the XML_d and XML_sp values seem insane
+
mpFS->startElementNS( XML_a, XML_custDash, FSEND );
- int i;
- for( i = 0; i < aLineDash.Dots; i ++ )
- mpFS->singleElementNS( XML_a, XML_ds,
- XML_d, aLineDash.DotLen ? writePercentage( aLineDash.DotLen*1000 ) : "100000%",
- XML_sp, writePercentage( aLineDash.Distance*1000 ),
- FSEND );
- for( i = 0; i < aLineDash.Dashes; i ++ )
- mpFS->singleElementNS( XML_a, XML_ds,
- XML_d, aLineDash.DashLen ? writePercentage( aLineDash.DashLen*1000 ) : "100000%",
- XML_sp, writePercentage( aLineDash.Distance*1000 ),
- FSEND );
+
+ // Check that line-width is positive and distance between dashes\dots is positive
+ if ( nLineWidth > 0 && aLineDash.Distance > 0 )
+ {
+ // Write 'dashes' first, and then 'dots'
+ int i;
+ if ( aLineDash.Dashes > 0 )
+ {
+ for( i = 0; i < aLineDash.Dashes; i ++ )
+ mpFS->singleElementNS( XML_a , XML_ds,
+ XML_d , write1000thOfAPercent( aLineDash.DashLen > 0 ? aLineDash.DashLen / nLineWidth * 100 : 100 ),
+ XML_sp, write1000thOfAPercent( aLineDash.Distance > 0 ? aLineDash.Distance / nLineWidth * 100 : 100 ),
+ FSEND );
+ }
+ if ( aLineDash.Dots > 0 )
+ {
+ for( i = 0; i < aLineDash.Dots; i ++ )
+ mpFS->singleElementNS( XML_a, XML_ds,
+ XML_d , write1000thOfAPercent( aLineDash.DotLen > 0 ? aLineDash.DotLen / nLineWidth * 100 : 100 ),
+ XML_sp, write1000thOfAPercent( aLineDash.Distance > 0 ? aLineDash.Distance / nLineWidth * 100 : 100 ),
+ FSEND );
+ }
+ }
+
+ if ( nLineWidth <= 0 )
+ SAL_WARN("oox", "while writing outline - custom dash - line width was < 0 : " << nLineWidth);
+ if ( aLineDash.Dashes < 0 )
+ SAL_WARN("oox", "while writing outline - custom dash - number of dashes was < 0 : " << aLineDash.Dashes);
+ if ( aLineDash.Dashes > 0 && aLineDash.DashLen <= 0 )
+ SAL_WARN("oox", "while writing outline - custom dash - dash length was < 0 : " << aLineDash.DashLen);
+ if ( aLineDash.Dots < 0 )
+ SAL_WARN("oox", "while writing outline - custom dash - number of dots was < 0 : " << aLineDash.Dots);
+ if ( aLineDash.Dots > 0 && aLineDash.DotLen <= 0 )
+ SAL_WARN("oox", "while writing outline - custom dash - dot length was < 0 : " << aLineDash.DotLen);
+ if ( aLineDash.Distance <= 0 )
+ SAL_WARN("oox", "while writing outline - custom dash - distance was < 0 : " << aLineDash.Distance);
mpFS->endElementNS( XML_a, XML_custDash );
}