aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl
diff options
context:
space:
mode:
authormaxim-yurchuk <maxim-yurchuk@yandex-team.com>2024-10-09 12:29:46 +0300
committermaxim-yurchuk <maxim-yurchuk@yandex-team.com>2024-10-09 13:14:22 +0300
commit9731d8a4bb7ee2cc8554eaf133bb85498a4c7d80 (patch)
treea8fb3181d5947c0d78cf402aa56e686130179049 /contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl
parenta44b779cd359f06c3ebbef4ec98c6b38609d9d85 (diff)
downloadydb-9731d8a4bb7ee2cc8554eaf133bb85498a4c7d80.tar.gz
publishFullContrib: true for ydb
<HIDDEN_URL> commit_hash:c82a80ac4594723cebf2c7387dec9c60217f603e
Diffstat (limited to 'contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl')
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_bezier_ctrl.cpp370
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_cbox_ctrl.cpp214
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_gamma_ctrl.cpp433
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_gamma_spline.cpp130
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_polygon_ctrl.cpp332
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_rbox_ctrl.cpp325
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_scale_ctrl.cpp454
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_slider_ctrl.cpp349
-rw-r--r--contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_spline_ctrl.cpp407
9 files changed, 3014 insertions, 0 deletions
diff --git a/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_bezier_ctrl.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_bezier_ctrl.cpp
new file mode 100644
index 0000000000..13a4c15af9
--- /dev/null
+++ b/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_bezier_ctrl.cpp
@@ -0,0 +1,370 @@
+//----------------------------------------------------------------------------
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
+//
+// Permission to copy, use, modify, sell and distribute this software
+// is granted provided this copyright notice appears in all copies.
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+//
+//----------------------------------------------------------------------------
+// Contact: mcseem@antigrain.com
+// mcseemagg@yahoo.com
+// http://www.antigrain.com
+//----------------------------------------------------------------------------
+//
+// classes bezier_ctrl_impl, bezier_ctrl
+//
+//----------------------------------------------------------------------------
+
+#include <string.h>
+#include <stdio.h>
+#include "ctrl/agg_bezier_ctrl.h"
+
+namespace agg
+{
+
+ //------------------------------------------------------------------------
+ bezier_ctrl_impl::bezier_ctrl_impl() :
+ ctrl(0,0,1,1,false),
+ m_stroke(m_curve),
+ m_poly(4, 5.0),
+ m_idx(0)
+ {
+ m_poly.in_polygon_check(false);
+ m_poly.xn(0) = 100.0;
+ m_poly.yn(0) = 0.0;
+ m_poly.xn(1) = 100.0;
+ m_poly.yn(1) = 50.0;
+ m_poly.xn(2) = 50.0;
+ m_poly.yn(2) = 100.0;
+ m_poly.xn(3) = 0.0;
+ m_poly.yn(3) = 100.0;
+ }
+
+
+ //------------------------------------------------------------------------
+ void bezier_ctrl_impl::curve(double x1, double y1,
+ double x2, double y2,
+ double x3, double y3,
+ double x4, double y4)
+ {
+ m_poly.xn(0) = x1;
+ m_poly.yn(0) = y1;
+ m_poly.xn(1) = x2;
+ m_poly.yn(1) = y2;
+ m_poly.xn(2) = x3;
+ m_poly.yn(2) = y3;
+ m_poly.xn(3) = x4;
+ m_poly.yn(3) = y4;
+ curve();
+ }
+
+ //------------------------------------------------------------------------
+ curve4& bezier_ctrl_impl::curve()
+ {
+ m_curve.init(m_poly.xn(0), m_poly.yn(0),
+ m_poly.xn(1), m_poly.yn(1),
+ m_poly.xn(2), m_poly.yn(2),
+ m_poly.xn(3), m_poly.yn(3));
+ return m_curve;
+ }
+
+ //------------------------------------------------------------------------
+ void bezier_ctrl_impl::rewind(unsigned idx)
+ {
+ m_idx = idx;
+
+ m_curve.approximation_scale(scale());
+ switch(idx)
+ {
+ default:
+ case 0: // Control line 1
+ m_curve.init(m_poly.xn(0), m_poly.yn(0),
+ (m_poly.xn(0) + m_poly.xn(1)) * 0.5,
+ (m_poly.yn(0) + m_poly.yn(1)) * 0.5,
+ (m_poly.xn(0) + m_poly.xn(1)) * 0.5,
+ (m_poly.yn(0) + m_poly.yn(1)) * 0.5,
+ m_poly.xn(1), m_poly.yn(1));
+ m_stroke.rewind(0);
+ break;
+
+ case 1: // Control line 2
+ m_curve.init(m_poly.xn(2), m_poly.yn(2),
+ (m_poly.xn(2) + m_poly.xn(3)) * 0.5,
+ (m_poly.yn(2) + m_poly.yn(3)) * 0.5,
+ (m_poly.xn(2) + m_poly.xn(3)) * 0.5,
+ (m_poly.yn(2) + m_poly.yn(3)) * 0.5,
+ m_poly.xn(3), m_poly.yn(3));
+ m_stroke.rewind(0);
+ break;
+
+ case 2: // Curve itself
+ m_curve.init(m_poly.xn(0), m_poly.yn(0),
+ m_poly.xn(1), m_poly.yn(1),
+ m_poly.xn(2), m_poly.yn(2),
+ m_poly.xn(3), m_poly.yn(3));
+ m_stroke.rewind(0);
+ break;
+
+ case 3: // Point 1
+ m_ellipse.init(m_poly.xn(0), m_poly.yn(0), point_radius(), point_radius(), 20);
+ m_ellipse.rewind(0);
+ break;
+
+ case 4: // Point 2
+ m_ellipse.init(m_poly.xn(1), m_poly.yn(1), point_radius(), point_radius(), 20);
+ m_ellipse.rewind(0);
+ break;
+
+ case 5: // Point 3
+ m_ellipse.init(m_poly.xn(2), m_poly.yn(2), point_radius(), point_radius(), 20);
+ m_ellipse.rewind(0);
+ break;
+
+ case 6: // Point 4
+ m_ellipse.init(m_poly.xn(3), m_poly.yn(3), point_radius(), point_radius(), 20);
+ m_ellipse.rewind(0);
+ break;
+ }
+ }
+
+
+ //------------------------------------------------------------------------
+ unsigned bezier_ctrl_impl::vertex(double* x, double* y)
+ {
+ unsigned cmd = path_cmd_stop;
+ switch(m_idx)
+ {
+ case 0:
+ case 1:
+ case 2:
+ cmd = m_stroke.vertex(x, y);
+ break;
+
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ cmd = m_ellipse.vertex(x, y);
+ break;
+ }
+
+ if(!is_stop(cmd))
+ {
+ transform_xy(x, y);
+ }
+ return cmd;
+ }
+
+
+
+ //------------------------------------------------------------------------
+ bool bezier_ctrl_impl::in_rect(double x, double y) const
+ {
+ return false;
+ }
+
+
+ //------------------------------------------------------------------------
+ bool bezier_ctrl_impl::on_mouse_button_down(double x, double y)
+ {
+ inverse_transform_xy(&x, &y);
+ return m_poly.on_mouse_button_down(x, y);
+ }
+
+
+ //------------------------------------------------------------------------
+ bool bezier_ctrl_impl::on_mouse_move(double x, double y, bool button_flag)
+ {
+ inverse_transform_xy(&x, &y);
+ return m_poly.on_mouse_move(x, y, button_flag);
+ }
+
+
+ //------------------------------------------------------------------------
+ bool bezier_ctrl_impl::on_mouse_button_up(double x, double y)
+ {
+ return m_poly.on_mouse_button_up(x, y);
+ }
+
+
+ //------------------------------------------------------------------------
+ bool bezier_ctrl_impl::on_arrow_keys(bool left, bool right, bool down, bool up)
+ {
+ return m_poly.on_arrow_keys(left, right, down, up);
+ }
+
+
+
+
+
+
+ //------------------------------------------------------------------------
+ curve3_ctrl_impl::curve3_ctrl_impl() :
+ ctrl(0,0,1,1,false),
+ m_stroke(m_curve),
+ m_poly(3, 5.0),
+ m_idx(0)
+ {
+ m_poly.in_polygon_check(false);
+ m_poly.xn(0) = 100.0;
+ m_poly.yn(0) = 0.0;
+ m_poly.xn(1) = 100.0;
+ m_poly.yn(1) = 50.0;
+ m_poly.xn(2) = 50.0;
+ m_poly.yn(2) = 100.0;
+ }
+
+
+ //------------------------------------------------------------------------
+ void curve3_ctrl_impl::curve(double x1, double y1,
+ double x2, double y2,
+ double x3, double y3)
+ {
+ m_poly.xn(0) = x1;
+ m_poly.yn(0) = y1;
+ m_poly.xn(1) = x2;
+ m_poly.yn(1) = y2;
+ m_poly.xn(2) = x3;
+ m_poly.yn(2) = y3;
+ curve();
+ }
+
+ //------------------------------------------------------------------------
+ curve3& curve3_ctrl_impl::curve()
+ {
+ m_curve.init(m_poly.xn(0), m_poly.yn(0),
+ m_poly.xn(1), m_poly.yn(1),
+ m_poly.xn(2), m_poly.yn(2));
+ return m_curve;
+ }
+
+ //------------------------------------------------------------------------
+ void curve3_ctrl_impl::rewind(unsigned idx)
+ {
+ m_idx = idx;
+
+ switch(idx)
+ {
+ default:
+ case 0: // Control line
+ m_curve.init(m_poly.xn(0), m_poly.yn(0),
+ (m_poly.xn(0) + m_poly.xn(1)) * 0.5,
+ (m_poly.yn(0) + m_poly.yn(1)) * 0.5,
+ m_poly.xn(1), m_poly.yn(1));
+ m_stroke.rewind(0);
+ break;
+
+ case 1: // Control line 2
+ m_curve.init(m_poly.xn(1), m_poly.yn(1),
+ (m_poly.xn(1) + m_poly.xn(2)) * 0.5,
+ (m_poly.yn(1) + m_poly.yn(2)) * 0.5,
+ m_poly.xn(2), m_poly.yn(2));
+ m_stroke.rewind(0);
+ break;
+
+ case 2: // Curve itself
+ m_curve.init(m_poly.xn(0), m_poly.yn(0),
+ m_poly.xn(1), m_poly.yn(1),
+ m_poly.xn(2), m_poly.yn(2));
+ m_stroke.rewind(0);
+ break;
+
+ case 3: // Point 1
+ m_ellipse.init(m_poly.xn(0), m_poly.yn(0), point_radius(), point_radius(), 20);
+ m_ellipse.rewind(0);
+ break;
+
+ case 4: // Point 2
+ m_ellipse.init(m_poly.xn(1), m_poly.yn(1), point_radius(), point_radius(), 20);
+ m_ellipse.rewind(0);
+ break;
+
+ case 5: // Point 3
+ m_ellipse.init(m_poly.xn(2), m_poly.yn(2), point_radius(), point_radius(), 20);
+ m_ellipse.rewind(0);
+ break;
+ }
+ }
+
+
+ //------------------------------------------------------------------------
+ unsigned curve3_ctrl_impl::vertex(double* x, double* y)
+ {
+ unsigned cmd = path_cmd_stop;
+ switch(m_idx)
+ {
+ case 0:
+ case 1:
+ case 2:
+ cmd = m_stroke.vertex(x, y);
+ break;
+
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ cmd = m_ellipse.vertex(x, y);
+ break;
+ }
+
+ if(!is_stop(cmd))
+ {
+ transform_xy(x, y);
+ }
+ return cmd;
+ }
+
+
+
+ //------------------------------------------------------------------------
+ bool curve3_ctrl_impl::in_rect(double x, double y) const
+ {
+ return false;
+ }
+
+
+ //------------------------------------------------------------------------
+ bool curve3_ctrl_impl::on_mouse_button_down(double x, double y)
+ {
+ inverse_transform_xy(&x, &y);
+ return m_poly.on_mouse_button_down(x, y);
+ }
+
+
+ //------------------------------------------------------------------------
+ bool curve3_ctrl_impl::on_mouse_move(double x, double y, bool button_flag)
+ {
+ inverse_transform_xy(&x, &y);
+ return m_poly.on_mouse_move(x, y, button_flag);
+ }
+
+
+ //------------------------------------------------------------------------
+ bool curve3_ctrl_impl::on_mouse_button_up(double x, double y)
+ {
+ return m_poly.on_mouse_button_up(x, y);
+ }
+
+
+ //------------------------------------------------------------------------
+ bool curve3_ctrl_impl::on_arrow_keys(bool left, bool right, bool down, bool up)
+ {
+ return m_poly.on_arrow_keys(left, right, down, up);
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+}
+
diff --git a/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_cbox_ctrl.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_cbox_ctrl.cpp
new file mode 100644
index 0000000000..3cf14f6a85
--- /dev/null
+++ b/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_cbox_ctrl.cpp
@@ -0,0 +1,214 @@
+//----------------------------------------------------------------------------
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
+//
+// Permission to copy, use, modify, sell and distribute this software
+// is granted provided this copyright notice appears in all copies.
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+//
+//----------------------------------------------------------------------------
+// Contact: mcseem@antigrain.com
+// mcseemagg@yahoo.com
+// http://www.antigrain.com
+//----------------------------------------------------------------------------
+//
+// classes rbox_ctrl_impl, rbox_ctrl
+//
+//----------------------------------------------------------------------------
+
+#include <string.h>
+#include "ctrl/agg_cbox_ctrl.h"
+
+
+namespace agg
+{
+
+ //------------------------------------------------------------------------
+ cbox_ctrl_impl::cbox_ctrl_impl(double x, double y,
+ const char* l,
+ bool flip_y) :
+ ctrl(x, y, x + 9.0 * 1.5, y + 9.0 * 1.5, flip_y),
+ m_text_thickness(1.5),
+ m_text_height(9.0),
+ m_text_width(0.0),
+ m_status(false),
+ m_text_poly(m_text)
+ {
+ label(l);
+ }
+
+
+ //------------------------------------------------------------------------
+ void cbox_ctrl_impl::text_size(double h, double w)
+ {
+ m_text_width = w;
+ m_text_height = h;
+ }
+
+ //------------------------------------------------------------------------
+ void cbox_ctrl_impl::label(const char* l)
+ {
+ unsigned len = strlen(l);
+ if(len > 127) len = 127;
+ memcpy(m_label, l, len);
+ m_label[len] = 0;
+ }
+
+
+ //------------------------------------------------------------------------
+ bool cbox_ctrl_impl::on_mouse_button_down(double x, double y)
+ {
+ inverse_transform_xy(&x, &y);
+ if(x >= m_x1 && y >= m_y1 && x <= m_x2 && y <= m_y2)
+ {
+ m_status = !m_status;
+ return true;
+ }
+ return false;
+ }
+
+
+ //------------------------------------------------------------------------
+ bool cbox_ctrl_impl::on_mouse_move(double, double, bool)
+ {
+ return false;
+ }
+
+ //------------------------------------------------------------------------
+ bool cbox_ctrl_impl::in_rect(double x, double y) const
+ {
+ inverse_transform_xy(&x, &y);
+ return x >= m_x1 && y >= m_y1 && x <= m_x2 && y <= m_y2;
+ }
+
+ //------------------------------------------------------------------------
+ bool cbox_ctrl_impl::on_mouse_button_up(double, double)
+ {
+ return false;
+ }
+
+ //------------------------------------------------------------------------
+ bool cbox_ctrl_impl::on_arrow_keys(bool, bool, bool, bool)
+ {
+ return false;
+ }
+
+
+ //------------------------------------------------------------------------
+ void cbox_ctrl_impl::rewind(unsigned idx)
+ {
+ m_idx = idx;
+
+ double d2;
+ double t;
+
+ switch(idx)
+ {
+ default:
+ case 0: // Border
+ m_vertex = 0;
+ m_vx[0] = m_x1;
+ m_vy[0] = m_y1;
+ m_vx[1] = m_x2;
+ m_vy[1] = m_y1;
+ m_vx[2] = m_x2;
+ m_vy[2] = m_y2;
+ m_vx[3] = m_x1;
+ m_vy[3] = m_y2;
+ m_vx[4] = m_x1 + m_text_thickness;
+ m_vy[4] = m_y1 + m_text_thickness;
+ m_vx[5] = m_x1 + m_text_thickness;
+ m_vy[5] = m_y2 - m_text_thickness;
+ m_vx[6] = m_x2 - m_text_thickness;
+ m_vy[6] = m_y2 - m_text_thickness;
+ m_vx[7] = m_x2 - m_text_thickness;
+ m_vy[7] = m_y1 + m_text_thickness;
+ break;
+
+ case 1: // Text
+ m_text.text(m_label);
+ m_text.start_point(m_x1 + m_text_height * 2.0, m_y1 + m_text_height / 5.0);
+ m_text.size(m_text_height, m_text_width);
+ m_text_poly.width(m_text_thickness);
+ m_text_poly.line_join(round_join);
+ m_text_poly.line_cap(round_cap);
+ m_text_poly.rewind(0);
+ break;
+
+ case 2: // Active item
+ m_vertex = 0;
+ d2 = (m_y2 - m_y1) / 2.0;
+ t = m_text_thickness * 1.5;
+ m_vx[0] = m_x1 + m_text_thickness;
+ m_vy[0] = m_y1 + m_text_thickness;
+ m_vx[1] = m_x1 + d2;
+ m_vy[1] = m_y1 + d2 - t;
+ m_vx[2] = m_x2 - m_text_thickness;
+ m_vy[2] = m_y1 + m_text_thickness;
+ m_vx[3] = m_x1 + d2 + t;
+ m_vy[3] = m_y1 + d2;
+ m_vx[4] = m_x2 - m_text_thickness;
+ m_vy[4] = m_y2 - m_text_thickness;
+ m_vx[5] = m_x1 + d2;
+ m_vy[5] = m_y1 + d2 + t;
+ m_vx[6] = m_x1 + m_text_thickness;
+ m_vy[6] = m_y2 - m_text_thickness;
+ m_vx[7] = m_x1 + d2 - t;
+ m_vy[7] = m_y1 + d2;
+ break;
+
+ }
+ }
+
+
+
+
+ //------------------------------------------------------------------------
+ unsigned cbox_ctrl_impl::vertex(double* x, double* y)
+ {
+ unsigned cmd = path_cmd_line_to;
+ switch(m_idx)
+ {
+ case 0:
+ if(m_vertex == 0 || m_vertex == 4) cmd = path_cmd_move_to;
+ if(m_vertex >= 8) cmd = path_cmd_stop;
+ *x = m_vx[m_vertex];
+ *y = m_vy[m_vertex];
+ m_vertex++;
+ break;
+
+ case 1:
+ cmd = m_text_poly.vertex(x, y);
+ break;
+
+ case 2:
+ if(m_status)
+ {
+ if(m_vertex == 0) cmd = path_cmd_move_to;
+ if(m_vertex >= 8) cmd = path_cmd_stop;
+ *x = m_vx[m_vertex];
+ *y = m_vy[m_vertex];
+ m_vertex++;
+ }
+ else
+ {
+ cmd = path_cmd_stop;
+ }
+ break;
+
+ default:
+ cmd = path_cmd_stop;
+ break;
+ }
+
+ if(!is_stop(cmd))
+ {
+ transform_xy(x, y);
+ }
+ return cmd;
+ }
+}
+
+
+
diff --git a/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_gamma_ctrl.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_gamma_ctrl.cpp
new file mode 100644
index 0000000000..7fd6448cd5
--- /dev/null
+++ b/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_gamma_ctrl.cpp
@@ -0,0 +1,433 @@
+//----------------------------------------------------------------------------
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
+//
+// Permission to copy, use, modify, sell and distribute this software
+// is granted provided this copyright notice appears in all copies.
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+//
+//----------------------------------------------------------------------------
+// Contact: mcseem@antigrain.com
+// mcseemagg@yahoo.com
+// http://www.antigrain.com
+//----------------------------------------------------------------------------
+//
+// class gamma_ctrl_impl
+//
+//----------------------------------------------------------------------------
+
+#include <stdio.h>
+#include "agg_math.h"
+#include "ctrl/agg_gamma_ctrl.h"
+
+namespace agg
+{
+
+ //------------------------------------------------------------------------
+ gamma_ctrl_impl::gamma_ctrl_impl(double x1, double y1, double x2, double y2, bool flip_y) :
+ ctrl(x1, y1, x2, y2, flip_y),
+ m_border_width(2.0),
+ m_border_extra(0.0),
+ m_curve_width(2.0),
+ m_grid_width(0.2),
+ m_text_thickness(1.5),
+ m_point_size(5.0),
+ m_text_height(9.0),
+ m_text_width(0.0),
+ m_xc1(x1),
+ m_yc1(y1),
+ m_xc2(x2),
+ m_yc2(y2 - m_text_height * 2.0),
+ m_xt1(x1),
+ m_yt1(y2 - m_text_height * 2.0),
+ m_xt2(x2),
+ m_yt2(y2),
+ m_curve_poly(m_gamma_spline),
+ m_text_poly(m_text),
+ m_idx(0),
+ m_vertex(0),
+ m_p1_active(true),
+ m_mouse_point(0),
+ m_pdx(0.0),
+ m_pdy(0.0)
+ {
+ calc_spline_box();
+ }
+
+
+ //------------------------------------------------------------------------
+ void gamma_ctrl_impl::calc_spline_box()
+ {
+ m_xs1 = m_xc1 + m_border_width;
+ m_ys1 = m_yc1 + m_border_width;
+ m_xs2 = m_xc2 - m_border_width;
+ m_ys2 = m_yc2 - m_border_width * 0.5;
+ }
+
+
+ //------------------------------------------------------------------------
+ void gamma_ctrl_impl::calc_points()
+ {
+ double kx1, ky1, kx2, ky2;
+ m_gamma_spline.values(&kx1, &ky1, &kx2, &ky2);
+ m_xp1 = m_xs1 + (m_xs2 - m_xs1) * kx1 * 0.25;
+ m_yp1 = m_ys1 + (m_ys2 - m_ys1) * ky1 * 0.25;
+ m_xp2 = m_xs2 - (m_xs2 - m_xs1) * kx2 * 0.25;
+ m_yp2 = m_ys2 - (m_ys2 - m_ys1) * ky2 * 0.25;
+ }
+
+
+ //------------------------------------------------------------------------
+ void gamma_ctrl_impl::calc_values()
+ {
+ double kx1, ky1, kx2, ky2;
+
+ kx1 = (m_xp1 - m_xs1) * 4.0 / (m_xs2 - m_xs1);
+ ky1 = (m_yp1 - m_ys1) * 4.0 / (m_ys2 - m_ys1);
+ kx2 = (m_xs2 - m_xp2) * 4.0 / (m_xs2 - m_xs1);
+ ky2 = (m_ys2 - m_yp2) * 4.0 / (m_ys2 - m_ys1);
+ m_gamma_spline.values(kx1, ky1, kx2, ky2);
+ }
+
+
+ //------------------------------------------------------------------------
+ void gamma_ctrl_impl::text_size(double h, double w)
+ {
+ m_text_width = w;
+ m_text_height = h;
+ m_yc2 = m_y2 - m_text_height * 2.0;
+ m_yt1 = m_y2 - m_text_height * 2.0;
+ calc_spline_box();
+ }
+
+
+ //------------------------------------------------------------------------
+ void gamma_ctrl_impl::border_width(double t, double extra)
+ {
+ m_border_width = t;
+ m_border_extra = extra;
+ calc_spline_box();
+ }
+
+ //------------------------------------------------------------------------
+ void gamma_ctrl_impl::values(double kx1, double ky1, double kx2, double ky2)
+ {
+ m_gamma_spline.values(kx1, ky1, kx2, ky2);
+ }
+
+
+ //------------------------------------------------------------------------
+ void gamma_ctrl_impl::values(double* kx1, double* ky1, double* kx2, double* ky2) const
+ {
+ m_gamma_spline.values(kx1, ky1, kx2, ky2);
+ }
+
+ //------------------------------------------------------------------------
+ void gamma_ctrl_impl::rewind(unsigned idx)
+ {
+ double kx1, ky1, kx2, ky2;
+ char tbuf[32];
+
+ m_idx = idx;
+
+ switch(idx)
+ {
+ default:
+
+ case 0: // Background
+ m_vertex = 0;
+ m_vx[0] = m_x1 - m_border_extra;
+ m_vy[0] = m_y1 - m_border_extra;
+ m_vx[1] = m_x2 + m_border_extra;
+ m_vy[1] = m_y1 - m_border_extra;
+ m_vx[2] = m_x2 + m_border_extra;
+ m_vy[2] = m_y2 + m_border_extra;
+ m_vx[3] = m_x1 - m_border_extra;
+ m_vy[3] = m_y2 + m_border_extra;
+ break;
+
+ case 1: // Border
+ m_vertex = 0;
+ m_vx[0] = m_x1;
+ m_vy[0] = m_y1;
+ m_vx[1] = m_x2;
+ m_vy[1] = m_y1;
+ m_vx[2] = m_x2;
+ m_vy[2] = m_y2;
+ m_vx[3] = m_x1;
+ m_vy[3] = m_y2;
+ m_vx[4] = m_x1 + m_border_width;
+ m_vy[4] = m_y1 + m_border_width;
+ m_vx[5] = m_x1 + m_border_width;
+ m_vy[5] = m_y2 - m_border_width;
+ m_vx[6] = m_x2 - m_border_width;
+ m_vy[6] = m_y2 - m_border_width;
+ m_vx[7] = m_x2 - m_border_width;
+ m_vy[7] = m_y1 + m_border_width;
+ m_vx[8] = m_xc1 + m_border_width;
+ m_vy[8] = m_yc2 - m_border_width * 0.5;
+ m_vx[9] = m_xc2 - m_border_width;
+ m_vy[9] = m_yc2 - m_border_width * 0.5;
+ m_vx[10] = m_xc2 - m_border_width;
+ m_vy[10] = m_yc2 + m_border_width * 0.5;
+ m_vx[11] = m_xc1 + m_border_width;
+ m_vy[11] = m_yc2 + m_border_width * 0.5;
+ break;
+
+ case 2: // Curve
+ m_gamma_spline.box(m_xs1, m_ys1, m_xs2, m_ys2);
+ m_curve_poly.width(m_curve_width);
+ m_curve_poly.rewind(0);
+ break;
+
+ case 3: // Grid
+ m_vertex = 0;
+ m_vx[0] = m_xs1;
+ m_vy[0] = (m_ys1 + m_ys2) * 0.5 - m_grid_width * 0.5;
+ m_vx[1] = m_xs2;
+ m_vy[1] = (m_ys1 + m_ys2) * 0.5 - m_grid_width * 0.5;
+ m_vx[2] = m_xs2;
+ m_vy[2] = (m_ys1 + m_ys2) * 0.5 + m_grid_width * 0.5;
+ m_vx[3] = m_xs1;
+ m_vy[3] = (m_ys1 + m_ys2) * 0.5 + m_grid_width * 0.5;
+ m_vx[4] = (m_xs1 + m_xs2) * 0.5 - m_grid_width * 0.5;
+ m_vy[4] = m_ys1;
+ m_vx[5] = (m_xs1 + m_xs2) * 0.5 - m_grid_width * 0.5;
+ m_vy[5] = m_ys2;
+ m_vx[6] = (m_xs1 + m_xs2) * 0.5 + m_grid_width * 0.5;
+ m_vy[6] = m_ys2;
+ m_vx[7] = (m_xs1 + m_xs2) * 0.5 + m_grid_width * 0.5;
+ m_vy[7] = m_ys1;
+ calc_points();
+ m_vx[8] = m_xs1;
+ m_vy[8] = m_yp1 - m_grid_width * 0.5;
+ m_vx[9] = m_xp1 - m_grid_width * 0.5;
+ m_vy[9] = m_yp1 - m_grid_width * 0.5;
+ m_vx[10] = m_xp1 - m_grid_width * 0.5;
+ m_vy[10] = m_ys1;
+ m_vx[11] = m_xp1 + m_grid_width * 0.5;
+ m_vy[11] = m_ys1;
+ m_vx[12] = m_xp1 + m_grid_width * 0.5;
+ m_vy[12] = m_yp1 + m_grid_width * 0.5;
+ m_vx[13] = m_xs1;
+ m_vy[13] = m_yp1 + m_grid_width * 0.5;
+ m_vx[14] = m_xs2;
+ m_vy[14] = m_yp2 + m_grid_width * 0.5;
+ m_vx[15] = m_xp2 + m_grid_width * 0.5;
+ m_vy[15] = m_yp2 + m_grid_width * 0.5;
+ m_vx[16] = m_xp2 + m_grid_width * 0.5;
+ m_vy[16] = m_ys2;
+ m_vx[17] = m_xp2 - m_grid_width * 0.5;
+ m_vy[17] = m_ys2;
+ m_vx[18] = m_xp2 - m_grid_width * 0.5;
+ m_vy[18] = m_yp2 - m_grid_width * 0.5;
+ m_vx[19] = m_xs2;
+ m_vy[19] = m_yp2 - m_grid_width * 0.5;
+ break;
+
+ case 4: // Point1
+ calc_points();
+ if(m_p1_active) m_ellipse.init(m_xp2, m_yp2, m_point_size, m_point_size, 32);
+ else m_ellipse.init(m_xp1, m_yp1, m_point_size, m_point_size, 32);
+ break;
+
+ case 5: // Point2
+ calc_points();
+ if(m_p1_active) m_ellipse.init(m_xp1, m_yp1, m_point_size, m_point_size, 32);
+ else m_ellipse.init(m_xp2, m_yp2, m_point_size, m_point_size, 32);
+ break;
+
+ case 6: // Text
+ m_gamma_spline.values(&kx1, &ky1, &kx2, &ky2);
+ sprintf(tbuf, "%5.3f %5.3f %5.3f %5.3f", kx1, ky1, kx2, ky2);
+ m_text.text(tbuf);
+ m_text.size(m_text_height, m_text_width);
+ m_text.start_point(m_xt1 + m_border_width * 2.0, (m_yt1 + m_yt2) * 0.5 - m_text_height * 0.5);
+ m_text_poly.width(m_text_thickness);
+ m_text_poly.line_join(round_join);
+ m_text_poly.line_cap(round_cap);
+ m_text_poly.rewind(0);
+ break;
+ }
+ }
+
+
+ //------------------------------------------------------------------------
+ unsigned gamma_ctrl_impl::vertex(double* x, double* y)
+ {
+ unsigned cmd = path_cmd_line_to;
+ switch(m_idx)
+ {
+ case 0:
+ if(m_vertex == 0) cmd = path_cmd_move_to;
+ if(m_vertex >= 4) cmd = path_cmd_stop;
+ *x = m_vx[m_vertex];
+ *y = m_vy[m_vertex];
+ m_vertex++;
+ break;
+
+ case 1:
+ if(m_vertex == 0 || m_vertex == 4 || m_vertex == 8) cmd = path_cmd_move_to;
+ if(m_vertex >= 12) cmd = path_cmd_stop;
+ *x = m_vx[m_vertex];
+ *y = m_vy[m_vertex];
+ m_vertex++;
+ break;
+
+ case 2:
+ cmd = m_curve_poly.vertex(x, y);
+ break;
+
+ case 3:
+ if(m_vertex == 0 ||
+ m_vertex == 4 ||
+ m_vertex == 8 ||
+ m_vertex == 14) cmd = path_cmd_move_to;
+
+ if(m_vertex >= 20) cmd = path_cmd_stop;
+ *x = m_vx[m_vertex];
+ *y = m_vy[m_vertex];
+ m_vertex++;
+ break;
+
+ case 4: // Point1
+ case 5: // Point2
+ cmd = m_ellipse.vertex(x, y);
+ break;
+
+ case 6:
+ cmd = m_text_poly.vertex(x, y);
+ break;
+
+ default:
+ cmd = path_cmd_stop;
+ break;
+ }
+
+ if(!is_stop(cmd))
+ {
+ transform_xy(x, y);
+ }
+
+ return cmd;
+ }
+
+
+
+ //------------------------------------------------------------------------
+ bool gamma_ctrl_impl::on_arrow_keys(bool left, bool right, bool down, bool up)
+ {
+ double kx1, ky1, kx2, ky2;
+ bool ret = false;
+ m_gamma_spline.values(&kx1, &ky1, &kx2, &ky2);
+ if(m_p1_active)
+ {
+ if(left) { kx1 -= 0.005; ret = true; }
+ if(right) { kx1 += 0.005; ret = true; }
+ if(down) { ky1 -= 0.005; ret = true; }
+ if(up) { ky1 += 0.005; ret = true; }
+ }
+ else
+ {
+ if(left) { kx2 += 0.005; ret = true; }
+ if(right) { kx2 -= 0.005; ret = true; }
+ if(down) { ky2 += 0.005; ret = true; }
+ if(up) { ky2 -= 0.005; ret = true; }
+ }
+ if(ret)
+ {
+ m_gamma_spline.values(kx1, ky1, kx2, ky2);
+ }
+ return ret;
+ }
+
+
+
+ //------------------------------------------------------------------------
+ void gamma_ctrl_impl::change_active_point()
+ {
+ m_p1_active = m_p1_active ? false : true;
+ }
+
+
+
+
+ //------------------------------------------------------------------------
+ bool gamma_ctrl_impl::in_rect(double x, double y) const
+ {
+ inverse_transform_xy(&x, &y);
+ return x >= m_x1 && x <= m_x2 && y >= m_y1 && y <= m_y2;
+ }
+
+
+ //------------------------------------------------------------------------
+ bool gamma_ctrl_impl::on_mouse_button_down(double x, double y)
+ {
+ inverse_transform_xy(&x, &y);
+ calc_points();
+
+ if(calc_distance(x, y, m_xp1, m_yp1) <= m_point_size + 1)
+ {
+ m_mouse_point = 1;
+ m_pdx = m_xp1 - x;
+ m_pdy = m_yp1 - y;
+ m_p1_active = true;
+ return true;
+ }
+
+ if(calc_distance(x, y, m_xp2, m_yp2) <= m_point_size + 1)
+ {
+ m_mouse_point = 2;
+ m_pdx = m_xp2 - x;
+ m_pdy = m_yp2 - y;
+ m_p1_active = false;
+ return true;
+ }
+
+ return false;
+ }
+
+
+ //------------------------------------------------------------------------
+ bool gamma_ctrl_impl::on_mouse_button_up(double, double)
+ {
+ if(m_mouse_point)
+ {
+ m_mouse_point = 0;
+ return true;
+ }
+ return false;
+ }
+
+
+ //------------------------------------------------------------------------
+ bool gamma_ctrl_impl::on_mouse_move(double x, double y, bool button_flag)
+ {
+ inverse_transform_xy(&x, &y);
+ if(!button_flag)
+ {
+ return on_mouse_button_up(x, y);
+ }
+
+ if(m_mouse_point == 1)
+ {
+ m_xp1 = x + m_pdx;
+ m_yp1 = y + m_pdy;
+ calc_values();
+ return true;
+ }
+ if(m_mouse_point == 2)
+ {
+ m_xp2 = x + m_pdx;
+ m_yp2 = y + m_pdy;
+ calc_values();
+ return true;
+ }
+ return false;
+ }
+
+
+
+}
+
diff --git a/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_gamma_spline.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_gamma_spline.cpp
new file mode 100644
index 0000000000..f720fddd8e
--- /dev/null
+++ b/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_gamma_spline.cpp
@@ -0,0 +1,130 @@
+//----------------------------------------------------------------------------
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
+//
+// Permission to copy, use, modify, sell and distribute this software
+// is granted provided this copyright notice appears in all copies.
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+//
+//----------------------------------------------------------------------------
+// Contact: mcseem@antigrain.com
+// mcseemagg@yahoo.com
+// http://www.antigrain.com
+//----------------------------------------------------------------------------
+//
+// class gamma_spline
+//
+//----------------------------------------------------------------------------
+
+#include "ctrl/agg_gamma_spline.h"
+
+namespace agg
+{
+
+ //------------------------------------------------------------------------
+ gamma_spline::gamma_spline() :
+ m_x1(0), m_y1(0), m_x2(10), m_y2(10), m_cur_x(0.0)
+ {
+ values(1.0, 1.0, 1.0, 1.0);
+ }
+
+
+ //------------------------------------------------------------------------
+ double gamma_spline::y(double x) const
+ {
+ if(x < 0.0) x = 0.0;
+ if(x > 1.0) x = 1.0;
+ double val = m_spline.get(x);
+ if(val < 0.0) val = 0.0;
+ if(val > 1.0) val = 1.0;
+ return val;
+ }
+
+
+
+ //------------------------------------------------------------------------
+ void gamma_spline::values(double kx1, double ky1, double kx2, double ky2)
+ {
+ if(kx1 < 0.001) kx1 = 0.001;
+ if(kx1 > 1.999) kx1 = 1.999;
+ if(ky1 < 0.001) ky1 = 0.001;
+ if(ky1 > 1.999) ky1 = 1.999;
+ if(kx2 < 0.001) kx2 = 0.001;
+ if(kx2 > 1.999) kx2 = 1.999;
+ if(ky2 < 0.001) ky2 = 0.001;
+ if(ky2 > 1.999) ky2 = 1.999;
+
+ m_x[0] = 0.0;
+ m_y[0] = 0.0;
+ m_x[1] = kx1 * 0.25;
+ m_y[1] = ky1 * 0.25;
+ m_x[2] = 1.0 - kx2 * 0.25;
+ m_y[2] = 1.0 - ky2 * 0.25;
+ m_x[3] = 1.0;
+ m_y[3] = 1.0;
+
+ m_spline.init(4, m_x, m_y);
+
+ int i;
+ for(i = 0; i < 256; i++)
+ {
+ m_gamma[i] = (unsigned char)(y(double(i) / 255.0) * 255.0);
+ }
+ }
+
+
+ //------------------------------------------------------------------------
+ void gamma_spline::values(double* kx1, double* ky1, double* kx2, double* ky2) const
+ {
+ *kx1 = m_x[1] * 4.0;
+ *ky1 = m_y[1] * 4.0;
+ *kx2 = (1.0 - m_x[2]) * 4.0;
+ *ky2 = (1.0 - m_y[2]) * 4.0;
+ }
+
+
+ //------------------------------------------------------------------------
+ void gamma_spline::box(double x1, double y1, double x2, double y2)
+ {
+ m_x1 = x1;
+ m_y1 = y1;
+ m_x2 = x2;
+ m_y2 = y2;
+ }
+
+
+ //------------------------------------------------------------------------
+ void gamma_spline::rewind(unsigned)
+ {
+ m_cur_x = 0.0;
+ }
+
+
+ //------------------------------------------------------------------------
+ unsigned gamma_spline::vertex(double* vx, double* vy)
+ {
+ if(m_cur_x == 0.0)
+ {
+ *vx = m_x1;
+ *vy = m_y1;
+ m_cur_x += 1.0 / (m_x2 - m_x1);
+ return path_cmd_move_to;
+ }
+
+ if(m_cur_x > 1.0)
+ {
+ return path_cmd_stop;
+ }
+
+ *vx = m_x1 + m_cur_x * (m_x2 - m_x1);
+ *vy = m_y1 + y(m_cur_x) * (m_y2 - m_y1);
+
+ m_cur_x += 1.0 / (m_x2 - m_x1);
+ return path_cmd_line_to;
+ }
+
+
+
+}
+
diff --git a/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_polygon_ctrl.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_polygon_ctrl.cpp
new file mode 100644
index 0000000000..40daee45e8
--- /dev/null
+++ b/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_polygon_ctrl.cpp
@@ -0,0 +1,332 @@
+//----------------------------------------------------------------------------
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
+//
+// Permission to copy, use, modify, sell and distribute this software
+// is granted provided this copyright notice appears in all copies.
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+//
+//----------------------------------------------------------------------------
+// Contact: mcseem@antigrain.com
+// mcseemagg@yahoo.com
+// http://www.antigrain.com
+//----------------------------------------------------------------------------
+//
+// classes polygon_ctrl_impl
+//
+//----------------------------------------------------------------------------
+
+#include "ctrl/agg_polygon_ctrl.h"
+
+namespace agg
+{
+
+ polygon_ctrl_impl::polygon_ctrl_impl(unsigned np, double point_radius) :
+ ctrl(0, 0, 1, 1, false),
+ m_polygon(np * 2),
+ m_num_points(np),
+ m_node(-1),
+ m_edge(-1),
+ m_vs(&m_polygon[0], m_num_points, false),
+ m_stroke(m_vs),
+ m_point_radius(point_radius),
+ m_status(0),
+ m_dx(0.0),
+ m_dy(0.0),
+ m_in_polygon_check(true)
+ {
+ m_stroke.width(1.0);
+ }
+
+
+ void polygon_ctrl_impl::rewind(unsigned)
+ {
+ m_status = 0;
+ m_stroke.rewind(0);
+ }
+
+ unsigned polygon_ctrl_impl::vertex(double* x, double* y)
+ {
+ unsigned cmd = path_cmd_stop;
+ double r = m_point_radius;
+ if(m_status == 0)
+ {
+ cmd = m_stroke.vertex(x, y);
+ if(!is_stop(cmd))
+ {
+ transform_xy(x, y);
+ return cmd;
+ }
+ if(m_node >= 0 && m_node == int(m_status)) r *= 1.2;
+ m_ellipse.init(xn(m_status), yn(m_status), r, r, 32);
+ ++m_status;
+ }
+ cmd = m_ellipse.vertex(x, y);
+ if(!is_stop(cmd))
+ {
+ transform_xy(x, y);
+ return cmd;
+ }
+ if(m_status >= m_num_points) return path_cmd_stop;
+ if(m_node >= 0 && m_node == int(m_status)) r *= 1.2;
+ m_ellipse.init(xn(m_status), yn(m_status), r, r, 32);
+ ++m_status;
+ cmd = m_ellipse.vertex(x, y);
+ if(!is_stop(cmd))
+ {
+ transform_xy(x, y);
+ }
+ return cmd;
+ }
+
+
+ bool polygon_ctrl_impl::check_edge(unsigned i, double x, double y) const
+ {
+ bool ret = false;
+
+ unsigned n1 = i;
+ unsigned n2 = (i + m_num_points - 1) % m_num_points;
+ double x1 = xn(n1);
+ double y1 = yn(n1);
+ double x2 = xn(n2);
+ double y2 = yn(n2);
+
+ double dx = x2 - x1;
+ double dy = y2 - y1;
+
+ if(sqrt(dx*dx + dy*dy) > 0.0000001)
+ {
+ double x3 = x;
+ double y3 = y;
+ double x4 = x3 - dy;
+ double y4 = y3 + dx;
+
+ double den = (y4-y3) * (x2-x1) - (x4-x3) * (y2-y1);
+ double u1 = ((x4-x3) * (y1-y3) - (y4-y3) * (x1-x3)) / den;
+
+ double xi = x1 + u1 * (x2 - x1);
+ double yi = y1 + u1 * (y2 - y1);
+
+ dx = xi - x;
+ dy = yi - y;
+
+ if (u1 > 0.0 && u1 < 1.0 && sqrt(dx*dx + dy*dy) <= m_point_radius)
+ {
+ ret = true;
+ }
+ }
+ return ret;
+ }
+
+
+
+ bool polygon_ctrl_impl::in_rect(double x, double y) const
+ {
+ return false;
+ }
+
+
+ bool polygon_ctrl_impl::on_mouse_button_down(double x, double y)
+ {
+ unsigned i;
+ bool ret = false;
+ m_node = -1;
+ m_edge = -1;
+ inverse_transform_xy(&x, &y);
+ for (i = 0; i < m_num_points; i++)
+ {
+ if(sqrt( (x-xn(i)) * (x-xn(i)) + (y-yn(i)) * (y-yn(i)) ) < m_point_radius)
+ {
+ m_dx = x - xn(i);
+ m_dy = y - yn(i);
+ m_node = int(i);
+ ret = true;
+ break;
+ }
+ }
+
+ if(!ret)
+ {
+ for (i = 0; i < m_num_points; i++)
+ {
+ if(check_edge(i, x, y))
+ {
+ m_dx = x;
+ m_dy = y;
+ m_edge = int(i);
+ ret = true;
+ break;
+ }
+ }
+ }
+
+ if(!ret)
+ {
+ if(point_in_polygon(x, y))
+ {
+ m_dx = x;
+ m_dy = y;
+ m_node = int(m_num_points);
+ ret = true;
+ }
+ }
+ return ret;
+ }
+
+
+ bool polygon_ctrl_impl::on_mouse_move(double x, double y, bool button_flag)
+ {
+ bool ret = false;
+ double dx;
+ double dy;
+ inverse_transform_xy(&x, &y);
+ if(m_node == int(m_num_points))
+ {
+ dx = x - m_dx;
+ dy = y - m_dy;
+ unsigned i;
+ for(i = 0; i < m_num_points; i++)
+ {
+ xn(i) += dx;
+ yn(i) += dy;
+ }
+ m_dx = x;
+ m_dy = y;
+ ret = true;
+ }
+ else
+ {
+ if(m_edge >= 0)
+ {
+ unsigned n1 = m_edge;
+ unsigned n2 = (n1 + m_num_points - 1) % m_num_points;
+ dx = x - m_dx;
+ dy = y - m_dy;
+ xn(n1) += dx;
+ yn(n1) += dy;
+ xn(n2) += dx;
+ yn(n2) += dy;
+ m_dx = x;
+ m_dy = y;
+ ret = true;
+ }
+ else
+ {
+ if(m_node >= 0)
+ {
+ xn(m_node) = x - m_dx;
+ yn(m_node) = y - m_dy;
+ ret = true;
+ }
+ }
+ }
+ return ret;
+ }
+
+ bool polygon_ctrl_impl::on_mouse_button_up(double x, double y)
+ {
+ bool ret = (m_node >= 0) || (m_edge >= 0);
+ m_node = -1;
+ m_edge = -1;
+ return ret;
+ }
+
+
+ bool polygon_ctrl_impl::on_arrow_keys(bool left, bool right, bool down, bool up)
+ {
+ return false;
+ }
+
+
+ //======= Crossings Multiply algorithm of InsideTest ========================
+ //
+ // By Eric Haines, 3D/Eye Inc, erich@eye.com
+ //
+ // This version is usually somewhat faster than the original published in
+ // Graphics Gems IV; by turning the division for testing the X axis crossing
+ // into a tricky multiplication test this part of the test became faster,
+ // which had the additional effect of making the test for "both to left or
+ // both to right" a bit slower for triangles than simply computing the
+ // intersection each time. The main increase is in triangle testing speed,
+ // which was about 15% faster; all other polygon complexities were pretty much
+ // the same as before. On machines where division is very expensive (not the
+ // case on the HP 9000 series on which I tested) this test should be much
+ // faster overall than the old code. Your mileage may (in fact, will) vary,
+ // depending on the machine and the test data, but in general I believe this
+ // code is both shorter and faster. This test was inspired by unpublished
+ // Graphics Gems submitted by Joseph Samosky and Mark Haigh-Hutchinson.
+ // Related work by Samosky is in:
+ //
+ // Samosky, Joseph, "SectionView: A system for interactively specifying and
+ // visualizing sections through three-dimensional medical image data",
+ // M.S. Thesis, Department of Electrical Engineering and Computer Science,
+ // Massachusetts Institute of Technology, 1993.
+ //
+ // Shoot a test ray along +X axis. The strategy is to compare vertex Y values
+ // to the testing point's Y and quickly discard edges which are entirely to one
+ // side of the test ray. Note that CONVEX and WINDING code can be added as
+ // for the CrossingsTest() code; it is left out here for clarity.
+ //
+ // Input 2D polygon _pgon_ with _numverts_ number of vertices and test point
+ // _point_, returns 1 if inside, 0 if outside.
+ bool polygon_ctrl_impl::point_in_polygon(double tx, double ty) const
+ {
+ if(m_num_points < 3) return false;
+ if(!m_in_polygon_check) return false;
+
+ unsigned j;
+ int yflag0, yflag1, inside_flag;
+ double vtx0, vty0, vtx1, vty1;
+
+ vtx0 = xn(m_num_points - 1);
+ vty0 = yn(m_num_points - 1);
+
+ // get test bit for above/below X axis
+ yflag0 = (vty0 >= ty);
+
+ vtx1 = xn(0);
+ vty1 = yn(0);
+
+ inside_flag = 0;
+ for (j = 1; j <= m_num_points; ++j)
+ {
+ yflag1 = (vty1 >= ty);
+ // Check if endpoints straddle (are on opposite sides) of X axis
+ // (i.e. the Y's differ); if so, +X ray could intersect this edge.
+ // The old test also checked whether the endpoints are both to the
+ // right or to the left of the test point. However, given the faster
+ // intersection point computation used below, this test was found to
+ // be a break-even proposition for most polygons and a loser for
+ // triangles (where 50% or more of the edges which survive this test
+ // will cross quadrants and so have to have the X intersection computed
+ // anyway). I credit Joseph Samosky with inspiring me to try dropping
+ // the "both left or both right" part of my code.
+ if (yflag0 != yflag1)
+ {
+ // Check intersection of pgon segment with +X ray.
+ // Note if >= point's X; if so, the ray hits it.
+ // The division operation is avoided for the ">=" test by checking
+ // the sign of the first vertex wrto the test point; idea inspired
+ // by Joseph Samosky's and Mark Haigh-Hutchinson's different
+ // polygon inclusion tests.
+ if ( ((vty1-ty) * (vtx0-vtx1) >=
+ (vtx1-tx) * (vty0-vty1)) == yflag1 )
+ {
+ inside_flag ^= 1;
+ }
+ }
+
+ // Move to the next pair of vertices, retaining info as possible.
+ yflag0 = yflag1;
+ vtx0 = vtx1;
+ vty0 = vty1;
+
+ unsigned k = (j >= m_num_points) ? j - m_num_points : j;
+ vtx1 = xn(k);
+ vty1 = yn(k);
+ }
+ return inside_flag != 0;
+ }
+}
+
diff --git a/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_rbox_ctrl.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_rbox_ctrl.cpp
new file mode 100644
index 0000000000..4e36b3b26b
--- /dev/null
+++ b/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_rbox_ctrl.cpp
@@ -0,0 +1,325 @@
+//----------------------------------------------------------------------------
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
+//
+// Permission to copy, use, modify, sell and distribute this software
+// is granted provided this copyright notice appears in all copies.
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+//
+//----------------------------------------------------------------------------
+// Contact: mcseem@antigrain.com
+// mcseemagg@yahoo.com
+// http://www.antigrain.com
+//----------------------------------------------------------------------------
+//
+// classes rbox_ctrl_impl, rbox_ctrl
+//
+//----------------------------------------------------------------------------
+
+#include <string.h>
+#include "ctrl/agg_rbox_ctrl.h"
+
+namespace agg
+{
+
+ //------------------------------------------------------------------------
+ rbox_ctrl_impl::rbox_ctrl_impl(double x1, double y1,
+ double x2, double y2, bool flip_y) :
+ ctrl(x1, y1, x2, y2, flip_y),
+ m_border_width(1.0),
+ m_border_extra(0.0),
+ m_text_thickness(1.5),
+ m_text_height(9.0),
+ m_text_width(0.0),
+ m_num_items(0),
+ m_cur_item(-1),
+ m_ellipse_poly(m_ellipse),
+ m_text_poly(m_text),
+ m_idx(0),
+ m_vertex(0)
+ {
+ calc_rbox();
+ }
+
+
+ //------------------------------------------------------------------------
+ void rbox_ctrl_impl::calc_rbox()
+ {
+ m_xs1 = m_x1 + m_border_width;
+ m_ys1 = m_y1 + m_border_width;
+ m_xs2 = m_x2 - m_border_width;
+ m_ys2 = m_y2 - m_border_width;
+ }
+
+
+ //------------------------------------------------------------------------
+ void rbox_ctrl_impl::add_item(const char* text)
+ {
+ if(m_num_items < 32)
+ {
+ m_items[m_num_items].resize(strlen(text) + 1);
+ strcpy(&m_items[m_num_items][0], text);
+ m_num_items++;
+ }
+ }
+
+
+ //------------------------------------------------------------------------
+ void rbox_ctrl_impl::border_width(double t, double extra)
+ {
+ m_border_width = t;
+ m_border_extra = extra;
+ calc_rbox();
+ }
+
+
+ //------------------------------------------------------------------------
+ void rbox_ctrl_impl::text_size(double h, double w)
+ {
+ m_text_width = w;
+ m_text_height = h;
+ }
+
+
+
+ //------------------------------------------------------------------------
+ void rbox_ctrl_impl::rewind(unsigned idx)
+ {
+ m_idx = idx;
+ m_dy = m_text_height * 2.0;
+ m_draw_item = 0;
+
+ switch(idx)
+ {
+ default:
+
+ case 0: // Background
+ m_vertex = 0;
+ m_vx[0] = m_x1 - m_border_extra;
+ m_vy[0] = m_y1 - m_border_extra;
+ m_vx[1] = m_x2 + m_border_extra;
+ m_vy[1] = m_y1 - m_border_extra;
+ m_vx[2] = m_x2 + m_border_extra;
+ m_vy[2] = m_y2 + m_border_extra;
+ m_vx[3] = m_x1 - m_border_extra;
+ m_vy[3] = m_y2 + m_border_extra;
+ break;
+
+ case 1: // Border
+ m_vertex = 0;
+ m_vx[0] = m_x1;
+ m_vy[0] = m_y1;
+ m_vx[1] = m_x2;
+ m_vy[1] = m_y1;
+ m_vx[2] = m_x2;
+ m_vy[2] = m_y2;
+ m_vx[3] = m_x1;
+ m_vy[3] = m_y2;
+ m_vx[4] = m_x1 + m_border_width;
+ m_vy[4] = m_y1 + m_border_width;
+ m_vx[5] = m_x1 + m_border_width;
+ m_vy[5] = m_y2 - m_border_width;
+ m_vx[6] = m_x2 - m_border_width;
+ m_vy[6] = m_y2 - m_border_width;
+ m_vx[7] = m_x2 - m_border_width;
+ m_vy[7] = m_y1 + m_border_width;
+ break;
+
+ case 2: // Text
+ m_text.text(&m_items[0][0]);
+ m_text.start_point(m_xs1 + m_dy * 1.5, m_ys1 + m_dy / 2.0);
+ m_text.size(m_text_height, m_text_width);
+ m_text_poly.width(m_text_thickness);
+ m_text_poly.line_join(round_join);
+ m_text_poly.line_cap(round_cap);
+ m_text_poly.rewind(0);
+ break;
+
+ case 3: // Inactive items
+ m_ellipse.init(m_xs1 + m_dy / 1.3,
+ m_ys1 + m_dy / 1.3,
+ m_text_height / 1.5,
+ m_text_height / 1.5, 32);
+ m_ellipse_poly.width(m_text_thickness);
+ m_ellipse_poly.rewind(0);
+ break;
+
+
+ case 4: // Active Item
+ if(m_cur_item >= 0)
+ {
+ m_ellipse.init(m_xs1 + m_dy / 1.3,
+ m_ys1 + m_dy * m_cur_item + m_dy / 1.3,
+ m_text_height / 2.0,
+ m_text_height / 2.0, 32);
+ m_ellipse.rewind(0);
+ }
+ break;
+
+ }
+ }
+
+
+ //------------------------------------------------------------------------
+ unsigned rbox_ctrl_impl::vertex(double* x, double* y)
+ {
+ unsigned cmd = path_cmd_line_to;
+ switch(m_idx)
+ {
+ case 0:
+ if(m_vertex == 0) cmd = path_cmd_move_to;
+ if(m_vertex >= 4) cmd = path_cmd_stop;
+ *x = m_vx[m_vertex];
+ *y = m_vy[m_vertex];
+ m_vertex++;
+ break;
+
+ case 1:
+ if(m_vertex == 0 || m_vertex == 4) cmd = path_cmd_move_to;
+ if(m_vertex >= 8) cmd = path_cmd_stop;
+ *x = m_vx[m_vertex];
+ *y = m_vy[m_vertex];
+ m_vertex++;
+ break;
+
+ case 2:
+ cmd = m_text_poly.vertex(x, y);
+ if(is_stop(cmd))
+ {
+ m_draw_item++;
+ if(m_draw_item >= m_num_items)
+ {
+ break;
+ }
+ else
+ {
+ m_text.text(&m_items[m_draw_item][0]);
+ m_text.start_point(m_xs1 + m_dy * 1.5,
+ m_ys1 + m_dy * (m_draw_item + 1) - m_dy / 2.0);
+
+ m_text_poly.rewind(0);
+ cmd = m_text_poly.vertex(x, y);
+ }
+ }
+ break;
+
+ case 3:
+ cmd = m_ellipse_poly.vertex(x, y);
+ if(is_stop(cmd))
+ {
+ m_draw_item++;
+ if(m_draw_item >= m_num_items)
+ {
+ break;
+ }
+ else
+ {
+ m_ellipse.init(m_xs1 + m_dy / 1.3,
+ m_ys1 + m_dy * m_draw_item + m_dy / 1.3,
+ m_text_height / 1.5,
+ m_text_height / 1.5, 32);
+ m_ellipse_poly.rewind(0);
+ cmd = m_ellipse_poly.vertex(x, y);
+ }
+ }
+ break;
+
+
+ case 4:
+ if(m_cur_item >= 0)
+ {
+ cmd = m_ellipse.vertex(x, y);
+ }
+ else
+ {
+ cmd = path_cmd_stop;
+ }
+ break;
+
+ default:
+ cmd = path_cmd_stop;
+ break;
+ }
+
+ if(!is_stop(cmd))
+ {
+ transform_xy(x, y);
+ }
+
+ return cmd;
+ }
+
+
+ //------------------------------------------------------------------------
+ bool rbox_ctrl_impl::in_rect(double x, double y) const
+ {
+ inverse_transform_xy(&x, &y);
+ return x >= m_x1 && x <= m_x2 && y >= m_y1 && y <= m_y2;
+ }
+
+
+
+ //------------------------------------------------------------------------
+ bool rbox_ctrl_impl::on_mouse_button_down(double x, double y)
+ {
+ inverse_transform_xy(&x, &y);
+ unsigned i;
+ for(i = 0; i < m_num_items; i++)
+ {
+ double xp = m_xs1 + m_dy / 1.3;
+ double yp = m_ys1 + m_dy * i + m_dy / 1.3;
+ if(calc_distance(x, y, xp, yp) <= m_text_height / 1.5)
+ {
+ m_cur_item = int(i);
+ return true;
+ }
+ }
+ return false;
+ }
+
+
+ //------------------------------------------------------------------------
+ bool rbox_ctrl_impl::on_mouse_move(double, double, bool)
+ {
+ return false;
+ }
+
+ //------------------------------------------------------------------------
+ bool rbox_ctrl_impl::on_mouse_button_up(double, double)
+ {
+ return false;
+ }
+
+ //------------------------------------------------------------------------
+ bool rbox_ctrl_impl::on_arrow_keys(bool left, bool right, bool down, bool up)
+ {
+ if(m_cur_item >= 0)
+ {
+ if(up || right)
+ {
+ m_cur_item++;
+ if(m_cur_item >= int(m_num_items))
+ {
+ m_cur_item = 0;
+ }
+ return true;
+ }
+
+ if(down || left)
+ {
+ m_cur_item--;
+ if(m_cur_item < 0)
+ {
+ m_cur_item = m_num_items - 1;
+ }
+ return true;
+ }
+ }
+ return false;
+ }
+
+
+}
+
+
diff --git a/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_scale_ctrl.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_scale_ctrl.cpp
new file mode 100644
index 0000000000..7f167792bd
--- /dev/null
+++ b/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_scale_ctrl.cpp
@@ -0,0 +1,454 @@
+//----------------------------------------------------------------------------
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
+//
+// Permission to copy, use, modify, sell and distribute this software
+// is granted provided this copyright notice appears in all copies.
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+//
+//----------------------------------------------------------------------------
+// Contact: mcseem@antigrain.com
+// mcseemagg@yahoo.com
+// http://www.antigrain.com
+//----------------------------------------------------------------------------
+//
+// classes scale_ctrl_impl, scale_ctrl
+//
+//----------------------------------------------------------------------------
+
+#include "ctrl/agg_scale_ctrl.h"
+
+namespace agg
+{
+
+ //------------------------------------------------------------------------
+ scale_ctrl_impl::scale_ctrl_impl(double x1, double y1,
+ double x2, double y2, bool flip_y) :
+ ctrl(x1, y1, x2, y2, flip_y),
+ m_border_thickness(1.0),
+ m_border_extra((fabs(x2 - x1) > fabs(y2 - y1)) ? (y2 - y1) / 2 : (x2 - x1) / 2),
+ m_pdx(0.0),
+ m_pdy(0.0),
+ m_move_what(move_nothing),
+ m_value1(0.3),
+ m_value2(0.7),
+ m_min_d(0.01)
+ {
+ calc_box();
+ }
+
+
+ //------------------------------------------------------------------------
+ void scale_ctrl_impl::calc_box()
+ {
+ m_xs1 = m_x1 + m_border_thickness;
+ m_ys1 = m_y1 + m_border_thickness;
+ m_xs2 = m_x2 - m_border_thickness;
+ m_ys2 = m_y2 - m_border_thickness;
+ }
+
+
+ //------------------------------------------------------------------------
+ void scale_ctrl_impl::border_thickness(double t, double extra)
+ {
+ m_border_thickness = t;
+ m_border_extra = extra;
+ calc_box();
+ }
+
+
+ //------------------------------------------------------------------------
+ void scale_ctrl_impl::resize(double x1, double y1, double x2, double y2)
+ {
+ m_x1 = x1;
+ m_y1 = y1;
+ m_x2 = x2;
+ m_y2 = y2;
+ calc_box();
+ m_border_extra = (fabs(x2 - x1) > fabs(y2 - y1)) ?
+ (y2 - y1) / 2 :
+ (x2 - x1) / 2;
+ }
+
+
+ //------------------------------------------------------------------------
+ void scale_ctrl_impl::value1(double value)
+ {
+ if(value < 0.0) value = 0.0;
+ if(value > 1.0) value = 1.0;
+ if(m_value2 - value < m_min_d) value = m_value2 - m_min_d;
+ m_value1 = value;
+ }
+
+
+ //------------------------------------------------------------------------
+ void scale_ctrl_impl::value2(double value)
+ {
+ if(value < 0.0) value = 0.0;
+ if(value > 1.0) value = 1.0;
+ if(m_value1 + value < m_min_d) value = m_value1 + m_min_d;
+ m_value2 = value;
+ }
+
+
+ //------------------------------------------------------------------------
+ void scale_ctrl_impl::move(double d)
+ {
+ m_value1 += d;
+ m_value2 += d;
+ if(m_value1 < 0.0)
+ {
+ m_value2 -= m_value1;
+ m_value1 = 0.0;
+ }
+ if(m_value2 > 1.0)
+ {
+ m_value1 -= m_value2 - 1.0;
+ m_value2 = 1.0;
+ }
+ }
+
+
+ //------------------------------------------------------------------------
+ void scale_ctrl_impl::rewind(unsigned idx)
+ {
+ m_idx = idx;
+
+ switch(idx)
+ {
+ default:
+
+ case 0: // Background
+ m_vertex = 0;
+ m_vx[0] = m_x1 - m_border_extra;
+ m_vy[0] = m_y1 - m_border_extra;
+ m_vx[1] = m_x2 + m_border_extra;
+ m_vy[1] = m_y1 - m_border_extra;
+ m_vx[2] = m_x2 + m_border_extra;
+ m_vy[2] = m_y2 + m_border_extra;
+ m_vx[3] = m_x1 - m_border_extra;
+ m_vy[3] = m_y2 + m_border_extra;
+ break;
+
+ case 1: // Border
+ m_vertex = 0;
+ m_vx[0] = m_x1;
+ m_vy[0] = m_y1;
+ m_vx[1] = m_x2;
+ m_vy[1] = m_y1;
+ m_vx[2] = m_x2;
+ m_vy[2] = m_y2;
+ m_vx[3] = m_x1;
+ m_vy[3] = m_y2;
+ m_vx[4] = m_x1 + m_border_thickness;
+ m_vy[4] = m_y1 + m_border_thickness;
+ m_vx[5] = m_x1 + m_border_thickness;
+ m_vy[5] = m_y2 - m_border_thickness;
+ m_vx[6] = m_x2 - m_border_thickness;
+ m_vy[6] = m_y2 - m_border_thickness;
+ m_vx[7] = m_x2 - m_border_thickness;
+ m_vy[7] = m_y1 + m_border_thickness;
+ break;
+
+ case 2: // pointer1
+ if(fabs(m_x2 - m_x1) > fabs(m_y2 - m_y1))
+ {
+ m_ellipse.init(m_xs1 + (m_xs2 - m_xs1) * m_value1,
+ (m_ys1 + m_ys2) / 2.0,
+ m_y2 - m_y1,
+ m_y2 - m_y1,
+ 32);
+ }
+ else
+ {
+ m_ellipse.init((m_xs1 + m_xs2) / 2.0,
+ m_ys1 + (m_ys2 - m_ys1) * m_value1,
+ m_x2 - m_x1,
+ m_x2 - m_x1,
+ 32);
+ }
+ m_ellipse.rewind(0);
+ break;
+
+ case 3: // pointer2
+ if(fabs(m_x2 - m_x1) > fabs(m_y2 - m_y1))
+ {
+ m_ellipse.init(m_xs1 + (m_xs2 - m_xs1) * m_value2,
+ (m_ys1 + m_ys2) / 2.0,
+ m_y2 - m_y1,
+ m_y2 - m_y1,
+ 32);
+ }
+ else
+ {
+ m_ellipse.init((m_xs1 + m_xs2) / 2.0,
+ m_ys1 + (m_ys2 - m_ys1) * m_value2,
+ m_x2 - m_x1,
+ m_x2 - m_x1,
+ 32);
+ }
+ m_ellipse.rewind(0);
+ break;
+
+ case 4: // slider
+ m_vertex = 0;
+ if(fabs(m_x2 - m_x1) > fabs(m_y2 - m_y1))
+ {
+ m_vx[0] = m_xs1 + (m_xs2 - m_xs1) * m_value1;
+ m_vy[0] = m_y1 - m_border_extra / 2.0;
+ m_vx[1] = m_xs1 + (m_xs2 - m_xs1) * m_value2;
+ m_vy[1] = m_vy[0];
+ m_vx[2] = m_vx[1];
+ m_vy[2] = m_y2 + m_border_extra / 2.0;
+ m_vx[3] = m_vx[0];
+ m_vy[3] = m_vy[2];
+ }
+ else
+ {
+ m_vx[0] = m_x1 - m_border_extra / 2.0;
+ m_vy[0] = m_ys1 + (m_ys2 - m_ys1) * m_value1;
+ m_vx[1] = m_vx[0];
+ m_vy[1] = m_ys1 + (m_ys2 - m_ys1) * m_value2;
+ m_vx[2] = m_x2 + m_border_extra / 2.0;
+ m_vy[2] = m_vy[1];
+ m_vx[3] = m_vx[2];
+ m_vy[3] = m_vy[0];
+ }
+ break;
+ }
+ }
+
+
+ //------------------------------------------------------------------------
+ unsigned scale_ctrl_impl::vertex(double* x, double* y)
+ {
+ unsigned cmd = path_cmd_line_to;
+ switch(m_idx)
+ {
+ case 0:
+ case 4:
+ if(m_vertex == 0) cmd = path_cmd_move_to;
+ if(m_vertex >= 4) cmd = path_cmd_stop;
+ *x = m_vx[m_vertex];
+ *y = m_vy[m_vertex];
+ m_vertex++;
+ break;
+
+ case 1:
+ if(m_vertex == 0 || m_vertex == 4) cmd = path_cmd_move_to;
+ if(m_vertex >= 8) cmd = path_cmd_stop;
+ *x = m_vx[m_vertex];
+ *y = m_vy[m_vertex];
+ m_vertex++;
+ break;
+
+ case 2:
+ case 3:
+ cmd = m_ellipse.vertex(x, y);
+ break;
+
+ default:
+ cmd = path_cmd_stop;
+ break;
+ }
+
+ if(!is_stop(cmd))
+ {
+ transform_xy(x, y);
+ }
+
+ return cmd;
+ }
+
+
+
+ //------------------------------------------------------------------------
+ bool scale_ctrl_impl::in_rect(double x, double y) const
+ {
+ inverse_transform_xy(&x, &y);
+ return x >= m_x1 && x <= m_x2 && y >= m_y1 && y <= m_y2;
+ }
+
+
+ //------------------------------------------------------------------------
+ bool scale_ctrl_impl::on_mouse_button_down(double x, double y)
+ {
+ inverse_transform_xy(&x, &y);
+
+ double xp1;
+ double xp2;
+ double ys1;
+ double ys2;
+ double xp;
+ double yp;
+
+ if(fabs(m_x2 - m_x1) > fabs(m_y2 - m_y1))
+ {
+ xp1 = m_xs1 + (m_xs2 - m_xs1) * m_value1;
+ xp2 = m_xs1 + (m_xs2 - m_xs1) * m_value2;
+ ys1 = m_y1 - m_border_extra / 2.0;
+ ys2 = m_y2 + m_border_extra / 2.0;
+ yp = (m_ys1 + m_ys2) / 2.0;
+
+ if(x > xp1 && y > ys1 && x < xp2 && y < ys2)
+ {
+ m_pdx = xp1 - x;
+ m_move_what = move_slider;
+ return true;
+ }
+
+ //if(x < xp1 && calc_distance(x, y, xp1, yp) <= m_y2 - m_y1)
+ if(calc_distance(x, y, xp1, yp) <= m_y2 - m_y1)
+ {
+ m_pdx = xp1 - x;
+ m_move_what = move_value1;
+ return true;
+ }
+
+ //if(x > xp2 && calc_distance(x, y, xp2, yp) <= m_y2 - m_y1)
+ if(calc_distance(x, y, xp2, yp) <= m_y2 - m_y1)
+ {
+ m_pdx = xp2 - x;
+ m_move_what = move_value2;
+ return true;
+ }
+ }
+ else
+ {
+ xp1 = m_x1 - m_border_extra / 2.0;
+ xp2 = m_x2 + m_border_extra / 2.0;
+ ys1 = m_ys1 + (m_ys2 - m_ys1) * m_value1;
+ ys2 = m_ys1 + (m_ys2 - m_ys1) * m_value2;
+ xp = (m_xs1 + m_xs2) / 2.0;
+
+ if(x > xp1 && y > ys1 && x < xp2 && y < ys2)
+ {
+ m_pdy = ys1 - y;
+ m_move_what = move_slider;
+ return true;
+ }
+
+ //if(y < ys1 && calc_distance(x, y, xp, ys1) <= m_x2 - m_x1)
+ if(calc_distance(x, y, xp, ys1) <= m_x2 - m_x1)
+ {
+ m_pdy = ys1 - y;
+ m_move_what = move_value1;
+ return true;
+ }
+
+ //if(y > ys2 && calc_distance(x, y, xp, ys2) <= m_x2 - m_x1)
+ if(calc_distance(x, y, xp, ys2) <= m_x2 - m_x1)
+ {
+ m_pdy = ys2 - y;
+ m_move_what = move_value2;
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+
+ //------------------------------------------------------------------------
+ bool scale_ctrl_impl::on_mouse_move(double x, double y, bool button_flag)
+ {
+ inverse_transform_xy(&x, &y);
+ if(!button_flag)
+ {
+ return on_mouse_button_up(x, y);
+ }
+
+ double xp = x + m_pdx;
+ double yp = y + m_pdy;
+ double dv;
+
+ switch(m_move_what)
+ {
+ case move_value1:
+ if(fabs(m_x2 - m_x1) > fabs(m_y2 - m_y1))
+ {
+ m_value1 = (xp - m_xs1) / (m_xs2 - m_xs1);
+ }
+ else
+ {
+ m_value1 = (yp - m_ys1) / (m_ys2 - m_ys1);
+ }
+ if(m_value1 < 0.0) m_value1 = 0.0;
+ if(m_value1 > m_value2 - m_min_d) m_value1 = m_value2 - m_min_d;
+ return true;
+
+ case move_value2:
+ if(fabs(m_x2 - m_x1) > fabs(m_y2 - m_y1))
+ {
+ m_value2 = (xp - m_xs1) / (m_xs2 - m_xs1);
+ }
+ else
+ {
+ m_value2 = (yp - m_ys1) / (m_ys2 - m_ys1);
+ }
+ if(m_value2 > 1.0) m_value2 = 1.0;
+ if(m_value2 < m_value1 + m_min_d) m_value2 = m_value1 + m_min_d;
+ return true;
+
+ case move_slider:
+ dv = m_value2 - m_value1;
+ if(fabs(m_x2 - m_x1) > fabs(m_y2 - m_y1))
+ {
+ m_value1 = (xp - m_xs1) / (m_xs2 - m_xs1);
+ }
+ else
+ {
+ m_value1 = (yp - m_ys1) / (m_ys2 - m_ys1);
+ }
+ m_value2 = m_value1 + dv;
+ if(m_value1 < 0.0)
+ {
+ dv = m_value2 - m_value1;
+ m_value1 = 0.0;
+ m_value2 = m_value1 + dv;
+ }
+ if(m_value2 > 1.0)
+ {
+ dv = m_value2 - m_value1;
+ m_value2 = 1.0;
+ m_value1 = m_value2 - dv;
+ }
+ return true;
+ }
+
+ return false;
+ }
+
+
+ //------------------------------------------------------------------------
+ bool scale_ctrl_impl::on_mouse_button_up(double, double)
+ {
+ m_move_what = move_nothing;
+ return false;
+ }
+
+
+ //------------------------------------------------------------------------
+ bool scale_ctrl_impl::on_arrow_keys(bool left, bool right, bool down, bool up)
+ {
+/*
+ if(right || up)
+ {
+ m_value += 0.005;
+ if(m_value > 1.0) m_value = 1.0;
+ return true;
+ }
+
+ if(left || down)
+ {
+ m_value -= 0.005;
+ if(m_value < 0.0) m_value = 0.0;
+ return true;
+ }
+*/
+ return false;
+ }
+
+}
+
diff --git a/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_slider_ctrl.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_slider_ctrl.cpp
new file mode 100644
index 0000000000..ad0048631c
--- /dev/null
+++ b/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_slider_ctrl.cpp
@@ -0,0 +1,349 @@
+//----------------------------------------------------------------------------
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
+//
+// Permission to copy, use, modify, sell and distribute this software
+// is granted provided this copyright notice appears in all copies.
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+//
+//----------------------------------------------------------------------------
+// Contact: mcseem@antigrain.com
+// mcseemagg@yahoo.com
+// http://www.antigrain.com
+//----------------------------------------------------------------------------
+//
+// classes slider_ctrl_impl, slider_ctrl
+//
+//----------------------------------------------------------------------------
+
+#include <string.h>
+#include <stdio.h>
+#include "ctrl/agg_slider_ctrl.h"
+
+namespace agg
+{
+
+ //------------------------------------------------------------------------
+ slider_ctrl_impl::slider_ctrl_impl(double x1, double y1,
+ double x2, double y2, bool flip_y) :
+ ctrl(x1, y1, x2, y2, flip_y),
+ m_border_width(1.0),
+ m_border_extra((y2 - y1) / 2),
+ m_text_thickness(1.0),
+ m_pdx(0.0),
+ m_mouse_move(false),
+ m_value(0.5),
+ m_preview_value(0.5),
+ m_min(0.0),
+ m_max(1.0),
+ m_num_steps(0),
+ m_descending(false),
+ m_text_poly(m_text)
+ {
+ m_label[0] = 0;
+ calc_box();
+ }
+
+
+ //------------------------------------------------------------------------
+ void slider_ctrl_impl::calc_box()
+ {
+ m_xs1 = m_x1 + m_border_width;
+ m_ys1 = m_y1 + m_border_width;
+ m_xs2 = m_x2 - m_border_width;
+ m_ys2 = m_y2 - m_border_width;
+ }
+
+
+ //------------------------------------------------------------------------
+ bool slider_ctrl_impl::normalize_value(bool preview_value_flag)
+ {
+ bool ret = true;
+ if(m_num_steps)
+ {
+ int step = int(m_preview_value * m_num_steps + 0.5);
+ ret = m_value != step / double(m_num_steps);
+ m_value = step / double(m_num_steps);
+ }
+ else
+ {
+ m_value = m_preview_value;
+ }
+
+ if(preview_value_flag)
+ {
+ m_preview_value = m_value;
+ }
+ return ret;
+ }
+
+
+ //------------------------------------------------------------------------
+ void slider_ctrl_impl::border_width(double t, double extra)
+ {
+ m_border_width = t;
+ m_border_extra = extra;
+ calc_box();
+ }
+
+
+ //------------------------------------------------------------------------
+ void slider_ctrl_impl::value(double value)
+ {
+ m_preview_value = (value - m_min) / (m_max - m_min);
+ if(m_preview_value > 1.0) m_preview_value = 1.0;
+ if(m_preview_value < 0.0) m_preview_value = 0.0;
+ normalize_value(true);
+ }
+
+ //------------------------------------------------------------------------
+ void slider_ctrl_impl::label(const char* fmt)
+ {
+ m_label[0] = 0;
+ if(fmt)
+ {
+ unsigned len = strlen(fmt);
+ if(len > 63) len = 63;
+ memcpy(m_label, fmt, len);
+ m_label[len] = 0;
+ }
+ }
+
+ //------------------------------------------------------------------------
+ void slider_ctrl_impl::rewind(unsigned idx)
+ {
+ m_idx = idx;
+
+ switch(idx)
+ {
+ default:
+
+ case 0: // Background
+ m_vertex = 0;
+ m_vx[0] = m_x1 - m_border_extra;
+ m_vy[0] = m_y1 - m_border_extra;
+ m_vx[1] = m_x2 + m_border_extra;
+ m_vy[1] = m_y1 - m_border_extra;
+ m_vx[2] = m_x2 + m_border_extra;
+ m_vy[2] = m_y2 + m_border_extra;
+ m_vx[3] = m_x1 - m_border_extra;
+ m_vy[3] = m_y2 + m_border_extra;
+ break;
+
+ case 1: // Triangle
+ m_vertex = 0;
+ if(m_descending)
+ {
+ m_vx[0] = m_x1;
+ m_vy[0] = m_y1;
+ m_vx[1] = m_x2;
+ m_vy[1] = m_y1;
+ m_vx[2] = m_x1;
+ m_vy[2] = m_y2;
+ m_vx[3] = m_x1;
+ m_vy[3] = m_y1;
+ }
+ else
+ {
+ m_vx[0] = m_x1;
+ m_vy[0] = m_y1;
+ m_vx[1] = m_x2;
+ m_vy[1] = m_y1;
+ m_vx[2] = m_x2;
+ m_vy[2] = m_y2;
+ m_vx[3] = m_x1;
+ m_vy[3] = m_y1;
+ }
+ break;
+
+ case 2:
+ m_text.text(m_label);
+ if(m_label[0])
+ {
+ char buf[256];
+ sprintf(buf, m_label, value());
+ m_text.text(buf);
+ }
+ m_text.start_point(m_x1, m_y1);
+ m_text.size((m_y2 - m_y1) * 1.2, m_y2 - m_y1);
+ m_text_poly.width(m_text_thickness);
+ m_text_poly.line_join(round_join);
+ m_text_poly.line_cap(round_cap);
+ m_text_poly.rewind(0);
+ break;
+
+ case 3: // pointer preview
+ m_ellipse.init(m_xs1 + (m_xs2 - m_xs1) * m_preview_value,
+ (m_ys1 + m_ys2) / 2.0,
+ m_y2 - m_y1,
+ m_y2 - m_y1,
+ 32);
+ break;
+
+
+ case 4: // pointer
+ normalize_value(false);
+ m_ellipse.init(m_xs1 + (m_xs2 - m_xs1) * m_value,
+ (m_ys1 + m_ys2) / 2.0,
+ m_y2 - m_y1,
+ m_y2 - m_y1,
+ 32);
+ m_ellipse.rewind(0);
+ break;
+
+ case 5:
+ m_storage.remove_all();
+ if(m_num_steps)
+ {
+ unsigned i;
+ double d = (m_xs2 - m_xs1) / m_num_steps;
+ if(d > 0.004) d = 0.004;
+ for(i = 0; i < m_num_steps + 1; i++)
+ {
+ double x = m_xs1 + (m_xs2 - m_xs1) * i / m_num_steps;
+ m_storage.move_to(x, m_y1);
+ m_storage.line_to(x - d * (m_x2 - m_x1), m_y1 - m_border_extra);
+ m_storage.line_to(x + d * (m_x2 - m_x1), m_y1 - m_border_extra);
+ }
+ }
+ }
+ }
+
+
+ //------------------------------------------------------------------------
+ unsigned slider_ctrl_impl::vertex(double* x, double* y)
+ {
+ unsigned cmd = path_cmd_line_to;
+ switch(m_idx)
+ {
+ case 0:
+ if(m_vertex == 0) cmd = path_cmd_move_to;
+ if(m_vertex >= 4) cmd = path_cmd_stop;
+ *x = m_vx[m_vertex];
+ *y = m_vy[m_vertex];
+ m_vertex++;
+ break;
+
+ case 1:
+ if(m_vertex == 0) cmd = path_cmd_move_to;
+ if(m_vertex >= 4) cmd = path_cmd_stop;
+ *x = m_vx[m_vertex];
+ *y = m_vy[m_vertex];
+ m_vertex++;
+ break;
+
+ case 2:
+ cmd = m_text_poly.vertex(x, y);
+ break;
+
+ case 3:
+ case 4:
+ cmd = m_ellipse.vertex(x, y);
+ break;
+
+ case 5:
+ cmd = m_storage.vertex(x, y);
+ break;
+
+ default:
+ cmd = path_cmd_stop;
+ break;
+ }
+
+ if(!is_stop(cmd))
+ {
+ transform_xy(x, y);
+ }
+
+ return cmd;
+ }
+
+
+
+ //------------------------------------------------------------------------
+ bool slider_ctrl_impl::in_rect(double x, double y) const
+ {
+ inverse_transform_xy(&x, &y);
+ return x >= m_x1 && x <= m_x2 && y >= m_y1 && y <= m_y2;
+ }
+
+
+ //------------------------------------------------------------------------
+ bool slider_ctrl_impl::on_mouse_button_down(double x, double y)
+ {
+ inverse_transform_xy(&x, &y);
+
+ double xp = m_xs1 + (m_xs2 - m_xs1) * m_value;
+ double yp = (m_ys1 + m_ys2) / 2.0;
+
+ if(calc_distance(x, y, xp, yp) <= m_y2 - m_y1)
+ {
+ m_pdx = xp - x;
+ m_mouse_move = true;
+ return true;
+ }
+ return false;
+ }
+
+
+ //------------------------------------------------------------------------
+ bool slider_ctrl_impl::on_mouse_move(double x, double y, bool button_flag)
+ {
+ inverse_transform_xy(&x, &y);
+ if(!button_flag)
+ {
+ on_mouse_button_up(x, y);
+ return false;
+ }
+
+ if(m_mouse_move)
+ {
+ double xp = x + m_pdx;
+ m_preview_value = (xp - m_xs1) / (m_xs2 - m_xs1);
+ if(m_preview_value < 0.0) m_preview_value = 0.0;
+ if(m_preview_value > 1.0) m_preview_value = 1.0;
+ return true;
+ }
+ return false;
+ }
+
+
+ //------------------------------------------------------------------------
+ bool slider_ctrl_impl::on_mouse_button_up(double, double)
+ {
+ m_mouse_move = false;
+ normalize_value(true);
+ return true;
+ }
+
+
+ //------------------------------------------------------------------------
+ bool slider_ctrl_impl::on_arrow_keys(bool left, bool right, bool down, bool up)
+ {
+ double d = 0.005;
+ if(m_num_steps)
+ {
+ d = 1.0 / m_num_steps;
+ }
+
+ if(right || up)
+ {
+ m_preview_value += d;
+ if(m_preview_value > 1.0) m_preview_value = 1.0;
+ normalize_value(true);
+ return true;
+ }
+
+ if(left || down)
+ {
+ m_preview_value -= d;
+ if(m_preview_value < 0.0) m_preview_value = 0.0;
+ normalize_value(true);
+ return true;
+ }
+ return false;
+ }
+
+}
+
diff --git a/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_spline_ctrl.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_spline_ctrl.cpp
new file mode 100644
index 0000000000..74808d4f87
--- /dev/null
+++ b/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_spline_ctrl.cpp
@@ -0,0 +1,407 @@
+//----------------------------------------------------------------------------
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
+//
+// Permission to copy, use, modify, sell and distribute this software
+// is granted provided this copyright notice appears in all copies.
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+//
+//----------------------------------------------------------------------------
+// Contact: mcseem@antigrain.com
+// mcseemagg@yahoo.com
+// http://www.antigrain.com
+//----------------------------------------------------------------------------
+//
+// classes spline_ctrl_impl, spline_ctrl
+//
+//----------------------------------------------------------------------------
+
+#include "ctrl/agg_spline_ctrl.h"
+
+
+namespace agg
+{
+
+ //------------------------------------------------------------------------
+ spline_ctrl_impl::spline_ctrl_impl(double x1, double y1, double x2, double y2,
+ unsigned num_pnt, bool flip_y) :
+ ctrl(x1, y1, x2, y2, flip_y),
+ m_num_pnt(num_pnt),
+ m_border_width(1.0),
+ m_border_extra(0.0),
+ m_curve_width(1.0),
+ m_point_size(3.0),
+ m_curve_poly(m_curve_pnt),
+ m_idx(0),
+ m_vertex(0),
+ m_active_pnt(-1),
+ m_move_pnt(-1),
+ m_pdx(0.0),
+ m_pdy(0.0)
+ {
+ if(m_num_pnt < 4) m_num_pnt = 4;
+ if(m_num_pnt > 32) m_num_pnt = 32;
+
+ unsigned i;
+ for(i = 0; i < m_num_pnt; i++)
+ {
+ m_xp[i] = double(i) / double(m_num_pnt - 1);
+ m_yp[i] = 0.5;
+ }
+ calc_spline_box();
+ update_spline();
+ }
+
+
+ //------------------------------------------------------------------------
+ void spline_ctrl_impl::border_width(double t, double extra)
+ {
+ m_border_width = t;
+ m_border_extra = extra;
+ calc_spline_box();
+ }
+
+
+ //------------------------------------------------------------------------
+ void spline_ctrl_impl::calc_spline_box()
+ {
+ m_xs1 = m_x1 + m_border_width;
+ m_ys1 = m_y1 + m_border_width;
+ m_xs2 = m_x2 - m_border_width;
+ m_ys2 = m_y2 - m_border_width;
+ }
+
+
+ //------------------------------------------------------------------------
+ void spline_ctrl_impl::update_spline()
+ {
+ int i;
+ m_spline.init(m_num_pnt, m_xp, m_yp);
+ for(i = 0; i < 256; i++)
+ {
+ m_spline_values[i] = m_spline.get(double(i) / 255.0);
+ if(m_spline_values[i] < 0.0) m_spline_values[i] = 0.0;
+ if(m_spline_values[i] > 1.0) m_spline_values[i] = 1.0;
+ m_spline_values8[i] = (int8u)(m_spline_values[i] * 255.0);
+ }
+ }
+
+
+ //------------------------------------------------------------------------
+ void spline_ctrl_impl::calc_curve()
+ {
+ int i;
+ m_curve_pnt.remove_all();
+ m_curve_pnt.move_to(m_xs1, m_ys1 + (m_ys2 - m_ys1) * m_spline_values[0]);
+ for(i = 1; i < 256; i++)
+ {
+ m_curve_pnt.line_to(m_xs1 + (m_xs2 - m_xs1) * double(i) / 255.0,
+ m_ys1 + (m_ys2 - m_ys1) * m_spline_values[i]);
+ }
+ }
+
+
+ //------------------------------------------------------------------------
+ double spline_ctrl_impl::calc_xp(unsigned idx)
+ {
+ return m_xs1 + (m_xs2 - m_xs1) * m_xp[idx];
+ }
+
+
+ //------------------------------------------------------------------------
+ double spline_ctrl_impl::calc_yp(unsigned idx)
+ {
+ return m_ys1 + (m_ys2 - m_ys1) * m_yp[idx];
+ }
+
+
+ //------------------------------------------------------------------------
+ void spline_ctrl_impl::set_xp(unsigned idx, double val)
+ {
+ if(val < 0.0) val = 0.0;
+ if(val > 1.0) val = 1.0;
+
+ if(idx == 0)
+ {
+ val = 0.0;
+ }
+ else if(idx == m_num_pnt - 1)
+ {
+ val = 1.0;
+ }
+ else
+ {
+ if(val < m_xp[idx - 1] + 0.001) val = m_xp[idx - 1] + 0.001;
+ if(val > m_xp[idx + 1] - 0.001) val = m_xp[idx + 1] - 0.001;
+ }
+ m_xp[idx] = val;
+ }
+
+ //------------------------------------------------------------------------
+ void spline_ctrl_impl::set_yp(unsigned idx, double val)
+ {
+ if(val < 0.0) val = 0.0;
+ if(val > 1.0) val = 1.0;
+ m_yp[idx] = val;
+ }
+
+
+ //------------------------------------------------------------------------
+ void spline_ctrl_impl::point(unsigned idx, double x, double y)
+ {
+ if(idx < m_num_pnt)
+ {
+ set_xp(idx, x);
+ set_yp(idx, y);
+ }
+ }
+
+
+ //------------------------------------------------------------------------
+ void spline_ctrl_impl::value(unsigned idx, double y)
+ {
+ if(idx < m_num_pnt)
+ {
+ set_yp(idx, y);
+ }
+ }
+
+ //------------------------------------------------------------------------
+ double spline_ctrl_impl::value(double x) const
+ {
+ x = m_spline.get(x);
+ if(x < 0.0) x = 0.0;
+ if(x > 1.0) x = 1.0;
+ return x;
+ }
+
+
+ //------------------------------------------------------------------------
+ void spline_ctrl_impl::rewind(unsigned idx)
+ {
+ unsigned i;
+
+ m_idx = idx;
+
+ switch(idx)
+ {
+ default:
+
+ case 0: // Background
+ m_vertex = 0;
+ m_vx[0] = m_x1 - m_border_extra;
+ m_vy[0] = m_y1 - m_border_extra;
+ m_vx[1] = m_x2 + m_border_extra;
+ m_vy[1] = m_y1 - m_border_extra;
+ m_vx[2] = m_x2 + m_border_extra;
+ m_vy[2] = m_y2 + m_border_extra;
+ m_vx[3] = m_x1 - m_border_extra;
+ m_vy[3] = m_y2 + m_border_extra;
+ break;
+
+ case 1: // Border
+ m_vertex = 0;
+ m_vx[0] = m_x1;
+ m_vy[0] = m_y1;
+ m_vx[1] = m_x2;
+ m_vy[1] = m_y1;
+ m_vx[2] = m_x2;
+ m_vy[2] = m_y2;
+ m_vx[3] = m_x1;
+ m_vy[3] = m_y2;
+ m_vx[4] = m_x1 + m_border_width;
+ m_vy[4] = m_y1 + m_border_width;
+ m_vx[5] = m_x1 + m_border_width;
+ m_vy[5] = m_y2 - m_border_width;
+ m_vx[6] = m_x2 - m_border_width;
+ m_vy[6] = m_y2 - m_border_width;
+ m_vx[7] = m_x2 - m_border_width;
+ m_vy[7] = m_y1 + m_border_width;
+ break;
+
+ case 2: // Curve
+ calc_curve();
+ m_curve_poly.width(m_curve_width);
+ m_curve_poly.rewind(0);
+ break;
+
+
+ case 3: // Inactive points
+ m_curve_pnt.remove_all();
+ for(i = 0; i < m_num_pnt; i++)
+ {
+ if(int(i) != m_active_pnt)
+ {
+ m_ellipse.init(calc_xp(i), calc_yp(i),
+ m_point_size, m_point_size, 32);
+ m_curve_pnt.concat_path(m_ellipse);
+ }
+ }
+ m_curve_poly.rewind(0);
+ break;
+
+
+ case 4: // Active point
+ m_curve_pnt.remove_all();
+ if(m_active_pnt >= 0)
+ {
+ m_ellipse.init(calc_xp(m_active_pnt), calc_yp(m_active_pnt),
+ m_point_size, m_point_size, 32);
+
+ m_curve_pnt.concat_path(m_ellipse);
+ }
+ m_curve_poly.rewind(0);
+ break;
+
+ }
+ }
+
+
+ //------------------------------------------------------------------------
+ unsigned spline_ctrl_impl::vertex(double* x, double* y)
+ {
+ unsigned cmd = path_cmd_line_to;
+ switch(m_idx)
+ {
+ case 0:
+ if(m_vertex == 0) cmd = path_cmd_move_to;
+ if(m_vertex >= 4) cmd = path_cmd_stop;
+ *x = m_vx[m_vertex];
+ *y = m_vy[m_vertex];
+ m_vertex++;
+ break;
+
+ case 1:
+ if(m_vertex == 0 || m_vertex == 4) cmd = path_cmd_move_to;
+ if(m_vertex >= 8) cmd = path_cmd_stop;
+ *x = m_vx[m_vertex];
+ *y = m_vy[m_vertex];
+ m_vertex++;
+ break;
+
+ case 2:
+ cmd = m_curve_poly.vertex(x, y);
+ break;
+
+ case 3:
+ case 4:
+ cmd = m_curve_pnt.vertex(x, y);
+ break;
+
+ default:
+ cmd = path_cmd_stop;
+ break;
+ }
+
+ if(!is_stop(cmd))
+ {
+ transform_xy(x, y);
+ }
+
+ return cmd;
+ }
+
+
+
+ //------------------------------------------------------------------------
+ void spline_ctrl_impl::active_point(int i)
+ {
+ m_active_pnt = i;
+ }
+
+
+ //------------------------------------------------------------------------
+ bool spline_ctrl_impl::in_rect(double x, double y) const
+ {
+ inverse_transform_xy(&x, &y);
+ return x >= m_x1 && x <= m_x2 && y >= m_y1 && y <= m_y2;
+ }
+
+
+ //------------------------------------------------------------------------
+ bool spline_ctrl_impl::on_mouse_button_down(double x, double y)
+ {
+ inverse_transform_xy(&x, &y);
+ unsigned i;
+ for(i = 0; i < m_num_pnt; i++)
+ {
+ double xp = calc_xp(i);
+ double yp = calc_yp(i);
+ if(calc_distance(x, y, xp, yp) <= m_point_size + 1)
+ {
+ m_pdx = xp - x;
+ m_pdy = yp - y;
+ m_active_pnt = m_move_pnt = int(i);
+ return true;
+ }
+ }
+ return false;
+ }
+
+
+ //------------------------------------------------------------------------
+ bool spline_ctrl_impl::on_mouse_button_up(double, double)
+ {
+ if(m_move_pnt >= 0)
+ {
+ m_move_pnt = -1;
+ return true;
+ }
+ return false;
+ }
+
+
+ //------------------------------------------------------------------------
+ bool spline_ctrl_impl::on_mouse_move(double x, double y, bool button_flag)
+ {
+ inverse_transform_xy(&x, &y);
+ if(!button_flag)
+ {
+ return on_mouse_button_up(x, y);
+ }
+
+ if(m_move_pnt >= 0)
+ {
+ double xp = x + m_pdx;
+ double yp = y + m_pdy;
+
+ set_xp(m_move_pnt, (xp - m_xs1) / (m_xs2 - m_xs1));
+ set_yp(m_move_pnt, (yp - m_ys1) / (m_ys2 - m_ys1));
+
+ update_spline();
+ return true;
+ }
+ return false;
+ }
+
+
+ //------------------------------------------------------------------------
+ bool spline_ctrl_impl::on_arrow_keys(bool left, bool right, bool down, bool up)
+ {
+ double kx = 0.0;
+ double ky = 0.0;
+ bool ret = false;
+ if(m_active_pnt >= 0)
+ {
+ kx = m_xp[m_active_pnt];
+ ky = m_yp[m_active_pnt];
+ if(left) { kx -= 0.001; ret = true; }
+ if(right) { kx += 0.001; ret = true; }
+ if(down) { ky -= 0.001; ret = true; }
+ if(up) { ky += 0.001; ret = true; }
+ }
+ if(ret)
+ {
+ set_xp(m_active_pnt, kx);
+ set_yp(m_active_pnt, ky);
+ update_spline();
+ }
+ return ret;
+ }
+
+
+
+
+}
+