File poppler-0.12.3-text-selection-tables.patch of Package poppler

--- poppler-0.12.3/poppler/TextOutputDev.cc	2010-01-22 17:06:06.000000000 +0100
+++ poppler-0.12.3/poppler/TextOutputDev.cc	2010-01-22 17:06:29.000000000 +0100
@@ -38,6 +38,7 @@
 #include <stdlib.h>
 #include <stddef.h>
 #include <math.h>
+#include <limits>
 #include <ctype.h>
 #ifdef _WIN32
 #include <fcntl.h> // for O_BINARY
@@ -1154,6 +1155,8 @@ TextBlock::TextBlock(TextPage *pageA, in
   curLine = NULL;
   next = NULL;
   stackNext = NULL;
+  tableId = -1;
+  tableEnd = gFalse;
 }
 
 TextBlock::~TextBlock() {
@@ -1622,31 +1625,31 @@ GBool TextBlock::isBeforeByRule1(TextBlo
   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(TextBlo
 
   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
 
 #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
       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
   }
 #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
   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
   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<double>::max();
+    byMin0 = std::numeric_limits<double>::max();
+    bxMin1 = std::numeric_limits<double>::max();
+    byMin1 = std::numeric_limits<double>::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<double>::max();
+    envelopes[i].x2 = std::numeric_limits<double>::min();
+    envelopes[i].y1 = std::numeric_limits<double>::max();
+    envelopes[i].y2 = std::numeric_limits<double>::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<double>::max();
+      double xMin = std::numeric_limits<double>::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
 	   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 
 {
   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 
     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(TextSelect
   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;
+      }
     }
   }
 
--- poppler-0.12.3/poppler/TextOutputDev.h	2010-01-22 17:06:06.000000000 +0100
+++ poppler-0.12.3/poppler/TextOutputDev.h	2010-01-22 17:06:29.000000000 +0100
@@ -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;
 };
 
 //------------------------------------------------------------------------
openSUSE Build Service is sponsored by