@@ -27,6 +27,10 @@ namespace pdflib
27
27
28
28
bool is_adjacent_to (pdf_resource<PAGE_CELL>& other, double delta);
29
29
30
+ bool intersects (pdf_resource<PAGE_CELL>& other);
31
+
32
+ bool contains (double x, double y);
33
+
30
34
bool has_same_reading_orientation (pdf_resource<PAGE_CELL>& other);
31
35
32
36
bool merge_with (pdf_resource<PAGE_CELL>& other, double delta);
@@ -259,23 +263,46 @@ namespace pdflib
259
263
260
264
return (num_chars>0 ? len/num_chars : 0.0 );
261
265
}
262
-
266
+
267
+ bool pdf_resource<PAGE_CELL>::intersects(pdf_resource<PAGE_CELL>& other)
268
+ {
269
+ // Use point-in-polygon (via even-odd rule) to determine if
270
+ // bounding quadrilaterals intersect.
271
+ return contains (other.r_x0 , other.r_y0 )
272
+ or contains (other.r_x1 , other.r_y1 )
273
+ or contains (other.r_x2 , other.r_y2 )
274
+ or contains (other.r_x3 , other.r_y3 )
275
+ or other.contains (r_x0, r_y0)
276
+ or other.contains (r_x1, r_y1)
277
+ or other.contains (r_x2, r_y2)
278
+ or other.contains (r_x3, r_y3);
279
+ }
280
+
281
+ inline bool inside_plane (double x, double y, double xi, double yi, double xj, double yj)
282
+ {
283
+ return ((yi < y) != (yj > y)) and (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
284
+ }
285
+
286
+ bool pdf_resource<PAGE_CELL>::contains(double x, double y)
287
+ {
288
+ // point-in-polygon via even-odd rule
289
+ bool inside = false ;
290
+ if (inside_plane (x, y, r_x0, r_y0, r_x1, r_y1))
291
+ inside = not inside;
292
+ if (inside_plane (x, y, r_x1, r_y1, r_x2, r_y2))
293
+ inside = not inside;
294
+ if (inside_plane (x, y, r_x2, r_y2, r_x3, r_y3))
295
+ inside = not inside;
296
+ if (inside_plane (x, y, r_x3, r_y3, r_x0, r_y0))
297
+ inside = not inside;
298
+ return inside;
299
+ }
300
+
301
+
263
302
bool pdf_resource<PAGE_CELL>::is_adjacent_to(pdf_resource<PAGE_CELL>& other, double eps)
264
303
{
265
- // This assumes (even for right-to-left text) that other is to the
266
- // right of this. If two cells overlap then they are obviously
267
- // adjacent, otherwise the right side corners of this must be
268
- // within eps of the left side corners of other.
269
-
270
- // Intersection of bounding rectangles (FIXME: Does not actually
271
- // imply overlap for rotated cells, not immediately sure the
272
- // correct and efficient way to compute that)
273
- double max_x0 = std::max (x0, other.x0 );
274
- double min_x1 = std::min (x1, other.x1 );
275
- double max_y0 = std::max (y0 , other.y0 );
276
- double min_y1 = std::min (y1 , other.y1 );
277
- if (max_x0 < min_x1 and max_y0 < min_y1)
278
- return true ;
304
+ // NOTE: This assumes (even for right-to-left text) that other is
305
+ // to the right of this, as the calling code seems to do that.
279
306
280
307
// lower_right(this) : lower_left(other)
281
308
double dx0 = other.r_x0 - r_x1;
0 commit comments