From lrosenth at adobe.com Thu Apr 1 05:22:42 2010 From: lrosenth at adobe.com (Leonard Rosenthol) Date: Thu, 1 Apr 2010 05:22:42 -0700 Subject: [poppler] PDF/a validator with poppler In-Reply-To: <201004011749.20282.bradh@frogmouth.net> References: <201004011749.20282.bradh@frogmouth.net> Message-ID: A LOT of work and access to the lowest level APIs, which Poppler tries to keep private. So something like PoDoFo may be better suited, though Poppler's content parser would make it easier (though someone did a prototype of one with PoDoFo and it could use some loving care). Leonard -----Original Message----- From: poppler-bounces at lists.freedesktop.org [mailto:poppler-bounces at lists.freedesktop.org] On Behalf Of Brad Hards Sent: Thursday, April 01, 2010 2:49 AM To: poppler at lists.freedesktop.org Subject: Re: [poppler] PDF/a validator with poppler On Thursday 01 April 2010 02:29:51 am Johnny Mari?thoz wrote: > Hello, > > do you know if it is possible to create a pdf/a validator using poppler? I'm sure it is possible, but I think it would be quite a lot of work. Perhaps something like podofo would probably be an easier place to start? Brad _______________________________________________ poppler mailing list poppler at lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/poppler From erik at forcheck.nl Fri Apr 2 05:17:34 2010 From: erik at forcheck.nl (Erik Kruyt) Date: Fri, 2 Apr 2010 14:17:34 +0200 Subject: [poppler] libpoppler-qt4.dll Message-ID: <000501cad25e$799706a0$6cc513e0$@nl> I try to get poppler-qt4 running on Windows XP. I downloaded the mingw kit from sourceforge.net. However, the kit contains libpoppler-qt4.dll.a which is the import lib but not the dll! So I can compile and build but not run. Moreover I cannot link statically. Does anyone know where I can find the libpoppler-qt4.dll and the full lib? Thanks, Erik -------------- next part -------------- An HTML attachment was scrubbed... URL: From fr33g at web.de Fri Apr 2 08:09:51 2010 From: fr33g at web.de (Ingo Glaser) Date: Fri, 2 Apr 2010 17:09:51 +0200 (CEST) Subject: [poppler] Poppler on Windows 7 Message-ID: <3092055.83403.1270220991140.JavaMail.fmail@mwmweb049> An HTML attachment was scrubbed... URL: From erik at forcheck.nl Fri Apr 2 08:38:10 2010 From: erik at forcheck.nl (Erik Kruyt) Date: Fri, 2 Apr 2010 17:38:10 +0200 Subject: [poppler] Poppler on Windows 7 In-Reply-To: <3092055.83403.1270220991140.JavaMail.fmail@mwmweb049> References: <3092055.83403.1270220991140.JavaMail.fmail@mwmweb049> Message-ID: <000f01cad27a$7ff9f090$7fedd1b0$@nl> You can download the mingw kit from sourceforge.net. This kit contains poppler-qt4.h and libpoppler-qt4.dll.a which is the import lib but not the dll! So you can compile applications which use poppler-qt4 and build but not run. The dll should also have been placed in this kit! Can anyone provide this? Erik Forcheck b.v. Torenmolen 23 2317 NV Leiden Netherlands Van: poppler-bounces at lists.freedesktop.org [mailto:poppler-bounces at lists.freedesktop.org] Namens Ingo Glaser Verzonden: vrijdag 2 april 2010 17:10 Aan: poppler at lists.freedesktop.org Onderwerp: [poppler] Poppler on Windows 7 Hey people, I wanted to ask you like I Poppler on Windows to run agrees? I cannot simply compile it. I need Poppler in connection with Qt. Does somebody have an idea like me Poppler on Windows can compile? I have on my Pc MinGw and MySys on it, as well as Visual studio. Hope you Can help me Greeting freeG =) Hey people,I wanted to ask you like I Poppler on Windows to run agrees? I cannot simply compile it. I need Poppler in connection with Qt. Does somebody have an idea like me Poppler on Windows can compile? I have on my Pc MinGw and MySys on it, as well as Visual studio. Hope you Can help me, Greeting freeG =) Afbeelding verwijderd door afzender. NEU: WEB.DE DSL f?r 19,99 EUR/mtl. und ohne Mindest-Laufzeit! http://produkte.web.de/go/02/ -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: image/jpeg Size: 332 bytes Desc: not available URL: From fr33g at web.de Fri Apr 2 10:32:47 2010 From: fr33g at web.de (Ingo Glaser) Date: Fri, 2 Apr 2010 19:32:47 +0200 (CEST) Subject: [poppler] Poppler on Windows 7 Message-ID: <19335687.124409.1270229567758.JavaMail.fmail@mwmweb049> An HTML attachment was scrubbed... URL: From aacid at kde.org Sat Apr 3 04:51:07 2010 From: aacid at kde.org (Albert Astals Cid) Date: Sat, 3 Apr 2010 12:51:07 +0100 Subject: [poppler] libpoppler-qt4.dll In-Reply-To: <000501cad25e$799706a0$6cc513e0$@nl> References: <000501cad25e$799706a0$6cc513e0$@nl> Message-ID: <201004031251.07786.aacid@kde.org> A Divendres, 2 d'abril de 2010, Erik Kruyt va escriure: > I try to get poppler-qt4 running on Windows XP. > > I downloaded the mingw kit from sourceforge.net. However, the kit contains > libpoppler-qt4.dll.a which is the import lib but not the dll! So I can > compile and build but not run. Moreover I cannot link statically. > > Does anyone know where I can find the libpoppler-qt4.dll and the full lib? Any reason why you mailed us and not mingw people? Albert > > Thanks, > > Erik From aacid at kde.org Sat Apr 3 04:52:33 2010 From: aacid at kde.org (Albert Astals Cid) Date: Sat, 3 Apr 2010 12:52:33 +0100 Subject: [poppler] Poppler on Windows 7 In-Reply-To: <3092055.83403.1270220991140.JavaMail.fmail@mwmweb049> References: <3092055.83403.1270220991140.JavaMail.fmail@mwmweb049> Message-ID: <201004031252.33455.aacid@kde.org> A Divendres, 2 d'abril de 2010, Ingo Glaser va escriure: > Hey people, Hi, please never ever send HTML mail to the poppler mailing list. > I wanted to ask you like I Poppler on Windows to run agrees? Can't parse that sentence. > I cannot simply compile it. > I need Poppler in connection with Qt. > Does somebody have an idea like me Poppler on Windows can compile? Yes, poppler compiles on windows, go either the mingw way or the cmake way. Albert > I have on my Pc MinGw and MySys on it, as well as Visual studio. > Hope you Can help me > Greeting freeG =) From erik at forcheck.nl Sat Apr 3 05:07:28 2010 From: erik at forcheck.nl (Erik Kruyt) Date: Sat, 3 Apr 2010 14:07:28 +0200 Subject: [poppler] libpoppler-qt4.dll In-Reply-To: <201004031251.07786.aacid@kde.org> References: <000501cad25e$799706a0$6cc513e0$@nl> <201004031251.07786.aacid@kde.org> Message-ID: <001701cad326$3b4fbd60$b1ef3820$@nl> I am new in the field and found the poppler list. Thanks for your suggestion. I shall also contact the mingw people. Erik Forcheck b.v. Torenmolen 23 2317 NV Leiden Netherlands > -----Oorspronkelijk bericht----- > Van: poppler-bounces at lists.freedesktop.org [mailto:poppler- > bounces at lists.freedesktop.org] Namens Albert Astals Cid > Verzonden: zaterdag 3 april 2010 13:51 > Aan: poppler at lists.freedesktop.org > Onderwerp: Re: [poppler] libpoppler-qt4.dll > > A Divendres, 2 d'abril de 2010, Erik Kruyt va escriure: > > I try to get poppler-qt4 running on Windows XP. > > > > I downloaded the mingw kit from sourceforge.net. However, the kit > contains > > libpoppler-qt4.dll.a which is the import lib but not the dll! So I > can > > compile and build but not run. Moreover I cannot link statically. > > > > Does anyone know where I can find the libpoppler-qt4.dll and the full > lib? > > Any reason why you mailed us and not mingw people? > > Albert > > > > > Thanks, > > > > Erik > _______________________________________________ > poppler mailing list > poppler at lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/poppler From aacid at kde.org Sat Apr 3 14:54:56 2010 From: aacid at kde.org (Albert Astals Cid) Date: Sat, 3 Apr 2010 22:54:56 +0100 Subject: [poppler] Poppler on Windows 7 In-Reply-To: <23478759.359323.1270322689235.JavaMail.fmail@mwmweb050> References: <3092055.83403.1270220991140.JavaMail.fmail@mwmweb049> <201004031252.33455.aacid@kde.org> <23478759.359323.1270322689235.JavaMail.fmail@mwmweb050> Message-ID: <201004032254.56576.aacid@kde.org> A Dissabte, 3 d'abril de 2010, Ingo Glaser va escriure: > Hey many thanks for the answer. Hi, never mail me only, always mail the list too. > I try it with cmake, however, it does not > function. He always announces the mistake he does not find the > FREETYPE_INCLUDE_DIRS.What must I make then there? Get the freetype includes somewhere > Hope you can help me. No i can not, never compiled poppler on windows with cmake. > What I still wanted to ask how I can answer so that the answer is also > to be seen in the archive of the mailing list? You do not mail me directly, easy ;-) Albert > Many thanks Greeting freeG > -----Urspr?ngliche Nachricht----- > Von: Albert Astals Cid [ > Gesendet: 03.04.2010 13:52:33 > An: poppler at lists.freedesktop.org > Betreff: Re: [poppler] Poppler on Windows 7 > > >A Divendres, 2 d'abril de 2010, Ingo Glaser va escriure: > >> Hey people, > > > >Hi, please never ever send HTML mail to the poppler mailing list. > > > >> I wanted to ask you like I Poppler on Windows to run agrees? > > > >Can't parse that sentence. > > > >> I cannot simply compile it. > >> I need Poppler in connection with Qt. > >> Does somebody have an idea like me Poppler on Windows can compile? > > > >Yes, poppler compiles on windows, go either the mingw way or the cmake > >way. > > > >Albert > > > >> I have on my Pc MinGw and MySys on it, as well as Visual studio. > >> Hope you Can help me > >> Greeting freeG =) > > > >_______________________________________________ > >poppler mailing list > >poppler at lists.freedesktop.org > >http://lists.freedesktop.org/mailman/listinfo/poppler > > ___________________________________________________________ > GRATIS f?r alle WEB.DE-Nutzer: Die maxdome Movie-FLAT! > Jetzt freischalten unter http://movieflat.web.de From carlosgc at kemper.freedesktop.org Sun Apr 4 04:03:28 2010 From: carlosgc at kemper.freedesktop.org (Carlos Garcia Campos) Date: Sun, 4 Apr 2010 04:03:28 -0700 (PDT) Subject: [poppler] poppler/CairoOutputDev.cc Message-ID: <20100404110329.7C8D0C0001@kemper.freedesktop.org> poppler/CairoOutputDev.cc | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) New commits: commit a32f6f9ebaed3e4827b9dc6cb37e307c2798f521 Author: Carlos Garcia Campos Date: Sun Mar 28 18:43:14 2010 +0200 [cairo] Do not change device offset of mask surface Also call cairo_paint() after set_source_rgb() to paint the background. Fixes bug #27208. diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc index b066c9b..c433fdb 100644 --- a/poppler/CairoOutputDev.cc +++ b/poppler/CairoOutputDev.cc @@ -1263,19 +1263,12 @@ void CairoOutputDev::setSoftMask(GfxState * state, double * bbox, GBool alpha, colToDbl(backdropColorRGB.r), colToDbl(backdropColorRGB.g), colToDbl(backdropColorRGB.b)); - + cairo_paint(maskCtx); cairo_matrix_t mat; cairo_get_matrix(cairo, &mat); cairo_set_matrix(maskCtx, &mat); - /* make the device offset of the new mask match that of the group */ - double x_offset, y_offset; - cairo_surface_t *pats; - cairo_pattern_get_surface(group, &pats); - cairo_surface_get_device_offset(pats, &x_offset, &y_offset); - cairo_surface_set_device_offset(source, x_offset, y_offset); - /* paint the group */ cairo_set_source(maskCtx, group); cairo_paint(maskCtx); @@ -1308,9 +1301,7 @@ void CairoOutputDev::setSoftMask(GfxState * state, double * bbox, GBool alpha, /* setup the new mask pattern */ mask = cairo_pattern_create_for_surface(source); - cairo_matrix_t patMatrix; - cairo_pattern_get_matrix(group, &patMatrix); - cairo_pattern_set_matrix(mask, &patMatrix); + cairo_pattern_set_matrix(mask, &mat); cairo_surface_destroy(source); } else { From aacid at kemper.freedesktop.org Sun Apr 4 04:34:20 2010 From: aacid at kemper.freedesktop.org (Albert Astals Cid) Date: Sun, 4 Apr 2010 04:34:20 -0700 (PDT) Subject: [poppler] 2 commits - poppler/Function.cc utils/pdftoppm.1 utils/pdftoppm.cc Message-ID: <20100404113420.F09ADC0001@kemper.freedesktop.org> poppler/Function.cc | 12 +++++++----- utils/pdftoppm.1 | 6 ++++++ utils/pdftoppm.cc | 8 ++++++++ 3 files changed, 21 insertions(+), 5 deletions(-) New commits: commit ab5044e451e3714d385295f0b4ce9a15c8f2562c Author: Albert Astals Cid Date: Sun Apr 4 12:32:42 2010 +0100 Add the -o[dd] and -e[ven] options to pdftoppm I've been using this patch forever and it's a pain to apply and unapply it each time diff --git a/utils/pdftoppm.1 b/utils/pdftoppm.1 index fee97f8..de2405c 100644 --- a/utils/pdftoppm.1 +++ b/utils/pdftoppm.1 @@ -29,6 +29,12 @@ Specifies the first page to convert. .BI \-l " number" Specifies the last page to convert. .TP +.B \-o +Generates only the odd numbered pages. +.TP +.B \-e +Generates only the even numbered pages. +.TP .BI \-r " number" Specifies the X and Y resolution, in DPI. The default is 150 DPI. .TP diff --git a/utils/pdftoppm.cc b/utils/pdftoppm.cc index 5b318be..7d1e3bf 100644 --- a/utils/pdftoppm.cc +++ b/utils/pdftoppm.cc @@ -44,6 +44,8 @@ static int firstPage = 1; static int lastPage = 0; +static GBool printOnlyOdd = gFalse; +static GBool printOnlyEven = gFalse; static double resolution = 0.0; static double x_resolution = 150.0; static double y_resolution = 150.0; @@ -74,6 +76,10 @@ static const ArgDesc argDesc[] = { "first page to print"}, {"-l", argInt, &lastPage, 0, "last page to print"}, + {"-o", argFlag, &printOnlyOdd, 0, + "print only odd pages"}, + {"-e", argFlag, &printOnlyEven, 0, + "print only even pages"}, {"-r", argFP, &resolution, 0, "resolution, in DPI (default is 150)"}, @@ -287,6 +293,8 @@ int main(int argc, char *argv[]) { if (sz != 0) w = h = sz; pg_num_len = (int)ceil(log((double)doc->getNumPages()) / log((double)10)); for (pg = firstPage; pg <= lastPage; ++pg) { + if (printOnlyEven && pg % 2 == 0) continue; + if (printOnlyOdd && pg % 2 == 1) continue; if (useCropBox) { pg_w = doc->getPageCropWidth(pg); pg_h = doc->getPageCropHeight(pg); commit 0e371fb628a7e7d0cc1656e6405af4c97dbebf5d Author: Albert Astals Cid Date: Sun Apr 4 12:30:34 2010 +0100 Fix my roll optimization Thanks Carlos for noticing diff --git a/poppler/Function.cc b/poppler/Function.cc index 73a6b5f..b7c23fe 100644 --- a/poppler/Function.cc +++ b/poppler/Function.cc @@ -13,7 +13,7 @@ // All changes made under the Poppler project to this file are licensed // under GPL version 2 or later // -// Copyright (C) 2006, 2008, 2009 Albert Astals Cid +// Copyright (C) 2006, 2008-2010 Albert Astals Cid // Copyright (C) 2006 Jeff Muizelaar // // To see a description of the changes please see the Changelog file that @@ -1012,11 +1012,13 @@ void PSStack::roll(int n, int j) { } } else { j = n - j; - obj = stack[sp + n - 1]; - for (k = sp + n - 1; k > sp; --k) { - stack[k] = stack[k-1]; + for (i = 0; i < j; ++i) { + obj = stack[sp + n - 1]; + for (k = sp + n - 1; k > sp; --k) { + stack[k] = stack[k-1]; + } + stack[sp] = obj; } - stack[sp] = obj; } } From carlosgc at kemper.freedesktop.org Sun Apr 4 07:09:55 2010 From: carlosgc at kemper.freedesktop.org (Carlos Garcia Campos) Date: Sun, 4 Apr 2010 07:09:55 -0700 (PDT) Subject: [poppler] poppler/Lexer.cc Message-ID: <20100404140955.AF2F9C0001@kemper.freedesktop.org> poppler/Lexer.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) New commits: commit 8c6aefb8aa8929b9c47791d3062ed3ac8512626f Author: Carlos Garcia Campos Date: Sun Apr 4 16:08:12 2010 +0200 [lexer] Correctly parse numbers with '+' sign See GNOME Bug: https://bugzilla.gnome.org/show_bug.cgi?id=614549 diff --git a/poppler/Lexer.cc b/poppler/Lexer.cc index 5962185..60bb09e 100644 --- a/poppler/Lexer.cc +++ b/poppler/Lexer.cc @@ -13,6 +13,7 @@ // All changes made under the Poppler project to this file are licensed // under GPL version 2 or later // +// Copyright (C) 2010 Carlos Garcia Campos // Copyright (C) 2006-2009 Albert Astals Cid // Copyright (C) 2006 Krzysztof Kowalczyk // @@ -182,7 +183,7 @@ Object *Lexer::getObj(Object *obj, int objNum) { // number case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': - case '-': case '.': + case '+': case '-': case '.': overflownInteger = gFalse; neg = gFalse; xi = 0; @@ -190,7 +191,7 @@ Object *Lexer::getObj(Object *obj, int objNum) { neg = gTrue; } else if (c == '.') { goto doReal; - } else { + } else if (c != '+') { xi = c - '0'; } while (1) { From fr33g at web.de Sun Apr 4 07:32:37 2010 From: fr33g at web.de (Ingo Glaser) Date: Sun, 4 Apr 2010 16:32:37 +0200 (CEST) Subject: [poppler] Poppler on Windows 7 In-Reply-To: <000f01cad27a$7ff9f090$7fedd1b0$@nl> References: <3092055.83403.1270220991140.JavaMail.fmail@mwmweb049>, <000f01cad27a$7ff9f090$7fedd1b0$@nl> Message-ID: <8096713.477775.1270391557430.JavaMail.fmail@mwmweb051> An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: image/jpeg Size: 332 bytes Desc: not available URL: From msclrhd at googlemail.com Sun Apr 4 08:16:08 2010 From: msclrhd at googlemail.com (Reece Dunn) Date: Sun, 4 Apr 2010 16:16:08 +0100 Subject: [poppler] Poppler on Windows 7 In-Reply-To: <8096713.477775.1270391557430.JavaMail.fmail@mwmweb051> References: <3092055.83403.1270220991140.JavaMail.fmail@mwmweb049> <000f01cad27a$7ff9f090$7fedd1b0$@nl> <8096713.477775.1270391557430.JavaMail.fmail@mwmweb051> Message-ID: Hello, Es tut mir leid, wenn Google ?bersetzer hat den ?bersetzungen durcheinander. (I'm sorry if Google translator has messed up the translations.) On 4 April 2010 15:32, Ingo Glaser wrote: > > Hey many thanks for the answer and also for the other answers. > > Now I have libs and dlls and header-dateien. > > Now the problem is blos, I get my programme not begun, he announces the mistake to me: K?nnten Sie den deutschen Beitrag f?r dieses, zusammen mit dem Google/wasimmer ?bersetzung von Ihnen verwendete Programm. Das kann mir helfen / Sonstiges herauszufinden, was Sie sagen wollen - ich kann nicht herausfinden, was "the problem is blos" eingesehen werden kann. (Could you post the German for this, along with the Google/whatever translation program you are using. This may help me/others figure out what you are trying to say -- I cannot figure out what "the problem is blos" means.) > The use could not be begun correctly (0xc000007b), click them on OK around the use to finish. BTW, 0xc000007b is "The application failed to initialize properly (0xc000007b). Click Ok to terminate the application." in English (error code STATUS_INVALID_IMAGE_FORMAT). > I do not know what should be called. 1/ Haben sie ein 64-bit von Windows 7 zu installieren? (Do you have an 64-bit install of Windows 7?) 2/ Haben Sie Anti-Viren-Software installiert (wenn ja, welche)? (Do you have any anti-virus software installed (if so, which)?) 3/ Wie haben Sie beim Aufbau der Software? Mit MinGW oder Visual Studio (welche Version)? Durch CMake? (How did you build the software? With mingw or Visual Studio (which version)? Through CMake?) Eine Google-Suche f?r STATUS_INVALID_IMAGE_FORMAT darauf hinweisen, dass dies m?glicherweise auf eine 64-Bit-Programm versucht, 32-Bit-DLLs / Bibliotheken laufen. Sind Sie poppler Geb?ude in 64-Bit-oder 32-Bit-Modus? (A google search for STATUS_INVALID_IMAGE_FORMAT indicates that this might be due to a 64-bit program trying to run 32-bit DLLs/libraries. Are you building poppler in 64-bit or 32-bit mode?) - Reece From fr33g at web.de Sun Apr 4 09:33:54 2010 From: fr33g at web.de (Ingo Glaser) Date: Sun, 4 Apr 2010 18:33:54 +0200 (CEST) Subject: [poppler] Poppler on Windows 7 In-Reply-To: References: <3092055.83403.1270220991140.JavaMail.fmail@mwmweb049> <000f01cad27a$7ff9f090$7fedd1b0$@nl> <8096713.477775.1270391557430.JavaMail.fmail@mwmweb051>, Message-ID: <17129893.505553.1270398834916.JavaMail.fmail@mwmweb051> Hey, danke f?r die Antwort.Also ich habe ein Programm geschrieben in C++ und mit Qt. Zus?tzlich benutze ich Poppler.Da ich es nicht geschafft habe Poppler zu kompilieren, habe ich mir den KDE Installer runtergeladen, und ?ber ihn Poppler installiert, so dass ich die poppler-qt4.lib, poppler-qt.dll, poppler-qt4.dll.a und die poppler Header-Dateien habe.Ich habe dann die Header-Datei poppler-qt4.h inkludiert und gegen die Lib gelinkt.Leider startet mein Programm nicht, da die Fehlermeldung kommt, dass der Prozedureinstiegspunkt xmlCtxtGetLastError in der Dll libxml2.dll nicht gefunden wurde.So dann habe ich eine andere libxml2.dll geladen und diese ersetzt, dann kam der Fehler dass die Anwendung nicht korrekt gestartet werden konnte(0xc000007b).Ich habe Windows 7 64Bit.Virenscanner habe ich F-Secure.Und kompiliert und gelinkt wurde mein Programm mit MinGw, also ?ber die IDE Qt Creator.Hoffe ihr k?nnt mir helfen. Gru? freeGHey, danke f?r die Antwort.Also ich habe ein Programm geschrieben in C++ und mit Qt. Zus?tzlich benutze ich Poppler.Da ich es nicht geschafft habe Poppler zu kompilieren, habe ich mir den KDE Installer runtergeladen, und ?ber ihn Poppler installiert, so dass ich die poppler-qt4.lib, poppler-qt.dll, poppler-qt4.dll.a und die poppler Header-Dateien habe.Ich habe dann die Header-Datei poppler-qt4.h inkludiert und gegen die Lib gelinkt.Leider startet mein Programm nicht, da die Fehlermeldung kommt, dass der Prozedureinstiegspunkt xmlCtxtGetLastError in der Dll libxml2.dll nicht gefunden wurde.So dann habe ich eine andere libxml2.dll geladen und diese ersetzt, dann kam der Fehler dass die Anwendung nicht korrekt gestartet werden konnte(0xc000007b).Ich habe Windows 7 64Bit.Virenscanner habe ich F-Secure.Und kompiliert und gelinkt wurde mein Programm mit MinGw, also ?ber die IDE Qt Creator.Hoffe ihr k?nnt mir helfen. Gru? freeG Translated with [http://www.online-translator.com/Default.aspx/Text] Hey, thank you for the answer.So I have written a programme in C ++ and with Qt. In addition, I use Poppler.Because I have not got to compile Poppler, I have downloaded to me the KDE Installer, and about him have installed Poppler, so that I have poppler-qt4.lib, poppler-qt.dll, poppler-qt4.dll.a and the poppler Header files.Then I have conned on the Header file poppler-qt4.h inkludiert and against the Lib.Unfortunately, my programme does not start, because the error message comes that the procedure entrance point xmlCtxtGetLastError was not found in the Dll libxml2.dll.So then I have loaded another libxml2.dll and have substituted for this, then the mistake that the use did not come correctly could be begun (0xc000007b).I have Windows 7 64 bits.I have virus scanner F-Secure.And was compiled and was conned my programme with MinGw, so about the IDE Qt Creator.Hope you can help me. Greeting freeGHey, thank you for the answer.So I have written a programme in C ++ and with Qt. In addition, I use Poppler.Because I have not got to compile Poppler, I have downloaded to me the KDE Installer, and about him have installed Poppler, so that I have poppler-qt4.lib, poppler-qt.dll, poppler-qt4.dll.a and the poppler Header files.Then I have conned on the Header file poppler-qt4.h inkludiert and against the Lib.Unfortunately, my programme does not start, because the error message comes that the procedure entrance point xmlCtxtGetLastError was not found in the Dll libxml2.dll.So then I have loaded another libxml2.dll and have substituted for this, then the mistake that the use did not come correctly could be begun (0xc000007b).I have Windows 7 64 bits.I have virus scanner F-Secure.And was compiled and was conned my programme with MinGw, so about the IDE Qt Creator.Hope you can help me. Greeting freeG -----Urspr?ngliche Nachricht----- Von: Reece Dunn Gesendet: 04.04.2010 17:16:08 An: Ingo Glaser Betreff: Re: [poppler] Poppler on Windows 7 >Hello, > >Es tut mir leid, wenn Google ?bersetzer hat den ?bersetzungen durcheinander. > >(I'm sorry if Google translator has messed up the translations.) > >On 4 April 2010 15:32, Ingo Glaser wrote: >> >> Hey many thanks for the answer and also for the other answers. >> >> Now I have libs and dlls and header-dateien. >> >> Now the problem is blos, I get my programme not begun, he announces the mistake to me: > >K?nnten Sie den deutschen Beitrag f?r dieses, zusammen mit dem >Google/wasimmer ?bersetzung von Ihnen verwendete Programm. Das kann >mir helfen / Sonstiges herauszufinden, was Sie sagen wollen - ich kann >nicht herausfinden, was "the problem is blos" eingesehen werden kann. > >(Could you post the German for this, along with the Google/whatever >translation program you are using. This may help me/others figure out >what you are trying to say -- I cannot figure out what "the problem is >blos" means.) > >> The use could not be begun correctly (0xc000007b), click them on OK around the use to finish. > >BTW, 0xc000007b is "The application failed to initialize properly >(0xc000007b). Click Ok to terminate the application." in English >(error code STATUS_INVALID_IMAGE_FORMAT). > >> I do not know what should be called. > >1/ Haben sie ein 64-bit von Windows 7 zu installieren? (Do you have an >64-bit install of Windows 7?) >2/ Haben Sie Anti-Viren-Software installiert (wenn ja, welche)? (Do >you have any anti-virus software installed (if so, which)?) >3/ Wie haben Sie beim Aufbau der Software? Mit MinGW oder Visual >Studio (welche Version)? Durch CMake? (How did you build the software? >With mingw or Visual Studio (which version)? Through CMake?) > >Eine Google-Suche f?r STATUS_INVALID_IMAGE_FORMAT darauf hinweisen, >dass dies m?glicherweise auf eine 64-Bit-Programm versucht, >32-Bit-DLLs / Bibliotheken laufen. Sind Sie poppler Geb?ude in >64-Bit-oder 32-Bit-Modus? > >(A google search for STATUS_INVALID_IMAGE_FORMAT indicates that this >might be due to a 64-bit program trying to run 32-bit DLLs/libraries. >Are you building poppler in 64-bit or 32-bit mode?) > >- Reece ___________________________________________________________ NEU: WEB.DE DSL f?r 19,99 EUR/mtl. und ohne Mindest-Laufzeit! http://produkte.web.de/go/02/ From erik at forcheck.nl Sun Apr 4 11:02:00 2010 From: erik at forcheck.nl (Erik Kruyt) Date: Sun, 4 Apr 2010 20:02:00 +0200 Subject: [poppler] Poppler on Windows 7 In-Reply-To: <17129893.505553.1270398834916.JavaMail.fmail@mwmweb051> References: <3092055.83403.1270220991140.JavaMail.fmail@mwmweb049> <000f01cad27a$7ff9f090$7fedd1b0$@nl> <8096713.477775.1270391557430.JavaMail.fmail@mwmweb051>, <17129893.505553.1270398834916.JavaMail.fmail@mwmweb051> Message-ID: <002201cad420$ecd31960$c6794c20$@nl> Ich ben?tze 32 bit Windows XP und QT 4.6.2 mit minGW. Ich kan das QT beispiel compilieren und linken aber bekom denn ein runtime fehler: Kann das entrypoint from procedure _Z10qvsnprintfPcjPKcS_ nicht finden in DLL-datei QtCore4.dll Vieleicht doch ein mitmatch zwischen die .h, .dll. and .dll.a ? Erik Forcheck b.v. Torenmolen 23 2317 NV Leiden Netherlands > -----Oorspronkelijk bericht----- > Van: Ingo Glaser [mailto:fr33g at web.de] > Verzonden: zondag 4 april 2010 18:34 > Aan: Reece Dunn > CC: poppler at lists.freedesktop.org; Erik Kruyt > Onderwerp: Re: [poppler] Poppler on Windows 7 > > Hey, danke f?r die Antwort.Also ich habe ein Programm geschrieben in > C++ und mit Qt. Zus?tzlich benutze ich Poppler.Da ich es nicht > geschafft habe Poppler zu kompilieren, habe ich mir den KDE Installer > runtergeladen, und ?ber ihn Poppler installiert, so dass ich die > poppler-qt4.lib, poppler-qt.dll, poppler-qt4.dll.a und die poppler > Header-Dateien habe.Ich habe dann die Header-Datei poppler-qt4.h > inkludiert und gegen die Lib gelinkt.Leider startet mein Programm > nicht, da die Fehlermeldung kommt, dass der Prozedureinstiegspunkt > xmlCtxtGetLastError in der Dll libxml2.dll nicht gefunden wurde.So dann > habe ich eine andere libxml2.dll geladen und diese ersetzt, dann kam > der Fehler dass die Anwendung nicht korrekt gestartet werden > konnte(0xc000007b).Ich habe Windows 7 64Bit.Virenscanner habe ich F- > Secure.Und kompiliert und gelinkt wurde mein Programm mit MinGw, also > ?ber die IDE Qt Creator.Hoffe ihr k?nnt mir helfen. > Gru? freeGHey, danke f?r die Antwort.Also ich habe ein Programm > geschrieben in C++ und mit Qt. Zus?tzlich benutze ich Poppler.Da ich es > nicht geschafft habe Poppler zu kompilieren, habe ich mir den KDE > Installer runtergeladen, und ?ber ihn Poppler installiert, so dass ich > die poppler-qt4.lib, poppler-qt.dll, poppler-qt4.dll.a und die poppler > Header-Dateien habe.Ich habe dann die Header-Datei poppler-qt4.h > inkludiert und gegen die Lib gelinkt.Leider startet mein Programm > nicht, da die Fehlermeldung kommt, dass der Prozedureinstiegspunkt > xmlCtxtGetLastError in der Dll libxml2.dll nicht gefunden wurde.So dann > habe ich eine andere libxml2.dll geladen und diese ersetzt, dann kam > der Fehler dass die Anwendung nicht korrekt gestartet werden > konnte(0xc000007b).Ich habe Windows 7 64Bit.Virenscanner habe ich F- > Secure.Und kompiliert und gelinkt wurde mein Programm mit MinGw, also > ?ber die IDE Qt Creator.Hoffe ihr k?nnt mir helfen. > Gru? freeG > > Translated with [http://www.online-translator.com/Default.aspx/Text] > > Hey, thank you for the answer.So I have written a programme in C ++ and > with Qt. In addition, I use Poppler.Because I have not got to compile > Poppler, I have downloaded to me the KDE Installer, and about him have > installed Poppler, so that I have poppler-qt4.lib, poppler-qt.dll, > poppler-qt4.dll.a and the poppler Header files.Then I have conned on > the Header file poppler-qt4.h inkludiert and against the > Lib.Unfortunately, my programme does not start, because the error > message comes that the procedure entrance point xmlCtxtGetLastError was > not found in the Dll libxml2.dll.So then I have loaded another > libxml2.dll and have substituted for this, then the mistake that the > use did not come correctly could be begun (0xc000007b).I have Windows 7 > 64 bits.I have virus scanner F-Secure.And was compiled and was conned > my programme with MinGw, so about the IDE Qt Creator.Hope you can help > me. > Greeting freeGHey, thank you for the answer.So I have written a > programme in C ++ and with Qt. In addition, I use Poppler.Because I > have not got to compile Poppler, I have downloaded to me the KDE > Installer, and about him have installed Poppler, so that I have > poppler-qt4.lib, poppler-qt.dll, poppler-qt4.dll.a and the poppler > Header files.Then I have conned on the Header file poppler-qt4.h > inkludiert and against the Lib.Unfortunately, my programme does not > start, because the error message comes that the procedure entrance > point xmlCtxtGetLastError was not found in the Dll libxml2.dll.So then > I have loaded another libxml2.dll and have substituted for this, then > the mistake that the use did not come correctly could be begun > (0xc000007b).I have Windows 7 64 bits.I have virus scanner F-Secure.And > was compiled and was conned my programme with MinGw, so about the IDE > Qt Creator.Hope you can help me. > Greeting freeG > -----Urspr?ngliche Nachricht----- > Von: Reece Dunn > Gesendet: 04.04.2010 17:16:08 > An: Ingo Glaser > Betreff: Re: [poppler] Poppler on Windows 7 > > >Hello, > > > >Es tut mir leid, wenn Google ?bersetzer hat den ?bersetzungen > durcheinander. > > > >(I'm sorry if Google translator has messed up the translations.) > > > >On 4 April 2010 15:32, Ingo Glaser wrote: > >> > >> Hey many thanks for the answer and also for the other answers. > >> > >> Now I have libs and dlls and header-dateien. > >> > >> Now the problem is blos, I get my programme not begun, he announces > the mistake to me: > > > >K?nnten Sie den deutschen Beitrag f?r dieses, zusammen mit dem > >Google/wasimmer ?bersetzung von Ihnen verwendete Programm. Das kann > >mir helfen / Sonstiges herauszufinden, was Sie sagen wollen - ich kann > >nicht herausfinden, was "the problem is blos" eingesehen werden kann. > > > >(Could you post the German for this, along with the Google/whatever > >translation program you are using. This may help me/others figure out > >what you are trying to say -- I cannot figure out what "the problem is > >blos" means.) > > > >> The use could not be begun correctly (0xc000007b), click them on OK > around the use to finish. > > > >BTW, 0xc000007b is "The application failed to initialize properly > >(0xc000007b). Click Ok to terminate the application." in English > >(error code STATUS_INVALID_IMAGE_FORMAT). > > > >> I do not know what should be called. > > > >1/ Haben sie ein 64-bit von Windows 7 zu installieren? (Do you have an > >64-bit install of Windows 7?) > >2/ Haben Sie Anti-Viren-Software installiert (wenn ja, welche)? (Do > >you have any anti-virus software installed (if so, which)?) > >3/ Wie haben Sie beim Aufbau der Software? Mit MinGW oder Visual > >Studio (welche Version)? Durch CMake? (How did you build the software? > >With mingw or Visual Studio (which version)? Through CMake?) > > > >Eine Google-Suche f?r STATUS_INVALID_IMAGE_FORMAT darauf hinweisen, > >dass dies m?glicherweise auf eine 64-Bit-Programm versucht, > >32-Bit-DLLs / Bibliotheken laufen. Sind Sie poppler Geb?ude in > >64-Bit-oder 32-Bit-Modus? > > > >(A google search for STATUS_INVALID_IMAGE_FORMAT indicates that this > >might be due to a 64-bit program trying to run 32-bit DLLs/libraries. > >Are you building poppler in 64-bit or 32-bit mode?) > > > >- Reece > ___________________________________________________________ > NEU: WEB.DE DSL f?r 19,99 EUR/mtl. und ohne Mindest-Laufzeit! > http://produkte.web.de/go/02/ From hib at hiberis.nl Mon Apr 5 06:06:00 2010 From: hib at hiberis.nl (Hib Eris) Date: Mon, 5 Apr 2010 15:06:00 +0200 Subject: [poppler] Cached files, reading stdin, http streams and PDFDocBuilder In-Reply-To: <201003271520.02771.aacid@kde.org> References: <201003271520.02771.aacid@kde.org> Message-ID: Hi Albert and others, I have rewritten my patches taking your comments into account. I have attached the new patches. I am currently working on support for linearized pdf files. This will allow you to render any page from a pdf document without the need to download the complete pdf. Expect more patches soon. Cheers, Hib On Sat, Mar 27, 2010 at 4:20 PM, Albert Astals Cid wrote: > A Dijous, 25 de febrer de 2010, Hib Eris va escriure: >> Hi all, >> >> After some sleep, I noticed that my patches regarding the >> PDFDocBuilders could be simplified. So here are all patches updated >> with this new insight. >> >> Hib Eris > > Sorry it took too much, some comments: > ?* We try not to use the C++ standard library (yeah idiotic decision, but we > try to go on with it), do you really need ? > ?* Please move "enum CachedFileChunkState" inside CachedFile class, and drop > the CachedFile from the name > ?* The same for CachedFileChunk > ?* Make CachedFile::getFileName return a GooString, it's not a hot path and > will help people forgetting to delete it and causing leaks > ?* If you really need to do manual reference counting (man this is C++ doing > manual reference counting is bad) do it like it's done in GfxFont, that is, > the destructor is private and inc/decRef return void and recRef automatically > deletes when counter reaches 0 > ?* Also convert the "if (foo) delete foo;" statements to "delete foo;" > ?* In CurlCacheLoader::load you probably leak the range GooString > ?* The way builders are created/loaded/chained feels a bit weirdish, i think i > would prefer something like this (not well though names not the ones i would > probably use) > > class PDFDocLoader > { > ? ?PDFDoc *load(...) = 0; > ? ?GooStringList supportedProtocols() const = 0; > }; > > class PDFDocLoaderFactory > { > ? ? ? ?bool init(); // loads default builders > ? ? ? ?bool add(Builder *); // adds a non default builder (so that for example > the Qt4 frontend can "inject" a builder based in QNetworkAccessManager > ? ? ? ?PDFDoc *load(...); // uses supportedProtocols to see which PDFDocLoader > has to use > }; > > What do you think? > > Albert > _______________________________________________ > poppler mailing list > poppler at lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/poppler > -------------- next part -------------- From 397291f0a0a5447fbf1e59f870a8618dca505091 Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Sat, 3 Apr 2010 15:08:20 +0200 Subject: [PATCH 01/11] Add support for cached files --- CMakeLists.txt | 2 + poppler/CachedFile.cc | 246 +++++++++++++++++++++++++++++++++++++++++++++++++ poppler/CachedFile.h | 113 ++++++++++++++++++++++ poppler/Makefile.am | 2 + poppler/Stream.cc | 102 ++++++++++++++++++++ poppler/Stream.h | 58 ++++++++++++ 6 files changed, 523 insertions(+), 0 deletions(-) create mode 100644 poppler/CachedFile.cc create mode 100644 poppler/CachedFile.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 8411441..b5e6988 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -222,6 +222,7 @@ set(poppler_SRCS poppler/Array.cc poppler/BuiltinFont.cc poppler/BuiltinFontTables.cc + poppler/CachedFile.cc poppler/Catalog.cc poppler/CharCodeToUnicode.cc poppler/CMap.cc @@ -353,6 +354,7 @@ if(ENABLE_XPDF_HEADERS) poppler/Array.h poppler/BuiltinFont.h poppler/BuiltinFontTables.h + poppler/CachedFile.h poppler/Catalog.h poppler/CharCodeToUnicode.h poppler/CMap.h diff --git a/poppler/CachedFile.cc b/poppler/CachedFile.cc new file mode 100644 index 0000000..835079f --- /dev/null +++ b/poppler/CachedFile.cc @@ -0,0 +1,246 @@ +//======================================================================== +// +// CachedFile.cc +// +// This file is licensed under the GPLv2 or later +// +// Copyright 2009 Stefan Thomas +// Copyright 2010 Hib Eris +// +//======================================================================== + +#include +#include "CachedFile.h" + +//------------------------------------------------------------------------ +// CachedFile +//------------------------------------------------------------------------ + +CachedFile::CachedFile(CachedFileLoader *cachedFileLoaderA, GooString *uriA) +{ + uri = uriA; + loader = cachedFileLoaderA; + + streamPos = 0; + chunks = new GooVector(); + + length = loader->init(uri, this); + refCnt = 1; + + chunks->resize(length/CachedFileChunkSize + 1); +} + +CachedFile::~CachedFile() +{ + delete uri; + delete loader; + delete chunks; +} + +void CachedFile::incRefCnt() { + refCnt++; +} + +void CachedFile::decRefCnt() { + if (--refCnt == 0) + delete this; +} + +long int CachedFile::tell() { + return streamPos; +} + +int CachedFile::seek(long int offset, int origin) +{ + if (origin == SEEK_SET) { + streamPos = offset; + } else if (origin == SEEK_CUR) { + streamPos += offset; + } else { + streamPos = length + offset; + } + + if (streamPos > length) { + streamPos = 0; + return 1; + } + + return 0; +} + +int CachedFile::cache(GooVector* ranges) +{ + GooVector loadChunks; + int numChunks = length/CachedFileChunkSize + 1; + char chunkNeeded[numChunks]; + int startChunk, endChunk; + GooVector chunk_ranges, all; + ByteRange range; + + if (!ranges) { + ranges = &all; + range.offset = 0; + range.length = length; + ranges->push_back(range); + } + + memset(&chunkNeeded, 0, numChunks); + for (size_t i = 0; i < ranges->size(); i++) { + + if ((*ranges)[i].length == 0) continue; + if ((*ranges)[i].offset >= length) continue; + + size_t start = (*ranges)[i].offset; + size_t end = start + (*ranges)[i].length - 1; + if (end >= length) end = length - 1; + + startChunk = start / CachedFileChunkSize; + endChunk = end / CachedFileChunkSize; + for (int chunk = startChunk; chunk <= endChunk; chunk++) { + if ((*chunks)[chunk].state == chunkStateNew) { + chunkNeeded[chunk] = 1; + } + } + } + + int chunk = 0; + while (chunk < numChunks) { + while (!chunkNeeded[chunk] && (++chunk != numChunks)) ; + if (chunk == numChunks) break; + startChunk = chunk; + loadChunks.push_back(chunk); + + while ((++chunk != numChunks) && chunkNeeded[chunk]) { + loadChunks.push_back(chunk); + } + endChunk = chunk - 1; + + range.offset = startChunk * CachedFileChunkSize; + range.length = (endChunk - startChunk + 1) * CachedFileChunkSize; + + chunk_ranges.push_back(range); + } + + if (chunk_ranges.size() > 0) { + CachedFileWriter writer = + CachedFileWriter(this, &loadChunks); + return loader->load(&chunk_ranges, &writer); + } + + return 0; +} + +size_t CachedFile::read(void *ptr, size_t unitsize, size_t count) +{ + size_t bytes = unitsize*count; + if (length < (streamPos + bytes)) { + bytes = length - streamPos; + } + + if (bytes == 0) return 0; + + // Load data + if (cache(streamPos, bytes) != 0) return 0; + + // Copy data to buffer + size_t toCopy = bytes; + while (toCopy) { + int chunk = streamPos / CachedFileChunkSize; + int offset = streamPos % CachedFileChunkSize; + size_t len = CachedFileChunkSize-offset; + + if (len > toCopy) + len = toCopy; + + memcpy(ptr, (*chunks)[chunk].data + offset, len); + streamPos += len; + toCopy -= len; + ptr = (char*)ptr + len; + } + + return bytes; +} + +int CachedFile::cache(size_t offset, size_t length) +{ + GooVector r; + ByteRange range; + range.offset = offset; + range.length = length; + r.push_back(range); + return cache(&r); +} + +//------------------------------------------------------------------------ +// CachedFileWriter +//------------------------------------------------------------------------ + +CachedFileWriter::CachedFileWriter(CachedFile *cachedFileA, GooVector *chunksA) +{ + cachedFile = cachedFileA; + chunks = chunksA; + + if (chunks) { + offset = 0; + it = (*chunks).begin(); + } +} + +CachedFileWriter::~CachedFileWriter() +{ +} + +size_t CachedFileWriter::write(const char *ptr, size_t size) +{ + const char *cp = ptr; + size_t len = size; + size_t nfree, ncopy; + size_t written = 0; + size_t chunk; + + if (!len) return 0; + + while (len) { + if (chunks) { + if (offset == CachedFileChunkSize) { + it++; + if (it == (*chunks).end()) return written; + offset = 0; + } + chunk = *it; + } else { + offset = cachedFile->length % CachedFileChunkSize; + chunk = cachedFile->length / CachedFileChunkSize; + } + + if (chunk >= cachedFile->chunks->size()) { + cachedFile->chunks->resize(chunk + 1); + } + + nfree = CachedFileChunkSize - offset; + ncopy = (len >= nfree) ? nfree : len; + memcpy(&((*cachedFile->chunks)[chunk].data[offset]), cp, ncopy); + len -= ncopy; + cp += ncopy; + offset += ncopy; + written += ncopy; + + if (!chunks) { + cachedFile->length += ncopy; + } + + if (offset == CachedFileChunkSize) { + (*cachedFile->chunks)[chunk].state = CachedFile::chunkStateLoaded; + } + } + + if ((chunk == (cachedFile->length / CachedFileChunkSize)) && + (offset == (cachedFile->length % CachedFileChunkSize))) { + (*cachedFile->chunks)[chunk].state = CachedFile::chunkStateLoaded; + } + + return written; +} + +//------------------------------------------------------------------------ + diff --git a/poppler/CachedFile.h b/poppler/CachedFile.h new file mode 100644 index 0000000..e004578 --- /dev/null +++ b/poppler/CachedFile.h @@ -0,0 +1,113 @@ +//======================================================================== +// +// CachedFile.h +// +// Caching files support. +// +// This file is licensed under the GPLv2 or later +// +// Copyright 2009 Stefan Thomas +// Copyright 2010 Hib Eris +// +//======================================================================== + +#ifndef CACHEDFILE_H +#define CACHEDFILE_H + +#include "poppler-config.h" + +#include "goo/gtypes.h" +#include "Object.h" +#include "Stream.h" +#include "goo/GooVector.h" + +//------------------------------------------------------------------------ + +#define CachedFileChunkSize 8192 + +class GooString; +class CachedFileLoader; + +//------------------------------------------------------------------------ + +class CachedFile { + +friend class CachedFileWriter; + +public: + + CachedFile(CachedFileLoader *cacheLoader, GooString *uri); + ~CachedFile(); + + Guint getLength() { return length; } + long int tell(); + int seek(long int offset, int origin); + size_t read(void * ptr, size_t unitsize, size_t count); + size_t write(const char *ptr, size_t size, size_t fromByte); + int cache(GooVector* ranges); + + // Reference counting. + void incRefCnt(); + void decRefCnt(); + +private: + + enum ChunkState { + chunkStateNew = 0, + chunkStateLoaded + }; + + typedef struct { + ChunkState state; + char data[CachedFileChunkSize]; + } Chunk; + + int cache(size_t offset, size_t length); + + CachedFileLoader *loader; + GooString *uri; + + size_t length; + size_t streamPos; + + GooVector *chunks; + + int refCnt; // reference count + +}; + +//------------------------------------------------------------------------ + +class CachedFileWriter { + +public: + + CachedFileWriter(CachedFile *cachedFile, GooVector *chunksA); + ~CachedFileWriter(); + + size_t write(const char *ptr, size_t size); + +private: + + CachedFile *cachedFile; + GooVector *chunks; + GooVector::iterator it; + size_t offset; + +}; + +//------------------------------------------------------------------------ + +class CachedFileLoader { + +public: + + virtual ~CachedFileLoader() {}; + virtual size_t init(GooString *uri, CachedFile *cachedFile) = 0; + virtual int load(GooVector *ranges, CachedFileWriter *writer) = 0; + +}; + +//------------------------------------------------------------------------ + +#endif diff --git a/poppler/Makefile.am b/poppler/Makefile.am index 3bcb922..f225110 100644 --- a/poppler/Makefile.am +++ b/poppler/Makefile.am @@ -167,6 +167,7 @@ poppler_include_HEADERS = \ Array.h \ BuiltinFont.h \ BuiltinFontTables.h \ + CachedFile.h \ Catalog.h \ CharCodeToUnicode.h \ CMap.h \ @@ -239,6 +240,7 @@ libpoppler_la_SOURCES = \ Array.cc \ BuiltinFont.cc \ BuiltinFontTables.cc \ + CachedFile.cc \ Catalog.cc \ CharCodeToUnicode.cc \ CMap.cc \ diff --git a/poppler/Stream.cc b/poppler/Stream.cc index 6634317..0771e25 100644 --- a/poppler/Stream.cc +++ b/poppler/Stream.cc @@ -19,6 +19,8 @@ // Copyright (C) 2008 Julien Rebetez // Copyright (C) 2009 Carlos Garcia Campos // Copyright (C) 2009 Glenn Ganz +// Copyright (C) 2009 Stefan Thomas +// Copyright (C) 2010 Hib Eris // // 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 @@ -50,6 +52,7 @@ #include "Stream.h" #include "JBIG2Stream.h" #include "Stream-CCITT.h" +#include "CachedFile.h" #ifdef ENABLE_LIBJPEG #include "DCTStream.h" @@ -794,6 +797,105 @@ void FileStream::moveStart(int delta) { } //------------------------------------------------------------------------ +// CachedFileStream +//------------------------------------------------------------------------ + +CachedFileStream::CachedFileStream(CachedFile *ccA, Guint startA, + GBool limitedA, Guint lengthA, Object *dictA) + : BaseStream(dictA) +{ + cc = ccA; + start = startA; + limited = limitedA; + length = lengthA; + bufPtr = bufEnd = buf; + bufPos = start; + savePos = 0; + saved = gFalse; +} + +CachedFileStream::~CachedFileStream() +{ + close(); + cc->decRefCnt(); +} + +Stream *CachedFileStream::makeSubStream(Guint startA, GBool limitedA, + Guint lengthA, Object *dictA) +{ + cc->incRefCnt(); + return new CachedFileStream(cc, startA, limitedA, lengthA, dictA); +} + +void CachedFileStream::reset() +{ + savePos = (Guint)cc->tell(); + cc->seek(start, SEEK_SET); + + saved = gTrue; + bufPtr = bufEnd = buf; + bufPos = start; +} + +void CachedFileStream::close() +{ + if (saved) { + cc->seek(savePos, SEEK_SET); + saved = gFalse; + } +} + +GBool CachedFileStream::fillBuf() +{ + int n; + + bufPos += bufEnd - buf; + bufPtr = bufEnd = buf; + if (limited && bufPos >= start + length) { + return gFalse; + } + if (limited && bufPos + cachedStreamBufSize > start + length) { + n = start + length - bufPos; + } else { + n = cachedStreamBufSize; + } + cc->read(buf, 1, n); + bufEnd = buf + n; + if (bufPtr >= bufEnd) { + return gFalse; + } + return gTrue; +} + +void CachedFileStream::setPos(Guint pos, int dir) +{ + Guint size; + + if (dir >= 0) { + cc->seek(pos, SEEK_SET); + bufPos = pos; + } else { + cc->seek(0, SEEK_END); + size = (Guint)cc->tell(); + + if (pos > size) + pos = (Guint)size; + + cc->seek(-(int)pos, SEEK_END); + bufPos = (Guint)cc->tell(); + } + + bufPtr = bufEnd = buf; +} + +void CachedFileStream::moveStart(int delta) +{ + start += delta; + bufPtr = bufEnd = buf; + bufPos = start; +} + +//------------------------------------------------------------------------ // MemStream //------------------------------------------------------------------------ diff --git a/poppler/Stream.h b/poppler/Stream.h index 9c0068e..49ae8fb 100644 --- a/poppler/Stream.h +++ b/poppler/Stream.h @@ -17,6 +17,8 @@ // Copyright (C) 2008 Julien Rebetez // Copyright (C) 2008 Albert Astals Cid // Copyright (C) 2009 Carlos Garcia Campos +// Copyright (C) 2009 Stefan Thomas +// Copyright (C) 2010 Hib Eris // // 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,14 +34,17 @@ #include #include "goo/gtypes.h" +#include "goo/GooVector.h" #include "Object.h" class BaseStream; +class CachedFile; //------------------------------------------------------------------------ enum StreamKind { strFile, + strCachedFile, strASCIIHex, strASCII85, strLZW, @@ -69,6 +74,13 @@ enum CryptAlgorithm { }; //------------------------------------------------------------------------ + +typedef struct _ByteRange { + Guint offset; + Guint length; +} ByteRange; + +//------------------------------------------------------------------------ // Stream (base class) //------------------------------------------------------------------------ @@ -399,6 +411,52 @@ private: }; //------------------------------------------------------------------------ +// CachedFileStream +//------------------------------------------------------------------------ + +#define cachedStreamBufSize 1024 + +class CachedFileStream: public BaseStream { +public: + + CachedFileStream(CachedFile *ccA, Guint startA, GBool limitedA, + Guint lengthA, Object *dictA); + virtual ~CachedFileStream(); + virtual Stream *makeSubStream(Guint startA, GBool limitedA, + Guint lengthA, Object *dictA); + virtual StreamKind getKind() { return strCachedFile; } + virtual void reset(); + virtual void close(); + virtual int getChar() + { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); } + virtual int lookChar() + { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); } + virtual int getPos() { return bufPos + (bufPtr - buf); } + virtual void setPos(Guint pos, int dir = 0); + virtual Guint getStart() { return start; } + virtual void moveStart(int delta); + + virtual int getUnfilteredChar () { return getChar(); } + virtual void unfilteredReset () { reset(); } + +private: + + GBool fillBuf(); + + CachedFile *cc; + Guint start; + GBool limited; + Guint length; + char buf[cachedStreamBufSize]; + char *bufPtr; + char *bufEnd; + Guint bufPos; + int savePos; + GBool saved; +}; + + +//------------------------------------------------------------------------ // MemStream //------------------------------------------------------------------------ -- 1.6.4.2 From f19ca4a2a213aef06388bd07432373cd4b0403e4 Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Tue, 23 Feb 2010 02:02:10 +0100 Subject: [PATCH 02/11] Add support for reading a cached file from stdin --- CMakeLists.txt | 2 ++ poppler/Makefile.am | 2 ++ poppler/StdinCachedFile.cc | 37 +++++++++++++++++++++++++++++++++++++ poppler/StdinCachedFile.h | 26 ++++++++++++++++++++++++++ 4 files changed, 67 insertions(+), 0 deletions(-) create mode 100644 poppler/StdinCachedFile.cc create mode 100644 poppler/StdinCachedFile.h diff --git a/CMakeLists.txt b/CMakeLists.txt index b5e6988..7922dad 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -265,6 +265,7 @@ set(poppler_SRCS poppler/TextOutputDev.cc poppler/PageLabelInfo.cc poppler/SecurityHandler.cc + poppler/StdinCachedFile.cc poppler/Sound.cc poppler/XpdfPluginAPI.cc poppler/Movie.cc @@ -409,6 +410,7 @@ if(ENABLE_XPDF_HEADERS) poppler/PSOutputDev.h poppler/TextOutputDev.h poppler/SecurityHandler.h + poppler/StdinCachedFile.h poppler/UTF8.h poppler/XpdfPluginAPI.h poppler/Sound.h diff --git a/poppler/Makefile.am b/poppler/Makefile.am index f225110..a6bb9e9 100644 --- a/poppler/Makefile.am +++ b/poppler/Makefile.am @@ -205,6 +205,7 @@ poppler_include_HEADERS = \ PreScanOutputDev.h \ PSTokenizer.h \ Rendition.h \ + StdinCachedFile.h \ Stream-CCITT.h \ Stream.h \ UnicodeMap.h \ @@ -277,6 +278,7 @@ libpoppler_la_SOURCES = \ PreScanOutputDev.cc \ PSTokenizer.cc \ Rendition.cc \ + StdinCachedFile.cc \ Stream.cc \ UnicodeMap.cc \ UnicodeTypeTable.cc \ diff --git a/poppler/StdinCachedFile.cc b/poppler/StdinCachedFile.cc new file mode 100644 index 0000000..9b32136 --- /dev/null +++ b/poppler/StdinCachedFile.cc @@ -0,0 +1,37 @@ +//======================================================================== +// +// StdinCachedFile.cc +// +// This file is licensed under the GPLv2 or later +// +// Copyright 2010 Hib Eris +// +//======================================================================== + +#include + +#include "StdinCachedFile.h" + +#include + +size_t StdinCacheLoader::init(GooString *dummy, CachedFile *cachedFile) +{ + size_t read, size = 0; + char buf[CachedFileChunkSize]; + + CachedFileWriter writer = CachedFileWriter (cachedFile, NULL); + do { + read = fread(buf, 1, CachedFileChunkSize, stdin); + (writer.write) (buf, CachedFileChunkSize); + size += read; + } + while (read == CachedFileChunkSize); + + return size; +} + +int StdinCacheLoader::load(GooVector *ranges, CachedFileWriter *writer) +{ + return 0; +} + diff --git a/poppler/StdinCachedFile.h b/poppler/StdinCachedFile.h new file mode 100644 index 0000000..9af086a --- /dev/null +++ b/poppler/StdinCachedFile.h @@ -0,0 +1,26 @@ +//======================================================================== +// +// StdinCachedFile.h +// +// This file is licensed under the GPLv2 or later +// +// Copyright 2010 Hib Eris +// +//======================================================================== + +#ifndef STDINCACHELOADER_H +#define STDINCACHELOADER_H + +#include "CachedFile.h" + +class StdinCacheLoader : public CachedFileLoader { + +public: + + size_t init(GooString *dummy, CachedFile* cachedFile); + int load(GooVector *ranges, CachedFileWriter *writer); + +}; + +#endif + -- 1.6.4.2 From c226271dfb53bf384ceb1b2035df6dea0f6b3396 Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Wed, 24 Feb 2010 14:46:59 +0100 Subject: [PATCH 03/11] Use cached files to read from stdin in pdfinfo This fixes reading from stdin. --- utils/pdfinfo.cc | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-) diff --git a/utils/pdfinfo.cc b/utils/pdfinfo.cc index bfbe0b3..ceddd47 100644 --- a/utils/pdfinfo.cc +++ b/utils/pdfinfo.cc @@ -15,6 +15,7 @@ // // Copyright (C) 2006 Dom Lachowicz // Copyright (C) 2007-2009 Albert Astals Cid +// Copyright (C) 2010 Hib Eris // // 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 @@ -47,6 +48,7 @@ #include "PDFDocEncoding.h" #include "Error.h" #include "DateInfo.h" +#include "StdinCachedFile.h" static void printInfoString(Dict *infoDict, char *key, char *text, UnicodeMap *uMap); @@ -164,7 +166,9 @@ int main(int argc, char *argv[]) { Object obj; obj.initNull(); - doc = new PDFDoc(new FileStream(stdin, 0, gFalse, 0, &obj), ownerPW, userPW); + CachedFile *cachedFile = new CachedFile(new StdinCacheLoader(), NULL); + doc = new PDFDoc(new CachedFileStream(cachedFile, 0, gFalse, 0, &obj), + ownerPW, userPW); } if (userPW) { -- 1.6.4.2 From 4ad2ef6d323629b42e0ae01655adc25ec2816d00 Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Tue, 23 Feb 2010 02:29:26 +0100 Subject: [PATCH 04/11] Add HTTP support using libcurl With libcurl, poppler can handle documents over http. --- CMakeLists.txt | 18 ++++++++ config.h.cmake | 6 +++ configure.ac | 16 +++++++ poppler/CurlCachedFile.cc | 95 ++++++++++++++++++++++++++++++++++++++++ poppler/CurlCachedFile.h | 39 ++++++++++++++++ poppler/Makefile.am | 20 ++++++++ poppler/poppler-config.h.cmake | 5 ++ poppler/poppler-config.h.in | 5 ++ utils/pdfinfo.cc | 16 ++++++- 9 files changed, 219 insertions(+), 1 deletions(-) create mode 100644 poppler/CurlCachedFile.cc create mode 100644 poppler/CurlCachedFile.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 7922dad..70b0e06 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,6 +29,7 @@ option(ENABLE_CPP "Compile poppler cpp wrapper." ON) option(ENABLE_ABIWORD "Build the Abiword backend." ON) option(ENABLE_LIBOPENJPEG "Use libopenjpeg for JPX streams." ON) option(ENABLE_LCMS "Use liblcms for color management." ON) +option(ENABLE_LIBCURL "Build libcurl based HTTP support." OFF) option(ENABLE_ZLIB "Build with zlib (not totally safe)." OFF) option(USE_EXCEPTIONS "Throw exceptions to deal with not enough memory and similar problems." OFF) option(USE_FIXEDPOINT "Use fixed point arithmetic in the Splash backend" OFF) @@ -132,6 +133,11 @@ if(ENABLE_LCMS) find_package(LCMS) set(USE_CMS ${LCMS_FOUND}) endif(ENABLE_LCMS) +if(ENABLE_LIBCURL) + find_package(CURL) + include_directories(${CURL_INCLUDE_DIR}) + set(POPPLER_HAS_CURL_SUPPORT ON) +endif(ENABLE_LIBCURL) add_definitions(-DHAVE_CONFIG_H=1) if(FONTCONFIG_FOUND) @@ -311,6 +317,12 @@ if(ENABLE_ZLIB) ) set(poppler_LIBS ${poppler_LIBS} ${ZLIB_LIBRARIES}) endif(ENABLE_ZLIB) +if(ENABLE_LIBCURL) + set(poppler_SRCS ${poppler_SRCS} + poppler/CurlCachedFile.cc + ) + set(poppler_LIBS ${poppler_LIBS} ${CURL_LIBRARIES}) +endif(ENABLE_LIBCURL) if(LIBOPENJPEG_FOUND) set(poppler_SRCS ${poppler_SRCS} poppler/JPEG2000Stream.cc @@ -442,6 +454,11 @@ if(ENABLE_XPDF_HEADERS) fofi/FoFiType1.h fofi/FoFiType1C.h DESTINATION include/poppler/fofi) + if(ENABLE_LIBCURL) + install(FILES + poppler/CurlCachedFile.h + DESTINATION include/poppler) + endif(ENABLE_LIBCURL) if(LIBOPENJPEG_FOUND) install(FILES poppler/JPEG2000Stream.h @@ -552,6 +569,7 @@ show_end_message("use gtk-doc" "not supported with this CMake build system") show_end_message_yesno("use libjpeg" ENABLE_LIBJPEG) show_end_message_yesno("use libpng" ENABLE_LIBPNG) show_end_message_yesno("use zlib" ENABLE_ZLIB) +show_end_message_yesno("use curl" ENABLE_LIBCURL) show_end_message_yesno("use libopenjpeg" LIBOPENJPEG_FOUND) show_end_message_yesno("use cms" USE_CMS) show_end_message_yesno("command line utils" ENABLE_UTILS) diff --git a/config.h.cmake b/config.h.cmake index 70d8d5d..0879aeb 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -1,5 +1,8 @@ /* config.h. Generated from config.h.cmake by cmake. */ +/* Build against libcurl. */ +#cmakedefine ENABLE_LIBCURL 1 + /* Use libjpeg instead of builtin jpeg decoder. */ #cmakedefine ENABLE_LIBJPEG 1 @@ -153,6 +156,9 @@ /* Poppler data dir */ #define POPPLER_DATADIR "${CMAKE_INSTALL_PREFIX}/share/poppler" +/* Support for curl based doc builder is compiled in. */ +#cmakedefine POPPLER_HAS_CURL_SUPPORT 1 + /* Have GDK */ #cmakedefine POPPLER_WITH_GDK 1 diff --git a/configure.ac b/configure.ac index 68509ee..72041d5 100644 --- a/configure.ac +++ b/configure.ac @@ -210,6 +210,21 @@ AM_CONDITIONAL(BUILD_ZLIB, test x$enable_zlib = xyes) AH_TEMPLATE([ENABLE_ZLIB], [Use zlib instead of builtin zlib decoder.]) +dnl Test for libcurl +AC_ARG_ENABLE(libcurl, + AC_HELP_STRING([--enable-libcurl], + [Build with libcurl based HTTP support.]), + enable_libcurl=$enableval, + enable_libcurl="no") + +if test x$enable_libcurl = xyes; then + PKG_CHECK_MODULES(LIBCURL, libcurl) + AC_DEFINE(ENABLE_LIBCURL, 1, [Build against libcurl.]) + AC_DEFINE(POPPLER_HAS_CURL_SUPPORT, 1, + [Support for curl based doc builder is compiled in.]) +fi + +AM_CONDITIONAL(BUILD_LIBCURL, test x$enable_libcurl = xyes) dnl Test for libjpeg AC_ARG_ENABLE(libjpeg, @@ -651,6 +666,7 @@ echo " use gtk-doc: $enable_gtk_doc" echo " use libjpeg: $enable_libjpeg" echo " use libpng: $enable_libpng" echo " use zlib: $enable_zlib" +echo " use libcurl: $enable_libcurl" echo " use libopenjpeg: $enable_libopenjpeg" echo " use cms: $enable_cms" echo " command line utils: $enable_utils" diff --git a/poppler/CurlCachedFile.cc b/poppler/CurlCachedFile.cc new file mode 100644 index 0000000..b326fb7 --- /dev/null +++ b/poppler/CurlCachedFile.cc @@ -0,0 +1,95 @@ +//======================================================================== +// +// CurlCachedFile.cc +// +// This file is licensed under the GPLv2 or later +// +// Copyright 2009 Stefan Thomas +// Copyright 2010 Hib Eris +// +//======================================================================== + +#include + +#include "CurlCachedFile.h" + +#include "goo/GooString.h" +#include "goo/GooVector.h" + +//------------------------------------------------------------------------ + +CurlCachedFileLoader::CurlCachedFileLoader() +{ + url = NULL; + cachedFile = NULL; + curl = NULL; +} + +CurlCachedFileLoader::~CurlCachedFileLoader() { + curl_easy_cleanup(curl); +} + +static size_t +noop_cb(char *ptr, size_t size, size_t nmemb, void *ptr2) +{ + return size*nmemb; +} + +size_t +CurlCachedFileLoader::init(GooString *urlA, CachedFile *cachedFileA) +{ + long code = NULL; + double contentLength = -1; + size_t size; + + url = urlA; + cachedFile = cachedFileA; + curl = curl_easy_init(); + + curl_easy_setopt(curl, CURLOPT_URL, url->getCString()); + curl_easy_setopt(curl, CURLOPT_HEADER, 1); + curl_easy_setopt(curl, CURLOPT_NOBODY, 1); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &noop_cb); + curl_easy_perform(curl); + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code); + curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &contentLength); + curl_easy_reset(curl); + + size = contentLength; + + return size; +} + +static +size_t load_cb(const char *ptr, size_t size, size_t nmemb, void *data) +{ + CachedFileWriter *writer = (CachedFileWriter *) data; + return (writer->write) (ptr, size*nmemb); +} + +int CurlCachedFileLoader::load(GooVector *ranges, CachedFileWriter *writer) +{ + CURLcode r = CURLE_OK; + size_t fromByte, toByte; + for (size_t i = 0; i < (*ranges).size(); i++) { + + fromByte = (*ranges)[i].offset; + toByte = fromByte + (*ranges)[i].length - 1; + GooString *range = GooString::format("{0:ud}-{1:ud}", fromByte, toByte); + + curl_easy_setopt(curl, CURLOPT_URL, url->getCString()); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, load_cb); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, writer); + curl_easy_setopt(curl, CURLOPT_RANGE, range->getCString()); + r = curl_easy_perform(curl); + curl_easy_reset(curl); + + delete range; + + if (r != CURLE_OK) break; + } + return r; +} + +//------------------------------------------------------------------------ + diff --git a/poppler/CurlCachedFile.h b/poppler/CurlCachedFile.h new file mode 100644 index 0000000..b18b7f8 --- /dev/null +++ b/poppler/CurlCachedFile.h @@ -0,0 +1,39 @@ +//======================================================================== +// +// CurlCachedFile.h +// +// This file is licensed under the GPLv2 or later +// +// Copyright 2010 Hib Eris +// +//======================================================================== + +#ifndef CURLCACHELOADER_H +#define CURLCACHELOADER_H + +#include "poppler-config.h" +#include "CachedFile.h" + +#include + +//------------------------------------------------------------------------ + +class CurlCachedFileLoader : public CachedFileLoader { + +public: + + CurlCachedFileLoader(); + ~CurlCachedFileLoader(); + size_t init(GooString *url, CachedFile* cachedFile); + int load(GooVector *ranges, CachedFileWriter *writer); + +private: + + GooString *url; + CachedFile *cachedFile; + CURL *curl; + +}; + +#endif + diff --git a/poppler/Makefile.am b/poppler/Makefile.am index a6bb9e9..5cd68a4 100644 --- a/poppler/Makefile.am +++ b/poppler/Makefile.am @@ -102,6 +102,22 @@ zlib_libs = \ endif +if BUILD_LIBCURL + +libcurl_libs = \ + $(LIBCURL_LIBS) + +libcurl_includes = \ + $(LIBCURL_CFLAGS) + +curl_headers = \ + CurlCachedFile.h + +curl_sources = \ + CurlCachedFile.cc + +endif + if BUILD_ABIWORD_OUTPUT abiword_sources = \ @@ -130,6 +146,7 @@ INCLUDES = \ $(arthur_includes) \ $(abiword_includes) \ $(libpng_includes) \ + $(libcurl_includes) \ $(FREETYPE_CFLAGS) \ $(FONTCONFIG_CFLAGS) @@ -149,6 +166,7 @@ libpoppler_la_LIBADD = \ $(libjpeg_libs) \ $(libpng_libs) \ $(zlib_libs) \ + $(libcurl_libs) \ $(libjpeg2000_libs) \ $(abiword_libs) \ $(FREETYPE_LIBS) \ @@ -163,6 +181,7 @@ if ENABLE_XPDF_HEADERS poppler_includedir = $(includedir)/poppler poppler_include_HEADERS = \ $(splash_headers) \ + $(curl_headers) \ Annot.h \ Array.h \ BuiltinFont.h \ @@ -237,6 +256,7 @@ libpoppler_la_SOURCES = \ $(zlib_sources) \ $(libjpeg2000_sources) \ $(abiword_sources) \ + $(curl_sources) \ Annot.cc \ Array.cc \ BuiltinFont.cc \ diff --git a/poppler/poppler-config.h.cmake b/poppler/poppler-config.h.cmake index 7656e4f..95e95cc 100644 --- a/poppler/poppler-config.h.cmake +++ b/poppler/poppler-config.h.cmake @@ -49,6 +49,11 @@ #cmakedefine WITH_FONTCONFIGURATION_WIN32 1 #endif +/* Support for curl is compiled in. */ +#ifndef POPPLER_HAS_CURL_SUPPORT +#cmakedefine POPPLER_HAS_CURL_SUPPORT 1 +#endif + // Also, there's a couple of preprocessor symbols in the header files // that are used but never defined: DISABLE_OUTLINE, DEBUG_MEM and diff --git a/poppler/poppler-config.h.in b/poppler/poppler-config.h.in index f8db4ba..7b0644c 100644 --- a/poppler/poppler-config.h.in +++ b/poppler/poppler-config.h.in @@ -49,6 +49,11 @@ #undef WITH_FONTCONFIGURATION_WIN32 #endif +/* Support for curl is compiled in. */ +#ifndef POPPLER_HAS_CURL_SUPPORT +#undef POPPLER_HAS_CURL_SUPPORT +#endif + // Also, there's a couple of preprocessor symbols in the header files // that are used but never defined: DISABLE_OUTLINE, DEBUG_MEM and diff --git a/utils/pdfinfo.cc b/utils/pdfinfo.cc index ceddd47..48504d2 100644 --- a/utils/pdfinfo.cc +++ b/utils/pdfinfo.cc @@ -49,6 +49,9 @@ #include "Error.h" #include "DateInfo.h" #include "StdinCachedFile.h" +#if ENABLE_LIBCURL +#include "CurlCachedFile.h" +#endif static void printInfoString(Dict *infoDict, char *key, char *text, UnicodeMap *uMap); @@ -160,7 +163,18 @@ int main(int argc, char *argv[]) { userPW = NULL; } - if(fileName->cmp("-") != 0) { +#if ENABLE_LIBCURL + if (fileName->cmpN("http://", 7) == 0 || + fileName->cmpN("https://", 8) == 0) { + Object obj; + + obj.initNull(); + CachedFile *cachedFile = new CachedFile(new CurlCachedFileLoader(), fileName); + doc = new PDFDoc(new CachedFileStream(cachedFile, 0, gFalse, 0, &obj), + ownerPW, userPW); + } else +#endif + if (fileName->cmp("-") != 0) { doc = new PDFDoc(fileName, ownerPW, userPW); } else { Object obj; -- 1.6.4.2 From 09f44f62b89c47e7e1a0ec5ba6749297fdc341e4 Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Sun, 4 Apr 2010 11:17:37 +0200 Subject: [PATCH 05/11] Cleanup PDFDoc --- poppler/PDFDoc.cc | 40 +++++++++++++++------------------------- poppler/PDFDoc.h | 3 ++- 2 files changed, 17 insertions(+), 26 deletions(-) diff --git a/poppler/PDFDoc.cc b/poppler/PDFDoc.cc index b088f6c..12aff3c 100644 --- a/poppler/PDFDoc.cc +++ b/poppler/PDFDoc.cc @@ -21,6 +21,7 @@ // Copyright (C) 2009 Eric Toombs // Copyright (C) 2009 Kovid Goyal // Copyright (C) 2009 Axel Struebing +// Copyright (C) 2010 Hib Eris // // 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 @@ -73,15 +74,11 @@ // PDFDoc //------------------------------------------------------------------------ -PDFDoc::PDFDoc(GooString *fileNameA, GooString *ownerPassword, - GooString *userPassword, void *guiDataA) { - Object obj; - +void PDFDoc::init() +{ ok = gFalse; errCode = errNone; - - guiData = guiDataA; - + fileName = NULL; file = NULL; str = NULL; xref = NULL; @@ -89,8 +86,16 @@ PDFDoc::PDFDoc(GooString *fileNameA, GooString *ownerPassword, #ifndef DISABLE_OUTLINE outline = NULL; #endif +} + +PDFDoc::PDFDoc(GooString *fileNameA, GooString *ownerPassword, + GooString *userPassword, void *guiDataA) { + Object obj; + + init(); fileName = fileNameA; + guiData = guiDataA; // try to open file #ifdef VMS @@ -124,19 +129,10 @@ PDFDoc::PDFDoc(wchar_t *fileNameA, int fileNameLen, GooString *ownerPassword, Object obj; int i; - ok = gFalse; - errCode = errNone; + init(); guiData = guiDataA; - file = NULL; - str = NULL; - xref = NULL; - catalog = NULL; -#ifndef DISABLE_OUTLINE - outline = NULL; -#endif - //~ file name should be stored in Unicode (?) fileName = new GooString(); for (i = 0; i < fileNameLen; ++i) { @@ -174,21 +170,15 @@ PDFDoc::PDFDoc(wchar_t *fileNameA, int fileNameLen, GooString *ownerPassword, PDFDoc::PDFDoc(BaseStream *strA, GooString *ownerPassword, GooString *userPassword, void *guiDataA) { - ok = gFalse; - errCode = errNone; + + init(); guiData = guiDataA; if (strA->getFileName()) { fileName = strA->getFileName()->copy(); } else { fileName = NULL; } - file = NULL; str = strA; - xref = NULL; - catalog = NULL; -#ifndef DISABLE_OUTLINE - outline = NULL; -#endif ok = setup(ownerPassword, userPassword); } diff --git a/poppler/PDFDoc.h b/poppler/PDFDoc.h index 3db4b91..08e9da8 100644 --- a/poppler/PDFDoc.h +++ b/poppler/PDFDoc.h @@ -20,6 +20,7 @@ // Copyright (C) 2008 Carlos Garcia Campos // Copyright (C) 2009 Eric Toombs // Copyright (C) 2009 Kovid Goyal +// Copyright (C) 2010 Hib Eris // // 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 @@ -226,7 +227,7 @@ private: void saveIncrementalUpdate (OutStream* outStr); void saveCompleteRewrite (OutStream* outStr); - + void init(); GBool setup(GooString *ownerPassword, GooString *userPassword); GBool checkFooter(); void checkHeader(); -- 1.6.4.2 From ab4616d00dfe038cc89bfb30cd3e8af7a54699f5 Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Sun, 4 Apr 2010 11:29:53 +0200 Subject: [PATCH 06/11] Add PDFDoc::ErrorPDFDoc --- poppler/PDFDoc.cc | 14 ++++++++++++++ poppler/PDFDoc.h | 3 +++ 2 files changed, 17 insertions(+), 0 deletions(-) diff --git a/poppler/PDFDoc.cc b/poppler/PDFDoc.cc index 12aff3c..78b6593 100644 --- a/poppler/PDFDoc.cc +++ b/poppler/PDFDoc.cc @@ -88,6 +88,11 @@ void PDFDoc::init() #endif } +PDFDoc::PDFDoc() +{ + init(); +} + PDFDoc::PDFDoc(GooString *fileNameA, GooString *ownerPassword, GooString *userPassword, void *guiDataA) { Object obj; @@ -902,3 +907,12 @@ void PDFDoc::writeTrailer (Guint uxrefOffset, int uxrefSize, OutStream* outStr, delete trailerDict; } + +PDFDoc *PDFDoc::ErrorPDFDoc(int errorCode, GooString *fileNameA) +{ + PDFDoc *doc = new PDFDoc(); + doc->errCode = errorCode; + doc->fileName = fileNameA; + + return doc; +} diff --git a/poppler/PDFDoc.h b/poppler/PDFDoc.h index 08e9da8..79f6d6d 100644 --- a/poppler/PDFDoc.h +++ b/poppler/PDFDoc.h @@ -74,6 +74,8 @@ public: GooString *userPassword = NULL, void *guiDataA = NULL); ~PDFDoc(); + static PDFDoc *ErrorPDFDoc(int errorCode, GooString *fileNameA = NULL); + // Was PDF document successfully opened? GBool isOk() { return ok; } @@ -227,6 +229,7 @@ private: void saveIncrementalUpdate (OutStream* outStr); void saveCompleteRewrite (OutStream* outStr); + PDFDoc(); void init(); GBool setup(GooString *ownerPassword, GooString *userPassword); GBool checkFooter(); -- 1.6.4.2 From ef3af1851b7aac414afdf7701421cc2519339600 Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Sun, 4 Apr 2010 11:05:35 +0200 Subject: [PATCH 07/11] Add PDFDocBuilder --- CMakeLists.txt | 1 + poppler/Makefile.am | 1 + poppler/PDFDocBuilder.h | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 0 deletions(-) create mode 100644 poppler/PDFDocBuilder.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 70b0e06..3245730 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -400,6 +400,7 @@ if(ENABLE_XPDF_HEADERS) poppler/PageTransition.h poppler/Parser.h poppler/PDFDoc.h + poppler/PDFDocBuilder.h poppler/PDFDocEncoding.h poppler/PopplerCache.h poppler/ProfileData.h diff --git a/poppler/Makefile.am b/poppler/Makefile.am index 5cd68a4..a013460 100644 --- a/poppler/Makefile.am +++ b/poppler/Makefile.am @@ -218,6 +218,7 @@ poppler_include_HEADERS = \ PageTransition.h \ Parser.h \ PDFDoc.h \ + PDFDocBuilder.h \ PDFDocEncoding.h \ PopplerCache.h \ ProfileData.h \ diff --git a/poppler/PDFDocBuilder.h b/poppler/PDFDocBuilder.h new file mode 100644 index 0000000..8a1350b --- /dev/null +++ b/poppler/PDFDocBuilder.h @@ -0,0 +1,32 @@ +//======================================================================== +// +// PDFDocBuilder.h +// +// This file is licensed under the GPLv2 or later +// +// Copyright 2010 Hib Eris +// +//======================================================================== + +#ifndef PDFDOCBUILDER_H +#define PDFDOCBUILDER_H + +#include "PDFDoc.h" +class GooString; + +//------------------------------------------------------------------------ +// PDFDocBuilder +//------------------------------------------------------------------------ + +class PDFDocBuilder { + +public: + + virtual ~PDFDocBuilder() {}; + virtual PDFDoc *buildPDFDoc(GooString* uri, GooString *ownerPassword = NULL, + GooString *userPassword = NULL, void *guiDataA = NULL) = 0; + virtual GBool supports(GooString* uri) = 0; + +}; + +#endif /* PDFDOCBUILDER_H */ -- 1.6.4.2 From 40c3b1d6cf78337f1f4e3c17f520bedda70c6874 Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Thu, 25 Feb 2010 11:23:28 +0100 Subject: [PATCH 08/11] Add LocalPDFDocBuilder and StdinPDFDocBuilder --- CMakeLists.txt | 4 +++ poppler/LocalPDFDocBuilder.cc | 45 +++++++++++++++++++++++++++++++++++++++++ poppler/LocalPDFDocBuilder.h | 30 +++++++++++++++++++++++++++ poppler/Makefile.am | 4 +++ poppler/StdinPDFDocBuilder.cc | 42 ++++++++++++++++++++++++++++++++++++++ poppler/StdinPDFDocBuilder.h | 30 +++++++++++++++++++++++++++ 6 files changed, 155 insertions(+), 0 deletions(-) create mode 100644 poppler/LocalPDFDocBuilder.cc create mode 100644 poppler/LocalPDFDocBuilder.h create mode 100644 poppler/StdinPDFDocBuilder.cc create mode 100644 poppler/StdinPDFDocBuilder.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 3245730..cc255a5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -249,6 +249,7 @@ set(poppler_SRCS poppler/JBIG2Stream.cc poppler/Lexer.cc poppler/Link.cc + poppler/LocalPDFDocBuilder.cc poppler/NameToCharCode.cc poppler/Object.cc poppler/OptionalContent.cc @@ -272,6 +273,7 @@ set(poppler_SRCS poppler/PageLabelInfo.cc poppler/SecurityHandler.cc poppler/StdinCachedFile.cc + poppler/StdinPDFDocBuilder.cc poppler/Sound.cc poppler/XpdfPluginAPI.cc poppler/Movie.cc @@ -390,6 +392,7 @@ if(ENABLE_XPDF_HEADERS) poppler/JBIG2Stream.h poppler/Lexer.h poppler/Link.h + poppler/LocalPDFDocBuilder.h poppler/Movie.h poppler/NameToCharCode.h poppler/Object.h @@ -424,6 +427,7 @@ if(ENABLE_XPDF_HEADERS) poppler/TextOutputDev.h poppler/SecurityHandler.h poppler/StdinCachedFile.h + poppler/StdinPDFDocBuilder.h poppler/UTF8.h poppler/XpdfPluginAPI.h poppler/Sound.h diff --git a/poppler/LocalPDFDocBuilder.cc b/poppler/LocalPDFDocBuilder.cc new file mode 100644 index 0000000..c54faac --- /dev/null +++ b/poppler/LocalPDFDocBuilder.cc @@ -0,0 +1,45 @@ +//======================================================================== +// +// LocalPDFDocBuilder.cc +// +// This file is licensed under the GPLv2 or later +// +// Copyright 2010 Hib Eris +// +//======================================================================== + +#include + +#include "LocalPDFDocBuilder.h" + +//------------------------------------------------------------------------ +// LocalPDFDocBuilder +//------------------------------------------------------------------------ + +PDFDoc * +LocalPDFDocBuilder::buildPDFDoc( + GooString* uri, GooString *ownerPassword, GooString + *userPassword, void *guiDataA) +{ + if (uri->cmpN("file://", 7) == 0) { + GooString *fileName = new GooString(uri); + fileName->del(0, 7); + return new PDFDoc(fileName, ownerPassword, userPassword, guiDataA); + } else { + GooString *fileName = new GooString(uri); + return new PDFDoc(fileName, ownerPassword, userPassword, guiDataA); + } +} + +GBool LocalPDFDocBuilder::supports(GooString* uri) +{ + if (uri->cmpN("file://", 7) == 0) { + return gTrue; + } else if (!strstr(uri->getCString(), "://")) { + return gTrue; + } else { + return gFalse; + } +} + + diff --git a/poppler/LocalPDFDocBuilder.h b/poppler/LocalPDFDocBuilder.h new file mode 100644 index 0000000..439a131 --- /dev/null +++ b/poppler/LocalPDFDocBuilder.h @@ -0,0 +1,30 @@ +//======================================================================== +// +// LocalPDFDocBuilder.h +// +// This file is licensed under the GPLv2 or later +// +// Copyright 2010 Hib Eris +// +//======================================================================== + +#ifndef LOCALPDFDOCBUILDER_H +#define LOCALPDFDOCBUILDER_H + +#include "PDFDocBuilder.h" + +//------------------------------------------------------------------------ +// LocalPDFDocBuilder +//------------------------------------------------------------------------ + +class LocalPDFDocBuilder : public PDFDocBuilder { + +public: + + PDFDoc *buildPDFDoc(GooString* uri, GooString *ownerPassword = NULL, + GooString *userPassword = NULL, void *guiDataA = NULL); + GBool supports(GooString* uri); + +}; + +#endif /* LOCALPDFDOCBUILDER_H */ diff --git a/poppler/Makefile.am b/poppler/Makefile.am index a013460..3eb84fd 100644 --- a/poppler/Makefile.am +++ b/poppler/Makefile.am @@ -208,6 +208,7 @@ poppler_include_HEADERS = \ JBIG2Stream.h \ Lexer.h \ Link.h \ + LocalPDFDocBuilder.h \ Movie.h \ NameToCharCode.h \ Object.h \ @@ -226,6 +227,7 @@ poppler_include_HEADERS = \ PSTokenizer.h \ Rendition.h \ StdinCachedFile.h \ + StdinPDFDocBuilder.h \ Stream-CCITT.h \ Stream.h \ UnicodeMap.h \ @@ -283,6 +285,7 @@ libpoppler_la_SOURCES = \ JBIG2Stream.cc \ Lexer.cc \ Link.cc \ + LocalPDFDocBuilder.cc \ Movie.cc \ NameToCharCode.cc \ Object.cc \ @@ -300,6 +303,7 @@ libpoppler_la_SOURCES = \ PSTokenizer.cc \ Rendition.cc \ StdinCachedFile.cc \ + StdinPDFDocBuilder.cc \ Stream.cc \ UnicodeMap.cc \ UnicodeTypeTable.cc \ diff --git a/poppler/StdinPDFDocBuilder.cc b/poppler/StdinPDFDocBuilder.cc new file mode 100644 index 0000000..e260615 --- /dev/null +++ b/poppler/StdinPDFDocBuilder.cc @@ -0,0 +1,42 @@ +//======================================================================== +// +// StdinPDFDocBuilder.cc +// +// This file is licensed under the GPLv2 or later +// +// Copyright 2010 Hib Eris +// +//======================================================================== + +#include + +#include "StdinPDFDocBuilder.h" +#include "CachedFile.h" +#include "StdinCachedFile.h" + +//------------------------------------------------------------------------ +// StdinPDFDocBuilder +//------------------------------------------------------------------------ + +PDFDoc * +StdinPDFDocBuilder::buildPDFDoc(GooString* uri, GooString *ownerPassword, + GooString *userPassword, void *guiDataA) +{ + Object obj; + + obj.initNull(); + CachedFile *cachedFile = new CachedFile(new StdinCacheLoader(), NULL); + return new PDFDoc(new CachedFileStream(cachedFile, 0, gFalse, + cachedFile->getLength(), &obj), + ownerPassword, userPassword); +} + +GBool StdinPDFDocBuilder::supports(GooString* uri) +{ + if (uri->cmpN("fd://0", 6) == 0) { + return gTrue; + } else { + return gFalse; + } +} + diff --git a/poppler/StdinPDFDocBuilder.h b/poppler/StdinPDFDocBuilder.h new file mode 100644 index 0000000..fae32c0 --- /dev/null +++ b/poppler/StdinPDFDocBuilder.h @@ -0,0 +1,30 @@ +//======================================================================== +// +// StdinPDFDocBuilder.h +// +// This file is licensed under the GPLv2 or later +// +// Copyright 2010 Hib Eris +// +//======================================================================== + +#ifndef STDINPDFDOCBUILDER_H +#define STDINPDFDOCBUILDER_H + +#include "PDFDocBuilder.h" + +//------------------------------------------------------------------------ +// StdinPDFDocBuilder +//------------------------------------------------------------------------ + +class StdinPDFDocBuilder : public PDFDocBuilder { + +public: + + PDFDoc *buildPDFDoc(GooString* uri, GooString *ownerPassword = NULL, + GooString *userPassword = NULL, void *guiDataA = NULL); + GBool supports(GooString* uri); + +}; + +#endif /* STDINPDFDOCBUILDER_H */ -- 1.6.4.2 From 2f7a1cff2f70352791861f4fca61b9220e6b9c37 Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Wed, 24 Feb 2010 15:24:26 +0100 Subject: [PATCH 09/11] Add CurlPDFDocBuilder --- CMakeLists.txt | 2 + poppler/CurlPDFDocBuilder.cc | 46 ++++++++++++++++++++++++++++++++++++++++++ poppler/CurlPDFDocBuilder.h | 30 +++++++++++++++++++++++++++ poppler/Makefile.am | 6 +++- 4 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 poppler/CurlPDFDocBuilder.cc create mode 100644 poppler/CurlPDFDocBuilder.h diff --git a/CMakeLists.txt b/CMakeLists.txt index cc255a5..562f89c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -322,6 +322,7 @@ endif(ENABLE_ZLIB) if(ENABLE_LIBCURL) set(poppler_SRCS ${poppler_SRCS} poppler/CurlCachedFile.cc + poppler/CurlPDFDocBuilder.cc ) set(poppler_LIBS ${poppler_LIBS} ${CURL_LIBRARIES}) endif(ENABLE_LIBCURL) @@ -462,6 +463,7 @@ if(ENABLE_XPDF_HEADERS) if(ENABLE_LIBCURL) install(FILES poppler/CurlCachedFile.h + poppler/CurlPDFDocBuilder.h DESTINATION include/poppler) endif(ENABLE_LIBCURL) if(LIBOPENJPEG_FOUND) diff --git a/poppler/CurlPDFDocBuilder.cc b/poppler/CurlPDFDocBuilder.cc new file mode 100644 index 0000000..251a4eb --- /dev/null +++ b/poppler/CurlPDFDocBuilder.cc @@ -0,0 +1,46 @@ +//======================================================================== +// +// CurlPDFDocBuilder.cc +// +// This file is licensed under the GPLv2 or later +// +// Copyright 2010 Hib Eris +// +//======================================================================== + +#include + +#include "CurlPDFDocBuilder.h" + +#include "CachedFile.h" +#include "CurlCachedFile.h" + +//------------------------------------------------------------------------ +// CurlPDFDocBuilder +//------------------------------------------------------------------------ + +PDFDoc * +CurlPDFDocBuilder::buildPDFDoc(GooString* uri, + GooString *ownerPassword, GooString *userPassword, void *guiDataA) +{ + Object obj; + + CachedFile *cachedFile = new CachedFile( + new CurlCachedFileLoader(), new GooString(uri)); + + obj.initNull(); + BaseStream *str = new CachedFileStream( + cachedFile, 0, gFalse, cachedFile->getLength(), &obj); + + return new PDFDoc(str, ownerPassword, userPassword, guiDataA); +} + +GBool CurlPDFDocBuilder::supports(GooString* uri) +{ + if (uri->cmpN("http://", 7) == 0 || uri->cmpN("https://", 8) == 0) { + return gTrue; + } else { + return gFalse; + } +}; + diff --git a/poppler/CurlPDFDocBuilder.h b/poppler/CurlPDFDocBuilder.h new file mode 100644 index 0000000..e84a4c7 --- /dev/null +++ b/poppler/CurlPDFDocBuilder.h @@ -0,0 +1,30 @@ +//======================================================================== +// +// CurlPDFDocBuilder.h +// +// This file is licensed under the GPLv2 or later +// +// Copyright 2010 Hib Eris +// +//======================================================================== + +#ifndef CURLPDFDOCBUILDER_H +#define CURLPDFDOCBUILDER_H + +#include "PDFDocBuilder.h" + +//------------------------------------------------------------------------ +// CurlPDFDocBuilder +//------------------------------------------------------------------------ + +class CurlPDFDocBuilder : public PDFDocBuilder { + +public: + + PDFDoc *buildPDFDoc(GooString* uri, GooString *ownerPassword = NULL, + GooString *userPassword = NULL, void *guiDataA = NULL); + GBool supports(GooString* uri); + +}; + +#endif /* CURLPDFDOCBUILDER_H */ diff --git a/poppler/Makefile.am b/poppler/Makefile.am index 3eb84fd..6717734 100644 --- a/poppler/Makefile.am +++ b/poppler/Makefile.am @@ -111,10 +111,12 @@ libcurl_includes = \ $(LIBCURL_CFLAGS) curl_headers = \ - CurlCachedFile.h + CurlCachedFile.h \ + CurlPDFDocBuilder.h curl_sources = \ - CurlCachedFile.cc + CurlCachedFile.cc \ + CurlPDFDocBuilder.cc endif -- 1.6.4.2 From 2b5ebb6bcdac2b7541948c02406ae6b023fa4c2d Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Mon, 5 Apr 2010 14:35:52 +0200 Subject: [PATCH 10/11] Add PDFDocFactory --- CMakeLists.txt | 2 + poppler/Makefile.am | 2 + poppler/PDFDocFactory.cc | 71 ++++++++++++++++++++++++++++++++++++++++++++++ poppler/PDFDocFactory.h | 42 +++++++++++++++++++++++++++ 4 files changed, 117 insertions(+), 0 deletions(-) create mode 100644 poppler/PDFDocFactory.cc create mode 100644 poppler/PDFDocFactory.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 562f89c..0725747 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -260,6 +260,7 @@ set(poppler_SRCS poppler/Parser.cc poppler/PDFDoc.cc poppler/PDFDocEncoding.cc + poppler/PDFDocFactory.cc poppler/PopplerCache.cc poppler/ProfileData.cc poppler/PreScanOutputDev.cc @@ -406,6 +407,7 @@ if(ENABLE_XPDF_HEADERS) poppler/PDFDoc.h poppler/PDFDocBuilder.h poppler/PDFDocEncoding.h + poppler/PDFDocFactory.h poppler/PopplerCache.h poppler/ProfileData.h poppler/PreScanOutputDev.h diff --git a/poppler/Makefile.am b/poppler/Makefile.am index 6717734..5dd8082 100644 --- a/poppler/Makefile.am +++ b/poppler/Makefile.am @@ -223,6 +223,7 @@ poppler_include_HEADERS = \ PDFDoc.h \ PDFDocBuilder.h \ PDFDocEncoding.h \ + PDFDocFactory.h \ PopplerCache.h \ ProfileData.h \ PreScanOutputDev.h \ @@ -299,6 +300,7 @@ libpoppler_la_SOURCES = \ Parser.cc \ PDFDoc.cc \ PDFDocEncoding.cc \ + PDFDocFactory.cc \ PopplerCache.cc \ ProfileData.cc \ PreScanOutputDev.cc \ diff --git a/poppler/PDFDocFactory.cc b/poppler/PDFDocFactory.cc new file mode 100644 index 0000000..d8b5fcc --- /dev/null +++ b/poppler/PDFDocFactory.cc @@ -0,0 +1,71 @@ +//======================================================================== +// +// PDFDocFactory.cc +// +// This file is licensed under the GPLv2 or later +// +// Copyright 2010 Hib Eris +// +//======================================================================== + +#include + +#include "PDFDocFactory.h" + +#include "goo/GooList.h" +#include "goo/GooString.h" +#include "PDFDoc.h" +#include "LocalPDFDocBuilder.h" +#include "StdinPDFDocBuilder.h" +#if ENABLE_LIBCURL +#include "CurlPDFDocBuilder.h" +#endif +#include "ErrorCodes.h" + +//------------------------------------------------------------------------ +// PDFDocFactory +//------------------------------------------------------------------------ + +PDFDocFactory::PDFDocFactory(GooList *pdfDocBuilders) +{ + if (pdfDocBuilders) { + builders = pdfDocBuilders; + } else { + builders = new GooList(); + } +#if ENABLE_LIBCURL + builders->insert(0, new CurlPDFDocBuilder()); +#endif + builders->insert(0, new StdinPDFDocBuilder()); + builders->insert(0, new LocalPDFDocBuilder()); +} + +PDFDocFactory::~PDFDocFactory() +{ + if (builders) { + deleteGooList(builders, PDFDocBuilder); + } +} + +PDFDoc * +PDFDocFactory::createPDFDoc(GooString* uri, GooString *ownerPassword, + GooString *userPassword, void *guiDataA) +{ + for (int i = builders->getLength() - 1; i >= 0 ; i--) { + PDFDocBuilder *builder = (PDFDocBuilder *) builders->get(i); + if (builder->supports(uri)) { + return builder->buildPDFDoc(uri, ownerPassword, userPassword, guiDataA); + } + } + + error(-1, "Cannot handle URI '%s'.", uri->getCString()); + GooString *fileName = new GooString(uri); + return PDFDoc::ErrorPDFDoc(errOpenFile, fileName); +} + +void PDFDocFactory::registerPDFDocBuilder(PDFDocBuilder *pdfDocBuilder) +{ + builders->append(pdfDocBuilder); +} + + diff --git a/poppler/PDFDocFactory.h b/poppler/PDFDocFactory.h new file mode 100644 index 0000000..00ee359 --- /dev/null +++ b/poppler/PDFDocFactory.h @@ -0,0 +1,42 @@ +//======================================================================== +// +// PDFDocFactory.h +// +// This file is licensed under the GPLv2 or later +// +// Copyright 2010 Hib Eris +// +//======================================================================== + +#ifndef PDFDOCFACTORY_H +#define PDFDOCFACTORY_H + +#include "PDFDoc.h" + +class GooList; +class GooString; +class PDFDocBuilder; + +//------------------------------------------------------------------------ +// PDFDocFactory +//------------------------------------------------------------------------ + +class PDFDocFactory { + +public: + + PDFDocFactory(GooList *pdfDocBuilders = NULL); + ~PDFDocFactory(); + + PDFDoc *createPDFDoc(GooString* uri, GooString *ownerPassword = NULL, + GooString *userPassword = NULL, void *guiDataA = NULL); + + void registerPDFDocBuilder(PDFDocBuilder *pdfDocBuilder); + +private: + + GooList *builders; + +}; + +#endif /* PDFDOCFACTORY_H */ -- 1.6.4.2 From 9b4cbb011b1ae96ae36367497745db04a9c71f04 Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Mon, 5 Apr 2010 14:36:09 +0200 Subject: [PATCH 11/11] Use PDFDocFactory in utils --- utils/pdffonts.cc | 16 ++++++++-------- utils/pdfimages.cc | 11 ++++++++++- utils/pdfinfo.cc | 31 +++++++------------------------ utils/pdftoabw.cc | 10 +++++++++- utils/pdftohtml.cc | 10 +++++++++- utils/pdftoppm.cc | 17 +++++++++++------ utils/pdftops.cc | 9 ++++++++- utils/pdftotext.cc | 14 +++++++------- 8 files changed, 69 insertions(+), 49 deletions(-) diff --git a/utils/pdffonts.cc b/utils/pdffonts.cc index 752fa15..4849f5f 100644 --- a/utils/pdffonts.cc +++ b/utils/pdffonts.cc @@ -15,6 +15,7 @@ // // Copyright (C) 2006 Dominic Lachowicz // Copyright (C) 2007-2008 Albert Astals Cid +// Copyright (C) 2010 Hib Eris // // 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 @@ -38,6 +39,7 @@ #include "GfxFont.h" #include "Annot.h" #include "PDFDoc.h" +#include "PDFDocFactory.h" static char *fontTypeNames[] = { "unknown", @@ -131,16 +133,14 @@ int main(int argc, char *argv[]) { } else { userPW = NULL; } - - if(fileName->cmp("-") != 0) { - doc = new PDFDoc(fileName, ownerPW, userPW); - } else { - Object obj; - - obj.initNull(); - doc = new PDFDoc(new FileStream(stdin, 0, gFalse, 0, &obj), ownerPW, userPW); + if (fileName->cmp("-") == 0) { + delete fileName; + fileName = new GooString("fd://0"); } + doc = PDFDocFactory().createPDFDoc(fileName, ownerPW, userPW); + delete fileName; + if (userPW) { delete userPW; } diff --git a/utils/pdfimages.cc b/utils/pdfimages.cc index b821c79..60766b7 100644 --- a/utils/pdfimages.cc +++ b/utils/pdfimages.cc @@ -16,6 +16,7 @@ // under GPL version 2 or later // // Copyright (C) 2007-2008 Albert Astals Cid +// Copyright (C) 2010 Hib Eris // // 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 @@ -40,6 +41,7 @@ #include "Catalog.h" #include "Page.h" #include "PDFDoc.h" +#include "PDFDocFactory.h" #include "ImageOutputDev.h" #include "Error.h" @@ -120,7 +122,14 @@ int main(int argc, char *argv[]) { } else { userPW = NULL; } - doc = new PDFDoc(fileName, ownerPW, userPW); + if (fileName->cmp("-") == 0) { + delete fileName; + fileName = new GooString("fd://0"); + } + + doc = PDFDocFactory().createPDFDoc(fileName, ownerPW, userPW); + delete fileName; + if (userPW) { delete userPW; } diff --git a/utils/pdfinfo.cc b/utils/pdfinfo.cc index 48504d2..9644e9d 100644 --- a/utils/pdfinfo.cc +++ b/utils/pdfinfo.cc @@ -43,15 +43,12 @@ #include "Catalog.h" #include "Page.h" #include "PDFDoc.h" +#include "PDFDocFactory.h" #include "CharTypes.h" #include "UnicodeMap.h" #include "PDFDocEncoding.h" #include "Error.h" #include "DateInfo.h" -#include "StdinCachedFile.h" -#if ENABLE_LIBCURL -#include "CurlCachedFile.h" -#endif static void printInfoString(Dict *infoDict, char *key, char *text, UnicodeMap *uMap); @@ -163,28 +160,14 @@ int main(int argc, char *argv[]) { userPW = NULL; } -#if ENABLE_LIBCURL - if (fileName->cmpN("http://", 7) == 0 || - fileName->cmpN("https://", 8) == 0) { - Object obj; - - obj.initNull(); - CachedFile *cachedFile = new CachedFile(new CurlCachedFileLoader(), fileName); - doc = new PDFDoc(new CachedFileStream(cachedFile, 0, gFalse, 0, &obj), - ownerPW, userPW); - } else -#endif - if (fileName->cmp("-") != 0) { - doc = new PDFDoc(fileName, ownerPW, userPW); - } else { - Object obj; - - obj.initNull(); - CachedFile *cachedFile = new CachedFile(new StdinCacheLoader(), NULL); - doc = new PDFDoc(new CachedFileStream(cachedFile, 0, gFalse, 0, &obj), - ownerPW, userPW); + if (fileName->cmp("-") == 0) { + delete fileName; + fileName = new GooString("fd://0"); } + doc = PDFDocFactory().createPDFDoc(fileName, ownerPW, userPW); + delete fileName; + if (userPW) { delete userPW; } diff --git a/utils/pdftoabw.cc b/utils/pdftoabw.cc index 9c71c76..5cb651c 100644 --- a/utils/pdftoabw.cc +++ b/utils/pdftoabw.cc @@ -4,6 +4,7 @@ * Copyright (C) 2007 Kouhei Sutou * Copyright (C) 2009 Jakub Wilk * Copyright (C) 2009 Albert Astals Cid + * Copyright (C) 2010 Hib Eris * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -41,6 +42,7 @@ #include "Catalog.h" #include "Page.h" #include "PDFDoc.h" +#include "PDFDocFactory.h" #include "ABWOutputDev.h" #include "PSOutputDev.h" #include "GlobalParams.h" @@ -136,7 +138,13 @@ int main(int argc, char *argv[]) { userPW = NULL; } - doc = new PDFDoc(fileName, ownerPW, userPW); + if (fileName->cmp("-") == 0) { + delete fileName; + fileName = new GooString("fd://0"); + } + + doc = PDFDocFactory().createPDFDoc(fileName, ownerPW, userPW); + delete fileName; if (userPW) { delete userPW; diff --git a/utils/pdftohtml.cc b/utils/pdftohtml.cc index 41312de..7e2ac92 100644 --- a/utils/pdftohtml.cc +++ b/utils/pdftohtml.cc @@ -14,6 +14,7 @@ // under GPL version 2 or later // // Copyright (C) 2007-2008 Albert Astals Cid +// Copyright (C) 2010 Hib Eris // // 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,6 +42,7 @@ #include "Catalog.h" #include "Page.h" #include "PDFDoc.h" +#include "PDFDocFactory.h" #include "HtmlOutputDev.h" #include "PSOutputDev.h" #include "GlobalParams.h" @@ -187,7 +189,13 @@ int main(int argc, char *argv[]) { fileName = new GooString(argv[1]); - doc = new PDFDoc(fileName, ownerPW, userPW); + if (fileName->cmp("-") == 0) { + delete fileName; + fileName = new GooString("fd://0"); + } + + doc = PDFDocFactory().createPDFDoc(fileName, ownerPW, userPW); + if (userPW) { delete userPW; } diff --git a/utils/pdftoppm.cc b/utils/pdftoppm.cc index 7d1e3bf..72d2a5d 100644 --- a/utils/pdftoppm.cc +++ b/utils/pdftoppm.cc @@ -20,6 +20,7 @@ // Copyright (C) 2009 Stefan Thomas // Copyright (C) 2009, 2010 Albert Astals Cid // Copyright (C) 2010 Adrian Johnson +// Copyright (C) 2010 Hib Eris // // To see a description of the changes please see the Changelog file that // came with your tarball or type make ChangeLog if you are building from git @@ -36,6 +37,7 @@ #include "GlobalParams.h" #include "Object.h" #include "PDFDoc.h" +#include "PDFDocFactory.h" #include "splash/SplashBitmap.h" #include "splash/Splash.h" #include "SplashOutputDev.h" @@ -256,14 +258,17 @@ int main(int argc, char *argv[]) { } else { userPW = NULL; } - if(fileName != NULL && fileName->cmp("-") != 0) { - doc = new PDFDoc(fileName, ownerPW, userPW); - } else { - Object obj; - obj.initNull(); - doc = new PDFDoc(new FileStream(stdin, 0, gFalse, 0, &obj), ownerPW, userPW); + if (fileName == NULL) { + fileName = new GooString("fd://0"); + } + if (fileName->cmp("-") == 0) { + delete fileName; + fileName = new GooString("fd://0"); } + doc = PDFDocFactory().createPDFDoc(fileName, ownerPW, userPW); + delete fileName; + if (userPW) { delete userPW; } diff --git a/utils/pdftops.cc b/utils/pdftops.cc index 69d5c32..c549b4a 100644 --- a/utils/pdftops.cc +++ b/utils/pdftops.cc @@ -44,6 +44,7 @@ #include "Catalog.h" #include "Page.h" #include "PDFDoc.h" +#include "PDFDocFactory.h" #include "PSOutputDev.h" #include "Error.h" @@ -299,7 +300,13 @@ int main(int argc, char *argv[]) { } else { userPW = NULL; } - doc = new PDFDoc(fileName, ownerPW, userPW); + if (fileName->cmp("-") == 0) { + delete fileName; + fileName = new GooString("fd://0"); + } + + doc = PDFDocFactory().createPDFDoc(fileName, ownerPW, userPW); + if (userPW) { delete userPW; } diff --git a/utils/pdftotext.cc b/utils/pdftotext.cc index 4ebda19..143e754 100644 --- a/utils/pdftotext.cc +++ b/utils/pdftotext.cc @@ -18,6 +18,7 @@ // Copyright (C) 2006 Dominic Lachowicz // Copyright (C) 2007-2008 Albert Astals Cid // Copyright (C) 2009 Jan Jockusch +// Copyright (C) 2010 Hib Eris // // To see a description of the changes please see the Changelog file that // came with your tarball or type make ChangeLog if you are building from git @@ -43,6 +44,7 @@ #include "Catalog.h" #include "Page.h" #include "PDFDoc.h" +#include "PDFDocFactory.h" #include "TextOutputDev.h" #include "CharTypes.h" #include "UnicodeMap.h" @@ -192,15 +194,13 @@ int main(int argc, char *argv[]) { userPW = NULL; } - if(fileName->cmp("-") != 0) { - doc = new PDFDoc(fileName, ownerPW, userPW); - } else { - Object obj; - - obj.initNull(); - doc = new PDFDoc(new FileStream(stdin, 0, gFalse, 0, &obj), ownerPW, userPW); + if (fileName->cmp("-") == 0) { + delete fileName; + fileName = new GooString("fd://0"); } + doc = PDFDocFactory().createPDFDoc(fileName, ownerPW, userPW); + if (userPW) { delete userPW; } -- 1.6.4.2 From hib at hiberis.nl Mon Apr 5 08:10:04 2010 From: hib at hiberis.nl (Hib Eris) Date: Mon, 5 Apr 2010 17:10:04 +0200 Subject: [poppler] Cached files, reading stdin, http streams and PDFDocBuilder In-Reply-To: References: <201003271520.02771.aacid@kde.org> Message-ID: Some documentation attached. On Mon, Apr 5, 2010 at 3:06 PM, Hib Eris wrote: > Hi Albert and others, > > I have rewritten my patches taking your comments into account. I have > attached the new patches. > > I am currently working on support for linearized pdf files. This will > allow you to render any page from a pdf document without the need to > download the complete pdf. Expect more patches soon. > > Cheers, > > Hib > -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-Code-documentation.patch Type: text/x-diff Size: 6345 bytes Desc: not available URL: From aacid at kemper.freedesktop.org Mon Apr 5 08:55:40 2010 From: aacid at kemper.freedesktop.org (Albert Astals Cid) Date: Mon, 5 Apr 2010 08:55:40 -0700 (PDT) Subject: [poppler] 15 commits - CMakeLists.txt config.h.cmake configure.ac goo/GooString.cc goo/GooString.h poppler/CachedFile.cc poppler/CachedFile.h poppler/CurlCachedFile.cc poppler/CurlCachedFile.h poppler/CurlPDFDocBuilder.cc poppler/CurlPDFDocBuilder.h poppler/Form.cc poppler/LocalPDFDocBuilder.cc poppler/LocalPDFDocBuilder.h poppler/Makefile.am poppler/PDFDocBuilder.h poppler/PDFDoc.cc poppler/PDFDocFactory.cc poppler/PDFDocFactory.h poppler/PDFDoc.h poppler/poppler-config.h.cmake poppler/poppler-config.h.in poppler/StdinCachedFile.cc poppler/StdinCachedFile.h poppler/StdinPDFDocBuilder.cc poppler/StdinPDFDocBuilder.h poppler/Stream.cc poppler/Stream.h utils/pdffonts.cc utils/pdfimages.cc utils/pdfinfo.cc utils/pdftoabw.cc utils/pdftohtml.cc utils/pdftoppm.cc utils/pdftops.cc utils/pdftotext.cc Message-ID: <20100405155540.F07EEC0001@kemper.freedesktop.org> CMakeLists.txt | 31 +++++ config.h.cmake | 6 configure.ac | 16 ++ goo/GooString.cc | 12 - goo/GooString.h | 21 +-- poppler/CachedFile.cc | 248 +++++++++++++++++++++++++++++++++++++++++ poppler/CachedFile.h | 115 +++++++++++++++++++ poppler/CurlCachedFile.cc | 96 +++++++++++++++ poppler/CurlCachedFile.h | 40 ++++++ poppler/CurlPDFDocBuilder.cc | 47 +++++++ poppler/CurlPDFDocBuilder.h | 31 +++++ poppler/Form.cc | 4 poppler/LocalPDFDocBuilder.cc | 46 +++++++ poppler/LocalPDFDocBuilder.h | 31 +++++ poppler/Makefile.am | 33 +++++ poppler/PDFDoc.cc | 54 ++++---- poppler/PDFDoc.h | 6 poppler/PDFDocBuilder.h | 33 +++++ poppler/PDFDocFactory.cc | 72 +++++++++++ poppler/PDFDocFactory.h | 43 +++++++ poppler/StdinCachedFile.cc | 38 ++++++ poppler/StdinCachedFile.h | 27 ++++ poppler/StdinPDFDocBuilder.cc | 43 +++++++ poppler/StdinPDFDocBuilder.h | 31 +++++ poppler/Stream.cc | 102 ++++++++++++++++ poppler/Stream.h | 58 +++++++++ poppler/poppler-config.h.cmake | 5 poppler/poppler-config.h.in | 5 utils/pdffonts.cc | 18 +- utils/pdfimages.cc | 13 +- utils/pdfinfo.cc | 17 +- utils/pdftoabw.cc | 12 + utils/pdftohtml.cc | 12 + utils/pdftoppm.cc | 17 +- utils/pdftops.cc | 11 + utils/pdftotext.cc | 16 +- 36 files changed, 1328 insertions(+), 82 deletions(-) New commits: commit a9d801b2db20ecb08734ee5cdb703abf11994b6e Author: Albert Astals Cid Date: Mon Apr 5 16:55:02 2010 +0100 Make some paremeters const & to clearly show we just read them diff --git a/poppler/CachedFile.cc b/poppler/CachedFile.cc index 835079f..46627c3 100644 --- a/poppler/CachedFile.cc +++ b/poppler/CachedFile.cc @@ -6,6 +6,7 @@ // // Copyright 2009 Stefan Thomas // Copyright 2010 Hib Eris +// Copyright 2010 Albert Astals Cid // //======================================================================== @@ -68,7 +69,7 @@ int CachedFile::seek(long int offset, int origin) return 0; } -int CachedFile::cache(GooVector* ranges) +int CachedFile::cache(const GooVector &origRanges) { GooVector loadChunks; int numChunks = length/CachedFileChunkSize + 1; @@ -76,12 +77,13 @@ int CachedFile::cache(GooVector* ranges) int startChunk, endChunk; GooVector chunk_ranges, all; ByteRange range; + const GooVector *ranges = &origRanges; - if (!ranges) { - ranges = &all; - range.offset = 0; - range.length = length; - ranges->push_back(range); + if (ranges->empty()) { + range.offset = 0; + range.length = length; + all.push_back(range); + ranges = &all; } memset(&chunkNeeded, 0, numChunks); @@ -124,7 +126,7 @@ int CachedFile::cache(GooVector* ranges) if (chunk_ranges.size() > 0) { CachedFileWriter writer = CachedFileWriter(this, &loadChunks); - return loader->load(&chunk_ranges, &writer); + return loader->load(chunk_ranges, &writer); } return 0; @@ -168,7 +170,7 @@ int CachedFile::cache(size_t offset, size_t length) range.offset = offset; range.length = length; r.push_back(range); - return cache(&r); + return cache(r); } //------------------------------------------------------------------------ diff --git a/poppler/CachedFile.h b/poppler/CachedFile.h index e004578..eefb2a3 100644 --- a/poppler/CachedFile.h +++ b/poppler/CachedFile.h @@ -8,6 +8,7 @@ // // Copyright 2009 Stefan Thomas // Copyright 2010 Hib Eris +// Copyright 2010 Albert Astals Cid // //======================================================================== @@ -37,14 +38,13 @@ friend class CachedFileWriter; public: CachedFile(CachedFileLoader *cacheLoader, GooString *uri); - ~CachedFile(); Guint getLength() { return length; } long int tell(); int seek(long int offset, int origin); size_t read(void * ptr, size_t unitsize, size_t count); size_t write(const char *ptr, size_t size, size_t fromByte); - int cache(GooVector* ranges); + int cache(const GooVector &ranges); // Reference counting. void incRefCnt(); @@ -52,6 +52,8 @@ public: private: + ~CachedFile(); + enum ChunkState { chunkStateNew = 0, chunkStateLoaded @@ -104,7 +106,7 @@ public: virtual ~CachedFileLoader() {}; virtual size_t init(GooString *uri, CachedFile *cachedFile) = 0; - virtual int load(GooVector *ranges, CachedFileWriter *writer) = 0; + virtual int load(const GooVector &ranges, CachedFileWriter *writer) = 0; }; diff --git a/poppler/CurlCachedFile.cc b/poppler/CurlCachedFile.cc index b326fb7..35f5104 100644 --- a/poppler/CurlCachedFile.cc +++ b/poppler/CurlCachedFile.cc @@ -6,6 +6,7 @@ // // Copyright 2009 Stefan Thomas // Copyright 2010 Hib Eris +// Copyright 2010 Albert Astals Cid // //======================================================================== @@ -67,14 +68,14 @@ size_t load_cb(const char *ptr, size_t size, size_t nmemb, void *data) return (writer->write) (ptr, size*nmemb); } -int CurlCachedFileLoader::load(GooVector *ranges, CachedFileWriter *writer) +int CurlCachedFileLoader::load(const GooVector &ranges, CachedFileWriter *writer) { CURLcode r = CURLE_OK; size_t fromByte, toByte; - for (size_t i = 0; i < (*ranges).size(); i++) { + for (size_t i = 0; i < ranges.size(); i++) { - fromByte = (*ranges)[i].offset; - toByte = fromByte + (*ranges)[i].length - 1; + fromByte = ranges[i].offset; + toByte = fromByte + ranges[i].length - 1; GooString *range = GooString::format("{0:ud}-{1:ud}", fromByte, toByte); curl_easy_setopt(curl, CURLOPT_URL, url->getCString()); diff --git a/poppler/CurlCachedFile.h b/poppler/CurlCachedFile.h index b18b7f8..b5f2e7d 100644 --- a/poppler/CurlCachedFile.h +++ b/poppler/CurlCachedFile.h @@ -5,6 +5,7 @@ // This file is licensed under the GPLv2 or later // // Copyright 2010 Hib Eris +// Copyright 2010 Albert Astals Cid // //======================================================================== @@ -25,7 +26,7 @@ public: CurlCachedFileLoader(); ~CurlCachedFileLoader(); size_t init(GooString *url, CachedFile* cachedFile); - int load(GooVector *ranges, CachedFileWriter *writer); + int load(const GooVector &ranges, CachedFileWriter *writer); private: diff --git a/poppler/CurlPDFDocBuilder.cc b/poppler/CurlPDFDocBuilder.cc index 251a4eb..948cd7a 100644 --- a/poppler/CurlPDFDocBuilder.cc +++ b/poppler/CurlPDFDocBuilder.cc @@ -5,6 +5,7 @@ // This file is licensed under the GPLv2 or later // // Copyright 2010 Hib Eris +// Copyright 2010 Albert Astals Cid // //======================================================================== @@ -20,13 +21,13 @@ //------------------------------------------------------------------------ PDFDoc * -CurlPDFDocBuilder::buildPDFDoc(GooString* uri, +CurlPDFDocBuilder::buildPDFDoc(const GooString &uri, GooString *ownerPassword, GooString *userPassword, void *guiDataA) { Object obj; CachedFile *cachedFile = new CachedFile( - new CurlCachedFileLoader(), new GooString(uri)); + new CurlCachedFileLoader(), uri.copy()); obj.initNull(); BaseStream *str = new CachedFileStream( @@ -35,9 +36,9 @@ CurlPDFDocBuilder::buildPDFDoc(GooString* uri, return new PDFDoc(str, ownerPassword, userPassword, guiDataA); } -GBool CurlPDFDocBuilder::supports(GooString* uri) +GBool CurlPDFDocBuilder::supports(const GooString &uri) { - if (uri->cmpN("http://", 7) == 0 || uri->cmpN("https://", 8) == 0) { + if (uri.cmpN("http://", 7) == 0 || uri.cmpN("https://", 8) == 0) { return gTrue; } else { return gFalse; diff --git a/poppler/CurlPDFDocBuilder.h b/poppler/CurlPDFDocBuilder.h index e84a4c7..75f9f62 100644 --- a/poppler/CurlPDFDocBuilder.h +++ b/poppler/CurlPDFDocBuilder.h @@ -5,6 +5,7 @@ // This file is licensed under the GPLv2 or later // // Copyright 2010 Hib Eris +// Copyright 2010 Albert Astals Cid // //======================================================================== @@ -21,9 +22,9 @@ class CurlPDFDocBuilder : public PDFDocBuilder { public: - PDFDoc *buildPDFDoc(GooString* uri, GooString *ownerPassword = NULL, + PDFDoc *buildPDFDoc(const GooString &uri, GooString *ownerPassword = NULL, GooString *userPassword = NULL, void *guiDataA = NULL); - GBool supports(GooString* uri); + GBool supports(const GooString &uri); }; diff --git a/poppler/LocalPDFDocBuilder.cc b/poppler/LocalPDFDocBuilder.cc index c54faac..6f6f1fc 100644 --- a/poppler/LocalPDFDocBuilder.cc +++ b/poppler/LocalPDFDocBuilder.cc @@ -5,6 +5,7 @@ // This file is licensed under the GPLv2 or later // // Copyright 2010 Hib Eris +// Copyright 2010 Albert Astals Cid // //======================================================================== @@ -18,24 +19,24 @@ PDFDoc * LocalPDFDocBuilder::buildPDFDoc( - GooString* uri, GooString *ownerPassword, GooString + const GooString &uri, GooString *ownerPassword, GooString *userPassword, void *guiDataA) { - if (uri->cmpN("file://", 7) == 0) { - GooString *fileName = new GooString(uri); + if (uri.cmpN("file://", 7) == 0) { + GooString *fileName = uri.copy(); fileName->del(0, 7); return new PDFDoc(fileName, ownerPassword, userPassword, guiDataA); } else { - GooString *fileName = new GooString(uri); + GooString *fileName = uri.copy(); return new PDFDoc(fileName, ownerPassword, userPassword, guiDataA); } } -GBool LocalPDFDocBuilder::supports(GooString* uri) +GBool LocalPDFDocBuilder::supports(const GooString &uri) { - if (uri->cmpN("file://", 7) == 0) { + if (uri.cmpN("file://", 7) == 0) { return gTrue; - } else if (!strstr(uri->getCString(), "://")) { + } else if (!strstr(uri.getCString(), "://")) { return gTrue; } else { return gFalse; diff --git a/poppler/LocalPDFDocBuilder.h b/poppler/LocalPDFDocBuilder.h index 439a131..5b90a1e 100644 --- a/poppler/LocalPDFDocBuilder.h +++ b/poppler/LocalPDFDocBuilder.h @@ -5,6 +5,7 @@ // This file is licensed under the GPLv2 or later // // Copyright 2010 Hib Eris +// Copyright 2010 Albert Astals Cid // //======================================================================== @@ -21,9 +22,9 @@ class LocalPDFDocBuilder : public PDFDocBuilder { public: - PDFDoc *buildPDFDoc(GooString* uri, GooString *ownerPassword = NULL, + PDFDoc *buildPDFDoc(const GooString &uri, GooString *ownerPassword = NULL, GooString *userPassword = NULL, void *guiDataA = NULL); - GBool supports(GooString* uri); + GBool supports(const GooString &uri); }; diff --git a/poppler/PDFDocBuilder.h b/poppler/PDFDocBuilder.h index 8a1350b..43d7b0d 100644 --- a/poppler/PDFDocBuilder.h +++ b/poppler/PDFDocBuilder.h @@ -5,6 +5,7 @@ // This file is licensed under the GPLv2 or later // // Copyright 2010 Hib Eris +// Copyright 2010 Albert Astals Cid // //======================================================================== @@ -23,9 +24,9 @@ class PDFDocBuilder { public: virtual ~PDFDocBuilder() {}; - virtual PDFDoc *buildPDFDoc(GooString* uri, GooString *ownerPassword = NULL, + virtual PDFDoc *buildPDFDoc(const GooString &uri, GooString *ownerPassword = NULL, GooString *userPassword = NULL, void *guiDataA = NULL) = 0; - virtual GBool supports(GooString* uri) = 0; + virtual GBool supports(const GooString &uri) = 0; }; diff --git a/poppler/PDFDocFactory.cc b/poppler/PDFDocFactory.cc index d8b5fcc..7829b3e 100644 --- a/poppler/PDFDocFactory.cc +++ b/poppler/PDFDocFactory.cc @@ -5,6 +5,7 @@ // This file is licensed under the GPLv2 or later // // Copyright 2010 Hib Eris +// Copyright 2010 Albert Astals Cid // //======================================================================== @@ -48,7 +49,7 @@ PDFDocFactory::~PDFDocFactory() } PDFDoc * -PDFDocFactory::createPDFDoc(GooString* uri, GooString *ownerPassword, +PDFDocFactory::createPDFDoc(const GooString &uri, GooString *ownerPassword, GooString *userPassword, void *guiDataA) { for (int i = builders->getLength() - 1; i >= 0 ; i--) { @@ -58,8 +59,8 @@ PDFDocFactory::createPDFDoc(GooString* uri, GooString *ownerPassword, } } - error(-1, "Cannot handle URI '%s'.", uri->getCString()); - GooString *fileName = new GooString(uri); + error(-1, "Cannot handle URI '%s'.", uri.getCString()); + GooString *fileName = uri.copy(); return PDFDoc::ErrorPDFDoc(errOpenFile, fileName); } diff --git a/poppler/PDFDocFactory.h b/poppler/PDFDocFactory.h index 00ee359..609c4c4 100644 --- a/poppler/PDFDocFactory.h +++ b/poppler/PDFDocFactory.h @@ -5,6 +5,7 @@ // This file is licensed under the GPLv2 or later // // Copyright 2010 Hib Eris +// Copyright 2010 Albert Astals Cid // //======================================================================== @@ -28,7 +29,7 @@ public: PDFDocFactory(GooList *pdfDocBuilders = NULL); ~PDFDocFactory(); - PDFDoc *createPDFDoc(GooString* uri, GooString *ownerPassword = NULL, + PDFDoc *createPDFDoc(const GooString &uri, GooString *ownerPassword = NULL, GooString *userPassword = NULL, void *guiDataA = NULL); void registerPDFDocBuilder(PDFDocBuilder *pdfDocBuilder); diff --git a/poppler/StdinCachedFile.cc b/poppler/StdinCachedFile.cc index 9b32136..4bfc31e 100644 --- a/poppler/StdinCachedFile.cc +++ b/poppler/StdinCachedFile.cc @@ -5,6 +5,7 @@ // This file is licensed under the GPLv2 or later // // Copyright 2010 Hib Eris +// Copyright 2010 Albert Astals Cid // //======================================================================== @@ -30,7 +31,7 @@ size_t StdinCacheLoader::init(GooString *dummy, CachedFile *cachedFile) return size; } -int StdinCacheLoader::load(GooVector *ranges, CachedFileWriter *writer) +int StdinCacheLoader::load(const GooVector &ranges, CachedFileWriter *writer) { return 0; } diff --git a/poppler/StdinCachedFile.h b/poppler/StdinCachedFile.h index 9af086a..11b064b 100644 --- a/poppler/StdinCachedFile.h +++ b/poppler/StdinCachedFile.h @@ -5,6 +5,7 @@ // This file is licensed under the GPLv2 or later // // Copyright 2010 Hib Eris +// Copyright 2010 Albert Astals Cid // //======================================================================== @@ -18,7 +19,7 @@ class StdinCacheLoader : public CachedFileLoader { public: size_t init(GooString *dummy, CachedFile* cachedFile); - int load(GooVector *ranges, CachedFileWriter *writer); + int load(const GooVector &ranges, CachedFileWriter *writer); }; diff --git a/poppler/StdinPDFDocBuilder.cc b/poppler/StdinPDFDocBuilder.cc index e260615..571ee46 100644 --- a/poppler/StdinPDFDocBuilder.cc +++ b/poppler/StdinPDFDocBuilder.cc @@ -5,6 +5,7 @@ // This file is licensed under the GPLv2 or later // // Copyright 2010 Hib Eris +// Copyright 2010 Albert Astals Cid // //======================================================================== @@ -19,7 +20,7 @@ //------------------------------------------------------------------------ PDFDoc * -StdinPDFDocBuilder::buildPDFDoc(GooString* uri, GooString *ownerPassword, +StdinPDFDocBuilder::buildPDFDoc(const GooString &uri, GooString *ownerPassword, GooString *userPassword, void *guiDataA) { Object obj; @@ -31,9 +32,9 @@ StdinPDFDocBuilder::buildPDFDoc(GooString* uri, GooString *ownerPassword, ownerPassword, userPassword); } -GBool StdinPDFDocBuilder::supports(GooString* uri) +GBool StdinPDFDocBuilder::supports(const GooString &uri) { - if (uri->cmpN("fd://0", 6) == 0) { + if (uri.cmpN("fd://0", 6) == 0) { return gTrue; } else { return gFalse; diff --git a/poppler/StdinPDFDocBuilder.h b/poppler/StdinPDFDocBuilder.h index fae32c0..2fe60e0 100644 --- a/poppler/StdinPDFDocBuilder.h +++ b/poppler/StdinPDFDocBuilder.h @@ -5,6 +5,7 @@ // This file is licensed under the GPLv2 or later // // Copyright 2010 Hib Eris +// Copyright 2010 Albert Astals Cid // //======================================================================== @@ -21,9 +22,9 @@ class StdinPDFDocBuilder : public PDFDocBuilder { public: - PDFDoc *buildPDFDoc(GooString* uri, GooString *ownerPassword = NULL, + PDFDoc *buildPDFDoc(const GooString &uri, GooString *ownerPassword = NULL, GooString *userPassword = NULL, void *guiDataA = NULL); - GBool supports(GooString* uri); + GBool supports(const GooString &uri); }; diff --git a/utils/pdffonts.cc b/utils/pdffonts.cc index 4849f5f..81b20e4 100644 --- a/utils/pdffonts.cc +++ b/utils/pdffonts.cc @@ -14,7 +14,7 @@ // under GPL version 2 or later // // Copyright (C) 2006 Dominic Lachowicz -// Copyright (C) 2007-2008 Albert Astals Cid +// Copyright (C) 2007-2008, 2010 Albert Astals Cid // Copyright (C) 2010 Hib Eris // // To see a description of the changes please see the Changelog file that @@ -138,7 +138,7 @@ int main(int argc, char *argv[]) { fileName = new GooString("fd://0"); } - doc = PDFDocFactory().createPDFDoc(fileName, ownerPW, userPW); + doc = PDFDocFactory().createPDFDoc(*fileName, ownerPW, userPW); delete fileName; if (userPW) { diff --git a/utils/pdfimages.cc b/utils/pdfimages.cc index 60766b7..ffa7991 100644 --- a/utils/pdfimages.cc +++ b/utils/pdfimages.cc @@ -15,7 +15,7 @@ // All changes made under the Poppler project to this file are licensed // under GPL version 2 or later // -// Copyright (C) 2007-2008 Albert Astals Cid +// Copyright (C) 2007-2008, 2010 Albert Astals Cid // Copyright (C) 2010 Hib Eris // // To see a description of the changes please see the Changelog file that @@ -127,7 +127,7 @@ int main(int argc, char *argv[]) { fileName = new GooString("fd://0"); } - doc = PDFDocFactory().createPDFDoc(fileName, ownerPW, userPW); + doc = PDFDocFactory().createPDFDoc(*fileName, ownerPW, userPW); delete fileName; if (userPW) { diff --git a/utils/pdfinfo.cc b/utils/pdfinfo.cc index 9644e9d..c645816 100644 --- a/utils/pdfinfo.cc +++ b/utils/pdfinfo.cc @@ -14,7 +14,7 @@ // under GPL version 2 or later // // Copyright (C) 2006 Dom Lachowicz -// Copyright (C) 2007-2009 Albert Astals Cid +// Copyright (C) 2007-2010 Albert Astals Cid // Copyright (C) 2010 Hib Eris // // To see a description of the changes please see the Changelog file that @@ -165,7 +165,7 @@ int main(int argc, char *argv[]) { fileName = new GooString("fd://0"); } - doc = PDFDocFactory().createPDFDoc(fileName, ownerPW, userPW); + doc = PDFDocFactory().createPDFDoc(*fileName, ownerPW, userPW); delete fileName; if (userPW) { diff --git a/utils/pdftoabw.cc b/utils/pdftoabw.cc index 5cb651c..2f7f042 100644 --- a/utils/pdftoabw.cc +++ b/utils/pdftoabw.cc @@ -3,7 +3,7 @@ * Copyright (C) 2007 Dominic Lachowicz * Copyright (C) 2007 Kouhei Sutou * Copyright (C) 2009 Jakub Wilk - * Copyright (C) 2009 Albert Astals Cid + * Copyright (C) 2009, 2010 Albert Astals Cid * Copyright (C) 2010 Hib Eris * * This program is free software; you can redistribute it and/or modify @@ -143,7 +143,7 @@ int main(int argc, char *argv[]) { fileName = new GooString("fd://0"); } - doc = PDFDocFactory().createPDFDoc(fileName, ownerPW, userPW); + doc = PDFDocFactory().createPDFDoc(*fileName, ownerPW, userPW); delete fileName; if (userPW) { diff --git a/utils/pdftohtml.cc b/utils/pdftohtml.cc index 7e2ac92..53d9ecb 100644 --- a/utils/pdftohtml.cc +++ b/utils/pdftohtml.cc @@ -13,7 +13,7 @@ // All changes made under the Poppler project to this file are licensed // under GPL version 2 or later // -// Copyright (C) 2007-2008 Albert Astals Cid +// Copyright (C) 2007-2008, 2010 Albert Astals Cid // Copyright (C) 2010 Hib Eris // // To see a description of the changes please see the Changelog file that @@ -194,7 +194,7 @@ int main(int argc, char *argv[]) { fileName = new GooString("fd://0"); } - doc = PDFDocFactory().createPDFDoc(fileName, ownerPW, userPW); + doc = PDFDocFactory().createPDFDoc(*fileName, ownerPW, userPW); if (userPW) { delete userPW; diff --git a/utils/pdftoppm.cc b/utils/pdftoppm.cc index 72d2a5d..849e79f 100644 --- a/utils/pdftoppm.cc +++ b/utils/pdftoppm.cc @@ -266,7 +266,7 @@ int main(int argc, char *argv[]) { delete fileName; fileName = new GooString("fd://0"); } - doc = PDFDocFactory().createPDFDoc(fileName, ownerPW, userPW); + doc = PDFDocFactory().createPDFDoc(*fileName, ownerPW, userPW); delete fileName; if (userPW) { diff --git a/utils/pdftops.cc b/utils/pdftops.cc index c549b4a..58ba731 100644 --- a/utils/pdftops.cc +++ b/utils/pdftops.cc @@ -16,7 +16,7 @@ // under GPL version 2 or later // // Copyright (C) 2006 Kristian H??gsberg -// Copyright (C) 2007-2008 Albert Astals Cid +// Copyright (C) 2007-2008, 2010 Albert Astals Cid // Copyright (C) 2009 Till Kamppeter // Copyright (C) 2009 Sanjoy Mahajan // Copyright (C) 2009 William Bader @@ -305,7 +305,7 @@ int main(int argc, char *argv[]) { fileName = new GooString("fd://0"); } - doc = PDFDocFactory().createPDFDoc(fileName, ownerPW, userPW); + doc = PDFDocFactory().createPDFDoc(*fileName, ownerPW, userPW); if (userPW) { delete userPW; diff --git a/utils/pdftotext.cc b/utils/pdftotext.cc index 143e754..cb530a9 100644 --- a/utils/pdftotext.cc +++ b/utils/pdftotext.cc @@ -16,7 +16,7 @@ // under GPL version 2 or later // // Copyright (C) 2006 Dominic Lachowicz -// Copyright (C) 2007-2008 Albert Astals Cid +// Copyright (C) 2007-2008, 2010 Albert Astals Cid // Copyright (C) 2009 Jan Jockusch // Copyright (C) 2010 Hib Eris // @@ -199,7 +199,7 @@ int main(int argc, char *argv[]) { fileName = new GooString("fd://0"); } - doc = PDFDocFactory().createPDFDoc(fileName, ownerPW, userPW); + doc = PDFDocFactory().createPDFDoc(*fileName, ownerPW, userPW); if (userPW) { delete userPW; commit a04ee3ea6066c97d41fc40d5d97c600a1870855a Author: Albert Astals Cid Date: Mon Apr 5 16:50:58 2010 +0100 forgot my (C) diff --git a/poppler/Form.cc b/poppler/Form.cc index d7150fb..4df8a7d 100644 --- a/poppler/Form.cc +++ b/poppler/Form.cc @@ -5,7 +5,7 @@ // This file is licensed under the GPLv2 or later // // Copyright 2006-2008 Julien Rebetez -// Copyright 2007-2009 Albert Astals Cid +// Copyright 2007-2010 Albert Astals Cid // Copyright 2007-2008 Carlos Garcia Campos // Copyright 2007 Adrian Johnson // Copyright 2007 I??igo Mart??nez commit ed723c8ac4a21a50d7d236cdcf7a635defd8dffb Author: Albert Astals Cid Date: Mon Apr 5 16:50:15 2010 +0100 The copy constructor of GooString never worked, so do not use it diff --git a/poppler/Form.cc b/poppler/Form.cc index 7ccc96b..d7150fb 100644 --- a/poppler/Form.cc +++ b/poppler/Form.cc @@ -990,7 +990,7 @@ FormFieldText::FormFieldText(XRef *xrefA, Object *aobj, const Ref& ref) GooString* FormFieldText::getContentCopy () { if (!content) return NULL; - return new GooString(*content); + return new GooString(content); } void FormFieldText::setContentCopy (GooString* new_content) commit a28be8e4009b86fdfd92da928def194225a736c6 Author: Albert Astals Cid Date: Mon Apr 5 16:49:06 2010 +0100 Add some const correctnes to GooString diff --git a/goo/GooString.cc b/goo/GooString.cc index 0d4cb73..f1dcbc8 100644 --- a/goo/GooString.cc +++ b/goo/GooString.cc @@ -18,7 +18,7 @@ // Copyright (C) 2006 Kristian H??gsberg // Copyright (C) 2006 Krzysztof Kowalczyk // Copyright (C) 2007 Jeff Muizelaar -// Copyright (C) 2008, 2009 Albert Astals Cid +// Copyright (C) 2008-2010 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 @@ -197,7 +197,7 @@ GooString::GooString(GooString *str, int idx, int lengthA) { Set(str->getCString() + idx, lengthA); } -GooString::GooString(GooString *str) { +GooString::GooString(const GooString *str) { s = NULL; length = 0; Set(str->getCString(), str->length); @@ -684,7 +684,7 @@ GooString *GooString::lowerCase() { return this; } -int GooString::cmp(GooString *str) { +int GooString::cmp(GooString *str) const { int n1, n2, i, x; char *p1, *p2; @@ -699,7 +699,7 @@ int GooString::cmp(GooString *str) { return n1 - n2; } -int GooString::cmpN(GooString *str, int n) { +int GooString::cmpN(GooString *str, int n) const { int n1, n2, i, x; char *p1, *p2; @@ -719,7 +719,7 @@ int GooString::cmpN(GooString *str, int n) { return n1 - n2; } -int GooString::cmp(const char *sA) { +int GooString::cmp(const char *sA) const { int n1, i, x; const char *p1, *p2; @@ -739,7 +739,7 @@ int GooString::cmp(const char *sA) { return 0; } -int GooString::cmpN(const char *sA, int n) { +int GooString::cmpN(const char *sA, int n) const { int n1, i, x; const char *p1, *p2; diff --git a/goo/GooString.h b/goo/GooString.h index 731f640..e77308d 100644 --- a/goo/GooString.h +++ b/goo/GooString.h @@ -17,7 +17,7 @@ // // Copyright (C) 2006 Kristian H??gsberg // Copyright (C) 2006 Krzysztof Kowalczyk -// Copyright (C) 2008, 2009 Albert Astals Cid +// Copyright (C) 2008-2010 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 @@ -42,7 +42,7 @@ public: GooString(); // Create a string from a C string. - GooString(const char *sA); + explicit GooString(const char *sA); // Create a string from chars at . This string // can contain null characters. @@ -58,8 +58,8 @@ public: GooString* Set(const char *s1, int s1Len=CALC_STRING_LEN, const char *s2=NULL, int s2Len=CALC_STRING_LEN); // Copy a string. - GooString(GooString *str); - GooString *copy() { return new GooString(this); } + explicit GooString(const GooString *str); + GooString *copy() const { return new GooString(this); } // Concatenate two strings. GooString(GooString *str1, GooString *str2); @@ -98,7 +98,7 @@ public: int getLength() { return length; } // Get C string. - char *getCString() { return s; } + char *getCString() const { return s; } // Get th character. char getChar(int i) { return s[i]; } @@ -131,10 +131,10 @@ public: GooString *lowerCase(); // Compare two strings: -1:< 0:= +1:> - int cmp(GooString *str); - int cmpN(GooString *str, int n); - int cmp(const char *sA); - int cmpN(const char *sA, int n); + int cmp(GooString *str) const; + int cmpN(GooString *str, int n) const; + int cmp(const char *sA) const; + int cmpN(const char *sA, int n) const; GBool hasUnicodeMarker(void); @@ -145,6 +145,9 @@ public: GooString *sanitizedName(GBool psmode); private: + GooString(const GooString &other); + GooString& operator=(const GooString &other); + // you can tweak this number for a different speed/memory usage tradeoffs. // In libc malloc() rounding is 16 so it's best to choose a value that // results in sizeof(GooString) be a multiple of 16. commit 46aee9e4d225b88a3dfd4afbe57259f337bb15d3 Author: Hib Eris Date: Mon Apr 5 14:36:09 2010 +0200 Use PDFDocFactory in utils diff --git a/utils/pdffonts.cc b/utils/pdffonts.cc index 752fa15..4849f5f 100644 --- a/utils/pdffonts.cc +++ b/utils/pdffonts.cc @@ -15,6 +15,7 @@ // // Copyright (C) 2006 Dominic Lachowicz // Copyright (C) 2007-2008 Albert Astals Cid +// Copyright (C) 2010 Hib Eris // // 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 @@ -38,6 +39,7 @@ #include "GfxFont.h" #include "Annot.h" #include "PDFDoc.h" +#include "PDFDocFactory.h" static char *fontTypeNames[] = { "unknown", @@ -131,16 +133,14 @@ int main(int argc, char *argv[]) { } else { userPW = NULL; } - - if(fileName->cmp("-") != 0) { - doc = new PDFDoc(fileName, ownerPW, userPW); - } else { - Object obj; - - obj.initNull(); - doc = new PDFDoc(new FileStream(stdin, 0, gFalse, 0, &obj), ownerPW, userPW); + if (fileName->cmp("-") == 0) { + delete fileName; + fileName = new GooString("fd://0"); } + doc = PDFDocFactory().createPDFDoc(fileName, ownerPW, userPW); + delete fileName; + if (userPW) { delete userPW; } diff --git a/utils/pdfimages.cc b/utils/pdfimages.cc index b821c79..60766b7 100644 --- a/utils/pdfimages.cc +++ b/utils/pdfimages.cc @@ -16,6 +16,7 @@ // under GPL version 2 or later // // Copyright (C) 2007-2008 Albert Astals Cid +// Copyright (C) 2010 Hib Eris // // 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 @@ -40,6 +41,7 @@ #include "Catalog.h" #include "Page.h" #include "PDFDoc.h" +#include "PDFDocFactory.h" #include "ImageOutputDev.h" #include "Error.h" @@ -120,7 +122,14 @@ int main(int argc, char *argv[]) { } else { userPW = NULL; } - doc = new PDFDoc(fileName, ownerPW, userPW); + if (fileName->cmp("-") == 0) { + delete fileName; + fileName = new GooString("fd://0"); + } + + doc = PDFDocFactory().createPDFDoc(fileName, ownerPW, userPW); + delete fileName; + if (userPW) { delete userPW; } diff --git a/utils/pdfinfo.cc b/utils/pdfinfo.cc index 48504d2..9644e9d 100644 --- a/utils/pdfinfo.cc +++ b/utils/pdfinfo.cc @@ -43,15 +43,12 @@ #include "Catalog.h" #include "Page.h" #include "PDFDoc.h" +#include "PDFDocFactory.h" #include "CharTypes.h" #include "UnicodeMap.h" #include "PDFDocEncoding.h" #include "Error.h" #include "DateInfo.h" -#include "StdinCachedFile.h" -#if ENABLE_LIBCURL -#include "CurlCachedFile.h" -#endif static void printInfoString(Dict *infoDict, char *key, char *text, UnicodeMap *uMap); @@ -163,28 +160,14 @@ int main(int argc, char *argv[]) { userPW = NULL; } -#if ENABLE_LIBCURL - if (fileName->cmpN("http://", 7) == 0 || - fileName->cmpN("https://", 8) == 0) { - Object obj; - - obj.initNull(); - CachedFile *cachedFile = new CachedFile(new CurlCachedFileLoader(), fileName); - doc = new PDFDoc(new CachedFileStream(cachedFile, 0, gFalse, 0, &obj), - ownerPW, userPW); - } else -#endif - if (fileName->cmp("-") != 0) { - doc = new PDFDoc(fileName, ownerPW, userPW); - } else { - Object obj; - - obj.initNull(); - CachedFile *cachedFile = new CachedFile(new StdinCacheLoader(), NULL); - doc = new PDFDoc(new CachedFileStream(cachedFile, 0, gFalse, 0, &obj), - ownerPW, userPW); + if (fileName->cmp("-") == 0) { + delete fileName; + fileName = new GooString("fd://0"); } + doc = PDFDocFactory().createPDFDoc(fileName, ownerPW, userPW); + delete fileName; + if (userPW) { delete userPW; } diff --git a/utils/pdftoabw.cc b/utils/pdftoabw.cc index 9c71c76..5cb651c 100644 --- a/utils/pdftoabw.cc +++ b/utils/pdftoabw.cc @@ -4,6 +4,7 @@ * Copyright (C) 2007 Kouhei Sutou * Copyright (C) 2009 Jakub Wilk * Copyright (C) 2009 Albert Astals Cid + * Copyright (C) 2010 Hib Eris * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -41,6 +42,7 @@ #include "Catalog.h" #include "Page.h" #include "PDFDoc.h" +#include "PDFDocFactory.h" #include "ABWOutputDev.h" #include "PSOutputDev.h" #include "GlobalParams.h" @@ -136,7 +138,13 @@ int main(int argc, char *argv[]) { userPW = NULL; } - doc = new PDFDoc(fileName, ownerPW, userPW); + if (fileName->cmp("-") == 0) { + delete fileName; + fileName = new GooString("fd://0"); + } + + doc = PDFDocFactory().createPDFDoc(fileName, ownerPW, userPW); + delete fileName; if (userPW) { delete userPW; diff --git a/utils/pdftohtml.cc b/utils/pdftohtml.cc index 41312de..7e2ac92 100644 --- a/utils/pdftohtml.cc +++ b/utils/pdftohtml.cc @@ -14,6 +14,7 @@ // under GPL version 2 or later // // Copyright (C) 2007-2008 Albert Astals Cid +// Copyright (C) 2010 Hib Eris // // 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,6 +42,7 @@ #include "Catalog.h" #include "Page.h" #include "PDFDoc.h" +#include "PDFDocFactory.h" #include "HtmlOutputDev.h" #include "PSOutputDev.h" #include "GlobalParams.h" @@ -187,7 +189,13 @@ int main(int argc, char *argv[]) { fileName = new GooString(argv[1]); - doc = new PDFDoc(fileName, ownerPW, userPW); + if (fileName->cmp("-") == 0) { + delete fileName; + fileName = new GooString("fd://0"); + } + + doc = PDFDocFactory().createPDFDoc(fileName, ownerPW, userPW); + if (userPW) { delete userPW; } diff --git a/utils/pdftoppm.cc b/utils/pdftoppm.cc index 7d1e3bf..72d2a5d 100644 --- a/utils/pdftoppm.cc +++ b/utils/pdftoppm.cc @@ -20,6 +20,7 @@ // Copyright (C) 2009 Stefan Thomas // Copyright (C) 2009, 2010 Albert Astals Cid // Copyright (C) 2010 Adrian Johnson +// Copyright (C) 2010 Hib Eris // // To see a description of the changes please see the Changelog file that // came with your tarball or type make ChangeLog if you are building from git @@ -36,6 +37,7 @@ #include "GlobalParams.h" #include "Object.h" #include "PDFDoc.h" +#include "PDFDocFactory.h" #include "splash/SplashBitmap.h" #include "splash/Splash.h" #include "SplashOutputDev.h" @@ -256,14 +258,17 @@ int main(int argc, char *argv[]) { } else { userPW = NULL; } - if(fileName != NULL && fileName->cmp("-") != 0) { - doc = new PDFDoc(fileName, ownerPW, userPW); - } else { - Object obj; - obj.initNull(); - doc = new PDFDoc(new FileStream(stdin, 0, gFalse, 0, &obj), ownerPW, userPW); + if (fileName == NULL) { + fileName = new GooString("fd://0"); + } + if (fileName->cmp("-") == 0) { + delete fileName; + fileName = new GooString("fd://0"); } + doc = PDFDocFactory().createPDFDoc(fileName, ownerPW, userPW); + delete fileName; + if (userPW) { delete userPW; } diff --git a/utils/pdftops.cc b/utils/pdftops.cc index 69d5c32..c549b4a 100644 --- a/utils/pdftops.cc +++ b/utils/pdftops.cc @@ -44,6 +44,7 @@ #include "Catalog.h" #include "Page.h" #include "PDFDoc.h" +#include "PDFDocFactory.h" #include "PSOutputDev.h" #include "Error.h" @@ -299,7 +300,13 @@ int main(int argc, char *argv[]) { } else { userPW = NULL; } - doc = new PDFDoc(fileName, ownerPW, userPW); + if (fileName->cmp("-") == 0) { + delete fileName; + fileName = new GooString("fd://0"); + } + + doc = PDFDocFactory().createPDFDoc(fileName, ownerPW, userPW); + if (userPW) { delete userPW; } diff --git a/utils/pdftotext.cc b/utils/pdftotext.cc index 4ebda19..143e754 100644 --- a/utils/pdftotext.cc +++ b/utils/pdftotext.cc @@ -18,6 +18,7 @@ // Copyright (C) 2006 Dominic Lachowicz // Copyright (C) 2007-2008 Albert Astals Cid // Copyright (C) 2009 Jan Jockusch +// Copyright (C) 2010 Hib Eris // // To see a description of the changes please see the Changelog file that // came with your tarball or type make ChangeLog if you are building from git @@ -43,6 +44,7 @@ #include "Catalog.h" #include "Page.h" #include "PDFDoc.h" +#include "PDFDocFactory.h" #include "TextOutputDev.h" #include "CharTypes.h" #include "UnicodeMap.h" @@ -192,15 +194,13 @@ int main(int argc, char *argv[]) { userPW = NULL; } - if(fileName->cmp("-") != 0) { - doc = new PDFDoc(fileName, ownerPW, userPW); - } else { - Object obj; - - obj.initNull(); - doc = new PDFDoc(new FileStream(stdin, 0, gFalse, 0, &obj), ownerPW, userPW); + if (fileName->cmp("-") == 0) { + delete fileName; + fileName = new GooString("fd://0"); } + doc = PDFDocFactory().createPDFDoc(fileName, ownerPW, userPW); + if (userPW) { delete userPW; } commit d487a90688c4431075c9e4db040b3b02625e208f Author: Hib Eris Date: Mon Apr 5 14:35:52 2010 +0200 Add PDFDocFactory diff --git a/CMakeLists.txt b/CMakeLists.txt index 562f89c..0725747 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -260,6 +260,7 @@ set(poppler_SRCS poppler/Parser.cc poppler/PDFDoc.cc poppler/PDFDocEncoding.cc + poppler/PDFDocFactory.cc poppler/PopplerCache.cc poppler/ProfileData.cc poppler/PreScanOutputDev.cc @@ -406,6 +407,7 @@ if(ENABLE_XPDF_HEADERS) poppler/PDFDoc.h poppler/PDFDocBuilder.h poppler/PDFDocEncoding.h + poppler/PDFDocFactory.h poppler/PopplerCache.h poppler/ProfileData.h poppler/PreScanOutputDev.h diff --git a/poppler/Makefile.am b/poppler/Makefile.am index 6717734..5dd8082 100644 --- a/poppler/Makefile.am +++ b/poppler/Makefile.am @@ -223,6 +223,7 @@ poppler_include_HEADERS = \ PDFDoc.h \ PDFDocBuilder.h \ PDFDocEncoding.h \ + PDFDocFactory.h \ PopplerCache.h \ ProfileData.h \ PreScanOutputDev.h \ @@ -299,6 +300,7 @@ libpoppler_la_SOURCES = \ Parser.cc \ PDFDoc.cc \ PDFDocEncoding.cc \ + PDFDocFactory.cc \ PopplerCache.cc \ ProfileData.cc \ PreScanOutputDev.cc \ diff --git a/poppler/PDFDocFactory.cc b/poppler/PDFDocFactory.cc new file mode 100644 index 0000000..d8b5fcc --- /dev/null +++ b/poppler/PDFDocFactory.cc @@ -0,0 +1,71 @@ +//======================================================================== +// +// PDFDocFactory.cc +// +// This file is licensed under the GPLv2 or later +// +// Copyright 2010 Hib Eris +// +//======================================================================== + +#include + +#include "PDFDocFactory.h" + +#include "goo/GooList.h" +#include "goo/GooString.h" +#include "PDFDoc.h" +#include "LocalPDFDocBuilder.h" +#include "StdinPDFDocBuilder.h" +#if ENABLE_LIBCURL +#include "CurlPDFDocBuilder.h" +#endif +#include "ErrorCodes.h" + +//------------------------------------------------------------------------ +// PDFDocFactory +//------------------------------------------------------------------------ + +PDFDocFactory::PDFDocFactory(GooList *pdfDocBuilders) +{ + if (pdfDocBuilders) { + builders = pdfDocBuilders; + } else { + builders = new GooList(); + } +#if ENABLE_LIBCURL + builders->insert(0, new CurlPDFDocBuilder()); +#endif + builders->insert(0, new StdinPDFDocBuilder()); + builders->insert(0, new LocalPDFDocBuilder()); +} + +PDFDocFactory::~PDFDocFactory() +{ + if (builders) { + deleteGooList(builders, PDFDocBuilder); + } +} + +PDFDoc * +PDFDocFactory::createPDFDoc(GooString* uri, GooString *ownerPassword, + GooString *userPassword, void *guiDataA) +{ + for (int i = builders->getLength() - 1; i >= 0 ; i--) { + PDFDocBuilder *builder = (PDFDocBuilder *) builders->get(i); + if (builder->supports(uri)) { + return builder->buildPDFDoc(uri, ownerPassword, userPassword, guiDataA); + } + } + + error(-1, "Cannot handle URI '%s'.", uri->getCString()); + GooString *fileName = new GooString(uri); + return PDFDoc::ErrorPDFDoc(errOpenFile, fileName); +} + +void PDFDocFactory::registerPDFDocBuilder(PDFDocBuilder *pdfDocBuilder) +{ + builders->append(pdfDocBuilder); +} + + diff --git a/poppler/PDFDocFactory.h b/poppler/PDFDocFactory.h new file mode 100644 index 0000000..00ee359 --- /dev/null +++ b/poppler/PDFDocFactory.h @@ -0,0 +1,42 @@ +//======================================================================== +// +// PDFDocFactory.h +// +// This file is licensed under the GPLv2 or later +// +// Copyright 2010 Hib Eris +// +//======================================================================== + +#ifndef PDFDOCFACTORY_H +#define PDFDOCFACTORY_H + +#include "PDFDoc.h" + +class GooList; +class GooString; +class PDFDocBuilder; + +//------------------------------------------------------------------------ +// PDFDocFactory +//------------------------------------------------------------------------ + +class PDFDocFactory { + +public: + + PDFDocFactory(GooList *pdfDocBuilders = NULL); + ~PDFDocFactory(); + + PDFDoc *createPDFDoc(GooString* uri, GooString *ownerPassword = NULL, + GooString *userPassword = NULL, void *guiDataA = NULL); + + void registerPDFDocBuilder(PDFDocBuilder *pdfDocBuilder); + +private: + + GooList *builders; + +}; + +#endif /* PDFDOCFACTORY_H */ commit 869135920831fb0d15db734f3dcd7a67146cc241 Author: Hib Eris Date: Wed Feb 24 15:24:26 2010 +0100 Add CurlPDFDocBuilder diff --git a/CMakeLists.txt b/CMakeLists.txt index cc255a5..562f89c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -322,6 +322,7 @@ endif(ENABLE_ZLIB) if(ENABLE_LIBCURL) set(poppler_SRCS ${poppler_SRCS} poppler/CurlCachedFile.cc + poppler/CurlPDFDocBuilder.cc ) set(poppler_LIBS ${poppler_LIBS} ${CURL_LIBRARIES}) endif(ENABLE_LIBCURL) @@ -462,6 +463,7 @@ if(ENABLE_XPDF_HEADERS) if(ENABLE_LIBCURL) install(FILES poppler/CurlCachedFile.h + poppler/CurlPDFDocBuilder.h DESTINATION include/poppler) endif(ENABLE_LIBCURL) if(LIBOPENJPEG_FOUND) diff --git a/poppler/CurlPDFDocBuilder.cc b/poppler/CurlPDFDocBuilder.cc new file mode 100644 index 0000000..251a4eb --- /dev/null +++ b/poppler/CurlPDFDocBuilder.cc @@ -0,0 +1,46 @@ +//======================================================================== +// +// CurlPDFDocBuilder.cc +// +// This file is licensed under the GPLv2 or later +// +// Copyright 2010 Hib Eris +// +//======================================================================== + +#include + +#include "CurlPDFDocBuilder.h" + +#include "CachedFile.h" +#include "CurlCachedFile.h" + +//------------------------------------------------------------------------ +// CurlPDFDocBuilder +//------------------------------------------------------------------------ + +PDFDoc * +CurlPDFDocBuilder::buildPDFDoc(GooString* uri, + GooString *ownerPassword, GooString *userPassword, void *guiDataA) +{ + Object obj; + + CachedFile *cachedFile = new CachedFile( + new CurlCachedFileLoader(), new GooString(uri)); + + obj.initNull(); + BaseStream *str = new CachedFileStream( + cachedFile, 0, gFalse, cachedFile->getLength(), &obj); + + return new PDFDoc(str, ownerPassword, userPassword, guiDataA); +} + +GBool CurlPDFDocBuilder::supports(GooString* uri) +{ + if (uri->cmpN("http://", 7) == 0 || uri->cmpN("https://", 8) == 0) { + return gTrue; + } else { + return gFalse; + } +}; + diff --git a/poppler/CurlPDFDocBuilder.h b/poppler/CurlPDFDocBuilder.h new file mode 100644 index 0000000..e84a4c7 --- /dev/null +++ b/poppler/CurlPDFDocBuilder.h @@ -0,0 +1,30 @@ +//======================================================================== +// +// CurlPDFDocBuilder.h +// +// This file is licensed under the GPLv2 or later +// +// Copyright 2010 Hib Eris +// +//======================================================================== + +#ifndef CURLPDFDOCBUILDER_H +#define CURLPDFDOCBUILDER_H + +#include "PDFDocBuilder.h" + +//------------------------------------------------------------------------ +// CurlPDFDocBuilder +//------------------------------------------------------------------------ + +class CurlPDFDocBuilder : public PDFDocBuilder { + +public: + + PDFDoc *buildPDFDoc(GooString* uri, GooString *ownerPassword = NULL, + GooString *userPassword = NULL, void *guiDataA = NULL); + GBool supports(GooString* uri); + +}; + +#endif /* CURLPDFDOCBUILDER_H */ diff --git a/poppler/Makefile.am b/poppler/Makefile.am index 3eb84fd..6717734 100644 --- a/poppler/Makefile.am +++ b/poppler/Makefile.am @@ -111,10 +111,12 @@ libcurl_includes = \ $(LIBCURL_CFLAGS) curl_headers = \ - CurlCachedFile.h + CurlCachedFile.h \ + CurlPDFDocBuilder.h curl_sources = \ - CurlCachedFile.cc + CurlCachedFile.cc \ + CurlPDFDocBuilder.cc endif commit ec5c6117a64f9cb03560091c4d7948d4287b6975 Author: Hib Eris Date: Thu Feb 25 11:23:28 2010 +0100 Add LocalPDFDocBuilder and StdinPDFDocBuilder diff --git a/CMakeLists.txt b/CMakeLists.txt index 3245730..cc255a5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -249,6 +249,7 @@ set(poppler_SRCS poppler/JBIG2Stream.cc poppler/Lexer.cc poppler/Link.cc + poppler/LocalPDFDocBuilder.cc poppler/NameToCharCode.cc poppler/Object.cc poppler/OptionalContent.cc @@ -272,6 +273,7 @@ set(poppler_SRCS poppler/PageLabelInfo.cc poppler/SecurityHandler.cc poppler/StdinCachedFile.cc + poppler/StdinPDFDocBuilder.cc poppler/Sound.cc poppler/XpdfPluginAPI.cc poppler/Movie.cc @@ -390,6 +392,7 @@ if(ENABLE_XPDF_HEADERS) poppler/JBIG2Stream.h poppler/Lexer.h poppler/Link.h + poppler/LocalPDFDocBuilder.h poppler/Movie.h poppler/NameToCharCode.h poppler/Object.h @@ -424,6 +427,7 @@ if(ENABLE_XPDF_HEADERS) poppler/TextOutputDev.h poppler/SecurityHandler.h poppler/StdinCachedFile.h + poppler/StdinPDFDocBuilder.h poppler/UTF8.h poppler/XpdfPluginAPI.h poppler/Sound.h diff --git a/poppler/LocalPDFDocBuilder.cc b/poppler/LocalPDFDocBuilder.cc new file mode 100644 index 0000000..c54faac --- /dev/null +++ b/poppler/LocalPDFDocBuilder.cc @@ -0,0 +1,45 @@ +//======================================================================== +// +// LocalPDFDocBuilder.cc +// +// This file is licensed under the GPLv2 or later +// +// Copyright 2010 Hib Eris +// +//======================================================================== + +#include + +#include "LocalPDFDocBuilder.h" + +//------------------------------------------------------------------------ +// LocalPDFDocBuilder +//------------------------------------------------------------------------ + +PDFDoc * +LocalPDFDocBuilder::buildPDFDoc( + GooString* uri, GooString *ownerPassword, GooString + *userPassword, void *guiDataA) +{ + if (uri->cmpN("file://", 7) == 0) { + GooString *fileName = new GooString(uri); + fileName->del(0, 7); + return new PDFDoc(fileName, ownerPassword, userPassword, guiDataA); + } else { + GooString *fileName = new GooString(uri); + return new PDFDoc(fileName, ownerPassword, userPassword, guiDataA); + } +} + +GBool LocalPDFDocBuilder::supports(GooString* uri) +{ + if (uri->cmpN("file://", 7) == 0) { + return gTrue; + } else if (!strstr(uri->getCString(), "://")) { + return gTrue; + } else { + return gFalse; + } +} + + diff --git a/poppler/LocalPDFDocBuilder.h b/poppler/LocalPDFDocBuilder.h new file mode 100644 index 0000000..439a131 --- /dev/null +++ b/poppler/LocalPDFDocBuilder.h @@ -0,0 +1,30 @@ +//======================================================================== +// +// LocalPDFDocBuilder.h +// +// This file is licensed under the GPLv2 or later +// +// Copyright 2010 Hib Eris +// +//======================================================================== + +#ifndef LOCALPDFDOCBUILDER_H +#define LOCALPDFDOCBUILDER_H + +#include "PDFDocBuilder.h" + +//------------------------------------------------------------------------ +// LocalPDFDocBuilder +//------------------------------------------------------------------------ + +class LocalPDFDocBuilder : public PDFDocBuilder { + +public: + + PDFDoc *buildPDFDoc(GooString* uri, GooString *ownerPassword = NULL, + GooString *userPassword = NULL, void *guiDataA = NULL); + GBool supports(GooString* uri); + +}; + +#endif /* LOCALPDFDOCBUILDER_H */ diff --git a/poppler/Makefile.am b/poppler/Makefile.am index a013460..3eb84fd 100644 --- a/poppler/Makefile.am +++ b/poppler/Makefile.am @@ -208,6 +208,7 @@ poppler_include_HEADERS = \ JBIG2Stream.h \ Lexer.h \ Link.h \ + LocalPDFDocBuilder.h \ Movie.h \ NameToCharCode.h \ Object.h \ @@ -226,6 +227,7 @@ poppler_include_HEADERS = \ PSTokenizer.h \ Rendition.h \ StdinCachedFile.h \ + StdinPDFDocBuilder.h \ Stream-CCITT.h \ Stream.h \ UnicodeMap.h \ @@ -283,6 +285,7 @@ libpoppler_la_SOURCES = \ JBIG2Stream.cc \ Lexer.cc \ Link.cc \ + LocalPDFDocBuilder.cc \ Movie.cc \ NameToCharCode.cc \ Object.cc \ @@ -300,6 +303,7 @@ libpoppler_la_SOURCES = \ PSTokenizer.cc \ Rendition.cc \ StdinCachedFile.cc \ + StdinPDFDocBuilder.cc \ Stream.cc \ UnicodeMap.cc \ UnicodeTypeTable.cc \ diff --git a/poppler/StdinPDFDocBuilder.cc b/poppler/StdinPDFDocBuilder.cc new file mode 100644 index 0000000..e260615 --- /dev/null +++ b/poppler/StdinPDFDocBuilder.cc @@ -0,0 +1,42 @@ +//======================================================================== +// +// StdinPDFDocBuilder.cc +// +// This file is licensed under the GPLv2 or later +// +// Copyright 2010 Hib Eris +// +//======================================================================== + +#include + +#include "StdinPDFDocBuilder.h" +#include "CachedFile.h" +#include "StdinCachedFile.h" + +//------------------------------------------------------------------------ +// StdinPDFDocBuilder +//------------------------------------------------------------------------ + +PDFDoc * +StdinPDFDocBuilder::buildPDFDoc(GooString* uri, GooString *ownerPassword, + GooString *userPassword, void *guiDataA) +{ + Object obj; + + obj.initNull(); + CachedFile *cachedFile = new CachedFile(new StdinCacheLoader(), NULL); + return new PDFDoc(new CachedFileStream(cachedFile, 0, gFalse, + cachedFile->getLength(), &obj), + ownerPassword, userPassword); +} + +GBool StdinPDFDocBuilder::supports(GooString* uri) +{ + if (uri->cmpN("fd://0", 6) == 0) { + return gTrue; + } else { + return gFalse; + } +} + diff --git a/poppler/StdinPDFDocBuilder.h b/poppler/StdinPDFDocBuilder.h new file mode 100644 index 0000000..fae32c0 --- /dev/null +++ b/poppler/StdinPDFDocBuilder.h @@ -0,0 +1,30 @@ +//======================================================================== +// +// StdinPDFDocBuilder.h +// +// This file is licensed under the GPLv2 or later +// +// Copyright 2010 Hib Eris +// +//======================================================================== + +#ifndef STDINPDFDOCBUILDER_H +#define STDINPDFDOCBUILDER_H + +#include "PDFDocBuilder.h" + +//------------------------------------------------------------------------ +// StdinPDFDocBuilder +//------------------------------------------------------------------------ + +class StdinPDFDocBuilder : public PDFDocBuilder { + +public: + + PDFDoc *buildPDFDoc(GooString* uri, GooString *ownerPassword = NULL, + GooString *userPassword = NULL, void *guiDataA = NULL); + GBool supports(GooString* uri); + +}; + +#endif /* STDINPDFDOCBUILDER_H */ commit 919b735d1c0b99bf72280aff8db87ba503954498 Author: Hib Eris Date: Sun Apr 4 11:05:35 2010 +0200 Add PDFDocBuilder diff --git a/CMakeLists.txt b/CMakeLists.txt index 70b0e06..3245730 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -400,6 +400,7 @@ if(ENABLE_XPDF_HEADERS) poppler/PageTransition.h poppler/Parser.h poppler/PDFDoc.h + poppler/PDFDocBuilder.h poppler/PDFDocEncoding.h poppler/PopplerCache.h poppler/ProfileData.h diff --git a/poppler/Makefile.am b/poppler/Makefile.am index 5cd68a4..a013460 100644 --- a/poppler/Makefile.am +++ b/poppler/Makefile.am @@ -218,6 +218,7 @@ poppler_include_HEADERS = \ PageTransition.h \ Parser.h \ PDFDoc.h \ + PDFDocBuilder.h \ PDFDocEncoding.h \ PopplerCache.h \ ProfileData.h \ diff --git a/poppler/PDFDocBuilder.h b/poppler/PDFDocBuilder.h new file mode 100644 index 0000000..8a1350b --- /dev/null +++ b/poppler/PDFDocBuilder.h @@ -0,0 +1,32 @@ +//======================================================================== +// +// PDFDocBuilder.h +// +// This file is licensed under the GPLv2 or later +// +// Copyright 2010 Hib Eris +// +//======================================================================== + +#ifndef PDFDOCBUILDER_H +#define PDFDOCBUILDER_H + +#include "PDFDoc.h" +class GooString; + +//------------------------------------------------------------------------ +// PDFDocBuilder +//------------------------------------------------------------------------ + +class PDFDocBuilder { + +public: + + virtual ~PDFDocBuilder() {}; + virtual PDFDoc *buildPDFDoc(GooString* uri, GooString *ownerPassword = NULL, + GooString *userPassword = NULL, void *guiDataA = NULL) = 0; + virtual GBool supports(GooString* uri) = 0; + +}; + +#endif /* PDFDOCBUILDER_H */ commit 1ab07faf05661d6d92186974c4b1c279b6178747 Author: Hib Eris Date: Sun Apr 4 11:29:53 2010 +0200 Add PDFDoc::ErrorPDFDoc diff --git a/poppler/PDFDoc.cc b/poppler/PDFDoc.cc index 12aff3c..78b6593 100644 --- a/poppler/PDFDoc.cc +++ b/poppler/PDFDoc.cc @@ -88,6 +88,11 @@ void PDFDoc::init() #endif } +PDFDoc::PDFDoc() +{ + init(); +} + PDFDoc::PDFDoc(GooString *fileNameA, GooString *ownerPassword, GooString *userPassword, void *guiDataA) { Object obj; @@ -902,3 +907,12 @@ void PDFDoc::writeTrailer (Guint uxrefOffset, int uxrefSize, OutStream* outStr, delete trailerDict; } + +PDFDoc *PDFDoc::ErrorPDFDoc(int errorCode, GooString *fileNameA) +{ + PDFDoc *doc = new PDFDoc(); + doc->errCode = errorCode; + doc->fileName = fileNameA; + + return doc; +} diff --git a/poppler/PDFDoc.h b/poppler/PDFDoc.h index 08e9da8..79f6d6d 100644 --- a/poppler/PDFDoc.h +++ b/poppler/PDFDoc.h @@ -74,6 +74,8 @@ public: GooString *userPassword = NULL, void *guiDataA = NULL); ~PDFDoc(); + static PDFDoc *ErrorPDFDoc(int errorCode, GooString *fileNameA = NULL); + // Was PDF document successfully opened? GBool isOk() { return ok; } @@ -227,6 +229,7 @@ private: void saveIncrementalUpdate (OutStream* outStr); void saveCompleteRewrite (OutStream* outStr); + PDFDoc(); void init(); GBool setup(GooString *ownerPassword, GooString *userPassword); GBool checkFooter(); commit efc7e5efeddd8f70b7c74573d3194aba0a7d4631 Author: Hib Eris Date: Sun Apr 4 11:17:37 2010 +0200 Cleanup PDFDoc diff --git a/poppler/PDFDoc.cc b/poppler/PDFDoc.cc index b088f6c..12aff3c 100644 --- a/poppler/PDFDoc.cc +++ b/poppler/PDFDoc.cc @@ -21,6 +21,7 @@ // Copyright (C) 2009 Eric Toombs // Copyright (C) 2009 Kovid Goyal // Copyright (C) 2009 Axel Struebing +// Copyright (C) 2010 Hib Eris // // 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 @@ -73,15 +74,11 @@ // PDFDoc //------------------------------------------------------------------------ -PDFDoc::PDFDoc(GooString *fileNameA, GooString *ownerPassword, - GooString *userPassword, void *guiDataA) { - Object obj; - +void PDFDoc::init() +{ ok = gFalse; errCode = errNone; - - guiData = guiDataA; - + fileName = NULL; file = NULL; str = NULL; xref = NULL; @@ -89,8 +86,16 @@ PDFDoc::PDFDoc(GooString *fileNameA, GooString *ownerPassword, #ifndef DISABLE_OUTLINE outline = NULL; #endif +} + +PDFDoc::PDFDoc(GooString *fileNameA, GooString *ownerPassword, + GooString *userPassword, void *guiDataA) { + Object obj; + + init(); fileName = fileNameA; + guiData = guiDataA; // try to open file #ifdef VMS @@ -124,19 +129,10 @@ PDFDoc::PDFDoc(wchar_t *fileNameA, int fileNameLen, GooString *ownerPassword, Object obj; int i; - ok = gFalse; - errCode = errNone; + init(); guiData = guiDataA; - file = NULL; - str = NULL; - xref = NULL; - catalog = NULL; -#ifndef DISABLE_OUTLINE - outline = NULL; -#endif - //~ file name should be stored in Unicode (?) fileName = new GooString(); for (i = 0; i < fileNameLen; ++i) { @@ -174,21 +170,15 @@ PDFDoc::PDFDoc(wchar_t *fileNameA, int fileNameLen, GooString *ownerPassword, PDFDoc::PDFDoc(BaseStream *strA, GooString *ownerPassword, GooString *userPassword, void *guiDataA) { - ok = gFalse; - errCode = errNone; + + init(); guiData = guiDataA; if (strA->getFileName()) { fileName = strA->getFileName()->copy(); } else { fileName = NULL; } - file = NULL; str = strA; - xref = NULL; - catalog = NULL; -#ifndef DISABLE_OUTLINE - outline = NULL; -#endif ok = setup(ownerPassword, userPassword); } diff --git a/poppler/PDFDoc.h b/poppler/PDFDoc.h index 3db4b91..08e9da8 100644 --- a/poppler/PDFDoc.h +++ b/poppler/PDFDoc.h @@ -20,6 +20,7 @@ // Copyright (C) 2008 Carlos Garcia Campos // Copyright (C) 2009 Eric Toombs // Copyright (C) 2009 Kovid Goyal +// Copyright (C) 2010 Hib Eris // // 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 @@ -226,7 +227,7 @@ private: void saveIncrementalUpdate (OutStream* outStr); void saveCompleteRewrite (OutStream* outStr); - + void init(); GBool setup(GooString *ownerPassword, GooString *userPassword); GBool checkFooter(); void checkHeader(); commit 08a3435e67ebf21beac2fefcbd21ad65f9293fd1 Author: Hib Eris Date: Tue Feb 23 02:29:26 2010 +0100 Add HTTP support using libcurl With libcurl, poppler can handle documents over http. diff --git a/CMakeLists.txt b/CMakeLists.txt index 7922dad..70b0e06 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,6 +29,7 @@ option(ENABLE_CPP "Compile poppler cpp wrapper." ON) option(ENABLE_ABIWORD "Build the Abiword backend." ON) option(ENABLE_LIBOPENJPEG "Use libopenjpeg for JPX streams." ON) option(ENABLE_LCMS "Use liblcms for color management." ON) +option(ENABLE_LIBCURL "Build libcurl based HTTP support." OFF) option(ENABLE_ZLIB "Build with zlib (not totally safe)." OFF) option(USE_EXCEPTIONS "Throw exceptions to deal with not enough memory and similar problems." OFF) option(USE_FIXEDPOINT "Use fixed point arithmetic in the Splash backend" OFF) @@ -132,6 +133,11 @@ if(ENABLE_LCMS) find_package(LCMS) set(USE_CMS ${LCMS_FOUND}) endif(ENABLE_LCMS) +if(ENABLE_LIBCURL) + find_package(CURL) + include_directories(${CURL_INCLUDE_DIR}) + set(POPPLER_HAS_CURL_SUPPORT ON) +endif(ENABLE_LIBCURL) add_definitions(-DHAVE_CONFIG_H=1) if(FONTCONFIG_FOUND) @@ -311,6 +317,12 @@ if(ENABLE_ZLIB) ) set(poppler_LIBS ${poppler_LIBS} ${ZLIB_LIBRARIES}) endif(ENABLE_ZLIB) +if(ENABLE_LIBCURL) + set(poppler_SRCS ${poppler_SRCS} + poppler/CurlCachedFile.cc + ) + set(poppler_LIBS ${poppler_LIBS} ${CURL_LIBRARIES}) +endif(ENABLE_LIBCURL) if(LIBOPENJPEG_FOUND) set(poppler_SRCS ${poppler_SRCS} poppler/JPEG2000Stream.cc @@ -442,6 +454,11 @@ if(ENABLE_XPDF_HEADERS) fofi/FoFiType1.h fofi/FoFiType1C.h DESTINATION include/poppler/fofi) + if(ENABLE_LIBCURL) + install(FILES + poppler/CurlCachedFile.h + DESTINATION include/poppler) + endif(ENABLE_LIBCURL) if(LIBOPENJPEG_FOUND) install(FILES poppler/JPEG2000Stream.h @@ -552,6 +569,7 @@ show_end_message("use gtk-doc" "not supported with this CMake build system") show_end_message_yesno("use libjpeg" ENABLE_LIBJPEG) show_end_message_yesno("use libpng" ENABLE_LIBPNG) show_end_message_yesno("use zlib" ENABLE_ZLIB) +show_end_message_yesno("use curl" ENABLE_LIBCURL) show_end_message_yesno("use libopenjpeg" LIBOPENJPEG_FOUND) show_end_message_yesno("use cms" USE_CMS) show_end_message_yesno("command line utils" ENABLE_UTILS) diff --git a/config.h.cmake b/config.h.cmake index 70d8d5d..0879aeb 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -1,5 +1,8 @@ /* config.h. Generated from config.h.cmake by cmake. */ +/* Build against libcurl. */ +#cmakedefine ENABLE_LIBCURL 1 + /* Use libjpeg instead of builtin jpeg decoder. */ #cmakedefine ENABLE_LIBJPEG 1 @@ -153,6 +156,9 @@ /* Poppler data dir */ #define POPPLER_DATADIR "${CMAKE_INSTALL_PREFIX}/share/poppler" +/* Support for curl based doc builder is compiled in. */ +#cmakedefine POPPLER_HAS_CURL_SUPPORT 1 + /* Have GDK */ #cmakedefine POPPLER_WITH_GDK 1 diff --git a/configure.ac b/configure.ac index 68509ee..72041d5 100644 --- a/configure.ac +++ b/configure.ac @@ -210,6 +210,21 @@ AM_CONDITIONAL(BUILD_ZLIB, test x$enable_zlib = xyes) AH_TEMPLATE([ENABLE_ZLIB], [Use zlib instead of builtin zlib decoder.]) +dnl Test for libcurl +AC_ARG_ENABLE(libcurl, + AC_HELP_STRING([--enable-libcurl], + [Build with libcurl based HTTP support.]), + enable_libcurl=$enableval, + enable_libcurl="no") + +if test x$enable_libcurl = xyes; then + PKG_CHECK_MODULES(LIBCURL, libcurl) + AC_DEFINE(ENABLE_LIBCURL, 1, [Build against libcurl.]) + AC_DEFINE(POPPLER_HAS_CURL_SUPPORT, 1, + [Support for curl based doc builder is compiled in.]) +fi + +AM_CONDITIONAL(BUILD_LIBCURL, test x$enable_libcurl = xyes) dnl Test for libjpeg AC_ARG_ENABLE(libjpeg, @@ -651,6 +666,7 @@ echo " use gtk-doc: $enable_gtk_doc" echo " use libjpeg: $enable_libjpeg" echo " use libpng: $enable_libpng" echo " use zlib: $enable_zlib" +echo " use libcurl: $enable_libcurl" echo " use libopenjpeg: $enable_libopenjpeg" echo " use cms: $enable_cms" echo " command line utils: $enable_utils" diff --git a/poppler/CurlCachedFile.cc b/poppler/CurlCachedFile.cc new file mode 100644 index 0000000..b326fb7 --- /dev/null +++ b/poppler/CurlCachedFile.cc @@ -0,0 +1,95 @@ +//======================================================================== +// +// CurlCachedFile.cc +// +// This file is licensed under the GPLv2 or later +// +// Copyright 2009 Stefan Thomas +// Copyright 2010 Hib Eris +// +//======================================================================== + +#include + +#include "CurlCachedFile.h" + +#include "goo/GooString.h" +#include "goo/GooVector.h" + +//------------------------------------------------------------------------ + +CurlCachedFileLoader::CurlCachedFileLoader() +{ + url = NULL; + cachedFile = NULL; + curl = NULL; +} + +CurlCachedFileLoader::~CurlCachedFileLoader() { + curl_easy_cleanup(curl); +} + +static size_t +noop_cb(char *ptr, size_t size, size_t nmemb, void *ptr2) +{ + return size*nmemb; +} + +size_t +CurlCachedFileLoader::init(GooString *urlA, CachedFile *cachedFileA) +{ + long code = NULL; + double contentLength = -1; + size_t size; + + url = urlA; + cachedFile = cachedFileA; + curl = curl_easy_init(); + + curl_easy_setopt(curl, CURLOPT_URL, url->getCString()); + curl_easy_setopt(curl, CURLOPT_HEADER, 1); + curl_easy_setopt(curl, CURLOPT_NOBODY, 1); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &noop_cb); + curl_easy_perform(curl); + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code); + curl_easy_getinfo(curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &contentLength); + curl_easy_reset(curl); + + size = contentLength; + + return size; +} + +static +size_t load_cb(const char *ptr, size_t size, size_t nmemb, void *data) +{ + CachedFileWriter *writer = (CachedFileWriter *) data; + return (writer->write) (ptr, size*nmemb); +} + +int CurlCachedFileLoader::load(GooVector *ranges, CachedFileWriter *writer) +{ + CURLcode r = CURLE_OK; + size_t fromByte, toByte; + for (size_t i = 0; i < (*ranges).size(); i++) { + + fromByte = (*ranges)[i].offset; + toByte = fromByte + (*ranges)[i].length - 1; + GooString *range = GooString::format("{0:ud}-{1:ud}", fromByte, toByte); + + curl_easy_setopt(curl, CURLOPT_URL, url->getCString()); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, load_cb); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, writer); + curl_easy_setopt(curl, CURLOPT_RANGE, range->getCString()); + r = curl_easy_perform(curl); + curl_easy_reset(curl); + + delete range; + + if (r != CURLE_OK) break; + } + return r; +} + +//------------------------------------------------------------------------ + diff --git a/poppler/CurlCachedFile.h b/poppler/CurlCachedFile.h new file mode 100644 index 0000000..b18b7f8 --- /dev/null +++ b/poppler/CurlCachedFile.h @@ -0,0 +1,39 @@ +//======================================================================== +// +// CurlCachedFile.h +// +// This file is licensed under the GPLv2 or later +// +// Copyright 2010 Hib Eris +// +//======================================================================== + +#ifndef CURLCACHELOADER_H +#define CURLCACHELOADER_H + +#include "poppler-config.h" +#include "CachedFile.h" + +#include + +//------------------------------------------------------------------------ + +class CurlCachedFileLoader : public CachedFileLoader { + +public: + + CurlCachedFileLoader(); + ~CurlCachedFileLoader(); + size_t init(GooString *url, CachedFile* cachedFile); + int load(GooVector *ranges, CachedFileWriter *writer); + +private: + + GooString *url; + CachedFile *cachedFile; + CURL *curl; + +}; + +#endif + diff --git a/poppler/Makefile.am b/poppler/Makefile.am index a6bb9e9..5cd68a4 100644 --- a/poppler/Makefile.am +++ b/poppler/Makefile.am @@ -102,6 +102,22 @@ zlib_libs = \ endif +if BUILD_LIBCURL + +libcurl_libs = \ + $(LIBCURL_LIBS) + +libcurl_includes = \ + $(LIBCURL_CFLAGS) + +curl_headers = \ + CurlCachedFile.h + +curl_sources = \ + CurlCachedFile.cc + +endif + if BUILD_ABIWORD_OUTPUT abiword_sources = \ @@ -130,6 +146,7 @@ INCLUDES = \ $(arthur_includes) \ $(abiword_includes) \ $(libpng_includes) \ + $(libcurl_includes) \ $(FREETYPE_CFLAGS) \ $(FONTCONFIG_CFLAGS) @@ -149,6 +166,7 @@ libpoppler_la_LIBADD = \ $(libjpeg_libs) \ $(libpng_libs) \ $(zlib_libs) \ + $(libcurl_libs) \ $(libjpeg2000_libs) \ $(abiword_libs) \ $(FREETYPE_LIBS) \ @@ -163,6 +181,7 @@ if ENABLE_XPDF_HEADERS poppler_includedir = $(includedir)/poppler poppler_include_HEADERS = \ $(splash_headers) \ + $(curl_headers) \ Annot.h \ Array.h \ BuiltinFont.h \ @@ -237,6 +256,7 @@ libpoppler_la_SOURCES = \ $(zlib_sources) \ $(libjpeg2000_sources) \ $(abiword_sources) \ + $(curl_sources) \ Annot.cc \ Array.cc \ BuiltinFont.cc \ diff --git a/poppler/poppler-config.h.cmake b/poppler/poppler-config.h.cmake index 7656e4f..95e95cc 100644 --- a/poppler/poppler-config.h.cmake +++ b/poppler/poppler-config.h.cmake @@ -49,6 +49,11 @@ #cmakedefine WITH_FONTCONFIGURATION_WIN32 1 #endif +/* Support for curl is compiled in. */ +#ifndef POPPLER_HAS_CURL_SUPPORT +#cmakedefine POPPLER_HAS_CURL_SUPPORT 1 +#endif + // Also, there's a couple of preprocessor symbols in the header files // that are used but never defined: DISABLE_OUTLINE, DEBUG_MEM and diff --git a/poppler/poppler-config.h.in b/poppler/poppler-config.h.in index f8db4ba..7b0644c 100644 --- a/poppler/poppler-config.h.in +++ b/poppler/poppler-config.h.in @@ -49,6 +49,11 @@ #undef WITH_FONTCONFIGURATION_WIN32 #endif +/* Support for curl is compiled in. */ +#ifndef POPPLER_HAS_CURL_SUPPORT +#undef POPPLER_HAS_CURL_SUPPORT +#endif + // Also, there's a couple of preprocessor symbols in the header files // that are used but never defined: DISABLE_OUTLINE, DEBUG_MEM and diff --git a/utils/pdfinfo.cc b/utils/pdfinfo.cc index ceddd47..48504d2 100644 --- a/utils/pdfinfo.cc +++ b/utils/pdfinfo.cc @@ -49,6 +49,9 @@ #include "Error.h" #include "DateInfo.h" #include "StdinCachedFile.h" +#if ENABLE_LIBCURL +#include "CurlCachedFile.h" +#endif static void printInfoString(Dict *infoDict, char *key, char *text, UnicodeMap *uMap); @@ -160,7 +163,18 @@ int main(int argc, char *argv[]) { userPW = NULL; } - if(fileName->cmp("-") != 0) { +#if ENABLE_LIBCURL + if (fileName->cmpN("http://", 7) == 0 || + fileName->cmpN("https://", 8) == 0) { + Object obj; + + obj.initNull(); + CachedFile *cachedFile = new CachedFile(new CurlCachedFileLoader(), fileName); + doc = new PDFDoc(new CachedFileStream(cachedFile, 0, gFalse, 0, &obj), + ownerPW, userPW); + } else +#endif + if (fileName->cmp("-") != 0) { doc = new PDFDoc(fileName, ownerPW, userPW); } else { Object obj; commit a87abf6ad9fb66d35a70c9412adc5d8ba2889b96 Author: Hib Eris Date: Wed Feb 24 14:46:59 2010 +0100 Use cached files to read from stdin in pdfinfo This fixes reading from stdin. diff --git a/utils/pdfinfo.cc b/utils/pdfinfo.cc index bfbe0b3..ceddd47 100644 --- a/utils/pdfinfo.cc +++ b/utils/pdfinfo.cc @@ -15,6 +15,7 @@ // // Copyright (C) 2006 Dom Lachowicz // Copyright (C) 2007-2009 Albert Astals Cid +// Copyright (C) 2010 Hib Eris // // 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 @@ -47,6 +48,7 @@ #include "PDFDocEncoding.h" #include "Error.h" #include "DateInfo.h" +#include "StdinCachedFile.h" static void printInfoString(Dict *infoDict, char *key, char *text, UnicodeMap *uMap); @@ -164,7 +166,9 @@ int main(int argc, char *argv[]) { Object obj; obj.initNull(); - doc = new PDFDoc(new FileStream(stdin, 0, gFalse, 0, &obj), ownerPW, userPW); + CachedFile *cachedFile = new CachedFile(new StdinCacheLoader(), NULL); + doc = new PDFDoc(new CachedFileStream(cachedFile, 0, gFalse, 0, &obj), + ownerPW, userPW); } if (userPW) { commit 958b04b14baf03c07492fa1cbd225d9968b9efc1 Author: Hib Eris Date: Tue Feb 23 02:02:10 2010 +0100 Add support for reading a cached file from stdin diff --git a/CMakeLists.txt b/CMakeLists.txt index b5e6988..7922dad 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -265,6 +265,7 @@ set(poppler_SRCS poppler/TextOutputDev.cc poppler/PageLabelInfo.cc poppler/SecurityHandler.cc + poppler/StdinCachedFile.cc poppler/Sound.cc poppler/XpdfPluginAPI.cc poppler/Movie.cc @@ -409,6 +410,7 @@ if(ENABLE_XPDF_HEADERS) poppler/PSOutputDev.h poppler/TextOutputDev.h poppler/SecurityHandler.h + poppler/StdinCachedFile.h poppler/UTF8.h poppler/XpdfPluginAPI.h poppler/Sound.h diff --git a/poppler/Makefile.am b/poppler/Makefile.am index f225110..a6bb9e9 100644 --- a/poppler/Makefile.am +++ b/poppler/Makefile.am @@ -205,6 +205,7 @@ poppler_include_HEADERS = \ PreScanOutputDev.h \ PSTokenizer.h \ Rendition.h \ + StdinCachedFile.h \ Stream-CCITT.h \ Stream.h \ UnicodeMap.h \ @@ -277,6 +278,7 @@ libpoppler_la_SOURCES = \ PreScanOutputDev.cc \ PSTokenizer.cc \ Rendition.cc \ + StdinCachedFile.cc \ Stream.cc \ UnicodeMap.cc \ UnicodeTypeTable.cc \ diff --git a/poppler/StdinCachedFile.cc b/poppler/StdinCachedFile.cc new file mode 100644 index 0000000..9b32136 --- /dev/null +++ b/poppler/StdinCachedFile.cc @@ -0,0 +1,37 @@ +//======================================================================== +// +// StdinCachedFile.cc +// +// This file is licensed under the GPLv2 or later +// +// Copyright 2010 Hib Eris +// +//======================================================================== + +#include + +#include "StdinCachedFile.h" + +#include + +size_t StdinCacheLoader::init(GooString *dummy, CachedFile *cachedFile) +{ + size_t read, size = 0; + char buf[CachedFileChunkSize]; + + CachedFileWriter writer = CachedFileWriter (cachedFile, NULL); + do { + read = fread(buf, 1, CachedFileChunkSize, stdin); + (writer.write) (buf, CachedFileChunkSize); + size += read; + } + while (read == CachedFileChunkSize); + + return size; +} + +int StdinCacheLoader::load(GooVector *ranges, CachedFileWriter *writer) +{ + return 0; +} + diff --git a/poppler/StdinCachedFile.h b/poppler/StdinCachedFile.h new file mode 100644 index 0000000..9af086a --- /dev/null +++ b/poppler/StdinCachedFile.h @@ -0,0 +1,26 @@ +//======================================================================== +// +// StdinCachedFile.h +// +// This file is licensed under the GPLv2 or later +// +// Copyright 2010 Hib Eris +// +//======================================================================== + +#ifndef STDINCACHELOADER_H +#define STDINCACHELOADER_H + +#include "CachedFile.h" + +class StdinCacheLoader : public CachedFileLoader { + +public: + + size_t init(GooString *dummy, CachedFile* cachedFile); + int load(GooVector *ranges, CachedFileWriter *writer); + +}; + +#endif + commit 9539f75bd06150a3868209c5b04a75f5253722cc Author: Hib Eris Date: Sat Apr 3 15:08:20 2010 +0200 Add support for cached files diff --git a/CMakeLists.txt b/CMakeLists.txt index 8411441..b5e6988 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -222,6 +222,7 @@ set(poppler_SRCS poppler/Array.cc poppler/BuiltinFont.cc poppler/BuiltinFontTables.cc + poppler/CachedFile.cc poppler/Catalog.cc poppler/CharCodeToUnicode.cc poppler/CMap.cc @@ -353,6 +354,7 @@ if(ENABLE_XPDF_HEADERS) poppler/Array.h poppler/BuiltinFont.h poppler/BuiltinFontTables.h + poppler/CachedFile.h poppler/Catalog.h poppler/CharCodeToUnicode.h poppler/CMap.h diff --git a/poppler/CachedFile.cc b/poppler/CachedFile.cc new file mode 100644 index 0000000..835079f --- /dev/null +++ b/poppler/CachedFile.cc @@ -0,0 +1,246 @@ +//======================================================================== +// +// CachedFile.cc +// +// This file is licensed under the GPLv2 or later +// +// Copyright 2009 Stefan Thomas +// Copyright 2010 Hib Eris +// +//======================================================================== + +#include +#include "CachedFile.h" + +//------------------------------------------------------------------------ +// CachedFile +//------------------------------------------------------------------------ + +CachedFile::CachedFile(CachedFileLoader *cachedFileLoaderA, GooString *uriA) +{ + uri = uriA; + loader = cachedFileLoaderA; + + streamPos = 0; + chunks = new GooVector(); + + length = loader->init(uri, this); + refCnt = 1; + + chunks->resize(length/CachedFileChunkSize + 1); +} + +CachedFile::~CachedFile() +{ + delete uri; + delete loader; + delete chunks; +} + +void CachedFile::incRefCnt() { + refCnt++; +} + +void CachedFile::decRefCnt() { + if (--refCnt == 0) + delete this; +} + +long int CachedFile::tell() { + return streamPos; +} + +int CachedFile::seek(long int offset, int origin) +{ + if (origin == SEEK_SET) { + streamPos = offset; + } else if (origin == SEEK_CUR) { + streamPos += offset; + } else { + streamPos = length + offset; + } + + if (streamPos > length) { + streamPos = 0; + return 1; + } + + return 0; +} + +int CachedFile::cache(GooVector* ranges) +{ + GooVector loadChunks; + int numChunks = length/CachedFileChunkSize + 1; + char chunkNeeded[numChunks]; + int startChunk, endChunk; + GooVector chunk_ranges, all; + ByteRange range; + + if (!ranges) { + ranges = &all; + range.offset = 0; + range.length = length; + ranges->push_back(range); + } + + memset(&chunkNeeded, 0, numChunks); + for (size_t i = 0; i < ranges->size(); i++) { + + if ((*ranges)[i].length == 0) continue; + if ((*ranges)[i].offset >= length) continue; + + size_t start = (*ranges)[i].offset; + size_t end = start + (*ranges)[i].length - 1; + if (end >= length) end = length - 1; + + startChunk = start / CachedFileChunkSize; + endChunk = end / CachedFileChunkSize; + for (int chunk = startChunk; chunk <= endChunk; chunk++) { + if ((*chunks)[chunk].state == chunkStateNew) { + chunkNeeded[chunk] = 1; + } + } + } + + int chunk = 0; + while (chunk < numChunks) { + while (!chunkNeeded[chunk] && (++chunk != numChunks)) ; + if (chunk == numChunks) break; + startChunk = chunk; + loadChunks.push_back(chunk); + + while ((++chunk != numChunks) && chunkNeeded[chunk]) { + loadChunks.push_back(chunk); + } + endChunk = chunk - 1; + + range.offset = startChunk * CachedFileChunkSize; + range.length = (endChunk - startChunk + 1) * CachedFileChunkSize; + + chunk_ranges.push_back(range); + } + + if (chunk_ranges.size() > 0) { + CachedFileWriter writer = + CachedFileWriter(this, &loadChunks); + return loader->load(&chunk_ranges, &writer); + } + + return 0; +} + +size_t CachedFile::read(void *ptr, size_t unitsize, size_t count) +{ + size_t bytes = unitsize*count; + if (length < (streamPos + bytes)) { + bytes = length - streamPos; + } + + if (bytes == 0) return 0; + + // Load data + if (cache(streamPos, bytes) != 0) return 0; + + // Copy data to buffer + size_t toCopy = bytes; + while (toCopy) { + int chunk = streamPos / CachedFileChunkSize; + int offset = streamPos % CachedFileChunkSize; + size_t len = CachedFileChunkSize-offset; + + if (len > toCopy) + len = toCopy; + + memcpy(ptr, (*chunks)[chunk].data + offset, len); + streamPos += len; + toCopy -= len; + ptr = (char*)ptr + len; + } + + return bytes; +} + +int CachedFile::cache(size_t offset, size_t length) +{ + GooVector r; + ByteRange range; + range.offset = offset; + range.length = length; + r.push_back(range); + return cache(&r); +} + +//------------------------------------------------------------------------ +// CachedFileWriter +//------------------------------------------------------------------------ + +CachedFileWriter::CachedFileWriter(CachedFile *cachedFileA, GooVector *chunksA) +{ + cachedFile = cachedFileA; + chunks = chunksA; + + if (chunks) { + offset = 0; + it = (*chunks).begin(); + } +} + +CachedFileWriter::~CachedFileWriter() +{ +} + +size_t CachedFileWriter::write(const char *ptr, size_t size) +{ + const char *cp = ptr; + size_t len = size; + size_t nfree, ncopy; + size_t written = 0; + size_t chunk; + + if (!len) return 0; + + while (len) { + if (chunks) { + if (offset == CachedFileChunkSize) { + it++; + if (it == (*chunks).end()) return written; + offset = 0; + } + chunk = *it; + } else { + offset = cachedFile->length % CachedFileChunkSize; + chunk = cachedFile->length / CachedFileChunkSize; + } + + if (chunk >= cachedFile->chunks->size()) { + cachedFile->chunks->resize(chunk + 1); + } + + nfree = CachedFileChunkSize - offset; + ncopy = (len >= nfree) ? nfree : len; + memcpy(&((*cachedFile->chunks)[chunk].data[offset]), cp, ncopy); + len -= ncopy; + cp += ncopy; + offset += ncopy; + written += ncopy; + + if (!chunks) { + cachedFile->length += ncopy; + } + + if (offset == CachedFileChunkSize) { + (*cachedFile->chunks)[chunk].state = CachedFile::chunkStateLoaded; + } + } + + if ((chunk == (cachedFile->length / CachedFileChunkSize)) && + (offset == (cachedFile->length % CachedFileChunkSize))) { + (*cachedFile->chunks)[chunk].state = CachedFile::chunkStateLoaded; + } + + return written; +} + +//------------------------------------------------------------------------ + diff --git a/poppler/CachedFile.h b/poppler/CachedFile.h new file mode 100644 index 0000000..e004578 --- /dev/null +++ b/poppler/CachedFile.h @@ -0,0 +1,113 @@ +//======================================================================== +// +// CachedFile.h +// +// Caching files support. +// +// This file is licensed under the GPLv2 or later +// +// Copyright 2009 Stefan Thomas +// Copyright 2010 Hib Eris +// +//======================================================================== + +#ifndef CACHEDFILE_H +#define CACHEDFILE_H + +#include "poppler-config.h" + +#include "goo/gtypes.h" +#include "Object.h" +#include "Stream.h" +#include "goo/GooVector.h" + +//------------------------------------------------------------------------ + +#define CachedFileChunkSize 8192 + +class GooString; +class CachedFileLoader; + +//------------------------------------------------------------------------ + +class CachedFile { + +friend class CachedFileWriter; + +public: + + CachedFile(CachedFileLoader *cacheLoader, GooString *uri); + ~CachedFile(); + + Guint getLength() { return length; } + long int tell(); + int seek(long int offset, int origin); + size_t read(void * ptr, size_t unitsize, size_t count); + size_t write(const char *ptr, size_t size, size_t fromByte); + int cache(GooVector* ranges); + + // Reference counting. + void incRefCnt(); + void decRefCnt(); + +private: + + enum ChunkState { + chunkStateNew = 0, + chunkStateLoaded + }; + + typedef struct { + ChunkState state; + char data[CachedFileChunkSize]; + } Chunk; + + int cache(size_t offset, size_t length); + + CachedFileLoader *loader; + GooString *uri; + + size_t length; + size_t streamPos; + + GooVector *chunks; + + int refCnt; // reference count + +}; + +//------------------------------------------------------------------------ + +class CachedFileWriter { + +public: + + CachedFileWriter(CachedFile *cachedFile, GooVector *chunksA); + ~CachedFileWriter(); + + size_t write(const char *ptr, size_t size); + +private: + + CachedFile *cachedFile; + GooVector *chunks; + GooVector::iterator it; + size_t offset; + +}; + +//------------------------------------------------------------------------ + +class CachedFileLoader { + +public: + + virtual ~CachedFileLoader() {}; + virtual size_t init(GooString *uri, CachedFile *cachedFile) = 0; + virtual int load(GooVector *ranges, CachedFileWriter *writer) = 0; + +}; + +//------------------------------------------------------------------------ + +#endif diff --git a/poppler/Makefile.am b/poppler/Makefile.am index 3bcb922..f225110 100644 --- a/poppler/Makefile.am +++ b/poppler/Makefile.am @@ -167,6 +167,7 @@ poppler_include_HEADERS = \ Array.h \ BuiltinFont.h \ BuiltinFontTables.h \ + CachedFile.h \ Catalog.h \ CharCodeToUnicode.h \ CMap.h \ @@ -239,6 +240,7 @@ libpoppler_la_SOURCES = \ Array.cc \ BuiltinFont.cc \ BuiltinFontTables.cc \ + CachedFile.cc \ Catalog.cc \ CharCodeToUnicode.cc \ CMap.cc \ diff --git a/poppler/Stream.cc b/poppler/Stream.cc index 6634317..0771e25 100644 --- a/poppler/Stream.cc +++ b/poppler/Stream.cc @@ -19,6 +19,8 @@ // Copyright (C) 2008 Julien Rebetez // Copyright (C) 2009 Carlos Garcia Campos // Copyright (C) 2009 Glenn Ganz +// Copyright (C) 2009 Stefan Thomas +// Copyright (C) 2010 Hib Eris // // 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 @@ -50,6 +52,7 @@ #include "Stream.h" #include "JBIG2Stream.h" #include "Stream-CCITT.h" +#include "CachedFile.h" #ifdef ENABLE_LIBJPEG #include "DCTStream.h" @@ -794,6 +797,105 @@ void FileStream::moveStart(int delta) { } //------------------------------------------------------------------------ +// CachedFileStream +//------------------------------------------------------------------------ + +CachedFileStream::CachedFileStream(CachedFile *ccA, Guint startA, + GBool limitedA, Guint lengthA, Object *dictA) + : BaseStream(dictA) +{ + cc = ccA; + start = startA; + limited = limitedA; + length = lengthA; + bufPtr = bufEnd = buf; + bufPos = start; + savePos = 0; + saved = gFalse; +} + +CachedFileStream::~CachedFileStream() +{ + close(); + cc->decRefCnt(); +} + +Stream *CachedFileStream::makeSubStream(Guint startA, GBool limitedA, + Guint lengthA, Object *dictA) +{ + cc->incRefCnt(); + return new CachedFileStream(cc, startA, limitedA, lengthA, dictA); +} + +void CachedFileStream::reset() +{ + savePos = (Guint)cc->tell(); + cc->seek(start, SEEK_SET); + + saved = gTrue; + bufPtr = bufEnd = buf; + bufPos = start; +} + +void CachedFileStream::close() +{ + if (saved) { + cc->seek(savePos, SEEK_SET); + saved = gFalse; + } +} + +GBool CachedFileStream::fillBuf() +{ + int n; + + bufPos += bufEnd - buf; + bufPtr = bufEnd = buf; + if (limited && bufPos >= start + length) { + return gFalse; + } + if (limited && bufPos + cachedStreamBufSize > start + length) { + n = start + length - bufPos; + } else { + n = cachedStreamBufSize; + } + cc->read(buf, 1, n); + bufEnd = buf + n; + if (bufPtr >= bufEnd) { + return gFalse; + } + return gTrue; +} + +void CachedFileStream::setPos(Guint pos, int dir) +{ + Guint size; + + if (dir >= 0) { + cc->seek(pos, SEEK_SET); + bufPos = pos; + } else { + cc->seek(0, SEEK_END); + size = (Guint)cc->tell(); + + if (pos > size) + pos = (Guint)size; + + cc->seek(-(int)pos, SEEK_END); + bufPos = (Guint)cc->tell(); + } + + bufPtr = bufEnd = buf; +} + +void CachedFileStream::moveStart(int delta) +{ + start += delta; + bufPtr = bufEnd = buf; + bufPos = start; +} + +//------------------------------------------------------------------------ // MemStream //------------------------------------------------------------------------ diff --git a/poppler/Stream.h b/poppler/Stream.h index 9c0068e..49ae8fb 100644 --- a/poppler/Stream.h +++ b/poppler/Stream.h @@ -17,6 +17,8 @@ // Copyright (C) 2008 Julien Rebetez // Copyright (C) 2008 Albert Astals Cid // Copyright (C) 2009 Carlos Garcia Campos +// Copyright (C) 2009 Stefan Thomas +// Copyright (C) 2010 Hib Eris // // 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,14 +34,17 @@ #include #include "goo/gtypes.h" +#include "goo/GooVector.h" #include "Object.h" class BaseStream; +class CachedFile; //------------------------------------------------------------------------ enum StreamKind { strFile, + strCachedFile, strASCIIHex, strASCII85, strLZW, @@ -69,6 +74,13 @@ enum CryptAlgorithm { }; //------------------------------------------------------------------------ + +typedef struct _ByteRange { + Guint offset; + Guint length; +} ByteRange; + +//------------------------------------------------------------------------ // Stream (base class) //------------------------------------------------------------------------ @@ -399,6 +411,52 @@ private: }; //------------------------------------------------------------------------ +// CachedFileStream +//------------------------------------------------------------------------ + +#define cachedStreamBufSize 1024 + +class CachedFileStream: public BaseStream { +public: + + CachedFileStream(CachedFile *ccA, Guint startA, GBool limitedA, + Guint lengthA, Object *dictA); + virtual ~CachedFileStream(); + virtual Stream *makeSubStream(Guint startA, GBool limitedA, + Guint lengthA, Object *dictA); + virtual StreamKind getKind() { return strCachedFile; } + virtual void reset(); + virtual void close(); + virtual int getChar() + { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); } + virtual int lookChar() + { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); } + virtual int getPos() { return bufPos + (bufPtr - buf); } + virtual void setPos(Guint pos, int dir = 0); + virtual Guint getStart() { return start; } + virtual void moveStart(int delta); + + virtual int getUnfilteredChar () { return getChar(); } + virtual void unfilteredReset () { reset(); } + +private: + + GBool fillBuf(); + + CachedFile *cc; + Guint start; + GBool limited; + Guint length; + char buf[cachedStreamBufSize]; + char *bufPtr; + char *bufEnd; + Guint bufPos; + int savePos; + GBool saved; +}; + + +//------------------------------------------------------------------------ // MemStream //------------------------------------------------------------------------ From hib at hiberis.nl Mon Apr 5 09:47:47 2010 From: hib at hiberis.nl (Hib Eris) Date: Mon, 5 Apr 2010 18:47:47 +0200 Subject: [poppler] Cached files, reading stdin, http streams and PDFDocBuilder In-Reply-To: References: <201003271520.02771.aacid@kde.org> Message-ID: Updated documentation. On Mon, Apr 5, 2010 at 5:10 PM, Hib Eris wrote: > Some documentation attached. > > On Mon, Apr 5, 2010 at 3:06 PM, Hib Eris wrote: >> Hi Albert and others, >> >> I have rewritten my patches taking your comments into account. I have >> attached the new patches. >> >> I am currently working on support for linearized pdf files. This will >> allow you to render any page from a pdf document without the need to >> download the complete pdf. Expect more patches soon. >> >> Cheers, >> >> Hib >> > -------------- next part -------------- A non-text attachment was scrubbed... Name: 0001-Code-documentation.patch Type: text/x-diff Size: 6762 bytes Desc: not available URL: From aacid at kemper.freedesktop.org Mon Apr 5 11:14:21 2010 From: aacid at kemper.freedesktop.org (Albert Astals Cid) Date: Mon, 5 Apr 2010 11:14:21 -0700 (PDT) Subject: [poppler] poppler/DCTStream.cc poppler/DCTStream.h utils/HtmlOutputDev.cc Message-ID: <20100405181421.31712C0001@kemper.freedesktop.org> poppler/DCTStream.cc | 35 ++++++++++++++--------------------- poppler/DCTStream.h | 5 +++-- utils/HtmlOutputDev.cc | 4 ++-- 3 files changed, 19 insertions(+), 25 deletions(-) New commits: commit fc071d800cb4329a3ccf898d7bf16b4db7323ad8 Author: Albert Astals Cid Date: Mon Apr 5 19:11:26 2010 +0100 Rework DCTStream error handling, should work better now Fixes bug 26280 diff --git a/poppler/DCTStream.cc b/poppler/DCTStream.cc index 7c6ba70..5cbaced 100644 --- a/poppler/DCTStream.cc +++ b/poppler/DCTStream.cc @@ -5,7 +5,7 @@ // This file is licensed under the GPLv2 or later // // Copyright 2005 Jeff Muizelaar -// Copyright 2005-2009 Albert Astals Cid +// Copyright 2005-2010 Albert Astals Cid // Copyright 2009 Ryszard Trojnacki // //======================================================================== @@ -20,7 +20,6 @@ static boolean str_fill_input_buffer(j_decompress_ptr cinfo) { int c; struct str_src_mgr * src = (struct str_src_mgr *)cinfo->src; - if (src->abort) return FALSE; if (src->index == 0) { c = 0xFF; src->index++; @@ -70,7 +69,7 @@ DCTStream::~DCTStream() { static void exitErrorHandler(jpeg_common_struct *error) { j_decompress_ptr cinfo = (j_decompress_ptr)error; str_src_mgr * src = (struct str_src_mgr *)cinfo->src; - src->abort = true; + longjmp(src->setjmp_buffer, 1); } void DCTStream::init() @@ -86,7 +85,6 @@ void DCTStream::init() src.pub.next_input_byte = NULL; src.str = str; src.index = 0; - src.abort = false; current = NULL; limit = NULL; @@ -122,7 +120,6 @@ void DCTStream::reset() { if (c == -1) { error(-1, "Could not find start of jpeg data"); - src.abort = true; return; } if (c != 0xFF) c = 0; @@ -139,30 +136,28 @@ void DCTStream::reset() { } } - jpeg_read_header(&cinfo, TRUE); - if (src.abort) return; + if (!setjmp(src.setjmp_buffer)) { + jpeg_read_header(&cinfo, TRUE); + jpeg_start_decompress(&cinfo); - if (!jpeg_start_decompress(&cinfo)) - { - src.abort = true; - return; + row_stride = cinfo.output_width * cinfo.output_components; + row_buffer = cinfo.mem->alloc_sarray((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1); } - - row_stride = cinfo.output_width * cinfo.output_components; - row_buffer = cinfo.mem->alloc_sarray((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1); } int DCTStream::getChar() { - if (src.abort) return EOF; - int c; if (current == limit) { if (cinfo.output_scanline < cinfo.output_height) { - if (!jpeg_read_scanlines(&cinfo, row_buffer, 1)) return EOF; - current = &row_buffer[0][0]; - limit = &row_buffer[0][(cinfo.output_width - 1) * cinfo.output_components] + cinfo.output_components; + if (!setjmp(src.setjmp_buffer)) + { + if (!jpeg_read_scanlines(&cinfo, row_buffer, 1)) return EOF; + current = &row_buffer[0][0]; + limit = &row_buffer[0][(cinfo.output_width - 1) * cinfo.output_components] + cinfo.output_components; + } + else return EOF; } else return EOF; } @@ -172,8 +167,6 @@ int DCTStream::getChar() { } int DCTStream::lookChar() { - if (src.abort) return EOF; - return *current; } diff --git a/poppler/DCTStream.h b/poppler/DCTStream.h index 29f8cf9..6768ff2 100644 --- a/poppler/DCTStream.h +++ b/poppler/DCTStream.h @@ -6,7 +6,7 @@ // // Copyright 2005 Jeff Muizelaar // Copyright 2005 Martin Kretzschmar -// Copyright 2005-2007, 2009 Albert Astals Cid +// Copyright 2005-2007, 2009, 2010 Albert Astals Cid // //======================================================================== @@ -26,6 +26,7 @@ #include #include #include +#include #ifdef HAVE_UNISTD_H #include #endif @@ -48,7 +49,7 @@ struct str_src_mgr { JOCTET buffer; Stream *str; int index; - bool abort; + jmp_buf setjmp_buffer; }; diff --git a/utils/HtmlOutputDev.cc b/utils/HtmlOutputDev.cc index 6df1b7c..81f8b88 100644 --- a/utils/HtmlOutputDev.cc +++ b/utils/HtmlOutputDev.cc @@ -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-2009 Albert Astals Cid +// Copyright (C) 2005-2010 Albert Astals Cid // Copyright (C) 2008 Kjartan Maraas // Copyright (C) 2008 Boris Toloknov // Copyright (C) 2008 Haruyuki Kawabe @@ -50,13 +50,13 @@ #include "Error.h" #include "GfxState.h" #include "Page.h" +#include "PNGWriter.h" #ifdef ENABLE_LIBJPEG #include "DCTStream.h" #endif #include "GlobalParams.h" #include "HtmlOutputDev.h" #include "HtmlFonts.h" -#include "PNGWriter.h" int HtmlPage::pgNum=0; int HtmlOutputDev::imgNum=1; From aacid at kemper.freedesktop.org Mon Apr 5 12:15:44 2010 From: aacid at kemper.freedesktop.org (Albert Astals Cid) Date: Mon, 5 Apr 2010 12:15:44 -0700 (PDT) Subject: [poppler] 2 commits - poppler/CachedFile.h poppler/CurlPDFDocBuilder.h poppler/LocalPDFDocBuilder.h poppler/PDFDocBuilder.h poppler/PDFDocFactory.h poppler/StdinPDFDocBuilder.h utils/pdftohtml.cc utils/pdftops.cc utils/pdftotext.cc Message-ID: <20100405191544.EAA95C0001@kemper.freedesktop.org> poppler/CachedFile.h | 30 ++++++++++++++++++++++++++++++ poppler/CurlPDFDocBuilder.h | 2 ++ poppler/LocalPDFDocBuilder.h | 2 ++ poppler/PDFDocBuilder.h | 9 +++++++++ poppler/PDFDocFactory.h | 12 ++++++++++++ poppler/StdinPDFDocBuilder.h | 2 ++ utils/pdftohtml.cc | 1 + utils/pdftops.cc | 1 + utils/pdftotext.cc | 1 + 9 files changed, 60 insertions(+) New commits: commit c152d30f879e6cde45de58bb9249035e127e84e7 Author: Hib Eris Date: Mon Apr 5 18:55:29 2010 +0200 delete fileName in utils diff --git a/utils/pdftohtml.cc b/utils/pdftohtml.cc index 53d9ecb..74733e7 100644 --- a/utils/pdftohtml.cc +++ b/utils/pdftohtml.cc @@ -389,6 +389,7 @@ int main(int argc, char *argv[]) { // clean up error: if(doc) delete doc; + delete fileName; if(globalParams) delete globalParams; if(htmlFileName) delete htmlFileName; diff --git a/utils/pdftops.cc b/utils/pdftops.cc index 58ba731..0376e2f 100644 --- a/utils/pdftops.cc +++ b/utils/pdftops.cc @@ -378,6 +378,7 @@ int main(int argc, char *argv[]) { delete psFileName; err1: delete doc; + delete fileName; err0: delete globalParams; diff --git a/utils/pdftotext.cc b/utils/pdftotext.cc index cb530a9..cee40fa 100644 --- a/utils/pdftotext.cc +++ b/utils/pdftotext.cc @@ -334,6 +334,7 @@ int main(int argc, char *argv[]) { delete textFileName; err2: delete doc; + delete fileName; uMap->decRefCnt(); err1: delete globalParams; commit f091c83414ab32a4ecf1fa2bd15f13a3cf113a86 Author: Hib Eris Date: Mon Apr 5 20:12:01 2010 +0100 add some docu diff --git a/poppler/CachedFile.h b/poppler/CachedFile.h index eefb2a3..897ff4a 100644 --- a/poppler/CachedFile.h +++ b/poppler/CachedFile.h @@ -30,6 +30,13 @@ class GooString; class CachedFileLoader; //------------------------------------------------------------------------ +// CachedFile +// +// CachedFile gives FILE-like access to a document at a specified URI. +// In the constructor, you specify a CachedFileLoader that handles loading +// the data from the document. The CachedFile requests no more data then it +// needs from the CachedFileLoader. +//------------------------------------------------------------------------ class CachedFile { @@ -79,14 +86,24 @@ private: }; //------------------------------------------------------------------------ +// CachedFileWriter +// +// CachedFileWriter handles sequential writes to a CachedFile. +// On construction, you specify the CachedFile and the chunks of it to which data +// should be written. +//------------------------------------------------------------------------ class CachedFileWriter { public: + // Construct a CachedFile Writer. + // The caller is responsible for deleting the cachedFile and chunksA. CachedFileWriter(CachedFile *cachedFile, GooVector *chunksA); + ~CachedFileWriter(); + // Writes size bytes from ptr to cachedFile, returns number of bytes written. size_t write(const char *ptr, size_t size); private: @@ -99,13 +116,26 @@ private: }; //------------------------------------------------------------------------ +// CachedFileLoader +// +// CachedFileLoader is an abstact class that specifies the interface for +// loadng data from an URI into a CachedFile. +//------------------------------------------------------------------------ class CachedFileLoader { public: virtual ~CachedFileLoader() {}; + + // Initializes the file load. + // Returns the length of the file. + // The caller is responsible for deleting uri and cachedFile. virtual size_t init(GooString *uri, CachedFile *cachedFile) = 0; + + // Loads speficified byte ranges and passes it to the writer to store them. + // Returns 0 on success, Anything but 0 on failure. + // The caller is responsible for deleting the writer. virtual int load(const GooVector &ranges, CachedFileWriter *writer) = 0; }; diff --git a/poppler/CurlPDFDocBuilder.h b/poppler/CurlPDFDocBuilder.h index 75f9f62..fb34862 100644 --- a/poppler/CurlPDFDocBuilder.h +++ b/poppler/CurlPDFDocBuilder.h @@ -16,6 +16,8 @@ //------------------------------------------------------------------------ // CurlPDFDocBuilder +// +// The CurlPDFDocBuilder implements a PDFDocBuilder for 'http(s)://'. //------------------------------------------------------------------------ class CurlPDFDocBuilder : public PDFDocBuilder { diff --git a/poppler/LocalPDFDocBuilder.h b/poppler/LocalPDFDocBuilder.h index 5b90a1e..c2b1d90 100644 --- a/poppler/LocalPDFDocBuilder.h +++ b/poppler/LocalPDFDocBuilder.h @@ -16,6 +16,8 @@ //------------------------------------------------------------------------ // LocalPDFDocBuilder +// +// The LocalPDFDocBuilder implements a PDFDocBuilder for local files. //------------------------------------------------------------------------ class LocalPDFDocBuilder : public PDFDocBuilder { diff --git a/poppler/PDFDocBuilder.h b/poppler/PDFDocBuilder.h index 43d7b0d..d6eccf5 100644 --- a/poppler/PDFDocBuilder.h +++ b/poppler/PDFDocBuilder.h @@ -17,6 +17,9 @@ class GooString; //------------------------------------------------------------------------ // PDFDocBuilder +// +// PDFDocBuilder is an abstract class that specifies the interface for +// constructing PDFDocs. //------------------------------------------------------------------------ class PDFDocBuilder { @@ -24,8 +27,14 @@ class PDFDocBuilder { public: virtual ~PDFDocBuilder() {}; + + // Builds a new PDFDoc. Returns a PDFDoc. You should check this PDFDoc + // with PDFDoc::isOk() for failures. + // The caller is responsible for deleting ownerPassword, userPassWord and guiData. virtual PDFDoc *buildPDFDoc(const GooString &uri, GooString *ownerPassword = NULL, GooString *userPassword = NULL, void *guiDataA = NULL) = 0; + + // Returns gTrue if the builder supports building a PDFDoc from the URI. virtual GBool supports(const GooString &uri) = 0; }; diff --git a/poppler/PDFDocFactory.h b/poppler/PDFDocFactory.h index 609c4c4..dbceaa5 100644 --- a/poppler/PDFDocFactory.h +++ b/poppler/PDFDocFactory.h @@ -20,6 +20,14 @@ class PDFDocBuilder; //------------------------------------------------------------------------ // PDFDocFactory +// +// PDFDocFactory allows the construction of PDFDocs from different URIs. +// +// By default, it supports local files, 'file://' and 'fd:0' (stdin). When +// compiled with libcurl, it also supports 'http://' and 'https://'. +// +// You can extend the supported URIs by giving a list of PDFDocBuilders to +// the constructor, or by registering a new PDFDocBuilder afterwards. //------------------------------------------------------------------------ class PDFDocFactory { @@ -29,9 +37,13 @@ public: PDFDocFactory(GooList *pdfDocBuilders = NULL); ~PDFDocFactory(); + // Create a PDFDoc. Returns a PDFDoc. You should check this PDFDoc + // with PDFDoc::isOk() for failures. + // The caller is responsible for deleting ownerPassword, userPassWord and guiData. PDFDoc *createPDFDoc(const GooString &uri, GooString *ownerPassword = NULL, GooString *userPassword = NULL, void *guiDataA = NULL); + // Extend supported URIs with the ones from the PDFDocBuilder. void registerPDFDocBuilder(PDFDocBuilder *pdfDocBuilder); private: diff --git a/poppler/StdinPDFDocBuilder.h b/poppler/StdinPDFDocBuilder.h index 2fe60e0..e9b2f47 100644 --- a/poppler/StdinPDFDocBuilder.h +++ b/poppler/StdinPDFDocBuilder.h @@ -16,6 +16,8 @@ //------------------------------------------------------------------------ // StdinPDFDocBuilder +// +// The StdinPDFDocBuilder implements a PDFDocBuilder that read from stdin. //------------------------------------------------------------------------ class StdinPDFDocBuilder : public PDFDocBuilder { From hib at hiberis.nl Mon Apr 5 12:37:18 2010 From: hib at hiberis.nl (Hib Eris) Date: Mon, 5 Apr 2010 21:37:18 +0200 Subject: [poppler] Towards support for linearized PDFs Message-ID: Hi, As a first step towards support for linearized PDFs I have some patches that changes to way the Catalog is initialized. Much of the things it the Catalog are not always needed and their initialization can be deferred to when they are needed. This first batch of patches is fairly simple. The more invasive ones will come later. The last patch in this series is almost certainly incorrect, but I would like some input on it. It is dealing with form widgets. Question: can this postWidgetsLoad() be done on a per page basis, or is it something global to the whole document? Cheers, Hib -------------- next part -------------- From c2c8b384788fe521386371e04dad69227817c7fe Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Sat, 27 Mar 2010 14:43:57 +0100 Subject: [PATCH 01/10] Parse PageMode and PageLayout on demand --- poppler/Catalog.cc | 103 ++++++++++++++++++++++++++++++++++------------------ poppler/Catalog.h | 7 +++- 2 files changed, 73 insertions(+), 37 deletions(-) diff --git a/poppler/Catalog.cc b/poppler/Catalog.cc index b659180..cdcaf58 100644 --- a/poppler/Catalog.cc +++ b/poppler/Catalog.cc @@ -23,6 +23,7 @@ // Copyright (C) 2007 Julien Rebetez // Copyright (C) 2008 Pino Toscano // Copyright (C) 2009 Ilya Gorenbein +// Copyright (C) 2010 Hib Eris // // 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 @@ -148,41 +149,6 @@ Catalog::Catalog(XRef *xrefA) { pageLabelInfo = new PageLabelInfo(&obj, numPages); obj.free(); - // read page mode - pageMode = pageModeNone; - if (catDict.dictLookup("PageMode", &obj)->isName()) { - if (obj.isName("UseNone")) - pageMode = pageModeNone; - else if (obj.isName("UseOutlines")) - pageMode = pageModeOutlines; - else if (obj.isName("UseThumbs")) - pageMode = pageModeThumbs; - else if (obj.isName("FullScreen")) - pageMode = pageModeFullScreen; - else if (obj.isName("UseOC")) - pageMode = pageModeOC; - else if (obj.isName("UseAttachments")) - pageMode = pageModeAttach; - } - obj.free(); - - pageLayout = pageLayoutNone; - if (catDict.dictLookup("PageLayout", &obj)->isName()) { - if (obj.isName("SinglePage")) - pageLayout = pageLayoutSinglePage; - if (obj.isName("OneColumn")) - pageLayout = pageLayoutOneColumn; - if (obj.isName("TwoColumnLeft")) - pageLayout = pageLayoutTwoColumnLeft; - if (obj.isName("TwoColumnRight")) - pageLayout = pageLayoutTwoColumnRight; - if (obj.isName("TwoPageLeft")) - pageLayout = pageLayoutTwoPageLeft; - if (obj.isName("TwoPageRight")) - pageLayout = pageLayoutTwoPageRight; - } - obj.free(); - // read base URI if (catDict.dictLookup("URI", &obj)->isDict()) { if (obj.dictLookup("Base", &obj2)->isString()) { @@ -473,6 +439,73 @@ GooString *Catalog::getJS(int i) return js; } +Catalog::PageMode Catalog::getPageMode() { + + if (pageMode == pageModeNull) { + + Object catDict, obj; + + pageMode = pageModeNone; + + xref->getCatalog(&catDict); + if (!catDict.isDict()) { + error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName()); + return pageMode; + } + + if (catDict.dictLookup("PageMode", &obj)->isName()) { + if (obj.isName("UseNone")) + pageMode = pageModeNone; + else if (obj.isName("UseOutlines")) + pageMode = pageModeOutlines; + else if (obj.isName("UseThumbs")) + pageMode = pageModeThumbs; + else if (obj.isName("FullScreen")) + pageMode = pageModeFullScreen; + else if (obj.isName("UseOC")) + pageMode = pageModeOC; + else if (obj.isName("UseAttachments")) + pageMode = pageModeAttach; + } + obj.free(); + } + return pageMode; +} + +Catalog::PageLayout Catalog::getPageLayout() { + + if (pageLayout == pageLayoutNull) { + + Object catDict, obj; + + pageLayout = pageLayoutNone; + + xref->getCatalog(&catDict); + if (!catDict.isDict()) { + error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName()); + return pageLayout; + } + + pageLayout = pageLayoutNone; + if (catDict.dictLookup("PageLayout", &obj)->isName()) { + if (obj.isName("SinglePage")) + pageLayout = pageLayoutSinglePage; + if (obj.isName("OneColumn")) + pageLayout = pageLayoutOneColumn; + if (obj.isName("TwoColumnLeft")) + pageLayout = pageLayoutTwoColumnLeft; + if (obj.isName("TwoColumnRight")) + pageLayout = pageLayoutTwoColumnRight; + if (obj.isName("TwoPageLeft")) + pageLayout = pageLayoutTwoPageLeft; + if (obj.isName("TwoPageRight")) + pageLayout = pageLayoutTwoPageRight; + } + obj.free(); + } + return pageLayout; +} + NameTree::NameTree() { size = 0; diff --git a/poppler/Catalog.h b/poppler/Catalog.h index f5b389f..52ee966 100644 --- a/poppler/Catalog.h +++ b/poppler/Catalog.h @@ -19,6 +19,7 @@ // Copyright (C) 2005, 2006, 2008 Brad Hards // Copyright (C) 2007 Julien Rebetez // Copyright (C) 2008 Pino Toscano +// Copyright (C) 2010 Hib Eris // // 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 @@ -200,6 +201,7 @@ public: Form* getForm() { return form; } enum PageMode { + pageModeNull, pageModeNone, pageModeOutlines, pageModeThumbs, @@ -208,6 +210,7 @@ public: pageModeAttach }; enum PageLayout { + pageLayoutNull, pageLayoutNone, pageLayoutSinglePage, pageLayoutOneColumn, @@ -218,8 +221,8 @@ public: }; // Returns the page mode. - PageMode getPageMode() { return pageMode; } - PageLayout getPageLayout() { return pageLayout; } + PageMode getPageMode(); + PageLayout getPageLayout(); private: -- 1.6.4.2 From 8083b1fcc95f6c8ab504d223a6b86a90a514542c Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Thu, 25 Mar 2010 15:09:58 +0100 Subject: [PATCH 02/10] Parse PageLabelInfo on demand --- poppler/Catalog.cc | 35 +++++++++++++++++++++++++++-------- poppler/Catalog.h | 3 +++ 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/poppler/Catalog.cc b/poppler/Catalog.cc index cdcaf58..c537e7d 100644 --- a/poppler/Catalog.cc +++ b/poppler/Catalog.cc @@ -145,10 +145,6 @@ Catalog::Catalog(XRef *xrefA) { } obj.free(); - if (catDict.dictLookup("PageLabels", &obj)->isDict()) - pageLabelInfo = new PageLabelInfo(&obj, numPages); - obj.free(); - // read base URI if (catDict.dictLookup("URI", &obj)->isDict()) { if (obj.dictLookup("Base", &obj2)->isString()) { @@ -636,8 +632,9 @@ GBool Catalog::labelToIndex(GooString *label, int *index) { char *end; - if (pageLabelInfo != NULL) { - if (!pageLabelInfo->labelToIndex(label, index)) + PageLabelInfo *pli = getPageLabelInfo(); + if (pli != NULL) { + if (!pli->labelToIndex(label, index)) return gFalse; } else { *index = strtol(label->getCString(), &end, 10) - 1; @@ -658,8 +655,9 @@ GBool Catalog::indexToLabel(int index, GooString *label) if (index < 0 || index >= numPages) return gFalse; - if (pageLabelInfo != NULL) { - return pageLabelInfo->indexToLabel(index, label); + PageLabelInfo *pli = getPageLabelInfo(); + if (pli != NULL) { + return pli->indexToLabel(index, label); } else { snprintf(buffer, sizeof (buffer), "%d", index + 1); label->append(buffer); @@ -769,3 +767,24 @@ EmbFile::EmbFile(Object *efDict, GooString *description) if (!m_mimetype) m_mimetype = new GooString(); } + +PageLabelInfo *Catalog::getPageLabelInfo() +{ + if (!pageLabelInfo) { + Object catDict; + Object obj; + + xref->getCatalog(&catDict); + if (!catDict.isDict()) { + error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName()); + return NULL; + } + + if (catDict.dictLookup("PageLabels", &obj)->isDict()) { + pageLabelInfo = new PageLabelInfo(&obj, getNumPages()); + } + obj.free(); + } + + return pageLabelInfo; +} diff --git a/poppler/Catalog.h b/poppler/Catalog.h index 52ee966..3f65404 100644 --- a/poppler/Catalog.h +++ b/poppler/Catalog.h @@ -226,6 +226,9 @@ public: private: + // Get page label info. + PageLabelInfo *getPageLabelInfo(); + XRef *xref; // the xref table for this PDF file Page **pages; // array of pages Ref *pageRefs; // object ID for each page -- 1.6.4.2 From 96b2e0ab586f0086ae0f1d3f50f9866fbf1b8556 Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Thu, 25 Mar 2010 14:55:22 +0100 Subject: [PATCH 03/10] Parse Metadata on demand --- poppler/Catalog.cc | 15 ++++++++++++--- 1 files changed, 12 insertions(+), 3 deletions(-) diff --git a/poppler/Catalog.cc b/poppler/Catalog.cc index c537e7d..bc3deb1 100644 --- a/poppler/Catalog.cc +++ b/poppler/Catalog.cc @@ -154,9 +154,6 @@ Catalog::Catalog(XRef *xrefA) { } obj.free(); - // get the metadata stream - catDict.dictLookup("Metadata", &metadata); - // get the structure tree root catDict.dictLookup("StructTreeRoot", &structTreeRoot); @@ -222,6 +219,18 @@ GooString *Catalog::readMetadata() { Object obj; int c; + if (metadata.isNone()) { + Object catDict; + + xref->getCatalog(&catDict); + if (catDict.isDict()) { + catDict.dictLookup("Metadata", &metadata); + } else { + error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName()); + metadata.initNull(); + } + } + if (!metadata.isStream()) { return NULL; } -- 1.6.4.2 From b8247769b0f4f35fbaea13c9fee830655cfc4e63 Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Thu, 25 Mar 2010 15:51:51 +0100 Subject: [PATCH 04/10] Parse StructTreeRoot on demand --- poppler/Catalog.cc | 21 ++++++++++++++++++--- poppler/Catalog.h | 2 +- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/poppler/Catalog.cc b/poppler/Catalog.cc index bc3deb1..9f5d5e8 100644 --- a/poppler/Catalog.cc +++ b/poppler/Catalog.cc @@ -154,9 +154,6 @@ Catalog::Catalog(XRef *xrefA) { } obj.free(); - // get the structure tree root - catDict.dictLookup("StructTreeRoot", &structTreeRoot); - // get the outline dictionary catDict.dictLookup("Outlines", &outline); @@ -797,3 +794,21 @@ PageLabelInfo *Catalog::getPageLabelInfo() return pageLabelInfo; } + +Object *Catalog::getStructTreeRoot() +{ + if (structTreeRoot.isNone()) + { + Object catDict; + + xref->getCatalog(&catDict); + if (catDict.isDict()) { + catDict.dictLookup("StructTreeRoot", &structTreeRoot); + } else { + error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName()); + structTreeRoot.initNull(); + } + } + + return &structTreeRoot; +} diff --git a/poppler/Catalog.h b/poppler/Catalog.h index 3f65404..24b0295 100644 --- a/poppler/Catalog.h +++ b/poppler/Catalog.h @@ -164,7 +164,7 @@ public: GooString *readMetadata(); // Return the structure tree root object. - Object *getStructTreeRoot() { return &structTreeRoot; } + Object *getStructTreeRoot(); // Find a page, given its object ID. Returns page number, or 0 if // not found. -- 1.6.4.2 From e4a5621ef5d28e165667ab655c0bc466099763bb Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Thu, 25 Mar 2010 16:05:02 +0100 Subject: [PATCH 05/10] Parse Outline on demand --- poppler/Catalog.cc | 22 +++++++++++++++++++--- poppler/Catalog.h | 2 +- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/poppler/Catalog.cc b/poppler/Catalog.cc index 9f5d5e8..6918f08 100644 --- a/poppler/Catalog.cc +++ b/poppler/Catalog.cc @@ -154,9 +154,6 @@ Catalog::Catalog(XRef *xrefA) { } obj.free(); - // get the outline dictionary - catDict.dictLookup("Outlines", &outline); - // get the Optional Content dictionary if (catDict.dictLookup("OCProperties", &optContentProps)->isDict()) { optContent = new OCGs(&optContentProps, xref); @@ -812,3 +809,22 @@ Object *Catalog::getStructTreeRoot() return &structTreeRoot; } + +Object *Catalog::getOutline() +{ + if (outline.isNone()) + { + Object catDict; + + xref->getCatalog(&catDict); + if (catDict.isDict()) { + catDict.dictLookup("Outlines", &outline); + } else { + error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName()); + outline.initNull(); + } + } + + return &outline; +} + diff --git a/poppler/Catalog.h b/poppler/Catalog.h index 24b0295..c8c30ec 100644 --- a/poppler/Catalog.h +++ b/poppler/Catalog.h @@ -192,7 +192,7 @@ public: GBool labelToIndex(GooString *label, int *index); GBool indexToLabel(int index, GooString *label); - Object *getOutline() { return &outline; } + Object *getOutline(); Object *getAcroForm() { return &acroForm; } -- 1.6.4.2 From d04ce9305cf7f2da151d05d37f555ff505a93cd4 Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Thu, 25 Mar 2010 16:48:07 +0100 Subject: [PATCH 06/10] Parse Outline on demand in PDFDoc --- poppler/PDFDoc.cc | 17 ++++++++++++----- poppler/PDFDoc.h | 2 +- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/poppler/PDFDoc.cc b/poppler/PDFDoc.cc index 78b6593..ef8748a 100644 --- a/poppler/PDFDoc.cc +++ b/poppler/PDFDoc.cc @@ -226,11 +226,6 @@ GBool PDFDoc::setup(GooString *ownerPassword, GooString *userPassword) { return gFalse; } -#ifndef DISABLE_OUTLINE - // read outline - outline = new Outline(catalog->getOutline(), xref); -#endif - // done return gTrue; } @@ -908,6 +903,18 @@ void PDFDoc::writeTrailer (Guint uxrefOffset, int uxrefSize, OutStream* outStr, delete trailerDict; } +#ifndef DISABLE_OUTLINE +Outline *PDFDoc::getOutline() +{ + if (!outline) { + // read outline + outline = new Outline(catalog->getOutline(), xref); + } + + return outline; +} +#endif + PDFDoc *PDFDoc::ErrorPDFDoc(int errorCode, GooString *fileNameA) { PDFDoc *doc = new PDFDoc(); diff --git a/poppler/PDFDoc.h b/poppler/PDFDoc.h index 79f6d6d..6d7dea2 100644 --- a/poppler/PDFDoc.h +++ b/poppler/PDFDoc.h @@ -170,7 +170,7 @@ public: #ifndef DISABLE_OUTLINE // Return the outline object. - Outline *getOutline() { return outline; } + Outline *getOutline(); #endif // Is the file encrypted? -- 1.6.4.2 From 3f4fbd983212817f30b99d8b81eeb15fc29a315a Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Thu, 25 Mar 2010 16:32:22 +0100 Subject: [PATCH 07/10] Parse Dests on demand --- poppler/Catalog.cc | 26 ++++++++++++++++++++------ poppler/Catalog.h | 2 +- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/poppler/Catalog.cc b/poppler/Catalog.cc index 6918f08..549544a 100644 --- a/poppler/Catalog.cc +++ b/poppler/Catalog.cc @@ -128,9 +128,6 @@ Catalog::Catalog(XRef *xrefA) { } pagesDict.free(); - // read named destination dictionary - catDict.dictLookup("Dests", &dests); - // read root of named destination tree - PDF1.6 table 3.28 if (catDict.dictLookup("Names", &obj)->isDict()) { obj.dictLookup("Dests", &obj2); @@ -175,7 +172,6 @@ Catalog::Catalog(XRef *xrefA) { pagesDict.free(); err1: catDict.free(); - dests.initNull(); ok = gFalse; } @@ -340,8 +336,8 @@ LinkDest *Catalog::findDest(GooString *name) { // try named destination dictionary then name tree found = gFalse; - if (dests.isDict()) { - if (!dests.dictLookup(name->getCString(), &obj1)->isNull()) + if (getDests()->isDict()) { + if (!getDests()->dictLookup(name->getCString(), &obj1)->isNull()) found = gTrue; else obj1.free(); @@ -828,3 +824,21 @@ Object *Catalog::getOutline() return &outline; } +Object *Catalog::getDests() +{ + if (dests.isNone()) + { + Object catDict; + + xref->getCatalog(&catDict); + if (catDict.isDict()) { + catDict.dictLookup("Dests", &dests); + } else { + error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName()); + dests.initNull(); + } + } + + return &dests; +} + diff --git a/poppler/Catalog.h b/poppler/Catalog.h index c8c30ec..3d95b2e 100644 --- a/poppler/Catalog.h +++ b/poppler/Catalog.h @@ -174,7 +174,7 @@ public: // NULL if is not a destination. LinkDest *findDest(GooString *name); - Object *getDests() { return &dests; } + Object *getDests(); // Get the number of embedded files int numEmbeddedFiles() { return embeddedFileNameTree.numEntries(); } -- 1.6.4.2 From c2351c4ab7059f65817ae75423a7d093bc85fa7f Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Thu, 25 Mar 2010 17:33:11 +0100 Subject: [PATCH 08/10] Parse Names on demand --- poppler/Catalog.cc | 93 ++++++++++++++++++++++++++++++++++++++++++---------- poppler/Catalog.h | 9 +++++ 2 files changed, 84 insertions(+), 18 deletions(-) diff --git a/poppler/Catalog.cc b/poppler/Catalog.cc index 549544a..3ad9040 100644 --- a/poppler/Catalog.cc +++ b/poppler/Catalog.cc @@ -128,20 +128,6 @@ Catalog::Catalog(XRef *xrefA) { } pagesDict.free(); - // read root of named destination tree - PDF1.6 table 3.28 - if (catDict.dictLookup("Names", &obj)->isDict()) { - obj.dictLookup("Dests", &obj2); - destNameTree.init(xref, &obj2); - obj2.free(); - obj.dictLookup("EmbeddedFiles", &obj2); - embeddedFileNameTree.init(xref, &obj2); - obj2.free(); - obj.dictLookup("JavaScript", &obj2); - jsNameTree.init(xref, &obj2); - obj2.free(); - } - obj.free(); - // read base URI if (catDict.dictLookup("URI", &obj)->isDict()) { if (obj.dictLookup("Base", &obj2)->isString()) { @@ -343,7 +329,7 @@ LinkDest *Catalog::findDest(GooString *name) { obj1.free(); } if (!found) { - if (destNameTree.lookup(name, &obj1)) + if (getDestNameTree()->lookup(name, &obj1)) found = gTrue; else obj1.free(); @@ -377,10 +363,10 @@ EmbFile *Catalog::embeddedFile(int i) { Object efDict; Object obj; - obj = embeddedFileNameTree.getValue(i); + obj = getEmbeddedFileNameTree()->getValue(i); EmbFile *embeddedFile = 0; if (obj.isRef()) { - GooString desc(embeddedFileNameTree.getName(i)); + GooString desc(getEmbeddedFileNameTree()->getName(i)); embeddedFile = new EmbFile(obj.fetch(xref, &efDict), &desc); efDict.free(); } else { @@ -392,7 +378,7 @@ EmbFile *Catalog::embeddedFile(int i) GooString *Catalog::getJS(int i) { - Object obj = jsNameTree.getValue(i); + Object obj = getJSNameTree()->getValue(i); if (obj.isRef()) { Ref r = obj.getRef(); obj.free(); @@ -503,6 +489,7 @@ Catalog::PageLayout Catalog::getPageLayout() { NameTree::NameTree() { + initialized = gFalse; size = 0; length = 0; entries = NULL; @@ -543,6 +530,7 @@ void NameTree::addEntry(Entry *entry) void NameTree::init(XRef *xrefA, Object *tree) { xref = xrefA; parse(tree); + initialized = gTrue; } void NameTree::parse(Object *tree) { @@ -842,3 +830,72 @@ Object *Catalog::getDests() return &dests; } +Object *Catalog::getNames() +{ + if (names.isNone()) + { + Object catDict; + + xref->getCatalog(&catDict); + if (catDict.isDict()) { + catDict.dictLookup("Names", &names); + } else { + error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName()); + names.initNull(); + } + } + + return &names; +} + +NameTree *Catalog::getDestNameTree() +{ + if (!destNameTree.isInitialized()) { + + if (getNames()->isDict()) { + Object obj; + + getNames()->dictLookup("Dests", &obj); + destNameTree.init(xref, &obj); + obj.free(); + } + + } + + return &destNameTree; +} + +NameTree *Catalog::getEmbeddedFileNameTree() +{ + if (!embeddedFileNameTree.isInitialized()) { + + if (getNames()->isDict()) { + Object obj; + + getNames()->dictLookup("EmbeddedFiles", &obj); + embeddedFileNameTree.init(xref, &obj); + obj.free(); + } + + } + + return &embeddedFileNameTree; +} + +NameTree *Catalog::getJSNameTree() +{ + if (!jsNameTree.isInitialized()) { + + if (getNames()->isDict()) { + Object obj; + + getNames()->dictLookup("JavaScript", &obj); + jsNameTree.init(xref, &obj); + obj.free(); + } + + } + + return &jsNameTree; +} + diff --git a/poppler/Catalog.h b/poppler/Catalog.h index 3d95b2e..2c17060 100644 --- a/poppler/Catalog.h +++ b/poppler/Catalog.h @@ -50,6 +50,7 @@ class OCGs; class NameTree { public: NameTree(); + GBool isInitialized() { return initialized; }; void init(XRef *xref, Object *tree); void parse(Object *tree); GBool lookup(GooString *name, Object *obj); @@ -60,6 +61,7 @@ public: GooString *getName(int i); private: + GBool initialized; struct Entry { Entry(Array *array, int index); ~Entry(); @@ -236,6 +238,7 @@ private: int numPages; // number of pages int pagesSize; // size of pages array Object dests; // named destination dictionary + Object names; // named names dictionary NameTree destNameTree; // named destination name-tree NameTree embeddedFileNameTree; // embedded file name-tree NameTree jsNameTree; // Java Script name-tree @@ -253,6 +256,12 @@ private: int readPageTree(Dict *pages, PageAttrs *attrs, int start, char *alreadyRead); Object *findDestInTree(Object *tree, GooString *name, Object *obj); + + Object *getNames(); + NameTree *getDestNameTree(); + NameTree *getEmbeddedFileNameTree(); + NameTree *getJSNameTree(); + }; #endif -- 1.6.4.2 From 1da5a475e0de07bf7f07b866f6b6360a63a1ff5c Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Thu, 25 Mar 2010 15:33:33 +0100 Subject: [PATCH 09/10] Parse Form on demand --- poppler/Catalog.cc | 23 ++++++++++++++--------- poppler/Catalog.h | 2 +- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/poppler/Catalog.cc b/poppler/Catalog.cc index 3ad9040..94aa817 100644 --- a/poppler/Catalog.cc +++ b/poppler/Catalog.cc @@ -81,13 +81,7 @@ Catalog::Catalog(XRef *xrefA) { // get the AcroForm dictionary catDict.dictLookup("AcroForm", &acroForm); - // load Forms - if (acroForm.isDict()) { - form = new Form(xref,&acroForm); - } - - - // read page tree + // get page count catDict.dictLookup("Pages", &pagesDict); // This should really be isDict("Pages"), but I've seen at least one // PDF file where the /Type entry is missing. @@ -148,8 +142,8 @@ Catalog::Catalog(XRef *xrefA) { optContentProps.free(); // perform form-related loading after all widgets have been loaded - if (form) - form->postWidgetsLoad(); + if (getForm()) + getForm()->postWidgetsLoad(); catDict.free(); return; @@ -830,6 +824,17 @@ Object *Catalog::getDests() return &dests; } +Form *Catalog::getForm() +{ + if (!form) { + if (acroForm.isDict()) { + form = new Form(xref,&acroForm); + } + } + + return form; +} + Object *Catalog::getNames() { if (names.isNone()) diff --git a/poppler/Catalog.h b/poppler/Catalog.h index 2c17060..b0e1286 100644 --- a/poppler/Catalog.h +++ b/poppler/Catalog.h @@ -200,7 +200,7 @@ public: OCGs *getOptContentConfig() { return optContent; } - Form* getForm() { return form; } + Form* getForm(); enum PageMode { pageModeNull, -- 1.6.4.2 From 42439114cdb527bcf9019dc3171f04fe2b958c96 Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Thu, 25 Mar 2010 16:14:35 +0100 Subject: [PATCH 10/10] WIP Fix form loading I am not sure this can be done. --- poppler/Catalog.cc | 7 +++---- 1 files changed, 3 insertions(+), 4 deletions(-) diff --git a/poppler/Catalog.cc b/poppler/Catalog.cc index 94aa817..ba93405 100644 --- a/poppler/Catalog.cc +++ b/poppler/Catalog.cc @@ -141,10 +141,6 @@ Catalog::Catalog(XRef *xrefA) { } optContentProps.free(); - // perform form-related loading after all widgets have been loaded - if (getForm()) - getForm()->postWidgetsLoad(); - catDict.free(); return; @@ -829,6 +825,9 @@ Form *Catalog::getForm() if (!form) { if (acroForm.isDict()) { form = new Form(xref,&acroForm); + + // perform form-related loading after all widgets have been loaded + if (form) form->postWidgetsLoad(); } } -- 1.6.4.2 From aacid at kde.org Mon Apr 5 14:50:36 2010 From: aacid at kde.org (Albert Astals Cid) Date: Mon, 5 Apr 2010 22:50:36 +0100 Subject: [poppler] Towards support for linearized PDFs In-Reply-To: References: Message-ID: <201004052250.36319.aacid@kde.org> A Dilluns, 5 d'abril de 2010, Hib Eris va escriure: > Hi, > > As a first step towards support for linearized PDFs I have some > patches that changes to way the Catalog is initialized. Much of the > things it the Catalog are not always needed and their initialization > can be deferred to when they are needed. This first batch of patches > is fairly simple. The more invasive ones will come later. Some comments: * You don't initialize pageMode nor pageLayout to their null enum values. * I'd like the new enum values to be added to the end to be more saf in case anyone was using the int values to save them somewhere * You should be freeing catDict > > The last patch in this series is almost certainly incorrect, but I > would like some input on it. It is dealing with form widgets. > Question: can this postWidgetsLoad() be done on a per page basis, or > is it something global to the whole document? Probably it could be done per page, if you give a patch i can test all docs in my regression suite to see if we get the same behaviour with your patches or not. Also, can you please enlight us what does this give us towards getting linearized support? Albert > > Cheers, > > Hib From carlosgc at kemper.freedesktop.org Tue Apr 6 03:33:28 2010 From: carlosgc at kemper.freedesktop.org (Carlos Garcia Campos) Date: Tue, 6 Apr 2010 03:33:28 -0700 (PDT) Subject: [poppler] poppler/CairoOutputDev.cc Message-ID: <20100406103328.7969AC0001@kemper.freedesktop.org> poppler/CairoOutputDev.cc | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) New commits: commit 1422802f029483ad3e62a3a13e66b2d3990ac58f Author: Carlos Garcia Campos Date: Tue Apr 6 12:32:12 2010 +0200 [cairo] Use current fill_opacity when drawing soft masked images Fixes GNOME Bug https://bugzilla.gnome.org/show_bug.cgi?id=614915 diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc index c433fdb..cf0b31c 100644 --- a/poppler/CairoOutputDev.cc +++ b/poppler/CairoOutputDev.cc @@ -2140,19 +2140,32 @@ void CairoOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref, Stream *s cairo_matrix_scale (&maskMatrix, maskWidth, -maskHeight); cairo_pattern_set_matrix (maskPattern, &maskMatrix); - if (!printing) { + if (fill_opacity != 1.0) + cairo_push_group (cairo); + else cairo_save (cairo); - cairo_set_source (cairo, pattern); + + cairo_set_source (cairo, pattern); + if (!printing) { cairo_rectangle (cairo, 0., 0., MIN (width, maskWidth) / (double)width, MIN (height, maskHeight) / (double)height); cairo_clip (cairo); - cairo_mask (cairo, maskPattern); - cairo_restore (cairo); - } else { - cairo_set_source (cairo, pattern); - cairo_mask (cairo, maskPattern); } + cairo_mask (cairo, maskPattern); + + if (fill_opacity != 1.0) { + cairo_pop_group_to_source (cairo); + cairo_save (cairo); + if (!printing) { + cairo_rectangle (cairo, 0., 0., + MIN (width, maskWidth) / (double)width, + MIN (height, maskHeight) / (double)height); + cairo_clip (cairo); + } + cairo_paint_with_alpha (cairo, fill_opacity); + } + cairo_restore (cairo); if (cairo_shape) { cairo_save (cairo_shape); From lrosenth at adobe.com Tue Apr 6 04:29:24 2010 From: lrosenth at adobe.com (Leonard Rosenthol) Date: Tue, 6 Apr 2010 04:29:24 -0700 Subject: [poppler] Towards support for linearized PDFs In-Reply-To: References: Message-ID: IN THEORY you could do it per-page, but it would be a LOT more complex to implement since you'd still need to have back-pointers to the information in the /AcroForm dictionary from the catalog. Better to simply load that entire dictionary (and it's children) when encountered. It's why linearization and forms do NOT mix :(. Leonard -----Original Message----- From: poppler-bounces at lists.freedesktop.org [mailto:poppler-bounces at lists.freedesktop.org] On Behalf Of Hib Eris Sent: Monday, April 05, 2010 3:37 PM To: poppler at lists.freedesktop.org Subject: [poppler] Towards support for linearized PDFs Hi, As a first step towards support for linearized PDFs I have some patches that changes to way the Catalog is initialized. Much of the things it the Catalog are not always needed and their initialization can be deferred to when they are needed. This first batch of patches is fairly simple. The more invasive ones will come later. The last patch in this series is almost certainly incorrect, but I would like some input on it. It is dealing with form widgets. Question: can this postWidgetsLoad() be done on a per page basis, or is it something global to the whole document? Cheers, Hib From ceztkoml at gmail.com Tue Apr 6 10:35:52 2010 From: ceztkoml at gmail.com (Francesco Pretto) Date: Tue, 6 Apr 2010 19:35:52 +0200 Subject: [poppler] Which build system: Autotools or CMake? Message-ID: Hello, I'm a newcomer. I'd like to do some hacking with poppler (I will tell later what feature I'm interested in, first let see if I get inside the code enough) but I'm not sure about the build system: it seems that both Autotools and CMake are supported (atm only CMake works perfectly, Autotools seems broken in latest git), which should I prefer while playing with the code? Thanks, Francesco From hib at hiberis.nl Tue Apr 6 11:21:39 2010 From: hib at hiberis.nl (Hib Eris) Date: Tue, 6 Apr 2010 20:21:39 +0200 Subject: [poppler] Towards support for linearized PDFs In-Reply-To: References: <201004052250.36319.aacid@kde.org> Message-ID: Hi all, I have updated the patches taking Albert's comments into account. On Mon, Apr 5, 2010 at 11:50 PM, Albert Astals Cid wrote: > Some comments: > ?* You don't initialize pageMode nor pageLayout to their null enum values. > ?* I'd like the new enum values to be added to the end to be more saf in case > anyone was using the int values to save them somewhere > ?* You should be freeing catDict >> The last patch in this series is almost certainly incorrect, but I >> would like some input on it. It is dealing with form widgets. >> Question: can this postWidgetsLoad() be done on a per page basis, or >> is it something global to the whole document? > > Probably it could be done per page, if you give a patch i can test all docs in > my regression suite to see if we get the same behaviour with your patches or > not. Okay, for now I have left this last patch out of the new patch set. I will study the details of annotations and formfields some more to come up with a better patch. > Also, can you please enlight us what does this give us towards getting > linearized support? The goal of linearized support is to be able to render any page in a document without downloading any unrelated/unnecessary objects. ?To prevent downloading unnecessary objects, the Catalog should only initialize what is absolutely needed and defer initializing anything else to a when it is needed. Linearized support while still initializing objects from all over the document is just not very useful, so I thought it would be wise to first do these things. Hib -------------- next part -------------- From 104ad5659bf0d8584387db77507e16abe86d1e4f Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Sat, 27 Mar 2010 14:43:57 +0100 Subject: [PATCH 1/9] Parse PageMode and PageLayout on demand --- poppler/Catalog.cc | 109 +++++++++++++++++++++++++++++++++++----------------- poppler/Catalog.h | 11 +++-- 2 files changed, 81 insertions(+), 39 deletions(-) diff --git a/poppler/Catalog.cc b/poppler/Catalog.cc index b659180..94ccff2 100644 --- a/poppler/Catalog.cc +++ b/poppler/Catalog.cc @@ -23,6 +23,7 @@ // Copyright (C) 2007 Julien Rebetez // Copyright (C) 2008 Pino Toscano // Copyright (C) 2009 Ilya Gorenbein +// Copyright (C) 2010 Hib Eris // // 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 @@ -71,6 +72,8 @@ Catalog::Catalog(XRef *xrefA) { pageLabelInfo = NULL; form = NULL; optContent = NULL; + pageMode = pageModeNull; + pageLayout = pageLayoutNull; xref->getCatalog(&catDict); if (!catDict.isDict()) { @@ -148,41 +151,6 @@ Catalog::Catalog(XRef *xrefA) { pageLabelInfo = new PageLabelInfo(&obj, numPages); obj.free(); - // read page mode - pageMode = pageModeNone; - if (catDict.dictLookup("PageMode", &obj)->isName()) { - if (obj.isName("UseNone")) - pageMode = pageModeNone; - else if (obj.isName("UseOutlines")) - pageMode = pageModeOutlines; - else if (obj.isName("UseThumbs")) - pageMode = pageModeThumbs; - else if (obj.isName("FullScreen")) - pageMode = pageModeFullScreen; - else if (obj.isName("UseOC")) - pageMode = pageModeOC; - else if (obj.isName("UseAttachments")) - pageMode = pageModeAttach; - } - obj.free(); - - pageLayout = pageLayoutNone; - if (catDict.dictLookup("PageLayout", &obj)->isName()) { - if (obj.isName("SinglePage")) - pageLayout = pageLayoutSinglePage; - if (obj.isName("OneColumn")) - pageLayout = pageLayoutOneColumn; - if (obj.isName("TwoColumnLeft")) - pageLayout = pageLayoutTwoColumnLeft; - if (obj.isName("TwoColumnRight")) - pageLayout = pageLayoutTwoColumnRight; - if (obj.isName("TwoPageLeft")) - pageLayout = pageLayoutTwoPageLeft; - if (obj.isName("TwoPageRight")) - pageLayout = pageLayoutTwoPageRight; - } - obj.free(); - // read base URI if (catDict.dictLookup("URI", &obj)->isDict()) { if (obj.dictLookup("Base", &obj2)->isString()) { @@ -473,6 +441,77 @@ GooString *Catalog::getJS(int i) return js; } +Catalog::PageMode Catalog::getPageMode() { + + if (pageMode == pageModeNull) { + + Object catDict, obj; + + pageMode = pageModeNone; + + xref->getCatalog(&catDict); + if (!catDict.isDict()) { + error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName()); + catDict.free(); + return pageMode; + } + + if (catDict.dictLookup("PageMode", &obj)->isName()) { + if (obj.isName("UseNone")) + pageMode = pageModeNone; + else if (obj.isName("UseOutlines")) + pageMode = pageModeOutlines; + else if (obj.isName("UseThumbs")) + pageMode = pageModeThumbs; + else if (obj.isName("FullScreen")) + pageMode = pageModeFullScreen; + else if (obj.isName("UseOC")) + pageMode = pageModeOC; + else if (obj.isName("UseAttachments")) + pageMode = pageModeAttach; + } + obj.free(); + catDict.free(); + } + return pageMode; +} + +Catalog::PageLayout Catalog::getPageLayout() { + + if (pageLayout == pageLayoutNull) { + + Object catDict, obj; + + pageLayout = pageLayoutNone; + + xref->getCatalog(&catDict); + if (!catDict.isDict()) { + error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName()); + catDict.free(); + return pageLayout; + } + + pageLayout = pageLayoutNone; + if (catDict.dictLookup("PageLayout", &obj)->isName()) { + if (obj.isName("SinglePage")) + pageLayout = pageLayoutSinglePage; + if (obj.isName("OneColumn")) + pageLayout = pageLayoutOneColumn; + if (obj.isName("TwoColumnLeft")) + pageLayout = pageLayoutTwoColumnLeft; + if (obj.isName("TwoColumnRight")) + pageLayout = pageLayoutTwoColumnRight; + if (obj.isName("TwoPageLeft")) + pageLayout = pageLayoutTwoPageLeft; + if (obj.isName("TwoPageRight")) + pageLayout = pageLayoutTwoPageRight; + } + obj.free(); + catDict.free(); + } + return pageLayout; +} + NameTree::NameTree() { size = 0; diff --git a/poppler/Catalog.h b/poppler/Catalog.h index f5b389f..5e84679 100644 --- a/poppler/Catalog.h +++ b/poppler/Catalog.h @@ -19,6 +19,7 @@ // Copyright (C) 2005, 2006, 2008 Brad Hards // Copyright (C) 2007 Julien Rebetez // Copyright (C) 2008 Pino Toscano +// Copyright (C) 2010 Hib Eris // // 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 @@ -205,7 +206,8 @@ public: pageModeThumbs, pageModeFullScreen, pageModeOC, - pageModeAttach + pageModeAttach, + pageModeNull }; enum PageLayout { pageLayoutNone, @@ -214,12 +216,13 @@ public: pageLayoutTwoColumnLeft, pageLayoutTwoColumnRight, pageLayoutTwoPageLeft, - pageLayoutTwoPageRight + pageLayoutTwoPageRight, + pageLayoutNull }; // Returns the page mode. - PageMode getPageMode() { return pageMode; } - PageLayout getPageLayout() { return pageLayout; } + PageMode getPageMode(); + PageLayout getPageLayout(); private: -- 1.6.4.2 From 9adff5602d841a781f3dec5629c7d1e37b073572 Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Thu, 25 Mar 2010 15:09:58 +0100 Subject: [PATCH 2/9] Parse PageLabelInfo on demand --- poppler/Catalog.cc | 37 +++++++++++++++++++++++++++++-------- poppler/Catalog.h | 3 +++ 2 files changed, 32 insertions(+), 8 deletions(-) diff --git a/poppler/Catalog.cc b/poppler/Catalog.cc index 94ccff2..aa21b45 100644 --- a/poppler/Catalog.cc +++ b/poppler/Catalog.cc @@ -147,10 +147,6 @@ Catalog::Catalog(XRef *xrefA) { } obj.free(); - if (catDict.dictLookup("PageLabels", &obj)->isDict()) - pageLabelInfo = new PageLabelInfo(&obj, numPages); - obj.free(); - // read base URI if (catDict.dictLookup("URI", &obj)->isDict()) { if (obj.dictLookup("Base", &obj2)->isString()) { @@ -642,8 +638,9 @@ GBool Catalog::labelToIndex(GooString *label, int *index) { char *end; - if (pageLabelInfo != NULL) { - if (!pageLabelInfo->labelToIndex(label, index)) + PageLabelInfo *pli = getPageLabelInfo(); + if (pli != NULL) { + if (!pli->labelToIndex(label, index)) return gFalse; } else { *index = strtol(label->getCString(), &end, 10) - 1; @@ -664,8 +661,9 @@ GBool Catalog::indexToLabel(int index, GooString *label) if (index < 0 || index >= numPages) return gFalse; - if (pageLabelInfo != NULL) { - return pageLabelInfo->indexToLabel(index, label); + PageLabelInfo *pli = getPageLabelInfo(); + if (pli != NULL) { + return pli->indexToLabel(index, label); } else { snprintf(buffer, sizeof (buffer), "%d", index + 1); label->append(buffer); @@ -775,3 +773,26 @@ EmbFile::EmbFile(Object *efDict, GooString *description) if (!m_mimetype) m_mimetype = new GooString(); } + +PageLabelInfo *Catalog::getPageLabelInfo() +{ + if (!pageLabelInfo) { + Object catDict; + Object obj; + + xref->getCatalog(&catDict); + if (!catDict.isDict()) { + error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName()); + catDict.free(); + return NULL; + } + + if (catDict.dictLookup("PageLabels", &obj)->isDict()) { + pageLabelInfo = new PageLabelInfo(&obj, getNumPages()); + } + obj.free(); + catDict.free(); + } + + return pageLabelInfo; +} diff --git a/poppler/Catalog.h b/poppler/Catalog.h index 5e84679..2f7c616 100644 --- a/poppler/Catalog.h +++ b/poppler/Catalog.h @@ -226,6 +226,9 @@ public: private: + // Get page label info. + PageLabelInfo *getPageLabelInfo(); + XRef *xref; // the xref table for this PDF file Page **pages; // array of pages Ref *pageRefs; // object ID for each page -- 1.6.4.2 From d5239aa800f9a4e047f670ea8968d28e7ae5dd9d Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Thu, 25 Mar 2010 14:55:22 +0100 Subject: [PATCH 3/9] Parse Metadata on demand --- poppler/Catalog.cc | 16 +++++++++++++--- 1 files changed, 13 insertions(+), 3 deletions(-) diff --git a/poppler/Catalog.cc b/poppler/Catalog.cc index aa21b45..d27b6f1 100644 --- a/poppler/Catalog.cc +++ b/poppler/Catalog.cc @@ -156,9 +156,6 @@ Catalog::Catalog(XRef *xrefA) { } obj.free(); - // get the metadata stream - catDict.dictLookup("Metadata", &metadata); - // get the structure tree root catDict.dictLookup("StructTreeRoot", &structTreeRoot); @@ -224,6 +221,19 @@ GooString *Catalog::readMetadata() { Object obj; int c; + if (metadata.isNone()) { + Object catDict; + + xref->getCatalog(&catDict); + if (catDict.isDict()) { + catDict.dictLookup("Metadata", &metadata); + } else { + error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName()); + metadata.initNull(); + } + catDict.free(); + } + if (!metadata.isStream()) { return NULL; } -- 1.6.4.2 From 6f2306a1ae83fe74d0809f4bc36d109bd3e2118d Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Thu, 25 Mar 2010 15:51:51 +0100 Subject: [PATCH 4/9] Parse StructTreeRoot on demand --- poppler/Catalog.cc | 22 +++++++++++++++++++--- poppler/Catalog.h | 2 +- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/poppler/Catalog.cc b/poppler/Catalog.cc index d27b6f1..bcae737 100644 --- a/poppler/Catalog.cc +++ b/poppler/Catalog.cc @@ -156,9 +156,6 @@ Catalog::Catalog(XRef *xrefA) { } obj.free(); - // get the structure tree root - catDict.dictLookup("StructTreeRoot", &structTreeRoot); - // get the outline dictionary catDict.dictLookup("Outlines", &outline); @@ -806,3 +803,22 @@ PageLabelInfo *Catalog::getPageLabelInfo() return pageLabelInfo; } + +Object *Catalog::getStructTreeRoot() +{ + if (structTreeRoot.isNone()) + { + Object catDict; + + xref->getCatalog(&catDict); + if (catDict.isDict()) { + catDict.dictLookup("StructTreeRoot", &structTreeRoot); + } else { + error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName()); + structTreeRoot.initNull(); + } + catDict.free(); + } + + return &structTreeRoot; +} diff --git a/poppler/Catalog.h b/poppler/Catalog.h index 2f7c616..a55d449 100644 --- a/poppler/Catalog.h +++ b/poppler/Catalog.h @@ -164,7 +164,7 @@ public: GooString *readMetadata(); // Return the structure tree root object. - Object *getStructTreeRoot() { return &structTreeRoot; } + Object *getStructTreeRoot(); // Find a page, given its object ID. Returns page number, or 0 if // not found. -- 1.6.4.2 From 05ae1c68c1d80c2cb9f86428c3b6f5b60cc56ac5 Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Thu, 25 Mar 2010 16:05:02 +0100 Subject: [PATCH 5/9] Parse Outline on demand --- poppler/Catalog.cc | 23 ++++++++++++++++++++--- poppler/Catalog.h | 2 +- 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/poppler/Catalog.cc b/poppler/Catalog.cc index bcae737..f6a8bef 100644 --- a/poppler/Catalog.cc +++ b/poppler/Catalog.cc @@ -156,9 +156,6 @@ Catalog::Catalog(XRef *xrefA) { } obj.free(); - // get the outline dictionary - catDict.dictLookup("Outlines", &outline); - // get the Optional Content dictionary if (catDict.dictLookup("OCProperties", &optContentProps)->isDict()) { optContent = new OCGs(&optContentProps, xref); @@ -822,3 +819,23 @@ Object *Catalog::getStructTreeRoot() return &structTreeRoot; } + +Object *Catalog::getOutline() +{ + if (outline.isNone()) + { + Object catDict; + + xref->getCatalog(&catDict); + if (catDict.isDict()) { + catDict.dictLookup("Outlines", &outline); + } else { + error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName()); + outline.initNull(); + } + catDict.free(); + } + + return &outline; +} + diff --git a/poppler/Catalog.h b/poppler/Catalog.h index a55d449..cfae726 100644 --- a/poppler/Catalog.h +++ b/poppler/Catalog.h @@ -192,7 +192,7 @@ public: GBool labelToIndex(GooString *label, int *index); GBool indexToLabel(int index, GooString *label); - Object *getOutline() { return &outline; } + Object *getOutline(); Object *getAcroForm() { return &acroForm; } -- 1.6.4.2 From cf6f71c0a35a72ecb4a61fe80556e3c5d058fe76 Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Thu, 25 Mar 2010 16:48:07 +0100 Subject: [PATCH 6/9] Parse Outline on demand in PDFDoc --- poppler/PDFDoc.cc | 17 ++++++++++++----- poppler/PDFDoc.h | 2 +- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/poppler/PDFDoc.cc b/poppler/PDFDoc.cc index 78b6593..ef8748a 100644 --- a/poppler/PDFDoc.cc +++ b/poppler/PDFDoc.cc @@ -226,11 +226,6 @@ GBool PDFDoc::setup(GooString *ownerPassword, GooString *userPassword) { return gFalse; } -#ifndef DISABLE_OUTLINE - // read outline - outline = new Outline(catalog->getOutline(), xref); -#endif - // done return gTrue; } @@ -908,6 +903,18 @@ void PDFDoc::writeTrailer (Guint uxrefOffset, int uxrefSize, OutStream* outStr, delete trailerDict; } +#ifndef DISABLE_OUTLINE +Outline *PDFDoc::getOutline() +{ + if (!outline) { + // read outline + outline = new Outline(catalog->getOutline(), xref); + } + + return outline; +} +#endif + PDFDoc *PDFDoc::ErrorPDFDoc(int errorCode, GooString *fileNameA) { PDFDoc *doc = new PDFDoc(); diff --git a/poppler/PDFDoc.h b/poppler/PDFDoc.h index 79f6d6d..6d7dea2 100644 --- a/poppler/PDFDoc.h +++ b/poppler/PDFDoc.h @@ -170,7 +170,7 @@ public: #ifndef DISABLE_OUTLINE // Return the outline object. - Outline *getOutline() { return outline; } + Outline *getOutline(); #endif // Is the file encrypted? -- 1.6.4.2 From 735125f91dbc5be222257d39a901f70575c9f799 Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Thu, 25 Mar 2010 16:32:22 +0100 Subject: [PATCH 7/9] Parse Dests on demand --- poppler/Catalog.cc | 27 +++++++++++++++++++++------ poppler/Catalog.h | 2 +- 2 files changed, 22 insertions(+), 7 deletions(-) diff --git a/poppler/Catalog.cc b/poppler/Catalog.cc index f6a8bef..07b1e20 100644 --- a/poppler/Catalog.cc +++ b/poppler/Catalog.cc @@ -130,9 +130,6 @@ Catalog::Catalog(XRef *xrefA) { } pagesDict.free(); - // read named destination dictionary - catDict.dictLookup("Dests", &dests); - // read root of named destination tree - PDF1.6 table 3.28 if (catDict.dictLookup("Names", &obj)->isDict()) { obj.dictLookup("Dests", &obj2); @@ -177,7 +174,6 @@ Catalog::Catalog(XRef *xrefA) { pagesDict.free(); err1: catDict.free(); - dests.initNull(); ok = gFalse; } @@ -343,8 +339,8 @@ LinkDest *Catalog::findDest(GooString *name) { // try named destination dictionary then name tree found = gFalse; - if (dests.isDict()) { - if (!dests.dictLookup(name->getCString(), &obj1)->isNull()) + if (getDests()->isDict()) { + if (!getDests()->dictLookup(name->getCString(), &obj1)->isNull()) found = gTrue; else obj1.free(); @@ -839,3 +835,22 @@ Object *Catalog::getOutline() return &outline; } +Object *Catalog::getDests() +{ + if (dests.isNone()) + { + Object catDict; + + xref->getCatalog(&catDict); + if (catDict.isDict()) { + catDict.dictLookup("Dests", &dests); + } else { + error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName()); + dests.initNull(); + } + catDict.free(); + } + + return &dests; +} + diff --git a/poppler/Catalog.h b/poppler/Catalog.h index cfae726..134f1db 100644 --- a/poppler/Catalog.h +++ b/poppler/Catalog.h @@ -174,7 +174,7 @@ public: // NULL if is not a destination. LinkDest *findDest(GooString *name); - Object *getDests() { return &dests; } + Object *getDests(); // Get the number of embedded files int numEmbeddedFiles() { return embeddedFileNameTree.numEntries(); } -- 1.6.4.2 From f41b8a40f37cb1105695a5d40299c593f6f9e692 Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Thu, 25 Mar 2010 17:33:11 +0100 Subject: [PATCH 8/9] Parse Names on demand --- poppler/Catalog.cc | 112 ++++++++++++++++++++++++++++++++++++++++++---------- poppler/Catalog.h | 18 ++++++-- 2 files changed, 104 insertions(+), 26 deletions(-) diff --git a/poppler/Catalog.cc b/poppler/Catalog.cc index 07b1e20..4135d79 100644 --- a/poppler/Catalog.cc +++ b/poppler/Catalog.cc @@ -74,6 +74,9 @@ Catalog::Catalog(XRef *xrefA) { optContent = NULL; pageMode = pageModeNull; pageLayout = pageLayoutNull; + destNameTree = NULL; + embeddedFileNameTree = NULL; + jsNameTree = NULL; xref->getCatalog(&catDict); if (!catDict.isDict()) { @@ -130,20 +133,6 @@ Catalog::Catalog(XRef *xrefA) { } pagesDict.free(); - // read root of named destination tree - PDF1.6 table 3.28 - if (catDict.dictLookup("Names", &obj)->isDict()) { - obj.dictLookup("Dests", &obj2); - destNameTree.init(xref, &obj2); - obj2.free(); - obj.dictLookup("EmbeddedFiles", &obj2); - embeddedFileNameTree.init(xref, &obj2); - obj2.free(); - obj.dictLookup("JavaScript", &obj2); - jsNameTree.init(xref, &obj2); - obj2.free(); - } - obj.free(); - // read base URI if (catDict.dictLookup("URI", &obj)->isDict()) { if (obj.dictLookup("Base", &obj2)->isString()) { @@ -190,9 +179,9 @@ Catalog::~Catalog() { gfree(pageRefs); } dests.free(); - destNameTree.free(); - embeddedFileNameTree.free(); - jsNameTree.free(); + delete destNameTree; + delete embeddedFileNameTree; + delete jsNameTree; if (baseURI) { delete baseURI; } @@ -346,7 +335,7 @@ LinkDest *Catalog::findDest(GooString *name) { obj1.free(); } if (!found) { - if (destNameTree.lookup(name, &obj1)) + if (getDestNameTree()->lookup(name, &obj1)) found = gTrue; else obj1.free(); @@ -380,10 +369,10 @@ EmbFile *Catalog::embeddedFile(int i) { Object efDict; Object obj; - obj = embeddedFileNameTree.getValue(i); + obj = getEmbeddedFileNameTree()->getValue(i); EmbFile *embeddedFile = 0; if (obj.isRef()) { - GooString desc(embeddedFileNameTree.getName(i)); + GooString desc(getEmbeddedFileNameTree()->getName(i)); embeddedFile = new EmbFile(obj.fetch(xref, &efDict), &desc); efDict.free(); } else { @@ -395,7 +384,7 @@ EmbFile *Catalog::embeddedFile(int i) GooString *Catalog::getJS(int i) { - Object obj = jsNameTree.getValue(i); + Object obj = getJSNameTree()->getValue(i); if (obj.isRef()) { Ref r = obj.getRef(); obj.free(); @@ -515,6 +504,11 @@ NameTree::NameTree() entries = NULL; } +NameTree::~NameTree() +{ + this->free(); +} + NameTree::Entry::Entry(Array *array, int index) { if (!array->getString(index, &name) || !array->getNF(index + 1, &value)) { Object aux; @@ -854,3 +848,79 @@ Object *Catalog::getDests() return &dests; } +Object *Catalog::getNames() +{ + if (names.isNone()) + { + Object catDict; + + xref->getCatalog(&catDict); + if (catDict.isDict()) { + catDict.dictLookup("Names", &names); + } else { + error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName()); + names.initNull(); + } + catDict.free(); + } + + return &names; +} + +NameTree *Catalog::getDestNameTree() +{ + if (!destNameTree) { + + destNameTree = new NameTree(); + + if (getNames()->isDict()) { + Object obj; + + getNames()->dictLookup("Dests", &obj); + destNameTree->init(xref, &obj); + obj.free(); + } + + } + + return destNameTree; +} + +NameTree *Catalog::getEmbeddedFileNameTree() +{ + if (!embeddedFileNameTree) { + + embeddedFileNameTree = new NameTree(); + + if (getNames()->isDict()) { + Object obj; + + getNames()->dictLookup("EmbeddedFiles", &obj); + embeddedFileNameTree->init(xref, &obj); + obj.free(); + } + + } + + return embeddedFileNameTree; +} + +NameTree *Catalog::getJSNameTree() +{ + if (!jsNameTree) { + + jsNameTree = new NameTree(); + + if (getNames()->isDict()) { + Object obj; + + getNames()->dictLookup("JavaScript", &obj); + jsNameTree->init(xref, &obj); + obj.free(); + } + + } + + return jsNameTree; +} + diff --git a/poppler/Catalog.h b/poppler/Catalog.h index 134f1db..6021eed 100644 --- a/poppler/Catalog.h +++ b/poppler/Catalog.h @@ -50,6 +50,7 @@ class OCGs; class NameTree { public: NameTree(); + ~NameTree(); void init(XRef *xref, Object *tree); void parse(Object *tree); GBool lookup(GooString *name, Object *obj); @@ -177,13 +178,13 @@ public: Object *getDests(); // Get the number of embedded files - int numEmbeddedFiles() { return embeddedFileNameTree.numEntries(); } + int numEmbeddedFiles() { return getEmbeddedFileNameTree()->numEntries(); } // Get the i'th file embedded (at the Document level) in the document EmbFile *embeddedFile(int i); // Get the number of javascript scripts - int numJS() { return jsNameTree.numEntries(); } + int numJS() { return getJSNameTree()->numEntries(); } // Get the i'th JavaScript script (at the Document level) in the document GooString *getJS(int i); @@ -236,9 +237,10 @@ private: int numPages; // number of pages int pagesSize; // size of pages array Object dests; // named destination dictionary - NameTree destNameTree; // named destination name-tree - NameTree embeddedFileNameTree; // embedded file name-tree - NameTree jsNameTree; // Java Script name-tree + Object names; // named names dictionary + NameTree *destNameTree; // named destination name-tree + NameTree *embeddedFileNameTree; // embedded file name-tree + NameTree *jsNameTree; // Java Script name-tree GooString *baseURI; // base URI for URI-type links Object metadata; // metadata stream Object structTreeRoot; // structure tree root dictionary @@ -253,6 +255,12 @@ private: int readPageTree(Dict *pages, PageAttrs *attrs, int start, char *alreadyRead); Object *findDestInTree(Object *tree, GooString *name, Object *obj); + + Object *getNames(); + NameTree *getDestNameTree(); + NameTree *getEmbeddedFileNameTree(); + NameTree *getJSNameTree(); + }; #endif -- 1.6.4.2 From 9535240d32caafadc15bfa113b841e57f8972339 Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Thu, 25 Mar 2010 15:33:33 +0100 Subject: [PATCH 9/9] Parse Form on demand --- poppler/Catalog.cc | 21 +++++++++++++-------- poppler/Catalog.h | 2 +- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/poppler/Catalog.cc b/poppler/Catalog.cc index 4135d79..a0d33cf 100644 --- a/poppler/Catalog.cc +++ b/poppler/Catalog.cc @@ -86,12 +86,6 @@ Catalog::Catalog(XRef *xrefA) { // get the AcroForm dictionary catDict.dictLookup("AcroForm", &acroForm); - // load Forms - if (acroForm.isDict()) { - form = new Form(xref,&acroForm); - } - - // read page tree catDict.dictLookup("Pages", &pagesDict); // This should really be isDict("Pages"), but I've seen at least one @@ -153,8 +147,8 @@ Catalog::Catalog(XRef *xrefA) { optContentProps.free(); // perform form-related loading after all widgets have been loaded - if (form) - form->postWidgetsLoad(); + if (getForm()) + getForm()->postWidgetsLoad(); catDict.free(); return; @@ -848,6 +842,17 @@ Object *Catalog::getDests() return &dests; } +Form *Catalog::getForm() +{ + if (!form) { + if (acroForm.isDict()) { + form = new Form(xref,&acroForm); + } + } + + return form; +} + Object *Catalog::getNames() { if (names.isNone()) diff --git a/poppler/Catalog.h b/poppler/Catalog.h index 6021eed..fd1c32e 100644 --- a/poppler/Catalog.h +++ b/poppler/Catalog.h @@ -199,7 +199,7 @@ public: OCGs *getOptContentConfig() { return optContent; } - Form* getForm() { return form; } + Form* getForm(); enum PageMode { pageModeNone, -- 1.6.4.2 From aacid at kde.org Tue Apr 6 11:25:51 2010 From: aacid at kde.org (Albert Astals Cid) Date: Tue, 6 Apr 2010 19:25:51 +0100 Subject: [poppler] Which build system: Autotools or CMake? In-Reply-To: References: Message-ID: <201004061925.51720.aacid@kde.org> A Dimarts, 6 d'abril de 2010, Francesco Pretto va escriure: > Hello, > > I'm a newcomer. I'd like to do some hacking with poppler (I will tell > later what feature I'm interested in, first let see if I get inside > the code enough) but I'm not sure about the build system: it seems > that both Autotools and CMake are supported (atm only CMake works > perfectly, Autotools seems broken in latest git), which should I > prefer while playing with the code? Both should work. /me goes to look what happens with autotools. Albert > > Thanks, > Francesco > _______________________________________________ > poppler mailing list > poppler at lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/poppler From aacid at kde.org Tue Apr 6 11:37:58 2010 From: aacid at kde.org (Albert Astals Cid) Date: Tue, 6 Apr 2010 19:37:58 +0100 Subject: [poppler] Which build system: Autotools or CMake? In-Reply-To: <201004061925.51720.aacid@kde.org> References: <201004061925.51720.aacid@kde.org> Message-ID: <201004061937.58999.aacid@kde.org> A Dimarts, 6 d'abril de 2010, Albert Astals Cid va escriure: > A Dimarts, 6 d'abril de 2010, Francesco Pretto va escriure: > > Hello, > > > > I'm a newcomer. I'd like to do some hacking with poppler (I will tell > > later what feature I'm interested in, first let see if I get inside > > the code enough) but I'm not sure about the build system: it seems > > that both Autotools and CMake are supported (atm only CMake works > > perfectly, Autotools seems broken in latest git), which should I > > prefer while playing with the code? > > Both should work. > > /me goes to look what happens with autotools. Works for me, can you please post your problem? Albert > > Albert > > > Thanks, > > Francesco > > _______________________________________________ > > poppler mailing list > > poppler at lists.freedesktop.org > > http://lists.freedesktop.org/mailman/listinfo/poppler > > _______________________________________________ > poppler mailing list > poppler at lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/poppler From ceztkoml at gmail.com Tue Apr 6 12:31:59 2010 From: ceztkoml at gmail.com (Francesco Pretto) Date: Tue, 6 Apr 2010 21:31:59 +0200 Subject: [poppler] Which build system: Autotools or CMake? In-Reply-To: <201004061937.58999.aacid@kde.org> References: <201004061925.51720.aacid@kde.org> <201004061937.58999.aacid@kde.org> Message-ID: 2010/4/6 Albert Astals Cid : > Works for me, can you please post your problem? > Sorted, had to do "autoreconf -i". I'm new with autotools so I'm not sure if there were really a problem, anyway autoconf with clean git pull was failing: $ autoconf configure.ac:9: error: possibly undefined macro: AM_INIT_AUTOMAKE If this token and others are legitimate, please use m4_pattern_allow. See the Autoconf documentation. configure.ac:11: error: possibly undefined macro: AM_CONFIG_HEADER configure.ac:15: error: possibly undefined macro: AC_LIBTOOL_WIN32_DLL configure.ac:17: error: possibly undefined macro: AC_PROG_LIBTOOL configure.ac:69: error: possibly undefined macro: AM_CONDITIONAL configure.ac:105: error: possibly undefined macro: AC_DEFINE_DIR configure.ac:524: error: possibly undefined macro: AM_ICONV From hib at hiberis.nl Tue Apr 6 12:39:50 2010 From: hib at hiberis.nl (Hib Eris) Date: Tue, 6 Apr 2010 21:39:50 +0200 Subject: [poppler] Which build system: Autotools or CMake? In-Reply-To: References: <201004061925.51720.aacid@kde.org> <201004061937.58999.aacid@kde.org> Message-ID: On Tue, Apr 6, 2010 at 9:31 PM, Francesco Pretto wrote: > Sorted, had to do "autoreconf -i". I'm new with autotools so I'm not > sure if there were really a problem, anyway autoconf with clean git > pull was failing: > > $ autoconf > configure.ac:9: error: possibly undefined macro: AM_INIT_AUTOMAKE > ? ? ?If this token and others are legitimate, please use m4_pattern_allow. > ? ? ?See the Autoconf documentation. When you checkout from git, you should use $ ./autogen.sh instead of autoconf/automake/autoreconf. Hib From aacid at kde.org Tue Apr 6 12:39:04 2010 From: aacid at kde.org (Albert Astals Cid) Date: Tue, 6 Apr 2010 20:39:04 +0100 Subject: [poppler] Which build system: Autotools or CMake? In-Reply-To: References: <201004061937.58999.aacid@kde.org> Message-ID: <201004062039.05020.aacid@kde.org> A Dimarts, 6 d'abril de 2010, Francesco Pretto va escriure: > 2010/4/6 Albert Astals Cid : > > Works for me, can you please post your problem? > > Sorted, had to do "autoreconf -i". I'm new with autotools so I'm not > sure if there were really a problem, anyway autoconf with clean git > pull was failing: > > $ autoconf > configure.ac:9: error: possibly undefined macro: AM_INIT_AUTOMAKE > If this token and others are legitimate, please use m4_pattern_allow. > See the Autoconf documentation. > configure.ac:11: error: possibly undefined macro: AM_CONFIG_HEADER > configure.ac:15: error: possibly undefined macro: AC_LIBTOOL_WIN32_DLL > configure.ac:17: error: possibly undefined macro: AC_PROG_LIBTOOL > configure.ac:69: error: possibly undefined macro: AM_CONDITIONAL > configure.ac:105: error: possibly undefined macro: AC_DEFINE_DIR > configure.ac:524: error: possibly undefined macro: AM_ICONV You don't run autoconf and expect it to work, that'd be too easy :D You have autogen.sh to do all the needed voodoo for you if you want to run autotools. Albert > _______________________________________________ > poppler mailing list > poppler at lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/poppler From ceztkoml at gmail.com Tue Apr 6 13:22:38 2010 From: ceztkoml at gmail.com (Francesco Pretto) Date: Tue, 6 Apr 2010 22:22:38 +0200 Subject: [poppler] Which build system: Autotools or CMake? In-Reply-To: <201004062039.05020.aacid@kde.org> References: <201004061937.58999.aacid@kde.org> <201004062039.05020.aacid@kde.org> Message-ID: 2010/4/6 Albert Astals Cid : > > You don't run autoconf and expect it to work, that'd be too easy :D > > You have autogen.sh to do all the needed voodoo for you if you want to run > autotools. > Thanks you and Hib for the primer. Now a good autotools tutorial will help me a lot :) From aacid at kemper.freedesktop.org Tue Apr 6 14:08:08 2010 From: aacid at kemper.freedesktop.org (Albert Astals Cid) Date: Tue, 6 Apr 2010 14:08:08 -0700 (PDT) Subject: [poppler] poppler/Annot.cc Message-ID: <20100406210808.C1EE5C0001@kemper.freedesktop.org> poppler/Annot.cc | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) New commits: commit 198c9d61ba93ba62ea2da44a23cd948d43556c3e Author: Albert Astals Cid Date: Tue Apr 6 22:00:14 2010 +0100 Use the topleft of the Rect of text annots to draw Not use the full rect when we are drawing "our" notes diff --git a/poppler/Annot.cc b/poppler/Annot.cc index 4725686..54faadf 100644 --- a/poppler/Annot.cc +++ b/poppler/Annot.cc @@ -15,7 +15,7 @@ // // Copyright (C) 2006 Scott Turner // Copyright (C) 2007, 2008 Julien Rebetez -// Copyright (C) 2007-2009 Albert Astals Cid +// Copyright (C) 2007-2010 Albert Astals Cid // Copyright (C) 2007-2010 Carlos Garcia Campos // Copyright (C) 2007, 2008 I??igo Mart??nez // Copyright (C) 2007 Jeff Muizelaar @@ -1847,6 +1847,8 @@ void AnnotText::draw(Gfx *gfx, GBool printing) { if (!isVisible (printing)) return; + double rectx2 = rect->x2; + double recty2 = rect->y2; if (appearance.isNull()) { ca = opacity; @@ -1894,12 +1896,15 @@ void AnnotText::draw(Gfx *gfx, GBool printing) { appearStream->setNeedFree(gTrue); appearance.initStream(appearStream); delete appearBuf; + + rectx2 = rect->x1 + 24; + recty2 = rect->y1 + 24; } // draw the appearance stream appearance.fetch(xref, &obj); gfx->drawAnnot(&obj, border, color, ca, - rect->x1, rect->y1, rect->x2, rect->y2); + rect->x1, rect->y1, rectx2, recty2); obj.free(); } From aacid at kemper.freedesktop.org Tue Apr 6 14:48:56 2010 From: aacid at kemper.freedesktop.org (Albert Astals Cid) Date: Tue, 6 Apr 2010 14:48:56 -0700 (PDT) Subject: [poppler] utils/pdfinfo.cc utils/pdftoabw.cc Message-ID: <20100406214856.B2C7FC0001@kemper.freedesktop.org> utils/pdfinfo.cc | 2 +- utils/pdftoabw.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) New commits: commit 425a62b5fa8e4e69bfc1c64ed126b5baac06d78a Author: Hib Eris Date: Tue Apr 6 10:57:30 2010 +0200 pdfutils: fix deleting fileName diff --git a/utils/pdfinfo.cc b/utils/pdfinfo.cc index c645816..2abe8b4 100644 --- a/utils/pdfinfo.cc +++ b/utils/pdfinfo.cc @@ -166,7 +166,6 @@ int main(int argc, char *argv[]) { } doc = PDFDocFactory().createPDFDoc(*fileName, ownerPW, userPW); - delete fileName; if (userPW) { delete userPW; @@ -320,6 +319,7 @@ int main(int argc, char *argv[]) { err2: uMap->decRefCnt(); delete doc; + delete fileName; err1: delete globalParams; err0: diff --git a/utils/pdftoabw.cc b/utils/pdftoabw.cc index 2f7f042..5a53281 100644 --- a/utils/pdftoabw.cc +++ b/utils/pdftoabw.cc @@ -144,7 +144,6 @@ int main(int argc, char *argv[]) { } doc = PDFDocFactory().createPDFDoc(*fileName, ownerPW, userPW); - delete fileName; if (userPW) { delete userPW; @@ -190,6 +189,7 @@ int main(int argc, char *argv[]) { // clean up if(globalParams) delete globalParams; if(doc) delete doc; + delete fileName; if(XMLdoc) xmlFreeDoc(XMLdoc); if(abwOut) delete abwOut; err0: From pino at kemper.freedesktop.org Tue Apr 6 15:13:55 2010 From: pino at kemper.freedesktop.org (Pino Toscano) Date: Tue, 6 Apr 2010 15:13:55 -0700 (PDT) Subject: [poppler] poppler/CachedFile.cc Message-ID: <20100406221355.A81E9C0001@kemper.freedesktop.org> poppler/CachedFile.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) New commits: commit 3f302fdd78cd78873bf5376af84e83741a8daadb Author: Pino Toscano Date: Tue Apr 6 23:58:46 2010 +0200 use a GooVector instead of a non-standard variable-length-array diff --git a/poppler/CachedFile.cc b/poppler/CachedFile.cc index 46627c3..95cc58b 100644 --- a/poppler/CachedFile.cc +++ b/poppler/CachedFile.cc @@ -73,7 +73,7 @@ int CachedFile::cache(const GooVector &origRanges) { GooVector loadChunks; int numChunks = length/CachedFileChunkSize + 1; - char chunkNeeded[numChunks]; + GooVector chunkNeeded(numChunks); int startChunk, endChunk; GooVector chunk_ranges, all; ByteRange range; @@ -86,7 +86,7 @@ int CachedFile::cache(const GooVector &origRanges) ranges = &all; } - memset(&chunkNeeded, 0, numChunks); + memset(&chunkNeeded[0], 0, sizeof(bool) * numChunks); for (size_t i = 0; i < ranges->size(); i++) { if ((*ranges)[i].length == 0) continue; @@ -100,7 +100,7 @@ int CachedFile::cache(const GooVector &origRanges) endChunk = end / CachedFileChunkSize; for (int chunk = startChunk; chunk <= endChunk; chunk++) { if ((*chunks)[chunk].state == chunkStateNew) { - chunkNeeded[chunk] = 1; + chunkNeeded[chunk] = true; } } } From hib at hiberis.nl Wed Apr 7 01:06:27 2010 From: hib at hiberis.nl (Hib Eris) Date: Wed, 7 Apr 2010 10:06:27 +0200 Subject: [poppler] poppler/CachedFile.cc In-Reply-To: <20100406221355.A81E9C0001@kemper.freedesktop.org> References: <20100406221355.A81E9C0001@kemper.freedesktop.org> Message-ID: Hi Pino, Thank you for improving my code. Just a question: I see you are using 'bool'. Often I see the use of 'gBool' in poppler's code. What is preferred in poppler? Hib On Wed, Apr 7, 2010 at 12:13 AM, Pino Toscano wrote: > ?poppler/CachedFile.cc | ? ?6 +++--- > ?1 file changed, 3 insertions(+), 3 deletions(-) > > New commits: > commit 3f302fdd78cd78873bf5376af84e83741a8daadb > Author: Pino Toscano > Date: ? Tue Apr 6 23:58:46 2010 +0200 > > ? ?use a GooVector instead of a non-standard variable-length-array > > diff --git a/poppler/CachedFile.cc b/poppler/CachedFile.cc > index 46627c3..95cc58b 100644 > --- a/poppler/CachedFile.cc > +++ b/poppler/CachedFile.cc > @@ -73,7 +73,7 @@ int CachedFile::cache(const GooVector &origRanges) > ?{ > ? GooVector loadChunks; > ? int numChunks = length/CachedFileChunkSize + 1; > - ?char chunkNeeded[numChunks]; > + ?GooVector chunkNeeded(numChunks); > ? int startChunk, endChunk; > ? GooVector chunk_ranges, all; > ? ByteRange range; > @@ -86,7 +86,7 @@ int CachedFile::cache(const GooVector &origRanges) > ? ? ranges = &all; > ? } > > - ?memset(&chunkNeeded, 0, numChunks); > + ?memset(&chunkNeeded[0], 0, sizeof(bool) * numChunks); > ? for (size_t i = 0; i < ranges->size(); i++) { > > ? ? if ((*ranges)[i].length == 0) continue; > @@ -100,7 +100,7 @@ int CachedFile::cache(const GooVector &origRanges) > ? ? endChunk = end / CachedFileChunkSize; > ? ? for (int chunk = startChunk; chunk <= endChunk; chunk++) { > ? ? ? if ((*chunks)[chunk].state == chunkStateNew) { > - ? ? ? ? ? chunkNeeded[chunk] = 1; > + ? ? ? ? ? chunkNeeded[chunk] = true; > ? ? ? } > ? ? } > ? } > _______________________________________________ > poppler mailing list > poppler at lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/poppler > From aacid at kde.org Wed Apr 7 11:04:45 2010 From: aacid at kde.org (Albert Astals Cid) Date: Wed, 7 Apr 2010 19:04:45 +0100 Subject: [poppler] poppler/CachedFile.cc In-Reply-To: References: <20100406221355.A81E9C0001@kemper.freedesktop.org> Message-ID: <201004071904.45995.aacid@kde.org> A Dimecres, 7 d'abril de 2010, Hib Eris va escriure: > Hi Pino, > > Thank you for improving my code. Just a question: I see you are using > 'bool'. Often I see the use of 'gBool' in poppler's code. What is > preferred in poppler? Usually GBool is preferred for the sake of consistency. Albert > > Hib > > > On Wed, Apr 7, 2010 at 12:13 AM, Pino Toscano > > wrote: > > poppler/CachedFile.cc | 6 +++--- > > 1 file changed, 3 insertions(+), 3 deletions(-) > > > > New commits: > > commit 3f302fdd78cd78873bf5376af84e83741a8daadb > > Author: Pino Toscano > > Date: Tue Apr 6 23:58:46 2010 +0200 > > > > use a GooVector instead of a non-standard variable-length-array > > > > diff --git a/poppler/CachedFile.cc b/poppler/CachedFile.cc > > index 46627c3..95cc58b 100644 > > --- a/poppler/CachedFile.cc > > +++ b/poppler/CachedFile.cc > > @@ -73,7 +73,7 @@ int CachedFile::cache(const GooVector > > &origRanges) { > > GooVector loadChunks; > > int numChunks = length/CachedFileChunkSize + 1; > > - char chunkNeeded[numChunks]; > > + GooVector chunkNeeded(numChunks); > > int startChunk, endChunk; > > GooVector chunk_ranges, all; > > ByteRange range; > > @@ -86,7 +86,7 @@ int CachedFile::cache(const GooVector > > &origRanges) ranges = &all; > > } > > > > - memset(&chunkNeeded, 0, numChunks); > > + memset(&chunkNeeded[0], 0, sizeof(bool) * numChunks); > > for (size_t i = 0; i < ranges->size(); i++) { > > > > if ((*ranges)[i].length == 0) continue; > > @@ -100,7 +100,7 @@ int CachedFile::cache(const GooVector > > &origRanges) endChunk = end / CachedFileChunkSize; > > for (int chunk = startChunk; chunk <= endChunk; chunk++) { > > if ((*chunks)[chunk].state == chunkStateNew) { > > - chunkNeeded[chunk] = 1; > > + chunkNeeded[chunk] = true; > > } > > } > > } > > _______________________________________________ > > poppler mailing list > > poppler at lists.freedesktop.org > > http://lists.freedesktop.org/mailman/listinfo/poppler > > _______________________________________________ > poppler mailing list > poppler at lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/poppler From carlosgc at kemper.freedesktop.org Wed Apr 7 12:11:00 2010 From: carlosgc at kemper.freedesktop.org (Carlos Garcia Campos) Date: Wed, 7 Apr 2010 12:11:00 -0700 (PDT) Subject: [poppler] poppler/PDFDoc.cc Message-ID: <20100407191100.93F4FC0001@kemper.freedesktop.org> poppler/PDFDoc.cc | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) New commits: commit f5dd5be64d09186ee289632c1a61979d15edd605 Author: Carlos Garcia Campos Date: Wed Apr 7 19:48:39 2010 +0200 Fix saving update docs that have a compressed xref table - Use the original xref table size as Size field in the trailer dictionary to make sure size = maxObjId + 1 - Use the right generation number for compressed objects that which must be 0. gen field in xref entry for compressed objects is the index of the object in the stream, not the generation number. Fixes bug #27450. diff --git a/poppler/PDFDoc.cc b/poppler/PDFDoc.cc index 78b6593..9505639 100644 --- a/poppler/PDFDoc.cc +++ b/poppler/PDFDoc.cc @@ -17,7 +17,7 @@ // Copyright (C) 2005, 2007-2009 Albert Astals Cid // Copyright (C) 2008 Julien Rebetez // Copyright (C) 2008 Pino Toscano -// Copyright (C) 2008 Carlos Garcia Campos +// Copyright (C) 2008, 2010 Carlos Garcia Campos // Copyright (C) 2009 Eric Toombs // Copyright (C) 2009 Kovid Goyal // Copyright (C) 2009 Axel Struebing @@ -544,17 +544,16 @@ void PDFDoc::saveIncrementalUpdate (OutStream* outStr) uxref = new XRef(); uxref->add(0, 65535, 0, gFalse); - int objectsCount = 0; //count the number of objects in the XRef(s) for(int i=0; igetNumObjects(); i++) { if ((xref->getEntry(i)->type == xrefEntryFree) && (xref->getEntry(i)->gen == 0)) //we skip the irrelevant free objects continue; - objectsCount++; + if (xref->getEntry(i)->updated) { //we have an updated object Object obj1; Ref ref; ref.num = i; - ref.gen = xref->getEntry(i)->gen; + ref.gen = xref->getEntry(i)->type == xrefEntryCompressed ? 0 : xref->getEntry(i)->gen; xref->fetch(ref.num, ref.gen, &obj1); Guint offset = writeObject(&obj1, &ref, outStr); uxref->add(ref.num, ref.gen, offset, gTrue); @@ -569,7 +568,7 @@ void PDFDoc::saveIncrementalUpdate (OutStream* outStr) Guint uxrefOffset = outStr->getPos(); uxref->writeToFile(outStr, gFalse /* do not write unnecessary entries */); - writeTrailer(uxrefOffset, objectsCount, outStr, gTrue); + writeTrailer(uxrefOffset, xref->getSize(), outStr, gTrue); delete uxref; } From aacid at kemper.freedesktop.org Wed Apr 7 12:25:44 2010 From: aacid at kemper.freedesktop.org (Albert Astals Cid) Date: Wed, 7 Apr 2010 12:25:44 -0700 (PDT) Subject: [poppler] 10 commits - poppler/Catalog.cc poppler/Catalog.h poppler/PDFDoc.cc poppler/PDFDoc.h Message-ID: <20100407192544.C30C9C0001@kemper.freedesktop.org> poppler/Catalog.cc | 384 +++++++++++++++++++++++++++++++++++++++-------------- poppler/Catalog.h | 43 +++-- poppler/PDFDoc.cc | 17 +- poppler/PDFDoc.h | 2 4 files changed, 327 insertions(+), 119 deletions(-) New commits: commit d46581c574b3088a82555cbc3b76e95e2571b9c0 Author: Albert Astals Cid Date: Wed Apr 7 20:25:23 2010 +0100 Fix destructor diff --git a/poppler/Catalog.cc b/poppler/Catalog.cc index a0d33cf..74af00e 100644 --- a/poppler/Catalog.cc +++ b/poppler/Catalog.cc @@ -14,7 +14,7 @@ // under GPL version 2 or later // // Copyright (C) 2005 Kristian H??gsberg -// Copyright (C) 2005-2009 Albert Astals Cid +// Copyright (C) 2005-2010 Albert Astals Cid // Copyright (C) 2005 Jeff Muizelaar // Copyright (C) 2005 Jonathan Blandford // Copyright (C) 2005 Marco Pesenti Gritti @@ -500,7 +500,12 @@ NameTree::NameTree() NameTree::~NameTree() { - this->free(); + int i; + + for (i = 0; i < length; i++) + delete entries[i]; + + gfree(entries); } NameTree::Entry::Entry(Array *array, int index) { @@ -612,16 +617,6 @@ GooString *NameTree::getName(int index) } } -void NameTree::free() -{ - int i; - - for (i = 0; i < length; i++) - delete entries[i]; - - gfree(entries); -} - GBool Catalog::labelToIndex(GooString *label, int *index) { char *end; diff --git a/poppler/Catalog.h b/poppler/Catalog.h index fd1c32e..2cab80a 100644 --- a/poppler/Catalog.h +++ b/poppler/Catalog.h @@ -14,7 +14,7 @@ // under GPL version 2 or later // // Copyright (C) 2005 Kristian H??gsberg -// Copyright (C) 2005, 2007, 2009 Albert Astals Cid +// Copyright (C) 2005, 2007, 2009, 2010 Albert Astals Cid // Copyright (C) 2005 Jonathan Blandford // Copyright (C) 2005, 2006, 2008 Brad Hards // Copyright (C) 2007 Julien Rebetez @@ -54,7 +54,6 @@ public: void init(XRef *xref, Object *tree); void parse(Object *tree); GBool lookup(GooString *name, Object *obj); - void free(); int numEntries() { return length; }; // iterator accessor Object getValue(int i); commit ab14433f8b3d7c67f279cece65dfdd40c6675ac0 Author: Hib Eris Date: Thu Mar 25 15:33:33 2010 +0100 Parse Form on demand diff --git a/poppler/Catalog.cc b/poppler/Catalog.cc index 4135d79..a0d33cf 100644 --- a/poppler/Catalog.cc +++ b/poppler/Catalog.cc @@ -86,12 +86,6 @@ Catalog::Catalog(XRef *xrefA) { // get the AcroForm dictionary catDict.dictLookup("AcroForm", &acroForm); - // load Forms - if (acroForm.isDict()) { - form = new Form(xref,&acroForm); - } - - // read page tree catDict.dictLookup("Pages", &pagesDict); // This should really be isDict("Pages"), but I've seen at least one @@ -153,8 +147,8 @@ Catalog::Catalog(XRef *xrefA) { optContentProps.free(); // perform form-related loading after all widgets have been loaded - if (form) - form->postWidgetsLoad(); + if (getForm()) + getForm()->postWidgetsLoad(); catDict.free(); return; @@ -848,6 +842,17 @@ Object *Catalog::getDests() return &dests; } +Form *Catalog::getForm() +{ + if (!form) { + if (acroForm.isDict()) { + form = new Form(xref,&acroForm); + } + } + + return form; +} + Object *Catalog::getNames() { if (names.isNone()) diff --git a/poppler/Catalog.h b/poppler/Catalog.h index 6021eed..fd1c32e 100644 --- a/poppler/Catalog.h +++ b/poppler/Catalog.h @@ -199,7 +199,7 @@ public: OCGs *getOptContentConfig() { return optContent; } - Form* getForm() { return form; } + Form* getForm(); enum PageMode { pageModeNone, commit c72a2c7f70b13a7b7b531b3c983d9a9bc104bac7 Author: Hib Eris Date: Thu Mar 25 17:33:11 2010 +0100 Parse Names on demand diff --git a/poppler/Catalog.cc b/poppler/Catalog.cc index 07b1e20..4135d79 100644 --- a/poppler/Catalog.cc +++ b/poppler/Catalog.cc @@ -74,6 +74,9 @@ Catalog::Catalog(XRef *xrefA) { optContent = NULL; pageMode = pageModeNull; pageLayout = pageLayoutNull; + destNameTree = NULL; + embeddedFileNameTree = NULL; + jsNameTree = NULL; xref->getCatalog(&catDict); if (!catDict.isDict()) { @@ -130,20 +133,6 @@ Catalog::Catalog(XRef *xrefA) { } pagesDict.free(); - // read root of named destination tree - PDF1.6 table 3.28 - if (catDict.dictLookup("Names", &obj)->isDict()) { - obj.dictLookup("Dests", &obj2); - destNameTree.init(xref, &obj2); - obj2.free(); - obj.dictLookup("EmbeddedFiles", &obj2); - embeddedFileNameTree.init(xref, &obj2); - obj2.free(); - obj.dictLookup("JavaScript", &obj2); - jsNameTree.init(xref, &obj2); - obj2.free(); - } - obj.free(); - // read base URI if (catDict.dictLookup("URI", &obj)->isDict()) { if (obj.dictLookup("Base", &obj2)->isString()) { @@ -190,9 +179,9 @@ Catalog::~Catalog() { gfree(pageRefs); } dests.free(); - destNameTree.free(); - embeddedFileNameTree.free(); - jsNameTree.free(); + delete destNameTree; + delete embeddedFileNameTree; + delete jsNameTree; if (baseURI) { delete baseURI; } @@ -346,7 +335,7 @@ LinkDest *Catalog::findDest(GooString *name) { obj1.free(); } if (!found) { - if (destNameTree.lookup(name, &obj1)) + if (getDestNameTree()->lookup(name, &obj1)) found = gTrue; else obj1.free(); @@ -380,10 +369,10 @@ EmbFile *Catalog::embeddedFile(int i) { Object efDict; Object obj; - obj = embeddedFileNameTree.getValue(i); + obj = getEmbeddedFileNameTree()->getValue(i); EmbFile *embeddedFile = 0; if (obj.isRef()) { - GooString desc(embeddedFileNameTree.getName(i)); + GooString desc(getEmbeddedFileNameTree()->getName(i)); embeddedFile = new EmbFile(obj.fetch(xref, &efDict), &desc); efDict.free(); } else { @@ -395,7 +384,7 @@ EmbFile *Catalog::embeddedFile(int i) GooString *Catalog::getJS(int i) { - Object obj = jsNameTree.getValue(i); + Object obj = getJSNameTree()->getValue(i); if (obj.isRef()) { Ref r = obj.getRef(); obj.free(); @@ -515,6 +504,11 @@ NameTree::NameTree() entries = NULL; } +NameTree::~NameTree() +{ + this->free(); +} + NameTree::Entry::Entry(Array *array, int index) { if (!array->getString(index, &name) || !array->getNF(index + 1, &value)) { Object aux; @@ -854,3 +848,79 @@ Object *Catalog::getDests() return &dests; } +Object *Catalog::getNames() +{ + if (names.isNone()) + { + Object catDict; + + xref->getCatalog(&catDict); + if (catDict.isDict()) { + catDict.dictLookup("Names", &names); + } else { + error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName()); + names.initNull(); + } + catDict.free(); + } + + return &names; +} + +NameTree *Catalog::getDestNameTree() +{ + if (!destNameTree) { + + destNameTree = new NameTree(); + + if (getNames()->isDict()) { + Object obj; + + getNames()->dictLookup("Dests", &obj); + destNameTree->init(xref, &obj); + obj.free(); + } + + } + + return destNameTree; +} + +NameTree *Catalog::getEmbeddedFileNameTree() +{ + if (!embeddedFileNameTree) { + + embeddedFileNameTree = new NameTree(); + + if (getNames()->isDict()) { + Object obj; + + getNames()->dictLookup("EmbeddedFiles", &obj); + embeddedFileNameTree->init(xref, &obj); + obj.free(); + } + + } + + return embeddedFileNameTree; +} + +NameTree *Catalog::getJSNameTree() +{ + if (!jsNameTree) { + + jsNameTree = new NameTree(); + + if (getNames()->isDict()) { + Object obj; + + getNames()->dictLookup("JavaScript", &obj); + jsNameTree->init(xref, &obj); + obj.free(); + } + + } + + return jsNameTree; +} + diff --git a/poppler/Catalog.h b/poppler/Catalog.h index 134f1db..6021eed 100644 --- a/poppler/Catalog.h +++ b/poppler/Catalog.h @@ -50,6 +50,7 @@ class OCGs; class NameTree { public: NameTree(); + ~NameTree(); void init(XRef *xref, Object *tree); void parse(Object *tree); GBool lookup(GooString *name, Object *obj); @@ -177,13 +178,13 @@ public: Object *getDests(); // Get the number of embedded files - int numEmbeddedFiles() { return embeddedFileNameTree.numEntries(); } + int numEmbeddedFiles() { return getEmbeddedFileNameTree()->numEntries(); } // Get the i'th file embedded (at the Document level) in the document EmbFile *embeddedFile(int i); // Get the number of javascript scripts - int numJS() { return jsNameTree.numEntries(); } + int numJS() { return getJSNameTree()->numEntries(); } // Get the i'th JavaScript script (at the Document level) in the document GooString *getJS(int i); @@ -236,9 +237,10 @@ private: int numPages; // number of pages int pagesSize; // size of pages array Object dests; // named destination dictionary - NameTree destNameTree; // named destination name-tree - NameTree embeddedFileNameTree; // embedded file name-tree - NameTree jsNameTree; // Java Script name-tree + Object names; // named names dictionary + NameTree *destNameTree; // named destination name-tree + NameTree *embeddedFileNameTree; // embedded file name-tree + NameTree *jsNameTree; // Java Script name-tree GooString *baseURI; // base URI for URI-type links Object metadata; // metadata stream Object structTreeRoot; // structure tree root dictionary @@ -253,6 +255,12 @@ private: int readPageTree(Dict *pages, PageAttrs *attrs, int start, char *alreadyRead); Object *findDestInTree(Object *tree, GooString *name, Object *obj); + + Object *getNames(); + NameTree *getDestNameTree(); + NameTree *getEmbeddedFileNameTree(); + NameTree *getJSNameTree(); + }; #endif commit 32053360c93607cf9bdc092257cefad5d4df9ec5 Author: Hib Eris Date: Thu Mar 25 16:32:22 2010 +0100 Parse Dests on demand diff --git a/poppler/Catalog.cc b/poppler/Catalog.cc index f6a8bef..07b1e20 100644 --- a/poppler/Catalog.cc +++ b/poppler/Catalog.cc @@ -130,9 +130,6 @@ Catalog::Catalog(XRef *xrefA) { } pagesDict.free(); - // read named destination dictionary - catDict.dictLookup("Dests", &dests); - // read root of named destination tree - PDF1.6 table 3.28 if (catDict.dictLookup("Names", &obj)->isDict()) { obj.dictLookup("Dests", &obj2); @@ -177,7 +174,6 @@ Catalog::Catalog(XRef *xrefA) { pagesDict.free(); err1: catDict.free(); - dests.initNull(); ok = gFalse; } @@ -343,8 +339,8 @@ LinkDest *Catalog::findDest(GooString *name) { // try named destination dictionary then name tree found = gFalse; - if (dests.isDict()) { - if (!dests.dictLookup(name->getCString(), &obj1)->isNull()) + if (getDests()->isDict()) { + if (!getDests()->dictLookup(name->getCString(), &obj1)->isNull()) found = gTrue; else obj1.free(); @@ -839,3 +835,22 @@ Object *Catalog::getOutline() return &outline; } +Object *Catalog::getDests() +{ + if (dests.isNone()) + { + Object catDict; + + xref->getCatalog(&catDict); + if (catDict.isDict()) { + catDict.dictLookup("Dests", &dests); + } else { + error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName()); + dests.initNull(); + } + catDict.free(); + } + + return &dests; +} + diff --git a/poppler/Catalog.h b/poppler/Catalog.h index cfae726..134f1db 100644 --- a/poppler/Catalog.h +++ b/poppler/Catalog.h @@ -174,7 +174,7 @@ public: // NULL if is not a destination. LinkDest *findDest(GooString *name); - Object *getDests() { return &dests; } + Object *getDests(); // Get the number of embedded files int numEmbeddedFiles() { return embeddedFileNameTree.numEntries(); } commit da0f8e69eecb944e128474f62829f729eeabd189 Author: Hib Eris Date: Thu Mar 25 16:48:07 2010 +0100 Parse Outline on demand in PDFDoc diff --git a/poppler/PDFDoc.cc b/poppler/PDFDoc.cc index 9505639..2d1477d 100644 --- a/poppler/PDFDoc.cc +++ b/poppler/PDFDoc.cc @@ -226,11 +226,6 @@ GBool PDFDoc::setup(GooString *ownerPassword, GooString *userPassword) { return gFalse; } -#ifndef DISABLE_OUTLINE - // read outline - outline = new Outline(catalog->getOutline(), xref); -#endif - // done return gTrue; } @@ -907,6 +902,18 @@ void PDFDoc::writeTrailer (Guint uxrefOffset, int uxrefSize, OutStream* outStr, delete trailerDict; } +#ifndef DISABLE_OUTLINE +Outline *PDFDoc::getOutline() +{ + if (!outline) { + // read outline + outline = new Outline(catalog->getOutline(), xref); + } + + return outline; +} +#endif + PDFDoc *PDFDoc::ErrorPDFDoc(int errorCode, GooString *fileNameA) { PDFDoc *doc = new PDFDoc(); diff --git a/poppler/PDFDoc.h b/poppler/PDFDoc.h index 79f6d6d..6d7dea2 100644 --- a/poppler/PDFDoc.h +++ b/poppler/PDFDoc.h @@ -170,7 +170,7 @@ public: #ifndef DISABLE_OUTLINE // Return the outline object. - Outline *getOutline() { return outline; } + Outline *getOutline(); #endif // Is the file encrypted? commit d7a69c8cad112cb6616d0192d8a4028fdaee2f73 Author: Hib Eris Date: Thu Mar 25 16:05:02 2010 +0100 Parse Outline on demand diff --git a/poppler/Catalog.cc b/poppler/Catalog.cc index bcae737..f6a8bef 100644 --- a/poppler/Catalog.cc +++ b/poppler/Catalog.cc @@ -156,9 +156,6 @@ Catalog::Catalog(XRef *xrefA) { } obj.free(); - // get the outline dictionary - catDict.dictLookup("Outlines", &outline); - // get the Optional Content dictionary if (catDict.dictLookup("OCProperties", &optContentProps)->isDict()) { optContent = new OCGs(&optContentProps, xref); @@ -822,3 +819,23 @@ Object *Catalog::getStructTreeRoot() return &structTreeRoot; } + +Object *Catalog::getOutline() +{ + if (outline.isNone()) + { + Object catDict; + + xref->getCatalog(&catDict); + if (catDict.isDict()) { + catDict.dictLookup("Outlines", &outline); + } else { + error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName()); + outline.initNull(); + } + catDict.free(); + } + + return &outline; +} + diff --git a/poppler/Catalog.h b/poppler/Catalog.h index a55d449..cfae726 100644 --- a/poppler/Catalog.h +++ b/poppler/Catalog.h @@ -192,7 +192,7 @@ public: GBool labelToIndex(GooString *label, int *index); GBool indexToLabel(int index, GooString *label); - Object *getOutline() { return &outline; } + Object *getOutline(); Object *getAcroForm() { return &acroForm; } commit c149e027fa76824221a78fe6d3bf9bfe953491d4 Author: Hib Eris Date: Thu Mar 25 15:51:51 2010 +0100 Parse StructTreeRoot on demand diff --git a/poppler/Catalog.cc b/poppler/Catalog.cc index d27b6f1..bcae737 100644 --- a/poppler/Catalog.cc +++ b/poppler/Catalog.cc @@ -156,9 +156,6 @@ Catalog::Catalog(XRef *xrefA) { } obj.free(); - // get the structure tree root - catDict.dictLookup("StructTreeRoot", &structTreeRoot); - // get the outline dictionary catDict.dictLookup("Outlines", &outline); @@ -806,3 +803,22 @@ PageLabelInfo *Catalog::getPageLabelInfo() return pageLabelInfo; } + +Object *Catalog::getStructTreeRoot() +{ + if (structTreeRoot.isNone()) + { + Object catDict; + + xref->getCatalog(&catDict); + if (catDict.isDict()) { + catDict.dictLookup("StructTreeRoot", &structTreeRoot); + } else { + error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName()); + structTreeRoot.initNull(); + } + catDict.free(); + } + + return &structTreeRoot; +} diff --git a/poppler/Catalog.h b/poppler/Catalog.h index 2f7c616..a55d449 100644 --- a/poppler/Catalog.h +++ b/poppler/Catalog.h @@ -164,7 +164,7 @@ public: GooString *readMetadata(); // Return the structure tree root object. - Object *getStructTreeRoot() { return &structTreeRoot; } + Object *getStructTreeRoot(); // Find a page, given its object ID. Returns page number, or 0 if // not found. commit 3c6effe44d6d97f175c2ee7f3913d8c4ba34d612 Author: Hib Eris Date: Thu Mar 25 14:55:22 2010 +0100 Parse Metadata on demand diff --git a/poppler/Catalog.cc b/poppler/Catalog.cc index aa21b45..d27b6f1 100644 --- a/poppler/Catalog.cc +++ b/poppler/Catalog.cc @@ -156,9 +156,6 @@ Catalog::Catalog(XRef *xrefA) { } obj.free(); - // get the metadata stream - catDict.dictLookup("Metadata", &metadata); - // get the structure tree root catDict.dictLookup("StructTreeRoot", &structTreeRoot); @@ -224,6 +221,19 @@ GooString *Catalog::readMetadata() { Object obj; int c; + if (metadata.isNone()) { + Object catDict; + + xref->getCatalog(&catDict); + if (catDict.isDict()) { + catDict.dictLookup("Metadata", &metadata); + } else { + error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName()); + metadata.initNull(); + } + catDict.free(); + } + if (!metadata.isStream()) { return NULL; } commit 749d67ea2346a3453ef41dc37ba59d419ad900b0 Author: Hib Eris Date: Thu Mar 25 15:09:58 2010 +0100 Parse PageLabelInfo on demand diff --git a/poppler/Catalog.cc b/poppler/Catalog.cc index 94ccff2..aa21b45 100644 --- a/poppler/Catalog.cc +++ b/poppler/Catalog.cc @@ -147,10 +147,6 @@ Catalog::Catalog(XRef *xrefA) { } obj.free(); - if (catDict.dictLookup("PageLabels", &obj)->isDict()) - pageLabelInfo = new PageLabelInfo(&obj, numPages); - obj.free(); - // read base URI if (catDict.dictLookup("URI", &obj)->isDict()) { if (obj.dictLookup("Base", &obj2)->isString()) { @@ -642,8 +638,9 @@ GBool Catalog::labelToIndex(GooString *label, int *index) { char *end; - if (pageLabelInfo != NULL) { - if (!pageLabelInfo->labelToIndex(label, index)) + PageLabelInfo *pli = getPageLabelInfo(); + if (pli != NULL) { + if (!pli->labelToIndex(label, index)) return gFalse; } else { *index = strtol(label->getCString(), &end, 10) - 1; @@ -664,8 +661,9 @@ GBool Catalog::indexToLabel(int index, GooString *label) if (index < 0 || index >= numPages) return gFalse; - if (pageLabelInfo != NULL) { - return pageLabelInfo->indexToLabel(index, label); + PageLabelInfo *pli = getPageLabelInfo(); + if (pli != NULL) { + return pli->indexToLabel(index, label); } else { snprintf(buffer, sizeof (buffer), "%d", index + 1); label->append(buffer); @@ -775,3 +773,26 @@ EmbFile::EmbFile(Object *efDict, GooString *description) if (!m_mimetype) m_mimetype = new GooString(); } + +PageLabelInfo *Catalog::getPageLabelInfo() +{ + if (!pageLabelInfo) { + Object catDict; + Object obj; + + xref->getCatalog(&catDict); + if (!catDict.isDict()) { + error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName()); + catDict.free(); + return NULL; + } + + if (catDict.dictLookup("PageLabels", &obj)->isDict()) { + pageLabelInfo = new PageLabelInfo(&obj, getNumPages()); + } + obj.free(); + catDict.free(); + } + + return pageLabelInfo; +} diff --git a/poppler/Catalog.h b/poppler/Catalog.h index 5e84679..2f7c616 100644 --- a/poppler/Catalog.h +++ b/poppler/Catalog.h @@ -226,6 +226,9 @@ public: private: + // Get page label info. + PageLabelInfo *getPageLabelInfo(); + XRef *xref; // the xref table for this PDF file Page **pages; // array of pages Ref *pageRefs; // object ID for each page commit 78f7d106714fa489a66c39410163a6902ba24856 Author: Hib Eris Date: Sat Mar 27 14:43:57 2010 +0100 Parse PageMode and PageLayout on demand diff --git a/poppler/Catalog.cc b/poppler/Catalog.cc index b659180..94ccff2 100644 --- a/poppler/Catalog.cc +++ b/poppler/Catalog.cc @@ -23,6 +23,7 @@ // Copyright (C) 2007 Julien Rebetez // Copyright (C) 2008 Pino Toscano // Copyright (C) 2009 Ilya Gorenbein +// Copyright (C) 2010 Hib Eris // // 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 @@ -71,6 +72,8 @@ Catalog::Catalog(XRef *xrefA) { pageLabelInfo = NULL; form = NULL; optContent = NULL; + pageMode = pageModeNull; + pageLayout = pageLayoutNull; xref->getCatalog(&catDict); if (!catDict.isDict()) { @@ -148,41 +151,6 @@ Catalog::Catalog(XRef *xrefA) { pageLabelInfo = new PageLabelInfo(&obj, numPages); obj.free(); - // read page mode - pageMode = pageModeNone; - if (catDict.dictLookup("PageMode", &obj)->isName()) { - if (obj.isName("UseNone")) - pageMode = pageModeNone; - else if (obj.isName("UseOutlines")) - pageMode = pageModeOutlines; - else if (obj.isName("UseThumbs")) - pageMode = pageModeThumbs; - else if (obj.isName("FullScreen")) - pageMode = pageModeFullScreen; - else if (obj.isName("UseOC")) - pageMode = pageModeOC; - else if (obj.isName("UseAttachments")) - pageMode = pageModeAttach; - } - obj.free(); - - pageLayout = pageLayoutNone; - if (catDict.dictLookup("PageLayout", &obj)->isName()) { - if (obj.isName("SinglePage")) - pageLayout = pageLayoutSinglePage; - if (obj.isName("OneColumn")) - pageLayout = pageLayoutOneColumn; - if (obj.isName("TwoColumnLeft")) - pageLayout = pageLayoutTwoColumnLeft; - if (obj.isName("TwoColumnRight")) - pageLayout = pageLayoutTwoColumnRight; - if (obj.isName("TwoPageLeft")) - pageLayout = pageLayoutTwoPageLeft; - if (obj.isName("TwoPageRight")) - pageLayout = pageLayoutTwoPageRight; - } - obj.free(); - // read base URI if (catDict.dictLookup("URI", &obj)->isDict()) { if (obj.dictLookup("Base", &obj2)->isString()) { @@ -473,6 +441,77 @@ GooString *Catalog::getJS(int i) return js; } +Catalog::PageMode Catalog::getPageMode() { + + if (pageMode == pageModeNull) { + + Object catDict, obj; + + pageMode = pageModeNone; + + xref->getCatalog(&catDict); + if (!catDict.isDict()) { + error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName()); + catDict.free(); + return pageMode; + } + + if (catDict.dictLookup("PageMode", &obj)->isName()) { + if (obj.isName("UseNone")) + pageMode = pageModeNone; + else if (obj.isName("UseOutlines")) + pageMode = pageModeOutlines; + else if (obj.isName("UseThumbs")) + pageMode = pageModeThumbs; + else if (obj.isName("FullScreen")) + pageMode = pageModeFullScreen; + else if (obj.isName("UseOC")) + pageMode = pageModeOC; + else if (obj.isName("UseAttachments")) + pageMode = pageModeAttach; + } + obj.free(); + catDict.free(); + } + return pageMode; +} + +Catalog::PageLayout Catalog::getPageLayout() { + + if (pageLayout == pageLayoutNull) { + + Object catDict, obj; + + pageLayout = pageLayoutNone; + + xref->getCatalog(&catDict); + if (!catDict.isDict()) { + error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName()); + catDict.free(); + return pageLayout; + } + + pageLayout = pageLayoutNone; + if (catDict.dictLookup("PageLayout", &obj)->isName()) { + if (obj.isName("SinglePage")) + pageLayout = pageLayoutSinglePage; + if (obj.isName("OneColumn")) + pageLayout = pageLayoutOneColumn; + if (obj.isName("TwoColumnLeft")) + pageLayout = pageLayoutTwoColumnLeft; + if (obj.isName("TwoColumnRight")) + pageLayout = pageLayoutTwoColumnRight; + if (obj.isName("TwoPageLeft")) + pageLayout = pageLayoutTwoPageLeft; + if (obj.isName("TwoPageRight")) + pageLayout = pageLayoutTwoPageRight; + } + obj.free(); + catDict.free(); + } + return pageLayout; +} + NameTree::NameTree() { size = 0; diff --git a/poppler/Catalog.h b/poppler/Catalog.h index f5b389f..5e84679 100644 --- a/poppler/Catalog.h +++ b/poppler/Catalog.h @@ -19,6 +19,7 @@ // Copyright (C) 2005, 2006, 2008 Brad Hards // Copyright (C) 2007 Julien Rebetez // Copyright (C) 2008 Pino Toscano +// Copyright (C) 2010 Hib Eris // // 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 @@ -205,7 +206,8 @@ public: pageModeThumbs, pageModeFullScreen, pageModeOC, - pageModeAttach + pageModeAttach, + pageModeNull }; enum PageLayout { pageLayoutNone, @@ -214,12 +216,13 @@ public: pageLayoutTwoColumnLeft, pageLayoutTwoColumnRight, pageLayoutTwoPageLeft, - pageLayoutTwoPageRight + pageLayoutTwoPageRight, + pageLayoutNull }; // Returns the page mode. - PageMode getPageMode() { return pageMode; } - PageLayout getPageLayout() { return pageLayout; } + PageMode getPageMode(); + PageLayout getPageLayout(); private: From aacid at kde.org Wed Apr 7 12:26:13 2010 From: aacid at kde.org (Albert Astals Cid) Date: Wed, 7 Apr 2010 20:26:13 +0100 Subject: [poppler] Towards support for linearized PDFs In-Reply-To: References: Message-ID: <201004072026.14261.aacid@kde.org> A Dimarts, 6 d'abril de 2010, Hib Eris va escriure: > Hi all, > > I have updated the patches taking Albert's comments into account. > > On Mon, Apr 5, 2010 at 11:50 PM, Albert Astals Cid wrote: > > Some comments: > > * You don't initialize pageMode nor pageLayout to their null enum > > values. * I'd like the new enum values to be added to the end to be more > > saf in case anyone was using the int values to save them somewhere > > * You should be freeing catDict > > > >> The last patch in this series is almost certainly incorrect, but I > >> would like some input on it. It is dealing with form widgets. > >> Question: can this postWidgetsLoad() be done on a per page basis, or > >> is it something global to the whole document? > > > > Probably it could be done per page, if you give a patch i can test all > > docs in my regression suite to see if we get the same behaviour with > > your patches or not. > > Okay, for now I have left this last patch out of the new patch set. I > will study the details of annotations and formfields some more to come > up with a better patch. > > > Also, can you please enlight us what does this give us towards getting > > linearized support? > > The goal of linearized support is to be able to render any page in a > document without downloading any unrelated/unnecessary objects. To > prevent downloading unnecessary objects, the Catalog should only > initialize what is absolutely needed and defer initializing anything > else to a when it is needed. > > Linearized support while still initializing objects from all over the > document is just not very useful, so I thought it would be wise to > first do these things. Pushed. Albert > > Hib From pino at kde.org Wed Apr 7 12:37:19 2010 From: pino at kde.org (Pino Toscano) Date: Wed, 7 Apr 2010 21:37:19 +0200 Subject: [poppler] poppler/CachedFile.cc In-Reply-To: References: <20100406221355.A81E9C0001@kemper.freedesktop.org> Message-ID: <201004072137.46360.pino@kde.org> Alle mercoled? 7 aprile 2010, Hib Eris ha scritto: > Thank you for improving my code. Just a question: I see you are using > 'bool'. Often I see the use of 'gBool' in poppler's code. What is > preferred in poppler? The preferred should be GBool; in that vector, I chose bool instead of GBool as sizeof(bool) == 1, while sizeof(GBool) == 4 (as it's a typedef of int), so using GBool for a simple "visited" list is a kind of memory waste, IMHO. (Note that using std::vector would be even more efficient, as it would use a bitarray-like list for the items, so at most (N/8)+1 bytes for N items.) PS: no need to CC me directly, I'm subscribed to the ml. -- Pino Toscano -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 190 bytes Desc: This is a digitally signed message part. URL: From carlosgc at kemper.freedesktop.org Thu Apr 8 03:06:52 2010 From: carlosgc at kemper.freedesktop.org (Carlos Garcia Campos) Date: Thu, 8 Apr 2010 03:06:52 -0700 (PDT) Subject: [poppler] poppler/Catalog.cc Message-ID: <20100408100652.A7BF6C0001@kemper.freedesktop.org> poppler/Catalog.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) New commits: commit bcb405c43fb7140f5d601d00de4d30913a0050ef Author: Carlos Garcia Campos Date: Thu Apr 8 12:02:48 2010 +0200 Pages were always created without forms by Catalog Use getForm() instead of form when creating a page object. diff --git a/poppler/Catalog.cc b/poppler/Catalog.cc index 74af00e..900cdd7 100644 --- a/poppler/Catalog.cc +++ b/poppler/Catalog.cc @@ -256,7 +256,7 @@ int Catalog::readPageTree(Dict *pagesDict, PageAttrs *attrs, int start, kids.arrayGet(i, &kid); if (kid.isDict("Page")) { attrs2 = new PageAttrs(attrs1, kid.getDict()); - page = new Page(xref, start+1, kid.getDict(), kidRef.getRef(), attrs2, form); + page = new Page(xref, start+1, kid.getDict(), kidRef.getRef(), attrs2, getForm()); if (!page->isOk()) { ++start; goto err3; From mathieu.malaterre at gmail.com Thu Apr 8 03:35:15 2010 From: mathieu.malaterre at gmail.com (Mathieu Malaterre) Date: Thu, 8 Apr 2010 12:35:15 +0200 Subject: [poppler] Reading Meta Information from PDF Message-ID: Hi, This is slightly of topic to poppler. I am looking for a way to read the Meta Information of a PDF file (basically the output of pdfinfo). I find it a little bit cumbersome to integrate poppler (license issue, no real need for a full rendering PDF library). Could someone suggest another solution for reading those Meta Information from PDF files ? Will a simple regex (such as: ")") works ? thanks ! -- Mathieu From ceztkoml at gmail.com Thu Apr 8 09:38:12 2010 From: ceztkoml at gmail.com (Francesco Pretto) Date: Thu, 8 Apr 2010 18:38:12 +0200 Subject: [poppler] poppler/CachedFile.cc In-Reply-To: <201004072137.46360.pino@kde.org> References: <20100406221355.A81E9C0001@kemper.freedesktop.org> <201004072137.46360.pino@kde.org> Message-ID: 2010/4/7 Pino Toscano : > > PS: no need to CC me directly, I'm subscribed to the ml. > Isn't that the default "reply_goes_to_list=Poster" mailman configuration? See [1] for references. [1] http://www.gnu.org/software/mailman/mailman-admin/node11.html From carlosgc at kemper.freedesktop.org Fri Apr 9 03:05:40 2010 From: carlosgc at kemper.freedesktop.org (Carlos Garcia Campos) Date: Fri, 9 Apr 2010 03:05:40 -0700 (PDT) Subject: [poppler] poppler/CairoOutputDev.cc Message-ID: <20100409100540.D435AF81F7@kemper.freedesktop.org> poppler/CairoOutputDev.cc | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) New commits: commit bd8f44289770175a17ac45e4788b0d374cc93d5a Author: Carlos Garcia Campos Date: Fri Apr 9 12:02:38 2010 +0200 Partially revert "[cairo] Do not change device offset of mask surface" This partially reverts commit a32f6f9ebaed3e4827b9dc6cb37e307c2798f521. It fixed bug #27208, but it's causing regressions on other documents. diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc index cf0b31c..52941d8 100644 --- a/poppler/CairoOutputDev.cc +++ b/poppler/CairoOutputDev.cc @@ -1269,6 +1269,13 @@ void CairoOutputDev::setSoftMask(GfxState * state, double * bbox, GBool alpha, cairo_get_matrix(cairo, &mat); cairo_set_matrix(maskCtx, &mat); + /* make the device offset of the new mask match that of the group */ + double x_offset, y_offset; + cairo_surface_t *pats; + cairo_pattern_get_surface(group, &pats); + cairo_surface_get_device_offset(pats, &x_offset, &y_offset); + cairo_surface_set_device_offset(source, x_offset, y_offset); + /* paint the group */ cairo_set_source(maskCtx, group); cairo_paint(maskCtx); @@ -1301,7 +1308,9 @@ void CairoOutputDev::setSoftMask(GfxState * state, double * bbox, GBool alpha, /* setup the new mask pattern */ mask = cairo_pattern_create_for_surface(source); - cairo_pattern_set_matrix(mask, &mat); + cairo_matrix_t patMatrix; + cairo_pattern_get_matrix(group, &patMatrix); + cairo_pattern_set_matrix(mask, &patMatrix); cairo_surface_destroy(source); } else { From carlosgc at kemper.freedesktop.org Fri Apr 9 03:51:15 2010 From: carlosgc at kemper.freedesktop.org (Carlos Garcia Campos) Date: Fri, 9 Apr 2010 03:51:15 -0700 (PDT) Subject: [poppler] poppler/CairoOutputDev.cc Message-ID: <20100409105116.0DF9BF81F7@kemper.freedesktop.org> poppler/CairoOutputDev.cc | 9 +++++++++ 1 file changed, 9 insertions(+) New commits: commit 51aefe1423a068e8c119c21a8791d265aecbeaf5 Author: Carlos Garcia Campos Date: Fri Apr 9 12:50:00 2010 +0200 [cairo] Implement colorizing image masks with pattern colorspace diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc index 52941d8..49fb191 100644 --- a/poppler/CairoOutputDev.cc +++ b/poppler/CairoOutputDev.cc @@ -1511,6 +1511,9 @@ void CairoOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, return; } + if (state->getFillColorSpace()->getMode() == csPattern) + cairo_push_group_with_content (cairo, CAIRO_CONTENT_ALPHA); + /* shape is 1.0 for painted areas, 0.0 for unpainted ones */ cairo_matrix_t matrix; @@ -1522,6 +1525,12 @@ void CairoOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, } else { drawImageMaskRegular(state, ref, str, width, height, invert, interpolate, inlineImg); } + + if (state->getFillColorSpace()->getMode() == csPattern) { + if (mask) + cairo_pattern_destroy (mask); + mask = cairo_pop_group (cairo); + } } void CairoOutputDev::drawImageMaskRegular(GfxState *state, Object *ref, Stream *str, From reavertm at gmail.com Fri Apr 9 19:50:51 2010 From: reavertm at gmail.com (Maciej Mrozowski) Date: Sat, 10 Apr 2010 04:50:51 +0200 Subject: [poppler] [PATCH] [CMake] Preserve compile flags Message-ID: <201004100450.52068.reavertm@gmail.com> From 9ba3a289672cc596d98f4b92dcfe11a61ec85124 Mon Sep 17 00:00:00 2001 From: Maciej Mrozowski Date: Sat, 10 Apr 2010 04:38:47 +0200 Subject: [PATCH] [CMake] Preserve compiler flags - preserve GCC compiler flags passed by environment instead of replacing them with COMPILER_WARNINGS - add warnings for C compiled objects as well - use add_definitions() to pass preprocessor definitions instead of CMAKE_CXX_FLAGS --- CMakeLists.txt | 15 --------------- cmake/modules/PopplerMacros.cmake | 13 ++++--------- 2 files changed, 4 insertions(+), 24 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0725747..0505dff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -185,21 +185,6 @@ if(LCMS_FOUND) include_directories(${LCMS_INCLUDE_DIR}) endif(LCMS_FOUND) -if(DEFINED COMPILE_WARNINGS) -else(DEFINED COMPILE_WARNINGS) - set(COMPILE_WARNINGS "yes") -endif(DEFINED COMPILE_WARNINGS) -string(TOLOWER "${COMPILE_WARNINGS}" _comp_warnings) -if(_comp_warnings STREQUAL "no") - set(CMAKE_CXX_FLAGS "${DEFAULT_COMPILE_WARNINGS_NO} ${CMAKE_CXX_FLAGS}") -endif(_comp_warnings STREQUAL "no") -if(_comp_warnings STREQUAL "yes") - set(CMAKE_CXX_FLAGS "${DEFAULT_COMPILE_WARNINGS_YES} ${CMAKE_CXX_FLAGS}") -endif(_comp_warnings STREQUAL "yes") -if(_comp_warnings STREQUAL "kde") - set(CMAKE_CXX_FLAGS "${DEFAULT_COMPILE_WARNINGS_KDE} ${CMAKE_CXX_FLAGS}") -endif(_comp_warnings STREQUAL "kde") - include(ConfigureChecks.cmake) configure_file(config.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config.h) diff --git a/cmake/modules/PopplerMacros.cmake b/cmake/modules/PopplerMacros.cmake index befd20a..3ca29a9 100644 --- a/cmake/modules/PopplerMacros.cmake +++ b/cmake/modules/PopplerMacros.cmake @@ -99,12 +99,9 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) endif(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES) if(CMAKE_COMPILER_IS_GNUCXX) - # set the default compile warnings - set(DEFAULT_COMPILE_WARNINGS_NO) - set(DEFAULT_COMPILE_WARNINGS_YES "-Wall -Wno-write-strings") - set(DEFAULT_COMPILE_WARNINGS_KDE "-Wno-long-long -Wundef - D_XOPEN_SOURCE=500 -D_BSD_SOURCE -Wcast-align -Wconversion -Wchar-subscripts - Wall -W -Wpointer-arith -Wwrite-strings -O2 -Wformat-security -Wmissing- format-attribute -fno-exceptions -fno-check-new -fno-common") - - set(CMAKE_CXX_FLAGS "-Wnon-virtual-dtor -Woverloaded- virtual") + add_definitions(-D_XOPEN_SOURCE=500 -D_BSD_SOURCE) + set(CMAKE_C_FLAGS "-Wall -Wno-write-strings -Wno-long-long -Wundef -Wcast- align -Wconversion -Wchar-subscripts -W -Wpointer-arith -Wwrite-strings - Wformat-security -Wmissing-format-attribute -fno-common ${CMAKE_C_FLAGS}") + set(CMAKE_CXX_FLAGS "-Wall -Wno-write-strings -Wno-long-long -Wundef - Wcast-align -Wconversion -Wchar-subscripts -W -Wpointer-arith -Wwrite-strings -Wformat-security -Wmissing-format-attribute -fno-common -fno-check-new - Woverloaded-virtual -Wnon-virtual-dtor ${CMAKE_CXX_FLAGS}") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g") set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG") set(CMAKE_CXX_FLAGS_DEBUG "-g -O2 -fno-reorder-blocks -fno- schedule-insns -fno-inline") @@ -117,8 +114,7 @@ if(CMAKE_COMPILER_IS_GNUCXX) set(CMAKE_C_FLAGS_PROFILE "-g3 -fno-inline -ftest-coverage - fprofile-arcs") if(CMAKE_SYSTEM_NAME MATCHES Linux) - set(DEFAULT_COMPILE_WARNINGS_YES "${DEFAULT_COMPILE_WARNINGS_YES} -ansi") - set(DEFAULT_COMPILE_WARNINGS_KDE "${DEFAULT_COMPILE_WARNINGS_KDE} -ansi") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ansi") endif(CMAKE_SYSTEM_NAME MATCHES Linux) poppler_check_link_flag("-Wl,--as-needed" GCC_HAS_AS_NEEDED) @@ -139,4 +135,3 @@ if(CMAKE_C_COMPILER MATCHES "icc") set(CMAKE_C_FLAGS_DEBUG "-O2 -g -Ob0 -noalign") set(CMAKE_C_FLAGS_DEBUGFULL "-g -Ob0 -noalign") endif(CMAKE_C_COMPILER MATCHES "icc") - -- 1.6.4.4 -- regards MM From bradh at frogmouth.net Sat Apr 10 18:42:48 2010 From: bradh at frogmouth.net (Brad Hards) Date: Sun, 11 Apr 2010 11:42:48 +1000 Subject: [poppler] Reading Meta Information from PDF In-Reply-To: References: Message-ID: <201004111142.49051.bradh@frogmouth.net> On Thursday 08 April 2010 08:35:15 pm Mathieu Malaterre wrote: > This is slightly of topic to poppler. I am looking for a way to read > the Meta Information of a PDF file (basically the output of pdfinfo). This isn't a lot of context to work with, so I'm guessing what might work for you. > I find it a little bit cumbersome to integrate poppler (license issue, > no real need for a full rendering PDF library). Could someone suggest > another solution for reading those Meta Information from PDF files ? If you don't want to use poppler / pdfinfo, you could buy the adobe libraries, or you could try pdftk. Podofo may also be a possibility. > Will a simple regex (such as: ")") works ? I do not think this will work in general. It might work for all the PDF files you care about though. Read the PDF specification (Section 10.2.2 or thereabouts) for information on the metadata stream(s). Brad From mathieu.malaterre at gmail.com Sun Apr 11 00:59:21 2010 From: mathieu.malaterre at gmail.com (Mathieu Malaterre) Date: Sun, 11 Apr 2010 09:59:21 +0200 Subject: [poppler] Reading Meta Information from PDF In-Reply-To: <201004111142.49051.bradh@frogmouth.net> References: <201004111142.49051.bradh@frogmouth.net> Message-ID: On Sun, Apr 11, 2010 at 3:42 AM, Brad Hards wrote: > On Thursday 08 April 2010 08:35:15 pm Mathieu Malaterre wrote: >> ? This is slightly of topic to poppler. I am looking for a way to read >> the Meta Information of a PDF file (basically the output of pdfinfo). > This isn't a lot of context to work with, so I'm guessing what might work for > you. >> I find it a little bit cumbersome to integrate poppler (license issue, >> no real need for a full rendering PDF library). Could someone suggest >> another solution for reading those Meta Information from PDF files ? > If you don't want to use poppler / pdfinfo, you could buy the adobe libraries, > or you could try pdftk. Podofo may also be a possibility. I should have mention this is for integration in an open source/ cross platform toolkit with BSD license. For now I use tricks to link to private header of -system installed- poppler (due to API changes). But I still lack a PDF parser for Win32 platforms. >> ? Will a simple regex (such as: ")") works ? > I do not think this will work in general. It might work for all the PDF files > you care about though. Read the PDF specification (Section 10.2.2 or > thereabouts) for information on the metadata stream(s). If I find some time, I might get started with this python parser I found on the net: http://blog.didierstevens.com/programs/pdf-tools/ It is self contained, and is exactly focus on what I am looking for a stream interface (what is SAX to XML people) for PDF people. Thanks anyway, -- Mathieu From aacid at kde.org Sun Apr 11 07:01:51 2010 From: aacid at kde.org (Albert Astals Cid) Date: Sun, 11 Apr 2010 15:01:51 +0100 Subject: [poppler] Won't be releasing poppler 0.13.3 today Message-ID: <201004111501.51959.aacid@kde.org> I still have some patches that want to sneak in. Also remember that this is feature freeze, so Hib technically your patches for supporting linearized files are already late. How much time do you think you need for getting them in? Anyone else working on a feature that wants to be included in 0.14.0? Albert From carlosgc at kemper.freedesktop.org Mon Apr 12 10:35:20 2010 From: carlosgc at kemper.freedesktop.org (Carlos Garcia Campos) Date: Mon, 12 Apr 2010 10:35:20 -0700 (PDT) Subject: [poppler] glib/poppler-page.cc Message-ID: <20100412173520.A979DF8186@kemper.freedesktop.org> glib/poppler-page.cc | 227 ++++++++++++++++++++------------------------------- 1 file changed, 93 insertions(+), 134 deletions(-) New commits: commit 55c76069c52f9f51c6b8c60fe1aa8de499012ea8 Author: Carlos Garcia Campos Date: Mon Apr 12 19:32:46 2010 +0200 [glib] Use existing cairo api when rendering to a pixbuf I should fix bug #5589 for the GDK api too. diff --git a/glib/poppler-page.cc b/glib/poppler-page.cc index 747ee0c..39645bd 100644 --- a/glib/poppler-page.cc +++ b/glib/poppler-page.cc @@ -256,59 +256,8 @@ poppler_page_get_text_page (PopplerPage *page) } #ifdef POPPLER_WITH_GDK -typedef struct { - unsigned char *cairo_data; - cairo_surface_t *surface; - cairo_t *cairo; -} OutputDevData; - -static void -poppler_page_prepare_output_dev (PopplerPage *page, - double scale, - int rotation, - gboolean transparent, - OutputDevData *output_dev_data) -{ - CairoOutputDev *output_dev; - cairo_surface_t *surface; - double width, height; - int cairo_width, cairo_height, cairo_rowstride, rotate; - unsigned char *cairo_data; - - rotate = rotation + page->page->getRotate (); - if (rotate == 90 || rotate == 270) { - height = page->page->getCropWidth (); - width = page->page->getCropHeight (); - } else { - width = page->page->getCropWidth (); - height = page->page->getCropHeight (); - } - - cairo_width = (int) ceil(width * scale); - cairo_height = (int) ceil(height * scale); - - output_dev = page->document->output_dev; - cairo_rowstride = cairo_width * 4; - cairo_data = (guchar *) gmallocn (cairo_height, cairo_rowstride); - if (transparent) - memset (cairo_data, 0x00, cairo_height * cairo_rowstride); - else - memset (cairo_data, 0xff, cairo_height * cairo_rowstride); - - surface = cairo_image_surface_create_for_data(cairo_data, - CAIRO_FORMAT_ARGB32, - cairo_width, cairo_height, - cairo_rowstride); - - output_dev_data->cairo_data = cairo_data; - output_dev_data->surface = surface; - output_dev_data->cairo = cairo_create (surface); - output_dev->setCairo (output_dev_data->cairo); -} - static void copy_cairo_surface_to_pixbuf (cairo_surface_t *surface, - unsigned char *data, GdkPixbuf *pixbuf) { int cairo_width, cairo_height, cairo_rowstride; @@ -319,8 +268,8 @@ copy_cairo_surface_to_pixbuf (cairo_surface_t *surface, cairo_width = cairo_image_surface_get_width (surface); cairo_height = cairo_image_surface_get_height (surface); - cairo_rowstride = cairo_width * 4; - cairo_data = data; + cairo_rowstride = cairo_image_surface_get_stride (surface); + cairo_data = cairo_image_surface_get_data (surface); pixbuf_data = gdk_pixbuf_get_pixels (pixbuf); pixbuf_rowstride = gdk_pixbuf_get_rowstride (pixbuf); @@ -346,31 +295,6 @@ copy_cairo_surface_to_pixbuf (cairo_surface_t *surface, } } } - -static void -poppler_page_copy_to_pixbuf (PopplerPage *page, - GdkPixbuf *pixbuf, - OutputDevData *output_dev_data) -{ - copy_cairo_surface_to_pixbuf (output_dev_data->surface, - output_dev_data->cairo_data, - pixbuf); - - page->document->output_dev->setCairo (NULL); - cairo_surface_destroy (output_dev_data->surface); - cairo_destroy (output_dev_data->cairo); - gfree (output_dev_data->cairo_data); -} - -static void -poppler_page_set_selection_alpha (PopplerPage *page, - double scale, - GdkPixbuf *pixbuf, - PopplerSelectionStyle style, - PopplerRectangle *selection) -{ - /* Cairo doesn't need this, since cairo generates an alpha channel. */ -} #endif /* POPPLER_WITH_GDK */ static GBool @@ -611,23 +535,47 @@ _poppler_page_render_to_pixbuf (PopplerPage *page, GBool printing, GdkPixbuf *pixbuf) { - OutputDevData data; - - poppler_page_prepare_output_dev (page, scale, rotation, FALSE, &data); + cairo_t *cr; + cairo_surface_t *surface; - page->page->displaySlice(page->document->output_dev, - 72.0 * scale, 72.0 * scale, - rotation, - gFalse, /* useMediaBox */ - gTrue, /* Crop */ - src_x, src_y, - src_width, src_height, - printing, - page->document->doc->getCatalog (), - NULL, NULL, - printing ? poppler_print_annot_cb : NULL, NULL); - - poppler_page_copy_to_pixbuf (page, pixbuf, &data); + surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, + src_width, src_height); + cr = cairo_create (surface); + cairo_save (cr); + switch (rotation) { + case 90: + cairo_translate (cr, src_x + src_width, -src_y); + break; + case 180: + cairo_translate (cr, src_x + src_width, src_y + src_height); + break; + case 270: + cairo_translate (cr, -src_x, src_y + src_height); + break; + default: + cairo_translate (cr, -src_x, -src_y); + } + + if (scale != 1.0) + cairo_scale (cr, scale, scale); + + if (rotation != 0) + cairo_rotate (cr, rotation * G_PI / 180.0); + + if (printing) + poppler_page_render_for_printing (page, cr); + else + poppler_page_render (page, cr); + cairo_restore (cr); + + cairo_set_operator (cr, CAIRO_OPERATOR_DEST_OVER); + cairo_set_source_rgb (cr, 1., 1., 1.); + cairo_paint (cr); + + cairo_destroy (cr); + + copy_cairo_surface_to_pixbuf (surface, pixbuf); + cairo_surface_destroy (surface); } /** @@ -761,53 +709,64 @@ poppler_page_render_selection_to_pixbuf (PopplerPage *page, GdkColor *glyph_color, GdkColor *background_color) { - OutputDev *output_dev; - OutputDevData data; - TextPage *text; - SelectionStyle selection_style = selectionStyleGlyph; - PDFRectangle pdf_selection(selection->x1, selection->y1, - selection->x2, selection->y2); + cairo_t *cr; + cairo_surface_t *surface; + double width, height; + int cairo_width, cairo_height, rotate; + PopplerColor poppler_background_color; + PopplerColor poppler_glyph_color; - GfxColor gfx_background_color = { - { - background_color->red, - background_color->green, - background_color->blue - } - }; - GfxColor gfx_glyph_color = { - { - glyph_color->red, - glyph_color->green, - glyph_color->blue - } - }; + poppler_background_color.red = background_color->red; + poppler_background_color.green = background_color->green; + poppler_background_color.blue = background_color->blue; + poppler_glyph_color.red = glyph_color->red; + poppler_glyph_color.green = glyph_color->green; + poppler_glyph_color.blue = glyph_color->blue; - switch (style) - { - case POPPLER_SELECTION_GLYPH: - selection_style = selectionStyleGlyph; - break; - case POPPLER_SELECTION_WORD: - selection_style = selectionStyleWord; - break; - case POPPLER_SELECTION_LINE: - selection_style = selectionStyleLine; - break; - } + rotate = rotation + page->page->getRotate (); + if (rotate == 90 || rotate == 270) { + height = page->page->getCropWidth (); + width = page->page->getCropHeight (); + } else { + width = page->page->getCropWidth (); + height = page->page->getCropHeight (); + } - output_dev = page->document->output_dev; + cairo_width = (int) ceil(width * scale); + cairo_height = (int) ceil(height * scale); - poppler_page_prepare_output_dev (page, scale, rotation, TRUE, &data); + surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, + cairo_width, cairo_height); + cr = cairo_create (surface); + cairo_set_source_rgba (cr, 0, 0, 0, 0); + cairo_paint (cr); - text = poppler_page_get_text_page (page); - text->drawSelection (output_dev, scale, rotation, - &pdf_selection, selection_style, - &gfx_glyph_color, &gfx_background_color); + switch (rotate) { + case 90: + cairo_translate (cr, cairo_width, 0); + break; + case 180: + cairo_translate (cr, cairo_width, cairo_height); + break; + case 270: + cairo_translate (cr, 0, cairo_height); + break; + default: + cairo_translate (cr, 0, 0); + } + if (scale != 1.0) + cairo_scale (cr, scale, scale); + + if (rotate != 0) + cairo_rotate (cr, rotation * G_PI / 180.0); + + poppler_page_render_selection (page, cr, selection, old_selection, style, + &poppler_glyph_color, &poppler_background_color); - poppler_page_copy_to_pixbuf (page, pixbuf, &data); + cairo_destroy (cr); - poppler_page_set_selection_alpha (page, scale, pixbuf, style, selection); + copy_cairo_surface_to_pixbuf (surface, pixbuf); + cairo_surface_destroy (surface); } #endif /* POPPLER_WITH_GDK */ From aacid at kde.org Mon Apr 12 15:33:09 2010 From: aacid at kde.org (Albert Astals Cid) Date: Mon, 12 Apr 2010 23:33:09 +0100 Subject: [poppler] [PATCH] [CMake] Preserve compile flags In-Reply-To: <201004100450.52068.reavertm@gmail.com> References: <201004100450.52068.reavertm@gmail.com> Message-ID: <201004122333.09528.aacid@kde.org> A Dissabte, 10 d'abril de 2010, Maciej Mrozowski va escriure: > From 9ba3a289672cc596d98f4b92dcfe11a61ec85124 Mon Sep 17 00:00:00 2001 > From: Maciej Mrozowski > Date: Sat, 10 Apr 2010 04:38:47 +0200 > Subject: [PATCH] [CMake] Preserve compiler flags > > - preserve GCC compiler flags passed by environment instead of replacing > them with COMPILER_WARNINGS > - add warnings for C compiled objects as well > - use add_definitions() to pass preprocessor definitions instead of > CMAKE_CXX_FLAGS Spoke about it on IRC, the patch is rejected since it changes the default warning flags passed to the compiler. And that is not in your changelog, please make your changelog say what your patch does. Albert From fluffymike at googlemail.com Tue Apr 13 09:34:03 2010 From: fluffymike at googlemail.com (Mike Tonks) Date: Tue, 13 Apr 2010 17:34:03 +0100 Subject: [poppler] Static build of utils Message-ID: Hi, Is it easy to build the utils statically - I would really like a statically linked pdftohtml.exe (on Windows). I have sucessfully built poppler under cygwin using: ./configure make Is there some option I can add to this to create a static build? Thanks for any help. mike From aacid at kemper.freedesktop.org Wed Apr 14 11:27:48 2010 From: aacid at kemper.freedesktop.org (Albert Astals Cid) Date: Wed, 14 Apr 2010 11:27:48 -0700 (PDT) Subject: [poppler] 2 commits - cmake/modules configure.ac poppler/GlobalParams.cc test/perf-test.cc Message-ID: <20100414182748.CE527F80C1@kemper.freedesktop.org> cmake/modules/PopplerMacros.cmake | 2 +- configure.ac | 2 +- poppler/GlobalParams.cc | 2 ++ test/perf-test.cc | 2 ++ 4 files changed, 6 insertions(+), 2 deletions(-) New commits: commit a8d43ec1c7f5448a7f63d9bbd9062d56ee1c7c58 Author: Albert Astals Cid Date: Wed Apr 14 19:21:33 2010 +0100 update XOPEN_SOURCE to 600 in non standard compile options it seems helps compiling on some BSD diff --git a/cmake/modules/PopplerMacros.cmake b/cmake/modules/PopplerMacros.cmake index befd20a..e6b1efc 100644 --- a/cmake/modules/PopplerMacros.cmake +++ b/cmake/modules/PopplerMacros.cmake @@ -102,7 +102,7 @@ if(CMAKE_COMPILER_IS_GNUCXX) # set the default compile warnings set(DEFAULT_COMPILE_WARNINGS_NO) set(DEFAULT_COMPILE_WARNINGS_YES "-Wall -Wno-write-strings") - set(DEFAULT_COMPILE_WARNINGS_KDE "-Wno-long-long -Wundef -D_XOPEN_SOURCE=500 -D_BSD_SOURCE -Wcast-align -Wconversion -Wchar-subscripts -Wall -W -Wpointer-arith -Wwrite-strings -O2 -Wformat-security -Wmissing-format-attribute -fno-exceptions -fno-check-new -fno-common") + set(DEFAULT_COMPILE_WARNINGS_KDE "-Wno-long-long -Wundef -D_XOPEN_SOURCE=600 -D_BSD_SOURCE -Wcast-align -Wconversion -Wchar-subscripts -Wall -W -Wpointer-arith -Wwrite-strings -O2 -Wformat-security -Wmissing-format-attribute -fno-exceptions -fno-check-new -fno-common") set(CMAKE_CXX_FLAGS "-Wnon-virtual-dtor -Woverloaded-virtual") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g") diff --git a/configure.ac b/configure.ac index 72041d5..0a83b08 100644 --- a/configure.ac +++ b/configure.ac @@ -598,7 +598,7 @@ case "$enable_compile_warnings" in no) ;; yes) CXXFLAGS="-Wall -Wno-write-strings -Woverloaded-virtual -Wnon-virtual-dtor -ansi $CXXFLAGS" ;; kde) CXXFLAGS="-Wnon-virtual-dtor -Wno-long-long -Wundef -ansi \ - -D_XOPEN_SOURCE=500 -D_BSD_SOURCE -Wcast-align \ + -D_XOPEN_SOURCE=600 -D_BSD_SOURCE -Wcast-align \ -Wconversion -Wchar-subscripts -Wall -W -Wpointer-arith \ -Wwrite-strings -O2 -Wformat-security \ -Wmissing-format-attribute -fno-exceptions -fno-check-new \ commit 4cce1f14e964edf1bf2d9fb8286ee002a67dc212 Author: Albert Astals Cid Date: Tue Apr 13 21:57:16 2010 +0100 include strings.h on non windows platforms diff --git a/poppler/GlobalParams.cc b/poppler/GlobalParams.cc index 09a1b20..bf79585 100644 --- a/poppler/GlobalParams.cc +++ b/poppler/GlobalParams.cc @@ -68,6 +68,8 @@ #ifdef _WIN32 # define strcasecmp stricmp +#else +# include #endif #if MULTITHREADED diff --git a/test/perf-test.cc b/test/perf-test.cc index a11a377..6d6961e 100644 --- a/test/perf-test.cc +++ b/test/perf-test.cc @@ -22,6 +22,8 @@ #ifdef _WIN32 #include +#else +#include #endif // Define COPY_FILE if you want the file to be copied to a local disk first From aacid at kemper.freedesktop.org Wed Apr 14 15:17:09 2010 From: aacid at kemper.freedesktop.org (Albert Astals Cid) Date: Wed, 14 Apr 2010 15:17:09 -0700 (PDT) Subject: [poppler] 4 commits - poppler/CachedFile.cc utils/pdftohtml.cc utils/pdftops.cc utils/pdftotext.cc Message-ID: <20100414221709.62DE2F8178@kemper.freedesktop.org> poppler/CachedFile.cc | 1 + utils/pdftohtml.cc | 3 +++ utils/pdftops.cc | 3 +++ utils/pdftotext.cc | 3 +++ 4 files changed, 10 insertions(+) New commits: commit 84cd2186861436fbaa7c29aa691e69fcd543a1c2 Author: Hib Eris Date: Tue Apr 13 23:42:28 2010 +0200 Properly initialize variable diff --git a/poppler/CachedFile.cc b/poppler/CachedFile.cc index 95cc58b..cc86c89 100644 --- a/poppler/CachedFile.cc +++ b/poppler/CachedFile.cc @@ -24,6 +24,7 @@ CachedFile::CachedFile(CachedFileLoader *cachedFileLoaderA, GooString *uriA) streamPos = 0; chunks = new GooVector(); + length = 0; length = loader->init(uri, this); refCnt = 1; commit 24f244f486f332b0bd76c6525c5d9d03168a76e6 Author: Hib Eris Date: Tue Apr 13 23:54:28 2010 +0200 pdftops: require output filename when reading from stdin diff --git a/utils/pdftops.cc b/utils/pdftops.cc index 0376e2f..0bc43a1 100644 --- a/utils/pdftops.cc +++ b/utils/pdftops.cc @@ -330,6 +330,9 @@ int main(int argc, char *argv[]) { // construct PostScript file name if (argc == 3) { psFileName = new GooString(argv[2]); + } else if (fileName->cmp("fd://0") == 0) { + error(-1, "You have to provide an output filename when reading form stdin."); + goto err1; } else { p = fileName->getCString() + fileName->getLength() - 4; if (!strcmp(p, ".pdf") || !strcmp(p, ".PDF")) { commit 955f9f53ff225f6794a494fdd0f0fe5ee1a41d88 Author: Hib Eris Date: Tue Apr 13 23:47:40 2010 +0200 pdftotext: require output filename when reading from stdin diff --git a/utils/pdftotext.cc b/utils/pdftotext.cc index cee40fa..d4e004b 100644 --- a/utils/pdftotext.cc +++ b/utils/pdftotext.cc @@ -224,6 +224,9 @@ int main(int argc, char *argv[]) { // construct text file name if (argc == 3) { textFileName = new GooString(argv[2]); + } else if (fileName->cmp("fd://0") == 0) { + error(-1, "You have to provide an output filename when reading form stdin."); + goto err2; } else { p = fileName->getCString() + fileName->getLength() - 4; if (!strcmp(p, ".pdf") || !strcmp(p, ".PDF")) { commit 31388aa8b5117619878431b7fed2d033000af541 Author: Hib Eris Date: Tue Apr 13 23:27:20 2010 +0200 pdftohtml: require output filename when reading from stdin diff --git a/utils/pdftohtml.cc b/utils/pdftohtml.cc index 74733e7..0e0a376 100644 --- a/utils/pdftohtml.cc +++ b/utils/pdftohtml.cc @@ -231,6 +231,9 @@ int main(int argc, char *argv[]) { else htmlFileName =new GooString(tmp); delete tmp; + } else if (fileName->cmp("fd://0") == 0) { + error(-1, "You have to provide an output filename when reading form stdin."); + goto error; } else { p = fileName->getCString() + fileName->getLength() - 4; if (!strcmp(p, ".pdf") || !strcmp(p, ".PDF")) From fluffymike at googlemail.com Thu Apr 15 02:27:13 2010 From: fluffymike at googlemail.com (Mike Tonks) Date: Thu, 15 Apr 2010 10:27:13 +0100 Subject: [poppler] Output images from pdftohtml in xml mode Message-ID: Hi, I'm new here and I'm considering a patch to pdftohtml (well HtmlOutputDev). I'm coming from a perl background so I may not get it right first time but I'll do my best! It will be my first patch so any help appreciated. Changes: 1) Include the images in xml mode unless -ignore is specified. 2) Include the top, left, width, height data in img tags, where appropriate depending on mode. Not applicable to complex mode, in html mode height and width probably useful, positioning would be great but can be expanded later if required e.g. left, right or position relative to text. In xml mode just output all available data. Use Case: I'm post processing the xml and I do need the image data to be output. It's part of a workflow to produce epub ebook format from pdf. I've had a look at the code and it seems fairly straight forward, as the images are already output in other modes. Currently only the image src attribute is passed through so I guess there needs to be a new HtmlImage class (plus HtmlImages / HtmlImageAccu to handle the iteration). It looks like I can base this on the HtmlFont & HtmlLink modules, so I'll just follow the existing patterns there. Would you be likely to accept this patch once I get it working? Any suggestions? cheers, mike From ps_ml at gmx.de Thu Apr 15 02:57:40 2010 From: ps_ml at gmx.de (Patrick Spendrin) Date: Thu, 15 Apr 2010 11:57:40 +0200 Subject: [poppler] Static build of utils In-Reply-To: References: Message-ID: <4BC6E314.9040500@gmx.de> -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Am 13.04.2010 18:34, schrieb Mike Tonks: > Hi, > > Is it easy to build the utils statically - I would really like a > statically linked pdftohtml.exe (on Windows). > > I have sucessfully built poppler under cygwin using: > > ./configure > make > > Is there some option I can add to this to create a static build? > > Thanks for any help. Well, the problem is to have all your dependencies as static libraries as well. For me this freetype, jpeg, openjpeg, lcms, libpng, for you also cygwin*, which you would all need as static libraries as well. This is probably much harder than getting poppler itself building statically (you already do not have any dependency on libpoppler at all for pdftohtml). You can see the dependencies of your .exe or your dll with depends.exe (Dependency Walker, search for it on google). - From my point of view, I would rethink why you need a static file. > > mike regards, Patrick * it might be even impossible to have a static cygwin.dll > _______________________________________________ > poppler mailing list > poppler at lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/poppler > -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.10 (MingW32) iEYEARECAAYFAkvG4xMACgkQi49rfdk/G3blRwCfb33BJKm6y7W/86GHT7J6Ksyi 1BYAoJqVM/l+nR/WeYxLX0XPuXcYJsnU =YZ+P -----END PGP SIGNATURE----- From fluffymike at googlemail.com Thu Apr 15 03:59:19 2010 From: fluffymike at googlemail.com (Mike Tonks) Date: Thu, 15 Apr 2010 11:59:19 +0100 Subject: [poppler] Static build of utils In-Reply-To: <4BC6E314.9040500@gmx.de> References: <4BC6E314.9040500@gmx.de> Message-ID: Thanks Patrick, I guess I should try again to build with mingw to get away from the cygwin issues. Just that cygwin has most of the dependencies if you hunt through the package list, and I didn't have much luck with mingw on the first attempt. Ideally I would like to deploy to various windows machines just by dropping in an exe, without having to install a load of stuff. I guess if I have all the dll's this might not be a problem. We have an old pdf2xml.exe for example that does just this, built against the original xpdf libraries. mike On 15 April 2010 10:57, Patrick Spendrin wrote: > -----BEGIN PGP SIGNED MESSAGE----- > Hash: SHA1 > > Am 13.04.2010 18:34, schrieb Mike Tonks: >> Hi, >> >> Is it easy to build the utils statically - I would really like a >> statically linked pdftohtml.exe (on Windows). >> >> I have sucessfully built poppler under cygwin using: >> >> ./configure >> make >> >> Is there some option I can add to this to create a static build? >> >> Thanks for any help. > > Well, the problem is to have all your dependencies as static libraries > as well. > For me this freetype, jpeg, openjpeg, lcms, libpng, for you also > cygwin*, which you would all need as static libraries as well. This is > probably much harder than getting poppler itself building statically > (you already do not have any dependency on libpoppler at all for pdftohtml). > You can see the dependencies of your .exe or your dll with depends.exe > (Dependency Walker, search for it on google). > - From my point of view, I would rethink why you need a static file. > >> >> mike > > regards, > Patrick > > * it might be even impossible to have a static cygwin.dll > >> _______________________________________________ >> poppler mailing list >> poppler at lists.freedesktop.org >> http://lists.freedesktop.org/mailman/listinfo/poppler >> > > -----BEGIN PGP SIGNATURE----- > Version: GnuPG v2.0.10 (MingW32) > > iEYEARECAAYFAkvG4xMACgkQi49rfdk/G3blRwCfb33BJKm6y7W/86GHT7J6Ksyi > 1BYAoJqVM/l+nR/WeYxLX0XPuXcYJsnU > =YZ+P > -----END PGP SIGNATURE----- > _______________________________________________ > poppler mailing list > poppler at lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/poppler > From aacid at kde.org Sat Apr 17 03:17:45 2010 From: aacid at kde.org (Albert Astals Cid) Date: Sat, 17 Apr 2010 11:17:45 +0100 Subject: [poppler] Output images from pdftohtml in xml mode In-Reply-To: References: Message-ID: <201004171117.45583.aacid@kde.org> A Dijous, 15 d'abril de 2010, Mike Tonks va escriure: > Hi, Hi > > I'm new here welcome > and I'm considering a patch to pdftohtml (well > HtmlOutputDev). I'm coming from a perl background so I may not get it > right first time but I'll do my best! It will be my first patch so > any help appreciated. > > Changes: > > 1) Include the images in xml mode unless -ignore is specified. > > 2) Include the top, left, width, height data in img tags, where > appropriate depending on mode. Not applicable to complex mode, in > html mode height and width probably useful, positioning would be great > but can be expanded later if required e.g. left, right or position > relative to text. In xml mode just output all available data. > > Use Case: I'm post processing the xml and I do need the image data to > be output. It's part of a workflow to produce epub ebook format from > pdf. Seems sane. > > I've had a look at the code and it seems fairly straight forward, as > the images are already output in other modes. Currently only the > image src attribute is passed through so I guess there needs to be a > new HtmlImage class (plus HtmlImages / HtmlImageAccu to handle the > iteration). It looks like I can base this on the HtmlFont & HtmlLink > modules, so I'll just follow the existing patterns there. > > > Would you be likely to accept this patch once I get it working? If the code is ok, yes, we'll probably accept it. Thanks and welcome again :-) Albert > Any suggestions? > > cheers, > > mike > _______________________________________________ > poppler mailing list > poppler at lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/poppler From carlosgc at kemper.freedesktop.org Sun Apr 18 08:58:49 2010 From: carlosgc at kemper.freedesktop.org (Carlos Garcia Campos) Date: Sun, 18 Apr 2010 08:58:49 -0700 (PDT) Subject: [poppler] 2 commits - poppler/CairoOutputDev.cc Message-ID: <20100418155849.C2076F8205@kemper.freedesktop.org> poppler/CairoOutputDev.cc | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) New commits: commit 12d83931ae1b899b70c7ea5c01f03f123b1bb9a8 Author: Carlos Garcia Campos Date: Sun Apr 18 17:53:48 2010 +0200 [cairo] Check pattern status after setting matrix when rendering images Fixes rendering of document attached to kde bug http://bugs.kde.org/show_bug.cgi?id=135417. diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc index 96407d4..845bf9d 100644 --- a/poppler/CairoOutputDev.cc +++ b/poppler/CairoOutputDev.cc @@ -1594,6 +1594,10 @@ void CairoOutputDev::drawImageMaskRegular(GfxState *state, Object *ref, Stream * cairo_matrix_init_translate (&matrix, 0, height); cairo_matrix_scale (&matrix, width, -height); cairo_pattern_set_matrix (pattern, &matrix); + if (cairo_pattern_status (pattern)) { + cairo_pattern_destroy (pattern); + goto cleanup; + } if (state->getFillColorSpace()->getMode() == csPattern) { mask = cairo_pattern_reference (pattern); @@ -1861,6 +1865,12 @@ void CairoOutputDev::drawImageMaskPrescaled(GfxState *state, Object *ref, Stream cairo_matrix_init_translate (&matrix, 0, scaledHeight); cairo_matrix_scale (&matrix, scaledWidth, -scaledHeight); cairo_pattern_set_matrix (pattern, &matrix); + if (cairo_pattern_status (pattern)) { + cairo_pattern_destroy (pattern); + imgStr->close(); + delete imgStr; + return; + } mask = cairo_pattern_reference (pattern); } else { @@ -2016,10 +2026,20 @@ void CairoOutputDev::drawMaskedImage(GfxState *state, Object *ref, cairo_matrix_init_translate (&matrix, 0, height); cairo_matrix_scale (&matrix, width, -height); cairo_pattern_set_matrix (pattern, &matrix); + if (cairo_pattern_status (pattern)) { + cairo_pattern_destroy (pattern); + cairo_pattern_destroy (maskPattern); + goto cleanup; + } cairo_matrix_init_translate (&maskMatrix, 0, maskHeight); cairo_matrix_scale (&maskMatrix, maskWidth, -maskHeight); cairo_pattern_set_matrix (maskPattern, &maskMatrix); + if (cairo_pattern_status (maskPattern)) { + cairo_pattern_destroy (maskPattern); + cairo_pattern_destroy (pattern); + goto cleanup; + } if (!printing) { cairo_save (cairo); @@ -2156,10 +2176,20 @@ void CairoOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref, Stream *s cairo_matrix_init_translate (&matrix, 0, height); cairo_matrix_scale (&matrix, width, -height); cairo_pattern_set_matrix (pattern, &matrix); + if (cairo_pattern_status (pattern)) { + cairo_pattern_destroy (pattern); + cairo_pattern_destroy (maskPattern); + goto cleanup; + } cairo_matrix_init_translate (&maskMatrix, 0, maskHeight); cairo_matrix_scale (&maskMatrix, maskWidth, -maskHeight); cairo_pattern_set_matrix (maskPattern, &maskMatrix); + if (cairo_pattern_status (maskPattern)) { + cairo_pattern_destroy (maskPattern); + cairo_pattern_destroy (pattern); + goto cleanup; + } if (fill_opacity != 1.0) cairo_push_group (cairo); @@ -2379,6 +2409,10 @@ void CairoOutputDev::drawImage(GfxState *state, Object *ref, Stream *str, cairo_matrix_init_translate (&matrix, 0, height); cairo_matrix_scale (&matrix, width, -height); cairo_pattern_set_matrix (pattern, &matrix); + if (cairo_pattern_status (pattern)) { + cairo_pattern_destroy (pattern); + goto cleanup; + } if (!mask && fill_opacity != 1.0) { maskPattern = cairo_pattern_create_rgba (1., 1., 1., fill_opacity); commit ff6d501a2fc887fd49a985161f756d6d6b8e6c0d Author: Carlos Garcia Campos Date: Sun Apr 18 17:51:42 2010 +0200 [cairo] Fix a crash when rendering 0x0 images See kde bug http://bugs.kde.org/show_bug.cgi?id=135417 diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc index 49fb191..96407d4 100644 --- a/poppler/CairoOutputDev.cc +++ b/poppler/CairoOutputDev.cc @@ -1465,6 +1465,9 @@ CairoOutputDev::getFilterForSurface(cairo_surface_t *image, int orig_width = cairo_image_surface_get_width (image); int orig_height = cairo_image_surface_get_height (image); + if (orig_width == 0 || orig_height == 0) + return CAIRO_FILTER_NEAREST; + int scaled_width, scaled_height; getScaledSize (orig_width, orig_height, &scaled_width, &scaled_height); From carlosgc at kemper.freedesktop.org Mon Apr 19 05:49:18 2010 From: carlosgc at kemper.freedesktop.org (Carlos Garcia Campos) Date: Mon, 19 Apr 2010 05:49:18 -0700 (PDT) Subject: [poppler] 6 commits - poppler/TextOutputDev.cc poppler/TextOutputDev.h Message-ID: <20100419124918.AEADBF811A@kemper.freedesktop.org> poppler/TextOutputDev.cc | 1014 +++++++++++++++++++++++++++++++++++------------ poppler/TextOutputDev.h | 13 2 files changed, 773 insertions(+), 254 deletions(-) New commits: commit 9c5612f6e013a8698eff6531ec388a7e6c1fb89a Author: Marek Kasik Date: Fri Feb 12 14:31:01 2010 +0100 Distinguish between columns and tables when selecting text This commit add ability to detect tables in text by checking borders of 4 neighbouring text blocks for arrangement (to the left, to the right, center, ...). Detected border of whole table is then stored in ExMin, ExMax, EyMin and EyMax of each block together with id of detected table. Sorting of blocks is then performed on the these borders to be able to distinguish tables from columns. Pasting of selected text was modified so that tables are pasted correctly (even with multi line cells). diff --git a/poppler/TextOutputDev.cc b/poppler/TextOutputDev.cc index 1dfe560..e03cc8d 100644 --- a/poppler/TextOutputDev.cc +++ b/poppler/TextOutputDev.cc @@ -38,6 +38,7 @@ #include #include #include +#include #include #ifdef _WIN32 #include // for O_BINARY @@ -1154,6 +1155,8 @@ TextBlock::TextBlock(TextPage *pageA, int rotA) { curLine = NULL; next = NULL; stackNext = NULL; + tableId = -1; + tableEnd = gFalse; } TextBlock::~TextBlock() { @@ -1622,31 +1625,31 @@ GBool TextBlock::isBeforeByRule1(TextBlock *blk1) { switch (this->page->primaryRot) { case 0: case 2: - overlap = ((this->xMin <= blk1->xMin) && - (blk1->xMin <= this->xMax)) || - ((blk1->xMin <= this->xMin) && - (this->xMin <= blk1->xMax)); + overlap = ((this->ExMin <= blk1->ExMin) && + (blk1->ExMin <= this->ExMax)) || + ((blk1->ExMin <= this->ExMin) && + (this->ExMin <= blk1->ExMax)); break; case 1: case 3: - overlap = ((this->yMin <= blk1->yMin) && - (blk1->yMin <= this->yMax)) || - ((blk1->yMin <= this->yMin) && - (this->yMin <= blk1->yMax)); + overlap = ((this->EyMin <= blk1->EyMin) && + (blk1->EyMin <= this->EyMax)) || + ((blk1->EyMin <= this->EyMin) && + (this->EyMin <= blk1->EyMax)); break; } switch (this->page->primaryRot) { case 0: - before = overlap && this->yMin < blk1->yMin; + before = overlap && this->EyMin < blk1->EyMin; break; case 1: - before = overlap && this->xMax > blk1->xMax; + before = overlap && this->ExMax > blk1->ExMax; break; case 2: - before = overlap && this->yMax > blk1->yMax; + before = overlap && this->EyMax > blk1->EyMax; break; case 3: - before = overlap && this->xMin < blk1->xMin; + before = overlap && this->ExMin < blk1->ExMin; break; } return before; @@ -1662,16 +1665,16 @@ GBool TextBlock::isBeforeByRule2(TextBlock *blk1) { switch (rotLR) { case 0: - cmp = xMax - blk1->xMin; + cmp = ExMax - blk1->ExMin; break; case 1: - cmp = yMin - blk1->yMax; + cmp = EyMin - blk1->EyMax; break; case 2: - cmp = blk1->xMax - xMin; + cmp = blk1->ExMax - ExMin; break; case 3: - cmp = blk1->yMin - yMax; + cmp = blk1->EyMin - EyMax; break; } return cmp <= 0; @@ -1697,7 +1700,7 @@ int TextBlock::visitDepthFirst(TextBlock *blkList, int pos1, #if 0 // for debugging printf("visited: %d %.2f..%.2f %.2f..%.2f\n", - sortPos, blk1->xMin, blk1->xMax, blk1->yMin, blk1->yMax); + sortPos, blk1->ExMin, blk1->ExMax, blk1->EyMin, blk1->EyMax); #endif visited[pos1] = gTrue; pos2 = -1; @@ -1708,36 +1711,55 @@ int TextBlock::visitDepthFirst(TextBlock *blkList, int pos1, continue; } before = gFalse; - if (blk2->isBeforeByRule1(blk1)) { - // Rule (1) blk1 and blk2 overlap, and blk2 is above blk1. - before = gTrue; -#if 0 // for debugging - printf("rule1: %.2f..%.2f %.2f..%.2f %.2f..%.2f %.2f..%.2f\n", - blk2->xMin, blk2->xMax, blk2->yMin, blk2->yMax, - blk1->xMin, blk1->xMax, blk1->yMin, blk1->yMax); -#endif - } else if (blk2->isBeforeByRule2(blk1)) { - // Rule (2) blk2 left of blk1, and no intervening blk3 - // such that blk1 is before blk3 by rule 1, - // and blk3 is before blk2 by rule 1. - before = gTrue; - for (blk3 = blkList; blk3; blk3 = blk3->next) { - if (blk3 == blk2 || blk3 == blk1) { - continue; - } - if (blk1->isBeforeByRule1(blk3) && - blk3->isBeforeByRule1(blk2)) { - before = gFalse; - break; - } + + // is blk2 before blk1? (for table entries) + if (blk1->tableId >= 0 && blk1->tableId == blk2->tableId) { + if (page->primaryLR) { + if (blk2->xMax <= blk1->xMin && + blk2->yMin <= blk1->yMax && + blk2->yMax >= blk1->yMin) + before = gTrue; + } else { + if (blk2->xMin >= blk1->xMax && + blk2->yMin <= blk1->yMax && + blk2->yMax >= blk1->yMin) + before = gTrue; } + + if (blk2->yMax <= blk1->yMin) + before = gTrue; + } else { + if (blk2->isBeforeByRule1(blk1)) { + // Rule (1) blk1 and blk2 overlap, and blk2 is above blk1. + before = gTrue; +#if 0 // for debugging + printf("rule1: %.2f..%.2f %.2f..%.2f %.2f..%.2f %.2f..%.2f\n", + blk2->ExMin, blk2->ExMax, blk2->EyMin, blk2->EyMax, + blk1->ExMin, blk1->ExMax, blk1->EyMin, blk1->EyMax); +#endif + } else if (blk2->isBeforeByRule2(blk1)) { + // Rule (2) blk2 left of blk1, and no intervening blk3 + // such that blk1 is before blk3 by rule 1, + // and blk3 is before blk2 by rule 1. + before = gTrue; + for (blk3 = blkList; blk3; blk3 = blk3->next) { + if (blk3 == blk2 || blk3 == blk1) { + continue; + } + if (blk1->isBeforeByRule1(blk3) && + blk3->isBeforeByRule1(blk2)) { + before = gFalse; + break; + } + } #if 0 // for debugging - if (before) { - printf("rule2: %.2f..%.2f %.2f..%.2f %.2f..%.2f %.2f..%.2f\n", - blk1->xMin, blk1->xMax, blk1->yMin, blk1->yMax, - blk2->xMin, blk2->xMax, blk2->yMin, blk2->yMax); - } + if (before) { + printf("rule2: %.2f..%.2f %.2f..%.2f %.2f..%.2f %.2f..%.2f\n", + blk1->ExMin, blk1->ExMax, blk1->EyMin, blk1->EyMax, + blk2->ExMin, blk2->ExMax, blk2->EyMin, blk2->EyMax); + } #endif + } } if (before) { // blk2 is before blk1, so it needs to be visited @@ -1747,7 +1769,7 @@ int TextBlock::visitDepthFirst(TextBlock *blkList, int pos1, } #if 0 // for debugging printf("sorted: %d %.2f..%.2f %.2f..%.2f\n", - sortPos, blk1->xMin, blk1->xMax, blk1->yMin, blk1->yMax); + sortPos, blk1->ExMin, blk1->ExMax, blk1->EyMin, blk1->EyMax); #endif sorted[sortPos++] = blk1; return sortPos; @@ -2321,7 +2343,7 @@ void TextPage::coalesce(GBool physLayout, GBool doHTML) { TextPool *pool; TextWord *word0, *word1, *word2; TextLine *line; - TextBlock *blkList, *blk, *lastBlk, *blk0, *blk1; + TextBlock *blkList, *blk, *lastBlk, *blk0, *blk1, *blk2; TextFlow *flow, *lastFlow; TextUnderline *underline; TextLink *link; @@ -2997,6 +3019,263 @@ void TextPage::coalesce(GBool physLayout, GBool doHTML) { for (i = 0; i < nBlocks; i++) { visited[i] = gFalse; } + + double bxMin0, byMin0, bxMin1, byMin1; + int numTables = 0; + int tableId = -1; + int correspondenceX, correspondenceY; + double xCentre1, yCentre1, xCentre2, yCentre2; + double xCentre3, yCentre3, xCentre4, yCentre4; + double deltaX, deltaY; + TextBlock *fblk2 = NULL, *fblk3 = NULL, *fblk4 = NULL; + + for (blk1 = blkList; blk1; blk1 = blk1->next) { + blk1->ExMin = blk1->xMin; + blk1->ExMax = blk1->xMax; + blk1->EyMin = blk1->yMin; + blk1->EyMax = blk1->yMax; + + bxMin0 = std::numeric_limits::max(); + byMin0 = std::numeric_limits::max(); + bxMin1 = std::numeric_limits::max(); + byMin1 = std::numeric_limits::max(); + + fblk2 = NULL; + fblk3 = NULL; + fblk4 = NULL; + + /* find fblk2, fblk3 and fblk4 so that + * fblk2 is on the right of blk1 and overlap with blk1 in y axis + * fblk3 is under blk1 and overlap with blk1 in x axis + * fblk4 is under blk1 and on the right of blk1 + * and they are closest to blk1 + */ + for (blk2 = blkList; blk2; blk2 = blk2->next) { + if (blk2 != blk1) { + if (blk2->yMin <= blk1->yMax && + blk2->yMax >= blk1->yMin && + blk2->xMin > blk1->xMax && + blk2->xMin < bxMin0) { + bxMin0 = blk2->xMin; + fblk2 = blk2; + } else if (blk2->xMin <= blk1->xMax && + blk2->xMax >= blk1->xMin && + blk2->yMin > blk1->yMax && + blk2->yMin < byMin0) { + byMin0 = blk2->yMin; + fblk3 = blk2; + } else if (blk2->xMin > blk1->xMax && + blk2->xMin < bxMin1 && + blk2->yMin > blk1->yMax && + blk2->yMin < byMin1) { + bxMin1 = blk2->xMin; + byMin1 = blk2->yMin; + fblk4 = blk2; + } + } + } + + /* fblk4 can not overlap with fblk3 in x and with fblk2 in y + * fblk4 has to overlap with fblk3 in y and with fblk2 in x + */ + if (fblk2 != NULL && + fblk3 != NULL && + fblk4 != NULL) { + if (((fblk3->xMin <= fblk4->xMax && fblk3->xMax >= fblk4->xMin) || + (fblk2->yMin <= fblk4->yMax && fblk2->yMax >= fblk4->yMin)) || + !(fblk4->xMin <= fblk2->xMax && fblk4->xMax >= fblk2->xMin && + fblk4->yMin <= fblk3->yMax && fblk4->yMax >= fblk3->yMin)) { + fblk2 = NULL; + fblk3 = NULL; + fblk4 = NULL; + } + } + + // if we found any then look whether they form a table + if (fblk2 != NULL && + fblk3 != NULL && + fblk4 != NULL) { + tableId = -1; + correspondenceX = 0; + correspondenceY = 0; + deltaX = 0.0; + deltaY = 0.0; + + if (blk1->lines && blk1->lines->words) + deltaX = blk1->lines->words->getFontSize(); + if (fblk2->lines && fblk2->lines->words) + deltaX = deltaX < fblk2->lines->words->getFontSize() ? + deltaX : fblk2->lines->words->getFontSize(); + if (fblk3->lines && fblk3->lines->words) + deltaX = deltaX < fblk3->lines->words->getFontSize() ? + deltaX : fblk3->lines->words->getFontSize(); + if (fblk4->lines && fblk4->lines->words) + deltaX = deltaX < fblk4->lines->words->getFontSize() ? + deltaX : fblk4->lines->words->getFontSize(); + + deltaY = deltaX; + + deltaX *= minColSpacing1; + deltaY *= maxIntraLineDelta; + + xCentre1 = (blk1->xMax + blk1->xMin) / 2.0; + yCentre1 = (blk1->yMax + blk1->yMin) / 2.0; + xCentre2 = (fblk2->xMax + fblk2->xMin) / 2.0; + yCentre2 = (fblk2->yMax + fblk2->yMin) / 2.0; + xCentre3 = (fblk3->xMax + fblk3->xMin) / 2.0; + yCentre3 = (fblk3->yMax + fblk3->yMin) / 2.0; + xCentre4 = (fblk4->xMax + fblk4->xMin) / 2.0; + yCentre4 = (fblk4->yMax + fblk4->yMin) / 2.0; + + // are blocks centrally aligned in x ? + if (abs (xCentre1 - xCentre3) <= deltaX && + abs (xCentre2 - xCentre4) <= deltaX) + correspondenceX++; + + // are blocks centrally aligned in y ? + if (abs (yCentre1 - yCentre2) <= deltaY && + abs (yCentre3 - yCentre4) <= deltaY) + correspondenceY++; + + // are blocks aligned to the left ? + if (abs (blk1->xMin - fblk3->xMin) <= deltaX && + abs (fblk2->xMin - fblk4->xMin) <= deltaX) + correspondenceX++; + + // are blocks aligned to the right ? + if (abs (blk1->xMax - fblk3->xMax) <= deltaX && + abs (fblk2->xMax - fblk4->xMax) <= deltaX) + correspondenceX++; + + // are blocks aligned to the top ? + if (abs (blk1->yMin - fblk2->yMin) <= deltaY && + abs (fblk3->yMin - fblk4->yMin) <= deltaY) + correspondenceY++; + + // are blocks aligned to the bottom ? + if (abs (blk1->yMax - fblk2->yMax) <= deltaY && + abs (fblk3->yMax - fblk4->yMax) <= deltaY) + correspondenceY++; + + // are blocks aligned in x and y ? + if (correspondenceX > 0 && + correspondenceY > 0) { + + // find maximal tableId + tableId = tableId < fblk4->tableId ? fblk4->tableId : tableId; + tableId = tableId < fblk3->tableId ? fblk3->tableId : tableId; + tableId = tableId < fblk2->tableId ? fblk2->tableId : tableId; + tableId = tableId < blk1->tableId ? blk1->tableId : tableId; + + // if the tableId is -1, then we found new table + if (tableId < 0) { + tableId = numTables; + numTables++; + } + + blk1->tableId = tableId; + fblk2->tableId = tableId; + fblk3->tableId = tableId; + fblk4->tableId = tableId; + } + } + } + + /* set extended bounding boxes of all table entries + * so that they contain whole table + * (we need to process whole table size when comparing it + * with regular text blocks) + */ + PDFRectangle *envelopes = new PDFRectangle [numTables]; + TextBlock **ending_blocks = new TextBlock* [numTables]; + + for (i = 0; i < numTables; i++) { + envelopes[i].x1 = std::numeric_limits::max(); + envelopes[i].x2 = std::numeric_limits::min(); + envelopes[i].y1 = std::numeric_limits::max(); + envelopes[i].y2 = std::numeric_limits::min(); + } + + for (blk1 = blkList; blk1; blk1 = blk1->next) { + if (blk1->tableId >= 0) { + if (blk1->ExMin < envelopes[blk1->tableId].x1) { + envelopes[blk1->tableId].x1 = blk1->ExMin; + if (!blk1->page->primaryLR) + ending_blocks[blk1->tableId] = blk1; + } + + if (blk1->ExMax > envelopes[blk1->tableId].x2) { + envelopes[blk1->tableId].x2 = blk1->ExMax; + if (blk1->page->primaryLR) + ending_blocks[blk1->tableId] = blk1; + } + + envelopes[blk1->tableId].y1 = blk1->EyMin < envelopes[blk1->tableId].y1 ? + blk1->EyMin : envelopes[blk1->tableId].y1; + envelopes[blk1->tableId].y2 = blk1->EyMax > envelopes[blk1->tableId].y2 ? + blk1->EyMax : envelopes[blk1->tableId].y2; + } + } + + for (blk1 = blkList; blk1; blk1 = blk1->next) { + if (blk1->tableId >= 0 && + blk1->xMin <= ending_blocks[blk1->tableId]->xMax && + blk1->xMax >= ending_blocks[blk1->tableId]->xMin) { + blk1->tableEnd = gTrue; + } + } + + for (blk1 = blkList; blk1; blk1 = blk1->next) { + if (blk1->tableId >= 0) { + blk1->ExMin = envelopes[blk1->tableId].x1; + blk1->ExMax = envelopes[blk1->tableId].x2; + blk1->EyMin = envelopes[blk1->tableId].y1; + blk1->EyMax = envelopes[blk1->tableId].y2; + } + } + delete[] envelopes; + delete[] ending_blocks; + + + /* set extended bounding boxes of all other blocks + * so that they extend in x without hitting neighbours + */ + for (blk1 = blkList; blk1; blk1 = blk1->next) { + if (!blk1->tableId >= 0) { + double xMax = std::numeric_limits::max(); + double xMin = std::numeric_limits::min(); + + for (blk2 = blkList; blk2; blk2 = blk2->next) { + if (blk2 == blk1) + continue; + + if (blk1->yMin <= blk2->yMax && blk1->yMax >= blk2->yMin) { + if (blk2->xMin < xMax && blk2->xMin > blk1->xMax) + xMax = blk2->xMin; + + if (blk2->xMax > xMin && blk2->xMax < blk1->xMin) + xMin = blk2->xMax; + } + } + + for (blk2 = blkList; blk2; blk2 = blk2->next) { + if (blk2 == blk1) + continue; + + if (blk2->xMax > blk1->ExMax && + blk2->xMax <= xMax && + blk2->yMin >= blk1->yMax) { + blk1->ExMax = blk2->xMax; + } + + if (blk2->xMin < blk1->ExMin && + blk2->xMin >= xMin && + blk2->yMin >= blk1->yMax) + blk1->ExMin = blk2->xMin; + } + } + } + i = -1; for (blk1 = blkList; blk1; blk1 = blk1->next) { i++; @@ -3072,7 +3351,7 @@ void TextPage::coalesce(GBool physLayout, GBool doHTML) { flow->priMin, flow->priMax); for (blk = flow->blocks; blk; blk = blk->next) { printf(" block: rot=%d x=%.2f..%.2f y=%.2f..%.2f pri=%.2f..%.2f\n", - blk->rot, blk->xMin, blk->xMax, blk->yMin, blk->yMax, + blk->rot, blk->ExMin, blk->ExMax, blk->EyMin, blk->EyMax, blk->priMin, blk->priMax); for (line = blk->lines; line; line = line->next) { printf(" line:\n"); @@ -3615,11 +3894,16 @@ GooString *TextSelectionDumper::getText (void) { GooString *s; TextLineFrag *frag; - int i; + int i, j; GBool multiLine; UnicodeMap *uMap; char space[8], eol[16]; int spaceLen, eolLen; + GooList *strings = NULL; + int actual_table = -1; + int actual_line = -1; + int last_length = 0; + TextBlock *actual_block = NULL; s = new GooString(); @@ -3636,8 +3920,84 @@ GooString *TextSelectionDumper::getText (void) for (i = 0; i < nFrags; ++i) { frag = &frags[i]; - page->dumpFragment(frag->line->text + frag->start, frag->len, uMap, s); - s->append(eol, eolLen); + if (actual_table >= 0 && frag->line->blk->tableId < 0) { + for (j = 0; j < strings->getLength (); j++) { + s->append ((GooString*) strings->get (j)); + s->append (eol, eolLen); + delete ((GooString*) strings->get (j)); + } + delete strings; + strings = NULL; + actual_table = -1; + actual_line = -1; + actual_block = NULL; + } + + // a table + if (frag->line->blk->tableId >= 0) { + if (actual_table == -1) { + strings = new GooList(); + actual_table = frag->line->blk->tableId; + actual_block = frag->line->blk; + actual_line = -1; + } + + // the same block + if (actual_block == frag->line->blk) { + actual_line++; + if (actual_line >= strings->getLength ()) { + GooString *t = new GooString (); + // add some spaces to have this block correctly aligned + if (actual_line > 0) + for (j = 0; j < ((GooString*) (strings->get (actual_line - 1)))->getLength() - last_length - 1; j++) + t->append (space, spaceLen); + strings->append (t); + } + } + // another block + else { + // previous block ended its row + if (actual_block->tableEnd) { + for (j = 0; j < strings->getLength (); j++) { + s->append ((GooString*) strings->get (j)); + s->append (eol, eolLen); + delete ((GooString*) strings->get (j)); + } + delete strings; + + strings = new GooList(); + GooString *t = new GooString (); + strings->append (t); + } + actual_block = frag->line->blk; + actual_line = 0; + } + + page->dumpFragment(frag->line->text + frag->start, frag->len, uMap, ((GooString*) strings->get (actual_line))); + last_length = frag->len; + + if (!frag->line->blk->tableEnd) { + ((GooString*) strings->get (actual_line))->append (space, spaceLen); + } + } + // not a table + else { + page->dumpFragment (frag->line->text + frag->start, frag->len, uMap, s); + s->append (eol, eolLen); + } + } + + if (strings != NULL) { + for (j = 0; j < strings->getLength (); j++) { + s->append((GooString*) strings->get (j)); + s->append(eol, eolLen); + delete ((GooString*) strings->get (j)); + } + delete strings; + strings = NULL; + actual_table = -1; + actual_line = -1; + actual_block = NULL; } } @@ -3867,14 +4227,28 @@ void TextLine::visitSelection(TextSelectionVisitor *visitor, end = NULL; current = NULL; for (p = words; p != NULL; p = p->next) { - if ((selection->x1 < p->xMax && selection->y1 < p->yMax) || - (selection->x2 < p->xMax && selection->y2 < p->yMax)) - if (begin == NULL) - begin = p; - if (((selection->x1 > p->xMin && selection->y1 > p->yMin) || - (selection->x2 > p->xMin && selection->y2 > p->yMin)) && (begin != NULL)) { - end = p->next; - current = p; + if (blk->page->primaryLR) { + if ((selection->x1 < p->xMax && selection->y1 < p->yMax) || + (selection->x2 < p->xMax && selection->y2 < p->yMax)) + if (begin == NULL) + begin = p; + + if (((selection->x1 > p->xMin && selection->y1 > p->yMin) || + (selection->x2 > p->xMin && selection->y2 > p->yMin)) && (begin != NULL)) { + end = p->next; + current = p; + } + } else { + if ((selection->x1 > p->xMin && selection->y1 < p->yMax) || + (selection->x2 > p->xMin && selection->y2 < p->yMax)) + if (begin == NULL) + begin = p; + + if (((selection->x1 < p->xMax && selection->y1 > p->yMin) || + (selection->x2 < p->xMax && selection->y2 > p->yMin)) && (begin != NULL)) { + end = p->next; + current = p; + } } } diff --git a/poppler/TextOutputDev.h b/poppler/TextOutputDev.h index 12453c3..62e2d4c 100644 --- a/poppler/TextOutputDev.h +++ b/poppler/TextOutputDev.h @@ -374,6 +374,10 @@ private: double xMin, xMax; // bounding box x coordinates double yMin, yMax; // bounding box y coordinates double priMin, priMax; // whitespace bounding box along primary axis + double ExMin, ExMax; // extended bounding box x coordinates + double EyMin, EyMax; // extended bounding box y coordinates + int tableId; // id of table to which this block belongs + GBool tableEnd; // is this block at end of line of actual table TextPool *pool; // pool of words (used only until lines // are built) @@ -393,6 +397,7 @@ private: friend class TextWordList; friend class TextPage; friend class TextSelectionPainter; + friend class TextSelectionDumper; }; //------------------------------------------------------------------------ commit db014ffb357e760d9397544c5a8fe747cdb497ab Author: Brian Ewins Date: Mon Nov 23 08:58:19 2009 +0000 Select top right to bottom left in RTL mode This makes pure RTL selection work. Bidi is not handled at all. Rendering of the selection is poor and the dumped text appears to still be in reverse order to me. diff --git a/poppler/TextOutputDev.cc b/poppler/TextOutputDev.cc index 9ddf296..1dfe560 100644 --- a/poppler/TextOutputDev.cc +++ b/poppler/TextOutputDev.cc @@ -3932,13 +3932,24 @@ void TextBlock::visitSelection(TextSelectionVisitor *visitor, // the corners, so we have to force them to be // selected when the selection runs outside this // block. - all[i] = x[i] >= this->xMax && y[i] >= this->yMax; - if (x[i] <= this->xMin && y[i] <= this->yMin) { - best_line[i] = this->lines; - best_count[i] = 1; + if (page->primaryLR) { + all[i] = x[i] >= this->xMax && y[i] >= this->yMax; + if (x[i] <= this->xMin && y[i] <= this->yMin) { + best_line[i] = this->lines; + best_count[i] = 1; + } else { + best_line[i] = NULL; + best_count[i] = 0; + } } else { - best_line[i] = NULL; - best_count[i] = 0; + all[i] = x[i] <= this->xMin && y[i] >= this->yMax; + if (x[i] >= this->xMax && y[i] <= this->yMin) { + best_line[i] = this->lines; + best_count[i] = 1; + } else { + best_line[i] = NULL; + best_count[i] = 0; + } } best_d[i] = 0; } @@ -3979,9 +3990,14 @@ void TextBlock::visitSelection(TextSelectionVisitor *visitor, visitor->visitBlock(this, best_line[start], best_line[stop], selection); for (p = best_line[start]; p; p = p->next) { - child_selection.x1 = p->xMin; + if (page->primaryLR) { + child_selection.x1 = p->xMin; + child_selection.x2 = p->xMax; + } else { + child_selection.x1 = p->xMax; + child_selection.x2 = p->xMin; + } child_selection.y1 = p->yMin; - child_selection.x2 = p->xMax; child_selection.y2 = p->yMax; if (style == selectionStyleLine) { if (p == best_line[start]) { @@ -4072,10 +4088,18 @@ void TextPage::visitSelection(TextSelectionVisitor *visitor, } } for (i = 0; i < 2; i++) { - if (x[i] < xMin && y[i] < yMin) { - best_block[i] = flows->blocks; - best_flow[i] = flows; - best_count[i] = 1; + if (primaryLR) { + if (x[i] < xMin && y[i] < yMin) { + best_block[i] = flows->blocks; + best_flow[i] = flows; + best_count[i] = 1; + } + } else { + if (x[i] > xMax && y[i] < yMin) { + best_block[i] = flows->blocks; + best_flow[i] = flows; + best_count[i] = 1; + } } } // assert: best is always set. @@ -4100,9 +4124,14 @@ void TextPage::visitSelection(TextSelectionVisitor *visitor, blk = flow->blocks; } for (; blk; blk = blk->next) { - child_selection.x1 = blk->xMin; + if (primaryLR) { + child_selection.x1 = blk->xMin; + child_selection.x2 = blk->xMax; + } else { + child_selection.x1 = blk->xMax; + child_selection.x2 = blk->xMin; + } child_selection.y1 = blk->yMin; - child_selection.x2 = blk->xMax; child_selection.y2 = blk->yMax; if (blk == best_block[start]) { child_selection.x1 = fmax(blk->xMin, fmin(blk->xMax, x[start])); commit b1d43fa052d9160c4f319a67415ecf3ebf2cf9b3 Author: Brian Ewins Date: Sun Nov 22 09:47:40 2009 +0000 Make pdftotext newlines match copy and paste The output of pdftotext didn't insert line breaks, resulting in jumbled text. Change the rules to emit a newline at the end of each line unless a hyphenation is being supressed, and an extra newline at the end of each flow. diff --git a/poppler/TextOutputDev.cc b/poppler/TextOutputDev.cc index b8eca28..9ddf296 100644 --- a/poppler/TextOutputDev.cc +++ b/poppler/TextOutputDev.cc @@ -4400,24 +4400,13 @@ void TextPage::dump(void *outputStream, TextOutputFunc outputFunc, dumpFragment(line->text, n, uMap, s); (*outputFunc)(outputStream, s->getCString(), s->getLength()); delete s; - if (!line->hyphenated) { - if (line->next) { - (*outputFunc)(outputStream, space, spaceLen); - } else if (blk->next) { - //~ this is a bit of a kludge - we should really do a more - //~ intelligent determination of paragraphs - if (blk->next->lines->words->fontSize == - blk->lines->words->fontSize) { - (*outputFunc)(outputStream, space, spaceLen); - } else { - (*outputFunc)(outputStream, eol, eolLen); - } - } + // output a newline when a hyphen is not suppressed + if (n == line->len) { + (*outputFunc)(outputStream, eol, eolLen); } } } (*outputFunc)(outputStream, eol, eolLen); - (*outputFunc)(outputStream, eol, eolLen); } } commit f83b677a8eb44d65698b77edb13a5c7de3a72c0f Author: Brian Ewins Date: Thu Nov 12 02:50:29 2009 +0000 Use a reading-order sort to order blocks This switches the block sort from XY to reading order, using the rules from T. Breuel's "High Performance Document Layout Analysis". Signed-off-by: Brian Ewins diff --git a/poppler/TextOutputDev.cc b/poppler/TextOutputDev.cc index ee59c9c..b8eca28 100644 --- a/poppler/TextOutputDev.cc +++ b/poppler/TextOutputDev.cc @@ -1615,6 +1615,144 @@ GBool TextBlock::isBelow(TextBlock *blk) { return below; } +GBool TextBlock::isBeforeByRule1(TextBlock *blk1) { + GBool before = gFalse; + GBool overlap = gFalse; + + switch (this->page->primaryRot) { + case 0: + case 2: + overlap = ((this->xMin <= blk1->xMin) && + (blk1->xMin <= this->xMax)) || + ((blk1->xMin <= this->xMin) && + (this->xMin <= blk1->xMax)); + break; + case 1: + case 3: + overlap = ((this->yMin <= blk1->yMin) && + (blk1->yMin <= this->yMax)) || + ((blk1->yMin <= this->yMin) && + (this->yMin <= blk1->yMax)); + break; + } + switch (this->page->primaryRot) { + case 0: + before = overlap && this->yMin < blk1->yMin; + break; + case 1: + before = overlap && this->xMax > blk1->xMax; + break; + case 2: + before = overlap && this->yMax > blk1->yMax; + break; + case 3: + before = overlap && this->xMin < blk1->xMin; + break; + } + return before; +} + +GBool TextBlock::isBeforeByRule2(TextBlock *blk1) { + double cmp = 0; + int rotLR = rot; + + if (!page->primaryLR) { + rotLR = (rotLR + 2) % 4; + } + + switch (rotLR) { + case 0: + cmp = xMax - blk1->xMin; + break; + case 1: + cmp = yMin - blk1->yMax; + break; + case 2: + cmp = blk1->xMax - xMin; + break; + case 3: + cmp = blk1->yMin - yMax; + break; + } + return cmp <= 0; +} + +// Sort into reading order by performing a topological sort using the rules +// given in "High Performance Document Layout Analysis", T.M. Breuel, 2003. +// See http://pubs.iupr.org/#2003-breuel-sdiut +// Topological sort is done by depth first search, see +// http://en.wikipedia.org/wiki/Topological_sorting +int TextBlock::visitDepthFirst(TextBlock *blkList, int pos1, + TextBlock **sorted, int sortPos, + GBool* visited) { + int pos2; + TextBlock *blk1, *blk2, *blk3; + GBool before; + + if (visited[pos1]) { + return sortPos; + } + + blk1 = this; + +#if 0 // for debugging + printf("visited: %d %.2f..%.2f %.2f..%.2f\n", + sortPos, blk1->xMin, blk1->xMax, blk1->yMin, blk1->yMax); +#endif + visited[pos1] = gTrue; + pos2 = -1; + for (blk2 = blkList; blk2; blk2 = blk2->next) { + pos2++; + if (visited[pos2]) { + // skip visited nodes + continue; + } + before = gFalse; + if (blk2->isBeforeByRule1(blk1)) { + // Rule (1) blk1 and blk2 overlap, and blk2 is above blk1. + before = gTrue; +#if 0 // for debugging + printf("rule1: %.2f..%.2f %.2f..%.2f %.2f..%.2f %.2f..%.2f\n", + blk2->xMin, blk2->xMax, blk2->yMin, blk2->yMax, + blk1->xMin, blk1->xMax, blk1->yMin, blk1->yMax); +#endif + } else if (blk2->isBeforeByRule2(blk1)) { + // Rule (2) blk2 left of blk1, and no intervening blk3 + // such that blk1 is before blk3 by rule 1, + // and blk3 is before blk2 by rule 1. + before = gTrue; + for (blk3 = blkList; blk3; blk3 = blk3->next) { + if (blk3 == blk2 || blk3 == blk1) { + continue; + } + if (blk1->isBeforeByRule1(blk3) && + blk3->isBeforeByRule1(blk2)) { + before = gFalse; + break; + } + } +#if 0 // for debugging + if (before) { + printf("rule2: %.2f..%.2f %.2f..%.2f %.2f..%.2f %.2f..%.2f\n", + blk1->xMin, blk1->xMax, blk1->yMin, blk1->yMax, + blk2->xMin, blk2->xMax, blk2->yMin, blk2->yMax); + } +#endif + } + if (before) { + // blk2 is before blk1, so it needs to be visited + // before we can add blk1 to the sorted list. + sortPos = blk2->visitDepthFirst(blkList, pos2, sorted, sortPos, visited); + } + } +#if 0 // for debugging + printf("sorted: %d %.2f..%.2f %.2f..%.2f\n", + sortPos, blk1->xMin, blk1->xMax, blk1->yMin, blk1->yMax); +#endif + sorted[sortPos++] = blk1; + return sortPos; +} + //------------------------------------------------------------------------ // TextFlow //------------------------------------------------------------------------ @@ -2685,7 +2823,7 @@ void TextPage::coalesce(GBool physLayout, GBool doHTML) { } } -#if 0 // for debugging +#if 0 // for debugging printf("*** rotation ***\n"); for (rot = 0; rot < 4; ++rot) { printf(" %d: %6d\n", rot, count[rot]); @@ -2839,9 +2977,6 @@ void TextPage::coalesce(GBool physLayout, GBool doHTML) { //----- reading order sort - // sort blocks into xy order (in preparation for reading order sort) - qsort(blocks, nBlocks, sizeof(TextBlock *), &TextBlock::cmpXYPrimaryRot); - // compute space on left and right sides of each block for (i = 0; i < nBlocks; ++i) { blk0 = blocks[i]; @@ -2854,7 +2989,25 @@ void TextPage::coalesce(GBool physLayout, GBool doHTML) { } #if 0 // for debugging - printf("*** blocks, after yx sort ***\n"); + printf("PAGE\n"); +#endif + + int sortPos = 0; + GBool *visited = (GBool *)gmallocn(nBlocks, sizeof(GBool)); + for (i = 0; i < nBlocks; i++) { + visited[i] = gFalse; + } + i = -1; + for (blk1 = blkList; blk1; blk1 = blk1->next) { + i++; + sortPos = blk1->visitDepthFirst(blkList, i, blocks, sortPos, visited); + } + if (visited) { + gfree(visited); + } + +#if 0 // for debugging + printf("*** blocks, after ro sort ***\n"); for (i = 0; i < nBlocks; ++i) { blk = blocks[i]; printf("block: rot=%d x=%.2f..%.2f y=%.2f..%.2f space=%.2f..%.2f\n", @@ -2874,6 +3027,7 @@ void TextPage::coalesce(GBool physLayout, GBool doHTML) { } } printf("\n"); + fflush(stdout); #endif // build the flows diff --git a/poppler/TextOutputDev.h b/poppler/TextOutputDev.h index d3ae2f9..12453c3 100644 --- a/poppler/TextOutputDev.h +++ b/poppler/TextOutputDev.h @@ -361,6 +361,14 @@ public: private: + GBool isBeforeByRule1(TextBlock *blk1); + GBool isBeforeByRepeatedRule1(TextBlock *blkList, TextBlock *blk1); + GBool isBeforeByRule2(TextBlock *blk1); + + int visitDepthFirst(TextBlock *blkList, int pos1, + TextBlock **sorted, int sortPos, + GBool* visited); + TextPage *page; // the parent page int rot; // text rotation double xMin, xMax; // bounding box x coordinates commit a2191a4d45e0abaec97c19aacae37c4c5824bd36 Author: Brian Ewins Date: Mon Nov 9 06:24:51 2009 +0000 Separate flow construction from reading order If the blocks were already in reading order, then constructing flows is simplified, since blocks cannot be picked out-of-order. Make this change first in preparation for adding a reading-order sort. Signed-off-by: Brian Ewins diff --git a/poppler/TextOutputDev.cc b/poppler/TextOutputDev.cc index 92a1ff4..ee59c9c 100644 --- a/poppler/TextOutputDev.cc +++ b/poppler/TextOutputDev.cc @@ -2183,8 +2183,7 @@ void TextPage::coalesce(GBool physLayout, GBool doHTML) { TextPool *pool; TextWord *word0, *word1, *word2; TextLine *line; - TextBlock *blkList, *blkStack, *blk, *lastBlk, *blk0, *blk1; - TextBlock **blkArray; + TextBlock *blkList, *blk, *lastBlk, *blk0, *blk1; TextFlow *flow, *lastFlow; TextUnderline *underline; TextLink *link; @@ -2194,7 +2193,6 @@ void TextPage::coalesce(GBool physLayout, GBool doHTML) { GBool found; int count[4]; int lrCount; - int firstBlkIdx, nBlocksLeft; int col1, col2; int i, j, n; @@ -2841,8 +2839,8 @@ void TextPage::coalesce(GBool physLayout, GBool doHTML) { //----- reading order sort - // sort blocks into yx order (in preparation for reading order sort) - qsort(blocks, nBlocks, sizeof(TextBlock *), &TextBlock::cmpYXPrimaryRot); + // sort blocks into xy order (in preparation for reading order sort) + qsort(blocks, nBlocks, sizeof(TextBlock *), &TextBlock::cmpXYPrimaryRot); // compute space on left and right sides of each block for (i = 0; i < nBlocks; ++i) { @@ -2881,39 +2879,28 @@ void TextPage::coalesce(GBool physLayout, GBool doHTML) { // build the flows //~ this needs to be adjusted for writing mode (vertical text) //~ this also needs to account for right-to-left column ordering - blkArray = (TextBlock **)gmallocn(nBlocks, sizeof(TextBlock *)); - memcpy(blkArray, blocks, nBlocks * sizeof(TextBlock *)); + flow = NULL; while (flows) { flow = flows; flows = flows->next; delete flow; } flows = lastFlow = NULL; - firstBlkIdx = 0; - nBlocksLeft = nBlocks; - while (nBlocksLeft > 0) { - - // find the upper-left-most block - for (; !blkArray[firstBlkIdx]; ++firstBlkIdx) ; - i = firstBlkIdx; - blk = blkArray[i]; - for (j = firstBlkIdx + 1; j < nBlocks; ++j) { - blk1 = blkArray[j]; - if (blk1) { - if (blk && blk->secondaryDelta(blk1) > 0) { - break; - } - if (blk1->primaryCmp(blk) < 0) { - i = j; - blk = blk1; - } + // assume blocks are already in reading order, + // and construct flows accordingly. + for (i = 0; i < nBlocks; i++) { + blk = blocks[i]; + blk->next = NULL; + if (flow) { + blk1 = blocks[i - 1]; + blkSpace = maxBlockSpacing * blk1->lines->words->fontSize; + if (blk1->secondaryDelta(blk) <= blkSpace && + blk->isBelow(blk1) && + flow->blockFits(blk, blk1)) { + flow->addBlock(blk); + continue; } } - blkArray[i] = NULL; - --nBlocksLeft; - blk->next = NULL; - - // create a new flow, starting with the upper-left-most block flow = new TextFlow(this, blk); if (lastFlow) { lastFlow->next = flow; @@ -2921,56 +2908,7 @@ void TextPage::coalesce(GBool physLayout, GBool doHTML) { flows = flow; } lastFlow = flow; - fontSize = blk->lines->words->fontSize; - - // push the upper-left-most block on the stack - blk->stackNext = NULL; - blkStack = blk; - - // find the other blocks in this flow - while (blkStack) { - - // find the upper-left-most block under (but within - // maxBlockSpacing of) the top block on the stack - blkSpace = maxBlockSpacing * blkStack->lines->words->fontSize; - blk = NULL; - i = -1; - for (j = firstBlkIdx; j < nBlocks; ++j) { - blk1 = blkArray[j]; - if (blk1) { - if (blkStack->secondaryDelta(blk1) > blkSpace) { - break; - } - if (blk && blk->secondaryDelta(blk1) > 0) { - break; - } - if (blk1->isBelow(blkStack) && - (!blk || blk1->primaryCmp(blk) < 0)) { - i = j; - blk = blk1; - } - } - } - - // if a suitable block was found, add it to the flow and push it - // onto the stack - if (blk && flow->blockFits(blk, blkStack)) { - blkArray[i] = NULL; - --nBlocksLeft; - blk->next = NULL; - flow->addBlock(blk); - fontSize = blk->lines->words->fontSize; - blk->stackNext = blkStack; - blkStack = blk; - - // otherwise (if there is no block under the top block or the - // block is not suitable), pop the stack - } else { - blkStack = blkStack->stackNext; - } - } } - gfree(blkArray); #if 0 // for debugging printf("*** flows ***\n"); commit 345ed51af9b9e7ea53af42727b91ed68dcc52370 Author: Brian Ewins Date: Thu Oct 29 01:46:29 2009 +0000 Fix bug 3188, text selection across table cells Bug 3188. When selecting text, poppler goes across the whole page then down, rather than across each cell, down that cell, then across to the next cell. This leads to illegible paste results. Teach TextPage to visit the selection in flow order rather than block order. Signed-off-by: Brian Ewins diff --git a/poppler/TextOutputDev.cc b/poppler/TextOutputDev.cc index 5b6f39b..92a1ff4 100644 --- a/poppler/TextOutputDev.cc +++ b/poppler/TextOutputDev.cc @@ -3521,10 +3521,9 @@ void TextSelectionDumper::visitLine (TextLine *line, GooString *TextSelectionDumper::getText (void) { - GBool oneRot = gTrue; GooString *s; TextLineFrag *frag; - int i, col; + int i; GBool multiLine; UnicodeMap *uMap; char space[8], eol[16]; @@ -3541,45 +3540,11 @@ GooString *TextSelectionDumper::getText (void) eolLen = uMap->mapUnicode(0x0a, eol, sizeof(eol)); if (nFrags > 0) { - for (i = 0; i < nFrags; ++i) { - frags[i].computeCoords(oneRot); - } - page->assignColumns(frags, nFrags, oneRot); - - // if all lines in the region have the same rotation, use it; - // otherwise, use the page's primary rotation - if (oneRot) { - qsort(frags, nFrags, sizeof(TextLineFrag), - &TextLineFrag::cmpYXLineRot); - } else { - qsort(frags, nFrags, sizeof(TextLineFrag), - &TextLineFrag::cmpYXPrimaryRot); - } - - col = 0; multiLine = gFalse; for (i = 0; i < nFrags; ++i) { frag = &frags[i]; - // insert a return - if (frag->col < col || - (i > 0 && fabs(frag->base - frags[i-1].base) > - maxIntraLineDelta * frags[i-1].line->words->fontSize)) { - s->append(eol, eolLen); - col = 0; - multiLine = gTrue; - } - - // column alignment - for (; col < frag->col; ++col) { - s->append(space, spaceLen); - } - - // get the fragment text - col += page->dumpFragment(frag->line->text + frag->start, frag->len, uMap, s); - } - - if (multiLine) { + page->dumpFragment(frag->line->text + frag->start, frag->len, uMap, s); s->append(eol, eolLen); } } @@ -3859,75 +3824,96 @@ void TextLine::visitSelection(TextSelectionVisitor *visitor, void TextBlock::visitSelection(TextSelectionVisitor *visitor, PDFRectangle *selection, SelectionStyle style) { - TextLine *p, *begin, *end; PDFRectangle child_selection; - double start_x, start_y, stop_x, stop_y; - - begin = NULL; - end = NULL; - start_x = selection->x1; - start_y = selection->y1; - stop_x = selection->x2; - stop_y = selection->y2; - - for (p = lines; p != NULL; p = p->next) { - if (selection->x1 < p->xMax && selection->y1 < p->yMax && - selection->x2 < p->xMax && selection->y2 < p->yMax && begin == NULL) { - begin = p; - if (selection->x1 < selection->x2) { - start_x = selection->x1; - start_y = selection->y1; - stop_x = selection->x2; - stop_y = selection->y2; - } else { - start_x = selection->x2; - start_y = selection->y2; - stop_x = selection->x1; - stop_y = selection->y1; + double x[2], y[2], d, best_d[2]; + TextLine *p, *best_line[2]; + int i, count = 0, best_count[2], start, stop; + GBool all[2]; + + x[0] = selection->x1; + y[0] = selection->y1; + x[1] = selection->x2; + y[1] = selection->y2; + + for (i = 0; i < 2; i++) { + // the first/last lines are often not nearest + // the corners, so we have to force them to be + // selected when the selection runs outside this + // block. + all[i] = x[i] >= this->xMax && y[i] >= this->yMax; + if (x[i] <= this->xMin && y[i] <= this->yMin) { + best_line[i] = this->lines; + best_count[i] = 1; + } else { + best_line[i] = NULL; + best_count[i] = 0; + } + best_d[i] = 0; + } + + // find the nearest line to the selection points + // using the manhattan distance. + for (p = this->lines; p; p = p->next) { + count++; + for (i = 0; i < 2; i++) { + d = fmax(p->xMin - x[i], 0.0) + + fmax(x[i] - p->xMax, 0.0) + + fmax(p->yMin - y[i], 0.0) + + fmax(y[i] - p->yMax, 0.0); + if (!best_line[i] || all[i] || + d < best_d[i]) { + best_line[i] = p; + best_count[i] = count; + best_d[i] = d; } - } else if (selection->x1 < p->xMax && selection->y1 < p->yMax && begin == NULL) { - begin = p; - start_x = selection->x1; - start_y = selection->y1; - stop_x = selection->x2; - stop_y = selection->y2; - } else if (selection->x2 < p->xMax && selection->y2 < p->yMax && begin == NULL) { - begin = p; - start_x = selection->x2; - start_y = selection->y2; - stop_x = selection->x1; - stop_y = selection->y1; } - - if (((selection->x1 > p->xMin && selection->y1 > p->yMin) || - (selection->x2 > p->xMin && selection->y2 > p->yMin)) - && (begin != NULL)) - end = p->next; } - - /* Skip empty selection. */ - if (end == begin) + // assert: best is always set. + if (!best_line[0] || !best_line[1]) { return; + } - visitor->visitBlock (this, begin, end, selection); + // Now decide which point was first. + if (best_count[0] < best_count[1] || + (best_count[0] == best_count[1] && + y[0] < y[1])) { + start = 0; + stop = 1; + } else { + start = 1; + stop = 0; + } - for (p = begin; p != end; p = p->next) { - if (p == begin && style != selectionStyleLine) { - child_selection.x1 = start_x; - child_selection.y1 = start_y; - } else { - child_selection.x1 = 0; - child_selection.y1 = 0; - } - if (p->next == end && style != selectionStyleLine) { - child_selection.x2 = stop_x; - child_selection.y2 = stop_y; + visitor->visitBlock(this, best_line[start], best_line[stop], selection); + + for (p = best_line[start]; p; p = p->next) { + child_selection.x1 = p->xMin; + child_selection.y1 = p->yMin; + child_selection.x2 = p->xMax; + child_selection.y2 = p->yMax; + if (style == selectionStyleLine) { + if (p == best_line[start]) { + child_selection.x1 = 0; + child_selection.y1 = 0; + } + if (p == best_line[stop]) { + child_selection.x2 = page->pageWidth; + child_selection.y2 = page->pageHeight; + } } else { - child_selection.x2 = page->pageWidth; - child_selection.y2 = page->pageHeight; + if (p == best_line[start]) { + child_selection.x1 = fmax(p->xMin, fmin(p->xMax, x[start])); + child_selection.y1 = fmax(p->yMin, fmin(p->yMax, y[start])); + } + if (p == best_line[stop]) { + child_selection.x2 = fmax(p->xMin, fmin(p->xMax, x[stop])); + child_selection.y2 = fmax(p->yMin, fmin(p->yMax, y[stop])); + } } - p->visitSelection(visitor, &child_selection, style); + if (p == best_line[stop]) { + return; + } } } @@ -3935,73 +3921,109 @@ void TextPage::visitSelection(TextSelectionVisitor *visitor, PDFRectangle *selection, SelectionStyle style) { - int i, begin, end; PDFRectangle child_selection; - double start_x, start_y, stop_x, stop_y; - TextBlock *b; + double x[2], y[2], d, best_d[2]; + double xMin, yMin, xMax, yMax; + TextFlow *flow, *best_flow[2]; + TextBlock *blk, *best_block[2]; + int i, count = 0, best_count[2], start, stop; - begin = nBlocks; - end = 0; - start_x = selection->x1; - start_y = selection->y1; - stop_x = selection->x2; - stop_y = selection->y2; - - for (i = 0; i < nBlocks; i++) { - b = blocks[i]; - - if (selection->x1 < b->xMax && selection->y1 < b->yMax && - selection->x2 < b->xMax && selection->y2 < b->yMax && i < begin) { - begin = i; - if (selection->y1 < selection->y2) { - start_x = selection->x1; - start_y = selection->y1; - stop_x = selection->x2; - stop_y = selection->y2; - } else { - start_x = selection->x2; - start_y = selection->y2; - stop_x = selection->x1; - stop_y = selection->y1; - } - } else if (selection->x1 < b->xMax && selection->y1 < b->yMax && i < begin) { - begin = i; - start_x = selection->x1; - start_y = selection->y1; - stop_x = selection->x2; - stop_y = selection->y2; - } else if (selection->x2 < b->xMax && selection->y2 < b->yMax && i < begin) { - begin = i; - start_x = selection->x2; - start_y = selection->y2; - stop_x = selection->x1; - stop_y = selection->y1; - } - - if ((selection->x1 > b->xMin && selection->y1 > b->yMin) || - (selection->x2 > b->xMin && selection->y2 > b->yMin)) - end = i + 1; + if (!flows) + return; + + x[0] = selection->x1; + y[0] = selection->y1; + x[1] = selection->x2; + y[1] = selection->y2; + + xMin = pageWidth; + yMin = pageHeight; + xMax = 0.0; + yMax = 0.0; + + for (i = 0; i < 2; i++) { + best_block[i] = NULL; + best_flow[i] = NULL; + best_count[i] = 0; + best_d[i] = 0; } - for (i = begin; i < end; i++) { - if (blocks[i]->xMin < start_x && start_x < blocks[i]->xMax && - blocks[i]->yMin < start_y && start_y < blocks[i]->yMax) { - child_selection.x1 = start_x; - child_selection.y1 = start_y; - } else { - child_selection.x1 = 0; - child_selection.y1 = 0; + // find the nearest blocks to the selection points + // using the manhattan distance. + for (flow = flows; flow; flow = flow->next) { + for (blk = flow->blocks; blk; blk = blk->next) { + count++; + // the first/last blocks in reading order are + // often not the closest to the page corners; + // track the corners, force those blocks to + // be selected if the selection runs across + // multiple pages. + xMin = fmin(xMin, blk->xMin); + yMin = fmin(yMin, blk->yMin); + xMax = fmax(xMax, blk->xMax); + yMax = fmax(yMax, blk->yMax); + for (i = 0; i < 2; i++) { + d = fmax(blk->xMin - x[i], 0.0) + + fmax(x[i] - blk->xMax, 0.0) + + fmax(blk->yMin - y[i], 0.0) + + fmax(y[i] - blk->yMax, 0.0); + if (!best_block[i] || + d < best_d[i] || + (!blk->next && !flow->next && + x[i] > xMax && y[i] > yMax)) { + best_block[i] = blk; + best_flow[i] = flow; + best_count[i] = count; + best_d[i] = d; + } + } } - if (blocks[i]->xMin < stop_x && stop_x < blocks[i]->xMax && - blocks[i]->yMin < stop_y && stop_y < blocks[i]->yMax) { - child_selection.x2 = stop_x; - child_selection.y2 = stop_y; - } else { - child_selection.x2 = pageWidth; - child_selection.y2 = pageHeight; + } + for (i = 0; i < 2; i++) { + if (x[i] < xMin && y[i] < yMin) { + best_block[i] = flows->blocks; + best_flow[i] = flows; + best_count[i] = 1; } + } + // assert: best is always set. + if (!best_block[0] || !best_block[1]) { + return; + } + + // Now decide which point was first. + if (best_count[0] < best_count[1] || + (best_count[0] == best_count[1] && y[0] < y[1])) { + start = 0; + stop = 1; + } else { + start = 1; + stop = 0; + } - blocks[i]->visitSelection(visitor, &child_selection, style); + for (flow = best_flow[start]; flow; flow = flow->next) { + if (flow == best_flow[start]) { + blk = best_block[start]; + } else { + blk = flow->blocks; + } + for (; blk; blk = blk->next) { + child_selection.x1 = blk->xMin; + child_selection.y1 = blk->yMin; + child_selection.x2 = blk->xMax; + child_selection.y2 = blk->yMax; + if (blk == best_block[start]) { + child_selection.x1 = fmax(blk->xMin, fmin(blk->xMax, x[start])); + child_selection.y1 = fmax(blk->yMin, fmin(blk->yMax, y[start])); + } + if (blk == best_block[stop]) { + child_selection.x2 = fmax(blk->xMin, fmin(blk->xMax, x[stop])); + child_selection.y2 = fmax(blk->yMin, fmin(blk->yMax, y[stop])); + blk->visitSelection(visitor, &child_selection, style); + return; + } + blk->visitSelection(visitor, &child_selection, style); + } } } From carlosgc at kemper.freedesktop.org Wed Apr 21 03:43:32 2010 From: carlosgc at kemper.freedesktop.org (Carlos Garcia Campos) Date: Wed, 21 Apr 2010 03:43:32 -0700 (PDT) Subject: [poppler] poppler/CairoOutputDev.cc Message-ID: <20100421104332.38BDDF8153@kemper.freedesktop.org> poppler/CairoOutputDev.cc | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) New commits: commit 4f71d64c69500ed78daf4d797c8af6cfbd3d970e Author: Carlos Garcia Campos Date: Wed Apr 21 11:44:49 2010 +0200 [cairo] Fix pattern size when bbox is not at 0,0 diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc index 845bf9d..768fbba 100644 --- a/poppler/CairoOutputDev.cc +++ b/poppler/CairoOutputDev.cc @@ -716,14 +716,18 @@ GBool CairoOutputDev::tilingPatternFill(GfxState *state, Object *str, cairo_matrix_t matrix; cairo_t *old_cairo; double xMin, yMin, xMax, yMax; + double width, height; - if (xStep != bbox[2] || yStep != bbox[3]) + width = bbox[2] - bbox[0]; + height = bbox[3] - bbox[1]; + + if (xStep != width || yStep != height) return gFalse; /* TODO: implement the other cases here too */ surface = cairo_surface_create_similar (cairo_get_target (cairo), CAIRO_CONTENT_COLOR_ALPHA, - bbox[2], bbox[3]); + width, height); if (cairo_surface_status (surface)) return gFalse; @@ -746,6 +750,9 @@ GBool CairoOutputDev::tilingPatternFill(GfxState *state, Object *str, state->getUserClipBBox(&xMin, &yMin, &xMax, &yMax); cairo_rectangle (cairo, xMin, yMin, xMax - xMin, yMax - yMin); + cairo_matrix_init_scale (&matrix, (int)width / width, (int)height / height); + cairo_pattern_set_matrix (pattern, &matrix); + cairo_matrix_init (&matrix, mat[0], mat[1], mat[2], mat[3], mat[4], mat[5]); cairo_transform (cairo, &matrix); cairo_set_source (cairo, pattern); From carlosgc at kemper.freedesktop.org Wed Apr 21 10:58:04 2010 From: carlosgc at kemper.freedesktop.org (Carlos Garcia Campos) Date: Wed, 21 Apr 2010 10:58:04 -0700 (PDT) Subject: [poppler] poppler/CairoOutputDev.cc Message-ID: <20100421175804.7806FF811A@kemper.freedesktop.org> poppler/CairoOutputDev.cc | 1 + 1 file changed, 1 insertion(+) New commits: commit 6b14c18d60cae130869f9a5c7688dfe880602224 Author: Carlos Garcia Campos Date: Wed Apr 21 19:56:49 2010 +0200 [cairo] Make sure we always use a new path in doPath() Fixes document http://acroeng.adobe.com/Test_Files/images/transparency/Untitled-2.pdf when rendering with cairo backend. diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc index 768fbba..0ae0885 100644 --- a/poppler/CairoOutputDev.cc +++ b/poppler/CairoOutputDev.cc @@ -618,6 +618,7 @@ void CairoOutputDev::updateRender(GfxState *state) { void CairoOutputDev::doPath(cairo_t *cairo, GfxState *state, GfxPath *path) { GfxSubpath *subpath; int i, j; + cairo_new_path (cairo); for (i = 0; i < path->getNumSubpaths(); ++i) { subpath = path->getSubpath(i); if (subpath->getNumPoints() > 0) { From carlosgc at kemper.freedesktop.org Wed Apr 21 11:04:22 2010 From: carlosgc at kemper.freedesktop.org (Carlos Garcia Campos) Date: Wed, 21 Apr 2010 11:04:22 -0700 (PDT) Subject: [poppler] glib/demo Message-ID: <20100421180422.BA054F811A@kemper.freedesktop.org> glib/demo/images.c | 2 +- glib/demo/layers.c | 4 ++-- glib/demo/render.c | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) New commits: commit 6f9f3d33ff8058e28243ba45b8547e21ad0d088a Author: Andre Klapper Date: Wed Apr 21 19:57:15 2010 +0200 [glib-demo] Compile with -DGSEAL_ENABLE Fixes bug #27579. diff --git a/glib/demo/images.c b/glib/demo/images.c index b1fe8e2..6e987d2 100644 --- a/glib/demo/images.c +++ b/glib/demo/images.c @@ -76,7 +76,7 @@ pgd_image_view_drawing_area_expose (GtkWidget *area, cairo_image_surface_get_width (image), cairo_image_surface_get_height (image)); - cr = gdk_cairo_create (area->window); + cr = gdk_cairo_create (gtk_widget_get_window (area)); cairo_set_source_surface (cr, image, 0, 0); cairo_paint (cr); cairo_destroy (cr); diff --git a/glib/demo/layers.c b/glib/demo/layers.c index 348f9db..fc0ba35 100644 --- a/glib/demo/layers.c +++ b/glib/demo/layers.c @@ -193,9 +193,9 @@ pgd_layers_viewer_drawing_area_expose (GtkWidget *area, return FALSE; } - gdk_window_clear (area->window); + gdk_window_clear (gtk_widget_get_window (area)); - cr = gdk_cairo_create (area->window); + cr = gdk_cairo_create (gtk_widget_get_window (area)); cairo_set_source_surface (cr, demo->surface, 0, 0); cairo_paint (cr); cairo_destroy (cr); diff --git a/glib/demo/render.c b/glib/demo/render.c index 4365a4b..1fa4761 100644 --- a/glib/demo/render.c +++ b/glib/demo/render.c @@ -86,18 +86,18 @@ pgd_render_drawing_area_expose (GtkWidget *area, if (demo->mode == PGD_RENDER_PIXBUF && !demo->pixbuf) return FALSE; - gdk_window_clear (area->window); + gdk_window_clear (gtk_widget_get_window (area)); if (demo->mode == PGD_RENDER_CAIRO) { cairo_t *cr; - cr = gdk_cairo_create (area->window); + cr = gdk_cairo_create (gtk_widget_get_window (area)); cairo_set_source_surface (cr, demo->surface, 0, 0); cairo_paint (cr); cairo_destroy (cr); } else if (demo->mode == PGD_RENDER_PIXBUF) { - gdk_draw_pixbuf (area->window, - area->style->fg_gc[GTK_STATE_NORMAL], + gdk_draw_pixbuf (gtk_widget_get_window (area), + gtk_widget_get_style(area)->fg_gc[GTK_STATE_NORMAL], demo->pixbuf, 0, 0, 0, 0, From aacid at kemper.freedesktop.org Wed Apr 21 11:22:26 2010 From: aacid at kemper.freedesktop.org (Albert Astals Cid) Date: Wed, 21 Apr 2010 11:22:26 -0700 (PDT) Subject: [poppler] 2 commits - poppler/Gfx.cc poppler/Gfx.h poppler/SplashOutputDev.cc poppler/SplashOutputDev.h poppler/TextOutputDev.cc poppler/TextOutputDev.h Message-ID: <20100421182226.55674F811A@kemper.freedesktop.org> poppler/Gfx.cc | 137 +++++++++++++++++++++------------------------ poppler/Gfx.h | 4 - poppler/SplashOutputDev.cc | 41 ++++++++++++- poppler/SplashOutputDev.h | 3 poppler/TextOutputDev.cc | 1 poppler/TextOutputDev.h | 1 6 files changed, 108 insertions(+), 79 deletions(-) New commits: commit ccf238b32e236f69c0507a5421ac2649dfa8d865 Author: Thomas Freitag Date: Wed Apr 21 19:21:37 2010 +0100 Improve colorizing text and masks in pattern colorspace Bug #27482 diff --git a/poppler/Gfx.cc b/poppler/Gfx.cc index 85d657b..8a7dfee 100644 --- a/poppler/Gfx.cc +++ b/poppler/Gfx.cc @@ -1304,24 +1304,19 @@ void Gfx::opSetFillGray(Object args[], int numArgs) { doPatternFill(gTrue); } out->restoreState(state); - state->setFillPattern(NULL); - state->setFillColorSpace(new GfxDeviceGrayColorSpace()); - out->updateFillColorSpace(state); - color.c[0] = dblToCol(args[0].getNum()); - state->setFillColor(&color); - out->updateFillColor(state); + } + state->setFillPattern(NULL); + state->setFillColorSpace(new GfxDeviceGrayColorSpace()); + out->updateFillColorSpace(state); + color.c[0] = dblToCol(args[0].getNum()); + state->setFillColor(&color); + out->updateFillColor(state); + if (textHaveCSPattern) { out->beginTextObject(state); out->updateRender(state); out->updateTextMat(state); out->updateTextPos(state); textHaveCSPattern = gFalse; - } else { - state->setFillPattern(NULL); - state->setFillColorSpace(new GfxDeviceGrayColorSpace()); - out->updateFillColorSpace(state); - color.c[0] = dblToCol(args[0].getNum()); - state->setFillColor(&color); - out->updateFillColor(state); } } @@ -1341,19 +1336,27 @@ void Gfx::opSetFillCMYKColor(Object args[], int numArgs) { int i; if (textHaveCSPattern) { - colorSpaceText = new GfxDeviceCMYKColorSpace(); - for (i = 0; i < 4; ++i) { - colorText.c[i] = dblToCol(args[i].getNum()); - } - } else { - state->setFillPattern(NULL); - state->setFillColorSpace(new GfxDeviceCMYKColorSpace()); - out->updateFillColorSpace(state); - for (i = 0; i < 4; ++i) { - color.c[i] = dblToCol(args[i].getNum()); + GBool needFill = out->deviceHasTextClip(state); + out->endTextObject(state); + if (needFill) { + doPatternFill(gTrue); } - state->setFillColor(&color); - out->updateFillColor(state); + out->restoreState(state); + } + state->setFillPattern(NULL); + state->setFillColorSpace(new GfxDeviceCMYKColorSpace()); + out->updateFillColorSpace(state); + for (i = 0; i < 4; ++i) { + color.c[i] = dblToCol(args[i].getNum()); + } + state->setFillColor(&color); + out->updateFillColor(state); + if (textHaveCSPattern) { + out->beginTextObject(state); + out->updateRender(state); + out->updateTextMat(state); + out->updateTextPos(state); + textHaveCSPattern = gFalse; } } @@ -1376,19 +1379,27 @@ void Gfx::opSetFillRGBColor(Object args[], int numArgs) { int i; if (textHaveCSPattern) { - colorSpaceText = new GfxDeviceRGBColorSpace(); - for (i = 0; i < 3; ++i) { - colorText.c[i] = dblToCol(args[i].getNum()); - } - } else { - state->setFillPattern(NULL); - state->setFillColorSpace(new GfxDeviceRGBColorSpace()); - out->updateFillColorSpace(state); - for (i = 0; i < 3; ++i) { - color.c[i] = dblToCol(args[i].getNum()); + GBool needFill = out->deviceHasTextClip(state); + out->endTextObject(state); + if (needFill) { + doPatternFill(gTrue); } - state->setFillColor(&color); - out->updateFillColor(state); + out->restoreState(state); + } + state->setFillPattern(NULL); + state->setFillColorSpace(new GfxDeviceRGBColorSpace()); + out->updateFillColorSpace(state); + for (i = 0; i < 3; ++i) { + color.c[i] = dblToCol(args[i].getNum()); + } + state->setFillColor(&color); + out->updateFillColor(state); + if (textHaveCSPattern) { + out->beginTextObject(state); + out->updateRender(state); + out->updateTextMat(state); + out->updateTextPos(state); + textHaveCSPattern = gFalse; } } @@ -1411,7 +1422,6 @@ void Gfx::opSetFillColorSpace(Object args[], int numArgs) { GfxColorSpace *colorSpace; GfxColor color; - state->setFillPattern(NULL); res->lookupColorSpace(args[0].getName(), &obj); if (obj.isNull()) { colorSpace = GfxColorSpace::parse(&args[0], this); @@ -1420,35 +1430,29 @@ void Gfx::opSetFillColorSpace(Object args[], int numArgs) { } obj.free(); if (colorSpace) { + if (textHaveCSPattern) { + GBool needFill = out->deviceHasTextClip(state); + out->endTextObject(state); + if (needFill) { + doPatternFill(gTrue); + } + out->restoreState(state); + } + state->setFillPattern(NULL); state->setFillColorSpace(colorSpace); out->updateFillColorSpace(state); colorSpace->getDefaultColor(&color); state->setFillColor(&color); out->updateFillColor(state); - if (drawText) { - if (colorSpace->getMode() == csPattern) { - if (out->supportTextCSPattern(state) && textHaveCSPattern) { - GBool needFill = out->deviceHasTextClip(state); - out->endTextObject(state); - if (needFill) - doPatternFill(gTrue); - out->restoreState(state); - } - colorSpaceText = NULL; - textHaveCSPattern = gTrue; - out->beginTextObject(state); - } else if (textHaveCSPattern) { - GBool needFill = out->deviceHasTextClip(state); - out->endTextObject(state); - if (needFill) { - doPatternFill(gTrue); - } - out->beginTextObject(state); - out->updateRender(state); - out->updateTextMat(state); - out->updateTextPos(state); - textHaveCSPattern = gFalse; - } + if (textHaveCSPattern) { + out->beginTextObject(state); + out->updateRender(state); + out->updateTextMat(state); + out->updateTextPos(state); + textHaveCSPattern = colorSpace->getMode() == csPattern; + } else if (drawText && out->supportTextCSPattern(state)) { + out->beginTextObject(state); + textHaveCSPattern = gTrue; } } else { error(getPos(), "Bad color space (fill)"); @@ -3329,7 +3333,6 @@ void Gfx::opBeginText(Object args[], int numArgs) { out->updateTextPos(state); fontChanged = gTrue; if (out->supportTextCSPattern(state)) { - colorSpaceText = NULL; textHaveCSPattern = gTrue; } } @@ -3343,14 +3346,6 @@ void Gfx::opEndText(Object args[], int numArgs) { doPatternFill(gTrue); } out->restoreState(state); - if (colorSpaceText != NULL) { - state->setFillPattern(NULL); - state->setFillColorSpace(colorSpaceText); - out->updateFillColorSpace(state); - state->setFillColor(&colorText); - out->updateFillColor(state); - colorSpaceText = NULL; - } } textHaveCSPattern = gFalse; } diff --git a/poppler/Gfx.h b/poppler/Gfx.h index 3e12509..f1a8964 100644 --- a/poppler/Gfx.h +++ b/poppler/Gfx.h @@ -18,7 +18,7 @@ // Copyright (C) 2008 Brad Hards // Copyright (C) 2008, 2010 Carlos Garcia Campos // Copyright (C) 2009 Albert Astals Cid -// Copyright (C) 2009 Thomas Freitag +// Copyright (C) 2009, 2010 Thomas Freitag // Copyright (C) 2010 David Benjamin // // To see a description of the changes please see the Changelog file that @@ -196,8 +196,6 @@ private: GBool drawText; // in text drawing GBool maskHaveCSPattern; // in mask drawing and mask has pattern colorspace GBool commandAborted; // did the previous command abort the drawing? - GfxColorSpace *colorSpaceText;// colorspace after text has filled with pattern - GfxColor colorText; // fill color after after text has filled with pattern GfxResources *res; // resource stack int updateLevel; diff --git a/poppler/SplashOutputDev.cc b/poppler/SplashOutputDev.cc index bb5cb7f..00aae92 100644 --- a/poppler/SplashOutputDev.cc +++ b/poppler/SplashOutputDev.cc @@ -1974,7 +1974,20 @@ GBool SplashOutputDev::imageMaskSrc(void *data, SplashColorPtr line) { } void SplashOutputDev::endMaskClip(GfxState * state) { - splash->setSoftMask(NULL); + double bbox[4] = {0,0,1,1}; // dummy + /* transfer mask to alpha channel! */ + // memcpy(maskBitmap->getAlphaPtr(), maskBitmap->getDataPtr(), bitmap->getRowSize() * bitmap->getHeight()); + // memset(maskBitmap->getDataPtr(), 0, bitmap->getRowSize() * bitmap->getHeight()); + int c; + Guchar *dest = bitmap->getAlphaPtr(); + Guchar *src = maskBitmap->getDataPtr(); + for (c= 0; c < maskBitmap->getRowSize() * maskBitmap->getHeight(); c++) { + dest[c] = src[c]; + } + delete maskBitmap; + maskBitmap = NULL; + endTransparencyGroup(state); + paintTransparencyGroup(state, bbox); } void SplashOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, @@ -2007,10 +2020,31 @@ void SplashOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, imgMaskData.y = 0; if (state->getFillColorSpace()->getMode() == csPattern) { - SplashBitmap *maskBitmap; Splash *maskSplash; SplashColor maskColor; - + + /* from beginTransparencyGroup: */ + // push a new stack entry + SplashTransparencyGroup *transpGroup = new SplashTransparencyGroup(); + transpGroup->tx = 0; + transpGroup->ty = 0; + transpGroup->blendingColorSpace = NULL; + transpGroup->isolated = gFalse; + transpGroup->next = transpGroupStack; + transpGroupStack = transpGroup; + // save state + transpGroup->origBitmap = bitmap; + transpGroup->origSplash = splash; + //~ this ignores the blendingColorSpace arg + // create the temporary bitmap + bitmap = new SplashBitmap(bitmap->getWidth(), bitmap->getHeight(), bitmapRowPad, colorMode, gTrue, + bitmapTopDown); + splash = new Splash(bitmap, vectorAntialias, + transpGroup->origSplash->getScreen()); + splash->blitTransparent(transpGroup->origBitmap, 0, 0, 0, 0, bitmap->getWidth(), bitmap->getHeight()); + splash->setInNonIsolatedGroup(transpGroup->origBitmap, 0, 0); + transpGroup->tBitmap = bitmap; + maskBitmap = new SplashBitmap(bitmap->getWidth(), bitmap->getHeight(), 1, splashModeMono8, gFalse); maskSplash = new Splash(maskBitmap, vectorAntialias); maskColor[0] = 0; @@ -2019,7 +2053,6 @@ void SplashOutputDev::drawImageMask(GfxState *state, Object *ref, Stream *str, maskSplash->setFillPattern(new SplashSolidColor(maskColor)); maskSplash->fillImageMask(&imageMaskSrc, &imgMaskData, width, height, mat, t3GlyphStack != NULL); delete maskSplash; - splash->setSoftMask(maskBitmap); } else { splash->fillImageMask(&imageMaskSrc, &imgMaskData, width, height, mat, t3GlyphStack != NULL); if (inlineImg) { diff --git a/poppler/SplashOutputDev.h b/poppler/SplashOutputDev.h index df33850..37b771a 100644 --- a/poppler/SplashOutputDev.h +++ b/poppler/SplashOutputDev.h @@ -14,7 +14,7 @@ // under GPL version 2 or later // // Copyright (C) 2005 Takashi Iwai -// Copyright (C) 2009 Thomas Freitag +// Copyright (C) 2009, 2010 Thomas Freitag // Copyright (C) 2009 Carlos Garcia Campos // // To see a description of the changes please see the Changelog file that @@ -277,6 +277,7 @@ private: SplashTransparencyGroup * // transparency group stack transpGroupStack; + SplashBitmap *maskBitmap; // for image masks in pattern colorspace }; #endif commit 8e86dfb328d94939ecf390d34af533b831b2837b Author: Albert Astals Cid Date: Wed Apr 21 19:19:53 2010 +0100 Add copyright diff --git a/poppler/TextOutputDev.cc b/poppler/TextOutputDev.cc index e03cc8d..afca5f2 100644 --- a/poppler/TextOutputDev.cc +++ b/poppler/TextOutputDev.cc @@ -22,6 +22,7 @@ // Copyright (C) 2008, 2010 Hib Eris // Copyright (C) 2009 Ross Moore // Copyright (C) 2009 Kovid Goyal +// Copyright (C) 2010 Brian Ewins // // 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 diff --git a/poppler/TextOutputDev.h b/poppler/TextOutputDev.h index 62e2d4c..cceec20 100644 --- a/poppler/TextOutputDev.h +++ b/poppler/TextOutputDev.h @@ -15,6 +15,7 @@ // Copyright (C) 2007-2008 Carlos Garcia Campos // Copyright (C) 2007 Adrian Johnson // Copyright (C) 2008 Albert Astals Cid +// Copyright (C) 2010 Brian Ewins // // 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 From pino at kemper.freedesktop.org Thu Apr 22 04:33:22 2010 From: pino at kemper.freedesktop.org (Pino Toscano) Date: Thu, 22 Apr 2010 04:33:22 -0700 (PDT) Subject: [poppler] 2 commits - poppler/GlobalParamsWin.cc poppler/TextOutputDev.cc Message-ID: <20100422113322.3FC01F819C@kemper.freedesktop.org> poppler/GlobalParamsWin.cc | 2 ++ poppler/TextOutputDev.cc | 11 +++++++---- 2 files changed, 9 insertions(+), 4 deletions(-) New commits: commit a7dcb2b4ffee57b7f78529cbaeaab647ab93de86 Author: Pino Toscano Date: Thu Apr 22 13:31:41 2010 +0200 Windows: include config.h in GlobalParamsWin.cc only if not included already GlobalParamsWin.cc is not compiled standalone but only #include'd by GlobalParams.cc (on Windows only), so config.h has already included already as safety check, check for PACKAGE_NAME (#define'd in config.h) before #include'ing it again diff --git a/poppler/GlobalParamsWin.cc b/poppler/GlobalParamsWin.cc index 2333ddb..f989fb8 100644 --- a/poppler/GlobalParamsWin.cc +++ b/poppler/GlobalParamsWin.cc @@ -8,7 +8,9 @@ scan the whole fonts directory, parse TTF files and build font description for all fonts available in Windows. That's how MuPDF works. */ +#ifndef PACKAGE_NAME #include +#endif #ifdef USE_GCC_PRAGMAS #pragma implementation commit fba076e17af24a9c9883504282316bba119a908c Author: Pino Toscano Date: Thu Apr 22 13:24:04 2010 +0200 avoid accidental max() macro replacement with some compilers (eg MSVC) defining an empty macro and using it between "max" and "(", such compilers won't try to replace their macro max(a, b) there; in any case, empty spaces are just fine diff --git a/poppler/TextOutputDev.cc b/poppler/TextOutputDev.cc index afca5f2..20593b5 100644 --- a/poppler/TextOutputDev.cc +++ b/poppler/TextOutputDev.cc @@ -63,6 +63,9 @@ #include "ICSupport.h" #endif +// ugly way to workaround compilers which #define min()/max() +#define POPPLER_AVOID_MACRO_SUBSTITUTION + //------------------------------------------------------------------------ // parameters //------------------------------------------------------------------------ @@ -3036,10 +3039,10 @@ void TextPage::coalesce(GBool physLayout, GBool doHTML) { blk1->EyMin = blk1->yMin; blk1->EyMax = blk1->yMax; - bxMin0 = std::numeric_limits::max(); - byMin0 = std::numeric_limits::max(); - bxMin1 = std::numeric_limits::max(); - byMin1 = std::numeric_limits::max(); + bxMin0 = std::numeric_limits::max POPPLER_AVOID_MACRO_SUBSTITUTION (); + byMin0 = std::numeric_limits::max POPPLER_AVOID_MACRO_SUBSTITUTION (); + bxMin1 = std::numeric_limits::max POPPLER_AVOID_MACRO_SUBSTITUTION (); + byMin1 = std::numeric_limits::max POPPLER_AVOID_MACRO_SUBSTITUTION (); fblk2 = NULL; fblk3 = NULL; From aacid at kemper.freedesktop.org Thu Apr 22 15:12:03 2010 From: aacid at kemper.freedesktop.org (Albert Astals Cid) Date: Thu, 22 Apr 2010 15:12:03 -0700 (PDT) Subject: [poppler] poppler/TextOutputDev.cc Message-ID: <20100422221204.14F1AF81A3@kemper.freedesktop.org> poppler/TextOutputDev.cc | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) New commits: commit 16a004784043e2a8587c0c3c6d23889df8a80470 Author: Albert Astals Cid Date: Thu Apr 22 19:39:01 2010 +0100 Avoid the usage of std:: diff --git a/poppler/TextOutputDev.cc b/poppler/TextOutputDev.cc index 20593b5..15912c5 100644 --- a/poppler/TextOutputDev.cc +++ b/poppler/TextOutputDev.cc @@ -39,7 +39,7 @@ #include #include #include -#include +#include #include #ifdef _WIN32 #include // for O_BINARY @@ -63,9 +63,6 @@ #include "ICSupport.h" #endif -// ugly way to workaround compilers which #define min()/max() -#define POPPLER_AVOID_MACRO_SUBSTITUTION - //------------------------------------------------------------------------ // parameters //------------------------------------------------------------------------ @@ -3039,10 +3036,10 @@ void TextPage::coalesce(GBool physLayout, GBool doHTML) { blk1->EyMin = blk1->yMin; blk1->EyMax = blk1->yMax; - bxMin0 = std::numeric_limits::max POPPLER_AVOID_MACRO_SUBSTITUTION (); - byMin0 = std::numeric_limits::max POPPLER_AVOID_MACRO_SUBSTITUTION (); - bxMin1 = std::numeric_limits::max POPPLER_AVOID_MACRO_SUBSTITUTION (); - byMin1 = std::numeric_limits::max POPPLER_AVOID_MACRO_SUBSTITUTION (); + bxMin0 = DBL_MAX; + byMin0 = DBL_MAX; + bxMin1 = DBL_MAX; + byMin1 = DBL_MAX; fblk2 = NULL; fblk3 = NULL; @@ -3194,10 +3191,10 @@ void TextPage::coalesce(GBool physLayout, GBool doHTML) { TextBlock **ending_blocks = new TextBlock* [numTables]; for (i = 0; i < numTables; i++) { - envelopes[i].x1 = std::numeric_limits::max(); - envelopes[i].x2 = std::numeric_limits::min(); - envelopes[i].y1 = std::numeric_limits::max(); - envelopes[i].y2 = std::numeric_limits::min(); + envelopes[i].x1 = DBL_MAX; + envelopes[i].x2 = DBL_MIN; + envelopes[i].y1 = DBL_MAX; + envelopes[i].y2 = DBL_MIN; } for (blk1 = blkList; blk1; blk1 = blk1->next) { @@ -3246,8 +3243,8 @@ void TextPage::coalesce(GBool physLayout, GBool doHTML) { */ for (blk1 = blkList; blk1; blk1 = blk1->next) { if (!blk1->tableId >= 0) { - double xMax = std::numeric_limits::max(); - double xMin = std::numeric_limits::min(); + double xMax = DBL_MAX; + double xMin = DBL_MIN; for (blk2 = blkList; blk2; blk2 = blk2->next) { if (blk2 == blk1) From oinos at web.de Fri Apr 23 07:56:44 2010 From: oinos at web.de (=?ISO-8859-1?Q?Pablo_Rodr=EDguez?=) Date: Fri, 23 Apr 2010 16:56:44 +0200 Subject: [poppler] next stable release? Message-ID: <4BD1B52C.60001@web.de> Hi there, I wonder when the next stable release 0.14 will happen. Thanks for your help, Pablo From aacid at kde.org Fri Apr 23 10:52:04 2010 From: aacid at kde.org (Albert Astals Cid) Date: Fri, 23 Apr 2010 18:52:04 +0100 Subject: [poppler] next stable release? In-Reply-To: <4BD1B52C.60001@web.de> References: <4BD1B52C.60001@web.de> Message-ID: <201004231852.04270.aacid@kde.org> A Divendres, 23 d'abril de 2010, Pablo Rodr?guez va escriure: > Hi there, > > I wonder when the next stable release 0.14 will happen. http://lmgtfy.com/?q=poppler+release+0.14 Probably you can add 2 weeks to that schedule since that's amount we are behind for the poppler 0.13.3 release that i plan to release this weekend, hopefully. Albert > > Thanks for your help, > > > Pablo > _______________________________________________ > poppler mailing list > poppler at lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/poppler From aacid at kemper.freedesktop.org Fri Apr 23 14:59:53 2010 From: aacid at kemper.freedesktop.org (Albert Astals Cid) Date: Fri, 23 Apr 2010 14:59:53 -0700 (PDT) Subject: [poppler] poppler/CharCodeToUnicode.cc Message-ID: <20100423215953.74512F8153@kemper.freedesktop.org> poppler/CharCodeToUnicode.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) New commits: commit 4ed53e30e735b79c46eab9d54883531c6e187b17 Author: William Bader Date: Fri Apr 23 22:52:24 2010 +0100 Silence some Illegal entry in bfrange block in ToUnicode CMap Fixes #27728 diff --git a/poppler/CharCodeToUnicode.cc b/poppler/CharCodeToUnicode.cc index 5941190..80fd4c5 100644 --- a/poppler/CharCodeToUnicode.cc +++ b/poppler/CharCodeToUnicode.cc @@ -18,6 +18,7 @@ // Copyright (C) 2007 Koji Otani // Copyright (C) 2008 Michael Vrable // Copyright (C) 2008 Vasile Gaburici +// Copyright (C) 2010 William Bader // // 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 @@ -307,8 +308,10 @@ void CharCodeToUnicode::parseCMap1(int (*getCharFunc)(void *), void *data, error(-1, "Illegal entry in bfrange block in ToUnicode CMap"); break; } - if (!(n1 == 2 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>' && - n2 == 2 + nDigits && tok2[0] == '<' && tok2[n2 - 1] == '>')) { + if (!(((n1 == 2 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>') || + (n1 == 4 + nDigits && tok1[0] == '<' && tok1[n1 - 1] == '>' && tok1[1] == '0' && tok1[2] == '0')) && + ((n2 == 2 + nDigits && tok2[0] == '<' && tok2[n2 - 1] == '>') || + (n2 == 4 + nDigits && tok2[0] == '<' && tok2[n2 - 1] == '>' && tok1[1] == '0' && tok1[2] == '0')))) { error(-1, "Illegal entry in bfrange block in ToUnicode CMap"); continue; } From aacid at kemper.freedesktop.org Sat Apr 24 05:11:31 2010 From: aacid at kemper.freedesktop.org (Albert Astals Cid) Date: Sat, 24 Apr 2010 05:11:31 -0700 (PDT) Subject: [poppler] 3 commits - goo/GooVector.h utils/HtmlLinks.cc utils/HtmlLinks.h utils/pdftohtml.cc Message-ID: <20100424121131.BE511F8216@kemper.freedesktop.org> goo/GooVector.h | 5 +++-- utils/HtmlLinks.cc | 15 ++------------- utils/HtmlLinks.h | 16 ++++++++++++++-- utils/pdftohtml.cc | 30 ++++++++++++++++++------------ 4 files changed, 37 insertions(+), 29 deletions(-) New commits: commit 07864c9e2a7a32b48bdbab92c8b2f79bce1d9f5b Author: Albert Astals Cid Date: Sat Apr 24 13:07:02 2010 +0100 minor cleanups diff --git a/utils/HtmlLinks.cc b/utils/HtmlLinks.cc index 0fd093c..c0ca89a 100644 --- a/utils/HtmlLinks.cc +++ b/utils/HtmlLinks.cc @@ -18,6 +18,7 @@ // under GPL version 2 or later // // Copyright (C) 2008 Boris Toloknov +// Copyright (C) 2010 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 @@ -56,7 +57,7 @@ HtmlLink::HtmlLink(double xmin,double ymin,double xmax,double ymax,GooString * _ } HtmlLink::~HtmlLink(){ - if (dest) delete dest; + delete dest; } GBool HtmlLink::isEqualDest(const HtmlLink& x) const{ @@ -69,18 +70,6 @@ GBool HtmlLink::inLink(double xmin,double ymin,double xmax,double ymax) const { return (y>Ymin)&&(xminXmin); } - -HtmlLink& HtmlLink::operator=(const HtmlLink& x){ - if (this==&x) return *this; - if (dest) {delete dest;dest=NULL;} - Xmin=x.Xmin; - Ymin=x.Ymin; - Xmax=x.Xmax; - Ymax=x.Ymax; - dest=new GooString(x.dest); - return *this; -} - static GooString* EscapeSpecialChars( GooString* s ) { GooString* tmp = NULL; diff --git a/utils/HtmlLinks.h b/utils/HtmlLinks.h index 571c2a7..1212844 100644 --- a/utils/HtmlLinks.h +++ b/utils/HtmlLinks.h @@ -10,6 +10,20 @@ // //======================================================================== +//======================================================================== +// +// Modified under the Poppler project - http://poppler.freedesktop.org +// +// All changes made under the Poppler project to this file are licensed +// under GPL version 2 or later +// +// Copyright (C) 2010 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 +// +//======================================================================== + #ifndef _HTML_LINKS #define _HTML_LINKS @@ -28,9 +42,7 @@ private: GooString* dest; public: - HtmlLink(){dest=NULL;} HtmlLink(const HtmlLink& x); - HtmlLink& operator=(const HtmlLink& x); HtmlLink(double xmin,double ymin,double xmax,double ymax,GooString *_dest); ~HtmlLink(); GBool isEqualDest(const HtmlLink& x) const; commit e501eabb2f0775444a2bf64005a3a3f1ffa281b4 Author: Albert Astals Cid Date: Sat Apr 24 13:06:12 2010 +0100 Do not assume the parameter will have more than 5 chars diff --git a/utils/pdftohtml.cc b/utils/pdftohtml.cc index 0e0a376..3c74c6e 100644 --- a/utils/pdftohtml.cc +++ b/utils/pdftohtml.cc @@ -218,18 +218,24 @@ int main(int argc, char *argv[]) { // construct text file name if (argc == 3) { GooString* tmp = new GooString(argv[2]); - p=tmp->getCString()+tmp->getLength()-5; - if (!xml) - if (!strcmp(p, ".html") || !strcmp(p, ".HTML")) - htmlFileName = new GooString(tmp->getCString(), - tmp->getLength() - 5); - else htmlFileName =new GooString(tmp); - else - if (!strcmp(p, ".xml") || !strcmp(p, ".XML")) - htmlFileName = new GooString(tmp->getCString(), - tmp->getLength() - 5); - else htmlFileName =new GooString(tmp); - + if (!xml) { + if (tmp->getLength() >= 5) { + p = tmp->getCString() + tmp->getLength() - 5; + if (!strcmp(p, ".html") || !strcmp(p, ".HTML")) { + htmlFileName = new GooString(tmp->getCString(), tmp->getLength() - 5); + } + } + } else { + if (tmp->getLength() >= 4) { + p = tmp->getCString() + tmp->getLength() - 4; + if (!strcmp(p, ".xml") || !strcmp(p, ".XML")) { + htmlFileName = new GooString(tmp->getCString(), tmp->getLength() - 4); + } + } + } + if (!htmlFileName) { + htmlFileName =new GooString(tmp); + } delete tmp; } else if (fileName->cmp("fd://0") == 0) { error(-1, "You have to provide an output filename when reading form stdin."); commit 6cc4d571339214e9eeeb682ba48fb220cef905f9 Author: Albert Astals Cid Date: Sat Apr 24 13:04:05 2010 +0100 Fix end() to return the correct last valid value diff --git a/goo/GooVector.h b/goo/GooVector.h index d396c6f..e35fd8a 100644 --- a/goo/GooVector.h +++ b/goo/GooVector.h @@ -5,6 +5,7 @@ // This file is licensed under the GPLv2 or later // // Copyright 2010 David Benjamin +// Copyright 2010 Albert Astals Cid // //======================================================================== @@ -58,8 +59,8 @@ public: iterator begin() { return m_data; } const_iterator begin() const { return m_data; } - iterator end() { return m_data + m_capacity; } - const_iterator end() const { return m_data + m_capacity; } + iterator end() { return m_data + m_size; } + const_iterator end() const { return m_data + m_size; } size_type size() const { return m_size; } size_type capacity() const { return m_capacity; } From harry.roberts at midnight-labs.org Sat Apr 24 06:02:17 2010 From: harry.roberts at midnight-labs.org (Harry Roberts) Date: Sat, 24 Apr 2010 14:02:17 +0100 Subject: [poppler] Allow quality & progressive mode to be utilised in JpegWriter Message-ID: Hi all, Attached is a patch which allows quality & progressive mode to be set in JpegWriter. Another writeImgFile method is added to SplashBitmap which allows a pre-created ImgWriter to be passed (e.g. a JpegWriter with custom quality/progressive mode settings), deletion of the ImgWriter is moved into the writeImgFile method which creates it. This is backwards compatible with current applications using JpegWriter or SplashBitmap::writeImgFile. I've been using something similar in an application for about a month, but avoided using SplashBitmap::writeImgFile because I needed to do resampling and post-processing before hand, with this patch it'll allow me to create (for example) ResamplingImgWriter to resample it before passing it onto another ImgWriter, thus avoiding the duplication that I have at the moment (and generally allowing much more flexibility or new image-output formats without modifying poppler). Many Regards, - Harry Roberts - Midnight Labs. -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: poppler-jpegquality.diff Type: application/octet-stream Size: 4481 bytes Desc: not available URL: From aacid at kemper.freedesktop.org Sat Apr 24 07:52:37 2010 From: aacid at kemper.freedesktop.org (Albert Astals Cid) Date: Sat, 24 Apr 2010 07:52:37 -0700 (PDT) Subject: [poppler] CMakeLists.txt configure.ac cpp/Doxyfile NEWS qt4/src Message-ID: <20100424145237.ED08AF8146@kemper.freedesktop.org> CMakeLists.txt | 2 +- NEWS | 31 +++++++++++++++++++++++++++++++ configure.ac | 2 +- cpp/Doxyfile | 2 +- qt4/src/Doxyfile | 2 +- 5 files changed, 35 insertions(+), 4 deletions(-) New commits: commit dee7cb8691528293bb5b8f266970cdb6771e301b Author: Albert Astals Cid Date: Sat Apr 24 15:39:23 2010 +0100 0.13.3 diff --git a/CMakeLists.txt b/CMakeLists.txt index 0725747..1eba1fe 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,7 +14,7 @@ find_package(Threads) set(POPPLER_MAJOR_VERSION "0") set(POPPLER_MINOR_VERSION "13") -set(POPPLER_MICRO_VERSION "2") +set(POPPLER_MICRO_VERSION "3") set(POPPLER_VERSION "${POPPLER_MAJOR_VERSION}.${POPPLER_MINOR_VERSION}.${POPPLER_MICRO_VERSION}") # command line switches diff --git a/NEWS b/NEWS index baf38d5..66f048e 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,34 @@ +Release 0.13.3 (0.14 Beta 2) + + core: + * Fix roll optimization in the PS function interpreter + * Correctly parse numbers with '+' sign. Gnome bug #614549 + * Add support for cached files + * Add support for reading a cached file from stdin + * Add HTTP support using libcurl, disabled by default + * Add some const correctnes to GooString + * Rework DCTStream error handling. Bug #26280 + * Use current fill_opacity when drawing soft masked images in Cairo backend. Gnome bug #614915 + * Use the topleft of the Rect of text annots to draw + * Fix saving update docs that have a compressed xref table. Bug #27450 + * Parse varius part of the document catalog on demand + * Implement colorizing image masks with pattern colorspace in Cairo backend + * Fix a crash when rendering 0x0 images in Cairo backend + * Check pattern status after setting matrix when rendering images + * Improve text selection/extraction order. Bug #3188 + * Fix pattern size when bbox is not at 0,0 + * Improve colorizing text and masks in pattern colorspace. Bug #27482 + * Silence some Illegal entry in bfrange block in ToUnicode CMap. Bug #27728 + + utils: + * Add the -o[dd] and -e[ven] options to pdftoppm + * Allow read from stdin using the new cached files feature + * Fix crash in pdftohtml when output filename was shorter than 5 characters + + glib: + * Use existing cairo api when rendering to a pixbuf + * Compile with -DGSEAL_ENABLE. Bug #27579 + Release 0.13.2 (0.14 Beta 1) core: diff --git a/configure.ac b/configure.ac index 0a83b08..c92eac2 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ m4_define([poppler_version_major],[0]) m4_define([poppler_version_minor],[13]) -m4_define([poppler_version_micro],[2]) +m4_define([poppler_version_micro],[3]) m4_define([poppler_version],[poppler_version_major.poppler_version_minor.poppler_version_micro]) AC_PREREQ(2.59) diff --git a/cpp/Doxyfile b/cpp/Doxyfile index 62fd80a..489833e 100644 --- a/cpp/Doxyfile +++ b/cpp/Doxyfile @@ -31,7 +31,7 @@ PROJECT_NAME = "Poppler CPP" # This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = 0.13.2 +PROJECT_NUMBER = 0.13.3 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. diff --git a/qt4/src/Doxyfile b/qt4/src/Doxyfile index 367a88b..ac087fc 100644 --- a/qt4/src/Doxyfile +++ b/qt4/src/Doxyfile @@ -31,7 +31,7 @@ PROJECT_NAME = "Poppler Qt4 " # This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = 0.13.2 +PROJECT_NUMBER = 0.13.3 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. From aacid at kemper.freedesktop.org Sat Apr 24 07:52:50 2010 From: aacid at kemper.freedesktop.org (Albert Astals Cid) Date: Sat, 24 Apr 2010 07:52:50 -0700 (PDT) Subject: [poppler] Changes to 'refs/tags/poppler-0.13.3' Message-ID: <20100424145250.8A740F8146@kemper.freedesktop.org> Tag 'poppler-0.13.3' created by Albert Astals Cid at 2010-04-24 15:52 -0700 0.13.3 Changes since poppler-0.13.2-68: --- 0 files changed --- From aacid at kde.org Sat Apr 24 08:23:41 2010 From: aacid at kde.org (Albert Astals Cid) Date: Sat, 24 Apr 2010 16:23:41 +0100 Subject: [poppler] Poppler 0.13.3 (0.14 Beta 2) released Message-ID: <201004241623.41432.aacid@kde.org> Available from http://poppler.freedesktop.org/poppler-0.13.3.tar.gz WARNING: This is a unstable release, it is actually 0.14 Beta release, it should work like any release from the 0.12 branch, but do not blame us if it makes a volcano stop your plane. Changes against the 0.13.2 release: core: * Fix roll optimization in the PS function interpreter * Correctly parse numbers with '+' sign. Gnome bug #614549 * Add support for cached files * Add support for reading a cached file from stdin * Add HTTP support using libcurl, disabled by default * Add some const correctnes to GooString * Rework DCTStream error handling. Bug #26280 * Use current fill_opacity when drawing soft masked images in Cairo backend. Gnome bug #614915 * Use the topleft of the Rect of text annots to draw * Fix saving update docs that have a compressed xref table. Bug #27450 * Parse varius part of the document catalog on demand * Implement colorizing image masks with pattern colorspace in Cairo backend * Fix a crash when rendering 0x0 images in Cairo backend * Check pattern status after setting matrix when rendering images * Improve text selection/extraction order. Bug #3188 * Fix pattern size when bbox is not at 0,0 * Improve colorizing text and masks in pattern colorspace. Bug #27482 * Silence some Illegal entry in bfrange block in ToUnicode CMap. Bug #27728 utils: * Add the -o[dd] and -e[ven] options to pdftoppm * Allow read from stdin using the new cached files feature * Fix crash in pdftohtml when output filename was shorter than 5 characters glib: * Use existing cairo api when rendering to a pixbuf * Compile with -DGSEAL_ENABLE. Bug #27579 We are specially interested in possible regressions introduced to pdftotext because of the change on how text is extracted, mostly we are seeing improvements but it's not easy to test so any help there is welcome. Testing, patches and bug reports welcome. Next release will be poppler 0.13.4 (0.14 Release Candidate) scheduled for 9 May Albert From pino at kemper.freedesktop.org Sat Apr 24 09:22:06 2010 From: pino at kemper.freedesktop.org (Pino Toscano) Date: Sat, 24 Apr 2010 09:22:06 -0700 (PDT) Subject: [poppler] poppler/TextOutputDev.cc Message-ID: <20100424162206.407E6F8146@kemper.freedesktop.org> poppler/TextOutputDev.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) New commits: commit 5b822011029f3721fbafd4a7bf01b9d6fee35d25 Author: Pino Toscano Date: Sat Apr 24 18:18:08 2010 +0200 include standard float.h instead of unportable values.h diff --git a/poppler/TextOutputDev.cc b/poppler/TextOutputDev.cc index 15912c5..cdb5526 100644 --- a/poppler/TextOutputDev.cc +++ b/poppler/TextOutputDev.cc @@ -39,7 +39,7 @@ #include #include #include -#include +#include #include #ifdef _WIN32 #include // for O_BINARY From aacid at kde.org Mon Apr 26 11:25:37 2010 From: aacid at kde.org (Albert Astals Cid) Date: Mon, 26 Apr 2010 19:25:37 +0100 Subject: [poppler] Allow quality & progressive mode to be utilised in JpegWriter In-Reply-To: References: Message-ID: <201004261925.37329.aacid@kde.org> A Dissabte, 24 d'abril de 2010, Harry Roberts va escriure: > Hi all, > > Attached is a patch which allows quality & progressive mode to be set in > JpegWriter. > Another writeImgFile method is added to SplashBitmap which allows a > pre-created ImgWriter to be passed (e.g. a JpegWriter with custom > quality/progressive mode settings), deletion of the ImgWriter is moved into > the writeImgFile method which creates it. > This is backwards compatible with current applications using JpegWriter or > SplashBitmap::writeImgFile. > > I've been using something similar in an application for about a month, but > avoided using SplashBitmap::writeImgFile because I needed to do resampling > and post-processing before hand, with this patch it'll allow me to create > (for example) ResamplingImgWriter to resample it before passing it onto > another ImgWriter, thus avoiding the duplication that I have at the moment > (and generally allowing much more flexibility or new image-output formats > without modifying poppler). if( quality < 0 || quality > 100 ) seems like reversed logic? Albert > > Many Regards, > - Harry Roberts > - Midnight Labs. From carlosgc at kemper.freedesktop.org Tue Apr 27 05:28:26 2010 From: carlosgc at kemper.freedesktop.org (Carlos Garcia Campos) Date: Tue, 27 Apr 2010 05:28:26 -0700 (PDT) Subject: [poppler] poppler/Gfx.cc Message-ID: <20100427122826.56DCEF8111@kemper.freedesktop.org> poppler/Gfx.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) New commits: commit f9f0e4b747a1527bd6354897cdba7954d58651de Author: Carlos Garcia Campos Date: Tue Apr 27 14:26:23 2010 +0200 Fix first color stop offset of linear gradients Fixes bug #27837. diff --git a/poppler/Gfx.cc b/poppler/Gfx.cc index 8a7dfee..6259733 100644 --- a/poppler/Gfx.cc +++ b/poppler/Gfx.cc @@ -2524,7 +2524,7 @@ void Gfx::doAxialShFill(GfxAxialShading *shading) { if (out->useFillColorStop()) { // make sure we add stop color when t = tMin state->setFillColor(&color0); - out->updateFillColorStop(state, (tt - tMin)/(tMax - tMin)); + out->updateFillColorStop(state, 0); } // compute the coordinates of the point on the t axis at t = tMin; From danigm at yaco.es Tue Apr 27 09:28:45 2010 From: danigm at yaco.es (Daniel Garcia Moreno) Date: Tue, 27 Apr 2010 18:28:45 +0200 Subject: [poppler] TextPage::getText in rawOrder mode. Message-ID: <1272385725.2591.60.camel@tate> Hi to all: I'm reading the poppler code and touching something here and there because I'll implement the atk interface for evince and I need to know how to get the text of a pdf file from glib. I want to get the text ordered like you'll read it, I saw that pdftotext get the text well ordered using the "-raw" option. I looked the code and I saw that it use TextOutputDev with rawOrder = true. It's easy to dump the text to a file using the first argument that receive the TextOutputDev constructor, but I want to get the text as char *. I saw that using rawOrder in TextOutputDev you can't use getText method, it always returns an empty GooString: ... 3603 s = new GooString(); 3604 3605 if (rawOrder) { 3606 return s; 3607 } ... And here is the question, that is a bug/not_implemented_feature or it's like that for some reason? If you think that's a bug I could create the bug and upload a patch to "solve" it using the TextWordList. From aacid at kemper.freedesktop.org Tue Apr 27 15:35:37 2010 From: aacid at kemper.freedesktop.org (Albert Astals Cid) Date: Tue, 27 Apr 2010 15:35:37 -0700 (PDT) Subject: [poppler] splash/SplashBitmap.cc Message-ID: <20100427223538.7BF2AF811C@kemper.freedesktop.org> splash/SplashBitmap.cc | 1 + 1 file changed, 1 insertion(+) New commits: commit 4905e2bd764ea601e3bf9c5195c740e5bf186af5 Author: Albert Astals Cid Date: Tue Apr 27 23:34:34 2010 +0100 fix include diff --git a/splash/SplashBitmap.cc b/splash/SplashBitmap.cc index 6832293..7e99fc8 100644 --- a/splash/SplashBitmap.cc +++ b/splash/SplashBitmap.cc @@ -37,6 +37,7 @@ #include "poppler/Error.h" #include "goo/JpegWriter.h" #include "goo/PNGWriter.h" +#include "goo/ImgWriter.h" //------------------------------------------------------------------------ // SplashBitmap From aacid at kde.org Tue Apr 27 15:37:58 2010 From: aacid at kde.org (Albert Astals Cid) Date: Tue, 27 Apr 2010 23:37:58 +0100 Subject: [poppler] Broken build with TEXTOUT_WORD_LIST defined to 0 Message-ID: <201004272337.59168.aacid@kde.org> Hi guys, your patches to fix selection break the build when TEXTOUT_WORD_LIST is defined to 0, could you please fix it? Albert From aacid at kemper.freedesktop.org Tue Apr 27 15:40:00 2010 From: aacid at kemper.freedesktop.org (Albert Astals Cid) Date: Tue, 27 Apr 2010 15:40:00 -0700 (PDT) Subject: [poppler] poppler/TextOutputDev.cc Message-ID: <20100427224000.A3D1BF811C@kemper.freedesktop.org> poppler/TextOutputDev.cc | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) New commits: commit 29572d6ac7829b60efce2d8e489473c55e370f26 Author: Albert Astals Cid Date: Tue Apr 27 23:39:23 2010 +0100 fabs for doubles diff --git a/poppler/TextOutputDev.cc b/poppler/TextOutputDev.cc index cdb5526..ef9c486 100644 --- a/poppler/TextOutputDev.cc +++ b/poppler/TextOutputDev.cc @@ -3129,33 +3129,33 @@ void TextPage::coalesce(GBool physLayout, GBool doHTML) { yCentre4 = (fblk4->yMax + fblk4->yMin) / 2.0; // are blocks centrally aligned in x ? - if (abs (xCentre1 - xCentre3) <= deltaX && - abs (xCentre2 - xCentre4) <= deltaX) + if (fabs (xCentre1 - xCentre3) <= deltaX && + fabs (xCentre2 - xCentre4) <= deltaX) correspondenceX++; // are blocks centrally aligned in y ? - if (abs (yCentre1 - yCentre2) <= deltaY && - abs (yCentre3 - yCentre4) <= deltaY) + if (fabs (yCentre1 - yCentre2) <= deltaY && + fabs (yCentre3 - yCentre4) <= deltaY) correspondenceY++; // are blocks aligned to the left ? - if (abs (blk1->xMin - fblk3->xMin) <= deltaX && - abs (fblk2->xMin - fblk4->xMin) <= deltaX) + if (fabs (blk1->xMin - fblk3->xMin) <= deltaX && + fabs (fblk2->xMin - fblk4->xMin) <= deltaX) correspondenceX++; // are blocks aligned to the right ? - if (abs (blk1->xMax - fblk3->xMax) <= deltaX && - abs (fblk2->xMax - fblk4->xMax) <= deltaX) + if (fabs (blk1->xMax - fblk3->xMax) <= deltaX && + fabs (fblk2->xMax - fblk4->xMax) <= deltaX) correspondenceX++; // are blocks aligned to the top ? - if (abs (blk1->yMin - fblk2->yMin) <= deltaY && - abs (fblk3->yMin - fblk4->yMin) <= deltaY) + if (fabs (blk1->yMin - fblk2->yMin) <= deltaY && + fabs (fblk3->yMin - fblk4->yMin) <= deltaY) correspondenceY++; // are blocks aligned to the bottom ? - if (abs (blk1->yMax - fblk2->yMax) <= deltaY && - abs (fblk3->yMax - fblk4->yMax) <= deltaY) + if (fabs (blk1->yMax - fblk2->yMax) <= deltaY && + fabs (fblk3->yMax - fblk4->yMax) <= deltaY) correspondenceY++; // are blocks aligned in x and y ? From fluffymike at googlemail.com Wed Apr 28 08:33:07 2010 From: fluffymike at googlemail.com (Mike Tonks) Date: Wed, 28 Apr 2010 16:33:07 +0100 Subject: [poppler] Compile Error: undefined reference to `png_destroy_write_struct' Message-ID: Can anyone help? I'm building poppler-0.12.4 on windows with mingw (msys) when I get the following error: C:\msys\1.0\home\Owner\poppler-0.12.4\goo/PNGWriter.cc:26: undefined reference to `png_destroy_write_struct' ../goo/.libs/libgoo.a(PNGWriter.o):C:\msys\1.0\home\Owner\poppler-0.12.4\goo/PNGWriter.cc:32: undefined reference to `png_create_write_struct' ../goo/.libs/libgoo.a(PNGWriter.o):C:\msys\1.0\home\Owner\poppler-0.12.4\goo/PNGWriter.cc:38: undefined reference to `png_create_info_struct' ../goo/.libs/libgoo.a(PNGWriter.o):C:\msys\1.0\home\Owner\poppler-0.12.4\goo/PNGWriter.cc:50: undefined reference to `png_init_io' ../goo/.libs/libgoo.a(PNGWriter.o):C:\msys\1.0\home\Owner\poppler-0.12.4\goo/PNGWriter.cc:57: undefined reference to `png_set_compression_level' ../goo/.libs/libgoo.a(PNGWriter.o):C:\msys\1.0\home\Owner\poppler-0.12.4\goo/PNGWriter.cc:63: undefined reference to `png_set_IHDR' ../goo/.libs/libgoo.a(PNGWriter.o):C:\msys\1.0\home\Owner\poppler-0.12.4\goo/PNGWriter.cc:65: undefined reference to `png_write_info' ../goo/.libs/libgoo.a(PNGWriter.o):C:\msys\1.0\home\Owner\poppler-0.12.4\goo/PNGWriter.cc:76: undefined reference to `png_write_image' ../goo/.libs/libgoo.a(PNGWriter.o):C:\msys\1.0\home\Owner\poppler-0.12.4\goo/PNGWriter.cc:89: undefined reference to `png_write_rows' ../goo/.libs/libgoo.a(PNGWriter.o):C:\msys\1.0\home\Owner\poppler-0.12.4\goo/PNGWriter.cc:101: undefined reference to `png_write_end' collect2: ld returned 1 exit status make[1]: *** [libpoppler.la] Error 1 make[1]: Leaving directory `/home/Owner/poppler-0.12.4/poppler' make: *** [install-recursive] Error 1 Thanks for any assistance, mike Here's a longer log output in case this helps: -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT FileSpec.lo -MD -MP -MF .deps/FileSpec.Tpo -c FileSpec.cc -DDLL_EXPORT -DPIC -o .libs/FileSp ec.o mv -f .deps/FileSpec.Tpo .deps/FileSpec.Plo /bin/sh ../libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/ MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT FontEncodingTables.lo -MD -MP -MF .deps/FontEncodingT ables.Tpo -c -o FontEncodingTables.lo FontEncodingTables.cc libtool: compile: g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT FontEncodingTables.lo -MD -MP -MF .deps/FontEncodingTables.Tpo -c FontEncodingTables.cc -DDL L_EXPORT -DPIC -o .libs/FontEncodingTables.o mv -f .deps/FontEncodingTables.Tpo .deps/FontEncodingTables.Plo /bin/sh ../libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/ MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT Form.lo -MD -MP -MF .deps/Form.Tpo -c -o Form.lo Form .cc libtool: compile: g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT Form.lo -MD -MP -MF .deps/Form.Tpo -c Form.cc -DDLL_EXPORT -DPIC -o .libs/Form.o mv -f .deps/Form.Tpo .deps/Form.Plo /bin/sh ../libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/ MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT FontInfo.lo -MD -MP -MF .deps/FontInfo.Tpo -c -o Font Info.lo FontInfo.cc libtool: compile: g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT FontInfo.lo -MD -MP -MF .deps/FontInfo.Tpo -c FontInfo.cc -DDLL_EXPORT -DPIC -o .libs/FontIn fo.o mv -f .deps/FontInfo.Tpo .deps/FontInfo.Plo /bin/sh ../libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/ MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT Function.lo -MD -MP -MF .deps/Function.Tpo -c -o Func tion.lo Function.cc libtool: compile: g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT Function.lo -MD -MP -MF .deps/Function.Tpo -c Function.cc -DDLL_EXPORT -DPIC -o .libs/Functi on.o mv -f .deps/Function.Tpo .deps/Function.Plo /bin/sh ../libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/ MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT Gfx.lo -MD -MP -MF .deps/Gfx.Tpo -c -o Gfx.lo Gfx.cc libtool: compile: g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT Gfx.lo -MD -MP -MF .deps/Gfx.Tpo -c Gfx.cc -DDLL_EXPORT -DPIC -o .libs/Gfx.o mv -f .deps/Gfx.Tpo .deps/Gfx.Plo /bin/sh ../libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/ MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT GfxFont.lo -MD -MP -MF .deps/GfxFont.Tpo -c -o GfxFon t.lo GfxFont.cc libtool: compile: g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT GfxFont.lo -MD -MP -MF .deps/GfxFont.Tpo -c GfxFont.cc -DDLL_EXPORT -DPIC -o .libs/GfxFont.o GfxFont.cc: In constructor 'GfxCIDFont::GfxCIDFont(XRef*, char*, Ref, GooString*, Dict*)': GfxFont.cc:1333:27: warning: 'cMapName' may be used uninitialized in this function mv -f .deps/GfxFont.Tpo .deps/GfxFont.Plo /bin/sh ../libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/ MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT GfxState.lo -MD -MP -MF .deps/GfxState.Tpo -c -o GfxS tate.lo GfxState.cc libtool: compile: g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT GfxState.lo -MD -MP -MF .deps/GfxState.Tpo -c GfxState.cc -DDLL_EXPORT -DPIC -o .libs/GfxSta te.o mv -f .deps/GfxState.Tpo .deps/GfxState.Plo /bin/sh ../libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/ MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT GlobalParams.lo -MD -MP -MF .deps/GlobalParams.Tpo -c -o GlobalParams.lo GlobalParams.cc libtool: compile: g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT GlobalParams.lo -MD -MP -MF .deps/GlobalParams.Tpo -c GlobalParams.cc -DDLL_EXPORT -DPIC -o .libs/GlobalParams.o mv -f .deps/GlobalParams.Tpo .deps/GlobalParams.Plo /bin/sh ../libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/ MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT JArithmeticDecoder.lo -MD -MP -MF .deps/JArithmeticDe coder.Tpo -c -o JArithmeticDecoder.lo JArithmeticDecoder.cc libtool: compile: g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT JArithmeticDecoder.lo -MD -MP -MF .deps/JArithmeticDecoder.Tpo -c JArithmeticDecoder.cc -DDL L_EXPORT -DPIC -o .libs/JArithmeticDecoder.o mv -f .deps/JArithmeticDecoder.Tpo .deps/JArithmeticDecoder.Plo /bin/sh ../libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/ MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT JBIG2Stream.lo -MD -MP -MF .deps/JBIG2Stream.Tpo -c - o JBIG2Stream.lo JBIG2Stream.cc libtool: compile: g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT JBIG2Stream.lo -MD -MP -MF .deps/JBIG2Stream.Tpo -c JBIG2Stream.cc -DDLL_EXPORT -DPIC -o .li bs/JBIG2Stream.o mv -f .deps/JBIG2Stream.Tpo .deps/JBIG2Stream.Plo /bin/sh ../libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/ MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT Lexer.lo -MD -MP -MF .deps/Lexer.Tpo -c -o Lexer.lo L exer.cc libtool: compile: g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT Lexer.lo -MD -MP -MF .deps/Lexer.Tpo -c Lexer.cc -DDLL_EXPORT -DPIC -o .libs/Lexer.o Lexer.cc: In member function 'Object* Lexer::getObj(Object*, int)': Lexer.cc:159:10: warning: 'xf' may be used uninitialized in this function mv -f .deps/Lexer.Tpo .deps/Lexer.Plo /bin/sh ../libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/ MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT Link.lo -MD -MP -MF .deps/Link.Tpo -c -o Link.lo Link .cc libtool: compile: g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT Link.lo -MD -MP -MF .deps/Link.Tpo -c Link.cc -DDLL_EXPORT -DPIC -o .libs/Link.o mv -f .deps/Link.Tpo .deps/Link.Plo /bin/sh ../libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/ MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT Movie.lo -MD -MP -MF .deps/Movie.Tpo -c -o Movie.lo M ovie.cc libtool: compile: g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT Movie.lo -MD -MP -MF .deps/Movie.Tpo -c Movie.cc -DDLL_EXPORT -DPIC -o .libs/Movie.o mv -f .deps/Movie.Tpo .deps/Movie.Plo /bin/sh ../libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/ MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT NameToCharCode.lo -MD -MP -MF .deps/NameToCharCode.Tp o -c -o NameToCharCode.lo NameToCharCode.cc libtool: compile: g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT NameToCharCode.lo -MD -MP -MF .deps/NameToCharCode.Tpo -c NameToCharCode.cc -DDLL_EXPORT -DP IC -o .libs/NameToCharCode.o mv -f .deps/NameToCharCode.Tpo .deps/NameToCharCode.Plo /bin/sh ../libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/ MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT Object.lo -MD -MP -MF .deps/Object.Tpo -c -o Object.l o Object.cc libtool: compile: g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT Object.lo -MD -MP -MF .deps/Object.Tpo -c Object.cc -DDLL_EXPORT -DPIC -o .libs/Object.o mv -f .deps/Object.Tpo .deps/Object.Plo /bin/sh ../libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/ MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT OptionalContent.lo -MD -MP -MF .deps/OptionalContent. Tpo -c -o OptionalContent.lo OptionalContent.cc libtool: compile: g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT OptionalContent.lo -MD -MP -MF .deps/OptionalContent.Tpo -c OptionalContent.cc -DDLL_EXPORT -DPIC -o .libs/OptionalContent.o mv -f .deps/OptionalContent.Tpo .deps/OptionalContent.Plo /bin/sh ../libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/ MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT Outline.lo -MD -MP -MF .deps/Outline.Tpo -c -o Outlin e.lo Outline.cc libtool: compile: g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT Outline.lo -MD -MP -MF .deps/Outline.Tpo -c Outline.cc -DDLL_EXPORT -DPIC -o .libs/Outline.o mv -f .deps/Outline.Tpo .deps/Outline.Plo /bin/sh ../libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/ MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT OutputDev.lo -MD -MP -MF .deps/OutputDev.Tpo -c -o Ou tputDev.lo OutputDev.cc libtool: compile: g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT OutputDev.lo -MD -MP -MF .deps/OutputDev.Tpo -c OutputDev.cc -DDLL_EXPORT -DPIC -o .libs/Out putDev.o mv -f .deps/OutputDev.Tpo .deps/OutputDev.Plo /bin/sh ../libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/ MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT Page.lo -MD -MP -MF .deps/Page.Tpo -c -o Page.lo Page .cc libtool: compile: g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT Page.lo -MD -MP -MF .deps/Page.Tpo -c Page.cc -DDLL_EXPORT -DPIC -o .libs/Page.o mv -f .deps/Page.Tpo .deps/Page.Plo /bin/sh ../libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/ MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT PageTransition.lo -MD -MP -MF .deps/PageTransition.Tp o -c -o PageTransition.lo PageTransition.cc libtool: compile: g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT PageTransition.lo -MD -MP -MF .deps/PageTransition.Tpo -c PageTransition.cc -DDLL_EXPORT -DP IC -o .libs/PageTransition.o mv -f .deps/PageTransition.Tpo .deps/PageTransition.Plo /bin/sh ../libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/ MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT Parser.lo -MD -MP -MF .deps/Parser.Tpo -c -o Parser.l o Parser.cc libtool: compile: g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT Parser.lo -MD -MP -MF .deps/Parser.Tpo -c Parser.cc -DDLL_EXPORT -DPIC -o .libs/Parser.o mv -f .deps/Parser.Tpo .deps/Parser.Plo /bin/sh ../libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/ MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT PDFDoc.lo -MD -MP -MF .deps/PDFDoc.Tpo -c -o PDFDoc.l o PDFDoc.cc libtool: compile: g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT PDFDoc.lo -MD -MP -MF .deps/PDFDoc.Tpo -c PDFDoc.cc -DDLL_EXPORT -DPIC -o .libs/PDFDoc.o mv -f .deps/PDFDoc.Tpo .deps/PDFDoc.Plo /bin/sh ../libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/ MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT PDFDocEncoding.lo -MD -MP -MF .deps/PDFDocEncoding.Tp o -c -o PDFDocEncoding.lo PDFDocEncoding.cc libtool: compile: g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT PDFDocEncoding.lo -MD -MP -MF .deps/PDFDocEncoding.Tpo -c PDFDocEncoding.cc -DDLL_EXPORT -DP IC -o .libs/PDFDocEncoding.o mv -f .deps/PDFDocEncoding.Tpo .deps/PDFDocEncoding.Plo /bin/sh ../libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/ MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT PopplerCache.lo -MD -MP -MF .deps/PopplerCache.Tpo -c -o PopplerCache.lo PopplerCache.cc libtool: compile: g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT PopplerCache.lo -MD -MP -MF .deps/PopplerCache.Tpo -c PopplerCache.cc -DDLL_EXPORT -DPIC -o .libs/PopplerCache.o mv -f .deps/PopplerCache.Tpo .deps/PopplerCache.Plo /bin/sh ../libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/ MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT ProfileData.lo -MD -MP -MF .deps/ProfileData.Tpo -c - o ProfileData.lo ProfileData.cc libtool: compile: g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT ProfileData.lo -MD -MP -MF .deps/ProfileData.Tpo -c ProfileData.cc -DDLL_EXPORT -DPIC -o .li bs/ProfileData.o mv -f .deps/ProfileData.Tpo .deps/ProfileData.Plo /bin/sh ../libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/ MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT PreScanOutputDev.lo -MD -MP -MF .deps/PreScanOutputDe v.Tpo -c -o PreScanOutputDev.lo PreScanOutputDev.cc libtool: compile: g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT PreScanOutputDev.lo -MD -MP -MF .deps/PreScanOutputDev.Tpo -c PreScanOutputDev.cc -DDLL_EXPO RT -DPIC -o .libs/PreScanOutputDev.o mv -f .deps/PreScanOutputDev.Tpo .deps/PreScanOutputDev.Plo /bin/sh ../libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/ MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT PSTokenizer.lo -MD -MP -MF .deps/PSTokenizer.Tpo -c - o PSTokenizer.lo PSTokenizer.cc libtool: compile: g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT PSTokenizer.lo -MD -MP -MF .deps/PSTokenizer.Tpo -c PSTokenizer.cc -DDLL_EXPORT -DPIC -o .li bs/PSTokenizer.o mv -f .deps/PSTokenizer.Tpo .deps/PSTokenizer.Plo /bin/sh ../libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/ MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT Stream.lo -MD -MP -MF .deps/Stream.Tpo -c -o Stream.l o Stream.cc libtool: compile: g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT Stream.lo -MD -MP -MF .deps/Stream.Tpo -c Stream.cc -DDLL_EXPORT -DPIC -o .libs/Stream.o mv -f .deps/Stream.Tpo .deps/Stream.Plo /bin/sh ../libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/ MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT UnicodeMap.lo -MD -MP -MF .deps/UnicodeMap.Tpo -c -o UnicodeMap.lo UnicodeMap.cc libtool: compile: g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT UnicodeMap.lo -MD -MP -MF .deps/UnicodeMap.Tpo -c UnicodeMap.cc -DDLL_EXPORT -DPIC -o .libs/ UnicodeMap.o mv -f .deps/UnicodeMap.Tpo .deps/UnicodeMap.Plo /bin/sh ../libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/ MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT UnicodeTypeTable.lo -MD -MP -MF .deps/UnicodeTypeTabl e.Tpo -c -o UnicodeTypeTable.lo UnicodeTypeTable.cc libtool: compile: g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT UnicodeTypeTable.lo -MD -MP -MF .deps/UnicodeTypeTable.Tpo -c UnicodeTypeTable.cc -DDLL_EXPO RT -DPIC -o .libs/UnicodeTypeTable.o mv -f .deps/UnicodeTypeTable.Tpo .deps/UnicodeTypeTable.Plo /bin/sh ../libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/ MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT XRef.lo -MD -MP -MF .deps/XRef.Tpo -c -o XRef.lo XRef .cc libtool: compile: g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT XRef.lo -MD -MP -MF .deps/XRef.Tpo -c XRef.cc -DDLL_EXPORT -DPIC -o .libs/XRef.o mv -f .deps/XRef.Tpo .deps/XRef.Plo /bin/sh ../libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/ MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT PSOutputDev.lo -MD -MP -MF .deps/PSOutputDev.Tpo -c - o PSOutputDev.lo PSOutputDev.cc libtool: compile: g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT PSOutputDev.lo -MD -MP -MF .deps/PSOutputDev.Tpo -c PSOutputDev.cc -DDLL_EXPORT -DPIC -o .li bs/PSOutputDev.o mv -f .deps/PSOutputDev.Tpo .deps/PSOutputDev.Plo /bin/sh ../libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/ MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT TextOutputDev.lo -MD -MP -MF .deps/TextOutputDev.Tpo -c -o TextOutputDev.lo TextOutputDev.cc libtool: compile: g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT TextOutputDev.lo -MD -MP -MF .deps/TextOutputDev.Tpo -c TextOutputDev.cc -DDLL_EXPORT -DPIC -o .libs/TextOutputDev.o mv -f .deps/TextOutputDev.Tpo .deps/TextOutputDev.Plo /bin/sh ../libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/ MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT PageLabelInfo.lo -MD -MP -MF .deps/PageLabelInfo.Tpo -c -o PageLabelInfo.lo PageLabelInfo.cc libtool: compile: g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT PageLabelInfo.lo -MD -MP -MF .deps/PageLabelInfo.Tpo -c PageLabelInfo.cc -DDLL_EXPORT -DPIC -o .libs/PageLabelInfo.o mv -f .deps/PageLabelInfo.Tpo .deps/PageLabelInfo.Plo /bin/sh ../libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/ MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT SecurityHandler.lo -MD -MP -MF .deps/SecurityHandler. Tpo -c -o SecurityHandler.lo SecurityHandler.cc libtool: compile: g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT SecurityHandler.lo -MD -MP -MF .deps/SecurityHandler.Tpo -c SecurityHandler.cc -DDLL_EXPORT -DPIC -o .libs/SecurityHandler.o mv -f .deps/SecurityHandler.Tpo .deps/SecurityHandler.Plo /bin/sh ../libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/ MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT Sound.lo -MD -MP -MF .deps/Sound.Tpo -c -o Sound.lo S ound.cc libtool: compile: g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT Sound.lo -MD -MP -MF .deps/Sound.Tpo -c Sound.cc -DDLL_EXPORT -DPIC -o .libs/Sound.o mv -f .deps/Sound.Tpo .deps/Sound.Plo /bin/sh ../libtool --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/ MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT XpdfPluginAPI.lo -MD -MP -MF .deps/XpdfPluginAPI.Tpo -c -o XpdfPluginAPI.lo XpdfPluginAPI.cc libtool: compile: g++ -DHAVE_CONFIG_H -I. -I.. -I.. -I../goo -Ic:/MinGW/include/freetype2 -Ic:/MinGW/include -Ic:/MinGW/include -I/usr/local/include -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -MT XpdfPluginAPI.lo -MD -MP -MF .deps/XpdfPluginAPI.Tpo -c XpdfPluginAPI.cc -DDLL_EXPORT -DPIC -o .libs/XpdfPluginAPI.o mv -f .deps/XpdfPluginAPI.Tpo .deps/XpdfPluginAPI.Plo /bin/sh ../libtool --tag=CXX --mode=link g++ -Wall -Wno-write-strings -Woverloaded-virtual -g -O2 -version-info 5:0:0 -no-undefined -L/usr/local/ lib -o libpoppler.la -rpath /usr/local/lib SplashOutputDev.lo DCTStream.lo JPEG2000Stream.lo Annot.lo Array.lo BuiltinFont.lo BuiltinFontTables.lo C atalog.lo CharCodeToUnicode.lo CMap.lo DateInfo.lo Decrypt.lo Dict.lo Error.lo FileSpec.lo FontEncodingTables.lo Form.lo FontInfo.lo Function.lo Gfx.l o GfxFont.lo GfxState.lo GlobalParams.lo JArithmeticDecoder.lo JBIG2Stream.lo Lexer.lo Link.lo Movie.lo NameToCharCode.lo Object.lo OptionalContent.lo Outline.lo OutputDev.lo Page.lo PageTransition.lo Parser.lo PDFDoc.lo PDFDocEncoding.lo PopplerCache.lo ProfileData.lo PreScanOutputDev.lo PSTokenize r.lo Stream.lo UnicodeMap.lo UnicodeTypeTable.lo XRef.lo PSOutputDev.lo TextOutputDev.lo PageLabelInfo.lo SecurityHandler.lo Sound.lo XpdfPluginAPI.lo ../goo/libgoo.la ../fofi/libfofi.la ../splash/libsplash.la -ljpeg -lpng -lopenjpeg -Lc:/MinGW/lib -lfreetype -Lc:/MinGW/lib -lfontconfig -lpt hread -lgdi32 libtool: link: g++ -shared -nostdlib c:/mingw/bin/../lib/gcc/mingw32/4.5.0/../../../dllcrt2.o c:/mingw/bin/../lib/gcc/mingw32/4.5.0/crtbegin.o .libs/ SplashOutputDev.o .libs/DCTStream.o .libs/JPEG2000Stream.o .libs/Annot.o .libs/Array.o .libs/BuiltinFont.o .libs/BuiltinFontTables.o .libs/Catalog.o . libs/CharCodeToUnicode.o .libs/CMap.o .libs/DateInfo.o .libs/Decrypt.o .libs/Dict.o .libs/Error.o .libs/FileSpec.o .libs/FontEncodingTables.o .libs/Fo rm.o .libs/FontInfo.o .libs/Function.o .libs/Gfx.o .libs/GfxFont.o .libs/GfxState.o .libs/GlobalParams.o .libs/JArithmeticDecoder.o .libs/JBIG2Stream. o .libs/Lexer.o .libs/Link.o .libs/Movie.o .libs/NameToCharCode.o .libs/Object.o .libs/OptionalContent.o .libs/Outline.o .libs/OutputDev.o .libs/Page. o .libs/PageTransition.o .libs/Parser.o .libs/PDFDoc.o .libs/PDFDocEncoding.o .libs/PopplerCache.o .libs/ProfileData.o .libs/PreScanOutputDev.o .libs/ PSTokenizer.o .libs/Stream.o .libs/UnicodeMap.o .libs/UnicodeTypeTable.o .libs/XRef.o .libs/PSOutputDev.o .libs/TextOutputDev.o .libs/PageLabelInfo.o .libs/SecurityHandler.o .libs/Sound.o .libs/XpdfPluginAPI.o -Wl,--whole-archive ../goo/.libs/libgoo.a ../fofi/.libs/libfofi.a ../splash/.libs/libspla sh.a -Wl,--no-whole-archive -L/usr/local/lib -L/projetos/gcc/build/mingw32/libstdc++-v3/src -L/projetos/gcc/build/mingw32/libstdc++-v3/src/.libs -L/p rojetos/gcc/build/mingw32/winsup/mingw -L/projetos/gcc/build/mingw32/winsup/w32api/lib /usr/local/lib/libjpeg.dll.a -LC:/msys/1.0/local/lib /usr/local /lib/libpng12.dll.a -lopenjpeg -Lc:/MinGW/lib /usr/local/lib/libfreetype.dll.a /usr/local/lib/libfontconfig.dll.a -lpthread -lgdi32 -Lc:/mingw/bin/../ lib/gcc/mingw32/4.5.0 -Lc:/mingw/bin/../lib/gcc -Lc:/mingw/bin/../lib/gcc/mingw32/4.5.0/../../../../mingw32/lib -Lc:/mingw/bin/../lib/gcc/mingw32/4.5. 0/../../.. -L/mingw/lib /mingw/lib/gcc/mingw32/4.5.0/libstdc++.dll.a -lmingw32 -lgcc_s -lgcc -lmoldname -lmingwex -lmsvcrt -luser32 -lkernel32 -ladvap i32 -lshell32 -lmingw32 -lgcc_s -lgcc -lmoldname -lmingwex -lmsvcrt c:/mingw/bin/../lib/gcc/mingw32/4.5.0/crtend.o -o .libs/libpoppler-5.dll -Wl,-- enable-auto-image-base -Xlinker --out-implib -Xlinker .libs/libpoppler.dll.a Info: resolving vtable for __cxxabiv1::__si_class_type_info by linking to __imp___ZTVN10__cxxabiv120__si_class_type_infoE (auto-import) Info: resolving vtable for __cxxabiv1::__class_type_info by linking to __imp___ZTVN10__cxxabiv117__class_type_infoE (auto-import) Creating library file: .libs/libpoppler.dll.a c:/mingw/bin/../lib/gcc/mingw32/4.5.0/../../../../mingw32/bin/ld.exe: warning: auto-importing has been activated without --enable-auto-import specifie d on the command line. This should work unless it involves constant data structures referencing symbols from auto-imported DLLs. ../goo/.libs/libgoo.a(PNGWriter.o): In function `~PNGWriter': C:\msys\1.0\home\Owner\poppler-0.12.4\goo/PNGWriter.cc:26: undefined reference to `png_destroy_write_struct' ../goo/.libs/libgoo.a(PNGWriter.o):C:\msys\1.0\home\Owner\poppler-0.12.4\goo/PNGWriter.cc:32: undefined reference to `png_create_write_struct' ../goo/.libs/libgoo.a(PNGWriter.o):C:\msys\1.0\home\Owner\poppler-0.12.4\goo/PNGWriter.cc:38: undefined reference to `png_create_info_struct' ../goo/.libs/libgoo.a(PNGWriter.o):C:\msys\1.0\home\Owner\poppler-0.12.4\goo/PNGWriter.cc:50: undefined reference to `png_init_io' ../goo/.libs/libgoo.a(PNGWriter.o):C:\msys\1.0\home\Owner\poppler-0.12.4\goo/PNGWriter.cc:57: undefined reference to `png_set_compression_level' ../goo/.libs/libgoo.a(PNGWriter.o):C:\msys\1.0\home\Owner\poppler-0.12.4\goo/PNGWriter.cc:63: undefined reference to `png_set_IHDR' ../goo/.libs/libgoo.a(PNGWriter.o):C:\msys\1.0\home\Owner\poppler-0.12.4\goo/PNGWriter.cc:65: undefined reference to `png_write_info' ../goo/.libs/libgoo.a(PNGWriter.o):C:\msys\1.0\home\Owner\poppler-0.12.4\goo/PNGWriter.cc:76: undefined reference to `png_write_image' ../goo/.libs/libgoo.a(PNGWriter.o):C:\msys\1.0\home\Owner\poppler-0.12.4\goo/PNGWriter.cc:89: undefined reference to `png_write_rows' ../goo/.libs/libgoo.a(PNGWriter.o):C:\msys\1.0\home\Owner\poppler-0.12.4\goo/PNGWriter.cc:101: undefined reference to `png_write_end' collect2: ld returned 1 exit status make[1]: *** [libpoppler.la] Error 1 make[1]: Leaving directory `/home/Owner/poppler-0.12.4/poppler' make: *** [install-recursive] Error 1 From aacid at kde.org Wed Apr 28 13:39:41 2010 From: aacid at kde.org (Albert Astals Cid) Date: Wed, 28 Apr 2010 21:39:41 +0100 Subject: [poppler] Compile Error: undefined reference to `png_destroy_write_struct' In-Reply-To: References: Message-ID: <201004282139.41249.aacid@kde.org> A Dimecres, 28 d'abril de 2010, Mike Tonks va escriure: > Can anyone help? I'm building poppler-0.12.4 on windows with mingw > (msys) when I get the following error: Can you try poppler 0.13.3? Albert From henrich at debian.or.jp Thu Apr 29 01:08:11 2010 From: henrich at debian.or.jp (Hideki Yamane) Date: Thu, 29 Apr 2010 17:08:11 +0900 Subject: [poppler] FYI: Adobe updated CMap resource Message-ID: <20100429170811.9ed2fb2f.henrich@debian.or.jp> Hi, Probably you know but FYI. Adobe updated CMap resource see http://forums.adobe.com/thread/625534 - Adobe-CNS1-6 - Adobe-GB1-5 - Adobe-Japan1-6 Please consider to update poppler-data as well, thanks. -- Regards, Hideki Yamane henrich @ debian.or.jp/iijmio-mail.jp http://wiki.debian.org/HidekiYamane From fluffymike at googlemail.com Thu Apr 29 02:12:01 2010 From: fluffymike at googlemail.com (Mike Tonks) Date: Thu, 29 Apr 2010 10:12:01 +0100 Subject: [poppler] Compile Error: undefined reference to `png_destroy_write_struct' In-Reply-To: <201004282139.41249.aacid@kde.org> References: <201004282139.41249.aacid@kde.org> Message-ID: Hi Albert, With 0.13.3 it also fails but more quickly: Owner at ANONYMOUS ~/poppler-0.13.3 $ make make all-recursive make[1]: Entering directory `/home/Owner/poppler-0.13.3' Making all in goo make[2]: Entering directory `/home/Owner/poppler-0.13.3/goo' CXX gfile.lo gfile.cc: In function 'GooString* makePathAbsolute(GooString*)': gfile.cc:379:12: error: '_MAX_PATH' was not declared in this scope gfile.cc:382:3: error: 'buf' was not declared in this scope make[2]: *** [gfile.lo] Error 1 make[2]: Leaving directory `/home/Owner/poppler-0.13.3/goo' make[1]: *** [all-recursive] Error 1 make[1]: Leaving directory `/home/Owner/poppler-0.13.3' make: *** [all] Error 2 Note 0.13.3 compiles fine on my ubuntu (9.10) system. It's just the windows (mingw / msys) build I'm having trouble with. It may be my inexperience with mingw that's at fault, but I have successfully built all the dependent libraries (zlib, fontconfig, freetype, libpng, jpeg, libopenjpg) so I'm getting the hang of it I think. mike On 28 April 2010 21:39, Albert Astals Cid wrote: > A Dimecres, 28 d'abril de 2010, Mike Tonks va escriure: >> Can anyone help? ?I'm building poppler-0.12.4 on windows with mingw >> (msys) when I get the following error: > > Can you try poppler 0.13.3? > > Albert > _______________________________________________ > poppler mailing list > poppler at lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/poppler > From webquinty at gmail.com Thu Apr 29 02:22:58 2010 From: webquinty at gmail.com (webquinty quinty) Date: Thu, 29 Apr 2010 11:22:58 +0200 Subject: [poppler] Does poppler depend of X11? Message-ID: Hello, I would like to use poppler with Qt embedded 4.5.0 withouy X server ( Qt framebuffer -qws ). is it possible? Best regards. John Martin Spain -------------- next part -------------- An HTML attachment was scrubbed... URL: From hib at hiberis.nl Thu Apr 29 03:11:17 2010 From: hib at hiberis.nl (Hib Eris) Date: Thu, 29 Apr 2010 12:11:17 +0200 Subject: [poppler] Compile Error: undefined reference to `png_destroy_write_struct' In-Reply-To: References: <201004282139.41249.aacid@kde.org> Message-ID: Hi Mike, On Thu, Apr 29, 2010 at 11:12 AM, Mike Tonks wrote: > Hi Albert, > > With 0.13.3 it also fails but more quickly: > > Owner at ANONYMOUS ~/poppler-0.13.3 > $ make > make ?all-recursive > make[1]: Entering directory `/home/Owner/poppler-0.13.3' > Making all in goo > make[2]: Entering directory `/home/Owner/poppler-0.13.3/goo' > ?CXX ? ?gfile.lo > gfile.cc: In function 'GooString* makePathAbsolute(GooString*)': > gfile.cc:379:12: error: '_MAX_PATH' was not declared in this scope > gfile.cc:382:3: error: 'buf' was not declared in this scope > make[2]: *** [gfile.lo] Error 1 > make[2]: Leaving directory `/home/Owner/poppler-0.13.3/goo' > make[1]: *** [all-recursive] Error 1 > make[1]: Leaving directory `/home/Owner/poppler-0.13.3' > make: *** [all] Error 2 This error might come from compiling with the '-ansi' flag, which causes the mingw compiler to use header files that only include strict ansi. You can avoid it by running configure with the "--disable-compile-warnings" option. (Yes, this should be fixed in poppler, but I have not found the time to do it properly: by making poppler use only strict ansi, not by removing the -ansi flag). Hib From hib at hiberis.nl Thu Apr 29 04:52:32 2010 From: hib at hiberis.nl (Hib Eris) Date: Thu, 29 Apr 2010 13:52:32 +0200 Subject: [poppler] Linearization support Message-ID: Hi all, I have two series of patches that allow poppler to handle linearized documents more efficiently. The first series, linearization-patches-v1.txt, changes to way the XRef table is initialized and used. A linearized document contains two XRef tables, one at the beginning of the document and one at the end. The one at the beginning contains the xref's necessary to render the first page. To allow rendering the frist page without having to load the xref table at the end, I changed to code to read the entries in the end xref table (and other previous xref tables) only when needed. The second series, page-on-demand-v1.txt, changes how the page tree is initialized. In a linearized document the 'Page' objects are scattered all over the document. If you only want to render a specific page, you do not want to have to read all these Page objects to initialize a page tree. Linearized documents contain extra information in hint tables that allow you to find the Page objects without using the page tree. These patches make poppler initialize the page tree only when needed, instead of on document initialization. Because page objects are parsed only when you call getPage(), it can no longer be guaranteed that getPage() will always return a valid Page object, so you will have to check it's return value. These patches, along with the HTTP streaming support make it possible to use pdftoppm to render a specific page of a remote document by only loading the necessary document data for that page. Hib -------------- next part -------------- From a9f2d19d18dd509d3f495c4c2fbb830516fa0527 Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Tue, 6 Apr 2010 19:24:42 +0200 Subject: [PATCH 01/12] Cleanup XRef constructors --- poppler/XRef.cc | 14 ++++++-------- poppler/XRef.h | 1 + 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/poppler/XRef.cc b/poppler/XRef.cc index 3ab23d9..8ae30b2 100644 --- a/poppler/XRef.cc +++ b/poppler/XRef.cc @@ -226,7 +226,7 @@ Object *ObjectStream::getObject(int objIdx, int objNum, Object *obj) { // XRef //------------------------------------------------------------------------ -XRef::XRef() { +void XRef::init() { ok = gTrue; errCode = errNone; entries = NULL; @@ -236,17 +236,15 @@ XRef::XRef() { objStr = NULL; } +XRef::XRef() { + init(); +} + XRef::XRef(BaseStream *strA) { Guint pos; Object obj; - ok = gTrue; - errCode = errNone; - size = 0; - entries = NULL; - streamEnds = NULL; - streamEndsLen = 0; - objStr = NULL; + init(); encrypted = gFalse; permFlags = defPermFlags; diff --git a/poppler/XRef.h b/poppler/XRef.h index 2dbd469..98db234 100644 --- a/poppler/XRef.h +++ b/poppler/XRef.h @@ -155,6 +155,7 @@ private: Guchar fileKey[16]; // file decryption key GBool ownerPasswordOk; // true if owner password is correct + void init(); Guint getStartXref(); GBool readXRef(Guint *pos); GBool readXRefTable(Parser *parser, Guint *pos); -- 1.6.4.2 From f1bf4283fce1793d5d0a07810c7de4bfd0389562 Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Tue, 6 Apr 2010 19:16:45 +0200 Subject: [PATCH 02/12] Create no more XRef entries than specified --- poppler/XRef.cc | 126 +++++++++++++++++++++++++++--------------------------- poppler/XRef.h | 5 ++- 2 files changed, 67 insertions(+), 64 deletions(-) diff --git a/poppler/XRef.cc b/poppler/XRef.cc index 8ae30b2..49ff809 100644 --- a/poppler/XRef.cc +++ b/poppler/XRef.cc @@ -230,6 +230,7 @@ void XRef::init() { ok = gTrue; errCode = errNone; entries = NULL; + capacity = 0; size = 0; streamEnds = NULL; streamEndsLen = 0; @@ -311,6 +312,50 @@ XRef::~XRef() { } } +int XRef::reserve(int newSize) +{ + if (newSize > capacity) { + + int realNewSize; + for (realNewSize = capacity ? 2 * capacity : 1024; + newSize > realNewSize && realNewSize > 0; + realNewSize <<= 1) ; + if ((realNewSize < 0) || + (realNewSize >= INT_MAX / (int)sizeof(XRefEntry))) { + return 0; + } + + entries = (XRefEntry *)greallocn(entries, realNewSize, sizeof(XRefEntry)); + capacity = realNewSize; + } + + return capacity; +} + +int XRef::resize(int newSize) +{ + if (newSize > size) { + + if (reserve(newSize) < newSize) return size; + + for (int i = size; i < newSize; ++i) { + entries[i].offset = 0xffffffff; + entries[i].type = xrefEntryFree; + entries[i].obj.initNull (); + entries[i].updated = false; + entries[i].gen = 0; + } + } else { + for (int i = newSize; i < size; i++) { + entries[i].obj.free (); + } + } + + size = newSize; + + return size; +} + // Read the 'startxref' position. Guint XRef::getStartXref() { char buf[xrefSearchSize+1]; @@ -398,7 +443,7 @@ GBool XRef::readXRefTable(Parser *parser, Guint *pos) { GBool more; Object obj, obj2; Guint pos2; - int first, n, newSize, i; + int first, n, i; while (1) { parser->getObj(&obj); @@ -417,29 +462,13 @@ GBool XRef::readXRefTable(Parser *parser, Guint *pos) { n = obj.getInt(); obj.free(); if (first < 0 || n < 0 || first + n < 0) { - goto err1; + goto err0; } if (first + n > size) { - for (newSize = size ? 2 * size : 1024; - first + n > newSize && newSize > 0; - newSize <<= 1) ; - if (newSize < 0) { - goto err1; - } - if (newSize >= INT_MAX / (int)sizeof(XRefEntry)) { + if (resize(first + n) != first + n) { error(-1, "Invalid 'obj' parameters'"); - goto err1; + goto err0; } - - entries = (XRefEntry *)greallocn(entries, newSize, sizeof(XRefEntry)); - for (i = size; i < newSize; ++i) { - entries[i].offset = 0xffffffff; - entries[i].type = xrefEntryFree; - entries[i].obj.initNull (); - entries[i].updated = false; - entries[i].gen = 0; - } - size = newSize; } for (i = first; i < first + n; ++i) { if (!parser->getObj(&obj)->isInt()) { @@ -520,6 +549,7 @@ GBool XRef::readXRefTable(Parser *parser, Guint *pos) { err1: obj.free(); + err0: ok = gFalse; return gFalse; } @@ -542,19 +572,10 @@ GBool XRef::readXRefStream(Stream *xrefStr, Guint *pos) { goto err1; } if (newSize > size) { - if (newSize >= INT_MAX / (int)sizeof(XRefEntry)) { - error(-1, "Invalid 'size' parameter."); - return gFalse; - } - entries = (XRefEntry *)greallocn(entries, newSize, sizeof(XRefEntry)); - for (i = size; i < newSize; ++i) { - entries[i].offset = 0xffffffff; - entries[i].type = xrefEntryFree; - entries[i].obj.initNull (); - entries[i].updated = false; - entries[i].gen = 0; + if (resize(newSize) != newSize) { + error(-1, "Invalid 'size' parameter"); + goto err0; } - size = newSize; } if (!dict->lookupNF("W", &obj)->isArray() || @@ -627,31 +648,16 @@ GBool XRef::readXRefStream(Stream *xrefStr, Guint *pos) { GBool XRef::readXRefStreamSection(Stream *xrefStr, int *w, int first, int n) { Guint offset; - int type, gen, c, newSize, i, j; + int type, gen, c, i, j; if (first + n < 0) { return gFalse; } if (first + n > size) { - for (newSize = size ? 2 * size : 1024; - first + n > newSize && newSize > 0; - newSize <<= 1) ; - if (newSize < 0) { - return gFalse; - } - if (newSize >= INT_MAX / (int)sizeof(XRefEntry)) { - error(-1, "Invalid 'size' inside xref table."); + if (resize(first + n) != size) { + error(-1, "Invalid 'size' inside xref table"); return gFalse; } - entries = (XRefEntry *)greallocn(entries, newSize, sizeof(XRefEntry)); - for (i = size; i < newSize; ++i) { - entries[i].offset = 0xffffffff; - entries[i].type = xrefEntryFree; - entries[i].obj.initNull (); - entries[i].updated = false; - entries[i].gen = 0; - } - size = newSize; } for (i = first; i < first + n; ++i) { if (w[0] == 0) { @@ -712,13 +718,13 @@ GBool XRef::constructXRef() { int newSize; int streamEndsSize; char *p; - int i; GBool gotRoot; char* token = NULL; bool oneCycle = true; int offset = 0; gfree(entries); + capacity = 0; size = 0; entries = NULL; @@ -800,19 +806,10 @@ GBool XRef::constructXRef() { error(-1, "Bad object number"); return gFalse; } - if (newSize >= INT_MAX / (int)sizeof(XRefEntry)) { - error(-1, "Invalid 'obj' parameters."); + if (resize(newSize) != newSize) { + error(-1, "Invalid 'obj' parameters"); return gFalse; } - entries = (XRefEntry *) - greallocn(entries, newSize, sizeof(XRefEntry)); - for (i = size; i < newSize; ++i) { - entries[i].offset = 0xffffffff; - entries[i].type = xrefEntryFree; - entries[i].obj.initNull (); - entries[i].updated = false; - } - size = newSize; } if (entries[num].type == xrefEntryFree || gen >= entries[num].gen) { @@ -1085,7 +1082,10 @@ Guint XRef::strToUnsigned(char *s) { void XRef::add(int num, int gen, Guint offs, GBool used) { if (num >= size) { - entries = (XRefEntry *)greallocn(entries, num + 1, sizeof(XRefEntry)); + if (num >= capacity) { + entries = (XRefEntry *)greallocn(entries, num + 1, sizeof(XRefEntry)); + capacity = num + 1; + } for (int i = size; i < num + 1; ++i) { entries[i].offset = 0xffffffff; entries[i].type = xrefEntryFree; diff --git a/poppler/XRef.h b/poppler/XRef.h index 98db234..f86e5ee 100644 --- a/poppler/XRef.h +++ b/poppler/XRef.h @@ -136,7 +136,8 @@ private: Guint start; // offset in file (to allow for garbage // at beginning of file) XRefEntry *entries; // xref entries - int size; // size of array + int capacity; // size of array + int size; // number of entries int rootNum, rootGen; // catalog dict GBool ok; // true if xref table is valid int errCode; // error code (if is false) @@ -156,6 +157,8 @@ private: GBool ownerPasswordOk; // true if owner password is correct void init(); + int reserve(int newSize); + int resize(int newSize); Guint getStartXref(); GBool readXRef(Guint *pos); GBool readXRefTable(Parser *parser, Guint *pos); -- 1.6.4.2 From fa5a0beb6f86a6cea7ba98ef5ef3c04a53b7319d Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Wed, 28 Apr 2010 12:45:42 +0200 Subject: [PATCH 03/12] Use XRef::add() in XRef::addIndirectObject() --- poppler/XRef.cc | 4 +--- 1 files changed, 1 insertions(+), 3 deletions(-) diff --git a/poppler/XRef.cc b/poppler/XRef.cc index 49ff809..012f91c 100644 --- a/poppler/XRef.cc +++ b/poppler/XRef.cc @@ -1127,10 +1127,8 @@ Ref XRef::addIndirectObject (Object* o) { XRefEntry *e; if (entryIndexToUse == -1) { entryIndexToUse = size; - size++; - entries = (XRefEntry *)greallocn(entries, size, sizeof(XRefEntry)); + add(entryIndexToUse, 0, 0, gFalse); e = &entries[entryIndexToUse]; - e->gen = 0; } else { //reuse a free entry e = &entries[entryIndexToUse]; -- 1.6.4.2 From 7ce2bb1aac50315145ebc21ae34b5c37f00e0c35 Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Wed, 14 Apr 2010 12:20:49 +0200 Subject: [PATCH 04/12] Use XRef::getEntry() to access entries --- poppler/XRef.cc | 49 +++++++++++++++++++++++++------------------------ poppler/XRef.h | 2 +- 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/poppler/XRef.cc b/poppler/XRef.cc index 012f91c..d615ec0 100644 --- a/poppler/XRef.cc +++ b/poppler/XRef.cc @@ -927,7 +927,7 @@ Object *XRef::fetch(int num, int gen, Object *obj) { goto err; } - e = &entries[num]; + e = getEntry(num); if(!e->obj.isNull ()) { //check for updated object obj = e->obj.copy(obj); return obj; @@ -1047,20 +1047,20 @@ GBool XRef::getStreamEnd(Guint streamStart, Guint *streamEnd) { return gTrue; } -int XRef::getNumEntry(Guint offset) const +int XRef::getNumEntry(Guint offset) { if (size > 0) { int res = 0; - Guint resOffset = entries[0].offset; - XRefEntry e; + Guint resOffset = getEntry(0)->offset; + XRefEntry *e; for (int i = 1; i < size; ++i) { - e = entries[i]; - if (e.offset < offset && e.offset >= resOffset) + e = getEntry(i); + if (e->offset < offset && e->offset >= resOffset) { res = i; - resOffset = e.offset; + resOffset = e->offset; } } return res; @@ -1095,7 +1095,7 @@ void XRef::add(int num, int gen, Guint offs, GBool used) { } size = num + 1; } - XRefEntry *e = &entries[num]; + XRefEntry *e = getEntry(num); e->gen = gen; e->obj.initNull (); e->updated = false; @@ -1113,25 +1113,26 @@ void XRef::setModifiedObject (Object* o, Ref r) { error(-1,"XRef::setModifiedObject on unknown ref: %i, %i\n", r.num, r.gen); return; } - entries[r.num].obj.free(); - o->copy(&entries[r.num].obj); - entries[r.num].updated = true; + XRefEntry *e = getEntry(r.num); + e->obj.free(); + o->copy(&(e->obj)); + e->updated = true; } Ref XRef::addIndirectObject (Object* o) { int entryIndexToUse = -1; for (int i = 1; entryIndexToUse == -1 && i < size; ++i) { - if (entries[i].type == xrefEntryFree) entryIndexToUse = i; + if (getEntry(i)->type == xrefEntryFree) entryIndexToUse = i; } XRefEntry *e; if (entryIndexToUse == -1) { entryIndexToUse = size; add(entryIndexToUse, 0, 0, gFalse); - e = &entries[entryIndexToUse]; + e = getEntry(entryIndexToUse); } else { //reuse a free entry - e = &entries[entryIndexToUse]; + e = getEntry(entryIndexToUse); //we don't touch gen number, because it should have been //incremented when the object was deleted } @@ -1147,13 +1148,13 @@ Ref XRef::addIndirectObject (Object* o) { void XRef::writeToFile(OutStream* outStr, GBool writeAllEntries) { //create free entries linked-list - if (entries[0].gen != 65535) { + if (getEntry(0)->gen != 65535) { error(-1, "XRef::writeToFile, entry 0 of the XRef is invalid (gen != 65535)\n"); } int lastFreeEntry = 0; for (int i=0; itype == xrefEntryFree) { + getEntry(lastFreeEntry)->offset = i; lastFreeEntry = i; } } @@ -1163,10 +1164,10 @@ void XRef::writeToFile(OutStream* outStr, GBool writeAllEntries) { outStr->printf("xref\r\n"); outStr->printf("%i %i\r\n", 0, size); for (int i=0; i 65535) e.gen = 65535; //cap generation number to 65535 (required by PDFReference) - outStr->printf("%010i %05i %c\r\n", e.offset, e.gen, (e.type==xrefEntryFree)?'f':'n'); + if(e->gen > 65535) e->gen = 65535; //cap generation number to 65535 (required by PDFReference) + outStr->printf("%010i %05i %c\r\n", e->offset, e->gen, (e->type==xrefEntryFree)?'f':'n'); } } else { //write the new xref @@ -1175,16 +1176,16 @@ void XRef::writeToFile(OutStream* outStr, GBool writeAllEntries) { while (i < size) { int j; for(j=i; jtype == xrefEntryFree) && (getEntry(j)->gen == 0)) break; } if (j-i != 0) { outStr->printf("%i %i\r\n", i, j-i); for (int k=i; k 65535) e.gen = 65535; //cap generation number to 65535 (required by PDFReference) - outStr->printf("%010i %05i %c\r\n", e.offset, e.gen, (e.type==xrefEntryFree)?'f':'n'); + XRefEntry *e = getEntry(k); + if(e->gen > 65535) e->gen = 65535; //cap generation number to 65535 (required by PDFReference) + outStr->printf("%010i %05i %c\r\n", e->offset, e->gen, (e->type==xrefEntryFree)?'f':'n'); } i = j; } diff --git a/poppler/XRef.h b/poppler/XRef.h index f86e5ee..344b764 100644 --- a/poppler/XRef.h +++ b/poppler/XRef.h @@ -117,7 +117,7 @@ public: GBool getStreamEnd(Guint streamStart, Guint *streamEnd); // Retuns the entry that belongs to the offset - int getNumEntry(Guint offset) const; + int getNumEntry(Guint offset); // Direct access. int getSize() { return size; } -- 1.6.4.2 From d1849ee55fb37f20db86e7a5cf2f44e63478cd66 Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Thu, 15 Apr 2010 17:34:13 +0200 Subject: [PATCH 05/12] Read XRef table sections on demand --- poppler/XRef.cc | 37 ++++++++++++++++++++++++++++++++----- poppler/XRef.h | 6 ++++-- 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/poppler/XRef.cc b/poppler/XRef.cc index d615ec0..a0c77fc 100644 --- a/poppler/XRef.cc +++ b/poppler/XRef.cc @@ -242,7 +242,6 @@ XRef::XRef() { } XRef::XRef(BaseStream *strA) { - Guint pos; Object obj; init(); @@ -254,11 +253,11 @@ XRef::XRef(BaseStream *strA) { // read the trailer str = strA; start = str->getStart(); - pos = getStartXref(); + prevXRefOffset = pos; // if there was a problem with the 'startxref' position, try to // reconstruct the xref table - if (pos == 0) { + if (prevXRefOffset == 0) { if (!(ok = constructXRef())) { errCode = errDamaged; return; @@ -266,7 +265,7 @@ XRef::XRef(BaseStream *strA) { // read the xref table } else { - while (readXRef(&pos)) ; + readXRef(&prevXRefOffset); // if there was a problem with the xref table, // try to reconstruct it @@ -278,6 +277,18 @@ XRef::XRef(BaseStream *strA) { } } + // set size according to trailer dict + trailerDict.dictLookupNF("Size", &obj); + if (obj.isInt() && (resize(obj.getInt()) == obj.getInt())) { + obj.free(); + } else { + obj.free(); + if (!(ok = constructXRef())) { + errCode = errDamaged; + return; + } + } + // get the root dictionary (catalog) object trailerDict.dictLookupNF("Root", &obj); if (obj.isRef()) { @@ -340,7 +351,7 @@ int XRef::resize(int newSize) for (int i = size; i < newSize; ++i) { entries[i].offset = 0xffffffff; - entries[i].type = xrefEntryFree; + entries[i].type = xrefEntryNone; entries[i].obj.initNull (); entries[i].updated = false; entries[i].gen = 0; @@ -1194,3 +1205,19 @@ void XRef::writeToFile(OutStream* outStr, GBool writeAllEntries) { } } +XRefEntry *XRef::getEntry(int i) +{ + if (entries[i].type == xrefEntryNone) { + + while (readXRef(&prevXRefOffset) && (entries[i].type == xrefEntryNone)) ; + + if (entries[i].type == xrefEntryNone) { + error(-1, "Invalid XRef entry"); + entries[i].type = xrefEntryFree; + } + } + + return &entries[i]; +} + + diff --git a/poppler/XRef.h b/poppler/XRef.h index 344b764..a013e5a 100644 --- a/poppler/XRef.h +++ b/poppler/XRef.h @@ -45,7 +45,8 @@ class ObjectStream; enum XRefEntryType { xrefEntryFree, xrefEntryUncompressed, - xrefEntryCompressed + xrefEntryCompressed, + xrefEntryNone }; struct XRefEntry { @@ -121,7 +122,7 @@ public: // Direct access. int getSize() { return size; } - XRefEntry *getEntry(int i) { return &entries[i]; } + XRefEntry *getEntry(int i); Object *getTrailerDict() { return &trailerDict; } // Write access @@ -155,6 +156,7 @@ private: int permFlags; // permission bits Guchar fileKey[16]; // file decryption key GBool ownerPasswordOk; // true if owner password is correct + Guint prevXRefOffset; // position of prev XRef section (= next to read) void init(); int reserve(int newSize); -- 1.6.4.2 From 298adf8080b96fa7d4c2534c087ab50453ddb679 Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Wed, 24 Mar 2010 18:26:17 +0100 Subject: [PATCH 06/12] Add Linearization dictionary support --- CMakeLists.txt | 2 + poppler/Linearization.cc | 212 ++++++++++++++++++++++++++++++++++++++++++++++ poppler/Linearization.h | 45 ++++++++++ poppler/Makefile.am | 2 + poppler/PDFDoc.cc | 13 +++ poppler/PDFDoc.h | 5 + 6 files changed, 279 insertions(+), 0 deletions(-) create mode 100644 poppler/Linearization.cc create mode 100644 poppler/Linearization.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 1eba1fe..a119a6d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -249,6 +249,7 @@ set(poppler_SRCS poppler/JBIG2Stream.cc poppler/Lexer.cc poppler/Link.cc + poppler/Linearization.cc poppler/LocalPDFDocBuilder.cc poppler/NameToCharCode.cc poppler/Object.cc @@ -394,6 +395,7 @@ if(ENABLE_XPDF_HEADERS) poppler/JBIG2Stream.h poppler/Lexer.h poppler/Link.h + poppler/Linearization.h poppler/LocalPDFDocBuilder.h poppler/Movie.h poppler/NameToCharCode.h diff --git a/poppler/Linearization.cc b/poppler/Linearization.cc new file mode 100644 index 0000000..b2791c8 --- /dev/null +++ b/poppler/Linearization.cc @@ -0,0 +1,212 @@ +//======================================================================== +// +// Linearization.cc +// +// This file is licensed under the GPLv2 or later +// +// Copyright 2010 Hib Eris +// +//======================================================================== + +#include "Linearization.h" +#include "Parser.h" +#include "Lexer.h" + +//------------------------------------------------------------------------ +// Linearization +//------------------------------------------------------------------------ + +Linearization::Linearization (BaseStream *str) +{ + Parser *parser; + Object obj1, obj2, obj3, obj4, obj5; + + linDict.initNull(); + + str->reset(); + obj1.initNull(); + parser = new Parser(NULL, + new Lexer(NULL, str->makeSubStream(str->getStart(), gFalse, 0, &obj1)), + gTrue); + parser->getObj(&obj1); + parser->getObj(&obj2); + parser->getObj(&obj3); + parser->getObj(&linDict); + parser->getObj(&obj4); + if (obj1.isInt() && obj2.isInt() && obj3.isCmd("obj") && linDict.isDict()) { + linDict.dictLookup("Linearized", &obj5); + if (!(obj5.isNum() && obj5.getNum() > 0)) { + linDict.free(); + linDict.initNull(); + } + obj5.free(); + } + obj4.free(); + obj4.free(); + obj3.free(); + obj2.free(); + obj1.free(); + delete parser; +} + +Linearization:: ~Linearization() +{ + linDict.free(); +} + +Guint Linearization::getLength() +{ + int length = -1; + + if (linDict.isDict()) { + linDict.getDict()->lookupInt("L", NULL, &length); + } + + return length; +} + +Guint Linearization::getHintsOffset() +{ + int hintsOffset = -1; + + Object obj1, obj2; + + if (linDict.isDict()) { + linDict.dictLookup("H", &obj1); + if (obj1.isArray() && (obj1.arrayGetLength()>=1)) { + obj1.arrayGet(0, &obj2); + if (obj2.isInt()) { + hintsOffset = obj2.getInt(); + } + obj2.free(); + } + obj1.free(); + } + + return hintsOffset; +} + +Guint Linearization::getHintsLength() +{ + int hintsLength = -1; + + Object obj1, obj2; + + if (linDict.isDict()) { + linDict.dictLookup("H", &obj1); + if (obj1.isArray() && (obj1.arrayGetLength()>=2)) { + obj1.arrayGet(1, &obj2); + if (obj2.isInt()) { + hintsLength = obj2.getInt(); + } + obj2.free(); + } + obj1.free(); + } + + return hintsLength; +} + +Guint Linearization::getHintsOffset2() +{ + int hintsOffset2 = -1; + + Object obj1, obj2; + + if (linDict.isDict()) { + linDict.dictLookup("H", &obj1); + if (obj1.isArray() && (obj1.arrayGetLength()>=3)) { + obj1.arrayGet(2, &obj2); + if (obj2.isInt()) { + hintsOffset2 = obj2.getInt(); + } + obj2.free(); + } + obj1.free(); + } + + return hintsOffset2; +} + +Guint Linearization::getHintsLength2() +{ + int hintsLength2 = -1; + + Object obj1, obj2; + + if (linDict.isDict()) { + linDict.dictLookup("H", &obj1); + if (obj1.isArray() && (obj1.arrayGetLength()>=4)) { + obj1.arrayGet(3, &obj2); + if (obj2.isInt()) { + hintsLength2 = obj2.getInt(); + } + obj2.free(); + } + obj1.free(); + } + + return hintsLength2; +} + +int Linearization::getObjectNumberFirst() +{ + int objectNumberFirst = -1; + + if (linDict.isDict()) { + linDict.getDict()->lookupInt("O", NULL, &objectNumberFirst); + } + + return objectNumberFirst; +} + + +Guint Linearization::getEndFirst() +{ + int pageEndFirst = -1; + + if (linDict.isDict()) { + linDict.getDict()->lookupInt("E", NULL, &pageEndFirst); + } + + return pageEndFirst; +} + +int Linearization::getNumPages() +{ + int numPages; + + if (linDict.isDict() && + linDict.getDict()->lookupInt("N", NULL, &numPages) && + numPages > 0) { + return numPages; + } else { + error(-1, "Page count in linearization table is invalid"); + return 0; + } +} + +Guint Linearization::getMainXRefEntriesOffset() +{ + int mainXRefEntriesOffset = -1; + + if (linDict.isDict()) { + linDict.getDict()->lookupInt("T", NULL, &mainXRefEntriesOffset); + } + + return mainXRefEntriesOffset; +} + +int Linearization::getPageFirst() +{ + int pageFirst = 1; // Optional, defaults to 1. + + if (linDict.isDict() && + linDict.getDict()->lookupInt("P", NULL, &pageFirst)) { + pageFirst++; + } + + return pageFirst; +} + + diff --git a/poppler/Linearization.h b/poppler/Linearization.h new file mode 100644 index 0000000..6728a75 --- /dev/null +++ b/poppler/Linearization.h @@ -0,0 +1,45 @@ +//======================================================================== +// +// Linearization.h +// +// This file is licensed under the GPLv2 or later +// +// Copyright 2010 Hib Eris +// +//======================================================================== + +#ifndef LINEARIZATION_H +#define LINEARIZATION_H + +#include "goo/gtypes.h" +#include "Object.h" +class BaseStream; + +//------------------------------------------------------------------------ +// Linearization +//------------------------------------------------------------------------ + +class Linearization { +public: + + Linearization(BaseStream *str); + ~Linearization(); + + Guint getLength(); + Guint getHintsOffset(); + Guint getHintsLength(); + Guint getHintsOffset2(); + Guint getHintsLength2(); + int getObjectNumberFirst(); + Guint getEndFirst(); + int getNumPages(); + Guint getMainXRefEntriesOffset(); + int getPageFirst(); + +private: + + Object linDict; + +}; + +#endif diff --git a/poppler/Makefile.am b/poppler/Makefile.am index 5dd8082..8c1e019 100644 --- a/poppler/Makefile.am +++ b/poppler/Makefile.am @@ -209,6 +209,7 @@ poppler_include_HEADERS = \ JArithmeticDecoder.h \ JBIG2Stream.h \ Lexer.h \ + Linearization.h \ Link.h \ LocalPDFDocBuilder.h \ Movie.h \ @@ -287,6 +288,7 @@ libpoppler_la_SOURCES = \ JArithmeticDecoder.cc \ JBIG2Stream.cc \ Lexer.cc \ + Linearization.cc \ Link.cc \ LocalPDFDocBuilder.cc \ Movie.cc \ diff --git a/poppler/PDFDoc.cc b/poppler/PDFDoc.cc index 2d1477d..fe568a0 100644 --- a/poppler/PDFDoc.cc +++ b/poppler/PDFDoc.cc @@ -52,6 +52,7 @@ #include "Catalog.h" #include "Stream.h" #include "XRef.h" +#include "Linearization.h" #include "Link.h" #include "OutputDev.h" #include "Error.h" @@ -82,6 +83,7 @@ void PDFDoc::init() file = NULL; str = NULL; xref = NULL; + linearization = NULL; catalog = NULL; #ifndef DISABLE_OUTLINE outline = NULL; @@ -242,6 +244,9 @@ PDFDoc::~PDFDoc() { if (xref) { delete xref; } + if (linearization) { + delete linearization; + } if (str) { delete str; } @@ -412,6 +417,14 @@ void PDFDoc::processLinks(OutputDev *out, int page) { catalog->getPage(page)->processLinks(out, catalog); } +Linearization *PDFDoc::getLinearization() +{ + if (!linearization) { + linearization = new Linearization(str); + } + return linearization; +} + GBool PDFDoc::isLinearized() { Parser *parser; Object obj1, obj2, obj3, obj4, obj5; diff --git a/poppler/PDFDoc.h b/poppler/PDFDoc.h index 6d7dea2..011f4c0 100644 --- a/poppler/PDFDoc.h +++ b/poppler/PDFDoc.h @@ -48,6 +48,7 @@ class Links; class LinkAction; class LinkDest; class Outline; +class Linearization; enum PDFWriteMode { writeStandard, @@ -89,6 +90,9 @@ public: // Get file name. GooString *getFileName() { return fileName; } + // Get the linearization table. + Linearization *getLinearization(); + // Get the xref table. XRef *getXRef() { return xref; } @@ -242,6 +246,7 @@ private: void *guiData; int pdfMajorVersion; int pdfMinorVersion; + Linearization *linearization; XRef *xref; Catalog *catalog; #ifndef DISABLE_OUTLINE -- 1.6.4.2 From 677e771b646c62788bdad0ad1dbeeb953c29f737 Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Tue, 13 Apr 2010 18:51:40 +0200 Subject: [PATCH 07/12] Add getLength() to BaseStream --- poppler/Stream.cc | 11 ++++++----- poppler/Stream.h | 11 ++++++----- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/poppler/Stream.cc b/poppler/Stream.cc index 0771e25..f4f9351 100644 --- a/poppler/Stream.cc +++ b/poppler/Stream.cc @@ -363,8 +363,9 @@ void FileOutStream::printf(const char *format, ...) // BaseStream //------------------------------------------------------------------------ -BaseStream::BaseStream(Object *dictA) { +BaseStream::BaseStream(Object *dictA, Guint lengthA) { dict = *dictA; + length = lengthA; } BaseStream::~BaseStream() { @@ -677,7 +678,7 @@ GBool StreamPredictor::getNextLine() { FileStream::FileStream(FILE *fA, Guint startA, GBool limitedA, Guint lengthA, Object *dictA): - BaseStream(dictA) { + BaseStream(dictA, lengthA) { f = fA; start = startA; limited = limitedA; @@ -802,7 +803,7 @@ void FileStream::moveStart(int delta) { CachedFileStream::CachedFileStream(CachedFile *ccA, Guint startA, GBool limitedA, Guint lengthA, Object *dictA) - : BaseStream(dictA) + : BaseStream(dictA, lengthA) { cc = ccA; start = startA; @@ -900,7 +901,7 @@ void CachedFileStream::moveStart(int delta) //------------------------------------------------------------------------ MemStream::MemStream(char *bufA, Guint startA, Guint lengthA, Object *dictA): - BaseStream(dictA) { + BaseStream(dictA, lengthA) { buf = bufA; start = startA; length = lengthA; @@ -964,7 +965,7 @@ void MemStream::moveStart(int delta) { EmbedStream::EmbedStream(Stream *strA, Object *dictA, GBool limitedA, Guint lengthA): - BaseStream(dictA) { + BaseStream(dictA, lengthA) { str = strA; limited = limitedA; length = lengthA; diff --git a/poppler/Stream.h b/poppler/Stream.h index 49ae8fb..6896d20 100644 --- a/poppler/Stream.h +++ b/poppler/Stream.h @@ -240,7 +240,7 @@ private: class BaseStream: public Stream { public: - BaseStream(Object *dictA); + BaseStream(Object *dictA, Guint lengthA); virtual ~BaseStream(); virtual Stream *makeSubStream(Guint start, GBool limited, Guint length, Object *dict) = 0; @@ -250,11 +250,16 @@ public: virtual Stream *getUndecodedStream() { return this; } virtual Dict *getDict() { return dict.getDict(); } virtual GooString *getFileName() { return NULL; } + virtual Guint getLength() { return length; } // Get/set position of first byte of stream within the file. virtual Guint getStart() = 0; virtual void moveStart(int delta) = 0; +protected: + + Guint length; + private: Object dict; @@ -401,7 +406,6 @@ private: FILE *f; Guint start; GBool limited; - Guint length; char buf[fileStreamBufSize]; char *bufPtr; char *bufEnd; @@ -446,7 +450,6 @@ private: CachedFile *cc; Guint start; GBool limited; - Guint length; char buf[cachedStreamBufSize]; char *bufPtr; char *bufEnd; @@ -490,7 +493,6 @@ private: char *buf; Guint start; - Guint length; char *bufEnd; char *bufPtr; GBool needFree; @@ -530,7 +532,6 @@ private: Stream *str; GBool limited; - Guint length; }; //------------------------------------------------------------------------ -- 1.6.4.2 From b7f47f34df6da648b34a810e07baf2ba1a4cd32e Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Wed, 24 Mar 2010 19:16:14 +0100 Subject: [PATCH 08/12] Pass size of file when creating FileStream --- poppler/PDFDoc.cc | 19 +++++++++++++++++-- 1 files changed, 17 insertions(+), 2 deletions(-) diff --git a/poppler/PDFDoc.cc b/poppler/PDFDoc.cc index fe568a0..0a018fd 100644 --- a/poppler/PDFDoc.cc +++ b/poppler/PDFDoc.cc @@ -44,6 +44,7 @@ #ifdef _WIN32 # include #endif +#include #include "goo/gstrtod.h" #include "goo/GooString.h" #include "poppler-config.h" @@ -98,12 +99,18 @@ PDFDoc::PDFDoc() PDFDoc::PDFDoc(GooString *fileNameA, GooString *ownerPassword, GooString *userPassword, void *guiDataA) { Object obj; + int size = 0; init(); fileName = fileNameA; guiData = guiDataA; + struct stat buf; + if (stat(fileName->getCString(), &buf) == 0) { + size = buf.st_size; + } + // try to open file #ifdef VMS file = fopen(fileName->getCString(), "rb", "ctx=stm"); @@ -123,7 +130,7 @@ PDFDoc::PDFDoc(GooString *fileNameA, GooString *ownerPassword, // create stream obj.initNull(); - str = new FileStream(file, 0, gFalse, 0, &obj); + str = new FileStream(file, 0, gFalse, size, &obj); ok = setup(ownerPassword, userPassword); } @@ -154,11 +161,19 @@ PDFDoc::PDFDoc(wchar_t *fileNameA, int fileNameLen, GooString *ownerPassword, // try to open file // NB: _wfopen is only available in NT + struct stat buf; + int size; version.dwOSVersionInfoSize = sizeof(version); GetVersionEx(&version); if (version.dwPlatformId == VER_PLATFORM_WIN32_NT) { + if (_wstat(fileName2, &buf) == 0) { + size = buf.st_size; + } file = _wfopen(fileName2, L"rb"); } else { + if (_wstat(fileName->getCString(), &buf) == 0) { + size = buf.st_size; + } file = fopen(fileName->getCString(), "rb"); } if (!file) { @@ -169,7 +184,7 @@ PDFDoc::PDFDoc(wchar_t *fileNameA, int fileNameLen, GooString *ownerPassword, // create stream obj.initNull(); - str = new FileStream(file, 0, gFalse, 0, &obj); + str = new FileStream(file, 0, gFalse, size, &obj); ok = setup(ownerPassword, userPassword); } -- 1.6.4.2 From cd0ffbf22dabb7582ac5e64b0dfbce31eb50e99c Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Wed, 24 Mar 2010 19:32:59 +0100 Subject: [PATCH 09/12] Improve linearization check --- poppler/PDFDoc.cc | 33 +++++---------------------------- 1 files changed, 5 insertions(+), 28 deletions(-) diff --git a/poppler/PDFDoc.cc b/poppler/PDFDoc.cc index 0a018fd..35f5cc9 100644 --- a/poppler/PDFDoc.cc +++ b/poppler/PDFDoc.cc @@ -441,34 +441,11 @@ Linearization *PDFDoc::getLinearization() } GBool PDFDoc::isLinearized() { - Parser *parser; - Object obj1, obj2, obj3, obj4, obj5; - GBool lin; - - lin = gFalse; - obj1.initNull(); - parser = new Parser(xref, - new Lexer(xref, - str->makeSubStream(str->getStart(), gFalse, 0, &obj1)), - gTrue); - parser->getObj(&obj1); - parser->getObj(&obj2); - parser->getObj(&obj3); - parser->getObj(&obj4); - if (obj1.isInt() && obj2.isInt() && obj3.isCmd("obj") && - obj4.isDict()) { - obj4.dictLookup("Linearized", &obj5); - if (obj5.isNum() && obj5.getNum() > 0) { - lin = gTrue; - } - obj5.free(); - } - obj4.free(); - obj3.free(); - obj2.free(); - obj1.free(); - delete parser; - return lin; + if ((str->getLength()) && + (getLinearization()->getLength() == str->getLength())) + return gTrue; + else + return gFalse; } int PDFDoc::saveAs(GooString *name, PDFWriteMode mode) { -- 1.6.4.2 From 15c02cc41e8af2e0d73b435c843e19cd8d904c93 Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Wed, 7 Apr 2010 12:05:56 +0200 Subject: [PATCH 10/12] Move getStartXref from XRef to PDFDoc --- poppler/PDFDoc.cc | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++- poppler/PDFDoc.h | 5 ++++ poppler/XRef.cc | 50 +------------------------------------------ poppler/XRef.h | 6 +---- 4 files changed, 66 insertions(+), 56 deletions(-) diff --git a/poppler/PDFDoc.cc b/poppler/PDFDoc.cc index 35f5cc9..6c4159a 100644 --- a/poppler/PDFDoc.cc +++ b/poppler/PDFDoc.cc @@ -34,6 +34,7 @@ #pragma implementation #endif +#include #include #include #include @@ -72,6 +73,9 @@ #define headerSearchSize 1024 // read this many bytes at beginning of // file to look for '%PDF' +#define xrefSearchSize 1024 // read this many bytes at end of file + // to look for 'startxref' + //------------------------------------------------------------------------ // PDFDoc //------------------------------------------------------------------------ @@ -89,6 +93,7 @@ void PDFDoc::init() #ifndef DISABLE_OUTLINE outline = NULL; #endif + startXRefPos = ~(Guint)0; } PDFDoc::PDFDoc() @@ -222,7 +227,7 @@ GBool PDFDoc::setup(GooString *ownerPassword, GooString *userPassword) { checkHeader(); // read xref table - xref = new XRef(str); + xref = new XRef(str, getStartXRef()); if (!xref->isOk()) { error(-1, "Couldn't read xref table"); errCode = xref->getErrorCode(); @@ -889,7 +894,7 @@ void PDFDoc::writeTrailer (Guint uxrefOffset, int uxrefSize, OutStream* outStr, trailerDict->set("Root", &obj1); if (incrUpdate) { - obj1.initInt(xref->getLastXRefPos()); + obj1.initInt(getStartXRef()); trailerDict->set("Prev", &obj1); } @@ -927,3 +932,55 @@ PDFDoc *PDFDoc::ErrorPDFDoc(int errorCode, GooString *fileNameA) return doc; } + +Guint PDFDoc::strToUnsigned(char *s) { + Guint x; + char *p; + int i; + + x = 0; + for (p = s, i = 0; *p && isdigit(*p) && i < 10; ++p, ++i) { + x = 10 * x + (*p - '0'); + } + return x; +} + +// Read the 'startxref' position. +Guint PDFDoc::getStartXRef() +{ + if (startXRefPos == ~(Guint)0) { + + { + char buf[xrefSearchSize+1]; + char *p; + int c, n, i; + + // read last xrefSearchSize bytes + str->setPos(xrefSearchSize, -1); + for (n = 0; n < xrefSearchSize; ++n) { + if ((c = str->getChar()) == EOF) { + break; + } + buf[n] = c; + } + buf[n] = '\0'; + + // find startxref + for (i = n - 9; i >= 0; --i) { + if (!strncmp(&buf[i], "startxref", 9)) { + break; + } + } + if (i < 0) { + startXRefPos = 0; + } + for (p = &buf[i+9]; isspace(*p); ++p) ; + startXRefPos = strToUnsigned(p); + } + + } + + return startXRefPos; +} + + diff --git a/poppler/PDFDoc.h b/poppler/PDFDoc.h index 011f4c0..d093b59 100644 --- a/poppler/PDFDoc.h +++ b/poppler/PDFDoc.h @@ -239,6 +239,9 @@ private: GBool checkFooter(); void checkHeader(); GBool checkEncryption(GooString *ownerPassword, GooString *userPassword); + // Get the offset of the start xref table. + Guint getStartXRef(); + Guint strToUnsigned(char *s); GooString *fileName; FILE *file; @@ -258,6 +261,8 @@ private: //If there is an error opening the PDF file with fopen() in the constructor, //then the POSIX errno will be here. int fopenErrno; + + Guint startXRefPos; // offset of last xref table }; #endif diff --git a/poppler/XRef.cc b/poppler/XRef.cc index a0c77fc..b69bf9a 100644 --- a/poppler/XRef.cc +++ b/poppler/XRef.cc @@ -47,11 +47,6 @@ #include "XRef.h" //------------------------------------------------------------------------ - -#define xrefSearchSize 1024 // read this many bytes at end of file - // to look for 'startxref' - -//------------------------------------------------------------------------ // Permission bits // Note that the PDF spec uses 1 base (eg bit 3 is 1<<2) //------------------------------------------------------------------------ @@ -241,7 +236,7 @@ XRef::XRef() { init(); } -XRef::XRef(BaseStream *strA) { +XRef::XRef(BaseStream *strA, Guint pos) { Object obj; init(); @@ -367,37 +362,6 @@ int XRef::resize(int newSize) return size; } -// Read the 'startxref' position. -Guint XRef::getStartXref() { - char buf[xrefSearchSize+1]; - char *p; - int c, n, i; - - // read last xrefSearchSize bytes - str->setPos(xrefSearchSize, -1); - for (n = 0; n < xrefSearchSize; ++n) { - if ((c = str->getChar()) == EOF) { - break; - } - buf[n] = c; - } - buf[n] = '\0'; - - // find startxref - for (i = n - 9; i >= 0; --i) { - if (!strncmp(&buf[i], "startxref", 9)) { - break; - } - } - if (i < 0) { - return 0; - } - for (p = &buf[i+9]; isspace(*p); ++p) ; - lastXRefPos = strToUnsigned(p); - - return lastXRefPos; -} - // Read one xref table section. Also reads the associated trailer // dictionary, and returns the prev pointer (if any). GBool XRef::readXRef(Guint *pos) { @@ -1079,18 +1043,6 @@ int XRef::getNumEntry(Guint offset) else return -1; } -Guint XRef::strToUnsigned(char *s) { - Guint x; - char *p; - int i; - - x = 0; - for (p = s, i = 0; *p && isdigit(*p) && i < 10; ++p, ++i) { - x = 10 * x + (*p - '0'); - } - return x; -} - void XRef::add(int num, int gen, Guint offs, GBool used) { if (num >= size) { if (num >= capacity) { diff --git a/poppler/XRef.h b/poppler/XRef.h index a013e5a..7cd8ebe 100644 --- a/poppler/XRef.h +++ b/poppler/XRef.h @@ -63,7 +63,7 @@ public: // Constructor, create an empty XRef, used for PDF writing XRef(); // Constructor. Read xref table from stream. - XRef(BaseStream *strA); + XRef(BaseStream *strA, Guint pos); // Destructor. ~XRef(); @@ -106,9 +106,6 @@ public: // Return the number of objects in the xref table. int getNumObjects() { return size; } - // Return the offset of the last xref table. - Guint getLastXRefPos() { return lastXRefPos; } - // Return the catalog object reference. int getRootNum() { return rootNum; } int getRootGen() { return rootGen; } @@ -143,7 +140,6 @@ private: GBool ok; // true if xref table is valid int errCode; // error code (if is false) Object trailerDict; // trailer dictionary - Guint lastXRefPos; // offset of last xref table Guint *streamEnds; // 'endstream' positions - only used in // damaged files int streamEndsLen; // number of valid entries in streamEnds -- 1.6.4.2 From a4caf1906288f6cf40f1bfa842ea08425c32b967 Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Wed, 7 Apr 2010 12:35:05 +0200 Subject: [PATCH 11/12] Use XRef table at start of linearized document --- poppler/PDFDoc.cc | 27 ++++++++++++++++++++++++++- 1 files changed, 26 insertions(+), 1 deletions(-) diff --git a/poppler/PDFDoc.cc b/poppler/PDFDoc.cc index 6c4159a..e590f3c 100644 --- a/poppler/PDFDoc.cc +++ b/poppler/PDFDoc.cc @@ -73,6 +73,10 @@ #define headerSearchSize 1024 // read this many bytes at beginning of // file to look for '%PDF' +#define linearizationSearchSize 1024 // read this many bytes at beginning of + // file to look for linearization + // dictionary + #define xrefSearchSize 1024 // read this many bytes at end of file // to look for 'startxref' @@ -950,7 +954,28 @@ Guint PDFDoc::getStartXRef() { if (startXRefPos == ~(Guint)0) { - { + if (isLinearized()) { + char buf[linearizationSearchSize+1]; + int c, n, i; + + str->setPos(0); + for (n = 0; n < linearizationSearchSize; ++n) { + if ((c = str->getChar()) == EOF) { + break; + } + buf[n] = c; + } + buf[n] = '\0'; + + // find end of first obj + startXRefPos = 0; + for (i = 0; i < n; i++) { + if (!strncmp("endobj", &buf[i], 6)) { + startXRefPos = i+6; + break; + } + } + } else { char buf[xrefSearchSize+1]; char *p; int c, n, i; -- 1.6.4.2 From 25dcd380a03b911b300691502d1641425693c766 Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Sun, 25 Apr 2010 17:34:49 +0200 Subject: [PATCH 12/12] Use linearization data to parse XRef entries --- poppler/PDFDoc.cc | 12 +++++++++++- poppler/PDFDoc.h | 3 +++ poppler/XRef.cc | 45 +++++++++++++++++++++++++++++++++++++++++++-- poppler/XRef.h | 6 +++++- 4 files changed, 62 insertions(+), 4 deletions(-) diff --git a/poppler/PDFDoc.cc b/poppler/PDFDoc.cc index e590f3c..172f766 100644 --- a/poppler/PDFDoc.cc +++ b/poppler/PDFDoc.cc @@ -231,7 +231,7 @@ GBool PDFDoc::setup(GooString *ownerPassword, GooString *userPassword) { checkHeader(); // read xref table - xref = new XRef(str, getStartXRef()); + xref = new XRef(str, getStartXRef(), getMainXRefEntriesOffset()); if (!xref->isOk()) { error(-1, "Couldn't read xref table"); errCode = xref->getErrorCode(); @@ -1008,4 +1008,14 @@ Guint PDFDoc::getStartXRef() return startXRefPos; } +Guint PDFDoc::getMainXRefEntriesOffset() +{ + Guint mainXRefEntriesOffset = 0; + + if (isLinearized()) { + mainXRefEntriesOffset = getLinearization()->getMainXRefEntriesOffset(); + } + + return mainXRefEntriesOffset; +} diff --git a/poppler/PDFDoc.h b/poppler/PDFDoc.h index d093b59..f6f8c8f 100644 --- a/poppler/PDFDoc.h +++ b/poppler/PDFDoc.h @@ -241,6 +241,9 @@ private: GBool checkEncryption(GooString *ownerPassword, GooString *userPassword); // Get the offset of the start xref table. Guint getStartXRef(); + // Get the offset of the entries in the main XRef table of a + // linearized document (0 for non linearized documents). + Guint getMainXRefEntriesOffset(); Guint strToUnsigned(char *s); GooString *fileName; diff --git a/poppler/XRef.cc b/poppler/XRef.cc index b69bf9a..ab92cd8 100644 --- a/poppler/XRef.cc +++ b/poppler/XRef.cc @@ -230,16 +230,19 @@ void XRef::init() { streamEnds = NULL; streamEndsLen = 0; objStr = NULL; + mainXRefEntriesOffset = 0; + xRefStream = gFalse; } XRef::XRef() { init(); } -XRef::XRef(BaseStream *strA, Guint pos) { +XRef::XRef(BaseStream *strA, Guint pos, Guint mainXRefEntriesOffsetA) { Object obj; init(); + mainXRefEntriesOffset = mainXRefEntriesOffsetA; encrypted = gFalse; permFlags = defPermFlags; @@ -396,6 +399,9 @@ GBool XRef::readXRef(Guint *pos) { if (!parser->getObj(&obj)->isStream()) { goto err1; } + if (trailerDict.isNone()) { + xRefStream = gTrue; + } more = readXRefStream(obj.getStream(), pos); obj.free(); @@ -1157,11 +1163,46 @@ void XRef::writeToFile(OutStream* outStr, GBool writeAllEntries) { } } +GBool XRef::parseEntry(Guint offset, XRefEntry *entry) +{ + GBool r; + + Object obj; + obj.initNull(); + Parser parser = Parser(NULL, new Lexer(NULL, + str->makeSubStream(offset, gFalse, 20, &obj)), gTrue); + + Object obj1, obj2, obj3; + if ((parser.getObj(&obj1)->isInt()) && + (parser.getObj(&obj2)->isInt()) && + (parser.getObj(&obj3)->isCmd("n") || obj3.isCmd("f"))) { + entry->offset = (Guint) obj1.getInt(); + entry->gen = obj2.getInt(); + entry->type = obj3.isCmd("n") ? xrefEntryUncompressed : xrefEntryFree; + entry->obj.initNull (); + entry->updated = false; + r = gTrue; + } else { + r = gFalse; + } + obj1.free(); + obj2.free(); + obj3.free(); + + return r; +} + XRefEntry *XRef::getEntry(int i) { if (entries[i].type == xrefEntryNone) { - while (readXRef(&prevXRefOffset) && (entries[i].type == xrefEntryNone)) ; + if ((!xRefStream) && mainXRefEntriesOffset) { + if (!parseEntry(mainXRefEntriesOffset + 20*i, &entries[i])) { + error(-1, "Failed to parse XRef entry [%d].", i); + } + } else { + while (readXRef(&prevXRefOffset) && (entries[i].type == xrefEntryNone)) ; + } if (entries[i].type == xrefEntryNone) { error(-1, "Invalid XRef entry"); diff --git a/poppler/XRef.h b/poppler/XRef.h index 7cd8ebe..a4548e6 100644 --- a/poppler/XRef.h +++ b/poppler/XRef.h @@ -63,7 +63,7 @@ public: // Constructor, create an empty XRef, used for PDF writing XRef(); // Constructor. Read xref table from stream. - XRef(BaseStream *strA, Guint pos); + XRef(BaseStream *strA, Guint pos, Guint mainXRefEntriesOffsetA = 0); // Destructor. ~XRef(); @@ -153,6 +153,8 @@ private: Guchar fileKey[16]; // file decryption key GBool ownerPasswordOk; // true if owner password is correct Guint prevXRefOffset; // position of prev XRef section (= next to read) + Guint mainXRefEntriesOffset; // offset of entries in main XRef table + GBool xRefStream; // true if last XRef section is a stream void init(); int reserve(int newSize); @@ -164,6 +166,8 @@ private: GBool readXRefStream(Stream *xrefStr, Guint *pos); GBool constructXRef(); Guint strToUnsigned(char *s); + GBool parseEntry(Guint offset, XRefEntry *entry); + }; #endif -- 1.6.4.2 -------------- next part -------------- From 2159c5ac797fcedaeef2191d03acf12bd8351cb1 Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Tue, 20 Apr 2010 19:03:54 +0200 Subject: [PATCH 01/15] add PDFDoc::getPage() --- poppler/PDFDoc.cc | 8 ++++++++ poppler/PDFDoc.h | 3 +++ 2 files changed, 11 insertions(+), 0 deletions(-) diff --git a/poppler/PDFDoc.cc b/poppler/PDFDoc.cc index 172f766..b52b280 100644 --- a/poppler/PDFDoc.cc +++ b/poppler/PDFDoc.cc @@ -1019,3 +1019,11 @@ Guint PDFDoc::getMainXRefEntriesOffset() return mainXRefEntriesOffset; } +Page *PDFDoc::getPage(int page) +{ + if ((page < 1) || page > getNumPages()) return NULL; + + { + return catalog->getPage(page); + } +} diff --git a/poppler/PDFDoc.h b/poppler/PDFDoc.h index f6f8c8f..011e6e1 100644 --- a/poppler/PDFDoc.h +++ b/poppler/PDFDoc.h @@ -127,6 +127,9 @@ public: // Return the structure tree root object. Object *getStructTreeRoot() { return catalog->getStructTreeRoot(); } + // Get page. + Page *getPage(int page); + // Display a page. void displayPage(OutputDev *out, int page, double hDPI, double vDPI, int rotate, -- 1.6.4.2 From 5de023c53f1c9581b2cb7ca322bb8f2045d8fc0d Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Tue, 20 Apr 2010 19:36:08 +0200 Subject: [PATCH 02/15] Use PDFDoc::getPage() in PDFDoc --- poppler/PDFDoc.cc | 28 +++++++++++++++++++++------- poppler/PDFDoc.h | 10 +++++----- 2 files changed, 26 insertions(+), 12 deletions(-) diff --git a/poppler/PDFDoc.cc b/poppler/PDFDoc.cc index b52b280..89dba6f 100644 --- a/poppler/PDFDoc.cc +++ b/poppler/PDFDoc.cc @@ -395,8 +395,11 @@ void PDFDoc::displayPage(OutputDev *out, int page, if (globalParams->getPrintCommands()) { printf("***** page %d *****\n", page); } - catalog->getPage(page)->display(out, hDPI, vDPI, - rotate, useMediaBox, crop, printing, catalog, + + Page *p = getPage(page); + if (!p) return; + + p->display(out, hDPI, vDPI, rotate, useMediaBox, crop, printing, catalog, abortCheckCbk, abortCheckCbkData, annotDisplayDecideCbk, annotDisplayDecideCbkData); } @@ -425,8 +428,11 @@ void PDFDoc::displayPageSlice(OutputDev *out, int page, void *abortCheckCbkData, GBool (*annotDisplayDecideCbk)(Annot *annot, void *user_data), void *annotDisplayDecideCbkData) { - catalog->getPage(page)->displaySlice(out, hDPI, vDPI, - rotate, useMediaBox, crop, + + Page *p = getPage(page); + if (!p) return; + + p->displaySlice(out, hDPI, vDPI, rotate, useMediaBox, crop, sliceX, sliceY, sliceW, sliceH, printing, catalog, abortCheckCbk, abortCheckCbkData, @@ -434,11 +440,19 @@ void PDFDoc::displayPageSlice(OutputDev *out, int page, } Links *PDFDoc::getLinks(int page) { - return catalog->getPage(page)->getLinks(catalog); + Page *p = getPage(page); + if (!p) { + Object obj; + obj.initNull(); + return new Links (&obj, NULL); + } + return p->getLinks(catalog); } - + void PDFDoc::processLinks(OutputDev *out, int page) { - catalog->getPage(page)->processLinks(out, catalog); + Page *p = getPage(page); + if (!p) return; + p->processLinks(out, catalog); } Linearization *PDFDoc::getLinearization() diff --git a/poppler/PDFDoc.h b/poppler/PDFDoc.h index 011e6e1..8de139f 100644 --- a/poppler/PDFDoc.h +++ b/poppler/PDFDoc.h @@ -107,15 +107,15 @@ public: // Get page parameters. double getPageMediaWidth(int page) - { return catalog->getPage(page)->getMediaWidth(); } + { return getPage(page) ? getPage(page)->getMediaWidth() : 0.0 ; } double getPageMediaHeight(int page) - { return catalog->getPage(page)->getMediaHeight(); } + { return getPage(page) ? getPage(page)->getMediaHeight() : 0.0 ; } double getPageCropWidth(int page) - { return catalog->getPage(page)->getCropWidth(); } + { return getPage(page) ? getPage(page)->getCropWidth() : 0.0 ; } double getPageCropHeight(int page) - { return catalog->getPage(page)->getCropHeight(); } + { return getPage(page) ? getPage(page)->getCropHeight() : 0.0 ; } int getPageRotate(int page) - { return catalog->getPage(page)->getRotate(); } + { return getPage(page) ? getPage(page)->getRotate() : 0 ; } // Get number of pages. int getNumPages() { return catalog->getNumPages(); } -- 1.6.4.2 From 739a4430d509999901c6834a358e0fcf88e7a826 Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Tue, 20 Apr 2010 20:48:30 +0200 Subject: [PATCH 03/15] Use PDFDoc::getPage() in FontInfo --- poppler/FontInfo.cc | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-) diff --git a/poppler/FontInfo.cc b/poppler/FontInfo.cc index 0037e07..c348d14 100644 --- a/poppler/FontInfo.cc +++ b/poppler/FontInfo.cc @@ -70,7 +70,9 @@ GooList *FontInfoScanner::scan(int nPages) { } for (int pg = currentPage; pg < lastPage; ++pg) { - page = doc->getCatalog()->getPage(pg); + page = doc->getPage(pg); + if (!page) continue; + if ((resDict = page->getResourceDict())) { scanFonts(resDict, result); } -- 1.6.4.2 From e287781c5490ae23dd5506a33f814c1d33f66a8b Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Thu, 22 Apr 2010 11:11:11 +0200 Subject: [PATCH 04/15] Use PDFDoc::getPage() in pdfinfo --- utils/pdfinfo.cc | 22 +++++++++++++++------- 1 files changed, 15 insertions(+), 7 deletions(-) diff --git a/utils/pdfinfo.cc b/utils/pdfinfo.cc index 2abe8b4..a94e4e8 100644 --- a/utils/pdfinfo.cc +++ b/utils/pdfinfo.cc @@ -257,7 +257,11 @@ int main(int argc, char *argv[]) { if (printBoxes) { if (multiPage) { for (pg = firstPage; pg <= lastPage; ++pg) { - page = doc->getCatalog()->getPage(pg); + page = doc->getPage(pg); + if (!page) { + error(-1, "Failed to print boxes for page %d", pg); + continue; + } sprintf(buf, "Page %4d MediaBox: ", pg); printBox(buf, page->getMediaBox()); sprintf(buf, "Page %4d CropBox: ", pg); @@ -270,12 +274,16 @@ int main(int argc, char *argv[]) { printBox(buf, page->getArtBox()); } } else { - page = doc->getCatalog()->getPage(firstPage); - printBox("MediaBox: ", page->getMediaBox()); - printBox("CropBox: ", page->getCropBox()); - printBox("BleedBox: ", page->getBleedBox()); - printBox("TrimBox: ", page->getTrimBox()); - printBox("ArtBox: ", page->getArtBox()); + page = doc->getPage(firstPage); + if (!page) { + error(-1, "Failed to print boxes for page %d", firstPage); + } else { + printBox("MediaBox: ", page->getMediaBox()); + printBox("CropBox: ", page->getCropBox()); + printBox("BleedBox: ", page->getBleedBox()); + printBox("TrimBox: ", page->getTrimBox()); + printBox("ArtBox: ", page->getArtBox()); + } } } -- 1.6.4.2 From 8766d0369705e84f835eb80c795c3ac00d3111ff Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Thu, 22 Apr 2010 11:19:53 +0200 Subject: [PATCH 05/15] Use PDFDoc::getPage() in pdffonts --- utils/pdffonts.cc | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-) diff --git a/utils/pdffonts.cc b/utils/pdffonts.cc index 81b20e4..30e25dc 100644 --- a/utils/pdffonts.cc +++ b/utils/pdffonts.cc @@ -166,7 +166,11 @@ int main(int argc, char *argv[]) { fonts = NULL; fontsLen = fontsSize = 0; for (pg = firstPage; pg <= lastPage; ++pg) { - page = doc->getCatalog()->getPage(pg); + page = doc->getPage(pg); + if (!page) { + error(-1, "Failed to read fonts from page %d", pg); + continue; + } if ((resDict = page->getResourceDict())) { scanFonts(resDict, doc); } -- 1.6.4.2 From 8ba03542b2f29feb184e17a88bedb211eaf23adb Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Thu, 22 Apr 2010 15:52:20 +0200 Subject: [PATCH 06/15] Use PDFDoc::getPage() in glib --- glib/poppler-action.cc | 4 ++-- glib/poppler-document.cc | 17 ++++++++++------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/glib/poppler-action.cc b/glib/poppler-action.cc index ffc1842..a0f8576 100644 --- a/glib/poppler-action.cc +++ b/glib/poppler-action.cc @@ -422,13 +422,13 @@ find_annot_movie_for_action (PopplerDocument *document, xref->fetch (ref->num, ref->gen, &annotObj); } else if (link->hasAnnotTitle ()) { - Catalog *catalog = document->doc->getCatalog (); Object annots; GooString *title = link->getAnnotTitle (); int i; for (i = 1; i <= document->doc->getNumPages (); ++i) { - Page *p = catalog->getPage (i); + Page *p = document->doc->getPage (i); + if (!p) continue; if (p->getAnnots (&annots)->isArray ()) { int j; diff --git a/glib/poppler-document.cc b/glib/poppler-document.cc index cd6794a..ccb0f1c 100644 --- a/glib/poppler-document.cc +++ b/glib/poppler-document.cc @@ -379,15 +379,14 @@ PopplerPage * poppler_document_get_page (PopplerDocument *document, int index) { - Catalog *catalog; Page *page; g_return_val_if_fail (0 <= index && index < poppler_document_get_n_pages (document), NULL); - catalog = document->doc->getCatalog(); - page = catalog->getPage (index + 1); + page = document->doc->getPage (index + 1); + if (!page) return NULL; return _poppler_page_new (document, page, index); } @@ -1909,18 +1908,22 @@ PopplerFormField * poppler_document_get_form_field (PopplerDocument *document, gint id) { - Catalog *catalog = document->doc->getCatalog(); + Page *page; unsigned pageNum; unsigned fieldNum; FormPageWidgets *widgets; FormWidget *field; FormWidget::decodeID (id, &pageNum, &fieldNum); - - widgets = catalog->getPage (pageNum)->getPageWidgets (); + + page = document->doc->getPage (pageNum); + if (!page) + return NULL; + + widgets = page->getPageWidgets (); if (!widgets) return NULL; - + field = widgets->getWidget (fieldNum); if (field) return _poppler_form_field_new (document, field); -- 1.6.4.2 From 12c8bf93e3e8e38f357f3165e5a4517056a9af0b Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Thu, 22 Apr 2010 17:59:01 +0200 Subject: [PATCH 07/15] Use PDFDoc::getPage() in qt4 Note API change: With this patch, Document::Page(int index) can now return NULL when poppler fails to create a page. Any application using these bindings should check the return value. --- qt4/src/poppler-document.cc | 8 +++++++- qt4/src/poppler-link.cc | 6 ++++-- qt4/src/poppler-page.cc | 3 ++- qt4/src/poppler-qt4.h | 3 +++ 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/qt4/src/poppler-document.cc b/qt4/src/poppler-document.cc index 41d35b6..dc0ce97 100644 --- a/qt4/src/poppler-document.cc +++ b/qt4/src/poppler-document.cc @@ -98,7 +98,13 @@ namespace Poppler { Page *Document::page(int index) const { - return new Page(m_doc, index); + Page *page = new Page(m_doc, index); + if (!page->isOk()) { + delete page; + return NULL; + } + + return page; } bool Document::isLocked() const diff --git a/qt4/src/poppler-link.cc b/qt4/src/poppler-link.cc index de06242..4f54201 100644 --- a/qt4/src/poppler-link.cc +++ b/qt4/src/poppler-link.cc @@ -232,9 +232,11 @@ class LinkMoviePrivate : public LinkPrivate int leftAux = 0, topAux = 0, rightAux = 0, bottomAux = 0; - if (d->pageNum > 0 && d->pageNum <= data.doc->doc->getNumPages()) + ::Page *page; + if (d->pageNum > 0 && + d->pageNum <= data.doc->doc->getNumPages() && + (page = data.doc->doc->getPage( d->pageNum ))) { - ::Page *page = data.doc->doc->getCatalog()->getPage( d->pageNum ); cvtUserToDev( page, left, top, &leftAux, &topAux ); cvtUserToDev( page, right, bottom, &rightAux, &bottomAux ); diff --git a/qt4/src/poppler-page.cc b/qt4/src/poppler-page.cc index 6dbf50f..335f2ce 100644 --- a/qt4/src/poppler-page.cc +++ b/qt4/src/poppler-page.cc @@ -186,8 +186,9 @@ Page::Page(DocumentData *doc, int index) { m_page = new PageData(); m_page->index = index; m_page->parentDoc = doc; - m_page->page = doc->doc->getCatalog()->getPage(m_page->index + 1); + m_page->page = doc->doc->getPage(m_page->index + 1); m_page->transition = 0; + ok = m_page->page ? true : false; } Page::~Page() diff --git a/qt4/src/poppler-qt4.h b/qt4/src/poppler-qt4.h index 117dc43..2e77f48 100644 --- a/qt4/src/poppler-qt4.h +++ b/qt4/src/poppler-qt4.h @@ -587,11 +587,14 @@ delete it; **/ QString label() const; + bool isOk() { return ok; }; + private: Q_DISABLE_COPY(Page) Page(DocumentData *doc, int index); PageData *m_page; + bool ok; }; /** -- 1.6.4.2 From b9e850e99b987d15c569ad8a7ee2bb76aae413e3 Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Fri, 23 Apr 2010 09:21:23 +0200 Subject: [PATCH 08/15] Use PDFDoc::getPage() in qt Note API change: With this patch, Document::getPage(int index) can now return NULL when poppler fails to create a page. Any application using these bindings should check the return value. --- qt/poppler-document.cc | 11 +++++++++++ qt/poppler-page.cc | 11 +++++++---- qt/poppler-qt.h | 6 +++++- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/qt/poppler-document.cc b/qt/poppler-document.cc index bade1d1..1a5892b 100644 --- a/qt/poppler-document.cc +++ b/qt/poppler-document.cc @@ -113,6 +113,17 @@ int Document::getNumPages() const return data->doc.getNumPages(); } +Page *Document::getPage(int index) const +{ + Page *p = new Page(this, index); + if (!p->isOk()) { + delete p; + return NULL; + } + + return p; +} + QValueList Document::fonts() const { QValueList ourList; diff --git a/qt/poppler-page.cc b/qt/poppler-page.cc index a42aa15..ef077a7 100644 --- a/qt/poppler-page.cc +++ b/qt/poppler-page.cc @@ -47,6 +47,7 @@ class PageData { const Document *doc; int index; PageTransition *transition; + ::Page *page; }; Page::Page(const Document *doc, int index) { @@ -54,6 +55,8 @@ Page::Page(const Document *doc, int index) { data->index = index; data->doc = doc; data->transition = 0; + data->page = doc->data->doc.getPage(data->index + 1); + ok = data->page ? true : false; } Page::~Page() @@ -132,7 +135,7 @@ QString Page::getText(const Rectangle &r) const output_dev = new TextOutputDev(0, gFalse, gFalse, gFalse); data->doc->data->doc.displayPageSlice(output_dev, data->index + 1, 72, 72, 0, false, false, false, -1, -1, -1, -1); - p = data->doc->data->doc.getCatalog()->getPage(data->index + 1); + p = data->page; if (r.isNull()) { rect = p->getCropBox(); @@ -197,7 +200,7 @@ PageTransition *Page::getTransition() const { Object o; PageTransitionParams params; - params.dictObj = data->doc->data->doc.getCatalog()->getPage(data->index + 1)->getTrans(&o); + params.dictObj = data->page->getTrans(&o); data->transition = new PageTransition(params); o.free(); } @@ -208,7 +211,7 @@ QSize Page::pageSize() const { ::Page *p; - p = data->doc->data->doc.getCatalog()->getPage(data->index + 1); + p = data->page; if ( ( Page::Landscape == orientation() ) || (Page::Seascape == orientation() ) ) { return QSize( (int)p->getCropHeight(), (int)p->getCropWidth() ); } else { @@ -218,7 +221,7 @@ QSize Page::pageSize() const Page::Orientation Page::orientation() const { - ::Page *p = data->doc->data->doc.getCatalog()->getPage(data->index + 1); + ::Page *p = data->page; int rotation = p->getRotate(); switch (rotation) { diff --git a/qt/poppler-qt.h b/qt/poppler-qt.h index a6b1e6e..549ffd2 100644 --- a/qt/poppler-qt.h +++ b/qt/poppler-qt.h @@ -31,6 +31,7 @@ #include #include + namespace Poppler { class Document; @@ -198,9 +199,12 @@ class Page { */ QValueList links() const; + bool isOk() { return ok; }; + private: Page(const Document *doc, int index); PageData *data; + bool ok; }; class DocumentData; @@ -219,7 +223,7 @@ public: static Document *load(const QString & filePath); - Page *getPage(int index) const{ return new Page(this, index); } + Page *getPage(int index) const; int getNumPages() const; -- 1.6.4.2 From 0cf7f1d38625e278938880bc5cd61841533a97d1 Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Fri, 23 Apr 2010 12:07:39 +0200 Subject: [PATCH 09/15] Use PDFDoc::getPage() in PSOutputDev --- glib/poppler-page.cc | 1 + poppler/PSOutputDev.cc | 37 ++++++++++++++++++++++--------------- poppler/PSOutputDev.h | 13 ++++++++----- qt/poppler-document.cc | 2 +- qt4/src/poppler-ps-converter.cc | 1 + utils/pdftohtml.cc | 2 +- utils/pdftops.cc | 2 +- 7 files changed, 35 insertions(+), 23 deletions(-) diff --git a/glib/poppler-page.cc b/glib/poppler-page.cc index 39645bd..106b636 100644 --- a/glib/poppler-page.cc +++ b/glib/poppler-page.cc @@ -1161,6 +1161,7 @@ poppler_page_render_to_ps (PopplerPage *page, if (!ps_file->out) ps_file->out = new PSOutputDev (ps_file->filename, + ps_file->document->doc, ps_file->document->doc->getXRef(), ps_file->document->doc->getCatalog(), NULL, diff --git a/poppler/PSOutputDev.cc b/poppler/PSOutputDev.cc index 179a494..5e5d3d0 100644 --- a/poppler/PSOutputDev.cc +++ b/poppler/PSOutputDev.cc @@ -70,6 +70,7 @@ # include "SplashOutputDev.h" #endif #include "PSOutputDev.h" +#include "PDFDoc.h" #ifdef MACOS // needed for setting type/creator of MacOS files @@ -972,7 +973,7 @@ static void outputToFile(void *stream, char *data, int len) { fwrite(data, 1, len, (FILE *)stream); } -PSOutputDev::PSOutputDev(const char *fileName, XRef *xrefA, Catalog *catalog, +PSOutputDev::PSOutputDev(const char *fileName, PDFDoc *doc, XRef *xrefA, Catalog *catalog, char *psTitle, int firstPage, int lastPage, PSOutMode modeA, int paperWidthA, int paperHeightA, GBool duplexA, @@ -1033,13 +1034,14 @@ PSOutputDev::PSOutputDev(const char *fileName, XRef *xrefA, Catalog *catalog, } init(outputToFile, f, fileTypeA, psTitle, - xrefA, catalog, firstPage, lastPage, modeA, + doc, xrefA, catalog, firstPage, lastPage, modeA, imgLLXA, imgLLYA, imgURXA, imgURYA, manualCtrlA, paperWidthA, paperHeightA, duplexA); } PSOutputDev::PSOutputDev(PSOutputFunc outputFuncA, void *outputStreamA, char *psTitle, + PDFDoc *doc, XRef *xrefA, Catalog *catalog, int firstPage, int lastPage, PSOutMode modeA, int paperWidthA, int paperHeightA, GBool duplexA, @@ -1068,18 +1070,17 @@ PSOutputDev::PSOutputDev(PSOutputFunc outputFuncA, void *outputStreamA, forceRasterize = forceRasterizeA; init(outputFuncA, outputStreamA, psGeneric, psTitle, - xrefA, catalog, firstPage, lastPage, modeA, + doc, xrefA, catalog, firstPage, lastPage, modeA, imgLLXA, imgLLYA, imgURXA, imgURYA, manualCtrlA, paperWidthA, paperHeightA, duplexA); } void PSOutputDev::init(PSOutputFunc outputFuncA, void *outputStreamA, - PSFileType fileTypeA, char *pstitle, XRef *xrefA, Catalog *catalog, + PSFileType fileTypeA, char *pstitle, PDFDoc *doc, XRef *xrefA, Catalog *catalog, int firstPage, int lastPage, PSOutMode modeA, int imgLLXA, int imgLLYA, int imgURXA, int imgURYA, GBool manualCtrlA, int paperWidthA, int paperHeightA, GBool duplexA) { - Page *page; PDFRectangle *box; // initialize @@ -1099,12 +1100,12 @@ void PSOutputDev::init(PSOutputFunc outputFuncA, void *outputStreamA, imgURX = imgURXA; imgURY = imgURYA; if (paperWidth < 0 || paperHeight < 0) { - // this check is needed in case the document has zero pages - if (firstPage > 0 && firstPage <= catalog->getNumPages()) { - page = catalog->getPage(firstPage); + Page *page; + if ((page = doc->getPage(firstPage))) { paperWidth = (int)ceil(page->getMediaWidth()); paperHeight = (int)ceil(page->getMediaHeight()); } else { + error(-1, "Invalid page %d", firstPage); paperWidth = 1; paperHeight = 1; } @@ -1170,14 +1171,16 @@ void PSOutputDev::init(PSOutputFunc outputFuncA, void *outputStreamA, embFontList = new GooString(); if (!manualCtrl) { + Page *page; // this check is needed in case the document has zero pages - if (firstPage > 0 && firstPage <= catalog->getNumPages()) { + if ((page = doc->getPage(firstPage))) { writeHeader(firstPage, lastPage, - catalog->getPage(firstPage)->getMediaBox(), - catalog->getPage(firstPage)->getCropBox(), - catalog->getPage(firstPage)->getRotate(), + page->getMediaBox(), + page->getCropBox(), + page->getRotate(), pstitle); } else { + error(-1, "Invalid page %d", firstPage); box = new PDFRectangle(0, 0, 1, 1); writeHeader(firstPage, lastPage, box, box, 0, pstitle); delete box; @@ -1190,7 +1193,7 @@ void PSOutputDev::init(PSOutputFunc outputFuncA, void *outputStreamA, writePS("%%EndProlog\n"); writePS("%%BeginSetup\n"); } - writeDocSetup(catalog, firstPage, lastPage, duplexA); + writeDocSetup(doc, catalog, firstPage, lastPage, duplexA); if (mode != psModeForm) { writePS("%%EndSetup\n"); } @@ -1400,7 +1403,7 @@ void PSOutputDev::writeXpdfProcset() { } } -void PSOutputDev::writeDocSetup(Catalog *catalog, +void PSOutputDev::writeDocSetup(PDFDoc *doc, Catalog *catalog, int firstPage, int lastPage, GBool duplexA) { Page *page; @@ -1416,7 +1419,11 @@ void PSOutputDev::writeDocSetup(Catalog *catalog, writePS("xpdf begin\n"); } for (pg = firstPage; pg <= lastPage; ++pg) { - page = catalog->getPage(pg); + page = doc->getPage(pg); + if (!page) { + error(-1, "Failed writing resources for page %d", pg); + continue; + } if ((resDict = page->getResourceDict())) { setupResources(resDict); } diff --git a/poppler/PSOutputDev.h b/poppler/PSOutputDev.h index 38c838c..a84a638 100644 --- a/poppler/PSOutputDev.h +++ b/poppler/PSOutputDev.h @@ -50,6 +50,7 @@ struct PSFont8Info; struct PSFont16Enc; class PSOutCustomColor; class Function; +class PDFDoc; //------------------------------------------------------------------------ // PSOutputDev @@ -75,7 +76,7 @@ class PSOutputDev: public OutputDev { public: // Open a PostScript output file, and write the prolog. - PSOutputDev(const char *fileName, XRef *xrefA, Catalog *catalog, + PSOutputDev(const char *fileName, PDFDoc *doc, XRef *xrefA, Catalog *catalog, char *psTitle, int firstPage, int lastPage, PSOutMode modeA, int paperWidthA = -1, int paperHeightA = -1, @@ -88,6 +89,7 @@ public: // Open a PSOutputDev that will write to a generic stream. PSOutputDev(PSOutputFunc outputFuncA, void *outputStreamA, char *psTitle, + PDFDoc *doc, XRef *xrefA, Catalog *catalog, int firstPage, int lastPage, PSOutMode modeA, int paperWidthA = -1, int paperHeightA = -1, @@ -145,9 +147,6 @@ public: // Write the Xpdf procset. void writeXpdfProcset(); - // Write the document-level setup. - void writeDocSetup(Catalog *catalog, int firstPage, int lastPage, GBool duplexA); - // Write the trailer for the current page. void writePageTrailer(); @@ -287,7 +286,7 @@ public: private: void init(PSOutputFunc outputFuncA, void *outputStreamA, - PSFileType fileTypeA, char *pstitle, XRef *xrefA, Catalog *catalog, + PSFileType fileTypeA, char *pstitle, PDFDoc *doc, XRef *xrefA, Catalog *catalog, int firstPage, int lastPage, PSOutMode modeA, int imgLLXA, int imgLLYA, int imgURXA, int imgURYA, GBool manualCtrlA, int paperWidthA, int paperHeightA, @@ -341,6 +340,10 @@ private: double *x1, double *y1); #endif void cvtFunction(Function *func); + + // Write the document-level setup. + void writeDocSetup(PDFDoc *doc, Catalog *catalog, int firstPage, int lastPage, GBool duplexA); + void writePSChar(char c); void writePS(char *s); void writePSFmt(const char *fmt, ...); diff --git a/qt/poppler-document.cc b/qt/poppler-document.cc index 1a5892b..03d01fa 100644 --- a/qt/poppler-document.cc +++ b/qt/poppler-document.cc @@ -325,7 +325,7 @@ bool Document::print(const QString &fileName, QValueList pageList, double h bool Document::print(const QString &file, QValueList pageList, double hDPI, double vDPI, int rotate, int paperWidth, int paperHeight) { - PSOutputDev *psOut = new PSOutputDev(file.latin1(), data->doc.getXRef(), data->doc.getCatalog(), NULL, 1, data->doc.getNumPages(), psModePS, paperWidth, paperHeight); + PSOutputDev *psOut = new PSOutputDev(file.latin1(), &(data->doc), data->doc.getXRef(), data->doc.getCatalog(), NULL, 1, data->doc.getNumPages(), psModePS, paperWidth, paperHeight); if (psOut->isOk()) { QValueList::iterator it; diff --git a/qt4/src/poppler-ps-converter.cc b/qt4/src/poppler-ps-converter.cc index 7a1957b..9dc82ec 100644 --- a/qt4/src/poppler-ps-converter.cc +++ b/qt4/src/poppler-ps-converter.cc @@ -195,6 +195,7 @@ bool PSConverter::convert() PSOutputDev *psOut = new PSOutputDev(outputToQIODevice, dev, pstitlechar, + d->document->doc, d->document->doc->getXRef(), d->document->doc->getCatalog(), 1, diff --git a/utils/pdftohtml.cc b/utils/pdftohtml.cc index 3c74c6e..0558e5c 100644 --- a/utils/pdftohtml.cc +++ b/utils/pdftohtml.cc @@ -350,7 +350,7 @@ int main(int argc, char *argv[]) { psFileName = new GooString(htmlFileName->getCString()); psFileName->append(".ps"); - psOut = new PSOutputDev(psFileName->getCString(), doc->getXRef(), + psOut = new PSOutputDev(psFileName->getCString(), doc, doc->getXRef(), doc->getCatalog(), NULL, firstPage, lastPage, psModePS, w, h); psOut->setDisplayText(gFalse); doc->displayPages(psOut, firstPage, lastPage, 72, 72, 0, diff --git a/utils/pdftops.cc b/utils/pdftops.cc index 0bc43a1..8231458 100644 --- a/utils/pdftops.cc +++ b/utils/pdftops.cc @@ -359,7 +359,7 @@ int main(int argc, char *argv[]) { } // write PostScript file - psOut = new PSOutputDev(psFileName->getCString(), doc->getXRef(), + psOut = new PSOutputDev(psFileName->getCString(), doc, doc->getXRef(), doc->getCatalog(), NULL, firstPage, lastPage, mode, paperWidth, paperHeight, -- 1.6.4.2 From 5fb2cd2ba2da29ec6b062d43701481c25f4402dc Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Sat, 24 Apr 2010 10:17:56 +0200 Subject: [PATCH 10/15] Use PDFDoc::getPage() in HtmlOutputDev --- utils/HtmlOutputDev.cc | 2 +- utils/HtmlOutputDev.h | 2 ++ 2 files changed, 3 insertions(+), 1 deletions(-) diff --git a/utils/HtmlOutputDev.cc b/utils/HtmlOutputDev.cc index 81f8b88..4f7dff6 100644 --- a/utils/HtmlOutputDev.cc +++ b/utils/HtmlOutputDev.cc @@ -1093,7 +1093,7 @@ void HtmlOutputDev::startPage(int pageNum, GfxState *state) { void HtmlOutputDev::endPage() { - Links *linksList = catalog->getPage(pageNum)->getLinks(catalog); + Links *linksList = docPage->getLinks(catalog); for (int i = 0; i < linksList->getNumLinks(); ++i) { doProcessLink(linksList->getLink(i)); diff --git a/utils/HtmlOutputDev.h b/utils/HtmlOutputDev.h index 24ccfd1..48b04c6 100644 --- a/utils/HtmlOutputDev.h +++ b/utils/HtmlOutputDev.h @@ -256,6 +256,7 @@ public: GBool (* abortCheckCbk)(void *data) = NULL, void * abortCheckCbkData = NULL) { + docPage = page; catalog = catalogA; return gTrue; } @@ -323,6 +324,7 @@ private: GooString *docTitle; GooList *glMetaVars; Catalog *catalog; + Page *docPage; friend class HtmlPage; }; -- 1.6.4.2 From ecbc8526bf49c512578f74940c2be1c1d221a085 Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Wed, 31 Mar 2010 14:39:57 +0200 Subject: [PATCH 11/15] Parse page tree on demand --- poppler/Catalog.cc | 266 ++++++++++++++++++++++++++++++++++----------------- poppler/Catalog.h | 12 ++- 2 files changed, 185 insertions(+), 93 deletions(-) diff --git a/poppler/Catalog.cc b/poppler/Catalog.cc index 900cdd7..416fb66 100644 --- a/poppler/Catalog.cc +++ b/poppler/Catalog.cc @@ -59,9 +59,6 @@ Catalog::Catalog(XRef *xrefA) { Object catDict, pagesDict, pagesDictRef; Object obj, obj2; Object optContentProps; - char *alreadyRead; - int numPages0; - int i; ok = gTrue; xref = xrefA; @@ -78,6 +75,12 @@ Catalog::Catalog(XRef *xrefA) { embeddedFileNameTree = NULL; jsNameTree = NULL; + pagesList = NULL; + pagesRefList = NULL; + attrsList = NULL; + kidsIdxList = NULL; + lastCachedPage = 0; + xref->getCatalog(&catDict); if (!catDict.isDict()) { error(-1, "Catalog object is wrong type (%s)", catDict.getTypeName()); @@ -100,31 +103,11 @@ Catalog::Catalog(XRef *xrefA) { if (!obj.isNum()) { error(-1, "Page count in top-level pages object is wrong type (%s)", obj.getTypeName()); - pagesSize = numPages0 = 0; + numPages = 0; } else { - pagesSize = numPages0 = (int)obj.getNum(); + numPages = (int)obj.getNum(); } obj.free(); - pages = (Page **)gmallocn(pagesSize, sizeof(Page *)); - pageRefs = (Ref *)gmallocn(pagesSize, sizeof(Ref)); - for (i = 0; i < pagesSize; ++i) { - pages[i] = NULL; - pageRefs[i].num = -1; - pageRefs[i].gen = -1; - } - alreadyRead = (char *)gmalloc(xref->getNumObjects()); - memset(alreadyRead, 0, xref->getNumObjects()); - if (catDict.dictLookupNF("Pages", &pagesDictRef)->isRef() && - pagesDictRef.getRefNum() >= 0 && - pagesDictRef.getRefNum() < xref->getNumObjects()) { - alreadyRead[pagesDictRef.getRefNum()] = 1; - } - pagesDictRef.free(); - numPages = readPageTree(pagesDict.getDict(), NULL, 0, alreadyRead); - gfree(alreadyRead); - if (numPages != numPages0) { - error(-1, "Page count in top-level pages object is incorrect"); - } pagesDict.free(); // read base URI @@ -163,6 +146,10 @@ Catalog::Catalog(XRef *xrefA) { Catalog::~Catalog() { int i; + delete kidsIdxList; + delete attrsList; + delete pagesRefList; + delete pagesList; if (pages) { for (i = 0; i < pagesSize; ++i) { if (pages[i]) { @@ -225,91 +212,192 @@ GooString *Catalog::readMetadata() { return s; } -int Catalog::readPageTree(Dict *pagesDict, PageAttrs *attrs, int start, - char *alreadyRead) { - Object kids; - Object kid; - Object kidRef; - PageAttrs *attrs1, *attrs2; - Page *page; - int i, j; - - attrs1 = new PageAttrs(attrs, pagesDict); - pagesDict->lookup("Kids", &kids); - if (!kids.isArray()) { - error(-1, "Kids object (page %d) is wrong type (%s)", - start+1, kids.getTypeName()); - return start; - } - for (i = 0; i < kids.arrayGetLength(); ++i) { - kids.arrayGetNF(i, &kidRef); - if (kidRef.isRef() && - kidRef.getRefNum() >= 0 && - kidRef.getRefNum() < xref->getNumObjects()) { - if (alreadyRead[kidRef.getRefNum()]) { - error(-1, "Loop in Pages tree"); - kidRef.free(); - continue; +Page *Catalog::getPage(int i) +{ + if (i < 1) return NULL; + + if (i > lastCachedPage) { + if (cachePageTree(i) == gFalse) return NULL; + } + return pages[i-1]; +} + +Ref *Catalog::getPageRef(int i) +{ + if (i < 1) return NULL; + + if (i > lastCachedPage) { + if (cachePageTree(i) == gFalse) return NULL; + } + return &pageRefs[i-1]; +} + +GBool Catalog::cachePageTree(int page) +{ + Dict *pagesDict; + + if (pagesList == NULL) { + + Object catDict; + Ref pagesRef; + + xref->getCatalog(&catDict); + + Object pagesDictRef; + if (catDict.dictLookupNF("Pages", &pagesDictRef)->isRef() && + pagesDictRef.getRefNum() >= 0 && + pagesDictRef.getRefNum() < xref->getNumObjects()) { + pagesRef = pagesDictRef.getRef(); + pagesDictRef.free(); + } else { + error(-1, "Catalog dictionary does not contain a valid \"Pages\" entry"); + pagesDictRef.free(); + return gFalse; + } + + Object obj; + catDict.dictLookup("Pages", &obj); + // This should really be isDict("Pages"), but I've seen at least one + // PDF file where the /Type entry is missing. + if (obj.isDict()) { + obj.getDict()->incRef(); + pagesDict = obj.getDict(); + obj.free(); + } + else { + error(-1, "Top-level pages object is wrong type (%s)", obj.getTypeName()); + obj.free(); + return gFalse; + } + + pagesSize = numPages; + pages = (Page **)gmallocn(pagesSize, sizeof(Page *)); + pageRefs = (Ref *)gmallocn(pagesSize, sizeof(Ref)); + for (int i = 0; i < pagesSize; ++i) { + pages[i] = NULL; + pageRefs[i].num = -1; + pageRefs[i].gen = -1; + } + + pagesList = new GooVector(); + pagesList->push_back(pagesDict); + pagesRefList = new GooVector(); + pagesRefList->push_back(pagesRef); + attrsList = new GooVector(); + attrsList->push_back(new PageAttrs(NULL, pagesDict)); + kidsIdxList = new GooVector(); + kidsIdxList->push_back(0); + lastCachedPage = 0; + + } + + while(1) { + + if (page <= lastCachedPage) return gTrue; + + if (pagesList->empty()) return gFalse; + + pagesDict = pagesList->back(); + Object kids; + pagesDict->lookup("Kids", &kids); + if (!kids.isArray()) { + error(-1, "Kids object (page %d) is wrong type (%s)", + lastCachedPage+1, kids.getTypeName()); + kids.free(); + return gFalse; + } + + int kidsIdx = kidsIdxList->back(); + if (kidsIdx >= kids.arrayGetLength()) { + delete pagesList->back(); + pagesList->pop_back(); + pagesRefList->pop_back(); + delete attrsList->back(); + attrsList->pop_back(); + kidsIdxList->pop_back(); + if (!kidsIdxList->empty()) kidsIdxList->back()++; + kids.free(); + continue; + } + + Object kidRef; + kids.arrayGetNF(kidsIdx, &kidRef); + if (!kidRef.isRef()) { + error(-1, "Kid object (page %d) is not an indirect reference (%s)", + lastCachedPage+1, kidRef.getTypeName()); + kidRef.free(); + kids.free(); + return gFalse; + } + + for (size_t i = 0; i < pagesRefList->size(); i++) { + if (((*pagesRefList)[i]).num == kidRef.getRefNum()) { + error(-1, "Loop in Pages tree"); + kidRef.free(); + kids.free(); + kidsIdxList->back()++; + continue; } - alreadyRead[kidRef.getRefNum()] = 1; } - kids.arrayGet(i, &kid); + + Object kid; + kids.arrayGet(kidsIdx, &kid); + kids.free(); if (kid.isDict("Page")) { - attrs2 = new PageAttrs(attrs1, kid.getDict()); - page = new Page(xref, start+1, kid.getDict(), kidRef.getRef(), attrs2, getForm()); - if (!page->isOk()) { - ++start; - goto err3; - } - if (start >= pagesSize) { - pagesSize += 32; - pages = (Page **)greallocn(pages, pagesSize, sizeof(Page *)); - pageRefs = (Ref *)greallocn(pageRefs, pagesSize, sizeof(Ref)); - for (j = pagesSize - 32; j < pagesSize; ++j) { - pages[j] = NULL; - pageRefs[j].num = -1; - pageRefs[j].gen = -1; - } + PageAttrs *attrs = new PageAttrs(attrsList->back(), kid.getDict()); + Page *p = new Page(xref, lastCachedPage+1, kid.getDict(), + kidRef.getRef(), attrs, form); + if (!p->isOk()) { + error(-1, "Failed to create page (page %d)", lastCachedPage+1); + delete p; + kidRef.free(); + kid.free(); + return gFalse; } - pages[start] = page; - if (kidRef.isRef()) { - pageRefs[start].num = kidRef.getRefNum(); - pageRefs[start].gen = kidRef.getRefGen(); + + if (lastCachedPage >= numPages) { + error(-1, "Page count in top-level pages object is incorrect"); + kidRef.free(); + kid.free(); + return gFalse; } - ++start; + + pages[lastCachedPage] = p; + pageRefs[lastCachedPage].num = kidRef.getRefNum(); + pageRefs[lastCachedPage].gen = kidRef.getRefGen(); + + lastCachedPage++; + kidsIdxList->back()++; + // This should really be isDict("Pages"), but I've seen at least one // PDF file where the /Type entry is missing. } else if (kid.isDict()) { - if ((start = readPageTree(kid.getDict(), attrs1, start, alreadyRead)) - < 0) - goto err2; + attrsList->push_back(new PageAttrs(attrsList->back(), kid.getDict())); + pagesRefList->push_back(kidRef.getRef()); + kid.getDict()->incRef(); + pagesList->push_back(kid.getDict()); + kidsIdxList->push_back(0); } else { error(-1, "Kid object (page %d) is wrong type (%s)", - start+1, kid.getTypeName()); + lastCachedPage+1, kid.getTypeName()); + kidRef.free(); + kid.free(); + return gFalse; } - kid.free(); kidRef.free(); + kid.free(); + } - delete attrs1; - kids.free(); - return start; - err3: - delete page; - err2: - kid.free(); - kidRef.free(); - kids.free(); - delete attrs1; - ok = gFalse; - return -1; + return gFalse; } int Catalog::findPage(int num, int gen) { int i; for (i = 0; i < numPages; ++i) { - if (pageRefs[i].num == num && pageRefs[i].gen == gen) + Ref *ref = getPageRef(i+1); + if (ref->num == num && ref->gen == gen) return i + 1; } return 0; diff --git a/poppler/Catalog.h b/poppler/Catalog.h index 2cab80a..5a25109 100644 --- a/poppler/Catalog.h +++ b/poppler/Catalog.h @@ -151,10 +151,10 @@ public: int getNumPages() { return numPages; } // Get a page. - Page *getPage(int i) { return pages[i-1]; } + Page *getPage(int i); // Get the reference for a page object. - Ref *getPageRef(int i) { return &pageRefs[i-1]; } + Ref *getPageRef(int i); // Return base URI, or NULL if none. GooString *getBaseURI() { return baseURI; } @@ -232,6 +232,11 @@ private: XRef *xref; // the xref table for this PDF file Page **pages; // array of pages Ref *pageRefs; // object ID for each page + int lastCachedPage; + GooVector *pagesList; + GooVector *pagesRefList; + GooVector *attrsList; + GooVector *kidsIdxList; Form *form; int numPages; // number of pages int pagesSize; // size of pages array @@ -251,8 +256,7 @@ private: PageMode pageMode; // page mode PageLayout pageLayout; // page layout - int readPageTree(Dict *pages, PageAttrs *attrs, int start, - char *alreadyRead); + GBool cachePageTree(int page); // Cache first pages. Object *findDestInTree(Object *tree, GooString *name, Object *obj); Object *getNames(); -- 1.6.4.2 From 90f6562d9f148cfd28bc29a71fbfc0d2cdbb380a Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Wed, 24 Mar 2010 22:01:41 +0100 Subject: [PATCH 12/15] Parse number of pages on demand --- poppler/Catalog.cc | 70 +++++++++++++++++++++++++++++++-------------------- poppler/Catalog.h | 2 +- 2 files changed, 43 insertions(+), 29 deletions(-) diff --git a/poppler/Catalog.cc b/poppler/Catalog.cc index 416fb66..536e474 100644 --- a/poppler/Catalog.cc +++ b/poppler/Catalog.cc @@ -64,7 +64,8 @@ Catalog::Catalog(XRef *xrefA) { xref = xrefA; pages = NULL; pageRefs = NULL; - numPages = pagesSize = 0; + numPages = -1; + pagesSize = 0; baseURI = NULL; pageLabelInfo = NULL; form = NULL; @@ -89,27 +90,6 @@ Catalog::Catalog(XRef *xrefA) { // get the AcroForm dictionary catDict.dictLookup("AcroForm", &acroForm); - // read page tree - catDict.dictLookup("Pages", &pagesDict); - // This should really be isDict("Pages"), but I've seen at least one - // PDF file where the /Type entry is missing. - if (!pagesDict.isDict()) { - error(-1, "Top-level pages object is wrong type (%s)", - pagesDict.getTypeName()); - goto err2; - } - pagesDict.dictLookup("Count", &obj); - // some PDF files actually use real numbers here ("/Count 9.0") - if (!obj.isNum()) { - error(-1, "Page count in top-level pages object is wrong type (%s)", - obj.getTypeName()); - numPages = 0; - } else { - numPages = (int)obj.getNum(); - } - obj.free(); - pagesDict.free(); - // read base URI if (catDict.dictLookup("URI", &obj)->isDict()) { if (obj.dictLookup("Base", &obj2)->isString()) { @@ -136,8 +116,6 @@ Catalog::Catalog(XRef *xrefA) { catDict.free(); return; - err2: - pagesDict.free(); err1: catDict.free(); ok = gFalse; @@ -270,7 +248,7 @@ GBool Catalog::cachePageTree(int page) return gFalse; } - pagesSize = numPages; + pagesSize = getNumPages(); pages = (Page **)gmallocn(pagesSize, sizeof(Page *)); pageRefs = (Ref *)gmallocn(pagesSize, sizeof(Ref)); for (int i = 0; i < pagesSize; ++i) { @@ -395,7 +373,7 @@ GBool Catalog::cachePageTree(int page) int Catalog::findPage(int num, int gen) { int i; - for (i = 0; i < numPages; ++i) { + for (i = 0; i < getNumPages(); ++i) { Ref *ref = getPageRef(i+1); if (ref->num == num && ref->gen == gen) return i + 1; @@ -719,7 +697,7 @@ GBool Catalog::labelToIndex(GooString *label, int *index) return gFalse; } - if (*index < 0 || *index >= numPages) + if (*index < 0 || *index >= getNumPages()) return gFalse; return gTrue; @@ -729,7 +707,7 @@ GBool Catalog::indexToLabel(int index, GooString *label) { char buffer[32]; - if (index < 0 || index >= numPages) + if (index < 0 || index >= getNumPages()) return gFalse; PageLabelInfo *pli = getPageLabelInfo(); @@ -845,6 +823,42 @@ EmbFile::EmbFile(Object *efDict, GooString *description) m_mimetype = new GooString(); } +int Catalog::getNumPages() +{ + if (numPages == -1) + { + Object catDict, pagesDict, obj; + + xref->getCatalog(&catDict); + catDict.dictLookup("Pages", &pagesDict); + catDict.free(); + + // This should really be isDict("Pages"), but I've seen at least one + // PDF file where the /Type entry is missing. + if (!pagesDict.isDict()) { + error(-1, "Top-level pages object is wrong type (%s)", + pagesDict.getTypeName()); + pagesDict.free(); + return 0; + } + + pagesDict.dictLookup("Count", &obj); + // some PDF files actually use real numbers here ("/Count 9.0") + if (!obj.isNum()) { + error(-1, "Page count in top-level pages object is wrong type (%s)", + obj.getTypeName()); + numPages = 0; + } else { + numPages = (int)obj.getNum(); + } + + obj.free(); + pagesDict.free(); + } + + return numPages; +} + PageLabelInfo *Catalog::getPageLabelInfo() { if (!pageLabelInfo) { diff --git a/poppler/Catalog.h b/poppler/Catalog.h index 5a25109..8bca80b 100644 --- a/poppler/Catalog.h +++ b/poppler/Catalog.h @@ -148,7 +148,7 @@ public: GBool isOk() { return ok; } // Get number of pages. - int getNumPages() { return numPages; } + int getNumPages(); // Get a page. Page *getPage(int i); -- 1.6.4.2 From 244b93adc29781136fab10b31ac7370c392f53e5 Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Thu, 25 Mar 2010 18:53:54 +0100 Subject: [PATCH 13/15] Get number of pages from linearization table --- poppler/PDFDoc.cc | 9 +++++++++ poppler/PDFDoc.h | 2 +- 2 files changed, 10 insertions(+), 1 deletions(-) diff --git a/poppler/PDFDoc.cc b/poppler/PDFDoc.cc index 89dba6f..8f105fd 100644 --- a/poppler/PDFDoc.cc +++ b/poppler/PDFDoc.cc @@ -1033,6 +1033,15 @@ Guint PDFDoc::getMainXRefEntriesOffset() return mainXRefEntriesOffset; } +int PDFDoc::getNumPages() +{ + if (isLinearized()) { + return getLinearization()->getNumPages(); + } else { + return catalog->getNumPages(); + } +} + Page *PDFDoc::getPage(int page) { if ((page < 1) || page > getNumPages()) return NULL; diff --git a/poppler/PDFDoc.h b/poppler/PDFDoc.h index 8de139f..9069698 100644 --- a/poppler/PDFDoc.h +++ b/poppler/PDFDoc.h @@ -118,7 +118,7 @@ public: { return getPage(page) ? getPage(page)->getRotate() : 0 ; } // Get number of pages. - int getNumPages() { return catalog->getNumPages(); } + int getNumPages(); // Return the contents of the metadata stream, or NULL if there is // no metadata. -- 1.6.4.2 From de1909113f3389f8df15e044470bb56c5a1d122c Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Wed, 24 Mar 2010 22:03:27 +0100 Subject: [PATCH 14/15] Add hint tables support --- CMakeLists.txt | 2 + poppler/Hints.cc | 337 +++++++++++++++++++++++++++++++++++++++++++++++++++ poppler/Hints.h | 89 ++++++++++++++ poppler/Makefile.am | 2 + poppler/PDFDoc.cc | 14 ++ poppler/PDFDoc.h | 5 + 6 files changed, 449 insertions(+), 0 deletions(-) create mode 100644 poppler/Hints.cc create mode 100644 poppler/Hints.h diff --git a/CMakeLists.txt b/CMakeLists.txt index a119a6d..6d43826 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -245,6 +245,7 @@ set(poppler_SRCS poppler/GfxFont.cc poppler/GfxState.cc poppler/GlobalParams.cc + poppler/Hints.cc poppler/JArithmeticDecoder.cc poppler/JBIG2Stream.cc poppler/Lexer.cc @@ -391,6 +392,7 @@ if(ENABLE_XPDF_HEADERS) poppler/GfxState.h poppler/GfxState_helpers.h poppler/GlobalParams.h + poppler/Hints.h poppler/JArithmeticDecoder.h poppler/JBIG2Stream.h poppler/Lexer.h diff --git a/poppler/Hints.cc b/poppler/Hints.cc new file mode 100644 index 0000000..9b488ba --- /dev/null +++ b/poppler/Hints.cc @@ -0,0 +1,337 @@ +//======================================================================== +// +// Hints.cc +// +// This file is licensed under the GPLv2 or later +// +// Copyright 2010 Hib Eris +// +//======================================================================== + +#include + +#include "Hints.h" + +#include "Linearization.h" +#include "Object.h" +#include "Stream.h" +#include "XRef.h" +#include "Parser.h" +#include "Lexer.h" + +//------------------------------------------------------------------------ +// Hints +//------------------------------------------------------------------------ + +Hints::Hints(BaseStream *str, Linearization *linearization, XRef *xref) +{ + hintsOffset = linearization->getHintsOffset(); + hintsLength = linearization->getHintsLength(); + + mainXRefEntriesOffset = linearization->getMainXRefEntriesOffset(); + + nPages = linearization->getNumPages(); + if (nPages < 0) nPages = 0; + + pageFirst = linearization->getPageFirst(); + pageFirst = (pageFirst > 0) && (pageFirst <= nPages) ? pageFirst : 1; + + objectNumberFirst = linearization->getObjectNumberFirst(); + pageOffsetFirst = xref->getEntry(objectNumberFirst)->offset; + + pageEndFirst = linearization->getEndFirst(); + + nObjects = (Guint *) gmallocn(nPages, sizeof(Guint)); + xRefOffset = (Guint *) gmallocn(nPages, sizeof(Guint)); + pageLength = (Guint *) gmallocn(nPages, sizeof(Guint)); + pageOffset = (Guint *) gmallocn(nPages, sizeof(Guint)); + numSharedObject = (Guint *) gmallocn(nPages, sizeof(Guint)); + sharedObjectId = (Guint **) gmallocn(nPages, sizeof(Guint)); + + readTables(str, linearization); +} + +Hints::~Hints() +{ + gfree(nObjects); + gfree(xRefOffset); + gfree(pageLength); + gfree(pageOffset); + gfree(numSharedObject); + for (int i=0; i< nPages; i++) gfree(sharedObjectId[i]); + gfree(sharedObjectId); + gfree(groupLength); + gfree(groupOffset); + gfree(groupHasSignature); + gfree(groupNumObjects); + gfree(groupXRefOffset); +} + +void Hints::readTables(BaseStream *str, Linearization *linearization) +{ + Parser *parser; + Object obj; + + //TODO: overflow hint table? + int hintsEnd = hintsOffset + hintsLength - 1; + + obj.initNull(); + parser = new Parser(NULL, + new Lexer(NULL, + str->makeSubStream(hintsOffset, gFalse, hintsEnd, &obj)), + gTrue); + if (parser->getObj(&obj)->isInt() && + (obj.free(), parser->getObj(&obj)->isInt()) && + (obj.free(), parser->getObj(&obj)->isCmd("obj")) && + (obj.free(), parser->getObj(&obj)->isStream())){ + Stream *hintsStream = obj.getStream(); + Dict *hintsDict = obj.streamGetDict(); + + int sharedStreamOffset; + if (hintsDict->lookupInt("S", NULL, &sharedStreamOffset)) { + + hintsStream->reset(); + readPageOffsetTable(hintsStream); + + hintsStream->reset(); + for (int i=0; igetChar(); + readSharedObjectsTable(hintsStream); + } + obj.free(); + } + + delete parser; +} + +void Hints::readPageOffsetTable(Stream *str) +{ + if (nPages < 1) return; + + inputBits = 0; // reset on byte boundary. + + nObjectLeast = readBits(32, str); + + objectOffsetFirst = readBits(32, str); + if (objectOffsetFirst >= hintsOffset) objectOffsetFirst += hintsLength; + + nBitsDiffObjects = readBits(16, str); + + pageLengthLeast = readBits(32, str); + + nBitsDiffPageLength = readBits(16, str); + + OffsetStreamLeast = readBits(32, str); + + nBitsOffsetStream = readBits(16, str); + + lengthStreamLeast = readBits(32, str); + + nBitsLengthStream = readBits(16, str); + + nBitsNumShared = readBits(16, str); + + nBitsShared = readBits(16, str); + + nBitsNumerator = readBits(16, str); + + denominator = readBits(16, str); + + for (int i=0; i nPages)) return 0; + + if (page > pageFirst) + return pageOffset[page-1]; + else if (page < pageFirst) + return pageOffset[page]; + else + return pageOffset[0]; +} + +GooVector* Hints::getPageRanges(int page) +{ + if ((page < 1) || (page > nPages)) return NULL; + + int idx; + if (page > pageFirst) + idx = page-1; + else if (page < pageFirst) + idx = page; + else + idx = 0; + + ByteRange pageRange; + GooVector *v = new GooVector; + + pageRange.offset = pageOffset[idx]; + pageRange.length = pageLength[idx]; + v->push_back(pageRange); + + pageRange.offset = xRefOffset[idx]; + pageRange.length = 20*nObjects[idx]; + v->push_back(pageRange); + + for (Guint j=0; jpush_back(pageRange); + + pageRange.offset = groupXRefOffset[k]; + pageRange.length = 20*groupNumObjects[k]; + v->push_back(pageRange); + } + + return v; +} + +Guint Hints::readBit(Stream *str) +{ + Guint bit; + int c; + + if (inputBits == 0) { + if ((c = str->getChar()) == EOF) { + return (Guint) -1; + } + bitsBuffer = c; + inputBits = 8; + } + bit = (bitsBuffer >> (inputBits - 1)) & 1; + --inputBits; + return bit; +} + +Guint Hints::readBits(int n, Stream *str) +{ + Guint bit, bits; + + if (n < 1) return -1; + + if (n == 1) + return readBit(str); + + bit = (readBit(str) << (n-1)); + if (bit == (Guint) -1) + return -1; + + bits = readBits(n-1, str); + if (bits == (Guint) -1) + return -1; + + return bit | bits; +} + + diff --git a/poppler/Hints.h b/poppler/Hints.h new file mode 100644 index 0000000..7cacf00 --- /dev/null +++ b/poppler/Hints.h @@ -0,0 +1,89 @@ +//======================================================================== +// +// Hints.h +// +// This file is licensed under the GPLv2 or later +// +// Copyright 2010 Hib Eris +// +//======================================================================== + +#ifndef HINTS_H +#define HINTS_H + +#include +#include "goo/gtypes.h" +#include "goo/GooVector.h" +//#include +#include "PDFDoc.h" + +class Stream; +class BaseStream; +class Linearization; +class XRef; + +//------------------------------------------------------------------------ +// Hints +//------------------------------------------------------------------------ + +class Hints { +public: + + Hints(BaseStream *str, Linearization *linearization, XRef *xref); + ~Hints(); + + Guint getPageOffset(int page); + GooVector* getPageRanges(int page); + +private: + + void readTables(BaseStream *str, Linearization *linearization); + void readPageOffsetTable(Stream *str); + void readSharedObjectsTable(Stream *str); + + Guint readBit(Stream *str); + Guint readBits(int n, Stream *str); + + Guint hintsOffset; + Guint hintsLength; + Guint mainXRefEntriesOffset; + + int nPages; + int pageFirst; + Guint pageOffsetFirst; + Guint pageEndFirst; + int objectNumberFirst; + + Guint nObjectLeast; + Guint objectOffsetFirst; + Guint nBitsDiffObjects; + Guint pageLengthLeast; + Guint nBitsDiffPageLength; + Guint OffsetStreamLeast; + Guint nBitsOffsetStream; + Guint lengthStreamLeast; + Guint nBitsLengthStream; + Guint nBitsNumShared; + Guint nBitsShared; + Guint nBitsNumerator; + Guint denominator; + + Guint *nObjects; + Guint *xRefOffset; + Guint *pageLength; + Guint *pageOffset; + Guint *numSharedObject; + Guint **sharedObjectId; + + Guint *groupLength; + Guint *groupOffset; + Guint *groupHasSignature; + Guint *groupNumObjects; + Guint *groupXRefOffset; + + int inputBits; + char bitsBuffer; + +}; + +#endif diff --git a/poppler/Makefile.am b/poppler/Makefile.am index 8c1e019..a6b7990 100644 --- a/poppler/Makefile.am +++ b/poppler/Makefile.am @@ -206,6 +206,7 @@ poppler_include_HEADERS = \ GfxState.h \ GfxState_helpers.h \ GlobalParams.h \ + Hints.h \ JArithmeticDecoder.h \ JBIG2Stream.h \ Lexer.h \ @@ -285,6 +286,7 @@ libpoppler_la_SOURCES = \ GfxFont.cc \ GfxState.cc \ GlobalParams.cc \ + Hints.cc \ JArithmeticDecoder.cc \ JBIG2Stream.cc \ Lexer.cc \ diff --git a/poppler/PDFDoc.cc b/poppler/PDFDoc.cc index 8f105fd..37e5d20 100644 --- a/poppler/PDFDoc.cc +++ b/poppler/PDFDoc.cc @@ -67,6 +67,7 @@ #include "Outline.h" #endif #include "PDFDoc.h" +#include "Hints.h" //------------------------------------------------------------------------ @@ -94,6 +95,7 @@ void PDFDoc::init() xref = NULL; linearization = NULL; catalog = NULL; + hints = NULL; #ifndef DISABLE_OUTLINE outline = NULL; #endif @@ -268,6 +270,9 @@ PDFDoc::~PDFDoc() { if (xref) { delete xref; } + if (hints) { + delete hints; + } if (linearization) { delete linearization; } @@ -471,6 +476,15 @@ GBool PDFDoc::isLinearized() { return gFalse; } +Hints *PDFDoc::getHints() +{ + if (!hints && isLinearized()) { + hints = new Hints(str, getLinearization(), xref); + } + + return hints; +} + int PDFDoc::saveAs(GooString *name, PDFWriteMode mode) { FILE *f; OutStream *outStr; diff --git a/poppler/PDFDoc.h b/poppler/PDFDoc.h index 9069698..b2f40c9 100644 --- a/poppler/PDFDoc.h +++ b/poppler/PDFDoc.h @@ -49,6 +49,7 @@ class LinkAction; class LinkDest; class Outline; class Linearization; +class Hints; enum PDFWriteMode { writeStandard, @@ -236,6 +237,9 @@ private: void saveIncrementalUpdate (OutStream* outStr); void saveCompleteRewrite (OutStream* outStr); + // Get hints. + Hints *getHints(); + PDFDoc(); void init(); GBool setup(GooString *ownerPassword, GooString *userPassword); @@ -258,6 +262,7 @@ private: Linearization *linearization; XRef *xref; Catalog *catalog; + Hints *hints; #ifndef DISABLE_OUTLINE Outline *outline; #endif -- 1.6.4.2 From 99fa4a4f91713c28de8c17b05dd269dbd5e89324 Mon Sep 17 00:00:00 2001 From: Hib Eris Date: Tue, 20 Apr 2010 19:06:02 +0200 Subject: [PATCH 15/15] Use hint tables for PDFDoc::getPage() --- poppler/PDFDoc.cc | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++- poppler/PDFDoc.h | 4 +++ 2 files changed, 76 insertions(+), 1 deletions(-) diff --git a/poppler/PDFDoc.cc b/poppler/PDFDoc.cc index 37e5d20..1441428 100644 --- a/poppler/PDFDoc.cc +++ b/poppler/PDFDoc.cc @@ -100,6 +100,7 @@ void PDFDoc::init() outline = NULL; #endif startXRefPos = ~(Guint)0; + pageCache = NULL; } PDFDoc::PDFDoc() @@ -259,6 +260,14 @@ GBool PDFDoc::setup(GooString *ownerPassword, GooString *userPassword) { } PDFDoc::~PDFDoc() { + if (pageCache) { + for (int i = 0; i < getNumPages(); i++) { + if (pageCache[i]) { + delete pageCache[i]; + } + } + gfree(pageCache); + } #ifndef DISABLE_OUTLINE if (outline) { delete outline; @@ -1056,11 +1065,73 @@ int PDFDoc::getNumPages() } } +Guint PDFDoc::getPageOffset(int page) +{ + Guint offset; + + if (getHints() && (offset = getHints()->getPageOffset(page))) { + return offset; + } else { + error(-1, "Failed getting page offset from hint table"); + return 0; + } +} + +Page *PDFDoc::parsePage(Guint offset, int page) +{ + Page *p = NULL; + Object obj; + + obj.initNull(); + Stream *stream = str->makeSubStream(offset, gFalse, 0, &obj); + Parser parser = Parser(xref, new Lexer(xref, stream), gTrue); + + Object obj1, obj2, obj3, obj4; + if (parser.getObj(&obj1)->isInt() && + parser.getObj(&obj2)->isInt() && + parser.getObj(&obj3)->isCmd("obj") && + parser.getObj(&obj4)->isDict("Page")) { + Ref pageRef; + Dict *pageDict; + pageRef.num = obj1.getInt(); + pageRef.gen = obj2.getInt(); + pageDict = obj4.getDict(); + p = new Page(xref, page, pageDict, pageRef, + new PageAttrs(NULL, pageDict), + catalog->getForm()); + if (!p->isOk()) { + delete p; + p = NULL; + } + } + obj4.free(); + obj3.free(); + obj2.free(); + obj1.free(); + + return p; +} + Page *PDFDoc::getPage(int page) { if ((page < 1) || page > getNumPages()) return NULL; - { + if (isLinearized()) { + if (!pageCache) { + pageCache = (Page **) gmallocn(getNumPages(), sizeof(Page *)); + for (int i = 0; i < getNumPages(); i++) { + pageCache[i] = NULL; + } + } + if (!pageCache[page-1]) { + pageCache[page-1] = parsePage(getPageOffset(page), page); + if (!pageCache[page-1]) { + error(-1, "Failed parsing page %d at offset", + page, getPageOffset(page)); + } + } + return pageCache[page-1]; + } else { return catalog->getPage(page); } } diff --git a/poppler/PDFDoc.h b/poppler/PDFDoc.h index b2f40c9..99c005e 100644 --- a/poppler/PDFDoc.h +++ b/poppler/PDFDoc.h @@ -237,6 +237,9 @@ private: void saveIncrementalUpdate (OutStream* outStr); void saveCompleteRewrite (OutStream* outStr); + Guint getPageOffset(int page); + Page *parsePage(Guint offset, int page); + // Get hints. Hints *getHints(); @@ -266,6 +269,7 @@ private: #ifndef DISABLE_OUTLINE Outline *outline; #endif + Page **pageCache; GBool ok; int errCode; -- 1.6.4.2 From fluffymike at googlemail.com Thu Apr 29 05:54:18 2010 From: fluffymike at googlemail.com (Mike Tonks) Date: Thu, 29 Apr 2010 13:54:18 +0100 Subject: [poppler] Compile Error: undefined reference to `png_destroy_write_struct' In-Reply-To: References: <201004282139.41249.aacid@kde.org> Message-ID: Hi Hib, Yes, that seemed to get things moving, but then failed later in the build: TextOutputDev.cc: In member function 'void TextPage::coalesce(GBool, GBool)': TextOutputDev.cc:3039:14: error: 'DBL_MAX' was not declared in this scope TextOutputDev.cc:3194:23: error: 'DBL_MAX' was not declared in this scope TextOutputDev.cc:3195:23: error: 'DBL_MIN' was not declared in this scope TextOutputDev.cc:3246:21: error: 'DBL_MAX' was not declared in this scope TextOutputDev.cc:3247:21: error: 'DBL_MIN' was not declared in this scope TextOutputDev.cc: In member function 'void ActualText::beginMC(Dict*)': TextOutputDev.cc:5058:58: warning: deprecated conversion from string constant to 'char*' TextOutputDev.cc: In constructor 'TextOutputDev::TextOutputDev(char*, GBool, GBool, GBool)': TextOutputDev.cc:5149:57: warning: deprecated conversion from string constant to 'char*' make[3]: *** [TextOutputDev.lo] Error 1 make[3]: Leaving directory `/home/Owner/poppler-0.13.3/poppler' make[2]: *** [all] Error 2 make[2]: Leaving directory `/home/Owner/poppler-0.13.3/poppler' make[1]: *** [all-recursive] Error 1 make[1]: Leaving directory `/home/Owner/poppler-0.13.3' From hib at hiberis.nl Thu Apr 29 06:08:03 2010 From: hib at hiberis.nl (Hib Eris) Date: Thu, 29 Apr 2010 15:08:03 +0200 Subject: [poppler] Compile Error: undefined reference to `png_destroy_write_struct' In-Reply-To: References: <201004282139.41249.aacid@kde.org> Message-ID: On Thu, Apr 29, 2010 at 2:54 PM, Mike Tonks wrote: > Hi Hib, > > Yes, that seemed to get things moving, but then failed later in the build: > > TextOutputDev.cc: In member function 'void TextPage::coalesce(GBool, GBool)': > TextOutputDev.cc:3039:14: error: 'DBL_MAX' was not declared in this scope > TextOutputDev.cc:3194:23: error: 'DBL_MAX' was not declared in this scope > TextOutputDev.cc:3195:23: error: 'DBL_MIN' was not declared in this scope > TextOutputDev.cc:3246:21: error: 'DBL_MAX' was not declared in this scope > TextOutputDev.cc:3247:21: error: 'DBL_MIN' was not declared in this scope > TextOutputDev.cc: In member function 'void ActualText::beginMC(Dict*)': > TextOutputDev.cc:5058:58: warning: deprecated conversion from string > constant to 'char*' > TextOutputDev.cc: In constructor 'TextOutputDev::TextOutputDev(char*, > GBool, GBool, GBool)': > TextOutputDev.cc:5149:57: warning: deprecated conversion from string > constant to 'char*' > make[3]: *** [TextOutputDev.lo] Error 1 > make[3]: Leaving directory `/home/Owner/poppler-0.13.3/poppler' > make[2]: *** [all] Error 2 > make[2]: Leaving directory `/home/Owner/poppler-0.13.3/poppler' > make[1]: *** [all-recursive] Error 1 > make[1]: Leaving directory `/home/Owner/poppler-0.13.3' > Try this patch: http://cgit.freedesktop.org/poppler/poppler/commit/?id=5b822011029f3721fbafd4a7bf01b9d6fee35d25 From fluffymike at googlemail.com Thu Apr 29 06:30:10 2010 From: fluffymike at googlemail.com (Mike Tonks) Date: Thu, 29 Apr 2010 14:30:10 +0100 Subject: [poppler] Compile Error: undefined reference to `png_destroy_write_struct' In-Reply-To: References: <201004282139.41249.aacid@kde.org> Message-ID: Hi Hib, Yes, your patch seemed to fix that one, thanks! Now I'm getting a similar message to the one with 0.12.4: ... CXXLD libpoppler.la Info: resolving vtable for __cxxabiv1::__si_class_type_info by linking to __imp___ZTVN10__cxxabiv120__si_class_type_infoE (auto-import) Info: resolving vtable for __cxxabiv1::__class_type_info by linking to __imp___ZTVN10__cxxabiv117__class_type_infoE (auto-import) Creating library file: .libs/libpoppler.dll.a c:/mingw/bin/../lib/gcc/mingw32/4.5.0/../../../../mingw32/bin/ld.exe: warning: auto-importing has been activated without --enable-auto-import specifie d on the command line. This should work unless it involves constant data structures referencing symbols from auto-imported DLLs. ../goo/.libs/libgoo.a(PNGWriter.o):C:\msys\1.0\home\Owner\poppler-0.13.3\goo/PNGWriter.cc:106: undefined reference to `png_write_end' ../goo/.libs/libgoo.a(PNGWriter.o):C:\msys\1.0\home\Owner\poppler-0.13.3\goo/PNGWriter.cc:94: undefined reference to `png_write_rows' ../goo/.libs/libgoo.a(PNGWriter.o):C:\msys\1.0\home\Owner\poppler-0.13.3\goo/PNGWriter.cc:81: undefined reference to `png_write_image' ../goo/.libs/libgoo.a(PNGWriter.o):C:\msys\1.0\home\Owner\poppler-0.13.3\goo/PNGWriter.cc:34: undefined reference to `png_create_write_struct' ../goo/.libs/libgoo.a(PNGWriter.o):C:\msys\1.0\home\Owner\poppler-0.13.3\goo/PNGWriter.cc:40: undefined reference to `png_create_info_struct' ../goo/.libs/libgoo.a(PNGWriter.o):C:\msys\1.0\home\Owner\poppler-0.13.3\goo/PNGWriter.cc:52: undefined reference to `png_init_io' ../goo/.libs/libgoo.a(PNGWriter.o):C:\msys\1.0\home\Owner\poppler-0.13.3\goo/PNGWriter.cc:59: undefined reference to `png_set_compression_level' ../goo/.libs/libgoo.a(PNGWriter.o):C:\msys\1.0\home\Owner\poppler-0.13.3\goo/PNGWriter.cc:65: undefined reference to `png_set_IHDR' ../goo/.libs/libgoo.a(PNGWriter.o):C:\msys\1.0\home\Owner\poppler-0.13.3\goo/PNGWriter.cc:68: undefined reference to `png_set_pHYs' ../goo/.libs/libgoo.a(PNGWriter.o):C:\msys\1.0\home\Owner\poppler-0.13.3\goo/PNGWriter.cc:70: undefined reference to `png_write_info' ../goo/.libs/libgoo.a(PNGWriter.o): In function `~PNGWriter': C:\msys\1.0\home\Owner\poppler-0.13.3\goo/PNGWriter.cc:28: undefined reference to `png_destroy_write_struct' collect2: ld returned 1 exit status make[3]: *** [libpoppler.la] Error 1 make[3]: Leaving directory `/home/Owner/poppler-0.13.3/poppler' make[2]: *** [all] Error 2 make[2]: Leaving directory `/home/Owner/poppler-0.13.3/poppler' make[1]: *** [all-recursive] Error 1 make[1]: Leaving directory `/home/Owner/poppler-0.13.3' make: *** [all] Error 2 On 29 April 2010 14:08, Hib Eris wrote: > On Thu, Apr 29, 2010 at 2:54 PM, Mike Tonks wrote: >> Hi Hib, >> >> Yes, that seemed to get things moving, but then failed later in the build: >> >> TextOutputDev.cc: In member function 'void TextPage::coalesce(GBool, GBool)': >> TextOutputDev.cc:3039:14: error: 'DBL_MAX' was not declared in this scope >> TextOutputDev.cc:3194:23: error: 'DBL_MAX' was not declared in this scope >> TextOutputDev.cc:3195:23: error: 'DBL_MIN' was not declared in this scope >> TextOutputDev.cc:3246:21: error: 'DBL_MAX' was not declared in this scope >> TextOutputDev.cc:3247:21: error: 'DBL_MIN' was not declared in this scope >> TextOutputDev.cc: In member function 'void ActualText::beginMC(Dict*)': >> TextOutputDev.cc:5058:58: warning: deprecated conversion from string >> constant to 'char*' >> TextOutputDev.cc: In constructor 'TextOutputDev::TextOutputDev(char*, >> GBool, GBool, GBool)': >> TextOutputDev.cc:5149:57: warning: deprecated conversion from string >> constant to 'char*' >> make[3]: *** [TextOutputDev.lo] Error 1 >> make[3]: Leaving directory `/home/Owner/poppler-0.13.3/poppler' >> make[2]: *** [all] Error 2 >> make[2]: Leaving directory `/home/Owner/poppler-0.13.3/poppler' >> make[1]: *** [all-recursive] Error 1 >> make[1]: Leaving directory `/home/Owner/poppler-0.13.3' >> > > Try this patch: > > http://cgit.freedesktop.org/poppler/poppler/commit/?id=5b822011029f3721fbafd4a7bf01b9d6fee35d25 > From hib at hiberis.nl Thu Apr 29 06:41:56 2010 From: hib at hiberis.nl (Hib Eris) Date: Thu, 29 Apr 2010 15:41:56 +0200 Subject: [poppler] Compile Error: undefined reference to `png_destroy_write_struct' In-Reply-To: References: <201004282139.41249.aacid@kde.org> Message-ID: On Thu, Apr 29, 2010 at 3:30 PM, Mike Tonks wrote: > Yes, your patch seemed to fix that one, thanks! (It was not my patch) > > Now I'm getting a similar message to the one with 0.12.4: > > ... > ?CXXLD ?libpoppler.la > Info: resolving vtable for __cxxabiv1::__si_class_type_info by linking > to __imp___ZTVN10__cxxabiv120__si_class_type_infoE (auto-import) > Info: resolving vtable for __cxxabiv1::__class_type_info by linking to > __imp___ZTVN10__cxxabiv117__class_type_infoE (auto-import) > Creating library file: .libs/libpoppler.dll.a > warning: auto-importing has been activated without > --enable-auto-import specifie > d on the command line. > This should work unless it involves constant data structures > referencing symbols from auto-imported DLLs. > ../goo/.libs/libgoo.a(PNGWriter.o):C:\msys\1.0\home\Owner\poppler-0.13.3\goo/PNGWriter.cc:106: > undefined reference to `png_write_end' Seems like you have a problem with your png library, not sure what it is. Can you build poppler without png support with 'configure --disable-libpng'? Hib From carlosgc at kemper.freedesktop.org Thu Apr 29 09:36:19 2010 From: carlosgc at kemper.freedesktop.org (Carlos Garcia Campos) Date: Thu, 29 Apr 2010 09:36:19 -0700 (PDT) Subject: [poppler] poppler/Gfx.cc Message-ID: <20100429163619.ECAEBF8111@kemper.freedesktop.org> poppler/Gfx.cc | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) New commits: commit e909219d8e92994bd52976f9676015fa6ca9fc91 Author: Carlos Garcia Campos Date: Thu Apr 29 18:34:22 2010 +0200 Set textHaveCSPattern=false again before filling the pattern in opEndText() Fixes cairo backend regressions caused by commit ccf238b32e236f69c0507a5421ac2649dfa8d865. diff --git a/poppler/Gfx.cc b/poppler/Gfx.cc index 6259733..de4eb24 100644 --- a/poppler/Gfx.cc +++ b/poppler/Gfx.cc @@ -3341,13 +3341,13 @@ void Gfx::opEndText(Object args[], int numArgs) { GBool needFill = out->deviceHasTextClip(state); out->endTextObject(state); drawText = gFalse; - if (out->supportTextCSPattern(state) && textHaveCSPattern) { + if (textHaveCSPattern) { + textHaveCSPattern = gFalse; if (needFill) { doPatternFill(gTrue); } out->restoreState(state); } - textHaveCSPattern = gFalse; } //------------------------------------------------------------------------ From carlosgc at kemper.freedesktop.org Thu Apr 29 11:29:23 2010 From: carlosgc at kemper.freedesktop.org (Carlos Garcia Campos) Date: Thu, 29 Apr 2010 11:29:23 -0700 (PDT) Subject: [poppler] poppler/Gfx.cc Message-ID: <20100429182923.CA57FF8111@kemper.freedesktop.org> poppler/Gfx.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) New commits: commit 71063d51a45835b0267a7e3f823ef49689cfd06f Author: Carlos Garcia Campos Date: Thu Apr 29 20:28:07 2010 +0200 Make sure we are drawing text before calling endTextObject() This is actually the right fix for the previous commit. diff --git a/poppler/Gfx.cc b/poppler/Gfx.cc index de4eb24..221caef 100644 --- a/poppler/Gfx.cc +++ b/poppler/Gfx.cc @@ -1297,7 +1297,7 @@ void Gfx::opSetRenderingIntent(Object args[], int numArgs) { void Gfx::opSetFillGray(Object args[], int numArgs) { GfxColor color; - if (textHaveCSPattern) { + if (textHaveCSPattern && drawText) { GBool needFill = out->deviceHasTextClip(state); out->endTextObject(state); if (needFill) { @@ -1335,7 +1335,7 @@ void Gfx::opSetFillCMYKColor(Object args[], int numArgs) { GfxColor color; int i; - if (textHaveCSPattern) { + if (textHaveCSPattern && drawText) { GBool needFill = out->deviceHasTextClip(state); out->endTextObject(state); if (needFill) { @@ -1378,7 +1378,7 @@ void Gfx::opSetFillRGBColor(Object args[], int numArgs) { GfxColor color; int i; - if (textHaveCSPattern) { + if (textHaveCSPattern && drawText) { GBool needFill = out->deviceHasTextClip(state); out->endTextObject(state); if (needFill) { @@ -1430,7 +1430,7 @@ void Gfx::opSetFillColorSpace(Object args[], int numArgs) { } obj.free(); if (colorSpace) { - if (textHaveCSPattern) { + if (textHaveCSPattern && drawText) { GBool needFill = out->deviceHasTextClip(state); out->endTextObject(state); if (needFill) { @@ -3342,12 +3342,12 @@ void Gfx::opEndText(Object args[], int numArgs) { out->endTextObject(state); drawText = gFalse; if (textHaveCSPattern) { - textHaveCSPattern = gFalse; if (needFill) { doPatternFill(gTrue); } out->restoreState(state); } + textHaveCSPattern = gFalse; } //------------------------------------------------------------------------ From pino at kemper.freedesktop.org Thu Apr 29 16:14:46 2010 From: pino at kemper.freedesktop.org (Pino Toscano) Date: Thu, 29 Apr 2010 16:14:46 -0700 (PDT) Subject: [poppler] 2 commits - poppler/ArthurOutputDev.cc poppler/poppler-config.h.cmake poppler/poppler-config.h.in Message-ID: <20100429231446.A5C91F8187@kemper.freedesktop.org> poppler/ArthurOutputDev.cc | 4 +--- poppler/poppler-config.h.cmake | 5 +++++ poppler/poppler-config.h.in | 5 +++++ 3 files changed, 11 insertions(+), 3 deletions(-) New commits: commit ac32021704178721ee007a6b6831283e323e500f Author: Pino Toscano Date: Fri Apr 30 01:14:14 2010 +0200 demote the #warning to a simple FIXME comment diff --git a/poppler/ArthurOutputDev.cc b/poppler/ArthurOutputDev.cc index 821b84e..7573f3f 100644 --- a/poppler/ArthurOutputDev.cc +++ b/poppler/ArthurOutputDev.cc @@ -600,9 +600,7 @@ void ArthurOutputDev::drawChar(GfxState *state, double x, double y, fontPath->pts[i+1].x+x0, fontPath->pts[i+1].y+y0); ++i; } -#ifdef __GNUC__ -#warning FIX THIS -#endif +// FIXME fix this // else if (fontPath->flags[i] & splashPathArcCW) { // qDebug() << "Need to implement arc"; // } commit 8c1bc17552c989c15f318d9d109607a9a594ca6b Author: Pino Toscano Date: Fri Apr 30 01:12:19 2010 +0200 MSVC: define fmax() and fmin() MSVC does not provide those functions, so we need to define them to the existing max()/mix() macros. Thanks to Patrick Spendrin for the hint! diff --git a/poppler/poppler-config.h.cmake b/poppler/poppler-config.h.cmake index 95e95cc..3131f6b 100644 --- a/poppler/poppler-config.h.cmake +++ b/poppler/poppler-config.h.cmake @@ -101,5 +101,10 @@ #define GCC_PRINTF_FORMAT(fmt_index, va_index) #endif +#if defined(_MSC_VER) +#define fmax(a, b) max(a, b) +#define fmin(a, b) min(a, b) +#endif + #endif /* POPPLER_CONFIG_H */ diff --git a/poppler/poppler-config.h.in b/poppler/poppler-config.h.in index 7b0644c..1764363 100644 --- a/poppler/poppler-config.h.in +++ b/poppler/poppler-config.h.in @@ -101,5 +101,10 @@ #define GCC_PRINTF_FORMAT(fmt_index, va_index) #endif +#if defined(_MSC_VER) +#define fmax(a, b) max(a, b) +#define fmin(a, b) min(a, b) +#endif + #endif /* POPPLER_CONFIG_H */ From aacid at kde.org Thu Apr 29 16:22:59 2010 From: aacid at kde.org (Albert Astals Cid) Date: Fri, 30 Apr 2010 00:22:59 +0100 Subject: [poppler] Does poppler depend of X11? In-Reply-To: References: Message-ID: <201004300023.00093.aacid@kde.org> A Dijous, 29 d'abril de 2010, webquinty quinty va escriure: > Hello, > > I would like to use poppler with Qt embedded 4.5.0 withouy X server ( Qt > framebuffer -qws ). > is it possible? Try it, report if it works. Albert > > Best regards. > John Martin > Spain From fluffymike at googlemail.com Fri Apr 30 02:12:40 2010 From: fluffymike at googlemail.com (Mike Tonks) Date: Fri, 30 Apr 2010 10:12:40 +0100 Subject: [poppler] Does poppler depend of X11? In-Reply-To: <201004300023.00093.aacid@kde.org> References: <201004300023.00093.aacid@kde.org> Message-ID: I have poppler building fine on headless ubuntu server, no X server / x11 packages installed. So should be ok I think. On 30 April 2010 00:22, Albert Astals Cid wrote: > A Dijous, 29 d'abril de 2010, webquinty quinty va escriure: >> Hello, >> >> I would like to use poppler with Qt embedded 4.5.0 withouy X server ( Qt >> framebuffer -qws ). >> is it possible? > > Try it, report if it works. > > Albert > >> >> Best regards. >> John Martin >> Spain > _______________________________________________ > poppler mailing list > poppler at lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/poppler > From thomas at txtbear.com Fri Apr 30 05:51:37 2010 From: thomas at txtbear.com (Stefan Thomas) Date: Fri, 30 Apr 2010 14:51:37 +0200 Subject: [poppler] [PATCH] Message-ID: <4BDAD259.2040900@txtbear.com> Hey folks, Got a quick patch. The GfxFont parses the FontWeight as per the PDF Specification, allowing only certain discrete values and raising an error otherwise. We've encountered PDFs in the wild that don't adhere to the standard. Acroread seems to handle the case gracefully, falling back to the nearest valid font weight. Poppler raises an error and ignores the FontWeight property altogether. This patch adds the same graceful handling to Poppler. I don't see a reason not to allow non-standard font weights. Poppler is a renderer, not a validator. If we can handle this case gracefully and transparently to the user, we should. However, one could make an argument for adding a basic bounds check for values outside of 50-950 or so. Personally I'm from the school of trying to handle problems as locally as possible, but if a PDF has a font weight with nonsensical values, perhaps that would be better handled with an error. We opted to go without the bounds check for simplicity, but it would be easy enough to add: if (obj2.getNum() < 50 || obj2.getNum() > 950) error(-1, "Invalid Font Weight"); else if (obj2.getNum() <= 150) weight = W100; [..etc..] Cheers, Stefan Thomas CTO TxtBear AG Switzerland | www.txtbear.com | thomas at txtbear.com -------------- next part -------------- An embedded and charset-unspecified text was scrubbed... Name: 0001-Changed-GfxFont-to-accept-non-standard-font-sizes.patch URL: From thomas at txtbear.com Thu Apr 29 04:59:04 2010 From: thomas at txtbear.com (Stefan Thomas) Date: Thu, 29 Apr 2010 12:59:04 +0100 Subject: [PATCH] Changed GfxFont to accept non-standard font sizes. Message-ID: Only certain font sizes are allowed according to the PDF Specification. However, other sizes do appear in the wild and there is no reason not to handle them gracefully, by falling back to the nearest valid value. --- poppler/GfxFont.cc | 19 +++++++++---------- 1 files changed, 9 insertions(+), 10 deletions(-) diff --git a/poppler/GfxFont.cc b/poppler/GfxFont.cc index f823faf..8787a3b 100644 --- a/poppler/GfxFont.cc +++ b/poppler/GfxFont.cc @@ -264,16 +264,15 @@ void GfxFont::readFontDescriptor(XRef *xref, Dict *fontDict) { // get weight obj1.dictLookup("FontWeight", &obj2); if (obj2.isNum()) { - if (obj2.getNum() == 100) weight = W100; - else if (obj2.getNum() == 200) weight = W200; - else if (obj2.getNum() == 300) weight = W300; - else if (obj2.getNum() == 400) weight = W400; - else if (obj2.getNum() == 500) weight = W500; - else if (obj2.getNum() == 600) weight = W600; - else if (obj2.getNum() == 700) weight = W700; - else if (obj2.getNum() == 800) weight = W800; - else if (obj2.getNum() == 900) weight = W900; - else error(-1, "Invalid Font Weight"); + if (obj2.getNum() <= 150) weight = W100; + else if (obj2.getNum() <= 250) weight = W200; + else if (obj2.getNum() <= 350) weight = W300; + else if (obj2.getNum() <= 450) weight = W400; + else if (obj2.getNum() <= 550) weight = W500; + else if (obj2.getNum() <= 650) weight = W600; + else if (obj2.getNum() <= 750) weight = W700; + else if (obj2.getNum() <= 850) weight = W800; + else weight = W900; } obj2.free(); -- 1.6.3.3 --------------090002060809000209090806-- From carlosgc at kemper.freedesktop.org Fri Apr 30 06:09:16 2010 From: carlosgc at kemper.freedesktop.org (Carlos Garcia Campos) Date: Fri, 30 Apr 2010 06:09:16 -0700 (PDT) Subject: [poppler] poppler/CairoOutputDev.cc Message-ID: <20100430130916.0CE19F81CD@kemper.freedesktop.org> poppler/CairoOutputDev.cc | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) New commits: commit 6b2983f89e87792a393880dab6dc1fedb748db2c Author: Carlos Garcia Campos Date: Fri Apr 30 14:48:50 2010 +0200 [cairo] Set device offset and matrix to smask depending on the group target It seems to fix all of my test cases. Fixes bug #27208. diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc index 0ae0885..01ff92c 100644 --- a/poppler/CairoOutputDev.cc +++ b/poppler/CairoOutputDev.cc @@ -1279,9 +1279,13 @@ void CairoOutputDev::setSoftMask(GfxState * state, double * bbox, GBool alpha, /* make the device offset of the new mask match that of the group */ double x_offset, y_offset; - cairo_surface_t *pats; - cairo_pattern_get_surface(group, &pats); - cairo_surface_get_device_offset(pats, &x_offset, &y_offset); + if (cairo_get_group_target(cairo) == cairo_get_target(cairo)) { + cairo_surface_get_device_offset(cairo_get_group_target(cairo), &x_offset, &y_offset); + } else { + cairo_surface_t *pats; + cairo_pattern_get_surface(group, &pats); + cairo_surface_get_device_offset(pats, &x_offset, &y_offset); + } cairo_surface_set_device_offset(source, x_offset, y_offset); /* paint the group */ @@ -1316,9 +1320,14 @@ void CairoOutputDev::setSoftMask(GfxState * state, double * bbox, GBool alpha, /* setup the new mask pattern */ mask = cairo_pattern_create_for_surface(source); - cairo_matrix_t patMatrix; - cairo_pattern_get_matrix(group, &patMatrix); - cairo_pattern_set_matrix(mask, &patMatrix); + + if (cairo_get_group_target(cairo) == cairo_get_target(cairo)) { + cairo_pattern_set_matrix(mask, &mat); + } else { + cairo_matrix_t patMatrix; + cairo_pattern_get_matrix(group, &patMatrix); + cairo_pattern_set_matrix(mask, &patMatrix); + } cairo_surface_destroy(source); } else { From aacid at kde.org Fri Apr 30 12:56:32 2010 From: aacid at kde.org (Albert Astals Cid) Date: Fri, 30 Apr 2010 20:56:32 +0100 Subject: [poppler] [PATCH] In-Reply-To: <4BDAD259.2040900@txtbear.com> References: <4BDAD259.2040900@txtbear.com> Message-ID: <201004302056.32334.aacid@kde.org> A Divendres, 30 d'abril de 2010, Stefan Thomas va escriure: > Hey folks, > > Got a quick patch. The GfxFont parses the FontWeight as per the PDF > Specification, allowing only certain discrete values and raising an > error otherwise. We've encountered PDFs in the wild that don't adhere to > the standard. Acroread seems to handle the case gracefully, falling back > to the nearest valid font weight. Poppler raises an error and ignores > the FontWeight property altogether. > > This patch adds the same graceful handling to Poppler. I don't see a > reason not to allow non-standard font weights. Poppler is a renderer, > not a validator. If we can handle this case gracefully and transparently > to the user, we should. > > However, one could make an argument for adding a basic bounds check for > values outside of 50-950 or so. Personally I'm from the school of trying > to handle problems as locally as possible, but if a PDF has a font > weight with nonsensical values, perhaps that would be better handled > with an error. We opted to go without the bounds check for simplicity, > but it would be easy enough to add: > > if (obj2.getNum() < 50 || obj2.getNum() > 950) error(-1, "Invalid Font > Weight"); > else if (obj2.getNum() <= 150) weight = W100; > [..etc..] Is there any chance we can get such a PDF? Albert > > Cheers, > > Stefan Thomas > CTO > > TxtBear AG Switzerland | www.txtbear.com | thomas at txtbear.com From aacid at kde.org Fri Apr 30 21:26:56 2010 From: aacid at kde.org (Albert Astals Cid) Date: Sat, 1 May 2010 05:26:56 +0100 Subject: [poppler] FYI: Adobe updated CMap resource In-Reply-To: <20100429170811.9ed2fb2f.henrich@debian.or.jp> References: <20100429170811.9ed2fb2f.henrich@debian.or.jp> Message-ID: <201005010526.56669.aacid@kde.org> A Dijous, 29 d'abril de 2010, Hideki Yamane va escriure: > Hi, > > Probably you know but FYI. Adobe updated CMap resource > see http://forums.adobe.com/thread/625534 > - Adobe-CNS1-6 > - Adobe-GB1-5 > - Adobe-Japan1-6 > > Please consider to update poppler-data as well, thanks. Actually no, i had no idea of those updates. Albert From aacid at kde.org Fri Apr 30 21:28:14 2010 From: aacid at kde.org (Albert Astals Cid) Date: Sat, 1 May 2010 05:28:14 +0100 Subject: [poppler] Poppler-data 0.4.1 released Message-ID: <201005010528.14378.aacid@kde.org> Available from http://poppler.freedesktop.org/poppler-data-0.4.1.tar.gz Changes since 0.4.0: Updated some files as done by Adobe at http://forums.adobe.com/thread/625534 Albert