[poppler] Branch 'qt5' - poppler/ArthurOutputDev.cc poppler/ArthurOutputDev.h poppler/Makefile.am qt4/src qt5/src
Albert Astals Cid
aacid at kemper.freedesktop.org
Tue Jun 18 11:51:20 PDT 2013
poppler/ArthurOutputDev.cc | 816 ------------------------------------------
poppler/ArthurOutputDev.h | 170 --------
poppler/Makefile.am | 23 -
qt4/src/ArthurOutputDev.cc | 816 ++++++++++++++++++++++++++++++++++++++++++
qt4/src/ArthurOutputDev.h | 170 ++++++++
qt4/src/CMakeLists.txt | 2
qt4/src/Makefile.am | 5
qt5/src/ArthurOutputDev.cc | 816 ++++++++++++++++++++++++++++++++++++++++++
qt5/src/ArthurOutputDev.h | 170 ++++++++
qt5/src/CMakeLists.txt | 2
qt5/src/Makefile.am | 5
qt5/src/poppler-optcontent.cc | 2
12 files changed, 1983 insertions(+), 1014 deletions(-)
New commits:
commit 1adb1ab7aee026e227d25716a4b7be22b19b5b84
Author: Albert Astals Cid <aacid at kde.org>
Date: Tue Jun 18 20:50:49 2013 +0200
Make it build with autotools
diff --git a/poppler/ArthurOutputDev.cc b/poppler/ArthurOutputDev.cc
deleted file mode 100644
index 5d57e93..0000000
--- a/poppler/ArthurOutputDev.cc
+++ /dev/null
@@ -1,816 +0,0 @@
-//========================================================================
-//
-// ArthurOutputDev.cc
-//
-// Copyright 2003 Glyph & Cog, LLC
-//
-//========================================================================
-
-//========================================================================
-//
-// Modified under the Poppler project - http://poppler.freedesktop.org
-//
-// All changes made under the Poppler project to this file are licensed
-// under GPL version 2 or later
-//
-// Copyright (C) 2005 Brad Hards <bradh at frogmouth.net>
-// Copyright (C) 2005-2009, 2011, 2012 Albert Astals Cid <aacid at kde.org>
-// Copyright (C) 2008, 2010 Pino Toscano <pino at kde.org>
-// Copyright (C) 2009, 2011 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>
-// Copyright (C) 2011 Andreas Hartmetz <ahartmetz at gmail.com>
-// Copyright (C) 2013 Thomas Freitag <Thomas.Freitag at alfa.de>
-//
-// 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
-//
-//========================================================================
-
-#include <config.h>
-
-#ifdef USE_GCC_PRAGMAS
-#pragma implementation
-#endif
-
-#include <string.h>
-#include <math.h>
-
-#include "goo/gfile.h"
-#include "GlobalParams.h"
-#include "Error.h"
-#include "Object.h"
-#include "GfxState.h"
-#include "GfxFont.h"
-#include "Link.h"
-#include "FontEncodingTables.h"
-#include <fofi/FoFiTrueType.h>
-#include "ArthurOutputDev.h"
-
-#include <QtCore/QtDebug>
-#include <QtGui/QPainterPath>
-//------------------------------------------------------------------------
-
-#ifdef HAVE_SPLASH
-#include "splash/SplashFontFileID.h"
-#include "splash/SplashFontFile.h"
-#include "splash/SplashFontEngine.h"
-#include "splash/SplashFont.h"
-#include "splash/SplashMath.h"
-#include "splash/SplashPath.h"
-#include "splash/SplashGlyphBitmap.h"
-//------------------------------------------------------------------------
-// SplashOutFontFileID
-//------------------------------------------------------------------------
-
-class SplashOutFontFileID: public SplashFontFileID {
-public:
-
- SplashOutFontFileID(Ref *rA) { r = *rA; }
-
- ~SplashOutFontFileID() {}
-
- GBool matches(SplashFontFileID *id) {
- return ((SplashOutFontFileID *)id)->r.num == r.num &&
- ((SplashOutFontFileID *)id)->r.gen == r.gen;
- }
-
-private:
-
- Ref r;
-};
-
-#endif
-
-//------------------------------------------------------------------------
-// ArthurOutputDev
-//------------------------------------------------------------------------
-
-ArthurOutputDev::ArthurOutputDev(QPainter *painter):
- m_painter(painter),
- m_fontHinting(NoHinting)
-{
- m_currentBrush = QBrush(Qt::SolidPattern);
- m_fontEngine = 0;
- m_font = 0;
-}
-
-ArthurOutputDev::~ArthurOutputDev()
-{
-#ifdef HAVE_SPLASH
- delete m_fontEngine;
-#endif
-}
-
-void ArthurOutputDev::startDoc(XRef *xrefA) {
- xref = xrefA;
-#ifdef HAVE_SPLASH
- delete m_fontEngine;
-
- const bool isHintingEnabled = m_fontHinting != NoHinting;
- const bool isSlightHinting = m_fontHinting == SlightHinting;
-
- m_fontEngine = new SplashFontEngine(
-#if HAVE_T1LIB_H
- globalParams->getEnableT1lib(),
-#endif
-#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
- globalParams->getEnableFreeType(),
- isHintingEnabled,
- isSlightHinting,
-#endif
- m_painter->testRenderHint(QPainter::TextAntialiasing));
-#endif
-}
-
-void ArthurOutputDev::startPage(int pageNum, GfxState *state, XRef *xref)
-{
- // fill page with white background.
- int w = static_cast<int>(state->getPageWidth());
- int h = static_cast<int>(state->getPageHeight());
- QColor fillColour(Qt::white);
- QBrush fill(fillColour);
- m_painter->save();
- m_painter->setPen(fillColour);
- m_painter->setBrush(fill);
- m_painter->drawRect(0, 0, w, h);
- m_painter->restore();
-}
-
-void ArthurOutputDev::endPage() {
-}
-
-void ArthurOutputDev::saveState(GfxState *state)
-{
- m_painter->save();
-}
-
-void ArthurOutputDev::restoreState(GfxState *state)
-{
- m_painter->restore();
-}
-
-void ArthurOutputDev::updateAll(GfxState *state)
-{
- OutputDev::updateAll(state);
- m_needFontUpdate = gTrue;
-}
-
-// This looks wrong - why aren't adjusting the matrix?
-void ArthurOutputDev::updateCTM(GfxState *state, double m11, double m12,
- double m21, double m22,
- double m31, double m32)
-{
- updateLineDash(state);
- updateLineJoin(state);
- updateLineCap(state);
- updateLineWidth(state);
-}
-
-void ArthurOutputDev::updateLineDash(GfxState *state)
-{
- double *dashPattern;
- int dashLength;
- double dashStart;
- state->getLineDash(&dashPattern, &dashLength, &dashStart);
- QVector<qreal> pattern(dashLength);
- for (int i = 0; i < dashLength; ++i) {
- pattern[i] = dashPattern[i];
- }
- m_currentPen.setDashPattern(pattern);
- m_currentPen.setDashOffset(dashStart);
- m_painter->setPen(m_currentPen);
-}
-
-void ArthurOutputDev::updateFlatness(GfxState *state)
-{
- // qDebug() << "updateFlatness";
-}
-
-void ArthurOutputDev::updateLineJoin(GfxState *state)
-{
- switch (state->getLineJoin()) {
- case 0:
- m_currentPen.setJoinStyle(Qt::MiterJoin);
- break;
- case 1:
- m_currentPen.setJoinStyle(Qt::RoundJoin);
- break;
- case 2:
- m_currentPen.setJoinStyle(Qt::BevelJoin);
- break;
- }
- m_painter->setPen(m_currentPen);
-}
-
-void ArthurOutputDev::updateLineCap(GfxState *state)
-{
- switch (state->getLineCap()) {
- case 0:
- m_currentPen.setCapStyle(Qt::FlatCap);
- break;
- case 1:
- m_currentPen.setCapStyle(Qt::RoundCap);
- break;
- case 2:
- m_currentPen.setCapStyle(Qt::SquareCap);
- break;
- }
- m_painter->setPen(m_currentPen);
-}
-
-void ArthurOutputDev::updateMiterLimit(GfxState *state)
-{
- m_currentPen.setMiterLimit(state->getMiterLimit());
- m_painter->setPen(m_currentPen);
-}
-
-void ArthurOutputDev::updateLineWidth(GfxState *state)
-{
- m_currentPen.setWidthF(state->getLineWidth());
- m_painter->setPen(m_currentPen);
-}
-
-void ArthurOutputDev::updateFillColor(GfxState *state)
-{
- GfxRGB rgb;
- QColor brushColour = m_currentBrush.color();
- state->getFillRGB(&rgb);
- brushColour.setRgbF(colToDbl(rgb.r), colToDbl(rgb.g), colToDbl(rgb.b), brushColour.alphaF());
- m_currentBrush.setColor(brushColour);
-}
-
-void ArthurOutputDev::updateStrokeColor(GfxState *state)
-{
- GfxRGB rgb;
- QColor penColour = m_currentPen.color();
- state->getStrokeRGB(&rgb);
- penColour.setRgbF(colToDbl(rgb.r), colToDbl(rgb.g), colToDbl(rgb.b), penColour.alphaF());
- m_currentPen.setColor(penColour);
- m_painter->setPen(m_currentPen);
-}
-
-void ArthurOutputDev::updateFillOpacity(GfxState *state)
-{
- QColor brushColour= m_currentBrush.color();
- brushColour.setAlphaF(state->getFillOpacity());
- m_currentBrush.setColor(brushColour);
-}
-
-void ArthurOutputDev::updateStrokeOpacity(GfxState *state)
-{
- QColor penColour= m_currentPen.color();
- penColour.setAlphaF(state->getStrokeOpacity());
- m_currentPen.setColor(penColour);
- m_painter->setPen(m_currentPen);
-}
-
-void ArthurOutputDev::updateFont(GfxState *state)
-{
-#ifdef HAVE_SPLASH
- GfxFont *gfxFont;
- GfxFontLoc *fontLoc;
- GfxFontType fontType;
- SplashOutFontFileID *id;
- SplashFontFile *fontFile;
- SplashFontSrc *fontsrc = NULL;
- FoFiTrueType *ff;
- Object refObj, strObj;
- GooString *fileName;
- char *tmpBuf;
- int tmpBufLen;
- int *codeToGID;
- double *textMat;
- double m11, m12, m21, m22, fontSize;
- SplashCoord mat[4];
- int n;
- int faceIndex = 0;
- SplashCoord matrix[6];
-
- m_needFontUpdate = false;
- m_font = NULL;
- fileName = NULL;
- tmpBuf = NULL;
- fontLoc = NULL;
-
- if (!(gfxFont = state->getFont())) {
- goto err1;
- }
- fontType = gfxFont->getType();
- if (fontType == fontType3) {
- goto err1;
- }
-
- // check the font file cache
- id = new SplashOutFontFileID(gfxFont->getID());
- if ((fontFile = m_fontEngine->getFontFile(id))) {
- delete id;
-
- } else {
-
- if (!(fontLoc = gfxFont->locateFont(xref, gFalse))) {
- error(errSyntaxError, -1, "Couldn't find a font for '{0:s}'",
- gfxFont->getName() ? gfxFont->getName()->getCString()
- : "(unnamed)");
- goto err2;
- }
-
- // embedded font
- if (fontLoc->locType == gfxFontLocEmbedded) {
- // if there is an embedded font, read it to memory
- tmpBuf = gfxFont->readEmbFontFile(xref, &tmpBufLen);
- if (! tmpBuf)
- goto err2;
-
- // external font
- } else { // gfxFontLocExternal
- fileName = fontLoc->path;
- fontType = fontLoc->fontType;
- }
-
- fontsrc = new SplashFontSrc;
- if (fileName)
- fontsrc->setFile(fileName, gFalse);
- else
- fontsrc->setBuf(tmpBuf, tmpBufLen, gTrue);
-
- // load the font file
- switch (fontType) {
- case fontType1:
- if (!(fontFile = m_fontEngine->loadType1Font(
- id,
- fontsrc,
- (const char **)((Gfx8BitFont *)gfxFont)->getEncoding()))) {
- error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
- gfxFont->getName() ? gfxFont->getName()->getCString()
- : "(unnamed)");
- goto err2;
- }
- break;
- case fontType1C:
- if (!(fontFile = m_fontEngine->loadType1CFont(
- id,
- fontsrc,
- (const char **)((Gfx8BitFont *)gfxFont)->getEncoding()))) {
- error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
- gfxFont->getName() ? gfxFont->getName()->getCString()
- : "(unnamed)");
- goto err2;
- }
- break;
- case fontType1COT:
- if (!(fontFile = m_fontEngine->loadOpenTypeT1CFont(
- id,
- fontsrc,
- (const char **)((Gfx8BitFont *)gfxFont)->getEncoding()))) {
- error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
- gfxFont->getName() ? gfxFont->getName()->getCString()
- : "(unnamed)");
- goto err2;
- }
- break;
- case fontTrueType:
- case fontTrueTypeOT:
- if (fileName)
- ff = FoFiTrueType::load(fileName->getCString());
- else
- ff = FoFiTrueType::make(tmpBuf, tmpBufLen);
- if (ff) {
- codeToGID = ((Gfx8BitFont *)gfxFont)->getCodeToGIDMap(ff);
- n = 256;
- delete ff;
- } else {
- codeToGID = NULL;
- n = 0;
- }
- if (!(fontFile = m_fontEngine->loadTrueTypeFont(
- id,
- fontsrc,
- codeToGID, n))) {
- error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
- gfxFont->getName() ? gfxFont->getName()->getCString()
- : "(unnamed)");
- goto err2;
- }
- break;
- case fontCIDType0:
- case fontCIDType0C:
- if (!(fontFile = m_fontEngine->loadCIDFont(
- id,
- fontsrc))) {
- error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
- gfxFont->getName() ? gfxFont->getName()->getCString()
- : "(unnamed)");
- goto err2;
- }
- break;
- case fontCIDType0COT:
- if (((GfxCIDFont *)gfxFont)->getCIDToGID()) {
- n = ((GfxCIDFont *)gfxFont)->getCIDToGIDLen();
- codeToGID = (int *)gmallocn(n, sizeof(int));
- memcpy(codeToGID, ((GfxCIDFont *)gfxFont)->getCIDToGID(),
- n * sizeof(int));
- } else {
- codeToGID = NULL;
- n = 0;
- }
- if (!(fontFile = m_fontEngine->loadOpenTypeCFFFont(
- id,
- fontsrc,
- codeToGID, n))) {
- error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
- gfxFont->getName() ? gfxFont->getName()->getCString()
- : "(unnamed)");
- goto err2;
- }
- break;
- case fontCIDType2:
- case fontCIDType2OT:
- codeToGID = NULL;
- n = 0;
- if (((GfxCIDFont *)gfxFont)->getCIDToGID()) {
- n = ((GfxCIDFont *)gfxFont)->getCIDToGIDLen();
- if (n) {
- codeToGID = (int *)gmallocn(n, sizeof(int));
- memcpy(codeToGID, ((GfxCIDFont *)gfxFont)->getCIDToGID(),
- n * sizeof(Gushort));
- }
- } else {
- if (fileName)
- ff = FoFiTrueType::load(fileName->getCString());
- else
- ff = FoFiTrueType::make(tmpBuf, tmpBufLen);
- if (! ff)
- goto err2;
- codeToGID = ((GfxCIDFont *)gfxFont)->getCodeToGIDMap(ff, &n);
- delete ff;
- }
- if (!(fontFile = m_fontEngine->loadTrueTypeFont(
- id,
- fontsrc,
- codeToGID, n, faceIndex))) {
- error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
- gfxFont->getName() ? gfxFont->getName()->getCString()
- : "(unnamed)");
- goto err2;
- }
- break;
- default:
- // this shouldn't happen
- goto err2;
- }
- }
-
- // get the font matrix
- textMat = state->getTextMat();
- fontSize = state->getFontSize();
- m11 = textMat[0] * fontSize * state->getHorizScaling();
- m12 = textMat[1] * fontSize * state->getHorizScaling();
- m21 = textMat[2] * fontSize;
- m22 = textMat[3] * fontSize;
-
- {
- QMatrix painterMatrix = m_painter->worldMatrix();
- matrix[0] = painterMatrix.m11();
- matrix[1] = painterMatrix.m12();
- matrix[2] = painterMatrix.m21();
- matrix[3] = painterMatrix.m22();
- matrix[4] = painterMatrix.dx();
- matrix[5] = painterMatrix.dy();
- }
-
- // create the scaled font
- mat[0] = m11; mat[1] = -m12;
- mat[2] = m21; mat[3] = -m22;
- m_font = m_fontEngine->getFont(fontFile, mat, matrix);
-
- delete fontLoc;
- if (fontsrc && !fontsrc->isFile)
- fontsrc->unref();
- return;
-
- err2:
- delete id;
- delete fontLoc;
- err1:
- if (fontsrc && !fontsrc->isFile)
- fontsrc->unref();
- return;
-#endif
-}
-
-static QPainterPath convertPath(GfxState *state, GfxPath *path, Qt::FillRule fillRule)
-{
- GfxSubpath *subpath;
- double x1, y1, x2, y2, x3, y3;
- int i, j;
-
- QPainterPath qPath;
- qPath.setFillRule(fillRule);
- for (i = 0; i < path->getNumSubpaths(); ++i) {
- subpath = path->getSubpath(i);
- if (subpath->getNumPoints() > 0) {
- state->transform(subpath->getX(0), subpath->getY(0), &x1, &y1);
- qPath.moveTo(x1, y1);
- j = 1;
- while (j < subpath->getNumPoints()) {
- if (subpath->getCurve(j)) {
- state->transform(subpath->getX(j), subpath->getY(j), &x1, &y1);
- state->transform(subpath->getX(j+1), subpath->getY(j+1), &x2, &y2);
- state->transform(subpath->getX(j+2), subpath->getY(j+2), &x3, &y3);
- qPath.cubicTo( x1, y1, x2, y2, x3, y3);
- j += 3;
- } else {
- state->transform(subpath->getX(j), subpath->getY(j), &x1, &y1);
- qPath.lineTo(x1, y1);
- ++j;
- }
- }
- if (subpath->isClosed()) {
- qPath.closeSubpath();
- }
- }
- }
- return qPath;
-}
-
-void ArthurOutputDev::stroke(GfxState *state)
-{
- m_painter->strokePath( convertPath( state, state->getPath(), Qt::OddEvenFill ), m_currentPen );
-}
-
-void ArthurOutputDev::fill(GfxState *state)
-{
- m_painter->fillPath( convertPath( state, state->getPath(), Qt::WindingFill ), m_currentBrush );
-}
-
-void ArthurOutputDev::eoFill(GfxState *state)
-{
- m_painter->fillPath( convertPath( state, state->getPath(), Qt::OddEvenFill ), m_currentBrush );
-}
-
-void ArthurOutputDev::clip(GfxState *state)
-{
- m_painter->setClipPath(convertPath( state, state->getPath(), Qt::WindingFill ) );
-}
-
-void ArthurOutputDev::eoClip(GfxState *state)
-{
- m_painter->setClipPath(convertPath( state, state->getPath(), Qt::OddEvenFill ) );
-}
-
-void ArthurOutputDev::drawChar(GfxState *state, double x, double y,
- double dx, double dy,
- double originX, double originY,
- CharCode code, int nBytes, Unicode *u, int uLen) {
-#ifdef HAVE_SPLASH
- double x1, y1;
- double x2, y2;
-// SplashPath *path;
- int render;
-
- if (m_needFontUpdate) {
- updateFont(state);
- }
- if (!m_font) {
- return;
- }
-
- // check for invisible text -- this is used by Acrobat Capture
- render = state->getRender();
- if (render == 3) {
- return;
- }
-
- x -= originX;
- y -= originY;
-
- // fill
- if (!(render & 1)) {
- 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) {
- 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();
- }
- }
- GfxRGB rgb;
- QColor brushColour = m_currentBrush.color();
- state->getFillRGB(&rgb);
- brushColour.setRgbF(colToDbl(rgb.r), colToDbl(rgb.g), colToDbl(rgb.b), state->getFillOpacity());
- m_painter->setBrush(brushColour);
- QColor penColour = m_currentPen.color();
- state->getStrokeRGB(&rgb);
- penColour.setRgbF(colToDbl(rgb.r), colToDbl(rgb.g), colToDbl(rgb.b), state->getStrokeOpacity());
- m_painter->setPen(penColour);
- m_painter->drawPath( qPath );
- delete fontPath;
- }
- }
-
- // stroke
- if ((render & 3) == 1 || (render & 3) == 2) {
- qDebug() << "no stroke";
- /*
- if ((path = m_font->getGlyphPath(code))) {
- path->offset((SplashCoord)x1, (SplashCoord)y1);
- splash->stroke(path);
- delete path;
- }
- */
- }
-
- // clip
- if (render & 4) {
- qDebug() << "no clip";
- /*
- path = m_font->getGlyphPath(code);
- path->offset((SplashCoord)x1, (SplashCoord)y1);
- if (textClipPath) {
- textClipPath->append(path);
- delete path;
- } else {
- textClipPath = path;
- }
- */
- }
-#endif
-}
-
-GBool ArthurOutputDev::beginType3Char(GfxState *state, double x, double y,
- double dx, double dy,
- CharCode code, Unicode *u, int uLen)
-{
- return gFalse;
-}
-
-void ArthurOutputDev::endType3Char(GfxState *state)
-{
-}
-
-void ArthurOutputDev::type3D0(GfxState *state, double wx, double wy)
-{
-}
-
-void ArthurOutputDev::type3D1(GfxState *state, double wx, double wy,
- double llx, double lly, double urx, double ury)
-{
-}
-
-void ArthurOutputDev::endTextObject(GfxState *state)
-{
-}
-
-
-void ArthurOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
- int width, int height, GBool invert,
- GBool interpolate, GBool inlineImg)
-{
- qDebug() << "drawImageMask";
-#if 0
- unsigned char *buffer;
- unsigned char *dest;
- cairo_surface_t *image;
- cairo_pattern_t *pattern;
- int x, y;
- ImageStream *imgStr;
- Guchar *pix;
- double *ctm;
- cairo_matrix_t matrix;
- int invert_bit;
- int row_stride;
-
- row_stride = (width + 3) & ~3;
- buffer = (unsigned char *) malloc (height * row_stride);
- if (buffer == NULL) {
- error(-1, "Unable to allocate memory for image.");
- return;
- }
-
- /* TODO: Do we want to cache these? */
- imgStr = new ImageStream(str, width, 1, 1);
- imgStr->reset();
-
- invert_bit = invert ? 1 : 0;
-
- for (y = 0; y < height; y++) {
- pix = imgStr->getLine();
- dest = buffer + y * row_stride;
- for (x = 0; x < width; x++) {
-
- if (pix[x] ^ invert_bit)
- *dest++ = 0;
- else
- *dest++ = 255;
- }
- }
-
- image = cairo_image_surface_create_for_data (buffer, CAIRO_FORMAT_A8,
- width, height, row_stride);
- if (image == NULL)
- return;
- pattern = cairo_pattern_create_for_surface (image);
- if (pattern == NULL)
- return;
-
- ctm = state->getCTM();
- LOG (printf ("drawImageMask %dx%d, matrix: %f, %f, %f, %f, %f, %f\n",
- width, height, ctm[0], ctm[1], ctm[2], ctm[3], ctm[4], ctm[5]));
- matrix.xx = ctm[0] / width;
- matrix.xy = -ctm[2] / height;
- matrix.yx = ctm[1] / width;
- matrix.yy = -ctm[3] / height;
- matrix.x0 = ctm[2] + ctm[4];
- matrix.y0 = ctm[3] + ctm[5];
- cairo_matrix_invert (&matrix);
- cairo_pattern_set_matrix (pattern, &matrix);
-
- cairo_pattern_set_filter (pattern, CAIRO_FILTER_BEST);
- /* FIXME: Doesn't the image mask support any colorspace? */
- cairo_set_source_rgb (cairo, fill_color.r, fill_color.g, fill_color.b);
- cairo_mask (cairo, pattern);
-
- cairo_pattern_destroy (pattern);
- cairo_surface_destroy (image);
- free (buffer);
- imgStr->close ();
- delete imgStr;
-#endif
-}
-
-//TODO: lots more work here.
-void ArthurOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
- int width, int height,
- GfxImageColorMap *colorMap,
- GBool interpolate, int *maskColors, GBool inlineImg)
-{
- unsigned int *data;
- unsigned int *line;
- int x, y;
- ImageStream *imgStr;
- Guchar *pix;
- int i;
- double *ctm;
- QMatrix matrix;
- QImage image;
- int stride;
-
- /* TODO: Do we want to cache these? */
- imgStr = new ImageStream(str, width,
- colorMap->getNumPixelComps(),
- colorMap->getBits());
- imgStr->reset();
-
- 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) {
- *line = *line | 0xff000000;
- break;
- }
- }
- pix += colorMap->getNumPixelComps();
- line++;
- }
- } else {
- for (x = 0; x < width; x++) { *line = *line | 0xff000000; line++; }
- }
- }
-
- 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), image );
- delete imgStr;
-
-}
diff --git a/poppler/ArthurOutputDev.h b/poppler/ArthurOutputDev.h
deleted file mode 100644
index 9d5e867..0000000
--- a/poppler/ArthurOutputDev.h
+++ /dev/null
@@ -1,170 +0,0 @@
-//========================================================================
-//
-// ArthurOutputDev.h
-//
-// Copyright 2003 Glyph & Cog, LLC
-//
-//========================================================================
-
-//========================================================================
-//
-// Modified under the Poppler project - http://poppler.freedesktop.org
-//
-// All changes made under the Poppler project to this file are licensed
-// under GPL version 2 or later
-//
-// Copyright (C) 2005 Brad Hards <bradh at frogmouth.net>
-// Copyright (C) 2005 Albert Astals Cid <aacid at kde.org>
-// Copyright (C) 2009, 2011 Carlos Garcia Campos <carlosgc at gnome.org>
-// Copyright (C) 2010 Pino Toscano <pino at kde.org>
-// Copyright (C) 2011 Andreas Hartmetz <ahartmetz at gmail.com>
-// Copyright (C) 2013 Thomas Freitag <Thomas.Freitag at alfa.de>
-//
-// 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
-//
-//========================================================================
-
-#ifndef ARTHUROUTPUTDEV_H
-#define ARTHUROUTPUTDEV_H
-
-#ifdef USE_GCC_PRAGMAS
-#pragma interface
-#endif
-
-#include "goo/gtypes.h"
-#include "OutputDev.h"
-#include "GfxState.h"
-
-#include <QtGui/QPainter>
-
-class GfxState;
-class GfxPath;
-class Gfx8BitFont;
-struct GfxRGB;
-
-class SplashFont;
-class SplashFontEngine;
-struct SplashGlyphBitmap;
-
-//------------------------------------------------------------------------
-// ArthurOutputDev - Qt 4 QPainter renderer
-//------------------------------------------------------------------------
-
-class ArthurOutputDev: public OutputDev {
-public:
- /**
- * Describes how fonts are distorted (aka hinted) to fit the pixel grid.
- * More hinting means sharper edges and less adherence to the true letter shapes.
- */
- enum FontHinting {
- NoHinting = 0, ///< Font shapes are left unchanged
- SlightHinting, ///< Font shapes are distorted vertically only
- FullHinting ///< Font shapes are distorted horizontally and vertically
- };
-
- // Constructor.
- ArthurOutputDev(QPainter *painter );
-
- // Destructor.
- virtual ~ArthurOutputDev();
-
- void setFontHinting(FontHinting hinting) { m_fontHinting = hinting; }
-
- //----- get info about output device
-
- // Does this device use upside-down coordinates?
- // (Upside-down means (0,0) is the top left corner of the page.)
- virtual GBool upsideDown() { return gTrue; }
-
- // Does this device use drawChar() or drawString()?
- virtual GBool useDrawChar() { return gTrue; }
-
- // Does this device use beginType3Char/endType3Char? Otherwise,
- // text in Type 3 fonts will be drawn with drawChar/drawString.
- virtual GBool interpretType3Chars() { return gTrue; }
-
- //----- initialization and control
-
- // Start a page.
- virtual void startPage(int pageNum, GfxState *state, XRef *xref);
-
- // End a page.
- virtual void endPage();
-
- //----- save/restore graphics state
- virtual void saveState(GfxState *state);
- virtual void restoreState(GfxState *state);
-
- //----- update graphics state
- virtual void updateAll(GfxState *state);
- virtual void updateCTM(GfxState *state, double m11, double m12,
- double m21, double m22, double m31, double m32);
- virtual void updateLineDash(GfxState *state);
- virtual void updateFlatness(GfxState *state);
- virtual void updateLineJoin(GfxState *state);
- virtual void updateLineCap(GfxState *state);
- virtual void updateMiterLimit(GfxState *state);
- virtual void updateLineWidth(GfxState *state);
- virtual void updateFillColor(GfxState *state);
- virtual void updateStrokeColor(GfxState *state);
- virtual void updateFillOpacity(GfxState *state);
- virtual void updateStrokeOpacity(GfxState *state);
-
- //----- update text state
- virtual void updateFont(GfxState *state);
-
- //----- path painting
- virtual void stroke(GfxState *state);
- virtual void fill(GfxState *state);
- virtual void eoFill(GfxState *state);
-
- //----- path clipping
- virtual void clip(GfxState *state);
- virtual void eoClip(GfxState *state);
-
- //----- text drawing
- // virtual void drawString(GfxState *state, GooString *s);
- virtual void drawChar(GfxState *state, double x, double y,
- double dx, double dy,
- double originX, double originY,
- CharCode code, int nBytes, Unicode *u, int uLen);
- virtual GBool beginType3Char(GfxState *state, double x, double y,
- double dx, double dy,
- CharCode code, Unicode *u, int uLen);
- virtual void endType3Char(GfxState *state);
- virtual void endTextObject(GfxState *state);
-
- //----- image drawing
- virtual void drawImageMask(GfxState *state, Object *ref, Stream *str,
- int width, int height, GBool invert,
- GBool interpolate, GBool inlineImg);
- virtual void drawImage(GfxState *state, Object *ref, Stream *str,
- int width, int height, GfxImageColorMap *colorMap,
- GBool interpolate, int *maskColors, GBool inlineImg);
-
- //----- Type 3 font operators
- virtual void type3D0(GfxState *state, double wx, double wy);
- virtual void type3D1(GfxState *state, double wx, double wy,
- double llx, double lly, double urx, double ury);
-
- //----- special access
-
- // Called to indicate that a new PDF document has been loaded.
- void startDoc(XRef *xrefA);
-
- GBool isReverseVideo() { return gFalse; }
-
-private:
- QPainter *m_painter;
- FontHinting m_fontHinting;
- QFont m_currentFont;
- QPen m_currentPen;
- QBrush m_currentBrush;
- GBool m_needFontUpdate; // set when the font needs to be updated
- SplashFontEngine *m_fontEngine;
- SplashFont *m_font; // current font
- XRef *xref; // xref table for current document
-};
-
-#endif
diff --git a/poppler/Makefile.am b/poppler/Makefile.am
index 8786e12..db6b34e 100644
--- a/poppler/Makefile.am
+++ b/poppler/Makefile.am
@@ -15,24 +15,6 @@ splash_libs = \
endif
-if BUILD_POPPLER_QT4
-
-poppler_arthur = libpoppler-arthur.la
-
-libpoppler_arthur_la_SOURCES = \
- ArthurOutputDev.h \
- ArthurOutputDev.cc
-
-arthur_includes = \
- $(POPPLER_QT4_CFLAGS)
-
-arthur_libs = \
- $(POPPLER_QT4_LIBS)
-
-endif
-
-
-
if BUILD_CAIRO_OUTPUT
poppler_cairo = libpoppler-cairo.la
@@ -144,7 +126,6 @@ INCLUDES = \
$(cms_includes) \
$(splash_includes) \
$(cairo_includes) \
- $(arthur_includes) \
$(libjpeg_includes) \
$(libtiff_includes) \
$(libjpeg2000_includes) \
@@ -155,8 +136,7 @@ INCLUDES = \
lib_LTLIBRARIES = libpoppler.la
-noinst_LTLIBRARIES = $(poppler_cairo) \
- $(poppler_arthur)
+noinst_LTLIBRARIES = $(poppler_cairo)
CFLAGS+=$(PTHREAD_CFLAGS)
CXXFLAGS+=$(PTHREAD_CFLAGS)
@@ -262,7 +242,6 @@ endif
libpoppler_la_SOURCES = \
$(splash_sources) \
$(cairo_sources) \
- $(arthur_sources) \
$(libjpeg_sources) \
$(zlib_sources) \
$(libjpeg2000_sources) \
diff --git a/qt4/src/ArthurOutputDev.cc b/qt4/src/ArthurOutputDev.cc
new file mode 100644
index 0000000..5d57e93
--- /dev/null
+++ b/qt4/src/ArthurOutputDev.cc
@@ -0,0 +1,816 @@
+//========================================================================
+//
+// ArthurOutputDev.cc
+//
+// Copyright 2003 Glyph & Cog, LLC
+//
+//========================================================================
+
+//========================================================================
+//
+// Modified under the Poppler project - http://poppler.freedesktop.org
+//
+// All changes made under the Poppler project to this file are licensed
+// under GPL version 2 or later
+//
+// Copyright (C) 2005 Brad Hards <bradh at frogmouth.net>
+// Copyright (C) 2005-2009, 2011, 2012 Albert Astals Cid <aacid at kde.org>
+// Copyright (C) 2008, 2010 Pino Toscano <pino at kde.org>
+// Copyright (C) 2009, 2011 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>
+// Copyright (C) 2011 Andreas Hartmetz <ahartmetz at gmail.com>
+// Copyright (C) 2013 Thomas Freitag <Thomas.Freitag at alfa.de>
+//
+// 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
+//
+//========================================================================
+
+#include <config.h>
+
+#ifdef USE_GCC_PRAGMAS
+#pragma implementation
+#endif
+
+#include <string.h>
+#include <math.h>
+
+#include "goo/gfile.h"
+#include "GlobalParams.h"
+#include "Error.h"
+#include "Object.h"
+#include "GfxState.h"
+#include "GfxFont.h"
+#include "Link.h"
+#include "FontEncodingTables.h"
+#include <fofi/FoFiTrueType.h>
+#include "ArthurOutputDev.h"
+
+#include <QtCore/QtDebug>
+#include <QtGui/QPainterPath>
+//------------------------------------------------------------------------
+
+#ifdef HAVE_SPLASH
+#include "splash/SplashFontFileID.h"
+#include "splash/SplashFontFile.h"
+#include "splash/SplashFontEngine.h"
+#include "splash/SplashFont.h"
+#include "splash/SplashMath.h"
+#include "splash/SplashPath.h"
+#include "splash/SplashGlyphBitmap.h"
+//------------------------------------------------------------------------
+// SplashOutFontFileID
+//------------------------------------------------------------------------
+
+class SplashOutFontFileID: public SplashFontFileID {
+public:
+
+ SplashOutFontFileID(Ref *rA) { r = *rA; }
+
+ ~SplashOutFontFileID() {}
+
+ GBool matches(SplashFontFileID *id) {
+ return ((SplashOutFontFileID *)id)->r.num == r.num &&
+ ((SplashOutFontFileID *)id)->r.gen == r.gen;
+ }
+
+private:
+
+ Ref r;
+};
+
+#endif
+
+//------------------------------------------------------------------------
+// ArthurOutputDev
+//------------------------------------------------------------------------
+
+ArthurOutputDev::ArthurOutputDev(QPainter *painter):
+ m_painter(painter),
+ m_fontHinting(NoHinting)
+{
+ m_currentBrush = QBrush(Qt::SolidPattern);
+ m_fontEngine = 0;
+ m_font = 0;
+}
+
+ArthurOutputDev::~ArthurOutputDev()
+{
+#ifdef HAVE_SPLASH
+ delete m_fontEngine;
+#endif
+}
+
+void ArthurOutputDev::startDoc(XRef *xrefA) {
+ xref = xrefA;
+#ifdef HAVE_SPLASH
+ delete m_fontEngine;
+
+ const bool isHintingEnabled = m_fontHinting != NoHinting;
+ const bool isSlightHinting = m_fontHinting == SlightHinting;
+
+ m_fontEngine = new SplashFontEngine(
+#if HAVE_T1LIB_H
+ globalParams->getEnableT1lib(),
+#endif
+#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
+ globalParams->getEnableFreeType(),
+ isHintingEnabled,
+ isSlightHinting,
+#endif
+ m_painter->testRenderHint(QPainter::TextAntialiasing));
+#endif
+}
+
+void ArthurOutputDev::startPage(int pageNum, GfxState *state, XRef *xref)
+{
+ // fill page with white background.
+ int w = static_cast<int>(state->getPageWidth());
+ int h = static_cast<int>(state->getPageHeight());
+ QColor fillColour(Qt::white);
+ QBrush fill(fillColour);
+ m_painter->save();
+ m_painter->setPen(fillColour);
+ m_painter->setBrush(fill);
+ m_painter->drawRect(0, 0, w, h);
+ m_painter->restore();
+}
+
+void ArthurOutputDev::endPage() {
+}
+
+void ArthurOutputDev::saveState(GfxState *state)
+{
+ m_painter->save();
+}
+
+void ArthurOutputDev::restoreState(GfxState *state)
+{
+ m_painter->restore();
+}
+
+void ArthurOutputDev::updateAll(GfxState *state)
+{
+ OutputDev::updateAll(state);
+ m_needFontUpdate = gTrue;
+}
+
+// This looks wrong - why aren't adjusting the matrix?
+void ArthurOutputDev::updateCTM(GfxState *state, double m11, double m12,
+ double m21, double m22,
+ double m31, double m32)
+{
+ updateLineDash(state);
+ updateLineJoin(state);
+ updateLineCap(state);
+ updateLineWidth(state);
+}
+
+void ArthurOutputDev::updateLineDash(GfxState *state)
+{
+ double *dashPattern;
+ int dashLength;
+ double dashStart;
+ state->getLineDash(&dashPattern, &dashLength, &dashStart);
+ QVector<qreal> pattern(dashLength);
+ for (int i = 0; i < dashLength; ++i) {
+ pattern[i] = dashPattern[i];
+ }
+ m_currentPen.setDashPattern(pattern);
+ m_currentPen.setDashOffset(dashStart);
+ m_painter->setPen(m_currentPen);
+}
+
+void ArthurOutputDev::updateFlatness(GfxState *state)
+{
+ // qDebug() << "updateFlatness";
+}
+
+void ArthurOutputDev::updateLineJoin(GfxState *state)
+{
+ switch (state->getLineJoin()) {
+ case 0:
+ m_currentPen.setJoinStyle(Qt::MiterJoin);
+ break;
+ case 1:
+ m_currentPen.setJoinStyle(Qt::RoundJoin);
+ break;
+ case 2:
+ m_currentPen.setJoinStyle(Qt::BevelJoin);
+ break;
+ }
+ m_painter->setPen(m_currentPen);
+}
+
+void ArthurOutputDev::updateLineCap(GfxState *state)
+{
+ switch (state->getLineCap()) {
+ case 0:
+ m_currentPen.setCapStyle(Qt::FlatCap);
+ break;
+ case 1:
+ m_currentPen.setCapStyle(Qt::RoundCap);
+ break;
+ case 2:
+ m_currentPen.setCapStyle(Qt::SquareCap);
+ break;
+ }
+ m_painter->setPen(m_currentPen);
+}
+
+void ArthurOutputDev::updateMiterLimit(GfxState *state)
+{
+ m_currentPen.setMiterLimit(state->getMiterLimit());
+ m_painter->setPen(m_currentPen);
+}
+
+void ArthurOutputDev::updateLineWidth(GfxState *state)
+{
+ m_currentPen.setWidthF(state->getLineWidth());
+ m_painter->setPen(m_currentPen);
+}
+
+void ArthurOutputDev::updateFillColor(GfxState *state)
+{
+ GfxRGB rgb;
+ QColor brushColour = m_currentBrush.color();
+ state->getFillRGB(&rgb);
+ brushColour.setRgbF(colToDbl(rgb.r), colToDbl(rgb.g), colToDbl(rgb.b), brushColour.alphaF());
+ m_currentBrush.setColor(brushColour);
+}
+
+void ArthurOutputDev::updateStrokeColor(GfxState *state)
+{
+ GfxRGB rgb;
+ QColor penColour = m_currentPen.color();
+ state->getStrokeRGB(&rgb);
+ penColour.setRgbF(colToDbl(rgb.r), colToDbl(rgb.g), colToDbl(rgb.b), penColour.alphaF());
+ m_currentPen.setColor(penColour);
+ m_painter->setPen(m_currentPen);
+}
+
+void ArthurOutputDev::updateFillOpacity(GfxState *state)
+{
+ QColor brushColour= m_currentBrush.color();
+ brushColour.setAlphaF(state->getFillOpacity());
+ m_currentBrush.setColor(brushColour);
+}
+
+void ArthurOutputDev::updateStrokeOpacity(GfxState *state)
+{
+ QColor penColour= m_currentPen.color();
+ penColour.setAlphaF(state->getStrokeOpacity());
+ m_currentPen.setColor(penColour);
+ m_painter->setPen(m_currentPen);
+}
+
+void ArthurOutputDev::updateFont(GfxState *state)
+{
+#ifdef HAVE_SPLASH
+ GfxFont *gfxFont;
+ GfxFontLoc *fontLoc;
+ GfxFontType fontType;
+ SplashOutFontFileID *id;
+ SplashFontFile *fontFile;
+ SplashFontSrc *fontsrc = NULL;
+ FoFiTrueType *ff;
+ Object refObj, strObj;
+ GooString *fileName;
+ char *tmpBuf;
+ int tmpBufLen;
+ int *codeToGID;
+ double *textMat;
+ double m11, m12, m21, m22, fontSize;
+ SplashCoord mat[4];
+ int n;
+ int faceIndex = 0;
+ SplashCoord matrix[6];
+
+ m_needFontUpdate = false;
+ m_font = NULL;
+ fileName = NULL;
+ tmpBuf = NULL;
+ fontLoc = NULL;
+
+ if (!(gfxFont = state->getFont())) {
+ goto err1;
+ }
+ fontType = gfxFont->getType();
+ if (fontType == fontType3) {
+ goto err1;
+ }
+
+ // check the font file cache
+ id = new SplashOutFontFileID(gfxFont->getID());
+ if ((fontFile = m_fontEngine->getFontFile(id))) {
+ delete id;
+
+ } else {
+
+ if (!(fontLoc = gfxFont->locateFont(xref, gFalse))) {
+ error(errSyntaxError, -1, "Couldn't find a font for '{0:s}'",
+ gfxFont->getName() ? gfxFont->getName()->getCString()
+ : "(unnamed)");
+ goto err2;
+ }
+
+ // embedded font
+ if (fontLoc->locType == gfxFontLocEmbedded) {
+ // if there is an embedded font, read it to memory
+ tmpBuf = gfxFont->readEmbFontFile(xref, &tmpBufLen);
+ if (! tmpBuf)
+ goto err2;
+
+ // external font
+ } else { // gfxFontLocExternal
+ fileName = fontLoc->path;
+ fontType = fontLoc->fontType;
+ }
+
+ fontsrc = new SplashFontSrc;
+ if (fileName)
+ fontsrc->setFile(fileName, gFalse);
+ else
+ fontsrc->setBuf(tmpBuf, tmpBufLen, gTrue);
+
+ // load the font file
+ switch (fontType) {
+ case fontType1:
+ if (!(fontFile = m_fontEngine->loadType1Font(
+ id,
+ fontsrc,
+ (const char **)((Gfx8BitFont *)gfxFont)->getEncoding()))) {
+ error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
+ gfxFont->getName() ? gfxFont->getName()->getCString()
+ : "(unnamed)");
+ goto err2;
+ }
+ break;
+ case fontType1C:
+ if (!(fontFile = m_fontEngine->loadType1CFont(
+ id,
+ fontsrc,
+ (const char **)((Gfx8BitFont *)gfxFont)->getEncoding()))) {
+ error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
+ gfxFont->getName() ? gfxFont->getName()->getCString()
+ : "(unnamed)");
+ goto err2;
+ }
+ break;
+ case fontType1COT:
+ if (!(fontFile = m_fontEngine->loadOpenTypeT1CFont(
+ id,
+ fontsrc,
+ (const char **)((Gfx8BitFont *)gfxFont)->getEncoding()))) {
+ error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
+ gfxFont->getName() ? gfxFont->getName()->getCString()
+ : "(unnamed)");
+ goto err2;
+ }
+ break;
+ case fontTrueType:
+ case fontTrueTypeOT:
+ if (fileName)
+ ff = FoFiTrueType::load(fileName->getCString());
+ else
+ ff = FoFiTrueType::make(tmpBuf, tmpBufLen);
+ if (ff) {
+ codeToGID = ((Gfx8BitFont *)gfxFont)->getCodeToGIDMap(ff);
+ n = 256;
+ delete ff;
+ } else {
+ codeToGID = NULL;
+ n = 0;
+ }
+ if (!(fontFile = m_fontEngine->loadTrueTypeFont(
+ id,
+ fontsrc,
+ codeToGID, n))) {
+ error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
+ gfxFont->getName() ? gfxFont->getName()->getCString()
+ : "(unnamed)");
+ goto err2;
+ }
+ break;
+ case fontCIDType0:
+ case fontCIDType0C:
+ if (!(fontFile = m_fontEngine->loadCIDFont(
+ id,
+ fontsrc))) {
+ error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
+ gfxFont->getName() ? gfxFont->getName()->getCString()
+ : "(unnamed)");
+ goto err2;
+ }
+ break;
+ case fontCIDType0COT:
+ if (((GfxCIDFont *)gfxFont)->getCIDToGID()) {
+ n = ((GfxCIDFont *)gfxFont)->getCIDToGIDLen();
+ codeToGID = (int *)gmallocn(n, sizeof(int));
+ memcpy(codeToGID, ((GfxCIDFont *)gfxFont)->getCIDToGID(),
+ n * sizeof(int));
+ } else {
+ codeToGID = NULL;
+ n = 0;
+ }
+ if (!(fontFile = m_fontEngine->loadOpenTypeCFFFont(
+ id,
+ fontsrc,
+ codeToGID, n))) {
+ error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
+ gfxFont->getName() ? gfxFont->getName()->getCString()
+ : "(unnamed)");
+ goto err2;
+ }
+ break;
+ case fontCIDType2:
+ case fontCIDType2OT:
+ codeToGID = NULL;
+ n = 0;
+ if (((GfxCIDFont *)gfxFont)->getCIDToGID()) {
+ n = ((GfxCIDFont *)gfxFont)->getCIDToGIDLen();
+ if (n) {
+ codeToGID = (int *)gmallocn(n, sizeof(int));
+ memcpy(codeToGID, ((GfxCIDFont *)gfxFont)->getCIDToGID(),
+ n * sizeof(Gushort));
+ }
+ } else {
+ if (fileName)
+ ff = FoFiTrueType::load(fileName->getCString());
+ else
+ ff = FoFiTrueType::make(tmpBuf, tmpBufLen);
+ if (! ff)
+ goto err2;
+ codeToGID = ((GfxCIDFont *)gfxFont)->getCodeToGIDMap(ff, &n);
+ delete ff;
+ }
+ if (!(fontFile = m_fontEngine->loadTrueTypeFont(
+ id,
+ fontsrc,
+ codeToGID, n, faceIndex))) {
+ error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
+ gfxFont->getName() ? gfxFont->getName()->getCString()
+ : "(unnamed)");
+ goto err2;
+ }
+ break;
+ default:
+ // this shouldn't happen
+ goto err2;
+ }
+ }
+
+ // get the font matrix
+ textMat = state->getTextMat();
+ fontSize = state->getFontSize();
+ m11 = textMat[0] * fontSize * state->getHorizScaling();
+ m12 = textMat[1] * fontSize * state->getHorizScaling();
+ m21 = textMat[2] * fontSize;
+ m22 = textMat[3] * fontSize;
+
+ {
+ QMatrix painterMatrix = m_painter->worldMatrix();
+ matrix[0] = painterMatrix.m11();
+ matrix[1] = painterMatrix.m12();
+ matrix[2] = painterMatrix.m21();
+ matrix[3] = painterMatrix.m22();
+ matrix[4] = painterMatrix.dx();
+ matrix[5] = painterMatrix.dy();
+ }
+
+ // create the scaled font
+ mat[0] = m11; mat[1] = -m12;
+ mat[2] = m21; mat[3] = -m22;
+ m_font = m_fontEngine->getFont(fontFile, mat, matrix);
+
+ delete fontLoc;
+ if (fontsrc && !fontsrc->isFile)
+ fontsrc->unref();
+ return;
+
+ err2:
+ delete id;
+ delete fontLoc;
+ err1:
+ if (fontsrc && !fontsrc->isFile)
+ fontsrc->unref();
+ return;
+#endif
+}
+
+static QPainterPath convertPath(GfxState *state, GfxPath *path, Qt::FillRule fillRule)
+{
+ GfxSubpath *subpath;
+ double x1, y1, x2, y2, x3, y3;
+ int i, j;
+
+ QPainterPath qPath;
+ qPath.setFillRule(fillRule);
+ for (i = 0; i < path->getNumSubpaths(); ++i) {
+ subpath = path->getSubpath(i);
+ if (subpath->getNumPoints() > 0) {
+ state->transform(subpath->getX(0), subpath->getY(0), &x1, &y1);
+ qPath.moveTo(x1, y1);
+ j = 1;
+ while (j < subpath->getNumPoints()) {
+ if (subpath->getCurve(j)) {
+ state->transform(subpath->getX(j), subpath->getY(j), &x1, &y1);
+ state->transform(subpath->getX(j+1), subpath->getY(j+1), &x2, &y2);
+ state->transform(subpath->getX(j+2), subpath->getY(j+2), &x3, &y3);
+ qPath.cubicTo( x1, y1, x2, y2, x3, y3);
+ j += 3;
+ } else {
+ state->transform(subpath->getX(j), subpath->getY(j), &x1, &y1);
+ qPath.lineTo(x1, y1);
+ ++j;
+ }
+ }
+ if (subpath->isClosed()) {
+ qPath.closeSubpath();
+ }
+ }
+ }
+ return qPath;
+}
+
+void ArthurOutputDev::stroke(GfxState *state)
+{
+ m_painter->strokePath( convertPath( state, state->getPath(), Qt::OddEvenFill ), m_currentPen );
+}
+
+void ArthurOutputDev::fill(GfxState *state)
+{
+ m_painter->fillPath( convertPath( state, state->getPath(), Qt::WindingFill ), m_currentBrush );
+}
+
+void ArthurOutputDev::eoFill(GfxState *state)
+{
+ m_painter->fillPath( convertPath( state, state->getPath(), Qt::OddEvenFill ), m_currentBrush );
+}
+
+void ArthurOutputDev::clip(GfxState *state)
+{
+ m_painter->setClipPath(convertPath( state, state->getPath(), Qt::WindingFill ) );
+}
+
+void ArthurOutputDev::eoClip(GfxState *state)
+{
+ m_painter->setClipPath(convertPath( state, state->getPath(), Qt::OddEvenFill ) );
+}
+
+void ArthurOutputDev::drawChar(GfxState *state, double x, double y,
+ double dx, double dy,
+ double originX, double originY,
+ CharCode code, int nBytes, Unicode *u, int uLen) {
+#ifdef HAVE_SPLASH
+ double x1, y1;
+ double x2, y2;
+// SplashPath *path;
+ int render;
+
+ if (m_needFontUpdate) {
+ updateFont(state);
+ }
+ if (!m_font) {
+ return;
+ }
+
+ // check for invisible text -- this is used by Acrobat Capture
+ render = state->getRender();
+ if (render == 3) {
+ return;
+ }
+
+ x -= originX;
+ y -= originY;
+
+ // fill
+ if (!(render & 1)) {
+ 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) {
+ 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();
+ }
+ }
+ GfxRGB rgb;
+ QColor brushColour = m_currentBrush.color();
+ state->getFillRGB(&rgb);
+ brushColour.setRgbF(colToDbl(rgb.r), colToDbl(rgb.g), colToDbl(rgb.b), state->getFillOpacity());
+ m_painter->setBrush(brushColour);
+ QColor penColour = m_currentPen.color();
+ state->getStrokeRGB(&rgb);
+ penColour.setRgbF(colToDbl(rgb.r), colToDbl(rgb.g), colToDbl(rgb.b), state->getStrokeOpacity());
+ m_painter->setPen(penColour);
+ m_painter->drawPath( qPath );
+ delete fontPath;
+ }
+ }
+
+ // stroke
+ if ((render & 3) == 1 || (render & 3) == 2) {
+ qDebug() << "no stroke";
+ /*
+ if ((path = m_font->getGlyphPath(code))) {
+ path->offset((SplashCoord)x1, (SplashCoord)y1);
+ splash->stroke(path);
+ delete path;
+ }
+ */
+ }
+
+ // clip
+ if (render & 4) {
+ qDebug() << "no clip";
+ /*
+ path = m_font->getGlyphPath(code);
+ path->offset((SplashCoord)x1, (SplashCoord)y1);
+ if (textClipPath) {
+ textClipPath->append(path);
+ delete path;
+ } else {
+ textClipPath = path;
+ }
+ */
+ }
+#endif
+}
+
+GBool ArthurOutputDev::beginType3Char(GfxState *state, double x, double y,
+ double dx, double dy,
+ CharCode code, Unicode *u, int uLen)
+{
+ return gFalse;
+}
+
+void ArthurOutputDev::endType3Char(GfxState *state)
+{
+}
+
+void ArthurOutputDev::type3D0(GfxState *state, double wx, double wy)
+{
+}
+
+void ArthurOutputDev::type3D1(GfxState *state, double wx, double wy,
+ double llx, double lly, double urx, double ury)
+{
+}
+
+void ArthurOutputDev::endTextObject(GfxState *state)
+{
+}
+
+
+void ArthurOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
+ int width, int height, GBool invert,
+ GBool interpolate, GBool inlineImg)
+{
+ qDebug() << "drawImageMask";
+#if 0
+ unsigned char *buffer;
+ unsigned char *dest;
+ cairo_surface_t *image;
+ cairo_pattern_t *pattern;
+ int x, y;
+ ImageStream *imgStr;
+ Guchar *pix;
+ double *ctm;
+ cairo_matrix_t matrix;
+ int invert_bit;
+ int row_stride;
+
+ row_stride = (width + 3) & ~3;
+ buffer = (unsigned char *) malloc (height * row_stride);
+ if (buffer == NULL) {
+ error(-1, "Unable to allocate memory for image.");
+ return;
+ }
+
+ /* TODO: Do we want to cache these? */
+ imgStr = new ImageStream(str, width, 1, 1);
+ imgStr->reset();
+
+ invert_bit = invert ? 1 : 0;
+
+ for (y = 0; y < height; y++) {
+ pix = imgStr->getLine();
+ dest = buffer + y * row_stride;
+ for (x = 0; x < width; x++) {
+
+ if (pix[x] ^ invert_bit)
+ *dest++ = 0;
+ else
+ *dest++ = 255;
+ }
+ }
+
+ image = cairo_image_surface_create_for_data (buffer, CAIRO_FORMAT_A8,
+ width, height, row_stride);
+ if (image == NULL)
+ return;
+ pattern = cairo_pattern_create_for_surface (image);
+ if (pattern == NULL)
+ return;
+
+ ctm = state->getCTM();
+ LOG (printf ("drawImageMask %dx%d, matrix: %f, %f, %f, %f, %f, %f\n",
+ width, height, ctm[0], ctm[1], ctm[2], ctm[3], ctm[4], ctm[5]));
+ matrix.xx = ctm[0] / width;
+ matrix.xy = -ctm[2] / height;
+ matrix.yx = ctm[1] / width;
+ matrix.yy = -ctm[3] / height;
+ matrix.x0 = ctm[2] + ctm[4];
+ matrix.y0 = ctm[3] + ctm[5];
+ cairo_matrix_invert (&matrix);
+ cairo_pattern_set_matrix (pattern, &matrix);
+
+ cairo_pattern_set_filter (pattern, CAIRO_FILTER_BEST);
+ /* FIXME: Doesn't the image mask support any colorspace? */
+ cairo_set_source_rgb (cairo, fill_color.r, fill_color.g, fill_color.b);
+ cairo_mask (cairo, pattern);
+
+ cairo_pattern_destroy (pattern);
+ cairo_surface_destroy (image);
+ free (buffer);
+ imgStr->close ();
+ delete imgStr;
+#endif
+}
+
+//TODO: lots more work here.
+void ArthurOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
+ int width, int height,
+ GfxImageColorMap *colorMap,
+ GBool interpolate, int *maskColors, GBool inlineImg)
+{
+ unsigned int *data;
+ unsigned int *line;
+ int x, y;
+ ImageStream *imgStr;
+ Guchar *pix;
+ int i;
+ double *ctm;
+ QMatrix matrix;
+ QImage image;
+ int stride;
+
+ /* TODO: Do we want to cache these? */
+ imgStr = new ImageStream(str, width,
+ colorMap->getNumPixelComps(),
+ colorMap->getBits());
+ imgStr->reset();
+
+ 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) {
+ *line = *line | 0xff000000;
+ break;
+ }
+ }
+ pix += colorMap->getNumPixelComps();
+ line++;
+ }
+ } else {
+ for (x = 0; x < width; x++) { *line = *line | 0xff000000; line++; }
+ }
+ }
+
+ 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), image );
+ delete imgStr;
+
+}
diff --git a/qt4/src/ArthurOutputDev.h b/qt4/src/ArthurOutputDev.h
new file mode 100644
index 0000000..9d5e867
--- /dev/null
+++ b/qt4/src/ArthurOutputDev.h
@@ -0,0 +1,170 @@
+//========================================================================
+//
+// ArthurOutputDev.h
+//
+// Copyright 2003 Glyph & Cog, LLC
+//
+//========================================================================
+
+//========================================================================
+//
+// Modified under the Poppler project - http://poppler.freedesktop.org
+//
+// All changes made under the Poppler project to this file are licensed
+// under GPL version 2 or later
+//
+// Copyright (C) 2005 Brad Hards <bradh at frogmouth.net>
+// Copyright (C) 2005 Albert Astals Cid <aacid at kde.org>
+// Copyright (C) 2009, 2011 Carlos Garcia Campos <carlosgc at gnome.org>
+// Copyright (C) 2010 Pino Toscano <pino at kde.org>
+// Copyright (C) 2011 Andreas Hartmetz <ahartmetz at gmail.com>
+// Copyright (C) 2013 Thomas Freitag <Thomas.Freitag at alfa.de>
+//
+// 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
+//
+//========================================================================
+
+#ifndef ARTHUROUTPUTDEV_H
+#define ARTHUROUTPUTDEV_H
+
+#ifdef USE_GCC_PRAGMAS
+#pragma interface
+#endif
+
+#include "goo/gtypes.h"
+#include "OutputDev.h"
+#include "GfxState.h"
+
+#include <QtGui/QPainter>
+
+class GfxState;
+class GfxPath;
+class Gfx8BitFont;
+struct GfxRGB;
+
+class SplashFont;
+class SplashFontEngine;
+struct SplashGlyphBitmap;
+
+//------------------------------------------------------------------------
+// ArthurOutputDev - Qt 4 QPainter renderer
+//------------------------------------------------------------------------
+
+class ArthurOutputDev: public OutputDev {
+public:
+ /**
+ * Describes how fonts are distorted (aka hinted) to fit the pixel grid.
+ * More hinting means sharper edges and less adherence to the true letter shapes.
+ */
+ enum FontHinting {
+ NoHinting = 0, ///< Font shapes are left unchanged
+ SlightHinting, ///< Font shapes are distorted vertically only
+ FullHinting ///< Font shapes are distorted horizontally and vertically
+ };
+
+ // Constructor.
+ ArthurOutputDev(QPainter *painter );
+
+ // Destructor.
+ virtual ~ArthurOutputDev();
+
+ void setFontHinting(FontHinting hinting) { m_fontHinting = hinting; }
+
+ //----- get info about output device
+
+ // Does this device use upside-down coordinates?
+ // (Upside-down means (0,0) is the top left corner of the page.)
+ virtual GBool upsideDown() { return gTrue; }
+
+ // Does this device use drawChar() or drawString()?
+ virtual GBool useDrawChar() { return gTrue; }
+
+ // Does this device use beginType3Char/endType3Char? Otherwise,
+ // text in Type 3 fonts will be drawn with drawChar/drawString.
+ virtual GBool interpretType3Chars() { return gTrue; }
+
+ //----- initialization and control
+
+ // Start a page.
+ virtual void startPage(int pageNum, GfxState *state, XRef *xref);
+
+ // End a page.
+ virtual void endPage();
+
+ //----- save/restore graphics state
+ virtual void saveState(GfxState *state);
+ virtual void restoreState(GfxState *state);
+
+ //----- update graphics state
+ virtual void updateAll(GfxState *state);
+ virtual void updateCTM(GfxState *state, double m11, double m12,
+ double m21, double m22, double m31, double m32);
+ virtual void updateLineDash(GfxState *state);
+ virtual void updateFlatness(GfxState *state);
+ virtual void updateLineJoin(GfxState *state);
+ virtual void updateLineCap(GfxState *state);
+ virtual void updateMiterLimit(GfxState *state);
+ virtual void updateLineWidth(GfxState *state);
+ virtual void updateFillColor(GfxState *state);
+ virtual void updateStrokeColor(GfxState *state);
+ virtual void updateFillOpacity(GfxState *state);
+ virtual void updateStrokeOpacity(GfxState *state);
+
+ //----- update text state
+ virtual void updateFont(GfxState *state);
+
+ //----- path painting
+ virtual void stroke(GfxState *state);
+ virtual void fill(GfxState *state);
+ virtual void eoFill(GfxState *state);
+
+ //----- path clipping
+ virtual void clip(GfxState *state);
+ virtual void eoClip(GfxState *state);
+
+ //----- text drawing
+ // virtual void drawString(GfxState *state, GooString *s);
+ virtual void drawChar(GfxState *state, double x, double y,
+ double dx, double dy,
+ double originX, double originY,
+ CharCode code, int nBytes, Unicode *u, int uLen);
+ virtual GBool beginType3Char(GfxState *state, double x, double y,
+ double dx, double dy,
+ CharCode code, Unicode *u, int uLen);
+ virtual void endType3Char(GfxState *state);
+ virtual void endTextObject(GfxState *state);
+
+ //----- image drawing
+ virtual void drawImageMask(GfxState *state, Object *ref, Stream *str,
+ int width, int height, GBool invert,
+ GBool interpolate, GBool inlineImg);
+ virtual void drawImage(GfxState *state, Object *ref, Stream *str,
+ int width, int height, GfxImageColorMap *colorMap,
+ GBool interpolate, int *maskColors, GBool inlineImg);
+
+ //----- Type 3 font operators
+ virtual void type3D0(GfxState *state, double wx, double wy);
+ virtual void type3D1(GfxState *state, double wx, double wy,
+ double llx, double lly, double urx, double ury);
+
+ //----- special access
+
+ // Called to indicate that a new PDF document has been loaded.
+ void startDoc(XRef *xrefA);
+
+ GBool isReverseVideo() { return gFalse; }
+
+private:
+ QPainter *m_painter;
+ FontHinting m_fontHinting;
+ QFont m_currentFont;
+ QPen m_currentPen;
+ QBrush m_currentBrush;
+ GBool m_needFontUpdate; // set when the font needs to be updated
+ SplashFontEngine *m_fontEngine;
+ SplashFont *m_font; // current font
+ XRef *xref; // xref table for current document
+};
+
+#endif
diff --git a/qt4/src/CMakeLists.txt b/qt4/src/CMakeLists.txt
index dff7aa6..59953ed 100644
--- a/qt4/src/CMakeLists.txt
+++ b/qt4/src/CMakeLists.txt
@@ -26,7 +26,7 @@ set(poppler_qt4_SRCS
poppler-textbox.cc
poppler-page-transition.cc
poppler-media.cc
- ${CMAKE_SOURCE_DIR}/poppler/ArthurOutputDev.cc
+ ArthurOutputDev.cc
)
qt4_automoc(${poppler_qt4_SRCS})
add_library(poppler-qt4 SHARED ${poppler_qt4_SRCS})
diff --git a/qt4/src/Makefile.am b/qt4/src/Makefile.am
index efa0e14..13ab7ff 100644
--- a/qt4/src/Makefile.am
+++ b/qt4/src/Makefile.am
@@ -51,14 +51,15 @@ libpoppler_qt4_la_SOURCES = \
poppler-export.h \
poppler-private.h \
poppler-page-transition-private.h \
- poppler-embeddedfile-private.h
+ poppler-embeddedfile-private.h \
+ ArthurOutputDev.h \
+ ArthurOutputDev.cc
libpoppler_qt4_la_CXXFLAGS = \
-Dpoppler_qt4_EXPORTS
libpoppler_qt4_la_LIBADD = \
$(top_builddir)/poppler/libpoppler.la \
- $(top_builddir)/poppler/libpoppler-arthur.la \
$(POPPLER_QT4_LIBS)
libpoppler_qt4_la_LDFLAGS = -version-info 7:0:3 @create_shared_lib@ @auto_import_flags@
diff --git a/qt5/src/ArthurOutputDev.cc b/qt5/src/ArthurOutputDev.cc
new file mode 100644
index 0000000..5d57e93
--- /dev/null
+++ b/qt5/src/ArthurOutputDev.cc
@@ -0,0 +1,816 @@
+//========================================================================
+//
+// ArthurOutputDev.cc
+//
+// Copyright 2003 Glyph & Cog, LLC
+//
+//========================================================================
+
+//========================================================================
+//
+// Modified under the Poppler project - http://poppler.freedesktop.org
+//
+// All changes made under the Poppler project to this file are licensed
+// under GPL version 2 or later
+//
+// Copyright (C) 2005 Brad Hards <bradh at frogmouth.net>
+// Copyright (C) 2005-2009, 2011, 2012 Albert Astals Cid <aacid at kde.org>
+// Copyright (C) 2008, 2010 Pino Toscano <pino at kde.org>
+// Copyright (C) 2009, 2011 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>
+// Copyright (C) 2011 Andreas Hartmetz <ahartmetz at gmail.com>
+// Copyright (C) 2013 Thomas Freitag <Thomas.Freitag at alfa.de>
+//
+// 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
+//
+//========================================================================
+
+#include <config.h>
+
+#ifdef USE_GCC_PRAGMAS
+#pragma implementation
+#endif
+
+#include <string.h>
+#include <math.h>
+
+#include "goo/gfile.h"
+#include "GlobalParams.h"
+#include "Error.h"
+#include "Object.h"
+#include "GfxState.h"
+#include "GfxFont.h"
+#include "Link.h"
+#include "FontEncodingTables.h"
+#include <fofi/FoFiTrueType.h>
+#include "ArthurOutputDev.h"
+
+#include <QtCore/QtDebug>
+#include <QtGui/QPainterPath>
+//------------------------------------------------------------------------
+
+#ifdef HAVE_SPLASH
+#include "splash/SplashFontFileID.h"
+#include "splash/SplashFontFile.h"
+#include "splash/SplashFontEngine.h"
+#include "splash/SplashFont.h"
+#include "splash/SplashMath.h"
+#include "splash/SplashPath.h"
+#include "splash/SplashGlyphBitmap.h"
+//------------------------------------------------------------------------
+// SplashOutFontFileID
+//------------------------------------------------------------------------
+
+class SplashOutFontFileID: public SplashFontFileID {
+public:
+
+ SplashOutFontFileID(Ref *rA) { r = *rA; }
+
+ ~SplashOutFontFileID() {}
+
+ GBool matches(SplashFontFileID *id) {
+ return ((SplashOutFontFileID *)id)->r.num == r.num &&
+ ((SplashOutFontFileID *)id)->r.gen == r.gen;
+ }
+
+private:
+
+ Ref r;
+};
+
+#endif
+
+//------------------------------------------------------------------------
+// ArthurOutputDev
+//------------------------------------------------------------------------
+
+ArthurOutputDev::ArthurOutputDev(QPainter *painter):
+ m_painter(painter),
+ m_fontHinting(NoHinting)
+{
+ m_currentBrush = QBrush(Qt::SolidPattern);
+ m_fontEngine = 0;
+ m_font = 0;
+}
+
+ArthurOutputDev::~ArthurOutputDev()
+{
+#ifdef HAVE_SPLASH
+ delete m_fontEngine;
+#endif
+}
+
+void ArthurOutputDev::startDoc(XRef *xrefA) {
+ xref = xrefA;
+#ifdef HAVE_SPLASH
+ delete m_fontEngine;
+
+ const bool isHintingEnabled = m_fontHinting != NoHinting;
+ const bool isSlightHinting = m_fontHinting == SlightHinting;
+
+ m_fontEngine = new SplashFontEngine(
+#if HAVE_T1LIB_H
+ globalParams->getEnableT1lib(),
+#endif
+#if HAVE_FREETYPE_FREETYPE_H || HAVE_FREETYPE_H
+ globalParams->getEnableFreeType(),
+ isHintingEnabled,
+ isSlightHinting,
+#endif
+ m_painter->testRenderHint(QPainter::TextAntialiasing));
+#endif
+}
+
+void ArthurOutputDev::startPage(int pageNum, GfxState *state, XRef *xref)
+{
+ // fill page with white background.
+ int w = static_cast<int>(state->getPageWidth());
+ int h = static_cast<int>(state->getPageHeight());
+ QColor fillColour(Qt::white);
+ QBrush fill(fillColour);
+ m_painter->save();
+ m_painter->setPen(fillColour);
+ m_painter->setBrush(fill);
+ m_painter->drawRect(0, 0, w, h);
+ m_painter->restore();
+}
+
+void ArthurOutputDev::endPage() {
+}
+
+void ArthurOutputDev::saveState(GfxState *state)
+{
+ m_painter->save();
+}
+
+void ArthurOutputDev::restoreState(GfxState *state)
+{
+ m_painter->restore();
+}
+
+void ArthurOutputDev::updateAll(GfxState *state)
+{
+ OutputDev::updateAll(state);
+ m_needFontUpdate = gTrue;
+}
+
+// This looks wrong - why aren't adjusting the matrix?
+void ArthurOutputDev::updateCTM(GfxState *state, double m11, double m12,
+ double m21, double m22,
+ double m31, double m32)
+{
+ updateLineDash(state);
+ updateLineJoin(state);
+ updateLineCap(state);
+ updateLineWidth(state);
+}
+
+void ArthurOutputDev::updateLineDash(GfxState *state)
+{
+ double *dashPattern;
+ int dashLength;
+ double dashStart;
+ state->getLineDash(&dashPattern, &dashLength, &dashStart);
+ QVector<qreal> pattern(dashLength);
+ for (int i = 0; i < dashLength; ++i) {
+ pattern[i] = dashPattern[i];
+ }
+ m_currentPen.setDashPattern(pattern);
+ m_currentPen.setDashOffset(dashStart);
+ m_painter->setPen(m_currentPen);
+}
+
+void ArthurOutputDev::updateFlatness(GfxState *state)
+{
+ // qDebug() << "updateFlatness";
+}
+
+void ArthurOutputDev::updateLineJoin(GfxState *state)
+{
+ switch (state->getLineJoin()) {
+ case 0:
+ m_currentPen.setJoinStyle(Qt::MiterJoin);
+ break;
+ case 1:
+ m_currentPen.setJoinStyle(Qt::RoundJoin);
+ break;
+ case 2:
+ m_currentPen.setJoinStyle(Qt::BevelJoin);
+ break;
+ }
+ m_painter->setPen(m_currentPen);
+}
+
+void ArthurOutputDev::updateLineCap(GfxState *state)
+{
+ switch (state->getLineCap()) {
+ case 0:
+ m_currentPen.setCapStyle(Qt::FlatCap);
+ break;
+ case 1:
+ m_currentPen.setCapStyle(Qt::RoundCap);
+ break;
+ case 2:
+ m_currentPen.setCapStyle(Qt::SquareCap);
+ break;
+ }
+ m_painter->setPen(m_currentPen);
+}
+
+void ArthurOutputDev::updateMiterLimit(GfxState *state)
+{
+ m_currentPen.setMiterLimit(state->getMiterLimit());
+ m_painter->setPen(m_currentPen);
+}
+
+void ArthurOutputDev::updateLineWidth(GfxState *state)
+{
+ m_currentPen.setWidthF(state->getLineWidth());
+ m_painter->setPen(m_currentPen);
+}
+
+void ArthurOutputDev::updateFillColor(GfxState *state)
+{
+ GfxRGB rgb;
+ QColor brushColour = m_currentBrush.color();
+ state->getFillRGB(&rgb);
+ brushColour.setRgbF(colToDbl(rgb.r), colToDbl(rgb.g), colToDbl(rgb.b), brushColour.alphaF());
+ m_currentBrush.setColor(brushColour);
+}
+
+void ArthurOutputDev::updateStrokeColor(GfxState *state)
+{
+ GfxRGB rgb;
+ QColor penColour = m_currentPen.color();
+ state->getStrokeRGB(&rgb);
+ penColour.setRgbF(colToDbl(rgb.r), colToDbl(rgb.g), colToDbl(rgb.b), penColour.alphaF());
+ m_currentPen.setColor(penColour);
+ m_painter->setPen(m_currentPen);
+}
+
+void ArthurOutputDev::updateFillOpacity(GfxState *state)
+{
+ QColor brushColour= m_currentBrush.color();
+ brushColour.setAlphaF(state->getFillOpacity());
+ m_currentBrush.setColor(brushColour);
+}
+
+void ArthurOutputDev::updateStrokeOpacity(GfxState *state)
+{
+ QColor penColour= m_currentPen.color();
+ penColour.setAlphaF(state->getStrokeOpacity());
+ m_currentPen.setColor(penColour);
+ m_painter->setPen(m_currentPen);
+}
+
+void ArthurOutputDev::updateFont(GfxState *state)
+{
+#ifdef HAVE_SPLASH
+ GfxFont *gfxFont;
+ GfxFontLoc *fontLoc;
+ GfxFontType fontType;
+ SplashOutFontFileID *id;
+ SplashFontFile *fontFile;
+ SplashFontSrc *fontsrc = NULL;
+ FoFiTrueType *ff;
+ Object refObj, strObj;
+ GooString *fileName;
+ char *tmpBuf;
+ int tmpBufLen;
+ int *codeToGID;
+ double *textMat;
+ double m11, m12, m21, m22, fontSize;
+ SplashCoord mat[4];
+ int n;
+ int faceIndex = 0;
+ SplashCoord matrix[6];
+
+ m_needFontUpdate = false;
+ m_font = NULL;
+ fileName = NULL;
+ tmpBuf = NULL;
+ fontLoc = NULL;
+
+ if (!(gfxFont = state->getFont())) {
+ goto err1;
+ }
+ fontType = gfxFont->getType();
+ if (fontType == fontType3) {
+ goto err1;
+ }
+
+ // check the font file cache
+ id = new SplashOutFontFileID(gfxFont->getID());
+ if ((fontFile = m_fontEngine->getFontFile(id))) {
+ delete id;
+
+ } else {
+
+ if (!(fontLoc = gfxFont->locateFont(xref, gFalse))) {
+ error(errSyntaxError, -1, "Couldn't find a font for '{0:s}'",
+ gfxFont->getName() ? gfxFont->getName()->getCString()
+ : "(unnamed)");
+ goto err2;
+ }
+
+ // embedded font
+ if (fontLoc->locType == gfxFontLocEmbedded) {
+ // if there is an embedded font, read it to memory
+ tmpBuf = gfxFont->readEmbFontFile(xref, &tmpBufLen);
+ if (! tmpBuf)
+ goto err2;
+
+ // external font
+ } else { // gfxFontLocExternal
+ fileName = fontLoc->path;
+ fontType = fontLoc->fontType;
+ }
+
+ fontsrc = new SplashFontSrc;
+ if (fileName)
+ fontsrc->setFile(fileName, gFalse);
+ else
+ fontsrc->setBuf(tmpBuf, tmpBufLen, gTrue);
+
+ // load the font file
+ switch (fontType) {
+ case fontType1:
+ if (!(fontFile = m_fontEngine->loadType1Font(
+ id,
+ fontsrc,
+ (const char **)((Gfx8BitFont *)gfxFont)->getEncoding()))) {
+ error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
+ gfxFont->getName() ? gfxFont->getName()->getCString()
+ : "(unnamed)");
+ goto err2;
+ }
+ break;
+ case fontType1C:
+ if (!(fontFile = m_fontEngine->loadType1CFont(
+ id,
+ fontsrc,
+ (const char **)((Gfx8BitFont *)gfxFont)->getEncoding()))) {
+ error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
+ gfxFont->getName() ? gfxFont->getName()->getCString()
+ : "(unnamed)");
+ goto err2;
+ }
+ break;
+ case fontType1COT:
+ if (!(fontFile = m_fontEngine->loadOpenTypeT1CFont(
+ id,
+ fontsrc,
+ (const char **)((Gfx8BitFont *)gfxFont)->getEncoding()))) {
+ error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
+ gfxFont->getName() ? gfxFont->getName()->getCString()
+ : "(unnamed)");
+ goto err2;
+ }
+ break;
+ case fontTrueType:
+ case fontTrueTypeOT:
+ if (fileName)
+ ff = FoFiTrueType::load(fileName->getCString());
+ else
+ ff = FoFiTrueType::make(tmpBuf, tmpBufLen);
+ if (ff) {
+ codeToGID = ((Gfx8BitFont *)gfxFont)->getCodeToGIDMap(ff);
+ n = 256;
+ delete ff;
+ } else {
+ codeToGID = NULL;
+ n = 0;
+ }
+ if (!(fontFile = m_fontEngine->loadTrueTypeFont(
+ id,
+ fontsrc,
+ codeToGID, n))) {
+ error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
+ gfxFont->getName() ? gfxFont->getName()->getCString()
+ : "(unnamed)");
+ goto err2;
+ }
+ break;
+ case fontCIDType0:
+ case fontCIDType0C:
+ if (!(fontFile = m_fontEngine->loadCIDFont(
+ id,
+ fontsrc))) {
+ error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
+ gfxFont->getName() ? gfxFont->getName()->getCString()
+ : "(unnamed)");
+ goto err2;
+ }
+ break;
+ case fontCIDType0COT:
+ if (((GfxCIDFont *)gfxFont)->getCIDToGID()) {
+ n = ((GfxCIDFont *)gfxFont)->getCIDToGIDLen();
+ codeToGID = (int *)gmallocn(n, sizeof(int));
+ memcpy(codeToGID, ((GfxCIDFont *)gfxFont)->getCIDToGID(),
+ n * sizeof(int));
+ } else {
+ codeToGID = NULL;
+ n = 0;
+ }
+ if (!(fontFile = m_fontEngine->loadOpenTypeCFFFont(
+ id,
+ fontsrc,
+ codeToGID, n))) {
+ error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
+ gfxFont->getName() ? gfxFont->getName()->getCString()
+ : "(unnamed)");
+ goto err2;
+ }
+ break;
+ case fontCIDType2:
+ case fontCIDType2OT:
+ codeToGID = NULL;
+ n = 0;
+ if (((GfxCIDFont *)gfxFont)->getCIDToGID()) {
+ n = ((GfxCIDFont *)gfxFont)->getCIDToGIDLen();
+ if (n) {
+ codeToGID = (int *)gmallocn(n, sizeof(int));
+ memcpy(codeToGID, ((GfxCIDFont *)gfxFont)->getCIDToGID(),
+ n * sizeof(Gushort));
+ }
+ } else {
+ if (fileName)
+ ff = FoFiTrueType::load(fileName->getCString());
+ else
+ ff = FoFiTrueType::make(tmpBuf, tmpBufLen);
+ if (! ff)
+ goto err2;
+ codeToGID = ((GfxCIDFont *)gfxFont)->getCodeToGIDMap(ff, &n);
+ delete ff;
+ }
+ if (!(fontFile = m_fontEngine->loadTrueTypeFont(
+ id,
+ fontsrc,
+ codeToGID, n, faceIndex))) {
+ error(errSyntaxError, -1, "Couldn't create a font for '{0:s}'",
+ gfxFont->getName() ? gfxFont->getName()->getCString()
+ : "(unnamed)");
+ goto err2;
+ }
+ break;
+ default:
+ // this shouldn't happen
+ goto err2;
+ }
+ }
+
+ // get the font matrix
+ textMat = state->getTextMat();
+ fontSize = state->getFontSize();
+ m11 = textMat[0] * fontSize * state->getHorizScaling();
+ m12 = textMat[1] * fontSize * state->getHorizScaling();
+ m21 = textMat[2] * fontSize;
+ m22 = textMat[3] * fontSize;
+
+ {
+ QMatrix painterMatrix = m_painter->worldMatrix();
+ matrix[0] = painterMatrix.m11();
+ matrix[1] = painterMatrix.m12();
+ matrix[2] = painterMatrix.m21();
+ matrix[3] = painterMatrix.m22();
+ matrix[4] = painterMatrix.dx();
+ matrix[5] = painterMatrix.dy();
+ }
+
+ // create the scaled font
+ mat[0] = m11; mat[1] = -m12;
+ mat[2] = m21; mat[3] = -m22;
+ m_font = m_fontEngine->getFont(fontFile, mat, matrix);
+
+ delete fontLoc;
+ if (fontsrc && !fontsrc->isFile)
+ fontsrc->unref();
+ return;
+
+ err2:
+ delete id;
+ delete fontLoc;
+ err1:
+ if (fontsrc && !fontsrc->isFile)
+ fontsrc->unref();
+ return;
+#endif
+}
+
+static QPainterPath convertPath(GfxState *state, GfxPath *path, Qt::FillRule fillRule)
+{
+ GfxSubpath *subpath;
+ double x1, y1, x2, y2, x3, y3;
+ int i, j;
+
+ QPainterPath qPath;
+ qPath.setFillRule(fillRule);
+ for (i = 0; i < path->getNumSubpaths(); ++i) {
+ subpath = path->getSubpath(i);
+ if (subpath->getNumPoints() > 0) {
+ state->transform(subpath->getX(0), subpath->getY(0), &x1, &y1);
+ qPath.moveTo(x1, y1);
+ j = 1;
+ while (j < subpath->getNumPoints()) {
+ if (subpath->getCurve(j)) {
+ state->transform(subpath->getX(j), subpath->getY(j), &x1, &y1);
+ state->transform(subpath->getX(j+1), subpath->getY(j+1), &x2, &y2);
+ state->transform(subpath->getX(j+2), subpath->getY(j+2), &x3, &y3);
+ qPath.cubicTo( x1, y1, x2, y2, x3, y3);
+ j += 3;
+ } else {
+ state->transform(subpath->getX(j), subpath->getY(j), &x1, &y1);
+ qPath.lineTo(x1, y1);
+ ++j;
+ }
+ }
+ if (subpath->isClosed()) {
+ qPath.closeSubpath();
+ }
+ }
+ }
+ return qPath;
+}
+
+void ArthurOutputDev::stroke(GfxState *state)
+{
+ m_painter->strokePath( convertPath( state, state->getPath(), Qt::OddEvenFill ), m_currentPen );
+}
+
+void ArthurOutputDev::fill(GfxState *state)
+{
+ m_painter->fillPath( convertPath( state, state->getPath(), Qt::WindingFill ), m_currentBrush );
+}
+
+void ArthurOutputDev::eoFill(GfxState *state)
+{
+ m_painter->fillPath( convertPath( state, state->getPath(), Qt::OddEvenFill ), m_currentBrush );
+}
+
+void ArthurOutputDev::clip(GfxState *state)
+{
+ m_painter->setClipPath(convertPath( state, state->getPath(), Qt::WindingFill ) );
+}
+
+void ArthurOutputDev::eoClip(GfxState *state)
+{
+ m_painter->setClipPath(convertPath( state, state->getPath(), Qt::OddEvenFill ) );
+}
+
+void ArthurOutputDev::drawChar(GfxState *state, double x, double y,
+ double dx, double dy,
+ double originX, double originY,
+ CharCode code, int nBytes, Unicode *u, int uLen) {
+#ifdef HAVE_SPLASH
+ double x1, y1;
+ double x2, y2;
+// SplashPath *path;
+ int render;
+
+ if (m_needFontUpdate) {
+ updateFont(state);
+ }
+ if (!m_font) {
+ return;
+ }
+
+ // check for invisible text -- this is used by Acrobat Capture
+ render = state->getRender();
+ if (render == 3) {
+ return;
+ }
+
+ x -= originX;
+ y -= originY;
+
+ // fill
+ if (!(render & 1)) {
+ 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) {
+ 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();
+ }
+ }
+ GfxRGB rgb;
+ QColor brushColour = m_currentBrush.color();
+ state->getFillRGB(&rgb);
+ brushColour.setRgbF(colToDbl(rgb.r), colToDbl(rgb.g), colToDbl(rgb.b), state->getFillOpacity());
+ m_painter->setBrush(brushColour);
+ QColor penColour = m_currentPen.color();
+ state->getStrokeRGB(&rgb);
+ penColour.setRgbF(colToDbl(rgb.r), colToDbl(rgb.g), colToDbl(rgb.b), state->getStrokeOpacity());
+ m_painter->setPen(penColour);
+ m_painter->drawPath( qPath );
+ delete fontPath;
+ }
+ }
+
+ // stroke
+ if ((render & 3) == 1 || (render & 3) == 2) {
+ qDebug() << "no stroke";
+ /*
+ if ((path = m_font->getGlyphPath(code))) {
+ path->offset((SplashCoord)x1, (SplashCoord)y1);
+ splash->stroke(path);
+ delete path;
+ }
+ */
+ }
+
+ // clip
+ if (render & 4) {
+ qDebug() << "no clip";
+ /*
+ path = m_font->getGlyphPath(code);
+ path->offset((SplashCoord)x1, (SplashCoord)y1);
+ if (textClipPath) {
+ textClipPath->append(path);
+ delete path;
+ } else {
+ textClipPath = path;
+ }
+ */
+ }
+#endif
+}
+
+GBool ArthurOutputDev::beginType3Char(GfxState *state, double x, double y,
+ double dx, double dy,
+ CharCode code, Unicode *u, int uLen)
+{
+ return gFalse;
+}
+
+void ArthurOutputDev::endType3Char(GfxState *state)
+{
+}
+
+void ArthurOutputDev::type3D0(GfxState *state, double wx, double wy)
+{
+}
+
+void ArthurOutputDev::type3D1(GfxState *state, double wx, double wy,
+ double llx, double lly, double urx, double ury)
+{
+}
+
+void ArthurOutputDev::endTextObject(GfxState *state)
+{
+}
+
+
+void ArthurOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
+ int width, int height, GBool invert,
+ GBool interpolate, GBool inlineImg)
+{
+ qDebug() << "drawImageMask";
+#if 0
+ unsigned char *buffer;
+ unsigned char *dest;
+ cairo_surface_t *image;
+ cairo_pattern_t *pattern;
+ int x, y;
+ ImageStream *imgStr;
+ Guchar *pix;
+ double *ctm;
+ cairo_matrix_t matrix;
+ int invert_bit;
+ int row_stride;
+
+ row_stride = (width + 3) & ~3;
+ buffer = (unsigned char *) malloc (height * row_stride);
+ if (buffer == NULL) {
+ error(-1, "Unable to allocate memory for image.");
+ return;
+ }
+
+ /* TODO: Do we want to cache these? */
+ imgStr = new ImageStream(str, width, 1, 1);
+ imgStr->reset();
+
+ invert_bit = invert ? 1 : 0;
+
+ for (y = 0; y < height; y++) {
+ pix = imgStr->getLine();
+ dest = buffer + y * row_stride;
+ for (x = 0; x < width; x++) {
+
+ if (pix[x] ^ invert_bit)
+ *dest++ = 0;
+ else
+ *dest++ = 255;
+ }
+ }
+
+ image = cairo_image_surface_create_for_data (buffer, CAIRO_FORMAT_A8,
+ width, height, row_stride);
+ if (image == NULL)
+ return;
+ pattern = cairo_pattern_create_for_surface (image);
+ if (pattern == NULL)
+ return;
+
+ ctm = state->getCTM();
+ LOG (printf ("drawImageMask %dx%d, matrix: %f, %f, %f, %f, %f, %f\n",
+ width, height, ctm[0], ctm[1], ctm[2], ctm[3], ctm[4], ctm[5]));
+ matrix.xx = ctm[0] / width;
+ matrix.xy = -ctm[2] / height;
+ matrix.yx = ctm[1] / width;
+ matrix.yy = -ctm[3] / height;
+ matrix.x0 = ctm[2] + ctm[4];
+ matrix.y0 = ctm[3] + ctm[5];
+ cairo_matrix_invert (&matrix);
+ cairo_pattern_set_matrix (pattern, &matrix);
+
+ cairo_pattern_set_filter (pattern, CAIRO_FILTER_BEST);
+ /* FIXME: Doesn't the image mask support any colorspace? */
+ cairo_set_source_rgb (cairo, fill_color.r, fill_color.g, fill_color.b);
+ cairo_mask (cairo, pattern);
+
+ cairo_pattern_destroy (pattern);
+ cairo_surface_destroy (image);
+ free (buffer);
+ imgStr->close ();
+ delete imgStr;
+#endif
+}
+
+//TODO: lots more work here.
+void ArthurOutputDev::drawImage(GfxState *state, Object *ref, Stream *str,
+ int width, int height,
+ GfxImageColorMap *colorMap,
+ GBool interpolate, int *maskColors, GBool inlineImg)
+{
+ unsigned int *data;
+ unsigned int *line;
+ int x, y;
+ ImageStream *imgStr;
+ Guchar *pix;
+ int i;
+ double *ctm;
+ QMatrix matrix;
+ QImage image;
+ int stride;
+
+ /* TODO: Do we want to cache these? */
+ imgStr = new ImageStream(str, width,
+ colorMap->getNumPixelComps(),
+ colorMap->getBits());
+ imgStr->reset();
+
+ 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) {
+ *line = *line | 0xff000000;
+ break;
+ }
+ }
+ pix += colorMap->getNumPixelComps();
+ line++;
+ }
+ } else {
+ for (x = 0; x < width; x++) { *line = *line | 0xff000000; line++; }
+ }
+ }
+
+ 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), image );
+ delete imgStr;
+
+}
diff --git a/qt5/src/ArthurOutputDev.h b/qt5/src/ArthurOutputDev.h
new file mode 100644
index 0000000..9d5e867
--- /dev/null
+++ b/qt5/src/ArthurOutputDev.h
@@ -0,0 +1,170 @@
+//========================================================================
+//
+// ArthurOutputDev.h
+//
+// Copyright 2003 Glyph & Cog, LLC
+//
+//========================================================================
+
+//========================================================================
+//
+// Modified under the Poppler project - http://poppler.freedesktop.org
+//
+// All changes made under the Poppler project to this file are licensed
+// under GPL version 2 or later
+//
+// Copyright (C) 2005 Brad Hards <bradh at frogmouth.net>
+// Copyright (C) 2005 Albert Astals Cid <aacid at kde.org>
+// Copyright (C) 2009, 2011 Carlos Garcia Campos <carlosgc at gnome.org>
+// Copyright (C) 2010 Pino Toscano <pino at kde.org>
+// Copyright (C) 2011 Andreas Hartmetz <ahartmetz at gmail.com>
+// Copyright (C) 2013 Thomas Freitag <Thomas.Freitag at alfa.de>
+//
+// 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
+//
+//========================================================================
+
+#ifndef ARTHUROUTPUTDEV_H
+#define ARTHUROUTPUTDEV_H
+
+#ifdef USE_GCC_PRAGMAS
+#pragma interface
+#endif
+
+#include "goo/gtypes.h"
+#include "OutputDev.h"
+#include "GfxState.h"
+
+#include <QtGui/QPainter>
+
+class GfxState;
+class GfxPath;
+class Gfx8BitFont;
+struct GfxRGB;
+
+class SplashFont;
+class SplashFontEngine;
+struct SplashGlyphBitmap;
+
+//------------------------------------------------------------------------
+// ArthurOutputDev - Qt 4 QPainter renderer
+//------------------------------------------------------------------------
+
+class ArthurOutputDev: public OutputDev {
+public:
+ /**
+ * Describes how fonts are distorted (aka hinted) to fit the pixel grid.
+ * More hinting means sharper edges and less adherence to the true letter shapes.
+ */
+ enum FontHinting {
+ NoHinting = 0, ///< Font shapes are left unchanged
+ SlightHinting, ///< Font shapes are distorted vertically only
+ FullHinting ///< Font shapes are distorted horizontally and vertically
+ };
+
+ // Constructor.
+ ArthurOutputDev(QPainter *painter );
+
+ // Destructor.
+ virtual ~ArthurOutputDev();
+
+ void setFontHinting(FontHinting hinting) { m_fontHinting = hinting; }
+
+ //----- get info about output device
+
+ // Does this device use upside-down coordinates?
+ // (Upside-down means (0,0) is the top left corner of the page.)
+ virtual GBool upsideDown() { return gTrue; }
+
+ // Does this device use drawChar() or drawString()?
+ virtual GBool useDrawChar() { return gTrue; }
+
+ // Does this device use beginType3Char/endType3Char? Otherwise,
+ // text in Type 3 fonts will be drawn with drawChar/drawString.
+ virtual GBool interpretType3Chars() { return gTrue; }
+
+ //----- initialization and control
+
+ // Start a page.
+ virtual void startPage(int pageNum, GfxState *state, XRef *xref);
+
+ // End a page.
+ virtual void endPage();
+
+ //----- save/restore graphics state
+ virtual void saveState(GfxState *state);
+ virtual void restoreState(GfxState *state);
+
+ //----- update graphics state
+ virtual void updateAll(GfxState *state);
+ virtual void updateCTM(GfxState *state, double m11, double m12,
+ double m21, double m22, double m31, double m32);
+ virtual void updateLineDash(GfxState *state);
+ virtual void updateFlatness(GfxState *state);
+ virtual void updateLineJoin(GfxState *state);
+ virtual void updateLineCap(GfxState *state);
+ virtual void updateMiterLimit(GfxState *state);
+ virtual void updateLineWidth(GfxState *state);
+ virtual void updateFillColor(GfxState *state);
+ virtual void updateStrokeColor(GfxState *state);
+ virtual void updateFillOpacity(GfxState *state);
+ virtual void updateStrokeOpacity(GfxState *state);
+
+ //----- update text state
+ virtual void updateFont(GfxState *state);
+
+ //----- path painting
+ virtual void stroke(GfxState *state);
+ virtual void fill(GfxState *state);
+ virtual void eoFill(GfxState *state);
+
+ //----- path clipping
+ virtual void clip(GfxState *state);
+ virtual void eoClip(GfxState *state);
+
+ //----- text drawing
+ // virtual void drawString(GfxState *state, GooString *s);
+ virtual void drawChar(GfxState *state, double x, double y,
+ double dx, double dy,
+ double originX, double originY,
+ CharCode code, int nBytes, Unicode *u, int uLen);
+ virtual GBool beginType3Char(GfxState *state, double x, double y,
+ double dx, double dy,
+ CharCode code, Unicode *u, int uLen);
+ virtual void endType3Char(GfxState *state);
+ virtual void endTextObject(GfxState *state);
+
+ //----- image drawing
+ virtual void drawImageMask(GfxState *state, Object *ref, Stream *str,
+ int width, int height, GBool invert,
+ GBool interpolate, GBool inlineImg);
+ virtual void drawImage(GfxState *state, Object *ref, Stream *str,
+ int width, int height, GfxImageColorMap *colorMap,
+ GBool interpolate, int *maskColors, GBool inlineImg);
+
+ //----- Type 3 font operators
+ virtual void type3D0(GfxState *state, double wx, double wy);
+ virtual void type3D1(GfxState *state, double wx, double wy,
+ double llx, double lly, double urx, double ury);
+
+ //----- special access
+
+ // Called to indicate that a new PDF document has been loaded.
+ void startDoc(XRef *xrefA);
+
+ GBool isReverseVideo() { return gFalse; }
+
+private:
+ QPainter *m_painter;
+ FontHinting m_fontHinting;
+ QFont m_currentFont;
+ QPen m_currentPen;
+ QBrush m_currentBrush;
+ GBool m_needFontUpdate; // set when the font needs to be updated
+ SplashFontEngine *m_fontEngine;
+ SplashFont *m_font; // current font
+ XRef *xref; // xref table for current document
+};
+
+#endif
diff --git a/qt5/src/CMakeLists.txt b/qt5/src/CMakeLists.txt
index 2d5ecaf..8679ae0 100644
--- a/qt5/src/CMakeLists.txt
+++ b/qt5/src/CMakeLists.txt
@@ -29,7 +29,7 @@ set(poppler_qt5_SRCS
poppler-textbox.cc
poppler-page-transition.cc
poppler-media.cc
- ${CMAKE_SOURCE_DIR}/poppler/ArthurOutputDev.cc
+ ArthurOutputDev.cc
)
add_library(poppler-qt5 SHARED ${poppler_qt5_SRCS})
set_target_properties(poppler-qt5 PROPERTIES VERSION 1.0.0 SOVERSION 1)
diff --git a/qt5/src/Makefile.am b/qt5/src/Makefile.am
index 77f16df..e892f04 100644
--- a/qt5/src/Makefile.am
+++ b/qt5/src/Makefile.am
@@ -51,14 +51,15 @@ libpoppler_qt5_la_SOURCES = \
poppler-export.h \
poppler-private.h \
poppler-page-transition-private.h \
- poppler-embeddedfile-private.h
+ poppler-embeddedfile-private.h \
+ ArthurOutputDev.h \
+ ArthurOutputDev.cc
libpoppler_qt5_la_CXXFLAGS = \
-Dpoppler_qt5_EXPORTS -fPIC
libpoppler_qt5_la_LIBADD = \
$(top_builddir)/poppler/libpoppler.la \
- $(top_builddir)/poppler/libpoppler-arthur.la \
$(POPPLER_QT5_LIBS)
libpoppler_qt5_la_LDFLAGS = -version-info 1:0:0 @create_shared_lib@ @auto_import_flags@
diff --git a/qt5/src/poppler-optcontent.cc b/qt5/src/poppler-optcontent.cc
index 81a9923..c8db680 100644
--- a/qt5/src/poppler-optcontent.cc
+++ b/qt5/src/poppler-optcontent.cc
@@ -425,3 +425,5 @@ namespace Poppler
}
}
}
+
+#include "poppler-optcontent.moc"
More information about the poppler
mailing list