diff options
Diffstat (limited to 'oox')
-rw-r--r-- | oox/source/drawingml/lineproperties.cxx | 24 | ||||
-rw-r--r-- | oox/source/export/drawingml.cxx | 49 |
2 files changed, 57 insertions, 16 deletions
diff --git a/oox/source/drawingml/lineproperties.cxx b/oox/source/drawingml/lineproperties.cxx index 3183d5ce4c24..451da4c6aa26 100644 --- a/oox/source/drawingml/lineproperties.cxx +++ b/oox/source/drawingml/lineproperties.cxx @@ -443,6 +443,11 @@ void LineProperties::pushToPropMap( ShapePropertyMap& rPropMap, sal_Int32 nLineWidth = getLineWidth(); // includes conversion from EMUs to 1/100mm rPropMap.setProperty( ShapeProperty::LineWidth, nLineWidth ); + // line cap type + LineCap eLineCap = moLineCap.has() ? lclGetLineCap( moLineCap.get() ) : LineCap_BUTT; + if( moLineCap.has() ) + rPropMap.setProperty( ShapeProperty::LineCap, eLineCap ); + // create line dash from preset dash token or dash stop vector (not for invisible line) if( (eLineStyle != drawing::LineStyle_NONE) && (moPresetDash.differsFrom( XML_solid ) || !maCustomDash.empty()) ) { @@ -456,12 +461,25 @@ void LineProperties::pushToPropMap( ShapePropertyMap& rPropMap, lclConvertCustomDash(aLineDash, maCustomDash); lclRecoverStandardDashStyles(aLineDash, nLineWidth); } + + // In MS Office (2020) for preset dash style line caps round and square are included in dash length. + // For custom dash style round line cap is included, square line cap is added. In ODF line caps are + // always added to dash length. Tweak the length accordingly. + if (eLineCap == LineCap_ROUND || (eLineCap == LineCap_SQUARE && maCustomDash.empty())) + { + // Cannot use -100 because that results in 0 length in some cases and + // LibreOffice interprets 0 length as 100%. + if (aLineDash.DotLen >= 100 || aLineDash.DashLen >= 100) + aLineDash.Distance += 99; + if (aLineDash.DotLen >= 100) + aLineDash.DotLen -= 99; + if (aLineDash.DashLen >= 100) + aLineDash.DashLen -= 99; + } + if( rPropMap.setProperty( ShapeProperty::LineDash, aLineDash ) ) eLineStyle = drawing::LineStyle_DASH; } - // line cap type - if( moLineCap.has() ) - rPropMap.setProperty( ShapeProperty::LineCap, lclGetLineCap( moLineCap.get() ) ); // set final line style property rPropMap.setProperty( ShapeProperty::LineStyle, eLineStyle ); diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx index f14129d0a2e8..607db7a33ae7 100644 --- a/oox/source/export/drawingml.cxx +++ b/oox/source/export/drawingml.cxx @@ -733,10 +733,11 @@ void DrawingML::WriteLineArrow( const Reference< XPropertySet >& rXPropSet, bool void DrawingML::WriteOutline( const Reference<XPropertySet>& rXPropSet, Reference< frame::XModel > const & xModel ) { drawing::LineStyle aLineStyle( drawing::LineStyle_NONE ); - if (GetProperty(rXPropSet, "LineStyle")) mAny >>= aLineStyle; + const LineCap aLineCap = GetProperty(rXPropSet, "LineCap") ? mAny.get<drawing::LineCap>() : LineCap_BUTT; + sal_uInt32 nLineWidth = 0; sal_uInt32 nEmuLineWidth = 0; ::Color nColor; @@ -747,6 +748,7 @@ void DrawingML::WriteOutline( const Reference<XPropertySet>& rXPropSet, Referenc bool bDashSet = false; bool bNoFill = false; + // get InteropGrabBag and search the relevant attributes OUString sColorFillScheme; @@ -846,14 +848,10 @@ void DrawingML::WriteOutline( const Reference<XPropertySet>& rXPropSet, Referenc { nColorAlpha = MAX_PERCENT - (mAny.get<sal_Int16>() * PER_PERCENT); } - if (GetProperty(rXPropSet, "LineCap")) - { - const LineCap aLineCap = mAny.get<drawing::LineCap>(); - if (aLineCap == LineCap_ROUND) - cap = "rnd"; - else if (aLineCap == LineCap_SQUARE) - cap = "sq"; - } + if (aLineCap == LineCap_ROUND) + cap = "rnd"; + else if (aLineCap == LineCap_SQUARE) + cap = "sq"; break; } @@ -899,13 +897,25 @@ void DrawingML::WriteOutline( const Reference<XPropertySet>& rXPropSet, Referenc // start with the longer one. Definitions are in OOXML part 1, 20.1.10.49 // The tests are strict, for to not catch styles from standard.sod (as of Aug 2019). bool bIsConverted = false; + bool bIsRelative(aLineDash.Style == DashStyle_RECTRELATIVE || aLineDash.Style == DashStyle_ROUNDRELATIVE); if ( bIsRelative && aLineDash.Dots == 1) - { + { // The length were tweaked on import in case of prstDash. Revert it here. + sal_uInt32 nDotLen = aLineDash.DotLen; + sal_uInt32 nDashLen = aLineDash.DashLen; + sal_uInt32 nDistance = aLineDash.Distance; + if (aLineCap != LineCap_BUTT && nDistance >= 99) + { + nDistance -= 99; + nDotLen += 99; + nDashLen += 99; + } // LO uses length 0 for 100%, if the attribute is missing in ODF. // Other applications might write 100%. Make is unique for the conditions. - sal_uInt32 nDotLen = (aLineDash.DotLen == 0) ? 100 : aLineDash.DotLen; - sal_uInt32 nDashLen = (aLineDash.DashLen == 0 && aLineDash.Dashes > 0) ? 100 : aLineDash.DashLen; + if (nDotLen == 0) + nDotLen = 100; + if (nDashLen == 0 && aLineDash.Dashes > 0) + nDashLen = 100; bIsConverted = true; if (nDotLen == 100 && aLineDash.Dashes == 0 && nDashLen == 0 && aLineDash.Distance == 300) { @@ -964,12 +974,21 @@ void DrawingML::WriteOutline( const Reference<XPropertySet>& rXPropSet, Referenc // So set 100% explicitly. if (aLineDash.Distance <= 0) fSp = 100.0; - if ( aLineDash.Dots > 0 ) + // In case of custDash, round caps are included in dash length in MS Office. Square caps are added + // to dash length, same as in ODF. Change the length values accordingly. + if (aLineCap == LineCap_ROUND && fSp > 99.0) + fSp -= 99.0; + + if (aLineDash.Dots > 0) { double fD = bIsRelative ? aLineDash.DotLen : aLineDash.DotLen * 100.0 / fLineWidth; // LO sets length to 0, if attribute is missing in ODF. Then a relative length of 100% is intended. if (aLineDash.DotLen == 0) fD = 100.0; + // Tweak dash length, see above. + if (aLineCap == LineCap_ROUND && fSp > 99.0) + fD += 99.0; + for( i = 0; i < aLineDash.Dots; i ++ ) { mpFS->singleElementNS( XML_a, XML_ds, @@ -983,6 +1002,10 @@ void DrawingML::WriteOutline( const Reference<XPropertySet>& rXPropSet, Referenc // LO sets length to 0, if attribute is missing in ODF. Then a relative length of 100% is intended. if (aLineDash.DashLen == 0) fD = 100.0; + // Tweak dash length, see above. + if (aLineCap == LineCap_ROUND && fSp > 99.0) + fD += 99.0; + for( i = 0; i < aLineDash.Dashes; i ++ ) { mpFS->singleElementNS( XML_a , XML_ds, |