drawinglayer/Library_drawinglayer.mk                               |    1 
 drawinglayer/source/primitive2d/BitmapAlphaPrimitive2D.cxx         |  105 
++++++++++
 drawinglayer/source/primitive2d/Tools.cxx                          |    2 
 drawinglayer/source/processor2d/cairopixelprocessor2d.cxx          |   47 ++++
 include/drawinglayer/primitive2d/BitmapAlphaPrimitive2D.hxx        |   82 
+++++++
 include/drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx |    1 
 include/drawinglayer/processor2d/cairopixelprocessor2d.hxx         |    7 
 7 files changed, 241 insertions(+), 4 deletions(-)

New commits:
commit 3dcee7e08008588181e69f13e223d3ed4d667dda
Author:     Armin Le Grand (Collabora) <[email protected]>
AuthorDate: Mon Jul 22 14:39:01 2024 +0200
Commit:     Armin Le Grand <[email protected]>
CommitDate: Mon Jul 22 20:06:20 2024 +0200

    CairoSDPR: Prepare BitmapAlphaPrimitive2D
    
    This provides a BitmapPrimitive2D extended by a unified
    transparency component. It will decompose to a
    UnifiedTransparencePrimitive2D containing a
    BitmapPrimitive2D and the transparence, so no primitive
    processor has to support this primitive directly - but
    can if feasible. I plan to use that ASAP
    
    Change-Id: I83ec84eaadc8ba2b21f0ba0cb1fdcf43bdc455db
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170852
    Tested-by: Jenkins
    Reviewed-by: Armin Le Grand <[email protected]>

diff --git a/drawinglayer/Library_drawinglayer.mk 
b/drawinglayer/Library_drawinglayer.mk
index 18578664cf67..7529c34a43b7 100644
--- a/drawinglayer/Library_drawinglayer.mk
+++ b/drawinglayer/Library_drawinglayer.mk
@@ -106,6 +106,7 @@ $(eval $(call 
gb_Library_add_exception_objects,drawinglayer,\
     drawinglayer/source/primitive2d/animatedprimitive2d \
     drawinglayer/source/primitive2d/backgroundcolorprimitive2d \
     drawinglayer/source/primitive2d/bitmapprimitive2d \
+    drawinglayer/source/primitive2d/BitmapAlphaPrimitive2D \
     drawinglayer/source/primitive2d/borderlineprimitive2d \
     drawinglayer/source/primitive2d/BufferedDecompositionGroupPrimitive2D \
     drawinglayer/source/primitive2d/controlprimitive2d \
diff --git a/drawinglayer/source/primitive2d/BitmapAlphaPrimitive2D.cxx 
b/drawinglayer/source/primitive2d/BitmapAlphaPrimitive2D.cxx
new file mode 100644
index 000000000000..8aaca2e5fd15
--- /dev/null
+++ b/drawinglayer/source/primitive2d/BitmapAlphaPrimitive2D.cxx
@@ -0,0 +1,105 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <drawinglayer/primitive2d/BitmapAlphaPrimitive2D.hxx>
+#include <drawinglayer/primitive2d/bitmapprimitive2d.hxx>
+#include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx>
+#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+#include <com/sun/star/awt/XBitmap.hpp>
+#include <utility>
+
+using namespace com::sun::star;
+
+namespace drawinglayer::primitive2d
+{
+Primitive2DReference BitmapAlphaPrimitive2D::create2DDecomposition(
+    const geometry::ViewInformation2D& /*rViewInformation*/) const
+{
+    if (basegfx::fTools::equal(getTransparency(), 1.0))
+    {
+        // completely transparent, done
+        return nullptr;
+    }
+
+    if (getBitmap().IsEmpty())
+    {
+        // no geometry, done
+        return nullptr;
+    }
+
+    if (basegfx::fTools::equalZero(getTransparency()))
+    {
+        // no transparency, use simple BitmapPrimitive2D
+        return Primitive2DReference{ new BitmapPrimitive2D(getBitmap(), 
getTransform()) };
+    }
+
+    // default: embed to UnifiedTransparencePrimitive2D
+    Primitive2DContainer aContent{ new BitmapPrimitive2D(getBitmap(), 
getTransform()) };
+    return Primitive2DReference{ new 
UnifiedTransparencePrimitive2D(std::move(aContent),
+                                                                    
getTransparency()) };
+}
+
+BitmapAlphaPrimitive2D::BitmapAlphaPrimitive2D(BitmapEx xXBitmap, 
basegfx::B2DHomMatrix aTransform,
+                                               double fTransparency)
+    : maBitmap(std::move(xXBitmap))
+    , maTransform(std::move(aTransform))
+    , mfTransparency(std::max(0.0, std::min(1.0, fTransparency)))
+{
+}
+
+bool BitmapAlphaPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) 
const
+{
+    if (BasePrimitive2D::operator==(rPrimitive))
+    {
+        const BitmapAlphaPrimitive2D& rCompare
+            = static_cast<const BitmapAlphaPrimitive2D&>(rPrimitive);
+
+        return (getBitmap() == rCompare.getBitmap() && getTransform() == 
rCompare.getTransform()
+                && basegfx::fTools::equal(getTransparency(), 
rCompare.getTransparency()));
+    }
+
+    return false;
+}
+
+basegfx::B2DRange
+BitmapAlphaPrimitive2D::getB2DRange(const geometry::ViewInformation2D& 
/*rViewInformation*/) const
+{
+    basegfx::B2DRange aRetval(0.0, 0.0, 1.0, 1.0);
+    aRetval.transform(maTransform);
+    return aRetval;
+}
+
+sal_Int64 BitmapAlphaPrimitive2D::estimateUsage()
+{
+    if (getBitmap().IsEmpty())
+    {
+        return 0;
+    }
+    return getBitmap().GetSizeBytes();
+}
+
+// provide unique ID
+sal_uInt32 BitmapAlphaPrimitive2D::getPrimitive2DID() const
+{
+    return PRIMITIVE2D_ID_BITMAPALPHAPRIMITIVE2D;
+}
+
+} // end of namespace
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/drawinglayer/source/primitive2d/Tools.cxx 
b/drawinglayer/source/primitive2d/Tools.cxx
index bd0011ab4625..2a4314c70ec4 100644
--- a/drawinglayer/source/primitive2d/Tools.cxx
+++ b/drawinglayer/source/primitive2d/Tools.cxx
@@ -237,6 +237,8 @@ OUString idToString(sal_uInt32 nId)
             return u"ANIMATEDGRAPHICPRIMITIVE2D"_ustr;
         case PRIMITIVE2D_ID_POLYPOLYGONRGBAPRIMITIVE2D:
             return u"POLYPOLYGONRGBAPRIMITIVE2D"_ustr;
+        case PRIMITIVE2D_ID_BITMAPALPHAPRIMITIVE2D:
+            return u"BITMAPALPHAPRIMITIVE2D"_ustr;
         default:
             return OUString::number((nId >> 16) & 0xFF) + "|" + 
OUString::number(nId & 0xFF);
     }
diff --git a/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx 
b/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx
index 24695b0b0a8a..715fc8ce302c 100644
--- a/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx
@@ -38,6 +38,7 @@
 #include <drawinglayer/primitive2d/invertprimitive2d.hxx>
 #include <drawinglayer/primitive2d/PolyPolygonGradientPrimitive2D.hxx>
 #include <drawinglayer/primitive2d/PolyPolygonRGBAPrimitive2D.hxx>
+#include <drawinglayer/primitive2d/BitmapAlphaPrimitive2D.hxx>
 #include <drawinglayer/converters.hxx>
 #include <basegfx/curve/b2dcubicbezier.hxx>
 #include <basegfx/matrix/b2dhommatrixtools.hxx>
@@ -826,10 +827,23 @@ CairoPixelProcessor2D::~CairoPixelProcessor2D()
 void CairoPixelProcessor2D::processBitmapPrimitive2D(
     const primitive2d::BitmapPrimitive2D& rBitmapCandidate)
 {
+    paintBitmapAlpha(rBitmapCandidate.getBitmap(), 
rBitmapCandidate.getTransform());
+}
+
+void CairoPixelProcessor2D::paintBitmapAlpha(const BitmapEx& rBitmapEx,
+                                             const basegfx::B2DHomMatrix& 
rTransform,
+                                             double fTransparency)
+{
+    // transparency invalid or completely transparent, done
+    if (fTransparency < 0.0 || fTransparency >= 1.0)
+    {
+        return;
+    }
+
     // check if graphic content is inside discrete local ViewPort
     const basegfx::B2DRange& 
rDiscreteViewPort(getViewInformation2D().getDiscreteViewport());
     const basegfx::B2DHomMatrix aLocalTransform(
-        getViewInformation2D().getObjectToViewTransformation() * 
rBitmapCandidate.getTransform());
+        getViewInformation2D().getObjectToViewTransformation() * rTransform);
 
     if (!rDiscreteViewPort.isEmpty())
     {
@@ -844,7 +858,7 @@ void CairoPixelProcessor2D::processBitmapPrimitive2D(
         }
     }
 
-    BitmapEx aBitmapEx(rBitmapCandidate.getBitmap());
+    BitmapEx aBitmapEx(rBitmapEx);
 
     if (aBitmapEx.IsEmpty() || aBitmapEx.GetSizePixel().IsEmpty())
     {
@@ -966,8 +980,11 @@ void CairoPixelProcessor2D::processBitmapPrimitive2D(
 
     cairo_pattern_set_matrix(sourcepattern, &aMatrix);
 
-    // paint bitmap data
-    cairo_paint(mpRT);
+    // paint bitmap data, evtl. with additional alpha channel
+    if (!basegfx::fTools::equalZero(fTransparency))
+        cairo_paint_with_alpha(mpRT, 1.0 - fTransparency);
+    else
+        cairo_paint(mpRT);
 
     cairo_restore(mpRT);
 }
@@ -2717,6 +2734,22 @@ void 
CairoPixelProcessor2D::processPolyPolygonRGBAPrimitive2D(
                          rPolyPolygonRGBAPrimitive2D.getTransparency());
 }
 
+void CairoPixelProcessor2D::processBitmapAlphaPrimitive2D(
+    const primitive2d::BitmapAlphaPrimitive2D& rBitmapAlphaPrimitive2D)
+{
+    if (!rBitmapAlphaPrimitive2D.hasTransparency())
+    {
+        // do what CairoPixelProcessor2D::processPolyPolygonColorPrimitive2D 
does
+        paintBitmapAlpha(rBitmapAlphaPrimitive2D.getBitmap(),
+                         rBitmapAlphaPrimitive2D.getTransform());
+        return;
+    }
+
+    // draw wiath alpha directly
+    paintBitmapAlpha(rBitmapAlphaPrimitive2D.getBitmap(), 
rBitmapAlphaPrimitive2D.getTransform(),
+                     rBitmapAlphaPrimitive2D.getTransparency());
+}
+
 void CairoPixelProcessor2D::processBasePrimitive2D(const 
primitive2d::BasePrimitive2D& rCandidate)
 {
     switch (rCandidate.getPrimitive2DID())
@@ -2839,6 +2872,12 @@ void CairoPixelProcessor2D::processBasePrimitive2D(const 
primitive2d::BasePrimit
                 static_cast<const 
primitive2d::PolyPolygonRGBAPrimitive2D&>(rCandidate));
             break;
         }
+        case PRIMITIVE2D_ID_BITMAPALPHAPRIMITIVE2D:
+        {
+            processBitmapAlphaPrimitive2D(
+                static_cast<const 
primitive2d::BitmapAlphaPrimitive2D&>(rCandidate));
+            break;
+        }
 
         // continue with decompose
         default:
diff --git a/include/drawinglayer/primitive2d/BitmapAlphaPrimitive2D.hxx 
b/include/drawinglayer/primitive2d/BitmapAlphaPrimitive2D.hxx
new file mode 100644
index 000000000000..105eb4c516c4
--- /dev/null
+++ b/include/drawinglayer/primitive2d/BitmapAlphaPrimitive2D.hxx
@@ -0,0 +1,82 @@
+/* -*- 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/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ *   Licensed to the Apache Software Foundation (ASF) under one or more
+ *   contributor license agreements. See the NOTICE file distributed
+ *   with this work for additional information regarding copyright
+ *   ownership. The ASF licenses this file to you under the Apache
+ *   License, Version 2.0 (the "License"); you may not use this file
+ *   except in compliance with the License. You may obtain a copy of
+ *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#pragma once
+
+#include <drawinglayer/drawinglayerdllapi.h>
+
+#include <drawinglayer/primitive2d/BufferedDecompositionPrimitive2D.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <vcl/bitmapex.hxx>
+
+namespace drawinglayer::primitive2d
+{
+/** BitmapAlphaPrimitive2D class
+
+    This class is a BitmapPrimitive2D extended by a unified transparency
+    aspect. It will decompose to a UnifiedTransparencePrimitive2D containing
+    a BitmapPrimitive2D and the transparence, so no primitive processor
+    has to support this primitive directly - but can if feasible.
+ */
+class DRAWINGLAYER_DLLPUBLIC BitmapAlphaPrimitive2D final : public 
BufferedDecompositionPrimitive2D
+{
+private:
+    /// the Bitmap-data
+    BitmapEx maBitmap;
+
+    /** the object transformation from unit coordinates, defining
+        size, shear, rotate and position
+     */
+    basegfx::B2DHomMatrix maTransform;
+
+    /// the transparency in range [0.0 .. 1.0]
+    double mfTransparency;
+
+    /// create local decomposition
+    virtual Primitive2DReference
+    create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) 
const override;
+
+public:
+    /// constructor
+    BitmapAlphaPrimitive2D(BitmapEx xBitmap, basegfx::B2DHomMatrix aTransform,
+                           double fTransparency = 0.0);
+
+    /// data read access
+    const BitmapEx& getBitmap() const { return maBitmap; }
+    const basegfx::B2DHomMatrix& getTransform() const { return maTransform; }
+    double getTransparency() const { return mfTransparency; }
+    bool hasTransparency() const { return 
!basegfx::fTools::equalZero(mfTransparency); }
+
+    /// compare operator
+    virtual bool operator==(const BasePrimitive2D& rPrimitive) const override;
+
+    /// get range
+    virtual basegfx::B2DRange
+    getB2DRange(const geometry::ViewInformation2D& rViewInformation) const 
override;
+
+    // XAccounting
+    virtual sal_Int64 estimateUsage() override;
+
+    /// provide unique ID
+    virtual sal_uInt32 getPrimitive2DID() const override;
+};
+
+} // end of namespace drawinglayer::primitive2d
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx 
b/include/drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx
index fcdee2ec8aed..8f86167dc5f7 100644
--- a/include/drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx
+++ b/include/drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx
@@ -110,6 +110,7 @@
 #define PRIMITIVE2D_ID_EXCLUSIVEEDITVIEWPRIMITIVE2D         
(PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 76)
 #define PRIMITIVE2D_ID_ANIMATEDGRAPHICPRIMITIVE2D           
(PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 77)
 #define PRIMITIVE2D_ID_POLYPOLYGONRGBAPRIMITIVE2D           
(PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 78)
+#define PRIMITIVE2D_ID_BITMAPALPHAPRIMITIVE2D               
(PRIMITIVE2D_ID_RANGE_DRAWINGLAYER| 79)
 // When you add a new primitive, please update the 
drawinglayer::primitive2d::idToString() function
 // in drawinglayer/source/primitive2d/Tools.cxx.
 
diff --git a/include/drawinglayer/processor2d/cairopixelprocessor2d.hxx 
b/include/drawinglayer/processor2d/cairopixelprocessor2d.hxx
index e17d568bec0c..129daaef86fa 100644
--- a/include/drawinglayer/processor2d/cairopixelprocessor2d.hxx
+++ b/include/drawinglayer/processor2d/cairopixelprocessor2d.hxx
@@ -38,6 +38,7 @@ class FillGradientPrimitive2D;
 class PolyPolygonRGBAGradientPrimitive2D;
 class FillGraphicPrimitive2D;
 class PolyPolygonRGBAPrimitive2D;
+class BitmapAlphaPrimitive2D;
 }
 
 namespace basegfx
@@ -45,6 +46,8 @@ namespace basegfx
 class B2DPolyPolygon;
 }
 
+class BitmapEx;
+
 namespace drawinglayer::processor2d
 {
 class UNLESS_MERGELIBS(DRAWINGLAYER_DLLPUBLIC) CairoPixelProcessor2D final : 
public BaseProcessor2D
@@ -92,6 +95,10 @@ class UNLESS_MERGELIBS(DRAWINGLAYER_DLLPUBLIC) 
CairoPixelProcessor2D final : pub
         const primitive2d::FillGraphicPrimitive2D& rFillGraphicPrimitive2D);
     void processPolyPolygonRGBAPrimitive2D(
         const primitive2d::PolyPolygonRGBAPrimitive2D& 
rPolyPolygonRGBAPrimitive2D);
+    void paintBitmapAlpha(const BitmapEx& rBitmapEx, const 
basegfx::B2DHomMatrix& rTransform,
+                          double fTransparency = 0.0);
+    void processBitmapAlphaPrimitive2D(
+        const primitive2d::BitmapAlphaPrimitive2D& rBitmapAlphaPrimitive2D);
 
     /*  the local processor for BasePrimitive2D-Implementation based 
primitives,
         called from the common process()-implementation

Reply via email to