diff options
author | Mark Hung <marklh9@gmail.com> | 2018-08-19 23:49:26 +0800 |
---|---|---|
committer | Mark Hung <marklh9@gmail.com> | 2018-08-24 15:07:14 +0200 |
commit | 34dff8df7b9fc46fed6e6ffbaa8b6847ad6ed1b1 (patch) | |
tree | 01dc2f3d9d3bbcc0a9fad2b0bd783c06f1712a22 /oox | |
parent | 80d6cba424439803704dbddf4fc832bd73e90e97 (diff) |
tdf#73547 fix ooxml export / import custom dashes.
Fix import logic as well as arithmatic precion of both import
and export.
Change-Id: I97e9bde847e0a2425421af2f2175d4d0b7af0cab
Reviewed-on: https://gerrit.libreoffice.org/59306
Tested-by: Jenkins
Reviewed-by: Mark Hung <marklh9@gmail.com>
Diffstat (limited to 'oox')
-rw-r--r-- | oox/source/drawingml/lineproperties.cxx | 86 | ||||
-rw-r--r-- | oox/source/export/drawingml.cxx | 11 |
2 files changed, 41 insertions, 56 deletions
diff --git a/oox/source/drawingml/lineproperties.cxx b/oox/source/drawingml/lineproperties.cxx index 25bbbcd25f1e..2b5de7a1f8c0 100644 --- a/oox/source/drawingml/lineproperties.cxx +++ b/oox/source/drawingml/lineproperties.cxx @@ -55,11 +55,8 @@ void lclSetDashData( LineDash& orLineDash, sal_Int16 nDots, sal_Int32 nDotLen, } /** Converts the specified preset dash to API dash. - - Line length and dot length are set relative to line width and have to be - multiplied by the actual line width after this function. */ -void lclConvertPresetDash( LineDash& orLineDash, sal_Int32 nPresetDash ) +void lclConvertPresetDash(LineDash& orLineDash, sal_Int32 nPresetDash, sal_Int32 nLineWidth) { switch( nPresetDash ) { @@ -80,54 +77,41 @@ void lclConvertPresetDash( LineDash& orLineDash, sal_Int32 nPresetDash ) OSL_FAIL( "lclConvertPresetDash - unsupported preset dash" ); lclSetDashData( orLineDash, 0, 0, 1, 4, 3 ); } + // convert relative dash/dot length to absolute length + orLineDash.DotLen *= nLineWidth; + orLineDash.DashLen *= nLineWidth; + orLineDash.Distance *= nLineWidth; } -/** Converts the passed custom dash to API dash. - - Line length and dot length are set relative to line width and have to be - multiplied by the actual line width after this function. +/** Converts the passed custom dash to API dash. rCustomDash should not be empty. */ -void lclConvertCustomDash( LineDash& orLineDash, const LineProperties::DashStopVector& rCustomDash ) +void lclConvertCustomDash(LineDash& orLineDash, const LineProperties::DashStopVector& rCustomDash, sal_Int32 nLineWidth) { - if( rCustomDash.empty() ) + OSL_ASSERT(!rCustomDash.empty()); + orLineDash.Dashes = 0; + // Follow the order we export custDash: dashes first. + orLineDash.DashLen = rCustomDash[0].first; + // Also assume dash and dot have the same sp values. + orLineDash.Distance = rCustomDash[0].second; + orLineDash.DotLen = 0; + + for(const auto& rIt : rCustomDash) { - OSL_FAIL( "lclConvertCustomDash - unexpected empty custom dash" ); - lclSetDashData( orLineDash, 0, 0, 1, 4, 3 ); - return; - } - - // count dashes and dots (stops equal or less than 2 are assumed to be dots) - sal_Int16 nDots = 0; - sal_Int32 nDotLen = 0; - 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 ) - { - // 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 += nConvertedLen; - } - else + sal_Int32 nLen = rIt.first; + if (nLen != orLineDash.DashLen) { - ++nDashes; - nDashLen += nConvertedLen; + orLineDash.DotLen = nLen; + break; } - nDistance += nConvertedDistance; + ++orLineDash.Dashes; } - orLineDash.DotLen = (nDots > 0) ? ::std::max< sal_Int32 >( nDotLen / nDots, 1 ) : 0; - orLineDash.Dots = nDots; - orLineDash.DashLen = (nDashes > 0) ? ::std::max< sal_Int32 >( nDashLen / nDashes, 1 ) : 0; - orLineDash.Dashes = nDashes; - orLineDash.Distance = ::std::max< sal_Int32 >( nDistance / rCustomDash.size(), 1 ); + // TODO: verify the assumption and approximate complex line patterns. + + // Assume we only have two types of dash stops, the rest are all dots. + orLineDash.Dots = rCustomDash.size() - orLineDash.Dashes; + orLineDash.DashLen = orLineDash.DashLen / 100000.0 * nLineWidth; + orLineDash.DotLen = orLineDash.DotLen / 100000.0 * nLineWidth; + orLineDash.Distance = orLineDash.Distance / 100000.0 * nLineWidth; } DashStyle lclGetDashStyle( sal_Int32 nToken ) @@ -386,16 +370,14 @@ void LineProperties::pushToPropMap( ShapePropertyMap& rPropMap, aLineDash.Style = lclGetDashStyle( moLineCap.get( XML_rnd ) ); // convert preset dash or custom dash - if( moPresetDash.differsFrom( XML_solid ) ) - lclConvertPresetDash( aLineDash, moPresetDash.get() ); + if(moPresetDash.differsFrom(XML_solid) || maCustomDash.empty()) + { + sal_Int32 nBaseLineWidth = ::std::max<sal_Int32>(nLineWidth, 35); + lclConvertPresetDash(aLineDash, moPresetDash.get(XML_dash), nBaseLineWidth); + } else - lclConvertCustomDash( aLineDash, maCustomDash ); + lclConvertCustomDash(aLineDash, maCustomDash, nLineWidth); - // convert relative dash/dot length to absolute length - sal_Int32 nBaseLineWidth = ::std::max< sal_Int32 >( nLineWidth, 35 ); - aLineDash.DotLen *= nBaseLineWidth; - aLineDash.DashLen *= nBaseLineWidth; - aLineDash.Distance *= nBaseLineWidth; if( rPropMap.setProperty( ShapeProperty::LineDash, aLineDash ) ) eLineStyle = drawing::LineStyle_DASH; diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx index 6536798be85b..b42bdb67caad 100644 --- a/oox/source/export/drawingml.cxx +++ b/oox/source/export/drawingml.cxx @@ -738,23 +738,26 @@ void DrawingML::WriteOutline( const Reference<XPropertySet>& rXPropSet ) { // Write 'dashes' first, and then 'dots' int i; + sal_Int32 nSp = aLineDash.Distance * 100 / nLineWidth; if ( aLineDash.Dashes > 0 ) { + sal_Int32 nD = aLineDash.DashLen * 100 / nLineWidth; 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 ), + XML_d , write1000thOfAPercent(nD), + XML_sp, write1000thOfAPercent(nSp), FSEND ); } } if ( aLineDash.Dots > 0 ) { + sal_Int32 nD = aLineDash.DotLen * 100 / nLineWidth; 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 ), + XML_d , write1000thOfAPercent(nD), + XML_sp, write1000thOfAPercent(nSp), FSEND ); } } |