summaryrefslogtreecommitdiff
path: root/sdext
diff options
context:
space:
mode:
authorDr. David Alan Gilbert <dave@treblig.org>2024-02-18 21:45:42 +0000
committerNoel Grandin <noel.grandin@collabora.co.uk>2024-02-29 08:22:38 +0100
commit8ac5f40b330c6cd248073b8686c05f566ecd7195 (patch)
tree845fae018407ca83ea6c933ea07f050fa5939d89 /sdext
parent8e4a351f12d777ad9102086298741d0a97e5eeb9 (diff)
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.grandin@collabora.co.uk>
Diffstat (limited to 'sdext')
-rw-r--r--sdext/source/pdfimport/xpdfwrapper/pdfioutdev_gpl.cxx64
1 files changed, 62 insertions, 2 deletions
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;