drawinglayer/source/attribute/fillgraphicattribute.cxx | 5 drawinglayer/source/primitive2d/PolyPolygonGraphicPrimitive2D.cxx | 27 +--- drawinglayer/source/primitive2d/graphicprimitivehelper2d.cxx | 64 +++++++++- include/drawinglayer/attribute/fillgraphicattribute.hxx | 1 include/drawinglayer/primitive2d/graphicprimitivehelper2d.hxx | 14 ++ svx/source/sdr/contact/viewobjectcontact.cxx | 27 ---- 6 files changed, 94 insertions(+), 44 deletions(-)
New commits: commit 1b74b95bba6b84225248e5b7badf1de7ae401a79 Author: Armin Le Grand (Collabora) <[email protected]> AuthorDate: Wed Jul 24 13:45:58 2024 +0200 Commit: Armin Le Grand <[email protected]> CommitDate: Wed Jul 24 17:00:56 2024 +0200 CairoSDPR: Improve animated tiled fills Up to now these needed to be decomposed to be rendered and did not support animation. I already added animation, but that was a compromize. Done that now in the correct way, so that animation is possible and can be directly rendered using a FillGraphicPrimitive2D if wanted, including one extra layer of alpha, too. This will also enhance other primitive processors, but of course most those that do handle that now directly, so CairoPixelProcessor2D does that. Note that it does not need to support animation in any way (that is part of the primitive stack), but just direct tiled rendering. Change-Id: I8860098dfb3f2369e361579cf1deea7c67b662b9 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170937 Tested-by: Jenkins Reviewed-by: Armin Le Grand <[email protected]> diff --git a/drawinglayer/source/attribute/fillgraphicattribute.cxx b/drawinglayer/source/attribute/fillgraphicattribute.cxx index 300d6f6123f1..3da913eee8d0 100644 --- a/drawinglayer/source/attribute/fillgraphicattribute.cxx +++ b/drawinglayer/source/attribute/fillgraphicattribute.cxx @@ -94,6 +94,11 @@ namespace drawinglayer::attribute } } + FillGraphicAttribute::FillGraphicAttribute() + : mpFillGraphicAttribute(theGlobalDefault()) + { + } + FillGraphicAttribute::FillGraphicAttribute( const Graphic& rGraphic, const basegfx::B2DRange& rGraphicRange, diff --git a/drawinglayer/source/primitive2d/PolyPolygonGraphicPrimitive2D.cxx b/drawinglayer/source/primitive2d/PolyPolygonGraphicPrimitive2D.cxx index 7853709b9541..fee818e23d65 100644 --- a/drawinglayer/source/primitive2d/PolyPolygonGraphicPrimitive2D.cxx +++ b/drawinglayer/source/primitive2d/PolyPolygonGraphicPrimitive2D.cxx @@ -24,6 +24,7 @@ #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx> #include <drawinglayer/primitive2d/fillgraphicprimitive2d.hxx> #include <drawinglayer/primitive2d/maskprimitive2d.hxx> +#include <drawinglayer/primitive2d/graphicprimitivehelper2d.hxx> #include <utility> #include <vcl/graph.hxx> @@ -46,7 +47,7 @@ Primitive2DReference PolyPolygonGraphicPrimitive2D::create2DDecomposition( return nullptr; } - const Graphic& rGraphic = getFillGraphic().getGraphic(); + const Graphic& rGraphic(getFillGraphic().getGraphic()); const GraphicType aType(rGraphic.GetType()); // is there a bitmap or a metafile (do we have content)? @@ -67,10 +68,9 @@ Primitive2DReference PolyPolygonGraphicPrimitive2D::create2DDecomposition( // create SubSequence with FillGraphicPrimitive2D based on polygon range const basegfx::B2DRange aOutRange(getB2DPolyPolygon().getB2DRange()); - const basegfx::B2DHomMatrix aNewObjectTransform( - basegfx::utils::createScaleTranslateB2DHomMatrix(aOutRange.getRange(), - aOutRange.getMinimum())); - Primitive2DReference xSubRef; + const basegfx::B2DHomMatrix aTransform(basegfx::utils::createScaleTranslateB2DHomMatrix( + aOutRange.getRange(), aOutRange.getMinimum())); + drawinglayer::attribute::FillGraphicAttribute aFillGraphicAttribute(getFillGraphic()); if (aOutRange != getDefinitionRange()) { @@ -96,21 +96,18 @@ Primitive2DReference PolyPolygonGraphicPrimitive2D::create2DDecomposition( aAdaptedRange.transform(aFromGlobalToOutRange); - const drawinglayer::attribute::FillGraphicAttribute aAdaptedFillGraphicAttribute( + aFillGraphicAttribute = drawinglayer::attribute::FillGraphicAttribute( getFillGraphic().getGraphic(), aAdaptedRange, getFillGraphic().getTiling(), getFillGraphic().getOffsetX(), getFillGraphic().getOffsetY()); - - xSubRef = new FillGraphicPrimitive2D(aNewObjectTransform, aAdaptedFillGraphicAttribute, - getTransparency()); - } - else - { - xSubRef - = new FillGraphicPrimitive2D(aNewObjectTransform, getFillGraphic(), getTransparency()); } + // use tooling due to evtl. animation info needs to be created if + // the Graphic is animated somehow + Primitive2DReference aContent( + createFillGraphicPrimitive2D(aTransform, aFillGraphicAttribute, getTransparency())); + // embed to mask primitive - return new MaskPrimitive2D(getB2DPolyPolygon(), Primitive2DContainer{ xSubRef }); + return new MaskPrimitive2D(getB2DPolyPolygon(), Primitive2DContainer{ aContent }); } PolyPolygonGraphicPrimitive2D::PolyPolygonGraphicPrimitive2D( diff --git a/drawinglayer/source/primitive2d/graphicprimitivehelper2d.cxx b/drawinglayer/source/primitive2d/graphicprimitivehelper2d.cxx index d97d1bd36245..09573c6772a6 100644 --- a/drawinglayer/source/primitive2d/graphicprimitivehelper2d.cxx +++ b/drawinglayer/source/primitive2d/graphicprimitivehelper2d.cxx @@ -31,6 +31,7 @@ #include <drawinglayer/primitive2d/transformprimitive2d.hxx> #include <drawinglayer/primitive2d/maskprimitive2d.hxx> #include <drawinglayer/primitive2d/modifiedcolorprimitive2d.hxx> +#include <drawinglayer/primitive2d/fillgraphicprimitive2d.hxx> #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx> #include <drawinglayer/geometry/viewinformation2d.hxx> #include <basegfx/polygon/b2dpolygon.hxx> @@ -64,6 +65,12 @@ namespace drawinglayer::primitive2d */ Graphic maGraphic; + /** defines parameters for tiling if this AnimatedGraphicPrimitive2D + is to be used for a FillGraphicPrimitive2D. In that case, + maFillGraphicAttribute.isDefault() will be false + */ + drawinglayer::attribute::FillGraphicAttribute maFillGraphicAttribute; + /// local animation processing data, excerpt from maGraphic ::Animation maAnimation; @@ -198,8 +205,26 @@ namespace drawinglayer::primitive2d bitmap = BitmapEx(aMainBitmap, aMaskBitmap); } - if(basegfx::fTools::equal(getTransparency(), 0.0)) + if (!maFillGraphicAttribute.isDefault()) + { + // need to create FillGraphicPrimitive2D + const drawinglayer::attribute::FillGraphicAttribute aAttribute( + Graphic(bitmap), + maFillGraphicAttribute.getGraphicRange(), + maFillGraphicAttribute.getTiling(), + maFillGraphicAttribute.getOffsetX(), + maFillGraphicAttribute.getOffsetY()); + + return new FillGraphicPrimitive2D( + getTransform(), + aAttribute, + getTransparency()); + } + + // need to create BitmapAlphaPrimitive2D/BitmapPrimitive2D + if (basegfx::fTools::equal(getTransparency(), 0.0)) return new BitmapPrimitive2D(bitmap, getTransform()); + return new BitmapAlphaPrimitive2D(bitmap, getTransform(), getTransparency()); } @@ -363,6 +388,7 @@ namespace drawinglayer::primitive2d /// constructor AnimatedGraphicPrimitive2D( const Graphic& rGraphic, + const drawinglayer::attribute::FillGraphicAttribute* pFillGraphicAttribute, basegfx::B2DHomMatrix aTransform, double fTransparency = 0.0); virtual ~AnimatedGraphicPrimitive2D(); @@ -388,6 +414,7 @@ namespace drawinglayer::primitive2d AnimatedGraphicPrimitive2D::AnimatedGraphicPrimitive2D( const Graphic& rGraphic, + const drawinglayer::attribute::FillGraphicAttribute* pFillGraphicAttribute, basegfx::B2DHomMatrix aTransform, double fTransparency) : AnimatedSwitchPrimitive2D( @@ -396,6 +423,7 @@ namespace drawinglayer::primitive2d false), maTransform(std::move(aTransform)), maGraphic(rGraphic), + maFillGraphicAttribute(), maAnimation(rGraphic.GetAnimation()), mfTransparency(std::max(0.0, std::min(1.0, fTransparency))), maVirtualDevice(*Application::GetDefaultDevice()), @@ -404,6 +432,10 @@ namespace drawinglayer::primitive2d mbBufferingAllowed(false), mbHugeSize(false) { + // if FillGraphicAttribute copy it -> FillGraphicPrimitive2D is intended + if (nullptr != pFillGraphicAttribute) + maFillGraphicAttribute = *pFillGraphicAttribute; + // initialize AnimationTiming, needed to detect which frame is requested // in get2DDecomposition createAndSetAnimationTiming(); @@ -538,6 +570,35 @@ namespace drawinglayer::primitive2d namespace drawinglayer::primitive2d { + Primitive2DReference createFillGraphicPrimitive2D( + const basegfx::B2DHomMatrix& rTransform, + const drawinglayer::attribute::FillGraphicAttribute& rFillGraphicAttribute, + double fTransparency) + { + if (basegfx::fTools::equal(fTransparency, 1.0)) + { + // completely transparent, done + return nullptr; + } + + const Graphic& rGraphic(rFillGraphicAttribute.getGraphic()); + const GraphicType aType(rGraphic.GetType()); + + if (GraphicType::Bitmap == aType && rGraphic.IsAnimated()) + { + return new AnimatedGraphicPrimitive2D( + rGraphic, + &rFillGraphicAttribute, + rTransform, + fTransparency); + } + + return new FillGraphicPrimitive2D( + rTransform, + rFillGraphicAttribute, + fTransparency); + } + void create2DDecompositionOfGraphic( Primitive2DContainer& rContainer, const Graphic& rGraphic, @@ -560,6 +621,7 @@ namespace drawinglayer::primitive2d // support for alpha rContainer.append(new AnimatedGraphicPrimitive2D( rGraphic, + nullptr, rTransform, fTransparency)); } diff --git a/include/drawinglayer/attribute/fillgraphicattribute.hxx b/include/drawinglayer/attribute/fillgraphicattribute.hxx index 976d7bd37586..e313ae4a3770 100644 --- a/include/drawinglayer/attribute/fillgraphicattribute.hxx +++ b/include/drawinglayer/attribute/fillgraphicattribute.hxx @@ -43,6 +43,7 @@ private: public: /// constructors/assignmentoperator/destructor + FillGraphicAttribute(); FillGraphicAttribute(const Graphic& rGraphic, const basegfx::B2DRange& rGraphicRange, bool bTiling, double fOffsetX = 0.0, double fOffsetY = 0.0); FillGraphicAttribute(const FillGraphicAttribute&); diff --git a/include/drawinglayer/primitive2d/graphicprimitivehelper2d.hxx b/include/drawinglayer/primitive2d/graphicprimitivehelper2d.hxx index 024ad3fce28a..34412486b202 100644 --- a/include/drawinglayer/primitive2d/graphicprimitivehelper2d.hxx +++ b/include/drawinglayer/primitive2d/graphicprimitivehelper2d.hxx @@ -24,6 +24,11 @@ class Graphic; +namespace drawinglayer::attribute +{ +class FillGraphicAttribute; +} + namespace drawinglayer::primitive2d { /** Helper method with supports decomposing a Graphic with all @@ -38,12 +43,19 @@ namespace drawinglayer::primitive2d alpha directly: all paths are now capable of handling a given alpha, including metafile, SVG and animated graphics */ - void DRAWINGLAYER_DLLPUBLIC create2DDecompositionOfGraphic( + void create2DDecompositionOfGraphic( Primitive2DContainer& rContainer, const Graphic& rGraphic, const basegfx::B2DHomMatrix& rTransform, double fTransparency = 0.0); + // helper to create either a FillGraphicPrimitive2D or a + // AnimatedGraphicPrimitive2D if the content is animated + Primitive2DReference createFillGraphicPrimitive2D( + const basegfx::B2DHomMatrix& rTransform, + const drawinglayer::attribute::FillGraphicAttribute& rFillGraphicAttribute, + double fTransparency = 0.0); + /** Helper to embed given sequence of primitives to evtl. a stack of ModifiedColorPrimitive2D's to get all the needed modifications applied. diff --git a/svx/source/sdr/contact/viewobjectcontact.cxx b/svx/source/sdr/contact/viewobjectcontact.cxx index e7ee53f55f74..ea1418f45850 100644 --- a/svx/source/sdr/contact/viewobjectcontact.cxx +++ b/svx/source/sdr/contact/viewobjectcontact.cxx @@ -26,8 +26,6 @@ #include <basegfx/color/bcolor.hxx> #include <drawinglayer/primitive2d/modifiedcolorprimitive2d.hxx> #include <drawinglayer/primitive2d/animatedprimitive2d.hxx> -#include <drawinglayer/primitive2d/fillgraphicprimitive2d.hxx> -#include <drawinglayer/primitive2d/graphicprimitivehelper2d.hxx> #include <drawinglayer/processor2d/baseprocessor2d.hxx> #include <svx/sdr/primitive2d/svx_primitivetypes2d.hxx> #include <drawinglayer/primitive2d/transformprimitive2d.hxx> @@ -112,31 +110,6 @@ void AnimatedExtractingProcessor2D::processBasePrimitive2D(const drawinglayer::p break; } - // CairoSDPR: handle FillGraphicPrimitive2D to avoid expensive decompose, - // this also activates that tiled stuff gets *animated*. If that is not - // wanted this primitive might just be ignored - case PRIMITIVE2D_ID_FILLGRAPHICPRIMITIVE2D: - { - const drawinglayer::primitive2d::FillGraphicPrimitive2D& rFill( - static_cast<const drawinglayer::primitive2d::FillGraphicPrimitive2D&>(rCandidate)); - const drawinglayer::attribute::FillGraphicAttribute& rAttribute(rFill.getFillGraphic()); - const Graphic& rGraphic(rAttribute.getGraphic()); - - if(rGraphic.IsAnimated()) - { - // create temporary GraphicPrimitive to recursively extract evtl. animation - drawinglayer::primitive2d::Primitive2DContainer aContainer; - drawinglayer::primitive2d::create2DDecompositionOfGraphic( - aContainer, - rGraphic, - rFill.getTransformation(), - rFill.getTransparency()); - process(aContainer); - } - - break; - } - // decompose animated gifs where SdrGrafPrimitive2D produces a GraphicPrimitive2D // which then produces the animation infos (all when used/needed) case PRIMITIVE2D_ID_SDRGRAFPRIMITIVE2D :
