vcl/inc/pdf/pdfwriter_impl.hxx | 4 ++ vcl/source/gdi/pdfwriter_impl.cxx | 62 +++++++++++++++++++------------------- 2 files changed, 36 insertions(+), 30 deletions(-)
New commits: commit ffb6133176d5bc1824b15893b2cf1a80aea6aa02 Author: Noel Grandin <[email protected]> AuthorDate: Thu Feb 1 15:47:33 2024 +0200 Commit: Noel Grandin <[email protected]> CommitDate: Mon Feb 5 15:41:27 2024 +0100 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 <[email protected]> diff --git a/vcl/inc/pdf/pdfwriter_impl.hxx b/vcl/inc/pdf/pdfwriter_impl.hxx index 090f3e090c35..483201f624fd 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 3a86641ae9fb..11a62a156bb0 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 /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 /Im" ); sal_Int32 nObject = rBitmap.m_aReferenceXObject.getObject(); - aLine.append(nObject); - aLine.append( " Do Q " ); + rLine.append(nObject); + rLine.append( " Do Q " ); if( nCheckWidth == 0 || nCheckHeight == 0 ) { // #i97512# avoid invalid current matrix - aLine.setLength( 0 ); - aLine.append( " %bitmap image /Im" ); - aLine.append( rBitmap.m_nObject ); - aLine.append( " scaled to zero size, omitted " ); + rLine.setLength( 0 ); + rLine.append( " %bitmap image /Im" ); + rLine.append( rBitmap.m_nObject ); + rLine.append( " scaled to zero size, omitted " ); } - 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 " ); + rLine.append( "W* 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( " " ); + appendStrokingColor( rNewState.m_aLineColor, rLine ); + rLine.append( " " ); } } @@ -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( " " ); + appendNonStrokingColor( rNewState.m_aFillColor, rLine ); + rLine.append( " " ); } } @@ -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:
