On 06/10/2013 09:13 PM, Mihai Niculescu wrote:
On 06/10/2013 08:32 PM, Albert Astals Cid wrote:
El Dilluns, 3 de juny de 2013, a les 09:41:41, Mihai Niculescu va
escriure:
Hi,
I am working on Arthur backend and did some changes for the backend not
to use Splash, but only Qt and QPainter.
Right now, the backend can render very good PDF files with the
exceptions:
- does not render non-latin characters
- does not render multiple resolutions
BTW, are you aware we are releasing a new verison really soon and
that if you
want your changes in you should send your patches *now*?
Cheers,
Albert
Hi,
I didnt use git, so I must get the trunk from git, apply the
modifications and create the patch and later I'll send you the patch.
I hope it is not too late.
Cheers,
Mihai
I attached the patch file. This patch removes any code in Arthur's dev
that is dependent on Splash. It also sets a transparent background for
the page - this feature is what I need a lot. A user can set manually
the background color by himself in a QWidget/QImage. Maybe a better
approach is to set it to the color of the document. I'll look into this
in the future.
As mentioned above, my tests showed that it can not display non-latin
chars and also it displays only at a single resolution.
Cheers,
Mihai
These are the only problems I found. Are you interested in these
changes
and how can I add these to git repo?
Also, I am thinking of modifying the wrapper to also support Qt5 but I
dont know how to modify the build system (configure, makefiles) to
search for Qt5/Qt4, set libraries and moc accordingly and to set a
global variable to use it in the code in order to know which code to
enable:
#ifdef QT5_VERSION
or something like this. If someone can help me with this, than I'll
make
poppler-qt4 support even Qt5.
Cheers,
Mihai
_______________________________________________
poppler mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/poppler
_______________________________________________
poppler mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/poppler
>From 865e1e9c99f1eea8589f1fec092d045b325865fd Mon Sep 17 00:00:00 2001
From: Mihai Niculescu <[email protected]>
Date: Mon, 10 Jun 2013 21:56:26 +0200
Subject: [PATCH] Remove ArthurOutputDev dependency of Splash
---
poppler/ArthurOutputDev.cc | 1163 ++++++++++++++++++++------------------------
poppler/ArthurOutputDev.h | 235 ++++-----
qt4/src/poppler-page.cc | 14 +-
3 files changed, 668 insertions(+), 744 deletions(-)
diff --git a/poppler/ArthurOutputDev.cc b/poppler/ArthurOutputDev.cc
index 5d57e93..17db7e4 100644
--- a/poppler/ArthurOutputDev.cc
+++ b/poppler/ArthurOutputDev.cc
@@ -20,7 +20,6 @@
// Copyright (C) 2009 Petr Gajdos <[email protected]>
// Copyright (C) 2010 Matthias Fauconneau <[email protected]>
// Copyright (C) 2011 Andreas Hartmetz <[email protected]>
-// Copyright (C) 2013 Thomas Freitag <[email protected]>
//
// To see a description of the changes please see the Changelog file that
// came with your tarball or type make ChangeLog if you are building from git
@@ -43,774 +42,690 @@
#include "GfxState.h"
#include "GfxFont.h"
#include "Link.h"
-#include "FontEncodingTables.h"
-#include <fofi/FoFiTrueType.h>
+#include "PDFDoc.h"
#include "ArthurOutputDev.h"
-#include <QtCore/QtDebug>
-#include <QtGui/QPainterPath>
-//------------------------------------------------------------------------
+#include <QtDebug>
+#include <QBrush>
+#include <QRawFont>
+#include <QPainter>
+#include <QPen>
+#include <QPointF>
+#include <QGlyphRun>
+#include <QTextCodec>
-#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
+// ArthurOutputDev
//------------------------------------------------------------------------
-class SplashOutFontFileID: public SplashFontFileID {
-public:
+ArthurOutputDev::ArthurOutputDev(QPainter *painter):
+ m_doc(0),
+ m_pageWidth(0),
+ m_pageHeight(0),
+ m_glyphChars(0),
+ m_glyphCharsCount(0),
+ m_glyphPositions(0),
+ m_painter(painter),
+ m_rawFont(0),
+ m_pen(0),
+ m_brush(0)
+{
- SplashOutFontFileID(Ref *rA) { r = *rA; }
+}
- ~SplashOutFontFileID() {}
+ArthurOutputDev::~ArthurOutputDev()
+{
+ cleanup();
+}
- GBool matches(SplashFontFileID *id) {
- return ((SplashOutFontFileID *)id)->r.num == r.num &&
- ((SplashOutFontFileID *)id)->r.gen == r.gen;
- }
+void ArthurOutputDev::cleanup()
+{
+ m_glyphCharsCount = 0;
-private:
+ if(m_glyphChars) delete [] m_glyphChars; m_glyphChars=0;
+ if(m_glyphPositions) delete [] m_glyphPositions; m_glyphPositions=0;
+ if(m_brush) delete m_brush;
+ if(m_pen) delete m_pen;
+ if(m_rawFont) delete m_rawFont;
- Ref r;
-};
+}
-#endif
+void ArthurOutputDev::startDoc(PDFDoc *doc) {
+ m_doc = doc;
-//------------------------------------------------------------------------
-// ArthurOutputDev
-//------------------------------------------------------------------------
+ cleanup();
-ArthurOutputDev::ArthurOutputDev(QPainter *painter):
- m_painter(painter),
- m_fontHinting(NoHinting)
-{
- m_currentBrush = QBrush(Qt::SolidPattern);
- m_fontEngine = 0;
- m_font = 0;
+ m_pen = new QPen;
+ m_brush= new QBrush;
+ m_rawFont= new QRawFont; // constructs invalid raw font
+
+ m_painter->setPen(*m_pen);
+ m_painter->setBrush(*m_brush);
}
-ArthurOutputDev::~ArthurOutputDev()
+void ArthurOutputDev::startPage(int pageNum, GfxState *state, XRef* ref)
{
-#ifdef HAVE_SPLASH
- delete m_fontEngine;
-#endif
-}
+ m_pageWidth = state->getPageWidth();
+ m_pageHeight = state->getPageHeight();
-void ArthurOutputDev::startDoc(XRef *xrefA) {
- xref = xrefA;
-#ifdef HAVE_SPLASH
- delete m_fontEngine;
+ //m_painter->setWindow(0,0, m_pageWidth,m_pageHeight);
+ // m_painter->setViewport(0,0, m_pageWidth,m_pageHeight);
- const bool isHintingEnabled = m_fontHinting != NoHinting;
- const bool isSlightHinting = m_fontHinting == SlightHinting;
+ m_pen->setColor(Qt::black);
+ m_pen->setStyle(Qt::SolidLine);
+ m_pen->setWidthF(1.0);
+ m_brush->setColor(Qt::white);// can be transparent
+ m_brush->setStyle(Qt::SolidPattern);
+
+ m_painter->save();
+ m_brush->setColor(Qt::transparent);// can be transparent
+ m_painter->setPen(*m_pen);
+ m_painter->setBrush(*m_brush);
+
+ // draw page
+ m_painter->drawRect(0, 0, m_pageWidth, m_pageHeight);
+ m_painter->restore();
- 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)
+void ArthurOutputDev::endPage()
{
- // 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();
+ m_painter->save();
}
void ArthurOutputDev::restoreState(GfxState *state)
{
- m_painter->restore();
+ m_painter->restore();
}
void ArthurOutputDev::updateAll(GfxState *state)
{
- OutputDev::updateAll(state);
- m_needFontUpdate = gTrue;
+ OutputDev::updateAll(state);
+}
+
+void ArthurOutputDev::setDefaultCTM(double *ctm)
+{
+ QTransform matrix(ctm[0],ctm[1],ctm[2],ctm[3],ctm[4],ctm[5]);
+
+ //m_painter->setTransform(matrix);
+
+ OutputDev::setDefaultCTM(ctm);
}
-// 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)
+ double m21, double m22,
+ double m31, double m32)
{
- updateLineDash(state);
- updateLineJoin(state);
- updateLineCap(state);
- updateLineWidth(state);
+ QTransform trans(m11, m12, m21, m22,m31, m32);
+
+ //m_painter->setTransform(trans);
}
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);
+ 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_pen->setDashPattern(pattern);
+ m_pen->setDashOffset(dashStart);
+ m_painter->setPen(*m_pen);
}
void ArthurOutputDev::updateFlatness(GfxState *state)
{
- // qDebug() << "updateFlatness";
+ // //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);
+ switch (state->getLineJoin()) {
+ case 0:
+ m_pen->setJoinStyle(Qt::MiterJoin);
+ break;
+ case 1:
+ m_pen->setJoinStyle(Qt::RoundJoin);
+ break;
+ case 2:
+ m_pen->setJoinStyle(Qt::BevelJoin);
+ break;
+ default:
+ m_pen->setJoinStyle(Qt::SvgMiterJoin);
+ }
+ m_painter->setPen(*m_pen);
}
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);
+ switch (state->getLineCap()) {
+ case 0:
+ m_pen->setCapStyle(Qt::FlatCap);
+ break;
+ case 1:
+ m_pen->setCapStyle(Qt::RoundCap);
+ break;
+ case 2:
+ m_pen->setCapStyle(Qt::SquareCap);
+ break;
+ default:
+ m_pen->setCapStyle(Qt::RoundCap);
+ }
+ m_painter->setPen(*m_pen);
}
void ArthurOutputDev::updateMiterLimit(GfxState *state)
{
- m_currentPen.setMiterLimit(state->getMiterLimit());
- m_painter->setPen(m_currentPen);
+ m_pen->setMiterLimit(state->getMiterLimit());
}
void ArthurOutputDev::updateLineWidth(GfxState *state)
{
- m_currentPen.setWidthF(state->getLineWidth());
- m_painter->setPen(m_currentPen);
+ m_pen->setWidthF(state->getLineWidth());
}
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);
+ GfxRGB rgb;
+ QColor brushColour = m_brush->color();
+ state->getFillRGB(&rgb);
+ brushColour.setRgbF(colToDbl(rgb.r), colToDbl(rgb.g), colToDbl(rgb.b), brushColour.alphaF());
+ m_brush->setColor(brushColour);
+ m_painter->setBrush(*m_brush);
}
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);
+ GfxRGB rgb;
+ QColor penColour = m_pen->color();
+ state->getStrokeRGB(&rgb);
+ penColour.setRgbF(colToDbl(rgb.r), colToDbl(rgb.g), colToDbl(rgb.b), penColour.alphaF());
+ m_pen->setColor(penColour);
+ m_painter->setPen(*m_pen);
+}
+
+void ArthurOutputDev::updateBlendMode(GfxState * state)
+{
+ GfxBlendMode blendMode = state->getBlendMode();
+
+ // missing composition modes in QPainter:
+ // - CompositionMode_Hue
+ // - CompositionMode_Color
+ // - CompositionMode_Luminosity
+ // - CompositionMode_Saturation
+
+ switch(blendMode){
+ case gfxBlendMultiply:
+ m_painter->setCompositionMode(QPainter::CompositionMode_Multiply);
+ break;
+ case gfxBlendScreen:
+ m_painter->setCompositionMode(QPainter::CompositionMode_Screen);
+ break;
+ case gfxBlendDarken:
+ m_painter->setCompositionMode(QPainter::CompositionMode_Darken);
+ break;
+ case gfxBlendLighten:
+ m_painter->setCompositionMode(QPainter::CompositionMode_Lighten);
+ break;
+ case gfxBlendColorDodge:
+ m_painter->setCompositionMode(QPainter::CompositionMode_ColorDodge);
+ break;
+ case gfxBlendColorBurn:
+ m_painter->setCompositionMode(QPainter::CompositionMode_ColorBurn);
+ break;
+ case gfxBlendHardLight:
+ m_painter->setCompositionMode(QPainter::CompositionMode_HardLight);
+ break;
+ case gfxBlendSoftLight:
+ m_painter->setCompositionMode(QPainter::CompositionMode_SoftLight);
+ break;
+ case gfxBlendDifference:
+ m_painter->setCompositionMode(QPainter::CompositionMode_Difference);
+ break;
+ case gfxBlendExclusion:
+ m_painter->setCompositionMode(QPainter::CompositionMode_Exclusion);
+ break;
+ case gfxBlendColor:
+ m_painter->setCompositionMode(QPainter::CompositionMode_Plus);
+ break;
+ case gfxBlendNormal:
+ default:
+ m_painter->setCompositionMode(QPainter::CompositionMode_SourceOver);
+ break;
+ }
+
}
+
void ArthurOutputDev::updateFillOpacity(GfxState *state)
{
- QColor brushColour= m_currentBrush.color();
- brushColour.setAlphaF(state->getFillOpacity());
- m_currentBrush.setColor(brushColour);
+ QColor brushColour= m_brush->color();
+ brushColour.setAlphaF(state->getFillOpacity());
+ m_brush->setColor(brushColour);
+ m_painter->setBrush(*m_brush);
}
void ArthurOutputDev::updateStrokeOpacity(GfxState *state)
{
- QColor penColour= m_currentPen.color();
- penColour.setAlphaF(state->getStrokeOpacity());
- m_currentPen.setColor(penColour);
- m_painter->setPen(m_currentPen);
+ QColor penColour= m_pen->color();
+ penColour.setAlphaF(state->getStrokeOpacity());
+ m_pen->setColor(penColour);
+ m_painter->setPen(*m_pen);
}
+
+
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;
- }
+ GfxFont *font = state->getFont();
+ GfxFontLoc *fontLoc;
+ char* fontData; int fontDataLen;
+
+ if(!font) return;
+
+ float fontSize = state->getTransformedFontSize();
+
+ fontLoc = font->locateFont(m_doc->getXRef(), gFalse);
+
+ delete m_rawFont;
+
+ if(fontLoc){
+ // load the font from respective location
+ switch(fontLoc->locType){
+ case gfxFontLocEmbedded: {// if there is an embedded font, read it to memory
+ fontData = font->readEmbFontFile(m_doc->getXRef(), &fontDataLen);
+
+ m_rawFont = new QRawFont(QByteArray(fontData, fontDataLen), fontSize);
+ break;
+ }
+ case gfxFontLocExternal:{ // font is in a file
+ QString fontFile(fontLoc->path->getCString());
+ m_rawFont = new QRawFont(fontFile, fontSize);
+ break;
+ }
+ case gfxFontLocResident:{ // font is in PS
+ qDebug() <<"\t\tFont Resident Encoding:"<<fontLoc->encoding->getCString();
+
+ break;
+ }
+ }// end switch
+
+ // retrieve font encoding
+ qDebug() << "Font EncodingName:"<<font->getEncodingName()->getCString()<<" Tag:"<<font->getTag()->getCString();
+
+ char **enc; GooString *collection = new GooString;
+ switch(fontLoc->fontType){
+ case fontType1:
+ case fontType1C:
+ case fontType1COT:
+ case fontTrueType:
+ case fontTrueTypeOT:
+ enc = ((Gfx8BitFont *)font)->getEncoding();
+ qDebug() << "FONT is encoded:"<<QString(*enc);
+ break;
+ case fontCIDType0COT:
+ case fontCIDType2:
+ case fontCIDType2OT:
+ collection = ((GfxCIDFont *)font)->getCollection();
+ qDebug() << "CID FONT collection:"<<collection->getCString();
+ break;
+ default:
+ break;
+
+ }
- 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();
- }
+ QTextCodec *codec = QTextCodec::codecForCStrings();
+ if(!codec){
+ qDebug() << "\t\tTextCodec not available";
+ }
+
+
+
+
+ if(!m_rawFont->isValid()){
+ qDebug() << "RawFont is not valid";
+ }
}
- }
- return qPath;
+
}
void ArthurOutputDev::stroke(GfxState *state)
{
- m_painter->strokePath( convertPath( state, state->getPath(), Qt::OddEvenFill ), m_currentPen );
+ m_painter->strokePath( convertPath( state, state->getPath(), Qt::OddEvenFill ), *m_pen );
}
void ArthurOutputDev::fill(GfxState *state)
{
- m_painter->fillPath( convertPath( state, state->getPath(), Qt::WindingFill ), m_currentBrush );
+ m_painter->fillPath( convertPath( state, state->getPath(), Qt::WindingFill ), *m_brush );
}
void ArthurOutputDev::eoFill(GfxState *state)
{
- m_painter->fillPath( convertPath( state, state->getPath(), Qt::OddEvenFill ), m_currentBrush );
+ m_painter->fillPath( convertPath( state, state->getPath(), Qt::OddEvenFill ), *m_brush );
}
void ArthurOutputDev::clip(GfxState *state)
{
- m_painter->setClipPath(convertPath( state, state->getPath(), Qt::WindingFill ) );
+ m_painter->setClipPath(convertPath( state, state->getPath(), Qt::WindingFill ) );
}
void ArthurOutputDev::eoClip(GfxState *state)
{
- m_painter->setClipPath(convertPath( state, state->getPath(), Qt::OddEvenFill ) );
+ m_painter->setClipPath(convertPath( state, state->getPath(), Qt::OddEvenFill ) );
+}
+
+void ArthurOutputDev::beginString(GfxState *state, GooString *s)
+{
+ if (!m_rawFont)
+ return;
+
+ int len = s->getLength();
+
+ m_glyphChars = new QChar[len];
+ m_glyphCharsCount = 0;
+ m_glyphPositions= new QPointF[len];
}
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;
+ double dx, double dy,
+ double originX, double originY,
+ CharCode code, int nBytes, Unicode *u, int uLen)
+{
+ GBool doFill, doStroke, doClip;
+ QChar chr; // holds the glyph
+
+ // check for invisible text -- this is used by Acrobat Capture
+ int render = state->getRender();
+ if (render == 3 || !m_rawFont) {
+ return;
}
- }
-
- // 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;
+
+
+
+ doFill = !(render & 1) && !state->getFillColorSpace()->isNonMarking();
+ doStroke = ((render & 3) == 1 || (render & 3) == 2) &&
+ !state->getStrokeColorSpace()->isNonMarking();
+ doClip = render & 4;
+
+ u!=0 ? chr=QChar((uint)*u) : chr=QChar((uint)code);
+
+ m_glyphChars[m_glyphCharsCount] = chr;
+ m_glyphPositions[m_glyphCharsCount] = QPointF(x-originX, m_pageHeight-y-originY);
+ m_glyphCharsCount++;
+
+}
+
+void ArthurOutputDev::endString(GfxState *state)
+{
+
+ // ignore empty strings and invisible text -- this is used by Acrobat Capture
+ int render = state->getRender();
+ if (render == 3 || m_glyphCharsCount==0) {
+ delete [] m_glyphChars; m_glyphChars=0;
+ delete [] m_glyphPositions; m_glyphPositions=0;
+ return;
}
- */
- }
-
- // 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;
+
+ if (!(render & 1))
+ {
+ double x = 0;
+ double y = 0;
+
+ QPointF pos(x, y);
+
+ //QTextDecoder * makeDecoder ()
+
+ QString text(m_glyphChars, m_glyphCharsCount);
+ qDebug() << "EndString: ["<< QString(m_glyphChars, m_glyphCharsCount) <<"] at "<< pos.x() << " "<< pos.y();
+
+ int numGlyphs = m_glyphCharsCount;
+ const QChar* glyphs = text.constData();
+ quint32* glyphIndexes = new quint32[numGlyphs];
+
+ if(!m_rawFont->glyphIndexesForChars(glyphs, m_glyphCharsCount, glyphIndexes, &numGlyphs)){
+ delete [] glyphIndexes;
+
+ glyphIndexes = new quint32[numGlyphs];
+ m_rawFont->glyphIndexesForChars(glyphs, m_glyphCharsCount, glyphIndexes, &numGlyphs);
+ }
+
+ QGlyphRun glyphRun;
+ glyphRun.setRawData(glyphIndexes, m_glyphPositions, numGlyphs);
+ glyphRun.setRawFont(*m_rawFont);
+
+ m_painter->drawGlyphRun(pos, glyphRun);
+
+ qDebug() << "EndString: ["<< text <<"] at "<< pos.x()<<" "<<pos.y();
}
- */
- }
-#endif
+
+ delete [] m_glyphChars; m_glyphChars=0;
+ delete [] m_glyphPositions; m_glyphPositions=0;
+ m_glyphCharsCount=0;
+
}
GBool ArthurOutputDev::beginType3Char(GfxState *state, double x, double y,
- double dx, double dy,
- CharCode code, Unicode *u, int uLen)
+ double dx, double dy,
+ CharCode code, Unicode *u, int uLen)
{
- return gFalse;
+ qDebug() << "beginType3Char";
+
+ m_painter->save();
+
+ double *ctm = state->getCTM();
+ QTransform matrix(ctm[0],ctm[1],ctm[2],ctm[3],ctm[4],ctm[5]);
+
+ /* Restore the original matrix and then transform to matrix needed for the
+ * type3 font. This is ugly but seems to work. Perhaps there is a better way to do it?*/
+ // m_painter->setTransform(m_origTrans);
+ // m_painter->setTransform(matrix, true);
+
+ return gFalse;
}
void ArthurOutputDev::endType3Char(GfxState *state)
{
+ m_painter->restore();
}
void ArthurOutputDev::type3D0(GfxState *state, double wx, double wy)
{
+ qDebug() << "type3D0";
}
void ArthurOutputDev::type3D1(GfxState *state, double wx, double wy,
- double llx, double lly, double urx, double ury)
-{
-}
-
-void ArthurOutputDev::endTextObject(GfxState *state)
+ double llx, double lly, double urx, double ury)
{
+ qDebug() << "type3D1";
}
-
void ArthurOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str,
- int width, int height, GBool invert,
- GBool interpolate, GBool inlineImg)
+ int width, int height, GBool invert,
+ GBool interpolate, GBool inlineImg)
{
- qDebug() << "drawImageMask";
+ 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;
+ 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;
+
+ 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;
+ int width, int height,
+ GfxImageColorMap *colorMap,
+ GBool interpolate, int *maskColors, GBool inlineImg)
+{
+ qDebug() << "drawImage";
+
+ 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++; }
}
- 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]);
+ 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;
- m_painter->setMatrix(matrix, true);
- m_painter->drawImage( QPoint(0,0), image );
- delete imgStr;
+}
+QPainterPath ArthurOutputDev::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);
+ x1 = subpath->getX(0);
+ y1 = m_pageHeight - subpath->getY(0);
+ 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);
+ x1 = subpath->getX(j);
+ y1 = m_pageHeight - subpath->getY(j);
+ x2 = subpath->getX(j+1);
+ y2 = m_pageHeight - subpath->getY(j+1);
+ x3 = subpath->getX(j+2);
+ y3 = m_pageHeight - subpath->getY(j+2);
+
+ qPath.cubicTo( x1, y1, x2, y2, x3, y3);
+ j += 3;
+ } else {
+ //state->transform(subpath->getX(j), subpath->getY(j), &x1, &y1);
+ x1 = subpath->getX(j);
+ y1 = m_pageHeight - subpath->getY(j);
+ qPath.lineTo(x1, y1);
+ ++j;
+ }
+ }
+ if (subpath->isClosed()) {
+ qPath.closeSubpath();
+ }
+ }
+ }
+ return qPath;
}
diff --git a/poppler/ArthurOutputDev.h b/poppler/ArthurOutputDev.h
index 9d5e867..997952a 100644
--- a/poppler/ArthurOutputDev.h
+++ b/poppler/ArthurOutputDev.h
@@ -18,7 +18,6 @@
// Copyright (C) 2009, 2011 Carlos Garcia Campos <[email protected]>
// Copyright (C) 2010 Pino Toscano <[email protected]>
// Copyright (C) 2011 Andreas Hartmetz <[email protected]>
-// Copyright (C) 2013 Thomas Freitag <[email protected]>
//
// To see a description of the changes please see the Changelog file that
// came with your tarball or type make ChangeLog if you are building from git
@@ -36,16 +35,25 @@
#include "OutputDev.h"
#include "GfxState.h"
-#include <QtGui/QPainter>
+#include <QPainter>
+
class GfxState;
class GfxPath;
class Gfx8BitFont;
struct GfxRGB;
-class SplashFont;
-class SplashFontEngine;
-struct SplashGlyphBitmap;
+class PDFDoc;
+class TextPage;
+class ActualText;
+
+class QBrush;
+class QFont;
+class QRawFont;
+class QPainterPath;
+class QPen;
+class QPointF;
+
//------------------------------------------------------------------------
// ArthurOutputDev - Qt 4 QPainter renderer
@@ -53,118 +61,113 @@ struct SplashGlyphBitmap;
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; }
-
+ ArthurOutputDev(QPainter *painter );
+ virtual ~ArthurOutputDev();
+
+ void startDoc(PDFDoc *doc);
+ void setRenderHints(QPainter::RenderHints renderHints, bool on=true);
+
+ //----- 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 gFalse; }
+
+ //----- initialization and control
+
+ // Start a page.
+ virtual void startPage(int pageNum, GfxState *state, XRef* ref);
+
+ // 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 setDefaultCTM(double *ctm);
+ 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 updateBlendMode(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
+ void beginString(GfxState *state, GooString *s);
+ void endString(GfxState *state);
+ 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);
+
+ //----- 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);
+
+ 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
+ void cleanup();
+ QPainterPath convertPath(GfxState *state, GfxPath *path, Qt::FillRule fillRule);
+ void doFontUpdate(GfxState* state);
+
+ PDFDoc *m_doc; // pdf doc
+
+ float m_pageWidth;
+ float m_pageHeight;
+
+ QChar* m_glyphChars;
+ int m_glyphCharsCount; // number of chars
+ QPointF* m_glyphPositions;
+
+ QPainter *m_painter;
+ QRawFont *m_rawFont;
+ QPen *m_pen;
+ QBrush *m_brush;
+
};
#endif
diff --git a/qt4/src/poppler-page.cc b/qt4/src/poppler-page.cc
index f7c2427..1818945 100644
--- a/qt4/src/poppler-page.cc
+++ b/qt4/src/poppler-page.cc
@@ -351,7 +351,12 @@ QImage Page::renderToImage(double xres, double yres, int x, int y, int w, int h,
case Poppler::Document::ArthurBackend:
{
QSize size = pageSize();
- QImage tmpimg(w == -1 ? qRound( size.width() * xres / 72.0 ) : w, h == -1 ? qRound( size.height() * yres / 72.0 ) : h, QImage::Format_ARGB32);
+
+ double w = size.width()*xres/72.0;
+ double h = size.height()*yres/72.0;
+
+ QImage tmpimg(w,h, QImage::Format_ARGB32);
+ tmpimg.fill(Qt::transparent);
QPainter painter(&tmpimg);
renderToPainter(&painter, xres, yres, x, y, w, h, rotate, DontSaveAndRestore);
@@ -378,13 +383,14 @@ bool Page::renderToPainter(QPainter* painter, double xres, double yres, int x, i
const bool savePainter = !(flags & DontSaveAndRestore);
if (savePainter)
painter->save();
- if (m_page->parentDoc->m_hints & Document::Antialiasing)
+ 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());
+ arthur_output.startDoc(m_page->parentDoc->doc);
m_page->parentDoc->doc->displayPageSlice(&arthur_output,
m_page->index + 1,
xres,
--
1.8.1.2
_______________________________________________
poppler mailing list
[email protected]
http://lists.freedesktop.org/mailman/listinfo/poppler