diff options
author | Miklos Vajna <vmiklos@collabora.com> | 2020-12-02 14:09:31 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2020-12-02 17:19:47 +0100 |
commit | a75bf43a8d6c5dec6dcc86908c142ceec541aa8c (patch) | |
tree | 8a88986f2f6620ccd6f707c93125d94716274ae1 /svx | |
parent | 5b464179c19310504e5a6f900811b7cc523120b6 (diff) |
tdf#129961 svx: add rendering for table shadow as direct format
There was already shadow support in
ViewContactOfTableObj::createViewIndependentPrimitive2DSequence(), but
the UNO API and UI could only set the shadow properties on a shape
style, so shadow-as-direct-format is new.
One difference between the PowerPoint shadow and our shadow is that we
draw shadow for table text as well, while PowerPoint only does it for
the borders / cell fill style.
This means we're either backwards-compatible or compatible with
PowerPoint. Solve this problem by leaving the style case unchanged, but
render direct formatting like PowerPoint.
Change-Id: I2bc64fea8062f9d8162b95d1eaccb49c3466b5c5
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/107073
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins
Diffstat (limited to 'svx')
-rw-r--r-- | svx/inc/sdr/primitive2d/sdrdecompositiontools.hxx | 3 | ||||
-rw-r--r-- | svx/qa/unit/unodraw.cxx | 44 | ||||
-rw-r--r-- | svx/source/sdr/primitive2d/sdrdecompositiontools.cxx | 5 | ||||
-rw-r--r-- | svx/source/table/viewcontactoftableobj.cxx | 34 |
4 files changed, 81 insertions, 5 deletions
diff --git a/svx/inc/sdr/primitive2d/sdrdecompositiontools.hxx b/svx/inc/sdr/primitive2d/sdrdecompositiontools.hxx index 202354332b55..db1c94c1b7fa 100644 --- a/svx/inc/sdr/primitive2d/sdrdecompositiontools.hxx +++ b/svx/inc/sdr/primitive2d/sdrdecompositiontools.hxx @@ -71,7 +71,8 @@ namespace drawinglayer::primitive2d Primitive2DContainer SVXCORE_DLLPUBLIC createEmbeddedShadowPrimitive( const Primitive2DContainer& rContent, const attribute::SdrShadowAttribute& rShadow, - const basegfx::B2DHomMatrix& rObjectMatrix = basegfx::B2DHomMatrix()); + const basegfx::B2DHomMatrix& rObjectMatrix = basegfx::B2DHomMatrix(), + const Primitive2DContainer* pContentForShadow = nullptr); Primitive2DContainer SVXCORE_DLLPUBLIC createEmbeddedGlowPrimitive( const Primitive2DContainer& rContent, diff --git a/svx/qa/unit/unodraw.cxx b/svx/qa/unit/unodraw.cxx index 51b1c8b43847..938e44f9ca21 100644 --- a/svx/qa/unit/unodraw.cxx +++ b/svx/qa/unit/unodraw.cxx @@ -16,12 +16,23 @@ #include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/awt/XControlModel.hpp> #include <com/sun/star/graphic/XGraphic.hpp> +#include <com/sun/star/table/XCellRange.hpp> +#include <com/sun/star/text/XTextRange.hpp> #include <comphelper/processfactory.hxx> #include <comphelper/propertysequence.hxx> #include <test/bootstrapfixture.hxx> #include <unotest/macros_test.hxx> #include <unotools/tempfile.hxx> +#include <svx/unopage.hxx> +#include <vcl/virdev.hxx> +#include <svx/sdr/contact/displayinfo.hxx> +#include <drawinglayer/tools/primitive2dxmldump.hxx> +#include <svx/sdr/contact/viewcontact.hxx> +#include <svx/sdr/contact/viewobjectcontact.hxx> +#include <test/xmltesttools.hxx> + +#include <sdr/contact/objectcontactofobjlistpainter.hxx> using namespace ::com::sun::star; @@ -30,7 +41,7 @@ namespace char const DATA_DIRECTORY[] = "/svx/qa/unit/data/"; /// Tests for svx/source/unodraw/ code. -class UnodrawTest : public test::BootstrapFixture, public unotest::MacrosTest +class UnodrawTest : public test::BootstrapFixture, public unotest::MacrosTest, public XmlTestTools { protected: uno::Reference<lang::XComponent> mxComponent; @@ -132,6 +143,37 @@ CPPUNIT_TEST_FIXTURE(UnodrawTest, testTableShadowDirect) xShapeProps->setPropertyValue("ShadowColor", uno::makeAny(nRed)); CPPUNIT_ASSERT(xShapeProps->getPropertyValue("ShadowColor") >>= nRed); CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(0xff0000), nRed); + + // Add text. + uno::Reference<table::XCellRange> xTable(xShapeProps->getPropertyValue("Model"), + uno::UNO_QUERY); + uno::Reference<text::XTextRange> xCell(xTable->getCellByPosition(0, 0), uno::UNO_QUERY); + xCell->setString("A1"); + + // Generates drawinglayer primitives for the shape. + auto pDrawPage = dynamic_cast<SvxDrawPage*>(xDrawPage.get()); + CPPUNIT_ASSERT(pDrawPage); + SdrPage* pSdrPage = pDrawPage->GetSdrPage(); + ScopedVclPtrInstance<VirtualDevice> aVirtualDevice; + sdr::contact::ObjectContactOfObjListPainter aObjectContact(*aVirtualDevice, + { pSdrPage->GetObj(0) }, nullptr); + const sdr::contact::ViewObjectContact& rDrawPageVOContact + = pSdrPage->GetViewContact().GetViewObjectContact(aObjectContact); + sdr::contact::DisplayInfo aDisplayInfo; + drawinglayer::primitive2d::Primitive2DContainer xPrimitiveSequence + = rDrawPageVOContact.getPrimitive2DSequenceHierarchy(aDisplayInfo); + + // Check the primitives. + drawinglayer::Primitive2dXmlDump aDumper; + xmlDocUniquePtr pDocument = aDumper.dumpAndParse(xPrimitiveSequence); + assertXPath(pDocument, "//shadow", /*nNumberOfNodes=*/1); + + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 0 + // - Actual : 1 + // i.e. there was shadow for the cell text, while here PowerPoint-compatible output is expected, + // which has no shadow for cell text (only for cell borders and cell background). + assertXPath(pDocument, "//shadow//sdrblocktext", /*nNumberOfNodes=*/0); } } diff --git a/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx b/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx index 9d17e86959b9..0a720842a1e3 100644 --- a/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx +++ b/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx @@ -484,7 +484,8 @@ namespace drawinglayer::primitive2d Primitive2DContainer createEmbeddedShadowPrimitive( const Primitive2DContainer& rContent, const attribute::SdrShadowAttribute& rShadow, - const basegfx::B2DHomMatrix& rObjectMatrix) + const basegfx::B2DHomMatrix& rObjectMatrix, + const Primitive2DContainer* pContentForShadow) { if(!rContent.empty()) { @@ -524,7 +525,7 @@ namespace drawinglayer::primitive2d aShadowOffset, rShadow.getColor(), rShadow.getBlur(), - rContent)); + (pContentForShadow ? *pContentForShadow : rContent))); if(0.0 != rShadow.getTransparence()) { diff --git a/svx/source/table/viewcontactoftableobj.cxx b/svx/source/table/viewcontactoftableobj.cxx index fe6d03f1d900..bd950a02f7fb 100644 --- a/svx/source/table/viewcontactoftableobj.cxx +++ b/svx/source/table/viewcontactoftableobj.cxx @@ -36,6 +36,7 @@ #include <basegfx/matrix/b2dhommatrixtools.hxx> #include <svx/framelink.hxx> #include <svx/framelinkarray.hxx> +#include <svx/sdooitm.hxx> #include <vcl/canvastools.hxx> #include <cell.hxx> @@ -205,6 +206,7 @@ namespace sdr::contact // directly to aRetval, Border info to aBorderSequence and added // later to get the correct overlapping drawinglayer::primitive2d::Primitive2DContainer aRetval; + drawinglayer::primitive2d::Primitive2DContainer aRetvalForShadow; const sal_Int32 nRowCount(xTable->getRowCount()); const sal_Int32 nColCount(xTable->getColumnCount()); const sal_Int32 nAllCount(nRowCount * nColCount); @@ -317,6 +319,16 @@ namespace sdr::contact aCellMatrix, aAttribute)); aRetval.append(xCellReference); } + + // Create cell primitive without text. + aAttribute + = drawinglayer::primitive2d::createNewSdrFillTextAttribute( + rCellItemSet, nullptr); + const drawinglayer::primitive2d::Primitive2DReference + xCellReference( + new drawinglayer::primitive2d::SdrCellPrimitive2D( + aCellMatrix, aAttribute)); + aRetvalForShadow.append(xCellReference); } } } @@ -364,6 +376,10 @@ namespace sdr::contact new drawinglayer::primitive2d::TransformPrimitive2D( aTransform, aCellBorderPrimitives)); + + // Borders are always the same for shadow as well. + aRetvalForShadow.append(new drawinglayer::primitive2d::TransformPrimitive2D( + aTransform, aCellBorderPrimitives)); } } @@ -376,7 +392,23 @@ namespace sdr::contact if(!aNewShadowAttribute.isDefault()) { - aRetval = drawinglayer::primitive2d::createEmbeddedShadowPrimitive(aRetval, aNewShadowAttribute); + bool bDirectShadow + = rObjectItemSet.Get(SDRATTR_SHADOW, /*bSrchInParent=*/false) + .GetValue(); + if (bDirectShadow) + { + // Shadow as direct formatting: no shadow for text, to be compatible + // with PowerPoint. + basegfx::B2DHomMatrix aMatrix; + aRetval = drawinglayer::primitive2d::createEmbeddedShadowPrimitive( + aRetval, aNewShadowAttribute, aMatrix, &aRetvalForShadow); + } + else + { + // Shadow as style: shadow for text, to be backwards-compatible. + aRetval = drawinglayer::primitive2d::createEmbeddedShadowPrimitive( + aRetval, aNewShadowAttribute); + } } } |