move Draw* code from EditEngine to ImpEditEngine

so we have the implementation in one class, instead of bouncing
back and forth between two.

Change-Id: Iba2a42344aa5f8d00e4201d9a4ed72ca4c2b2193
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168925
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Tested-by: Jenkins
diff --git a/editeng/source/editeng/editdbg.cxx b/editeng/source/editeng/editdbg.cxx
index c49b988..39c7de5 100644
--- a/editeng/source/editeng/editdbg.cxx
+++ b/editeng/source/editeng/editdbg.cxx
@@ -328,11 +328,8 @@ static void DbgOutItemSet(FILE* fp, const SfxItemSet& rSet, bool bSearchInParent
    }
}

void EditEngine::DumpData(const EditEngine* pEE, bool bInfoBox)
void ImpEditEngine::DumpData(bool bInfoBox)
{
    if (!pEE)
        return;

    FILE* fp = fopen( "editenginedump.log", "w" );
    if ( fp == nullptr )
    {
@@ -340,14 +337,14 @@ void EditEngine::DumpData(const EditEngine* pEE, bool bInfoBox)
        return;
    }

    const SfxItemPool& rPool = *pEE->GetEmptyItemSet().GetPool();
    const SfxItemPool& rPool = *GetEmptyItemSet().GetPool();

    fprintf( fp, "================================================================================" );
    fprintf( fp, "\n==================   Document   ================================================" );
    fprintf( fp, "\n================================================================================" );
    for ( sal_Int32 nPortion = 0; nPortion < pEE->getImpl().GetParaPortions().Count(); nPortion++)
    for ( sal_Int32 nPortion = 0; nPortion < GetParaPortions().Count(); nPortion++)
    {
        ParaPortion const& rPPortion = pEE->getImpl().GetParaPortions().getRef(nPortion);
        ParaPortion const& rPPortion = GetParaPortions().getRef(nPortion);
        fprintf( fp, "\nParagraph %" SAL_PRIdINT32 ": Length = %" SAL_PRIdINT32 ", Invalid = %i\nText = '%s'",
                 nPortion, rPPortion.GetNode()->Len(), rPPortion.IsInvalid(),
                 OUStringToOString(rPPortion.GetNode()->GetString(), RTL_TEXTENCODING_UTF8).getStr() );
@@ -434,9 +431,9 @@ void EditEngine::DumpData(const EditEngine* pEE, bool bInfoBox)
        fprintf( fp, "\n-----------------------------------------------------------------------------" );
    }

    if (pEE->getImpl().GetStyleSheetPool())
    if (GetStyleSheetPool())
    {
        SfxStyleSheetIterator aIter(pEE->getImpl().GetStyleSheetPool(), SfxStyleFamily::All);
        SfxStyleSheetIterator aIter(GetStyleSheetPool(), SfxStyleFamily::All);
        sal_uInt16 nStyles = aIter.Count();
        fprintf( fp, "\n\n================================================================================" );
        fprintf( fp, "\n==================   Stylesheets   =============================================" );
@@ -458,21 +455,21 @@ void EditEngine::DumpData(const EditEngine* pEE, bool bInfoBox)
    fprintf( fp, "\n\n================================================================================" );
    fprintf( fp, "\n==================   Defaults   ================================================" );
    fprintf( fp, "\n================================================================================" );
    DbgOutItemSet(fp, pEE->getImpl().GetEmptyItemSet(), true, true);
    DbgOutItemSet(fp, GetEmptyItemSet(), true, true);

    fprintf( fp, "\n\n================================================================================" );
    fprintf( fp, "\n==================   EditEngine & Views   ======================================" );
    fprintf( fp, "\n================================================================================" );
    fprintf( fp, "\nControl: %x", unsigned( pEE->GetControlWord() ) );
    fprintf( fp, "\nRefMapMode: %i", int( pEE->getImpl().mpRefDev->GetMapMode().GetMapUnit()));
    fprintf( fp, "\nPaperSize: %" SAL_PRIdINT64 " x %" SAL_PRIdINT64, sal_Int64(pEE->GetPaperSize().Width()), sal_Int64(pEE->GetPaperSize().Height()) );
    fprintf( fp, "\nMaxAutoPaperSize: %" SAL_PRIdINT64 " x %" SAL_PRIdINT64, sal_Int64(pEE->GetMaxAutoPaperSize().Width()), sal_Int64(pEE->GetMaxAutoPaperSize().Height()) );
    fprintf( fp, "\nMinAutoPaperSize: %" SAL_PRIdINT64 " x %" SAL_PRIdINT64 , sal_Int64(pEE->GetMinAutoPaperSize().Width()), sal_Int64(pEE->GetMinAutoPaperSize().Height()) );
    fprintf( fp, "\nCalculateLayout: %i", pEE->IsUpdateLayout() );
    fprintf( fp, "\nNumber of Views: %" SAL_PRI_SIZET "i", pEE->GetViewCount() );
    for ( size_t nView = 0; nView < pEE->GetViewCount(); nView++ )
    fprintf( fp, "\nControl: %x", unsigned( GetStatus().GetControlWord() ) );
    fprintf( fp, "\nRefMapMode: %i", int( mpRefDev->GetMapMode().GetMapUnit()));
    fprintf( fp, "\nPaperSize: %" SAL_PRIdINT64 " x %" SAL_PRIdINT64, sal_Int64(GetPaperSize().Width()), sal_Int64(GetPaperSize().Height()) );
    fprintf( fp, "\nMaxAutoPaperSize: %" SAL_PRIdINT64 " x %" SAL_PRIdINT64, sal_Int64(GetMaxAutoPaperSize().Width()), sal_Int64(GetMaxAutoPaperSize().Height()) );
    fprintf( fp, "\nMinAutoPaperSize: %" SAL_PRIdINT64 " x %" SAL_PRIdINT64 , sal_Int64(GetMinAutoPaperSize().Width()), sal_Int64(GetMinAutoPaperSize().Height()) );
    fprintf( fp, "\nCalculateLayout: %i", IsUpdateLayout() );
    fprintf( fp, "\nNumber of Views: %" SAL_PRI_SIZET "i", GetEditViews().size() );
    for ( size_t nView = 0; nView < GetEditViews().size(); nView++ )
    {
        EditView* pV = pEE->GetView( nView );
        EditView* pV = GetEditViews()[nView];
        assert(pV && "View not found!");
        fprintf( fp, "\nView %zu: Focus=%i", nView, pV->GetWindow()->HasFocus() );
        tools::Rectangle aR( pV->GetOutputArea() );
@@ -484,12 +481,12 @@ void EditEngine::DumpData(const EditEngine* pEE, bool bInfoBox)
        ESelection aSel = pV->GetSelection();
        fprintf( fp, "\n  Selection: Start=%" SAL_PRIdINT32 ",%" SAL_PRIdINT32 ", End=%" SAL_PRIdINT32 ",%" SAL_PRIdINT32, aSel.nStartPara, aSel.nStartPos, aSel.nEndPara, aSel.nEndPos );
    }
    if ( pEE->GetActiveView() )
    if ( GetActiveView() )
    {
        fprintf( fp, "\n\n================================================================================" );
        fprintf( fp, "\n==================   Current View   ===========================================" );
        fprintf( fp, "\n================================================================================" );
        DbgOutItemSet( fp, pEE->GetActiveView()->GetAttribs(), true, false );
        DbgOutItemSet( fp, GetActiveView()->GetAttribs(), true, false );
    }
    fclose( fp );
    if ( bInfoBox )
diff --git a/editeng/source/editeng/editeng.cxx b/editeng/source/editeng/editeng.cxx
index d1ee7db..0c68a1e 100644
--- a/editeng/source/editeng/editeng.cxx
+++ b/editeng/source/editeng/editeng.cxx
@@ -81,10 +81,6 @@ using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::linguistic2;


#if (OSL_DEBUG_LEVEL > 1) || defined ( DBG_UTIL )
static bool bDebugPaint = false;
#endif

static rtl::Reference<SfxItemPool> pGlobalPool;

ImpEditEngine& EditEngine::getImpl() const
@@ -206,20 +202,7 @@ void EditEngine::Draw( OutputDevice& rOutDev, const tools::Rectangle& rOutRect )

void EditEngine::Draw( OutputDevice& rOutDev, const Point& rStartPos, Degree10 nOrientation )
{
    // 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 );
    if( rOutDev.GetConnectMetaFile() )
        rOutDev.Push();
    Point aStartPos( rStartPos );
    if ( IsEffectivelyVertical() )
    {
        aStartPos.AdjustX(GetPaperSize().Width() );
        rStartPos.RotateAround(aStartPos, nOrientation);
    }
    getImpl().Paint(rOutDev, aBigRect, aStartPos, false, nOrientation);
    if (rOutDev.GetConnectMetaFile())
        rOutDev.Pop();
    getImpl().Draw(rOutDev, rStartPos, nOrientation);
}

void EditEngine::Draw( OutputDevice& rOutDev, const tools::Rectangle& rOutRect, const Point& rStartDocPos )
@@ -229,67 +212,7 @@ void EditEngine::Draw( OutputDevice& rOutDev, const tools::Rectangle& rOutRect, 

void EditEngine::Draw( OutputDevice& rOutDev, const tools::Rectangle& rOutRect, const Point& rStartDocPos, bool bClip )
{
#if defined( DBG_UTIL ) || (OSL_DEBUG_LEVEL > 1)
    if ( bDebugPaint )
        DumpData(this, 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 );

    Point aStartPos;
    if ( !IsEffectivelyVertical() )
    {
        aStartPos.setX( aOutRect.Left() - rStartDocPos.X() );
        aStartPos.setY( aOutRect.Top() - rStartDocPos.Y() );
    }
    else
    {
        aStartPos.setX( aOutRect.Right() + rStartDocPos.Y() );
        aStartPos.setY( aOutRect.Top() - rStartDocPos.X() );
    }

    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 ( bClip )
    {
        // Clip only if necessary...
        if ( rStartDocPos.X() || rStartDocPos.Y() ||
             ( rOutRect.GetHeight() < static_cast<tools::Long>(GetTextHeight()) ) ||
             ( rOutRect.GetWidth() < static_cast<tools::Long>(CalcTextWidth()) ) )
        {
            // 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 );
        }
    }

    getImpl().Paint(rOutDev, aOutRect, aStartPos);

    if ( bMetafile )
        rOutDev.Pop();
    else if ( bClipRegion )
        rOutDev.SetClipRegion( aOldRegion );
    else
        rOutDev.SetClipRegion();
    getImpl().Draw(rOutDev, rOutRect, rStartDocPos, bClip);
}

void EditEngine::InsertView(EditView* pEditView, size_t nIndex)
@@ -1046,9 +969,9 @@ bool EditEngine::PostKeyEvent( const KeyEvent& rKeyEvent, EditView* pEditView, v
            {
                if ( rKeyEvent.GetKeyCode().IsMod1() && rKeyEvent.GetKeyCode().IsMod2() )
                {
                    bDebugPaint = !bDebugPaint;
                    ImpEditEngine::bDebugPaint = !ImpEditEngine::bDebugPaint;
                    OStringBuffer aInfo("DebugPaint: ");
                    aInfo.append(bDebugPaint ? "On" : "Off");
                    aInfo.append(ImpEditEngine::bDebugPaint ? "On" : "Off");
                    std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(pEditView->GetWindow()->GetFrameWeld(),
                                                                  VclMessageType::Info, VclButtonsType::Ok,
                                                                  OStringToOUString(aInfo, RTL_TEXTENCODING_ASCII_US)));
@@ -1061,7 +984,7 @@ bool EditEngine::PostKeyEvent( const KeyEvent& rKeyEvent, EditView* pEditView, v
            case KEY_F12:
            {
                if ( rKeyEvent.GetKeyCode().IsMod1() && rKeyEvent.GetKeyCode().IsMod2() )
                    DumpData(this, true);
                    getImpl().DumpData(true);
                bDone = false;
            }
            break;
diff --git a/editeng/source/editeng/impedit.hxx b/editeng/source/editeng/impedit.hxx
index 2da7087..36a276f 100644
--- a/editeng/source/editeng/impedit.hxx
+++ b/editeng/source/editeng/impedit.hxx
@@ -985,6 +985,8 @@ public:
    void FormatDoc();
    void FormatFullDoc();

    void                    Draw( OutputDevice& rOutDev, const Point& rStartPos, Degree10 nOrientation );
    void                    Draw( OutputDevice& rOutDev, const tools::Rectangle& rOutRect, const Point& rStartDocPos, bool bClip );
    void                    UpdateViews( EditView* pCurView = nullptr );
    void                    Paint( ImpEditView* pView, const tools::Rectangle& rRect, OutputDevice* pTargetDevice );
    void                    Paint(OutputDevice& rOutDev, tools::Rectangle aClipRect, Point aStartPos, bool bStripOnly = false, Degree10 nOrientation = 0_deg10);
@@ -1359,6 +1361,13 @@ public:
    // Offset of the rectangle's direction-aware corners in document coordinates
    tools::Long getBottomDocOffset(const tools::Rectangle& rect) const;
    Size getTopLeftDocOffset(const tools::Rectangle& rect) const;

#ifdef DBG_UTIL
    void DumpData(bool bInfoBox);
#endif
#if defined( DBG_UTIL ) || (OSL_DEBUG_LEVEL > 1)
    static bool bDebugPaint;
#endif
};

void ConvertItem( std::unique_ptr<SfxPoolItem>& rPoolItem, MapUnit eSourceUnit, MapUnit eDestUnit );
diff --git a/editeng/source/editeng/impedit3.cxx b/editeng/source/editeng/impedit3.cxx
index a644a3d..7df5c45 100644
--- a/editeng/source/editeng/impedit3.cxx
+++ b/editeng/source/editeng/impedit3.cxx
@@ -94,6 +94,10 @@ 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

namespace {

struct TabInfo
@@ -3401,6 +3405,92 @@ Point ImpEditEngine::MoveToNextLine(
    return rMovePos - aOld;
}

void ImpEditEngine::Draw( OutputDevice& rOutDev, const Point& rStartPos, Degree10 nOrientation )
{
    // 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 );
    if( rOutDev.GetConnectMetaFile() )
        rOutDev.Push();
    Point aStartPos( rStartPos );
    if ( IsEffectivelyVertical() )
    {
        aStartPos.AdjustX(GetPaperSize().Width() );
        rStartPos.RotateAround(aStartPos, nOrientation);
    }
    Paint(rOutDev, aBigRect, aStartPos, false, nOrientation);
    if (rOutDev.GetConnectMetaFile())
        rOutDev.Pop();
}

void ImpEditEngine::Draw( OutputDevice& rOutDev, const tools::Rectangle& rOutRect, const Point& rStartDocPos, bool bClip )
{
#if defined( DBG_UTIL ) || (OSL_DEBUG_LEVEL > 1)
    if ( bDebugPaint )
        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 );

    Point aStartPos;
    if ( !IsEffectivelyVertical() )
    {
        aStartPos.setX( aOutRect.Left() - rStartDocPos.X() );
        aStartPos.setY( aOutRect.Top() - rStartDocPos.Y() );
    }
    else
    {
        aStartPos.setX( aOutRect.Right() + rStartDocPos.Y() );
        aStartPos.setY( aOutRect.Top() - rStartDocPos.X() );
    }

    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 ( bClip )
    {
        // 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 );
        }
    }

    Paint(rOutDev, aOutRect, aStartPos);

    if ( bMetafile )
        rOutDev.Pop();
    else if ( bClipRegion )
        rOutDev.SetClipRegion( aOldRegion );
    else
        rOutDev.SetClipRegion();
}

// TODO: use IterateLineAreas in ImpEditEngine::Paint, to avoid algorithm duplication
void ImpEditEngine::Paint( OutputDevice& rOutDev, tools::Rectangle aClipRect, Point aStartPos, bool bStripOnly, Degree10 nOrientation )
{
diff --git a/include/editeng/editeng.hxx b/include/editeng/editeng.hxx
index 02f0e78..93ec140 100644
--- a/include/editeng/editeng.hxx
+++ b/include/editeng/editeng.hxx
@@ -649,10 +649,6 @@ public:

    void SetLOKSpecialPaperSize(const Size& rSize);
    const Size& GetLOKSpecialPaperSize() const;

#ifdef DBG_UTIL
    SAL_DLLPRIVATE static void DumpData(const EditEngine* pEE, bool bInfoBox);
#endif
};

#endif // INCLUDED_EDITENG_EDITENG_HXX