drawinglayer/source/processor2d/cairopixelprocessor2d.cxx  |  175 +++++++++++--
 drawinglayer/source/processor2d/d2dpixelprocessor2d.cxx    |    6 
 include/drawinglayer/processor2d/cairopixelprocessor2d.hxx |   23 +
 include/drawinglayer/processor2d/d2dpixelprocessor2d.hxx   |    2 
 4 files changed, 178 insertions(+), 28 deletions(-)

New commits:
commit d1c6eeba13c2551e270e8ff0ba919fc9bac101c9
Author:     Armin Le Grand (Collabora) <armin.le.gr...@me.com>
AuthorDate: Tue Jul 16 14:34:58 2024 +0200
Commit:     Armin Le Grand <armin.le.gr...@me.com>
CommitDate: Tue Jul 16 21:15:02 2024 +0200

    CairoSDPR: Direct support for RGBA Gradients (II)
    
    This step wil now use the new primitive
    PolyPolygonRGBAGradientPrimitive2D inside the
    CairoSDPR/CairoPixelProcessor2D to directly
    render gradients as RGBA, without painting
    RGB (content) and A (alpha) separate and mixing
    the results.
    Note that this is only possible for gradients
    which use the same graphical definition, see the
    method 'sameDefinitionThanAlpha' and it's usages
    in the code.
    
    Change-Id: I6c46a211ea26d3e4b7bb39c7f2aaff09ec38dec5
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/170584
    Reviewed-by: Armin Le Grand <armin.le.gr...@me.com>
    Tested-by: Jenkins

diff --git a/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx 
b/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx
index 1de46473d790..5761d8f4bdb1 100644
--- a/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/cairopixelprocessor2d.cxx
@@ -36,6 +36,7 @@
 #include <drawinglayer/primitive2d/fillgraphicprimitive2d.hxx>
 #include <drawinglayer/primitive2d/fillgradientprimitive2d.hxx>
 #include <drawinglayer/primitive2d/invertprimitive2d.hxx>
+#include <drawinglayer/primitive2d/PolyPolygonGradientPrimitive2D.hxx>
 #include <drawinglayer/converters.hxx>
 #include <basegfx/curve/b2dcubicbezier.hxx>
 #include <basegfx/matrix/b2dhommatrixtools.hxx>
@@ -1263,8 +1264,10 @@ void CairoPixelProcessor2D::processInvertPrimitive2D(
     cairo_restore(mpRT);
 }
 
-void CairoPixelProcessor2D::processMaskPrimitive2DPixel(
-    const primitive2d::MaskPrimitive2D& rMaskCandidate)
+void CairoPixelProcessor2D::processMaskPrimitive2D(
+    const primitive2d::MaskPrimitive2D& rMaskCandidate,
+    const primitive2d::FillGradientPrimitive2D* pFillGradientPrimitive2D,
+    const attribute::FillGradientAttribute* pFillGradientAlpha)
 {
     if (rMaskCandidate.getChildren().empty())
     {
@@ -1314,8 +1317,20 @@ void CairoPixelProcessor2D::processMaskPrimitive2DPixel(
     cairo_clip(mpRT);
     cairo_new_path(mpRT);
 
-    // process sub-content (that shall be masked)
-    process(rMaskCandidate.getChildren());
+    if (nullptr != pFillGradientPrimitive2D && nullptr != pFillGradientAlpha)
+    {
+        // special case: render given FillGradientPrimitive2D using
+        // FillGradientAlpha as RGBA gradient directly
+        // note that calling this method with nullptr != pFillGradientAlpha
+        // is only allowed internal from
+        // CairoPixelProcessor2D::processPolyPolygonRGBAGradientPrimitive2D
+        processFillGradientPrimitive2D(*pFillGradientPrimitive2D, 
pFillGradientAlpha);
+    }
+    else
+    {
+        // process sub-content (that shall be masked)
+        process(rMaskCandidate.getChildren());
+    }
 
     cairo_restore(mpRT);
 }
@@ -1922,7 +1937,8 @@ bool 
CairoPixelProcessor2D::processFillGradientPrimitive2D_isCompletelyBordered(
 }
 
 void CairoPixelProcessor2D::processFillGradientPrimitive2D_linear_axial(
-    const primitive2d::FillGradientPrimitive2D& rFillGradientPrimitive2D)
+    const primitive2d::FillGradientPrimitive2D& rFillGradientPrimitive2D,
+    const attribute::FillGradientAttribute* pFillGradientAlpha)
 {
     assert(
         (css::awt::GradientStyle_LINEAR == 
rFillGradientPrimitive2D.getFillGradient().getStyle()
@@ -1964,6 +1980,10 @@ void 
CairoPixelProcessor2D::processFillGradientPrimitive2D_linear_axial(
 
     // get color stops (make copy, might have to be changed)
     basegfx::BColorStops aBColorStops(rFillGradient.getColorStops());
+    basegfx::BColorStops aBColorStopsAlpha;
+    const bool bHasAlpha(nullptr != pFillGradientAlpha);
+    if (bHasAlpha)
+        aBColorStopsAlpha = pFillGradientAlpha->getColorStops();
     const bool bAxial(css::awt::GradientStyle_AXIAL == 
rFillGradient.getStyle());
 
     // get and apply border - create soace at start in gradient
@@ -1971,30 +1991,58 @@ void 
CairoPixelProcessor2D::processFillGradientPrimitive2D_linear_axial(
     if (!basegfx::fTools::equalZero(fBorder))
     {
         if (bAxial)
+        {
             aBColorStops.reverseColorStops();
+            if (bHasAlpha)
+                aBColorStopsAlpha.reverseColorStops();
+        }
+
         aBColorStops.createSpaceAtStart(fBorder);
+        if (bHasAlpha)
+            aBColorStopsAlpha.createSpaceAtStart(fBorder);
+
         if (bAxial)
+        {
             aBColorStops.reverseColorStops();
+            if (bHasAlpha)
+                aBColorStopsAlpha.reverseColorStops();
+        }
     }
 
     if (bAxial)
     {
         // expand with mirrored ColorStops to create axial
         aBColorStops.doApplyAxial();
+        if (bHasAlpha)
+            aBColorStopsAlpha.doApplyAxial();
     }
 
     // Apply steps if used to 'emulate' LO's 'discrete step' feature
     if (rFillGradient.getSteps())
     {
         aBColorStops.doApplySteps(rFillGradient.getSteps());
+        if (bHasAlpha)
+            aBColorStopsAlpha.doApplySteps(rFillGradient.getSteps());
     }
 
     // add color stops
-    for (const auto& aStop : aBColorStops)
+    for (size_t a(0); a < aBColorStops.size(); a++)
     {
-        const basegfx::BColor 
aColor(maBColorModifierStack.getModifiedColor(aStop.getStopColor()));
-        cairo_pattern_add_color_stop_rgb(pPattern, aStop.getStopOffset(), 
aColor.getRed(),
-                                         aColor.getGreen(), aColor.getBlue());
+        const basegfx::BColorStop& rStop(aBColorStops[a]);
+        const basegfx::BColor 
aColor(maBColorModifierStack.getModifiedColor(rStop.getStopColor()));
+
+        if (bHasAlpha)
+        {
+            const basegfx::BColor aAlpha(aBColorStopsAlpha[a].getStopColor());
+            cairo_pattern_add_color_stop_rgba(pPattern, rStop.getStopOffset(), 
aColor.getRed(),
+                                              aColor.getGreen(), 
aColor.getBlue(),
+                                              aAlpha.luminance());
+        }
+        else
+        {
+            cairo_pattern_add_color_stop_rgb(pPattern, rStop.getStopOffset(), 
aColor.getRed(),
+                                             aColor.getGreen(), 
aColor.getBlue());
+        }
     }
 
     // draw OutRange
@@ -2273,7 +2321,8 @@ void 
CairoPixelProcessor2D::processFillGradientPrimitive2D_square_rect(
 }
 
 void CairoPixelProcessor2D::processFillGradientPrimitive2D_radial_elliptical(
-    const primitive2d::FillGradientPrimitive2D& rFillGradientPrimitive2D)
+    const primitive2d::FillGradientPrimitive2D& rFillGradientPrimitive2D,
+    const attribute::FillGradientAttribute* pFillGradientAlpha)
 {
     assert((css::awt::GradientStyle_RADIAL == 
rFillGradientPrimitive2D.getFillGradient().getStyle()
             || css::awt::GradientStyle_ELLIPTICAL
@@ -2337,26 +2386,46 @@ void 
CairoPixelProcessor2D::processFillGradientPrimitive2D_radial_elliptical(
 
     // get color stops (make copy, might have to be changed)
     basegfx::BColorStops aBColorStops(rFillGradient.getColorStops());
+    basegfx::BColorStops aBColorStopsAlpha;
+    const bool bHasAlpha(nullptr != pFillGradientAlpha);
+    if (bHasAlpha)
+        aBColorStopsAlpha = pFillGradientAlpha->getColorStops();
 
     // get and apply border - create soace at start in gradient
     const double fBorder(std::max(std::min(rFillGradient.getBorder(), 1.0), 
0.0));
     if (!basegfx::fTools::equalZero(fBorder))
     {
         aBColorStops.createSpaceAtStart(fBorder);
+        if (bHasAlpha)
+            aBColorStopsAlpha.createSpaceAtStart(fBorder);
     }
 
     // Apply steps if used to 'emulate' LO's 'discrete step' feature
     if (rFillGradient.getSteps())
     {
         aBColorStops.doApplySteps(rFillGradient.getSteps());
+        if (bHasAlpha)
+            aBColorStopsAlpha.doApplySteps(rFillGradient.getSteps());
     }
 
     // add color stops
-    for (const auto& aStop : aBColorStops)
+    for (size_t a(0); a < aBColorStops.size(); a++)
     {
-        const basegfx::BColor 
aColor(maBColorModifierStack.getModifiedColor(aStop.getStopColor()));
-        cairo_pattern_add_color_stop_rgb(pPattern, aStop.getStopOffset(), 
aColor.getRed(),
-                                         aColor.getGreen(), aColor.getBlue());
+        const basegfx::BColorStop& rStop(aBColorStops[a]);
+        const basegfx::BColor 
aColor(maBColorModifierStack.getModifiedColor(rStop.getStopColor()));
+
+        if (bHasAlpha)
+        {
+            const basegfx::BColor aAlpha(aBColorStopsAlpha[a].getStopColor());
+            cairo_pattern_add_color_stop_rgba(pPattern, rStop.getStopOffset(), 
aColor.getRed(),
+                                              aColor.getGreen(), 
aColor.getBlue(),
+                                              aAlpha.luminance());
+        }
+        else
+        {
+            cairo_pattern_add_color_stop_rgb(pPattern, rStop.getStopOffset(), 
aColor.getRed(),
+                                             aColor.getGreen(), 
aColor.getBlue());
+        }
     }
 
     cairo_set_source(mpRT, pPattern);
@@ -2446,7 +2515,8 @@ void 
CairoPixelProcessor2D::processFillGradientPrimitive2D_fallback_decompose(
 }
 
 void CairoPixelProcessor2D::processFillGradientPrimitive2D(
-    const primitive2d::FillGradientPrimitive2D& rFillGradientPrimitive2D)
+    const primitive2d::FillGradientPrimitive2D& rFillGradientPrimitive2D,
+    const attribute::FillGradientAttribute* pFillGradientAlpha)
 {
     if (rFillGradientPrimitive2D.getDefinitionRange().isEmpty())
     {
@@ -2494,13 +2564,21 @@ void 
CairoPixelProcessor2D::processFillGradientPrimitive2D(
         return;
     }
 
+    // for dfirect RGBA gradient render support: assert when the definition
+    // is not allowed, it HAS to fulfil the requested preconditions. Note that
+    // the form to call this function using nullptr != pFillGradientAlpha is
+    // only allowed locally in CairoPixelProcessor2D::processMaskPrimitive2D
+    assert(nullptr == pFillGradientAlpha
+           || rFillGradient.sameDefinitionThanAlpha(*pFillGradientAlpha));
+
     switch (rFillGradient.getStyle())
     {
         case css::awt::GradientStyle_LINEAR:
         case css::awt::GradientStyle_AXIAL:
         {
             // use specialized renderer for this cases - linear, axial
-            
processFillGradientPrimitive2D_linear_axial(rFillGradientPrimitive2D);
+            
processFillGradientPrimitive2D_linear_axial(rFillGradientPrimitive2D,
+                                                        pFillGradientAlpha);
             return;
         }
         case css::awt::GradientStyle_RADIAL:
@@ -2517,13 +2595,20 @@ void 
CairoPixelProcessor2D::processFillGradientPrimitive2D(
             // also rare. IF that should make problems reactivation of that 
case
             // for the default case below is possible. main reason is that 
speed
             // for direct rendering in cairo is much better.
-            
processFillGradientPrimitive2D_radial_elliptical(rFillGradientPrimitive2D);
+            
processFillGradientPrimitive2D_radial_elliptical(rFillGradientPrimitive2D,
+                                                             
pFillGradientAlpha);
             return;
         }
         case css::awt::GradientStyle_SQUARE:
         case css::awt::GradientStyle_RECT:
         {
             // use specialized renderer for this cases - square, rect
+            // NOTE: *NO* support for FillGradientAlpha here. it is anyways
+            // hard to map these to direct rendering, but to do so the four
+            // trapezoids/sides are 'stitched' together, so painting RGBA
+            // directly will make the overlaps look bad and like errors.
+            // Anyways, these gradient types are only our internal heritage
+            // and rendering them directly is already much faster, will be 
okay.
             
processFillGradientPrimitive2D_square_rect(rFillGradientPrimitive2D);
             return;
         }
@@ -2538,6 +2623,53 @@ void 
CairoPixelProcessor2D::processFillGradientPrimitive2D(
     }
 }
 
+void CairoPixelProcessor2D::processPolyPolygonRGBAGradientPrimitive2D(
+    const primitive2d::PolyPolygonRGBAGradientPrimitive2D& 
rPolyPolygonRGBAGradientPrimitive2D)
+{
+    const attribute::FillGradientAttribute& rFill(
+        rPolyPolygonRGBAGradientPrimitive2D.getFillGradient());
+    const attribute::FillGradientAttribute& rAlpha(
+        rPolyPolygonRGBAGradientPrimitive2D.getFillGradientAlpha());
+
+    if (rFill.isDefault())
+    {
+        // no gradient definition, done
+        return;
+    }
+
+    // assert when the definition is not allowed, it HAS to fulfil the
+    // requested preconditions
+    assert(rFill.sameDefinitionThanAlpha(rAlpha));
+
+    // the gradient still needs to be masked to getB2DPolyPolygon() at the
+    // primitive, see PolyPolygonGradientPrimitive2D::create2DDecomposition.
+    // we could repeat here the code inside localprocessMaskPrimitive2D, but
+    // it is easier to just locally temporarily create the needed data 
structure
+    // and hand over the needed extra-data
+    const basegfx::B2DRange aPolyPolygonRange(
+        rPolyPolygonRGBAGradientPrimitive2D.getB2DPolyPolygon().getB2DRange());
+    primitive2d::FillGradientPrimitive2D* pFillGradientPrimitive2D(
+        new primitive2d::FillGradientPrimitive2D(
+            aPolyPolygonRange, 
rPolyPolygonRGBAGradientPrimitive2D.getDefinitionRange(), rFill));
+    primitive2d::Primitive2DContainer aContent{ pFillGradientPrimitive2D };
+
+    // NOTE: I had this like
+    //   const primitive2d::MaskPrimitive2D aMaskPrimitive2D(
+    //       rPolyPolygonRGBAGradientPrimitive2D.getB2DPolyPolygon(), 
std::move(aContent));
+    // but I got
+    //   error: salhelper::SimpleReferenceObject subclass being directly stack 
managed, should
+    //   be managed via rtl::Reference, const primitive2d::MaskPrimitive2D 
[loplugin:refcounting]
+    // thus I have *no choice* and have to use the heap here (?) It is no 
problem to use the stack
+    // and I wanted to do this here by purpose... sigh
+    primitive2d::MaskPrimitive2D* pMaskPrimitive2D(new 
primitive2d::MaskPrimitive2D(
+        rPolyPolygonRGBAGradientPrimitive2D.getB2DPolyPolygon(), 
std::move(aContent)));
+    primitive2d::Primitive2DContainer aMask{ pMaskPrimitive2D };
+    (void)aMask;
+
+    // render masked RGBA gradient
+    processMaskPrimitive2D(*pMaskPrimitive2D, pFillGradientPrimitive2D, 
&rAlpha);
+}
+
 void CairoPixelProcessor2D::processBasePrimitive2D(const 
primitive2d::BasePrimitive2D& rCandidate)
 {
     switch (rCandidate.getPrimitive2DID())
@@ -2582,8 +2714,7 @@ void CairoPixelProcessor2D::processBasePrimitive2D(const 
primitive2d::BasePrimit
         }
         case PRIMITIVE2D_ID_MASKPRIMITIVE2D:
         {
-            processMaskPrimitive2DPixel(
-                static_cast<const primitive2d::MaskPrimitive2D&>(rCandidate));
+            processMaskPrimitive2D(static_cast<const 
primitive2d::MaskPrimitive2D&>(rCandidate));
             break;
         }
         case PRIMITIVE2D_ID_MODIFIEDCOLORPRIMITIVE2D:
@@ -2654,6 +2785,12 @@ void CairoPixelProcessor2D::processBasePrimitive2D(const 
primitive2d::BasePrimit
                 static_cast<const 
primitive2d::FillGradientPrimitive2D&>(rCandidate));
             break;
         }
+        case PRIMITIVE2D_ID_POLYPOLYGONRGBAGRADIENTPRIMITIVE2D:
+        {
+            processPolyPolygonRGBAGradientPrimitive2D(
+                static_cast<const 
primitive2d::PolyPolygonRGBAGradientPrimitive2D&>(rCandidate));
+            break;
+        }
 
         // continue with decompose
         default:
diff --git a/drawinglayer/source/processor2d/d2dpixelprocessor2d.cxx 
b/drawinglayer/source/processor2d/d2dpixelprocessor2d.cxx
index 089106194754..e9bcc6c10423 100644
--- a/drawinglayer/source/processor2d/d2dpixelprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/d2dpixelprocessor2d.cxx
@@ -1269,8 +1269,7 @@ void 
D2DPixelProcessor2D::processUnifiedTransparencePrimitive2D(
         increaseError();
 }
 
-void D2DPixelProcessor2D::processMaskPrimitive2DPixel(
-    const primitive2d::MaskPrimitive2D& rMaskCandidate)
+void D2DPixelProcessor2D::processMaskPrimitive2D(const 
primitive2d::MaskPrimitive2D& rMaskCandidate)
 {
     if (rMaskCandidate.getChildren().empty())
     {
@@ -2082,8 +2081,7 @@ void D2DPixelProcessor2D::processBasePrimitive2D(const 
primitive2d::BasePrimitiv
         }
         case PRIMITIVE2D_ID_MASKPRIMITIVE2D:
         {
-            processMaskPrimitive2DPixel(
-                static_cast<const primitive2d::MaskPrimitive2D&>(rCandidate));
+            processMaskPrimitive2D(static_cast<const 
primitive2d::MaskPrimitive2D&>(rCandidate));
             break;
         }
         case PRIMITIVE2D_ID_MODIFIEDCOLORPRIMITIVE2D:
diff --git a/include/drawinglayer/processor2d/cairopixelprocessor2d.hxx 
b/include/drawinglayer/processor2d/cairopixelprocessor2d.hxx
index 8a8218e18e92..74977b704051 100644
--- a/include/drawinglayer/processor2d/cairopixelprocessor2d.hxx
+++ b/include/drawinglayer/processor2d/cairopixelprocessor2d.hxx
@@ -35,9 +35,15 @@ class LineRectanglePrimitive2D;
 class FilledRectanglePrimitive2D;
 class SingleLinePrimitive2D;
 class FillGradientPrimitive2D;
+class PolyPolygonRGBAGradientPrimitive2D;
 class FillGraphicPrimitive2D;
 }
 
+namespace drawinglayer::attribute
+{
+class FillGradientAttribute;
+}
+
 namespace drawinglayer::processor2d
 {
 class UNLESS_MERGELIBS(DRAWINGLAYER_DLLPUBLIC) CairoPixelProcessor2D final : 
public BaseProcessor2D
@@ -59,7 +65,11 @@ class UNLESS_MERGELIBS(DRAWINGLAYER_DLLPUBLIC) 
CairoPixelProcessor2D final : pub
     void processInvertPrimitive2D(const primitive2d::InvertPrimitive2D& 
rTransCandidate);
     void processUnifiedTransparencePrimitive2D(
         const primitive2d::UnifiedTransparencePrimitive2D& rTransCandidate);
-    void processMaskPrimitive2DPixel(const primitive2d::MaskPrimitive2D& 
rMaskCandidate);
+    void processMaskPrimitive2D(const primitive2d::MaskPrimitive2D& 
rMaskCandidate,
+                                const primitive2d::FillGradientPrimitive2D* 
pFillGradientPrimitive2D
+                                = nullptr,
+                                const attribute::FillGradientAttribute* 
pFillGradientAlpha
+                                = nullptr);
     void processModifiedColorPrimitive2D(
         const primitive2d::ModifiedColorPrimitive2D& rModifiedCandidate);
     void processTransformPrimitive2D(const primitive2d::TransformPrimitive2D& 
rTransformCandidate);
@@ -78,9 +88,12 @@ class UNLESS_MERGELIBS(DRAWINGLAYER_DLLPUBLIC) 
CairoPixelProcessor2D final : pub
     void
     processSingleLinePrimitive2D(const primitive2d::SingleLinePrimitive2D& 
rSingleLinePrimitive2D);
     void processFillGradientPrimitive2D(
-        const primitive2d::FillGradientPrimitive2D& rFillGradientPrimitive2D);
+        const primitive2d::FillGradientPrimitive2D& rFillGradientPrimitive2D,
+        const attribute::FillGradientAttribute* pFillGradientAlpha = nullptr);
     void processFillGraphicPrimitive2D(
         const primitive2d::FillGraphicPrimitive2D& rFillGraphicPrimitive2D);
+    void processPolyPolygonRGBAGradientPrimitive2D(
+        const primitive2d::PolyPolygonRGBAGradientPrimitive2D& 
rPolyPolygonRGBAGradientPrimitive2D);
 
     /*  the local processor for BasePrimitive2D-Implementation based 
primitives,
         called from the common process()-implementation
@@ -95,9 +108,11 @@ class UNLESS_MERGELIBS(DRAWINGLAYER_DLLPUBLIC) 
CairoPixelProcessor2D final : pub
     bool processFillGradientPrimitive2D_isCompletelyBordered(
         const primitive2d::FillGradientPrimitive2D& rFillGradientPrimitive2D);
     void processFillGradientPrimitive2D_linear_axial(
-        const primitive2d::FillGradientPrimitive2D& rFillGradientPrimitive2D);
+        const primitive2d::FillGradientPrimitive2D& rFillGradientPrimitive2D,
+        const attribute::FillGradientAttribute* pFillGradientAlpha = nullptr);
     void processFillGradientPrimitive2D_radial_elliptical(
-        const primitive2d::FillGradientPrimitive2D& rFillGradientPrimitive2D);
+        const primitive2d::FillGradientPrimitive2D& rFillGradientPrimitive2D,
+        const attribute::FillGradientAttribute* pFillGradientAlpha = nullptr);
     void processFillGradientPrimitive2D_square_rect(
         const primitive2d::FillGradientPrimitive2D& rFillGradientPrimitive2D);
 
diff --git a/include/drawinglayer/processor2d/d2dpixelprocessor2d.hxx 
b/include/drawinglayer/processor2d/d2dpixelprocessor2d.hxx
index b627bf2b164b..f3a564c8b2a5 100644
--- a/include/drawinglayer/processor2d/d2dpixelprocessor2d.hxx
+++ b/include/drawinglayer/processor2d/d2dpixelprocessor2d.hxx
@@ -81,7 +81,7 @@ class DRAWINGLAYER_DLLPUBLIC D2DPixelProcessor2D : public 
BaseProcessor2D
     processTransparencePrimitive2D(const primitive2d::TransparencePrimitive2D& 
rTransCandidate);
     void processUnifiedTransparencePrimitive2D(
         const primitive2d::UnifiedTransparencePrimitive2D& rTransCandidate);
-    void processMaskPrimitive2DPixel(const primitive2d::MaskPrimitive2D& 
rMaskCandidate);
+    void processMaskPrimitive2D(const primitive2d::MaskPrimitive2D& 
rMaskCandidate);
     void processModifiedColorPrimitive2D(
         const primitive2d::ModifiedColorPrimitive2D& rModifiedCandidate);
     void processTransformPrimitive2D(const primitive2d::TransformPrimitive2D& 
rTransformCandidate);

Reply via email to