slideshow/source/engine/slideshowimpl.cxx |  148 ++++++++++++++++++++----------
 1 file changed, 103 insertions(+), 45 deletions(-)

New commits:
commit 631964a2ce1da3fbbeb53a5550c0e6728ba644aa
Author:     Regina Henschel <rb.hensc...@t-online.de>
AuthorDate: Sat Aug 12 22:57:31 2023 +0200
Commit:     Regina Henschel <rb.hensc...@t-online.de>
CommitDate: Sun Aug 13 14:57:02 2023 +0200

    tfd#112687 Combine adjacent lines into one shape
    
    When the user makes a 'mouse as pen' drawing in slideshow, then each
    mouse drag step generates a separate, very short two-point line. When
    the drawings were made persistent, from each of this mini lines an
    individual shape was created.
    
    Now lines, were the end point of one line equals the start point of
    the next line, were combined to a polyline. That way a drawing, which
    was drawn with one mouse drag, becomes one shape now.
    
    This does not solve, that too many of such mini lines were generated.
    But it makes it easier to handle them in edit mode.
    
    Change-Id: I8662831f309b201c049844a613877190ca0da5b3
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/155643
    Tested-by: Jenkins
    Reviewed-by: Regina Henschel <rb.hensc...@t-online.de>

diff --git a/slideshow/source/engine/slideshowimpl.cxx 
b/slideshow/source/engine/slideshowimpl.cxx
index f02647097ea8..f681dc2a9559 100644
--- a/slideshow/source/engine/slideshowimpl.cxx
+++ b/slideshow/source/engine/slideshowimpl.cxx
@@ -48,6 +48,7 @@
 #include <com/sun/star/lang/NoSupportException.hpp>
 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
 #include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/drawing/LineCap.hpp>
 #include <com/sun/star/drawing/PointSequenceSequence.hpp>
 #include <com/sun/star/drawing/PointSequence.hpp>
 #include <com/sun/star/drawing/XLayer.hpp>
@@ -1398,6 +1399,59 @@ sal_Bool SlideShowImpl::removeView(
     return true;
 }
 
+drawing::PointSequenceSequence
+lcl_createPointSequenceSequenceFromB2DPolygon(const basegfx::B2DPolygon& rPoly)
+{
+    drawing::PointSequenceSequence aRetval;
+    //Create only one sequence for one pen drawing.
+    aRetval.realloc(1);
+    // Retrieve the sequence of points from aRetval
+    drawing::PointSequence* pOuterSequence = aRetval.getArray();
+    // Create points in this sequence from rPoly
+    pOuterSequence->realloc(rPoly.count());
+    // Get these points which are in an array
+    awt::Point* pInnerSequence = pOuterSequence->getArray();
+    for( sal_uInt32 n = 0; n < rPoly.count(); n++ )
+    {
+        //Create a point from the polygon
+        *pInnerSequence++ = 
awt::Point(basegfx::fround(rPoly.getB2DPoint(n).getX()),
+                                       
basegfx::fround(rPoly.getB2DPoint(n).getY()));
+    }
+    return aRetval;
+}
+
+void lcl_setPropertiesToShape(const drawing::PointSequenceSequence& rPoints,
+                              const cppcanvas::PolyPolygonSharedPtr 
pCanvasPolyPoly,
+                              uno::Reference< drawing::XShape >& rPolyShape)
+{
+    uno::Reference< beans::XPropertySet > aXPropSet(rPolyShape, 
uno::UNO_QUERY);
+    //Give the built PointSequenceSequence.
+    uno::Any aParam;
+    aParam <<= rPoints;
+    aXPropSet->setPropertyValue("PolyPolygon", aParam);
+
+    //LineStyle : SOLID by default
+    drawing::LineStyle eLS;
+    eLS = drawing::LineStyle_SOLID;
+    aXPropSet->setPropertyValue("LineStyle", uno::Any(eLS));
+
+    //LineCap : ROUND by default, same as in show mode
+    drawing::LineCap eLC;
+    eLC = drawing::LineCap_ROUND;
+    aXPropSet->setPropertyValue("LineCap", uno::Any(eLC));
+
+    //LineColor
+    sal_uInt32 nLineColor;
+    nLineColor = pCanvasPolyPoly->getRGBALineColor();
+    //Transform polygon color from RRGGBBAA to AARRGGBB
+    aXPropSet->setPropertyValue("LineColor", 
uno::Any(RGBAColor2UnoColor(nLineColor)));
+
+    //LineWidth
+    double  fLineWidth;
+    fLineWidth = pCanvasPolyPoly->getStrokeWidth();
+    aXPropSet->setPropertyValue("LineWidth", 
uno::Any(static_cast<sal_Int32>(fLineWidth)));
+}
+
 void SlideShowImpl::registerUserPaintPolygons( const uno::Reference< 
lang::XMultiServiceFactory >& xDocFactory )
 {
     //Retrieve Polygons if user ends presentation by context menu
@@ -1444,74 +1498,78 @@ void SlideShowImpl::registerUserPaintPolygons( const 
uno::Reference< lang::XMult
         PolyPolygonVector aPolygons = rPoly.second;
         //Get shapes for the slide
         css::uno::Reference< css::drawing::XShapes > Shapes = rPoly.first;
+
         //Retrieve polygons for one slide
+        // #tdf112687 A pen drawing in slideshow is actually a chain of 
individual line shapes, where
+        // the end point of one line shape equals the start point of the next 
line shape.
+        // We collect these points into one B2DPolygon and use that to 
generate the shape on the
+        // slide.
+        ::basegfx::B2DPolygon aDrawingPoints;
+        cppcanvas::PolyPolygonSharedPtr pFirstPolyPoly; // for style properties
         for( const auto& pPolyPoly : aPolygons )
         {
+            // Actually, each item in aPolygons has two points, but wrapped in 
a cppcanvas::PopyPolygon.
             ::basegfx::B2DPolyPolygon b2DPolyPoly = 
::basegfx::unotools::b2DPolyPolygonFromXPolyPolygon2D(pPolyPoly->getUNOPolyPolygon());
 
             //Normally there is only one polygon
             for(sal_uInt32 i=0; i< b2DPolyPoly.count();i++)
             {
                 const ::basegfx::B2DPolygon& aPoly =  
b2DPolyPoly.getB2DPolygon(i);
-                sal_uInt32 nPoints = aPoly.count();
 
-                if( nPoints > 1)
+                if (aPoly.count() > 1) // otherwise skip it, count should be 2
                 {
-                    //create the PolyLineShape
+                    if (aDrawingPoints.count() == 0)
+                    {
+                        aDrawingPoints.append(aPoly);
+                        pFirstPolyPoly = pPolyPoly;
+                        continue;
+                    }
+
+                    basegfx::B2DPoint aLast = 
aDrawingPoints.getB2DPoint(aDrawingPoints.count() - 1);
+                    if (aPoly.getB2DPoint(0).equal(aLast))
+                    {
+                        aDrawingPoints.append(aPoly, 1);
+                        continue;
+                    }
+
+                    // Put what we have collected to the slide and then start 
a new pen drawing object
+                    //create the PolyLineShape. The points will be in its 
PolyPolygon property.
                     uno::Reference< uno::XInterface > 
polyshape(xDocFactory->createInstance(
                                                                     
"com.sun.star.drawing.PolyLineShape" ) );
                     uno::Reference< drawing::XShape > rPolyShape(polyshape, 
uno::UNO_QUERY);
-
                     //Add the shape to the slide
                     Shapes->add(rPolyShape);
-
-                    //Retrieve shape properties
-                    uno::Reference< beans::XPropertySet > aXPropSet( 
rPolyShape, uno::UNO_QUERY );
                     //Construct a sequence of points sequence
-                    drawing::PointSequenceSequence aRetval;
-                    //Create only one sequence for one polygon
-                    aRetval.realloc( 1 );
-                    // Retrieve the sequence of points from aRetval
-                    drawing::PointSequence* pOuterSequence = 
aRetval.getArray();
-                    // Create 2 points in this sequence
-                    pOuterSequence->realloc(nPoints);
-                    // Get these points which are in an array
-                    awt::Point* pInnerSequence = pOuterSequence->getArray();
-                    for( sal_uInt32 n = 0; n < nPoints; n++ )
-                    {
-                        //Create a point from the polygon
-                        *pInnerSequence++ = awt::Point(
-                            basegfx::fround(aPoly.getB2DPoint(n).getX()),
-                            basegfx::fround(aPoly.getB2DPoint(n).getY()));
-                    }
-
+                    const drawing::PointSequenceSequence aRetval
+                        = 
lcl_createPointSequenceSequenceFromB2DPolygon(aDrawingPoints);
                     //Fill the properties
-                    //Give the built PointSequenceSequence.
-                    uno::Any aParam;
-                    aParam <<= aRetval;
-                    aXPropSet->setPropertyValue("PolyPolygon", aParam );
-
-                    //LineStyle : SOLID by default
-                    drawing::LineStyle  eLS;
-                    eLS = drawing::LineStyle_SOLID;
-                    aXPropSet->setPropertyValue("LineStyle", uno::Any(eLS) );
-
-                    //LineColor
-                    sal_uInt32          nLineColor;
-                    nLineColor = pPolyPoly->getRGBALineColor();
-                    //Transform polygon color from RRGGBBAA to AARRGGBB
-                    aXPropSet->setPropertyValue("LineColor", 
uno::Any(RGBAColor2UnoColor(nLineColor)) );
-
-                    //LineWidth
-                    double              fLineWidth;
-                    fLineWidth = pPolyPoly->getStrokeWidth();
-                    aXPropSet->setPropertyValue("LineWidth", 
uno::Any(static_cast<sal_Int32>(fLineWidth)) );
-
+                    lcl_setPropertiesToShape(aRetval, pFirstPolyPoly, 
rPolyShape);
                     // make polygons special
                     xLayerManager->attachShapeToLayer(rPolyShape, 
xDrawnInSlideshow);
+                    // Start next pen drawing object
+                    aDrawingPoints.clear();
+                    aDrawingPoints.append(aPoly);
+                    pFirstPolyPoly = pPolyPoly;
                 }
             }
         }
+        // Bring remaining points to slide
+        if (aDrawingPoints.count() > 1)
+        {
+            //create the PolyLineShape. The points will be in its PolyPolygon 
property.
+            uno::Reference< uno::XInterface > polyshape(
+                
xDocFactory->createInstance("com.sun.star.drawing.PolyLineShape"));
+            uno::Reference< drawing::XShape > rPolyShape(polyshape, 
uno::UNO_QUERY);
+            //Add the shape to the slide
+            Shapes->add(rPolyShape);
+            //Construct a sequence of points sequence
+            drawing::PointSequenceSequence aRetval
+                = 
lcl_createPointSequenceSequenceFromB2DPolygon(aDrawingPoints);
+            //Fill the properties
+            lcl_setPropertiesToShape(aRetval, aPolygons.back(), rPolyShape);
+            // make polygons special
+            xLayerManager->attachShapeToLayer(rPolyShape, xDrawnInSlideshow);
+        }
     }
 }
 

Reply via email to