📄 agg_path_storage.cpp.svn-base
字号:
//----------------------------------------------------------------------------// 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//----------------------------------------------------------------------------//// Class path_storage////----------------------------------------------------------------------------#include <string.h>#include <math.h>#include "agg_path_storage.h"#include "agg_math.h"#include "agg_bezier_arc.h"namespace agg{ //------------------------------------------------------------------------ path_storage::~path_storage() { if(m_total_blocks) { double** coord_blk = m_coord_blocks + m_total_blocks - 1; while(m_total_blocks--) { delete [] *coord_blk; --coord_blk; } delete [] m_coord_blocks; } } //------------------------------------------------------------------------ path_storage::path_storage() : m_total_vertices(0), m_total_blocks(0), m_max_blocks(0), m_coord_blocks(0), m_cmd_blocks(0), m_iterator(0) { } //------------------------------------------------------------------------ path_storage::path_storage(const path_storage& ps) : m_total_vertices(0), m_total_blocks(0), m_max_blocks(0), m_coord_blocks(0), m_cmd_blocks(0), m_iterator(0) { copy_from(ps); } //------------------------------------------------------------------------ void path_storage::remove_all() { m_total_vertices = 0; m_iterator = 0; } //------------------------------------------------------------------------ void path_storage::copy_from(const path_storage& ps) { remove_all(); unsigned i; for(i = 0; i < ps.total_vertices(); i++) { double x, y; unsigned cmd = ps.vertex(i, &x, &y); add_vertex(x, y, cmd); } } //------------------------------------------------------------------------ void path_storage::allocate_block(unsigned nb) { if(nb >= m_max_blocks) { double** new_coords = new double* [(m_max_blocks + block_pool) * 2]; unsigned char** new_cmds = (unsigned char**)(new_coords + m_max_blocks + block_pool); if(m_coord_blocks) { memcpy(new_coords, m_coord_blocks, m_max_blocks * sizeof(double*)); memcpy(new_cmds, m_cmd_blocks, m_max_blocks * sizeof(unsigned char*)); delete [] m_coord_blocks; } m_coord_blocks = new_coords; m_cmd_blocks = new_cmds; m_max_blocks += block_pool; } m_coord_blocks[nb] = new double [block_size * 2 + block_size / (sizeof(double) / sizeof(unsigned char))]; m_cmd_blocks[nb] = (unsigned char*)(m_coord_blocks[nb] + block_size * 2); m_total_blocks++; } //------------------------------------------------------------------------ void path_storage::rewind(unsigned path_id) { m_iterator = path_id; } //------------------------------------------------------------------------ void path_storage::arc_to(double rx, double ry, double angle, bool large_arc_flag, bool sweep_flag, double x, double y) { if(m_total_vertices && is_vertex(command(m_total_vertices - 1))) { const double epsilon = 1e-30; double x0 = 0.0; double y0 = 0.0; last_vertex(&x0, &y0); rx = fabs(rx); ry = fabs(ry); // Ensure radii are valid //------------------------- if(rx < epsilon || ry < epsilon) { line_to(x, y); return; } if(calc_distance(x0, y0, x, y) < epsilon) { // If the endpoints (x, y) and (x0, y0) are identical, then this // is equivalent to omitting the elliptical arc segment entirely. return; } bezier_arc_svg a(x0, y0, rx, ry, angle, large_arc_flag, sweep_flag, x, y); if(a.radii_ok()) { add_path(a, 0, true); } else { line_to(x, y); } } else { move_to(x, y); } } //------------------------------------------------------------------------ void path_storage::arc_rel(double rx, double ry, double angle, bool large_arc_flag, bool sweep_flag, double dx, double dy) { rel_to_abs(&dx, &dy); arc_to(rx, ry, angle, large_arc_flag, sweep_flag, dx, dy); } //------------------------------------------------------------------------ void path_storage::curve3(double x_ctrl, double y_ctrl, double x_to, double y_to) { add_vertex(x_ctrl, y_ctrl, path_cmd_curve3); add_vertex(x_to, y_to, path_cmd_curve3); } //------------------------------------------------------------------------ void path_storage::curve3_rel(double dx_ctrl, double dy_ctrl, double dx_to, double dy_to) { rel_to_abs(&dx_ctrl, &dy_ctrl); rel_to_abs(&dx_to, &dy_to); add_vertex(dx_ctrl, dy_ctrl, path_cmd_curve3); add_vertex(dx_to, dy_to, path_cmd_curve3); } //------------------------------------------------------------------------ void path_storage::curve3(double x_to, double y_to) { double x0; double y0; if(is_vertex(last_vertex(&x0, &y0))) { double x_ctrl; double y_ctrl; unsigned cmd = prev_vertex(&x_ctrl, &y_ctrl); if(is_curve(cmd)) { x_ctrl = x0 + x0 - x_ctrl; y_ctrl = y0 + y0 - y_ctrl; } else { x_ctrl = x0; y_ctrl = y0; } curve3(x_ctrl, y_ctrl, x_to, y_to); } } //------------------------------------------------------------------------ void path_storage::curve3_rel(double dx_to, double dy_to) { rel_to_abs(&dx_to, &dy_to); curve3(dx_to, dy_to); } //------------------------------------------------------------------------ void path_storage::curve4(double x_ctrl1, double y_ctrl1, double x_ctrl2, double y_ctrl2, double x_to, double y_to) { add_vertex(x_ctrl1, y_ctrl1, path_cmd_curve4); add_vertex(x_ctrl2, y_ctrl2, path_cmd_curve4); add_vertex(x_to, y_to, path_cmd_curve4); } //------------------------------------------------------------------------ void path_storage::curve4_rel(double dx_ctrl1, double dy_ctrl1, double dx_ctrl2, double dy_ctrl2, double dx_to, double dy_to)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -