Commit 8eb489c3 authored by Thomas Freitag's avatar Thomas Freitag Committed by Albert Astals Cid

Make rendering thread-safe

Bug #50992
parent 3db9472e
......@@ -41,6 +41,10 @@ PopplerInputStream::~PopplerInputStream()
g_object_unref(cancellable);
}
BaseStream *PopplerInputStream::copy() {
return new PopplerInputStream(inputStream, cancellable, start, limited, length, &dict);
}
Stream *PopplerInputStream::makeSubStream(Guint startA, GBool limitedA,
Guint lengthA, Object *dictA)
{
......
......@@ -33,6 +33,7 @@ public:
PopplerInputStream(GInputStream *inputStream, GCancellable *cancellableA,
Guint startA, GBool limitedA, Guint lengthA, Object *dictA);
virtual ~PopplerInputStream();
virtual BaseStream *copy();
virtual Stream *makeSubStream(Guint start, GBool limited,
Guint lengthA, Object *dictA);
virtual StreamKind getKind() { return strWeird; }
......
......@@ -25,7 +25,7 @@
// Copyright (C) 2009 Ilya Gorenbein <igorenbein@finjan.com>
// Copyright (C) 2011 José Aliste <jaliste@src.gnome.org>
// Copyright (C) 2012 Fabio D'Urso <fabiodurso@hotmail.it>
// Copyright (C) 2012 Thomas Freitag <Thomas.Freitag@alfa.de>
// Copyright (C) 2012, 2013 Thomas Freitag <Thomas.Freitag@alfa.de>
// Copyright (C) 2012 Tobias Koenig <tokoe@kdab.com>
//
// To see a description of the changes please see the Changelog file that
......@@ -1205,7 +1205,7 @@ void Annot::initialize(PDFDoc *docA, Dict *dict) {
if (dict->lookupNF("P", &obj1)->isRef()) {
Ref ref = obj1.getRef();
page = doc->getCatalog()->findPage (ref.num, ref.gen);
page = doc->getCatalog()->findPage (ref.num, ref.gen, gFalse);
} else {
page = 0;
}
......@@ -1748,7 +1748,7 @@ void Annot::draw(Gfx *gfx, GBool printing) {
return;
// draw the appearance stream
appearance.fetch(xref, &obj);
appearance.fetch(gfx->getXRef(), &obj);
gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
rect->x1, rect->y1, rect->x2, rect->y2);
obj.free();
......@@ -2412,7 +2412,7 @@ void AnnotText::draw(Gfx *gfx, GBool printing) {
}
// draw the appearance stream
appearance.fetch(xref, &obj);
appearance.fetch(gfx->getXRef(), &obj);
if (appearBBox) {
gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
appearBBox->getPageXMin(), appearBBox->getPageYMin(),
......@@ -2511,7 +2511,7 @@ void AnnotLink::draw(Gfx *gfx, GBool printing) {
return;
// draw the appearance stream
appearance.fetch(xref, &obj);
appearance.fetch(gfx->getXRef(), &obj);
gfx->drawAnnot(&obj, border, color,
rect->x1, rect->y1, rect->x2, rect->y2);
obj.free();
......@@ -2944,7 +2944,7 @@ void AnnotFreeText::draw(Gfx *gfx, GBool printing) {
}
// draw the appearance stream
appearance.fetch(xref, &obj);
appearance.fetch(gfx->getXRef(), &obj);
gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
rect->x1, rect->y1, rect->x2, rect->y2);
obj.free();
......@@ -3416,7 +3416,7 @@ void AnnotLine::draw(Gfx *gfx, GBool printing) {
}
// draw the appearance stream
appearance.fetch(xref, &obj);
appearance.fetch(gfx->getXRef(), &obj);
if (appearBBox) {
gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
appearBBox->getPageXMin(), appearBBox->getPageYMin(),
......@@ -3724,7 +3724,7 @@ void AnnotTextMarkup::draw(Gfx *gfx, GBool printing) {
}
// draw the appearance stream
appearance.fetch(xref, &obj);
appearance.fetch(gfx->getXRef(), &obj);
if (appearBBox) {
gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
appearBBox->getPageXMin(), appearBBox->getPageYMin(),
......@@ -3770,7 +3770,7 @@ AnnotWidget::~AnnotWidget() {
void AnnotWidget::initialize(PDFDoc *docA, Dict *dict) {
Object obj1;
form = doc->getCatalog()->getForm();
form = doc->getCatalog()->getForm(gFalse);
if(dict->lookup("H", &obj1)->isName()) {
const char *modeName = obj1.getName();
......@@ -4967,7 +4967,7 @@ void AnnotWidget::draw(Gfx *gfx, GBool printing) {
}
// draw the appearance stream
appearance.fetch(xref, &obj);
appearance.fetch(gfx->getXRef(), &obj);
if (addDingbatsResource) {
// We are forcing ZaDb but the font does not exist
// so create a fake one
......@@ -4976,19 +4976,19 @@ void AnnotWidget::draw(Gfx *gfx, GBool printing) {
subtypeObj.initName("Type1");
Object fontDictObj;
Dict *fontDict = new Dict(xref);
Dict *fontDict = new Dict(gfx->getXRef());
fontDict->decRef();
fontDict->add(copyString("BaseFont"), &baseFontObj);
fontDict->add(copyString("Subtype"), &subtypeObj);
fontDictObj.initDict(fontDict);
Object fontsDictObj;
Dict *fontsDict = new Dict(xref);
Dict *fontsDict = new Dict(gfx->getXRef());
fontsDict->decRef();
fontsDict->add(copyString("ZaDb"), &fontDictObj);
fontsDictObj.initDict(fontsDict);
Dict *dict = new Dict(xref);
Dict *dict = new Dict(gfx->getXRef());
dict->add(copyString("Font"), &fontsDictObj);
gfx->pushResources(dict);
delete dict;
......@@ -5084,25 +5084,25 @@ void AnnotMovie::draw(Gfx *gfx, GBool printing) {
appearBuf->append ("Q\n");
Object imgDict;
imgDict.initDict(xref);
imgDict.initDict(gfx->getXRef());
imgDict.dictSet ("MImg", &poster);
Object resDict;
resDict.initDict(xref);
resDict.initDict(gfx->getXRef());
resDict.dictSet ("XObject", &imgDict);
Object formDict, obj1, obj2;
formDict.initDict(xref);
formDict.initDict(gfx->getXRef());
formDict.dictSet("Length", obj1.initInt(appearBuf->getLength()));
formDict.dictSet("Subtype", obj1.initName("Form"));
formDict.dictSet("Name", obj1.initName("FRM"));
obj1.initArray(xref);
obj1.initArray(gfx->getXRef());
obj1.arrayAdd(obj2.initInt(0));
obj1.arrayAdd(obj2.initInt(0));
obj1.arrayAdd(obj2.initInt(width));
obj1.arrayAdd(obj2.initInt(height));
formDict.dictSet("BBox", &obj1);
obj1.initArray(xref);
obj1.initArray(gfx->getXRef());
obj1.arrayAdd(obj2.initInt(1));
obj1.arrayAdd(obj2.initInt(0));
obj1.arrayAdd(obj2.initInt(0));
......@@ -5120,10 +5120,10 @@ void AnnotMovie::draw(Gfx *gfx, GBool printing) {
delete appearBuf;
Object objDict;
objDict.initDict(xref);
objDict.initDict(gfx->getXRef());
objDict.dictSet ("FRM", &aStream);
resDict.initDict(xref);
resDict.initDict(gfx->getXRef());
resDict.dictSet ("XObject", &objDict);
appearBuf = new GooString ();
......@@ -5147,7 +5147,7 @@ void AnnotMovie::draw(Gfx *gfx, GBool printing) {
}
// draw the appearance stream
appearance.fetch(xref, &obj);
appearance.fetch(gfx->getXRef(), &obj);
gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
rect->x1, rect->y1, rect->x2, rect->y2);
obj.free();
......@@ -5489,7 +5489,7 @@ void AnnotGeometry::draw(Gfx *gfx, GBool printing) {
}
// draw the appearance stream
appearance.fetch(xref, &obj);
appearance.fetch(gfx->getXRef(), &obj);
gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
rect->x1, rect->y1, rect->x2, rect->y2);
obj.free();
......@@ -5773,7 +5773,7 @@ void AnnotPolygon::draw(Gfx *gfx, GBool printing) {
}
// draw the appearance stream
appearance.fetch(xref, &obj);
appearance.fetch(gfx->getXRef(), &obj);
if (appearBBox) {
gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
appearBBox->getPageXMin(), appearBBox->getPageYMin(),
......@@ -5985,7 +5985,7 @@ void AnnotInk::draw(Gfx *gfx, GBool printing) {
}
// draw the appearance stream
appearance.fetch(xref, &obj);
appearance.fetch(gfx->getXRef(), &obj);
if (appearBBox) {
gfx->drawAnnot(&obj, (AnnotBorder *)NULL, color,
appearBBox->getPageXMin(), appearBBox->getPageYMin(),
......@@ -6206,7 +6206,7 @@ void AnnotFileAttachment::draw(Gfx *gfx, GBool printing) {
}
// draw the appearance stream
appearance.fetch(xref, &obj);
appearance.fetch(gfx->getXRef(), &obj);
gfx->drawAnnot(&obj, border, color,
rect->x1, rect->y1, rect->x2, rect->y2);
obj.free();
......@@ -6367,7 +6367,7 @@ void AnnotSound::draw(Gfx *gfx, GBool printing) {
}
// draw the appearance stream
appearance.fetch(xref, &obj);
appearance.fetch(gfx->getXRef(), &obj);
gfx->drawAnnot(&obj, border, color,
rect->x1, rect->y1, rect->x2, rect->y2);
obj.free();
......
......@@ -15,6 +15,7 @@
//
// Copyright (C) 2005 Kristian Høgsberg <krh@redhat.com>
// Copyright (C) 2012 Fabio D'Urso <fabiodurso@hotmail.it>
// Copyright (C) 2013 Thomas Freitag <Thomas.Freitag@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
......@@ -33,6 +34,13 @@
#include "Object.h"
#include "Array.h"
#if MULTITHREADED
# define lockArray gLockMutex(&mutex)
# define unlockArray gUnlockMutex(&mutex)
#else
# define lockArray
# define unlockArray
#endif
//------------------------------------------------------------------------
// Array
//------------------------------------------------------------------------
......@@ -42,6 +50,9 @@ Array::Array(XRef *xrefA) {
elems = NULL;
size = length = 0;
ref = 1;
#if MULTITHREADED
gInitMutex(&mutex);
#endif
}
Array::~Array() {
......@@ -50,9 +61,38 @@ Array::~Array() {
for (i = 0; i < length; ++i)
elems[i].free();
gfree(elems);
#if MULTITHREADED
gDestroyMutex(&mutex);
#endif
}
Object *Array::copy(XRef *xrefA, Object *obj) {
lockArray;
obj->initArray(xrefA);
for (int i = 0; i < length; ++i) {
Object obj1;
obj->arrayAdd(elems[i].copy(&obj1));
}
unlockArray;
return obj;
}
int Array::incRef() {
lockArray;
++ref;
unlockArray;
return ref;
}
int Array::decRef() {
lockArray;
--ref;
unlockArray;
return ref;
}
void Array::add(Object *elem) {
lockArray;
if (length == size) {
if (length == 0) {
size = 8;
......@@ -63,21 +103,25 @@ void Array::add(Object *elem) {
}
elems[length] = *elem;
++length;
unlockArray;
}
void Array::remove(int i) {
lockArray;
if (i < 0 || i >= length) {
#ifdef DEBUG_MEM
abort();
#else
unlockArray;
return;
#endif
}
--length;
memmove( elems + i, elems + i + 1, sizeof(elems[0]) * (length - i) );
unlockArray;
}
Object *Array::get(int i, Object *obj) {
Object *Array::get(int i, Object *obj, int recursion) {
if (i < 0 || i >= length) {
#ifdef DEBUG_MEM
abort();
......@@ -85,7 +129,7 @@ Object *Array::get(int i, Object *obj) {
return obj->initNull();
#endif
}
return elems[i].fetch(xref, obj);
return elems[i].fetch(xref, obj, recursion);
}
Object *Array::getNF(int i, Object *obj) {
......
......@@ -15,6 +15,7 @@
//
// Copyright (C) 2005 Kristian Høgsberg <krh@redhat.com>
// Copyright (C) 2012 Fabio D'Urso <fabiodurso@hotmail.it>
// Copyright (C) 2013 Thomas Freitag <Thomas.Freitag@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
......@@ -28,7 +29,9 @@
#pragma interface
#endif
#include "poppler-config.h"
#include "Object.h"
#include "goo/GooMutex.h"
class XRef;
......@@ -46,12 +49,15 @@ public:
~Array();
// Reference counting.
int incRef() { return ++ref; }
int decRef() { return --ref; }
int incRef();
int decRef();
// Get number of elements.
int getLength() { return length; }
// Copy array with new xref
Object *copy(XRef *xrefA, Object *obj);
// Add an element.
void add(Object *elem);
......@@ -59,7 +65,7 @@ public:
void remove(int i);
// Accessors.
Object *get(int i, Object *obj);
Object *get(int i, Object *obj, int resursion = 0);
Object *getNF(int i, Object *obj);
GBool getString(int i, GooString *string);
......@@ -70,6 +76,9 @@ private:
int size; // size of <elems> array
int length; // number of elements in array
int ref; // reference count
#if MULTITHREADED
GooMutex mutex;
#endif
};
#endif
......@@ -20,6 +20,7 @@
// Copyright (C) 2009 Petr Gajdos <pgajdos@novell.com>
// Copyright (C) 2010 Matthias Fauconneau <matthias.fauconneau@gmail.com>
// Copyright (C) 2011 Andreas Hartmetz <ahartmetz@gmail.com>
// Copyright (C) 2013 Thomas Freitag <Thomas.Freitag@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
......@@ -122,7 +123,7 @@ void ArthurOutputDev::startDoc(XRef *xrefA) {
#endif
}
void ArthurOutputDev::startPage(int pageNum, GfxState *state)
void ArthurOutputDev::startPage(int pageNum, GfxState *state, XRef *xref)
{
// fill page with white background.
int w = static_cast<int>(state->getPageWidth());
......
......@@ -18,6 +18,7 @@
// Copyright (C) 2009, 2011 Carlos Garcia Campos <carlosgc@gnome.org>
// Copyright (C) 2010 Pino Toscano <pino@kde.org>
// Copyright (C) 2011 Andreas Hartmetz <ahartmetz@gmail.com>
// Copyright (C) 2013 Thomas Freitag <Thomas.Freitag@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
......@@ -86,7 +87,7 @@ public:
//----- initialization and control
// Start a page.
virtual void startPage(int pageNum, GfxState *state);
virtual void startPage(int pageNum, GfxState *state, XRef *xref);
// End a page.
virtual void endPage();
......
......@@ -26,6 +26,7 @@
// Copyright (C) 2010 Suzuki Toshiya <mpsuzuki@hiroshima-u.ac.jp>
// Copyright (C) 2010 Jan Kümmel <jan+freedesktop@snorc.org>
// Copyright (C) 2012 Hib Eris <hib@hiberis.nl>
// Copyright (C) 2013 Thomas Freitag <Thomas.Freitag@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
......@@ -58,6 +59,13 @@
#pragma implementation
#endif
#if MULTITHREADED
# define lockFontEngine gLockMutex(&mutex)
# define unlockFontEngine gUnlockMutex(&mutex)
#else
# define lockFontEngine
# define unlockFontEngine
#endif
//------------------------------------------------------------------------
// CairoFont
......@@ -558,6 +566,7 @@ typedef struct _type3_font_info {
PDFDoc *doc;
CairoFontEngine *fontEngine;
GBool printing;
XRef *xref;
} type3_font_info_t;
static void
......@@ -645,7 +654,7 @@ _render_type3_glyph (cairo_scaled_font_t *scaled_font,
box.y2 = mat[3];
gfx = new Gfx(info->doc, output_dev, resDict, &box, NULL);
output_dev->startDoc(info->doc, info->fontEngine);
output_dev->startPage (1, gfx->getState());
output_dev->startPage (1, gfx->getState(), gfx->getXRef());
output_dev->setInType3Char(gTrue);
gfx->display(charProcs->getVal(glyph, &charProc));
......@@ -674,7 +683,7 @@ _render_type3_glyph (cairo_scaled_font_t *scaled_font,
CairoType3Font *CairoType3Font::create(GfxFont *gfxFont, PDFDoc *doc,
CairoFontEngine *fontEngine,
GBool printing) {
GBool printing, XRef *xref) {
Object refObj, strObj;
type3_font_info_t *info;
cairo_font_face_t *font_face;
......@@ -697,6 +706,7 @@ CairoType3Font *CairoType3Font::create(GfxFont *gfxFont, PDFDoc *doc,
info->doc = doc;
info->fontEngine = fontEngine;
info->printing = printing;
info->xref = xref;
cairo_font_face_set_user_data (font_face, &type3_font_key, (void *) info, _free_type3_font_info);
......@@ -714,7 +724,7 @@ CairoType3Font *CairoType3Font::create(GfxFont *gfxFont, PDFDoc *doc,
}
}
return new CairoType3Font(ref, doc, font_face, codeToGID, codeToGIDLen, printing);
return new CairoType3Font(ref, doc, font_face, codeToGID, codeToGIDLen, printing, xref);
}
CairoType3Font::CairoType3Font(Ref ref,
......@@ -722,7 +732,7 @@ CairoType3Font::CairoType3Font(Ref ref,
cairo_font_face_t *cairo_font_face,
int *codeToGID,
Guint codeToGIDLen,
GBool printing) : CairoFont(ref,
GBool printing, XRef *xref) : CairoFont(ref,
cairo_font_face,
codeToGID,
codeToGIDLen,
......@@ -755,6 +765,9 @@ CairoFontEngine::CairoFontEngine(FT_Library libA) {
FT_Library_Version(lib, &major, &minor, &patch);
useCIDs = major > 2 ||
(major == 2 && (minor > 1 || (minor == 1 && patch > 7)));
#if MULTITHREADED
gInitMutex(&mutex);
#endif
}
CairoFontEngine::~CairoFontEngine() {
......@@ -764,15 +777,19 @@ CairoFontEngine::~CairoFontEngine() {
if (fontCache[i])
delete fontCache[i];
}
#if MULTITHREADED
gDestroyMutex(&mutex);
#endif
}
CairoFont *
CairoFontEngine::getFont(GfxFont *gfxFont, PDFDoc *doc, GBool printing) {
CairoFontEngine::getFont(GfxFont *gfxFont, PDFDoc *doc, GBool printing, XRef *xref) {
int i, j;
Ref ref;
CairoFont *font;
GfxFontType fontType;
lockFontEngine;
ref = *gfxFont->getID();
for (i = 0; i < cairoFontCacheSize; ++i) {
......@@ -782,15 +799,16 @@ CairoFontEngine::getFont(GfxFont *gfxFont, PDFDoc *doc, GBool printing) {
fontCache[j] = fontCache[j-1];
}
fontCache[0] = font;
unlockFontEngine;
return font;
}
}
fontType = gfxFont->getType();
if (fontType == fontType3)
font = CairoType3Font::create (gfxFont, doc, this, printing);
font = CairoType3Font::create (gfxFont, doc, this, printing, xref);
else
font = CairoFreeTypeFont::create (gfxFont, doc->getXRef(), lib, useCIDs);
font = CairoFreeTypeFont::create (gfxFont, xref, lib, useCIDs);
//XXX: if font is null should we still insert it into the cache?
if (fontCache[cairoFontCacheSize - 1]) {
......@@ -800,5 +818,6 @@ CairoFontEngine::getFont(GfxFont *gfxFont, PDFDoc *doc, GBool printing) {
fontCache[j] = fontCache[j-1];
}
fontCache[0] = font;
unlockFontEngine;
return font;
}
......@@ -19,6 +19,7 @@
// Copyright (C) 2006, 2007 Jeff Muizelaar <jeff@infidigm.net>
// Copyright (C) 2006, 2010 Carlos Garcia Campos <carlosgc@gnome.org>
// Copyright (C) 2008 Adrian Johnson <ajohnson@redneon.com>
// Copyright (C) 2013 Thomas Freitag <Thomas.Freitag@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
......@@ -32,6 +33,7 @@
#pragma interface
#endif
#include "poppler-config.h"
#include "goo/gtypes.h"
#include <cairo-ft.h>
......@@ -85,7 +87,7 @@ class CairoType3Font : public CairoFont {
public:
static CairoType3Font *create(GfxFont *gfxFont, PDFDoc *doc,
CairoFontEngine *fontEngine,
GBool printing);
GBool printing, XRef *xref);
virtual ~CairoType3Font();
virtual GBool matches(Ref &other, GBool printing);
......@@ -94,7 +96,7 @@ private:
CairoType3Font(Ref ref, PDFDoc *doc,
cairo_font_face_t *cairo_font_face,
int *codeToGID, Guint codeToGIDLen,
GBool printing);
GBool printing, XRef *xref);
PDFDoc *doc;
};
......@@ -113,12 +115,15 @@ public:
CairoFontEngine(FT_Library libA);
~CairoFontEngine();
CairoFont *getFont(GfxFont *gfxFont, PDFDoc *doc, GBool printing);
CairoFont *getFont(GfxFont *gfxFont, PDFDoc *doc, GBool printing, XRef *xref);
private:
CairoFont *fontCache[cairoFontCacheSize];
FT_Library lib;
GBool useCIDs;
#if MULTITHREADED
GooMutex mutex;
#endif
};
#endif
......@@ -25,7 +25,7 @@
// Copyright (C) 2008, 2009 Chris Wilson <chris@chris-wilson.co.uk>
// Copyright (C) 2008, 2012 Hib Eris <hib@hiberis.nl>
// Copyright (C) 2009, 2010 David Benjamin <davidben@mit.edu>
// Copyright (C) 2011, 2012 Thomas Freitag <Thomas.Freitag@alfa.de>
// Copyright (C) 2011-2013 Thomas Freitag <Thomas.Freitag@alfa.de>
// Copyright (C) 2012 Patrick Pfeifer <p2000@mailinator.com>
// Copyright (C) 2012 Jason Crain <jason@aquaticape.us>
//
......@@ -163,6 +163,7 @@ CairoOutputDev::CairoOutputDev() {
stroke_adjust = globalParams->getStrokeAdjust();
align_stroke_coords = gFalse;
adjusted_stroke_width = gFalse;
xref = NULL;
}
CairoOutputDev::~CairoOutputDev() {
......@@ -235,9 +236,10 @@ void CairoOutputDev::startDoc(PDFDoc *docA,
fontEngine = new CairoFontEngine(ft_lib);
fontEngine_owner = gTrue;
}
xref = doc->getXRef();
}
void CairoOutputDev::startPage(int pageNum, GfxState *state) {
void CairoOutputDev::startPage(int pageNum, GfxState *state, XRef *xrefA) {
/* set up some per page defaults */
cairo_pattern_destroy(fill_pattern);
cairo_pattern_destroy(stroke_pattern);
......@@ -249,6 +251,9 @@ void CairoOutputDev::startPage(int pageNum, GfxState *state) {
if (text)
text->startPage(state);
if (xrefA != NULL) {
xref = xrefA;
}
}
void CairoOutputDev::endPage() {
......@@ -602,7 +607,7 @@ void CairoOutputDev::updateFont(GfxState *state) {
if (text)
text->updateFont(state);
currentFont = fontEngine->getFont (state->getFont(), doc, printing);
currentFont = fontEngine->getFont (state->getFont(), doc, printing, xref);
if (!currentFont)
return;
......@@ -805,7 +810,7 @@ void CairoOutputDev::eoFill(GfxState *state) {
}
GBool CairoOutputDev::tilingPatternFill(GfxState *state, Gfx *gfx1, Catalog *cat, Object *str,
GBool CairoOutputDev::tilingPatternFill(GfxState *state, Gfx *gfxA, Catalog *cat, Object *str,
double *pmat, int paintType, int /*tilingType*/, Dict *resDict,
double *mat, double *bbox,
int x0, int y0, int x1, int y1,
......@@ -846,7 +851,7 @@ GBool CairoOutputDev::tilingPatternFill(GfxState *state, Gfx *gfx1, Catalog *cat
box.x2 = bbox[2]; box.y2 = bbox[3];
strokePathTmp = strokePathClip;
strokePathClip = NULL;
gfx = new Gfx(doc, this, resDict, &box, NULL);
gfx = new Gfx(doc, this, resDict, &box, NULL, NULL, NULL, gfxA->getXRef());
gfx->display(str);
delete gfx;
strokePathClip = strokePathTmp;
......
......@@ -20,7 +20,7 @@
// Copyright (C) 2006-2011 Carlos Garcia Campos <carlosgc@gnome.org>
// Copyright (C) 2008, 2009, 2011, 2012 Adrian Johnson <ajohnson@redneon.com>
// Copyright (C) 2008 Michael Vrable <mvrable@cs.ucsd.edu>
// Copyright (C) 2010-2012 Thomas Freitag <Thomas.Freitag@alfa.de>
// Copyright (C) 2010-2013 Thomas Freitag <Thomas.Freitag@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
......@@ -124,7 +124,7 @@ public:
//----- initialization and control
// Start a page.
virtual void startPage(int pageNum, GfxState *state);
virtual void startPage(int pageNum, GfxState *state, XRef *xref);
// End a page.
virtual void endPage();
......@@ -284,6 +284,7 @@ protected:
GBool adjusted_stroke_width;
GBool align_stroke_coords;
CairoFont *currentFont;
XRef *xref;
struct StrokePathClip {
GfxPath *path;
......
......@@ -25,6 +25,7 @@
// Copyright (C) 2009 Ilya Gorenbein <igorenbein@finjan.com>
// Copyright (C) 2010 Hib Eris <hib@hiberis.nl>
// Copyright (C) 2012 Fabio D'Urso <fabiodurso@hotmail.it>
// Copyright (C) 2013 Thomas Freitag <Thomas.Freitag@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
......@@ -55,6 +56,13 @@
#include "ViewerPreferences.h"
#include "FileSpec.h"
#if MULTITHREADED
# define lockCatalog gLockMutex(&mutex)
# define unlockCatalog gUnlockMutex(&mutex)
#else
# define lockCatalog
# define unlockCatalog
#endif
//------------------------------------------------------------------------
// Catalog
//------------------------------------------------------------------------
......@@ -64,6 +72,9 @@ Catalog::Catalog(PDFDoc *docA) {
Object obj, obj2;
Object optContentProps;
#if MULTITHREADED
gInitMutex(&mutex);
#endif
ok = gTrue;
doc = docA;
xref = doc->getXRef();
......@@ -170,6 +181,9 @@ Catalog::~Catalog() {
outline.free();
acroForm.free();
viewerPreferences.free();
#if MULTITHREADED
gDestroyMutex(&mutex);
#endif
}
GooString *Catalog::readMetadata() {
......@@ -177,6 +191,7 @@ GooString *Catalog::readMetadata() {
Dict *dict;
Object obj;
lockCatalog;
if (metadata.isNone()) {
Object catDict;
......@@ -191,6 +206,7 @@ GooString *Catalog::readMetadata() {
}
if (!metadata.isStream()) {
unlockCatalog;
return NULL;