summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.co.uk>2017-02-17 17:58:43 +0100
committerMiklos Vajna <vmiklos@collabora.co.uk>2017-02-17 19:26:02 +0000
commit42c0dfbd6b08ecbc5893595a4100d572a3082d8a (patch)
treece205b3c827489d77c4cc7c4e931678fc081f04b
parentb57d51e32fb85e9cde64f85719725253162c42e4 (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>
-rw-r--r--include/vcl/pdfwriter.hxx2
-rw-r--r--vcl/source/gdi/pdfwriter.cxx4
-rw-r--r--vcl/source/gdi/pdfwriter_impl.cxx51
-rw-r--r--vcl/source/gdi/pdfwriter_impl.hxx9
-rw-r--r--vcl/source/gdi/pdfwriter_impl2.cxx2
5 files changed, 53 insertions, 15 deletions
diff --git a/include/vcl/pdfwriter.hxx b/include/vcl/pdfwriter.hxx
index c660f16bf58c..a0346546c43b 100644
--- a/include/vcl/pdfwriter.hxx
+++ b/include/vcl/pdfwriter.hxx
@@ -802,7 +802,7 @@ The following structure describes the permissions used in PDF security
const Point& rStartPt, const Point& rEndPt );
void DrawBitmap( const Point& rDestPt, const Size& rDestSize,
- const Bitmap& rBitmap );
+ const Bitmap& rBitmap, const Graphic& rGraphic );
void DrawBitmapEx( const Point& rDestPt, const Size& rDestSize,
const BitmapEx& rBitmapEx );
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 9673087b237a..8eb3fadad9b4 100644
--- a/vcl/source/gdi/pdfwriter_impl.cxx
+++ b/vcl/source/gdi/pdfwriter_impl.cxx
@@ -11177,6 +11177,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;
}
@@ -11289,7 +11320,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 )
{
@@ -11302,7 +11334,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 )
@@ -11339,18 +11371,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)" );
@@ -11358,7 +11393,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 ) );
}
@@ -11370,7 +11405,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 ) );
}
@@ -11546,7 +11581,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 da953ccea6c0..14b41db7ebbf 100644
--- a/vcl/source/gdi/pdfwriter_impl.hxx
+++ b/vcl/source/gdi/pdfwriter_impl.hxx
@@ -213,9 +213,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)
{
}
};
@@ -821,7 +824,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 );
@@ -1183,7 +1186,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 bbfb7176f719..ea89ffe09608 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())
{