summaryrefslogtreecommitdiff
path: root/libs/canvas
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2020-04-10 17:48:07 +0200
committerRobin Gareus <robin@gareus.org>2020-04-10 18:06:41 +0200
commit7bb8ca1e76986d1b6075627679fe37c143a44ab5 (patch)
treedc2a5c4ddc9278e257840593319df41990c5c8e1 /libs/canvas
parent6cc1e5e75d63a42d37b1b98abd253f61b56e042b (diff)
Interpolate poly-line with view-point #6481
Diffstat (limited to 'libs/canvas')
-rw-r--r--libs/canvas/canvas/poly_item.h10
-rw-r--r--libs/canvas/poly_item.cc45
-rw-r--r--libs/canvas/poly_line.cc4
3 files changed, 54 insertions, 5 deletions
diff --git a/libs/canvas/canvas/poly_item.h b/libs/canvas/canvas/poly_item.h
index 083a9e5b22..25a832e571 100644
--- a/libs/canvas/canvas/poly_item.h
+++ b/libs/canvas/canvas/poly_item.h
@@ -45,6 +45,16 @@ protected:
void render_curve (Rect const&, Cairo::RefPtr<Cairo::Context>, Points const&, Points const&) const;
Points _points;
+
+ /* these return screen-cordidates of the most recent render_path() */
+ Duple const& leftedge () const { return _left; }
+ Duple const& rightedge () const { return _right; }
+
+private:
+ static bool interpolate_line (Duple&, Duple const&, Coord const);
+
+ mutable Duple _left;
+ mutable Duple _right;
};
}
diff --git a/libs/canvas/poly_item.cc b/libs/canvas/poly_item.cc
index c724ddf21d..3ea68c461d 100644
--- a/libs/canvas/poly_item.cc
+++ b/libs/canvas/poly_item.cc
@@ -77,17 +77,56 @@ PolyItem::render_path (Rect const & /* area */, Cairo::RefPtr<Cairo::Context> co
}
Points::const_iterator i = _points.begin();
- Duple c (item_to_window (Duple (i->x, i->y)));
+ Duple c0 (item_to_window (Duple (i->x, i->y)));
const double pixel_adjust = (_outline_width == 1.0 ? 0.5 : 0.0);
- context->move_to (c.x + pixel_adjust, c.y + pixel_adjust);
++i;
+ while (c0.x < -1.) {
+ Duple c1 (item_to_window (Duple (i->x, i->y)));
+ if (interpolate_line(c0, c1, -1)) {
+ break;
+ }
+ if (++i == _points.end()) {
+ c1.x = 0;
+ context->move_to (c1.x + pixel_adjust, c1.y + pixel_adjust);
+ _left = _right = c1;
+ return;
+ }
+ c0 = c1;
+ }
+
+ context->move_to (c0.x + pixel_adjust, c0.y + pixel_adjust);
+ _left = c0;
+
while (i != _points.end()) {
- c = item_to_window (Duple (i->x, i->y));
+ Duple c = item_to_window (Duple (i->x, i->y));
+ if (c.x > 16383) {
+ if (interpolate_line (c0, c, 16383)) {
+ context->line_to (c0.x + pixel_adjust, c0.y + pixel_adjust);
+ }
+ break;
+ }
context->line_to (c.x + pixel_adjust, c.y + pixel_adjust);
+ c0 = c;
++i;
}
+ _right = c0;
+}
+
+bool
+PolyItem::interpolate_line (Duple& c0, Duple const& c1, Coord const x)
+{
+ if (c1.x <= c0.x) {
+ return false;
+ }
+ if (x < c0.x || x > c1.x) {
+ return false;
+ }
+
+ c0.y += ((x - c0.x) / (c1.x - c0.x)) * (c1.y - c0.y);
+ c0.x = x;
+ return true;
}
void
diff --git a/libs/canvas/poly_line.cc b/libs/canvas/poly_line.cc
index ad14dbdd1d..7ef8e4a5aa 100644
--- a/libs/canvas/poly_line.cc
+++ b/libs/canvas/poly_line.cc
@@ -71,8 +71,8 @@ PolyLine::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) cons
Duple y (0, _y1);
float y1 = item_to_window (y).y;
render_path (area, context);
- Duple c0 (item_to_window (_points.back()));
- Duple c1 (item_to_window (_points.front()));
+ Duple const& c0 (rightedge ());
+ Duple const& c1 (leftedge ());
if (c0.x < vp.x1) {
context->line_to (vp.x1, c0.y);
context->line_to (vp.x1, y1);