include/vcl/gdimtf.hxx         |    1 
 sw/source/core/view/vprint.cxx |   65 +++++++++++------------------------------
 vcl/source/gdi/gdimtf.cxx      |    7 +++-
 3 files changed, 25 insertions(+), 48 deletions(-)

New commits:
commit a225b4dbd46897903b217969da5f97f2660022c9
Author:     Michael Stahl <michael.st...@allotropia.de>
AuthorDate: Fri Jun 30 14:44:21 2023 +0200
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Mon Jul 3 11:32:14 2023 +0200

    tdf#152231 vcl,sw: PDF/UA export: fix comments in the margin
    
    If enabled, the comments mess up the structure elements, because the
    PageSyncData::mActions stores indexes into the GDIMetaFile::m_aList
    vector, and in PageSyncData::PlaySyncPageAct() the indexes don't match.
    
    This is because SwViewShell::PrintOrPDFExport() replaces the GDIMetaFile
    with a temporary one, then records the page content, then applies
    scaling to the temporary one and replays it, recording with the original
    one; somehow replaying a temporary GDIMetaFile with 270 actions to one
    that already has 4 actions results in 392 actions.
    
    It's not obvious how this can work with the temporary GDIMetaFile, so
    try to get rid of it; not sure if there any drawbacks to this but the
    GDIMetaFile is freshly created by the caller in any case.
    
    Change-Id: Ic297367ea307aa8eee8d609751d06abf417e9629
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153808
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>

diff --git a/include/vcl/gdimtf.hxx b/include/vcl/gdimtf.hxx
index d62cd899623b..63bde564dcfd 100644
--- a/include/vcl/gdimtf.hxx
+++ b/include/vcl/gdimtf.hxx
@@ -115,6 +115,7 @@ public:
     void            Move( tools::Long nX, tools::Long nY );
     // additional Move method getting specifics how to handle MapMode( 
MapUnit::MapPixel )
     void            Move( tools::Long nX, tools::Long nY, tools::Long nDPIX, 
tools::Long nDPIY );
+    void            ScaleActions(double fScaleX, double fScaleY);
     void            Scale( double fScaleX, double fScaleY );
     void            Scale( const Fraction& rScaleX, const Fraction& rScaleY );
     void            Rotate( Degree10 nAngle10 );
diff --git a/sw/source/core/view/vprint.cxx b/sw/source/core/view/vprint.cxx
index 0ad22ccf5357..3cd0c524007e 100644
--- a/sw/source/core/view/vprint.cxx
+++ b/sw/source/core/view/vprint.cxx
@@ -446,32 +446,12 @@ bool SwViewShell::PrintOrPDFExport(
     // output device is now provided by a call from outside the Writer)
     pOutDev->Push();
 
-    // fdo#36815 for comments in margins print to a metafile
-    // and then scale that metafile down so that the comments
-    // will fit on the real page, and replay that scaled
-    // output to the real outputdevice
-    GDIMetaFile *pOrigRecorder(nullptr);
-    std::unique_ptr<GDIMetaFile> pMetaFile;
     SwPostItMode nPostItMode = rPrintData.GetPrintPostIts();
 
     // tdf#91680 Reserve space in margin for comments only if there are 
comments
     const bool bHasPostItsToPrintInMargins = ( nPostItMode == 
SwPostItMode::InMargins ) &&
                                 sw_GetPostIts( 
GetDoc()->getIDocumentFieldsAccess(), nullptr );
-
-    if ( bHasPostItsToPrintInMargins )
-    {
-        //get and disable the existing recorder
-        pOrigRecorder = pOutDev->GetConnectMetaFile();
-        pOutDev->SetConnectMetaFile(nullptr);
-        // turn off output to the device
-        pOutDev->EnableOutput(false);
-        // just record the rendering commands to the metafile
-        // instead
-        pMetaFile.reset(new GDIMetaFile);
-        pMetaFile->SetPrefSize(pOutDev->GetOutputSize());
-        pMetaFile->SetPrefMapMode(pOutDev->GetMapMode());
-        pMetaFile->Record(pOutDev);
-    }
+    ::std::optional<tools::Long> oOrigHeight;
 
     // Print/PDF export for (multi-)selection has already generated a
     // temporary document with the selected text.
@@ -535,32 +515,7 @@ bool SwViewShell::PrintOrPDFExport(
             pPostItManager->CalcRects();
             pPostItManager->LayoutPostIts();
             pPostItManager->DrawNotesForPage(pOutDev, nPage-1);
-
-            //Stop recording now
-            pMetaFile->Stop();
-            pMetaFile->WindStart();
-            //Enable output to the device again
-            pOutDev->EnableOutput();
-            //Restore the original recorder
-            pOutDev->SetConnectMetaFile(pOrigRecorder);
-
-            //Now scale the recorded page down so the notes
-            //will fit in the final page
-            double fScale = 0.75;
-            tools::Long nOrigHeight = pStPage->getFrameArea().Height();
-            tools::Long nNewHeight = nOrigHeight*fScale;
-            tools::Long nShiftY = (nOrigHeight-nNewHeight)/2;
-            pMetaFile->Scale( fScale, fScale );
-            pMetaFile->WindStart();
-            //Move the scaled page down to center it
-            //the other variant of Move does not map pixels
-            //back to the logical units correctly
-            pMetaFile->Move(0, convertTwipToMm100(nShiftY), 
pOutDev->GetDPIX(), pOutDev->GetDPIY());
-            pMetaFile->WindStart();
-
-            //play back the scaled page
-            pMetaFile->Play(*pOutDev);
-            pMetaFile.reset();
+            oOrigHeight.emplace(pStPage->getFrameArea().Height());
         }
     }
 
@@ -570,6 +525,22 @@ bool SwViewShell::PrintOrPDFExport(
     // output device is now provided by a call from outside the Writer)
     pOutDev->Pop();
 
+    // avoid a warning about unbalanced Push/Pop by doing this last:
+    if (oOrigHeight)
+    {
+        // fdo#36815 Now scale the recorded page down so the comments in
+        // margins will fit in the final page
+        double fScale = 0.75;
+        tools::Long nNewHeight = *oOrigHeight*fScale;
+        tools::Long nShiftY = (*oOrigHeight-nNewHeight)/2;
+        GDIMetaFile *const pMetaFile = pOutDev->GetConnectMetaFile();
+        pMetaFile->ScaleActions(fScale, fScale);
+        //Move the scaled page down to center it
+        //the other variant of Move does not map pixels
+        //back to the logical units correctly
+        pMetaFile->Move(0, convertTwipToMm100(nShiftY), pOutDev->GetDPIX(), 
pOutDev->GetDPIY());
+    }
+
     return true;
 }
 
diff --git a/vcl/source/gdi/gdimtf.cxx b/vcl/source/gdi/gdimtf.cxx
index e8bb8ba7e0bd..313d03811780 100644
--- a/vcl/source/gdi/gdimtf.cxx
+++ b/vcl/source/gdi/gdimtf.cxx
@@ -727,7 +727,7 @@ void GDIMetaFile::Move( tools::Long nX, tools::Long nY, 
tools::Long nDPIX, tools
     }
 }
 
-void GDIMetaFile::Scale( double fScaleX, double fScaleY )
+void GDIMetaFile::ScaleActions(double const fScaleX, double const fScaleY)
 {
     for( MetaAction* pAct = FirstAction(); pAct; pAct = NextAction() )
     {
@@ -743,6 +743,11 @@ void GDIMetaFile::Scale( double fScaleX, double fScaleY )
 
         pModAct->Scale( fScaleX, fScaleY );
     }
+}
+
+void GDIMetaFile::Scale( double fScaleX, double fScaleY )
+{
+    ScaleActions(fScaleX, fScaleY);
 
     m_aPrefSize.setWidth( FRound( m_aPrefSize.Width() * fScaleX ) );
     m_aPrefSize.setHeight( FRound( m_aPrefSize.Height() * fScaleY ) );

Reply via email to