updated agg-2.4

This commit is contained in:
Artem Pavlenko 2006-02-04 21:30:08 +00:00
parent 6b42c9fa4c
commit 95d26be572
6 changed files with 79 additions and 146 deletions

View file

@ -193,6 +193,13 @@ namespace agg
poly_subpixel_mask = poly_subpixel_scale-1, //----poly_subpixel_mask
};
//----------------------------------------------------------filling_rule_e
enum filling_rule_e
{
fill_non_zero,
fill_even_odd
};
//-----------------------------------------------------------------------pi
const double pi = 3.14159265358979323846;

View file

@ -38,9 +38,9 @@ namespace agg
{
miter_join = 0,
miter_join_revert = 1,
miter_join_round = 4,
round_join = 2,
bevel_join = 3
bevel_join = 3,
miter_join_round = 4
};
@ -71,14 +71,6 @@ namespace agg
double a2 = atan2(dy2, dx2);
double da = a1 - a2;
// Possible optimization. Not important at all; consumes time but happens rarely
//if(fabs(da) < stroke_theta)
//{
// out_vertices.add(coord_type((x + x + dx1 + dx2) * 0.5,
// (y + y + dy1 + dy2) * 0.5));
// return;
//}
bool ccw = da > 0.0 && da < pi;
if(width < 0) width = -width;
@ -280,6 +272,7 @@ namespace agg
typedef typename VertexConsumer::value_type coord_type;
double dx1, dy1, dx2, dy2;
double d;
dx1 = width * (v1.y - v0.y) / len1;
dy1 = width * (v1.x - v0.x) / len1;
@ -312,7 +305,7 @@ namespace agg
case inner_jag:
case inner_round:
{
double d = (dx1-dx2) * (dx1-dx2) + (dy1-dy2) * (dy1-dy2);
d = (dx1-dx2) * (dx1-dx2) + (dy1-dy2) * (dy1-dy2);
if(d < len1 * len1 && d < len2 * len2)
{
stroke_calc_miter(out_vertices,
@ -349,6 +342,34 @@ namespace agg
{
// Outer join
//---------------
if(line_join == round_join || line_join == bevel_join)
{
// This is an optimization that reduces the number of points
// in cases of almost collonear segments. If there's no
// visible difference between bevel and miter joins we'd rather
// use miter join because it adds only one point instead of two.
//
// Here we calculate the middle point between the bevel points
// and then, the distance between v1 and this middle point.
// At outer joins this distance always less than stroke width,
// because it's actually the height of an isosceles triangle of
// v1 and its two bevel points. If the difference between this
// width and this value is small (no visible bevel) we can switch
// to the miter join.
//
// The constant in the expression makes the result approximately
// the same as in round joins and caps. One can safely comment
// out this "if".
//-------------------
double dx = (dx1 + dx2) / 2;
double dy = (dy1 + dy2) / 2;
d = width - sqrt(dx * dx + dy * dy);
if(d < 0.0625 / approximation_scale)
{
line_join = miter_join;
}
}
switch(line_join)
{
case miter_join:

View file

@ -93,13 +93,16 @@ namespace agg
{
aa_shift = 8,
aa_scale = 1 << aa_shift,
aa_mask = aa_scale - 1
aa_mask = aa_scale - 1,
aa_scale2 = aa_scale * 2,
aa_mask2 = aa_scale2 - 1
};
//--------------------------------------------------------------------
rasterizer_compound_aa() :
m_outline(),
m_clipper(),
m_filling_rule(fill_non_zero),
m_styles(), // Active Styles
m_ast(), // Active Style Table (unique values)
m_asm(), // Active Style Mask
@ -113,6 +116,7 @@ namespace agg
void reset();
void reset_clipping();
void clip_box(double x1, double y1, double x2, double y2);
void filling_rule(filling_rule_e filling_rule);
//--------------------------------------------------------------------
void styles(int left, int right);
@ -161,6 +165,14 @@ namespace agg
{
int cover = area >> (poly_subpixel_shift*2 + 1 - aa_shift);
if(cover < 0) cover = -cover;
if(m_filling_rule == fill_even_odd)
{
cover &= aa_mask2;
if(cover > aa_scale)
{
cover = aa_scale2 - cover;
}
}
if(cover > aa_mask) cover = aa_mask;
return cover;
}
@ -229,6 +241,7 @@ namespace agg
private:
rasterizer_cells_aa<cell_style_aa> m_outline;
clip_type m_clipper;
filling_rule_e m_filling_rule;
pod_vector<style_info> m_styles; // Active Styles
pod_vector<unsigned> m_ast; // Active Style Table (unique values)
pod_vector<int8u> m_asm; // Active Style Mask
@ -258,6 +271,13 @@ namespace agg
m_scan_y = 0x7FFFFFFF;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_compound_aa<Clip>::filling_rule(filling_rule_e filling_rule)
{
m_filling_rule = filling_rule;
}
//------------------------------------------------------------------------
template<class Clip>
void rasterizer_compound_aa<Clip>::clip_box(double x1, double y1,

View file

@ -65,13 +65,6 @@ namespace agg
}
};
//----------------------------------------------------------filling_rule_e
enum filling_rule_e
{
fill_non_zero,
fill_even_odd
};
//==================================================rasterizer_scanline_aa
// Polygon rasterizer that is used to render filled polygons with

View file

@ -32,12 +32,9 @@ namespace agg
m_clip_box(0, 0, 1, 1),
m_x1(0),
m_y1(0),
m_f1(0),
m_x2(0),
m_y2(0),
m_f2(0),
m_num_vertices(0),
m_vertex(0)
m_vertex(0),
m_move_to(false)
{
}
@ -50,7 +47,6 @@ namespace agg
m_clip_box.normalize();
}
double x1() const { return m_clip_box.x1; }
double y1() const { return m_clip_box.y1; }
double x2() const { return m_clip_box.x2; }
@ -64,55 +60,16 @@ namespace agg
void line_to(double x, double y);
unsigned vertex(double* x, double* y);
private:
enum clipping_flags_def
{
clip_x1 = 1,
clip_x2 = 2,
clip_y1 = 4,
clip_y2 = 8
};
// Determine the clipping code of the vertex according to the
// Cyrus-Beck line clipping algorithm
//--------------------------------------------------------------------
unsigned clipping_flags_x(double x)
{
unsigned f = 0;
if(x < m_clip_box.x1) f |= clip_x1;
if(x > m_clip_box.x2) f |= clip_x2;
return f;
}
unsigned clipping_flags_y(double y)
{
unsigned f = 0;
if(y < m_clip_box.y1) f |= clip_y1;
if(y > m_clip_box.y2) f |= clip_y2;
return f;
}
unsigned clipping_flags(double x, double y)
{
return clipping_flags_x(x) | clipping_flags_y(y);
}
bool move_point(double& x, double& y, unsigned& flags);
void clip_line_segment();
private:
rect_d m_clip_box;
double m_x1;
double m_y1;
unsigned m_f1;
double m_x2;
double m_y2;
unsigned m_f2;
double m_x[2];
double m_y[2];
unsigned m_cmd[2];
unsigned m_num_vertices;
unsigned m_vertex;
bool m_move_to;
};
}

View file

@ -13,19 +13,17 @@
// http://www.antigrain.com
//----------------------------------------------------------------------------
#include <math.h>
#include "agg_vpgen_clip_polyline.h"
#include "agg_clip_liang_barsky.h"
namespace agg
{
static double clip_epsilon = 1e-10;
//----------------------------------------------------------------------------
void vpgen_clip_polyline::reset()
{
m_vertex = 0;
m_num_vertices = 0;
m_move_to = false;
}
//----------------------------------------------------------------------------
@ -33,99 +31,38 @@ namespace agg
{
m_vertex = 0;
m_num_vertices = 0;
m_f1 = clipping_flags(x, y);
if(m_f1 == 0)
{
m_x[0] = x;
m_y[0] = y;
m_cmd[0] = path_cmd_move_to;
m_num_vertices = 1;
}
m_x1 = x;
m_y1 = y;
}
//----------------------------------------------------------------------------
bool vpgen_clip_polyline::move_point(double& x, double& y, unsigned& flags)
{
double bound;
if(flags & (clip_x1 | clip_x2))
{
bound = (flags & clip_x1) ? m_clip_box.x1 : m_clip_box.x2;
y = (bound - m_x1) * (m_y2 - m_y1) / (m_x2 - m_x1) + m_y1;
x = bound;
flags = clipping_flags_y(y);
}
if(fabs(m_y2 - m_y1) < clip_epsilon && fabs(m_x2 - m_x1) < clip_epsilon)
{
return false;
}
if(flags & (clip_y1 | clip_y2))
{
bound = (flags & clip_y1) ? m_clip_box.y1 : m_clip_box.y2;
x = (bound - m_y1) * (m_x2 - m_x1) / (m_y2 - m_y1) + m_x1;
y = bound;
}
flags = 0;
return true;
m_move_to = true;
}
//----------------------------------------------------------------------------
void vpgen_clip_polyline::clip_line_segment()
void vpgen_clip_polyline::line_to(double x, double y)
{
if((m_f1 & m_f2) == 0)
double x2 = x;
double y2 = y;
unsigned flags = clip_line_segment(&m_x1, &m_y1, &x2, &y2, m_clip_box);
m_vertex = 0;
m_num_vertices = 0;
if((flags & 4) == 0)
{
if(m_f1)
{
if(!move_point(m_x1, m_y1, m_f1)) return;
if(m_f1) return;
if((flags & 1) != 0 || m_move_to)
{
m_x[0] = m_x1;
m_y[0] = m_y1;
m_cmd[0] = path_cmd_move_to;
m_num_vertices = 1;
}
if(m_f2)
{ // Move Point 2
if(!move_point(m_x2, m_y2, m_f2)) return;
}
m_x[m_num_vertices] = m_x2;
m_y[m_num_vertices] = m_y2;
m_x[m_num_vertices] = x2;
m_y[m_num_vertices] = y2;
m_cmd[m_num_vertices++] = path_cmd_line_to;
m_move_to = (flags & 2) != 0;
}
}
//----------------------------------------------------------------------------
void vpgen_clip_polyline::line_to(double x, double y)
{
m_vertex = 0;
m_num_vertices = 0;
unsigned f = m_f2 = clipping_flags(m_x2 = x, m_y2 = y);
if(m_f2 == m_f1)
{
if(m_f2 == 0)
{
m_x[0] = x;
m_y[0] = y;
m_cmd[0] = path_cmd_line_to;
m_num_vertices = 1;
}
}
else
{
clip_line_segment();
}
m_f1 = f;
m_x1 = x;
m_y1 = y;
}
//----------------------------------------------------------------------------
unsigned vpgen_clip_polyline::vertex(double* x, double* y)
{
@ -137,6 +74,4 @@ namespace agg
}
return path_cmd_stop;
}
}