//---------------------------------------------------------------------------- // Anti-Grain Geometry - Version 2.3 // 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 //---------------------------------------------------------------------------- #include "agg_vpgen_clip_polygon.h" #include "agg_clip_liang_barsky.h" namespace agg { //------------------------------------------------------------------------ // Determine the clipping code of the vertex according to the // Cyrus-Beck line clipping algorithm // // | | // 0110 | 0010 | 0011 // | | // -------+--------+-------- clip_box.y2 // | | // 0100 | 0000 | 0001 // | | // -------+--------+-------- clip_box.y1 // | | // 1100 | 1000 | 1001 // | | // clip_box.x1 clip_box.x2 // // unsigned vpgen_clip_polygon::clipping_flags(double x, double y) { if(x < m_clip_box.x1) { if(y > m_clip_box.y2) return 6; if(y < m_clip_box.y1) return 12; return 4; } if(x > m_clip_box.x2) { if(y > m_clip_box.y2) return 3; if(y < m_clip_box.y1) return 9; return 1; } if(y > m_clip_box.y2) return 2; if(y < m_clip_box.y1) return 8; return 0; } //---------------------------------------------------------------------------- void vpgen_clip_polygon::reset() { m_vertex = 0; m_num_vertices = 0; } //---------------------------------------------------------------------------- void vpgen_clip_polygon::move_to(double x, double y) { m_vertex = 0; m_num_vertices = 0; m_clip_flags = clipping_flags(x, y); if(m_clip_flags == 0) { m_x[0] = x; m_y[0] = y; m_num_vertices = 1; } m_x1 = x; m_y1 = y; m_cmd = path_cmd_move_to; } //---------------------------------------------------------------------------- void vpgen_clip_polygon::line_to(double x, double y) { m_vertex = 0; m_num_vertices = 0; unsigned flags = clipping_flags(x, y); if(m_clip_flags == flags) { if(flags == 0) { m_x[0] = x; m_y[0] = y; m_num_vertices = 1; } } else { m_num_vertices = clip_liang_barsky(m_x1, m_y1, x, y, m_clip_box, m_x, m_y); } m_clip_flags = flags; m_x1 = x; m_y1 = y; } //---------------------------------------------------------------------------- unsigned vpgen_clip_polygon::vertex(double* x, double* y) { if(m_vertex < m_num_vertices) { *x = m_x[m_vertex]; *y = m_y[m_vertex]; ++m_vertex; unsigned cmd = m_cmd; m_cmd = path_cmd_line_to; return cmd; } return path_cmd_stop; } }