[poppler] 5 commits - poppler/XRef.cc

Albert Astals Cid aacid at kemper.freedesktop.org
Sat Apr 6 14:19:37 PDT 2013


 poppler/XRef.cc |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

New commits:
commit 94bee4601cbbda0e7c6205a04650e0510f198aee
Merge: 42368fb b312210
Author: Albert Astals Cid <aacid at kde.org>
Date:   Sat Apr 6 23:19:25 2013 +0200

    Merge remote-tracking branch 'origin/poppler-0.22'

commit b312210b630f96baeb8b2f3b49b0b79779609d98
Author: Albert Astals Cid <aacid at kde.org>
Date:   Sat Apr 6 23:18:18 2013 +0200

    Fix for complete rewrites in repaired files
    
    Part 2 of bug #62985
    if You save a PDF with defect xref offsets, the
    
    readXRefUntil(-1 /* read all xref sections */, &xrefStreamObjNums)
    
    in XRef::scanSpecialFlags() will destroy the already reconstructed entries table, but this means that any modification which the user did in the meantime get lost. This can be tested i.e. with bug168518.pdf.

diff --git a/poppler/XRef.cc b/poppler/XRef.cc
index 81e939a..0e76993 100644
--- a/poppler/XRef.cc
+++ b/poppler/XRef.cc
@@ -1556,7 +1556,9 @@ void XRef::scanSpecialFlags() {
   prevXRefOffset = mainXRefOffset;
 
   std::vector<int> xrefStreamObjNums;
-  readXRefUntil(-1 /* read all xref sections */, &xrefStreamObjNums);
+  if (!streamEndsLen) { // don't do it for already reconstructed xref
+    readXRefUntil(-1 /* read all xref sections */, &xrefStreamObjNums);
+  }
 
   // Mark object streams as DontRewrite, because we write each object
   // individually in full rewrite mode.
commit 09ddb34f202be2111c70901724d64d3b61483c7a
Author: Albert Astals Cid <aacid at kde.org>
Date:   Mon Mar 25 22:55:58 2013 +0100

    Only write the file once when saving
    
    Bug #62739

diff --git a/poppler/PDFDoc.cc b/poppler/PDFDoc.cc
index 0d78588..dde32b8 100644
--- a/poppler/PDFDoc.cc
+++ b/poppler/PDFDoc.cc
@@ -795,7 +795,7 @@ int PDFDoc::saveAs(OutStream *outStr, PDFWriteMode mode) {
   if (!updated && mode == writeStandard) {
     // simply copy the original file
     saveWithoutChangesAs (outStr);
-  } if (mode == writeForceRewrite) {
+  } else if (mode == writeForceRewrite) {
     saveCompleteRewrite(outStr);
   } else {
     saveIncrementalUpdate(outStr);
commit 75378557f409a5a2305ea0fb42c56184c74ba887
Author: Carlos Garcia Campos <carlosgc at gnome.org>
Date:   Sun Mar 24 12:53:29 2013 +0100

    glib: Always start from the beginning when starting a new search on a page
    
    And start from previous match when searching the next one on the same
    page. This allows to search for the same string multiple times on the
    same page.
    
    https://bugs.freedesktop.org/show_bug.cgi?id=59972

diff --git a/glib/poppler-page.cc b/glib/poppler-page.cc
index b88c70b..631edb5 100644
--- a/glib/poppler-page.cc
+++ b/glib/poppler-page.cc
@@ -877,6 +877,7 @@ poppler_page_find_text_with_options (PopplerPage     *page,
   double height;
   TextPage *text_dev;
   gboolean backwards;
+  gboolean start_at_last = FALSE;
 
   g_return_val_if_fail (POPPLER_IS_PAGE (page), NULL);
   g_return_val_if_fail (text != NULL, NULL);
@@ -893,7 +894,8 @@ poppler_page_find_text_with_options (PopplerPage     *page,
 
   while (text_dev->findText (ucs4, ucs4_len,
                              gFalse, gTrue, // startAtTop, stopAtBottom
-                             gTrue, gFalse, // startAtLast, stopAtLast
+                             start_at_last,
+                             gFalse, //stopAtLast
                              options & POPPLER_FIND_CASE_SENSITIVE,
                              backwards,
                              options & POPPLER_FIND_WHOLE_WORDS_ONLY,
@@ -905,6 +907,7 @@ poppler_page_find_text_with_options (PopplerPage     *page,
       match->x2 = xMax;
       match->y2 = height - yMin;
       matches = g_list_prepend (matches, match);
+      start_at_last = TRUE;
     }
 
   g_free (ucs4);
commit 83cf2d3d3ecce6340d858a2ee037cd5120ac1db5
Author: Jason Crain <jason at aquaticape.us>
Date:   Sat Mar 9 08:44:36 2013 -0600

    TextOutputDev: Set text matrix when painting selection
    
    https://bugs.freedesktop.org/show_bug.cgi?id=61042

diff --git a/poppler/TextOutputDev.cc b/poppler/TextOutputDev.cc
index b0b53fc..cd1358c 100644
--- a/poppler/TextOutputDev.cc
+++ b/poppler/TextOutputDev.cc
@@ -246,6 +246,7 @@ TextWord::TextWord(GfxState *state, int rotA, double fontSizeA) {
   edge = NULL;
   charPos = NULL;
   font = NULL;
+  textMat = NULL;
   len = size = 0;
   spaceAfter = gFalse;
   next = NULL;
@@ -273,11 +274,12 @@ TextWord::~TextWord() {
   gfree(edge);
   gfree(charPos);
   gfree(font);
+  gfree(textMat);
 }
 
 void TextWord::addChar(GfxState *state, TextFontInfo *fontA, double x, double y,
 		       double dx, double dy, int charPosA, int charLen,
-		       CharCode c, Unicode u) {
+		       CharCode c, Unicode u, Matrix textMatA) {
   GfxFont *gfxFont;
   double ascent, descent;
   ascent = descent = 0; // make gcc happy
@@ -289,12 +291,14 @@ void TextWord::addChar(GfxState *state, TextFontInfo *fontA, double x, double y,
     edge = (double *)greallocn(edge, (size + 1), sizeof(double));
     charPos = (int *)greallocn(charPos, size + 1, sizeof(int));
     font = (TextFontInfo **)greallocn(font, size, sizeof(TextFontInfo *));
+    textMat = (Matrix *)greallocn(textMat, size, sizeof(Matrix));
   }
   text[len] = u;
   charcode[len] = c;
   charPos[len] = charPosA;
   charPos[len + 1] = charPosA + charLen;
   font[len] = fontA;
+  textMat[len] = textMatA;
 
   if (len == 0) {
     if ((gfxFont = fontA->gfxFont)) {
@@ -448,6 +452,7 @@ void TextWord::merge(TextWord *word) {
     edge = (double *)greallocn(edge, (size + 1), sizeof(double));
     charPos = (int *)greallocn(charPos, size + 1, sizeof(int));
     font = (TextFontInfo **)greallocn(font, size, sizeof(TextFontInfo *));
+    textMat = (Matrix *)greallocn(textMat, size, sizeof(Matrix));
   }
   for (i = 0; i < word->len; ++i) {
     text[len + i] = word->text[i];
@@ -455,6 +460,7 @@ void TextWord::merge(TextWord *word) {
     edge[len + i] = word->edge[i];
     charPos[len + i] = word->charPos[i];
     font[len + i] = word->font[i];
+    textMat[len + i] = word->textMat[i];
   }
   edge[len + word->len] = word->edge[word->len];
   charPos[len + word->len] = word->charPos[word->len];
@@ -2267,6 +2273,7 @@ void TextPage::addChar(GfxState *state, double x, double y,
   GBool overlap;
   int i;
   int wMode;
+  Matrix mat;
 
   // subtract char and word spacing from the dx,dy values
   sp = state->getCharSpace();
@@ -2361,6 +2368,10 @@ void TextPage::addChar(GfxState *state, double x, double y,
       beginWord(state);
     }
 
+    state->getFontTransMat(&mat.m[0], &mat.m[1], &mat.m[2], &mat.m[3]);
+    mat.m[4] = x1;
+    mat.m[5] = y1;
+
     // page rotation and/or transform matrices can cause text to be
     // drawn in reverse order -- in this case, swap the begin/end
     // coordinates and break text into individual chars
@@ -2380,7 +2391,7 @@ void TextPage::addChar(GfxState *state, double x, double y,
     w1 /= uLen;
     h1 /= uLen;
     for (i = 0; i < uLen; ++i) {
-      curWord->addChar(state, curFont, x1 + i*w1, y1 + i*h1, w1, h1, charPos, nBytes, c, u[i]);
+      curWord->addChar(state, curFont, x1 + i*w1, y1 + i*h1, w1, h1, charPos, nBytes, c, u[i], mat);
     }
   }
   charPos += nBytes;
@@ -4270,9 +4281,7 @@ TextSelectionPainter::TextSelectionPainter(TextPage *page,
   out->startPage (0, state);
   out->setDefaultCTM (state->getCTM());
 
-  state->setTextMat(1, 0, 0, -1, 0, 0);
   state->setFillColorSpace(new GfxDeviceRGBColorSpace());
-
 }
 
 TextSelectionPainter::~TextSelectionPainter()
@@ -4333,11 +4342,18 @@ void TextSelectionPainter::visitWord (TextWord *word, int begin, int end,
   while (begin < end) {
     TextFontInfo *font = word->font[begin];
     font->gfxFont->incRefCnt();
-    state->setFont(font->gfxFont, word->fontSize);
+    Matrix *mat = &word->textMat[begin];
+
+    state->setTextMat(mat->m[0], mat->m[1], mat->m[2], mat->m[3], 0, 0);
+    state->setFont(font->gfxFont, 1);
     out->updateFont(state);
 
     int fEnd = begin + 1;
-    while (fEnd < end && font->matches(word->font[fEnd]))
+    while (fEnd < end && font->matches(word->font[fEnd]) &&
+	   mat->m[0] == word->textMat[fEnd].m[0] &&
+	   mat->m[1] == word->textMat[fEnd].m[1] &&
+	   mat->m[2] == word->textMat[fEnd].m[2] &&
+	   mat->m[3] == word->textMat[fEnd].m[3])
       fEnd++;
 
     /* The only purpose of this string is to let the output device query
@@ -4346,7 +4362,7 @@ void TextSelectionPainter::visitWord (TextWord *word, int begin, int end,
     out->beginString(state, string);
 
     for (int i = begin; i < fEnd; i++) {
-      out->drawChar(state, word->edge[i], word->base, 0, 0, 0, 0,
+      out->drawChar(state, word->textMat[i].m[4], word->textMat[i].m[5], 0, 0, 0, 0,
 		    word->charcode[i], 1, NULL, 0);
     }
     out->endString(state);
diff --git a/poppler/TextOutputDev.h b/poppler/TextOutputDev.h
index 100f23e..77facbc 100644
--- a/poppler/TextOutputDev.h
+++ b/poppler/TextOutputDev.h
@@ -122,7 +122,7 @@ public:
   // Add a character to the word.
   void addChar(GfxState *state, TextFontInfo *fontA, double x, double y,
 	       double dx, double dy, int charPosA, int charLen,
-	       CharCode c, Unicode u);
+	       CharCode c, Unicode u, Matrix textMatA);
 
   // Merge <word> onto the end of <this>.
   void merge(TextWord *word);
@@ -187,6 +187,7 @@ private:
   int len;			// length of text/edge/charPos/font arrays
   int size;			// size of text/edge/charPos/font arrays
   TextFontInfo **font;		// font information for each char
+  Matrix *textMat;		// transformation matrix for each char
   double fontSize;		// font size
   GBool spaceAfter;		// set if there is a space between this
 				//   word and the next word on the line


More information about the poppler mailing list