[poppler] qt4/src splash/SplashBitmap.cc splash/SplashBitmap.h

Albert Astals Cid aacid at kemper.freedesktop.org
Fri Nov 2 14:48:46 PDT 2012


 qt4/src/poppler-document.cc |   23 +++++++++++---
 qt4/src/poppler-page.cc     |   38 +++++++++++++----------
 qt4/src/poppler-private.h   |   69 ++++++++++++++++++++++++++++---------------
 qt4/src/poppler-qt4.h       |   11 ++++++
 splash/SplashBitmap.cc      |   70 ++++++++++++++++++++++++++++++++++++++++++++
 splash/SplashBitmap.h       |    5 ++-
 6 files changed, 169 insertions(+), 47 deletions(-)

New commits:
commit ef11b4f0e642dff0be02bf3327eb56bf0b364847
Author: Thomas Freitag <Thomas.Freitag at alfa.de>
Date:   Fri Nov 2 22:44:27 2012 +0100

    Implement overprint in qt interface
    
    With minor api fixes by me (Albert Astals Cid)

diff --git a/qt4/src/poppler-document.cc b/qt4/src/poppler-document.cc
index e89b51e..0cf1d45 100644
--- a/qt4/src/poppler-document.cc
+++ b/qt4/src/poppler-document.cc
@@ -5,6 +5,7 @@
  * Copyright (C) 2006-2010, Pino Toscano <pino at kde.org>
  * Copyright (C) 2010, 2011 Hib Eris <hib at hiberis.nl>
  * Copyright (C) 2012 Koji Otani <sho at bbr.jp>
+ * Copyright (C) 2012 Thomas Freitag <Thomas.Freitag at alfa.de>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -519,14 +520,20 @@ namespace Poppler {
 
     void Document::setRenderHint( Document::RenderHint hint, bool on )
     {
+        const bool touchesAntialias = hint & ( Document::Antialiasing | Document::TextAntialiasing | Document::TextHinting );
+        const bool touchesOverprinting = hint & Document::OverprintPreview;
+        
+        int hintForOperation = hint;
+        if (touchesOverprinting && !isOverprintPreviewAvailable())
+            hintForOperation = hintForOperation & ~(int)Document::OverprintPreview;
+
         if ( on )
-            m_doc->m_hints |= hint;
+            m_doc->m_hints |= hintForOperation;
         else
-            m_doc->m_hints &= ~(int)hint;
+            m_doc->m_hints &= ~hintForOperation;
 
         // the only way to set antialiasing for Splash is on creation
-        if ( m_doc->m_backend == Document::SplashBackend &&
-             ( hint & ( Document::Antialiasing | Document::TextAntialiasing | Document::TextHinting ) ) )
+        if ( m_doc->m_backend == Document::SplashBackend && (touchesAntialias || touchesOverprinting) )
         {
             delete m_doc->m_outputDev;
             m_doc->m_outputDev = NULL;
@@ -645,4 +652,12 @@ namespace Poppler {
 #endif
     }
 
+    bool isOverprintPreviewAvailable() {
+#if defined(SPLASH_CMYK)
+        return true;
+#else
+        return false;
+#endif
+   }
+
 }
diff --git a/qt4/src/poppler-page.cc b/qt4/src/poppler-page.cc
index 03aa1bb..5475614 100644
--- a/qt4/src/poppler-page.cc
+++ b/qt4/src/poppler-page.cc
@@ -13,6 +13,7 @@
  * Copyright (C) 2012 Tobias Koenig <tokoe at kdab.com>
  * Copyright (C) 2012 Fabio D'Urso <fabiodurso at hotmail.it>
  * Copyright (C) 2012 Adam Reichold <adamreichold at myopera.com>
+ * Copyright (C) 2012 Thomas Freitag <Thomas.Freitag at alfa.de>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -266,27 +267,30 @@ QImage Page::renderToImage(double xres, double yres, int x, int y, int w, int h,
       int bw = bitmap->getWidth();
       int bh = bitmap->getHeight();
 
-      SplashColorPtr dataPtr = splash_output->getBitmap()->getDataPtr();
-
-      if (QSysInfo::BigEndian == QSysInfo::ByteOrder)
+      if (bitmap->convertToXBGR())
       {
-        uchar c;
-        int count = bw * bh * 4;
-        for (int k = 0; k < count; k += 4)
-        {
-          c = dataPtr[k];
-          dataPtr[k] = dataPtr[k+3];
-          dataPtr[k+3] = c;
+        SplashColorPtr dataPtr = bitmap->getDataPtr();
 
-          c = dataPtr[k+1];
-          dataPtr[k+1] = dataPtr[k+2];
-          dataPtr[k+2] = c;
+        if (QSysInfo::BigEndian == QSysInfo::ByteOrder)
+        {
+            uchar c;
+            int count = bw * bh * 4;
+            for (int k = 0; k < count; k += 4)
+            {
+            c = dataPtr[k];
+            dataPtr[k] = dataPtr[k+3];
+            dataPtr[k+3] = c;
+
+            c = dataPtr[k+1];
+            dataPtr[k+1] = dataPtr[k+2];
+            dataPtr[k+2] = c;
+            }
         }
-      }
 
-      // construct a qimage SHARING the raw bitmap data in memory
-      QImage tmpimg( dataPtr, bw, bh, QImage::Format_ARGB32 );
-      img = tmpimg.copy();
+        // construct a qimage SHARING the raw bitmap data in memory
+        QImage tmpimg( dataPtr, bw, bh, QImage::Format_ARGB32 );
+        img = tmpimg.copy();
+      }
       // unload underlying xpdf bitmap
       splash_output->startPage( 0, NULL );
 #endif
diff --git a/qt4/src/poppler-private.h b/qt4/src/poppler-private.h
index 6d2ef2a..5a9e1b8 100644
--- a/qt4/src/poppler-private.h
+++ b/qt4/src/poppler-private.h
@@ -1,10 +1,11 @@
 /* poppler-private.h: qt interface to poppler
  * Copyright (C) 2005, Net Integration Technologies, Inc.
  * Copyright (C) 2005, 2008, Brad Hards <bradh at frogmouth.net>
- * Copyright (C) 2006-2009, 2011 by Albert Astals Cid <aacid at kde.org>
+ * Copyright (C) 2006-2009, 2011, 2012 by Albert Astals Cid <aacid at kde.org>
  * Copyright (C) 2007-2009, 2011 by Pino Toscano <pino at kde.org>
  * Copyright (C) 2011 Andreas Hartmetz <ahartmetz at gmail.com>
  * Copyright (C) 2011 Hib Eris <hib at hiberis.nl>
+ * Copyright (C) 2012 Thomas Freitag <Thomas.Freitag at alfa.de>
  * Inspired on code by
  * Copyright (C) 2004 by Albert Astals Cid <tsdgeos at terra.es>
  * Copyright (C) 2004 by Enrico Ros <eros.kde at email.it>
@@ -124,11 +125,46 @@ namespace Poppler {
 			{
 #if defined(HAVE_SPLASH)
 			SplashColor bgColor;
-			bgColor[0] = paperColor.blue();
-			bgColor[1] = paperColor.green();
-			bgColor[2] = paperColor.red();
+			GBool overprint = m_hints & Document::OverprintPreview ? gTrue : gFalse;
+			globalParams->setOverprintPreview(overprint);
+#if defined(SPLASH_CMYK)
+			if (overprint)
+			{
+				Guchar c, m, y, k;
+
+				c = 255 - paperColor.blue();
+				m = 255 - paperColor.red();
+				y = 255 - paperColor.green();
+				k = c;
+				if (m < k) {
+					k = m;
+				}
+				if (y < k) {
+					k = y;
+				}
+				bgColor[0] = c - k;
+				bgColor[1] = m - k;
+				bgColor[2] = y - k;
+				bgColor[3] = k;
+				for (int i = 4; i < SPOT_NCOMPS + 4; i++) {
+					bgColor[i] = 0;
+				}
+			}
+			else
+#endif
+			{
+				bgColor[0] = paperColor.blue();
+				bgColor[1] = paperColor.green();
+				bgColor[2] = paperColor.red();
+			}
 			GBool AA = m_hints & Document::TextAntialiasing ? gTrue : gFalse;
-			SplashOutputDev * splashOutputDev = new SplashOutputDev(splashModeXBGR8, 4, gFalse, bgColor, gTrue, AA);
+			SplashOutputDev * splashOutputDev = new SplashOutputDev(
+#if defined(SPLASH_CMYK)
+				(overprint) ? splashModeDeviceN8 : splashModeXBGR8,
+#else
+				splashModeXBGR8,
+#endif 
+				4, gFalse, bgColor, gTrue, AA);
 			splashOutputDev->setVectorAntialias(m_hints & Document::Antialiasing ? gTrue : gFalse);
 			splashOutputDev->setFreeTypeHinting(m_hints & Document::TextHinting ? gTrue : gFalse, m_hints & Document::TextSlightHinting ? gTrue : gFalse);
 			splashOutputDev->startDoc(doc);
@@ -149,25 +185,10 @@ namespace Poppler {
 			return;
 
 		paperColor = color;
-		if ( m_outputDev == NULL )
-			return;
-
-		switch ( m_backend )
-		{
-			case Document::SplashBackend:
-			{
-#if defined(HAVE_SPLASH)
-				SplashOutputDev *splash_output = static_cast<SplashOutputDev *>( m_outputDev );
-				SplashColor bgColor;
-				bgColor[0] = paperColor.blue();
-				bgColor[1] = paperColor.green();
-				bgColor[2] = paperColor.red();
-				splash_output->setPaperColor(bgColor);
-#endif
-				break;
-			}
-			default: ;
-		}
+		
+		// Make sure the new paper color will be picked up for the next rendering
+		delete m_outputDev;
+		m_outputDev = NULL;
 	}
 	
 	void fillMembers()
diff --git a/qt4/src/poppler-qt4.h b/qt4/src/poppler-qt4.h
index 425b1e0..3002e65 100644
--- a/qt4/src/poppler-qt4.h
+++ b/qt4/src/poppler-qt4.h
@@ -13,6 +13,7 @@
  * Copyright (C) 2012, Fabio D'Urso <fabiodurso at hotmail.it>
  * Copyright (C) 2012, Tobias Koenig <tobias.koenig at kdab.com>
  * Copyright (C) 2012 Adam Reichold <adamreichold at myopera.com>
+ * Copyright (C) 2012 Thomas Freitag <Thomas.Freitag at alfa.de>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -846,7 +847,8 @@ delete it;
 	    Antialiasing = 0x00000001,      ///< Antialiasing for graphics
 	    TextAntialiasing = 0x00000002,  ///< Antialiasing for text
 	    TextHinting = 0x00000004,       ///< Hinting for text \since 0.12.1
-	    TextSlightHinting = 0x00000008  ///< Lighter hinting for text when combined with TextHinting \since 0.18
+	    TextSlightHinting = 0x00000008, ///< Lighter hinting for text when combined with TextHinting \since 0.18
+	    OverprintPreview = 0x00000010   ///< Overprint preview \since 0.22
 	};
 	Q_DECLARE_FLAGS( RenderHints, RenderHint )
 
@@ -1624,6 +1626,13 @@ height = dummy.height();
        \since 0.12
     */
     POPPLER_QT4_EXPORT bool isCmsAvailable();
+    
+    /**
+       Whether the overprint preview functionality is available.
+
+       \since 0.22
+    */
+    POPPLER_QT4_EXPORT bool isOverprintPreviewAvailable();
 
     class SoundData;
     /**
diff --git a/splash/SplashBitmap.cc b/splash/SplashBitmap.cc
index 5fe61a2..996f0aa 100644
--- a/splash/SplashBitmap.cc
+++ b/splash/SplashBitmap.cc
@@ -441,6 +441,76 @@ void SplashBitmap::getRGBLine(int yl, SplashColorPtr line) {
   }
 }
 
+void SplashBitmap::getXBGRLine(int yl, SplashColorPtr line) {
+  SplashColor col;
+  double c, m, y, k, c1, m1, y1, k1, r, g, b;
+
+  for (int x = 0; x < width; x++) {
+    getPixel(x, yl, col);
+    c = byteToDbl(col[0]);
+    m = byteToDbl(col[1]);
+    y = byteToDbl(col[2]);
+    k = byteToDbl(col[3]);
+#if SPLASH_CMYK
+    if (separationList->getLength() > 0) {
+      for (int i = 0; i < separationList->getLength(); i++) {
+        if (col[i+4] > 0) {
+          GfxCMYK cmyk;
+          GfxColor input;
+          input.c[0] = byteToCol(col[i+4]);
+          GfxSeparationColorSpace *sepCS = (GfxSeparationColorSpace *)separationList->get(i);
+          sepCS->getCMYK(&input, &cmyk);
+          col[0] = colToByte(cmyk.c);
+          col[1] = colToByte(cmyk.m);
+          col[2] = colToByte(cmyk.y);
+          col[3] = colToByte(cmyk.k);
+          c += byteToDbl(col[0]);
+          m += byteToDbl(col[1]);
+          y += byteToDbl(col[2]);
+          k += byteToDbl(col[3]);
+        }
+      }
+      if (c > 1) c = 1;
+      if (m > 1) m = 1;
+      if (y > 1) y = 1;
+      if (k > 1) k = 1;
+    }
+#endif
+    c1 = 1 - c;
+    m1 = 1 - m;
+    y1 = 1 - y;
+    k1 = 1 - k;
+    cmykToRGBMatrixMultiplication(c, m, y, k, c1, m1, y1, k1, r, g, b);
+    *line++ = dblToByte(clip01(b));
+    *line++ = dblToByte(clip01(g));
+    *line++ = dblToByte(clip01(r));
+    *line++ = 255;
+  }
+}
+
+GBool SplashBitmap::convertToXBGR() {
+  if (mode == splashModeXBGR8)
+    return gTrue;
+  
+  int newrowSize = width * 4;
+  SplashColorPtr newdata = (SplashColorPtr)gmallocn_checkoverflow(newrowSize, height);
+  if (newdata != NULL) {
+    for (int y = 0; y < height; y++) {
+      unsigned char *row = newdata + y * newrowSize;
+      getXBGRLine(y, row);
+    }
+    if (rowSize < 0) {
+      gfree(data + (height - 1) * rowSize);
+    } else {
+      gfree(data);
+    }
+    data = newdata;
+    rowSize = newrowSize;
+    mode = splashModeXBGR8;
+  }
+  return newdata != NULL;
+}
+
 #if SPLASH_CMYK
 void SplashBitmap::getCMYKLine(int yl, SplashColorPtr line) {
   SplashColor col;
diff --git a/splash/SplashBitmap.h b/splash/SplashBitmap.h
index 0bff205..70509ab 100644
--- a/splash/SplashBitmap.h
+++ b/splash/SplashBitmap.h
@@ -13,7 +13,7 @@
 //
 // Copyright (C) 2007 Ilmari Heikkinen <ilmari.heikkinen at gmail.com>
 // Copyright (C) 2009 Shen Liang <shenzhuxi at gmail.com>
-// Copyright (C) 2009 Albert Astals Cid <aacid at kde.org>
+// Copyright (C) 2009, 2012 Albert Astals Cid <aacid at kde.org>
 // Copyright (C) 2009 Stefan Thomas <thomas at eload24.com>
 // Copyright (C) 2010 Adrian Johnson <ajohnson at redneon.com>
 // Copyright (C) 2010 Harry Roberts <harry.roberts at midnight-labs.org>
@@ -75,8 +75,11 @@ public:
   SplashError writeImgFile(SplashImageFileFormat format, FILE *f, int hDPI, int vDPI, const char *compressionString = "");
   SplashError writeImgFile(ImgWriter *writer, FILE *f, int hDPI, int vDPI);
 
+  GBool convertToXBGR();
+
   void getPixel(int x, int y, SplashColorPtr pixel);
   void getRGBLine(int y, SplashColorPtr line);
+  void getXBGRLine(int y, SplashColorPtr line);
 #if SPLASH_CMYK
   void getCMYKLine(int y, SplashColorPtr line);
 #endif


More information about the poppler mailing list