tdf#108037 speed up exporting large pdf (2)

reduce the number of allocations we need to do for OStringBuffer

Shaves 2% off the convert time.

Change-Id: I0852c870b3c9e1941213f80f359d00cb8ee391df
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162879
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
diff --git a/vcl/inc/pdf/pdfwriter_impl.hxx b/vcl/inc/pdf/pdfwriter_impl.hxx
index 090f3e09..483201f 100644
--- a/vcl/inc/pdf/pdfwriter_impl.hxx
+++ b/vcl/inc/pdf/pdfwriter_impl.hxx
@@ -824,6 +824,10 @@ private:

    ::comphelper::Hash                      m_DocDigest;

    // reduce repeated allocations
    OStringBuffer                           updateGraphicsStateLine{256};
    OStringBuffer                           drawBitmapLine{80};

    sal_uInt64 getCurrentFilePosition()
    {
        sal_uInt64 nPosition{};
diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx
index 3a86641..11a62a1 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -9795,35 +9795,36 @@ void PDFWriterImpl::drawJPGBitmap( SvStream& rDCTData, bool bIsTrueColor, const 

void PDFWriterImpl::drawBitmap( const Point& rDestPoint, const Size& rDestSize, const BitmapEmit& rBitmap, const Color& rFillColor )
{
    OStringBuffer aLine( 80 );
    OStringBuffer& rLine = drawBitmapLine;
    rLine.setLength(0);
    updateGraphicsState();

    aLine.append( "q " );
    rLine.append( "q " );
    if( rFillColor != COL_TRANSPARENT )
    {
        appendNonStrokingColor( rFillColor, aLine );
        aLine.append( ' ' );
        appendNonStrokingColor( rFillColor, rLine );
        rLine.append( ' ' );
    }
    sal_Int32 nCheckWidth = 0;
    m_aPages.back().appendMappedLength( static_cast<sal_Int32>(rDestSize.Width()), aLine, false, &nCheckWidth );
    aLine.append( " 0 0 " );
    m_aPages.back().appendMappedLength( static_cast<sal_Int32>(rDestSize.Width()), rLine, false, &nCheckWidth );
    rLine.append( " 0 0 " );
    sal_Int32 nCheckHeight = 0;
    m_aPages.back().appendMappedLength( static_cast<sal_Int32>(rDestSize.Height()), aLine, true, &nCheckHeight );
    aLine.append( ' ' );
    m_aPages.back().appendPoint( rDestPoint + Point( 0, rDestSize.Height()-1 ), aLine );
    aLine.append( " cm\n/Im" );
    m_aPages.back().appendMappedLength( static_cast<sal_Int32>(rDestSize.Height()), rLine, true, &nCheckHeight );
    rLine.append( ' ' );
    m_aPages.back().appendPoint( rDestPoint + Point( 0, rDestSize.Height()-1 ), rLine );
    rLine.append( " cm\n/Im" );
    sal_Int32 nObject = rBitmap.m_aReferenceXObject.getObject();
    aLine.append(nObject);
    aLine.append( " Do Q\n" );
    rLine.append(nObject);
    rLine.append( " Do Q\n" );
    if( nCheckWidth == 0 || nCheckHeight == 0 )
    {
        // #i97512# avoid invalid current matrix
        aLine.setLength( 0 );
        aLine.append( "\n%bitmap image /Im" );
        aLine.append( rBitmap.m_nObject );
        aLine.append( " scaled to zero size, omitted\n" );
        rLine.setLength( 0 );
        rLine.append( "\n%bitmap image /Im" );
        rLine.append( rBitmap.m_nObject );
        rLine.append( " scaled to zero size, omitted\n" );
    }
    writeBuffer( aLine );
    writeBuffer( rLine );
}

const BitmapEmit& PDFWriterImpl::createBitmapEmit(const BitmapEx& i_rBitmap, const Graphic& rGraphic, std::list<BitmapEmit>& rBitmaps, ResourceDict& rResourceDict, std::list<StreamRedirect>& rOutputStreams)
@@ -10145,9 +10146,10 @@ void PDFWriterImpl::drawWallpaper( const tools::Rectangle& rRect, const Wallpape
    }
}

void PDFWriterImpl::updateGraphicsState(Mode const mode)
 void PDFWriterImpl::updateGraphicsState(Mode const mode)
{
    OStringBuffer aLine( 256 );
    OStringBuffer& rLine = updateGraphicsStateLine;
    rLine.setLength(0);
    GraphicsState& rNewState = m_aGraphicsStack.front();
    // first set clip region since it might invalidate everything else

@@ -10160,7 +10162,7 @@ void PDFWriterImpl::updateGraphicsState(Mode const mode)
        {
            if( m_aCurrentPDFState.m_bClipRegion )
            {
                aLine.append( "Q " );
                rLine.append( "Q " );
                // invalidate everything but the clip region
                m_aCurrentPDFState = GraphicsState();
                rNewState.m_nUpdateFlags = ~GraphicsStateUpdateFlags::ClipRegion;
@@ -10173,19 +10175,19 @@ void PDFWriterImpl::updateGraphicsState(Mode const mode)
                SetMapMode( rNewState.m_aMapMode );
                m_aCurrentPDFState.m_aMapMode = rNewState.m_aMapMode;

                aLine.append("q ");
                rLine.append("q ");
                if ( rNewState.m_aClipRegion.count() )
                {
                    m_aPages.back().appendPolyPolygon( rNewState.m_aClipRegion, aLine );
                    m_aPages.back().appendPolyPolygon( rNewState.m_aClipRegion, rLine );
                }
                else
                {
                    // tdf#130150 Need to revert tdf#99680, that breaks the
                    // rule that an set but empty clip-region clips everything
                    // aka draws nothing -> nothing is in an empty clip-region
                    aLine.append( "0 0 m h " ); // NULL clip, i.e. nothing visible
                    rLine.append( "0 0 m h " ); // NULL clip, i.e. nothing visible
                }
                aLine.append( "W* n\n" );
                rLine.append( "W* n\n" );

                rNewState.m_aMapMode = std::move(aNewMapMode);
                SetMapMode( rNewState.m_aMapMode );
@@ -10224,8 +10226,8 @@ void PDFWriterImpl::updateGraphicsState(Mode const mode)
        if( m_aCurrentPDFState.m_aLineColor != rNewState.m_aLineColor &&
            rNewState.m_aLineColor != COL_TRANSPARENT )
        {
            appendStrokingColor( rNewState.m_aLineColor, aLine );
            aLine.append( "\n" );
            appendStrokingColor( rNewState.m_aLineColor, rLine );
            rLine.append( "\n" );
        }
    }

@@ -10235,8 +10237,8 @@ void PDFWriterImpl::updateGraphicsState(Mode const mode)
        if( m_aCurrentPDFState.m_aFillColor != rNewState.m_aFillColor &&
            rNewState.m_aFillColor != COL_TRANSPARENT )
        {
            appendNonStrokingColor( rNewState.m_aFillColor, aLine );
            aLine.append( "\n" );
            appendNonStrokingColor( rNewState.m_aFillColor, rLine );
            rLine.append( "\n" );
        }
    }

@@ -10251,8 +10253,8 @@ void PDFWriterImpl::updateGraphicsState(Mode const mode)

    // everything is up to date now
    m_aCurrentPDFState = m_aGraphicsStack.front();
    if ((mode != Mode::NOWRITE) &&  !aLine.isEmpty())
        writeBuffer( aLine );
    if ((mode != Mode::NOWRITE) &&  !rLine.isEmpty())
        writeBuffer( rLine );
}

/* #i47544# imitate OutputDevice behaviour: