1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov 2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//---------------------------------------------------------------------------- 3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Anti-Grain Geometry - Version 2.3 4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) 5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// 6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Permission to copy, use, modify, sell and distribute this software 7ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// is granted provided this copyright notice appears in all copies. 8ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// This software is provided "as is" without express or implied 9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// warranty, and with no claim as to its suitability for any purpose. 10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// 11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//---------------------------------------------------------------------------- 12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Contact: mcseem@antigrain.com 13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// mcseemagg@yahoo.com 14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// http://www.antigrain.com 15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//---------------------------------------------------------------------------- 16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// 17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Line dash generator 18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// 19ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//---------------------------------------------------------------------------- 20ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "agg_shorten_path.h" 22ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann#include "agg_vcgen_dash.h" 234d3acf4ec42bf6e838f9060103aff98fbf170794Philip P. Moltmann#include "core/fxcrt/fx_basic.h" 24ac3d58cff7c80b0ef56bf55130d91da17cbaa3c4Philip P. Moltmann 25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovnamespace agg 26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvcgen_dash::vcgen_dash() : 28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_total_dash_len(0), 29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_num_dashes(0), 30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_dash_start(0), 31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_shorten(0), 32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_curr_dash_start(0), 33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_curr_dash(0), 34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_src_vertices(), 35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_closed(0), 36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_status(initial), 37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_src_vertex(0) 38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid vcgen_dash::remove_all_dashes() 41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_total_dash_len = 0; 43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_num_dashes = 0; 44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_curr_dash_start = 0; 45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_curr_dash = 0; 46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid vcgen_dash::add_dash(FX_FLOAT dash_len, FX_FLOAT gap_len) 48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(m_num_dashes < max_dashes) { 50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_total_dash_len += dash_len + gap_len; 51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_dashes[m_num_dashes++] = dash_len; 52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_dashes[m_num_dashes++] = gap_len; 53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid vcgen_dash::dash_start(FX_FLOAT ds) 56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_dash_start = ds; 58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov calc_dash_start(FXSYS_fabs(ds)); 59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid vcgen_dash::calc_dash_start(FX_FLOAT ds) 61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_curr_dash = 0; 63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_curr_dash_start = 0; 64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while(ds > 0) { 65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(ds > m_dashes[m_curr_dash]) { 66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ds -= m_dashes[m_curr_dash]; 67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ++m_curr_dash; 68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_curr_dash_start = 0; 69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(m_curr_dash >= m_num_dashes) { 70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_curr_dash = 0; 71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_curr_dash_start = ds; 74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ds = 0; 75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid vcgen_dash::remove_all() 79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_status = initial; 81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_src_vertices.remove_all(); 82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_closed = 0; 83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid vcgen_dash::add_vertex(FX_FLOAT x, FX_FLOAT y, unsigned cmd) 85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_status = initial; 87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(is_move_to(cmd)) { 88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_src_vertices.modify_last(vertex_dist(x, y)); 89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(is_vertex(cmd)) { 91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_src_vertices.add(vertex_dist(x, y)); 92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_closed = get_close_flag(cmd); 94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid vcgen_dash::rewind(unsigned) 98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(m_status == initial) { 100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_src_vertices.close(m_closed != 0); 101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov shorten_path(m_src_vertices, m_shorten, m_closed); 102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_status = ready; 104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_src_vertex = 0; 105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovunsigned vcgen_dash::vertex(FX_FLOAT* x, FX_FLOAT* y) 107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{ 108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov unsigned cmd = path_cmd_move_to; 109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov while(!is_stop(cmd)) { 110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov switch(m_status) { 111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case initial: 112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov rewind(0); 113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case ready: 114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(m_num_dashes < 2 || m_src_vertices.size() < 2) { 115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmd = path_cmd_stop; 116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_status = polyline; 119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_src_vertex = 1; 120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_v1 = &m_src_vertices[0]; 121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_v2 = &m_src_vertices[1]; 122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_curr_rest = m_v1->dist; 123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *x = m_v1->x; 124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *y = m_v1->y; 125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(m_dash_start >= 0) { 126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov calc_dash_start(m_dash_start); 127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return path_cmd_move_to; 129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case polyline: { 130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov FX_FLOAT dash_rest = m_dashes[m_curr_dash] - m_curr_dash_start; 131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov unsigned cmd = (m_curr_dash & 1) ? 132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov path_cmd_move_to : 133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov path_cmd_line_to; 134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(m_curr_rest > dash_rest) { 135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_curr_rest -= dash_rest; 136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ++m_curr_dash; 137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(m_curr_dash >= m_num_dashes) { 138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_curr_dash = 0; 139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_curr_dash_start = 0; 141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *x = m_v2->x - (m_v2->x - m_v1->x) * m_curr_rest / m_v1->dist; 142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *y = m_v2->y - (m_v2->y - m_v1->y) * m_curr_rest / m_v1->dist; 143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_curr_dash_start += m_curr_rest; 145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *x = m_v2->x; 146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov *y = m_v2->y; 147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ++m_src_vertex; 148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_v1 = m_v2; 149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_curr_rest = m_v1->dist; 150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(m_closed) { 151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(m_src_vertex > m_src_vertices.size()) { 152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_status = stop; 153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_v2 = &m_src_vertices 155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov [ 156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov (m_src_vertex >= m_src_vertices.size()) ? 0 : 157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_src_vertex 158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov ]; 159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov if(m_src_vertex >= m_src_vertices.size()) { 162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_status = stop; 163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } else { 164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov m_v2 = &m_src_vertices[m_src_vertex]; 165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return cmd; 169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov case stop: 172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov cmd = path_cmd_stop; 173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov break; 174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov } 176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov return path_cmd_stop; 177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov} 179