updated agg-2.4
This commit is contained in:
parent
6b42c9fa4c
commit
95d26be572
6 changed files with 79 additions and 146 deletions
|
@ -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;
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -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((flags & 1) != 0 || m_move_to)
|
||||
{
|
||||
if(!move_point(m_x1, m_y1, m_f1)) return;
|
||||
if(m_f1) return;
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue