[poppler] 3 commits - poppler/GfxState.cc qt5/src
Albert Astals Cid
aacid at kemper.freedesktop.org
Tue Apr 10 22:33:16 UTC 2018
poppler/GfxState.cc | 6 +
qt5/src/ArthurOutputDev.cc | 190 +++++++++++++++++++++++++++++++++++++--------
qt5/src/ArthurOutputDev.h | 16 ++-
qt5/src/poppler-page.cc | 4
4 files changed, 176 insertions(+), 40 deletions(-)
New commits:
commit d80e7aac3366f93865581a783751abb528c120b3
Author: Albert Astals Cid <aacid at kde.org>
Date: Wed Apr 11 00:32:35 2018 +0200
Make GfxGouraudTriangleShading::parse more accepting of malformed documents
Bug #105972
diff --git a/poppler/GfxState.cc b/poppler/GfxState.cc
index eaa3ab17..9ceae8fc 100644
--- a/poppler/GfxState.cc
+++ b/poppler/GfxState.cc
@@ -4918,7 +4918,11 @@ GfxGouraudTriangleShading *GfxGouraudTriangleShading::parse(GfxResources *res, i
if (typeA == 5 && nVerticesA > 0) {
nRows = nVerticesA / vertsPerRow;
nTrianglesA = (nRows - 1) * 2 * (vertsPerRow - 1);
- trianglesA = (int (*)[3])gmallocn(nTrianglesA * 3, sizeof(int));
+ trianglesA = (int (*)[3])gmallocn_checkoverflow(nTrianglesA * 3, sizeof(int));
+ if (unlikely(!trianglesA)) {
+ gfree(verticesA);
+ return nullptr;
+ }
k = 0;
for (i = 0; i < nRows - 1; ++i) {
for (j = 0; j < vertsPerRow - 1; ++j) {
commit fee13e935e4c9eaadff434436eaceeb13afcfc13
Author: Oliver Sander <oliver.sander at tu-dresden.de>
Date: Fri Mar 23 22:24:42 2018 +0100
Implement Type3 font support for ArthurOutputDev
diff --git a/qt5/src/ArthurOutputDev.cc b/qt5/src/ArthurOutputDev.cc
index b6620617..17da8f29 100644
--- a/qt5/src/ArthurOutputDev.cc
+++ b/qt5/src/ArthurOutputDev.cc
@@ -51,6 +51,9 @@
#include "FontEncodingTables.h"
#include <fofi/FoFiTrueType.h>
#include "ArthurOutputDev.h"
+#include "Page.h"
+#include "Gfx.h"
+#include "PDFDoc.h"
#include <QtCore/QtDebug>
#include <QRawFont>
@@ -87,6 +90,86 @@ private:
#endif
+class ArthurType3Font
+{
+public:
+
+ ArthurType3Font(PDFDoc* doc, Gfx8BitFont* font);
+
+ const QPicture& getGlyph(int gid) const;
+
+private:
+ PDFDoc* m_doc;
+ Gfx8BitFont* m_font;
+
+ mutable std::vector<std::unique_ptr<QPicture> > glyphs;
+
+public:
+ std::vector<int> codeToGID;
+};
+
+ArthurType3Font::ArthurType3Font(PDFDoc* doc, Gfx8BitFont* font)
+: m_doc(doc), m_font(font)
+{
+ char *name;
+ const Dict* charProcs = font->getCharProcs();
+
+ // Storage for the rendered glyphs
+ glyphs.resize(charProcs->getLength());
+
+ // Compute the code-to-GID map
+ char **enc = font->getEncoding();
+
+ codeToGID.resize(256);
+
+ for (int i = 0; i < 256; ++i) {
+ codeToGID[i] = 0;
+ if (charProcs && (name = enc[i])) {
+ for (int j = 0; j < charProcs->getLength(); j++) {
+ if (strcmp(name, charProcs->getKey(j)) == 0) {
+ codeToGID[i] = j;
+ }
+ }
+ }
+ }
+}
+
+const QPicture& ArthurType3Font::getGlyph(int gid) const
+{
+ if (!glyphs[gid]) {
+
+ // Glyph has not been rendered before: render it now
+
+ // Smallest box that contains all the glyphs from this font
+ const double* fontBBox = m_font->getFontBBox();
+ PDFRectangle box(fontBBox[0], fontBBox[1], fontBBox[2], fontBBox[3]);
+
+ Dict* resDict = m_font->getResources();
+
+ QPainter glyphPainter;
+ glyphs[gid] = std::unique_ptr<QPicture>(new QPicture);
+ glyphPainter.begin(glyphs[gid].get());
+ std::unique_ptr<ArthurOutputDev> output_dev(new ArthurOutputDev(&glyphPainter));
+
+ std::unique_ptr<Gfx> gfx(new Gfx(m_doc, output_dev.get(), resDict,
+ &box, // pagebox
+ nullptr)); // cropBox
+
+ output_dev->startDoc(m_doc);
+
+ output_dev->startPage (1, gfx->getState(), gfx->getXRef());
+
+ const Dict* charProcs = m_font->getCharProcs();
+ Object charProc = charProcs->getVal(gid);
+ gfx->display(&charProc);
+
+ glyphPainter.end();
+ }
+
+ return *glyphs[gid];
+}
+
+
//------------------------------------------------------------------------
// ArthurOutputDev
//------------------------------------------------------------------------
@@ -107,8 +190,9 @@ ArthurOutputDev::~ArthurOutputDev()
#endif
}
-void ArthurOutputDev::startDoc(XRef *xrefA) {
- xref = xrefA;
+void ArthurOutputDev::startDoc(PDFDoc* doc) {
+ xref = doc->getXRef();
+ m_doc = doc;
#ifdef HAVE_SPLASH
delete m_fontEngine;
@@ -134,6 +218,7 @@ void ArthurOutputDev::saveState(GfxState *state)
m_currentPenStack.push(m_currentPen);
m_currentBrushStack.push(m_currentBrush);
m_rawFontStack.push(m_rawFont);
+ m_type3FontStack.push(m_currentType3Font);
m_codeToGIDStack.push(m_codeToGID);
m_painter.top()->save();
@@ -147,6 +232,8 @@ void ArthurOutputDev::restoreState(GfxState *state)
m_codeToGIDStack.pop();
m_rawFont = m_rawFontStack.top();
m_rawFontStack.pop();
+ m_currentType3Font = m_type3FontStack.top();
+ m_type3FontStack.pop();
m_currentBrush = m_currentBrushStack.top();
m_currentBrushStack.pop();
m_currentPen = m_currentPenStack.top();
@@ -362,8 +449,30 @@ void ArthurOutputDev::updateFont(GfxState *state)
return;
}
- // is the font in the cache?
+ // The key to look in the font caches
ArthurFontID fontID = {*gfxFont->getID(), state->getFontSize()};
+
+ // Current font is a type3 font
+ if (gfxFont->getType() == fontType3)
+ {
+ auto cacheEntry = m_type3FontCache.find(fontID);
+
+ if (cacheEntry!=m_type3FontCache.end()) {
+
+ // Take the font from the cache
+ m_currentType3Font = cacheEntry->second.get();
+
+ } else {
+
+ m_currentType3Font = new ArthurType3Font(m_doc, (Gfx8BitFont*)gfxFont);
+ m_type3FontCache.insert(std::make_pair(fontID,std::unique_ptr<ArthurType3Font>(m_currentType3Font)));
+
+ }
+
+ return;
+ }
+
+ // Non-type3: is the font in the cache?
auto cacheEntry = m_rawFontCache.find(fontID);
if (cacheEntry!=m_rawFontCache.end()) {
@@ -818,6 +927,52 @@ void ArthurOutputDev::drawChar(GfxState *state, double x, double y,
double originX, double originY,
CharCode code, int nBytes, Unicode *u, int uLen) {
+ // First handle type3 fonts
+ GfxFont *gfxFont = state->getFont();
+
+ GfxFontType fontType = gfxFont->getType();
+ if (fontType == fontType3) {
+
+ /////////////////////////////////////////////////////////////////////
+ // Draw the QPicture that contains the glyph onto the page
+ /////////////////////////////////////////////////////////////////////
+
+ // Store the QPainter state; we need to modify it temporarily
+ m_painter.top()->save();
+
+ // Make the glyph position the coordinate origin -- that's our center of scaling
+ m_painter.top()->translate(QPointF(x-originX, y-originY));
+
+ const double* mat = gfxFont->getFontMatrix();
+ QTransform fontMatrix(mat[0], mat[1], mat[2], mat[3], mat[4], mat[5]);
+
+ // Scale with the font size
+ fontMatrix.scale(state->getFontSize(), state->getFontSize());
+ m_painter.top()->setTransform(fontMatrix,true);
+
+ // Apply the text matrix on top
+ const double *textMat = state->getTextMat();
+
+ QTransform textTransform(textMat[0] * state->getHorizScaling(),
+ textMat[1] * state->getHorizScaling(),
+ textMat[2],
+ textMat[3],
+ 0,
+ 0);
+
+ m_painter.top()->setTransform(textTransform,true);
+
+ // Actually draw the glyph
+ int gid = m_currentType3Font->codeToGID[code];
+ m_painter.top()->drawPicture(QPointF(0,0), m_currentType3Font->getGlyph(gid));
+
+ // Restore transformation
+ m_painter.top()->restore();
+
+ return;
+ }
+
+
// check for invisible text -- this is used by Acrobat Capture
int render = state->getRender();
if (render == 3 || !m_rawFont) {
@@ -825,11 +980,6 @@ void ArthurOutputDev::drawChar(GfxState *state, double x, double y,
return;
}
- // Don't do anything for type3 fonts -- they are not yet supported
- if (state->getFont()->getType() == fontType3) {
- return;
- }
-
if (!(render & 1))
{
quint32 glyphIndex = (m_codeToGID) ? m_codeToGID[code] : code;
@@ -889,17 +1039,6 @@ void ArthurOutputDev::drawChar(GfxState *state, double x, double y,
}
}
-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)
{
}
diff --git a/qt5/src/ArthurOutputDev.h b/qt5/src/ArthurOutputDev.h
index 0e68ac99..6d20fb7b 100644
--- a/qt5/src/ArthurOutputDev.h
+++ b/qt5/src/ArthurOutputDev.h
@@ -45,11 +45,14 @@
#include <QtGui/QPainter>
class GfxState;
+class PDFDoc;
class SplashFontEngine;
class QRawFont;
+class ArthurType3Font;
+
//------------------------------------------------------------------------
// ArthurOutputDev - Qt 5 QPainter renderer
//------------------------------------------------------------------------
@@ -143,10 +146,6 @@ public:
double dx, double dy,
double originX, double originY,
CharCode code, int nBytes, Unicode *u, int uLen) override;
- GBool beginType3Char(GfxState *state, double x, double y,
- double dx, double dy,
- CharCode code, Unicode *u, int uLen) override;
- void endType3Char(GfxState *state) override;
void endTextObject(GfxState *state) override;
//----- image drawing
@@ -182,8 +181,8 @@ public:
//----- special access
// Called to indicate that a new PDF document has been loaded.
- void startDoc(XRef *xrefA);
-
+ void startDoc(PDFDoc* doc);
+
GBool isReverseVideo() { return gFalse; }
private:
@@ -211,12 +210,16 @@ private:
GBool m_needFontUpdate; // set when the font needs to be updated
SplashFontEngine *m_fontEngine;
+ PDFDoc* m_doc;
XRef *xref; // xref table for current document
// The current font in use
QRawFont* m_rawFont;
std::stack<QRawFont*> m_rawFontStack;
+ ArthurType3Font* m_currentType3Font;
+ std::stack<ArthurType3Font*> m_type3FontStack;
+
// Identify a font by its 'Ref' and its font size
struct ArthurFontID
{
@@ -232,6 +235,7 @@ private:
// Cache all fonts
std::map<ArthurFontID,std::unique_ptr<QRawFont> > m_rawFontCache;
+ std::map<ArthurFontID,std::unique_ptr<ArthurType3Font> > m_type3FontCache;
// The table that maps character codes to glyph indexes
int* m_codeToGID;
diff --git a/qt5/src/poppler-page.cc b/qt5/src/poppler-page.cc
index 28ee1cd8..48dbe8ff 100644
--- a/qt5/src/poppler-page.cc
+++ b/qt5/src/poppler-page.cc
@@ -17,7 +17,7 @@
* Copyright (C) 2015 William Bader <williambader at hotmail.com>
* Copyright (C) 2016 Arseniy Lartsev <arseniy at alumni.chalmers.se>
* Copyright (C) 2016, Hanno Meyer-Thurow <h.mth at web.de>
- * Copyright (C) 2017, Oliver Sander <oliver.sander at tu-dresden.de>
+ * Copyright (C) 2017, 2018, Oliver Sander <oliver.sander at tu-dresden.de>
* Copyright (C) 2017 Adrian Johnson <ajohnson at redneon.com>
* Copyright (C) 2017, 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, <info at kdab.com>. Work sponsored by the LiMux project of the city of Munich
*
@@ -456,7 +456,7 @@ static bool renderToArthur(QImageDumpingArthurOutputDev *arthur_output, QPainter
painter->setRenderHint(QPainter::TextAntialiasing);
painter->translate(x == -1 ? 0 : -x, y == -1 ? 0 : -y);
- arthur_output->startDoc(page->parentDoc->doc->getXRef());
+ arthur_output->startDoc(page->parentDoc->doc);
const GBool hideAnnotations = page->parentDoc->m_hints & Document::HideAnnotations;
commit 79c588912f41aa6ee81ea058e7e649199a252f90
Author: Oliver Sander <oliver.sander at tu-dresden.de>
Date: Sun Mar 25 21:38:27 2018 +0200
Do not make ArthurOutputDev::startPage fill the page with white
diff --git a/qt5/src/ArthurOutputDev.cc b/qt5/src/ArthurOutputDev.cc
index 67485a2e..b6620617 100644
--- a/qt5/src/ArthurOutputDev.cc
+++ b/qt5/src/ArthurOutputDev.cc
@@ -124,18 +124,7 @@ void ArthurOutputDev::startDoc(XRef *xrefA) {
}
void ArthurOutputDev::startPage(int pageNum, GfxState *state, 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.top()->save();
- m_painter.top()->setPen(fillColour);
- m_painter.top()->setBrush(fill);
- m_painter.top()->drawRect(0, 0, w, h);
- m_painter.top()->restore();
-}
+{}
void ArthurOutputDev::endPage() {
}
More information about the poppler
mailing list