[Libreoffice-commits] core.git: Branch 'libreoffice-7-0' - oox/source sd/qa
Regina Henschel (via logerrit)
logerrit at kemper.freedesktop.org
Tue Jun 23 14:58:48 UTC 2020
oox/source/drawingml/lineproperties.cxx | 24 ++++++++++++-
oox/source/export/drawingml.cxx | 49 ++++++++++++++++++++--------
sd/qa/unit/data/pptx/tdf134053_dashdot.pptx |binary
sd/qa/unit/uiimpress.cxx | 34 +++++++++++++++++++
4 files changed, 91 insertions(+), 16 deletions(-)
New commits:
commit 1cbdc101c72309a97e9ee09c77f4fd36fbd71314
Author: Regina Henschel <rb.henschel at t-online.de>
AuthorDate: Sat Jun 20 15:08:12 2020 +0200
Commit: Adolfo Jayme Barrientos <fitojb at ubuntu.com>
CommitDate: Tue Jun 23 16:58:18 2020 +0200
tdf#134053 tweak dash and space length for ooxml
OOXML does not specify how line caps are applied to dashes. MS Office
keeps dash and space length for preset dash styles and for round
custom dash styles and add them for square line caps on custom dash
styles. ODF specifies, that the linecaps are added to the dashes and
the spaces are reduced, so that the dash-space pair keeps its length.
This patch changes the dash and space length on import and export so,
that they look nearly the same in LibreOffice as in MS Office.
For custom dash styles with square line cap the first dash is longer
as in MS Office. I have no solution for that. But I consider it as
minor problem, because MS Office has not even an UI for that case. It
should not hinder the improvement for the usual cases.
Change-Id: I3e3e4b7c9d71e440ed301d2be423100440cb688b
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/96769
Tested-by: Jenkins
Reviewed-by: Regina Henschel <rb.henschel at t-online.de>
(cherry picked from commit 3f3b50015e4fd9efc3459612a70409fca49cf390)
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/96796
Reviewed-by: Adolfo Jayme Barrientos <fitojb at ubuntu.com>
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,
diff --git a/sd/qa/unit/data/pptx/tdf134053_dashdot.pptx b/sd/qa/unit/data/pptx/tdf134053_dashdot.pptx
new file mode 100644
index 000000000000..f2d951c570fd
Binary files /dev/null and b/sd/qa/unit/data/pptx/tdf134053_dashdot.pptx differ
diff --git a/sd/qa/unit/uiimpress.cxx b/sd/qa/unit/uiimpress.cxx
index 93a76ac2597d..56d1f8fc789b 100644
--- a/sd/qa/unit/uiimpress.cxx
+++ b/sd/qa/unit/uiimpress.cxx
@@ -345,6 +345,40 @@ CPPUNIT_TEST_FIXTURE(SdUiImpressTest, testPageFillGradient)
CPPUNIT_ASSERT_EQUAL(OUString("ff0000"), aGradient.GetStartColor().AsRGBHexString());
CPPUNIT_ASSERT_EQUAL(OUString("0000ff"), aGradient.GetEndColor().AsRGBHexString());
}
+
+CPPUNIT_TEST_FIXTURE(SdUiImpressTest, testTdf134053)
+{
+ // Error was, that dashes and dots were longer than in MS Office.
+ mxComponent = loadFromDesktop(
+ m_directories.getURLFromSrc("sd/qa/unit/data/pptx/tdf134053_dashdot.pptx"));
+ auto pXImpressDocument = dynamic_cast<SdXImpressDocument*>(mxComponent.get());
+ sd::ViewShell* pViewShell = pXImpressDocument->GetDocShell()->GetViewShell();
+ SdPage* pActualPage = pViewShell->GetActualPage();
+ SdrObject* pShape = pActualPage->GetObj(0);
+ CPPUNIT_ASSERT_MESSAGE("No Shape", pShape);
+
+ // Break line into single dash and dot objects
+ SdrView* pView = pViewShell->GetView();
+ pView->MarkObj(pShape, pView->GetSdrPageView());
+ dispatchCommand(mxComponent, ".uno:ConvertIntoMetafile", {});
+ dispatchCommand(mxComponent, ".uno:Break", {});
+
+ // Measure the rendered length of dash, dot and distance
+ SdrObject* pDash = pActualPage->GetObj(0);
+ const tools::Rectangle& rBoundDashRect = pDash->GetCurrentBoundRect();
+ const double fDashLength(rBoundDashRect.GetWidth());
+ SdrObject* pDot = pActualPage->GetObj(1);
+ const tools::Rectangle& rBoundDotRect = pDot->GetCurrentBoundRect();
+ const double fDotLength(rBoundDotRect.GetWidth());
+ const double fDistance(rBoundDotRect.Left() - rBoundDashRect.Right());
+
+ // Because 0% is not possible as dash length (as of June 2020) 1% is used in the fix.
+ // For that a larger delta is here allowed to the ideal value than needed for
+ // rounding errors.
+ CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Distance", 2117, fDistance, 12);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Dot length", 706, fDotLength, 12);
+ CPPUNIT_ASSERT_DOUBLES_EQUAL_MESSAGE("Dash length", 2822, fDashLength, 12);
+}
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
More information about the Libreoffice-commits
mailing list