//---------------------------------------------------------------------------- // Anti-Grain Geometry (AGG) - Version 2.5 // A high quality rendering engine for C++ // Copyright (C) 2002-2006 Maxim Shemanarev // Contact: mcseem@antigrain.com // mcseemagg@yahoo.com // http://antigrain.com // // AGG is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 2 // of the License, or (at your option) any later version. // // AGG is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with AGG; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, // MA 02110-1301, USA. //---------------------------------------------------------------------------- #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); } }