summaryrefslogtreecommitdiff
path: root/oox
diff options
context:
space:
mode:
Diffstat (limited to 'oox')
-rw-r--r--oox/source/drawingml/lineproperties.cxx24
-rw-r--r--oox/source/export/drawingml.cxx49
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,