sdext/source/pdfimport/xpdfwrapper/pdfioutdev_gpl.cxx |   64 +++++++++++++++++-
 1 file changed, 62 insertions(+), 2 deletions(-)

New commits:
commit 8ac5f40b330c6cd248073b8686c05f566ecd7195
Author:     Dr. David Alan Gilbert <d...@treblig.org>
AuthorDate: Sun Feb 18 21:45:42 2024 +0000
Commit:     Noel Grandin <noel.gran...@collabora.co.uk>
CommitDate: Thu Feb 29 08:22:38 2024 +0100

    tdf#113050 sdext.pdfimport: Write the tiling pattern image
    
    Render the tile down to a common format using Splash
    and write it to the stream.
    
    Change-Id: Iccc451d1a02ed2ad77538883ab3fe5542fc633e2
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163562
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk>

diff --git a/sdext/source/pdfimport/xpdfwrapper/pdfioutdev_gpl.cxx 
b/sdext/source/pdfimport/xpdfwrapper/pdfioutdev_gpl.cxx
index e7afe67afef4..57eb30092141 100644
--- a/sdext/source/pdfimport/xpdfwrapper/pdfioutdev_gpl.cxx
+++ b/sdext/source/pdfimport/xpdfwrapper/pdfioutdev_gpl.cxx
@@ -1182,13 +1182,15 @@ void PDFOutDev::setSkipImages( bool bSkipImages )
 }
 
 #if POPPLER_CHECK_VERSION(21, 3, 0)
-poppler_bool PDFOutDev::tilingPatternFill(GfxState *, Gfx *, Catalog *,
+poppler_bool PDFOutDev::tilingPatternFill(GfxState *state, Gfx *, Catalog *,
                                           GfxTilingPattern *tPat, const double 
*mat,
                                           int x0, int y0, int x1, int y1,
                                           double xStep, double yStep)
 {
     const double *pBbox = tPat->getBBox();
     const int nPaintType = tPat->getPaintType();
+    Dict *pResDict = tPat->getResDict();
+    Object *aStr = tPat->getContentStream();
     double nWidth = pBbox[2] - pBbox[0];
     double nHeight = pBbox[3] - pBbox[1];
 
@@ -1215,7 +1217,65 @@ poppler_bool PDFOutDev::tilingPatternFill(GfxState *, 
Gfx *, Catalog *,
             normalize(mat[4]), normalize(mat[5])
             );
 
-    // TODO: Write the image
+    PDFRectangle aBox;
+    aBox.x1 = pBbox[0];
+    aBox.y1 = pBbox[1];
+    aBox.x2 = pBbox[2];
+    aBox.y2 = pBbox[3];
+
+    const int nDPI = 72; // GfxState seems to have 72.0 as magic for some 
reason
+    auto pSplashGfxState = new GfxState(nDPI, nDPI, &aBox, 0, false);
+    auto pSplashOut = new SplashOutputDev(splashModeRGB8, 1, false, nullptr);
+    pSplashOut->setEnableFreeType(false);
+    pSplashOut->startPage(0 /* pageNum */, pSplashGfxState, nullptr /* xref 
*/);
+
+    auto pSplashGfx = new Gfx(m_pDoc, pSplashOut, pResDict, &aBox, nullptr);
+    pSplashGfx->display(aStr);
+    auto pSplashBitmap = pSplashOut->takeBitmap();
+    delete pSplashGfxState;
+    delete pSplashGfx;
+    delete pSplashOut;
+
+    auto nBitmapWidth = static_cast<size_t>(pSplashBitmap->getWidth());
+    auto nBitmapHeight = static_cast<size_t>(pSplashBitmap->getHeight());
+
+    char *pBitmapData = reinterpret_cast<char *>(pSplashBitmap->getDataPtr());
+    if (nPaintType == 2)
+    {
+        // My understanding is Type 2 fills are just bitmaps of *what* to fill
+        // in the current fill colour.
+        // sending it to LO as a flat colour image with the alpha map is 
easiest
+        GfxRGB aCurFill;
+        unsigned char r,g,b;
+        state->getFillColorSpace()->getRGB(state->getFillColor(), &aCurFill);
+        r = colToByte(aCurFill.r);
+        g = colToByte(aCurFill.g);
+        b = colToByte(aCurFill.b);
+
+        for(size_t i=0; i < (nBitmapWidth * nBitmapHeight * 3); i+=3)
+        {
+            pBitmapData[i  ] = r;
+            pBitmapData[i+1] = g;
+            pBitmapData[i+2] = b;
+        }
+    }
+
+    auto pRgbStr = new MemStream(pBitmapData, 0,
+        nBitmapWidth * nBitmapHeight * 3, Object(objNull));
+    auto pAlphaStr = new MemStream(reinterpret_cast<char 
*>(pSplashBitmap->getAlphaPtr()), 0,
+        nBitmapWidth * nBitmapHeight, Object(objNull));
+    auto aDecode = Object(objNull);
+    auto pRgbIdentityColorMap = new GfxImageColorMap(8, &aDecode, new 
GfxDeviceRGBColorSpace());
+    auto pGrayIdentityColorMap = new GfxImageColorMap(8, &aDecode, new 
GfxDeviceGrayColorSpace());
+
+    OutputBuffer aBuf; initBuf(aBuf);
+    writePng_(aBuf, pRgbStr, nBitmapWidth, nBitmapHeight, pRgbIdentityColorMap,
+        pAlphaStr, nBitmapWidth, nBitmapHeight, pGrayIdentityColorMap);
+    writeBinaryBuffer(aBuf);
+
+    delete pAlphaStr;
+    delete pRgbStr;
+    delete pSplashBitmap;
 
     // If we return false here we can fall back to the slow path
     return true;

Reply via email to