diff options
author | Regina Henschel <rb.henschel@t-online.de> | 2020-07-27 21:55:05 +0200 |
---|---|---|
committer | Regina Henschel <rb.henschel@t-online.de> | 2020-08-06 13:10:14 +0200 |
commit | 74be8bb787a44464957e5d3105c8de6d36e81b4a (patch) | |
tree | 390e2feb729f68226f2f55f62942837118b122ed | |
parent | a814825461b1fc26288655535b64fc38b18ecf15 (diff) |
tdf#135184 add linecaps in charts
Chart is currently not able to interpret property linecap. But in
case of linecap 'round' or 'square', line dashes lengths are adapted
so that they look same as in MS Office (tdf#134053). This does not
work, if the corresponding linecap property is not interpreted.
Dashed border of data labels is not fixed because of bug
tdf#135366.
In addition I have fixed errors in prstDash detection, which I
have noticed while creating unit tests.
The unit tests cover file text, not visual appearence.
Change-Id: I8cf2d2b2fc0923c2882f8148b4550bc363270480
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/99562
Tested-by: Jenkins
Reviewed-by: Regina Henschel <rb.henschel@t-online.de>
-rw-r--r-- | chart2/CppunitTest_chart2_geometry.mk | 139 | ||||
-rw-r--r-- | chart2/Module_chart2.mk | 1 | ||||
-rw-r--r-- | chart2/qa/extras/chart2geometry.cxx | 242 | ||||
-rw-r--r-- | chart2/qa/extras/data/xlsx/tdf135184RoundLineCap.xlsx | bin | 0 -> 25538 bytes | |||
-rw-r--r-- | chart2/qa/extras/data/xlsx/tdf135184RoundLineCap2.xlsx | bin | 0 -> 21937 bytes | |||
-rw-r--r-- | chart2/source/controller/chartapiwrapper/DataSeriesPointWrapper.cxx | 1 | ||||
-rw-r--r-- | chart2/source/controller/itemsetwrapper/GraphicPropertyItemConverter.cxx | 6 | ||||
-rw-r--r-- | chart2/source/inc/LinePropertiesHelper.hxx | 3 | ||||
-rw-r--r-- | chart2/source/model/main/DataPointProperties.cxx | 8 | ||||
-rw-r--r-- | chart2/source/tools/LinePropertiesHelper.cxx | 8 | ||||
-rw-r--r-- | chart2/source/view/inc/VLineProperties.hxx | 1 | ||||
-rw-r--r-- | chart2/source/view/main/PropertyMapper.cxx | 9 | ||||
-rw-r--r-- | chart2/source/view/main/ShapeFactory.cxx | 5 | ||||
-rw-r--r-- | chart2/source/view/main/VLineProperties.cxx | 3 | ||||
-rw-r--r-- | oox/source/drawingml/chart/objectformatter.cxx | 6 | ||||
-rw-r--r-- | oox/source/export/drawingml.cxx | 23 |
16 files changed, 435 insertions, 20 deletions
diff --git a/chart2/CppunitTest_chart2_geometry.mk b/chart2/CppunitTest_chart2_geometry.mk new file mode 100644 index 000000000000..fb07f9108a5f --- /dev/null +++ b/chart2/CppunitTest_chart2_geometry.mk @@ -0,0 +1,139 @@ +# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*- +#************************************************************************* +# +# This file is part of the LibreOffice project. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +#************************************************************************* + +$(eval $(call gb_CppunitTest_CppunitTest,chart2_geometry)) + +$(eval $(call gb_CppunitTest_use_externals,chart2_geometry, \ + boost_headers \ + libxml2 \ +)) + +$(eval $(call gb_CppunitTest_add_exception_objects,chart2_geometry, \ + chart2/qa/extras/chart2geometry \ +)) + +$(eval $(call gb_CppunitTest_use_libraries,chart2_geometry, \ + $(call gb_Helper_optional,AVMEDIA,avmedia) \ + basegfx \ + comphelper \ + cppu \ + cppuhelper \ + drawinglayer \ + editeng \ + for \ + forui \ + i18nlangtag \ + msfilter \ + oox \ + sal \ + salhelper \ + sax \ + sb \ + sc \ + sw \ + sd \ + sfx \ + sot \ + svl \ + svt \ + svx \ + svxcore \ + test \ + tl \ + tk \ + ucbhelper \ + unotest \ + utl \ + vbahelper \ + vcl \ + xo \ +)) + +$(eval $(call gb_CppunitTest_set_include,chart2_geometry,\ + -I$(SRCDIR)/chart2/inc \ + $$(INCLUDE) \ +)) + +$(eval $(call gb_CppunitTest_use_sdk_api,chart2_geometry)) + +$(eval $(call gb_CppunitTest_use_ure,chart2_geometry)) +$(eval $(call gb_CppunitTest_use_vcl,chart2_geometry)) + +$(eval $(call gb_CppunitTest_use_components,chart2_geometry,\ + basic/util/sb \ + animations/source/animcore/animcore \ + chart2/source/controller/chartcontroller \ + chart2/source/chartcore \ + comphelper/util/comphelp \ + configmgr/source/configmgr \ + dtrans/util/mcnttype \ + dbaccess/util/dba \ + embeddedobj/util/embobj \ + emfio/emfio \ + eventattacher/source/evtatt \ + filter/source/config/cache/filterconfig1 \ + filter/source/odfflatxml/odfflatxml \ + filter/source/storagefilterdetect/storagefd \ + filter/source/xmlfilteradaptor/xmlfa \ + filter/source/xmlfilterdetect/xmlfd \ + forms/util/frm \ + framework/util/fwk \ + i18npool/util/i18npool \ + linguistic/source/lng \ + oox/util/oox \ + package/source/xstor/xstor \ + package/util/package2 \ + sax/source/expatwrap/expwrap \ + sc/util/sc \ + sc/util/scd \ + sc/util/scfilt \ + sw/util/sw \ + sw/util/swd \ + sw/util/msword \ + sd/util/sd \ + sd/util/sdfilt \ + sd/util/sdd \ + $(call gb_Helper_optional,SCRIPTING, \ + sc/util/vbaobj) \ + scaddins/source/analysis/analysis \ + scaddins/source/datefunc/date \ + scripting/source/basprov/basprov \ + scripting/util/scriptframe \ + sfx2/util/sfx \ + sot/util/sot \ + svl/source/fsstor/fsstorage \ + svl/util/svl \ + svtools/util/svt \ + svx/util/svx \ + svx/util/svxcore \ + toolkit/util/tk \ + vcl/vcl.common \ + ucb/source/core/ucb1 \ + ucb/source/ucp/file/ucpfile1 \ + ucb/source/ucp/tdoc/ucptdoc1 \ + unotools/util/utl \ + unoxml/source/rdf/unordf \ + unoxml/source/service/unoxml \ + uui/util/uui \ + writerfilter/util/writerfilter \ + xmloff/util/xo \ + xmlscript/util/xmlscript \ +)) + +$(eval $(call gb_CppunitTest_use_uiconfigs,chart2_geometry, \ + modules/swriter \ +)) + +$(eval $(call gb_CppunitTest_use_configuration,chart2_geometry)) + +$(call gb_CppunitTest_get_target,chart2_geometry): $(call gb_Package_get_target,postprocess_images) + +# vim: set noet sw=4 ts=4: diff --git a/chart2/Module_chart2.mk b/chart2/Module_chart2.mk index c2498b10d96d..37acfdc3730f 100644 --- a/chart2/Module_chart2.mk +++ b/chart2/Module_chart2.mk @@ -30,6 +30,7 @@ $(eval $(call gb_Module_add_slowcheck_targets,chart2,\ CppunitTest_chart2_trendcalculators \ CppunitTest_chart2_dump \ CppunitTest_chart2_pivot_chart_test \ + CppunitTest_chart2_geometry \ )) ifeq ($(ENABLE_CHART_TESTS),TRUE) diff --git a/chart2/qa/extras/chart2geometry.cxx b/chart2/qa/extras/chart2geometry.cxx new file mode 100644 index 000000000000..dedfda6e1c24 --- /dev/null +++ b/chart2/qa/extras/chart2geometry.cxx @@ -0,0 +1,242 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +#include "charttest.hxx" + +#include <test/xmltesttools.hxx> + +#include <com/sun/star/chart2/XRegressionCurveContainer.hpp> +#include <com/sun/star/lang/XServiceName.hpp> +#include <com/sun/star/packages/zip/ZipFileAccess.hpp> +#include <com/sun/star/drawing/LineStyle.hpp> + +#include <unotools/ucbstreamhelper.hxx> + +#include <libxml/xpathInternals.h> + +#include <algorithm> + +using uno::Reference; +using beans::XPropertySet; + +class Chart2GeometryTest : public ChartTest, public XmlTestTools +{ +protected: + virtual void registerNamespaces(xmlXPathContextPtr& pXmlXPathCtx) override; + +public: + Chart2GeometryTest() + : ChartTest() + { + } + void testTdf135184RoundLineCap(); + void testTdf135184RoundLineCap2(); + void testTdf135184RoundLineCap3(); + void testTdf135184RoundLineCap4(); + + CPPUNIT_TEST_SUITE(Chart2GeometryTest); + CPPUNIT_TEST(testTdf135184RoundLineCap); + CPPUNIT_TEST(testTdf135184RoundLineCap2); + CPPUNIT_TEST(testTdf135184RoundLineCap3); + CPPUNIT_TEST(testTdf135184RoundLineCap4); + + CPPUNIT_TEST_SUITE_END(); + +protected: + /** + * Given that some problem doesn't affect the result in the importer, we + * test the resulting file directly, by opening the zip file, parsing an + * xml stream, and asserting an XPath expression. This method returns the + * xml stream, so that you can do the asserting. + */ + xmlDocUniquePtr parseExport(const OUString& rDir, const OUString& rFilterFormat); +}; + +namespace +{ +struct CheckForChartName +{ +private: + OUString aDir; + +public: + explicit CheckForChartName(const OUString& rDir) + : aDir(rDir) + { + } + + bool operator()(const OUString& rName) + { + if (!rName.startsWith(aDir)) + return false; + + if (!rName.endsWith(".xml")) + return false; + + return true; + } +}; + +OUString findChartFile(const OUString& rDir, uno::Reference<container::XNameAccess> const& xNames) +{ + uno::Sequence<OUString> aNames = xNames->getElementNames(); + OUString* pElement = std::find_if(aNames.begin(), aNames.end(), CheckForChartName(rDir)); + + CPPUNIT_ASSERT(pElement != aNames.end()); + return *pElement; +} +} + +xmlDocUniquePtr Chart2GeometryTest::parseExport(const OUString& rDir, const OUString& rFilterFormat) +{ + std::shared_ptr<utl::TempFile> pTempFile = save(rFilterFormat); + + // Read the XML stream we're interested in. + uno::Reference<packages::zip::XZipFileAccess2> xNameAccess + = packages::zip::ZipFileAccess::createWithURL(comphelper::getComponentContext(m_xSFactory), + pTempFile->GetURL()); + uno::Reference<io::XInputStream> xInputStream( + xNameAccess->getByName(findChartFile(rDir, xNameAccess)), uno::UNO_QUERY); + CPPUNIT_ASSERT(xInputStream.is()); + std::unique_ptr<SvStream> pStream(utl::UcbStreamHelper::CreateStream(xInputStream, true)); + + return parseXmlStream(pStream.get()); +} + +void Chart2GeometryTest::registerNamespaces(xmlXPathContextPtr& pXmlXPathCtx) +{ + static struct + { + char const* pPrefix; + char const* pURI; + } const aNamespaces[] + = { { "w", "http://schemas.openxmlformats.org/wordprocessingml/2006/main" }, + { "v", "urn:schemas-microsoft-com:vml" }, + { "c", "http://schemas.openxmlformats.org/drawingml/2006/chart" }, + { "a", "http://schemas.openxmlformats.org/drawingml/2006/main" }, + { "mc", "http://schemas.openxmlformats.org/markup-compatibility/2006" }, + { "wps", "http://schemas.microsoft.com/office/word/2010/wordprocessingShape" }, + { "wpg", "http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" }, + { "wp", "http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" }, + { "c15", "http://schemas.microsoft.com/office/drawing/2012/chart" }, + { "office", "urn:oasis:names:tc:opendocument:xmlns:office:1.0" }, + { "chart", "urn:oasis:names:tc:opendocument:xmlns:chart:1.0" }, + { "style", "urn:oasis:names:tc:opendocument:xmlns:style:1.0" }, + { "svg", "urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" }, + { "table", "urn:oasis:names:tc:opendocument:xmlns:table:1.0" }, + { "text", "urn:oasis:names:tc:opendocument:xmlns:text:1.0" }, + { "xlink", "http://www.w3c.org/1999/xlink" }, + { "c15", "http://schemas.microsoft.com/office/drawing/2012/chart" } }; + for (size_t i = 0; i < SAL_N_ELEMENTS(aNamespaces); ++i) + { + xmlXPathRegisterNs(pXmlXPathCtx, reinterpret_cast<xmlChar const*>(aNamespaces[i].pPrefix), + reinterpret_cast<xmlChar const*>(aNamespaces[i].pURI)); + } +} + +static OString OU2O(const OUString& sOUSource) +{ + return rtl::OUStringToOString(sOUSource, RTL_TEXTENCODING_UTF8); +} + +// Without the patch for tdf#135184, charts were not able to use linecap at all. +// These two tests verify, that round linecaps in the xlsx file are saved in ods. +void Chart2GeometryTest::testTdf135184RoundLineCap() +{ + // It tests chart area, data series line and regression-curve line. + load("/chart2/qa/extras/data/xlsx/", "tdf135184RoundLineCap.xlsx"); + xmlDocUniquePtr pXmlDoc = parseExport("Object 1/content.xml", "calc8"); + CPPUNIT_ASSERT(pXmlDoc); + + const OString sStyleStart("/office:document-content/office:automatic-styles"); + const OString sCap("/style:graphic-properties[@svg:stroke-linecap='round']"); + const OString sChartStart("/office:document-content/office:body/office:chart/chart:chart"); + OString sPredicate; + // chart area + const OUString sOUAreaStyleName = getXPathContent(pXmlDoc, sChartStart + "/@chart:style-name"); + sPredicate = "[@style:name='" + OU2O(sOUAreaStyleName) + "']"; + assertXPath(pXmlDoc, sStyleStart + "/style:style" + sPredicate + sCap); + // data series line + const OString sSeries(sChartStart + "/chart:plot-area/chart:series"); + const OUString sOUSeriesStyleName = getXPathContent(pXmlDoc, sSeries + "/@chart:style-name"); + sPredicate = "[@style:name='" + OU2O(sOUSeriesStyleName) + "']"; + assertXPath(pXmlDoc, sStyleStart + "/style:style" + sPredicate + sCap); + // regression-curve (trend line) + const OString sTrend(sChartStart + "/chart:plot-area/chart:series/chart:regression-curve"); + const OUString sOUTrendStyleName = getXPathContent(pXmlDoc, sTrend + "/@chart:style-name"); + sPredicate = "[@style:name='" + OU2O(sOUTrendStyleName) + "']"; + assertXPath(pXmlDoc, sStyleStart + "/style:style" + sPredicate + sCap); +} + +void Chart2GeometryTest::testTdf135184RoundLineCap2() +{ + // It tests legend, data series sector and title. + load("/chart2/qa/extras/data/xlsx/", "tdf135184RoundLineCap2.xlsx"); + xmlDocUniquePtr pXmlDoc = parseExport("Object 1/content.xml", "calc8"); + CPPUNIT_ASSERT(pXmlDoc); + + const OString sStyleStart("/office:document-content/office:automatic-styles"); + const OString sCap("/style:graphic-properties[@svg:stroke-linecap='round']"); + const OString sChartStart("/office:document-content/office:body/office:chart/chart:chart"); + OString sPredicate; + // legend + const OString sLegend(sChartStart + "/chart:legend"); + const OUString sOULegendStyleName = getXPathContent(pXmlDoc, sLegend + "/@chart:style-name"); + sPredicate = "[@style:name='" + OU2O(sOULegendStyleName) + "']"; + assertXPath(pXmlDoc, sStyleStart + "/style:style" + sPredicate + sCap); + // title + const OString sTitle(sChartStart + "/chart:title"); + const OUString sOUTitleStyleName = getXPathContent(pXmlDoc, sTitle + "/@chart:style-name"); + sPredicate = "[@style:name='" + OU2O(sOUTitleStyleName) + "']"; + assertXPath(pXmlDoc, sStyleStart + "/style:style" + sPredicate + sCap); + // sector + const OString sSector(sChartStart + "/chart:plot-area/chart:series/chart:data-point[3]"); + const OUString sOUSectorStyleName = getXPathContent(pXmlDoc, sSector + "/@chart:style-name"); + sPredicate = "[@style:name='" + OU2O(sOUSectorStyleName) + "']"; + assertXPath(pXmlDoc, sStyleStart + "/style:style" + sPredicate + sCap); +} + +// These two tests verify the round-trip of preset dash styles in the xlsx file. +void Chart2GeometryTest::testTdf135184RoundLineCap3() +{ + // It tests chart area, data series line and regression-curve line. + load("/chart2/qa/extras/data/xlsx/", "tdf135184RoundLineCap.xlsx"); + xmlDocUniquePtr pXmlDoc = parseExport("xl/charts/chart", "Calc Office Open XML"); + CPPUNIT_ASSERT(pXmlDoc); + + const OString sDash("/c:spPr/a:ln/a:prstDash"); + // chart area + assertXPath(pXmlDoc, "/c:chartSpace" + sDash, "val", "dashDot"); + // data series line + const OString sStart("/c:chartSpace/c:chart/c:plotArea/c:scatterChart/c:ser"); + assertXPath(pXmlDoc, sStart + sDash, "val", "dash"); + // regression-curve (trendline) + assertXPath(pXmlDoc, sStart + "/c:trendline" + sDash, "val", "sysDot"); +} + +void Chart2GeometryTest::testTdf135184RoundLineCap4() +{ + // It tests legend, data series sector and title. + load("/chart2/qa/extras/data/xlsx/", "tdf135184RoundLineCap2.xlsx"); + xmlDocUniquePtr pXmlDoc = parseExport("xl/charts/chart", "Calc Office Open XML"); + CPPUNIT_ASSERT(pXmlDoc); + + const OString sChartStart("/c:chartSpace/c:chart"); + const OString sDash("/c:spPr/a:ln/a:prstDash"); + assertXPath(pXmlDoc, sChartStart + "/c:legend" + sDash, "val", "sysDot"); + const OString sSeries(sChartStart + "/c:plotArea/c:pieChart/c:ser/c:dPt[3]"); + assertXPath(pXmlDoc, sSeries + sDash, "val", "dash"); + assertXPath(pXmlDoc, sChartStart + "/c:title" + sDash, "val", "dashDot"); +} + +CPPUNIT_TEST_SUITE_REGISTRATION(Chart2GeometryTest); + +CPPUNIT_PLUGIN_IMPLEMENT(); + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/chart2/qa/extras/data/xlsx/tdf135184RoundLineCap.xlsx b/chart2/qa/extras/data/xlsx/tdf135184RoundLineCap.xlsx Binary files differnew file mode 100644 index 000000000000..69cad0d671fd --- /dev/null +++ b/chart2/qa/extras/data/xlsx/tdf135184RoundLineCap.xlsx diff --git a/chart2/qa/extras/data/xlsx/tdf135184RoundLineCap2.xlsx b/chart2/qa/extras/data/xlsx/tdf135184RoundLineCap2.xlsx Binary files differnew file mode 100644 index 000000000000..ced797258ad2 --- /dev/null +++ b/chart2/qa/extras/data/xlsx/tdf135184RoundLineCap2.xlsx diff --git a/chart2/source/controller/chartapiwrapper/DataSeriesPointWrapper.cxx b/chart2/source/controller/chartapiwrapper/DataSeriesPointWrapper.cxx index e98ebe65bbbd..a6d45dddaa47 100644 --- a/chart2/source/controller/chartapiwrapper/DataSeriesPointWrapper.cxx +++ b/chart2/source/controller/chartapiwrapper/DataSeriesPointWrapper.cxx @@ -737,6 +737,7 @@ std::vector< std::unique_ptr<WrappedProperty> > DataSeriesPointWrapper::createWr aWrappedProperties.emplace_back( new WrappedSeriesAreaOrLineProperty("LineDashName","BorderDashName","LineDashName", this ) ); aWrappedProperties.emplace_back( new WrappedSeriesAreaOrLineProperty("LineTransparence","BorderTransparency","Transparency", this ) ); aWrappedProperties.emplace_back( new WrappedSeriesAreaOrLineProperty("LineWidth","BorderWidth","LineWidth", this ) ); + aWrappedProperties.emplace_back( new WrappedSeriesAreaOrLineProperty("LineCap","LineCap","LineCap", this ) ); aWrappedProperties.emplace_back( new WrappedProperty("FillStyle","FillStyle" ) ); aWrappedProperties.emplace_back( new WrappedProperty("FillTransparence","Transparency") ); diff --git a/chart2/source/controller/itemsetwrapper/GraphicPropertyItemConverter.cxx b/chart2/source/controller/itemsetwrapper/GraphicPropertyItemConverter.cxx index ffa8c29a5b77..55e954e946d9 100644 --- a/chart2/source/controller/itemsetwrapper/GraphicPropertyItemConverter.cxx +++ b/chart2/source/controller/itemsetwrapper/GraphicPropertyItemConverter.cxx @@ -71,7 +71,8 @@ ItemPropertyMapType & lcl_GetDataPointLinePropertyMap() static ItemPropertyMapType aDataPointPropertyLineMap{ {XATTR_LINECOLOR, {"Color", 0}}, {XATTR_LINESTYLE, {"LineStyle", 0}}, - {XATTR_LINEWIDTH, {"LineWidth", 0}}}; + {XATTR_LINEWIDTH, {"LineWidth", 0}}, + {XATTR_LINECAP, {"LineCap", 0}}}; return aDataPointPropertyLineMap; } ItemPropertyMapType & lcl_GetLinePropertyMap() @@ -80,7 +81,8 @@ ItemPropertyMapType & lcl_GetLinePropertyMap() {XATTR_LINESTYLE, {"LineStyle", 0}}, {XATTR_LINEWIDTH, {"LineWidth", 0}}, {XATTR_LINECOLOR, {"LineColor", 0}}, - {XATTR_LINEJOINT, {"LineJoint", 0}}}; + {XATTR_LINEJOINT, {"LineJoint", 0}}, + {XATTR_LINECAP, {"LineCap", 0}}}; return aLinePropertyMap; } ItemPropertyMapType & lcl_GetFillPropertyMap() diff --git a/chart2/source/inc/LinePropertiesHelper.hxx b/chart2/source/inc/LinePropertiesHelper.hxx index 11c56b186eaf..e870a5688cf1 100644 --- a/chart2/source/inc/LinePropertiesHelper.hxx +++ b/chart2/source/inc/LinePropertiesHelper.hxx @@ -45,7 +45,8 @@ namespace LinePropertiesHelper PROP_LINE_COLOR, PROP_LINE_TRANSPARENCE, PROP_LINE_WIDTH, - PROP_LINE_JOINT + PROP_LINE_JOINT, + PROP_LINE_CAP }; OOO_DLLPUBLIC_CHARTTOOLS void AddPropertiesToVector( diff --git a/chart2/source/model/main/DataPointProperties.cxx b/chart2/source/model/main/DataPointProperties.cxx index 7bc20bbc30e6..dba488fdd924 100644 --- a/chart2/source/model/main/DataPointProperties.cxx +++ b/chart2/source/model/main/DataPointProperties.cxx @@ -26,6 +26,7 @@ #include <com/sun/star/drawing/FillStyle.hpp> #include <com/sun/star/drawing/LineStyle.hpp> #include <com/sun/star/drawing/LineDash.hpp> +#include <com/sun/star/drawing/LineCap.hpp> #include <com/sun/star/drawing/BitmapMode.hpp> #include <com/sun/star/drawing/RectanglePoint.hpp> #include <com/sun/star/chart2/RelativePosition.hpp> @@ -220,6 +221,12 @@ void DataPointProperties::AddPropertiesToVector( beans::PropertyAttribute::BOUND | beans::PropertyAttribute::MAYBEVOID ); + rOutProperties.emplace_back( "LineCap", + ::chart::LinePropertiesHelper::PROP_LINE_CAP, + cppu::UnoType<drawing::LineCap>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT ); + // FillProperties // bitmap properties rOutProperties.emplace_back( "FillBitmapOffsetX", @@ -466,6 +473,7 @@ void DataPointProperties::AddDefaultsToMap( PropertyHelper::setPropertyValueDefault< sal_Int32 >( rOutMap, LinePropertiesHelper::PROP_LINE_WIDTH, 0 ); PropertyHelper::setPropertyValueDefault( rOutMap, LinePropertiesHelper::PROP_LINE_DASH, drawing::LineDash()); PropertyHelper::setEmptyPropertyValueDefault( rOutMap, LinePropertiesHelper::PROP_LINE_DASH_NAME ); + PropertyHelper::setPropertyValueDefault( rOutMap, LinePropertiesHelper::PROP_LINE_CAP, drawing::LineCap_BUTT); //fill bitmap PropertyHelper::setPropertyValueDefault< sal_Int16 >( rOutMap, FillProperties::PROP_FILL_BITMAP_OFFSETX, 0 ); diff --git a/chart2/source/tools/LinePropertiesHelper.cxx b/chart2/source/tools/LinePropertiesHelper.cxx index 227ec99b6383..7e6d28860903 100644 --- a/chart2/source/tools/LinePropertiesHelper.cxx +++ b/chart2/source/tools/LinePropertiesHelper.cxx @@ -22,6 +22,7 @@ #include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/drawing/LineStyle.hpp> #include <com/sun/star/drawing/LineDash.hpp> +#include <com/sun/star/drawing/LineCap.hpp> #include <com/sun/star/drawing/LineJoint.hpp> #include <tools/diagnose_ex.h> @@ -79,6 +80,12 @@ void LinePropertiesHelper::AddPropertiesToVector( cppu::UnoType<drawing::LineJoint>::get(), beans::PropertyAttribute::BOUND | beans::PropertyAttribute::MAYBEDEFAULT ); + + rOutProperties.emplace_back( "LineCap", + PROP_LINE_CAP, + cppu::UnoType<drawing::LineCap>::get(), + beans::PropertyAttribute::BOUND + | beans::PropertyAttribute::MAYBEDEFAULT ); } void LinePropertiesHelper::AddDefaultsToMap( @@ -89,6 +96,7 @@ void LinePropertiesHelper::AddDefaultsToMap( ::chart::PropertyHelper::setPropertyValueDefault< sal_Int32 >( rOutMap, PROP_LINE_COLOR, 0x000000 ); // black ::chart::PropertyHelper::setPropertyValueDefault< sal_Int16 >( rOutMap, PROP_LINE_TRANSPARENCE, 0 ); ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_LINE_JOINT, drawing::LineJoint_ROUND ); + ::chart::PropertyHelper::setPropertyValueDefault( rOutMap, PROP_LINE_CAP, drawing::LineCap_BUTT ); } bool LinePropertiesHelper::IsLineVisible( const css::uno::Reference< diff --git a/chart2/source/view/inc/VLineProperties.hxx b/chart2/source/view/inc/VLineProperties.hxx index a255499fd088..864e78316322 100644 --- a/chart2/source/view/inc/VLineProperties.hxx +++ b/chart2/source/view/inc/VLineProperties.hxx @@ -35,6 +35,7 @@ struct VLineProperties css::uno::Any Transparence;//type sal_Int16 for property UNO_NAME_LINETRANSPARENCE css::uno::Any Width;//type sal_Int32 for property UNO_NAME_LINEWIDTH css::uno::Any DashName;//type OUString for property "LineDashName" + css::uno::Any LineCap; //type drawing::LineCap for propertey UNO_NAME_LINECAP VLineProperties(); void initFromPropertySet( const css::uno::Reference< css::beans::XPropertySet >& xProp ); diff --git a/chart2/source/view/main/PropertyMapper.cxx b/chart2/source/view/main/PropertyMapper.cxx index 0550cdd5ce11..8611cef5d43a 100644 --- a/chart2/source/view/main/PropertyMapper.cxx +++ b/chart2/source/view/main/PropertyMapper.cxx @@ -282,7 +282,8 @@ const tPropertyNameMap& PropertyMapper::getPropertyNameMapForLineProperties() {"LineJoint", "LineJoint"}, {"LineStyle", "LineStyle"}, {"LineTransparence", "LineTransparence"}, - {"LineWidth", "LineWidth"}}; + {"LineWidth", "LineWidth"}, + {"LineCap", "LineCap"}}; return s_aShapePropertyMapForLineProperties; } @@ -329,7 +330,8 @@ const tPropertyNameMap& PropertyMapper::getPropertyNameMapForLineSeriesPropertie {"LineDashName", "LineDashName"}, {"LineStyle", "LineStyle"}, {"LineTransparence", "Transparency"}, - {"LineWidth", "LineWidth"}}; + {"LineWidth", "LineWidth"}, + {"LineCap", "LineCap"}}; return s_aShapePropertyMapForLineSeriesProperties; } @@ -385,7 +387,8 @@ const tPropertyNameMap& PropertyMapper::getPropertyNameMapForFilledSeriesPropert {"LineDashName", "BorderDashName"}, {"LineStyle", "BorderStyle"}, {"LineTransparence", "BorderTransparency"}, - {"LineWidth", "BorderWidth"}}; + {"LineWidth", "BorderWidth"}, + {"LineCap", "LineCap"}}; return s_aShapePropertyMapForFilledSeriesProperties; } diff --git a/chart2/source/view/main/ShapeFactory.cxx b/chart2/source/view/main/ShapeFactory.cxx index 674d42ddbacc..59cf88675070 100644 --- a/chart2/source/view/main/ShapeFactory.cxx +++ b/chart2/source/view/main/ShapeFactory.cxx @@ -2029,6 +2029,11 @@ uno::Reference< drawing::XShape > if(pLineProperties->DashName.hasValue()) xProp->setPropertyValue( "LineDashName" , pLineProperties->DashName ); + + //LineCap + if(pLineProperties->LineCap.hasValue()) + xProp->setPropertyValue( UNO_NAME_LINECAP + , pLineProperties->LineCap ); } } catch( const uno::Exception& ) diff --git a/chart2/source/view/main/VLineProperties.cxx b/chart2/source/view/main/VLineProperties.cxx index f1ca35e71730..e86c5f7b810f 100644 --- a/chart2/source/view/main/VLineProperties.cxx +++ b/chart2/source/view/main/VLineProperties.cxx @@ -19,6 +19,7 @@ #include <VLineProperties.hxx> #include <com/sun/star/drawing/LineStyle.hpp> +#include <com/sun/star/drawing/LineCap.hpp> #include <com/sun/star/beans/XPropertySet.hpp> #include <tools/diagnose_ex.h> @@ -34,6 +35,7 @@ VLineProperties::VLineProperties() LineStyle <<= drawing::LineStyle_SOLID; //type drawing::LineStyle for property UNO_NAME_LINESTYLE Transparence <<= sal_Int16(0);//type sal_Int16 for property UNO_NAME_LINETRANSPARENCE Width <<= sal_Int32(0);//type sal_Int32 for property UNO_NAME_LINEWIDTH + LineCap <<= drawing::LineCap_BUTT; //type drawing::LineCap for property UNO_NAME_LINECAP } void VLineProperties::initFromPropertySet( const uno::Reference< beans::XPropertySet >& xProp ) @@ -47,6 +49,7 @@ void VLineProperties::initFromPropertySet( const uno::Reference< beans::XPropert Transparence = xProp->getPropertyValue( "LineTransparence" ); Width = xProp->getPropertyValue( "LineWidth" ); DashName = xProp->getPropertyValue( "LineDashName" ); + LineCap = xProp->getPropertyValue( "LineCap" ); } catch( const uno::Exception& ) { diff --git a/oox/source/drawingml/chart/objectformatter.cxx b/oox/source/drawingml/chart/objectformatter.cxx index c0669678eee0..326f632e84b3 100644 --- a/oox/source/drawingml/chart/objectformatter.cxx +++ b/oox/source/drawingml/chart/objectformatter.cxx @@ -446,7 +446,7 @@ const AutoTextEntry* lclGetAutoTextEntry( const AutoTextEntry* pEntries, sal_Int const ShapePropertyIds spnCommonPropIds = { PROP_LineStyle, PROP_LineWidth, PROP_LineColor, PROP_LineTransparence, PROP_LineDashName, - PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, + PROP_LineCap, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_FillStyle, PROP_FillColor, PROP_FillTransparence, PROP_INVALID, PROP_FillGradientName, PROP_FillBitmapName, PROP_FillBitmapMode, PROP_FillBitmapSizeX, PROP_FillBitmapSizeY, PROP_FillBitmapPositionOffsetX, PROP_FillBitmapPositionOffsetY, PROP_FillBitmapRectanglePoint, @@ -456,7 +456,7 @@ const ShapePropertyIds spnCommonPropIds = const ShapePropertyIds spnLinearPropIds = { PROP_LineStyle, PROP_LineWidth, PROP_Color, PROP_Transparency, PROP_LineDashName, - PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, + PROP_LineCap, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, PROP_INVALID, @@ -470,7 +470,7 @@ const ShapePropertyIds spnFilledPropIds = PROP_BorderColor, PROP_BorderTransparency, PROP_BorderDashName, - PROP_INVALID, + PROP_LineCap, PROP_INVALID, PROP_INVALID, PROP_INVALID, diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx index 155c33796f70..a0d24576d371 100644 --- a/oox/source/export/drawingml.cxx +++ b/oox/source/export/drawingml.cxx @@ -959,7 +959,8 @@ void DrawingML::WriteOutline( const Reference<XPropertySet>& rXPropSet, Referenc { nDistance -= 99; nDotLen += 99; - nDashLen += 99; + if (nDashLen > 0) + 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. @@ -968,43 +969,43 @@ void DrawingML::WriteOutline( const Reference<XPropertySet>& rXPropSet, Referenc if (nDashLen == 0 && aLineDash.Dashes > 0) nDashLen = 100; bIsConverted = true; - if (nDotLen == 100 && aLineDash.Dashes == 0 && nDashLen == 0 && aLineDash.Distance == 300) + if (nDotLen == 100 && aLineDash.Dashes == 0 && nDashLen == 0 && nDistance == 300) { mpFS->singleElementNS(XML_a, XML_prstDash, XML_val, "dot"); } - else if (nDotLen == 400 && aLineDash.Dashes == 0 && nDashLen == 0 && aLineDash.Distance == 300) + else if (nDotLen == 400 && aLineDash.Dashes == 0 && nDashLen == 0 && nDistance == 300) { mpFS->singleElementNS(XML_a, XML_prstDash, XML_val, "dash"); } - else if (nDotLen == 400 && aLineDash.Dashes == 1 && nDashLen == 100 && aLineDash.Distance == 300) + else if (nDotLen == 400 && aLineDash.Dashes == 1 && nDashLen == 100 && nDistance == 300) { mpFS->singleElementNS(XML_a, XML_prstDash, XML_val, "dashDot"); } - else if (nDotLen == 800 && aLineDash.Dashes == 0 && nDashLen == 0 && aLineDash.Distance == 300) + else if (nDotLen == 800 && aLineDash.Dashes == 0 && nDashLen == 0 && nDistance == 300) { mpFS->singleElementNS(XML_a, XML_prstDash, XML_val, "lgDash"); } - else if (nDotLen == 800 && aLineDash.Dashes == 1 && nDashLen == 100 && aLineDash.Distance == 300) + else if (nDotLen == 800 && aLineDash.Dashes == 1 && nDashLen == 100 && nDistance == 300) { mpFS->singleElementNS(XML_a, XML_prstDash, XML_val, "lgDashDot"); } - else if (nDotLen == 800 && aLineDash.Dashes == 2 && nDashLen == 100 && aLineDash.Distance == 300) + else if (nDotLen == 800 && aLineDash.Dashes == 2 && nDashLen == 100 && nDistance == 300) { mpFS->singleElementNS(XML_a, XML_prstDash, XML_val, "lgDashDotDot"); } - else if (nDotLen == 100 && aLineDash.Dashes == 0 && nDashLen == 0 && aLineDash.Distance == 100) + else if (nDotLen == 100 && aLineDash.Dashes == 0 && nDashLen == 0 && nDistance == 100) { mpFS->singleElementNS(XML_a, XML_prstDash, XML_val, "sysDot"); } - else if (nDotLen == 300 && aLineDash.Dashes == 0 && nDashLen == 0 && aLineDash.Distance == 100) + else if (nDotLen == 300 && aLineDash.Dashes == 0 && nDashLen == 0 && nDistance == 100) { mpFS->singleElementNS(XML_a, XML_prstDash, XML_val, "sysDash"); } - else if (nDotLen == 300 && aLineDash.Dashes == 1 && nDashLen == 100 && aLineDash.Distance == 100) + else if (nDotLen == 300 && aLineDash.Dashes == 1 && nDashLen == 100 && nDistance == 100) { mpFS->singleElementNS(XML_a, XML_prstDash, XML_val, "sysDashDot"); } - else if (nDotLen == 300 && aLineDash.Dashes == 2 && nDashLen == 100 && aLineDash.Distance == 100) + else if (nDotLen == 300 && aLineDash.Dashes == 2 && nDashLen == 100 && nDistance == 100) { mpFS->singleElementNS(XML_a, XML_prstDash, XML_val, "sysDashDotDot"); } |