diff options
author | Miklos Vajna <vmiklos@collabora.co.uk> | 2017-02-17 17:58:43 +0100 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.co.uk> | 2017-03-14 12:28:16 +0100 |
commit | e352169285ce4f45167a60557e969722895712d4 (patch) | |
tree | 7323a3733f2601281ff588459e51125932422f84 /vcl | |
parent | a44d89f495e34a1233ef902d01b42e60a7a5132c (diff) |
tdf#106059 PDF export: write form XObject proxy for PDF images
PDF allows referencing a page of an existing (embedded) PDF file
together with a fallback bitmap, but this is only allowed for form
XObjects, not for image XObjects.
So case the image is a PDF one, wrap the image XObject in a form
XObject, that will allow later referring to the embedded PDF image.
Change-Id: I30839dd6696f1fddd8ca2caa0d33123e90fcedbc
Reviewed-on: https://gerrit.libreoffice.org/34376
Reviewed-by: Miklos Vajna <vmiklos@collabora.co.uk>
Tested-by: Jenkins <ci@libreoffice.org>
(cherry picked from commit 42c0dfbd6b08ecbc5893595a4100d572a3082d8a)
Diffstat (limited to 'vcl')
-rw-r--r-- | vcl/source/gdi/pdfwriter.cxx | 4 | ||||
-rw-r--r-- | vcl/source/gdi/pdfwriter_impl.cxx | 51 | ||||
-rw-r--r-- | vcl/source/gdi/pdfwriter_impl.hxx | 9 | ||||
-rw-r--r-- | vcl/source/gdi/pdfwriter_impl2.cxx | 2 |
4 files changed, 52 insertions, 14 deletions
diff --git a/vcl/source/gdi/pdfwriter.cxx b/vcl/source/gdi/pdfwriter.cxx index cda66dd642db..cb56a0e0953f 100644 --- a/vcl/source/gdi/pdfwriter.cxx +++ b/vcl/source/gdi/pdfwriter.cxx @@ -186,9 +186,9 @@ void PDFWriter::DrawPixel( const Point& rPos, const Color& rColor ) xImplementation->drawPixel( rPos, rColor ); } -void PDFWriter::DrawBitmap( const Point& rDestPt, const Size& rDestSize, const Bitmap& rBitmap ) +void PDFWriter::DrawBitmap( const Point& rDestPt, const Size& rDestSize, const Bitmap& rBitmap, const Graphic& rGraphic ) { - xImplementation->drawBitmap( rDestPt, rDestSize, rBitmap ); + xImplementation->drawBitmap( rDestPt, rDestSize, rBitmap, rGraphic ); } void PDFWriter::DrawBitmapEx( const Point& rDestPt, const Size& rDestSize, const BitmapEx& rBitmap ) diff --git a/vcl/source/gdi/pdfwriter_impl.cxx b/vcl/source/gdi/pdfwriter_impl.cxx index 82e6ceb1dd90..57e926a6d969 100644 --- a/vcl/source/gdi/pdfwriter_impl.cxx +++ b/vcl/source/gdi/pdfwriter_impl.cxx @@ -12011,6 +12011,37 @@ bool PDFWriterImpl::writeBitmapObject( BitmapEmit& rObject, bool bMask ) return writeBitmapObject( aEmit, true ); } + // Write the form XObject proxy for the image. + if (rObject.m_nFormObject > 0) + { + aLine.setLength(0); + if (!updateObject(rObject.m_nFormObject)) + return false; + + aLine.append(rObject.m_nFormObject); + aLine.append(" 0 obj\n"); + aLine.append("<< /Type /XObject"); + aLine.append(" /Subtype /Form"); + aLine.append(" /Resources << /XObject<</Im"); + aLine.append(rObject.m_nObject); + aLine.append(" "); + aLine.append(rObject.m_nObject); + aLine.append(" 0 R>> >>"); + aLine.append(" /BBox [ 0 0 1 1 ]"); + aLine.append(" /Length "); + + OStringBuffer aStream; + aStream.append("/Im"); + aStream.append(rObject.m_nObject); + aStream.append(" Do"); + aLine.append(aStream.getLength()); + + aLine.append(">>\nstream\n"); + aLine.append(aStream.getStr()); + aLine.append("\nendstream\nendobj\n\n"); + CHECK_RETURN(writeBuffer(aLine.getStr(), aLine.getLength())); + } + return true; } @@ -12123,7 +12154,8 @@ void PDFWriterImpl::drawBitmap( const Point& rDestPoint, const Size& rDestSize, aLine.append( ' ' ); m_aPages.back().appendPoint( rDestPoint + Point( 0, rDestSize.Height()-1 ), aLine ); aLine.append( " cm\n/Im" ); - aLine.append( rBitmap.m_nObject ); + sal_Int32 nObject = rBitmap.m_nFormObject > 0 ? rBitmap.m_nFormObject : rBitmap.m_nObject; + aLine.append(nObject); aLine.append( " Do Q\n" ); if( nCheckWidth == 0 || nCheckHeight == 0 ) { @@ -12136,7 +12168,7 @@ void PDFWriterImpl::drawBitmap( const Point& rDestPoint, const Size& rDestSize, writeBuffer( aLine.getStr(), aLine.getLength() ); } -const PDFWriterImpl::BitmapEmit& PDFWriterImpl::createBitmapEmit( const BitmapEx& i_rBitmap ) +const PDFWriterImpl::BitmapEmit& PDFWriterImpl::createBitmapEmit( const BitmapEx& i_rBitmap, const Graphic& rGraphic ) { BitmapEx aBitmap( i_rBitmap ); if( m_aContext.ColorMode == PDFWriter::DrawGreyscale ) @@ -12173,18 +12205,21 @@ const PDFWriterImpl::BitmapEmit& PDFWriterImpl::createBitmapEmit( const BitmapEx m_aBitmaps.front().m_aID = aID; m_aBitmaps.front().m_aBitmap = aBitmap; m_aBitmaps.front().m_nObject = createObject(); + if (rGraphic.getPdfData().hasElements()) + m_aBitmaps.front().m_nFormObject = createObject(); it = m_aBitmaps.begin(); } OStringBuffer aObjName( 16 ); aObjName.append( "Im" ); - aObjName.append( it->m_nObject ); - pushResource( ResXObject, aObjName.makeStringAndClear(), it->m_nObject ); + sal_Int32 nObject = it->m_nFormObject > 0 ? it->m_nFormObject : it->m_nObject; + aObjName.append(nObject); + pushResource( ResXObject, aObjName.makeStringAndClear(), nObject ); return *it; } -void PDFWriterImpl::drawBitmap( const Point& rDestPoint, const Size& rDestSize, const Bitmap& rBitmap ) +void PDFWriterImpl::drawBitmap( const Point& rDestPoint, const Size& rDestSize, const Bitmap& rBitmap, const Graphic& rGraphic ) { MARK( "drawBitmap (Bitmap)" ); @@ -12192,7 +12227,7 @@ void PDFWriterImpl::drawBitmap( const Point& rDestPoint, const Size& rDestSize, if( ! (rDestSize.Width() && rDestSize.Height()) ) return; - const BitmapEmit& rEmit = createBitmapEmit( BitmapEx( rBitmap ) ); + const BitmapEmit& rEmit = createBitmapEmit( BitmapEx( rBitmap ), rGraphic ); drawBitmap( rDestPoint, rDestSize, rEmit, Color( COL_TRANSPARENT ) ); } @@ -12204,7 +12239,7 @@ void PDFWriterImpl::drawBitmap( const Point& rDestPoint, const Size& rDestSize, if( ! (rDestSize.Width() && rDestSize.Height()) ) return; - const BitmapEmit& rEmit = createBitmapEmit( rBitmap ); + const BitmapEmit& rEmit = createBitmapEmit( rBitmap, Graphic() ); drawBitmap( rDestPoint, rDestSize, rEmit, Color( COL_TRANSPARENT ) ); } @@ -12380,7 +12415,7 @@ void PDFWriterImpl::drawWallpaper( const Rectangle& rRect, const Wallpaper& rWal else { // push the bitmap - const BitmapEmit& rEmit = createBitmapEmit( BitmapEx( aBitmap ) ); + const BitmapEmit& rEmit = createBitmapEmit( BitmapEx( aBitmap ), Graphic() ); // convert to page coordinates; this needs to be done here // since the emit does not know the page anymore diff --git a/vcl/source/gdi/pdfwriter_impl.hxx b/vcl/source/gdi/pdfwriter_impl.hxx index d082d25183ce..0516f242f08e 100644 --- a/vcl/source/gdi/pdfwriter_impl.hxx +++ b/vcl/source/gdi/pdfwriter_impl.hxx @@ -195,9 +195,12 @@ public: BitmapID m_aID; BitmapEx m_aBitmap; sal_Int32 m_nObject; + /// ID of the Form XObject, if any. + sal_Int32 m_nFormObject; BitmapEmit() - : m_nObject(0) + : m_nObject(0), + m_nFormObject(0) { } }; @@ -826,7 +829,7 @@ i12626 /* tries to find the bitmap by its id and returns its emit data if exists, else creates a new emit data block */ - const BitmapEmit& createBitmapEmit( const BitmapEx& rBitmapEx ); + const BitmapEmit& createBitmapEmit( const BitmapEx& rBitmapEx, const Graphic& rGraphic ); /* writes the Do operation inside the content stream */ void drawBitmap( const Point& rDestPt, const Size& rDestSize, const BitmapEmit& rBitmap, const Color& rFillColor ); @@ -1190,7 +1193,7 @@ public: void drawEllipse( const Rectangle& rRect ); void drawArc( const Rectangle& rRect, const Point& rStart, const Point& rStop, bool bWithPie, bool bWidthChord ); - void drawBitmap( const Point& rDestPoint, const Size& rDestSize, const Bitmap& rBitmap ); + void drawBitmap( const Point& rDestPoint, const Size& rDestSize, const Bitmap& rBitmap, const Graphic& rGraphic ); void drawBitmap( const Point& rDestPoint, const Size& rDestSize, const BitmapEx& rBitmap ); void drawJPGBitmap( SvStream& rDCTData, bool bIsTrueColor, const Size& rSizePixel, const Rectangle& rTargetArea, const Bitmap& rMask ); diff --git a/vcl/source/gdi/pdfwriter_impl2.cxx b/vcl/source/gdi/pdfwriter_impl2.cxx index ee5c31122c99..92914883fecf 100644 --- a/vcl/source/gdi/pdfwriter_impl2.cxx +++ b/vcl/source/gdi/pdfwriter_impl2.cxx @@ -247,7 +247,7 @@ void PDFWriterImpl::implWriteBitmapEx( const Point& i_rPoint, const Size& i_rSiz else if ( aBitmapEx.IsTransparent() ) m_rOuterFace.DrawBitmapEx( aPoint, aSize, aBitmapEx ); else - m_rOuterFace.DrawBitmap( aPoint, aSize, aBitmapEx.GetBitmap() ); + m_rOuterFace.DrawBitmap( aPoint, aSize, aBitmapEx.GetBitmap(), i_Graphic ); if (i_Graphic.getPdfData().hasElements()) { |