[Libreoffice-commits] core.git: include/vcl vcl/source

Miklos Vajna vmiklos at collabora.co.uk
Fri Feb 17 19:26:24 UTC 2017


 include/vcl/pdfwriter.hxx          |    2 -
 vcl/source/gdi/pdfwriter.cxx       |    4 +-
 vcl/source/gdi/pdfwriter_impl.cxx  |   51 +++++++++++++++++++++++++++++++------
 vcl/source/gdi/pdfwriter_impl.hxx  |    9 ++++--
 vcl/source/gdi/pdfwriter_impl2.cxx |    2 -
 5 files changed, 53 insertions(+), 15 deletions(-)

New commits:
commit 42c0dfbd6b08ecbc5893595a4100d572a3082d8a
Author: Miklos Vajna <vmiklos at collabora.co.uk>
Date:   Fri Feb 17 17:58:43 2017 +0100

    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 at collabora.co.uk>
    Tested-by: Jenkins <ci at libreoffice.org>

diff --git a/include/vcl/pdfwriter.hxx b/include/vcl/pdfwriter.hxx
index c660f16..a034654 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 cda66dd..cb56a0e 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 9673087..8eb3fad 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 da953cc..14b41db 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 bbfb717..ea89ffe 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())
             {


More information about the Libreoffice-commits mailing list