poppler/ArthurOutputDev.cc |  123 +++++++++++++++++++--------------------------
 poppler/ArthurOutputDev.h  |    2 
 qt4/src/poppler-page.cc    |   62 +++++++++++++++-------
 qt4/src/poppler-qt4.h      |   65 +++++++++++++++++++++++
 4 files changed, 162 insertions(+), 90 deletions(-)

New commits:
commit f077e82af0724be88d28c896a3c208f1d50ccff9
Author: Pino Toscano <[email protected]>
Date:   Sun Nov 7 21:50:48 2010 +0100

    [qt4] New Page::renderToPainter()
    
    This new painter-based painting function ican be used for painting (with 
Arthur only for now) without getting an image first.
    Also add a new flag type for it, with a single item telling whether do not 
save+restore the provided painter.
    
    Mostly based on a patch by Matthias Fauconneau 
([email protected]), thanks!

diff --git a/qt4/src/poppler-page.cc b/qt4/src/poppler-page.cc
index 293d09b..1b55c33 100644
--- a/qt4/src/poppler-page.cc
+++ b/qt4/src/poppler-page.cc
@@ -8,6 +8,7 @@
  * Copyright (C) 2009 Shawn Rutledge <[email protected]>
  * Copyright (C) 2010, Guillermo Amaral <[email protected]>
  * Copyright (C) 2010 Suzuki Toshiya <[email protected]>
+ * Copyright (C) 2010 Matthias Fauconneau <[email protected]>
  *
  * 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
@@ -250,25 +251,7 @@ QImage Page::renderToImage(double xres, double yres, int 
x, int y, int w, int h,
       QImage tmpimg(w == -1 ? qRound( size.width() * xres / 72.0 ) : w, h == 
-1 ? qRound( size.height() * yres / 72.0 ) : h, QImage::Format_ARGB32);
 
       QPainter painter(&tmpimg);
-      if (m_page->parentDoc->m_hints & Document::Antialiasing)
-          painter.setRenderHint(QPainter::Antialiasing);
-      if (m_page->parentDoc->m_hints & Document::TextAntialiasing)
-          painter.setRenderHint(QPainter::TextAntialiasing);
-      painter.translate(x == -1 ? 0 : -x, y == -1 ? 0 : -y);
-      ArthurOutputDev arthur_output(&painter);
-      arthur_output.startDoc(m_page->parentDoc->doc->getXRef());
-      m_page->parentDoc->doc->displayPageSlice(&arthur_output,
-                                                m_page->index + 1,
-                                                xres,
-                                                yres,
-                                                rotation,
-                                                false,
-                                                true,
-                                                false,
-                                                x,
-                                                y,
-                                                w,
-                                                h);
+      renderToPainter(&painter, xres, yres, x, y, w, h, rotate, 
DontSaveAndRestore);
       painter.end();
       img = tmpimg;
       break;
@@ -278,6 +261,47 @@ QImage Page::renderToImage(double xres, double yres, int 
x, int y, int w, int h,
   return img;
 }
 
+bool Page::renderToPainter(QPainter* painter, double xres, double yres, int x, 
int y, int w, int h, Rotation rotate, PainterFlags flags) const
+{
+  if (!painter)
+    return false;
+
+  switch(m_page->parentDoc->m_backend)
+  {
+    case Poppler::Document::SplashBackend:
+      return false;
+    case Poppler::Document::ArthurBackend:
+    {
+      const bool savePainter = !(flags & DontSaveAndRestore);
+      if (savePainter)
+         painter->save();
+      if (m_page->parentDoc->m_hints & Document::Antialiasing)
+          painter->setRenderHint(QPainter::Antialiasing);
+      if (m_page->parentDoc->m_hints & Document::TextAntialiasing)
+          painter->setRenderHint(QPainter::TextAntialiasing);
+      painter->translate(x == -1 ? 0 : -x, y == -1 ? 0 : -y);
+      ArthurOutputDev arthur_output(painter);
+      arthur_output.startDoc(m_page->parentDoc->doc->getXRef());
+      m_page->parentDoc->doc->displayPageSlice(&arthur_output,
+                                               m_page->index + 1,
+                                               xres,
+                                               yres,
+                                               (int)rotate * 90,
+                                               false,
+                                               true,
+                                               false,
+                                               x,
+                                               y,
+                                               w,
+                                               h);
+      if (savePainter)
+         painter->restore();
+      return true;
+    }
+  }
+  return false;
+}
+
 QImage Page::thumbnail() const
 {
   unsigned char* data = 0;
diff --git a/qt4/src/poppler-qt4.h b/qt4/src/poppler-qt4.h
index d742973..c50e4f9 100644
--- a/qt4/src/poppler-qt4.h
+++ b/qt4/src/poppler-qt4.h
@@ -3,9 +3,10 @@
  * Copyright (C) 2005, 2007, Brad Hards <[email protected]>
  * Copyright (C) 2005-2010, Albert Astals Cid <[email protected]>
  * Copyright (C) 2005, Stefan Kebekus <[email protected]>
- * Copyright (C) 2006-2009, Pino Toscano <[email protected]>
+ * Copyright (C) 2006-2010, Pino Toscano <[email protected]>
  * Copyright (C) 2009 Shawn Rutledge <[email protected]>
  * Copyright (C) 2010 Suzuki Toshiya <[email protected]>
+ * Copyright (C) 2010 Matthias Fauconneau <[email protected]>
  *
  * 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
@@ -398,6 +399,22 @@ delete it;
            RawOrderLayout          ///< The text is returned without any type 
of processing
        };
 
+        /**
+           Additional flags for the renderToPainter method
+           \since 0.16
+        */
+        enum PainterFlag {
+            /**
+               Do not save/restore the caller-owned painter.
+
+               renderToPainter() by default preserves, using save() + 
restore(),
+               the state of the painter specified; if this is not needed, this
+               flag can avoid this job
+             */
+            DontSaveAndRestore = 0x00000001
+        };
+        Q_DECLARE_FLAGS( PainterFlags, PainterFlag )
+
        /** 
           Render the page to a QImage using the current
           \link Document::renderBackend() Document renderer\endlink.
@@ -438,6 +455,51 @@ delete it;
         */
        QImage renderToImage(double xres=72.0, double yres=72.0, int x=-1, int 
y=-1, int w=-1, int h=-1, Rotation rotate = Rotate0) const;
 
+        /**
+           Render the page to the specified QPainter using the current
+           \link Document::renderBackend() Document renderer\endlink.
+
+           If \p x = \p y = \p w = \p h = -1, the method will automatically
+           compute the size of the page area from the horizontal and vertical
+           resolutions specified in \p xres and \p yres. Otherwise, the
+           method renders only a part of the page, specified by the
+           parameters (\p x, \p y, \p w, \p h) in pixel coordinates.
+
+           \param painter the painter to paint on
+
+           \param x specifies the left x-coordinate of the box, in
+           pixels.
+
+           \param y specifies the top y-coordinate of the box, in
+           pixels.
+
+           \param w specifies the width of the box, in pixels.
+
+           \param h specifies the height of the box, in pixels.
+
+           \param xres horizontal resolution of the graphics device,
+           in dots per inch
+
+           \param yres vertical resolution of the graphics device, in
+           dots per inch
+
+           \param rotate how to rotate the page
+
+           \param flags additional painter flags
+
+           \warning The parameter (\p x, \p y, \p w, \p h) are not
+           well-tested. Unusual or meaningless parameters may lead to
+           rather unexpected results.
+
+           \returns whether the painting succeeded
+
+           \note This method is only supported for Arthur
+
+           \since 0.16
+        */
+        bool renderToPainter(QPainter* painter, double xres=72.0, double 
yres=72.0, int x=-1, int y=-1, int w=-1, int h=-1,
+                             Rotation rotate = Rotate0, PainterFlags flags = 
0) const;
+
        /**
           Get the page thumbnail if it exists.
 
@@ -1626,6 +1688,7 @@ height = dummy.height();
 
 }
 
+Q_DECLARE_OPERATORS_FOR_FLAGS(Poppler::Page::PainterFlags)
 Q_DECLARE_OPERATORS_FOR_FLAGS(Poppler::Document::RenderHints)
 Q_DECLARE_OPERATORS_FOR_FLAGS(Poppler::PDFConverter::PDFOptions)
 Q_DECLARE_OPERATORS_FOR_FLAGS(Poppler::PSConverter::PSOptions)
commit df02d1fc9e65422121e5e8f493c13229552ec0e7
Author: Pino Toscano <[email protected]>
Date:   Sun Nov 7 19:47:56 2010 +0100

    [arthur] remove unused 'm_image' attribute

diff --git a/poppler/ArthurOutputDev.cc b/poppler/ArthurOutputDev.cc
index 7e417c0..54acf12 100644
--- a/poppler/ArthurOutputDev.cc
+++ b/poppler/ArthurOutputDev.cc
@@ -91,7 +91,6 @@ ArthurOutputDev::ArthurOutputDev(QPainter *painter):
   m_currentBrush = QBrush(Qt::SolidPattern);
   m_fontEngine = 0;
   m_font = 0;
-  m_image = 0;
 }
 
 ArthurOutputDev::~ArthurOutputDev()
diff --git a/poppler/ArthurOutputDev.h b/poppler/ArthurOutputDev.h
index 5340318..3fa586b 100644
--- a/poppler/ArthurOutputDev.h
+++ b/poppler/ArthurOutputDev.h
@@ -16,6 +16,7 @@
 // Copyright (C) 2005 Brad Hards <[email protected]>
 // Copyright (C) 2005 Albert Astals Cid <[email protected]>
 // Copyright (C) 2009 Carlos Garcia Campos <[email protected]>
+// Copyright (C) 2010, 2010 Pino Toscano <[email protected]>
 //
 // To see a description of the changes please see the Changelog file that
 // came with your tarball or type make ChangeLog if you are building from git
@@ -150,7 +151,6 @@ private:
   QPen m_currentPen;
   QBrush m_currentBrush;
   GBool m_needFontUpdate;              // set when the font needs to be updated
-  QImage *m_image;
   SplashFontEngine *m_fontEngine;
   SplashFont *m_font;          // current font
   XRef *xref;                  // xref table for current document
commit b29582cd0d542a3e70dbca3fb75770daa4cc91ca
Author: Matthias Fauconneau <[email protected]>
Date:   Sun Nov 7 19:44:11 2010 +0100

    [arthur] small fixes and memory leaks
    
    - fix font rendering (transforming the glyph path and not only the glyph 
origin)
    - fix image rendering (alpha was set to zero)

diff --git a/poppler/ArthurOutputDev.cc b/poppler/ArthurOutputDev.cc
index 7573f3f..7e417c0 100644
--- a/poppler/ArthurOutputDev.cc
+++ b/poppler/ArthurOutputDev.cc
@@ -18,6 +18,7 @@
 // Copyright (C) 2008, 2010 Pino Toscano <[email protected]>
 // Copyright (C) 2009 Carlos Garcia Campos <[email protected]>
 // Copyright (C) 2009 Petr Gajdos <[email protected]>
+// Copyright (C) 2010 Matthias Fauconneau <[email protected]>
 //
 // To see a description of the changes please see the Changelog file that
 // came with your tarball or type make ChangeLog if you are building from git
@@ -269,7 +270,7 @@ void ArthurOutputDev::updateFont(GfxState *state)
   GfxFontType fontType;
   SplashOutFontFileID *id;
   SplashFontFile *fontFile;
-  SplashFontSrc *fontsrc;
+  SplashFontSrc *fontsrc = NULL;
   FoFiTrueType *ff;
   Ref embRef;
   Object refObj, strObj;
@@ -342,7 +343,7 @@ void ArthurOutputDev::updateFont(GfxState *state)
     if (fileName)
       fontsrc->setFile(fileName, gFalse);
     else
-      fontsrc->setBuf(tmpBuf, tmpBufLen, gFalse);
+      fontsrc->setBuf(tmpBuf, tmpBufLen, gTrue);
 
     // load the font file
     switch (fontType) {
@@ -484,11 +485,15 @@ void ArthurOutputDev::updateFont(GfxState *state)
   mat[2] = m21;  mat[3] = -m22;
   m_font = m_fontEngine->getFont(fontFile, mat, matrix);
 
+  if (fontsrc && !fontsrc->isFile)
+      fontsrc->unref();
   return;
 
  err2:
   delete id;
  err1:
+  if (fontsrc && !fontsrc->isFile)
+      fontsrc->unref();
   return;
 #endif
 }
@@ -530,7 +535,7 @@ static QPainterPath convertPath(GfxState *state, GfxPath 
*path, Qt::FillRule fil
 
 void ArthurOutputDev::stroke(GfxState *state)
 {
-  m_painter->drawPath( convertPath( state, state->getPath(), Qt::OddEvenFill ) 
);
+  m_painter->strokePath( convertPath( state, state->getPath(), Qt::OddEvenFill 
), m_currentPen );
 }
 
 void ArthurOutputDev::fill(GfxState *state)
@@ -559,6 +564,7 @@ void ArthurOutputDev::drawChar(GfxState *state, double x, 
double y,
                               CharCode code, int nBytes, Unicode *u, int uLen) 
{
 #ifdef HAVE_SPLASH
   double x1, y1;
+  double x2, y2;
 //   SplashPath *path;
   int render;
 
@@ -577,41 +583,36 @@ void ArthurOutputDev::drawChar(GfxState *state, double x, 
double y,
 
   x -= originX;
   y -= originY;
-  state->transform(x, y, &x1, &y1);
 
   // fill
   if (!(render & 1)) {
-    int x0, y0, xFrac, yFrac;
-
-    x0 = static_cast<int>(floor(x1));
-    xFrac = splashFloor((x1 - x0) * splashFontFraction);
-    y0 = static_cast<int>(floor(y1));
-    yFrac = splashFloor((y1 - y0) * splashFontFraction);
     SplashPath * fontPath;
     fontPath = m_font->getGlyphPath(code);
     if (fontPath) {
       QPainterPath qPath;
       qPath.setFillRule(Qt::WindingFill);
       for (int i = 0; i < fontPath->length; ++i) {
-       if (fontPath->flags[i] & splashPathFirst) {
-         qPath.moveTo(fontPath->pts[i].x+x0, fontPath->pts[i].y+y0);
-       } else if (fontPath->flags[i] & splashPathCurve) {
-         qPath.quadTo(fontPath->pts[i].x+x0, fontPath->pts[i].y+y0,
-                      fontPath->pts[i+1].x+x0, fontPath->pts[i+1].y+y0);
-         ++i;
-       }
-// FIXME fix this
-//     else if (fontPath->flags[i] & splashPathArcCW) {
-//       qDebug() << "Need to implement arc";
-//     }
-       else {
-         qPath.lineTo(fontPath->pts[i].x+x0, fontPath->pts[i].y+y0);
-       }
-       if (fontPath->flags[i] & splashPathLast) {
-         qPath.closeSubpath();
-       }
+        if (fontPath->flags[i] & splashPathFirst) {
+            state->transform(fontPath->pts[i].x+x, -fontPath->pts[i].y+y, &x1, 
&y1);
+            qPath.moveTo(x1,y1);
+        } else if (fontPath->flags[i] & splashPathCurve) {
+            state->transform(fontPath->pts[i].x+x, -fontPath->pts[i].y+y, &x1, 
&y1);
+            state->transform(fontPath->pts[i+1].x+x, -fontPath->pts[i+1].y+y, 
&x2, &y2);
+            qPath.quadTo(x1,y1,x2,y2);
+            ++i;
+        }
+        // FIXME fix this
+        //     else if (fontPath->flags[i] & splashPathArcCW) {
+        //       qDebug() << "Need to implement arc";
+        //     }
+        else {
+            state->transform(fontPath->pts[i].x+x, -fontPath->pts[i].y+y, &x1, 
&y1);
+            qPath.lineTo(x1,y1);
+        }
+        if (fontPath->flags[i] & splashPathLast) {
+            qPath.closeSubpath();
+        }
       }
-      m_painter->save();
       GfxRGB rgb;
       QColor brushColour = m_currentBrush.color();
       state->getFillRGB(&rgb);
@@ -622,7 +623,7 @@ void ArthurOutputDev::drawChar(GfxState *state, double x, 
double y,
       penColour.setRgbF(colToDbl(rgb.r), colToDbl(rgb.g), colToDbl(rgb.b), 
state->getStrokeOpacity());
       m_painter->setPen(penColour);
       m_painter->drawPath( qPath );
-      m_painter->restore();
+      delete fontPath;
     }
   }
 
@@ -762,8 +763,8 @@ void ArthurOutputDev::drawImage(GfxState *state, Object 
*ref, Stream *str,
                                GfxImageColorMap *colorMap,
                                GBool interpolate, int *maskColors, GBool 
inlineImg)
 {
-  unsigned char *buffer;
-  unsigned int *dest;
+  unsigned int *data;
+  unsigned int *line;
   int x, y;
   ImageStream *imgStr;
   Guchar *pix;
@@ -771,9 +772,9 @@ void ArthurOutputDev::drawImage(GfxState *state, Object 
*ref, Stream *str,
   double *ctm;
   QMatrix matrix;
   int is_identity_transform;
+  QImage image;
+  int stride;
   
-  buffer = (unsigned char *)gmallocn3(width, height, 4);
-
   /* TODO: Do we want to cache these? */
   imgStr = new ImageStream(str, width,
                           colorMap->getNumPixelComps(),
@@ -786,51 +787,36 @@ void ArthurOutputDev::drawImage(GfxState *state, Object 
*ref, Stream *str,
                  (colorMap->getColorSpace()->getMode() == csICCBased && 
                  
((GfxICCBasedColorSpace*)colorMap->getColorSpace())->getAlt()->getMode() == 
csDeviceRGB);
 
-  if (maskColors) {
-    for (y = 0; y < height; y++) {
-      dest = (unsigned int *) (buffer + y * 4 * width);
-      pix = imgStr->getLine();
-      colorMap->getRGBLine (pix, dest, width);
+  image = QImage(width, height, QImage::Format_ARGB32);
+  data = (unsigned int *)image.bits();
+  stride = image.bytesPerLine()/4;
+  for (y = 0; y < height; y++) {
+    pix = imgStr->getLine();
+    line = data+y*stride;
+    colorMap->getRGBLine(pix, line, width);
 
+    if (maskColors) {
       for (x = 0; x < width; x++) {
-       for (i = 0; i < colorMap->getNumPixelComps(); ++i) {
-         
-         if (pix[i] < maskColors[2*i] * 255||
-             pix[i] > maskColors[2*i+1] * 255) {
-           *dest = *dest | 0xff000000;
-           break;
-         }
-       }
-       pix += colorMap->getNumPixelComps();
-       dest++;
+        for (i = 0; i < colorMap->getNumPixelComps(); ++i) {
+            if (pix[i] < maskColors[2*i] * 255||
+                pix[i] > maskColors[2*i+1] * 255) {
+                *line = *line | 0xff000000;
+                break;
+            }
+        }
+        pix += colorMap->getNumPixelComps();
+        line++;
       }
+    } else {
+      for (x = 0; x < width; x++) { *line = *line | 0xff000000; line++; }
     }
-
-    m_image = new QImage(buffer, width, height, QImage::Format_ARGB32);
-  }
-  else {
-    for (y = 0; y < height; y++) {
-      dest = (unsigned int *) (buffer + y * 4 * width);
-      pix = imgStr->getLine();
-      colorMap->getRGBLine (pix, dest, width);
-    }
-
-    m_image = new QImage(buffer, width, height, QImage::Format_RGB32);
   }
 
-  if (m_image == NULL || m_image->isNull()) {
-    qDebug() << "Null image";
-    delete imgStr;
-    return;
-  }
   ctm = state->getCTM();
   matrix.setMatrix(ctm[0] / width, ctm[1] / width, -ctm[2] / height, -ctm[3] / 
height, ctm[2] + ctm[4], ctm[3] + ctm[5]);
 
   m_painter->setMatrix(matrix, true);
-  m_painter->drawImage( QPoint(0,0), *m_image );
-  delete m_image;
-  m_image = 0;
-  free (buffer);
+  m_painter->drawImage( QPoint(0,0), image );
   delete imgStr;
 
 }
_______________________________________________
poppler mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/poppler

Reply via email to