drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx |    2 
 editeng/inc/outleeng.hxx                                   |    2 
 editeng/source/editeng/editeng.cxx                         |    4 
 editeng/source/editeng/impedit.hxx                         |    2 
 editeng/source/editeng/impedit3.cxx                        |  885 +++----------
 editeng/source/outliner/outleeng.cxx                       |    6 
 editeng/source/outliner/outliner.cxx                       |  105 -
 include/editeng/editeng.hxx                                |    2 
 include/editeng/outliner.hxx                               |   13 
 sd/source/ui/view/outlview.cxx                             |   79 -
 10 files changed, 335 insertions(+), 765 deletions(-)

New commits:
commit 83ffcdd964611c739e5235e829d015c4965b55d7
Author:     Armin Le Grand (collabora) <[email protected]>
AuthorDate: Mon Aug 4 14:15:15 2025 +0200
Commit:     Armin Le Grand <[email protected]>
CommitDate: Mon Aug 4 20:35:16 2025 +0200

    StripPortions: Further simplify EditEngine
    
    Since 6c8b8020510f8816c40a42e6c3a7fde12012b142 which is
    'StripPortions: full Primitive usage for EditEngine Paint'
    all DrawText_To* methods were already using a full
    conversion to Primitives which then get painted directly,
    see commit comment there.
    
    Since then no complaints/errors came up I now continue
    to move EditEngine to Primitive usage. Lots of code for
    the still also existing DirectPaint gets removed.
    
    I also drive forward changes to have less parameters
    for the ImpEditEngine::StripAllPortions method. It is
    already cleared by the former possible rotation, this
    can (and is) replaced by embedding the result to a
    transform primitive doing that rotation. I changed
    two of three using methods to strip always to
    position (0, 0) which can also be unified to embedding
    to a transformation. The third one will need some more
    work here due to doing wild things in Outliner mode in
    Impress (callbacks & creating Primitives in fixed
    positions for which an embedding translate would be
    wrong).
    
    When being able to strip without position and rotation
    the result will be usable to be buffered, so the goal
    is to re-use that, transformed as needed (translate,
    scale, rotate, ...) as long as the text itself does
    not change.
    
    Change-Id: I52ab548ccbb1b5b3b16c50451a314bc7f3b39d93
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/188918
    Tested-by: Jenkins
    Reviewed-by: Armin Le Grand <[email protected]>

diff --git a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx 
b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
index 95769d43212d..7f826a9b040c 100644
--- a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
@@ -1470,7 +1470,7 @@ void 
VclMetafileProcessor2D::processTextHierarchyBulletPrimitive2D(
 
     // process recursively and add MetaFile comment
     process(rBulletPrimitive);
-    // in Outliner::PaintOrStripBullet(), a MetafileComment for bullets is 
added, too. The
+    // in Outliner::StripBullet(), a MetafileComment for bullets is added, 
too. The
     // "XTEXT_EOC" is used, use here, too.
     mpMetaFile->AddAction(new MetaCommentAction("XTEXT_EOC"_ostr));
 
diff --git a/editeng/inc/outleeng.hxx b/editeng/inc/outleeng.hxx
index b9def51b9ff0..ea0aac27056a 100644
--- a/editeng/inc/outleeng.hxx
+++ b/editeng/inc/outleeng.hxx
@@ -35,7 +35,7 @@ public:
                         OutlinerEditEng( Outliner* pOwner, SfxItemPool* pPool 
);
                         virtual ~OutlinerEditEng() override;
 
-    virtual void        ProcessFirstLineOfParagraph(sal_Int32 nPara, const 
Point& rStartPos, const Point& rOrigin, Degree10 nOrientation, OutputDevice& 
rOutDev, StripPortionsHelper* pStripPortionsHelper) override;
+    virtual void        ProcessFirstLineOfParagraph(sal_Int32 nPara, const 
Point& rStartPos, OutputDevice& rOutDev, StripPortionsHelper& 
rStripPortionsHelper) override;
 
     virtual void        ParagraphInserted( sal_Int32 nNewParagraph ) override;
     virtual void        ParagraphDeleted( sal_Int32 nDeletedParagraph ) 
override;
diff --git a/editeng/source/editeng/editeng.cxx 
b/editeng/source/editeng/editeng.cxx
index b9a23c68f4d2..ac2530ec67aa 100644
--- a/editeng/source/editeng/editeng.cxx
+++ b/editeng/source/editeng/editeng.cxx
@@ -1079,7 +1079,7 @@ void EditEngine::StripPortions(StripPortionsHelper& 
rStripPortionsHelper)
         }
     }
 
-    getImpl().PaintOrStrip(*aTmpDev, aBigRect, Point(), 0_deg10, 
&rStripPortionsHelper);
+    getImpl().StripAllPortions(*aTmpDev, aBigRect, Point(), 
rStripPortionsHelper);
 }
 
 void EditEngine::GetPortions( sal_Int32 nPara, std::vector<sal_Int32>& rList )
@@ -1569,7 +1569,7 @@ EditEngine::CreateTransferable(const ESelection& 
rSelection)
 
 // ======================    Virtual Methods    ========================
 
-void EditEngine::ProcessFirstLineOfParagraph(sal_Int32, const Point&, const 
Point&, Degree10, OutputDevice&, StripPortionsHelper*)
+void EditEngine::ProcessFirstLineOfParagraph(sal_Int32, const Point&, 
OutputDevice&, StripPortionsHelper&)
 {
 }
 
diff --git a/editeng/source/editeng/impedit.hxx 
b/editeng/source/editeng/impedit.hxx
index 8e61f99c8dd6..792bddf36efb 100644
--- a/editeng/source/editeng/impedit.hxx
+++ b/editeng/source/editeng/impedit.hxx
@@ -1003,7 +1003,7 @@ public:
     void                    UpdateViews( EditView* pCurView = nullptr );
     Point CalculateTextPaintStartPosition(ImpEditView& rView) const;
     void                    DrawText_ToEditView( TextHierarchyBreakup& 
rHelper, ImpEditView* pView, const tools::Rectangle& rRect, OutputDevice* 
pTargetDevice );
-    void PaintOrStrip( OutputDevice& rOutDev, tools::Rectangle aClipRect, 
Point aStartPos, Degree10 nOrientation = 0_deg10, StripPortionsHelper* 
pStripPortionsHelper = nullptr);
+    void StripAllPortions( OutputDevice& rOutDev, tools::Rectangle aClipRect, 
Point aStartPos, StripPortionsHelper& rStripPortionsHelper);
 
     bool                MouseButtonUp( const MouseEvent& rMouseEvent, 
EditView* pView );
     bool                MouseButtonDown( const MouseEvent& rMouseEvent, 
EditView* pView );
diff --git a/editeng/source/editeng/impedit3.cxx 
b/editeng/source/editeng/impedit3.cxx
index 7ddae54bd77d..18cb268d07f5 100644
--- a/editeng/source/editeng/impedit3.cxx
+++ b/editeng/source/editeng/impedit3.cxx
@@ -96,6 +96,8 @@
 #include <basegfx/polygon/b2dpolygontools.hxx>
 #include <drawinglayer/primitive2d/transformprimitive2d.hxx>
 #include <basegfx/matrix/b2dhommatrixtools.hxx>
+#include <basegfx/color/bcolormodifier.hxx>
+#include <drawinglayer/primitive2d/modifiedcolorprimitive2d.hxx>
 
 #include <unicode/uchar.h>
 
@@ -106,8 +108,6 @@ using namespace ::com::sun::star::linguistic2;
 
 constexpr OUString CH_HYPH = u"-"_ustr;
 
-constexpr tools::Long WRONG_SHOW_MIN = 5;
-
 #if (OSL_DEBUG_LEVEL > 1) || defined ( DBG_UTIL )
 bool ImpEditEngine::bDebugPaint = false;
 #endif
@@ -160,92 +160,6 @@ AsianCompressionFlags GetCharTypeForCompression( 
sal_Unicode cChar )
     }
 }
 
-static void lcl_DrawRedLines( OutputDevice& rOutDev,
-                              tools::Long nFontHeight,
-                              const Point& rPoint,
-                              size_t nIndex,
-                              size_t nMaxEnd,
-                              KernArraySpan pDXArray,
-                              WrongList const * pWrongs,
-                              Degree10 nOrientation,
-                              const Point& rOrigin,
-                              bool bVertical,
-                              bool bIsRightToLeft )
-{
-    // But only if font is not too small...
-    tools::Long nHeight = rOutDev.LogicToPixel(Size(0, nFontHeight)).Height();
-    if (WRONG_SHOW_MIN >= nHeight)
-        return;
-
-    size_t nEnd, nStart = nIndex;
-    bool bWrong = pWrongs->NextWrong(nStart, nEnd);
-
-    while (bWrong)
-    {
-        if (nStart >= nMaxEnd)
-            break;
-
-        if (nStart < nIndex)  // Corrected
-            nStart = nIndex;
-
-        if (nEnd > nMaxEnd)
-            nEnd = nMaxEnd;
-
-        Point aPoint1(rPoint);
-        if (bVertical)
-        {
-            // VCL doesn't know that the text is vertical, and is manipulating
-            // the positions a little bit in y direction...
-            tools::Long nOnePixel = rOutDev.PixelToLogic(Size(0, 1)).Height();
-            tools::Long nCorrect = 2 * nOnePixel;
-            aPoint1.AdjustY(-nCorrect);
-            aPoint1.AdjustX(-nCorrect);
-        }
-        if (nStart > nIndex)
-        {
-            if (!bVertical)
-            {
-                // since for RTL portions rPoint is on the visual right end of 
the portion
-                // (i.e. at the start of the first RTL char) we need to 
subtract the offset
-                // for RTL portions...
-                aPoint1.AdjustX((bIsRightToLeft ? -1 : 1) * pDXArray[nStart - 
nIndex - 1]);
-            }
-            else
-                aPoint1.AdjustY(pDXArray[nStart - nIndex - 1]);
-        }
-        Point aPoint2(rPoint);
-        assert(nEnd > nIndex && "RedLine: aPnt2?");
-        if (!bVertical)
-        {
-            // since for RTL portions rPoint is on the visual right end of the 
portion
-            // (i.e. at the start of the first RTL char) we need to subtract 
the offset
-            // for RTL portions...
-            aPoint2.AdjustX((bIsRightToLeft ? -1 : 1) * pDXArray[nEnd - nIndex 
- 1]);
-        }
-        else
-        {
-            aPoint2.AdjustY(pDXArray[nEnd - nIndex - 1]);
-        }
-
-        if (nOrientation)
-        {
-            rOrigin.RotateAround(aPoint1, nOrientation);
-            rOrigin.RotateAround(aPoint2, nOrientation);
-        }
-
-        {
-            vcl::ScopedAntialiasing a(rOutDev, true);
-            rOutDev.DrawWaveLine(aPoint1, aPoint2);
-        }
-
-        nStart = nEnd + 1;
-        if (nEnd < nMaxEnd)
-            bWrong = pWrongs->NextWrong(nStart, nEnd);
-        else
-            bWrong = false;
-    }
-}
-
 void ImpEditEngine::UpdateViews( EditView* pCurView )
 {
     if ( !IsUpdateLayout() || IsFormatting() || maInvalidRect.IsEmpty() )
@@ -3361,65 +3275,75 @@ Point ImpEditEngine::MoveToNextLine(
     return rMovePos - aOld;
 }
 
-void ImpEditEngine::DrawText_ToPosition( OutputDevice& rOutDev, const Point& 
rStartPos, Degree10 nOrientation )
+void ImpEditEngine::DrawText_ToPosition(
+    OutputDevice& rOutDev, const Point& rStartPos, Degree10 nOrientation )
 {
-    if( rOutDev.GetConnectMetaFile() )
-        rOutDev.Push();
-
     // Create with 2 points, as with positive points it will end up with
     // LONGMAX as Size, Bottom and Right in the range > LONGMAX.
-    tools::Rectangle aBigRect( -0x3FFFFFFF, -0x3FFFFFFF, 0x3FFFFFFF, 
0x3FFFFFFF );
-    Point aStartPos( rStartPos );
+    const tools::Rectangle aBigRect( -0x3FFFFFFF, -0x3FFFFFFF, 0x3FFFFFFF, 
0x3FFFFFFF );
+
+    // extract Primitives
+    TextHierarchyBreakup aHelper;
+    StripAllPortions(rOutDev, aBigRect, Point(), aHelper);
 
+    if (aHelper.getTextPortionPrimitives().empty())
+        // no Primitives, done
+        return;
+
+    // get content
+    drawinglayer::primitive2d::Primitive2DContainer 
aContent(aHelper.getTextPortionPrimitives());
+
+    // calculate StartPos
+    Point aStartPos( rStartPos );
     if ( IsEffectivelyVertical() )
     {
         aStartPos.AdjustX(GetPaperSize().Width() );
         rStartPos.RotateAround(aStartPos, nOrientation);
     }
 
-    static bool bUsePrimitives(nullptr == 
std::getenv("DISBALE_EDITENGINE_ON_PRIMITIVES"));
+    basegfx::B2DHomMatrix aTransform;
 
-    if (bUsePrimitives)
+    if (0_deg10 != nOrientation)
     {
-        // extract Primitives.
-        // Do not use Orientation, that will be added below as transformation
-        TextHierarchyBreakup aHelper;
-        PaintOrStrip(rOutDev, aBigRect, aStartPos, 0_deg10, &aHelper);
-
-        if (aHelper.getTextPortionPrimitives().empty())
-            // no Primitives, done
-            return;
-
-        // create ViewInformation2D based on target OutputDevice
-        drawinglayer::geometry::ViewInformation2D aViewInformation2D;
-        
aViewInformation2D.setViewTransformation(rOutDev.GetViewTransformation());
-
-        // get content
-        drawinglayer::primitive2d::Primitive2DContainer 
aContent(aHelper.getTextPortionPrimitives());
+        // if we have an Orientation, add rotation. Note that input value is
+        // 10th degree and wrong oriented for a right-hand coordinate system 
(sigh)
+        // add rotation around (0, 0) before translation to StartPos
+        const double fAngle(-toRadians(nOrientation));
+        aTransform = basegfx::utils::createRotateB2DHomMatrix(fAngle);
+    }
 
-        if (0_deg10 != nOrientation)
-        {
-            // if we have an Orientation, add rotation. Note that input value 
is
-            // 10th degree and wrong oriented for a right-hand coordinate 
system (sigh)
-            const double fAngle(-toRadians(nOrientation));
-            aContent = drawinglayer::primitive2d::Primitive2DContainer{
-                new drawinglayer::primitive2d::TransformPrimitive2D(
-                    basegfx::utils::createRotateAroundPoint(aStartPos.X(), 
aStartPos.Y(), fAngle),
-                    std::move(aContent))};
-        }
+    if (0 != aStartPos.X() || 0 != aStartPos.Y())
+    {
+        // translate by aStartPos
+        aTransform *= 
basegfx::utils::createTranslateB2DHomMatrix(aStartPos.X(), aStartPos.Y());
+    }
 
-        // create PrimitiveProcessor and render to target
-        std::unique_ptr<drawinglayer::processor2d::BaseProcessor2D> xProcessor(
-            
drawinglayer::processor2d::createProcessor2DFromOutputDevice(rOutDev, 
aViewInformation2D));
-        xProcessor->process(aContent);
+    if (!aTransform.isIdentity())
+    {
+        // embed to transformation
+        aContent = drawinglayer::primitive2d::Primitive2DContainer{
+            new drawinglayer::primitive2d::TransformPrimitive2D(
+                aTransform,
+                std::move(aContent))};
     }
-    else
+
+    static bool bBlendForTest(false);
+    if(bBlendForTest)
     {
-        PaintOrStrip(rOutDev, aBigRect, aStartPos, nOrientation);
+        aContent = drawinglayer::primitive2d::Primitive2DContainer{
+            new drawinglayer::primitive2d::ModifiedColorPrimitive2D(
+                std::move(aContent),
+                
std::make_shared<basegfx::BColorModifier_interpolate>(COL_LIGHTRED.getBColor(), 
0.5)) };
     }
 
-    if (rOutDev.GetConnectMetaFile())
-        rOutDev.Pop();
+    // create ViewInformation2D based on target OutputDevice
+    drawinglayer::geometry::ViewInformation2D aViewInformation2D;
+    aViewInformation2D.setViewTransformation(rOutDev.GetViewTransformation());
+
+    // create PrimitiveProcessor and render to target
+    std::unique_ptr<drawinglayer::processor2d::BaseProcessor2D> xProcessor(
+        drawinglayer::processor2d::createProcessor2DFromOutputDevice(rOutDev, 
aViewInformation2D));
+    xProcessor->process(aContent);
 }
 
 void ImpEditEngine::DrawText_ToRectangle( OutputDevice& rOutDev, const 
tools::Rectangle& rOutRect, const Point& rStartDocPos, bool bHardClip )
@@ -3429,11 +3353,43 @@ void ImpEditEngine::DrawText_ToRectangle( OutputDevice& 
rOutDev, const tools::Re
         DumpData(false);
 #endif
 
-    // Align to the pixel boundary, so that it becomes exactly the same
-    // as Paint ()
-    tools::Rectangle aOutRect( rOutDev.LogicToPixel( rOutRect ) );
-    aOutRect = rOutDev.PixelToLogic( aOutRect );
+    // get aOutRect and align to the pixel boundary, so that it
+    // becomes exactly the same as Paint()
+    const tools::Rectangle 
aOutRect(rOutDev.PixelToLogic(rOutDev.LogicToPixel(rOutRect)));
+    const tools::Rectangle aClipRect(0, 0, aOutRect.GetWidth(), 
aOutRect.GetHeight());
+
+    // extract Primitives
+    TextHierarchyBreakup aHelper;
+    StripAllPortions(rOutDev, aClipRect, Point(), aHelper);
+
+    if (aHelper.getTextPortionPrimitives().empty())
+        // no Primitives, done
+        return;
+
+    // create ViewInformation2D based on target OutputDevice
+    drawinglayer::geometry::ViewInformation2D aViewInformation2D;
+    aViewInformation2D.setViewTransformation(rOutDev.GetViewTransformation());
+
+    // get content and it's range, plus ClipRange
+    drawinglayer::primitive2d::Primitive2DContainer 
aContent(aHelper.getTextPortionPrimitives());
+    const basegfx::B2DRange 
aContentRange(aContent.getB2DRange(aViewInformation2D));
+    const basegfx::B2DRange 
aClipRange(vcl::unotools::b2DRectangleFromRectangle(aClipRect));
+
+    if (!aContentRange.overlaps(aClipRange))
+        // no overlap, nothing visible
+        return;
+
+    if (bHardClip && !aClipRange.isInside(aContentRange))
+    {
+        // not completely inside aClipRange and clipping requested
+        // Embed to MaskPrimitive2D
+        aContent = drawinglayer::primitive2d::Primitive2DContainer{
+            new drawinglayer::primitive2d::MaskPrimitive2D(
+                
basegfx::B2DPolyPolygon(basegfx::utils::createPolygonFromRect(aClipRange)),
+                std::move(aContent))};
+    }
 
+    // calculate StartPos
     Point aStartPos;
     if ( !IsEffectivelyVertical() )
     {
@@ -3446,127 +3402,51 @@ void ImpEditEngine::DrawText_ToRectangle( 
OutputDevice& rOutDev, const tools::Re
         aStartPos.setY( aOutRect.Top() - rStartDocPos.X() );
     }
 
-    static bool bUsePrimitives(nullptr == 
std::getenv("DISBALE_EDITENGINE_ON_PRIMITIVES"));
-
-    if (bUsePrimitives)
+    if (0 != aStartPos.X() || 0 != aStartPos.Y())
     {
-        // extract Primitives
-        TextHierarchyBreakup aHelper;
-        PaintOrStrip(rOutDev, aOutRect, aStartPos, 0_deg10, &aHelper);
-
-        if (aHelper.getTextPortionPrimitives().empty())
-            // no Primitives, done
-            return;
-
-        // create ViewInformation2D based on target OutputDevice
-        drawinglayer::geometry::ViewInformation2D aViewInformation2D;
-        
aViewInformation2D.setViewTransformation(rOutDev.GetViewTransformation());
-        const basegfx::B2DRange 
aClipRange(vcl::unotools::b2DRectangleFromRectangle(aOutRect));
-        aViewInformation2D.setViewport(aClipRange);
-
-        // get content and it's range
-        drawinglayer::primitive2d::Primitive2DContainer 
aContent(aHelper.getTextPortionPrimitives());
-        const basegfx::B2DRange 
aContentRange(aContent.getB2DRange(aViewInformation2D));
-
-        if (!aContentRange.overlaps(aClipRange))
-            // no overlap, nothing visible
-            return;
-
-        if (bHardClip && !aClipRange.isInside(aContentRange))
-        {
-            // not completely inside aClipRange and clipping requested
-            // Embed to MaskPrimitive2D
-            aContent = drawinglayer::primitive2d::Primitive2DContainer{
-                new drawinglayer::primitive2d::MaskPrimitive2D(
-                    
basegfx::B2DPolyPolygon(basegfx::utils::createPolygonFromRect(aClipRange)),
-                    std::move(aContent))};
-        }
-
-        // create PrimitiveProcessor and render to target
-        std::unique_ptr<drawinglayer::processor2d::BaseProcessor2D> xProcessor(
-            
drawinglayer::processor2d::createProcessor2DFromOutputDevice(rOutDev, 
aViewInformation2D));
-        xProcessor->process(aContent);
+        // embed to StartPos translation
+        aContent = drawinglayer::primitive2d::Primitive2DContainer{
+            new drawinglayer::primitive2d::TransformPrimitive2D(
+                basegfx::utils::createTranslateB2DHomMatrix(aStartPos.X(), 
aStartPos.Y()),
+                std::move(aContent))};
     }
-    else
-    {
-        bool bClipRegion = rOutDev.IsClipRegion();
-        bool bMetafile = rOutDev.GetConnectMetaFile();
-        vcl::Region aOldRegion = rOutDev.GetClipRegion();
-
-        // If one existed => intersection!
-        // Use Push/pop for creating the Meta file
-        if ( bMetafile )
-            rOutDev.Push();
 
-        // Always use the Intersect method, it is a must for Metafile!
-        if ( bHardClip )
-        {
-            // Clip only if necessary...
-            if (!IsFormatted())
-                FormatDoc();
-            tools::Long nTextWidth = !IsEffectivelyVertical() ? 
CalcTextWidth(true) : GetTextHeight();
-            if ( rStartDocPos.X() || rStartDocPos.Y() ||
-                ( rOutRect.GetHeight() < 
static_cast<tools::Long>(GetTextHeight()) ) ||
-                ( rOutRect.GetWidth() < nTextWidth ) )
-            {
-                // Some printer drivers cause problems if characters graze the
-                // ClipRegion, therefore rather add a pixel more ...
-                tools::Rectangle aClipRect( aOutRect );
-                if ( rOutDev.GetOutDevType() == OUTDEV_PRINTER )
-                {
-                    Size aPixSz( 1, 0 );
-                    aPixSz = rOutDev.PixelToLogic( aPixSz );
-                    aClipRect.AdjustRight(aPixSz.Width() );
-                    aClipRect.AdjustBottom(aPixSz.Width() );
-                }
-                rOutDev.IntersectClipRegion( aClipRect );
-            }
-        }
-
-        PaintOrStrip(rOutDev, aOutRect, aStartPos);
-
-        if ( bMetafile )
-            rOutDev.Pop();
-        else if ( bClipRegion )
-            rOutDev.SetClipRegion( aOldRegion );
-        else
-            rOutDev.SetClipRegion();
+    static bool bBlendForTest(false);
+    if(bBlendForTest)
+    {
+        aContent = drawinglayer::primitive2d::Primitive2DContainer{
+            new drawinglayer::primitive2d::ModifiedColorPrimitive2D(
+                std::move(aContent),
+                
std::make_shared<basegfx::BColorModifier_interpolate>(COL_LIGHTRED.getBColor(), 
0.5)) };
     }
+
+    // create PrimitiveProcessor and render to target
+    std::unique_ptr<drawinglayer::processor2d::BaseProcessor2D> xProcessor(
+        drawinglayer::processor2d::createProcessor2DFromOutputDevice(rOutDev, 
aViewInformation2D));
+    xProcessor->process(aContent);
 }
 
 // TODO: use IterateLineAreas in ImpEditEngine::Paint, to avoid algorithm 
duplication
-void ImpEditEngine::PaintOrStrip( OutputDevice& rOutDev, tools::Rectangle 
aClipRect, Point aStartPos, Degree10 nOrientation, StripPortionsHelper* 
pStripPortionsHelper)
+void ImpEditEngine::StripAllPortions( OutputDevice& rOutDev, tools::Rectangle 
aClipRect, Point aStartPos, StripPortionsHelper& rStripPortionsHelper)
 {
-    if ( !IsUpdateLayout() && !pStripPortionsHelper )
+    if ( !IsUpdateLayout() )
         return;
 
     if ( !IsFormatted() )
         FormatDoc();
 
-    tools::Long nFirstVisXPos = - rOutDev.GetMapMode().GetOrigin().X();
-    tools::Long nFirstVisYPos = - rOutDev.GetMapMode().GetOrigin().Y();
-
     DBG_ASSERT( GetParaPortions().Count(), "No ParaPortion?!" );
     SvxFont aTmpFont = 
GetParaPortions().getRef(0).GetNode()->GetCharAttribs().GetDefFont();
-    vcl::PDFExtOutDevData* const pPDFExtOutDevData = dynamic_cast< 
vcl::PDFExtOutDevData* >( rOutDev.GetExtOutDevData() );
 
     // In the case of rotated text is aStartPos considered TopLeft because
     // other information is missing, and since the whole object is shown anyway
     // un-scrolled.
     // The rectangle is infinite.
     const Point aOrigin( aStartPos );
-
-    // #110496# Added some more optional metafile comments. This
-    // change: factored out some duplicated code.
-    GDIMetaFile* pMtf = rOutDev.GetConnectMetaFile();
-    const bool bMetafileValid( pMtf != nullptr );
-
     const tools::Long nVertLineSpacing = CalcVertLineSpacing(aStartPos);
-
     sal_Int16 nColumn = 0;
 
     // Over all the paragraphs...
-
     for (sal_Int32 nParaPortion = 0; nParaPortion < GetParaPortions().Count(); 
nParaPortion++)
     {
         ParaPortion const& rParaPortion = 
GetParaPortions().getRef(nParaPortion);
@@ -3575,9 +3455,6 @@ void ImpEditEngine::PaintOrStrip( OutputDevice& rOutDev, 
tools::Rectangle aClipR
         if (rParaPortion.IsVisible() && rParaPortion.IsInvalid())
             return;
 
-        if ( pPDFExtOutDevData )
-            
pPDFExtOutDevData->WrapBeginStructureElement(vcl::pdf::StructElement::Paragraph);
-
         const tools::Long nParaHeight = rParaPortion.GetHeight();
         if (rParaPortion.IsVisible() && (
                 ( !IsEffectivelyVertical() && ( ( aStartPos.Y() + nParaHeight 
) > aClipRect.Top() ) ) ||
@@ -3621,13 +3498,13 @@ void ImpEditEngine::PaintOrStrip( OutputDevice& 
rOutDev, tools::Rectangle aClipR
 
                     // Why not just also call when stripping portions? This 
will give the correct values
                     // and needs no position corrections in 
OutlinerEditEng::DrawingText which tries to call
-                    // PaintOrStripBullet correctly; exactly what 
GetEditEnginePtr()->ProcessFirstLineOfParagraph
+                    // StripBullet correctly; exactly what 
GetEditEnginePtr()->ProcessFirstLineOfParagraph
                     // does, too. No change for not-layouting (painting).
                     if(0 == nLine) // && !bStripOnly)
                     {
                         Point aLineStart(aStartPos);
                         adjustYDirectionAware(aLineStart, -nLineHeight);
-                        
GetEditEnginePtr()->ProcessFirstLineOfParagraph(nParaPortion, aLineStart, 
aOrigin, nOrientation, rOutDev, pStripPortionsHelper);//, rDrawPortion, 
rDrawBullet);
+                        
GetEditEnginePtr()->ProcessFirstLineOfParagraph(nParaPortion, aLineStart, 
/*aOrigin, nOrientation,*/ rOutDev, rStripPortionsHelper);
 
                         // Remember whether a bullet was painted.
                         const SfxBoolItem& rBulletState = 
mpEditEngine->GetParaAttrib(nParaPortion, EE_PARA_BULLETSTATE);
@@ -3670,29 +3547,26 @@ void ImpEditEngine::PaintOrStrip( OutputDevice& 
rOutDev, tools::Rectangle aClipR
                                 SeekCursor(rParaPortion.GetNode(), nIndex, 
aTmpFont, &rOutDev);
 
                                 const auto* pRuby = static_cast<const 
SvxRubyItem*>(pRubyAttr->GetItem());
-                                if (pStripPortionsHelper)
-                                {
-                                    const bool bEndOfLine(nPortion == 
pLine->GetEndPortion());
-                                    const bool bEndOfParagraph(bEndOfLine && 
nLine + 1 == nLines);
-
-                                    const Color 
aOverlineColor(rOutDev.GetOverlineColor());
-                                    const Color 
aTextLineColor(rOutDev.GetTextLineColor());
-
-                                    Point aRubyPos = aTmpPos;
-                                    aRubyPos.AdjustX(pRubyInfo->nXOffset);
-                                    aRubyPos.AdjustY(-pRubyInfo->nYOffset);
-
-                                    auto nPrevSz = aTmpFont.GetFontSize();
-                                    aTmpFont.SetFontSize(nPrevSz / 2);
-
-                                    const DrawPortionInfo aInfo(
-                                        aRubyPos, pRuby->GetText(), 0, 
pRuby->GetText().getLength(),
-                                        {}, {}, aTmpFont, nParaPortion, 0, 
nullptr, nullptr,
-                                        bEndOfLine, bEndOfParagraph, false, 
nullptr, aOverlineColor,
-                                        aTextLineColor);
-                                    
pStripPortionsHelper->processDrawPortionInfo(aInfo);
-                                    aTmpFont.SetFontSize(nPrevSz);
-                                }
+                                const bool bEndOfLine(nPortion == 
pLine->GetEndPortion());
+                                const bool bEndOfParagraph(bEndOfLine && nLine 
+ 1 == nLines);
+
+                                const Color 
aOverlineColor(rOutDev.GetOverlineColor());
+                                const Color 
aTextLineColor(rOutDev.GetTextLineColor());
+
+                                Point aRubyPos = aTmpPos;
+                                aRubyPos.AdjustX(pRubyInfo->nXOffset);
+                                aRubyPos.AdjustY(-pRubyInfo->nYOffset);
+
+                                auto nPrevSz = aTmpFont.GetFontSize();
+                                aTmpFont.SetFontSize(nPrevSz / 2);
+
+                                const DrawPortionInfo aInfo(
+                                    aRubyPos, pRuby->GetText(), 0, 
pRuby->GetText().getLength(),
+                                    {}, {}, aTmpFont, nParaPortion, 0, 
nullptr, nullptr,
+                                    bEndOfLine, bEndOfParagraph, false, 
nullptr, aOverlineColor,
+                                    aTextLineColor);
+                                
rStripPortionsHelper.processDrawPortionInfo(aInfo);
+                                aTmpFont.SetFontSize(nPrevSz);
                             }
                         }
 
@@ -3704,8 +3578,6 @@ void ImpEditEngine::PaintOrStrip( OutputDevice& rOutDev, 
tools::Rectangle aClipR
                             {
                                 SeekCursor(rParaPortion.GetNode(), nIndex + 1, 
aTmpFont, &rOutDev);
 
-                                bool bDrawFrame = false;
-
                                 if ( ( rTextPortion.GetKind() == 
PortionKind::FIELD ) && !aTmpFont.IsTransparent() &&
                                      ( GetBackgroundColor() != COL_AUTO ) && 
GetBackgroundColor().IsDark() &&
                                      ( IsAutoColorEnabled() && ( 
rOutDev.GetOutDevType() != OUTDEV_PRINTER ) ) )
@@ -3713,7 +3585,6 @@ void ImpEditEngine::PaintOrStrip( OutputDevice& rOutDev, 
tools::Rectangle aClipR
                                     aTmpFont.SetTransparent( true );
                                     rOutDev.SetFillColor();
                                     rOutDev.SetLineColor( GetAutoColor() );
-                                    bDrawFrame = true;
                                 }
 
 #if OSL_DEBUG_LEVEL > 2
@@ -3850,7 +3721,7 @@ void ImpEditEngine::PaintOrStrip( OutputDevice& rOutDev, 
tools::Rectangle aClipR
                                     //It is not perfect, it still use 
lineBreaksList, so it won’t seek
                                     //word ends to wrap text there, but it 
would be difficult to change
                                     //this due to needed adaptations in 
EditEngine
-                                    if (pStripPortionsHelper && 
!bParsingFields && pExtraInfo && !pExtraInfo->lineBreaksList.empty())
+                                    if (!bParsingFields && pExtraInfo && 
!pExtraInfo->lineBreaksList.empty())
                                     {
                                         bParsingFields = true;
                                         itSubLines = 
pExtraInfo->lineBreaksList.begin();
@@ -3916,19 +3787,6 @@ void ImpEditEngine::PaintOrStrip( OutputDevice& rOutDev, 
tools::Rectangle aClipR
                                     aTmpFont.QuickGetTextSize( GetRefDevice(), 
aText, nTextStart, nTextLen,
                                         &aTmpDXArray );
                                     pDXArray = KernArraySpan(aTmpDXArray);
-
-                                    // add a meta file comment if we record to 
a metafile
-                                    if( !pStripPortionsHelper && 
bMetafileValid )
-                                    {
-                                        const SvxFieldItem* pFieldItem = 
dynamic_cast<const SvxFieldItem*>(pAttr->GetItem());
-                                        if( pFieldItem )
-                                        {
-                                            const SvxFieldData* pFieldData = 
pFieldItem->GetField();
-                                            if( pFieldData )
-                                                pMtf->AddAction( 
pFieldData->createBeginComment() );
-                                        }
-                                    }
-
                                 }
                                 else if ( rTextPortion.GetKind() == 
PortionKind::HYPHENATOR )
                                 {
@@ -3945,8 +3803,6 @@ void ImpEditEngine::PaintOrStrip( OutputDevice& rOutDev, 
tools::Rectangle aClipR
                                     pDXArray = aTmpDXArray;
                                 }
 
-                                tools::Long nTxtWidth = 
rTextPortion.GetSize().Width();
-
                                 Point aOutPos( aTmpPos );
                                 Point aRedLineTmpPos = aTmpPos;
                                 // In RTL portions spell markup pos should be 
at the start of the
@@ -3954,298 +3810,104 @@ void ImpEditEngine::PaintOrStrip( OutputDevice& 
rOutDev, tools::Rectangle aClipR
                                 if (rTextPortion.IsRightToLeft())
                                     
aRedLineTmpPos.AdjustX(rTextPortion.GetSize().Width() );
 
-                                if (pStripPortionsHelper)
+                                EEngineData::WrongSpellVector 
aWrongSpellVector;
+
+                                if(GetStatus().DoOnlineSpelling() && 
rTextPortion.GetLen())
                                 {
-                                    EEngineData::WrongSpellVector 
aWrongSpellVector;
+                                    WrongList* pWrongs = 
rParaPortion.GetNode()->GetWrongList();
 
-                                    if(GetStatus().DoOnlineSpelling() && 
rTextPortion.GetLen())
+                                    if(pWrongs && !pWrongs->empty())
                                     {
-                                        WrongList* pWrongs = 
rParaPortion.GetNode()->GetWrongList();
+                                        size_t nStart = nIndex, nEnd = 0;
+                                        bool bWrong = 
pWrongs->NextWrong(nStart, nEnd);
+                                        const size_t nMaxEnd(nIndex + 
rTextPortion.GetLen());
 
-                                        if(pWrongs && !pWrongs->empty())
+                                        while(bWrong)
                                         {
-                                            size_t nStart = nIndex, nEnd = 0;
-                                            bool bWrong = 
pWrongs->NextWrong(nStart, nEnd);
-                                            const size_t nMaxEnd(nIndex + 
rTextPortion.GetLen());
-
-                                            while(bWrong)
+                                            if(nStart >= nMaxEnd)
                                             {
-                                                if(nStart >= nMaxEnd)
-                                                {
-                                                    break;
-                                                }
-
-                                                if(nStart < 
o3tl::make_unsigned(nIndex))
-                                                {
-                                                    nStart = nIndex;
-                                                }
-
-                                                if(nEnd > nMaxEnd)
-                                                {
-                                                    nEnd = nMaxEnd;
-                                                }
-
-                                                // add to vector
-                                                
aWrongSpellVector.emplace_back(nStart, nEnd);
-
-                                                // goto next index
-                                                nStart = nEnd + 1;
-
-                                                if(nEnd < nMaxEnd)
-                                                {
-                                                    bWrong = 
pWrongs->NextWrong(nStart, nEnd);
-                                                }
-                                                else
-                                                {
-                                                    bWrong = false;
-                                                }
+                                                break;
                                             }
-                                        }
-                                    }
-
-                                    const SvxFieldData* pFieldData = nullptr;
-
-                                    if(PortionKind::FIELD == 
rTextPortion.GetKind())
-                                    {
-                                        const EditCharAttrib* pAttr = 
rParaPortion.GetNode()->GetCharAttribs().FindFeature(nIndex);
-                                        const SvxFieldItem* pFieldItem = 
dynamic_cast<const SvxFieldItem*>(pAttr->GetItem());
-
-                                        if(pFieldItem)
-                                        {
-                                            pFieldData = 
pFieldItem->GetField();
-                                        }
-                                    }
-
-                                    // support for EOC, EOW, EOS TEXT 
comments. To support that,
-                                    // the locale is needed. With the locale 
and a XBreakIterator it is
-                                    // possible to re-create the text marking 
info on primitive level
-                                    const lang::Locale 
aLocale(GetLocale(EditPaM(rParaPortion.GetNode(), nIndex + 1)));
-
-                                    // create EOL and EOP bools
-                                    const bool bEndOfLine(nPortion == 
pLine->GetEndPortion());
-                                    const bool bEndOfParagraph(bEndOfLine && 
nLine + 1 == nLines);
-
-                                    // get Overline color (from ((const 
SvxOverlineItem*)GetItem())->GetColor() in
-                                    // consequence, but also already set at 
rOutDev)
-                                    const Color 
aOverlineColor(rOutDev.GetOverlineColor());
-
-                                    // get TextLine color (from ((const 
SvxUnderlineItem*)GetItem())->GetColor() in
-                                    // consequence, but also already set at 
rOutDev)
-                                    const Color 
aTextLineColor(rOutDev.GetTextLineColor());
-
-                                    // Unicode code points conversion 
according to ctl text numeral setting
-                                    aText = convertDigits(aText, nTextStart, 
nTextLen,
-                                        
ImplCalcDigitLang(aTmpFont.GetLanguage()));
-
-                                    // StripPortions() data callback
-                                    const DrawPortionInfo aInfo(
-                                        aOutPos, aText, nTextStart, nTextLen, 
pDXArray, pKashidaArray,
-                                        aTmpFont, nParaPortion, 
rTextPortion.GetRightToLeftLevel(),
-                                        !aWrongSpellVector.empty() ? 
&aWrongSpellVector : nullptr,
-                                        pFieldData,
-                                        bEndOfLine, bEndOfParagraph, false, // 
support for EOL/EOP TEXT comments
-                                        &aLocale,
-                                        aOverlineColor,
-                                        aTextLineColor);
-                                    
pStripPortionsHelper->processDrawPortionInfo(aInfo);
-
-                                    // #108052# remember that EOP is written 
already for this ParaPortion
-                                    if(bEndOfParagraph)
-                                    {
-                                        bEndOfParagraphWritten = true;
-                                    }
-                                }
-                                else
-                                {
-                                    short nEsc = aTmpFont.GetEscapement();
-                                    if ( nOrientation )
-                                    {
-                                        // In case of high/low do it yourself:
-                                        if ( aTmpFont.GetEscapement() )
-                                        {
-                                            tools::Long nDiff = 
aTmpFont.GetFontSize().Height() * aTmpFont.GetEscapement() / 100L;
-                                            adjustYDirectionAware(aOutPos, 
-nDiff);
-                                            aRedLineTmpPos = aOutPos;
-                                            aTmpFont.SetEscapement( 0 );
-                                        }
 
-                                        aOrigin.RotateAround(aOutPos, 
nOrientation);
-                                        aTmpFont.SetOrientation( 
aTmpFont.GetOrientation()+nOrientation );
-                                        aTmpFont.SetPhysFont(rOutDev);
-
-                                    }
-
-                                    // Take only what begins in the visible 
range:
-                                    // Important, because of a bug in some 
graphic cards
-                                    // when transparent font, output when 
negative
-                                    if ( nOrientation || ( 
!IsEffectivelyVertical() && ( ( aTmpPos.X() + nTxtWidth ) >= nFirstVisXPos ) )
-                                            || ( IsEffectivelyVertical() && ( 
( aTmpPos.Y() + nTxtWidth ) >= nFirstVisYPos ) ) )
-                                    {
-                                        if ( nEsc && ( aTmpFont.GetUnderline() 
!= LINESTYLE_NONE ) )
-                                        {
-                                            // Paint the high/low without 
underline,
-                                            // Display the Underline on the
-                                            // base line of the original font 
height...
-                                            // But only if there was something 
underlined before!
-                                            bool bSpecialUnderline = false;
-                                            EditCharAttrib* pPrev = 
rParaPortion.GetNode()->GetCharAttribs().FindAttrib( EE_CHAR_ESCAPEMENT, nIndex 
);
-                                            if ( pPrev )
+                                            if(nStart < 
o3tl::make_unsigned(nIndex))
                                             {
-                                                SvxFont aDummy;
-                                                // Underscore in front?
-                                                if ( pPrev->GetStart() )
-                                                {
-                                                    SeekCursor( 
rParaPortion.GetNode(), pPrev->GetStart(), aDummy );
-                                                    if ( aDummy.GetUnderline() 
!= LINESTYLE_NONE )
-                                                        bSpecialUnderline = 
true;
-                                                }
-                                                if ( !bSpecialUnderline && ( 
pPrev->GetEnd() < rParaPortion.GetNode()->Len() ) )
-                                                {
-                                                    SeekCursor( 
rParaPortion.GetNode(), pPrev->GetEnd()+1, aDummy );
-                                                    if ( aDummy.GetUnderline() 
!= LINESTYLE_NONE )
-                                                        bSpecialUnderline = 
true;
-                                                }
+                                                nStart = nIndex;
                                             }
-                                            if ( bSpecialUnderline )
-                                            {
-                                                Size aSz = 
aTmpFont.GetPhysTxtSize( &rOutDev, aText, nTextStart, nTextLen );
-                                                sal_uInt8 nProp = 
aTmpFont.GetPropr();
-                                                aTmpFont.SetEscapement( 0 );
-                                                aTmpFont.SetPropr( 100 );
-                                                aTmpFont.SetPhysFont(rOutDev);
-                                                OUStringBuffer 
aBlanks(nTextLen);
-                                                
comphelper::string::padToLength( aBlanks, nTextLen, ' ' );
-                                                Point aUnderlinePos( aOutPos );
-                                                if ( nOrientation )
-                                                {
-                                                    aUnderlinePos = aTmpPos;
-                                                    
aOrigin.RotateAround(aUnderlinePos, nOrientation);
-                                                }
-                                                rOutDev.DrawStretchText( 
aUnderlinePos, aSz.Width(), aBlanks.makeStringAndClear(), 0, nTextLen );
 
-                                                aTmpFont.SetUnderline( 
LINESTYLE_NONE );
-                                                if ( !nOrientation )
-                                                    aTmpFont.SetEscapement( 
nEsc );
-                                                aTmpFont.SetPropr( nProp );
-                                                aTmpFont.SetPhysFont(rOutDev);
-                                            }
-                                        }
-                                        Point aRealOutPos( aOutPos );
-                                        if ( ( rTextPortion.GetKind() == 
PortionKind::TEXT )
-                                               && rTextPortion.GetExtraInfos() 
&& rTextPortion.GetExtraInfos()->bCompressed
-                                               && 
rTextPortion.GetExtraInfos()->bFirstCharIsRightPunctuation )
-                                        {
-                                            
aRealOutPos.AdjustX(rTextPortion.GetExtraInfos()->nPortionOffsetX );
-                                        }
-
-                                        // RTL portions with (#i37132#)
-                                        // compressed blank should not paint 
this blank:
-                                        if ( rTextPortion.IsRightToLeft() && 
nTextLen >= 2 &&
-                                             pDXArray[ nTextLen - 1 ] ==
-                                             pDXArray[ nTextLen - 2 ] &&
-                                             ' ' == aText[nTextStart + 
nTextLen - 1] )
-                                            --nTextLen;
-
-                                        // PDF export:
-                                        const SvxFieldData* pFieldData = 
nullptr;
-                                        if (pPDFExtOutDevData)
-                                        {
-                                            if (rTextPortion.GetKind() == 
PortionKind::FIELD)
+                                            if(nEnd > nMaxEnd)
                                             {
-                                                const EditCharAttrib* pAttr = 
rParaPortion.GetNode()->GetCharAttribs().FindFeature(nIndex);
-                                                const SvxFieldItem* pFieldItem 
= dynamic_cast<const SvxFieldItem*>(pAttr->GetItem());
-                                                if (pFieldItem)
-                                                {
-                                                    pFieldData = 
pFieldItem->GetField();
-                                                    auto pUrlField = 
dynamic_cast<const SvxURLField*>(pFieldData);
-                                                    if (pUrlField)
-                                                        if 
(pPDFExtOutDevData->GetIsExportTaggedPDF())
-                                                            
pPDFExtOutDevData->WrapBeginStructureElement(vcl::pdf::StructElement::Link, 
u"Link"_ustr);
-                                                }
+                                                nEnd = nMaxEnd;
                                             }
-                                        }
 
-                                        // output directly
-                                        aTmpFont.QuickDrawText( &rOutDev, 
aRealOutPos, aText, nTextStart, nTextLen, pDXArray, pKashidaArray );
+                                            // add to vector
+                                            
aWrongSpellVector.emplace_back(nStart, nEnd);
 
-                                        if ( bDrawFrame )
-                                        {
-                                            Point aTopLeft( aTmpPos );
-                                            aTopLeft.AdjustY( 
-(pLine->GetMaxAscent()) );
-                                            if ( nOrientation )
-                                                aOrigin.RotateAround(aTopLeft, 
nOrientation);
-                                            tools::Rectangle aRect( aTopLeft, 
rTextPortion.GetSize() );
-                                            rOutDev.DrawRect( aRect );
-                                        }
+                                            // goto next index
+                                            nStart = nEnd + 1;
 
-                                        // PDF export:
-                                        if (pPDFExtOutDevData)
-                                        {
-                                            if (auto pUrlField = 
dynamic_cast<const SvxURLField*>(pFieldData))
+                                            if(nEnd < nMaxEnd)
                                             {
-                                                Point aTopLeft(aTmpPos);
-                                                
aTopLeft.AdjustY(-(pLine->GetMaxAscent()));
-
-                                                tools::Rectangle 
aRect(aTopLeft, rTextPortion.GetSize());
-                                                vcl::PDFExtOutDevBookmarkEntry 
aBookmark;
-                                                aBookmark.nLinkId = 
pPDFExtOutDevData->CreateLink(aRect, pUrlField->GetName());
-                                                aBookmark.aBookmark = 
pUrlField->GetURL();
-                                                std::vector< 
vcl::PDFExtOutDevBookmarkEntry >& rBookmarks = 
pPDFExtOutDevData->GetBookmarks();
-                                                
rBookmarks.push_back(aBookmark);
-
-                                                if 
(pPDFExtOutDevData->GetIsExportTaggedPDF())
-                                                {
-                                                    
pPDFExtOutDevData->SetStructureAttributeNumerical(vcl::PDFWriter::LinkAnnotation,
 aBookmark.nLinkId);
-                                                    
pPDFExtOutDevData->EndStructureElement();
-                                                }
+                                                bWrong = 
pWrongs->NextWrong(nStart, nEnd);
                                             }
-                                        }
-                                    }
-
-                                    const WrongList* const pWrongList = 
rParaPortion.GetNode()->GetWrongList();
-                                    if ( GetStatus().DoOnlineSpelling() && 
pWrongList && !pWrongList->empty() && rTextPortion.GetLen() )
-                                    {
-                                        {//#105750# adjust LinePos for 
superscript or subscript text
-                                            short _nEsc = 
aTmpFont.GetEscapement();
-                                            if( _nEsc )
+                                            else
                                             {
-                                                tools::Long nShift = (_nEsc * 
aTmpFont.GetFontSize().Height()) / 100L;
-                                                
adjustYDirectionAware(aRedLineTmpPos, -nShift);
+                                                bWrong = false;
                                             }
                                         }
-                                        
rOutDev.Push(vcl::PushFlags::LINECOLOR);
-                                        rOutDev.SetLineColor( 
GetColorConfig().GetColorValue( svtools::SPELL ).nColor );
-                                        lcl_DrawRedLines(rOutDev, 
aTmpFont.GetFontSize().Height(), aRedLineTmpPos,
-                                                         
static_cast<size_t>(nIndex), static_cast<size_t>(nIndex) + 
rTextPortion.GetLen(),
-                                                         pDXArray, 
rParaPortion.GetNode()->GetWrongList(), nOrientation,
-                                                         aOrigin, 
IsEffectivelyVertical(), rTextPortion.IsRightToLeft());
-                                        rOutDev.Pop();
                                     }
                                 }
 
-                                rOutDev.Pop();
+                                const SvxFieldData* pFieldData = nullptr;
 
-                                if ( rTextPortion.GetKind() == 
PortionKind::FIELD )
+                                if(PortionKind::FIELD == 
rTextPortion.GetKind())
                                 {
-                                    // add a meta file comment if we record to 
a metafile
-                                    if( !pStripPortionsHelper && 
bMetafileValid )
-                                    {
-                                        const EditCharAttrib* pAttr = 
rParaPortion.GetNode()->GetCharAttribs().FindFeature(nIndex);
-                                        assert( pAttr && "Field not found" );
-
-                                        const SvxFieldItem* pFieldItem = 
dynamic_cast<const SvxFieldItem*>(pAttr->GetItem());
-                                        DBG_ASSERT( pFieldItem !=  nullptr, 
"Wrong type of field!" );
+                                    const EditCharAttrib* pAttr = 
rParaPortion.GetNode()->GetCharAttribs().FindFeature(nIndex);
+                                    const SvxFieldItem* pFieldItem = 
dynamic_cast<const SvxFieldItem*>(pAttr->GetItem());
 
-                                        if( pFieldItem )
-                                        {
-                                            const SvxFieldData* pFieldData = 
pFieldItem->GetField();
-                                            if( pFieldData )
-                                                pMtf->AddAction( 
SvxFieldData::createEndComment() );
-                                        }
+                                    if(pFieldItem)
+                                    {
+                                        pFieldData = pFieldItem->GetField();
                                     }
-
                                 }
 
+                                // support for EOC, EOW, EOS TEXT comments. To 
support that,
+                                // the locale is needed. With the locale and a 
XBreakIterator it is
+                                // possible to re-create the text marking info 
on primitive level
+                                const lang::Locale 
aLocale(GetLocale(EditPaM(rParaPortion.GetNode(), nIndex + 1)));
+
+                                // create EOL and EOP bools
+                                const bool bEndOfLine(nPortion == 
pLine->GetEndPortion());
+                                const bool bEndOfParagraph(bEndOfLine && nLine 
+ 1 == nLines);
+
+                                // get Overline color (from ((const 
SvxOverlineItem*)GetItem())->GetColor() in
+                                // consequence, but also already set at 
rOutDev)
+                                const Color 
aOverlineColor(rOutDev.GetOverlineColor());
+
+                                // get TextLine color (from ((const 
SvxUnderlineItem*)GetItem())->GetColor() in
+                                // consequence, but also already set at 
rOutDev)
+                                const Color 
aTextLineColor(rOutDev.GetTextLineColor());
+
+                                // Unicode code points conversion according to 
ctl text numeral setting
+                                aText = convertDigits(aText, nTextStart, 
nTextLen,
+                                    ImplCalcDigitLang(aTmpFont.GetLanguage()));
+
+                                // StripPortions() data callback
+                                const DrawPortionInfo aInfo(
+                                    aOutPos, aText, nTextStart, nTextLen, 
pDXArray, pKashidaArray,
+                                    aTmpFont, nParaPortion, 
rTextPortion.GetRightToLeftLevel(),
+                                    !aWrongSpellVector.empty() ? 
&aWrongSpellVector : nullptr,
+                                    pFieldData,
+                                    bEndOfLine, bEndOfParagraph, false, // 
support for EOL/EOP TEXT comments
+                                    &aLocale,
+                                    aOverlineColor,
+                                    aTextLineColor);
+                                
rStripPortionsHelper.processDrawPortionInfo(aInfo);
+
+                                // #108052# remember that EOP is written 
already for this ParaPortion
+                                if(bEndOfParagraph)
+                                {
+                                    bEndOfParagraphWritten = true;
+                                }
                             }
                             break;
                             case PortionKind::TAB:
@@ -4272,35 +3934,26 @@ void ImpEditEngine::PaintOrStrip( OutputDevice& 
rOutDev, tools::Rectangle aClipR
                                     comphelper::string::padToLength(aBuf, 
nChars, rTextPortion.GetExtraValue());
                                     OUString aText(aBuf.makeStringAndClear());
 
-                                    if (pStripPortionsHelper)
-                                    {
-                                        // create EOL and EOP bools
-                                        const bool bEndOfLine(nPortion == 
pLine->GetEndPortion());
-                                        const bool bEndOfParagraph(bEndOfLine 
&& nLine + 1 == nLines);
-
-                                        const Color 
aOverlineColor(rOutDev.GetOverlineColor());
-                                        const Color 
aTextLineColor(rOutDev.GetTextLineColor());
-
-                                        // StripPortions() data callback
-                                        const DrawPortionInfo aInfo(
-                                            aTmpPos, aText, 0, 
aText.getLength(), {}, {},
-                                            aTmpFont, nParaPortion, 0,
-                                            nullptr,
-                                            nullptr,
-                                            bEndOfLine, bEndOfParagraph, false,
-                                            nullptr,
-                                            aOverlineColor,
-                                            aTextLineColor);
-                                        
pStripPortionsHelper->processDrawPortionInfo(aInfo);
-                                    }
-                                    else
-                                    {
-                                        // direct paint needed
-                                        aTmpFont.QuickDrawText( &rOutDev, 
aTmpPos, aText, 0, aText.getLength(), {} );
-                                        rOutDev.DrawStretchText( aTmpPos, 
rTextPortion.GetSize().Width(), aText );
-                                    }
+                                    // create EOL and EOP bools
+                                    const bool bEndOfLine(nPortion == 
pLine->GetEndPortion());
+                                    const bool bEndOfParagraph(bEndOfLine && 
nLine + 1 == nLines);
+
+                                    const Color 
aOverlineColor(rOutDev.GetOverlineColor());
+                                    const Color 
aTextLineColor(rOutDev.GetTextLineColor());
+
+                                    // StripPortions() data callback
+                                    const DrawPortionInfo aInfo(
+                                        aTmpPos, aText, 0, aText.getLength(), 
{}, {},
+                                        aTmpFont, nParaPortion, 0,
+                                        nullptr,
+                                        nullptr,
+                                        bEndOfLine, bEndOfParagraph, false,
+                                        nullptr,
+                                        aOverlineColor,
+                                        aTextLineColor);
+                                    
rStripPortionsHelper.processDrawPortionInfo(aInfo);
                                 }
-                                else if (pStripPortionsHelper)
+                                else
                                 {
                                     // #i108052# When stripping, a callback 
for _empty_ paragraphs is also needed.
                                     // This was optimized away (by not 
rendering the space-only tab portion), so do
@@ -4320,7 +3973,7 @@ void ImpEditEngine::PaintOrStrip( OutputDevice& rOutDev, 
tools::Rectangle aClipR
                                         nullptr,
                                         aOverlineColor,
                                         aTextLineColor);
-                                    
pStripPortionsHelper->processDrawPortionInfo(aInfo);
+                                    
rStripPortionsHelper.processDrawPortionInfo(aInfo);
                                 }
                             }
                             break;
@@ -4356,7 +4009,7 @@ void ImpEditEngine::PaintOrStrip( OutputDevice& rOutDev, 
tools::Rectangle aClipR
             // that the reason for #i108052# was fixed/removed again, so this 
is a try to fix
             // the number of paragraphs (and counting empty ones) now 
independent from the
             // changes in EditEngine behaviour.
-            if(!bEndOfParagraphWritten && !bPaintBullet && 
pStripPortionsHelper)
+            if(!bEndOfParagraphWritten && !bPaintBullet)
             {
                 const Color aOverlineColor(rOutDev.GetOverlineColor());
                 const Color aTextLineColor(rOutDev.GetTextLineColor());
@@ -4370,7 +4023,7 @@ void ImpEditEngine::PaintOrStrip( OutputDevice& rOutDev, 
tools::Rectangle aClipR
                     nullptr,
                     aOverlineColor,
                     aTextLineColor);
-                pStripPortionsHelper->processDrawPortionInfo(aInfo);
+                rStripPortionsHelper.processDrawPortionInfo(aInfo);
             }
         }
         else
@@ -4378,9 +4031,6 @@ void ImpEditEngine::PaintOrStrip( OutputDevice& rOutDev, 
tools::Rectangle aClipR
             adjustYDirectionAware(aStartPos, nParaHeight);
         }
 
-        if ( pPDFExtOutDevData )
-            pPDFExtOutDevData->EndStructureElement();
-
         // no more visible actions?
         if (getYOverflowDirectionAware(aStartPos, aClipRect))
             break;
@@ -4418,9 +4068,9 @@ void ImpEditEngine::DrawText_ToEditView( 
TextHierarchyBreakup& rHelper, ImpEditV
     tools::Rectangle aClipRect( pView->GetOutputArea() );
     aClipRect.Intersection( rRect );
 
-    OutputDevice& rTarget = pTargetDevice ? *pTargetDevice : 
*pView->GetWindow()->GetOutDev();
-
-    const Point aStartPos(CalculateTextPaintStartPosition(*pView));
+    if (aClipRect.IsEmpty())
+        // no area, no paint
+        return;
 
     // If Doc-width < Output Area,Width and not wrapped fields,
     // the fields usually protrude if > line.
@@ -4435,60 +4085,55 @@ void ImpEditEngine::DrawText_ToEditView( 
TextHierarchyBreakup& rHelper, ImpEditV
             aClipRect.SetRight( nMaxX );
     }
 
-    static bool bUsePrimitives(nullptr == 
std::getenv("DISBALE_EDITENGINE_ON_PRIMITIVES"));
-
-    if (bUsePrimitives)
-    {
-        // extract Primitives
-        PaintOrStrip(rTarget, aClipRect, aStartPos, 0_deg10, &rHelper);
-
-        if (rHelper.getTextPortionPrimitives().empty())
-            // no Primitives, done
-            return;
+    // extract Primitives
+    OutputDevice& rTarget = pTargetDevice ? *pTargetDevice : 
*pView->GetWindow()->GetOutDev();
+    const Point aStartPos(CalculateTextPaintStartPosition(*pView));
+    StripAllPortions(rTarget, aClipRect, aStartPos, rHelper);
 
-        // create ViewInformation2D based on target OutputDevice
-        drawinglayer::geometry::ViewInformation2D aViewInformation2D;
-        
aViewInformation2D.setViewTransformation(rTarget.GetViewTransformation());
-        const basegfx::B2DRange 
aClipRange(vcl::unotools::b2DRectangleFromRectangle(aClipRect));
-        aViewInformation2D.setViewport(aClipRange);
+    if (rHelper.getTextPortionPrimitives().empty())
+        // no Primitives, done
+        return;
 
-        // get content and it's range
-        drawinglayer::primitive2d::Primitive2DContainer 
aContent(rHelper.getTextPortionPrimitives());
-        const basegfx::B2DRange 
aContentRange(aContent.getB2DRange(aViewInformation2D));
+    // create ViewInformation2D based on target OutputDevice
+    drawinglayer::geometry::ViewInformation2D aViewInformation2D;
+    aViewInformation2D.setViewTransformation(rTarget.GetViewTransformation());
 
-        if (!aContentRange.overlaps(aClipRange))
-            // no overlap, nothing visible
-            return;
+    // get content and it's range
+    drawinglayer::primitive2d::Primitive2DContainer 
aContent(rHelper.getTextPortionPrimitives());
+    const basegfx::B2DRange 
aContentRange(aContent.getB2DRange(aViewInformation2D));
+    const basegfx::B2DRange 
aClipRange(vcl::unotools::b2DRectangleFromRectangle(aClipRect));
 
-        if (!aClipRange.isInside(aContentRange))
-        {
-            // not completely inside aClipRange, clipping needed.
-            // Embed to MaskPrimitive2D
-            aContent = drawinglayer::primitive2d::Primitive2DContainer{
-                new drawinglayer::primitive2d::MaskPrimitive2D(
-                    
basegfx::B2DPolyPolygon(basegfx::utils::createPolygonFromRect(aClipRange)),
-                    std::move(aContent))};
-        }
+    if (!aContentRange.overlaps(aClipRange))
+        // no overlap, nothing visible
+        return;
 
-        // create PrimitiveProcessor and render to target
-        std::unique_ptr<drawinglayer::processor2d::BaseProcessor2D> xProcessor(
-            
drawinglayer::processor2d::createProcessor2DFromOutputDevice(rTarget, 
aViewInformation2D));
-        xProcessor->process(aContent);
-    }
-    else
+    if (!aClipRange.isInside(aContentRange))
     {
-        bool bClipRegion = rTarget.IsClipRegion();
-        vcl::Region aOldRegion = rTarget.GetClipRegion();
-        rTarget.IntersectClipRegion( aClipRect );
-
-        PaintOrStrip(rTarget, aClipRect, aStartPos);
+        // not completely inside aClipRange, clipping needed.
+        // Embed to MaskPrimitive2D
+        aContent = drawinglayer::primitive2d::Primitive2DContainer{
+            new drawinglayer::primitive2d::MaskPrimitive2D(
+                
basegfx::B2DPolyPolygon(basegfx::utils::createPolygonFromRect(aClipRange)),
+                std::move(aContent))};
+    }
 
-        if ( bClipRegion )
-            rTarget.SetClipRegion( aOldRegion );
-        else
-            rTarget.SetClipRegion();
+    static bool bBlendForTest(false);
+    if(bBlendForTest)
+    {
+        aContent = drawinglayer::primitive2d::Primitive2DContainer{
+            new drawinglayer::primitive2d::ModifiedColorPrimitive2D(
+                std::move(aContent),
+                
std::make_shared<basegfx::BColorModifier_interpolate>(COL_LIGHTRED.getBColor(), 
0.5)) };
     }
 
+    // create PrimitiveProcessor and render to target
+    std::unique_ptr<drawinglayer::processor2d::BaseProcessor2D> xProcessor(
+        drawinglayer::processor2d::createProcessor2DFromOutputDevice(rTarget, 
aViewInformation2D));
+    xProcessor->process(aContent);
+    // It is NECESSARY to destruct the PrimitiveProcessor here get the paint
+    // updated, else XOR may be out of sync here, e.g. in OutlinerView in 
Presentation (!)
+    xProcessor.reset();
+
     pView->DrawSelectionXOR(pView->GetEditSelection(), nullptr, &rTarget);
 }
 
diff --git a/editeng/source/outliner/outleeng.cxx 
b/editeng/source/outliner/outleeng.cxx
index 92dcbfb78fab..7fda1ef47c72 100644
--- a/editeng/source/outliner/outleeng.cxx
+++ b/editeng/source/outliner/outleeng.cxx
@@ -39,15 +39,15 @@ OutlinerEditEng::~OutlinerEditEng()
 {
 }
 
-void OutlinerEditEng::ProcessFirstLineOfParagraph(sal_Int32 nPara, const 
Point& rStartPos, const Point& rOrigin, Degree10 nOrientation, OutputDevice& 
rOutDev, StripPortionsHelper* pStripPortionsHelper)
+void OutlinerEditEng::ProcessFirstLineOfParagraph(sal_Int32 nPara, const 
Point& rStartPos, OutputDevice& rOutDev, StripPortionsHelper& 
rStripPortionsHelper)
 {
     if( GetControlWord() & EEControlBits::OUTLINER )
     {
-        PaintFirstLineInfo aInfo(nPara, rStartPos, &rOutDev, 
pStripPortionsHelper);
+        PaintFirstLineInfo aInfo(nPara, rStartPos, &rOutDev, 
rStripPortionsHelper);
         pOwner->maPaintFirstLineHdl.Call( &aInfo );
     }
 
-    pOwner->PaintOrStripBullet(nPara, rStartPos, rOrigin, nOrientation, 
rOutDev, pStripPortionsHelper);
+    pOwner->StripBullet(nPara, rStartPos, rOutDev, rStripPortionsHelper);
 }
 
 const SvxNumberFormat* OutlinerEditEng::GetNumberFormat( sal_Int32 nPara ) 
const
diff --git a/editeng/source/outliner/outliner.cxx 
b/editeng/source/outliner/outliner.cxx
index f9f5ac0f72ab..404a3bfa299a 100644
--- a/editeng/source/outliner/outliner.cxx
+++ b/editeng/source/outliner/outliner.cxx
@@ -870,10 +870,8 @@ vcl::Font Outliner::ImpCalcBulletFont( sal_Int32 nPara ) 
const
     return aBulletFont;
 }
 
-void Outliner::PaintOrStripBullet(
-    sal_Int32 nPara, const Point& rStartPos, const Point& rOrigin,
-    Degree10 nOrientation, OutputDevice& rOutDev,
-    StripPortionsHelper* pStripPortionsHelper)
+void Outliner::StripBullet(
+    sal_Int32 nPara, const Point& rStartPos, OutputDevice& rOutDev, 
StripPortionsHelper& rStripPortionsHelper)
 {
 
     bool bDrawBullet = false;
@@ -939,17 +937,6 @@ void Outliner::PaintOrStripBullet(
                 }
             }
 
-            if ( nOrientation )
-            {
-                // Both TopLeft and bottom left is not quite correct,
-                // since in EditEngine baseline ...
-                rOrigin.RotateAround(aTextPos, nOrientation);
-
-                vcl::Font aRotatedFont( std::move(aBulletFont) );
-                aRotatedFont.SetOrientation( nOrientation );
-                rOutDev.SetFont( aRotatedFont );
-            }
-
             // VCL will take care of brackets and so on...
             vcl::text::ComplexTextLayoutFlags nLayoutMode = 
rOutDev.GetLayoutMode();
             nLayoutMode &= 
~vcl::text::ComplexTextLayoutFlags(vcl::text::ComplexTextLayoutFlags::BiDiRtl|vcl::text::ComplexTextLayoutFlags::BiDiStrong);
@@ -957,29 +944,22 @@ void Outliner::PaintOrStripBullet(
                 nLayoutMode |= vcl::text::ComplexTextLayoutFlags::BiDiRtl | 
vcl::text::ComplexTextLayoutFlags::TextOriginLeft | 
vcl::text::ComplexTextLayoutFlags::BiDiStrong;
             rOutDev.SetLayoutMode( nLayoutMode );
 
-            if (pStripPortionsHelper)
-            {
-                const SvxFont aSvxFont(rOutDev.GetFont());
-                KernArray aBuf;
-                rOutDev.GetTextArray( pPara->GetText(), &aBuf );
-
-                if(bSymbol)
-                {
-                    // aTextPos is Bottom, go to Baseline
-                    FontMetric aMetric(rOutDev.GetFontMetric());
-                    aTextPos.AdjustY( -(aMetric.GetDescent()) );
-                }
+            const SvxFont aSvxFont(rOutDev.GetFont());
+            KernArray aBuf;
+            rOutDev.GetTextArray( pPara->GetText(), &aBuf );
 
-                const DrawPortionInfo aInfo(
-                    aTextPos, pPara->GetText(), 0, 
pPara->GetText().getLength(), aBuf, {},
-                    aSvxFont, nPara, bRightToLeftPara ? 1 : 0, nullptr, 
nullptr, false, false, true, nullptr, Color(), Color());
-                pStripPortionsHelper->processDrawPortionInfo(aInfo);
-            }
-            else
+            if(bSymbol)
             {
-                rOutDev.DrawText( aTextPos, pPara->GetText() );
+                // aTextPos is Bottom, go to Baseline
+                FontMetric aMetric(rOutDev.GetFontMetric());
+                aTextPos.AdjustY( -(aMetric.GetDescent()) );
             }
 
+            const DrawPortionInfo aInfo(
+                aTextPos, pPara->GetText(), 0, pPara->GetText().getLength(), 
aBuf, {},
+                aSvxFont, nPara, bRightToLeftPara ? 1 : 0, nullptr, nullptr, 
false, false, true, nullptr, Color(), Color());
+            rStripPortionsHelper.processDrawPortionInfo(aInfo);
+
             rOutDev.SetFont( aOldFont );
         }
         else
@@ -1009,55 +989,18 @@ void Outliner::PaintOrStripBullet(
                     }
                 }
 
-                if (pStripPortionsHelper)
-                {
-                    // call something analog to aDrawPortionHdl (if set) and 
feed it something
-                    // analog to DrawPortionInfo...
-                    // created aDrawBulletHdl, Set/GetDrawBulletHdl.
-                    // created DrawBulletInfo and added handling to 
sdrtextdecomposition.cxx
-                    DrawBulletInfo aDrawBulletInfo(
-                        *pFmt->GetBrush()->GetGraphicObject(),
-                        aBulletPos,
-                        pPara->aBulSize);
-                    
pStripPortionsHelper->processDrawBulletInfo(aDrawBulletInfo);
-                }
-                else
-                {
-                    pFmt->GetBrush()->GetGraphicObject()->Draw(rOutDev, 
aBulletPos, pPara->aBulSize);
-                }
+                // call something analog to aDrawPortionHdl (if set) and feed 
it something
+                // analog to DrawPortionInfo...
+                // created aDrawBulletHdl, Set/GetDrawBulletHdl.
+                // created DrawBulletInfo and added handling to 
sdrtextdecomposition.cxx
+                DrawBulletInfo aDrawBulletInfo(
+                    *pFmt->GetBrush()->GetGraphicObject(),
+                    aBulletPos,
+                    pPara->aBulSize);
+                rStripPortionsHelper.processDrawBulletInfo(aDrawBulletInfo);
             }
         }
     }
-
-    // In case of collapsed subparagraphs paint a line before the text.
-    if( !pParaList->HasChildren(pPara) || pParaList->HasVisibleChildren(pPara) 
|| pStripPortionsHelper || nOrientation )
-        return;
-
-    tools::Long nWidth = rOutDev.PixelToLogic( Size( 10, 0 ) ).Width();
-
-    Point aStartPos, aEndPos;
-    if ( !bVertical )
-    {
-        aStartPos.setY( rStartPos.Y() + aBulletArea.Bottom() );
-        if ( !bRightToLeftPara )
-            aStartPos.setX( rStartPos.X() + aBulletArea.Right() );
-        else
-            aStartPos.setX( rStartPos.X() + GetPaperSize().Width() - 
aBulletArea.Left() );
-        aEndPos = aStartPos;
-        aEndPos.AdjustX(nWidth );
-    }
-    else
-    {
-        aStartPos.setX( rStartPos.X() - aBulletArea.Bottom() );
-        aStartPos.setY( rStartPos.Y() + aBulletArea.Right() );
-        aEndPos = aStartPos;
-        aEndPos.AdjustY(nWidth );
-    }
-
-    const Color& rOldLineColor = rOutDev.GetLineColor();
-    rOutDev.SetLineColor( COL_BLACK );
-    rOutDev.DrawLine( aStartPos, aEndPos );
-    rOutDev.SetLineColor( rOldLineColor );
 }
 
 void Outliner::InvalidateBullet(sal_Int32 nPara)
@@ -1513,7 +1456,7 @@ tools::Rectangle Outliner::ImpCalcBulletArea( sal_Int32 
nPara, bool bAdjust, boo
         ParagraphInfos aInfos = pEditEngine->GetParagraphInfos( nPara );
         if ( aInfos.bValid )
         {
-            aTopLeft.setY( /* aInfos.nFirstLineOffset + */ // nFirstLineOffset 
is already added to the StartPos (PaintOrStripBullet) from the EditEngine
+            aTopLeft.setY( /* aInfos.nFirstLineOffset + */ // nFirstLineOffset 
is already added to the StartPos (StripBullet) from the EditEngine
                             aInfos.nFirstLineHeight - 
aInfos.nFirstLineTextHeight
                             + aInfos.nFirstLineTextHeight / 2
                             - aBulletSize.Height() / 2 );
diff --git a/include/editeng/editeng.hxx b/include/editeng/editeng.hxx
index ca00ddd807d6..c53ad6ff764e 100644
--- a/include/editeng/editeng.hxx
+++ b/include/editeng/editeng.hxx
@@ -489,7 +489,7 @@ public:
     SAL_DLLPRIVATE void            SetBeginPasteOrDropHdl( const 
Link<PasteOrDropInfos&,void>& rLink );
     SAL_DLLPRIVATE void            SetEndPasteOrDropHdl( const 
Link<PasteOrDropInfos&,void>& rLink );
 
-    virtual void    ProcessFirstLineOfParagraph(sal_Int32 nPara, const Point& 
rStartPos, const Point& rOrigin, Degree10 nOrientation, OutputDevice& rOutDev, 
StripPortionsHelper* pStripPortionsHelper);
+    virtual void    ProcessFirstLineOfParagraph(sal_Int32 nPara, const Point& 
rStartPos, OutputDevice& rOutDev, StripPortionsHelper& rStripPortionsHelper);
 
     virtual void    ParagraphInserted( sal_Int32 nNewParagraph );
     virtual void    ParagraphDeleted( sal_Int32 nDeletedParagraph );
diff --git a/include/editeng/outliner.hxx b/include/editeng/outliner.hxx
index 92d7117f5796..80aee72f0070 100644
--- a/include/editeng/outliner.hxx
+++ b/include/editeng/outliner.hxx
@@ -407,10 +407,10 @@ struct EDITENG_DLLPUBLIC PaintFirstLineInfo
     sal_Int32 mnPara;
     const Point& mrStartPos;
     VclPtr<OutputDevice> mpOutDev;
-    StripPortionsHelper* mpStripPortionsHelper;
+    StripPortionsHelper& mrStripPortionsHelper;
 
-    PaintFirstLineInfo( sal_Int32 nPara, const Point& rStartPos, OutputDevice* 
pOutDev, StripPortionsHelper* pStripPortionsHelper )
-        : mnPara( nPara ), mrStartPos( rStartPos ), mpOutDev( pOutDev ), 
mpStripPortionsHelper( pStripPortionsHelper )
+    PaintFirstLineInfo( sal_Int32 nPara, const Point& rStartPos, OutputDevice* 
pOutDev, StripPortionsHelper& rStripPortionsHelper )
+        : mnPara( nPara ), mrStartPos( rStartPos ), mpOutDev( pOutDev ), 
mrStripPortionsHelper( rStripPortionsHelper )
     {}
 };
 
@@ -579,11 +579,8 @@ protected:
     SAL_DLLPRIVATE void            StyleSheetChanged( SfxStyleSheet const * 
pStyle );
 
     SAL_DLLPRIVATE void            InvalidateBullet(sal_Int32 nPara);
-    SAL_DLLPRIVATE void            PaintOrStripBullet(
-        sal_Int32 nPara, const Point& rStartPos,
-        const Point& rOrigin, Degree10 nOrientation,
-        OutputDevice& rOutDev,
-        StripPortionsHelper* pStripPortionsHelper);
+    SAL_DLLPRIVATE void            StripBullet(
+        sal_Int32 nPara, const Point& rStartPos, OutputDevice& rOutDev, 
StripPortionsHelper& rStripPortionsHelper);
 
     // used by OutlinerEditEng. Allows Outliner objects to provide
     // bullet access to the EditEngine.
diff --git a/sd/source/ui/view/outlview.cxx b/sd/source/ui/view/outlview.cxx
index a076ffe61ada..4d6799a521fa 100644
--- a/sd/source/ui/view/outlview.cxx
+++ b/sd/source/ui/view/outlview.cxx
@@ -1583,23 +1583,15 @@ IMPL_LINK(OutlineView, PaintingFirstLineHdl, 
PaintFirstLineInfo*, pInfo, void)
     Point aImagePos( pInfo->mrStartPos );
     aImagePos.AdjustX(aOutSize.Width() - aImageSize.Width() - aOffset.Width() 
) ;
     aImagePos.AdjustY((aOutSize.Height() - aImageSize.Height()) / 2 );
-    static bool bUsePrimitives(nullptr == 
std::getenv("DISBALE_EDITENGINE_ON_PRIMITIVES"));
 
-    if (bUsePrimitives && pInfo->mpStripPortionsHelper)
-    {
-        // create BitmapPrimitive2D and add directly
-        const drawinglayer::primitive2d::Primitive2DReference xBitmap(
-            new drawinglayer::primitive2d::BitmapPrimitive2D(
-                BitmapEx(maSlideImage.GetBitmap()),
-                basegfx::utils::createScaleTranslateB2DHomMatrix(
-                    aImageSize.Width(), aImageSize.Height(),
-                    aImagePos.X(), aImagePos.Y())));
-        pInfo->mpStripPortionsHelper->directlyAddB2DPrimitive(xBitmap);
-    }
-    else
-    {
-        pInfo->mpOutDev->DrawImage( aImagePos, aImageSize, maSlideImage );
-    }
+    // create BitmapPrimitive2D and add directly
+    const drawinglayer::primitive2d::Primitive2DReference xBitmap(
+        new drawinglayer::primitive2d::BitmapPrimitive2D(
+            BitmapEx(maSlideImage.GetBitmap()),
+            basegfx::utils::createScaleTranslateB2DHomMatrix(
+                aImageSize.Width(), aImageSize.Height(),
+                aImagePos.X(), aImagePos.Y())));
+    pInfo->mrStripPortionsHelper.directlyAddB2DPrimitive(xBitmap);
 
     const bool bVertical = mrOutliner.IsVertical();
     const bool bRightToLeftPara = rEditEngine.IsRightToLeft( pInfo->mnPara );
@@ -1635,37 +1627,30 @@ IMPL_LINK(OutlineView, PaintingFirstLineHdl, 
PaintFirstLineInfo*, pInfo, void)
         aTextPos.AdjustX(nBulletHeight / 2 );
     }
 
-    if (bUsePrimitives && pInfo->mpStripPortionsHelper)
-    {
-        // create TextSimplePortionPrimitive2D and add directly
-        basegfx::B2DVector aFontSize;
-        const vcl::Font& rFont(pInfo->mpOutDev->GetFont());
-        drawinglayer::attribute::FontAttribute aFontAttr(
-            drawinglayer::primitive2d::getFontAttributeFromVclFont(aFontSize, 
rFont, false, false));
-        const FontMetric aFontMetric(pInfo->mpOutDev->GetFontMetric(rFont));
-        const double fTextOffsetY(aFontMetric.GetAscent());
-        const basegfx::B2DHomMatrix aTextTransform(
-            basegfx::utils::createScaleTranslateB2DHomMatrix(
-                aFontSize.getX(), aFontSize.getY(),
-                aTextPos.X(), aTextPos.Y() + fTextOffsetY));
-
-        const drawinglayer::primitive2d::Primitive2DReference xText(
-            new drawinglayer::primitive2d::TextSimplePortionPrimitive2D(
-                aTextTransform,
-                aPageText,
-                0,
-                aPageText.getLength(),
-                std::vector<double>(),
-                {},
-                std::move(aFontAttr),
-                css::lang::Locale(),
-                pInfo->mpOutDev->GetTextColor().getBColor()));
-        pInfo->mpStripPortionsHelper->directlyAddB2DPrimitive(xText);
-    }
-    else
-    {
-        pInfo->mpOutDev->DrawText( aTextPos, aPageText );
-    }
+    // create TextSimplePortionPrimitive2D and add directly
+    basegfx::B2DVector aFontSize;
+    const vcl::Font& rFont(pInfo->mpOutDev->GetFont());
+    drawinglayer::attribute::FontAttribute aFontAttr(
+        drawinglayer::primitive2d::getFontAttributeFromVclFont(aFontSize, 
rFont, false, false));
+    const FontMetric aFontMetric(pInfo->mpOutDev->GetFontMetric(rFont));
+    const double fTextOffsetY(aFontMetric.GetAscent());
+    const basegfx::B2DHomMatrix aTextTransform(
+        basegfx::utils::createScaleTranslateB2DHomMatrix(
+            aFontSize.getX(), aFontSize.getY(),
+            aTextPos.X(), aTextPos.Y() + fTextOffsetY));
+
+    const drawinglayer::primitive2d::Primitive2DReference xText(
+        new drawinglayer::primitive2d::TextSimplePortionPrimitive2D(
+            aTextTransform,
+            aPageText,
+            0,
+            aPageText.getLength(),
+            std::vector<double>(),
+            {},
+            std::move(aFontAttr),
+            css::lang::Locale(),
+            pInfo->mpOutDev->GetTextColor().getBColor()));
+    pInfo->mrStripPortionsHelper.directlyAddB2DPrimitive(xText);
 }
 
 void OutlineView::UpdateParagraph( sal_Int32 nPara )

Reply via email to