--- a/glib/poppler-attachment.cc 2011-06-30 23:41:10.000000000 +0200 +++ b/glib/poppler-attachment.cc 2012-02-29 18:16:00.000000000 +0100 @@ -210,7 +210,7 @@ poppler_attachment_save (PopplerAttachme return FALSE; } - return TRUE; + return result; } #define BUF_SIZE 1024 --- a/goo/GooString.cc 2011-08-29 22:06:43.000000000 +0200 +++ b/goo/GooString.cc 2012-02-29 18:16:00.000000000 +0100 @@ -19,6 +19,7 @@ // Copyright (C) 2006 Krzysztof Kowalczyk <kkowalczyk@gmail.com> // Copyright (C) 2007 Jeff Muizelaar <jeff@infidigm.net> // Copyright (C) 2008-2011 Albert Astals Cid <aacid@kde.org> +// Copyright (C) 2011 Kenji Uno <ku@digitaldolphins.jp> // // 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 @@ -129,6 +130,8 @@ void inline GooString::resize(int newLen } else { memcpy(s1, s, length); } + if (s != sStatic) + gfree(s); } } --- a/goo/JpegWriter.cc 2011-07-29 00:24:01.000000000 +0200 +++ b/goo/JpegWriter.cc 2012-02-29 18:16:00.000000000 +0100 @@ -53,6 +53,10 @@ bool JpegWriter::init(FILE *f, int width // Initialize libjpeg jpeg_create_compress(&cinfo); + // Set colorspace and initialise defaults + cinfo.in_color_space = colorMode; /* colorspace of input image */ + jpeg_set_defaults(&cinfo); + // Set destination file jpeg_stdio_dest(&cinfo, f); @@ -62,7 +66,6 @@ bool JpegWriter::init(FILE *f, int width cinfo.density_unit = 1; // dots per inch cinfo.X_density = hDPI; cinfo.Y_density = vDPI; - cinfo.in_color_space = colorMode; /* colorspace of input image */ /* # of color components per pixel */ switch (colorMode) { case JCS_GRAYSCALE: @@ -77,7 +80,6 @@ bool JpegWriter::init(FILE *f, int width default: return false; } - jpeg_set_defaults(&cinfo); if (cinfo.in_color_space == JCS_CMYK) { jpeg_set_colorspace(&cinfo, JCS_YCCK); cinfo.write_JFIF_header = TRUE; --- a/goo/PNGWriter.cc 2011-08-30 19:00:31.000000000 +0200 +++ b/goo/PNGWriter.cc 2012-02-29 18:16:00.000000000 +0100 @@ -6,7 +6,7 @@ // // Copyright (C) 2009 Warren Toomey <wkt@tuhs.org> // Copyright (C) 2009 Shen Liang <shenzhuxi@gmail.com> -// Copyright (C) 2009 Albert Astals Cid <aacid@kde.org> +// Copyright (C) 2009, 2011 Albert Astals Cid <aacid@kde.org> // Copyright (C) 2009 Stefan Thomas <thomas@eload24.com> // Copyright (C) 2010, 2011 Adrian Johnson <ajohnson@redneon.com> // Copyright (C) 2011 Thomas Klausner <wiz@danbala.tuwien.ac.at> @@ -19,6 +19,7 @@ #include <zlib.h> #include <stdlib.h> +#include <string.h> #include "poppler/Error.h" #include "goo/gmem.h" --- a/poppler/CairoFontEngine.cc 2011-06-30 23:41:10.000000000 +0200 +++ b/poppler/CairoFontEngine.cc 2012-02-29 18:16:00.000000000 +0100 @@ -106,7 +106,7 @@ CairoFont::getGlyph(CharCode code, double CairoFont::getSubstitutionCorrection(GfxFont *gfxFont) { - double w1, w2,w3; + double w1, w2; CharCode code; char *name; @@ -134,7 +134,6 @@ CairoFont::getSubstitutionCorrection(Gfx cairo_scaled_font_destroy(scaled_font); cairo_font_options_destroy(options); - w3 = extents.width; w2 = extents.x_advance; } if (!gfxFont->isSymbolic()) { --- a/poppler/CairoOutputDev.cc 2012-02-29 17:53:31.000000000 +0100 +++ b/poppler/CairoOutputDev.cc 2012-02-29 18:16:00.000000000 +0100 @@ -434,7 +434,7 @@ void CairoOutputDev::updateLineWidth(Gfx /* find out line width in device units */ cairo_user_to_device_distance(cairo, &x, &y); - if (x <= 1.0 && y <= 1.0) { + if (fabs(x) <= 1.0 && fabs(y) <= 1.0) { /* adjust width to at least one device pixel */ x = y = 1.0; cairo_device_to_user_distance(cairo, &x, &y); --- a/poppler/CairoRescaleBox.cc 2011-08-21 23:41:12.000000000 +0200 +++ b/poppler/CairoRescaleBox.cc 2012-02-29 18:16:00.000000000 +0100 @@ -347,5 +347,5 @@ cleanup: free (y_coverage); free (temp_buf); - return gTrue; + return retval; } --- a/poppler/Gfx.cc 2011-09-27 00:15:13.000000000 +0200 +++ b/poppler/Gfx.cc 2012-02-29 18:16:00.000000000 +0100 @@ -33,6 +33,7 @@ // Copyright (C) 2009, 2010 David Benjamin <davidben@mit.edu> // Copyright (C) 2010 Nils Höglund <nils.hoglund@gmail.com> // Copyright (C) 2010 Christian Feuersänger <cfeuersaenger@googlemail.com> +// Copyright (C) 2011 Axel Strübing <axel.struebing@freenet.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 @@ -1319,7 +1320,7 @@ void Gfx::opSetRenderingIntent(Object ar void Gfx::opSetFillGray(Object args[], int numArgs) { GfxColor color; - GfxColorSpace *colorSpace; + GfxColorSpace *colorSpace = NULL; Object obj; if (textHaveCSPattern && drawText) { @@ -1332,11 +1333,12 @@ void Gfx::opSetFillGray(Object args[], i } state->setFillPattern(NULL); res->lookupColorSpace("DefaultGray", &obj); - if (obj.isNull()) { - colorSpace = new GfxDeviceGrayColorSpace(); - } else { + if (!obj.isNull()) { colorSpace = GfxColorSpace::parse(&obj, this); } + if (colorSpace == NULL) { + colorSpace = new GfxDeviceGrayColorSpace(); + } obj.free(); state->setFillColorSpace(colorSpace); out->updateFillColorSpace(state); @@ -1354,16 +1356,17 @@ void Gfx::opSetFillGray(Object args[], i void Gfx::opSetStrokeGray(Object args[], int numArgs) { GfxColor color; - GfxColorSpace *colorSpace; + GfxColorSpace *colorSpace = NULL; Object obj; state->setStrokePattern(NULL); res->lookupColorSpace("DefaultGray", &obj); - if (obj.isNull()) { - colorSpace = new GfxDeviceGrayColorSpace(); - } else { + if (!obj.isNull()) { colorSpace = GfxColorSpace::parse(&obj, this); } + if (colorSpace == NULL) { + colorSpace = new GfxDeviceGrayColorSpace(); + } obj.free(); state->setStrokeColorSpace(colorSpace); out->updateStrokeColorSpace(state); @@ -1374,7 +1377,7 @@ void Gfx::opSetStrokeGray(Object args[], void Gfx::opSetFillCMYKColor(Object args[], int numArgs) { GfxColor color; - GfxColorSpace *colorSpace; + GfxColorSpace *colorSpace = NULL; Object obj; int i; @@ -1387,11 +1390,12 @@ void Gfx::opSetFillCMYKColor(Object args out->restoreState(state); } res->lookupColorSpace("DefaultCMYK", &obj); - if (obj.isNull()) { - colorSpace = new GfxDeviceCMYKColorSpace(); - } else { + if (!obj.isNull()) { colorSpace = GfxColorSpace::parse(&obj, this); } + if (colorSpace == NULL) { + colorSpace = new GfxDeviceCMYKColorSpace(); + } obj.free(); state->setFillPattern(NULL); state->setFillColorSpace(colorSpace); @@ -1412,17 +1416,18 @@ void Gfx::opSetFillCMYKColor(Object args void Gfx::opSetStrokeCMYKColor(Object args[], int numArgs) { GfxColor color; - GfxColorSpace *colorSpace; + GfxColorSpace *colorSpace = NULL; Object obj; int i; state->setStrokePattern(NULL); res->lookupColorSpace("DefaultCMYK", &obj); - if (obj.isNull()) { - colorSpace = new GfxDeviceCMYKColorSpace(); - } else { + if (!obj.isNull()) { colorSpace = GfxColorSpace::parse(&obj, this); } + if (colorSpace == NULL) { + colorSpace = new GfxDeviceCMYKColorSpace(); + } obj.free(); state->setStrokeColorSpace(colorSpace); out->updateStrokeColorSpace(state); @@ -1435,7 +1440,7 @@ void Gfx::opSetStrokeCMYKColor(Object ar void Gfx::opSetFillRGBColor(Object args[], int numArgs) { Object obj; - GfxColorSpace *colorSpace; + GfxColorSpace *colorSpace = NULL; GfxColor color; int i; @@ -1449,11 +1454,12 @@ void Gfx::opSetFillRGBColor(Object args[ } state->setFillPattern(NULL); res->lookupColorSpace("DefaultRGB", &obj); - if (obj.isNull()) { - colorSpace = new GfxDeviceRGBColorSpace(); - } else { + if (!obj.isNull()) { colorSpace = GfxColorSpace::parse(&obj, this); } + if (colorSpace == NULL) { + colorSpace = new GfxDeviceRGBColorSpace(); + } obj.free(); state->setFillColorSpace(colorSpace); out->updateFillColorSpace(state); @@ -1473,17 +1479,18 @@ void Gfx::opSetFillRGBColor(Object args[ void Gfx::opSetStrokeRGBColor(Object args[], int numArgs) { Object obj; - GfxColorSpace *colorSpace; + GfxColorSpace *colorSpace = NULL; GfxColor color; int i; state->setStrokePattern(NULL); res->lookupColorSpace("DefaultRGB", &obj); - if (obj.isNull()) { - colorSpace = new GfxDeviceRGBColorSpace(); - } else { + if (!obj.isNull()) { colorSpace = GfxColorSpace::parse(&obj, this); } + if (colorSpace == NULL) { + colorSpace = new GfxDeviceRGBColorSpace(); + } obj.free(); state->setStrokeColorSpace(colorSpace); out->updateStrokeColorSpace(state); --- a/poppler/GfxFont.cc 2011-08-29 22:06:43.000000000 +0200 +++ b/poppler/GfxFont.cc 2012-02-29 18:16:00.000000000 +0100 @@ -449,7 +449,7 @@ CharCodeToUnicode *GfxFont::readToUnicod void GfxFont::findExtFontFile() { static char *type1Exts[] = { ".pfa", ".pfb", ".ps", "", NULL }; - static char *ttExts[] = { ".ttf", ".ttc", NULL }; + static char *ttExts[] = { ".ttf", ".ttc", ".otf", NULL }; if (name) { if (type == fontType1) { --- a/poppler/GfxState.cc 2011-07-28 12:58:37.000000000 +0200 +++ b/poppler/GfxState.cc 2012-02-29 18:16:00.000000000 +0100 @@ -257,8 +257,20 @@ GfxColorSpace *GfxColorSpace::parse(Obje error(-1, "Bad color space"); } obj1.free(); + } else if (csObj->isDict()) { + csObj->dictLookup("ColorSpace", &obj1); + if (obj1.isName("DeviceGray")) { + cs = new GfxDeviceGrayColorSpace(); + } else if (obj1.isName("DeviceRGB")) { + cs = new GfxDeviceRGBColorSpace(); + } else if (obj1.isName("DeviceCMYK")) { + cs = new GfxDeviceCMYKColorSpace(); + } else { + error(-1, "Bad color space '%s'", csObj->getName()); + } + obj1.free(); } else { - error(-1, "Bad color space - expected name or array"); + error(-1, "Bad color space - expected name, array or dict"); } return cs; } --- a/poppler/GlobalParams.cc 2011-07-28 12:43:53.000000000 +0200 +++ b/poppler/GlobalParams.cc 2012-02-29 18:16:00.000000000 +0100 @@ -1247,7 +1247,7 @@ DisplayFontParam *GlobalParams::getDispl ext = strrchr((char*)s,'.'); if (!ext) continue; - if (!strncasecmp(ext,".ttf",4) || !strncasecmp(ext, ".ttc", 4)) + if (!strncasecmp(ext,".ttf",4) || !strncasecmp(ext, ".ttc", 4) || !strncasecmp(ext, ".otf", 4)) { dfp = new DisplayFontParam(fontName->copy(), displayFontTT); dfp->tt.fileName = new GooString((char*)s); --- a/poppler/Lexer.cc 2010-07-16 00:43:51.000000000 +0200 +++ b/poppler/Lexer.cc 2012-02-29 18:16:00.000000000 +0100 @@ -228,11 +228,13 @@ Object *Lexer::getObj(Object *obj, int o break; } } - if (neg) + if (neg) { xi = -xi; + xf = -xf; + } if (unlikely(overflownInteger)) { if (overflownUnsignedInteger) { - obj->initError(); + obj->initReal(xf); } else { obj->initUint(xui); } --- a/poppler/PDFDoc.cc 2011-08-29 22:20:01.000000000 +0200 +++ b/poppler/PDFDoc.cc 2012-02-29 18:16:00.000000000 +0100 @@ -26,7 +26,7 @@ // Copyright (C) 2010 Ilya Gorenbein <igorenbein@finjan.com> // Copyright (C) 2010 Srinivas Adicherla <srinivas.adicherla@geodesic.com> // Copyright (C) 2010 Philip Lorenz <lorenzph+freedesktop@gmail.com> -// Copyright (C) 2011 Thomas Freitag <Thomas.Freitag@alfa.de> +// Copyright (C) 2011, 2012 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 @@ -707,35 +707,44 @@ int PDFDoc::saveAs(GooString *name, PDFW int PDFDoc::saveAs(OutStream *outStr, PDFWriteMode mode) { - // we don't support files with Encrypt at the moment + // find if we have updated objects + GBool updated = gFalse; + for(int i=0; i<xref->getNumObjects(); i++) { + if (xref->getEntry(i)->updated) { + updated = gTrue; + break; + } + } + + // we don't support rewriting files with Encrypt at the moment Object obj; xref->getTrailerDict()->getDict()->lookupNF("Encrypt", &obj); if (!obj.isNull()) { obj.free(); - return errEncrypted; + if (!updated && mode == writeStandard) { + // simply copy the original file + saveWithoutChangesAs (outStr); + } else { + return errEncrypted; + } } - obj.free(); + else + { + obj.free(); - if (mode == writeForceRewrite) { - saveCompleteRewrite(outStr); - } else if (mode == writeForceIncremental) { - saveIncrementalUpdate(outStr); - } else { // let poppler decide - // find if we have updated objects - GBool updated = gFalse; - for(int i=0; i<xref->getNumObjects(); i++) { - if (xref->getEntry(i)->updated) { - updated = gTrue; - break; + if (mode == writeForceRewrite) { + saveCompleteRewrite(outStr); + } else if (mode == writeForceIncremental) { + saveIncrementalUpdate(outStr); + } else { // let poppler decide + if(updated) { + saveIncrementalUpdate(outStr); + } else { + // simply copy the original file + saveWithoutChangesAs (outStr); } } - if(updated) { - saveIncrementalUpdate(outStr); - } else { - // simply copy the original file - saveWithoutChangesAs (outStr); - } } return errNone; @@ -1225,6 +1234,8 @@ void PDFDoc::markObject (Object* obj, XR } else { XRefEntry *entry = countRef->getEntry(obj->getRef().num + numOffset); entry->gen++; + if (entry->gen > 9) + break; } Object obj1; getXRef()->fetch(obj->getRef().num, obj->getRef().gen, &obj1); --- a/poppler/PSOutputDev.cc 2011-08-21 23:22:54.000000000 +0200 +++ b/poppler/PSOutputDev.cc 2012-02-29 18:16:00.000000000 +0100 @@ -15,7 +15,7 @@ // // Copyright (C) 2005 Martin Kretzschmar <martink@gnome.org> // Copyright (C) 2005, 2006 Kristian Høgsberg <krh@redhat.com> -// Copyright (C) 2006-2009 Albert Astals Cid <aacid@kde.org> +// Copyright (C) 2006-2009, 2011 Albert Astals Cid <aacid@kde.org> // Copyright (C) 2006 Jeff Muizelaar <jeff@infidigm.net> // Copyright (C) 2007, 2008 Brad Hards <bradh@kde.org> // Copyright (C) 2008, 2009 Koji Otani <sho@bbr.jp> @@ -1315,7 +1315,7 @@ void PSOutputDev::writeHeader(int firstP writePS("%!PS-Adobe-3.0 Resource-Form\n"); break; } - writePSFmt("% Produced by poppler pdftops version: {0:s} (http://poppler.freedesktop.org)\n", PACKAGE_VERSION); + writePSFmt("%Produced by poppler pdftops version: {0:s} (http://poppler.freedesktop.org)\n", PACKAGE_VERSION); xref->getDocInfo(&info); if (info.isDict() && info.dictLookup("Creator", &obj1)->isString()) { writePS("%%Creator: "); @@ -4080,7 +4080,6 @@ GBool PSOutputDev::tilingPatternFillL2(G double xStep, double yStep) { PDFRectangle box; Gfx *gfx; - double cxMin, cyMin, cxMax, cyMax; writePS("<<\n /PatternType 1\n"); writePSFmt(" /PaintType {0:d}\n", paintType); @@ -4100,10 +4099,9 @@ GBool PSOutputDev::tilingPatternFillL2(G delete gfx; writePS(" }\n"); writePS(">>\n"); - writePSFmt("[{0:.6g} {1:.6g} {2:.6g} {3:.6g} {4:.6g} {5:.6g}]\n", pmat[0], pmat[1], pmat[2], pmat[3], pmat[4], pmat[5]); + writePSFmt("[{0:.6g} {1:.6g} {2:.6g} {3:.6g} {4:.6g} {5:.6g}]\n", mat[0], mat[1], mat[2], mat[3], mat[4], mat[5]); writePS("makepattern setpattern\n"); - state->getClipBBox(&cxMin, &cyMin, &cxMax, &cyMax); - writePSFmt("{0:.6g} {1:.6g} {2:.6g} {3:.6g} rectfill\n", cxMin, cyMin, cxMax - cxMin, cyMax - cyMin); + writePS("clippath fill\n"); // Gfx sets up a clip before calling out->tilingPatternFill() return gTrue; } @@ -4113,8 +4111,28 @@ GBool PSOutputDev::tilingPatternFill(Gfx double *mat, double *bbox, int x0, int y0, int x1, int y1, double xStep, double yStep) { - if (x1 - x0 == 1 && y1 - y0 == 1) - return gFalse; // Don't need to use patterns if only one instance of the pattern is used + if (x1 - x0 == 1 && y1 - y0 == 1) { + // Don't need to use patterns if only one instance of the pattern is used + PDFRectangle box; + Gfx *gfx; + double x, y, tx, ty; + + x = x0 * xStep; + y = y0 * yStep; + tx = x * mat[0] + y * mat[2] + mat[4]; + ty = x * mat[1] + y * mat[3] + mat[5]; + box.x1 = bbox[0]; + box.y1 = bbox[1]; + box.x2 = bbox[2]; + box.y2 = bbox[3]; + gfx = new Gfx(xref, this, resDict, m_catalog, &box, NULL); + writePSFmt("[{0:.6g} {1:.6g} {2:.6g} {3:.6g} {4:.6g} {5:.6g}] cm\n", mat[0], mat[1], mat[2], mat[3], tx, ty); + inType3Char = gTrue; + gfx->display(str); + inType3Char = gFalse; + delete gfx; + return gTrue; + } if (level == psLevel1 || level == psLevel1Sep) { return tilingPatternFillL1(state, cat, str, pmat, paintType, tilingType, resDict, --- a/splash/SplashXPath.cc 2011-06-30 23:41:10.000000000 +0200 +++ b/splash/SplashXPath.cc 2012-02-29 18:16:00.000000000 +0100 @@ -281,9 +281,9 @@ void SplashXPath::addCurve(SplashCoord x SplashCoord x3, SplashCoord y3, SplashCoord flatness, GBool first, GBool last, GBool end0, GBool end1) { - SplashCoord cx[splashMaxCurveSplits + 1][3]; - SplashCoord cy[splashMaxCurveSplits + 1][3]; - int cNext[splashMaxCurveSplits + 1]; + SplashCoord *cx = new SplashCoord[(splashMaxCurveSplits + 1) * 3]; + SplashCoord *cy = new SplashCoord[(splashMaxCurveSplits + 1) * 3]; + int *cNext = new int[splashMaxCurveSplits + 1]; SplashCoord xl0, xl1, xl2, xr0, xr1, xr2, xr3, xx1, xx2, xh; SplashCoord yl0, yl1, yl2, yr0, yr1, yr2, yr3, yy1, yy2, yh; SplashCoord dx, dy, mx, my, d1, d2, flatness2; @@ -294,20 +294,34 @@ void SplashXPath::addCurve(SplashCoord x // initial segment p1 = 0; p2 = splashMaxCurveSplits; - cx[p1][0] = x0; cy[p1][0] = y0; - cx[p1][1] = x1; cy[p1][1] = y1; - cx[p1][2] = x2; cy[p1][2] = y2; - cx[p2][0] = x3; cy[p2][0] = y3; - cNext[p1] = p2; + + *(cx + p1 * 3 + 0) = x0; + *(cx + p1 * 3 + 1) = x1; + *(cx + p1 * 3 + 2) = x2; + *(cx + p2 * 3 + 0) = x3; + + *(cy + p1 * 3 + 0) = y0; + *(cy + p1 * 3 + 1) = y1; + *(cy + p1 * 3 + 2) = y2; + *(cy + p2 * 3 + 0) = y3; + + *(cNext + p1) = p2; while (p1 < splashMaxCurveSplits) { // get the next segment - xl0 = cx[p1][0]; yl0 = cy[p1][0]; - xx1 = cx[p1][1]; yy1 = cy[p1][1]; - xx2 = cx[p1][2]; yy2 = cy[p1][2]; - p2 = cNext[p1]; - xr3 = cx[p2][0]; yr3 = cy[p2][0]; + xl0 = *(cx + p1 * 3 + 0); + xx1 = *(cx + p1 * 3 + 1); + xx2 = *(cx + p1 * 3 + 2); + + yl0 = *(cy + p1 * 3 + 0); + yy1 = *(cy + p1 * 3 + 1); + yy2 = *(cy + p1 * 3 + 2); + + p2 = *(cNext + p1); + + xr3 = *(cx + p2 * 3 + 0); + yr3 = *(cy + p2 * 3 + 0); // compute the distances from the control points to the // midpoint of the straight line (this is a bit of a hack, but @@ -348,15 +362,30 @@ void SplashXPath::addCurve(SplashCoord x yr0 = (yl2 + yr1) * 0.5; // add the new subdivision points p3 = (p1 + p2) / 2; - cx[p1][1] = xl1; cy[p1][1] = yl1; - cx[p1][2] = xl2; cy[p1][2] = yl2; - cNext[p1] = p3; - cx[p3][0] = xr0; cy[p3][0] = yr0; - cx[p3][1] = xr1; cy[p3][1] = yr1; - cx[p3][2] = xr2; cy[p3][2] = yr2; - cNext[p3] = p2; + + *(cx + p1 * 3 + 1) = xl1; + *(cx + p1 * 3 + 2) = xl2; + + *(cy + p1 * 3 + 1) = yl1; + *(cy + p1 * 3 + 2) = yl2; + + *(cNext + p1) = p3; + + *(cx + p3 * 3 + 0) = xr0; + *(cx + p3 * 3 + 1) = xr1; + *(cx + p3 * 3 + 2) = xr2; + + *(cy + p3 * 3 + 0) = yr0; + *(cy + p3 * 3 + 1) = yr1; + *(cy + p3 * 3 + 2) = yr2; + + *(cNext + p3) = p2; } } + + delete [] cx; + delete [] cy; + delete [] cNext; } void SplashXPath::addSegment(SplashCoord x0, SplashCoord y0, --- a/utils/HtmlOutputDev.cc 2011-09-26 15:49:55.000000000 +0200 +++ b/utils/HtmlOutputDev.cc 2012-02-29 18:16:00.000000000 +0100 @@ -17,7 +17,7 @@ // All changes made under the Poppler project to this file are licensed // under GPL version 2 or later // -// Copyright (C) 2005-2011 Albert Astals Cid <aacid@kde.org> +// Copyright (C) 2005-2012 Albert Astals Cid <aacid@kde.org> // Copyright (C) 2008 Kjartan Maraas <kmaraas@gnome.org> // Copyright (C) 2008 Boris Toloknov <tlknv@yandex.ru> // Copyright (C) 2008 Haruyuki Kawabe <Haruyuki.Kawabe@unisys.co.jp> @@ -30,6 +30,7 @@ // Copyright (C) 2010 OSSD CDAC Mumbai by Leena Chourey (leenac@cdacmumbai.in) and Onkar Potdar (onkar@cdacmumbai.in) // Copyright (C) 2011 Joshua Richardson <jric@chegg.com> // Copyright (C) 2011 Stephen Reichling <sreichling@chegg.com> +// Copyright (C) 2012 Igor Slepchin <igor.redhat@gmail.com> // // 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 @@ -61,6 +62,8 @@ #include "HtmlOutputDev.h" #include "HtmlFonts.h" #include "HtmlUtils.h" +#include "Outline.h" +#include "PDFDoc.h" #define DEBUG __FILE__ << ": " << __LINE__ << ": DEBUG: " @@ -739,7 +742,6 @@ void HtmlPage::dumpAsXML(FILE* f,int pag int HtmlPage::dumpComplexHeaders(FILE * const file, FILE *& pageFile, int page) { GooString* tmp; - char* htmlEncoding; if( !noframes ) { @@ -766,11 +768,12 @@ int HtmlPage::dumpComplexHeaders(FILE * delete tmp; - htmlEncoding = HtmlOutputDev::mapEncodingToHtml(globalParams->getTextEncodingName()); + GooString *htmlEncoding = HtmlOutputDev::mapEncodingToHtml(globalParams->getTextEncodingName()); if (!singleHtml) - fprintf(pageFile, "<META http-equiv=\"Content-Type\" content=\"text/html; charset=%s\"/>\n", htmlEncoding); + fprintf(pageFile, "<META http-equiv=\"Content-Type\" content=\"text/html; charset=%s\"/>\n", htmlEncoding->getCString()); else - fprintf(pageFile, "<META http-equiv=\"Content-Type\" content=\"text/html; charset=%s\"/>\n <br/>\n", htmlEncoding); + fprintf(pageFile, "<META http-equiv=\"Content-Type\" content=\"text/html; charset=%s\"/>\n <br/>\n", htmlEncoding->getCString()); + delete htmlEncoding; } else { @@ -956,23 +959,23 @@ static char* HtmlEncodings[][2] = { {NULL, NULL} }; - -char* HtmlOutputDev::mapEncodingToHtml(GooString* encoding) +GooString* HtmlOutputDev::mapEncodingToHtml(GooString* encoding) { - char* enc = encoding->getCString(); - for(int i = 0; HtmlEncodings[i][0] != NULL; i++) + GooString* enc = encoding; + for(int i = 0; HtmlEncodings[i][0] != NULL; i++) + { + if( enc->cmp(HtmlEncodings[i][0]) == 0 ) { - if( strcmp(enc, HtmlEncodings[i][0]) == 0 ) - { - return HtmlEncodings[i][1]; - } + delete enc; + return new GooString(HtmlEncodings[i][1]); } - return enc; + } + return enc; } void HtmlOutputDev::doFrame(int firstPage){ GooString* fName=new GooString(Docname); - char* htmlEncoding; + GooString* htmlEncoding; fName->append(".html"); if (!(fContentsFrame = fopen(fName->getCString(), "w"))){ @@ -989,7 +992,7 @@ void HtmlOutputDev::doFrame(int firstPag fputs("\n<HEAD>",fContentsFrame); fprintf(fContentsFrame,"\n<TITLE>%s</TITLE>",docTitle->getCString()); htmlEncoding = mapEncodingToHtml(globalParams->getTextEncodingName()); - fprintf(fContentsFrame, "\n<META http-equiv=\"Content-Type\" content=\"text/html; charset=%s\"/>\n", htmlEncoding); + fprintf(fContentsFrame, "\n<META http-equiv=\"Content-Type\" content=\"text/html; charset=%s\"/>\n", htmlEncoding->getCString()); dumpMetaVars(fContentsFrame); fprintf(fContentsFrame, "</HEAD>\n"); fputs("<FRAMESET cols=\"100,*\">\n",fContentsFrame); @@ -1003,6 +1006,7 @@ void HtmlOutputDev::doFrame(int firstPag fputs(">\n</FRAMESET>\n</HTML>\n",fContentsFrame); delete fName; + delete htmlEncoding; fclose(fContentsFrame); } @@ -1011,8 +1015,6 @@ HtmlOutputDev::HtmlOutputDev(char *fileN char *extension, GBool rawOrder, int firstPage, GBool outline) { - char *htmlEncoding; - fContentsFrame = NULL; docTitle = new GooString(title); pages = NULL; @@ -1099,10 +1101,10 @@ HtmlOutputDev::HtmlOutputDev(char *fileN delete right; } - htmlEncoding = mapEncodingToHtml(globalParams->getTextEncodingName()); + GooString *htmlEncoding = mapEncodingToHtml(globalParams->getTextEncodingName()); if (xml) { - fprintf(page, "<?xml version=\"1.0\" encoding=\"%s\"?>\n", htmlEncoding); + fprintf(page, "<?xml version=\"1.0\" encoding=\"%s\"?>\n", htmlEncoding->getCString()); fputs("<!DOCTYPE pdf2xml SYSTEM \"pdf2xml.dtd\">\n\n", page); fputs("<pdf2xml>\n",page); } @@ -1110,12 +1112,13 @@ HtmlOutputDev::HtmlOutputDev(char *fileN { fprintf(page,"%s\n<HTML xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"\" xml:lang=\"\">\n<HEAD>\n<TITLE>%s</TITLE>\n", DOCTYPE, docTitle->getCString()); - fprintf(page, "<META http-equiv=\"Content-Type\" content=\"text/html; charset=%s\"/>\n", htmlEncoding); + fprintf(page, "<META http-equiv=\"Content-Type\" content=\"text/html; charset=%s\"/>\n", htmlEncoding->getCString()); dumpMetaVars(page); fprintf(page,"</HEAD>\n"); fprintf(page,"<BODY bgcolor=\"#A0A0A0\" vlink=\"blue\" link=\"blue\">\n"); } + delete htmlEncoding; } ok = gTrue; } @@ -1551,17 +1554,25 @@ void HtmlOutputDev::dumpMetaVars(FILE *f } } -GBool HtmlOutputDev::dumpDocOutline(Catalog* catalog) +GBool HtmlOutputDev::dumpDocOutline(PDFDoc* doc) { +#ifdef DISABLE_OUTLINE + return gFalse; +#else FILE * output = NULL; GBool bClose = gFalse; + Catalog *catalog = doc->getCatalog(); if (!ok || xml) - return gFalse; + return gFalse; - Object *outlines = catalog->getOutline(); - if (!outlines->isDict()) - return gFalse; + Outline *outline = doc->getOutline(); + if (!outline) + return gFalse; + + GooList *outlines = outline->getItems(); + if (!outlines) + return gFalse; if (!complexMode && !xml) { @@ -1583,7 +1594,18 @@ GBool HtmlOutputDev::dumpDocOutline(Cata return gFalse; delete str; bClose = gTrue; - fputs("<HTML xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"\" xml:lang=\"\">\n<HEAD>\n<TITLE>Document Outline</TITLE>\n</HEAD>\n<BODY>\n", output); + + GooString *htmlEncoding = + HtmlOutputDev::mapEncodingToHtml(globalParams->getTextEncodingName()); + + fprintf(output, "<HTML xmlns=\"http://www.w3.org/1999/xhtml\" " \ + "lang=\"\" xml:lang=\"\">\n" \ + "<HEAD>\n" \ + "<TITLE>Document Outline</TITLE>\n" \ + "<META http-equiv=\"Content-Type\" content=\"text/html; " \ + "charset=%s\"/>\n" \ + "</HEAD>\n<BODY>\n", htmlEncoding->getCString()); + delete htmlEncoding; } } @@ -1597,97 +1619,95 @@ GBool HtmlOutputDev::dumpDocOutline(Cata fclose(output); } return done; +#endif } -GBool HtmlOutputDev::newOutlineLevel(FILE *output, Object *node, Catalog* catalog, int level) +GBool HtmlOutputDev::newOutlineLevel(FILE *output, GooList *outlines, Catalog* catalog, int level) { - Object curr, next; - GBool atLeastOne = gFalse; - - if (node->dictLookup("First", &curr)->isDict()) { - if (level == 1) + GBool atLeastOne = gFalse; + + if (level == 1) { fputs("<A name=\"outline\"></a>", output); fputs("<h1>Document Outline</h1>\n", output); } - fputs("<ul>",output); - do { - // get title, give up if not found - Object title; - if (curr.dictLookup("Title", &title)->isNull()) { - title.free(); - break; - } - GooString *titleStr = new GooString(title.getString()); - title.free(); + fputs("<ul>\n",output); - // get corresponding link - // Note: some code duplicated from HtmlOutputDev::getLinkDest(). - GooString *linkName = NULL;; - Object dest; - if (!curr.dictLookup("Dest", &dest)->isNull()) { - LinkGoTo *link = new LinkGoTo(&dest); - LinkDest *linkdest=NULL; - if (link->getDest()!=NULL) - linkdest=link->getDest()->copy(); - else if (link->getNamedDest()!=NULL) - linkdest=catalog->findDest(link->getNamedDest()); - - delete link; - if (linkdest) { - int page; - if (linkdest->isPageRef()) { - Ref pageref=linkdest->getPageRef(); - page=catalog->findPage(pageref.num,pageref.gen); - } else { - page=linkdest->getPageNum(); - } - delete linkdest; - - /* complex simple - frames file-4.html files.html#4 - noframes file.html#4 file.html#4 - */ - linkName=basename(Docname); - GooString *str=GooString::fromInt(page); - if (noframes) { - linkName->append(".html#"); - linkName->append(str); - } else { - if( complexMode ) { - linkName->append("-"); - linkName->append(str); - linkName->append(".html"); - } else { - linkName->append("s.html#"); - linkName->append(str); - } - } - delete str; + for (int i = 0; i < outlines->getLength(); i++) + { + OutlineItem *item = (OutlineItem*)outlines->get(i); + GooString *titleStr = HtmlFont::HtmlFilter(item->getTitle(), + item->getTitleLength()); + + // get corresponding link + GooString *linkName = NULL;; + LinkAction *action = item->getAction(); + LinkGoTo *link = NULL; + Object dest; + if (action && action->getKind() == actionGoTo) + link = dynamic_cast<LinkGoTo*>(action); + if (link && link->isOk()) { + LinkDest *linkdest=NULL; + if (link->getDest()!=NULL) + linkdest=link->getDest()->copy(); + else if (link->getNamedDest()!=NULL) + linkdest=catalog->findDest(link->getNamedDest()); + + if (linkdest) { + int page; + if (linkdest->isPageRef()) { + Ref pageref=linkdest->getPageRef(); + page=catalog->findPage(pageref.num,pageref.gen); + } else { + page=linkdest->getPageNum(); + } + delete linkdest; + + /* complex simple + frames file-4.html files.html#4 + noframes file.html#4 file.html#4 + */ + linkName=basename(Docname); + GooString *str=GooString::fromInt(page); + if (noframes) { + linkName->append(".html#"); + linkName->append(str); + } else { + if( complexMode ) { + linkName->append("-"); + linkName->append(str); + linkName->append(".html"); + } else { + linkName->append("s.html#"); + linkName->append(str); + } + } + delete str; + } } - } - dest.free(); + dest.free(); - fputs("<li>",output); - if (linkName) - fprintf(output,"<A href=\"%s\">", linkName->getCString()); - fputs(titleStr->getCString(),output); - if (linkName) { - fputs("</A>",output); - delete linkName; - } - fputs("\n",output); - delete titleStr; - atLeastOne = gTrue; - - newOutlineLevel(output, &curr, catalog, level+1); - curr.dictLookup("Next", &next); - curr.free(); - curr = next; - } while(curr.isDict()); - fputs("</ul>",output); - } - curr.free(); + fputs("<li>",output); + if (linkName) + fprintf(output,"<A href=\"%s\">", linkName->getCString()); + fputs(titleStr->getCString(),output); + if (linkName) { + fputs("</A>",output); + delete linkName; + } + delete titleStr; + atLeastOne = gTrue; + + item->open(); + if (item->hasKids()) + { + fputs("\n",output); + newOutlineLevel(output, item->getKids(), catalog, level+1); + } + item->close(); + fputs("</li>\n",output); + } + fputs("</ul>\n",output); - return atLeastOne; + return atLeastOne; } --- a/utils/HtmlOutputDev.h 2011-08-18 18:11:13.000000000 +0200 +++ b/utils/HtmlOutputDev.h 2012-02-29 18:16:00.000000000 +0100 @@ -14,13 +14,14 @@ // All changes made under the Poppler project to this file are licensed // under GPL version 2 or later // -// Copyright (C) 2006, 2007, 2009 Albert Astals Cid <aacid@kde.org> +// Copyright (C) 2006, 2007, 2009, 2012 Albert Astals Cid <aacid@kde.org> // Copyright (C) 2008, 2009 Warren Toomey <wkt@tuhs.org> // Copyright (C) 2009, 2011 Carlos Garcia Campos <carlosgc@gnome.org> // Copyright (C) 2009 Kovid Goyal <kovid@kovidgoyal.net> // Copyright (C) 2010 Hib Eris <hib@hiberis.nl> // Copyright (C) 2011 Joshua Richardson <jric@chegg.com> // Copyright (C) 2011 Stephen Reichling <sreichling@chegg.com> +// Copyright (C) 2012 Igor Slepchin <igor.redhat@gmail.com> // // 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,7 @@ class GfxState; class GooString; +class PDFDoc; //------------------------------------------------------------------------ // HtmlString //------------------------------------------------------------------------ @@ -298,17 +300,18 @@ public: int getPageWidth() { return maxPageWidth; } int getPageHeight() { return maxPageHeight; } - GBool dumpDocOutline(Catalog* catalog); + GBool dumpDocOutline(PDFDoc* catalog); private: // convert encoding into a HTML standard, or encoding->getCString if not - // recognized - static char* mapEncodingToHtml(GooString* encoding); + // recognized. Will delete encoding for you and return a new one + // that you have to delete + static GooString* mapEncodingToHtml(GooString* encoding); void doProcessLink(AnnotLink *link); GooString* getLinkDest(AnnotLink *link,Catalog *catalog); void dumpMetaVars(FILE *); void doFrame(int firstPage); - GBool newOutlineLevel(FILE *output, Object *node, Catalog* catalog, int level = 1); + GBool newOutlineLevel(FILE *output, GooList *outlines, Catalog* catalog, int level = 1); FILE *fContentsFrame; FILE *page; // html file --- a/utils/parseargs.cc 2011-01-15 12:43:25.000000000 +0100 +++ b/utils/parseargs.cc 2012-02-29 18:16:00.000000000 +0100 @@ -30,6 +30,7 @@ #include "parseargs.h" #include "goo/gstrtod.h" +#include "goo/GooString.h" static const ArgDesc *findArg(const ArgDesc *args, char *arg); static GBool grabArg(const ArgDesc *arg, int i, int *argc, char *argv[]); @@ -87,6 +88,7 @@ void printUsage(char *program, char *oth break; case argString: case argStringDummy: + case argGooString: typ = " <string>"; break; case argFlag: @@ -149,6 +151,15 @@ static GBool grabArg(const ArgDesc *arg, n = 2; } else { ok = gFalse; + n = 1; + } + break; + case argGooString: + if (i + 1 < *argc) { + ((GooString*)arg->val)->Set(argv[i+1]); + n = 2; + } else { + ok = gFalse; n = 1; } break; --- a/utils/parseargs.h 2009-10-09 00:26:36.000000000 +0200 +++ b/utils/parseargs.h 2012-02-29 18:16:00.000000000 +0100 @@ -41,6 +41,8 @@ typedef enum { /* [val: double *] */ argString, /* string arg */ /* [val: char *] */ + argGooString, /* string arg */ + /* [val: GooString *] */ /* dummy entries -- these show up in the usage listing only; */ /* useful for X args, for example */ argFlagDummy, --- a/utils/pdfseparate.cc 2011-09-27 00:08:36.000000000 +0200 +++ b/utils/pdfseparate.cc 2012-02-29 18:16:00.000000000 +0100 @@ -4,7 +4,7 @@ // // This file is licensed under the GPLv2 or later // -// Copyright (C) 2011 Thomas Freitag <Thomas.Freitag@alfa.de> +// Copyright (C) 2011, 2012 Thomas Freitag <Thomas.Freitag@alfa.de> // //======================================================================== #include "config.h" @@ -17,6 +17,7 @@ #include "goo/GooString.h" #include "PDFDoc.h" #include "ErrorCodes.h" +#include "GlobalParams.h" static int firstPage = 0; static int lastPage = 0; @@ -107,7 +108,9 @@ main (int argc, char *argv[]) exitCode = 0; goto err0; } + globalParams = new GlobalParams(); extractPages (argv[1], argv[2]); + delete globalParams; err0: --- a/utils/pdftocairo.cc 2011-08-21 23:39:36.000000000 +0200 +++ b/utils/pdftocairo.cc 2012-02-29 18:16:00.000000000 +0100 @@ -32,7 +32,6 @@ #include "config.h" #include <poppler-config.h> -#include <sys/param.h> // for MAXPATHLEN #include <stdio.h> #include <math.h> #include <string.h> @@ -91,7 +90,7 @@ static GBool useCropBox = gFalse; static GBool mono = gFalse; static GBool gray = gFalse; static GBool transp = gFalse; -static char icc[MAXPATHLEN] = ""; +static GooString icc; static GBool level2 = gFalse; static GBool level3 = gFalse; @@ -179,7 +178,7 @@ static const ArgDesc argDesc[] = { {"-transp", argFlag, &transp, 0, "use a transparent background instead of white (PNG)"}, #if USE_CMS - {"-icc", argString, &icc, sizeof(icc), + {"-icc", argGooString, &icc, 0, "ICC color profile to use"}, #endif @@ -336,6 +335,8 @@ void writePageImage(GooString *filename) gfree(row); writer->close(); delete writer; + if (file == stdout) fflush(file); + else fclose(file); } static void getCropSize(double page_w, double page_h, double *width, double *height) @@ -754,7 +755,7 @@ int main(int argc, char *argv[]) { checkInvalidPrintOption(mono, "-mono"); checkInvalidPrintOption(gray, "-gray"); checkInvalidPrintOption(transp, "-transp"); - checkInvalidPrintOption(icc[0], "-icc"); + checkInvalidPrintOption(icc.getCString()[0], "-icc"); checkInvalidPrintOption(singleFile, "-singlefile"); } else { checkInvalidImageOption(level2, "-level2"); @@ -770,7 +771,7 @@ int main(int argc, char *argv[]) { checkInvalidImageOption(duplex, "-duplex"); } - if (icc[0] && !png) { + if (icc.getCString()[0] && !png) { fprintf(stderr, "Error: -icc may only be used with png output.\n"); exit(99); } @@ -840,10 +841,10 @@ int main(int argc, char *argv[]) { #if USE_CMS icc_data = NULL; - if (icc[0]) { - FILE *file = fopen(icc, "rb"); + if (icc.getCString()[0]) { + FILE *file = fopen(icc.getCString(), "rb"); if (!file) { - fprintf(stderr, "Error: unable to open icc profile %s\n", icc); + fprintf(stderr, "Error: unable to open icc profile %s\n", icc.getCString()); exit(4); } fseek (file, 0, SEEK_END); @@ -851,7 +852,7 @@ int main(int argc, char *argv[]) { fseek (file, 0, SEEK_SET); icc_data = (unsigned char*)gmalloc(icc_data_size); if (fread(icc_data, icc_data_size, 1, file) != 1) { - fprintf(stderr, "Error: unable to read icc profile %s\n", icc); + fprintf(stderr, "Error: unable to read icc profile %s\n", icc.getCString()); exit(4); } fclose(file); @@ -902,6 +903,10 @@ int main(int argc, char *argv[]) { lastPage = firstPage; } + // Make sure firstPage is always used so that beginDocument() is called + if ((printOnlyEven && firstPage % 2 == 0) || (printOnlyOdd && firstPage % 2 == 1)) + firstPage++; + cairoOut = new CairoOutputDev(); cairoOut->startDoc(doc->getXRef(), doc->getCatalog()); if (sz != 0) --- a/utils/pdftohtml.cc 2011-08-18 18:25:53.000000000 +0200 +++ b/utils/pdftohtml.cc 2012-02-29 18:16:00.000000000 +0100 @@ -13,12 +13,13 @@ // All changes made under the Poppler project to this file are licensed // under GPL version 2 or later // -// Copyright (C) 2007-2008, 2010 Albert Astals Cid <aacid@kde.org> +// Copyright (C) 2007-2008, 2010, 2012 Albert Astals Cid <aacid@kde.org> // Copyright (C) 2010 Hib Eris <hib@hiberis.nl> // Copyright (C) 2010 Mike Slegeir <tehpola@yahoo.com> // Copyright (C) 2010 Suzuki Toshiya <mpsuzuki@hiroshima-u.ac.jp> // Copyright (C) 2010 OSSD CDAC Mumbai by Leena Chourey (leenac@cdacmumbai.in) and Onkar Potdar (onkar@cdacmumbai.in) // Copyright (C) 2011 Steven Murdoch <Steven.Murdoch@cl.cam.ac.uk> +// Copyright (C) 2012 Igor Slepchin <igor.redhat@gmail.com> // // 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 @@ -404,7 +405,7 @@ int main(int argc, char *argv[]) { gTrue, gFalse, gFalse); if (!xml) { - htmlOut->dumpDocOutline(doc->getCatalog()); + htmlOut->dumpDocOutline(doc); } } @@ -527,7 +528,6 @@ static GooString* getInfoString(Dict *in rawString = obj.getString(); // Convert rawString to unicode - encodedString = new GooString(); if (rawString->hasUnicodeMarker()) { isUnicode = gTrue; unicodeLength = (obj.getString()->getLength() - 2) / 2; --- a/utils/pdfunite.cc 2011-09-27 00:06:17.000000000 +0200 +++ b/utils/pdfunite.cc 2012-02-29 18:16:00.000000000 +0100 @@ -5,9 +5,11 @@ // This file is licensed under the GPLv2 or later // // Copyright (C) 2011 Thomas Freitag <Thomas.Freitag@alfa.de> +// Copyright (C) 2012 Arseny Solokha <asolokha@gmx.com> // //======================================================================== #include <PDFDoc.h> +#include <GlobalParams.h> #include "parseargs.h" #include "config.h" #include <poppler-config.h> @@ -66,6 +68,7 @@ int main (int argc, char *argv[]) return exitCode; } exitCode = 0; + globalParams = new GlobalParams(); for (i = 1; i < argc - 1; i++) { GooString *gfileName = new GooString(argv[i]); @@ -172,5 +175,6 @@ int main (int argc, char *argv[]) delete countRef; for (j = 0; j < (int) pages.size (); j++) pages[j].free(); for (i = 0; i < (int) docs.size (); i++) delete docs[i]; + delete globalParams; return exitCode; }