[poppler] poppler/poppler: CairoOutputDev.cc, 1.17, 1.18 TextOutputDev.cc, 1.4, 1.5

Kristian Hogsberg krh at freedesktop.org
Thu Jul 28 15:52:45 EST 2005


Update of /cvs/poppler/poppler/poppler
In directory gabe:/tmp/cvs-serv5910/poppler

Modified Files:
	CairoOutputDev.cc TextOutputDev.cc 
Log Message:
2005-07-28  Kristian Høgsberg  <krh at redhat.com>

        * poppler/TextOutputDev.cc (TextBlock::visitSelection): Assign
        start and stop coordinates in one place so we don't assign the
        same point to both in some corner cases.
        (TextWord::visitSelection): Initialize begin to len, not len + 1
        to fix crash.

        (TextWord::visitSelection, TextLine::visitSelection): Change
        selection trigger; now midpoint of glyph must be included in
        selection area for glyph to be in selection.



Index: CairoOutputDev.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/CairoOutputDev.cc,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -d -r1.17 -r1.18
--- CairoOutputDev.cc	29 Jun 2005 21:24:57 -0000	1.17
+++ CairoOutputDev.cc	28 Jul 2005 05:52:43 -0000	1.18
@@ -473,7 +473,7 @@
   }
 
   image = cairo_image_surface_create_for_data (buffer, CAIRO_FORMAT_A8,
-					  width, height, row_stride);
+					       width, height, row_stride);
   if (image == NULL)
     return;
   pattern = cairo_pattern_create_for_surface (image);

Index: TextOutputDev.cc
===================================================================
RCS file: /cvs/poppler/poppler/poppler/TextOutputDev.cc,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- TextOutputDev.cc	8 Jul 2005 04:59:41 -0000	1.4
+++ TextOutputDev.cc	28 Jul 2005 05:52:43 -0000	1.5
@@ -2992,6 +2992,8 @@
   virtual void visitLine (TextLine *line, 
 			  TextWord *begin,
 			  TextWord *end,
+			  int edge_begin,
+			  int edge_end,
 			  PDFRectangle *selection) = 0;
   virtual void visitWord (TextWord *word, int begin, int end,
 			  PDFRectangle *selection) = 0;
@@ -3018,6 +3020,8 @@
   virtual void visitLine (TextLine *line,
 			  TextWord *begin,
 			  TextWord *end,
+			  int edge_begin,
+			  int edge_end,
 			  PDFRectangle *selection) { };
   virtual void visitWord (TextWord *word, int begin, int end,
 			  PDFRectangle *selection);
@@ -3083,6 +3087,8 @@
   virtual void visitLine (TextLine *line, 
 			  TextWord *begin,
 			  TextWord *end,
+			  int edge_begin,
+			  int edge_end,
 			  PDFRectangle *selection);
   virtual void visitWord (TextWord *word, int begin, int end,
 			  PDFRectangle *selection) { };
@@ -3104,6 +3110,8 @@
 void TextSelectionSizer::visitLine (TextLine *line, 
 				    TextWord *begin,
 				    TextWord *end,
+				    int edge_begin,
+				    int edge_end,
 				    PDFRectangle *selection)
 {
   PDFRectangle *rect;
@@ -3111,18 +3119,11 @@
   int i;
 
   margin = (line->yMax - line->yMin) / 8;
-  x1 = line->xMax;
+  x1 = line->edge[edge_begin];
   y1 = line->yMin - margin;
-  x2 = line->xMin;
+  x2 = line->edge[edge_end];
   y2 = line->yMax + margin;
 
-  for (i = 0; i < line->len; i++) {
-    if (selection->x1 < line->edge[i + 1] && line->edge[i] < x1)
-      x1 = line->edge[i];
-    if (line->edge[i] < selection->x2)
-      x2 = line->edge[i + 1];
-  }
-
   rect = new PDFRectangle (floor (x1 * scale), 
 			   floor (y1 * scale),
 			   ceil (x2 * scale),
@@ -3147,6 +3148,8 @@
   virtual void visitLine (TextLine *line, 
 			  TextWord *begin,
 			  TextWord *end,
+			  int edge_begin,
+			  int edge_end,
 			  PDFRectangle *selection);
   virtual void visitWord (TextWord *word, int begin, int end,
 			  PDFRectangle *selection);
@@ -3188,6 +3191,8 @@
 void TextSelectionPainter::visitLine (TextLine *line,
 				      TextWord *begin,
 				      TextWord *end,
+				      int edge_begin,
+				      int edge_end,
 				      PDFRectangle *selection)
 {
   double x1, y1, x2, y2, margin;
@@ -3197,19 +3202,11 @@
   out->updateFillColor(state);
 
   margin = (line->yMax - line->yMin) / 8;
-  x1 = floor (line->xMax);
+  x1 = floor (line->edge[edge_begin]);
   y1 = floor (line->yMin - margin);
-  x2 = ceil (line->xMin);
+  x2 = ceil (line->edge[edge_end]);
   y2 = ceil (line->yMax + margin);
 
-  for (i = 0; i < line->len; i++) {
-    if (selection->x1 < line->edge[i + 1] || selection->x2 < line->edge[i + 1])
-      if (line->edge[i] < x1)
-	x1 = floor (line->edge[i]);
-    if (line->edge[i] < selection->x2 || line->edge[i] < selection->x1)
-      x2 = ceil (line->edge[i + 1]);
-  }
-
   state->moveTo(x1, y1);
   state->lineTo(x2, y1);
   state->lineTo(x2, y2);
@@ -3248,14 +3245,16 @@
 void TextWord::visitSelection(TextSelectionVisitor *visitor,
 			      PDFRectangle *selection) {
   int i, begin, end;
+  double mid;
 
-  begin = len + 1;
+  begin = len;
   end = 0;
   for (i = 0; i < len; i++) {
-    if (selection->x1 < edge[i + 1] || selection->x2 < edge[i + 1])
+    mid = (edge[i] + edge[i + 1]) / 2;
+    if (selection->x1 < mid || selection->x2 < mid)
       if (i < begin)
 	begin = i;
-    if (edge[i] < selection->x1 || edge[i] < selection->x2)
+    if (mid < selection->x1 || mid < selection->x2)
       end = i + 1;
   }
 
@@ -3265,6 +3264,7 @@
 void TextLine::visitSelection(TextSelectionVisitor *visitor,
 			      PDFRectangle *selection) {
   TextWord *p, *begin, *end;
+  int i, edge_begin, edge_end;
 
   begin = NULL;
   end = NULL;
@@ -3278,7 +3278,18 @@
       end = p->next;
   }
 
-  visitor->visitLine (this, begin, end, selection);
+  edge_begin = len;
+  edge_end = 0;
+  for (i = 0; i < len; i++) {
+    double mid = (edge[i] + edge[i + 1]) /  2;
+    if (selection->x1 < mid || selection->x2 < mid)
+      if (i < edge_begin)
+	edge_begin = i;
+    if (mid < selection->x2 || mid < selection->x1)
+      edge_end = i + 1;
+  }
+
+  visitor->visitLine (this, begin, end, edge_begin, edge_end, selection);
 
   for (p = begin; p != end; p = p->next)
     p->visitSelection (visitor, selection);
@@ -3299,39 +3310,31 @@
       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;
       }
     } 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;
-    }
-
-    if (selection->x1 > p->xMin && selection->y1 > p->yMin &&
-	selection->x2 > p->xMin && selection->y2 > p->yMin) {
-      end = p->next;
-      if (selection->x2 < selection->x1) {
-	stop_x = selection->x1;
-	stop_y = selection->y1;
-      } else {
-	stop_x = selection->x2;
-	stop_y = selection->y2;
-      }
-    } else if (selection->x1 > p->xMin && selection->y1 > p->yMin) {
-      end = p->next;
       stop_x = selection->x1;
       stop_y = selection->y1;
-    } else if (selection->x2 > p->xMin && selection->y2 > p->yMin) {
-      end = p->next;
-      stop_x = selection->x2;
-      stop_y = selection->y2;
     }
+
+    if (selection->x1 > p->xMin && selection->y1 > p->yMin ||
+	selection->x2 > p->xMin && selection->y2 > p->yMin)
+      end = p->next;
   }
 
   visitor->visitBlock (this, begin, end, selection);
@@ -3375,39 +3378,31 @@
       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;
-    }
-
-    if (selection->x1 > b->xMin && selection->y1 > b->yMin &&
-	selection->x2 > b->xMin && selection->y2 > b->yMin) {
-      end = i + 1;
-      if (selection->y2 < selection->y1) {
-	stop_x = selection->x1;
-	stop_y = selection->y1;
-      } else {
-	stop_x = selection->x2;
-	stop_y = selection->y2;
-      }
-    } else if (selection->x1 > b->xMin && selection->y1 > b->yMin) {
-      end = i + 1;
       stop_x = selection->x1;
       stop_y = selection->y1;
-    } else if (selection->x2 > b->xMin && selection->y2 > b->yMin) {
-      end = i + 1;
-      stop_x = selection->x2;
-      stop_y = selection->y2;
     }
+
+    if (selection->x1 > b->xMin && selection->y1 > b->yMin ||
+	selection->x2 > b->xMin && selection->y2 > b->yMin)
+      end = i + 1;
   }
 
   for (i = begin; i < end; i++) {



More information about the poppler mailing list