e002a0cb2a
OBS-URL: https://build.opensuse.org/request/show/922532 OBS-URL: https://build.opensuse.org/package/show/LibreOffice:Factory/libreoffice?expand=0&rev=980
306 lines
14 KiB
Diff
306 lines
14 KiB
Diff
From 1d5dc93089ee2e9b3b3761fd7b5558d55ac8a1fa Mon Sep 17 00:00:00 2001
|
|
From: Miklos Vajna <vmiklos@collabora.com>
|
|
Date: Mon, 20 Sep 2021 11:26:53 +0200
|
|
Subject: [PATCH] tdf#144091 svx: fix unwanted blur of shadow from table cell
|
|
fill
|
|
|
|
Initial render support for shadows of table shapes were added in commit
|
|
a75bf43a8d6c5dec6dcc86908c142ceec541aa8c (tdf#129961 svx: add rendering
|
|
for table shadow as direct format, 2020-12-02).
|
|
|
|
That already noticed a trick with the shadow of table shapes: the shadow
|
|
is generate from the cell fill and the border, but not from the text.
|
|
|
|
An additional trick is that when blur is enabled for the table shape's
|
|
shadow, then only the border should be blurred, not the cell fill.
|
|
|
|
In the bug document's case, the effective cell background was gray, with
|
|
a semi-transparent red shadow. We used to render cc0000 with blur and
|
|
cccccc without blur, now we correctly render cca3a3, matching
|
|
PowerPoint.
|
|
|
|
(cherry picked from commit 37a52d30bbfcf1d073779b50139c4dafa507be4b)
|
|
|
|
Conflicts:
|
|
drawinglayer/source/primitive2d/shadowprimitive2d.cxx
|
|
drawinglayer/source/tools/primitive2dxmldump.cxx
|
|
include/drawinglayer/primitive2d/BufferedDecompositionPrimitive2D.hxx
|
|
|
|
Change-Id: I7326a5f6254cf19b2d05181084c78e734ff7a7b4
|
|
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/122357
|
|
Tested-by: Jenkins
|
|
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
|
|
|
|
Related: tdf#144091 svx: fix interaction of transp cell fill and transp shadow
|
|
|
|
This is a follow-up to commit 37a52d30bbfcf1d073779b50139c4dafa507be4b
|
|
(tdf#144091 svx: fix unwanted blur of shadow from table cell fill,
|
|
2021-09-20), where it turned out that the original bugdoc was just a
|
|
special case of almost full transparency (80%), that's why avoiding the
|
|
blur fixed the problem.
|
|
|
|
A more general approach instead is to multiply the alpha or the cell
|
|
fill of table shapes and the alpha of the shadow itself. The end result
|
|
is the same (80% transparency) for the first bugdoc, but this gives back
|
|
the blur on the second bugdoc.
|
|
|
|
(cherry picked from commit 00fa364a2403dc23a786d3f91fde06e10b3a4a9a)
|
|
|
|
Conflicts:
|
|
drawinglayer/source/primitive2d/shadowprimitive2d.cxx
|
|
drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
|
|
include/drawinglayer/primitive2d/BufferedDecompositionPrimitive2D.hxx
|
|
svx/source/sdr/primitive2d/sdrdecompositiontools.cxx
|
|
|
|
Change-Id: I63560e3a73473c70157ecee8365ec7154217f269
|
|
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/122565
|
|
Tested-by: Jenkins
|
|
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
|
|
---
|
|
.../processor2d/vclpixelprocessor2d.cxx | 2 +-
|
|
.../source/tools/primitive2dxmldump.cxx | 33 +++++-
|
|
.../primitive2d/baseprimitive2d.hxx | 11 ++
|
|
.../sdr/primitive2d/sdrdecompositiontools.cxx | 72 ++++++++++---
|
|
svx/source/table/viewcontactoftableobj.cxx | 16 ++-
|
|
vcl/source/bitmap/bitmapfilter.cxx | 5 +
|
|
9 files changed, 221 insertions(+), 21 deletions(-)
|
|
|
|
diff --git a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
|
|
index 9bdbf95a015b..5e6c6a73cd60 100644
|
|
--- a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
|
|
+++ b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
|
|
@@ -1037,7 +1037,7 @@ void VclPixelProcessor2D::processGlowPrimitive2D(const primitive2d::GlowPrimitiv
|
|
const sal_uInt8 nAlpha = rCandidate.getGlowColor().GetAlpha();
|
|
|
|
impBufferDevice aBufferDevice(*mpOutputDevice, aRange);
|
|
- if (aBufferDevice.isVisible())
|
|
+ if (aBufferDevice.isVisible() && !aRange.isEmpty())
|
|
{
|
|
// remember last OutDev and set to content
|
|
OutputDevice* pLastOutputDevice = mpOutputDevice;
|
|
diff --git a/drawinglayer/source/tools/primitive2dxmldump.cxx b/drawinglayer/source/tools/primitive2dxmldump.cxx
|
|
index 7c5e5771d9bc..1e99ac91ed54 100644
|
|
--- a/drawinglayer/source/tools/primitive2dxmldump.cxx
|
|
+++ b/drawinglayer/source/tools/primitive2dxmldump.cxx
|
|
@@ -569,11 +569,42 @@ void Primitive2dXmlDump::decomposeAndWrite(
|
|
break;
|
|
}
|
|
|
|
+ case PRIMITIVE2D_ID_MODIFIEDCOLORPRIMITIVE2D:
|
|
+ {
|
|
+ // ModifiedColorPrimitive2D.
|
|
+ rWriter.startElement("modifiedColor");
|
|
+ drawinglayer::primitive2d::Primitive2DContainer aPrimitiveContainer;
|
|
+ pBasePrimitive->get2DDecomposition(aPrimitiveContainer,
|
|
+ drawinglayer::geometry::ViewInformation2D());
|
|
+ decomposeAndWrite(aPrimitiveContainer, rWriter);
|
|
+ rWriter.endElement();
|
|
+ break;
|
|
+ }
|
|
+
|
|
default:
|
|
{
|
|
- rWriter.startElement("unhandled");
|
|
+ OString aName("unhandled");
|
|
+ switch (nId)
|
|
+ {
|
|
+ case PRIMITIVE2D_ID_RANGE_SVX | 14: // PRIMITIVE2D_ID_SDRCELLPRIMITIVE2D
|
|
+ {
|
|
+ aName = "sdrCell";
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+ rWriter.startElement(aName);
|
|
rWriter.attribute("id", OUStringToOString(sCurrentElementTag, RTL_TEXTENCODING_UTF8));
|
|
rWriter.attribute("idNumber", nId);
|
|
+
|
|
+ auto pBufferedDecomposition
|
|
+ = dynamic_cast<const BufferedDecompositionPrimitive2D*>(pBasePrimitive);
|
|
+ if (pBufferedDecomposition)
|
|
+ {
|
|
+ rWriter.attribute(
|
|
+ "transparenceForShadow",
|
|
+ OString::number(pBufferedDecomposition->getTransparenceForShadow()));
|
|
+ }
|
|
+
|
|
drawinglayer::primitive2d::Primitive2DContainer aPrimitiveContainer;
|
|
pBasePrimitive->get2DDecomposition(aPrimitiveContainer,
|
|
drawinglayer::geometry::ViewInformation2D());
|
|
diff --git a/include/drawinglayer/primitive2d/baseprimitive2d.hxx b/include/drawinglayer/primitive2d/baseprimitive2d.hxx
|
|
index 7619e04e5279..f697886c1ac5 100644
|
|
--- a/include/drawinglayer/primitive2d/baseprimitive2d.hxx
|
|
+++ b/include/drawinglayer/primitive2d/baseprimitive2d.hxx
|
|
@@ -204,6 +204,10 @@ private:
|
|
/// a sequence used for buffering the last create2DDecomposition() result
|
|
Primitive2DContainer maBuffered2DDecomposition;
|
|
|
|
+ /// When a shadow wraps a list of primitives, this primitive wants to influence the transparency
|
|
+ /// of the shadow.
|
|
+ sal_uInt16 mnTransparenceForShadow = 0;
|
|
+
|
|
protected:
|
|
/** access methods to maBuffered2DDecomposition. The usage of this methods may allow
|
|
later thread-safe stuff to be added if needed. Only to be used by getDecomposition()
|
|
@@ -236,6 +240,13 @@ public:
|
|
virtual void
|
|
get2DDecomposition(Primitive2DDecompositionVisitor& rVisitor,
|
|
const geometry::ViewInformation2D& rViewInformation) const override;
|
|
+
|
|
+ void setTransparenceForShadow(sal_uInt16 nTransparenceForShadow)
|
|
+ {
|
|
+ mnTransparenceForShadow = nTransparenceForShadow;
|
|
+ }
|
|
+
|
|
+ sal_uInt16 getTransparenceForShadow() const { return mnTransparenceForShadow; }
|
|
};
|
|
|
|
} // end of namespace drawinglayer::primitive2d
|
|
diff --git a/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx b/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx
|
|
index dcff748ea60f..1cd60e75d925 100644
|
|
--- a/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx
|
|
+++ b/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx
|
|
@@ -545,7 +545,6 @@ basegfx::B2DRange getTextAnchorRange(const attribute::SdrTextAttribute& rText,
|
|
{
|
|
if(!rContent.empty())
|
|
{
|
|
- Primitive2DContainer aRetval(2);
|
|
basegfx::B2DHomMatrix aShadowOffset;
|
|
|
|
{
|
|
@@ -576,25 +575,66 @@ basegfx::B2DRange getTextAnchorRange(const attribute::SdrTextAttribute& rText,
|
|
}
|
|
|
|
// create shadow primitive and add content
|
|
- aRetval[0] = Primitive2DReference(
|
|
- new ShadowPrimitive2D(
|
|
- aShadowOffset,
|
|
- rShadow.getColor(),
|
|
- rShadow.getBlur(),
|
|
- (pContentForShadow ? *pContentForShadow : rContent)));
|
|
-
|
|
- if(0.0 != rShadow.getTransparence())
|
|
+ const Primitive2DContainer& rContentForShadow
|
|
+ = pContentForShadow ? *pContentForShadow : rContent;
|
|
+ int nContentWithTransparence = std::count_if(
|
|
+ rContentForShadow.begin(), rContentForShadow.end(),
|
|
+ [](const Primitive2DReference& xChild) {
|
|
+ auto pChild = dynamic_cast<BufferedDecompositionPrimitive2D*>(xChild.get());
|
|
+ return pChild && pChild->getTransparenceForShadow() != 0;
|
|
+ });
|
|
+ if (nContentWithTransparence == 0)
|
|
{
|
|
- // create SimpleTransparencePrimitive2D
|
|
- const Primitive2DContainer aTempContent { aRetval[0] };
|
|
-
|
|
+ Primitive2DContainer aRetval(2);
|
|
aRetval[0] = Primitive2DReference(
|
|
- new UnifiedTransparencePrimitive2D(
|
|
- aTempContent,
|
|
- rShadow.getTransparence()));
|
|
+ new ShadowPrimitive2D(
|
|
+ aShadowOffset,
|
|
+ rShadow.getColor(),
|
|
+ rShadow.getBlur(),
|
|
+ (pContentForShadow ? *pContentForShadow : rContent)));
|
|
+
|
|
+ if(0.0 != rShadow.getTransparence())
|
|
+ {
|
|
+ // create SimpleTransparencePrimitive2D
|
|
+ const Primitive2DContainer aTempContent { aRetval[0] };
|
|
+
|
|
+ aRetval[0] = Primitive2DReference(
|
|
+ new UnifiedTransparencePrimitive2D(
|
|
+ aTempContent,
|
|
+ rShadow.getTransparence()));
|
|
+ }
|
|
+
|
|
+ aRetval[1] = Primitive2DReference(new GroupPrimitive2D(rContent));
|
|
+ return aRetval;
|
|
+ }
|
|
+
|
|
+ Primitive2DContainer aRetval;
|
|
+ for (const auto& xChild : rContentForShadow)
|
|
+ {
|
|
+ double fChildTransparence = 0.0;
|
|
+ auto pChild = dynamic_cast<BufferedDecompositionPrimitive2D*>(xChild.get());
|
|
+ if (pChild)
|
|
+ {
|
|
+ fChildTransparence = pChild->getTransparenceForShadow();
|
|
+ fChildTransparence /= 100;
|
|
+ }
|
|
+ aRetval.push_back(Primitive2DReference(
|
|
+ new ShadowPrimitive2D(aShadowOffset, rShadow.getColor(), rShadow.getBlur(),
|
|
+ { xChild })));
|
|
+ if (rShadow.getTransparence() != 0.0 || fChildTransparence != 0.0)
|
|
+ {
|
|
+ Primitive2DContainer aTempContent{ aRetval.back() };
|
|
+
|
|
+ double fChildAlpha = 1.0 - fChildTransparence;
|
|
+ double fShadowAlpha = 1.0 - rShadow.getTransparence();
|
|
+ double fTransparence = 1.0 - fChildAlpha * fShadowAlpha;
|
|
+ aRetval.back() = Primitive2DReference(new UnifiedTransparencePrimitive2D(
|
|
+ std::move(aTempContent), fTransparence));
|
|
+ }
|
|
}
|
|
|
|
- aRetval[1] = Primitive2DReference(new GroupPrimitive2D(rContent));
|
|
+ aRetval.push_back(
|
|
+ Primitive2DReference(new GroupPrimitive2D(rContent)));
|
|
return aRetval;
|
|
}
|
|
else
|
|
diff --git a/svx/source/table/viewcontactoftableobj.cxx b/svx/source/table/viewcontactoftableobj.cxx
|
|
index 967bfe820738..41d60d7652f8 100644
|
|
--- a/svx/source/table/viewcontactoftableobj.cxx
|
|
+++ b/svx/source/table/viewcontactoftableobj.cxx
|
|
@@ -39,6 +39,7 @@
|
|
#include <svx/sdooitm.hxx>
|
|
#include <vcl/canvastools.hxx>
|
|
#include <o3tl/unit_conversion.hxx>
|
|
+#include <svx/xfltrit.hxx>
|
|
|
|
#include <cell.hxx>
|
|
#include "tablelayouter.hxx"
|
|
@@ -326,10 +327,19 @@ namespace sdr::contact
|
|
aAttribute
|
|
= drawinglayer::primitive2d::createNewSdrFillTextAttribute(
|
|
rCellItemSet, nullptr);
|
|
+ rtl::Reference pCellReference
|
|
+ = new drawinglayer::primitive2d::SdrCellPrimitive2D(
|
|
+ aCellMatrix, aAttribute);
|
|
+
|
|
+ sal_uInt16 nTransparence(
|
|
+ rCellItemSet.Get(XATTR_FILLTRANSPARENCE).GetValue());
|
|
+ if (nTransparence != 0)
|
|
+ {
|
|
+ pCellReference->setTransparenceForShadow(nTransparence);
|
|
+ }
|
|
+
|
|
const drawinglayer::primitive2d::Primitive2DReference
|
|
- xCellReference(
|
|
- new drawinglayer::primitive2d::SdrCellPrimitive2D(
|
|
- aCellMatrix, aAttribute));
|
|
+ xCellReference(pCellReference);
|
|
aRetvalForShadow.append(xCellReference);
|
|
}
|
|
}
|
|
diff --git a/vcl/source/bitmap/bitmapfilter.cxx b/vcl/source/bitmap/bitmapfilter.cxx
|
|
index f2020539e04d..9ede4e578b10 100644
|
|
--- a/vcl/source/bitmap/bitmapfilter.cxx
|
|
+++ b/vcl/source/bitmap/bitmapfilter.cxx
|
|
@@ -19,6 +19,11 @@ BitmapFilter::~BitmapFilter() {}
|
|
|
|
bool BitmapFilter::Filter(BitmapEx& rBmpEx, BitmapFilter const& rFilter)
|
|
{
|
|
+ if (rBmpEx.IsEmpty())
|
|
+ {
|
|
+ return true;
|
|
+ }
|
|
+
|
|
BitmapEx aTmpBmpEx(rFilter.execute(rBmpEx));
|
|
|
|
if (aTmpBmpEx.IsEmpty())
|
|
--
|
|
2.31.1
|
|
|