diff --git a/3rdparty/poppler/git/CairoFontEngine.cc b/3rdparty/poppler/git/CairoFontEngine.cc index 76ffb5c..69b88dc 100644 --- a/3rdparty/poppler/git/CairoFontEngine.cc +++ b/3rdparty/poppler/git/CairoFontEngine.cc @@ -17,10 +17,11 @@ // Copyright (C) 2005-2007 Jeff Muizelaar // Copyright (C) 2005, 2006 Kristian Høgsberg // Copyright (C) 2005 Martin Kretzschmar +// Copyright (C) 2005, 2009, 2012, 2013, 2015, 2017 Albert Astals Cid // Copyright (C) 2006, 2007, 2010, 2011 Carlos Garcia Campos // Copyright (C) 2007 Koji Otani // Copyright (C) 2008, 2009 Chris Wilson -// Copyright (C) 2008, 2012, 2014, 2016 Adrian Johnson +// Copyright (C) 2008, 2012, 2014, 2016, 2017 Adrian Johnson // Copyright (C) 2009 Darren Kenny // Copyright (C) 2010 Suzuki Toshiya // Copyright (C) 2010 Jan Kümmel @@ -33,8 +34,9 @@ // //======================================================================== -#include +#include +#include "config.h" #include #include "CairoFontEngine.h" #include "CairoOutputDev.h" @@ -47,7 +49,7 @@ #include "Gfx.h" #include "Page.h" -#if HAVE_FCNTL_H && HAVE_SYS_MMAN_H && HAVE_SYS_STAT_H +#if defined(HAVE_FCNTL_H) && defined(HAVE_SYS_MMAN_H) && defined(HAVE_SYS_STAT_H) #include #include #include @@ -58,7 +60,7 @@ #pragma implementation #endif -#if MULTITHREADED +#ifdef MULTITHREADED # define fontEngineLocker() MutexLocker locker(&mutex) #else # define fontEngineLocker() @@ -179,7 +181,7 @@ _ft_new_face_uncached (FT_Library lib, FT_Face face; cairo_font_face_t *font_face; - if (font_data == NULL) { + if (font_data == nullptr) { if (FT_New_Face (lib, filename, 0, &face)) return gFalse; } else { @@ -205,7 +207,7 @@ _ft_new_face_uncached (FT_Library lib, return gTrue; } -#if CAN_CHECK_OPEN_FACES +#ifdef CAN_CHECK_OPEN_FACES static struct _ft_face_data { struct _ft_face_data *prev, *next, **head; @@ -285,7 +287,7 @@ _ft_new_face (FT_Library lib, tmpl.fd = -1; - if (font_data == NULL) { + if (font_data == nullptr) { /* if we fail to mmap the file, just pass it to FreeType instead */ tmpl.fd = open (filename, O_RDONLY); if (tmpl.fd == -1) @@ -296,7 +298,7 @@ _ft_new_face (FT_Library lib, return _ft_new_face_uncached (lib, filename, font_data, font_data_len, face_out, font_face_out); } - tmpl.bytes = (unsigned char *) mmap (NULL, st.st_size, + tmpl.bytes = (unsigned char *) mmap (nullptr, st.st_size, PROT_READ, MAP_PRIVATE, tmpl.fd, 0); if (tmpl.bytes == MAP_FAILED) { @@ -350,7 +352,7 @@ _ft_new_face (FT_Library lib, l = (struct _ft_face_data *) gmallocn (1, sizeof (struct _ft_face_data)); *l = tmpl; - l->prev = NULL; + l->prev = nullptr; l->next = _ft_open_faces; if (_ft_open_faces) _ft_open_faces->prev = l; @@ -410,20 +412,20 @@ CairoFreeTypeFont *CairoFreeTypeFont::create(GfxFont *gfxFont, XRef *xref, int *codeToGID; Guint codeToGIDLen; - - codeToGID = NULL; + + codeToGID = nullptr; codeToGIDLen = 0; - font_data = NULL; + font_data = nullptr; font_data_len = 0; - fileName = NULL; - fileNameC = NULL; + fileName = nullptr; + fileNameC = nullptr; GBool substitute = gFalse; - + ref = *gfxFont->getID(); fontType = gfxFont->getType(); - if (!(fontLoc = gfxFont->locateFont(xref, NULL))) { + if (!(fontLoc = gfxFont->locateFont(xref, nullptr))) { error(errSyntaxError, -1, "Couldn't find a font for '{0:s}'", gfxFont->getName() ? gfxFont->getName()->getCString() : "(unnamed)"); @@ -433,7 +435,7 @@ CairoFreeTypeFont *CairoFreeTypeFont::create(GfxFont *gfxFont, XRef *xref, // embedded font if (fontLoc->locType == gfxFontLocEmbedded) { font_data = gfxFont->readEmbFontFile(xref, &font_data_len); - if (NULL == font_data) + if (nullptr == font_data) goto err2; // external font @@ -443,7 +445,7 @@ CairoFreeTypeFont *CairoFreeTypeFont::create(GfxFont *gfxFont, XRef *xref, substitute = gTrue; } - if (fileName != NULL) { + if (fileName != nullptr) { fileNameC = fileName->getCString(); } @@ -455,9 +457,9 @@ CairoFreeTypeFont *CairoFreeTypeFont::create(GfxFont *gfxFont, XRef *xref, error(errSyntaxError, -1, "could not create type1 face"); goto err2; } - + enc = ((Gfx8BitFont *)gfxFont)->getEncoding(); - + codeToGID = (int *)gmallocn(256, sizeof(int)); codeToGIDLen = 256; for (i = 0; i < 256; ++i) { @@ -480,7 +482,7 @@ CairoFreeTypeFont *CairoFreeTypeFont::create(GfxFont *gfxFont, XRef *xref, break; case fontCIDType2: case fontCIDType2OT: - codeToGID = NULL; + codeToGID = nullptr; n = 0; if (((GfxCIDFont *)gfxFont)->getCIDToGID()) { n = ((GfxCIDFont *)gfxFont)->getCIDToGIDLen(); @@ -490,7 +492,7 @@ CairoFreeTypeFont *CairoFreeTypeFont::create(GfxFont *gfxFont, XRef *xref, n * sizeof(int)); } } else { - if (font_data != NULL) { + if (font_data != nullptr) { ff = FoFiTrueType::make(font_data, font_data_len); } else { ff = FoFiTrueType::load(fileNameC); @@ -504,7 +506,7 @@ CairoFreeTypeFont *CairoFreeTypeFont::create(GfxFont *gfxFont, XRef *xref, /* Fall through */ case fontTrueType: case fontTrueTypeOT: - if (font_data != NULL) { + if (font_data != nullptr) { ff = FoFiTrueType::make(font_data, font_data_len); } else { ff = FoFiTrueType::load(fileNameC); @@ -524,16 +526,16 @@ CairoFreeTypeFont *CairoFreeTypeFont::create(GfxFont *gfxFont, XRef *xref, goto err2; } break; - + case fontCIDType0: case fontCIDType0C: - codeToGID = NULL; + codeToGID = nullptr; codeToGIDLen = 0; if (!useCIDs) { - if (font_data != NULL) { + if (font_data != nullptr) { ff1c = FoFiType1C::make(font_data, font_data_len); } else { ff1c = FoFiType1C::load(fileNameC); @@ -551,7 +553,7 @@ CairoFreeTypeFont *CairoFreeTypeFont::create(GfxFont *gfxFont, XRef *xref, break; case fontCIDType0COT: - codeToGID = NULL; + codeToGID = nullptr; n = 0; if (((GfxCIDFont *)gfxFont)->getCIDToGID()) { n = ((GfxCIDFont *)gfxFont)->getCIDToGIDLen(); @@ -565,7 +567,7 @@ CairoFreeTypeFont *CairoFreeTypeFont::create(GfxFont *gfxFont, XRef *xref, if (!codeToGID) { if (!useCIDs) { - if (font_data != NULL) { + if (font_data != nullptr) { ff = FoFiTrueType::make(font_data, font_data_len); } else { ff = FoFiTrueType::load(fileNameC); @@ -602,7 +604,7 @@ CairoFreeTypeFont *CairoFreeTypeFont::create(GfxFont *gfxFont, XRef *xref, gfree (codeToGID); gfree (font_data); fprintf (stderr, "some font thing failed\n"); - return NULL; + return nullptr; } //------------------------------------------------------------------------ @@ -702,7 +704,7 @@ _render_type3_glyph (cairo_scaled_font_t *scaled_font, box.y1 = mat[1]; box.x2 = mat[2]; box.y2 = mat[3]; - gfx = new Gfx(info->doc, output_dev, resDict, &box, NULL); + gfx = new Gfx(info->doc, output_dev, resDict, &box, nullptr); output_dev->startDoc(info->doc, info->fontEngine); output_dev->startPage (1, gfx->getState(), gfx->getXRef()); output_dev->setInType3Char(gTrue); @@ -807,27 +809,27 @@ CairoFontEngine::CairoFontEngine(FT_Library libA) { lib = libA; for (i = 0; i < cairoFontCacheSize; ++i) { - fontCache[i] = NULL; + fontCache[i] = nullptr; } - + FT_Int major, minor, patch; // as of FT 2.1.8, CID fonts are indexed by CID instead of GID FT_Library_Version(lib, &major, &minor, &patch); useCIDs = major > 2 || (major == 2 && (minor > 1 || (minor == 1 && patch > 7))); -#if MULTITHREADED +#ifdef MULTITHREADED gInitMutex(&mutex); #endif } CairoFontEngine::~CairoFontEngine() { int i; - + for (i = 0; i < cairoFontCacheSize; ++i) { if (fontCache[i]) delete fontCache[i]; } -#if MULTITHREADED +#ifdef MULTITHREADED gDestroyMutex(&mutex); #endif } @@ -838,7 +840,7 @@ CairoFontEngine::getFont(GfxFont *gfxFont, PDFDoc *doc, GBool printing, XRef *xr Ref ref; CairoFont *font; GfxFontType fontType; - + fontEngineLocker(); ref = *gfxFont->getID(); @@ -852,7 +854,7 @@ CairoFontEngine::getFont(GfxFont *gfxFont, PDFDoc *doc, GBool printing, XRef *xr return font; } } - + fontType = gfxFont->getType(); if (fontType == fontType3) font = CairoType3Font::create (gfxFont, doc, this, printing, xref); diff --git a/3rdparty/poppler/git/CairoFontEngine.h b/3rdparty/poppler/git/CairoFontEngine.h index af63719..601fbae 100644 --- a/3rdparty/poppler/git/CairoFontEngine.h +++ b/3rdparty/poppler/git/CairoFontEngine.h @@ -15,10 +15,10 @@ // under GPL version 2 or later // // Copyright (C) 2005, 2006 Kristian Høgsberg -// Copyright (C) 2005 Albert Astals Cid +// Copyright (C) 2005, 2018 Albert Astals Cid // Copyright (C) 2006, 2007 Jeff Muizelaar // Copyright (C) 2006, 2010 Carlos Garcia Campos -// Copyright (C) 2008 Adrian Johnson +// Copyright (C) 2008, 2017 Adrian Johnson // Copyright (C) 2013 Thomas Freitag // // To see a description of the changes please see the Changelog file that @@ -51,6 +51,8 @@ public: GBool substitute, GBool printing); virtual ~CairoFont(); + CairoFont(const CairoFont &) = delete; + CairoFont& operator=(const CairoFont &other) = delete; virtual GBool matches(Ref &other, GBool printing); cairo_font_face_t *getFontFace(void); @@ -114,6 +116,8 @@ public: // Create a font engine. CairoFontEngine(FT_Library libA); ~CairoFontEngine(); + CairoFontEngine(const CairoFontEngine &) = delete; + CairoFontEngine& operator=(const CairoFontEngine &other) = delete; CairoFont *getFont(GfxFont *gfxFont, PDFDoc *doc, GBool printing, XRef *xref); @@ -121,9 +125,9 @@ private: CairoFont *fontCache[cairoFontCacheSize]; FT_Library lib; GBool useCIDs; -#if MULTITHREADED +#ifdef MULTITHREADED GooMutex mutex; #endif }; -#endif \ No newline at end of file +#endif diff --git a/3rdparty/poppler/git/CairoOutputDev.cc b/3rdparty/poppler/git/CairoOutputDev.cc index 71e27cd..330f7b0 100644 --- a/3rdparty/poppler/git/CairoOutputDev.cc +++ b/3rdparty/poppler/git/CairoOutputDev.cc @@ -18,8 +18,9 @@ // Copyright (C) 2005, 2006 Kristian Høgsberg // Copyright (C) 2005, 2009, 2012, 2017 Albert Astals Cid // Copyright (C) 2005 Nickolay V. Shmyrev -// Copyright (C) 2006-2011, 2013, 2014 Carlos Garcia Campos +// Copyright (C) 2006-2011, 2013, 2014, 2017 Carlos Garcia Campos // Copyright (C) 2008 Carl Worth +// Copyright (C) 2008-2017 Adrian Johnson // Copyright (C) 2008 Michael Vrable // Copyright (C) 2008, 2009 Chris Wilson // Copyright (C) 2008, 2012 Hib Eris @@ -34,19 +35,19 @@ // //======================================================================== -#include +#include #ifdef USE_GCC_PRAGMAS #pragma implementation #endif +#include #include #include #include #include #include "goo/gfile.h" -//#include "goo/gtypes_p.h" #include "GlobalParams.h" #include "Error.h" #include "Object.h" @@ -68,6 +69,11 @@ // #define LOG_CAIRO +// To limit memory usage and improve performance when printing, limit +// cairo images to this size. 8192 is sufficient for an A2 sized +// 300ppi image. +#define MAX_PRINT_IMAGE_SIZE 8192 + #ifdef LOG_CAIRO #define LOG(x) (x) #else @@ -90,7 +96,7 @@ static inline void printMatrix(cairo_matrix_t *matrix){ //------------------------------------------------------------------------ CairoImage::CairoImage (double x1, double y1, double x2, double y2) { - this->image = NULL; + this->image = nullptr; this->x1 = x1; this->y1 = y1; this->x2 = x2; @@ -122,26 +128,26 @@ FT_Library CairoOutputDev::ft_lib; GBool CairoOutputDev::ft_lib_initialized = gFalse; CairoOutputDev::CairoOutputDev() { - doc = NULL; + doc = nullptr; if (!ft_lib_initialized) { FT_Init_FreeType(&ft_lib); ft_lib_initialized = gTrue; } - fontEngine = NULL; + fontEngine = nullptr; fontEngine_owner = gFalse; - glyphs = NULL; - fill_pattern = NULL; + glyphs = nullptr; + fill_pattern = nullptr; fill_color.r = fill_color.g = fill_color.b = 0; - stroke_pattern = NULL; + stroke_pattern = nullptr; stroke_color.r = stroke_color.g = stroke_color.b = 0; stroke_opacity = 1.0; fill_opacity = 1.0; - textClipPath = NULL; - strokePathClip = NULL; - cairo = NULL; - currentFont = NULL; + textClipPath = nullptr; + strokePathClip = nullptr; + cairo = nullptr; + currentFont = nullptr; #if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 14, 0) prescaleImages = gFalse; #else @@ -155,23 +161,23 @@ CairoOutputDev::CairoOutputDev() { text_matrix_valid = gTrue; antialias = CAIRO_ANTIALIAS_DEFAULT; - groupColorSpaceStack = NULL; - maskStack = NULL; - group = NULL; - mask = NULL; - shape = NULL; - cairo_shape = NULL; + groupColorSpaceStack = nullptr; + maskStack = nullptr; + group = nullptr; + mask = nullptr; + shape = nullptr; + cairo_shape = nullptr; knockoutCount = 0; - text = NULL; - actualText = NULL; + text = nullptr; + actualText = nullptr; // the SA parameter supposedly defaults to false, but Acrobat // apparently hardwires it to true - stroke_adjust = globalParams->getStrokeAdjust(); + stroke_adjust = gTrue; align_stroke_coords = gFalse; adjusted_stroke_width = gFalse; - xref = NULL; + xref = nullptr; } CairoOutputDev::~CairoOutputDev() { @@ -189,15 +195,15 @@ CairoOutputDev::~CairoOutputDev() { cairo_pattern_destroy (mask); if (shape) cairo_pattern_destroy (shape); - if (text) + if (text) text->decRefCnt(); if (actualText) - delete actualText; + delete actualText; } void CairoOutputDev::setCairo(cairo_t *cairo) { - if (this->cairo != NULL) { + if (this->cairo != nullptr) { cairo_status_t status = cairo_status (this->cairo); if (status) { error(errInternal, -1, "cairo context error: {0:s}\n", cairo_status_to_string(status)); @@ -205,21 +211,21 @@ void CairoOutputDev::setCairo(cairo_t *cairo) cairo_destroy (this->cairo); assert(!cairo_shape); } - if (cairo != NULL) { + if (cairo != nullptr) { this->cairo = cairo_reference (cairo); /* save the initial matrix so that we can use it for type3 fonts. */ //XXX: is this sufficient? could we miss changes to the matrix somehow? cairo_get_matrix(cairo, &orig_matrix); setContextAntialias(cairo, antialias); } else { - this->cairo = NULL; - this->cairo_shape = NULL; + this->cairo = nullptr; + this->cairo_shape = nullptr; } } void CairoOutputDev::setTextPage(TextPage *text) { - if (this->text) + if (this->text) this->text->decRefCnt(); if (actualText) delete actualText; @@ -228,8 +234,8 @@ void CairoOutputDev::setTextPage(TextPage *text) this->text->incRefCnt(); actualText = new ActualText(text); } else { - this->text = NULL; - actualText = NULL; + this->text = nullptr; + actualText = nullptr; } } @@ -280,7 +286,7 @@ void CairoOutputDev::startPage(int pageNum, GfxState *state, XRef *xrefA) { if (text) text->startPage(state); - if (xrefA != NULL) { + if (xrefA != nullptr) { xref = xrefA; } } @@ -339,7 +345,7 @@ void CairoOutputDev::restoreState(GfxState *state) { if (strokePathClip->dashes) gfree (strokePathClip->dashes); gfree (strokePathClip); - strokePathClip = NULL; + strokePathClip = nullptr; } } @@ -663,7 +669,7 @@ void CairoOutputDev::updateFont(GfxState *state) { //FIXME: use cairo font engine? if (text) text->updateFont(state); - + currentFont = fontEngine->getFont (state->getFont(), doc, printing, xref); if (!currentFont) @@ -674,7 +680,7 @@ void CairoOutputDev::updateFont(GfxState *state) { use_show_text_glyphs = state->getFont()->hasToUnicodeCMap() && cairo_surface_has_show_text_glyphs (cairo_get_target (cairo)); - + double fontSize = state->getFontSize(); double *m = state->getTextMat(); /* NOTE: adjusting by a constant is hack. The correct solution @@ -949,11 +955,11 @@ GBool CairoOutputDev::tilingPatternFill(GfxState *state, Gfx *gfxA, Catalog *cat cairo_translate (cairo, -box.x1, -box.y1); strokePathTmp = strokePathClip; - strokePathClip = NULL; + strokePathClip = nullptr; adjusted_stroke_width_tmp = adjusted_stroke_width; maskTmp = mask; - mask = NULL; - gfx = new Gfx(doc, this, resDict, &box, NULL, NULL, NULL, gfxA->getXRef()); + mask = nullptr; + gfx = new Gfx(doc, this, resDict, &box, nullptr, nullptr, nullptr, gfxA->getXRef()); if (paintType == 2) inUncoloredPattern = gTrue; gfx->display(str); @@ -1350,7 +1356,7 @@ void CairoOutputDev::clipToStrokePath(GfxState *state) { strokePathClip->dashes = (double*) gmallocn (sizeof(double), strokePathClip->dash_count); cairo_get_dash (cairo, strokePathClip->dashes, &strokePathClip->dash_offset); } else { - strokePathClip->dashes = NULL; + strokePathClip->dashes = nullptr; } strokePathClip->cap = cairo_get_line_cap (cairo); strokePathClip->join = cairo_get_line_join (cairo); @@ -1487,11 +1493,11 @@ void CairoOutputDev::endString(GfxState *state) } cairo_path_destroy (textClipPath); } - + // append the glyph path cairo_glyph_path (cairo, glyphs, glyphCount); - - // move the path back into textClipPath + + // move the path back into textClipPath // and clear the current path textClipPath = cairo_copy_path (cairo); cairo_new_path (cairo); @@ -1502,12 +1508,12 @@ void CairoOutputDev::endString(GfxState *state) finish: gfree (glyphs); - glyphs = NULL; + glyphs = nullptr; if (use_show_text_glyphs) { gfree (clusters); - clusters = NULL; + clusters = nullptr; gfree (utf8); - utf8 = NULL; + utf8 = nullptr; } } @@ -1578,7 +1584,7 @@ void CairoOutputDev::endTextObject(GfxState *state) { cairo_clip (cairo_shape); } cairo_path_destroy (textClipPath); - textClipPath = NULL; + textClipPath = nullptr; } } @@ -1610,7 +1616,7 @@ static cairo_surface_t *cairo_surface_create_similar_clip (cairo_t *cairo, cairo_content_t content) { cairo_pattern_t *pattern; - cairo_surface_t *surface = NULL; + cairo_surface_t *surface = nullptr; cairo_push_group_with_content (cairo, content); pattern = cairo_pop_group (cairo); @@ -1722,7 +1728,7 @@ void CairoOutputDev::paintTransparencyGroup(GfxState * /*state*/, double * /*bbo cairo_paint_with_alpha (cairo, fill_opacity); } cairo_pattern_destroy(mask); - mask = NULL; + mask = nullptr; } if (shape) { @@ -1732,7 +1738,7 @@ void CairoOutputDev::paintTransparencyGroup(GfxState * /*state*/, double * /*bbo cairo_set_source_rgb (cairo_shape, 0, 0, 0); } cairo_pattern_destroy (shape); - shape = NULL; + shape = nullptr; } popTransparencyGroup(); @@ -1833,7 +1839,7 @@ void CairoOutputDev::setSoftMask(GfxState * state, double * bbox, GBool alpha, /* convert to a luminocity map */ uint32_t *source_data = (uint32_t*)cairo_image_surface_get_data(source); /* get stride in units of 32 bits */ - int stride = cairo_image_surface_get_stride(source)/4; + ptrdiff_t stride = cairo_image_surface_get_stride(source)/4; for (int y=0; ynext; @@ -1891,7 +1897,7 @@ void CairoOutputDev::popTransparencyGroup() { void CairoOutputDev::clearSoftMask(GfxState * /*state*/) { if (mask) cairo_pattern_destroy(mask); - mask = NULL; + mask = nullptr; } /* Taken from cairo/doc/tutorial/src/singular.c */ @@ -2027,7 +2033,7 @@ void CairoOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, cairo_matrix_t matrix; cairo_get_matrix (cairo, &matrix); - //XXX: it is possible that we should only do sub pixel positioning if + //XXX: it is possible that we should only do sub pixel positioning if // we are rendering fonts */ if (!printing && prescaleImages /* not rotated */ @@ -2080,7 +2086,7 @@ void CairoOutputDev::setSoftMaskFromImageMask(GfxState *state, Object *ref, Stre cairo_matrix_t matrix; cairo_get_matrix (cairo, &matrix); - //XXX: it is possible that we should only do sub pixel positioning if + //XXX: it is possible that we should only do sub pixel positioning if // we are rendering fonts */ if (!printing && prescaleImages && matrix.xy == 0.0 && matrix.yx == 0.0) { drawImageMaskPrescaled(state, ref, str, width, height, invert, gFalse, inlineImg); @@ -2126,7 +2132,7 @@ void CairoOutputDev::drawImageMaskRegular(GfxState *state, Object *ref, Stream * Guchar *pix; cairo_matrix_t matrix; int invert_bit; - int row_stride; + ptrdiff_t row_stride; cairo_filter_t filter; /* TODO: Do we want to cache these? */ @@ -2177,9 +2183,6 @@ void CairoOutputDev::drawImageMaskRegular(GfxState *state, Object *ref, Stream * cairo_pattern_set_filter (pattern, filter); - if (!printing) - cairo_pattern_set_extend (pattern, CAIRO_EXTEND_PAD); - cairo_matrix_init_translate (&matrix, 0, height); cairo_matrix_scale (&matrix, width, -height); cairo_pattern_set_matrix (pattern, &matrix); @@ -2195,6 +2198,11 @@ void CairoOutputDev::drawImageMaskRegular(GfxState *state, Object *ref, Stream * cairo_save (cairo); cairo_rectangle (cairo, 0., 0., 1., 1.); cairo_clip (cairo); + if (strokePathClip) { + cairo_push_group (cairo); + fillToStrokePathClip (state); + cairo_pop_group_to_source (cairo); + } cairo_mask (cairo, pattern); cairo_restore (cairo); } else { @@ -2231,7 +2239,7 @@ void CairoOutputDev::drawImageMaskPrescaled(GfxState *state, Object *ref, Stream Guchar *pix; cairo_matrix_t matrix; int invert_bit; - int row_stride; + ptrdiff_t row_stride; /* cairo does a very poor job of scaling down images so we scale them ourselves */ @@ -2524,7 +2532,7 @@ void CairoOutputDev::drawMaskedImage(GfxState *state, Object *ref, GBool maskInterpolate) { ImageStream *maskImgStr, *imgStr; - int row_stride; + ptrdiff_t row_stride; unsigned char *maskBuffer, *buffer; unsigned char *maskDest; unsigned int *dest; @@ -2580,7 +2588,7 @@ void CairoOutputDev::drawMaskedImage(GfxState *state, Object *ref, * so check its underlying color space as well */ int is_identity_transform; is_identity_transform = colorMap->getColorSpace()->getMode() == csDeviceRGB || - (colorMap->getColorSpace()->getMode() == csICCBased && + (colorMap->getColorSpace()->getMode() == csICCBased && ((GfxICCBasedColorSpace*)colorMap->getColorSpace())->getAlt()->getMode() == csDeviceRGB); #endif @@ -2682,7 +2690,7 @@ void CairoOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref, Stream *s GBool maskInterpolate) { ImageStream *maskImgStr, *imgStr; - int row_stride; + ptrdiff_t row_stride; unsigned char *maskBuffer, *buffer; unsigned char *maskDest; unsigned int *dest; @@ -2711,7 +2719,9 @@ void CairoOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref, Stream *s for (y = 0; y < maskHeight; y++) { maskDest = (unsigned char *) (maskBuffer + y * row_stride); pix = maskImgStr->getLine(); - maskColorMap->getGrayLine (pix, maskDest, maskWidth); + if (likely(pix != nullptr)) { + maskColorMap->getGrayLine (pix, maskDest, maskWidth); + } } maskImgStr->close(); @@ -2756,7 +2766,7 @@ void CairoOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref, Stream *s cairo_surface_mark_dirty (image); - setMimeData(state, str, ref, colorMap, image); + setMimeData(state, str, ref, colorMap, image, height); pattern = cairo_pattern_create_for_surface (image); cairo_surface_destroy (image); @@ -2910,7 +2920,7 @@ GBool CairoOutputDev::setMimeDataForJBIG2Globals(Stream *str, if (!globalsStr->isStream()) return gTrue; - if (setMimeIdFromRef(image, CAIRO_MIME_TYPE_JBIG2_GLOBAL_ID, NULL, + if (setMimeIdFromRef(image, CAIRO_MIME_TYPE_JBIG2_GLOBAL_ID, nullptr, jb2Str->getGlobalsStreamRef())) return gFalse; @@ -2930,8 +2940,38 @@ GBool CairoOutputDev::setMimeDataForJBIG2Globals(Stream *str, } #endif +#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 15, 10) +GBool CairoOutputDev::setMimeDataForCCITTParams(Stream *str, + cairo_surface_t *image, int height) +{ + CCITTFaxStream *ccittStr = static_cast(str); + + GooString params; + params.appendf("Columns={0:d}", ccittStr->getColumns()); + params.appendf(" Rows={0:d}", height); + params.appendf(" K={0:d}", ccittStr->getEncoding()); + params.appendf(" EndOfLine={0:d}", ccittStr->getEndOfLine() ? 1 : 0); + params.appendf(" EncodedByteAlign={0:d}", ccittStr->getEncodedByteAlign() ? 1 : 0); + params.appendf(" EndOfBlock={0:d}", ccittStr->getEndOfBlock() ? 1 : 0); + params.appendf(" BlackIs1={0:d}", ccittStr->getBlackIs1() ? 1 : 0); + params.appendf(" DamagedRowsBeforeError={0:d}", ccittStr->getDamagedRowsBeforeError()); + + char *p = strdup(params.getCString()); + if (cairo_surface_set_mime_data (image, CAIRO_MIME_TYPE_CCITT_FAX_PARAMS, + (const unsigned char*)p, + params.getLength(), + gfree, (void*)p)) + { + gfree (p); + return gFalse; + } + + return gTrue; +} +#endif + void CairoOutputDev::setMimeData(GfxState *state, Stream *str, Object *ref, - GfxImageColorMap *colorMap, cairo_surface_t *image) + GfxImageColorMap *colorMap, cairo_surface_t *image, int height) { char *strBuffer; int len; @@ -2954,14 +2994,18 @@ void CairoOutputDev::setMimeData(GfxState *state, Stream *str, Object *ref, case strJBIG2: mime_type = CAIRO_MIME_TYPE_JBIG2; break; +#endif +#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 15, 10) + case strCCITTFax: + mime_type = CAIRO_MIME_TYPE_CCITT_FAX; + break; #endif default: return; } obj = str->getDict()->lookup("ColorSpace"); - colorSpace = GfxColorSpace::parse(NULL, &obj, this, state); - obj.free(); + colorSpace = GfxColorSpace::parse(nullptr, &obj, this, state); // colorspace in stream dict may be different from colorspace in jpx // data @@ -2998,6 +3042,11 @@ void CairoOutputDev::setMimeData(GfxState *state, Stream *str, Object *ref, return; #endif +#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 15, 10) + if (strKind == strCCITTFax && !setMimeDataForCCITTParams(str, image, height)) + return; +#endif + if (getStreamData (str->getNextStream(), &strBuffer, &len)) { cairo_status_t status = CAIRO_STATUS_SUCCESS; @@ -3035,10 +3084,10 @@ public: GBool printing, GfxImageColorMap *colorMapA, int *maskColorsA) { - cairo_surface_t *image = NULL; + cairo_surface_t *image = nullptr; int i; - lookup = NULL; + lookup = nullptr; colorMap = colorMapA; maskColors = maskColorsA; width = widthA; @@ -3075,10 +3124,31 @@ public: } } - if (printing || scaledWidth >= width || scaledHeight >= height) { +#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 14, 0) + bool needsCustomDownscaling = false; +#else + bool needsCustomDownscaling = true; +#endif + + if (printing) { + if (width > MAX_PRINT_IMAGE_SIZE || height > MAX_PRINT_IMAGE_SIZE) { + if (width > height) { + scaledWidth = MAX_PRINT_IMAGE_SIZE; + scaledHeight = MAX_PRINT_IMAGE_SIZE * (double)height/width; + } else { + scaledHeight = MAX_PRINT_IMAGE_SIZE; + scaledWidth = MAX_PRINT_IMAGE_SIZE * (double)width/height; + } + needsCustomDownscaling = true; + } else { + needsCustomDownscaling = false; + } + } + + if (!needsCustomDownscaling || scaledWidth >= width || scaledHeight >= height) { // No downscaling. Create cairo image containing the source image data. unsigned char *buffer; - int stride; + ptrdiff_t stride; image = cairo_image_surface_create (maskColors ? CAIRO_FORMAT_ARGB32 : @@ -3134,7 +3204,7 @@ public: current_row++; } - if (unlikely(pix == NULL)) { + if (unlikely(pix == nullptr)) { memset(row_data, 0, width*4); if (!imageError) { error(errInternal, -1, "Bad image stream"); @@ -3189,7 +3259,7 @@ void CairoOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, cairo_matrix_t matrix; int width, height; int scaledWidth, scaledHeight; - cairo_filter_t filter = CAIRO_FILTER_BILINEAR; + cairo_filter_t filter = CAIRO_FILTER_BEST; RescaleDrawImage rescale; LOG (printf ("drawImage %dx%d\n", widthA, heightA)); @@ -3205,8 +3275,17 @@ void CairoOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, if (width == widthA && height == heightA) filter = getFilterForSurface (image, interpolate); - if (!inlineImg) /* don't read stream twice if it is an inline image */ - setMimeData(state, str, ref, colorMap, image); + if (!inlineImg) { /* don't read stream twice if it is an inline image */ + // cairo 1.15.10 allows mime image data to have different size to cairo image + // mime image size will be scaled to same size as cairo image +#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 15, 10) + bool requireSameSize = false; +#else + bool requireSameSize = true; +#endif + if (!requireSameSize || (width == widthA && height == heightA)) + setMimeData(state, str, ref, colorMap, image, heightA); + } pattern = cairo_pattern_create_for_surface (image); cairo_surface_destroy (image); @@ -3231,7 +3310,7 @@ void CairoOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, } else if (mask) { maskPattern = cairo_pattern_reference (mask); } else { - maskPattern = NULL; + maskPattern = nullptr; } cairo_save (cairo); @@ -3276,11 +3355,11 @@ void CairoOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, CairoImageOutputDev::CairoImageOutputDev() { - images = NULL; + images = nullptr; numImages = 0; size = 0; - imgDrawCbk = NULL; - imgDrawCbkData = NULL; + imgDrawCbk = nullptr; + imgDrawCbkData = nullptr; } CairoImageOutputDev::~CairoImageOutputDev() @@ -3293,7 +3372,7 @@ CairoImageOutputDev::~CairoImageOutputDev() } void CairoImageOutputDev::saveImage(CairoImage *image) -{ +{ if (numImages >= size) { size += 16; images = (CairoImage **) greallocn (images, size, sizeof (CairoImage *)); @@ -3353,7 +3432,7 @@ void CairoImageOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *st CairoOutputDev::drawImageMask(state, ref, str, width, height, invert, interpolate, inlineImg); image->setImage (surface); - setCairo (NULL); + setCairo (nullptr); cairo_surface_destroy (surface); cairo_destroy (cr); } @@ -3386,7 +3465,7 @@ void CairoImageOutputDev::setSoftMaskFromImageMask(GfxState *state, Object *ref, } image->setImage (surface); - setCairo (NULL); + setCairo (nullptr); cairo_surface_destroy (surface); cairo_destroy (cr); } @@ -3412,11 +3491,11 @@ void CairoImageOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, setCairo (cr); cairo_translate (cr, 0, height); cairo_scale (cr, width, -height); - + CairoOutputDev::drawImage(state, ref, str, width, height, colorMap, interpolate, maskColors, inlineImg); image->setImage (surface); - - setCairo (NULL); + + setCairo (nullptr); cairo_surface_destroy (surface); cairo_destroy (cr); } @@ -3447,12 +3526,12 @@ void CairoImageOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref, Stre setCairo (cr); cairo_translate (cr, 0, height); cairo_scale (cr, width, -height); - + CairoOutputDev::drawSoftMaskedImage(state, ref, str, width, height, colorMap, interpolate, maskStr, maskWidth, maskHeight, maskColorMap, maskInterpolate); image->setImage (surface); - - setCairo (NULL); + + setCairo (nullptr); cairo_surface_destroy (surface); cairo_destroy (cr); } @@ -3482,12 +3561,12 @@ void CairoImageOutputDev::drawMaskedImage(GfxState *state, Object *ref, Stream * setCairo (cr); cairo_translate (cr, 0, height); cairo_scale (cr, width, -height); - + CairoOutputDev::drawMaskedImage(state, ref, str, width, height, colorMap, interpolate, maskStr, maskWidth, maskHeight, maskInvert, maskInterpolate); image->setImage (surface); - - setCairo (NULL); + + setCairo (nullptr); cairo_surface_destroy (surface); cairo_destroy (cr); } diff --git a/3rdparty/poppler/git/CairoOutputDev.h b/3rdparty/poppler/git/CairoOutputDev.h index 837ce15..451fa78 100644 --- a/3rdparty/poppler/git/CairoOutputDev.h +++ b/3rdparty/poppler/git/CairoOutputDev.h @@ -23,6 +23,7 @@ // Copyright (C) 2010-2013 Thomas Freitag // Copyright (C) 2015 Suzuki Toshiya // Copyright (C) 2016 Jason Crain +// Copyright (C) 2018 Albert Astals Cid // // 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 @@ -63,16 +64,19 @@ public: // Destructor. ~CairoImage (); + CairoImage(const CairoImage &) = delete; + CairoImage& operator=(const CairoImage &) = delete; + // Set the image cairo surface void setImage (cairo_surface_t *image); - + // Get the image cairo surface cairo_surface_t *getImage () const { return image; } // Get the image rectangle void getRect (double *xa1, double *ya1, double *xa2, double *ya2) { *xa1 = x1; *ya1 = y1; *xa2 = x2; *ya2 = y2; } - + private: cairo_surface_t *image; // image cairo surface double x1, y1; // upper left corner @@ -257,12 +261,12 @@ public: double llx, double lly, double urx, double ury) override; //----- special access - + // Called to indicate that a new PDF document has been loaded. void startDoc(PDFDoc *docA, CairoFontEngine *fontEngine = NULL); - + GBool isReverseVideo() { return gFalse; } - + void setCairo (cairo_t *cr); void setTextPage (TextPage *text); void setPrinting (GBool printing) { this->printing = printing; needFontUpdate = gTrue; } @@ -283,11 +287,14 @@ protected: GBool interpolate); GBool getStreamData (Stream *str, char **buffer, int *length); void setMimeData(GfxState *state, Stream *str, Object *ref, - GfxImageColorMap *colorMap, cairo_surface_t *image); + GfxImageColorMap *colorMap, cairo_surface_t *image, int height); void fillToStrokePathClip(GfxState *state); void alignStrokeCoords(GfxSubpath *subpath, int i, double *x, double *y); #if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 14, 0) GBool setMimeDataForJBIG2Globals (Stream *str, cairo_surface_t *image); +#endif +#if CAIRO_VERSION >= CAIRO_VERSION_ENCODE(1, 15, 10) + GBool setMimeDataForCCITTParams(Stream *str, cairo_surface_t *image, int height); #endif static void setContextAntialias(cairo_t *cr, cairo_antialias_t antialias); @@ -513,7 +520,7 @@ private: void saveImage(CairoImage *image); void getBBox(GfxState *state, int width, int height, double *x1, double *y1, double *x2, double *y2); - + CairoImage **images; int numImages; int size; diff --git a/3rdparty/poppler/git/CairoRescaleBox.cc b/3rdparty/poppler/git/CairoRescaleBox.cc index 37c6c89..f34b1e1 100644 --- a/3rdparty/poppler/git/CairoRescaleBox.cc +++ b/3rdparty/poppler/git/CairoRescaleBox.cc @@ -31,7 +31,7 @@ // under GPL version 2 or later // // Copyright (C) 2012 Hib Eris -// Copyright (C) 2012 Adrian Johnson +// Copyright (C) 2012, 2017 Adrian Johnson // // 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 @@ -41,17 +41,15 @@ /* This implements a box filter that supports non-integer box sizes */ -#ifdef HAVE_CONFIG_H #include -#endif +#include #include #include #include #include #include #include "goo/gmem.h" -//#include "goo/gtypes_p.h" #include "CairoRescaleBox.h" @@ -273,9 +271,9 @@ GBool CairoRescaleBox::downScaleImage(unsigned orig_width, unsigned orig_height, int dest_y; int src_y = 0; uint32_t *scanline; - int *x_coverage = NULL; - int *y_coverage = NULL; - uint32_t *temp_buf = NULL; + int *x_coverage = nullptr; + int *y_coverage = nullptr; + uint32_t *temp_buf = nullptr; GBool retval = gFalse; unsigned int *dest; int dst_stride; @@ -375,4 +373,4 @@ cleanup: free (scanline); return retval; -} \ No newline at end of file +} diff --git a/3rdparty/poppler/git/CairoRescaleBox.h b/3rdparty/poppler/git/CairoRescaleBox.h index b4117b8..ca307cb 100644 --- a/3rdparty/poppler/git/CairoRescaleBox.h +++ b/3rdparty/poppler/git/CairoRescaleBox.h @@ -30,6 +30,7 @@ // under GPL version 2 or later // // Copyright (C) 2012 Adrian Johnson +// Copyright (C) 2018 Albert Astals Cid // // 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 @@ -48,6 +49,9 @@ public: CairoRescaleBox() {}; virtual ~CairoRescaleBox() {}; + CairoRescaleBox(const CairoRescaleBox &) = delete; + CairoRescaleBox& operator=(const CairoRescaleBox &) = delete; + virtual GBool downScaleImage(unsigned orig_width, unsigned orig_height, signed scaled_width, signed scaled_height, unsigned short int start_column, unsigned short int start_row, @@ -58,4 +62,4 @@ public: }; -#endif /* CAIRO_RESCALE_BOX_H */ \ No newline at end of file +#endif /* CAIRO_RESCALE_BOX_H */