summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2021-09-23 16:55:19 +0200
committerMike Kaganski <mike.kaganski@collabora.com>2021-09-27 16:15:13 +0200
commit0f99f237be9ee4135a548e255c6c8dcceba8648d (patch)
treeb2b584561195c9864b6fe7f0d1e73678fd34b0a9
parent92adaab00003beb7314354018909e26272a245a9 (diff)
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 svx/source/table/viewcontactoftableobj.cxx Change-Id: I63560e3a73473c70157ecee8365ec7154217f269 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/122680 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
-rw-r--r--drawinglayer/source/primitive2d/shadowprimitive2d.cxx71
-rw-r--r--drawinglayer/source/processor2d/vclpixelprocessor2d.cxx12
-rw-r--r--drawinglayer/source/tools/primitive2dxmldump.cxx4
-rw-r--r--include/drawinglayer/primitive2d/baseprimitive2d.hxx12
-rw-r--r--include/drawinglayer/primitive2d/shadowprimitive2d.hxx8
-rw-r--r--svx/qa/unit/table.cxx12
-rw-r--r--svx/source/sdr/primitive2d/sdrdecompositiontools.cxx72
-rw-r--r--svx/source/table/viewcontactoftableobj.cxx15
-rw-r--r--vcl/source/bitmap/bitmapfilter.cxx5
9 files changed, 106 insertions, 105 deletions
diff --git a/drawinglayer/source/primitive2d/shadowprimitive2d.cxx b/drawinglayer/source/primitive2d/shadowprimitive2d.cxx
index 516cc0c0bd4a..f0efd64c7bdc 100644
--- a/drawinglayer/source/primitive2d/shadowprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/shadowprimitive2d.cxx
@@ -30,27 +30,6 @@ using namespace com::sun::star;
namespace drawinglayer::primitive2d
{
-namespace
-{
-void get2DDecompositionOfChildren(const ShadowPrimitive2D& rPrimitive,
- Primitive2DDecompositionVisitor& rVisitor,
- const Primitive2DContainer& rChildren)
-{
- if (rChildren.empty())
- return;
-
- // create a modifiedColorPrimitive containing the shadow color and the content
- const basegfx::BColorModifierSharedPtr aBColorModifier
- = std::make_shared<basegfx::BColorModifier_replace>(rPrimitive.getShadowColor());
- const Primitive2DReference xRefA(new ModifiedColorPrimitive2D(rChildren, aBColorModifier));
- Primitive2DContainer aSequenceB{ xRefA };
-
- // build transformed primitiveVector with shadow offset and add to target
- rVisitor.append(
- new TransformPrimitive2D(rPrimitive.getShadowTransform(), std::move(aSequenceB)));
-}
-}
-
ShadowPrimitive2D::ShadowPrimitive2D(
const basegfx::B2DHomMatrix& rShadowTransform,
const basegfx::BColor& rShadowColor,
@@ -87,41 +66,21 @@ void get2DDecompositionOfChildren(const ShadowPrimitive2D& rPrimitive,
void ShadowPrimitive2D::get2DDecomposition(Primitive2DDecompositionVisitor& rVisitor, const geometry::ViewInformation2D& /*rViewInformation*/) const
{
- get2DDecompositionOfChildren(*this, rVisitor, getChildren());
- }
-
- void ShadowPrimitive2D::get2DDecompositionWithoutBlur(
- Primitive2DDecompositionVisitor& rVisitor,
- const geometry::ViewInformation2D& /*rViewInformation*/) const
- {
- Primitive2DContainer aChildren;
- // Only decompose children which are not blurred (they opted in for this).
- std::copy_if(getChildren().begin(), getChildren().end(), std::back_inserter(aChildren),
- [](const Primitive2DReference& xChild) {
- auto pChild
- = dynamic_cast<primitive2d::BufferedDecompositionPrimitive2D*>(
- xChild.get());
- return pChild && pChild->getExcludeFromBlur();
- });
-
- get2DDecompositionOfChildren(*this, rVisitor, aChildren);
- }
-
- void ShadowPrimitive2D::get2DDecompositionWithBlur(
- Primitive2DDecompositionVisitor& rVisitor,
- const geometry::ViewInformation2D& /*rViewInformation*/) const
- {
- // Only decompose children which are blurred (which is the default).
- Primitive2DContainer aChildren;
- std::copy_if(getChildren().begin(), getChildren().end(), std::back_inserter(aChildren),
- [](const Primitive2DReference& xChild) {
- auto pChild
- = dynamic_cast<primitive2d::BufferedDecompositionPrimitive2D*>(
- xChild.get());
- return !pChild || !pChild->getExcludeFromBlur();
- });
-
- get2DDecompositionOfChildren(*this, rVisitor, aChildren);
+ if(getChildren().empty())
+ return;
+
+ // create a modifiedColorPrimitive containing the shadow color and the content
+ const basegfx::BColorModifierSharedPtr aBColorModifier =
+ std::make_shared<basegfx::BColorModifier_replace>(
+ getShadowColor());
+ const Primitive2DReference xRefA(
+ new ModifiedColorPrimitive2D(
+ getChildren(),
+ aBColorModifier));
+ const Primitive2DContainer aSequenceB { xRefA };
+
+ // build transformed primitiveVector with shadow offset and add to target
+ rVisitor.append(new TransformPrimitive2D(getShadowTransform(), aSequenceB));
}
// provide unique ID
diff --git a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
index 393c40c90842..10845409b9ec 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 nTransparency = rCandidate.getGlowColor().GetTransparency();
impBufferDevice aBufferDevice(*mpOutputDevice, aRange);
- if (aBufferDevice.isVisible())
+ if (aBufferDevice.isVisible() && !aRange.isEmpty())
{
// remember last OutDev and set to content
OutputDevice* pLastOutputDevice = mpOutputDevice;
@@ -1160,18 +1160,10 @@ void VclPixelProcessor2D::processShadowPrimitive2D(const primitive2d::ShadowPrim
impBufferDevice aBufferDevice(*mpOutputDevice, aRange);
if (aBufferDevice.isVisible())
{
- // Process children which don't want blur.
- primitive2d::Primitive2DContainer aContainer;
- rCandidate.get2DDecompositionWithoutBlur(aContainer, getViewInformation2D());
- process(aContainer);
-
- // Process children which want blur.
OutputDevice* pLastOutputDevice = mpOutputDevice;
mpOutputDevice = &aBufferDevice.getContent();
- aContainer.clear();
- rCandidate.get2DDecompositionWithBlur(aContainer, getViewInformation2D());
- process(aContainer);
+ process(rCandidate);
const tools::Rectangle aRect(static_cast<tools::Long>(std::floor(aRange.getMinX())),
static_cast<tools::Long>(std::floor(aRange.getMinY())),
diff --git a/drawinglayer/source/tools/primitive2dxmldump.cxx b/drawinglayer/source/tools/primitive2dxmldump.cxx
index 1342fd39354f..5fe1eb41fead 100644
--- a/drawinglayer/source/tools/primitive2dxmldump.cxx
+++ b/drawinglayer/source/tools/primitive2dxmldump.cxx
@@ -549,8 +549,8 @@ void Primitive2dXmlDump::decomposeAndWrite(
if (pBufferedDecomposition)
{
rWriter.attribute(
- "excludeFromBlur",
- OString::boolean(pBufferedDecomposition->getExcludeFromBlur()));
+ "transparenceForShadow",
+ OString::number(pBufferedDecomposition->getTransparenceForShadow()));
}
drawinglayer::primitive2d::Primitive2DContainer aPrimitiveContainer;
diff --git a/include/drawinglayer/primitive2d/baseprimitive2d.hxx b/include/drawinglayer/primitive2d/baseprimitive2d.hxx
index b94218b07111..c5d947c8b1de 100644
--- a/include/drawinglayer/primitive2d/baseprimitive2d.hxx
+++ b/include/drawinglayer/primitive2d/baseprimitive2d.hxx
@@ -204,8 +204,9 @@ private:
/// a sequence used for buffering the last create2DDecomposition() result
Primitive2DContainer maBuffered2DDecomposition;
- /// When blur is invoked on a list of primitives, exclude this primitive from the blur effect.
- bool mbExcludeFromBlur = false;
+ /// 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
@@ -241,9 +242,12 @@ public:
get2DDecomposition(Primitive2DDecompositionVisitor& rVisitor,
const geometry::ViewInformation2D& rViewInformation) const override;
- void setExcludeFromBlur(bool bExcludeFromBlur) { mbExcludeFromBlur = bExcludeFromBlur; }
+ void setTransparenceForShadow(sal_uInt16 nTransparenceForShadow)
+ {
+ mnTransparenceForShadow = nTransparenceForShadow;
+ }
- bool getExcludeFromBlur() const { return mbExcludeFromBlur; }
+ sal_uInt16 getTransparenceForShadow() const { return mnTransparenceForShadow; }
};
} // end of namespace drawinglayer::primitive2d
diff --git a/include/drawinglayer/primitive2d/shadowprimitive2d.hxx b/include/drawinglayer/primitive2d/shadowprimitive2d.hxx
index 7bd223847f8d..37258d8f34ed 100644
--- a/include/drawinglayer/primitive2d/shadowprimitive2d.hxx
+++ b/include/drawinglayer/primitive2d/shadowprimitive2d.hxx
@@ -76,14 +76,6 @@ namespace drawinglayer::primitive2d
/// create decomposition
virtual void get2DDecomposition(Primitive2DDecompositionVisitor& rVisitor, const geometry::ViewInformation2D& rViewInformation) const override;
- void get2DDecompositionWithoutBlur(
- Primitive2DDecompositionVisitor& rVisitor,
- const geometry::ViewInformation2D& rViewInformation) const;
-
- void
- get2DDecompositionWithBlur(Primitive2DDecompositionVisitor& rVisitor,
- const geometry::ViewInformation2D& rViewInformation) const;
-
/// provide unique ID
virtual sal_uInt32 getPrimitive2DID() const override;
};
diff --git a/svx/qa/unit/table.cxx b/svx/qa/unit/table.cxx
index 4419892a42ba..f65118e536c6 100644
--- a/svx/qa/unit/table.cxx
+++ b/svx/qa/unit/table.cxx
@@ -89,11 +89,13 @@ CPPUNIT_TEST_FIXTURE(Test, testTableShadowBlur)
drawinglayer::Primitive2dXmlDump aDumper;
xmlDocUniquePtr pDocument = aDumper.dumpAndParse(xPrimitiveSequence);
// Without the accompanying fix in place, this test would have failed with:
- // - Expected: true
- // - Actual : false
- // i.e. blur was applied on both the cell fill and the cell border.
- assertXPath(pDocument, "//shadow/transform/modifiedColor/sdrCell[1]", "excludeFromBlur",
- "true");
+ // - number of nodes is incorrect
+ // - Expected: 1
+ // - Actual : 0
+ // i.e. the shadow itself was not transparent and that resulted in a non-transparent rendering
+ // as well, while the rendering transparency should be based on the transparency of the shadow
+ // itself and the transparency of the cell fill.
+ assertXPath(pDocument, "//objectinfo/unifiedtransparence[1]", "transparence", "0.8");
}
}
diff --git a/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx b/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx
index 504862a64229..aef53062a492 100644
--- a/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx
+++ b/svx/source/sdr/primitive2d/sdrdecompositiontools.cxx
@@ -514,7 +514,6 @@ namespace drawinglayer::primitive2d
{
if(!rContent.empty())
{
- Primitive2DContainer aRetval(2);
basegfx::B2DHomMatrix aShadowOffset;
{
@@ -545,25 +544,66 @@ namespace drawinglayer::primitive2d
}
// 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 409e099ae3e5..6262c7a54d1c 100644
--- a/svx/source/table/viewcontactoftableobj.cxx
+++ b/svx/source/table/viewcontactoftableobj.cxx
@@ -38,6 +38,7 @@
#include <svx/framelinkarray.hxx>
#include <svx/sdooitm.hxx>
#include <vcl/canvastools.hxx>
+#include <svx/xfltrit.hxx>
#include <cell.hxx>
#include "tablelayouter.hxx"
@@ -320,14 +321,21 @@ namespace sdr::contact
aRetval.append(xCellReference);
}
- // Create cell primitive without text and blur.
+ // Create cell primitive without text.
aAttribute
= drawinglayer::primitive2d::createNewSdrFillTextAttribute(
rCellItemSet, nullptr);
rtl::Reference pCellReference
= new drawinglayer::primitive2d::SdrCellPrimitive2D(
aCellMatrix, aAttribute);
- pCellReference->setExcludeFromBlur(true);
+
+ sal_uInt16 nTransparence(
+ rCellItemSet.Get(XATTR_FILLTRANSPARENCE).GetValue());
+ if (nTransparence != 0)
+ {
+ pCellReference->setTransparenceForShadow(nTransparence);
+ }
+
const drawinglayer::primitive2d::Primitive2DReference
xCellReference(pCellReference.get());
aRetvalForShadow.append(xCellReference);
@@ -379,8 +387,7 @@ namespace sdr::contact
aTransform,
aCellBorderPrimitives));
- // Borders are always the same for shadow as well, and implicitly included
- // in blur.
+ // Borders are always the same for shadow as well.
aRetvalForShadow.append(new drawinglayer::primitive2d::TransformPrimitive2D(
aTransform, aCellBorderPrimitives));
}
diff --git a/vcl/source/bitmap/bitmapfilter.cxx b/vcl/source/bitmap/bitmapfilter.cxx
index 70d9cdd62dc1..67744e71aa05 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())