[poppler] 3 commits - poppler/ArthurOutputDev.cc poppler/ArthurOutputDev.h qt4/src
Pino Toscano
pino at kemper.freedesktop.org
Sun Nov 7 13:01:36 PST 2010
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 <pino at kde.org>
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 (matthias.fauconneau at gmail.com), 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 <shawn.t.rutledge at gmail.com>
* Copyright (C) 2010, Guillermo Amaral <gamaral at kdab.com>
* Copyright (C) 2010 Suzuki Toshiya <mpsuzuki at hiroshima-u.ac.jp>
+ * Copyright (C) 2010 Matthias Fauconneau <matthias.fauconneau at gmail.com>
*
* 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 <bradh at frogmouth.net>
* Copyright (C) 2005-2010, Albert Astals Cid <aacid at kde.org>
* Copyright (C) 2005, Stefan Kebekus <stefan.kebekus at math.uni-koeln.de>
- * Copyright (C) 2006-2009, Pino Toscano <pino at kde.org>
+ * Copyright (C) 2006-2010, Pino Toscano <pino at kde.org>
* Copyright (C) 2009 Shawn Rutledge <shawn.t.rutledge at gmail.com>
* Copyright (C) 2010 Suzuki Toshiya <mpsuzuki at hiroshima-u.ac.jp>
+ * Copyright (C) 2010 Matthias Fauconneau <matthias.fauconneau at gmail.com>
*
* 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 <pino at kde.org>
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 <bradh at frogmouth.net>
// Copyright (C) 2005 Albert Astals Cid <aacid at kde.org>
// Copyright (C) 2009 Carlos Garcia Campos <carlosgc at gnome.org>
+// Copyright (C) 2010, 2010 Pino Toscano <pino at kde.org>
//
// 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 <matthias.fauconneau at gmail.com>
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 <pino at kde.org>
// Copyright (C) 2009 Carlos Garcia Campos <carlosgc at gnome.org>
// Copyright (C) 2009 Petr Gajdos <pgajdos at novell.com>
+// Copyright (C) 2010 Matthias Fauconneau <matthias.fauconneau at gmail.com>
//
// 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;
}
More information about the poppler
mailing list