Sync to AGG tree to support stippi's Painter classes

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@10693 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
DarkWyrm
2005-01-12 11:05:58 +00:00
parent 75d0f2ba9b
commit abd0030237
52 changed files with 2979 additions and 287 deletions
+130 -7
View File
@@ -15,6 +15,7 @@
#ifndef AGG_ARRAY_INCLUDED
#define AGG_ARRAY_INCLUDED
#include <stddef.h>
#include <string.h>
#include "agg_basics.h"
@@ -45,7 +46,10 @@ namespace agg
void add(const T& v) { m_array[m_size++] = v; }
void inc_size(unsigned size) { m_size += size; }
unsigned size() const { return m_size; }
unsigned size() const { return m_size; }
unsigned byte_size() const { return m_size * sizeof(T); }
void serialize(int8u* ptr) const;
void deserialize(const int8u* data, unsigned byte_size);
const T& operator [] (unsigned idx) const { return m_array[idx]; }
T& operator [] (unsigned idx) { return m_array[idx]; }
@@ -116,9 +120,20 @@ namespace agg
return *this;
}
//------------------------------------------------------------------------
template<class T> void pod_array<T>::serialize(int8u* ptr) const
{
if(m_size) memcpy(ptr, m_array, m_size * sizeof(T));
}
//------------------------------------------------------------------------
template<class T>
void pod_array<T>::deserialize(const int8u* data, unsigned byte_size)
{
byte_size /= sizeof(T);
capacity(byte_size);
if(byte_size) memcpy(m_array, data, byte_size * sizeof(T));
}
//------------------------------------------------------------------------
template<class T> class pod_array_adaptor
@@ -154,6 +169,7 @@ namespace agg
//------------------------------------------------------------------------
template<class T, unsigned S=6> class pod_deque
{
public:
enum
{
block_shift = S,
@@ -161,7 +177,6 @@ namespace agg
block_mask = block_size - 1
};
public:
typedef T value_type;
~pod_deque();
@@ -181,6 +196,23 @@ namespace agg
int allocate_continuous_block(unsigned num_elements);
void add_array(const T* ptr, unsigned num_elem)
{
while(num_elem--)
{
add(*ptr++);
}
}
template<class DataAccessor> void add_data(DataAccessor& data)
{
while(data.size())
{
add(*data);
++data;
}
}
void cut_at(unsigned size)
{
if(size < m_size) m_size = size;
@@ -240,6 +272,58 @@ namespace agg
unsigned byte_size() const;
void serialize(int8u* ptr) const;
void deserialize(const int8u* data, unsigned byte_size);
void deserialize(unsigned start, const T& empty_val,
const int8u* data, unsigned byte_size);
template<class ByteAccessor>
void deserialize(ByteAccessor data)
{
remove_all();
unsigned elem_size = data.size() / sizeof(T);
for(unsigned i = 0; i < elem_size; ++i)
{
int8u* ptr = (int8u*)data_ptr();
for(unsigned j = 0; j < sizeof(T); ++j)
{
*ptr++ = *data;
++data;
}
++m_size;
}
}
template<class ByteAccessor>
void deserialize(unsigned start, const T& empty_val, ByteAccessor data)
{
while(m_size < start)
{
add(empty_val);
}
unsigned elem_size = data.size() / sizeof(T);
for(unsigned i = 0; i < elem_size; ++i)
{
int8u* ptr;
if(start + i < m_size)
{
ptr = (int8u*)(&((*this)[start + i]));
}
else
{
ptr = (int8u*)data_ptr();
++m_size;
}
for(unsigned j = 0; j < sizeof(T); ++j)
{
*ptr++ = *data;
++data;
}
}
}
const T* block(unsigned nb) const { return m_blocks[nb]; }
private:
void allocate_block(unsigned nb);
@@ -253,8 +337,6 @@ namespace agg
};
//------------------------------------------------------------------------
template<class T, unsigned S> pod_deque<T, S>::~pod_deque()
{
@@ -461,8 +543,49 @@ namespace agg
}
}
//------------------------------------------------------------------------
template<class T, unsigned S>
void pod_deque<T, S>::deserialize(const int8u* data, unsigned byte_size)
{
remove_all();
byte_size /= sizeof(T);
for(unsigned i = 0; i < byte_size; ++i)
{
T* ptr = data_ptr();
memcpy(ptr, data, sizeof(T));
++m_size;
data += sizeof(T);
}
}
// Replace or add a number of elements starting from "start" position
//------------------------------------------------------------------------
template<class T, unsigned S>
void pod_deque<T, S>::deserialize(unsigned start, const T& empty_val,
const int8u* data, unsigned byte_size)
{
while(m_size < start)
{
add(empty_val);
}
byte_size /= sizeof(T);
for(unsigned i = 0; i < byte_size; ++i)
{
if(start + i < m_size)
{
memcpy(&((*this)[start + i]), data, sizeof(T));
}
else
{
T* ptr = data_ptr();
memcpy(ptr, data, sizeof(T));
++m_size;
}
data += sizeof(T);
}
}
//-----------------------------------------------------------pod_allocator
@@ -520,7 +643,7 @@ namespace agg
int8u* ptr = m_buf_ptr;
if(alignment > 1)
{
unsigned align = (alignment - unsigned(ptr) % alignment) % alignment;
unsigned align = (alignment - unsigned((size_t)ptr) % alignment) % alignment;
size += align;
ptr += align;
if(size <= m_rest)
+2
View File
@@ -39,6 +39,7 @@ namespace agg
class bezier_arc
{
public:
//--------------------------------------------------------------------
bezier_arc() : m_vertex(26) {}
bezier_arc(double x, double y,
double rx, double ry,
@@ -48,6 +49,7 @@ namespace agg
init(x, y, rx, ry, start_angle, sweep_angle);
}
//--------------------------------------------------------------------
void init(double x, double y,
double rx, double ry,
double start_angle,
+10
View File
@@ -35,6 +35,11 @@ namespace agg
double y;
bool first = true;
*x1 = CoordT(1);
*y1 = CoordT(1);
*x2 = CoordT(0);
*y2 = CoordT(0);
for(i = 0; i < num; i++)
{
vs.rewind(gi[start + i]);
@@ -74,6 +79,11 @@ namespace agg
double y;
bool first = true;
*x1 = CoordT(1);
*y1 = CoordT(1);
*x2 = CoordT(0);
*y2 = CoordT(0);
vs.rewind(path_id);
unsigned cmd;
while(!is_stop(cmd = vs.vertex(&x, &y)))
+29
View File
@@ -24,6 +24,35 @@
namespace agg
{
//----------------------------------------------------------clipping_flags
// 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
//
//
template<class T>
inline unsigned clipping_flags(T x, T y, const rect_base<T>& clip_box)
{
return (x > clip_box.x2) |
((y > clip_box.y2) << 1) |
((x < clip_box.x1) << 2) |
((y < clip_box.y1) << 3);
}
//-------------------------------------------------------clip_liang_barsky
template<class T>
inline unsigned clip_liang_barsky(T x1, T y1, T x2, T y2,
+1
View File
@@ -28,6 +28,7 @@ namespace agg
//====================================================================rgba
struct rgba
{
typedef double alpha_type;
enum premul { pre };
double r;
+2 -1
View File
@@ -38,6 +38,7 @@ namespace agg
//==================================================================rgba8
struct rgba8
{
typedef int8u alpha_type;
enum order { rgb, bgr };
enum premul { pre };
@@ -230,7 +231,7 @@ namespace agg
//------------------------------------------------------------------------
inline rgba8 rgba8_pre(unsigned r, unsigned g, unsigned b, unsigned a=1.0)
inline rgba8 rgba8_pre(unsigned r, unsigned g, unsigned b, unsigned a=255)
{
return rgba8(rgba8::pre, r, g, b, a);
}
+45 -6
View File
@@ -51,6 +51,7 @@ namespace agg
double m_start_x;
double m_start_y;
unsigned m_poly_flags;
int m_vertices;
};
@@ -64,6 +65,7 @@ namespace agg
m_start_x = 0;
m_start_y = 0;
m_poly_flags = 0;
m_vertices = 0;
}
@@ -77,26 +79,51 @@ namespace agg
cmd = m_vpgen.vertex(x, y);
if(!is_stop(cmd)) break;
if(m_poly_flags)
if(m_poly_flags && !m_vpgen.auto_unclose())
{
*x = 0.0;
*y = 0.0;
cmd = m_poly_flags;
m_poly_flags = 0;
break;
}
if(m_vertices < 0)
{
if(m_vertices < -1)
{
m_vertices = 0;
return path_cmd_stop;
}
m_vpgen.move_to(m_start_x, m_start_y);
m_vertices = 1;
continue;
}
double tx, ty;
cmd = m_source->vertex(&tx, &ty);
if(is_vertex(cmd))
{
if(is_move_to(cmd))
{
if(m_vpgen.auto_close() && m_vertices > 2)
{
m_vpgen.line_to(m_start_x, m_start_y);
m_poly_flags = path_cmd_end_poly | path_flags_close;
m_start_x = tx;
m_start_y = ty;
m_vertices = -1;
continue;
}
m_vpgen.move_to(tx, ty);
m_start_x = tx;
m_start_y = ty;
m_start_x = tx;
m_start_y = ty;
m_vertices = 1;
}
else
{
m_vpgen.line_to(tx, ty);
++m_vertices;
}
}
else
@@ -104,14 +131,26 @@ namespace agg
if(is_end_poly(cmd))
{
m_poly_flags = cmd;
if(is_closed(cmd))
if(is_closed(cmd) || m_vpgen.auto_close())
{
m_vpgen.line_to(m_start_x, m_start_y);
if(m_vpgen.auto_close()) m_poly_flags |= path_flags_close;
if(m_vertices > 2)
{
m_vpgen.line_to(m_start_x, m_start_y);
}
m_vertices = 0;
}
}
else
{
// The adaptor should be transparent to all unknown commands
// path_cmd_stop
if(m_vpgen.auto_close() && m_vertices > 2)
{
m_vpgen.line_to(m_start_x, m_start_y);
m_poly_flags = path_cmd_end_poly | path_flags_close;
m_vertices = -2;
continue;
}
break;
}
}
+69
View File
@@ -0,0 +1,69 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 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: [email protected]
// [email protected]
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// polyline clipping converter
// There an optimized Liang-Basky algorithm is used.
// The algorithm doesn't optimize the degenerate edges, i.e. it will never
// break a closed polyline into two or more ones, instead, there will be
// degenerate edges coinciding with the respective clipping boundaries.
// This is a sub-optimal solution, because that optimization would require
// extra, rather expensive math while the rasterizer tolerates it quite well,
// without any considerable overhead.
//
//----------------------------------------------------------------------------
#ifndef AGG_CONV_CLIP_polyline_INCLUDED
#define AGG_CONV_CLIP_polyline_INCLUDED
#include "agg_basics.h"
#include "agg_conv_adaptor_vpgen.h"
#include "agg_vpgen_clip_polyline.h"
#include "agg_vertex_iterator.h"
namespace agg
{
//=======================================================conv_clip_polyline
template<class VertexSource>
struct conv_clip_polyline : public conv_adaptor_vpgen<VertexSource, vpgen_clip_polyline>
{
typedef conv_adaptor_vpgen<VertexSource, vpgen_clip_polyline> base_type;
conv_clip_polyline(VertexSource& vs) :
conv_adaptor_vpgen<VertexSource, vpgen_clip_polyline>(vs) {}
void clip_box(double x1, double y1, double x2, double y2)
{
base_type::vpgen().clip_box(x1, y1, x2, y2);
}
double x1() const { return base_type::vpgen().x1(); }
double y1() const { return base_type::vpgen().y1(); }
double x2() const { return base_type::vpgen().x2(); }
double y2() const { return base_type::vpgen().y2(); }
typedef conv_clip_polyline<VertexSource> source_type;
typedef vertex_iterator<source_type> iterator;
iterator begin(unsigned id) { return iterator(*this, id); }
iterator end() { return iterator(path_cmd_stop); }
private:
conv_clip_polyline(const conv_clip_polyline<VertexSource>&);
const conv_clip_polyline<VertexSource>&
operator = (const conv_clip_polyline<VertexSource>&);
};
}
#endif
+8
View File
@@ -37,13 +37,21 @@ namespace agg
{
}
void line_join(line_join_e lj) { base_type::generator().line_join(lj); }
void inner_line_join(line_join_e lj) { base_type::generator().inner_line_join(lj); }
void width(double w) { base_type::generator().width(w); }
void miter_limit(double ml) { base_type::generator().miter_limit(ml); }
void miter_limit_theta(double t) { base_type::generator().miter_limit_theta(t); }
void inner_miter_limit(double ml) { base_type::generator().inner_miter_limit(ml); }
void approximation_scale(double as) { base_type::generator().approximation_scale(as); }
void auto_detect_orientation(bool v) { base_type::generator().auto_detect_orientation(v); }
line_join_e line_join() const { return base_type::generator().line_join(); }
line_join_e inner_line_join() const { return base_type::generator().inner_line_join(); }
double width() const { return base_type::generator().width(); }
double miter_limit() const { return base_type::generator().miter_limit(); }
double inner_miter_limit() const { return base_type::generator().inner_miter_limit(); }
double approximation_scale() const { return base_type::generator().approximation_scale(); }
bool auto_detect_orientation() const { return base_type::generator().auto_detect_orientation(); }
private:
+8 -4
View File
@@ -39,19 +39,23 @@ namespace agg
{
}
void line_cap(vcgen_stroke::line_cap_e lc) { base_type::generator().line_cap(lc); }
void line_join(vcgen_stroke::line_join_e lj) { base_type::generator().line_join(lj); }
void line_cap(line_cap_e lc) { base_type::generator().line_cap(lc); }
void line_join(line_join_e lj) { base_type::generator().line_join(lj); }
void inner_line_join(line_join_e lj) { base_type::generator().inner_line_join(lj); }
vcgen_stroke::line_cap_e line_cap() const { return base_type::generator().line_cap(); }
vcgen_stroke::line_join_e line_join() const { return base_type::generator().line_join(); }
line_cap_e line_cap() const { return base_type::generator().line_cap(); }
line_join_e line_join() const { return base_type::generator().line_join(); }
line_join_e inner_line_join() const { return base_type::generator().inner_line_join(); }
void width(double w) { base_type::generator().width(w); }
void miter_limit(double ml) { base_type::generator().miter_limit(ml); }
void miter_limit_theta(double t) { base_type::generator().miter_limit_theta(t); }
void inner_miter_limit(double ml) { base_type::generator().inner_miter_limit(ml); }
void approximation_scale(double as) { base_type::generator().approximation_scale(as); }
double width() const { return base_type::generator().width(); }
double miter_limit() const { return base_type::generator().miter_limit(); }
double inner_miter_limit() const { return base_type::generator().inner_miter_limit(); }
double approximation_scale() const { return base_type::generator().approximation_scale(); }
void shorten(double s) { base_type::generator().shorten(s); }
+5 -2
View File
@@ -299,12 +299,15 @@ namespace agg
}
//--------------------------------------------------------------------
void init_embedded_adaptors(const glyph_cache* gl, double x, double y)
void init_embedded_adaptors(const glyph_cache* gl,
double x, double y,
double scale=1.0)
{
if(gl)
{
switch(gl->data_type)
{
default: return;
case glyph_data_mono:
m_mono_adaptor.init(gl->data, gl->data_size, x, y);
break;
@@ -314,7 +317,7 @@ namespace agg
break;
case glyph_data_outline:
m_path_adaptor.init(gl->data, gl->data_size, x, y);
m_path_adaptor.init(gl->data, gl->data_size, x, y, scale);
break;
}
}
+1
View File
@@ -30,6 +30,7 @@ namespace agg
//===================================================================gray8
struct gray8
{
typedef int8u alpha_type;
int8u v;
int8u a;
+2 -2
View File
@@ -132,8 +132,8 @@ namespace agg
void rewind(unsigned id)
{
m_trans.rewind(id);
m_polyline.line_join(vcgen_stroke::round_join);
m_polyline.line_cap(vcgen_stroke::round_cap);
m_polyline.line_join(round_join);
m_polyline.line_cap(round_cap);
}
unsigned vertex(double* x, double* y)
+340
View File
@@ -0,0 +1,340 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 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: [email protected]
// [email protected]
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// Stroke math
//
//----------------------------------------------------------------------------
#ifndef AGG_STROKE_MATH_INCLUDED
#define AGG_STROKE_MATH_INCLUDED
#include "agg_math.h"
#include "agg_vertex_sequence.h"
namespace agg
{
//-------------------------------------------------------------line_cap_e
enum line_cap_e
{
butt_cap,
square_cap,
round_cap
};
//------------------------------------------------------------line_join_e
enum line_join_e
{
miter_join,
miter_join_revert,
round_join,
bevel_join
};
// Minimal angle to calculate round joins, less than 0.1 degree.
const double stroke_theta = 0.001; //----stroke_theta
//--------------------------------------------------------stroke_calc_arc
template<class VertexConsumer>
void stroke_calc_arc(VertexConsumer& out_vertices,
double x, double y,
double dx1, double dy1,
double dx2, double dy2,
double width,
double approximation_scale)
{
typedef typename VertexConsumer::value_type coord_type;
// Check if we actually need the arc
//-----------------
double dd = calc_distance(dx1, dy1, dx2, dy2);
if(dd < approximation_scale)
{
out_vertices.add(coord_type(x + dx1, y + dy1));
if(dd > approximation_scale * 0.25)
{
out_vertices.add(coord_type(x + dx2, y + dy2));
}
return;
}
double a1 = atan2(dy1, dx1);
double a2 = atan2(dy2, dx2);
double da = a1 - a2;
//if(fabs(da) < stroke_theta)
//{
// out_vertices.add(coord_type(x + dx1, y + dy1));
// //out_vertices.add(coord_type(x + dx2, y + dy2));
// return;
//}
bool ccw = da > 0.0 && da < pi;
if(width < 0) width = -width;
da = fabs(1.0 / (width * approximation_scale));
if(!ccw)
{
if(a1 > a2) a2 += 2 * pi;
while(a1 < a2)
{
out_vertices.add(coord_type(x + cos(a1) * width, y + sin(a1) * width));
a1 += da;
}
}
else
{
if(a1 < a2) a2 -= 2 * pi;
while(a1 > a2)
{
out_vertices.add(coord_type(x + cos(a1) * width, y + sin(a1) * width));
a1 -= da;
}
}
out_vertices.add(coord_type(x + dx2, y + dy2));
}
//-------------------------------------------------------stroke_calc_miter
template<class VertexConsumer>
void stroke_calc_miter(VertexConsumer& out_vertices,
const vertex_dist& v0,
const vertex_dist& v1,
const vertex_dist& v2,
double dx1, double dy1,
double dx2, double dy2,
double width,
bool revert_flag,
double miter_limit)
{
typedef typename VertexConsumer::value_type coord_type;
double xi = v1.x;
double yi = v1.y;
if(!calc_intersection(v0.x + dx1, v0.y - dy1,
v1.x + dx1, v1.y - dy1,
v1.x + dx2, v1.y - dy2,
v2.x + dx2, v2.y - dy2,
&xi, &yi))
{
// The calculation didn't succeed, most probaly
// the three points lie one straight line
//----------------
if(calc_distance(dx1, -dy1, dx2, -dy2) < width * 0.025)
{
// This case means that the next segment continues
// the previous one (straight line)
//-----------------
out_vertices.add(coord_type(v1.x + dx1, v1.y - dy1));
}
else
{
// This case means that the next segment goes back
//-----------------
if(revert_flag)
{
out_vertices.add(coord_type(v1.x + dx1, v1.y - dy1));
out_vertices.add(coord_type(v1.x + dx2, v1.y - dy2));
}
else
{
// If no miter-revert, calcuate new dx1, dy1, dx2, dy2
out_vertices.add(coord_type(v1.x + dx1 + dy1 * miter_limit,
v1.y - dy1 + dx1 * miter_limit));
out_vertices.add(coord_type(v1.x + dx2 - dy2 * miter_limit,
v1.y - dy2 - dx2 * miter_limit));
}
}
}
else
{
double d1 = calc_distance(v1.x, v1.y, xi, yi);
double lim = width * miter_limit;
if(d1 > lim)
{
// Miter limit exceeded
//------------------------
if(revert_flag)
{
// For the compatibility with SVG, PDF, etc,
// we use a simple bevel join instead of
// "smart" bevel
//-------------------
out_vertices.add(coord_type(v1.x + dx1, v1.y - dy1));
out_vertices.add(coord_type(v1.x + dx2, v1.y - dy2));
}
else
{
// Smart bevel that cuts the miter at the limit point
//-------------------
d1 = lim / d1;
double x1 = v1.x + dx1;
double y1 = v1.y - dy1;
double x2 = v1.x + dx2;
double y2 = v1.y - dy2;
x1 += (xi - x1) * d1;
y1 += (yi - y1) * d1;
x2 += (xi - x2) * d1;
y2 += (yi - y2) * d1;
out_vertices.add(coord_type(x1, y1));
out_vertices.add(coord_type(x2, y2));
}
}
else
{
// Inside the miter limit
//---------------------
out_vertices.add(coord_type(xi, yi));
}
}
}
//--------------------------------------------------------stroke_calc_cap
template<class VertexConsumer>
void stroke_calc_cap(VertexConsumer& out_vertices,
const vertex_dist& v0,
const vertex_dist& v1,
double len,
line_cap_e line_cap,
double width,
double approximation_scale)
{
typedef typename VertexConsumer::value_type coord_type;
out_vertices.remove_all();
double dx1 = width * (v1.y - v0.y) / len;
double dy1 = width * (v1.x - v0.x) / len;
double dx2 = 0;
double dy2 = 0;
if(line_cap == square_cap)
{
dx2 = dy1;
dy2 = dx1;
}
if(line_cap == round_cap)
{
double a1 = atan2(dy1, -dx1);
double a2 = a1 + pi;
double da = fabs(1.0 / (width * approximation_scale));
while(a1 < a2)
{
out_vertices.add(coord_type(v0.x + cos(a1) * width,
v0.y + sin(a1) * width));
a1 += da;
}
out_vertices.add(coord_type(v0.x + dx1, v0.y - dy1));
}
else
{
out_vertices.add(coord_type(v0.x - dx1 - dx2, v0.y + dy1 - dy2));
out_vertices.add(coord_type(v0.x + dx1 - dx2, v0.y - dy1 - dy2));
}
}
//-------------------------------------------------------stroke_calc_join
template<class VertexConsumer>
void stroke_calc_join(VertexConsumer& out_vertices,
const vertex_dist& v0,
const vertex_dist& v1,
const vertex_dist& v2,
double len1,
double len2,
double width,
line_join_e line_join,
line_join_e inner_line_join,
double miter_limit,
double inner_miter_limit,
double approximation_scale)
{
typedef typename VertexConsumer::value_type coord_type;
double dx1, dy1, dx2, dy2;
dx1 = width * (v1.y - v0.y) / len1;
dy1 = width * (v1.x - v0.x) / len1;
dx2 = width * (v2.y - v1.y) / len2;
dy2 = width * (v2.x - v1.x) / len2;
out_vertices.remove_all();
if(calc_point_location(v0.x, v0.y, v1.x, v1.y, v2.x, v2.y) > 0.0)
{
// Inner join
//---------------
stroke_calc_miter(out_vertices,
v0, v1, v2, dx1, dy1, dx2, dy2,
width,
inner_line_join == miter_join_revert,
inner_miter_limit);
}
else
{
// Outer join
//---------------
switch(line_join)
{
case miter_join:
stroke_calc_miter(out_vertices,
v0, v1, v2, dx1, dy1, dx2, dy2,
width,
false,
miter_limit);
break;
case miter_join_revert:
stroke_calc_miter(out_vertices,
v0, v1, v2, dx1, dy1, dx2, dy2,
width,
true,
miter_limit);
break;
case round_join:
stroke_calc_arc(out_vertices,
v1.x, v1.y, dx1, -dy1, dx2, -dy2,
width, approximation_scale);
break;
default: // Bevel join
out_vertices.add(coord_type(v1.x + dx1, v1.y - dy1));
if(calc_distance(dx1, dy1, dx2, dy2) > approximation_scale * 0.25)
{
out_vertices.add(coord_type(v1.x + dx2, v1.y - dy2));
}
break;
}
}
}
}
#endif
-5
View File
@@ -166,11 +166,6 @@ namespace agg
bool solid_path = false,
unsigned end_flags = path_flags_none);
void add_vertices(const double* vertices, unsigned num)
{
add_poly(vertices, num, path_flags_none);
}
template<class VertexSource>
void add_path(VertexSource& vs,
unsigned path_id = 0,
+27 -20
View File
@@ -45,10 +45,12 @@ namespace agg
x(((x_ << 1) & ~1) | (flag & 1)),
y(((y_ << 1) & ~1) | (flag >> 1)) {}
unsigned vertex(double* x_, double* y_, double dx=0, double dy=0) const
unsigned vertex(double* x_, double* y_,
double dx=0, double dy=0,
double scale=1.0) const
{
*x_ = dx + (double(x >> 1) / coord_mult);
*y_ = dy + (double(y >> 1) / coord_mult);
*x_ = dx + (double(x >> 1) / coord_mult) * scale;
*y_ = dy + (double(y >> 1) / coord_mult) * scale;
switch(((y & 1) << 1) | (x & 1))
{
case cmd_move_to: return path_cmd_move_to;
@@ -171,7 +173,7 @@ namespace agg
rect_d bounds(1e100, 1e100, -1e100, -1e100);
if(m_storage.size() == 0)
{
bounds.x1 = bounds.x1 = bounds.x2 = bounds.y2 = 0.0;
bounds.x1 = bounds.y1 = bounds.x2 = bounds.y2 = 0.0;
}
else
{
@@ -212,7 +214,8 @@ namespace agg
m_ptr(0),
m_dx(0.0),
m_dy(0.0),
m_closed(true)
m_scale(1.0),
m_vertices(0)
{}
//--------------------------------------------------------------------
@@ -223,26 +226,28 @@ namespace agg
m_ptr(data),
m_dx(dx),
m_dy(dy),
m_closed(true)
m_vertices(0)
{}
//--------------------------------------------------------------------
void init(const int8u* data, unsigned size, double dx, double dy)
void init(const int8u* data, unsigned size,
double dx, double dy, double scale=1.0)
{
m_data = data;
m_end = data + size;
m_ptr = data;
m_dx = dx;
m_dy = dy;
m_closed = true;
m_data = data;
m_end = data + size;
m_ptr = data;
m_dx = dx;
m_dy = dy;
m_scale = scale;
m_vertices = 0;
}
//--------------------------------------------------------------------
void rewind(unsigned)
{
m_ptr = m_data;
m_closed = true;
m_ptr = m_data;
m_vertices = 0;
}
//--------------------------------------------------------------------
@@ -254,6 +259,7 @@ namespace agg
*y = 0;
return path_cmd_stop;
}
if(m_ptr == m_end)
{
*x = 0;
@@ -264,15 +270,15 @@ namespace agg
vertex_integer_type v;
memcpy(&v, m_ptr, sizeof(vertex_integer_type));
unsigned cmd = v.vertex(x, y, m_dx, m_dy);
if(is_move_to(cmd) && !m_closed)
unsigned cmd = v.vertex(x, y, m_dx, m_dy, m_scale);
if(is_move_to(cmd) && m_vertices > 2)
{
*x = 0;
*y = 0;
m_closed = true;
m_vertices = 0;
return path_cmd_end_poly | path_flags_close;
}
m_closed = false;
++m_vertices;
m_ptr += sizeof(vertex_integer_type);
return cmd;
}
@@ -283,7 +289,8 @@ namespace agg
const int8u* m_ptr;
double m_dx;
double m_dy;
bool m_closed;
double m_scale;
unsigned m_vertices;
};
}
+429
View File
@@ -0,0 +1,429 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 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: [email protected]
// [email protected]
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_PIXFMT_CRB_RGBA32_INCLUDED
#define AGG_PIXFMT_CRB_RGBA32_INCLUDED
#include <string.h>
#include "agg_basics.h"
#include "agg_color_rgba8.h"
namespace agg
{
//================================================pixel_formats_crb_rgba32
template<class RenBuf, class Order> class pixel_formats_crb_rgba32
{
public:
typedef rgba8 color_type;
typedef RenBuf buffer_type;
typedef Order order_type;
typedef typename RenBuf::row_data row_data;
//--------------------------------------------------------------------
pixel_formats_crb_rgba32(RenBuf& rb) : m_rbuf(&rb) {}
//--------------------------------------------------------------------
unsigned width() const { return m_rbuf->width(); }
unsigned height() const { return m_rbuf->height(); }
//--------------------------------------------------------------------
color_type pixel(int x, int y) const
{
const int8u* p = m_rbuf->span_ptr(x, y, 1);
return p ? color_type(p[Order::R], p[Order::G], p[Order::B], p[Order::A]) :
color_type::no_color();
}
//--------------------------------------------------------------------
row_data span(int x, int y) const
{
return m_rbuf->span(x, y);
}
//--------------------------------------------------------------------
void copy_pixel(int x, int y, const color_type& c)
{
int8u* p = m_rbuf->span_ptr(x, y, 1);
p[Order::R] = (int8u)c.r;
p[Order::G] = (int8u)c.g;
p[Order::B] = (int8u)c.b;
p[Order::A] = (int8u)c.a;
}
//--------------------------------------------------------------------
void blend_pixel(int x, int y, const color_type& c, int8u cover)
{
int8u* p = m_rbuf->span_ptr(x, y, 1);
int alpha = int(cover) * int(c.a);
if(alpha == 255*255)
{
p[Order::R] = (int8u)c.r;
p[Order::G] = (int8u)c.g;
p[Order::B] = (int8u)c.b;
p[Order::A] = (int8u)c.a;
}
else
{
int r = p[Order::R];
int g = p[Order::G];
int b = p[Order::B];
int a = p[Order::A];
p[Order::R] = (int8u)((((c.r - r) * alpha) + (r << 16)) >> 16);
p[Order::G] = (int8u)((((c.g - g) * alpha) + (g << 16)) >> 16);
p[Order::B] = (int8u)((((c.b - b) * alpha) + (b << 16)) >> 16);
p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8);
}
}
//--------------------------------------------------------------------
void copy_hline(int x, int y, unsigned len, const color_type& c)
{
int32u v;
int8u* p8 = (int8u*)&v;
p8[Order::R] = (int8u)c.r;
p8[Order::G] = (int8u)c.g;
p8[Order::B] = (int8u)c.b;
p8[Order::A] = (int8u)c.a;
int32u* p32 = (int32u*)(m_rbuf->span_ptr(x, y, len));
do
{
*p32++ = v;
}
while(--len);
}
//--------------------------------------------------------------------
void copy_vline(int x, int y, unsigned len, const color_type& c)
{
int32u v;
int8u* p8 = (int8u*)&v;
p8[Order::R] = (int8u)c.r;
p8[Order::G] = (int8u)c.g;
p8[Order::B] = (int8u)c.b;
p8[Order::A] = (int8u)c.a;
do
{
*(int32u*)(m_rbuf->span_ptr(x, y, 1)) = v;
++y;
}
while(--len);
}
//--------------------------------------------------------------------
void blend_hline(int x, int y, unsigned len,
const color_type& c, int8u cover)
{
int alpha = int(cover) * int(c.a);
if(alpha == 255*255)
{
int32u v;
int8u* p8 = (int8u*)&v;
p8[Order::R] = (int8u)c.r;
p8[Order::G] = (int8u)c.g;
p8[Order::B] = (int8u)c.b;
p8[Order::A] = (int8u)c.a;
int32u* p32 = (int32u*)(m_rbuf->span_ptr(x, y, len));
do
{
*p32++ = v;
}
while(--len);
}
else
{
int8u* p = m_rbuf->span_ptr(x, y, len);
do
{
int r = p[Order::R];
int g = p[Order::G];
int b = p[Order::B];
int a = p[Order::A];
p[Order::R] = (int8u)((((c.r - r) * alpha) + (r << 16)) >> 16);
p[Order::G] = (int8u)((((c.g - g) * alpha) + (g << 16)) >> 16);
p[Order::B] = (int8u)((((c.b - b) * alpha) + (b << 16)) >> 16);
p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8);
p += 4;
}
while(--len);
}
}
//--------------------------------------------------------------------
void blend_vline(int x, int y, unsigned len,
const color_type& c, int8u cover)
{
int alpha = int(cover) * c.a;
if(alpha == 255*255)
{
int32u v;
int8u* p8 = (int8u*)&v;
p8[Order::R] = (int8u)c.r;
p8[Order::G] = (int8u)c.g;
p8[Order::B] = (int8u)c.b;
p8[Order::A] = (int8u)c.a;
do
{
*(int32u*)(m_rbuf->span_ptr(x, y, 1)) = v;
++y;
}
while(--len);
}
else
{
do
{
int8u* p = m_rbuf->span_ptr(x, y, 1);
int r = p[Order::R];
int g = p[Order::G];
int b = p[Order::B];
int a = p[Order::A];
p[Order::R] = (int8u)((((c.r - r) * alpha) + (r << 16)) >> 16);
p[Order::G] = (int8u)((((c.g - g) * alpha) + (g << 16)) >> 16);
p[Order::B] = (int8u)((((c.b - b) * alpha) + (b << 16)) >> 16);
p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8);
++y;
}
while(--len);
}
}
//--------------------------------------------------------------------
template<class RenBuf2> void copy_from(const RenBuf2& from,
int xdst, int ydst,
int xsrc, int ysrc,
unsigned len)
{
const int8u* p = from.row(ysrc);
if(p)
{
p += xsrc << 2;
memmove(m_rbuf->span_ptr(xdst, ydst, len), p, len * 4);
}
}
//--------------------------------------------------------------------
template<class SrcPixelFormatRenderer>
void blend_from(const SrcPixelFormatRenderer& from,
const int8u* psrc,
int xdst, int ydst,
int xsrc, int ysrc,
unsigned len)
{
typedef typename SrcPixelFormatRenderer::order_type src_order;
int8u* pdst = m_rbuf->span_ptr(xdst, ydst, len);
int incp = 4;
if(xdst > xsrc)
{
psrc += (len-1) << 2;
pdst += (len-1) << 2;
incp = -4;
}
do
{
int alpha = psrc[src_order::A];
if(alpha)
{
if(alpha == 255)
{
pdst[Order::R] = psrc[src_order::R];
pdst[Order::G] = psrc[src_order::G];
pdst[Order::B] = psrc[src_order::B];
pdst[Order::A] = psrc[src_order::A];
}
else
{
int r = pdst[Order::R];
int g = pdst[Order::G];
int b = pdst[Order::B];
int a = pdst[Order::A];
pdst[Order::R] = (int8u)((((psrc[src_order::R] - r) * alpha) + (r << 8)) >> 8);
pdst[Order::G] = (int8u)((((psrc[src_order::G] - g) * alpha) + (g << 8)) >> 8);
pdst[Order::B] = (int8u)((((psrc[src_order::B] - b) * alpha) + (b << 8)) >> 8);
pdst[Order::A] = (int8u)((alpha + a) - ((alpha * a) >> 8));
}
}
psrc += incp;
pdst += incp;
}
while(--len);
}
//--------------------------------------------------------------------
void blend_solid_hspan(int x, int y, unsigned len,
const color_type& c, const int8u* covers)
{
int8u* p = m_rbuf->span_ptr(x, y, len);
do
{
int alpha = int(*covers++) * c.a;
if(alpha)
{
if(alpha == 255*255)
{
p[Order::R] = (int8u)c.r;
p[Order::G] = (int8u)c.g;
p[Order::B] = (int8u)c.b;
p[Order::A] = (int8u)c.a;
}
else
{
int r = p[Order::R];
int g = p[Order::G];
int b = p[Order::B];
int a = p[Order::A];
p[Order::R] = (int8u)((((c.r - r) * alpha) + (r << 16)) >> 16);
p[Order::G] = (int8u)((((c.g - g) * alpha) + (g << 16)) >> 16);
p[Order::B] = (int8u)((((c.b - b) * alpha) + (b << 16)) >> 16);
p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8);
}
}
p += 4;
}
while(--len);
}
//--------------------------------------------------------------------
void blend_solid_vspan(int x, int y, unsigned len,
const color_type& c, const int8u* covers)
{
do
{
int8u* p = m_rbuf->span_ptr(x, y, 1);
int alpha = int(*covers++) * c.a;
if(alpha)
{
if(alpha == 255*255)
{
p[Order::R] = (int8u)c.r;
p[Order::G] = (int8u)c.g;
p[Order::B] = (int8u)c.b;
p[Order::A] = (int8u)c.a;
}
else
{
int r = p[Order::R];
int g = p[Order::G];
int b = p[Order::B];
int a = p[Order::A];
p[Order::R] = (int8u)((((c.r - r) * alpha) + (r << 16)) >> 16);
p[Order::G] = (int8u)((((c.g - g) * alpha) + (g << 16)) >> 16);
p[Order::B] = (int8u)((((c.b - b) * alpha) + (b << 16)) >> 16);
p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8);
}
}
++y;
}
while(--len);
}
//--------------------------------------------------------------------
void blend_color_hspan(int x, int y, unsigned len,
const color_type* colors,
const int8u* covers,
int8u cover)
{
int8u* p = m_rbuf->span_ptr(x, y, len);
do
{
int alpha = colors->a * (covers ? int(*covers++) : int(cover));
if(alpha)
{
if(alpha == 255*255)
{
p[Order::R] = (int8u)colors->r;
p[Order::G] = (int8u)colors->g;
p[Order::B] = (int8u)colors->b;
p[Order::A] = (int8u)colors->a;
}
else
{
int r = p[Order::R];
int g = p[Order::G];
int b = p[Order::B];
int a = p[Order::A];
p[Order::R] = (int8u)((((colors->r - r) * alpha) + (r << 16)) >> 16);
p[Order::G] = (int8u)((((colors->g - g) * alpha) + (g << 16)) >> 16);
p[Order::B] = (int8u)((((colors->b - b) * alpha) + (b << 16)) >> 16);
p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8);
}
}
p += 4;
++colors;
}
while(--len);
}
//--------------------------------------------------------------------
void blend_color_vspan(int x, int y, unsigned len,
const color_type* colors,
const int8u* covers,
int8u cover)
{
do
{
int8u* p = m_rbuf->span_ptr(x, y, 1);
int alpha = colors->a * (covers ? int(*covers++) : int(cover));
if(alpha)
{
if(alpha == 255*255)
{
p[Order::R] = (int8u)colors->r;
p[Order::G] = (int8u)colors->g;
p[Order::B] = (int8u)colors->b;
p[Order::A] = (int8u)colors->a;
}
else
{
int r = p[Order::R];
int g = p[Order::G];
int b = p[Order::B];
int a = p[Order::A];
p[Order::R] = (int8u)((((colors->r - r) * alpha) + (r << 16)) >> 16);
p[Order::G] = (int8u)((((colors->g - g) * alpha) + (g << 16)) >> 16);
p[Order::B] = (int8u)((((colors->b - b) * alpha) + (b << 16)) >> 16);
p[Order::A] = (int8u)(((alpha + (a << 8)) - ((alpha * a) >> 8)) >> 8);
}
}
++y;
++colors;
}
while(--len);
}
private:
RenBuf* m_rbuf;
};
}
#endif
@@ -0,0 +1,345 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 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: [email protected]
// [email protected]
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_PIXFMT_CRB_RGBA32_PRE_INCLUDED
#define AGG_PIXFMT_CRB_RGBA32_PRE_INCLUDED
#include <string.h>
#include "agg_basics.h"
#include "agg_color_rgba8.h"
namespace agg
{
//============================================pixel_formats_crb_rgba32_pre
template<class RenBuf, class Order> class pixel_formats_crb_rgba32_pre
{
public:
typedef rgba8 color_type;
typedef RenBuf buffer_type;
typedef Order order_type;
typedef typename RenBuf::row_data row_data;
private:
//--------------------------------------------------------------------
static inline void copy_pix(int8u* p, const color_type& c)
{
p[Order::R] = (int8u)c.r;
p[Order::G] = (int8u)c.g;
p[Order::B] = (int8u)c.b;
p[Order::A] = (int8u)c.a;
}
//--------------------------------------------------------------------
static inline void blend_pix(int8u* p, const color_type& c,
unsigned cover, unsigned alpha)
{
p[Order::R] = (int8u)((p[Order::R] * alpha + ((c.r * cover) << 8)) >> 16);
p[Order::G] = (int8u)((p[Order::G] * alpha + ((c.g * cover) << 8)) >> 16);
p[Order::B] = (int8u)((p[Order::B] * alpha + ((c.b * cover) << 8)) >> 16);
p[Order::A] = (int8u)(255 - ((alpha * (255 - p[Order::A])) >> 16));
}
//--------------------------------------------------------------------
static inline void copy_or_blend_pix(int8u* p, const color_type& c, unsigned cover)
{
unsigned alpha = 65535 - cover * c.a;
if(alpha < 65535)
{
if(alpha <= 65535-255*255)
{
copy_pix(p, c);
}
else
{
blend_pix(p, c, cover, alpha);
}
}
}
//--------------------------------------------------------------------
static inline void copy_or_blend_pix(int8u* p, const color_type& c)
{
unsigned alpha = 255 - c.a;
if(alpha < 255)
{
if(alpha == 0)
{
copy_pix(p, c);
}
else
{
p[Order::R] = (int8u)((p[Order::R] * alpha + (c.r << 8)) >> 8);
p[Order::G] = (int8u)((p[Order::G] * alpha + (c.g << 8)) >> 8);
p[Order::B] = (int8u)((p[Order::B] * alpha + (c.b << 8)) >> 8);
p[Order::A] = (int8u)(255 - ((alpha * (255 - p[Order::A])) >> 8));
}
}
}
public:
//--------------------------------------------------------------------
pixel_formats_crb_rgba32_pre(RenBuf& rb) : m_rbuf(&rb) {}
//--------------------------------------------------------------------
unsigned width() const { return m_rbuf->width(); }
unsigned height() const { return m_rbuf->height(); }
//--------------------------------------------------------------------
color_type pixel(int x, int y) const
{
const int8u* p = m_rbuf->span_ptr(x, y, 1);
return p ? color_type(p[Order::R], p[Order::G], p[Order::B], p[Order::A]) :
color_type::no_color();
}
//--------------------------------------------------------------------
row_data span(int x, int y) const
{
return m_rbuf->span(x, y);
}
//--------------------------------------------------------------------
void copy_pixel(int x, int y, const color_type& c)
{
int8u* p = m_rbuf->span_ptr(x, y, 1);
p[Order::R] = (int8u)c.r;
p[Order::G] = (int8u)c.g;
p[Order::B] = (int8u)c.b;
p[Order::A] = (int8u)c.a;
}
//--------------------------------------------------------------------
void blend_pixel(int x, int y, const color_type& c, int8u cover)
{
copy_or_blend_pix(m_rbuf->span_ptr(x, y, 1), c, cover);
}
//--------------------------------------------------------------------
void copy_hline(int x, int y, unsigned len, const color_type& c)
{
int32u v;
copy_pix((int8u*)&v, c);
int32u* p32 = (int32u*)(m_rbuf->span_ptr(x, y, len));
do
{
*p32++ = v;
}
while(--len);
}
//--------------------------------------------------------------------
void copy_vline(int x, int y, unsigned len, const color_type& c)
{
int32u v;
copy_pix((int8u*)&v, c);
do
{
*(int32u*)(m_rbuf->span_ptr(x, y, 1)) = v;
++y;
}
while(--len);
}
//--------------------------------------------------------------------
void blend_hline(int x, int y, unsigned len,
const color_type& c, int8u cover)
{
int alpha = int(cover) * int(c.a);
if(alpha == 255*255)
{
int32u v;
copy_pix((int8u*)&v, c);
int32u* p32 = (int32u*)(m_rbuf->span_ptr(x, y, len));
do
{
*p32++ = v;
}
while(--len);
}
else
{
int8u* p = m_rbuf->span_ptr(x, y, len);
alpha = 65535 - alpha;
do
{
blend_pix(p, c, cover, alpha);
p += 4;
}
while(--len);
}
}
//--------------------------------------------------------------------
void blend_vline(int x, int y, unsigned len,
const color_type& c, int8u cover)
{
int alpha = int(cover) * c.a;
if(alpha == 255*255)
{
int32u v;
copy_pix((int8u*)&v, c);
do
{
*(int32u*)(m_rbuf->span_ptr(x, y, 1)) = v;
++y;
}
while(--len);
}
else
{
alpha = 65535 - alpha;
do
{
blend_pix(m_rbuf->span_ptr(x, y, 1), c, cover, alpha);
++y;
}
while(--len);
}
}
//--------------------------------------------------------------------
template<class RenBuf2> void copy_from(const RenBuf2& from,
int xdst, int ydst,
int xsrc, int ysrc,
unsigned len)
{
const int8u* p = from.row(ysrc);
if(p)
{
p += xsrc << 2;
memmove(m_rbuf->span_ptr(xdst, ydst, len), p, len * 4);
}
}
//--------------------------------------------------------------------
template<class SrcPixelFormatRenderer>
void blend_from(const SrcPixelFormatRenderer& from,
const int8u* psrc,
int xdst, int ydst,
int xsrc, int ysrc,
unsigned len)
{
typedef typename SrcPixelFormatRenderer::order_type src_order;
int8u* pdst = m_rbuf->span_ptr(xdst, ydst, len);
int incp = 4;
if(xdst > xsrc)
{
psrc += (len-1) << 2;
pdst += (len-1) << 2;
incp = -4;
}
do
{
unsigned alpha = 255 - psrc[src_order::A];
if(alpha < 255)
{
if(alpha == 0)
{
pdst[Order::R] = psrc[src_order::R];
pdst[Order::G] = psrc[src_order::G];
pdst[Order::B] = psrc[src_order::B];
pdst[Order::A] = psrc[src_order::A];
}
else
{
pdst[Order::R] = (int8u)((pdst[Order::R] * alpha + (psrc[src_order::R] << 8)) >> 8);
pdst[Order::G] = (int8u)((pdst[Order::G] * alpha + (psrc[src_order::G] << 8)) >> 8);
pdst[Order::B] = (int8u)((pdst[Order::B] * alpha + (psrc[src_order::B] << 8)) >> 8);
pdst[Order::A] = (int8u)(255 - ((alpha * (255 - pdst[Order::A])) >> 8));
}
}
psrc += incp;
pdst += incp;
}
while(--len);
}
//--------------------------------------------------------------------
void blend_solid_hspan(int x, int y, unsigned len,
const color_type& c, const int8u* covers)
{
int8u* p = m_rbuf->span_ptr(x, y, len);
do
{
copy_or_blend_pix(p, c, *covers++);
p += 4;
}
while(--len);
}
//--------------------------------------------------------------------
void blend_solid_vspan(int x, int y, unsigned len,
const color_type& c, const int8u* covers)
{
do
{
copy_or_blend_pix(m_rbuf->span_ptr(x, y, 1), c, *covers++);
++y;
}
while(--len);
}
//--------------------------------------------------------------------
void blend_color_hspan(int x, int y, unsigned len,
const color_type* colors,
const int8u* covers,
int8u cover)
{
int8u* p = m_rbuf->span_ptr(x, y, len);
do
{
copy_or_blend_pix(p, *colors++, covers ? *covers++ : cover);
p += 4;
}
while(--len);
}
//--------------------------------------------------------------------
void blend_color_vspan(int x, int y, unsigned len,
const color_type* colors,
const int8u* covers,
int8u cover)
{
do
{
copy_or_blend_pix(m_rbuf->span_ptr(x, y, 1),
*colors++,
covers ? *covers++ : cover);
++y;
}
while(--len);
}
private:
RenBuf* m_rbuf;
};
}
#endif
+10 -1
View File
@@ -30,6 +30,9 @@ namespace agg
{
public:
typedef gray8 color_type;
typedef bool order_type;
typedef rendering_buffer::row_data row_data;
//--------------------------------------------------------------------
pixfmt_gray8_base(rendering_buffer& rb)
@@ -42,11 +45,17 @@ namespace agg
unsigned height() const { return m_rbuf->height(); }
//--------------------------------------------------------------------
color_type pixel(int x, int y)
color_type pixel(int x, int y) const
{
return color_type(m_rbuf->row(y)[x * Step + Offset]);
}
//--------------------------------------------------------------------
row_data span(int x, int y) const
{
return row_data(x, width() - 1, m_rbuf->row(y) + x);
}
//--------------------------------------------------------------------
void copy_pixel(int x, int y, const color_type& c)
{
+9 -1
View File
@@ -29,6 +29,8 @@ namespace agg
{
public:
typedef rgba8 color_type;
typedef Order order_type;
typedef rendering_buffer::row_data row_data;
//--------------------------------------------------------------------
pixel_formats_rgb24(rendering_buffer& rb)
@@ -41,12 +43,18 @@ namespace agg
unsigned height() const { return m_rbuf->height(); }
//--------------------------------------------------------------------
color_type pixel(int x, int y)
color_type pixel(int x, int y) const
{
int8u* p = m_rbuf->row(y) + x + x + x;
return color_type(p[Order::R], p[Order::G], p[Order::B]);
}
//--------------------------------------------------------------------
row_data span(int x, int y) const
{
return row_data(x, width() - 1, m_rbuf->row(y) + x * 3);
}
//--------------------------------------------------------------------
void copy_pixel(int x, int y, const color_type& c)
{
+9 -1
View File
@@ -32,6 +32,8 @@ namespace agg
public:
typedef rgba8 color_type;
typedef Gamma gamma_type;
typedef Order order_type;
typedef rendering_buffer::row_data row_data;
private:
//--------------------------------------------------------------------
@@ -105,12 +107,18 @@ namespace agg
unsigned height() const { return m_rbuf->height(); }
//--------------------------------------------------------------------
color_type pixel(int x, int y)
color_type pixel(int x, int y) const
{
int8u* p = m_rbuf->row(y) + x + x + x;
return color_type(p[Order::R], p[Order::G], p[Order::B]);
}
//--------------------------------------------------------------------
row_data span(int x, int y) const
{
return row_data(x, width() - 1, m_rbuf->row(y) + x * 3);
}
//--------------------------------------------------------------------
void copy_pixel(int x, int y, const color_type& c)
{
+9 -2
View File
@@ -30,7 +30,8 @@ namespace agg
{
public:
typedef rgba8 color_type;
typedef Order order_type;
typedef rendering_buffer::row_data row_data;
private:
//--------------------------------------------------------------------
@@ -101,12 +102,18 @@ namespace agg
unsigned height() const { return m_rbuf->height(); }
//--------------------------------------------------------------------
color_type pixel(int x, int y)
color_type pixel(int x, int y) const
{
int8u* p = m_rbuf->row(y) + x + x + x;
return color_type(p[Order::R], p[Order::G], p[Order::B]);
}
//--------------------------------------------------------------------
row_data span(int x, int y) const
{
return row_data(x, width() - 1, m_rbuf->row(y) + x * 3);
}
//--------------------------------------------------------------------
void copy_pixel(int x, int y, const color_type& c)
{
+9 -1
View File
@@ -36,6 +36,8 @@ namespace agg
{
public:
typedef rgba8 color_type;
typedef bool order_type;
typedef rendering_buffer::row_data row_data;
//--------------------------------------------------------------------
pixfmt_rgb555(rendering_buffer& rb)
@@ -48,7 +50,7 @@ namespace agg
unsigned height() const { return m_rbuf->height(); }
//--------------------------------------------------------------------
color_type pixel(int x, int y)
color_type pixel(int x, int y) const
{
unsigned rgb = ((int16u*)(m_rbuf->row(y)))[x];
return color_type((rgb >> 7) & 0xF8,
@@ -56,6 +58,12 @@ namespace agg
(rgb << 3) & 0xF8);
}
//--------------------------------------------------------------------
row_data span(int x, int y) const
{
return row_data(x, width() - 1, m_rbuf->row(y) + x * 2);
}
//--------------------------------------------------------------------
void copy_pixel(int x, int y, const color_type& c)
{
+9 -1
View File
@@ -36,6 +36,8 @@ namespace agg
{
public:
typedef rgba8 color_type;
typedef bool order_type;
typedef rendering_buffer::row_data row_data;
//--------------------------------------------------------------------
pixfmt_rgb565(rendering_buffer& rb)
@@ -48,7 +50,7 @@ namespace agg
unsigned height() const { return m_rbuf->height(); }
//--------------------------------------------------------------------
color_type pixel(int x, int y)
color_type pixel(int x, int y) const
{
unsigned rgb = ((int16u*)(m_rbuf->row(y)))[x];
return color_type((rgb >> 8) & 0xF8,
@@ -56,6 +58,12 @@ namespace agg
(rgb << 3) & 0xF8);
}
//--------------------------------------------------------------------
row_data span(int x, int y) const
{
return row_data(x, width() - 1, m_rbuf->row(y) + x * 2);
}
//--------------------------------------------------------------------
void copy_pixel(int x, int y, const color_type& c)
{
+62 -1
View File
@@ -29,6 +29,8 @@ namespace agg
{
public:
typedef rgba8 color_type;
typedef Order order_type;
typedef rendering_buffer::row_data row_data;
//--------------------------------------------------------------------
pixel_formats_rgba32(rendering_buffer& rb)
@@ -41,12 +43,18 @@ namespace agg
unsigned height() const { return m_rbuf->height(); }
//--------------------------------------------------------------------
color_type pixel(int x, int y)
color_type pixel(int x, int y) const
{
int8u* p = m_rbuf->row(y) + (x << 2);
return color_type(p[Order::R], p[Order::G], p[Order::B], p[Order::A]);
}
//--------------------------------------------------------------------
row_data span(int x, int y) const
{
return row_data(x, width() - 1, m_rbuf->row(y) + (x << 2));
}
//--------------------------------------------------------------------
void copy_pixel(int x, int y, const color_type& c)
{
@@ -207,6 +215,59 @@ namespace agg
}
//--------------------------------------------------------------------
template<class SrcPixelFormatRenderer>
void blend_from(const SrcPixelFormatRenderer& from,
const int8u* psrc,
int xdst, int ydst,
int xsrc, int ysrc,
unsigned len)
{
typedef typename SrcPixelFormatRenderer::order_type src_order;
int8u* pdst = m_rbuf->row(ydst) + (xdst << 2);
int incp = 4;
if(xdst > xsrc)
{
psrc += (len-1) << 2;
pdst += (len-1) << 2;
incp = -4;
}
do
{
int alpha = psrc[src_order::A];
if(alpha)
{
if(alpha == 255)
{
pdst[Order::R] = psrc[src_order::R];
pdst[Order::G] = psrc[src_order::G];
pdst[Order::B] = psrc[src_order::B];
pdst[Order::A] = psrc[src_order::A];
}
else
{
int r = pdst[Order::R];
int g = pdst[Order::G];
int b = pdst[Order::B];
int a = pdst[Order::A];
pdst[Order::R] = (int8u)((((psrc[src_order::R] - r) * alpha) + (r << 8)) >> 8);
pdst[Order::G] = (int8u)((((psrc[src_order::G] - g) * alpha) + (g << 8)) >> 8);
pdst[Order::B] = (int8u)((((psrc[src_order::B] - b) * alpha) + (b << 8)) >> 8);
pdst[Order::A] = (int8u)((alpha + a) - ((alpha * a) >> 8));
}
}
psrc += incp;
pdst += incp;
}
while(--len);
}
//--------------------------------------------------------------------
void blend_solid_hspan(int x, int y, unsigned len,
const color_type& c, const int8u* covers)
+9 -2
View File
@@ -30,7 +30,8 @@ namespace agg
{
public:
typedef rgba8 color_type;
typedef Order order_type;
typedef rendering_buffer::row_data row_data;
private:
//--------------------------------------------------------------------
@@ -117,12 +118,18 @@ namespace agg
unsigned height() const { return m_rbuf->height(); }
//--------------------------------------------------------------------
color_type pixel(int x, int y)
color_type pixel(int x, int y) const
{
int8u* p = m_rbuf->row(y) + (x << 2);
return color_type(p[Order::R], p[Order::G], p[Order::B], p[Order::A]);
}
//--------------------------------------------------------------------
row_data span(int x, int y) const
{
return row_data(x, width() - 1, m_rbuf->row(y) + (x << 2));
}
//--------------------------------------------------------------------
void copy_pixel(int x, int y, const color_type& c)
{
+55 -1
View File
@@ -30,6 +30,8 @@ namespace agg
{
public:
typedef rgba8 color_type;
typedef Order order_type;
typedef rendering_buffer::row_data row_data;
private:
@@ -104,12 +106,18 @@ namespace agg
unsigned height() const { return m_rbuf->height(); }
//--------------------------------------------------------------------
color_type pixel(int x, int y)
color_type pixel(int x, int y) const
{
int8u* p = m_rbuf->row(y) + (x << 2);
return color_type(p[Order::R], p[Order::G], p[Order::B], p[Order::A]);
}
//--------------------------------------------------------------------
row_data span(int x, int y) const
{
return row_data(x, width() - 1, m_rbuf->row(y) + (x << 2));
}
//--------------------------------------------------------------------
void copy_pixel(int x, int y, const color_type& c)
{
@@ -223,6 +231,52 @@ namespace agg
}
//--------------------------------------------------------------------
template<class SrcPixelFormatRenderer>
void blend_from(const SrcPixelFormatRenderer& from,
const int8u* psrc,
int xdst, int ydst,
int xsrc, int ysrc,
unsigned len)
{
typedef typename SrcPixelFormatRenderer::order_type src_order;
int8u* pdst = m_rbuf->row(ydst) + (xdst << 2);
int incp = 4;
if(xdst > xsrc)
{
psrc += (len-1) << 2;
pdst += (len-1) << 2;
incp = -4;
}
do
{
unsigned alpha = 255 - psrc[src_order::A];
if(alpha < 255)
{
if(alpha == 0)
{
pdst[Order::R] = psrc[src_order::R];
pdst[Order::G] = psrc[src_order::G];
pdst[Order::B] = psrc[src_order::B];
pdst[Order::A] = psrc[src_order::A];
}
else
{
pdst[Order::R] = (int8u)((pdst[Order::R] * alpha + (psrc[src_order::R] << 8)) >> 8);
pdst[Order::G] = (int8u)((pdst[Order::G] * alpha + (psrc[src_order::G] << 8)) >> 8);
pdst[Order::B] = (int8u)((pdst[Order::B] * alpha + (psrc[src_order::B] << 8)) >> 8);
pdst[Order::A] = (int8u)(255 - ((alpha * (255 - pdst[Order::A])) >> 8));
}
}
psrc += incp;
pdst += incp;
}
while(--len);
}
//--------------------------------------------------------------------
void blend_solid_hspan(int x, int y, unsigned len,
const color_type& c, const int8u* covers)
+37 -65
View File
@@ -148,34 +148,6 @@ namespace agg
};
//----------------------------------------------------------clipping_flags
// 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
//
//
inline unsigned clipping_flags(int x, int y, const rect& clip_box)
{
return (x > clip_box.x2) |
((y > clip_box.y2) << 1) |
((x < clip_box.x1) << 2) |
((y < clip_box.y1) << 3);
}
//==================================================rasterizer_scanline_aa
// Polygon rasterizer that is used to render filled polygons with
// high-quality Anti-Aliasing. Internally, by default, the class uses
@@ -207,7 +179,7 @@ namespace agg
//
// filling_rule() and gamma() can be called anytime before "sweeping".
//------------------------------------------------------------------------
template<unsigned AA_Shift=8> class rasterizer_scanline_aa
template<unsigned XScale=1, unsigned AA_Shift=8> class rasterizer_scanline_aa
{
enum status
{
@@ -455,9 +427,9 @@ namespace agg
private:
//--------------------------------------------------------------------
// Disable copying
rasterizer_scanline_aa(const rasterizer_scanline_aa<AA_Shift>&);
const rasterizer_scanline_aa<AA_Shift>&
operator = (const rasterizer_scanline_aa<AA_Shift>&);
rasterizer_scanline_aa(const rasterizer_scanline_aa<XScale, AA_Shift>&);
const rasterizer_scanline_aa<XScale, AA_Shift>&
operator = (const rasterizer_scanline_aa<XScale, AA_Shift>&);
//--------------------------------------------------------------------
void move_to_no_clip(int x, int y);
@@ -492,23 +464,23 @@ namespace agg
//------------------------------------------------------------------------
template<unsigned AA_Shift>
void rasterizer_scanline_aa<AA_Shift>::reset()
template<unsigned XScale, unsigned AA_Shift>
void rasterizer_scanline_aa<XScale, AA_Shift>::reset()
{
m_outline.reset();
m_status = status_initial;
}
//------------------------------------------------------------------------
template<unsigned AA_Shift>
void rasterizer_scanline_aa<AA_Shift>::filling_rule(filling_rule_e filling_rule)
template<unsigned XScale, unsigned AA_Shift>
void rasterizer_scanline_aa<XScale, AA_Shift>::filling_rule(filling_rule_e filling_rule)
{
m_filling_rule = filling_rule;
}
//------------------------------------------------------------------------
template<unsigned AA_Shift>
void rasterizer_scanline_aa<AA_Shift>::clip_box(double x1, double y1, double x2, double y2)
template<unsigned XScale, unsigned AA_Shift>
void rasterizer_scanline_aa<XScale, AA_Shift>::clip_box(double x1, double y1, double x2, double y2)
{
reset();
m_clip_box = rect(poly_coord(x1), poly_coord(y1),
@@ -518,8 +490,8 @@ namespace agg
}
//------------------------------------------------------------------------
template<unsigned AA_Shift>
void rasterizer_scanline_aa<AA_Shift>::reset_clipping()
template<unsigned XScale, unsigned AA_Shift>
void rasterizer_scanline_aa<XScale, AA_Shift>::reset_clipping()
{
reset();
m_clipping = false;
@@ -528,14 +500,14 @@ namespace agg
//------------------------------------------------------------------------
template<unsigned AA_Shift>
void rasterizer_scanline_aa<AA_Shift>::move_to_no_clip(int x, int y)
template<unsigned XScale, unsigned AA_Shift>
void rasterizer_scanline_aa<XScale, AA_Shift>::move_to_no_clip(int x, int y)
{
if(m_status == status_line_to)
{
close_polygon_no_clip();
}
m_outline.move_to(x, y);
m_outline.move_to(x * XScale, y);
m_clipped_start_x = x;
m_clipped_start_y = y;
m_status = status_line_to;
@@ -543,32 +515,32 @@ namespace agg
//------------------------------------------------------------------------
template<unsigned AA_Shift>
void rasterizer_scanline_aa<AA_Shift>::line_to_no_clip(int x, int y)
template<unsigned XScale, unsigned AA_Shift>
void rasterizer_scanline_aa<XScale, AA_Shift>::line_to_no_clip(int x, int y)
{
if(m_status != status_initial)
{
m_outline.line_to(x, y);
m_outline.line_to(x * XScale, y);
m_status = status_line_to;
}
}
//------------------------------------------------------------------------
template<unsigned AA_Shift>
void rasterizer_scanline_aa<AA_Shift>::close_polygon_no_clip()
template<unsigned XScale, unsigned AA_Shift>
void rasterizer_scanline_aa<XScale, AA_Shift>::close_polygon_no_clip()
{
if(m_status == status_line_to)
{
m_outline.line_to(m_clipped_start_x, m_clipped_start_y);
m_outline.line_to(m_clipped_start_x * XScale, m_clipped_start_y);
m_status = status_closed;
}
}
//------------------------------------------------------------------------
template<unsigned AA_Shift>
void rasterizer_scanline_aa<AA_Shift>::clip_segment(int x, int y)
template<unsigned XScale, unsigned AA_Shift>
void rasterizer_scanline_aa<XScale, AA_Shift>::clip_segment(int x, int y)
{
unsigned flags = clipping_flags(x, y, m_clip_box);
if(m_prev_flags == flags)
@@ -615,8 +587,8 @@ namespace agg
//------------------------------------------------------------------------
template<unsigned AA_Shift>
void rasterizer_scanline_aa<AA_Shift>::add_vertex(double x, double y, unsigned cmd)
template<unsigned XScale, unsigned AA_Shift>
void rasterizer_scanline_aa<XScale, AA_Shift>::add_vertex(double x, double y, unsigned cmd)
{
if(is_close(cmd))
{
@@ -641,8 +613,8 @@ namespace agg
//------------------------------------------------------------------------
template<unsigned AA_Shift>
void rasterizer_scanline_aa<AA_Shift>::move_to(int x, int y)
template<unsigned XScale, unsigned AA_Shift>
void rasterizer_scanline_aa<XScale, AA_Shift>::move_to(int x, int y)
{
if(m_clipping)
{
@@ -670,8 +642,8 @@ namespace agg
}
//------------------------------------------------------------------------
template<unsigned AA_Shift>
void rasterizer_scanline_aa<AA_Shift>::line_to(int x, int y)
template<unsigned XScale, unsigned AA_Shift>
void rasterizer_scanline_aa<XScale, AA_Shift>::line_to(int x, int y)
{
if(m_clipping)
{
@@ -684,8 +656,8 @@ namespace agg
}
//------------------------------------------------------------------------
template<unsigned AA_Shift>
void rasterizer_scanline_aa<AA_Shift>::close_polygon()
template<unsigned XScale, unsigned AA_Shift>
void rasterizer_scanline_aa<XScale, AA_Shift>::close_polygon()
{
if(m_clipping)
{
@@ -695,23 +667,23 @@ namespace agg
}
//------------------------------------------------------------------------
template<unsigned AA_Shift>
void rasterizer_scanline_aa<AA_Shift>::move_to_d(double x, double y)
template<unsigned XScale, unsigned AA_Shift>
void rasterizer_scanline_aa<XScale, AA_Shift>::move_to_d(double x, double y)
{
move_to(poly_coord(x), poly_coord(y));
}
//------------------------------------------------------------------------
template<unsigned AA_Shift>
void rasterizer_scanline_aa<AA_Shift>::line_to_d(double x, double y)
template<unsigned XScale, unsigned AA_Shift>
void rasterizer_scanline_aa<XScale, AA_Shift>::line_to_d(double x, double y)
{
line_to(poly_coord(x), poly_coord(y));
}
//------------------------------------------------------------------------
template<unsigned AA_Shift>
bool rasterizer_scanline_aa<AA_Shift>::hit_test(int tx, int ty)
template<unsigned XScale, unsigned AA_Shift>
bool rasterizer_scanline_aa<XScale, AA_Shift>::hit_test(int tx, int ty)
{
close_polygon();
const cell_aa* const* cells = m_outline.cells();
+154 -27
View File
@@ -25,6 +25,7 @@
namespace agg
{
//-----------------------------------------------------------renderer_base
template<class PixelFormat> class renderer_base
{
@@ -371,43 +372,169 @@ namespace agg
m_ren->blend_color_vspan(x, y, len, colors, covers, cover);
}
//--------------------------------------------------------------------
void copy_from(const rendering_buffer& from,
const rect* rc=0,
int x_to=0,
int y_to=0)
rect clip_rect_area(rect& dst, rect& src, int wsrc, int hsrc) const
{
rect tmp_rect(0, 0, from.width(), from.height());
if(rc == 0)
rect rc(0,0,0,0);
rect cb = clip_box();
++cb.x2;
++cb.y2;
if(src.x1 < 0)
{
rc = &tmp_rect;
dst.x1 -= src.x1;
src.x1 = 0;
}
if(src.y1 < 0)
{
dst.y1 -= src.y1;
src.y1 = 0;
}
rect rc2(*rc);
rc2.normalize();
if(rc2.clip(rect(0, 0, from.width() - 1, from.height() - 1)))
{
rect rc3(x_to + rc2.x1 - rc->x1,
y_to + rc2.y1 - rc->y1,
x_to + rc2.x2 - rc->x1,
y_to + rc2.y2 - rc->y1);
rc3.normalize();
if(src.x2 > wsrc) src.x2 = wsrc;
if(src.y2 > hsrc) src.y2 = hsrc;
if(rc3.clip(clip_box()))
if(dst.x1 < cb.x1)
{
src.x1 += cb.x1 - dst.x1;
dst.x1 = cb.x1;
}
if(dst.y1 < cb.y1)
{
src.y1 += cb.y1 - dst.y1;
dst.y1 = cb.y1;
}
if(dst.x2 > cb.x2) dst.x2 = cb.x2;
if(dst.y2 > cb.y2) dst.y2 = cb.y2;
rc.x2 = dst.x2 - dst.x1;
rc.y2 = dst.y2 - dst.y1;
if(rc.x2 > src.x2 - src.x1) rc.x2 = src.x2 - src.x1;
if(rc.y2 > src.y2 - src.y1) rc.y2 = src.y2 - src.y1;
return rc;
}
//--------------------------------------------------------------------
void copy_from(const rendering_buffer& src,
const rect* rect_src_ptr = 0,
int dx = 0,
int dy = 0)
{
rect rsrc(0, 0, src.width(), src.height());
if(rect_src_ptr)
{
rsrc.x1 = rect_src_ptr->x1;
rsrc.y1 = rect_src_ptr->y1;
rsrc.x2 = rect_src_ptr->x2 + 1;
rsrc.y2 = rect_src_ptr->y2 + 1;
}
// Version with xdst, ydst (absolute positioning)
//rect rdst(xdst, ydst, xdst + rsrc.x2 - rsrc.x1, ydst + rsrc.y2 - rsrc.y1);
// Version with dx, dy (relative positioning)
rect rdst(rsrc.x1 + dx, rsrc.y1 + dy, rsrc.x2 + dx, rsrc.y2 + dy);
rect rc = clip_rect_area(rdst, rsrc, src.width(), src.height());
if(rc.x2 > 0)
{
int incy = 1;
if(rdst.y1 > rsrc.y1)
{
while(rc3.y1 <= rc3.y2)
{
m_ren->copy_from(from,
rc3.x1, rc3.y1,
rc2.x1, rc2.y1,
rc3.x2 - rc3.x1 + 1);
++rc2.y1;
++rc3.y1;
}
rsrc.y1 += rc.y2 - 1;
rdst.y1 += rc.y2 - 1;
incy = -1;
}
while(rc.y2 > 0)
{
m_ren->copy_from(src,
rdst.x1, rdst.y1,
rsrc.x1, rsrc.y1,
rc.x2);
rdst.y1 += incy;
rsrc.y1 += incy;
--rc.y2;
}
}
}
//--------------------------------------------------------------------
template<class SrcPixelFormatRenderer>
void blend_from(const SrcPixelFormatRenderer& src,
const rect* rect_src_ptr = 0,
int dx = 0,
int dy = 0)
{
rect rsrc(0, 0, src.width(), src.height());
if(rect_src_ptr)
{
rsrc.x1 = rect_src_ptr->x1;
rsrc.y1 = rect_src_ptr->y1;
rsrc.x2 = rect_src_ptr->x2 + 1;
rsrc.y2 = rect_src_ptr->y2 + 1;
}
// Version with xdst, ydst (absolute positioning)
//rect rdst(xdst, ydst, xdst + rsrc.x2 - rsrc.x1, ydst + rsrc.y2 - rsrc.y1);
// Version with dx, dy (relative positioning)
rect rdst(rsrc.x1 + dx, rsrc.y1 + dy, rsrc.x2 + dx, rsrc.y2 + dy);
rect rc = clip_rect_area(rdst, rsrc, src.width(), src.height());
if(rc.x2 > 0)
{
int incy = 1;
if(rdst.y1 > rsrc.y1)
{
rsrc.y1 += rc.y2 - 1;
rdst.y1 += rc.y2 - 1;
incy = -1;
}
while(rc.y2 > 0)
{
typename SrcPixelFormatRenderer::row_data span = src.span(rsrc.x1, rsrc.y1);
if(span.ptr)
{
int x1src = rsrc.x1;
int x1dst = rdst.x1;
int len = rc.x2;
if(span.x1 > x1src)
{
x1dst += span.x1 - x1src;
len -= span.x1 - x1src;
x1src = span.x1;
}
if(len > 0)
{
if(x1src + len-1 > span.x2)
{
len -= x1src + len - span.x2 - 1;
}
if(len > 0)
{
m_ren->blend_from(src, span.ptr,
x1dst, rdst.y1,
x1src, rsrc.y1,
len);
}
}
}
rdst.y1 += incy;
rsrc.y1 += incy;
--rc.y2;
}
}
}
private:
pixfmt_type* m_ren;
+13 -8
View File
@@ -41,6 +41,7 @@ namespace agg
color_type pixel(int x, int y) const
{
//double src_y = (y + 0.5) * m_scale - 0.5;
double src_y = y * m_scale;
int h = int(m_source.height()) - 1;
int y1 = int(floor(src_y));
@@ -170,16 +171,16 @@ namespace agg
int line_width() const { return m_half_height_hr; }
//--------------------------------------------------------------------
color_type pixel(int x, int y) const
void pixel(color_type* p, int x, int y) const
{
return m_filter->pixel_high_res(m_buf.rows(),
x % m_width_hr + m_dilation_hr,
y + m_offset_y_hr);
m_filter->pixel_high_res(m_buf.rows(),
p,
x % m_width_hr + m_dilation_hr,
y + m_offset_y_hr);
}
//--------------------------------------------------------------------
const filter_type& filter() const { return m_filter; }
filter_type& filter() { return m_filter; }
const filter_type& filter() const { return *m_filter; }
private:
line_image_pattern(const line_image_pattern<filter_type>&);
@@ -830,8 +831,12 @@ namespace agg
const pattern_type& pattern() const { return *m_pattern; }
//---------------------------------------------------------------------
void scale_x(double s) { m_scale_x = s; }
double scale_x() const { return m_scale_x; }
void scale_x(double s) { m_scale_x = s; }
double scale_x() const { return m_scale_x; }
//---------------------------------------------------------------------
void start_x(double s) { m_start = int(s * line_subpixel_size); }
double start_x() const { return double(m_start) / line_subpixel_size; }
//---------------------------------------------------------------------
int subpixel_width() const { return m_pattern->line_width(); }
+5 -1
View File
@@ -72,9 +72,13 @@ namespace agg
if(x < xmin)
{
len -= xmin - x;
covers += xmin - x;
if(!solid)
{
covers += xmin - x;
}
x = xmin;
}
if(len > 0)
{
if(x + len > xmax)
+26
View File
@@ -29,6 +29,16 @@ namespace agg
template<class T> class row_ptr_cache
{
public:
//--------------------------------------------------------------------
struct row_data
{
int x1, x2;
const int8u* ptr;
row_data() {}
row_data(int x1_, int x2_, const int8u* ptr_) :
x1(x1_), x2(x2_), ptr(ptr_) {}
};
//-------------------------------------------------------------------
~row_ptr_cache()
{
@@ -122,6 +132,22 @@ namespace agg
}
}
//--------------------------------------------------------------------
void clear(T value)
{
unsigned y;
for(y = 0; y < height(); y++)
{
T* p = row(y);
unsigned x;
for(x = 0; x < stride_abs(); x++)
{
*p++ = value;
}
}
}
private:
//--------------------------------------------------------------------
// Prohibit copying
@@ -0,0 +1,184 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 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: [email protected]
// [email protected]
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// class rendering_buffer_dynarow
//
//----------------------------------------------------------------------------
#ifndef AGG_RENDERING_BUFFER_DYNAROW_INCLUDED
#define AGG_RENDERING_BUFFER_DYNAROW_INCLUDED
#include "agg_basics.h"
namespace agg
{
//===============================================rendering_buffer_dynarow
// Rendering buffer class with dynamic allocation of the rows.
// The rows are allocated as needed when requesting for span_ptr().
// The class automatically calculates min_x and max_x for each row.
// Generally it's more efficient to use this class as a temporary buffer
// for rendering a few lines and then to blend it with another buffer.
//
template<unsigned PixWidth> class rendering_buffer_dynarow
{
public:
//-------------------------------------------------------------------
struct row_data
{
int8u* ptr;
int x1;
int x2;
};
//-------------------------------------------------------------------
~rendering_buffer_dynarow()
{
init(0,0);
}
//-------------------------------------------------------------------
rendering_buffer_dynarow() :
m_rows(0),
m_width(0),
m_height(0)
{
}
// Allocate and clear the buffer
//--------------------------------------------------------------------
rendering_buffer_dynarow(unsigned width, unsigned height) :
m_rows(new row_data[height]),
m_width(width),
m_height(height)
{
memset(m_rows, 0, sizeof(row_data) * height);
}
// Allocate and clear the buffer
//--------------------------------------------------------------------
void init(unsigned width, unsigned height)
{
unsigned i;
for(i = 0; i < m_height; ++i) delete [] m_rows[i].ptr;
delete [] m_rows;
m_rows = 0;
if(width && height)
{
m_width = width;
m_height = height;
m_rows = new row_data[height];
memset(m_rows, 0, sizeof(row_data) * height);
}
}
//--------------------------------------------------------------------
unsigned width() const { return m_width; }
unsigned height() const { return m_height; }
// Get pointer to the beginning of the row. Memory for the row
// is allocated as needed.
//--------------------------------------------------------------------
int8u* row(int y)
{
row_data* r = m_rows + y;
if(r->ptr == 0)
{
r->ptr = new int8u [m_width * PixWidth];
memset(r->ptr, 0, m_width * PixWidth);
}
return r->ptr;
}
// Get const pointer to the row. The caller must check it for null.
//--------------------------------------------------------------------
const int8u* row(int y) const
{
return m_rows[y].ptr;
}
// Get the Y-th span. The pointer r.ptr is automatically adjusted
// to the actual beginning of the span. Use this function as follows:
//
// rendering_buffer_dynarow::row_data r = rbuf.span(x, y);
// if(r.ptr)
// {
// do { blend(r.ptr); r.ptr += PixWidth } while(++r.x1 < r.x2);
// }
//--------------------------------------------------------------------
row_data span(int x, int y) const
{
row_data r = m_rows[y];
if(r.ptr)
{
if(x < r.x1) x = r.x1;
r.ptr += x * PixWidth;
}
return r;
}
// The main function used for rendering. Returns pointer to the
// pre-allocated span. Memory for the row is allocated as needed.
//--------------------------------------------------------------------
int8u* span_ptr(int x, int y, unsigned len)
{
row_data* r = m_rows + y;
int x2 = x + len - 1;
if(r->ptr)
{
if(x < r->x1) { r->x1 = x; }
if(x2 > r->x2) { r->x2 = x2; }
}
else
{
r->ptr = new int8u [m_width * PixWidth];
r->x1 = x;
r->x2 = x2;
memset(r->ptr, 0, m_width * PixWidth);
}
return r->ptr + x * PixWidth;
}
// Get const pointer to the span. Used mostly in GetPixel function
// The caller must check the returned pointer for null.
//--------------------------------------------------------------------
const int8u* span_ptr(int x, int y, unsigned) const
{
row_data* r = m_rows + y;
return r->ptr ? r->ptr + x * PixWidth : 0;
}
private:
//--------------------------------------------------------------------
// Prohibit copying
rendering_buffer_dynarow(const rendering_buffer_dynarow<PixWidth>&);
const rendering_buffer_dynarow<PixWidth>&
operator = (const rendering_buffer_dynarow<PixWidth>&);
private:
//--------------------------------------------------------------------
row_data* m_rows; // Pointers to each row of the buffer
unsigned m_width; // Width in pixels
unsigned m_height; // Height in pixels
};
}
#endif
+3 -2
View File
@@ -303,12 +303,13 @@ namespace agg
sp.x = span_iterator->x;
sp.len = span_iterator->len;
int len = abs(int(sp.len));
sp.covers_id =
m_covers.add_cells(span_iterator->covers,
unsigned(abs(int(sp.len))));
unsigned(len));
m_spans.add(sp);
int x1 = sp.x;
int x2 = sp.x + sp.len - 1;
int x2 = sp.x + len - 1;
if(x1 < m_min_x) m_min_x = x1;
if(x2 > m_max_x) m_max_x = x2;
++span_iterator;
+2 -12
View File
@@ -236,18 +236,8 @@ namespace agg
for(i = 0; i < m_scanlines.size(); ++i)
{
size += sizeof(int16) * 2; // Y, num_spans
const scanline_data& sl_this = m_scanlines[i];
unsigned num_spans = sl_this.num_spans;
unsigned span_idx = sl_this.start_span;
do
{
const span_data& sp = m_spans[span_idx++];
size += sizeof(int16) * 2; // X, span_len
}
while(--num_spans);
size += sizeof(int16) * 2 + // Y, num_spans
unsigned(m_scanlines[i].num_spans) * sizeof(int16) * 2; // X, span_len
}
return size;
}
+1 -1
View File
@@ -39,7 +39,7 @@ namespace agg
color_type* generate(int x, int y, unsigned len)
{
color_type* span = m_span_gen->generate(x, y, len);
m_conv->convert(span, len);
m_conv->convert(span, x, y, len);
return span;
}
+213 -20
View File
@@ -26,6 +26,14 @@
namespace agg
{
enum
{
gradient_subpixel_shift = 4,
gradient_subpixel_size = 1 << gradient_subpixel_shift,
gradient_subpixel_mask = gradient_subpixel_size - 1
};
//==========================================================span_gradient
template<class ColorT,
class Interpolator,
@@ -45,12 +53,7 @@ namespace agg
base_shift = 8,
base_size = 1 << base_shift,
base_mask = base_size - 1,
gradient_shift = 4,
gradient_size = 1 << gradient_shift,
gradient_mask = gradient_size - 1,
downscale_shift = interpolator_type::subpixel_shift - gradient_shift
downscale_shift = interpolator_type::subpixel_shift - gradient_subpixel_shift
};
@@ -67,23 +70,23 @@ namespace agg
m_interpolator(&inter),
m_gradient_function(&gradient_function),
m_color_function(color_function),
m_d1(int(d1 * gradient_size)),
m_d2(int(d2 * gradient_size))
m_d1(int(d1 * gradient_subpixel_size)),
m_d2(int(d2 * gradient_subpixel_size))
{}
//--------------------------------------------------------------------
interpolator_type& interpolator() { return *m_interpolator; }
const GradientF& gradient_function() const { return *m_gradient_function; }
const ColorF color_function() const { return m_color_function; }
double d1() const { return double(m_d1) / gradient_size; }
double d2() const { return double(m_d2) / gradient_size; }
double d1() const { return double(m_d1) / gradient_subpixel_size; }
double d2() const { return double(m_d2) / gradient_subpixel_size; }
//--------------------------------------------------------------------
void interpolator(interpolator_type& i) { m_interpolator = &i; }
void gradient_function(const GradientF& gf) { m_gradient_function = &gf; }
void color_function(ColorF cf) { m_color_function = cf; }
void d1(double v) { m_d1 = int(v * gradient_size); }
void d2(double v) { m_d2 = int(v * gradient_size); }
void d1(double v) { m_d1 = int(v * gradient_subpixel_size); }
void d2(double v) { m_d2 = int(v * gradient_subpixel_size); }
//--------------------------------------------------------------------
color_type* generate(int x, int y, unsigned len)
@@ -150,9 +153,20 @@ namespace agg
};
//---------------------------------------------------------gradient_circle
//==========================================================gradient_circle
class gradient_circle
{
// Actually the same as radial. Just for compatibility
public:
static int calculate(int x, int y, int)
{
return int(fast_sqrt(x*x + y*y));
}
};
//==========================================================gradient_radial
class gradient_radial
{
public:
static int calculate(int x, int y, int)
@@ -162,7 +176,148 @@ namespace agg
};
//--------------------------------------------------------------gradient_x
//========================================================gradient_radial_d
class gradient_radial_d
{
public:
static int calculate(int x, int y, int)
{
return int(sqrt(double(x)*double(x) + double(y)*double(y)));
}
};
//====================================================gradient_radial_focus
class gradient_radial_focus
{
public:
//---------------------------------------------------------------------
gradient_radial_focus() :
m_radius(100 * gradient_subpixel_size),
m_focus_x(0),
m_focus_y(0)
{
update_values();
}
//---------------------------------------------------------------------
gradient_radial_focus(double r, double fx, double fy) :
m_radius (int(r * gradient_subpixel_size)),
m_focus_x(int(fx * gradient_subpixel_size)),
m_focus_y(int(fy * gradient_subpixel_size))
{
update_values();
}
//---------------------------------------------------------------------
void init(double r, double fx, double fy)
{
m_radius = int(r * gradient_subpixel_size);
m_focus_x = int(fx * gradient_subpixel_size);
m_focus_y = int(fy * gradient_subpixel_size);
update_values();
}
//---------------------------------------------------------------------
double radius() const { return double(m_radius) / gradient_subpixel_size; }
double focus_x() const { return double(m_focus_x) / gradient_subpixel_size; }
double focus_y() const { return double(m_focus_y) / gradient_subpixel_size; }
//---------------------------------------------------------------------
int calculate(int x, int y, int d) const
{
double solution_x;
double solution_y;
// Special case to avoid divide by zero or very near zero
//---------------------------------
if(x == int(m_focus_x))
{
solution_x = m_focus_x;
solution_y = 0.0;
solution_y += (y > m_focus_y) ? m_trivial : -m_trivial;
}
else
{
// Slope of the focus-current line
//-------------------------------
double slope = double(y - m_focus_y) / double(x - m_focus_x);
// y-intercept of that same line
//--------------------------------
double yint = double(y) - (slope * x);
// Use the classical quadratic formula to calculate
// the intersection point
//--------------------------------
double a = (slope * slope) + 1;
double b = 2 * slope * yint;
double c = yint * yint - m_radius2;
double det = sqrt((b * b) - (4.0 * a * c));
solution_x = -b;
// Choose the positive or negative root depending
// on where the X coord lies with respect to the focus.
solution_x += (x < m_focus_x) ? -det : det;
solution_x /= 2.0 * a;
// Calculating of Y is trivial
solution_y = (slope * solution_x) + yint;
}
// Calculate the percentage (0...1) of the current point along the
// focus-circumference line and return the normalized (0...d) value
//-------------------------------
solution_x -= double(m_focus_x);
solution_y -= double(m_focus_y);
double int_to_focus = solution_x * solution_x + solution_y * solution_y;
double cur_to_focus = double(x - m_focus_x) * double(x - m_focus_x) +
double(y - m_focus_y) * double(y - m_focus_y);
return int(sqrt(cur_to_focus / int_to_focus) * d);
}
private:
//---------------------------------------------------------------------
void update_values()
{
// For use in the quadractic equation
//-------------------------------
m_radius2 = double(m_radius) * double(m_radius);
double dist = sqrt(double(m_focus_x) * double(m_focus_x) +
double(m_focus_y) * double(m_focus_y));
// Test if distance from focus to center is greater than the radius
// For the sake of assurance factor restrict the point to be
// no further than 99% of the radius.
//-------------------------------
double r = m_radius * 0.99;
if(dist > r)
{
// clamp focus to radius
// x = r cos theta, y = r sin theta
//------------------------
double a = atan2(double(m_focus_y), double(m_focus_x));
m_focus_x = int(r * cos(a));
m_focus_y = int(r * sin(a));
}
// Calculate the solution to be used in the case where x == focus_x
//------------------------------
m_trivial = sqrt(m_radius2 - (m_focus_x * m_focus_x));
}
int m_radius;
int m_focus_x;
int m_focus_y;
double m_radius2;
double m_trivial;
};
//==============================================================gradient_x
class gradient_x
{
public:
@@ -170,7 +325,7 @@ namespace agg
};
//--------------------------------------------------------------gradient_y
//==============================================================gradient_y
class gradient_y
{
public:
@@ -178,7 +333,7 @@ namespace agg
};
//--------------------------------------------------------gradient_diamond
//========================================================gradient_diamond
class gradient_diamond
{
public:
@@ -191,7 +346,7 @@ namespace agg
};
//-------------------------------------------------------------gradient_xy
//=============================================================gradient_xy
class gradient_xy
{
public:
@@ -202,7 +357,7 @@ namespace agg
};
//--------------------------------------------------------gradient_sqrt_xy
//========================================================gradient_sqrt_xy
class gradient_sqrt_xy
{
public:
@@ -213,7 +368,7 @@ namespace agg
};
//----------------------------------------------------------gradient_conic
//==========================================================gradient_conic
class gradient_conic
{
public:
@@ -224,6 +379,44 @@ namespace agg
};
//=================================================gradient_repeat_adaptor
template<class GradientF> class gradient_repeat_adaptor
{
public:
gradient_repeat_adaptor(const GradientF& gradient) :
m_gradient(&gradient) {}
int calculate(int x, int y, int d) const
{
int ret = m_gradient->calculate(x, y, d) % d;
if(ret < 0) ret += d;
return ret;
}
private:
const GradientF* m_gradient;
};
//================================================gradient_reflect_adaptor
template<class GradientF> class gradient_reflect_adaptor
{
public:
gradient_reflect_adaptor(const GradientF& gradient) :
m_gradient(&gradient) {}
int calculate(int x, int y, int d) const
{
int d2 = d << 1;
int ret = m_gradient->calculate(x, y, d) % d2;
if(ret < 0) ret += d2;
if(ret >= d) ret = d2 - ret;
return ret;
}
private:
const GradientF* m_gradient;
};
}
+126
View File
@@ -0,0 +1,126 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 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: [email protected]
// [email protected]
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_SPAN_GRADIENT_ALPHA_INCLUDED
#define AGG_SPAN_GRADIENT_ALPHA_INCLUDED
#include "agg_span_gradient.h"
namespace agg
{
//======================================================span_gradient_alpha
template<class ColorT,
class Interpolator,
class GradientF,
class AlphaF>
class span_gradient_alpha
{
public:
typedef Interpolator interpolator_type;
typedef ColorT color_type;
typedef typename color_type::alpha_type alpha_type;
enum
{
base_shift = 8,
base_size = 1 << base_shift,
base_mask = base_size - 1,
downscale_shift = interpolator_type::subpixel_shift - gradient_subpixel_shift
};
//--------------------------------------------------------------------
span_gradient_alpha() {}
//--------------------------------------------------------------------
span_gradient_alpha(interpolator_type& inter,
const GradientF& gradient_function,
AlphaF alpha_function,
double d1, double d2) :
m_interpolator(&inter),
m_gradient_function(&gradient_function),
m_alpha_function(alpha_function),
m_d1(int(d1 * gradient_subpixel_size)),
m_d2(int(d2 * gradient_subpixel_size))
{}
//--------------------------------------------------------------------
interpolator_type& interpolator() { return *m_interpolator; }
const GradientF& gradient_function() const { return *m_gradient_function; }
const AlphaF alpha_function() const { return m_alpha_function; }
double d1() const { return double(m_d1) / gradient_subpixel_size; }
double d2() const { return double(m_d2) / gradient_subpixel_size; }
//--------------------------------------------------------------------
void interpolator(interpolator_type& i) { m_interpolator = &i; }
void gradient_function(const GradientF& gf) { m_gradient_function = &gf; }
void alpha_function(AlphaF af) { m_alpha_function = af; }
void d1(double v) { m_d1 = int(v * gradient_subpixel_size); }
void d2(double v) { m_d2 = int(v * gradient_subpixel_size); }
//--------------------------------------------------------------------
void convert(color_type* span, int x, int y, unsigned len)
{
int dd = m_d2 - m_d1;
if(dd < 1) dd = 1;
m_interpolator->begin(x+0.5, y+0.5, len);
do
{
m_interpolator->coordinates(&x, &y);
int d = m_gradient_function->calculate(x >> downscale_shift,
y >> downscale_shift, dd);
d = ((d - m_d1) << base_shift) / dd;
if(d < 0) d = 0;
if(d > base_mask) d = base_mask;
span->a = m_alpha_function[d];
++span;
++(*m_interpolator);
}
while(--len);
}
private:
interpolator_type* m_interpolator;
const GradientF* m_gradient_function;
AlphaF m_alpha_function;
int m_d1;
int m_d2;
};
//=======================================================gradient_alpha_x
template<class ColorT> struct gradient_alpha_x
{
typedef typename ColorT::alpha_type alpha_type;
alpha_type operator [] (alpha_type x) const { return x; }
};
//====================================================gradient_alpha_x_u8
struct gradient_alpha_x_u8
{
typedef int8u alpha_type;
alpha_type operator [] (alpha_type x) const { return x; }
};
//==========================================gradient_alpha_one_munus_x_u8
struct gradient_alpha_one_munus_x_u8
{
typedef int8u alpha_type;
alpha_type operator [] (alpha_type x) const { return 255-x; }
};
}
#endif
+83 -4
View File
@@ -52,19 +52,35 @@ namespace agg
m_src(&src),
m_back_color(back_color),
m_interpolator(&interpolator),
m_filter(filter)
m_filter(filter),
m_dx_dbl(0.5),
m_dy_dbl(0.5),
m_dx_int(image_subpixel_size / 2),
m_dy_int(image_subpixel_size / 2)
{}
//----------------------------------------------------------------
const rendering_buffer& source_image() const { return *m_src; }
const color_type& background_color() const { return m_back_color; }
const image_filter_base& filter() const { return *m_filter; }
const rendering_buffer& source_image() const { return *m_src; }
const color_type& background_color() const { return m_back_color; }
const image_filter_base& filter() const { return *m_filter; }
int filter_dx_int() const { return m_dx_int; }
int filter_dy_int() const { return m_dy_int; }
double filter_dx_dbl() const { return m_dx_dbl; }
double filter_dy_dbl() const { return m_dy_dbl; }
//----------------------------------------------------------------
void source_image(const rendering_buffer& v) { m_src = &v; }
void background_color(const color_type& v) { m_back_color = v; }
void interpolator(interpolator_type& v) { m_interpolator = &v; }
void filter(const image_filter_base& v) { m_filter = &v; }
void filter_offset(double dx, double dy)
{
m_dx_dbl = dx;
m_dy_dbl = dy;
m_dx_int = int(dx * image_subpixel_size);
m_dy_int = int(dy * image_subpixel_size);
}
void filter_offset(double d) { filter_offset(d, d); }
//----------------------------------------------------------------
interpolator_type& interpolator() { return *m_interpolator; }
@@ -75,6 +91,69 @@ namespace agg
color_type m_back_color;
interpolator_type* m_interpolator;
const image_filter_base* m_filter;
double m_dx_dbl;
double m_dy_dbl;
unsigned m_dx_int;
unsigned m_dy_int;
};
//-------------------------------------------------remainder_unsigned
class remainder_unsigned
{
public:
remainder_unsigned(unsigned size) :
m_size(size),
m_add(size * (0x3FFFFFFF / size))
{}
unsigned operator () (int v) const
{
return (unsigned(v) + m_add) % m_size;
}
private:
unsigned m_size;
unsigned m_add;
};
//----------------------------------------------------remainder_pow2
class remainder_pow2
{
public:
remainder_pow2(unsigned size)
{
m_mask = 1;
while(m_mask < size) m_mask = (m_mask << 1) | 1;
m_mask >>= 1;
}
unsigned operator () (int v) const { return unsigned(v) & m_mask; }
private:
unsigned m_mask;
};
//-----------------------------------------------remainder_auto_pow2
class remainder_auto_pow2
{
public:
remainder_auto_pow2(unsigned size) :
m_size(size),
m_add(size * (0x3FFFFFFF / size)),
m_mask((m_size & (m_size-1)) ? 0 : m_size-1)
{}
unsigned operator () (int v) const
{
if(m_mask) return unsigned(v) & m_mask;
return (unsigned(v) + m_add) % m_size;
}
private:
unsigned m_size;
unsigned m_add;
unsigned m_mask;
};
+15 -7
View File
@@ -52,7 +52,8 @@ namespace agg
//--------------------------------------------------------------------
color_type* generate(int x, int y, unsigned len)
{
base_type::interpolator().begin(x, y, len);
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
y + base_type::filter_dy_dbl(), len);
int fg[3];
int src_alpha;
@@ -130,8 +131,8 @@ namespace agg
//--------------------------------------------------------------------
color_type* generate(int x, int y, unsigned len)
{
base_type::interpolator().begin(x, y, len);
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
y + base_type::filter_dy_dbl(), len);
int fg[3];
int src_alpha;
int back_r = base_type::background_color().r;
@@ -154,6 +155,9 @@ namespace agg
base_type::interpolator().coordinates(&x_hr, &y_hr);
x_hr -= base_type::filter_dx_int();
y_hr -= base_type::filter_dy_int();
int x_lr = x_hr >> image_subpixel_shift;
int y_lr = y_hr >> image_subpixel_shift;
int weight;
@@ -349,7 +353,8 @@ namespace agg
//--------------------------------------------------------------------
color_type* generate(int x, int y, unsigned len)
{
base_type::interpolator().begin(x, y, len);
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
y + base_type::filter_dy_dbl(), len);
int fg[3];
int src_alpha;
@@ -381,6 +386,9 @@ namespace agg
{
base_type::interpolator().coordinates(&x, &y);
x -= base_type::filter_dx_int();
y -= base_type::filter_dy_int();
int x_hr = x;
int y_hr = y;
@@ -502,10 +510,10 @@ namespace agg
if(fg[2] < 0) fg[2] = 0;
if(src_alpha < 0) src_alpha = 0;
if(fg[0] > 255) fg[0] = 255;
if(fg[1] > 255) fg[1] = 255;
if(fg[2] > 255) fg[2] = 255;
if(src_alpha > 255) src_alpha = 255;
if(fg[0] > src_alpha) fg[0] = src_alpha;
if(fg[1] > src_alpha) fg[1] = src_alpha;
if(fg[2] > src_alpha) fg[2] = src_alpha;
}
}
@@ -61,8 +61,8 @@ namespace agg
//--------------------------------------------------------------------
color_type* generate(int x, int y, unsigned len)
{
base_type::interpolator().begin(x, y, len);
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
y + base_type::filter_dy_dbl(), len);
int fg[3];
int src_alpha;
int back_r = m_gamma->dir(base_type::background_color().r);
@@ -85,6 +85,9 @@ namespace agg
base_type::interpolator().coordinates(&x_hr, &y_hr);
x_hr -= base_type::filter_dx_int();
y_hr -= base_type::filter_dy_int();
int x_lr = x_hr >> image_subpixel_shift;
int y_lr = y_hr >> image_subpixel_shift;
int weight;
@@ -290,8 +293,8 @@ namespace agg
//--------------------------------------------------------------------
color_type* generate(int x, int y, unsigned len)
{
base_type::interpolator().begin(x, y, len);
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
y + base_type::filter_dy_dbl(), len);
int fg[3];
int src_alpha;
int back_r = m_gamma->dir(base_type::background_color().r);
@@ -322,6 +325,9 @@ namespace agg
{
base_type::interpolator().coordinates(&x, &y);
x -= base_type::filter_dx_int();
y -= base_type::filter_dy_int();
int x_hr = x;
int y_hr = y;
+22 -11
View File
@@ -54,7 +54,8 @@ namespace agg
//--------------------------------------------------------------------
color_type* generate(int x, int y, unsigned len)
{
base_type::interpolator().begin(x, y, len);
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
y + base_type::filter_dy_dbl(), len);
int fg[4];
@@ -139,7 +140,8 @@ namespace agg
//--------------------------------------------------------------------
color_type* generate(int x, int y, unsigned len)
{
base_type::interpolator().begin(x, y, len);
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
y + base_type::filter_dy_dbl(), len);
int fg[4];
int back_r = base_type::background_color().r;
@@ -162,8 +164,12 @@ namespace agg
base_type::interpolator().coordinates(&x_hr, &y_hr);
x_hr -= base_type::filter_dx_int();
y_hr -= base_type::filter_dy_int();
int x_lr = x_hr >> image_subpixel_shift;
int y_lr = y_hr >> image_subpixel_shift;
int weight;
if(x_lr >= 0 && y_lr >= 0 &&
@@ -176,6 +182,7 @@ namespace agg
x_hr &= image_subpixel_mask;
y_hr &= image_subpixel_mask;
fg_ptr = base_type::source_image().row(y_lr) + (x_lr << 2);
weight = (image_subpixel_size - x_hr) *
@@ -362,7 +369,8 @@ namespace agg
//--------------------------------------------------------------------
color_type* generate(int x, int y, unsigned len)
{
base_type::interpolator().begin(x, y, len);
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
y + base_type::filter_dy_dbl(), len);
int fg[4];
@@ -394,6 +402,9 @@ namespace agg
{
base_type::interpolator().coordinates(&x, &y);
x -= base_type::filter_dx_int();
y -= base_type::filter_dy_int();
int x_hr = x;
int y_hr = y;
@@ -446,10 +457,10 @@ namespace agg
if(fg[2] < 0) fg[2] = 0;
if(fg[3] < 0) fg[3] = 0;
if(fg[0] > 255) fg[0] = 255;
if(fg[1] > 255) fg[1] = 255;
if(fg[2] > 255) fg[2] = 255;
if(fg[3] > 255) fg[3] = 255;
if(fg[Order::A] > 255) fg[Order::A] = 255;
if(fg[Order::R] > fg[Order::A]) fg[Order::R] = fg[Order::A];
if(fg[Order::G] > fg[Order::A]) fg[Order::G] = fg[Order::A];
if(fg[Order::B] > fg[Order::A]) fg[Order::B] = fg[Order::A];
}
else
{
@@ -517,10 +528,10 @@ namespace agg
if(fg[2] < 0) fg[2] = 0;
if(fg[3] < 0) fg[3] = 0;
if(fg[0] > 255) fg[0] = 255;
if(fg[1] > 255) fg[1] = 255;
if(fg[2] > 255) fg[2] = 255;
if(fg[3] > 255) fg[3] = 255;
if(fg[Order::A] > 255) fg[Order::A] = 255;
if(fg[Order::R] > fg[Order::A]) fg[Order::R] = fg[Order::A];
if(fg[Order::G] > fg[Order::A]) fg[Order::G] = fg[Order::A];
if(fg[Order::B] > fg[Order::A]) fg[Order::B] = fg[Order::A];
}
}
+13
View File
@@ -141,12 +141,25 @@ namespace agg
*y = (*y - m_dy1) / m_ky + m_wy1;
}
//-------------------------------------------------------------------
double scale_x() const
{
return m_kx;
}
//-------------------------------------------------------------------
double scale_y() const
{
return m_ky;
}
//-------------------------------------------------------------------
double scale() const
{
return (m_kx + m_ky) * 0.5;
}
//-------------------------------------------------------------------
unsigned byte_size() const
{
+20 -12
View File
@@ -16,8 +16,8 @@
#ifndef AGG_VCGEN_CONTOUR_INCLUDED
#define AGG_VCGEN_CONTOUR_INCLUDED
#include "agg_basics.h"
#include "agg_vertex_sequence.h"
#include "agg_math_stroke.h"
#include "agg_vertex_iterator.h"
namespace agg
{
@@ -33,22 +33,32 @@ namespace agg
initial,
ready,
outline,
add_point,
end_poly
out_vertices,
end_poly,
stop
};
public:
typedef vertex_sequence<vertex_dist, 6> vertex_storage;
typedef pod_deque<point_type, 6> coord_storage;
vcgen_contour();
void line_join(line_join_e lj) { m_line_join = lj; }
void inner_line_join(line_join_e lj) { m_inner_line_join = lj; }
void width(double w) { m_width = w * 0.5; }
void miter_limit(double ml) { m_miter_limit = ml; }
void miter_limit_theta(double t);
void inner_miter_limit(double ml) { m_inner_miter_limit = ml; }
void approximation_scale(double as) { m_approx_scale = as; }
void auto_detect_orientation(bool v) { m_auto_detect = v; }
line_join_e line_join() const { return m_line_join; }
line_join_e inner_line_join() const { return m_inner_line_join; }
double width() const { return m_width * 2.0; }
double miter_limit() const { return m_miter_limit; }
double inner_miter_limit() const { return m_inner_miter_limit; }
double approximation_scale() const { return m_approx_scale; }
bool auto_detect_orientation() const { return m_auto_detect; }
// Generator interface
@@ -63,24 +73,22 @@ namespace agg
vcgen_contour(const vcgen_contour&);
const vcgen_contour& operator = (const vcgen_contour&);
bool calc_miter(const vertex_dist& v0,
const vertex_dist& v1,
const vertex_dist& v2);
vertex_storage m_src_vertices;
coord_storage m_out_vertices;
double m_width;
line_join_e m_line_join;
line_join_e m_inner_line_join;
double m_approx_scale;
double m_abs_width;
double m_signed_width;
double m_miter_limit;
double m_inner_miter_limit;
status_e m_status;
unsigned m_src_vertex;
unsigned m_out_vertex;
unsigned m_closed;
unsigned m_orientation;
bool m_auto_detect;
double m_x1;
double m_y1;
double m_x2;
double m_y2;
};
}
+9 -50
View File
@@ -16,16 +16,13 @@
#ifndef AGG_VCGEN_STROKE_INCLUDED
#define AGG_VCGEN_STROKE_INCLUDED
#include "agg_basics.h"
#include "agg_vertex_sequence.h"
#include "agg_math_stroke.h"
#include "agg_vertex_iterator.h"
namespace agg
{
// Minimal angle to calculate round joins
const double vcgen_stroke_theta = 1e-10; //----vcgen_stroke_theta
//============================================================vcgen_stroke
//
// See Implementation agg_vcgen_stroke.cpp
@@ -50,48 +47,28 @@ namespace agg
};
public:
enum line_cap_e
{
butt_cap,
square_cap,
round_cap
};
enum line_join_e
{
miter_join,
miter_join_revert,
round_join,
bevel_join
};
struct coord_type
{
double x, y;
coord_type() {}
coord_type(double x_, double y_) : x(x_), y(y_) {}
};
typedef vertex_sequence<vertex_dist, 6> vertex_storage;
typedef pod_deque<coord_type, 6> coord_storage;
typedef pod_deque<point_type, 6> coord_storage;
vcgen_stroke();
void line_cap(line_cap_e lc) { m_line_cap = lc; }
void line_join(line_join_e lj) { m_line_join = lj; }
void inner_line_join(line_join_e lj) { m_inner_line_join = lj; }
line_cap_e line_cap() const { return m_line_cap; }
line_join_e line_join() const { return m_line_join; }
line_join_e inner_line_join() const { return m_inner_line_join; }
void width(double w) { m_width = w * 0.5; }
void miter_limit(double ml) { m_miter_limit = ml; }
void miter_limit_theta(double t);
void inner_miter_limit(double ml) { m_inner_miter_limit = ml; }
void approximation_scale(double as) { m_approx_scale = as; }
double width() const { return m_width * 2.0; }
double miter_limit() const { return m_miter_limit; }
double inner_miter_limit() const { return m_inner_miter_limit; }
double approximation_scale() const { return m_approx_scale; }
void shorten(double s) { m_shorten = s; }
@@ -114,34 +91,16 @@ namespace agg
vcgen_stroke(const vcgen_stroke&);
const vcgen_stroke& operator = (const vcgen_stroke&);
void calc_join(const vertex_dist& v0,
const vertex_dist& v1,
const vertex_dist& v2,
double len1, double len2);
void calc_miter(const vertex_dist& v0,
const vertex_dist& v1,
const vertex_dist& v2,
double dx1, double dy1,
double dx2, double dy2,
bool revert_flag);
void calc_arc(double x, double y,
double dx1, double dy1,
double dx2, double dy2);
void calc_cap(const vertex_dist& v0,
const vertex_dist& v1,
double len);
vertex_storage m_src_vertices;
coord_storage m_out_vertices;
double m_width;
double m_miter_limit;
double m_inner_miter_limit;
double m_approx_scale;
double m_shorten;
line_cap_e m_line_cap;
line_join_e m_line_join;
line_join_e m_inner_line_join;
unsigned m_closed;
status_e m_status;
status_e m_prev_status;
@@ -54,6 +54,9 @@ namespace agg
double x2() const { return m_clip_box.x2; }
double y2() const { return m_clip_box.y2; }
static bool auto_close() { return true; }
static bool auto_unclose() { return false; }
void reset();
void move_to(double x, double y);
void line_to(double x, double y);
+121
View File
@@ -0,0 +1,121 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 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: [email protected]
// [email protected]
// http://www.antigrain.com
//----------------------------------------------------------------------------
#ifndef AGG_VPGEN_CLIP_POLYLINE_INCLUDED
#define AGG_VPGEN_CLIP_POLYLINE_INCLUDED
#include "agg_basics.h"
namespace agg
{
//======================================================vpgen_clip_polyline
//
// See Implementation agg_vpgen_clip_polyline.cpp
//
class vpgen_clip_polyline
{
public:
vpgen_clip_polyline() :
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)
{
}
void clip_box(double x1, double y1, double x2, double y2)
{
m_clip_box.x1 = x1;
m_clip_box.y1 = y1;
m_clip_box.x2 = x2;
m_clip_box.y2 = y2;
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; }
double y2() const { return m_clip_box.y2; }
static bool auto_close() { return false; }
static bool auto_unclose() { return true; }
void reset();
void move_to(double x, double y);
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;
};
}
#endif
+3 -2
View File
@@ -34,11 +34,12 @@ namespace agg
void approximation_scale(double s) { m_approximation_scale = s; }
double approximation_scale() const { return m_approximation_scale; }
void reset() { m_cmd = path_cmd_stop; }
static bool auto_close() { return false; }
static bool auto_unclose() { return false; }
void reset() { m_cmd = path_cmd_stop; }
void move_to(double x, double y);
void line_to(double x, double y);
unsigned vertex(double* x, double* y);
private:
+112
View File
@@ -0,0 +1,112 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 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: [email protected]
// [email protected]
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// classes bezier_ctrl_impl, bezier_ctrl
//
//----------------------------------------------------------------------------
#ifndef AGG_BEZIER_CTRL_INCLUDED
#define AGG_BEZIER_CTRL_INCLUDED
#include "agg_math.h"
#include "agg_ellipse.h"
#include "agg_trans_affine.h"
#include "agg_color_rgba.h"
#include "agg_conv_stroke.h"
#include "agg_conv_curve.h"
#include "agg_polygon_ctrl.h"
namespace agg
{
//--------------------------------------------------------bezier_ctrl_impl
class bezier_ctrl_impl : public ctrl
{
public:
bezier_ctrl_impl();
void curve(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4);
curve4& curve();
double x1() const { return m_poly.xn(0); }
double y1() const { return m_poly.yn(0); }
double x2() const { return m_poly.xn(1); }
double y2() const { return m_poly.yn(1); }
double x3() const { return m_poly.xn(2); }
double y3() const { return m_poly.yn(2); }
double x4() const { return m_poly.xn(3); }
double y4() const { return m_poly.yn(3); }
void line_width(double w) { m_stroke.width(w); }
double line_width() const { return m_stroke.width(); }
void point_radius(double r) { m_poly.point_radius(r); }
double point_radius() const { return m_poly.point_radius(); }
virtual bool in_rect(double x, double y) const;
virtual bool on_mouse_button_down(double x, double y);
virtual bool on_mouse_button_up(double x, double y);
virtual bool on_mouse_move(double x, double y, bool button_flag);
virtual bool on_arrow_keys(bool left, bool right, bool down, bool up);
// Vertex source interface
unsigned num_paths() { return 7; };
void rewind(unsigned id);
unsigned vertex(double* x, double* y);
private:
curve4 m_curve;
ellipse m_ellipse;
conv_stroke<curve4> m_stroke;
polygon_ctrl_impl m_poly;
unsigned m_idx;
};
//----------------------------------------------------------bezier_ctrl
template<class ColorT> class bezier_ctrl : public bezier_ctrl_impl
{
public:
bezier_ctrl() :
m_color(rgba(0.0, 0.0, 0.0))
{
}
void line_color(const ColorT& c) { m_color = c; }
const ColorT& color(unsigned i) const { return m_color; }
private:
bezier_ctrl(const bezier_ctrl<ColorT>&);
const bezier_ctrl<ColorT>& operator = (const bezier_ctrl<ColorT>&);
ColorT m_color;
};
}
#endif
+1
View File
@@ -31,6 +31,7 @@ namespace agg
{
public:
//--------------------------------------------------------------------
virtual ~ctrl() {}
ctrl(double x1, double y1, double x2, double y2, bool flip_y) :
m_x1(x1), m_y1(y1), m_x2(x2), m_y2(y2),
m_flip_y(flip_y),
+166
View File
@@ -0,0 +1,166 @@
//----------------------------------------------------------------------------
// Anti-Grain Geometry - Version 2.2
// Copyright (C) 2002-2004 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: [email protected]
// [email protected]
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
// classes polygon_ctrl_impl, polygon_ctrl
//
//----------------------------------------------------------------------------
#ifndef POLYGON_CTRL_INCLUDED
#define POLYGON_CTRL_INCLUDED
#include "agg_conv_stroke.h"
#include "agg_ellipse.h"
#include "agg_color_rgba.h"
#include "agg_ctrl.h"
namespace agg
{
class simple_polygon_vertex_source
{
public:
simple_polygon_vertex_source(const double* polygon, unsigned np,
bool roundoff = false,
bool close = true) :
m_polygon(polygon),
m_num_points(np),
m_vertex(0),
m_roundoff(roundoff),
m_close(close)
{
}
void close(bool f) { m_close = f; }
bool close() const { return m_close; }
void rewind(unsigned)
{
m_vertex = 0;
}
unsigned vertex(double* x, double* y)
{
if(m_vertex > m_num_points) return path_cmd_stop;
if(m_vertex == m_num_points)
{
++m_vertex;
return path_cmd_end_poly | (m_close ? path_flags_close : 0);
}
*x = m_polygon[m_vertex * 2];
*y = m_polygon[m_vertex * 2 + 1];
if(m_roundoff)
{
*x = floor(*x) + 0.5;
*y = floor(*y) + 0.5;
}
++m_vertex;
return (m_vertex == 1) ? path_cmd_move_to : path_cmd_line_to;
}
private:
const double* m_polygon;
unsigned m_num_points;
unsigned m_vertex;
bool m_roundoff;
bool m_close;
};
class polygon_ctrl_impl : public ctrl
{
public:
~polygon_ctrl_impl();
polygon_ctrl_impl(unsigned np, double point_radius=5);
unsigned num_points() const { return m_num_points; }
double xn(unsigned n) const { return m_polygon[n * 2]; }
double yn(unsigned n) const { return m_polygon[n * 2 + 1]; }
double& xn(unsigned n) { return m_polygon[n * 2]; }
double& yn(unsigned n) { return m_polygon[n * 2 + 1]; }
const double* polygon() const { return m_polygon; }
void line_width(double w) { m_stroke.width(w); }
double line_width() const { return m_stroke.width(); }
void point_radius(double r) { m_point_radius = r; }
double point_radius() const { return m_point_radius; }
void in_polygon_check(bool f) { m_in_polygon_check = f; }
bool in_polygon_check() const { return m_in_polygon_check; }
void close(bool f) { m_vs.close(f); }
bool close() const { return m_vs.close(); }
// Vertex source interface
unsigned num_paths() { return 1; }
void rewind(unsigned id);
unsigned vertex(double* x, double* y);
virtual bool in_rect(double x, double y) const;
virtual bool on_mouse_button_down(double x, double y);
virtual bool on_mouse_button_up(double x, double y);
virtual bool on_mouse_move(double x, double y, bool button_flag);
virtual bool on_arrow_keys(bool left, bool right, bool down, bool up);
private:
bool check_edge(unsigned i, double x, double y) const;
bool point_in_polygon(double x, double y) const;
double* m_polygon;
unsigned m_num_points;
int m_node;
int m_edge;
simple_polygon_vertex_source m_vs;
conv_stroke<simple_polygon_vertex_source> m_stroke;
ellipse m_ellipse;
double m_point_radius;
unsigned m_status;
double m_dx;
double m_dy;
bool m_in_polygon_check;
};
//----------------------------------------------------------polygon_ctrl
template<class ColorT> class polygon_ctrl : public polygon_ctrl_impl
{
public:
polygon_ctrl(unsigned np, double point_radius=5) :
polygon_ctrl_impl(np, point_radius),
m_color(rgba(0.0, 0.0, 0.0))
{
}
void line_color(const ColorT& c) { m_color = c; }
const ColorT& color(unsigned i) const { return m_color; }
private:
polygon_ctrl(const polygon_ctrl<ColorT>&);
const polygon_ctrl<ColorT>& operator = (const polygon_ctrl<ColorT>&);
ColorT m_color;
};
}
#endif
+3 -3
View File
@@ -58,8 +58,8 @@ namespace agg
void active_point(int i);
const double* spline() const { return m_spline_values; }
const unsigned char* spline8() const { return m_spline_values8; }
const double* spline() const { return m_spline_values; }
const int8u* spline8() const { return m_spline_values8; }
double value(double x) const;
void value(unsigned idx, double y);
void point(unsigned idx, double x, double y);
@@ -87,7 +87,7 @@ namespace agg
double m_yp[32];
bspline m_spline;
double m_spline_values[256];
unsigned char m_spline_values8[256];
int8u m_spline_values8[256];
double m_border_width;
double m_border_extra;
double m_curve_width;