summaryrefslogtreecommitdiff
path: root/agg/inc
diff options
context:
space:
mode:
authorPedro Giffuni <pfg@apache.org>2011-10-16 03:13:16 +0000
committerPedro Giffuni <pfg@apache.org>2011-10-16 03:13:16 +0000
commitef33060ab118d5ede5e96660dc05a3f961279392 (patch)
tree40e76ef24a102c6ec7f6113ea36b0baf2fd86cf6 /agg/inc
parent9d049b71d03c9073f77ab7f712c4551df3ae9a56 (diff)
i118508 - Update Anti-Grain Geometry (AGG) to version 2.4. Disable in configure since this is not really used by anything.
Diffstat (limited to 'agg/inc')
-rwxr-xr-xagg/inc/agg_alpha_mask_u8.h50
-rwxr-xr-xagg/inc/agg_arc.h2
-rwxr-xr-xagg/inc/agg_array.h454
-rwxr-xr-xagg/inc/agg_arrowhead.h4
-rwxr-xr-xagg/inc/agg_basics.h233
-rwxr-xr-xagg/inc/agg_bezier_arc.h7
-rwxr-xr-xagg/inc/agg_bitset_iterator.h2
-rwxr-xr-xagg/inc/agg_bounding_rect.h2
-rwxr-xr-xagg/inc/agg_bspline.h17
-rwxr-xr-xagg/inc/agg_clip_liang_barsky.h128
-rwxr-xr-xagg/inc/agg_color_gray.h90
-rwxr-xr-xagg/inc/agg_color_rgba.h233
-rwxr-xr-xagg/inc/agg_config.h21
-rwxr-xr-xagg/inc/agg_conv_adaptor_vcgen.h22
-rwxr-xr-xagg/inc/agg_conv_adaptor_vpgen.h13
-rwxr-xr-xagg/inc/agg_conv_bspline.h2
-rwxr-xr-xagg/inc/agg_conv_clip_polygon.h8
-rwxr-xr-xagg/inc/agg_conv_clip_polyline.h8
-rwxr-xr-xagg/inc/agg_conv_close_polygon.h13
-rwxr-xr-xagg/inc/agg_conv_concat.h17
-rwxr-xr-xagg/inc/agg_conv_contour.h6
-rwxr-xr-xagg/inc/agg_conv_curve.h95
-rwxr-xr-xagg/inc/agg_conv_dash.h2
-rwxr-xr-xagg/inc/agg_conv_gpc.h39
-rwxr-xr-xagg/inc/agg_conv_marker.h10
-rwxr-xr-xagg/inc/agg_conv_marker_adaptor.h2
-rwxr-xr-xagg/inc/agg_conv_segmentator.h2
-rwxr-xr-xagg/inc/agg_conv_shorten_path.h2
-rwxr-xr-xagg/inc/agg_conv_smooth_poly1.h2
-rwxr-xr-xagg/inc/agg_conv_stroke.h14
-rwxr-xr-xagg/inc/agg_conv_transform.h15
-rwxr-xr-xagg/inc/agg_conv_unclose_polygon.h13
-rwxr-xr-xagg/inc/agg_curves.h623
-rwxr-xr-xagg/inc/agg_dda_line.h32
-rwxr-xr-xagg/inc/agg_ellipse.h45
-rwxr-xr-xagg/inc/agg_ellipse_bresenham.h2
-rwxr-xr-xagg/inc/agg_embedded_raster_fonts.h2
-rwxr-xr-xagg/inc/agg_font_cache_manager.h54
-rwxr-xr-xagg/inc/agg_gamma_functions.h2
-rwxr-xr-xagg/inc/agg_gamma_lut.h29
-rwxr-xr-xagg/inc/agg_glyph_raster_bin.h2
-rwxr-xr-xagg/inc/agg_gsv_text.h59
-rw-r--r--agg/inc/agg_image_accessors.h481
-rwxr-xr-xagg/inc/agg_image_filters.h55
-rwxr-xr-xagg/inc/agg_line_aa_basics.h85
-rwxr-xr-xagg/inc/agg_math.h242
-rwxr-xr-xagg/inc/agg_math_stroke.h596
-rw-r--r--agg/inc/agg_path_length.h65
-rwxr-xr-xagg/inc/agg_path_storage.h1531
-rwxr-xr-xagg/inc/agg_path_storage_integer.h27
-rwxr-xr-xagg/inc/agg_pattern_filters_rgba.h12
-rwxr-xr-xagg/inc/agg_pixfmt_amask_adaptor.h131
-rwxr-xr-xagg/inc/agg_pixfmt_gray.h493
-rwxr-xr-xagg/inc/agg_pixfmt_rgb.h502
-rwxr-xr-xagg/inc/agg_pixfmt_rgb_packed.h410
-rwxr-xr-xagg/inc/agg_pixfmt_rgba.h2666
-rw-r--r--agg/inc/agg_rasterizer_cells_aa.h754
-rw-r--r--agg/inc/agg_rasterizer_compound_aa.h698
-rwxr-xr-xagg/inc/agg_rasterizer_outline.h17
-rwxr-xr-xagg/inc/agg_rasterizer_outline_aa.h289
-rwxr-xr-xagg/inc/agg_rasterizer_scanline_aa.h689
-rw-r--r--agg/inc/agg_rasterizer_sl_clip.h351
-rwxr-xr-xagg/inc/agg_render_scanlines.h66
-rwxr-xr-xagg/inc/agg_renderer_base.h324
-rwxr-xr-xagg/inc/agg_renderer_markers.h7
-rwxr-xr-xagg/inc/agg_renderer_mclip.h130
-rwxr-xr-xagg/inc/agg_renderer_outline_aa.h574
-rwxr-xr-xagg/inc/agg_renderer_outline_image.h199
-rwxr-xr-xagg/inc/agg_renderer_primitives.h10
-rwxr-xr-xagg/inc/agg_renderer_raster_text.h8
-rwxr-xr-xagg/inc/agg_renderer_scanline.h998
-rwxr-xr-xagg/inc/agg_rendering_buffer.h261
-rwxr-xr-xagg/inc/agg_rendering_buffer_dynarow.h131
-rwxr-xr-xagg/inc/agg_rounded_rect.h9
-rwxr-xr-xagg/inc/agg_scanline_bin.h277
-rwxr-xr-xagg/inc/agg_scanline_boolean_algebra.h68
-rwxr-xr-xagg/inc/agg_scanline_p.h364
-rwxr-xr-xagg/inc/agg_scanline_storage_aa.h159
-rwxr-xr-xagg/inc/agg_scanline_storage_bin.h139
-rwxr-xr-xagg/inc/agg_scanline_u.h454
-rwxr-xr-xagg/inc/agg_shorten_path.h2
-rwxr-xr-xagg/inc/agg_simul_eq.h2
-rwxr-xr-xagg/inc/agg_span_allocator.h44
-rwxr-xr-xagg/inc/agg_span_converter.h25
-rwxr-xr-xagg/inc/agg_span_generator.h50
-rwxr-xr-xagg/inc/agg_span_gouraud.h18
-rwxr-xr-xagg/inc/agg_span_gouraud_gray.h150
-rwxr-xr-xagg/inc/agg_span_gouraud_rgba.h199
-rwxr-xr-xagg/inc/agg_span_gradient.h204
-rwxr-xr-xagg/inc/agg_span_gradient_alpha.h23
-rwxr-xr-xagg/inc/agg_span_image_filter.h238
-rwxr-xr-xagg/inc/agg_span_image_filter_gray.h793
-rwxr-xr-xagg/inc/agg_span_image_filter_rgb.h972
-rwxr-xr-xagg/inc/agg_span_image_filter_rgba.h1004
-rwxr-xr-xagg/inc/agg_span_image_resample.h180
-rwxr-xr-xagg/inc/agg_span_image_resample_gray.h359
-rwxr-xr-xagg/inc/agg_span_image_resample_rgb.h393
-rwxr-xr-xagg/inc/agg_span_image_resample_rgba.h393
-rwxr-xr-xagg/inc/agg_span_interpolator_adaptor.h2
-rwxr-xr-xagg/inc/agg_span_interpolator_linear.h40
-rwxr-xr-xagg/inc/agg_span_interpolator_persp.h58
-rwxr-xr-xagg/inc/agg_span_interpolator_trans.h19
-rwxr-xr-xagg/inc/agg_span_pattern.h278
-rwxr-xr-xagg/inc/agg_span_pattern_filter_gray.h472
-rwxr-xr-xagg/inc/agg_span_pattern_filter_rgb.h568
-rwxr-xr-xagg/inc/agg_span_pattern_filter_rgba.h584
-rw-r--r--agg/inc/agg_span_pattern_gray.h93
-rwxr-xr-xagg/inc/agg_span_pattern_resample_gray.h320
-rwxr-xr-xagg/inc/agg_span_pattern_resample_rgb.h346
-rwxr-xr-xagg/inc/agg_span_pattern_resample_rgba.h354
-rwxr-xr-xagg/inc/agg_span_pattern_rgb.h141
-rwxr-xr-xagg/inc/agg_span_pattern_rgba.h81
-rwxr-xr-xagg/inc/agg_span_solid.h24
-rwxr-xr-xagg/inc/agg_span_subdiv_adaptor.h12
-rwxr-xr-xagg/inc/agg_trans_affine.h302
-rwxr-xr-xagg/inc/agg_trans_bilinear.h2
-rwxr-xr-xagg/inc/agg_trans_double_path.h2
-rwxr-xr-xagg/inc/agg_trans_perspective.h749
-rwxr-xr-xagg/inc/agg_trans_single_path.h2
-rwxr-xr-xagg/inc/agg_trans_viewport.h119
-rwxr-xr-xagg/inc/agg_trans_warp_magnifier.h7
-rwxr-xr-xagg/inc/agg_vcgen_bspline.h6
-rwxr-xr-xagg/inc/agg_vcgen_contour.h68
-rwxr-xr-xagg/inc/agg_vcgen_dash.h12
-rwxr-xr-xagg/inc/agg_vcgen_markers_term.h12
-rwxr-xr-xagg/inc/agg_vcgen_smooth_poly1.h4
-rwxr-xr-xagg/inc/agg_vcgen_stroke.h66
-rwxr-xr-xagg/inc/agg_vcgen_vertex_sequence.h4
-rwxr-xr-xagg/inc/agg_vertex_sequence.h16
-rwxr-xr-xagg/inc/agg_vpgen_clip_polygon.h12
-rwxr-xr-xagg/inc/agg_vpgen_clip_polyline.h61
-rwxr-xr-xagg/inc/agg_vpgen_segmentator.h2
132 files changed, 15617 insertions, 10920 deletions
diff --git a/agg/inc/agg_alpha_mask_u8.h b/agg/inc/agg_alpha_mask_u8.h
index b7e5c926092f..321defebc5ed 100755
--- a/agg/inc/agg_alpha_mask_u8.h
+++ b/agg/inc/agg_alpha_mask_u8.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -49,7 +49,7 @@ namespace agg
public:
typedef int8u cover_type;
typedef alpha_mask_u8<Step, Offset, MaskF> self_type;
- enum
+ enum cover_scale_e
{
cover_shift = 8,
cover_none = 0,
@@ -57,7 +57,7 @@ namespace agg
};
alpha_mask_u8() : m_rbuf(0) {}
- alpha_mask_u8(rendering_buffer& rbuf) : m_rbuf(&rbuf) {}
+ explicit alpha_mask_u8(rendering_buffer& rbuf) : m_rbuf(&rbuf) {}
void attach(rendering_buffer& rbuf) { m_rbuf = &rbuf; }
@@ -70,10 +70,10 @@ namespace agg
{
if(x >= 0 && y >= 0 &&
x < (int)m_rbuf->width() &&
- y <= (int)m_rbuf->height())
+ y < (int)m_rbuf->height())
{
return (cover_type)m_mask_function.calculate(
- m_rbuf->row(y) + x * Step + Offset);
+ m_rbuf->row_ptr(y) + x * Step + Offset);
}
return 0;
}
@@ -83,11 +83,11 @@ namespace agg
{
if(x >= 0 && y >= 0 &&
x < (int)m_rbuf->width() &&
- y <= (int)m_rbuf->height())
+ y < (int)m_rbuf->height())
{
- return (cover_type)((val *
+ return (cover_type)((cover_full + val *
m_mask_function.calculate(
- m_rbuf->row(y) + x * Step + Offset)) >>
+ m_rbuf->row_ptr(y) + x * Step + Offset)) >>
cover_shift);
}
return 0;
@@ -134,7 +134,7 @@ namespace agg
memset(covers + count, 0, rest * sizeof(cover_type));
}
- const int8u* mask = m_rbuf->row(y) + x * Step + Offset;
+ const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
do
{
*covers++ = (cover_type)m_mask_function.calculate(mask);
@@ -184,10 +184,10 @@ namespace agg
memset(covers + count, 0, rest * sizeof(cover_type));
}
- const int8u* mask = m_rbuf->row(y) + x * Step + Offset;
+ const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
do
{
- *covers = (cover_type)(((*covers) *
+ *covers = (cover_type)((cover_full + (*covers) *
m_mask_function.calculate(mask)) >>
cover_shift);
++covers;
@@ -236,7 +236,7 @@ namespace agg
memset(covers + count, 0, rest * sizeof(cover_type));
}
- const int8u* mask = m_rbuf->row(y) + x * Step + Offset;
+ const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
do
{
*covers++ = (cover_type)m_mask_function.calculate(mask);
@@ -285,10 +285,10 @@ namespace agg
memset(covers + count, 0, rest * sizeof(cover_type));
}
- const int8u* mask = m_rbuf->row(y) + x * Step + Offset;
+ const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
do
{
- *covers = (cover_type)(((*covers) *
+ *covers = (cover_type)((cover_full + (*covers) *
m_mask_function.calculate(mask)) >>
cover_shift);
++covers;
@@ -353,7 +353,7 @@ namespace agg
public:
typedef int8u cover_type;
typedef amask_no_clip_u8<Step, Offset, MaskF> self_type;
- enum
+ enum cover_scale_e
{
cover_shift = 8,
cover_none = 0,
@@ -361,7 +361,7 @@ namespace agg
};
amask_no_clip_u8() : m_rbuf(0) {}
- amask_no_clip_u8(rendering_buffer& rbuf) : m_rbuf(&rbuf) {}
+ explicit amask_no_clip_u8(rendering_buffer& rbuf) : m_rbuf(&rbuf) {}
void attach(rendering_buffer& rbuf) { m_rbuf = &rbuf; }
@@ -373,16 +373,16 @@ namespace agg
cover_type pixel(int x, int y) const
{
return (cover_type)m_mask_function.calculate(
- m_rbuf->row(y) + x * Step + Offset);
+ m_rbuf->row_ptr(y) + x * Step + Offset);
}
//--------------------------------------------------------------------
cover_type combine_pixel(int x, int y, cover_type val) const
{
- return (cover_type)((val *
+ return (cover_type)((cover_full + val *
m_mask_function.calculate(
- m_rbuf->row(y) + x * Step + Offset)) >>
+ m_rbuf->row_ptr(y) + x * Step + Offset)) >>
cover_shift);
}
@@ -390,7 +390,7 @@ namespace agg
//--------------------------------------------------------------------
void fill_hspan(int x, int y, cover_type* dst, int num_pix) const
{
- const int8u* mask = m_rbuf->row(y) + x * Step + Offset;
+ const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
do
{
*dst++ = (cover_type)m_mask_function.calculate(mask);
@@ -404,10 +404,10 @@ namespace agg
//--------------------------------------------------------------------
void combine_hspan(int x, int y, cover_type* dst, int num_pix) const
{
- const int8u* mask = m_rbuf->row(y) + x * Step + Offset;
+ const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
do
{
- *dst = (cover_type)(((*dst) *
+ *dst = (cover_type)((cover_full + (*dst) *
m_mask_function.calculate(mask)) >>
cover_shift);
++dst;
@@ -420,7 +420,7 @@ namespace agg
//--------------------------------------------------------------------
void fill_vspan(int x, int y, cover_type* dst, int num_pix) const
{
- const int8u* mask = m_rbuf->row(y) + x * Step + Offset;
+ const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
do
{
*dst++ = (cover_type)m_mask_function.calculate(mask);
@@ -433,10 +433,10 @@ namespace agg
//--------------------------------------------------------------------
void combine_vspan(int x, int y, cover_type* dst, int num_pix) const
{
- const int8u* mask = m_rbuf->row(y) + x * Step + Offset;
+ const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset;
do
{
- *dst = (cover_type)(((*dst) *
+ *dst = (cover_type)((cover_full + (*dst) *
m_mask_function.calculate(mask)) >>
cover_shift);
++dst;
diff --git a/agg/inc/agg_arc.h b/agg/inc/agg_arc.h
index 80b148d910d0..2b872490678f 100755
--- a/agg/inc/agg_arc.h
+++ b/agg/inc/agg_arc.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
diff --git a/agg/inc/agg_array.h b/agg/inc/agg_array.h
index 2970181c4510..a0b94408d425 100755
--- a/agg/inc/agg_array.h
+++ b/agg/inc/agg_array.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -22,26 +22,27 @@
namespace agg
{
-
-
//-------------------------------------------------------pod_array_adaptor
template<class T> class pod_array_adaptor
{
public:
typedef T value_type;
- pod_array_adaptor(T* array, unsigned _size) :
- m_array(array), m_size(_size) {}
+ pod_array_adaptor(T* array, unsigned size) :
+ m_array(array), m_size(size) {}
unsigned size() const { return m_size; }
- const T& operator [] (unsigned idx) const { return m_array[idx]; }
- T& operator [] (unsigned idx) { return m_array[idx]; }
+ const T& operator [] (unsigned i) const { return m_array[i]; }
+ T& operator [] (unsigned i) { return m_array[i]; }
+ const T& at(unsigned i) const { return m_array[i]; }
+ T& at(unsigned i) { return m_array[i]; }
+ T value_at(unsigned i) const { return m_array[i]; }
+
private:
T* m_array;
unsigned m_size;
};
-
//---------------------------------------------------------pod_auto_array
template<class T, unsigned Size> class pod_auto_array
{
@@ -64,46 +65,148 @@ namespace agg
static unsigned size() { return Size; }
const T& operator [] (unsigned i) const { return m_array[i]; }
T& operator [] (unsigned i) { return m_array[i]; }
+ const T& at(unsigned i) const { return m_array[i]; }
+ T& at(unsigned i) { return m_array[i]; }
+ T value_at(unsigned i) const { return m_array[i]; }
+
private:
T m_array[Size];
};
+ //--------------------------------------------------------pod_auto_vector
+ template<class T, unsigned Size> class pod_auto_vector
+ {
+ public:
+ typedef T value_type;
+ typedef pod_auto_vector<T, Size> self_type;
+
+ pod_auto_vector() : m_size(0) {}
+ void remove_all() { m_size = 0; }
+ void clear() { m_size = 0; }
+ void add(const T& v) { m_array[m_size++] = v; }
+ void push_back(const T& v) { m_array[m_size++] = v; }
+ void inc_size(unsigned size) { m_size += size; }
+
+ unsigned size() const { return m_size; }
+ const T& operator [] (unsigned i) const { return m_array[i]; }
+ T& operator [] (unsigned i) { return m_array[i]; }
+ const T& at(unsigned i) const { return m_array[i]; }
+ T& at(unsigned i) { return m_array[i]; }
+ T value_at(unsigned i) const { return m_array[i]; }
+
+ private:
+ T m_array[Size];
+ unsigned m_size;
+ };
//---------------------------------------------------------------pod_array
+ template<class T> class pod_array
+ {
+ public:
+ typedef T value_type;
+ typedef pod_array<T> self_type;
+
+ ~pod_array() { pod_allocator<T>::deallocate(m_array, m_size); }
+ pod_array() : m_array(0), m_size(0) {}
+
+ pod_array(unsigned size) :
+ m_array(pod_allocator<T>::allocate(size)),
+ m_size(size)
+ {}
+
+ pod_array(const self_type& v) :
+ m_array(pod_allocator<T>::allocate(v.m_size)),
+ m_size(v.m_size)
+ {
+ memcpy(m_array, v.m_array, sizeof(T) * m_size);
+ }
+
+ void resize(unsigned size)
+ {
+ if(size != m_size)
+ {
+ pod_allocator<T>::deallocate(m_array, m_size);
+ m_array = pod_allocator<T>::allocate(m_size = size);
+ }
+ }
+ const self_type& operator = (const self_type& v)
+ {
+ resize(v.size());
+ memcpy(m_array, v.m_array, sizeof(T) * m_size);
+ return *this;
+ }
+
+ unsigned size() const { return m_size; }
+ const T& operator [] (unsigned i) const { return m_array[i]; }
+ T& operator [] (unsigned i) { return m_array[i]; }
+ const T& at(unsigned i) const { return m_array[i]; }
+ T& at(unsigned i) { return m_array[i]; }
+ T value_at(unsigned i) const { return m_array[i]; }
+
+ const T* data() const { return m_array; }
+ T* data() { return m_array; }
+ private:
+ T* m_array;
+ unsigned m_size;
+ };
+
+
+
+ //--------------------------------------------------------------pod_vector
// A simple class template to store Plain Old Data, a vector
// of a fixed size. The data is continous in memory
//------------------------------------------------------------------------
- template<class T> class pod_array
+ template<class T> class pod_vector
{
public:
typedef T value_type;
- ~pod_array() { delete [] m_array; }
- pod_array() : m_size(0), m_capacity(0), m_array(0) {}
- pod_array(unsigned cap, unsigned extra_tail=0);
+ ~pod_vector() { pod_allocator<T>::deallocate(m_array, m_capacity); }
+ pod_vector() : m_size(0), m_capacity(0), m_array(0) {}
+ pod_vector(unsigned cap, unsigned extra_tail=0);
// Copying
- pod_array(const pod_array<T>&);
- const pod_array<T>& operator = (const pod_array<T>&);
+ pod_vector(const pod_vector<T>&);
+ const pod_vector<T>& operator = (const pod_vector<T>&);
- unsigned capacity() const { return m_capacity; }
+ // Set new capacity. All data is lost, size is set to zero.
void capacity(unsigned cap, unsigned extra_tail=0);
+ unsigned capacity() const { return m_capacity; }
+ // Allocate n elements. All data is lost,
+ // but elements can be accessed in range 0...size-1.
+ void allocate(unsigned size, unsigned extra_tail=0);
+
+ // Resize keeping the content.
void resize(unsigned new_size);
- 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 byte_size() const { return m_size * sizeof(T); }
+ void zero()
+ {
+ memset(m_array, 0, sizeof(T) * m_size);
+ }
+
+ void add(const T& v) { m_array[m_size++] = v; }
+ void push_back(const T& v) { m_array[m_size++] = v; }
+ void insert_at(unsigned pos, const T& val);
+ void inc_size(unsigned size) { m_size += 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]; }
+ const T& operator [] (unsigned i) const { return m_array[i]; }
+ T& operator [] (unsigned i) { return m_array[i]; }
+ const T& at(unsigned i) const { return m_array[i]; }
+ T& at(unsigned i) { return m_array[i]; }
+ T value_at(unsigned i) const { return m_array[i]; }
+
+ const T* data() const { return m_array; }
+ T* data() { return m_array; }
void remove_all() { m_size = 0; }
+ void clear() { m_size = 0; }
void cut_at(unsigned num) { if(num < m_size) m_size = num; }
private:
@@ -114,28 +217,37 @@ namespace agg
//------------------------------------------------------------------------
template<class T>
- void pod_array<T>::capacity(unsigned cap, unsigned extra_tail)
+ void pod_vector<T>::capacity(unsigned cap, unsigned extra_tail)
{
m_size = 0;
if(cap > m_capacity)
{
- delete [] m_array;
+ pod_allocator<T>::deallocate(m_array, m_capacity);
m_capacity = cap + extra_tail;
- m_array = m_capacity ? new T [m_capacity] : 0;
+ m_array = m_capacity ? pod_allocator<T>::allocate(m_capacity) : 0;
}
}
//------------------------------------------------------------------------
template<class T>
- void pod_array<T>::resize(unsigned new_size)
+ void pod_vector<T>::allocate(unsigned size, unsigned extra_tail)
+ {
+ capacity(size, extra_tail);
+ m_size = size;
+ }
+
+
+ //------------------------------------------------------------------------
+ template<class T>
+ void pod_vector<T>::resize(unsigned new_size)
{
if(new_size > m_size)
{
if(new_size > m_capacity)
{
- T* data = new T[new_size];
+ T* data = pod_allocator<T>::allocate(new_size);
memcpy(data, m_array, m_size * sizeof(T));
- delete [] m_array;
+ pod_allocator<T>::deallocate(m_array, m_capacity);
m_array = data;
}
}
@@ -146,47 +258,61 @@ namespace agg
}
//------------------------------------------------------------------------
- template<class T> pod_array<T>::pod_array(unsigned cap, unsigned extra_tail) :
- m_size(cap), m_capacity(cap + extra_tail), m_array(new T[m_capacity]) {}
+ template<class T> pod_vector<T>::pod_vector(unsigned cap, unsigned extra_tail) :
+ m_size(0),
+ m_capacity(cap + extra_tail),
+ m_array(pod_allocator<T>::allocate(m_capacity)) {}
//------------------------------------------------------------------------
- template<class T> pod_array<T>::pod_array(const pod_array<T>& v) :
+ template<class T> pod_vector<T>::pod_vector(const pod_vector<T>& v) :
m_size(v.m_size),
m_capacity(v.m_capacity),
- m_array(v.m_capacity ? new T [v.m_capacity] : 0)
+ m_array(v.m_capacity ? pod_allocator<T>::allocate(v.m_capacity) : 0)
{
memcpy(m_array, v.m_array, sizeof(T) * v.m_size);
}
//------------------------------------------------------------------------
- template<class T> const pod_array<T>&
- pod_array<T>::operator = (const pod_array<T>&v)
+ template<class T> const pod_vector<T>&
+ pod_vector<T>::operator = (const pod_vector<T>&v)
{
- capacity(v.m_capacity);
+ allocate(v.m_size);
if(v.m_size) memcpy(m_array, v.m_array, sizeof(T) * v.m_size);
return *this;
}
//------------------------------------------------------------------------
- template<class T> void pod_array<T>::serialize(int8u* ptr) const
+ template<class T> void pod_vector<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)
+ void pod_vector<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));
+ byte_size /= sizeof(T);
+ allocate(byte_size);
+ if(byte_size) memcpy(m_array, data, byte_size * sizeof(T));
}
+ //------------------------------------------------------------------------
+ template<class T>
+ void pod_vector<T>::insert_at(unsigned pos, const T& val)
+ {
+ if(pos >= m_size)
+ {
+ m_array[m_size] = val;
+ }
+ else
+ {
+ memmove(m_array + pos + 1, m_array + pos, (m_size - pos) * sizeof(T));
+ m_array[pos] = val;
+ }
+ ++m_size;
+ }
-
-
-
- //---------------------------------------------------------------pod_deque
+ //---------------------------------------------------------------pod_bvector
// A simple class template to store Plain Old Data, similar to std::deque
// It doesn't reallocate memory but instead, uses blocks of data of size
// of (1 << S), that is, power of two. The data is NOT contiguous in memory,
@@ -197,10 +323,10 @@ namespace agg
// of increment to reallocate the pointer buffer. See the second constructor.
// By default, the incremeent value equals (1 << S), i.e., the block size.
//------------------------------------------------------------------------
- template<class T, unsigned S=6> class pod_deque
+ template<class T, unsigned S=6> class pod_bvector
{
public:
- enum
+ enum block_scale_e
{
block_shift = S,
block_size = 1 << block_shift,
@@ -209,18 +335,20 @@ namespace agg
typedef T value_type;
- ~pod_deque();
- pod_deque();
- pod_deque(unsigned block_ptr_inc);
+ ~pod_bvector();
+ pod_bvector();
+ pod_bvector(unsigned block_ptr_inc);
// Copying
- pod_deque(const pod_deque<T, S>& v);
- const pod_deque<T, S>& operator = (const pod_deque<T, S>& v);
+ pod_bvector(const pod_bvector<T, S>& v);
+ const pod_bvector<T, S>& operator = (const pod_bvector<T, S>& v);
void remove_all() { m_size = 0; }
- void free_all() { free_tail(0); }
+ void clear() { m_size = 0; }
+ void free_all() { free_tail(0); }
void free_tail(unsigned size);
void add(const T& val);
+ void push_back(const T& val) { add(val); }
void modify_last(const T& val);
void remove_last();
@@ -243,21 +371,36 @@ namespace agg
}
}
- void cut_at(unsigned _size)
+ void cut_at(unsigned size)
{
- if(_size < m_size) m_size = _size;
+ if(size < m_size) m_size = size;
}
unsigned size() const { return m_size; }
- const T& operator [] (unsigned idx) const
+ const T& operator [] (unsigned i) const
+ {
+ return m_blocks[i >> block_shift][i & block_mask];
+ }
+
+ T& operator [] (unsigned i)
+ {
+ return m_blocks[i >> block_shift][i & block_mask];
+ }
+
+ const T& at(unsigned i) const
{
- return m_blocks[idx >> block_shift][idx & block_mask];
+ return m_blocks[i >> block_shift][i & block_mask];
}
- T& operator [] (unsigned idx)
+ T& at(unsigned i)
{
- return m_blocks[idx >> block_shift][idx & block_mask];
+ return m_blocks[i >> block_shift][i & block_mask];
+ }
+
+ T value_at(unsigned i) const
+ {
+ return m_blocks[i >> block_shift][i & block_mask];
}
const T& curr(unsigned idx) const
@@ -368,39 +511,45 @@ namespace agg
//------------------------------------------------------------------------
- template<class T, unsigned S> pod_deque<T, S>::~pod_deque()
+ template<class T, unsigned S> pod_bvector<T, S>::~pod_bvector()
{
if(m_num_blocks)
{
T** blk = m_blocks + m_num_blocks - 1;
while(m_num_blocks--)
{
- delete [] *blk;
+ pod_allocator<T>::deallocate(*blk, block_size);
--blk;
}
- delete [] m_blocks;
}
+ pod_allocator<T*>::deallocate(m_blocks, m_max_blocks);
}
//------------------------------------------------------------------------
template<class T, unsigned S>
- void pod_deque<T, S>::free_tail(unsigned _size)
+ void pod_bvector<T, S>::free_tail(unsigned size)
{
- if(_size < m_size)
+ if(size < m_size)
{
- unsigned nb = (_size + block_mask) >> block_shift;
+ unsigned nb = (size + block_mask) >> block_shift;
while(m_num_blocks > nb)
{
- delete [] m_blocks[--m_num_blocks];
+ pod_allocator<T>::deallocate(m_blocks[--m_num_blocks], block_size);
}
- m_size = _size;
+ if(m_num_blocks == 0)
+ {
+ pod_allocator<T*>::deallocate(m_blocks, m_max_blocks);
+ m_blocks = 0;
+ m_max_blocks = 0;
+ }
+ m_size = size;
}
}
//------------------------------------------------------------------------
- template<class T, unsigned S> pod_deque<T, S>::pod_deque() :
+ template<class T, unsigned S> pod_bvector<T, S>::pod_bvector() :
m_size(0),
m_num_blocks(0),
m_max_blocks(0),
@@ -412,7 +561,7 @@ namespace agg
//------------------------------------------------------------------------
template<class T, unsigned S>
- pod_deque<T, S>::pod_deque(unsigned block_ptr_inc) :
+ pod_bvector<T, S>::pod_bvector(unsigned block_ptr_inc) :
m_size(0),
m_num_blocks(0),
m_max_blocks(0),
@@ -424,17 +573,19 @@ namespace agg
//------------------------------------------------------------------------
template<class T, unsigned S>
- pod_deque<T, S>::pod_deque(const pod_deque<T, S>& v) :
+ pod_bvector<T, S>::pod_bvector(const pod_bvector<T, S>& v) :
m_size(v.m_size),
m_num_blocks(v.m_num_blocks),
m_max_blocks(v.m_max_blocks),
- m_blocks(v.m_max_blocks ? new T* [v.m_max_blocks] : 0),
+ m_blocks(v.m_max_blocks ?
+ pod_allocator<T*>::allocate(v.m_max_blocks) :
+ 0),
m_block_ptr_inc(v.m_block_ptr_inc)
{
unsigned i;
for(i = 0; i < v.m_num_blocks; ++i)
{
- m_blocks[i] = new T [block_size];
+ m_blocks[i] = pod_allocator<T>::allocate(block_size);
memcpy(m_blocks[i], v.m_blocks[i], block_size * sizeof(T));
}
}
@@ -442,7 +593,8 @@ namespace agg
//------------------------------------------------------------------------
template<class T, unsigned S>
- const pod_deque<T, S>& pod_deque<T, S>::operator = (const pod_deque<T, S>& v)
+ const pod_bvector<T, S>&
+ pod_bvector<T, S>::operator = (const pod_bvector<T, S>& v)
{
unsigned i;
for(i = m_num_blocks; i < v.m_num_blocks; ++i)
@@ -460,11 +612,11 @@ namespace agg
//------------------------------------------------------------------------
template<class T, unsigned S>
- void pod_deque<T, S>::allocate_block(unsigned nb)
+ void pod_bvector<T, S>::allocate_block(unsigned nb)
{
if(nb >= m_max_blocks)
{
- T** new_blocks = new T* [m_max_blocks + m_block_ptr_inc];
+ T** new_blocks = pod_allocator<T*>::allocate(m_max_blocks + m_block_ptr_inc);
if(m_blocks)
{
@@ -472,12 +624,12 @@ namespace agg
m_blocks,
m_num_blocks * sizeof(T*));
- delete [] m_blocks;
+ pod_allocator<T*>::deallocate(m_blocks, m_max_blocks);
}
m_blocks = new_blocks;
m_max_blocks += m_block_ptr_inc;
}
- m_blocks[nb] = new T [block_size];
+ m_blocks[nb] = pod_allocator<T>::allocate(block_size);
m_num_blocks++;
}
@@ -485,7 +637,7 @@ namespace agg
//------------------------------------------------------------------------
template<class T, unsigned S>
- inline T* pod_deque<T, S>::data_ptr()
+ inline T* pod_bvector<T, S>::data_ptr()
{
unsigned nb = m_size >> block_shift;
if(nb >= m_num_blocks)
@@ -499,7 +651,7 @@ namespace agg
//------------------------------------------------------------------------
template<class T, unsigned S>
- inline void pod_deque<T, S>::add(const T& val)
+ inline void pod_bvector<T, S>::add(const T& val)
{
*data_ptr() = val;
++m_size;
@@ -508,7 +660,7 @@ namespace agg
//------------------------------------------------------------------------
template<class T, unsigned S>
- inline void pod_deque<T, S>::remove_last()
+ inline void pod_bvector<T, S>::remove_last()
{
if(m_size) --m_size;
}
@@ -516,7 +668,7 @@ namespace agg
//------------------------------------------------------------------------
template<class T, unsigned S>
- void pod_deque<T, S>::modify_last(const T& val)
+ void pod_bvector<T, S>::modify_last(const T& val)
{
remove_last();
add(val);
@@ -525,7 +677,7 @@ namespace agg
//------------------------------------------------------------------------
template<class T, unsigned S>
- int pod_deque<T, S>::allocate_continuous_block(unsigned num_elements)
+ int pod_bvector<T, S>::allocate_continuous_block(unsigned num_elements)
{
if(num_elements < block_size)
{
@@ -555,7 +707,7 @@ namespace agg
//------------------------------------------------------------------------
template<class T, unsigned S>
- unsigned pod_deque<T, S>::byte_size() const
+ unsigned pod_bvector<T, S>::byte_size() const
{
return m_size * sizeof(T);
}
@@ -563,7 +715,7 @@ namespace agg
//------------------------------------------------------------------------
template<class T, unsigned S>
- void pod_deque<T, S>::serialize(int8u* ptr) const
+ void pod_bvector<T, S>::serialize(int8u* ptr) const
{
unsigned i;
for(i = 0; i < m_size; i++)
@@ -575,11 +727,11 @@ namespace agg
//------------------------------------------------------------------------
template<class T, unsigned S>
- void pod_deque<T, S>::deserialize(const int8u* data, unsigned _byte_size)
+ void pod_bvector<T, S>::deserialize(const int8u* data, unsigned byte_size)
{
remove_all();
- _byte_size /= sizeof(T);
- for(unsigned i = 0; i < _byte_size; ++i)
+ byte_size /= sizeof(T);
+ for(unsigned i = 0; i < byte_size; ++i)
{
T* ptr = data_ptr();
memcpy(ptr, data, sizeof(T));
@@ -592,16 +744,16 @@ namespace agg
// 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)
+ void pod_bvector<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)
+ byte_size /= sizeof(T);
+ for(unsigned i = 0; i < byte_size; ++i)
{
if(start + i < m_size)
{
@@ -618,7 +770,7 @@ namespace agg
}
- //-----------------------------------------------------------pod_allocator
+ //---------------------------------------------------------block_allocator
// Allocator for arbitrary POD data. Most usable in different cache
// systems for efficient memory allocations.
// Memory is allocated with blocks of fixed size ("block_size" in
@@ -626,20 +778,26 @@ namespace agg
// creates a new block of the required size. However, the most efficient
// use is when the average reqired size is much less than the block size.
//------------------------------------------------------------------------
- class pod_allocator
+ class block_allocator
{
+ struct block_type
+ {
+ int8u* data;
+ unsigned size;
+ };
+
public:
void remove_all()
{
if(m_num_blocks)
{
- int8u** blk = m_blocks + m_num_blocks - 1;
+ block_type* blk = m_blocks + m_num_blocks - 1;
while(m_num_blocks--)
{
- delete [] *blk;
+ pod_allocator<int8u>::deallocate(blk->data, blk->size);
--blk;
}
- delete [] m_blocks;
+ pod_allocator<block_type>::deallocate(m_blocks, m_max_blocks);
}
m_num_blocks = 0;
m_max_blocks = 0;
@@ -648,12 +806,12 @@ namespace agg
m_rest = 0;
}
- ~pod_allocator()
+ ~block_allocator()
{
remove_all();
}
- pod_allocator(unsigned block_size, unsigned block_ptr_inc=256-8) :
+ block_allocator(unsigned block_size, unsigned block_ptr_inc=256-8) :
m_block_size(block_size),
m_block_ptr_inc(block_ptr_inc),
m_num_blocks(0),
@@ -673,7 +831,9 @@ namespace agg
int8u* ptr = m_buf_ptr;
if(alignment > 1)
{
- unsigned align = (alignment - unsigned((size_t)ptr) % alignment) % alignment;
+ unsigned align =
+ (alignment - unsigned((size_t)ptr) % alignment) % alignment;
+
size += align;
ptr += align;
if(size <= m_rest)
@@ -700,31 +860,36 @@ namespace agg
if(size < m_block_size) size = m_block_size;
if(m_num_blocks >= m_max_blocks)
{
- int8u** new_blocks = new int8u* [m_max_blocks + m_block_ptr_inc];
+ block_type* new_blocks =
+ pod_allocator<block_type>::allocate(m_max_blocks + m_block_ptr_inc);
if(m_blocks)
{
memcpy(new_blocks,
m_blocks,
- m_num_blocks * sizeof(int8u*));
-
- delete [] m_blocks;
+ m_num_blocks * sizeof(block_type));
+ pod_allocator<block_type>::deallocate(m_blocks, m_max_blocks);
}
m_blocks = new_blocks;
m_max_blocks += m_block_ptr_inc;
}
- m_blocks[m_num_blocks] = m_buf_ptr = new int8u [size];
+
+ m_blocks[m_num_blocks].size = size;
+ m_blocks[m_num_blocks].data =
+ m_buf_ptr =
+ pod_allocator<int8u>::allocate(size);
+
m_num_blocks++;
m_rest = size;
}
- unsigned m_block_size;
- unsigned m_block_ptr_inc;
- unsigned m_num_blocks;
- unsigned m_max_blocks;
- int8u** m_blocks;
- int8u* m_buf_ptr;
- unsigned m_rest;
+ unsigned m_block_size;
+ unsigned m_block_ptr_inc;
+ unsigned m_num_blocks;
+ unsigned m_max_blocks;
+ block_type* m_blocks;
+ int8u* m_buf_ptr;
+ unsigned m_rest;
};
@@ -735,7 +900,7 @@ namespace agg
//------------------------------------------------------------------------
- enum
+ enum quick_sort_threshold_e
{
quick_sort_threshold = 9
};
@@ -859,7 +1024,7 @@ namespace agg
//------------------------------------------------------remove_duplicates
- // Remove duplicates from a sorted array. It doesn't cut the the
+ // Remove duplicates from a sorted array. It doesn't cut the
// tail of the array, it just returns the number of remaining elements.
//-----------------------------------------------------------------------
template<class Array, class Equal>
@@ -879,9 +1044,76 @@ namespace agg
return j;
}
+ //--------------------------------------------------------invert_container
+ template<class Array> void invert_container(Array& arr)
+ {
+ int i = 0;
+ int j = arr.size() - 1;
+ while(i < j)
+ {
+ swap_elements(arr[i++], arr[j--]);
+ }
+ }
+
+ //------------------------------------------------------binary_search_pos
+ template<class Array, class Value, class Less>
+ unsigned binary_search_pos(const Array& arr, const Value& val, Less less)
+ {
+ if(arr.size() == 0) return 0;
+
+ unsigned beg = 0;
+ unsigned end = arr.size() - 1;
+
+ if(less(val, arr[0])) return 0;
+ if(less(arr[end], val)) return end + 1;
+
+ while(end - beg > 1)
+ {
+ unsigned mid = (end + beg) >> 1;
+ if(less(val, arr[mid])) end = mid;
+ else beg = mid;
+ }
+
+ //if(beg <= 0 && less(val, arr[0])) return 0;
+ //if(end >= arr.size() - 1 && less(arr[end], val)) ++end;
+
+ return end;
+ }
+
+ //----------------------------------------------------------range_adaptor
+ template<class Array> class range_adaptor
+ {
+ public:
+ typedef typename Array::value_type value_type;
+
+ range_adaptor(Array& array, unsigned start, unsigned size) :
+ m_array(array), m_start(start), m_size(size)
+ {}
+
+ unsigned size() const { return m_size; }
+ const value_type& operator [] (unsigned i) const { return m_array[m_start + i]; }
+ value_type& operator [] (unsigned i) { return m_array[m_start + i]; }
+ const value_type& at(unsigned i) const { return m_array[m_start + i]; }
+ value_type& at(unsigned i) { return m_array[m_start + i]; }
+ value_type value_at(unsigned i) const { return m_array[m_start + i]; }
+
+ private:
+ Array& m_array;
+ unsigned m_start;
+ unsigned m_size;
+ };
+
+ //---------------------------------------------------------------int_less
+ inline bool int_less(int a, int b) { return a < b; }
+ //------------------------------------------------------------int_greater
+ inline bool int_greater(int a, int b) { return a > b; }
+ //----------------------------------------------------------unsigned_less
+ inline bool unsigned_less(unsigned a, unsigned b) { return a < b; }
+ //-------------------------------------------------------unsigned_greater
+ inline bool unsigned_greater(unsigned a, unsigned b) { return a > b; }
}
#endif
diff --git a/agg/inc/agg_arrowhead.h b/agg/inc/agg_arrowhead.h
index aac99c5ae980..d900d317b22f 100755
--- a/agg/inc/agg_arrowhead.h
+++ b/agg/inc/agg_arrowhead.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -57,7 +57,7 @@ namespace agg
void tail() { m_tail_flag = true; }
void no_tail() { m_tail_flag = false; }
- void rewind(unsigned id);
+ void rewind(unsigned path_id);
unsigned vertex(double* x, double* y);
private:
diff --git a/agg/inc/agg_basics.h b/agg/inc/agg_basics.h
index d9ca881ab328..a87050c85dbc 100755
--- a/agg/inc/agg_basics.h
+++ b/agg/inc/agg_basics.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -16,8 +16,46 @@
#ifndef AGG_BASICS_INCLUDED
#define AGG_BASICS_INCLUDED
+#include <math.h>
#include "agg_config.h"
+//---------------------------------------------------------AGG_CUSTOM_ALLOCATOR
+#ifdef AGG_CUSTOM_ALLOCATOR
+#include "agg_allocator.h"
+#else
+namespace agg
+{
+ // The policy of all AGG containers and memory allocation strategy
+ // in general is that no allocated data requires explicit construction.
+ // It means that the allocator can be really simple; you can even
+ // replace new/delete to malloc/free. The constructors and destructors
+ // won't be called in this case, however everything will remain working.
+ // The second argument of deallocate() is the size of the allocated
+ // block. You can use this information if you wish.
+ //------------------------------------------------------------pod_allocator
+ template<class T> struct pod_allocator
+ {
+ static T* allocate(unsigned num) { return new T [num]; }
+ static void deallocate(T* ptr, unsigned) { delete [] ptr; }
+ };
+
+ // Single object allocator. It's also can be replaced with your custom
+ // allocator. The difference is that it can only allocate a single
+ // object and the constructor and destructor must be called.
+ // In AGG there is no need to allocate an array of objects with
+ // calling their constructors (only single ones). So that, if you
+ // replace these new/delete to malloc/free make sure that the in-place
+ // new is called and take care of calling the destructor too.
+ //------------------------------------------------------------obj_allocator
+ template<class T> struct obj_allocator
+ {
+ static T* allocate() { return new T; }
+ static void deallocate(T* ptr) { delete ptr; }
+ };
+}
+#endif
+
+
//-------------------------------------------------------- Default basic types
//
// If the compiler has different capacity of the basic types you can redefine
@@ -49,7 +87,7 @@
#endif
#ifndef AGG_INT64
-#if defined(_MSC_VER)
+#if defined(_MSC_VER) || defined(__BORLANDC__)
#define AGG_INT64 signed __int64
#else
#define AGG_INT64 signed long long
@@ -57,7 +95,7 @@
#endif
#ifndef AGG_INT64U
-#if defined(_MSC_VER)
+#if defined(_MSC_VER) || defined(__BORLANDC__)
#define AGG_INT64U unsigned __int64
#else
#define AGG_INT64U unsigned long long
@@ -87,9 +125,92 @@ namespace agg
typedef AGG_INT64 int64; //----int64
typedef AGG_INT64U int64u; //----int64u
+#if defined(AGG_FISTP)
+#pragma warning(push)
+#pragma warning(disable : 4035) //Disable warning "no return value"
+ AGG_INLINE int iround(double v) //-------iround
+ {
+ int t;
+ __asm fld qword ptr [v]
+ __asm fistp dword ptr [t]
+ __asm mov eax, dword ptr [t]
+ }
+ AGG_INLINE unsigned uround(double v) //-------uround
+ {
+ unsigned t;
+ __asm fld qword ptr [v]
+ __asm fistp dword ptr [t]
+ __asm mov eax, dword ptr [t]
+ }
+#pragma warning(pop)
+ AGG_INLINE unsigned ufloor(double v) //-------ufloor
+ {
+ return unsigned(floor(v));
+ }
+ AGG_INLINE unsigned uceil(double v) //--------uceil
+ {
+ return unsigned(ceil(v));
+ }
+#elif defined(AGG_QIFIST)
+ AGG_INLINE int iround(double v)
+ {
+ return int(v);
+ }
+ AGG_INLINE int uround(double v)
+ {
+ return unsigned(v);
+ }
+ AGG_INLINE unsigned ufloor(double v)
+ {
+ return unsigned(floor(v));
+ }
+ AGG_INLINE unsigned uceil(double v)
+ {
+ return unsigned(ceil(v));
+ }
+#else
+ AGG_INLINE int iround(double v)
+ {
+ return int((v < 0.0) ? v - 0.5 : v + 0.5);
+ }
+ AGG_INLINE int uround(double v)
+ {
+ return unsigned(v + 0.5);
+ }
+ AGG_INLINE unsigned ufloor(double v)
+ {
+ return unsigned(v);
+ }
+ AGG_INLINE unsigned uceil(double v)
+ {
+ return unsigned(ceil(v));
+ }
+#endif
+
+ //---------------------------------------------------------------saturation
+ template<int Limit> struct saturation
+ {
+ AGG_INLINE static int iround(double v)
+ {
+ if(v < double(-Limit)) return -Limit;
+ if(v > double( Limit)) return Limit;
+ return agg::iround(v);
+ }
+ };
+
+ //------------------------------------------------------------------mul_one
+ template<unsigned Shift> struct mul_one
+ {
+ AGG_INLINE static unsigned mul(unsigned a, unsigned b)
+ {
+ register unsigned q = a * b + (1 << (Shift-1));
+ return (q + (q >> Shift)) >> Shift;
+ }
+ };
+
//-------------------------------------------------------------------------
typedef unsigned char cover_type; //----cover_type
- enum
+ enum cover_scale_e
{
cover_shift = 8, //----cover_shift
cover_size = 1 << cover_shift, //----cover_size
@@ -98,6 +219,25 @@ namespace agg
cover_full = cover_mask //----cover_full
};
+ //----------------------------------------------------poly_subpixel_scale_e
+ // These constants determine the subpixel accuracy, to be more precise,
+ // the number of bits of the fractional part of the coordinates.
+ // The possible coordinate capacity in bits can be calculated by formula:
+ // sizeof(int) * 8 - poly_subpixel_shift, i.e, for 32-bit integers and
+ // 8-bits fractional part the capacity is 24 bits.
+ enum poly_subpixel_scale_e
+ {
+ poly_subpixel_shift = 8, //----poly_subpixel_shift
+ poly_subpixel_scale = 1<<poly_subpixel_shift, //----poly_subpixel_scale
+ poly_subpixel_mask = poly_subpixel_scale-1, //----poly_subpixel_mask
+ };
+
+ //----------------------------------------------------------filling_rule_e
+ enum filling_rule_e
+ {
+ fill_non_zero,
+ fill_even_odd
+ };
//-----------------------------------------------------------------------pi
const double pi = 3.14159265358979323846;
@@ -117,16 +257,19 @@ namespace agg
//----------------------------------------------------------------rect_base
template<class T> struct rect_base
{
+ typedef T value_type;
typedef rect_base<T> self_type;
- T x1;
- T y1;
- T x2;
- T y2;
+ T x1, y1, x2, y2;
rect_base() {}
rect_base(T x1_, T y1_, T x2_, T y2_) :
x1(x1_), y1(y1_), x2(x2_), y2(y2_) {}
+ void init(T x1_, T y1_, T x2_, T y2_)
+ {
+ x1 = x1_; y1 = y1_; x2 = x2_; y2 = y2_;
+ }
+
const self_type& normalize()
{
T t;
@@ -148,6 +291,11 @@ namespace agg
{
return x1 <= x2 && y1 <= y2;
}
+
+ bool hit_test(T x, T y) const
+ {
+ return (x >= x1 && x <= x2 && y >= y1 && y <= y2);
+ }
};
//-----------------------------------------------------intersect_rectangles
@@ -181,7 +329,8 @@ namespace agg
return r;
}
- typedef rect_base<int> rect; //----rect
+ typedef rect_base<int> rect_i; //----rect_i
+ typedef rect_base<float> rect_f; //----rect_f
typedef rect_base<double> rect_d; //----rect_d
//---------------------------------------------------------path_commands_e
@@ -192,7 +341,10 @@ namespace agg
path_cmd_line_to = 2, //----path_cmd_line_to
path_cmd_curve3 = 3, //----path_cmd_curve3
path_cmd_curve4 = 4, //----path_cmd_curve4
- path_cmd_end_poly = 6, //----path_cmd_end_poly
+ path_cmd_curveN = 5, //----path_cmd_curveN
+ path_cmd_catrom = 6, //----path_cmd_catrom
+ path_cmd_ubspline = 7, //----path_cmd_ubspline
+ path_cmd_end_poly = 0x0F, //----path_cmd_end_poly
path_cmd_mask = 0x0F //----path_cmd_mask
};
@@ -212,6 +364,12 @@ namespace agg
return c >= path_cmd_move_to && c < path_cmd_end_poly;
}
+ //--------------------------------------------------------------is_drawing
+ inline bool is_drawing(unsigned c)
+ {
+ return c >= path_cmd_line_to && c < path_cmd_end_poly;
+ }
+
//-----------------------------------------------------------------is_stop
inline bool is_stop(unsigned c)
{
@@ -258,7 +416,7 @@ namespace agg
inline bool is_close(unsigned c)
{
return (c & ~(path_flags_cw | path_flags_ccw)) ==
- (((bool)path_cmd_end_poly) | ((bool)path_flags_close));
+ (path_cmd_end_poly | path_flags_close);
}
//------------------------------------------------------------is_next_poly
@@ -315,26 +473,55 @@ namespace agg
return clear_orientation(c) | o;
}
- //--------------------------------------------------------------point_type
- struct point_type
+ //--------------------------------------------------------------point_base
+ template<class T> struct point_base
{
- double x, y;
-
- point_type() {}
- point_type(double x_, double y_) : x(x_), y(y_) {}
+ typedef T value_type;
+ T x,y;
+ point_base() {}
+ point_base(T x_, T y_) : x(x_), y(y_) {}
};
+ typedef point_base<int> point_i; //-----point_i
+ typedef point_base<float> point_f; //-----point_f
+ typedef point_base<double> point_d; //-----point_d
- //-------------------------------------------------------------vertex_type
- struct vertex_type
+ //-------------------------------------------------------------vertex_base
+ template<class T> struct vertex_base
{
- double x, y;
+ typedef T value_type;
+ T x,y;
unsigned cmd;
+ vertex_base() {}
+ vertex_base(T x_, T y_, unsigned cmd_) : x(x_), y(y_), cmd(cmd_) {}
+ };
+ typedef vertex_base<int> vertex_i; //-----vertex_i
+ typedef vertex_base<float> vertex_f; //-----vertex_f
+ typedef vertex_base<double> vertex_d; //-----vertex_d
- vertex_type() {}
- vertex_type(double x_, double y_, unsigned cmd_) :
- x(x_), y(y_), cmd(cmd_) {}
+ //----------------------------------------------------------------row_info
+ template<class T> struct row_info
+ {
+ int x1, x2;
+ T* ptr;
+ row_info() {}
+ row_info(int x1_, int x2_, T* ptr_) : x1(x1_), x2(x2_), ptr(ptr_) {}
};
+ //----------------------------------------------------------const_row_info
+ template<class T> struct const_row_info
+ {
+ int x1, x2;
+ const T* ptr;
+ const_row_info() {}
+ const_row_info(int x1_, int x2_, const T* ptr_) :
+ x1(x1_), x2(x2_), ptr(ptr_) {}
+ };
+
+ //------------------------------------------------------------is_equal_eps
+ template<class T> inline bool is_equal_eps(T v1, T v2, T epsilon)
+ {
+ return fabs(v1 - v2) <= double(epsilon);
+ }
}
diff --git a/agg/inc/agg_bezier_arc.h b/agg/inc/agg_bezier_arc.h
index f437ab0a00bd..f92d5be4e5e9 100755
--- a/agg/inc/agg_bezier_arc.h
+++ b/agg/inc/agg_bezier_arc.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -40,7 +40,7 @@ namespace agg
{
public:
//--------------------------------------------------------------------
- bezier_arc() : m_vertex(26) {}
+ bezier_arc() : m_vertex(26), m_num_vertices(0), m_cmd(path_cmd_line_to) {}
bezier_arc(double x, double y,
double rx, double ry,
double start_angle,
@@ -68,7 +68,7 @@ namespace agg
*x = m_vertices[m_vertex];
*y = m_vertices[m_vertex + 1];
m_vertex += 2;
- return (m_vertex == 2) ? path_cmd_move_to : path_cmd_curve4;
+ return (m_vertex == 2) ? path_cmd_move_to : m_cmd;
}
// Supplemantary functions. num_vertices() actually returns doubled
@@ -82,6 +82,7 @@ namespace agg
unsigned m_vertex;
unsigned m_num_vertices;
double m_vertices[26];
+ unsigned m_cmd;
};
diff --git a/agg/inc/agg_bitset_iterator.h b/agg/inc/agg_bitset_iterator.h
index 543432b65d54..843a2b576d89 100755
--- a/agg/inc/agg_bitset_iterator.h
+++ b/agg/inc/agg_bitset_iterator.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
diff --git a/agg/inc/agg_bounding_rect.h b/agg/inc/agg_bounding_rect.h
index 9a3c301069d7..4c7886be86a7 100755
--- a/agg/inc/agg_bounding_rect.h
+++ b/agg/inc/agg_bounding_rect.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
diff --git a/agg/inc/agg_bspline.h b/agg/inc/agg_bspline.h
index ca58fa839b44..8d5fcf0b4cdf 100755
--- a/agg/inc/agg_bspline.h
+++ b/agg/inc/agg_bspline.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -20,7 +20,7 @@
#ifndef AGG_BSPLINE_INCLUDED
#define AGG_BSPLINE_INCLUDED
-#include "agg_basics.h"
+#include "agg_array.h"
namespace agg
{
@@ -40,7 +40,6 @@ namespace agg
class bspline
{
public:
- ~bspline();
bspline();
bspline(int num);
bspline(int num, const double* x, const double* y);
@@ -63,12 +62,12 @@ namespace agg
double extrapolation_right(double x) const;
double interpolation(double x, int i) const;
- int m_max;
- int m_num;
- double* m_x;
- double* m_y;
- double* m_am;
- mutable int m_last_idx;
+ int m_max;
+ int m_num;
+ double* m_x;
+ double* m_y;
+ pod_array<double> m_am;
+ mutable int m_last_idx;
};
diff --git a/agg/inc/agg_clip_liang_barsky.h b/agg/inc/agg_clip_liang_barsky.h
index e229d52bc6e9..28765a79cd09 100755
--- a/agg/inc/agg_clip_liang_barsky.h
+++ b/agg/inc/agg_clip_liang_barsky.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -24,6 +24,17 @@
namespace agg
{
+ //------------------------------------------------------------------------
+ enum clipping_flags_e
+ {
+ clipping_flags_x1_clipped = 4,
+ clipping_flags_x2_clipped = 1,
+ clipping_flags_y1_clipped = 8,
+ clipping_flags_y2_clipped = 2,
+ clipping_flags_x_clipped = clipping_flags_x1_clipped | clipping_flags_x2_clipped,
+ clipping_flags_y_clipped = clipping_flags_y1_clipped | clipping_flags_y2_clipped
+ };
+
//----------------------------------------------------------clipping_flags
// Determine the clipping code of the vertex according to the
// Cyrus-Beck line clipping algorithm
@@ -51,11 +62,25 @@ namespace agg
((y < clip_box.y1) << 3);
}
+ //--------------------------------------------------------clipping_flags_x
+ template<class T>
+ inline unsigned clipping_flags_x(T x, const rect_base<T>& clip_box)
+ {
+ return (x > clip_box.x2) | ((x < clip_box.x1) << 2);
+ }
+
+
+ //--------------------------------------------------------clipping_flags_y
+ template<class T>
+ inline unsigned clipping_flags_y(T y, const rect_base<T>& clip_box)
+ {
+ return ((y > clip_box.y2) << 1) | ((y < clip_box.y1) << 3);
+ }
//-------------------------------------------------------clip_liang_barsky
template<class T>
- /*inline*/ unsigned clip_liang_barsky(T x1, T y1, T x2, T y2,
+ inline unsigned clip_liang_barsky(T x1, T y1, T x2, T y2,
const rect_base<T>& clip_box,
T* x, T* y)
{
@@ -204,6 +229,105 @@ namespace agg
}
+ //----------------------------------------------------------------------------
+ template<class T>
+ bool clip_move_point(T x1, T y1, T x2, T y2,
+ const rect_base<T>& clip_box,
+ T* x, T* y, unsigned flags)
+ {
+ T bound;
+
+ if(flags & clipping_flags_x_clipped)
+ {
+ if(x1 == x2)
+ {
+ return false;
+ }
+ bound = (flags & clipping_flags_x1_clipped) ? clip_box.x1 : clip_box.x2;
+ *y = (T)(double(bound - x1) * (y2 - y1) / (x2 - x1) + y1);
+ *x = bound;
+ }
+
+ flags = clipping_flags_y(*y, clip_box);
+ if(flags & clipping_flags_y_clipped)
+ {
+ if(y1 == y2)
+ {
+ return false;
+ }
+ bound = (flags & clipping_flags_y1_clipped) ? clip_box.y1 : clip_box.y2;
+ *x = (T)(double(bound - y1) * (x2 - x1) / (y2 - y1) + x1);
+ *y = bound;
+ }
+ return true;
+ }
+
+ //-------------------------------------------------------clip_line_segment
+ // Returns: ret >= 4 - Fully clipped
+ // (ret & 1) != 0 - First point has been moved
+ // (ret & 2) != 0 - Second point has been moved
+ //
+ template<class T>
+ unsigned clip_line_segment(T* x1, T* y1, T* x2, T* y2,
+ const rect_base<T>& clip_box)
+ {
+ unsigned f1 = clipping_flags(*x1, *y1, clip_box);
+ unsigned f2 = clipping_flags(*x2, *y2, clip_box);
+ unsigned ret = 0;
+
+ if((f2 | f1) == 0)
+ {
+ // Fully visible
+ return 0;
+ }
+
+ if((f1 & clipping_flags_x_clipped) != 0 &&
+ (f1 & clipping_flags_x_clipped) == (f2 & clipping_flags_x_clipped))
+ {
+ // Fully clipped
+ return 4;
+ }
+
+ if((f1 & clipping_flags_y_clipped) != 0 &&
+ (f1 & clipping_flags_y_clipped) == (f2 & clipping_flags_y_clipped))
+ {
+ // Fully clipped
+ return 4;
+ }
+
+ T tx1 = *x1;
+ T ty1 = *y1;
+ T tx2 = *x2;
+ T ty2 = *y2;
+ if(f1)
+ {
+ if(!clip_move_point(tx1, ty1, tx2, ty2, clip_box, x1, y1, f1))
+ {
+ return 4;
+ }
+ if(*x1 == *x2 && *y1 == *y2)
+ {
+ return 4;
+ }
+ ret |= 1;
+ }
+ if(f2)
+ {
+ if(!clip_move_point(tx1, ty1, tx2, ty2, clip_box, x2, y2, f2))
+ {
+ return 4;
+ }
+ if(*x1 == *x2 && *y1 == *y2)
+ {
+ return 4;
+ }
+ ret |= 2;
+ }
+ return ret;
+ }
+
+
}
+
#endif
diff --git a/agg/inc/agg_color_gray.h b/agg/inc/agg_color_gray.h
index 1d0ffd8e773d..865798e9d06b 100755
--- a/agg/inc/agg_color_gray.h
+++ b/agg/inc/agg_color_gray.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -40,11 +40,11 @@ namespace agg
typedef int8u value_type;
typedef int32u calc_type;
typedef int32 long_type;
- enum
+ enum base_scale_e
{
base_shift = 8,
- base_size = 1 << base_shift,
- base_mask = base_size - 1
+ base_scale = 1 << base_shift,
+ base_mask = base_scale - 1
};
typedef gray8 self_type;
@@ -64,13 +64,13 @@ namespace agg
//--------------------------------------------------------------------
gray8(const rgba& c) :
- v(value_type((0.299*c.r + 0.587*c.g + 0.114*c.b) * double(base_mask) + 0.5)),
- a(value_type(c.a * double(base_mask))) {}
+ v((value_type)uround((0.299*c.r + 0.587*c.g + 0.114*c.b) * double(base_mask))),
+ a((value_type)uround(c.a * double(base_mask))) {}
//--------------------------------------------------------------------
gray8(const rgba& c, double a_) :
- v(value_type((0.299*c.r + 0.587*c.g + 0.114*c.b) * double(base_mask) + 0.5)),
- a(value_type(a_ * double(base_mask))) {}
+ v((value_type)uround((0.299*c.r + 0.587*c.g + 0.114*c.b) * double(base_mask))),
+ a((value_type)uround(a_ * double(base_mask))) {}
//--------------------------------------------------------------------
gray8(const rgba8& c) :
@@ -100,7 +100,7 @@ namespace agg
{
if(a_ < 0.0) a_ = 0.0;
if(a_ > 1.0) a_ = 1.0;
- a = value_type(a_ * double(base_mask));
+ a = (value_type)uround(a_ * double(base_mask));
}
//--------------------------------------------------------------------
@@ -148,7 +148,7 @@ namespace agg
return *this;
}
calc_type v_ = (calc_type(v) * base_mask) / a;
- v = value_type((v_ > base_mask) ? base_mask : v_);
+ v = value_type((v_ > base_mask) ? (value_type)base_mask : v_);
return *this;
}
@@ -156,13 +156,38 @@ namespace agg
self_type gradient(self_type c, double k) const
{
self_type ret;
- calc_type ik = calc_type(k * base_size);
+ calc_type ik = uround(k * base_scale);
ret.v = value_type(calc_type(v) + (((calc_type(c.v) - v) * ik) >> base_shift));
ret.a = value_type(calc_type(a) + (((calc_type(c.a) - a) * ik) >> base_shift));
return ret;
}
//--------------------------------------------------------------------
+ AGG_INLINE void add(const self_type& c, unsigned cover)
+ {
+ calc_type cv, ca;
+ if(cover == cover_mask)
+ {
+ if(c.a == base_mask)
+ {
+ *this = c;
+ }
+ else
+ {
+ cv = v + c.v; v = (cv > calc_type(base_mask)) ? calc_type(base_mask) : cv;
+ ca = a + c.a; a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca;
+ }
+ }
+ else
+ {
+ cv = v + ((c.v * cover + cover_mask/2) >> cover_shift);
+ ca = a + ((c.a * cover + cover_mask/2) >> cover_shift);
+ v = (cv > calc_type(base_mask)) ? calc_type(base_mask) : cv;
+ a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca;
+ }
+ }
+
+ //--------------------------------------------------------------------
static self_type no_color() { return self_type(0,0); }
};
@@ -202,11 +227,11 @@ namespace agg
typedef int16u value_type;
typedef int32u calc_type;
typedef int64 long_type;
- enum
+ enum base_scale_e
{
base_shift = 16,
- base_size = 1 << base_shift,
- base_mask = base_size - 1
+ base_scale = 1 << base_shift,
+ base_mask = base_scale - 1
};
typedef gray16 self_type;
@@ -226,13 +251,13 @@ namespace agg
//--------------------------------------------------------------------
gray16(const rgba& c) :
- v(value_type((0.299*c.r + 0.587*c.g + 0.114*c.b) * double(base_mask) + 0.5)),
- a(value_type(c.a * double(base_mask))) {}
+ v((value_type)uround((0.299*c.r + 0.587*c.g + 0.114*c.b) * double(base_mask))),
+ a((value_type)uround(c.a * double(base_mask))) {}
//--------------------------------------------------------------------
gray16(const rgba& c, double a_) :
- v(value_type((0.299*c.r + 0.587*c.g + 0.114*c.b) * double(base_mask) + 0.5)),
- a(value_type(a_ * double(base_mask))) {}
+ v((value_type)uround((0.299*c.r + 0.587*c.g + 0.114*c.b) * double(base_mask))),
+ a((value_type)uround(a_ * double(base_mask))) {}
//--------------------------------------------------------------------
gray16(const rgba8& c) :
@@ -262,7 +287,7 @@ namespace agg
{
if(a_ < 0.0) a_ = 0.0;
if(a_ > 1.0) a_ = 1.0;
- a = value_type(a_ * double(base_mask));
+ a = (value_type)uround(a_ * double(base_mask));
}
//--------------------------------------------------------------------
@@ -318,13 +343,38 @@ namespace agg
self_type gradient(self_type c, double k) const
{
self_type ret;
- calc_type ik = calc_type(k * base_size);
+ calc_type ik = uround(k * base_scale);
ret.v = value_type(calc_type(v) + (((calc_type(c.v) - v) * ik) >> base_shift));
ret.a = value_type(calc_type(a) + (((calc_type(c.a) - a) * ik) >> base_shift));
return ret;
}
//--------------------------------------------------------------------
+ AGG_INLINE void add(const self_type& c, unsigned cover)
+ {
+ calc_type cv, ca;
+ if(cover == cover_mask)
+ {
+ if(c.a == base_mask)
+ {
+ *this = c;
+ }
+ else
+ {
+ cv = v + c.v; v = (cv > calc_type(base_mask)) ? calc_type(base_mask) : cv;
+ ca = a + c.a; a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca;
+ }
+ }
+ else
+ {
+ cv = v + ((c.v * cover + cover_mask/2) >> cover_shift);
+ ca = a + ((c.a * cover + cover_mask/2) >> cover_shift);
+ v = (cv > calc_type(base_mask)) ? calc_type(base_mask) : cv;
+ a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca;
+ }
+ }
+
+ //--------------------------------------------------------------------
static self_type no_color() { return self_type(0,0); }
};
diff --git a/agg/inc/agg_color_rgba.h b/agg/inc/agg_color_rgba.h
index e1f77206cc66..9b9e9321db1b 100755
--- a/agg/inc/agg_color_rgba.h
+++ b/agg/inc/agg_color_rgba.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -31,12 +31,12 @@ namespace agg
{
// Supported byte orders for RGB and RGBA pixel formats
//=======================================================================
- struct order_rgb { enum { R=0, G=1, B=2, rgb_tag }; }; //----order_rgb
- struct order_bgr { enum { B=0, G=1, R=2, rgb_tag }; }; //----order_bgr
- struct order_rgba { enum { R=0, G=1, B=2, A=3, rgba_tag }; }; //----order_rgba
- struct order_argb { enum { A=0, R=1, G=2, B=3, rgba_tag }; }; //----order_argb
- struct order_abgr { enum { A=0, B=1, G=2, R=3, rgba_tag }; }; //----order_abgr
- struct order_bgra { enum { B=0, G=1, R=2, A=3, rgba_tag }; }; //----order_bgra
+ struct order_rgb { enum rgb_e { R=0, G=1, B=2, rgb_tag }; }; //----order_rgb
+ struct order_bgr { enum bgr_e { B=0, G=1, R=2, rgb_tag }; }; //----order_bgr
+ struct order_rgba { enum rgba_e { R=0, G=1, B=2, A=3, rgba_tag }; }; //----order_rgba
+ struct order_argb { enum argb_e { A=0, R=1, G=2, B=3, rgba_tag }; }; //----order_argb
+ struct order_abgr { enum abgr_e { A=0, B=1, G=2, R=3, rgba_tag }; }; //----order_abgr
+ struct order_bgra { enum bgra_e { B=0, G=1, R=2, A=3, rgba_tag }; }; //----order_bgra
//====================================================================rgba
struct rgba
@@ -145,7 +145,7 @@ namespace agg
static rgba from_wavelength(double wl, double gamma = 1.0);
//--------------------------------------------------------------------
- rgba(double wavelen, double gamma=1.0)
+ explicit rgba(double wavelen, double gamma=1.0)
{
*this = from_wavelength(wavelen, gamma);
}
@@ -225,11 +225,11 @@ namespace agg
typedef int8u value_type;
typedef int32u calc_type;
typedef int32 long_type;
- enum
+ enum base_scale_e
{
base_shift = 8,
- base_size = 1 << base_shift,
- base_mask = base_size - 1
+ base_scale = 1 << base_shift,
+ base_mask = base_scale - 1
};
typedef rgba8 self_type;
@@ -251,10 +251,10 @@ namespace agg
//--------------------------------------------------------------------
rgba8(const rgba& c, double a_) :
- r(value_type(c.r * double(base_mask) + 0.5)),
- g(value_type(c.g * double(base_mask) + 0.5)),
- b(value_type(c.b * double(base_mask) + 0.5)),
- a(value_type(a_ * double(base_mask) + 0.5)) {}
+ r((value_type)uround(c.r * double(base_mask))),
+ g((value_type)uround(c.g * double(base_mask))),
+ b((value_type)uround(c.b * double(base_mask))),
+ a((value_type)uround(a_ * double(base_mask))) {}
//--------------------------------------------------------------------
rgba8(const self_type& c, unsigned a_) :
@@ -262,10 +262,10 @@ namespace agg
//--------------------------------------------------------------------
rgba8(const rgba& c) :
- r(value_type(c.r * double(base_mask) + 0.5)),
- g(value_type(c.g * double(base_mask) + 0.5)),
- b(value_type(c.b * double(base_mask) + 0.5)),
- a(value_type(c.a * double(base_mask) + 0.5)) {}
+ r((value_type)uround(c.r * double(base_mask))),
+ g((value_type)uround(c.g * double(base_mask))),
+ b((value_type)uround(c.b * double(base_mask))),
+ a((value_type)uround(c.a * double(base_mask))) {}
//--------------------------------------------------------------------
void clear()
@@ -285,7 +285,7 @@ namespace agg
{
if(a_ < 0.0) a_ = 0.0;
if(a_ > 1.0) a_ = 1.0;
- a = value_type(a_ * double(base_mask) + 0.5);
+ a = (value_type)uround(a_ * double(base_mask));
return *this;
}
@@ -296,7 +296,7 @@ namespace agg
}
//--------------------------------------------------------------------
- const self_type& premultiply()
+ AGG_INLINE const self_type& premultiply()
{
if(a == base_mask) return *this;
if(a == 0)
@@ -311,7 +311,7 @@ namespace agg
}
//--------------------------------------------------------------------
- const self_type& premultiply(unsigned a_)
+ AGG_INLINE const self_type& premultiply(unsigned a_)
{
if(a == base_mask && a_ >= base_mask) return *this;
if(a == 0 || a_ == 0)
@@ -330,7 +330,7 @@ namespace agg
}
//--------------------------------------------------------------------
- const self_type& demultiply()
+ AGG_INLINE const self_type& demultiply()
{
if(a == base_mask) return *this;
if(a == 0)
@@ -341,17 +341,17 @@ namespace agg
calc_type r_ = (calc_type(r) * base_mask) / a;
calc_type g_ = (calc_type(g) * base_mask) / a;
calc_type b_ = (calc_type(b) * base_mask) / a;
- r = value_type((r_ > base_mask) ? base_mask : r_);
- g = value_type((g_ > base_mask) ? base_mask : g_);
- b = value_type((b_ > base_mask) ? base_mask : b_);
+ r = value_type((r_ > calc_type(base_mask)) ? calc_type(base_mask) : r_);
+ g = value_type((g_ > calc_type(base_mask)) ? calc_type(base_mask) : g_);
+ b = value_type((b_ > calc_type(base_mask)) ? calc_type(base_mask) : b_);
return *this;
}
//--------------------------------------------------------------------
- self_type gradient(const self_type& c, double k) const
+ AGG_INLINE self_type gradient(const self_type& c, double k) const
{
self_type ret;
- calc_type ik = calc_type(k * base_size);
+ calc_type ik = uround(k * base_scale);
ret.r = value_type(calc_type(r) + (((calc_type(c.r) - r) * ik) >> base_shift));
ret.g = value_type(calc_type(g) + (((calc_type(c.g) - g) * ik) >> base_shift));
ret.b = value_type(calc_type(b) + (((calc_type(c.b) - b) * ik) >> base_shift));
@@ -360,6 +360,55 @@ namespace agg
}
//--------------------------------------------------------------------
+ AGG_INLINE void add(const self_type& c, unsigned cover)
+ {
+ calc_type cr, cg, cb, ca;
+ if(cover == cover_mask)
+ {
+ if(c.a == base_mask)
+ {
+ *this = c;
+ }
+ else
+ {
+ cr = r + c.r; r = (cr > calc_type(base_mask)) ? calc_type(base_mask) : cr;
+ cg = g + c.g; g = (cg > calc_type(base_mask)) ? calc_type(base_mask) : cg;
+ cb = b + c.b; b = (cb > calc_type(base_mask)) ? calc_type(base_mask) : cb;
+ ca = a + c.a; a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca;
+ }
+ }
+ else
+ {
+ cr = r + ((c.r * cover + cover_mask/2) >> cover_shift);
+ cg = g + ((c.g * cover + cover_mask/2) >> cover_shift);
+ cb = b + ((c.b * cover + cover_mask/2) >> cover_shift);
+ ca = a + ((c.a * cover + cover_mask/2) >> cover_shift);
+ r = (cr > calc_type(base_mask)) ? calc_type(base_mask) : cr;
+ g = (cg > calc_type(base_mask)) ? calc_type(base_mask) : cg;
+ b = (cb > calc_type(base_mask)) ? calc_type(base_mask) : cb;
+ a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca;
+ }
+ }
+
+ //--------------------------------------------------------------------
+ template<class GammaLUT>
+ AGG_INLINE void apply_gamma_dir(const GammaLUT& gamma)
+ {
+ r = gamma.dir(r);
+ g = gamma.dir(g);
+ b = gamma.dir(b);
+ }
+
+ //--------------------------------------------------------------------
+ template<class GammaLUT>
+ AGG_INLINE void apply_gamma_inv(const GammaLUT& gamma)
+ {
+ r = gamma.inv(r);
+ g = gamma.inv(g);
+ b = gamma.inv(b);
+ }
+
+ //--------------------------------------------------------------------
static self_type no_color() { return self_type(0,0,0,0); }
//--------------------------------------------------------------------
@@ -394,42 +443,53 @@ namespace agg
}
- //-----------------------------------------------------------rgb8_packed
+ //-------------------------------------------------------------rgb8_packed
inline rgba8 rgb8_packed(unsigned v)
{
return rgba8((v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF);
}
- //-----------------------------------------------------------bgr8_packed
+ //-------------------------------------------------------------bgr8_packed
inline rgba8 bgr8_packed(unsigned v)
{
return rgba8(v & 0xFF, (v >> 8) & 0xFF, (v >> 16) & 0xFF);
}
- //----------------------------------------------------------argb8_packed
+ //------------------------------------------------------------argb8_packed
inline rgba8 argb8_packed(unsigned v)
{
return rgba8((v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF, v >> 24);
}
+ //---------------------------------------------------------rgba8_gamma_dir
+ template<class GammaLUT>
+ rgba8 rgba8_gamma_dir(rgba8 c, const GammaLUT& gamma)
+ {
+ return rgba8(gamma.dir(c.r), gamma.dir(c.g), gamma.dir(c.b), c.a);
+ }
+ //---------------------------------------------------------rgba8_gamma_inv
+ template<class GammaLUT>
+ rgba8 rgba8_gamma_inv(rgba8 c, const GammaLUT& gamma)
+ {
+ return rgba8(gamma.inv(c.r), gamma.inv(c.g), gamma.inv(c.b), c.a);
+ }
-
- //=================================================================rgba16
+ //==================================================================rgba16
struct rgba16
{
typedef int16u value_type;
typedef int32u calc_type;
typedef int64 long_type;
- enum
+ enum base_scale_e
{
base_shift = 16,
- base_size = 1 << base_shift,
- base_mask = base_size - 1
+ base_scale = 1 << base_shift,
+ base_mask = base_scale - 1
};
typedef rgba16 self_type;
@@ -454,17 +514,17 @@ namespace agg
//--------------------------------------------------------------------
rgba16(const rgba& c) :
- r(value_type(c.r * double(base_mask) + 0.5)),
- g(value_type(c.g * double(base_mask) + 0.5)),
- b(value_type(c.b * double(base_mask) + 0.5)),
- a(value_type(c.a * double(base_mask) + 0.5)) {}
+ r((value_type)uround(c.r * double(base_mask))),
+ g((value_type)uround(c.g * double(base_mask))),
+ b((value_type)uround(c.b * double(base_mask))),
+ a((value_type)uround(c.a * double(base_mask))) {}
//--------------------------------------------------------------------
rgba16(const rgba& c, double a_) :
- r(value_type(c.r * double(base_mask) + 0.5)),
- g(value_type(c.g * double(base_mask) + 0.5)),
- b(value_type(c.b * double(base_mask) + 0.5)),
- a(value_type(a_ * double(base_mask) + 0.5)) {}
+ r((value_type)uround(c.r * double(base_mask))),
+ g((value_type)uround(c.g * double(base_mask))),
+ b((value_type)uround(c.b * double(base_mask))),
+ a((value_type)uround(a_ * double(base_mask))) {}
//--------------------------------------------------------------------
rgba16(const rgba8& c) :
@@ -494,11 +554,11 @@ namespace agg
}
//--------------------------------------------------------------------
- const self_type& opacity(double a_)
+ AGG_INLINE const self_type& opacity(double a_)
{
if(a_ < 0.0) a_ = 0.0;
if(a_ > 1.0) a_ = 1.0;
- a = value_type(a_ * double(base_mask) + 0.5);
+ a = (value_type)uround(a_ * double(base_mask));
return *this;
}
@@ -509,7 +569,7 @@ namespace agg
}
//--------------------------------------------------------------------
- const self_type& premultiply()
+ AGG_INLINE const self_type& premultiply()
{
if(a == base_mask) return *this;
if(a == 0)
@@ -524,7 +584,7 @@ namespace agg
}
//--------------------------------------------------------------------
- const self_type& premultiply(unsigned a_)
+ AGG_INLINE const self_type& premultiply(unsigned a_)
{
if(a == base_mask && a_ >= base_mask) return *this;
if(a == 0 || a_ == 0)
@@ -543,7 +603,7 @@ namespace agg
}
//--------------------------------------------------------------------
- const self_type& demultiply()
+ AGG_INLINE const self_type& demultiply()
{
if(a == base_mask) return *this;
if(a == 0)
@@ -554,17 +614,17 @@ namespace agg
calc_type r_ = (calc_type(r) * base_mask) / a;
calc_type g_ = (calc_type(g) * base_mask) / a;
calc_type b_ = (calc_type(b) * base_mask) / a;
- r = value_type((r_ > base_mask) ? base_mask : r_);
- g = value_type((g_ > base_mask) ? base_mask : g_);
- b = value_type((b_ > base_mask) ? base_mask : b_);
+ r = value_type((r_ > calc_type(base_mask)) ? calc_type(base_mask) : r_);
+ g = value_type((g_ > calc_type(base_mask)) ? calc_type(base_mask) : g_);
+ b = value_type((b_ > calc_type(base_mask)) ? calc_type(base_mask) : b_);
return *this;
}
//--------------------------------------------------------------------
- self_type gradient(const self_type& c, double k) const
+ AGG_INLINE self_type gradient(const self_type& c, double k) const
{
self_type ret;
- calc_type ik = calc_type(k * base_size);
+ calc_type ik = uround(k * base_scale);
ret.r = value_type(calc_type(r) + (((calc_type(c.r) - r) * ik) >> base_shift));
ret.g = value_type(calc_type(g) + (((calc_type(c.g) - g) * ik) >> base_shift));
ret.b = value_type(calc_type(b) + (((calc_type(c.b) - b) * ik) >> base_shift));
@@ -573,6 +633,55 @@ namespace agg
}
//--------------------------------------------------------------------
+ AGG_INLINE void add(const self_type& c, unsigned cover)
+ {
+ calc_type cr, cg, cb, ca;
+ if(cover == cover_mask)
+ {
+ if(c.a == base_mask)
+ {
+ *this = c;
+ }
+ else
+ {
+ cr = r + c.r; r = (cr > calc_type(base_mask)) ? calc_type(base_mask) : cr;
+ cg = g + c.g; g = (cg > calc_type(base_mask)) ? calc_type(base_mask) : cg;
+ cb = b + c.b; b = (cb > calc_type(base_mask)) ? calc_type(base_mask) : cb;
+ ca = a + c.a; a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca;
+ }
+ }
+ else
+ {
+ cr = r + ((c.r * cover + cover_mask) >> cover_shift);
+ cg = g + ((c.g * cover + cover_mask) >> cover_shift);
+ cb = b + ((c.b * cover + cover_mask) >> cover_shift);
+ ca = a + ((c.a * cover + cover_mask) >> cover_shift);
+ r = (cr > calc_type(base_mask)) ? calc_type(base_mask) : cr;
+ g = (cg > calc_type(base_mask)) ? calc_type(base_mask) : cg;
+ b = (cb > calc_type(base_mask)) ? calc_type(base_mask) : cb;
+ a = (ca > calc_type(base_mask)) ? calc_type(base_mask) : ca;
+ }
+ }
+
+ //--------------------------------------------------------------------
+ template<class GammaLUT>
+ AGG_INLINE void apply_gamma_dir(const GammaLUT& gamma)
+ {
+ r = gamma.dir(r);
+ g = gamma.dir(g);
+ b = gamma.dir(b);
+ }
+
+ //--------------------------------------------------------------------
+ template<class GammaLUT>
+ AGG_INLINE void apply_gamma_inv(const GammaLUT& gamma)
+ {
+ r = gamma.inv(r);
+ g = gamma.inv(g);
+ b = gamma.inv(b);
+ }
+
+ //--------------------------------------------------------------------
static self_type no_color() { return self_type(0,0,0,0); }
//--------------------------------------------------------------------
@@ -611,6 +720,22 @@ namespace agg
return rgba16(c,a).premultiply();
}
+
+ //------------------------------------------------------rgba16_gamma_dir
+ template<class GammaLUT>
+ rgba16 rgba16_gamma_dir(rgba16 c, const GammaLUT& gamma)
+ {
+ return rgba16(gamma.dir(c.r), gamma.dir(c.g), gamma.dir(c.b), c.a);
+ }
+
+ //------------------------------------------------------rgba16_gamma_inv
+ template<class GammaLUT>
+ rgba16 rgba16_gamma_inv(rgba16 c, const GammaLUT& gamma)
+ {
+ return rgba16(gamma.inv(c.r), gamma.inv(c.g), gamma.inv(c.b), c.a);
+ }
+
+
}
diff --git a/agg/inc/agg_config.h b/agg/inc/agg_config.h
index b412a6dff178..9a17716c52fb 100755
--- a/agg/inc/agg_config.h
+++ b/agg/inc/agg_config.h
@@ -1,7 +1,10 @@
#ifndef AGG_CONFIG_INCLUDED
#define AGG_CONFIG_INCLUDED
-// This file can be used to redefine the default basic types such as:
+// This file can be used to redefine certain data types.
+
+//---------------------------------------
+// 1. Default basic types such as:
//
// AGG_INT8
// AGG_INT8U
@@ -23,9 +26,23 @@
// but it won't result any crash and the rest of the library will remain
// fully functional.
+//---------------------------------------
+// 2. Default rendering_buffer type. Can be:
+//
+// Provides faster access for massive pixel operations,
+// such as blur, image filtering:
+// #define AGG_RENDERING_BUFFER row_ptr_cache<int8u>
+//
+// Provides cheaper creation and destruction (no mem allocs):
+// #define AGG_RENDERING_BUFFER row_accessor<int8u>
+//
+// You can still use both of them simultaneouslyin your applications
+// This #define is used only for default rendering_buffer type,
+// in short hand typedefs like pixfmt_rgba32.
+
// #i65318# Passing agg version on to clients
#ifndef AGG_VERSION
-# define AGG_VERSION 2300
+# define AGG_VERSION 2400
#endif
#endif
diff --git a/agg/inc/agg_conv_adaptor_vcgen.h b/agg/inc/agg_conv_adaptor_vcgen.h
index f8233a388357..86bc3222de08 100755
--- a/agg/inc/agg_conv_adaptor_vcgen.h
+++ b/agg/inc/agg_conv_adaptor_vcgen.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -17,7 +17,6 @@
#define AGG_CONV_ADAPTOR_VCGEN_INCLUDED
#include "agg_basics.h"
-#include "agg_vertex_iterator.h"
namespace agg
{
@@ -30,11 +29,6 @@ namespace agg
void rewind(unsigned) {}
unsigned vertex(double*, double*) { return path_cmd_stop; }
-
- typedef null_markers source_type;
- typedef vertex_iterator<source_type> iterator;
- iterator begin(unsigned id) { return iterator(*this, id); }
- iterator end() { return iterator(path_cmd_stop); }
};
@@ -51,12 +45,11 @@ namespace agg
};
public:
- conv_adaptor_vcgen(VertexSource& source) :
+ explicit conv_adaptor_vcgen(VertexSource& source) :
m_source(&source),
m_status(initial)
{}
-
- void set_source(VertexSource& source) { m_source = &source; }
+ void attach(VertexSource& source) { m_source = &source; }
Generator& generator() { return m_generator; }
const Generator& generator() const { return m_generator; }
@@ -64,19 +57,14 @@ namespace agg
Markers& markers() { return m_markers; }
const Markers& markers() const { return m_markers; }
- void rewind(unsigned id)
+ void rewind(unsigned path_id)
{
- m_source->rewind(id);
+ m_source->rewind(path_id);
m_status = initial;
}
unsigned vertex(double* x, double* y);
- typedef conv_adaptor_vcgen<VertexSource, Generator, Markers> source_type;
- typedef vertex_iterator<source_type> iterator;
- iterator begin(unsigned id) { return iterator(*this, id); }
- iterator end() { return iterator(path_cmd_stop); }
-
private:
// Prohibit copying
conv_adaptor_vcgen(const conv_adaptor_vcgen<VertexSource, Generator, Markers>&);
diff --git a/agg/inc/agg_conv_adaptor_vpgen.h b/agg/inc/agg_conv_adaptor_vpgen.h
index f6afdb4d7f12..e18c080f38e6 100755
--- a/agg/inc/agg_conv_adaptor_vpgen.h
+++ b/agg/inc/agg_conv_adaptor_vpgen.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -17,7 +17,6 @@
#define AGG_CONV_ADAPTOR_VPGEN_INCLUDED
#include "agg_basics.h"
-#include "agg_vertex_iterator.h"
namespace agg
{
@@ -26,9 +25,8 @@ namespace agg
template<class VertexSource, class VPGen> class conv_adaptor_vpgen
{
public:
- conv_adaptor_vpgen(VertexSource& source) : m_source(&source) {}
-
- void set_source(VertexSource& source) { m_source = &source; }
+ explicit conv_adaptor_vpgen(VertexSource& source) : m_source(&source) {}
+ void attach(VertexSource& source) { m_source = &source; }
VPGen& vpgen() { return m_vpgen; }
const VPGen& vpgen() const { return m_vpgen; }
@@ -36,11 +34,6 @@ namespace agg
void rewind(unsigned path_id);
unsigned vertex(double* x, double* y);
- typedef conv_adaptor_vpgen<VertexSource, VPGen> 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_adaptor_vpgen(const conv_adaptor_vpgen<VertexSource, VPGen>&);
const conv_adaptor_vpgen<VertexSource, VPGen>&
diff --git a/agg/inc/agg_conv_bspline.h b/agg/inc/agg_conv_bspline.h
index 9c504daff209..9a70b4abea5d 100755
--- a/agg/inc/agg_conv_bspline.h
+++ b/agg/inc/agg_conv_bspline.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
diff --git a/agg/inc/agg_conv_clip_polygon.h b/agg/inc/agg_conv_clip_polygon.h
index cbecc51fbdd5..05106cf51f76 100755
--- a/agg/inc/agg_conv_clip_polygon.h
+++ b/agg/inc/agg_conv_clip_polygon.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -29,7 +29,6 @@
#include "agg_basics.h"
#include "agg_conv_adaptor_vpgen.h"
#include "agg_vpgen_clip_polygon.h"
-#include "agg_vertex_iterator.h"
namespace agg
{
@@ -53,11 +52,6 @@ namespace agg
double x2() const { return base_type::vpgen().x2(); }
double y2() const { return base_type::vpgen().y2(); }
- typedef conv_clip_polygon<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_polygon(const conv_clip_polygon<VertexSource>&);
const conv_clip_polygon<VertexSource>&
diff --git a/agg/inc/agg_conv_clip_polyline.h b/agg/inc/agg_conv_clip_polyline.h
index 4ac66276891c..3684d23ac27e 100755
--- a/agg/inc/agg_conv_clip_polyline.h
+++ b/agg/inc/agg_conv_clip_polyline.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -29,7 +29,6 @@
#include "agg_basics.h"
#include "agg_conv_adaptor_vpgen.h"
#include "agg_vpgen_clip_polyline.h"
-#include "agg_vertex_iterator.h"
namespace agg
{
@@ -53,11 +52,6 @@ namespace agg
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>&
diff --git a/agg/inc/agg_conv_close_polygon.h b/agg/inc/agg_conv_close_polygon.h
index 60a756a7408a..7b783ccc877b 100755
--- a/agg/inc/agg_conv_close_polygon.h
+++ b/agg/inc/agg_conv_close_polygon.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -17,7 +17,6 @@
#define AGG_CONV_CLOSE_POLYGON_INCLUDED
#include "agg_basics.h"
-#include "agg_vertex_iterator.h"
namespace agg
{
@@ -26,18 +25,12 @@ namespace agg
template<class VertexSource> class conv_close_polygon
{
public:
- conv_close_polygon(VertexSource& vs) : m_source(&vs) {}
-
- void set_source(VertexSource& source) { m_source = &source; }
+ explicit conv_close_polygon(VertexSource& vs) : m_source(&vs) {}
+ void attach(VertexSource& source) { m_source = &source; }
void rewind(unsigned path_id);
unsigned vertex(double* x, double* y);
- typedef conv_close_polygon<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_close_polygon(const conv_close_polygon<VertexSource>&);
const conv_close_polygon<VertexSource>&
diff --git a/agg/inc/agg_conv_concat.h b/agg/inc/agg_conv_concat.h
index 2b9886a1be46..dffaf656c23a 100755
--- a/agg/inc/agg_conv_concat.h
+++ b/agg/inc/agg_conv_concat.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -17,7 +17,6 @@
#define AGG_CONV_CONCAT_INCLUDED
#include "agg_basics.h"
-#include "agg_vertex_iterator.h"
namespace agg
{
@@ -29,14 +28,13 @@ namespace agg
public:
conv_concat(VS1& source1, VS2& source2) :
m_source1(&source1), m_source2(&source2), m_status(2) {}
+ void attach1(VS1& source) { m_source1 = &source; }
+ void attach2(VS2& source) { m_source2 = &source; }
- void set_source1(VS1& source) { m_source1 = &source; }
- void set_source2(VS2& source) { m_source2 = &source; }
-
- void rewind(unsigned id)
+ void rewind(unsigned path_id)
{
- m_source1->rewind(id);
+ m_source1->rewind(path_id);
m_source2->rewind(0);
m_status = 0;
}
@@ -59,11 +57,6 @@ namespace agg
return path_cmd_stop;
}
- typedef conv_concat<VS1, VS2> 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_concat(const conv_concat<VS1, VS2>&);
const conv_concat<VS1, VS2>&
diff --git a/agg/inc/agg_conv_contour.h b/agg/inc/agg_conv_contour.h
index 652a8e1fa4f3..ec3c1bbeb804 100755
--- a/agg/inc/agg_conv_contour.h
+++ b/agg/inc/agg_conv_contour.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -38,7 +38,7 @@ 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 inner_join(inner_join_e ij) { base_type::generator().inner_join(ij); }
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); }
@@ -47,7 +47,7 @@ namespace agg
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(); }
+ inner_join_e inner_join() const { return base_type::generator().inner_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(); }
diff --git a/agg/inc/agg_conv_curve.h b/agg/inc/agg_conv_curve.h
index 3b8e6cff2e2e..d90401054ed8 100755
--- a/agg/inc/agg_conv_curve.h
+++ b/agg/inc/agg_conv_curve.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -33,14 +33,14 @@ namespace agg
// and curve4. Curve3 is a conic Bezier curve with 2 endpoints and 1 control
// point. Curve4 has 2 control points (4 points in total) and can be used
// to interpolate more complicated curves. Curve4, unlike curve3 can be used
- // to approximate arcs, both curcular and elliptical. Curves are approximated
+ // to approximate arcs, both circular and elliptical. Curves are approximated
// with straight lines and one of the approaches is just to store the whole
// sequence of vertices that approximate our curve. It takes additional
// memory, and at the same time the consecutive vertices can be calculated
// on demand.
//
// Initially, path storages are not suppose to keep all the vertices of the
- // curves (although, nothig prevents us from doing so). Instead, path_storage
+ // curves (although, nothing prevents us from doing so). Instead, path_storage
// keeps only vertices, needed to calculate a curve on demand. Those vertices
// are marked with special commands. So, if the path_storage contains curves
// (which are not real curves yet), and we render this storage directly,
@@ -51,13 +51,29 @@ namespace agg
// Class conv_curve recognizes commands path_cmd_curve3 and path_cmd_curve4
// and converts these vertices into a move_to/line_to sequence.
//-----------------------------------------------------------------------
- template<class VertexSource> class conv_curve
+ template<class VertexSource,
+ class Curve3=curve3,
+ class Curve4=curve4> class conv_curve
{
public:
- conv_curve(VertexSource& source) :
+ typedef Curve3 curve3_type;
+ typedef Curve4 curve4_type;
+ typedef conv_curve<VertexSource, Curve3, Curve4> self_type;
+
+ explicit conv_curve(VertexSource& source) :
m_source(&source), m_last_x(0.0), m_last_y(0.0) {}
+ void attach(VertexSource& source) { m_source = &source; }
+
+ void approximation_method(curve_approximation_method_e v)
+ {
+ m_curve3.approximation_method(v);
+ m_curve4.approximation_method(v);
+ }
- void set_source(VertexSource& source) { m_source = &source; }
+ curve_approximation_method_e approximation_method() const
+ {
+ return m_curve4.approximation_method();
+ }
void approximation_scale(double s)
{
@@ -67,36 +83,52 @@ namespace agg
double approximation_scale() const
{
- return m_curve3.approximation_scale();
+ return m_curve4.approximation_scale();
}
- void rewind(unsigned id);
- unsigned vertex(double* x, double* y);
+ void angle_tolerance(double v)
+ {
+ m_curve3.angle_tolerance(v);
+ m_curve4.angle_tolerance(v);
+ }
- typedef conv_curve<VertexSource> source_type;
- typedef vertex_iterator<source_type> iterator;
- iterator begin(unsigned id) { return iterator(*this, id); }
- iterator end() { return iterator(path_cmd_stop); }
+ double angle_tolerance() const
+ {
+ return m_curve4.angle_tolerance();
+ }
+
+ void cusp_limit(double v)
+ {
+ m_curve3.cusp_limit(v);
+ m_curve4.cusp_limit(v);
+ }
+
+ double cusp_limit() const
+ {
+ return m_curve4.cusp_limit();
+ }
+
+ void rewind(unsigned path_id);
+ unsigned vertex(double* x, double* y);
private:
- conv_curve(const conv_curve<VertexSource>&);
- const conv_curve<VertexSource>&
- operator = (const conv_curve<VertexSource>&);
+ conv_curve(const self_type&);
+ const self_type& operator = (const self_type&);
VertexSource* m_source;
double m_last_x;
double m_last_y;
- curve3 m_curve3;
- curve4 m_curve4;
+ curve3_type m_curve3;
+ curve4_type m_curve4;
};
//------------------------------------------------------------------------
- template<class VertexSource>
- void conv_curve<VertexSource>::rewind(unsigned id)
+ template<class VertexSource, class Curve3, class Curve4>
+ void conv_curve<VertexSource, Curve3, Curve4>::rewind(unsigned path_id)
{
- m_source->rewind(id);
+ m_source->rewind(path_id);
m_last_x = 0.0;
m_last_y = 0.0;
m_curve3.reset();
@@ -105,8 +137,8 @@ namespace agg
//------------------------------------------------------------------------
- template<class VertexSource>
- unsigned conv_curve<VertexSource>::vertex(double* x, double* y)
+ template<class VertexSource, class Curve3, class Curve4>
+ unsigned conv_curve<VertexSource, Curve3, Curve4>::vertex(double* x, double* y)
{
if(!is_stop(m_curve3.vertex(x, y)))
{
@@ -122,21 +154,14 @@ namespace agg
return path_cmd_line_to;
}
- double ct2_x = 0;
- double ct2_y = 0;
- double end_x = 0;
- double end_y = 0;
+ double ct2_x;
+ double ct2_y;
+ double end_x;
+ double end_y;
unsigned cmd = m_source->vertex(x, y);
switch(cmd)
{
- case path_cmd_move_to:
- case path_cmd_line_to:
- m_last_x = *x;
- m_last_y = *y;
- default:
- break;
-
case path_cmd_curve3:
m_source->vertex(&end_x, &end_y);
@@ -163,6 +188,8 @@ namespace agg
cmd = path_cmd_line_to;
break;
}
+ m_last_x = *x;
+ m_last_y = *y;
return cmd;
}
diff --git a/agg/inc/agg_conv_dash.h b/agg/inc/agg_conv_dash.h
index 0520276bbb96..2c00d4e7f4e5 100755
--- a/agg/inc/agg_conv_dash.h
+++ b/agg/inc/agg_conv_dash.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
diff --git a/agg/inc/agg_conv_gpc.h b/agg/inc/agg_conv_gpc.h
index 1810309d208a..14232eb619a3 100755
--- a/agg/inc/agg_conv_gpc.h
+++ b/agg/inc/agg_conv_gpc.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -27,7 +27,6 @@
#include <math.h>
#include "agg_basics.h"
#include "agg_array.h"
-#include "agg_vertex_iterator.h"
extern "C"
{
@@ -63,8 +62,8 @@ namespace agg
gpc_vertex* vertices;
};
- typedef pod_deque<gpc_vertex, 8> vertex_array_type;
- typedef pod_deque<contour_header_type, 6> contour_header_array_type;
+ typedef pod_bvector<gpc_vertex, 8> vertex_array_type;
+ typedef pod_bvector<contour_header_type, 6> contour_header_array_type;
public:
@@ -90,20 +89,15 @@ namespace agg
memset(&m_result, 0, sizeof(m_result));
}
- void set_source1(VSA& source) { m_src_a = &source; }
- void set_source2(VSB& source) { m_src_b = &source; }
+ void attach1(VSA& source) { m_src_a = &source; }
+ void attach2(VSB& source) { m_src_b = &source; }
void operation(gpc_op_e v) { m_operation = v; }
// Vertex Source Interface
- void rewind(unsigned id);
+ void rewind(unsigned path_id);
unsigned vertex(double* x, double* y);
- // Iterator
- typedef vertex_iterator<self_type> iterator;
- iterator begin(unsigned id) { return iterator(*this, id); }
- iterator end() { return iterator(path_cmd_stop); }
-
private:
conv_gpc(const conv_gpc<VSA, VSB>&);
const conv_gpc<VSA, VSB>& operator = (const conv_gpc<VSA, VSB>&);
@@ -197,10 +191,10 @@ namespace agg
int i;
for(i = 0; i < p.num_contours; i++)
{
- delete [] p.contour[i].vertex;
+ pod_allocator<gpc_vertex>::deallocate(p.contour[i].vertex,
+ p.contour[i].num_vertices);
}
- delete [] p.hole;
- delete [] p.contour;
+ pod_allocator<gpc_vertex_list>::deallocate(p.contour, p.num_contours);
memset(&p, 0, sizeof(gpc_polygon));
}
@@ -266,7 +260,7 @@ namespace agg
// TO DO: Clarify the "holes"
//if(is_cw(orientation)) h.hole_flag = 1;
- h.vertices = new gpc_vertex [h.num_vertices];
+ h.vertices = pod_allocator<gpc_vertex>::allocate(h.num_vertices);
gpc_vertex* d = h.vertices;
int i;
for(i = 0; i < h.num_vertices; i++)
@@ -294,19 +288,14 @@ namespace agg
{
p.num_contours = m_contour_accumulator.size();
- // TO DO: Clarify the "holes"
- //p.hole = new int[p.num_contours];
p.hole = 0;
-
- p.contour = new gpc_vertex_list[p.num_contours];
+ p.contour = pod_allocator<gpc_vertex_list>::allocate(p.num_contours);
int i;
- //int* ph = p.hole;
gpc_vertex_list* pv = p.contour;
for(i = 0; i < p.num_contours; i++)
{
const contour_header_type& h = m_contour_accumulator[i];
- // *ph++ = h.hole_flag;
pv->num_vertices = h.num_vertices;
pv->vertex = h.vertices;
++pv;
@@ -356,11 +345,11 @@ namespace agg
//------------------------------------------------------------------------
template<class VSA, class VSB>
- void conv_gpc<VSA, VSB>::rewind(unsigned id)
+ void conv_gpc<VSA, VSB>::rewind(unsigned path_id)
{
free_result();
- m_src_a->rewind(id);
- m_src_b->rewind(id);
+ m_src_a->rewind(path_id);
+ m_src_b->rewind(path_id);
add(*m_src_a, m_poly_a);
add(*m_src_b, m_poly_b);
switch(m_operation)
diff --git a/agg/inc/agg_conv_marker.h b/agg/inc/agg_conv_marker.h
index 1ae7fc92307b..f311cb957cea 100755
--- a/agg/inc/agg_conv_marker.h
+++ b/agg/inc/agg_conv_marker.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -21,7 +21,6 @@
#include "agg_basics.h"
#include "agg_trans_affine.h"
-#include "agg_vertex_iterator.h"
namespace agg
{
@@ -35,14 +34,9 @@ namespace agg
trans_affine& transform() { return m_transform; }
const trans_affine& transform() const { return m_transform; }
- void rewind(unsigned id);
+ void rewind(unsigned path_id);
unsigned vertex(double* x, double* y);
- typedef conv_marker<MarkerLocator, MarkerShapes> 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_marker(const conv_marker<MarkerLocator, MarkerShapes>&);
const conv_marker<MarkerLocator, MarkerShapes>&
diff --git a/agg/inc/agg_conv_marker_adaptor.h b/agg/inc/agg_conv_marker_adaptor.h
index 282d26eb5afc..2e792aec3af9 100755
--- a/agg/inc/agg_conv_marker_adaptor.h
+++ b/agg/inc/agg_conv_marker_adaptor.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
diff --git a/agg/inc/agg_conv_segmentator.h b/agg/inc/agg_conv_segmentator.h
index df81fea9b276..5a43fb1b8e2d 100755
--- a/agg/inc/agg_conv_segmentator.h
+++ b/agg/inc/agg_conv_segmentator.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
diff --git a/agg/inc/agg_conv_shorten_path.h b/agg/inc/agg_conv_shorten_path.h
index 07bc9357d6ca..26f498a305bf 100755
--- a/agg/inc/agg_conv_shorten_path.h
+++ b/agg/inc/agg_conv_shorten_path.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
diff --git a/agg/inc/agg_conv_smooth_poly1.h b/agg/inc/agg_conv_smooth_poly1.h
index f50a48747f9a..c09a02da7ada 100755
--- a/agg/inc/agg_conv_smooth_poly1.h
+++ b/agg/inc/agg_conv_smooth_poly1.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
diff --git a/agg/inc/agg_conv_stroke.h b/agg/inc/agg_conv_stroke.h
index cbdce446b7be..a91ffadb2002 100755
--- a/agg/inc/agg_conv_stroke.h
+++ b/agg/inc/agg_conv_stroke.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -39,13 +39,13 @@ namespace agg
{
}
- 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); }
+ 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_join(inner_join_e ij) { base_type::generator().inner_join(ij); }
- 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(); }
+ line_cap_e line_cap() const { return base_type::generator().line_cap(); }
+ line_join_e line_join() const { return base_type::generator().line_join(); }
+ inner_join_e inner_join() const { return base_type::generator().inner_join(); }
void width(double w) { base_type::generator().width(w); }
void miter_limit(double ml) { base_type::generator().miter_limit(ml); }
diff --git a/agg/inc/agg_conv_transform.h b/agg/inc/agg_conv_transform.h
index fb2dddcef617..1e9306fb0c14 100755
--- a/agg/inc/agg_conv_transform.h
+++ b/agg/inc/agg_conv_transform.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -21,7 +21,6 @@
#include "agg_basics.h"
#include "agg_trans_affine.h"
-#include "agg_vertex_iterator.h"
namespace agg
{
@@ -32,12 +31,11 @@ namespace agg
public:
conv_transform(VertexSource& source, const Transformer& tr) :
m_source(&source), m_trans(&tr) {}
+ void attach(VertexSource& source) { m_source = &source; }
- void set_source(VertexSource& source) { m_source = &source; }
-
- void rewind(unsigned id)
+ void rewind(unsigned path_id)
{
- m_source->rewind(id);
+ m_source->rewind(path_id);
}
unsigned vertex(double* x, double* y)
@@ -55,11 +53,6 @@ namespace agg
m_trans = &tr;
}
- typedef conv_transform<VertexSource, Transformer> 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_transform(const conv_transform<VertexSource>&);
const conv_transform<VertexSource>&
diff --git a/agg/inc/agg_conv_unclose_polygon.h b/agg/inc/agg_conv_unclose_polygon.h
index a6ba30a1119e..95fc1d5e5784 100755
--- a/agg/inc/agg_conv_unclose_polygon.h
+++ b/agg/inc/agg_conv_unclose_polygon.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -17,7 +17,6 @@
#define AGG_CONV_UNCLOSE_POLYGON_INCLUDED
#include "agg_basics.h"
-#include "agg_vertex_iterator.h"
namespace agg
{
@@ -25,9 +24,8 @@ namespace agg
template<class VertexSource> class conv_unclose_polygon
{
public:
- conv_unclose_polygon(VertexSource& vs) : m_source(&vs) {}
-
- void set_source(VertexSource& source) { m_source = &source; }
+ explicit conv_unclose_polygon(VertexSource& vs) : m_source(&vs) {}
+ void attach(VertexSource& source) { m_source = &source; }
void rewind(unsigned path_id)
{
@@ -41,11 +39,6 @@ namespace agg
return cmd;
}
- typedef conv_unclose_polygon<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_unclose_polygon(const conv_unclose_polygon<VertexSource>&);
const conv_unclose_polygon<VertexSource>&
diff --git a/agg/inc/agg_curves.h b/agg/inc/agg_curves.h
index bfb02e91ab96..8e8fe37dc065 100755
--- a/agg/inc/agg_curves.h
+++ b/agg/inc/agg_curves.h
@@ -1,6 +1,7 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
+// Copyright (C) 2005 Tony Juricic (tonygeek@yahoo.com)
//
// Permission to copy, use, modify, sell and distribute this software
// is granted provided this copyright notice appears in all copies.
@@ -12,34 +13,35 @@
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
-//
-// classes curve3 and curve4
-//
-//----------------------------------------------------------------------------
#ifndef AGG_CURVES_INCLUDED
#define AGG_CURVES_INCLUDED
-#include "agg_basics.h"
-#include "agg_vertex_iterator.h"
+#include "agg_array.h"
namespace agg
{
- // See Implemantation agg_curves.cpp
+ // See Implementation agg_curves.cpp
+ //--------------------------------------------curve_approximation_method_e
+ enum curve_approximation_method_e
+ {
+ curve_inc,
+ curve_div
+ };
- //------------------------------------------------------------------curve3
- class curve3
+ //--------------------------------------------------------------curve3_inc
+ class curve3_inc
{
public:
- curve3() :
+ curve3_inc() :
m_num_steps(0), m_step(0), m_scale(1.0) { }
- curve3(double x1, double y1,
- double x2, double y2,
- double x3, double y3) :
- m_num_steps(0), m_step(0), m_scale(1.0)
+ curve3_inc(double x1, double y1,
+ double x2, double y2,
+ double x3, double y3) :
+ m_num_steps(0), m_step(0), m_scale(1.0)
{
init(x1, y1, x2, y2, x3, y3);
}
@@ -48,16 +50,21 @@ namespace agg
void init(double x1, double y1,
double x2, double y2,
double x3, double y3);
- void approximation_scale(double s) { m_scale = s; }
- double approximation_scale() const { return m_scale; }
- void rewind(unsigned id);
- unsigned vertex(double* x, double* y);
+ void approximation_method(curve_approximation_method_e) {}
+ curve_approximation_method_e approximation_method() const { return curve_inc; }
+
+ void approximation_scale(double s);
+ double approximation_scale() const;
+
+ void angle_tolerance(double) {}
+ double angle_tolerance() const { return 0.0; }
- typedef curve3 source_type;
- typedef vertex_iterator<source_type> iterator;
- iterator begin(unsigned id) { return iterator(*this, id); }
- iterator end() { return iterator(path_cmd_stop); }
+ void cusp_limit(double) {}
+ double cusp_limit() const { return 0.0; }
+
+ void rewind(unsigned path_id);
+ unsigned vertex(double* x, double* y);
private:
int m_num_steps;
@@ -83,40 +90,153 @@ namespace agg
+ //-------------------------------------------------------------curve3_div
+ class curve3_div
+ {
+ public:
+ curve3_div() :
+ m_approximation_scale(1.0),
+ m_angle_tolerance(0.0),
+ m_count(0)
+ {}
+
+ curve3_div(double x1, double y1,
+ double x2, double y2,
+ double x3, double y3) :
+ m_approximation_scale(1.0),
+ m_angle_tolerance(0.0),
+ m_count(0)
+ {
+ init(x1, y1, x2, y2, x3, y3);
+ }
+
+ void reset() { m_points.remove_all(); m_count = 0; }
+ void init(double x1, double y1,
+ double x2, double y2,
+ double x3, double y3);
+
+ void approximation_method(curve_approximation_method_e) {}
+ curve_approximation_method_e approximation_method() const { return curve_div; }
+
+ void approximation_scale(double s) { m_approximation_scale = s; }
+ double approximation_scale() const { return m_approximation_scale; }
+ void angle_tolerance(double a) { m_angle_tolerance = a; }
+ double angle_tolerance() const { return m_angle_tolerance; }
- //-----------------------------------------------------------------curve4
- class curve4
+ void cusp_limit(double) {}
+ double cusp_limit() const { return 0.0; }
+
+ void rewind(unsigned)
+ {
+ m_count = 0;
+ }
+
+ unsigned vertex(double* x, double* y)
+ {
+ if(m_count >= m_points.size()) return path_cmd_stop;
+ const point_d& p = m_points[m_count++];
+ *x = p.x;
+ *y = p.y;
+ return (m_count == 1) ? path_cmd_move_to : path_cmd_line_to;
+ }
+
+ private:
+ void bezier(double x1, double y1,
+ double x2, double y2,
+ double x3, double y3);
+ void recursive_bezier(double x1, double y1,
+ double x2, double y2,
+ double x3, double y3,
+ unsigned level);
+
+ double m_approximation_scale;
+ double m_distance_tolerance_square;
+ double m_angle_tolerance;
+ unsigned m_count;
+ pod_bvector<point_d> m_points;
+ };
+
+
+
+
+
+
+
+ //-------------------------------------------------------------curve4_points
+ struct curve4_points
+ {
+ double cp[8];
+ curve4_points() {}
+ curve4_points(double x1, double y1,
+ double x2, double y2,
+ double x3, double y3,
+ double x4, double y4)
+ {
+ cp[0] = x1; cp[1] = y1; cp[2] = x2; cp[3] = y2;
+ cp[4] = x3; cp[5] = y3; cp[6] = x4; cp[7] = y4;
+ }
+ void init(double x1, double y1,
+ double x2, double y2,
+ double x3, double y3,
+ double x4, double y4)
+ {
+ cp[0] = x1; cp[1] = y1; cp[2] = x2; cp[3] = y2;
+ cp[4] = x3; cp[5] = y3; cp[6] = x4; cp[7] = y4;
+ }
+ double operator [] (unsigned i) const { return cp[i]; }
+ double& operator [] (unsigned i) { return cp[i]; }
+ };
+
+
+
+ //-------------------------------------------------------------curve4_inc
+ class curve4_inc
{
public:
- curve4() :
- m_num_steps(0), m_step(0), m_scale(1.0) { }
+ curve4_inc() :
+ m_num_steps(0), m_step(0), m_scale(1.0) { }
- curve4(double x1, double y1,
- double x2, double y2,
- double x3, double y3,
- double x4, double y4) :
- m_num_steps(0), m_step(0), m_scale(1.0)
+ curve4_inc(double x1, double y1,
+ double x2, double y2,
+ double x3, double y3,
+ double x4, double y4) :
+ m_num_steps(0), m_step(0), m_scale(1.0)
{
init(x1, y1, x2, y2, x3, y3, x4, y4);
}
+ curve4_inc(const curve4_points& cp) :
+ m_num_steps(0), m_step(0), m_scale(1.0)
+ {
+ init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
+ }
+
void reset() { m_num_steps = 0; m_step = -1; }
void init(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x4, double y4);
- void approximation_scale(double s) { m_scale = s; }
- double approximation_scale() const { return m_scale; }
+ void init(const curve4_points& cp)
+ {
+ init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
+ }
+
+ void approximation_method(curve_approximation_method_e) {}
+ curve_approximation_method_e approximation_method() const { return curve_inc; }
- void rewind(unsigned id);
- unsigned vertex(double* x, double* y);
+ void approximation_scale(double s);
+ double approximation_scale() const;
+
+ void angle_tolerance(double) {}
+ double angle_tolerance() const { return 0.0; }
+
+ void cusp_limit(double) {}
+ double cusp_limit() const { return 0.0; }
- typedef curve4 source_type;
- typedef vertex_iterator<source_type> iterator;
- iterator begin(unsigned id) { return iterator(*this, id); }
- iterator end() { return iterator(path_cmd_stop); }
+ void rewind(unsigned path_id);
+ unsigned vertex(double* x, double* y);
private:
int m_num_steps;
@@ -144,6 +264,429 @@ namespace agg
+ //-------------------------------------------------------catrom_to_bezier
+ inline curve4_points catrom_to_bezier(double x1, double y1,
+ double x2, double y2,
+ double x3, double y3,
+ double x4, double y4)
+ {
+ // Trans. matrix Catmull-Rom to Bezier
+ //
+ // 0 1 0 0
+ // -1/6 1 1/6 0
+ // 0 1/6 1 -1/6
+ // 0 0 1 0
+ //
+ return curve4_points(
+ x2,
+ y2,
+ (-x1 + 6*x2 + x3) / 6,
+ (-y1 + 6*y2 + y3) / 6,
+ ( x2 + 6*x3 - x4) / 6,
+ ( y2 + 6*y3 - y4) / 6,
+ x3,
+ y3);
+ }
+
+
+ //-----------------------------------------------------------------------
+ inline curve4_points
+ catrom_to_bezier(const curve4_points& cp)
+ {
+ return catrom_to_bezier(cp[0], cp[1], cp[2], cp[3],
+ cp[4], cp[5], cp[6], cp[7]);
+ }
+
+
+
+ //-----------------------------------------------------ubspline_to_bezier
+ inline curve4_points ubspline_to_bezier(double x1, double y1,
+ double x2, double y2,
+ double x3, double y3,
+ double x4, double y4)
+ {
+ // Trans. matrix Uniform BSpline to Bezier
+ //
+ // 1/6 4/6 1/6 0
+ // 0 4/6 2/6 0
+ // 0 2/6 4/6 0
+ // 0 1/6 4/6 1/6
+ //
+ return curve4_points(
+ (x1 + 4*x2 + x3) / 6,
+ (y1 + 4*y2 + y3) / 6,
+ (4*x2 + 2*x3) / 6,
+ (4*y2 + 2*y3) / 6,
+ (2*x2 + 4*x3) / 6,
+ (2*y2 + 4*y3) / 6,
+ (x2 + 4*x3 + x4) / 6,
+ (y2 + 4*y3 + y4) / 6);
+ }
+
+
+ //-----------------------------------------------------------------------
+ inline curve4_points
+ ubspline_to_bezier(const curve4_points& cp)
+ {
+ return ubspline_to_bezier(cp[0], cp[1], cp[2], cp[3],
+ cp[4], cp[5], cp[6], cp[7]);
+ }
+
+
+
+
+ //------------------------------------------------------hermite_to_bezier
+ inline curve4_points hermite_to_bezier(double x1, double y1,
+ double x2, double y2,
+ double x3, double y3,
+ double x4, double y4)
+ {
+ // Trans. matrix Hermite to Bezier
+ //
+ // 1 0 0 0
+ // 1 0 1/3 0
+ // 0 1 0 -1/3
+ // 0 1 0 0
+ //
+ return curve4_points(
+ x1,
+ y1,
+ (3*x1 + x3) / 3,
+ (3*y1 + y3) / 3,
+ (3*x2 - x4) / 3,
+ (3*y2 - y4) / 3,
+ x2,
+ y2);
+ }
+
+
+
+ //-----------------------------------------------------------------------
+ inline curve4_points
+ hermite_to_bezier(const curve4_points& cp)
+ {
+ return hermite_to_bezier(cp[0], cp[1], cp[2], cp[3],
+ cp[4], cp[5], cp[6], cp[7]);
+ }
+
+
+ //-------------------------------------------------------------curve4_div
+ class curve4_div
+ {
+ public:
+ curve4_div() :
+ m_approximation_scale(1.0),
+ m_angle_tolerance(0.0),
+ m_cusp_limit(0.0),
+ m_count(0)
+ {}
+
+ curve4_div(double x1, double y1,
+ double x2, double y2,
+ double x3, double y3,
+ double x4, double y4) :
+ m_approximation_scale(1.0),
+ m_angle_tolerance(0.0),
+ m_cusp_limit(0.0),
+ m_count(0)
+ {
+ init(x1, y1, x2, y2, x3, y3, x4, y4);
+ }
+
+ curve4_div(const curve4_points& cp) :
+ m_approximation_scale(1.0),
+ m_angle_tolerance(0.0),
+ m_count(0)
+ {
+ init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
+ }
+
+ void reset() { m_points.remove_all(); m_count = 0; }
+ void init(double x1, double y1,
+ double x2, double y2,
+ double x3, double y3,
+ double x4, double y4);
+
+ void init(const curve4_points& cp)
+ {
+ init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
+ }
+
+ void approximation_method(curve_approximation_method_e) {}
+
+ curve_approximation_method_e approximation_method() const
+ {
+ return curve_div;
+ }
+
+ void approximation_scale(double s) { m_approximation_scale = s; }
+ double approximation_scale() const { return m_approximation_scale; }
+
+ void angle_tolerance(double a) { m_angle_tolerance = a; }
+ double angle_tolerance() const { return m_angle_tolerance; }
+
+ void cusp_limit(double v)
+ {
+ m_cusp_limit = (v == 0.0) ? 0.0 : pi - v;
+ }
+
+ double cusp_limit() const
+ {
+ return (m_cusp_limit == 0.0) ? 0.0 : pi - m_cusp_limit;
+ }
+
+ void rewind(unsigned)
+ {
+ m_count = 0;
+ }
+
+ unsigned vertex(double* x, double* y)
+ {
+ if(m_count >= m_points.size()) return path_cmd_stop;
+ const point_d& p = m_points[m_count++];
+ *x = p.x;
+ *y = p.y;
+ return (m_count == 1) ? path_cmd_move_to : path_cmd_line_to;
+ }
+
+ private:
+ void bezier(double x1, double y1,
+ double x2, double y2,
+ double x3, double y3,
+ double x4, double y4);
+
+ void recursive_bezier(double x1, double y1,
+ double x2, double y2,
+ double x3, double y3,
+ double x4, double y4,
+ unsigned level);
+
+ double m_approximation_scale;
+ double m_distance_tolerance_square;
+ double m_angle_tolerance;
+ double m_cusp_limit;
+ unsigned m_count;
+ pod_bvector<point_d> m_points;
+ };
+
+
+ //-----------------------------------------------------------------curve3
+ class curve3
+ {
+ public:
+ curve3() : m_approximation_method(curve_div) {}
+ curve3(double x1, double y1,
+ double x2, double y2,
+ double x3, double y3) :
+ m_approximation_method(curve_div)
+ {
+ init(x1, y1, x2, y2, x3, y3);
+ }
+
+ void reset()
+ {
+ m_curve_inc.reset();
+ m_curve_div.reset();
+ }
+
+ void init(double x1, double y1,
+ double x2, double y2,
+ double x3, double y3)
+ {
+ if(m_approximation_method == curve_inc)
+ {
+ m_curve_inc.init(x1, y1, x2, y2, x3, y3);
+ }
+ else
+ {
+ m_curve_div.init(x1, y1, x2, y2, x3, y3);
+ }
+ }
+
+ void approximation_method(curve_approximation_method_e v)
+ {
+ m_approximation_method = v;
+ }
+
+ curve_approximation_method_e approximation_method() const
+ {
+ return m_approximation_method;
+ }
+
+ void approximation_scale(double s)
+ {
+ m_curve_inc.approximation_scale(s);
+ m_curve_div.approximation_scale(s);
+ }
+
+ double approximation_scale() const
+ {
+ return m_curve_inc.approximation_scale();
+ }
+
+ void angle_tolerance(double a)
+ {
+ m_curve_div.angle_tolerance(a);
+ }
+
+ double angle_tolerance() const
+ {
+ return m_curve_div.angle_tolerance();
+ }
+
+ void cusp_limit(double v)
+ {
+ m_curve_div.cusp_limit(v);
+ }
+
+ double cusp_limit() const
+ {
+ return m_curve_div.cusp_limit();
+ }
+
+ void rewind(unsigned path_id)
+ {
+ if(m_approximation_method == curve_inc)
+ {
+ m_curve_inc.rewind(path_id);
+ }
+ else
+ {
+ m_curve_div.rewind(path_id);
+ }
+ }
+
+ unsigned vertex(double* x, double* y)
+ {
+ if(m_approximation_method == curve_inc)
+ {
+ return m_curve_inc.vertex(x, y);
+ }
+ return m_curve_div.vertex(x, y);
+ }
+
+ private:
+ curve3_inc m_curve_inc;
+ curve3_div m_curve_div;
+ curve_approximation_method_e m_approximation_method;
+ };
+
+
+
+
+
+ //-----------------------------------------------------------------curve4
+ class curve4
+ {
+ public:
+ curve4() : m_approximation_method(curve_div) {}
+ curve4(double x1, double y1,
+ double x2, double y2,
+ double x3, double y3,
+ double x4, double y4) :
+ m_approximation_method(curve_div)
+ {
+ init(x1, y1, x2, y2, x3, y3, x4, y4);
+ }
+
+ curve4(const curve4_points& cp) :
+ m_approximation_method(curve_div)
+ {
+ init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
+ }
+
+ void reset()
+ {
+ m_curve_inc.reset();
+ m_curve_div.reset();
+ }
+
+ void init(double x1, double y1,
+ double x2, double y2,
+ double x3, double y3,
+ double x4, double y4)
+ {
+ if(m_approximation_method == curve_inc)
+ {
+ m_curve_inc.init(x1, y1, x2, y2, x3, y3, x4, y4);
+ }
+ else
+ {
+ m_curve_div.init(x1, y1, x2, y2, x3, y3, x4, y4);
+ }
+ }
+
+ void init(const curve4_points& cp)
+ {
+ init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]);
+ }
+
+ void approximation_method(curve_approximation_method_e v)
+ {
+ m_approximation_method = v;
+ }
+
+ curve_approximation_method_e approximation_method() const
+ {
+ return m_approximation_method;
+ }
+
+ void approximation_scale(double s)
+ {
+ m_curve_inc.approximation_scale(s);
+ m_curve_div.approximation_scale(s);
+ }
+ double approximation_scale() const { return m_curve_inc.approximation_scale(); }
+
+ void angle_tolerance(double v)
+ {
+ m_curve_div.angle_tolerance(v);
+ }
+
+ double angle_tolerance() const
+ {
+ return m_curve_div.angle_tolerance();
+ }
+
+ void cusp_limit(double v)
+ {
+ m_curve_div.cusp_limit(v);
+ }
+
+ double cusp_limit() const
+ {
+ return m_curve_div.cusp_limit();
+ }
+
+ void rewind(unsigned path_id)
+ {
+ if(m_approximation_method == curve_inc)
+ {
+ m_curve_inc.rewind(path_id);
+ }
+ else
+ {
+ m_curve_div.rewind(path_id);
+ }
+ }
+
+ unsigned vertex(double* x, double* y)
+ {
+ if(m_approximation_method == curve_inc)
+ {
+ return m_curve_inc.vertex(x, y);
+ }
+ return m_curve_div.vertex(x, y);
+ }
+
+ private:
+ curve4_inc m_curve_inc;
+ curve4_div m_curve_div;
+ curve_approximation_method_e m_approximation_method;
+ };
+
+
+
}
diff --git a/agg/inc/agg_dda_line.h b/agg/inc/agg_dda_line.h
index 6e7335c6dfec..7d4c22d4b18e 100755
--- a/agg/inc/agg_dda_line.h
+++ b/agg/inc/agg_dda_line.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -86,7 +86,7 @@ namespace agg
{
public:
typedef int save_data_type;
- enum { save_size = 2 };
+ enum save_size_e { save_size = 2 };
//--------------------------------------------------------------------
dda2_line_interpolator() {}
@@ -125,10 +125,10 @@ namespace agg
}
//-------------------------------------------- Backward-adjusted line
- dda2_line_interpolator(int _y, int count) :
+ dda2_line_interpolator(int y, int count) :
m_cnt(count <= 0 ? 1 : count),
- m_lft(_y / m_cnt),
- m_rem(_y % m_cnt),
+ m_lft(y / m_cnt),
+ m_rem(y % m_cnt),
m_mod(m_rem),
m_y(0)
{
@@ -217,28 +217,28 @@ namespace agg
class line_bresenham_interpolator
{
public:
- enum
+ enum subpixel_scale_e
{
subpixel_shift = 8,
- subpixel_size = 1 << subpixel_shift,
- subpixel_mask = subpixel_size - 1
+ subpixel_scale = 1 << subpixel_shift,
+ subpixel_mask = subpixel_scale - 1
};
//--------------------------------------------------------------------
static int line_lr(int v) { return v >> subpixel_shift; }
//--------------------------------------------------------------------
- line_bresenham_interpolator(int _x1, int _y1, int _x2, int _y2) :
- m_x1_lr(line_lr(_x1)),
- m_y1_lr(line_lr(_y1)),
- m_x2_lr(line_lr(_x2)),
- m_y2_lr(line_lr(_y2)),
+ line_bresenham_interpolator(int x1, int y1, int x2, int y2) :
+ m_x1_lr(line_lr(x1)),
+ m_y1_lr(line_lr(y1)),
+ m_x2_lr(line_lr(x2)),
+ m_y2_lr(line_lr(y2)),
m_ver(abs(m_x2_lr - m_x1_lr) < abs(m_y2_lr - m_y1_lr)),
m_len(m_ver ? abs(m_y2_lr - m_y1_lr) :
abs(m_x2_lr - m_x1_lr)),
- m_inc(m_ver ? ((_y2 > _y1) ? 1 : -1) : ((_x2 > _x1) ? 1 : -1)),
- m_interpolator(m_ver ? _x1 : _y1,
- m_ver ? _x2 : _y2,
+ m_inc(m_ver ? ((y2 > y1) ? 1 : -1) : ((x2 > x1) ? 1 : -1)),
+ m_interpolator(m_ver ? x1 : y1,
+ m_ver ? x2 : y2,
m_len)
{
}
diff --git a/agg/inc/agg_ellipse.h b/agg/inc/agg_ellipse.h
index 158ecf8b55ed..f4ebc7d63f54 100755
--- a/agg/inc/agg_ellipse.h
+++ b/agg/inc/agg_ellipse.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -30,27 +30,41 @@ namespace agg
class ellipse
{
public:
- ellipse() : m_x(0.0), m_y(0.0), m_rx(1.0), m_ry(1.0), m_num(4), m_step(0) {}
- ellipse(double x, double y, double rx, double ry, unsigned num_steps)
- : m_x(x), m_y(y), m_rx(rx), m_ry(ry), m_num(num_steps), m_step(0) {}
+ ellipse() :
+ m_x(0.0), m_y(0.0), m_rx(1.0), m_ry(1.0), m_scale(1.0),
+ m_num(4), m_step(0), m_cw(false) {}
+
+ ellipse(double x, double y, double rx, double ry,
+ unsigned num_steps=0, bool cw=false) :
+ m_x(x), m_y(y), m_rx(rx), m_ry(ry), m_scale(1.0),
+ m_num(num_steps), m_step(0), m_cw(cw)
+ {
+ if(m_num == 0) calc_num_steps();
+ }
+
+ void init(double x, double y, double rx, double ry,
+ unsigned num_steps=0, bool cw=false);
- void init(double x, double y, double rx, double ry, unsigned num_steps);
void approximation_scale(double scale);
- void rewind(unsigned id);
+ void rewind(unsigned path_id);
unsigned vertex(double* x, double* y);
private:
+ void calc_num_steps();
+
double m_x;
double m_y;
double m_rx;
double m_ry;
+ double m_scale;
unsigned m_num;
unsigned m_step;
+ bool m_cw;
};
-
//------------------------------------------------------------------------
- inline void ellipse::init(double x, double y, double rx, double ry, unsigned num_steps)
+ inline void ellipse::init(double x, double y, double rx, double ry,
+ unsigned num_steps, bool cw)
{
m_x = x;
m_y = y;
@@ -58,13 +72,23 @@ namespace agg
m_ry = ry;
m_num = num_steps;
m_step = 0;
+ m_cw = cw;
+ if(m_num == 0) calc_num_steps();
}
//------------------------------------------------------------------------
inline void ellipse::approximation_scale(double scale)
{
- m_num = unsigned((fabs(m_rx) + fabs(m_ry) + 6.0) * scale);
- if(m_num < 6) m_num = 6;
+ m_scale = scale;
+ calc_num_steps();
+ }
+
+ //------------------------------------------------------------------------
+ inline void ellipse::calc_num_steps()
+ {
+ double ra = (fabs(m_rx) + fabs(m_ry)) / 2;
+ double da = acos(ra / (ra + 0.125 / m_scale)) * 2;
+ m_num = uround(2*pi / da);
}
//------------------------------------------------------------------------
@@ -83,6 +107,7 @@ namespace agg
}
if(m_step > m_num) return path_cmd_stop;
double angle = double(m_step) / double(m_num) * 2.0 * pi;
+ if(m_cw) angle = 2.0 * pi - angle;
*x = m_x + cos(angle) * m_rx;
*y = m_y + sin(angle) * m_ry;
m_step++;
diff --git a/agg/inc/agg_ellipse_bresenham.h b/agg/inc/agg_ellipse_bresenham.h
index 41133a473d9e..a83dde12286a 100755
--- a/agg/inc/agg_ellipse_bresenham.h
+++ b/agg/inc/agg_ellipse_bresenham.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
diff --git a/agg/inc/agg_embedded_raster_fonts.h b/agg/inc/agg_embedded_raster_fonts.h
index f30fedfebe39..3092054b2670 100755
--- a/agg/inc/agg_embedded_raster_fonts.h
+++ b/agg/inc/agg_embedded_raster_fonts.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
diff --git a/agg/inc/agg_font_cache_manager.h b/agg/inc/agg_font_cache_manager.h
index 55c4d39db75d..813a1a194599 100755
--- a/agg/inc/agg_font_cache_manager.h
+++ b/agg/inc/agg_font_cache_manager.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -39,7 +39,7 @@ namespace agg
int8u* data;
unsigned data_size;
glyph_data_type data_type;
- rect bounds;
+ rect_i bounds;
double advance_x;
double advance_y;
};
@@ -49,12 +49,16 @@ namespace agg
class font_cache
{
public:
- enum { block_size = 16384-16 };
+ enum block_size_e { block_size = 16384-16 };
//--------------------------------------------------------------------
- font_cache(const char* font_signature) :
+ font_cache() :
m_allocator(block_size),
m_font_signature(0)
+ {}
+
+ //--------------------------------------------------------------------
+ void signature(const char* font_signature)
{
m_font_signature = (char*)m_allocator.allocate(strlen(font_signature) + 1);
strcpy(m_font_signature, font_signature);
@@ -83,7 +87,7 @@ namespace agg
unsigned glyph_index,
unsigned data_size,
glyph_data_type data_type,
- const rect& bounds,
+ const rect_i& bounds,
double advance_x,
double advance_y)
{
@@ -103,18 +107,18 @@ namespace agg
(glyph_cache*)m_allocator.allocate(sizeof(glyph_cache),
sizeof(double));
- glyph->glyph_index = glyph_index;
- glyph->data = m_allocator.allocate(data_size);
- glyph->data_size = data_size;
- glyph->data_type = data_type;
- glyph->bounds = bounds;
- glyph->advance_x = advance_x;
- glyph->advance_y = advance_y;
+ glyph->glyph_index = glyph_index;
+ glyph->data = m_allocator.allocate(data_size);
+ glyph->data_size = data_size;
+ glyph->data_type = data_type;
+ glyph->bounds = bounds;
+ glyph->advance_x = advance_x;
+ glyph->advance_y = advance_y;
return m_glyphs[msb][lsb] = glyph;
}
private:
- pod_allocator m_allocator;
+ block_allocator m_allocator;
glyph_cache** m_glyphs[256];
char* m_font_signature;
};
@@ -135,14 +139,14 @@ namespace agg
unsigned i;
for(i = 0; i < m_num_fonts; ++i)
{
- delete m_fonts[i];
+ obj_allocator<font_cache>::deallocate(m_fonts[i]);
}
- delete [] m_fonts;
+ pod_allocator<font_cache*>::deallocate(m_fonts, m_max_fonts);
}
//--------------------------------------------------------------------
font_cache_pool(unsigned max_fonts=32) :
- m_fonts(new font_cache* [max_fonts]),
+ m_fonts(pod_allocator<font_cache*>::allocate(max_fonts)),
m_max_fonts(max_fonts),
m_num_fonts(0),
m_cur_font(0)
@@ -157,8 +161,9 @@ namespace agg
{
if(reset_cache)
{
- delete m_fonts[idx];
- m_fonts[idx] = new font_cache(font_signature);
+ obj_allocator<font_cache>::deallocate(m_fonts[idx]);
+ m_fonts[idx] = obj_allocator<font_cache>::allocate();
+ m_fonts[idx]->signature(font_signature);
}
m_cur_font = m_fonts[idx];
}
@@ -166,13 +171,14 @@ namespace agg
{
if(m_num_fonts >= m_max_fonts)
{
- delete m_fonts[0];
+ obj_allocator<font_cache>::deallocate(m_fonts[0]);
memcpy(m_fonts,
m_fonts + 1,
(m_max_fonts - 1) * sizeof(font_cache*));
m_num_fonts = m_max_fonts - 1;
}
- m_fonts[m_num_fonts] = new font_cache(font_signature);
+ m_fonts[m_num_fonts] = obj_allocator<font_cache>::allocate();
+ m_fonts[m_num_fonts]->signature(font_signature);
m_cur_font = m_fonts[m_num_fonts];
++m_num_fonts;
}
@@ -196,7 +202,7 @@ namespace agg
unsigned glyph_index,
unsigned data_size,
glyph_data_type data_type,
- const rect& bounds,
+ const rect_i& bounds,
double advance_x,
double advance_y)
{
@@ -270,6 +276,12 @@ namespace agg
{}
//--------------------------------------------------------------------
+ void reset_last_glyph()
+ {
+ m_prev_glyph = m_last_glyph = 0;
+ }
+
+ //--------------------------------------------------------------------
const glyph_cache* glyph(unsigned glyph_code)
{
synchronize();
diff --git a/agg/inc/agg_gamma_functions.h b/agg/inc/agg_gamma_functions.h
index 09a8305faedb..cfebf9c3ea50 100755
--- a/agg/inc/agg_gamma_functions.h
+++ b/agg/inc/agg_gamma_functions.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
diff --git a/agg/inc/agg_gamma_lut.h b/agg/inc/agg_gamma_lut.h
index 30e3b3c89d04..edbbe7440183 100755
--- a/agg/inc/agg_gamma_lut.h
+++ b/agg/inc/agg_gamma_lut.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -27,14 +27,16 @@ namespace agg
unsigned HiResShift=8> class gamma_lut
{
public:
- enum
+ typedef gamma_lut<LoResT, HiResT, GammaShift, HiResShift> self_type;
+
+ enum gamma_scale_e
{
gamma_shift = GammaShift,
gamma_size = 1 << gamma_shift,
gamma_mask = gamma_size - 1
};
- enum
+ enum hi_res_scale_e
{
hi_res_shift = HiResShift,
hi_res_size = 1 << hi_res_shift,
@@ -43,14 +45,14 @@ namespace agg
~gamma_lut()
{
- delete [] m_inv_gamma;
- delete [] m_dir_gamma;
+ pod_allocator<LoResT>::deallocate(m_inv_gamma, hi_res_size);
+ pod_allocator<HiResT>::deallocate(m_dir_gamma, gamma_size);
}
gamma_lut() :
m_gamma(1.0),
- m_dir_gamma(new HiResT[gamma_size]),
- m_inv_gamma(new LoResT[hi_res_size])
+ m_dir_gamma(pod_allocator<HiResT>::allocate(gamma_size)),
+ m_inv_gamma(pod_allocator<LoResT>::allocate(hi_res_size))
{
unsigned i;
for(i = 0; i < gamma_size; i++)
@@ -66,8 +68,8 @@ namespace agg
gamma_lut(double g) :
m_gamma(1.0),
- m_dir_gamma(new HiResT[gamma_size]),
- m_inv_gamma(new LoResT[hi_res_size])
+ m_dir_gamma(pod_allocator<HiResT>::allocate(gamma_size)),
+ m_inv_gamma(pod_allocator<LoResT>::allocate(hi_res_size))
{
gamma(g);
}
@@ -79,13 +81,15 @@ namespace agg
unsigned i;
for(i = 0; i < gamma_size; i++)
{
- m_dir_gamma[i] = (HiResT)(pow(double(i) / double(gamma_mask), m_gamma) * double(hi_res_mask) + 0.5);
+ m_dir_gamma[i] = (HiResT)
+ uround(pow(i / double(gamma_mask), m_gamma) * double(hi_res_mask));
}
double inv_g = 1.0 / g;
for(i = 0; i < hi_res_size; i++)
{
- m_inv_gamma[i] = (LoResT)(pow(double(i) / double(hi_res_mask), inv_g) * double(gamma_mask) + 0.5);
+ m_inv_gamma[i] = (LoResT)
+ uround(pow(i / double(hi_res_mask), inv_g) * double(gamma_mask));
}
}
@@ -105,6 +109,9 @@ namespace agg
}
private:
+ gamma_lut(const self_type&);
+ const self_type& operator = (const self_type&);
+
double m_gamma;
HiResT* m_dir_gamma;
LoResT* m_inv_gamma;
diff --git a/agg/inc/agg_glyph_raster_bin.h b/agg/inc/agg_glyph_raster_bin.h
index 851d9f94bd72..674c247b1395 100755
--- a/agg/inc/agg_glyph_raster_bin.h
+++ b/agg/inc/agg_glyph_raster_bin.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
diff --git a/agg/inc/agg_gsv_text.h b/agg/inc/agg_gsv_text.h
index 5d8e1cf63bab..2e125055b5a8 100755
--- a/agg/inc/agg_gsv_text.h
+++ b/agg/inc/agg_gsv_text.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -20,7 +20,7 @@
#ifndef AGG_GSV_TEXT_INCLUDED
#define AGG_GSV_TEXT_INCLUDED
-#include "agg_basics.h"
+#include "agg_array.h"
#include "agg_conv_stroke.h"
#include "agg_conv_transform.h"
@@ -43,7 +43,6 @@ namespace agg
};
public:
- ~gsv_text();
gsv_text();
void font(const void* font);
@@ -55,7 +54,9 @@ namespace agg
void start_point(double x, double y);
void text(const char* text);
- void rewind(unsigned id);
+ double text_width();
+
+ void rewind(unsigned path_id);
unsigned vertex(double* x, double* y);
private:
@@ -80,30 +81,28 @@ namespace agg
}
private:
- double m_x;
- double m_y;
- double m_start_x;
- double m_width;
- double m_height;
- double m_space;
- double m_line_space;
- char m_chr[2];
- char* m_text;
- char* m_text_buf;
- unsigned m_buf_size;
- char* m_cur_chr;
- const void* m_font;
- char* m_loaded_font;
- status m_status;
- bool m_big_endian;
- bool m_flip;
-
- int8u* m_indices;
- int8* m_glyphs;
- int8* m_bglyph;
- int8* m_eglyph;
- double m_w;
- double m_h;
+ double m_x;
+ double m_y;
+ double m_start_x;
+ double m_width;
+ double m_height;
+ double m_space;
+ double m_line_space;
+ char m_chr[2];
+ char* m_text;
+ pod_array<char> m_text_buf;
+ char* m_cur_chr;
+ const void* m_font;
+ pod_array<char> m_loaded_font;
+ status m_status;
+ bool m_big_endian;
+ bool m_flip;
+ int8u* m_indices;
+ int8* m_glyphs;
+ int8* m_bglyph;
+ int8* m_eglyph;
+ double m_w;
+ double m_h;
};
@@ -129,9 +128,9 @@ namespace agg
m_trans->transformer(trans);
}
- void rewind(unsigned id)
+ void rewind(unsigned path_id)
{
- m_trans.rewind(id);
+ m_trans.rewind(path_id);
m_polyline.line_join(round_join);
m_polyline.line_cap(round_cap);
}
diff --git a/agg/inc/agg_image_accessors.h b/agg/inc/agg_image_accessors.h
new file mode 100644
index 000000000000..043706fe2b69
--- /dev/null
+++ b/agg/inc/agg_image_accessors.h
@@ -0,0 +1,481 @@
+//----------------------------------------------------------------------------
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
+//
+// Permission to copy, use, modify, sell and distribute this software
+// is granted provided this copyright notice appears in all copies.
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+//
+//----------------------------------------------------------------------------
+// Contact: mcseem@antigrain.com
+// mcseemagg@yahoo.com
+// http://www.antigrain.com
+//----------------------------------------------------------------------------
+
+#ifndef AGG_IMAGE_ACCESSORS_INCLUDED
+#define AGG_IMAGE_ACCESSORS_INCLUDED
+
+#include "agg_basics.h"
+
+namespace agg
+{
+
+ //-----------------------------------------------------image_accessor_clip
+ template<class PixFmt> class image_accessor_clip
+ {
+ public:
+ typedef PixFmt pixfmt_type;
+ typedef typename pixfmt_type::color_type color_type;
+ typedef typename pixfmt_type::order_type order_type;
+ typedef typename pixfmt_type::value_type value_type;
+ enum pix_width_e { pix_width = pixfmt_type::pix_width };
+
+ image_accessor_clip() {}
+ explicit image_accessor_clip(const pixfmt_type& pixf,
+ const color_type& bk) :
+ m_pixf(&pixf)
+ {
+ pixfmt_type::make_pix(m_bk_buf, bk);
+ }
+
+ void attach(const pixfmt_type& pixf)
+ {
+ m_pixf = &pixf;
+ }
+
+ void background_color(const color_type& bk)
+ {
+ pixfmt_type::make_pix(m_bk_buf, bk);
+ }
+
+ private:
+ AGG_INLINE const int8u* pixel() const
+ {
+ if(m_y >= 0 && m_y < (int)m_pixf->height() &&
+ m_x >= 0 && m_x < (int)m_pixf->width())
+ {
+ return m_pixf->pix_ptr(m_x, m_y);
+ }
+ return m_bk_buf;
+ }
+
+ public:
+ AGG_INLINE const int8u* span(int x, int y, unsigned len)
+ {
+ m_x = m_x0 = x;
+ m_y = y;
+ if(y >= 0 && y < (int)m_pixf->height() &&
+ x >= 0 && x+(int)len <= (int)m_pixf->width())
+ {
+ return m_pix_ptr = m_pixf->pix_ptr(x, y);
+ }
+ m_pix_ptr = 0;
+ return pixel();
+ }
+
+ AGG_INLINE const int8u* next_x()
+ {
+ if(m_pix_ptr) return m_pix_ptr += pix_width;
+ ++m_x;
+ return pixel();
+ }
+
+ AGG_INLINE const int8u* next_y()
+ {
+ ++m_y;
+ m_x = m_x0;
+ if(m_pix_ptr &&
+ m_y >= 0 && m_y < (int)m_pixf->height())
+ {
+ return m_pix_ptr = m_pixf->pix_ptr(m_x, m_y);
+ }
+ m_pix_ptr = 0;
+ return pixel();
+ }
+
+ private:
+ const pixfmt_type* m_pixf;
+ int8u m_bk_buf[4];
+ int m_x, m_x0, m_y;
+ const int8u* m_pix_ptr;
+ };
+
+
+
+
+ //--------------------------------------------------image_accessor_no_clip
+ template<class PixFmt> class image_accessor_no_clip
+ {
+ public:
+ typedef PixFmt pixfmt_type;
+ typedef typename pixfmt_type::color_type color_type;
+ typedef typename pixfmt_type::order_type order_type;
+ typedef typename pixfmt_type::value_type value_type;
+ enum pix_width_e { pix_width = pixfmt_type::pix_width };
+
+ image_accessor_no_clip() {}
+ explicit image_accessor_no_clip(const pixfmt_type& pixf) :
+ m_pixf(&pixf)
+ {}
+
+ void attach(const pixfmt_type& pixf)
+ {
+ m_pixf = &pixf;
+ }
+
+ AGG_INLINE const int8u* span(int x, int y, unsigned)
+ {
+ m_x = x;
+ m_y = y;
+ return m_pix_ptr = m_pixf->pix_ptr(x, y);
+ }
+
+ AGG_INLINE const int8u* next_x()
+ {
+ return m_pix_ptr += pix_width;
+ }
+
+ AGG_INLINE const int8u* next_y()
+ {
+ ++m_y;
+ return m_pix_ptr = m_pixf->pix_ptr(m_x, m_y);
+ }
+
+ private:
+ const pixfmt_type* m_pixf;
+ int m_x, m_y;
+ const int8u* m_pix_ptr;
+ };
+
+
+
+
+ //----------------------------------------------------image_accessor_clone
+ template<class PixFmt> class image_accessor_clone
+ {
+ public:
+ typedef PixFmt pixfmt_type;
+ typedef typename pixfmt_type::color_type color_type;
+ typedef typename pixfmt_type::order_type order_type;
+ typedef typename pixfmt_type::value_type value_type;
+ enum pix_width_e { pix_width = pixfmt_type::pix_width };
+
+ image_accessor_clone() {}
+ explicit image_accessor_clone(const pixfmt_type& pixf) :
+ m_pixf(&pixf)
+ {}
+
+ void attach(const pixfmt_type& pixf)
+ {
+ m_pixf = &pixf;
+ }
+
+ private:
+ AGG_INLINE const int8u* pixel() const
+ {
+ register int x = m_x;
+ register int y = m_y;
+ if(x < 0) x = 0;
+ if(y < 0) y = 0;
+ if(x >= (int)m_pixf->width()) x = m_pixf->width() - 1;
+ if(y >= (int)m_pixf->height()) y = m_pixf->height() - 1;
+ return m_pixf->pix_ptr(x, y);
+ }
+
+ public:
+ AGG_INLINE const int8u* span(int x, int y, unsigned len)
+ {
+ m_x = m_x0 = x;
+ m_y = y;
+ if(y >= 0 && y < (int)m_pixf->height() &&
+ x >= 0 && x+len <= (int)m_pixf->width())
+ {
+ return m_pix_ptr = m_pixf->pix_ptr(x, y);
+ }
+ m_pix_ptr = 0;
+ return pixel();
+ }
+
+ AGG_INLINE const int8u* next_x()
+ {
+ if(m_pix_ptr) return m_pix_ptr += pix_width;
+ ++m_x;
+ return pixel();
+ }
+
+ AGG_INLINE const int8u* next_y()
+ {
+ ++m_y;
+ m_x = m_x0;
+ if(m_pix_ptr &&
+ m_y >= 0 && m_y < (int)m_pixf->height())
+ {
+ return m_pix_ptr = m_pixf->pix_ptr(m_x, m_y);
+ }
+ m_pix_ptr = 0;
+ return pixel();
+ }
+
+ private:
+ const pixfmt_type* m_pixf;
+ int m_x, m_x0, m_y;
+ const int8u* m_pix_ptr;
+ };
+
+
+
+
+
+ //-----------------------------------------------------image_accessor_wrap
+ template<class PixFmt, class WrapX, class WrapY> class image_accessor_wrap
+ {
+ public:
+ typedef PixFmt pixfmt_type;
+ typedef typename pixfmt_type::color_type color_type;
+ typedef typename pixfmt_type::order_type order_type;
+ typedef typename pixfmt_type::value_type value_type;
+ enum pix_width_e { pix_width = pixfmt_type::pix_width };
+
+ image_accessor_wrap() {}
+ explicit image_accessor_wrap(const pixfmt_type& pixf) :
+ m_pixf(&pixf),
+ m_wrap_x(pixf.width()),
+ m_wrap_y(pixf.height())
+ {}
+
+ void attach(const pixfmt_type& pixf)
+ {
+ m_pixf = &pixf;
+ }
+
+ AGG_INLINE const int8u* span(int x, int y, unsigned)
+ {
+ m_x = x;
+ m_row_ptr = m_pixf->row_ptr(m_wrap_y(y));
+ return m_row_ptr + m_wrap_x(x) * pix_width;
+ }
+
+ AGG_INLINE const int8u* next_x()
+ {
+ int x = ++m_wrap_x;
+ return m_row_ptr + x * pix_width;
+ }
+
+ AGG_INLINE const int8u* next_y()
+ {
+ m_row_ptr = m_pixf->row_ptr(++m_wrap_y);
+ return m_row_ptr + m_wrap_x(m_x) * pix_width;
+ }
+
+ private:
+ const pixfmt_type* m_pixf;
+ const int8u* m_row_ptr;
+ int m_x;
+ WrapX m_wrap_x;
+ WrapY m_wrap_y;
+ };
+
+
+
+
+ //--------------------------------------------------------wrap_mode_repeat
+ class wrap_mode_repeat
+ {
+ public:
+ wrap_mode_repeat() {}
+ wrap_mode_repeat(unsigned size) :
+ m_size(size),
+ m_add(size * (0x3FFFFFFF / size)),
+ m_value(0)
+ {}
+
+ AGG_INLINE unsigned operator() (int v)
+ {
+ return m_value = (unsigned(v) + m_add) % m_size;
+ }
+
+ AGG_INLINE unsigned operator++ ()
+ {
+ ++m_value;
+ if(m_value >= m_size) m_value = 0;
+ return m_value;
+ }
+ private:
+ unsigned m_size;
+ unsigned m_add;
+ unsigned m_value;
+ };
+
+
+ //---------------------------------------------------wrap_mode_repeat_pow2
+ class wrap_mode_repeat_pow2
+ {
+ public:
+ wrap_mode_repeat_pow2() {}
+ wrap_mode_repeat_pow2(unsigned size) : m_value(0)
+ {
+ m_mask = 1;
+ while(m_mask < size) m_mask = (m_mask << 1) | 1;
+ m_mask >>= 1;
+ }
+ AGG_INLINE unsigned operator() (int v)
+ {
+ return m_value = unsigned(v) & m_mask;
+ }
+ AGG_INLINE unsigned operator++ ()
+ {
+ ++m_value;
+ if(m_value > m_mask) m_value = 0;
+ return m_value;
+ }
+ private:
+ unsigned m_mask;
+ unsigned m_value;
+ };
+
+
+ //----------------------------------------------wrap_mode_repeat_auto_pow2
+ class wrap_mode_repeat_auto_pow2
+ {
+ public:
+ wrap_mode_repeat_auto_pow2() {}
+ wrap_mode_repeat_auto_pow2(unsigned size) :
+ m_size(size),
+ m_add(size * (0x3FFFFFFF / size)),
+ m_mask((m_size & (m_size-1)) ? 0 : m_size-1),
+ m_value(0)
+ {}
+
+ AGG_INLINE unsigned operator() (int v)
+ {
+ if(m_mask) return m_value = unsigned(v) & m_mask;
+ return m_value = (unsigned(v) + m_add) % m_size;
+ }
+ AGG_INLINE unsigned operator++ ()
+ {
+ ++m_value;
+ if(m_value >= m_size) m_value = 0;
+ return m_value;
+ }
+
+ private:
+ unsigned m_size;
+ unsigned m_add;
+ unsigned m_mask;
+ unsigned m_value;
+ };
+
+
+ //-------------------------------------------------------wrap_mode_reflect
+ class wrap_mode_reflect
+ {
+ public:
+ wrap_mode_reflect() {}
+ wrap_mode_reflect(unsigned size) :
+ m_size(size),
+ m_size2(size * 2),
+ m_add(m_size2 * (0x3FFFFFFF / m_size2)),
+ m_value(0)
+ {}
+
+ AGG_INLINE unsigned operator() (int v)
+ {
+ m_value = (unsigned(v) + m_add) % m_size2;
+ if(m_value >= m_size) return m_size2 - m_value - 1;
+ return m_value;
+ }
+
+ AGG_INLINE unsigned operator++ ()
+ {
+ ++m_value;
+ if(m_value >= m_size2) m_value = 0;
+ if(m_value >= m_size) return m_size2 - m_value - 1;
+ return m_value;
+ }
+ private:
+ unsigned m_size;
+ unsigned m_size2;
+ unsigned m_add;
+ unsigned m_value;
+ };
+
+
+
+ //--------------------------------------------------wrap_mode_reflect_pow2
+ class wrap_mode_reflect_pow2
+ {
+ public:
+ wrap_mode_reflect_pow2() {}
+ wrap_mode_reflect_pow2(unsigned size) : m_value(0)
+ {
+ m_mask = 1;
+ m_size = 1;
+ while(m_mask < size)
+ {
+ m_mask = (m_mask << 1) | 1;
+ m_size <<= 1;
+ }
+ }
+ AGG_INLINE unsigned operator() (int v)
+ {
+ m_value = unsigned(v) & m_mask;
+ if(m_value >= m_size) return m_mask - m_value;
+ return m_value;
+ }
+ AGG_INLINE unsigned operator++ ()
+ {
+ ++m_value;
+ m_value &= m_mask;
+ if(m_value >= m_size) return m_mask - m_value;
+ return m_value;
+ }
+ private:
+ unsigned m_size;
+ unsigned m_mask;
+ unsigned m_value;
+ };
+
+
+
+ //---------------------------------------------wrap_mode_reflect_auto_pow2
+ class wrap_mode_reflect_auto_pow2
+ {
+ public:
+ wrap_mode_reflect_auto_pow2() {}
+ wrap_mode_reflect_auto_pow2(unsigned size) :
+ m_size(size),
+ m_size2(size * 2),
+ m_add(m_size2 * (0x3FFFFFFF / m_size2)),
+ m_mask((m_size2 & (m_size2-1)) ? 0 : m_size2-1),
+ m_value(0)
+ {}
+
+ AGG_INLINE unsigned operator() (int v)
+ {
+ m_value = m_mask ? unsigned(v) & m_mask :
+ (unsigned(v) + m_add) % m_size2;
+ if(m_value >= m_size) return m_size2 - m_value - 1;
+ return m_value;
+ }
+ AGG_INLINE unsigned operator++ ()
+ {
+ ++m_value;
+ if(m_value >= m_size2) m_value = 0;
+ if(m_value >= m_size) return m_size2 - m_value - 1;
+ return m_value;
+ }
+
+ private:
+ unsigned m_size;
+ unsigned m_size2;
+ unsigned m_add;
+ unsigned m_mask;
+ unsigned m_value;
+ };
+
+
+}
+
+
+#endif
diff --git a/agg/inc/agg_image_filters.h b/agg/inc/agg_image_filters.h
index a2037fe0eff1..64f12cd25b7d 100755
--- a/agg/inc/agg_image_filters.h
+++ b/agg/inc/agg_image_filters.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -20,23 +20,26 @@
#ifndef AGG_IMAGE_FILTERS_INCLUDED
#define AGG_IMAGE_FILTERS_INCLUDED
-#include <math.h>
-#include "agg_basics.h"
+#include "agg_array.h"
+#include "agg_math.h"
namespace agg
{
// See Implementation agg_image_filters.cpp
- enum
+ enum image_filter_scale_e
{
image_filter_shift = 14, //----image_filter_shift
- image_filter_size = 1 << image_filter_shift, //----image_filter_size
- image_filter_mask = image_filter_size - 1, //----image_filter_mask
+ image_filter_scale = 1 << image_filter_shift, //----image_filter_scale
+ image_filter_mask = image_filter_scale - 1 //----image_filter_mask
+ };
+ enum image_subpixel_scale_e
+ {
image_subpixel_shift = 8, //----image_subpixel_shift
- image_subpixel_size = 1 << image_subpixel_shift, //----image_subpixel_size
- image_subpixel_mask = image_subpixel_size - 1 //----image_subpixel_mask
+ image_subpixel_scale = 1 << image_subpixel_shift, //----image_subpixel_scale
+ image_subpixel_mask = image_subpixel_scale - 1 //----image_subpixel_mask
};
@@ -44,22 +47,19 @@ namespace agg
class image_filter_lut
{
public:
- ~image_filter_lut();
- image_filter_lut();
-
template<class FilterF> void calculate(const FilterF& filter,
bool normalization=true)
{
double r = filter.radius();
- realloc(r);
+ realloc_lut(r);
unsigned i;
unsigned pivot = diameter() << (image_subpixel_shift - 1);
for(i = 0; i < pivot; i++)
{
- double x = double(i) / double(image_subpixel_size);
+ double x = double(i) / double(image_subpixel_scale);
double y = filter.calc_weight(x);
m_weight_array[pivot + i] =
- m_weight_array[pivot - i] = int16(y * image_filter_size + 0.5);
+ m_weight_array[pivot - i] = (int16)iround(y * image_filter_scale);
}
unsigned end = (diameter() << image_subpixel_shift) - 1;
m_weight_array[0] = m_weight_array[end];
@@ -69,30 +69,29 @@ namespace agg
}
}
+ image_filter_lut() : m_radius(0), m_diameter(0), m_start(0) {}
+
template<class FilterF> image_filter_lut(const FilterF& filter,
- bool normalization=true) :
- m_weight_array(0),
- m_max_size(0)
+ bool normalization=true)
{
calculate(filter, normalization);
}
- double radius() const { return m_radius; }
- unsigned diameter() const { return m_diameter; }
- int start() const { return m_start; }
- const int16* weight_array() const { return m_weight_array; }
+ double radius() const { return m_radius; }
+ unsigned diameter() const { return m_diameter; }
+ int start() const { return m_start; }
+ const int16* weight_array() const { return &m_weight_array[0]; }
void normalize();
private:
- void realloc(double radius);
+ void realloc_lut(double radius);
image_filter_lut(const image_filter_lut&);
const image_filter_lut& operator = (const image_filter_lut&);
- double m_radius;
- unsigned m_diameter;
- int m_start;
- int16* m_weight_array;
- unsigned m_max_size;
+ double m_radius;
+ unsigned m_diameter;
+ int m_start;
+ pod_array<int16> m_weight_array;
};
@@ -312,7 +311,7 @@ namespace agg
static double radius() { return 3.2383; }
static double calc_weight(double x)
{
- return (x == 0.0) ? pi / 4.0 : j1(pi * x) / (2.0 * x);
+ return (x == 0.0) ? pi / 4.0 : besj(pi * x, 1) / (2.0 * x);
}
};
diff --git a/agg/inc/agg_line_aa_basics.h b/agg/inc/agg_line_aa_basics.h
index ab8e94715019..d5c4feb36967 100755
--- a/agg/inc/agg_line_aa_basics.h
+++ b/agg/inc/agg_line_aa_basics.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -24,44 +24,58 @@ namespace agg
// See Implementation agg_line_aa_basics.cpp
//-------------------------------------------------------------------------
- enum
+ enum line_subpixel_scale_e
{
- line_subpixel_shift = 8, //----line_subpixel_shift
- line_subpixel_size = 1 << line_subpixel_shift, //----line_subpixel_size
- line_subpixel_mask = line_subpixel_size - 1 //----line_subpixel_mask
+ line_subpixel_shift = 8, //----line_subpixel_shift
+ line_subpixel_scale = 1 << line_subpixel_shift, //----line_subpixel_scale
+ line_subpixel_mask = line_subpixel_scale - 1, //----line_subpixel_mask
+ line_max_coord = (1 << 28) - 1, //----line_max_coord
+ line_max_length = 1 << (line_subpixel_shift + 10) //----line_max_length
};
//-------------------------------------------------------------------------
- enum
+ enum line_mr_subpixel_scale_e
{
line_mr_subpixel_shift = 4, //----line_mr_subpixel_shift
- line_mr_subpixel_size = 1 << line_mr_subpixel_shift, //----line_mr_subpixel_size
- line_mr_subpixel_mask = line_mr_subpixel_size - 1 //----line_mr_subpixel_mask
+ line_mr_subpixel_scale = 1 << line_mr_subpixel_shift, //----line_mr_subpixel_scale
+ line_mr_subpixel_mask = line_mr_subpixel_scale - 1 //----line_mr_subpixel_mask
};
//------------------------------------------------------------------line_mr
- inline int line_mr(int x)
+ AGG_INLINE int line_mr(int x)
{
- return x >> ((int)line_subpixel_shift - (int)line_mr_subpixel_shift);
+ return x >> (line_subpixel_shift - line_mr_subpixel_shift);
}
//-------------------------------------------------------------------line_hr
- inline int line_hr(int x)
+ AGG_INLINE int line_hr(int x)
{
- return x << ((int)line_subpixel_shift - (int)line_mr_subpixel_shift);
+ return x << (line_subpixel_shift - line_mr_subpixel_shift);
}
//---------------------------------------------------------------line_dbl_hr
- inline int line_dbl_hr(int x)
+ AGG_INLINE int line_dbl_hr(int x)
{
return x << line_subpixel_shift;
}
//---------------------------------------------------------------line_coord
- inline int line_coord(double x)
+ struct line_coord
{
- return int(x * line_subpixel_size);
- }
+ AGG_INLINE static int conv(double x)
+ {
+ return iround(x * line_subpixel_scale);
+ }
+ };
+
+ //-----------------------------------------------------------line_coord_sat
+ struct line_coord_sat
+ {
+ AGG_INLINE static int conv(double x)
+ {
+ return saturation<line_max_coord>::iround(x * line_subpixel_scale);
+ }
+ };
//==========================================================line_parameters
struct line_parameters
@@ -98,6 +112,29 @@ namespace agg
}
//---------------------------------------------------------------------
+ void divide(line_parameters& lp1, line_parameters& lp2) const
+ {
+ int xmid = (x1 + x2) >> 1;
+ int ymid = (y1 + y2) >> 1;
+ int len2 = len >> 1;
+
+ lp1 = *this;
+ lp2 = *this;
+
+ lp1.x2 = xmid;
+ lp1.y2 = ymid;
+ lp1.len = len2;
+ lp1.dx = abs(lp1.x2 - lp1.x1);
+ lp1.dy = abs(lp1.y2 - lp1.y1);
+
+ lp2.x1 = xmid;
+ lp2.y1 = ymid;
+ lp2.len = len2;
+ lp2.dx = abs(lp2.x2 - lp2.x1);
+ lp2.dy = abs(lp2.y2 - lp2.y1);
+ }
+
+ //---------------------------------------------------------------------
int x1, y1, x2, y2, dx, dy, sx, sy;
bool vertical;
int inc;
@@ -105,8 +142,8 @@ namespace agg
int octant;
//---------------------------------------------------------------------
- static int8u s_orthogonal_quadrant[8];
- static int8u s_diagonal_quadrant[8];
+ static const int8u s_orthogonal_quadrant[8];
+ static const int8u s_diagonal_quadrant[8];
};
@@ -123,9 +160,9 @@ namespace agg
void inline fix_degenerate_bisectrix_start(const line_parameters& lp,
int* x, int* y)
{
- int d = int((double(*x - lp.x2) * double(lp.y2 - lp.y1) -
- double(*y - lp.y2) * double(lp.x2 - lp.x1)) / lp.len);
- if(d < line_subpixel_size)
+ int d = iround((double(*x - lp.x2) * double(lp.y2 - lp.y1) -
+ double(*y - lp.y2) * double(lp.x2 - lp.x1)) / lp.len);
+ if(d < line_subpixel_scale/2)
{
*x = lp.x1 + (lp.y2 - lp.y1);
*y = lp.y1 - (lp.x2 - lp.x1);
@@ -137,9 +174,9 @@ namespace agg
void inline fix_degenerate_bisectrix_end(const line_parameters& lp,
int* x, int* y)
{
- int d = int((double(*x - lp.x2) * double(lp.y2 - lp.y1) -
- double(*y - lp.y2) * double(lp.x2 - lp.x1)) / lp.len);
- if(d < line_subpixel_size)
+ int d = iround((double(*x - lp.x2) * double(lp.y2 - lp.y1) -
+ double(*y - lp.y2) * double(lp.x2 - lp.x1)) / lp.len);
+ if(d < line_subpixel_scale/2)
{
*x = lp.x2 + (lp.y2 - lp.y1);
*y = lp.y2 - (lp.x2 - lp.x1);
diff --git a/agg/inc/agg_math.h b/agg/inc/agg_math.h
index 4aef4df9638e..2c35c805e673 100755
--- a/agg/inc/agg_math.h
+++ b/agg/inc/agg_math.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -12,6 +12,9 @@
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
+// Bessel function (besj) was adapted for use in AGG library by Andy Wilk
+// Contact: castor.vulgaris@gmail.com
+//----------------------------------------------------------------------------
#ifndef AGG_MATH_INCLUDED
#define AGG_MATH_INCLUDED
@@ -22,30 +25,34 @@
namespace agg
{
- const double intersection_epsilon = 1.0e-8;
+ //------------------------------------------------------vertex_dist_epsilon
+ // Coinciding points maximal distance (Epsilon)
+ const double vertex_dist_epsilon = 1e-14;
+
+ //-----------------------------------------------------intersection_epsilon
+ // See calc_intersection
+ const double intersection_epsilon = 1.0e-30;
- //------------------------------------------------------calc_point_location
- AGG_INLINE double calc_point_location(double x1, double y1,
- double x2, double y2,
- double x, double y)
+ //------------------------------------------------------------cross_product
+ AGG_INLINE double cross_product(double x1, double y1,
+ double x2, double y2,
+ double x, double y)
{
return (x - x2) * (y2 - y1) - (y - y2) * (x2 - x1);
}
-
//--------------------------------------------------------point_in_triangle
AGG_INLINE bool point_in_triangle(double x1, double y1,
double x2, double y2,
double x3, double y3,
double x, double y)
{
- bool cp1 = calc_point_location(x1, y1, x2, y2, x, y) < 0.0;
- bool cp2 = calc_point_location(x2, y2, x3, y3, x, y) < 0.0;
- bool cp3 = calc_point_location(x3, y3, x1, y1, x, y) < 0.0;
+ bool cp1 = cross_product(x1, y1, x2, y2, x, y) < 0.0;
+ bool cp2 = cross_product(x2, y2, x3, y3, x, y) < 0.0;
+ bool cp3 = cross_product(x3, y3, x1, y1, x, y) < 0.0;
return cp1 == cp2 && cp2 == cp3 && cp3 == cp1;
}
-
//-----------------------------------------------------------calc_distance
AGG_INLINE double calc_distance(double x1, double y1, double x2, double y2)
{
@@ -54,17 +61,76 @@ namespace agg
return sqrt(dx * dx + dy * dy);
}
+ //--------------------------------------------------------calc_sq_distance
+ AGG_INLINE double calc_sq_distance(double x1, double y1, double x2, double y2)
+ {
+ double dx = x2-x1;
+ double dy = y2-y1;
+ return dx * dx + dy * dy;
+ }
- //------------------------------------------------calc_point_line_distance
- AGG_INLINE double calc_point_line_distance(double x1, double y1,
+ //------------------------------------------------calc_line_point_distance
+ AGG_INLINE double calc_line_point_distance(double x1, double y1,
double x2, double y2,
double x, double y)
{
double dx = x2-x1;
double dy = y2-y1;
- return ((x - x2) * dy - (y - y2) * dx) / sqrt(dx * dx + dy * dy);
+ double d = sqrt(dx * dx + dy * dy);
+ if(d < vertex_dist_epsilon)
+ {
+ return calc_distance(x1, y1, x, y);
+ }
+ return ((x - x2) * dy - (y - y2) * dx) / d;
}
+ //-------------------------------------------------------calc_line_point_u
+ AGG_INLINE double calc_segment_point_u(double x1, double y1,
+ double x2, double y2,
+ double x, double y)
+ {
+ double dx = x2 - x1;
+ double dy = y2 - y1;
+
+ if(dx == 0 && dy == 0)
+ {
+ return 0;
+ }
+
+ double pdx = x - x1;
+ double pdy = y - y1;
+
+ return (pdx * dx + pdy * dy) / (dx * dx + dy * dy);
+ }
+
+ //---------------------------------------------calc_line_point_sq_distance
+ AGG_INLINE double calc_segment_point_sq_distance(double x1, double y1,
+ double x2, double y2,
+ double x, double y,
+ double u)
+ {
+ if(u <= 0)
+ {
+ return calc_sq_distance(x, y, x1, y1);
+ }
+ else
+ if(u >= 1)
+ {
+ return calc_sq_distance(x, y, x2, y2);
+ }
+ return calc_sq_distance(x, y, x1 + u * (x2 - x1), y1 + u * (y2 - y1));
+ }
+
+ //---------------------------------------------calc_line_point_sq_distance
+ AGG_INLINE double calc_segment_point_sq_distance(double x1, double y1,
+ double x2, double y2,
+ double x, double y)
+ {
+ return
+ calc_segment_point_sq_distance(
+ x1, y1, x2, y2, x, y,
+ calc_segment_point_u(x1, y1, x2, y2, x, y));
+ }
//-------------------------------------------------------calc_intersection
AGG_INLINE bool calc_intersection(double ax, double ay, double bx, double by,
@@ -80,6 +146,32 @@ namespace agg
return true;
}
+ //-----------------------------------------------------intersection_exists
+ AGG_INLINE bool intersection_exists(double x1, double y1, double x2, double y2,
+ double x3, double y3, double x4, double y4)
+ {
+ // It's less expensive but you can't control the
+ // boundary conditions: Less or LessEqual
+ double dx1 = x2 - x1;
+ double dy1 = y2 - y1;
+ double dx2 = x4 - x3;
+ double dy2 = y4 - y3;
+ return ((x3 - x2) * dy1 - (y3 - y2) * dx1 < 0.0) !=
+ ((x4 - x2) * dy1 - (y4 - y2) * dx1 < 0.0) &&
+ ((x1 - x4) * dy2 - (y1 - y4) * dx2 < 0.0) !=
+ ((x2 - x4) * dy2 - (y2 - y4) * dx2 < 0.0);
+
+ // It's is more expensive but more flexible
+ // in terms of boundary conditions.
+ //--------------------
+ //double den = (x2-x1) * (y4-y3) - (y2-y1) * (x4-x3);
+ //if(fabs(den) < intersection_epsilon) return false;
+ //double nom1 = (x4-x3) * (y1-y3) - (y4-y3) * (x1-x3);
+ //double nom2 = (x2-x1) * (y1-y3) - (y2-y1) * (x1-x3);
+ //double ua = nom1 / den;
+ //double ub = nom2 / den;
+ //return ua >= 0.0 && ua <= 1.0 && ub >= 0.0 && ub <= 1.0;
+ }
//--------------------------------------------------------calc_orthogonal
AGG_INLINE void calc_orthogonal(double thickness,
@@ -90,11 +182,10 @@ namespace agg
double dx = x2 - x1;
double dy = y2 - y1;
double d = sqrt(dx*dx + dy*dy);
- *x = thickness * dy / d;
- *y = thickness * dx / d;
+ *x = thickness * dy / d;
+ *y = -thickness * dx / d;
}
-
//--------------------------------------------------------dilate_triangle
AGG_INLINE void dilate_triangle(double x1, double y1,
double x2, double y2,
@@ -108,10 +199,10 @@ namespace agg
double dy2=0.0;
double dx3=0.0;
double dy3=0.0;
- double loc = calc_point_location(x1, y1, x2, y2, x3, y3);
+ double loc = cross_product(x1, y1, x2, y2, x3, y3);
if(fabs(loc) > intersection_epsilon)
{
- if(calc_point_location(x1, y1, x2, y2, x3, y3) > 0.0)
+ if(cross_product(x1, y1, x2, y2, x3, y3) > 0.0)
{
d = -d;
}
@@ -119,12 +210,20 @@ namespace agg
calc_orthogonal(d, x2, y2, x3, y3, &dx2, &dy2);
calc_orthogonal(d, x3, y3, x1, y1, &dx3, &dy3);
}
- *x++ = x1 + dx1; *y++ = y1 - dy1;
- *x++ = x2 + dx1; *y++ = y2 - dy1;
- *x++ = x2 + dx2; *y++ = y2 - dy2;
- *x++ = x3 + dx2; *y++ = y3 - dy2;
- *x++ = x3 + dx3; *y++ = y3 - dy3;
- *x++ = x1 + dx3; *y++ = y1 - dy3;
+ *x++ = x1 + dx1; *y++ = y1 + dy1;
+ *x++ = x2 + dx1; *y++ = y2 + dy1;
+ *x++ = x2 + dx2; *y++ = y2 + dy2;
+ *x++ = x3 + dx2; *y++ = y3 + dy2;
+ *x++ = x3 + dx3; *y++ = y3 + dy3;
+ *x++ = x1 + dx3; *y++ = y1 + dy3;
+ }
+
+ //------------------------------------------------------calc_triangle_area
+ AGG_INLINE double calc_triangle_area(double x1, double y1,
+ double x2, double y2,
+ double x3, double y3)
+ {
+ return (x1*y2 - x2*y1 + x2*y3 - x3*y2 + x3*y1 - x1*y3) * 0.5;
}
//-------------------------------------------------------calc_polygon_area
@@ -223,7 +322,7 @@ namespace agg
}
}
- //This is calculation sqrt itself.
+ //This code calculates the sqrt.
bit -= 9;
if(bit > 0)
{
@@ -241,6 +340,97 @@ namespace agg
+ //--------------------------------------------------------------------besj
+ // Function BESJ calculates Bessel function of first kind of order n
+ // Arguments:
+ // n - an integer (>=0), the order
+ // x - value at which the Bessel function is required
+ //--------------------
+ // C++ Mathematical Library
+ // Convereted from equivalent FORTRAN library
+ // Converetd by Gareth Walker for use by course 392 computational project
+ // All functions tested and yield the same results as the corresponding
+ // FORTRAN versions.
+ //
+ // If you have any problems using these functions please report them to
+ // M.Muldoon@UMIST.ac.uk
+ //
+ // Documentation available on the web
+ // http://www.ma.umist.ac.uk/mrm/Teaching/392/libs/392.html
+ // Version 1.0 8/98
+ // 29 October, 1999
+ //--------------------
+ // Adapted for use in AGG library by Andy Wilk (castor.vulgaris@gmail.com)
+ //------------------------------------------------------------------------
+ inline double besj(double x, int n)
+ {
+ if(n < 0)
+ {
+ return 0;
+ }
+ double d = 1E-6;
+ double b = 0;
+ if(fabs(x) <= d)
+ {
+ if(n != 0) return 0;
+ return 1;
+ }
+ double b1 = 0; // b1 is the value from the previous iteration
+ // Set up a starting order for recurrence
+ int m1 = (int)fabs(x) + 6;
+ if(fabs(x) > 5)
+ {
+ m1 = (int)(fabs(1.4 * x + 60 / x));
+ }
+ int m2 = (int)(n + 2 + fabs(x) / 4);
+ if (m1 > m2)
+ {
+ m2 = m1;
+ }
+
+ // Apply recurrence down from curent max order
+ for(;;)
+ {
+ double c3 = 0;
+ double c2 = 1E-30;
+ double c4 = 0;
+ int m8 = 1;
+ if (m2 / 2 * 2 == m2)
+ {
+ m8 = -1;
+ }
+ int imax = m2 - 2;
+ for (int i = 1; i <= imax; i++)
+ {
+ double c6 = 2 * (m2 - i) * c2 / x - c3;
+ c3 = c2;
+ c2 = c6;
+ if(m2 - i - 1 == n)
+ {
+ b = c6;
+ }
+ m8 = -1 * m8;
+ if (m8 > 0)
+ {
+ c4 = c4 + 2 * c6;
+ }
+ }
+ double c6 = 2 * c2 / x - c3;
+ if(n == 0)
+ {
+ b = c6;
+ }
+ c4 += c6;
+ b /= c4;
+ if(fabs(b - b1) < d)
+ {
+ return b;
+ }
+ b1 = b;
+ m2 += 3;
+ }
+ }
+
}
diff --git a/agg/inc/agg_math_stroke.h b/agg/inc/agg_math_stroke.h
index 84d83738a9cd..8cec034e11d2 100755
--- a/agg/inc/agg_math_stroke.h
+++ b/agg/inc/agg_math_stroke.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -36,297 +36,483 @@ namespace agg
//------------------------------------------------------------line_join_e
enum line_join_e
{
- miter_join,
- miter_join_revert,
- round_join,
- bevel_join
+ miter_join = 0,
+ miter_join_revert = 1,
+ round_join = 2,
+ bevel_join = 3,
+ miter_join_round = 4
};
- // Minimal angle to calculate round joins, less than 0.1 degree.
- const double stroke_theta = 0.001; //----stroke_theta
+ //-----------------------------------------------------------inner_join_e
+ enum inner_join_e
+ {
+ inner_bevel,
+ inner_miter,
+ inner_jag,
+ inner_round
+ };
- //--------------------------------------------------------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)
+ //------------------------------------------------------------math_stroke
+ template<class VertexConsumer> class math_stroke
{
+ public:
typedef typename VertexConsumer::value_type coord_type;
- //// Check if we actually need the arc (this optimization works bad)
- ////-----------------
- //double dd = calc_distance(dx1, dy1, dx2, dy2);
- //if(dd < 1.0/approximation_scale)
- //{
- // out_vertices.add(coord_type(x + dx1, y + dy1));
- // if(dd > 0.25/approximation_scale)
- // {
- // out_vertices.add(coord_type(x + dx2, y + dy2));
- // }
- // return;
- //}
-
- double a1 = atan2(dy1, dx1);
- double a2 = atan2(dy2, dx2);
- double da = a1 - a2;
+ math_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_join(inner_join_e ij) { m_inner_join = ij; }
+
+ line_cap_e line_cap() const { return m_line_cap; }
+ line_join_e line_join() const { return m_line_join; }
+ inner_join_e inner_join() const { return m_inner_join; }
+
+ void width(double w);
+ 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 calc_cap(VertexConsumer& vc,
+ const vertex_dist& v0,
+ const vertex_dist& v1,
+ double len);
+
+ void calc_join(VertexConsumer& vc,
+ const vertex_dist& v0,
+ const vertex_dist& v1,
+ const vertex_dist& v2,
+ double len1,
+ double len2);
+
+ private:
+ AGG_INLINE void add_vertex(VertexConsumer& vc, double x, double y)
+ {
+ vc.add(coord_type(x, y));
+ }
+
+ void calc_arc(VertexConsumer& vc,
+ double x, double y,
+ double dx1, double dy1,
+ double dx2, double dy2);
+
+ void calc_miter(VertexConsumer& vc,
+ const vertex_dist& v0,
+ const vertex_dist& v1,
+ const vertex_dist& v2,
+ double dx1, double dy1,
+ double dx2, double dy2,
+ line_join_e lj,
+ double mlimit,
+ double dbevel);
+
+ double m_width;
+ double m_width_abs;
+ double m_width_eps;
+ int m_width_sign;
+ double m_miter_limit;
+ double m_inner_miter_limit;
+ double m_approx_scale;
+ line_cap_e m_line_cap;
+ line_join_e m_line_join;
+ inner_join_e m_inner_join;
+ };
- if(fabs(da) < stroke_theta)
+ //-----------------------------------------------------------------------
+ template<class VC> math_stroke<VC>::math_stroke() :
+ m_width(0.5),
+ m_width_abs(0.5),
+ m_width_eps(0.5/1024.0),
+ m_width_sign(1),
+ m_miter_limit(4.0),
+ m_inner_miter_limit(1.01),
+ m_approx_scale(1.0),
+ m_line_cap(butt_cap),
+ m_line_join(miter_join),
+ m_inner_join(inner_miter)
+ {
+ }
+
+ //-----------------------------------------------------------------------
+ template<class VC> void math_stroke<VC>::width(double w)
+ {
+ m_width = w * 0.5;
+ if(m_width < 0)
+ {
+ m_width_abs = -m_width;
+ m_width_sign = -1;
+ }
+ else
{
- out_vertices.add(coord_type((x + x + dx1 + dx2) * 0.5,
- (y + y + dy1 + dy2) * 0.5));
- return;
+ m_width_abs = m_width;
+ m_width_sign = 1;
}
+ m_width_eps = m_width / 1024.0;
+ }
+
+ //-----------------------------------------------------------------------
+ template<class VC> void math_stroke<VC>::miter_limit_theta(double t)
+ {
+ m_miter_limit = 1.0 / sin(t * 0.5) ;
+ }
+
+ //-----------------------------------------------------------------------
+ template<class VC>
+ void math_stroke<VC>::calc_arc(VC& vc,
+ double x, double y,
+ double dx1, double dy1,
+ double dx2, double dy2)
+ {
+ double a1 = atan2(dy1 * m_width_sign, dx1 * m_width_sign);
+ double a2 = atan2(dy2 * m_width_sign, dx2 * m_width_sign);
+ double da = a1 - a2;
+ int i, n;
- bool ccw = da > 0.0 && da < pi;
+ da = acos(m_width_abs / (m_width_abs + 0.125 / m_approx_scale)) * 2;
- if(width < 0) width = -width;
- da = fabs(1.0 / (width * approximation_scale));
- if(!ccw)
+ add_vertex(vc, x + dx1, y + dy1);
+ if(m_width_sign > 0)
{
if(a1 > a2) a2 += 2 * pi;
- while(a1 < a2)
+ n = int((a2 - a1) / da);
+ da = (a2 - a1) / (n + 1);
+ a1 += da;
+ for(i = 0; i < n; i++)
{
- out_vertices.add(coord_type(x + cos(a1) * width, y + sin(a1) * width));
+ add_vertex(vc, x + cos(a1) * m_width, y + sin(a1) * m_width);
a1 += da;
}
}
else
{
if(a1 < a2) a2 -= 2 * pi;
- while(a1 > a2)
+ n = int((a1 - a2) / da);
+ da = (a1 - a2) / (n + 1);
+ a1 -= da;
+ for(i = 0; i < n; i++)
{
- out_vertices.add(coord_type(x + cos(a1) * width, y + sin(a1) * width));
+ add_vertex(vc, x + cos(a1) * m_width, y + sin(a1) * m_width);
a1 -= da;
}
}
- out_vertices.add(coord_type(x + dx2, y + dy2));
+ add_vertex(vc, 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)
+ //-----------------------------------------------------------------------
+ template<class VC>
+ void math_stroke<VC>::calc_miter(VC& vc,
+ const vertex_dist& v0,
+ const vertex_dist& v1,
+ const vertex_dist& v2,
+ double dx1, double dy1,
+ double dx2, double dy2,
+ line_join_e lj,
+ double mlimit,
+ double dbevel)
{
- 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))
+ double xi = v1.x;
+ double yi = v1.y;
+ double di = 1;
+ double lim = m_width_abs * mlimit;
+ bool miter_limit_exceeded = true; // Assume the worst
+ bool intersection_failed = true; // Assume the worst
+
+ 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
+ // Calculation of the intersection succeeded
+ //---------------------
+ di = calc_distance(v1.x, v1.y, xi, yi);
+ if(di <= lim)
+ {
+ // Inside the miter limit
+ //---------------------
+ add_vertex(vc, xi, yi);
+ miter_limit_exceeded = false;
+ }
+ intersection_failed = false;
+ }
+ else
+ {
+ // Calculation of the intersection failed, most probably
+ // the three points lie one straight line.
+ // First check if v0 and v2 lie on the opposite sides of vector:
+ // (v1.x, v1.y) -> (v1.x+dx1, v1.y-dy1), that is, the perpendicular
+ // to the line determined by vertices v0 and v1.
+ // This condition determines whether the next line segments continues
+ // the previous one or goes back.
//----------------
- if(calc_distance(dx1, -dy1, dx2, -dy2) < width * 0.025)
+ double x2 = v1.x + dx1;
+ double y2 = v1.y - dy1;
+ if((cross_product(v0.x, v0.y, v1.x, v1.y, x2, y2) < 0.0) ==
+ (cross_product(v1.x, v1.y, v2.x, v2.y, x2, y2) < 0.0))
{
// 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));
- }
+ add_vertex(vc, v1.x + dx1, v1.y - dy1);
+ miter_limit_exceeded = false;
}
}
- else
+
+ if(miter_limit_exceeded)
{
- double d1 = calc_distance(v1.x, v1.y, xi, yi);
- double lim = width * miter_limit;
- if(d1 > lim)
+ // Miter limit exceeded
+ //------------------------
+ switch(lj)
{
- // Miter limit exceeded
- //------------------------
- if(revert_flag)
+ case miter_join_revert:
+ // For the compatibility with SVG, PDF, etc,
+ // we use a simple bevel join instead of
+ // "smart" bevel
+ //-------------------
+ add_vertex(vc, v1.x + dx1, v1.y - dy1);
+ add_vertex(vc, v1.x + dx2, v1.y - dy2);
+ break;
+
+ case miter_join_round:
+ calc_arc(vc, v1.x, v1.y, dx1, -dy1, dx2, -dy2);
+ break;
+
+ default:
+ // If no miter-revert, calculate new dx1, dy1, dx2, dy2
+ //----------------
+ if(intersection_failed)
{
- // 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));
+ mlimit *= m_width_sign;
+ add_vertex(vc, v1.x + dx1 + dy1 * mlimit,
+ v1.y - dy1 + dx1 * mlimit);
+ add_vertex(vc, v1.x + dx2 - dy2 * mlimit,
+ v1.y - dy2 - dx2 * mlimit);
}
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));
+ di = (lim - dbevel) / (di - dbevel);
+ add_vertex(vc, x1 + (xi - x1) * di,
+ y1 + (yi - y1) * di);
+ add_vertex(vc, x2 + (xi - x2) * di,
+ y2 + (yi - y2) * di);
}
- }
- else
- {
- // Inside the miter limit
- //---------------------
- out_vertices.add(coord_type(xi, yi));
+ break;
}
}
}
-
-
-
-
-
//--------------------------------------------------------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)
+ template<class VC>
+ void math_stroke<VC>::calc_cap(VC& vc,
+ const vertex_dist& v0,
+ const vertex_dist& v1,
+ double len)
{
- typedef typename VertexConsumer::value_type coord_type;
+ vc.remove_all();
- out_vertices.remove_all();
-
- double dx1 = width * (v1.y - v0.y) / len;
- double dy1 = width * (v1.x - v0.x) / len;
+ double dx1 = (v1.y - v0.y) / len;
+ double dy1 = (v1.x - v0.x) / len;
double dx2 = 0;
double dy2 = 0;
- if(line_cap == square_cap)
- {
- dx2 = dy1;
- dy2 = dx1;
- }
+ dx1 *= m_width;
+ dy1 *= m_width;
- if(line_cap == round_cap)
+ if(m_line_cap != round_cap)
{
- double a1 = atan2(dy1, -dx1);
- double a2 = a1 + pi;
- double da = fabs(1.0 / (width * approximation_scale));
- while(a1 < a2)
+ if(m_line_cap == square_cap)
{
- out_vertices.add(coord_type(v0.x + cos(a1) * width,
- v0.y + sin(a1) * width));
- a1 += da;
+ dx2 = dy1 * m_width_sign;
+ dy2 = dx1 * m_width_sign;
}
- out_vertices.add(coord_type(v0.x + dx1, v0.y - dy1));
+ add_vertex(vc, v0.x - dx1 - dx2, v0.y + dy1 - dy2);
+ add_vertex(vc, v0.x + dx1 - dx2, v0.y - dy1 - dy2);
}
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));
+ double da = acos(m_width_abs / (m_width_abs + 0.125 / m_approx_scale)) * 2;
+ double a1;
+ int i;
+ int n = int(pi / da);
+
+ da = pi / (n + 1);
+ add_vertex(vc, v0.x - dx1, v0.y + dy1);
+ if(m_width_sign > 0)
+ {
+ a1 = atan2(dy1, -dx1);
+ a1 += da;
+ for(i = 0; i < n; i++)
+ {
+ add_vertex(vc, v0.x + cos(a1) * m_width,
+ v0.y + sin(a1) * m_width);
+ a1 += da;
+ }
+ }
+ else
+ {
+ a1 = atan2(-dy1, dx1);
+ a1 -= da;
+ for(i = 0; i < n; i++)
+ {
+ add_vertex(vc, v0.x + cos(a1) * m_width,
+ v0.y + sin(a1) * m_width);
+ a1 -= da;
+ }
+ }
+ add_vertex(vc, v0.x + dx1, v0.y - dy1);
}
}
-
-
- //-------------------------------------------------------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)
+ //-----------------------------------------------------------------------
+ template<class VC>
+ void math_stroke<VC>::calc_join(VC& vc,
+ const vertex_dist& v0,
+ const vertex_dist& v1,
+ const vertex_dist& v2,
+ double len1,
+ double len2)
{
- 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;
+ double dx1 = m_width * (v1.y - v0.y) / len1;
+ double dy1 = m_width * (v1.x - v0.x) / len1;
+ double dx2 = m_width * (v2.y - v1.y) / len2;
+ double dy2 = m_width * (v2.x - v1.x) / len2;
- out_vertices.remove_all();
+ vc.remove_all();
- if(calc_point_location(v0.x, v0.y, v1.x, v1.y, v2.x, v2.y) > 0.0)
+ double cp = cross_product(v0.x, v0.y, v1.x, v1.y, v2.x, v2.y);
+ if(cp != 0 && (cp > 0) == (m_width > 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);
+ double limit = ((len1 < len2) ? len1 : len2) / m_width_abs;
+ if(limit < m_inner_miter_limit)
+ {
+ limit = m_inner_miter_limit;
+ }
+
+ switch(m_inner_join)
+ {
+ default: // inner_bevel
+ add_vertex(vc, v1.x + dx1, v1.y - dy1);
+ add_vertex(vc, v1.x + dx2, v1.y - dy2);
+ break;
+
+ case inner_miter:
+ calc_miter(vc,
+ v0, v1, v2, dx1, dy1, dx2, dy2,
+ miter_join_revert,
+ limit, 0);
+ break;
+
+ case inner_jag:
+ case inner_round:
+ cp = (dx1-dx2) * (dx1-dx2) + (dy1-dy2) * (dy1-dy2);
+ if(cp < len1 * len1 && cp < len2 * len2)
+ {
+ calc_miter(vc,
+ v0, v1, v2, dx1, dy1, dx2, dy2,
+ miter_join_revert,
+ limit, 0);
+ }
+ else
+ {
+ if(m_inner_join == inner_jag)
+ {
+ add_vertex(vc, v1.x + dx1, v1.y - dy1);
+ add_vertex(vc, v1.x, v1.y );
+ add_vertex(vc, v1.x + dx2, v1.y - dy2);
+ }
+ else
+ {
+ add_vertex(vc, v1.x + dx1, v1.y - dy1);
+ add_vertex(vc, v1.x, v1.y );
+ calc_arc(vc, v1.x, v1.y, dx2, -dy2, dx1, -dy1);
+ add_vertex(vc, v1.x, v1.y );
+ add_vertex(vc, v1.x + dx2, v1.y - dy2);
+ }
+ }
+ break;
+ }
}
else
{
// Outer join
//---------------
- switch(line_join)
+
+ // Calculate the distance between v1 and
+ // the central point of the bevel line segment
+ //---------------
+ double dx = (dx1 + dx2) / 2;
+ double dy = (dy1 + dy2) / 2;
+ double dbevel = sqrt(dx * dx + dy * dy);
+
+ if(m_line_join == round_join || m_line_join == bevel_join)
{
- case miter_join:
- stroke_calc_miter(out_vertices,
- v0, v1, v2, dx1, dy1, dx2, dy2,
- width,
- false,
- miter_limit);
- break;
+ // This is an optimization that reduces the number of points
+ // in cases of almost collinear segments. If there's no
+ // visible difference between bevel and miter joins we'd rather
+ // use miter join because it adds only one point instead of two.
+ //
+ // Here we calculate the middle point between the bevel points
+ // and then, the distance between v1 and this middle point.
+ // At outer joins this distance always less than stroke width,
+ // because it's actually the height of an isosceles triangle of
+ // v1 and its two bevel points. If the difference between this
+ // width and this value is small (no visible bevel) we can
+ // add just one point.
+ //
+ // The constant in the expression makes the result approximately
+ // the same as in round joins and caps. You can safely comment
+ // out this entire "if".
+ //-------------------
+ if(m_approx_scale * (m_width_abs - dbevel) < m_width_eps)
+ {
+ 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,
+ &dx, &dy))
+ {
+ add_vertex(vc, dx, dy);
+ }
+ else
+ {
+ add_vertex(vc, v1.x + dx1, v1.y - dy1);
+ }
+ return;
+ }
+ }
+ switch(m_line_join)
+ {
+ case miter_join:
case miter_join_revert:
- stroke_calc_miter(out_vertices,
- v0, v1, v2, dx1, dy1, dx2, dy2,
- width,
- true,
- miter_limit);
+ case miter_join_round:
+ calc_miter(vc,
+ v0, v1, v2, dx1, dy1, dx2, dy2,
+ m_line_join,
+ m_miter_limit,
+ dbevel);
break;
case round_join:
- stroke_calc_arc(out_vertices,
- v1.x, v1.y, dx1, -dy1, dx2, -dy2,
- width, approximation_scale);
+ calc_arc(vc, v1.x, v1.y, dx1, -dy1, dx2, -dy2);
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));
- }
+ add_vertex(vc, v1.x + dx1, v1.y - dy1);
+ add_vertex(vc, v1.x + dx2, v1.y - dy2);
break;
}
}
diff --git a/agg/inc/agg_path_length.h b/agg/inc/agg_path_length.h
new file mode 100644
index 000000000000..8f9671748a18
--- /dev/null
+++ b/agg/inc/agg_path_length.h
@@ -0,0 +1,65 @@
+//----------------------------------------------------------------------------
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
+//
+// Permission to copy, use, modify, sell and distribute this software
+// is granted provided this copyright notice appears in all copies.
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+//
+//----------------------------------------------------------------------------
+// Contact: mcseem@antigrain.com
+// mcseemagg@yahoo.com
+// http://www.antigrain.com
+//----------------------------------------------------------------------------
+#ifndef AGG_PATH_LENGTH_INCLUDED
+#define AGG_PATH_LENGTH_INCLUDED
+
+#include "agg_math.h"
+
+namespace agg
+{
+ template<class VertexSource>
+ double path_length(VertexSource& vs, unsigned path_id = 0)
+ {
+ double len = 0.0;
+ double start_x = 0.0;
+ double start_y = 0.0;
+ double x1 = 0.0;
+ double y1 = 0.0;
+ double x2 = 0.0;
+ double y2 = 0.0;
+ bool first = true;
+
+ unsigned cmd;
+ vs.rewind(path_id);
+ while(!is_stop(cmd = vs.vertex(&x2, &y2)))
+ {
+ if(is_vertex(cmd))
+ {
+ if(first || is_move_to(cmd))
+ {
+ start_x = x2;
+ start_y = y2;
+ }
+ else
+ {
+ len += calc_distance(x1, y1, x2, y2);
+ }
+ x1 = x2;
+ y1 = y2;
+ first = false;
+ }
+ else
+ {
+ if(is_close(cmd) && !first)
+ {
+ len += calc_distance(x1, y1, start_x, start_y);
+ }
+ }
+ }
+ return len;
+ }
+}
+
+#endif
diff --git a/agg/inc/agg_path_storage.h b/agg/inc/agg_path_storage.h
index 8cdb9b9bbeb6..930521b4d48d 100755
--- a/agg/inc/agg_path_storage.h
+++ b/agg/inc/agg_path_storage.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -16,101 +16,609 @@
#ifndef AGG_PATH_STORAGE_INCLUDED
#define AGG_PATH_STORAGE_INCLUDED
-#include "agg_basics.h"
+#include <string.h>
+#include <math.h>
+#include "agg_math.h"
+#include "agg_array.h"
+#include "agg_bezier_arc.h"
namespace agg
{
- //------------------------------------------------------------path_storage
- // A container to store vertices with their flags.
- // A path consists of a number of contours separated with "move_to"
- // commands. The path storage can keep and maintain more than one
- // path.
- // To navigate to the beginning of a particular path, use rewind(path_id);
- // Where path_id is what start_new_path() returns. So, when you call
- // start_new_path() you need to store its return value somewhere else
- // to navigate to the path afterwards.
- //
- // See Implementation: agg_path_storage.cpp
- // See also: vertex_source concept
- //------------------------------------------------------------------------
- class path_storage
+
+ //----------------------------------------------------vertex_block_storage
+ template<class T, unsigned BlockShift=8, unsigned BlockPool=256>
+ class vertex_block_storage
{
+ public:
// Allocation parameters
- enum
+ enum block_scale_e
{
- block_shift = 8,
+ block_shift = BlockShift,
block_size = 1 << block_shift,
block_mask = block_size - 1,
- block_pool = 256
+ block_pool = BlockPool
};
- public:
+ typedef T value_type;
+ typedef vertex_block_storage<T, BlockShift, BlockPool> self_type;
- //--------------------------------------------------------------------
- class const_iterator
+ ~vertex_block_storage();
+ vertex_block_storage();
+ vertex_block_storage(const self_type& v);
+ const self_type& operator = (const self_type& ps);
+
+ void remove_all();
+ void free_all();
+
+ void add_vertex(double x, double y, unsigned cmd);
+ void modify_vertex(unsigned idx, double x, double y);
+ void modify_vertex(unsigned idx, double x, double y, unsigned cmd);
+ void modify_command(unsigned idx, unsigned cmd);
+ void swap_vertices(unsigned v1, unsigned v2);
+
+ unsigned last_command() const;
+ unsigned last_vertex(double* x, double* y) const;
+ unsigned prev_vertex(double* x, double* y) const;
+
+ double last_x() const;
+ double last_y() const;
+
+ unsigned total_vertices() const;
+ unsigned vertex(unsigned idx, double* x, double* y) const;
+ unsigned command(unsigned idx) const;
+
+ private:
+ void allocate_block(unsigned nb);
+ int8u* storage_ptrs(T** xy_ptr);
+
+ private:
+ unsigned m_total_vertices;
+ unsigned m_total_blocks;
+ unsigned m_max_blocks;
+ T** m_coord_blocks;
+ int8u** m_cmd_blocks;
+ };
+
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S, unsigned P>
+ void vertex_block_storage<T,S,P>::free_all()
+ {
+ if(m_total_blocks)
{
- void vertex()
+ T** coord_blk = m_coord_blocks + m_total_blocks - 1;
+ while(m_total_blocks--)
{
- if(m_vertex_idx < m_path->total_vertices())
- {
- m_vertex.cmd = m_path->vertex(m_vertex_idx, &m_vertex.x, &m_vertex.y);
- }
- else
- {
- m_vertex.cmd = path_cmd_stop;
- m_vertex.x = m_vertex.y = 0.0;
- }
+ pod_allocator<T>::deallocate(
+ *coord_blk,
+ block_size * 2 +
+ block_size / (sizeof(T) / sizeof(unsigned char)));
+ --coord_blk;
}
+ pod_allocator<T*>::deallocate(m_coord_blocks, m_max_blocks * 2);
+ m_total_blocks = 0;
+ m_max_blocks = 0;
+ m_coord_blocks = 0;
+ m_cmd_blocks = 0;
+ m_total_vertices = 0;
+ }
+ }
- public:
- const_iterator() {}
- const_iterator(unsigned cmd) { m_vertex.cmd = cmd; }
- const_iterator(const const_iterator& i) :
- m_path(i.m_path),
- m_vertex_idx(i.m_vertex_idx),
- m_vertex(i.m_vertex)
+ //------------------------------------------------------------------------
+ template<class T, unsigned S, unsigned P>
+ vertex_block_storage<T,S,P>::~vertex_block_storage()
+ {
+ free_all();
+ }
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S, unsigned P>
+ vertex_block_storage<T,S,P>::vertex_block_storage() :
+ m_total_vertices(0),
+ m_total_blocks(0),
+ m_max_blocks(0),
+ m_coord_blocks(0),
+ m_cmd_blocks(0)
+ {
+ }
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S, unsigned P>
+ vertex_block_storage<T,S,P>::vertex_block_storage(const vertex_block_storage<T,S,P>& v) :
+ m_total_vertices(0),
+ m_total_blocks(0),
+ m_max_blocks(0),
+ m_coord_blocks(0),
+ m_cmd_blocks(0)
+ {
+ *this = v;
+ }
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S, unsigned P>
+ const vertex_block_storage<T,S,P>&
+ vertex_block_storage<T,S,P>::operator = (const vertex_block_storage<T,S,P>& v)
+ {
+ remove_all();
+ unsigned i;
+ for(i = 0; i < v.total_vertices(); i++)
+ {
+ double x, y;
+ unsigned cmd = v.vertex(i, &x, &y);
+ add_vertex(x, y, cmd);
+ }
+ return *this;
+ }
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S, unsigned P>
+ inline void vertex_block_storage<T,S,P>::remove_all()
+ {
+ m_total_vertices = 0;
+ }
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S, unsigned P>
+ inline void vertex_block_storage<T,S,P>::add_vertex(double x, double y,
+ unsigned cmd)
+ {
+ T* coord_ptr = 0;
+ *storage_ptrs(&coord_ptr) = (int8u)cmd;
+ coord_ptr[0] = T(x);
+ coord_ptr[1] = T(y);
+ m_total_vertices++;
+ }
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S, unsigned P>
+ inline void vertex_block_storage<T,S,P>::modify_vertex(unsigned idx,
+ double x, double y)
+ {
+ T* pv = m_coord_blocks[idx >> block_shift] + ((idx & block_mask) << 1);
+ pv[0] = T(x);
+ pv[1] = T(y);
+ }
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S, unsigned P>
+ inline void vertex_block_storage<T,S,P>::modify_vertex(unsigned idx,
+ double x, double y,
+ unsigned cmd)
+ {
+ unsigned block = idx >> block_shift;
+ unsigned offset = idx & block_mask;
+ T* pv = m_coord_blocks[block] + (offset << 1);
+ pv[0] = T(x);
+ pv[1] = T(y);
+ m_cmd_blocks[block][offset] = (int8u)cmd;
+ }
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S, unsigned P>
+ inline void vertex_block_storage<T,S,P>::modify_command(unsigned idx,
+ unsigned cmd)
+ {
+ m_cmd_blocks[idx >> block_shift][idx & block_mask] = (int8u)cmd;
+ }
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S, unsigned P>
+ inline void vertex_block_storage<T,S,P>::swap_vertices(unsigned v1, unsigned v2)
+ {
+ unsigned b1 = v1 >> block_shift;
+ unsigned b2 = v2 >> block_shift;
+ unsigned o1 = v1 & block_mask;
+ unsigned o2 = v2 & block_mask;
+ T* pv1 = m_coord_blocks[b1] + (o1 << 1);
+ T* pv2 = m_coord_blocks[b2] + (o2 << 1);
+ T val;
+ val = pv1[0]; pv1[0] = pv2[0]; pv2[0] = val;
+ val = pv1[1]; pv1[1] = pv2[1]; pv2[1] = val;
+ int8u cmd = m_cmd_blocks[b1][o1];
+ m_cmd_blocks[b1][o1] = m_cmd_blocks[b2][o2];
+ m_cmd_blocks[b2][o2] = cmd;
+ }
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S, unsigned P>
+ inline unsigned vertex_block_storage<T,S,P>::last_command() const
+ {
+ if(m_total_vertices) return command(m_total_vertices - 1);
+ return path_cmd_stop;
+ }
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S, unsigned P>
+ inline unsigned vertex_block_storage<T,S,P>::last_vertex(double* x, double* y) const
+ {
+ if(m_total_vertices) return vertex(m_total_vertices - 1, x, y);
+ return path_cmd_stop;
+ }
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S, unsigned P>
+ inline unsigned vertex_block_storage<T,S,P>::prev_vertex(double* x, double* y) const
+ {
+ if(m_total_vertices > 1) return vertex(m_total_vertices - 2, x, y);
+ return path_cmd_stop;
+ }
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S, unsigned P>
+ inline double vertex_block_storage<T,S,P>::last_x() const
+ {
+ if(m_total_vertices)
+ {
+ unsigned idx = m_total_vertices - 1;
+ return m_coord_blocks[idx >> block_shift][(idx & block_mask) << 1];
+ }
+ return 0.0;
+ }
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S, unsigned P>
+ inline double vertex_block_storage<T,S,P>::last_y() const
+ {
+ if(m_total_vertices)
+ {
+ unsigned idx = m_total_vertices - 1;
+ return m_coord_blocks[idx >> block_shift][((idx & block_mask) << 1) + 1];
+ }
+ return 0.0;
+ }
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S, unsigned P>
+ inline unsigned vertex_block_storage<T,S,P>::total_vertices() const
+ {
+ return m_total_vertices;
+ }
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S, unsigned P>
+ inline unsigned vertex_block_storage<T,S,P>::vertex(unsigned idx,
+ double* x, double* y) const
+ {
+ unsigned nb = idx >> block_shift;
+ const T* pv = m_coord_blocks[nb] + ((idx & block_mask) << 1);
+ *x = pv[0];
+ *y = pv[1];
+ return m_cmd_blocks[nb][idx & block_mask];
+ }
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S, unsigned P>
+ inline unsigned vertex_block_storage<T,S,P>::command(unsigned idx) const
+ {
+ return m_cmd_blocks[idx >> block_shift][idx & block_mask];
+ }
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S, unsigned P>
+ void vertex_block_storage<T,S,P>::allocate_block(unsigned nb)
+ {
+ if(nb >= m_max_blocks)
+ {
+ T** new_coords =
+ pod_allocator<T*>::allocate((m_max_blocks + block_pool) * 2);
+
+ unsigned char** new_cmds =
+ (unsigned char**)(new_coords + m_max_blocks + block_pool);
+
+ if(m_coord_blocks)
{
+ memcpy(new_coords,
+ m_coord_blocks,
+ m_max_blocks * sizeof(T*));
+
+ memcpy(new_cmds,
+ m_cmd_blocks,
+ m_max_blocks * sizeof(unsigned char*));
+
+ pod_allocator<T*>::deallocate(m_coord_blocks, m_max_blocks * 2);
}
+ m_coord_blocks = new_coords;
+ m_cmd_blocks = new_cmds;
+ m_max_blocks += block_pool;
+ }
+ m_coord_blocks[nb] =
+ pod_allocator<T>::allocate(block_size * 2 +
+ block_size / (sizeof(T) / sizeof(unsigned char)));
+
+ m_cmd_blocks[nb] =
+ (unsigned char*)(m_coord_blocks[nb] + block_size * 2);
+
+ m_total_blocks++;
+ }
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S, unsigned P>
+ int8u* vertex_block_storage<T,S,P>::storage_ptrs(T** xy_ptr)
+ {
+ unsigned nb = m_total_vertices >> block_shift;
+ if(nb >= m_total_blocks)
+ {
+ allocate_block(nb);
+ }
+ *xy_ptr = m_coord_blocks[nb] + ((m_total_vertices & block_mask) << 1);
+ return m_cmd_blocks[nb] + (m_total_vertices & block_mask);
+ }
+
+
+
+
+ //-----------------------------------------------------poly_plain_adaptor
+ template<class T> class poly_plain_adaptor
+ {
+ public:
+ typedef T value_type;
+
+ poly_plain_adaptor() :
+ m_data(0),
+ m_ptr(0),
+ m_end(0),
+ m_closed(false),
+ m_stop(false)
+ {}
+
+ poly_plain_adaptor(const T* data, unsigned num_points, bool closed) :
+ m_data(data),
+ m_ptr(data),
+ m_end(data + num_points * 2),
+ m_closed(closed),
+ m_stop(false)
+ {}
+
+ void init(const T* data, unsigned num_points, bool closed)
+ {
+ m_data = data;
+ m_ptr = data;
+ m_end = data + num_points * 2;
+ m_closed = closed;
+ m_stop = false;
+ }
+
+ void rewind(unsigned)
+ {
+ m_ptr = m_data;
+ m_stop = false;
+ }
- const_iterator(const path_storage& p, unsigned id) :
- m_path(&p),
- m_vertex_idx(id)
+ unsigned vertex(double* x, double* y)
+ {
+ if(m_ptr < m_end)
+ {
+ bool first = m_ptr == m_data;
+ *x = *m_ptr++;
+ *y = *m_ptr++;
+ return first ? path_cmd_move_to : path_cmd_line_to;
+ }
+ *x = *y = 0.0;
+ if(m_closed && !m_stop)
{
- vertex();
+ m_stop = true;
+ return path_cmd_end_poly | path_flags_close;
}
+ return path_cmd_stop;
+ }
+
+ private:
+ const T* m_data;
+ const T* m_ptr;
+ const T* m_end;
+ bool m_closed;
+ bool m_stop;
+ };
+
+
+
+
+
+ //-------------------------------------------------poly_container_adaptor
+ template<class Container> class poly_container_adaptor
+ {
+ public:
+ typedef typename Container::value_type vertex_type;
+
+ poly_container_adaptor() :
+ m_container(0),
+ m_index(0),
+ m_closed(false),
+ m_stop(false)
+ {}
- const_iterator& operator++()
+ poly_container_adaptor(const Container& data, bool closed) :
+ m_container(&data),
+ m_index(0),
+ m_closed(closed),
+ m_stop(false)
+ {}
+
+ void init(const Container& data, bool closed)
+ {
+ m_container = &data;
+ m_index = 0;
+ m_closed = closed;
+ m_stop = false;
+ }
+
+ void rewind(unsigned)
+ {
+ m_index = 0;
+ m_stop = false;
+ }
+
+ unsigned vertex(double* x, double* y)
+ {
+ if(m_index < m_container->size())
+ {
+ bool first = m_index == 0;
+ const vertex_type& v = (*m_container)[m_index++];
+ *x = v.x;
+ *y = v.y;
+ return first ? path_cmd_move_to : path_cmd_line_to;
+ }
+ *x = *y = 0.0;
+ if(m_closed && !m_stop)
{
- ++m_vertex_idx;
- vertex();
- return *this;
+ m_stop = true;
+ return path_cmd_end_poly | path_flags_close;
}
+ return path_cmd_stop;
+ }
+
+ private:
+ const Container* m_container;
+ unsigned m_index;
+ bool m_closed;
+ bool m_stop;
+ };
+
+
+
+ //-----------------------------------------poly_container_reverse_adaptor
+ template<class Container> class poly_container_reverse_adaptor
+ {
+ public:
+ typedef typename Container::value_type vertex_type;
- const vertex_type& operator*() const { return m_vertex; }
- const vertex_type* operator->() const { return &m_vertex; }
+ poly_container_reverse_adaptor() :
+ m_container(0),
+ m_index(-1),
+ m_closed(false),
+ m_stop(false)
+ {}
- bool operator != (const const_iterator& i)
+ poly_container_reverse_adaptor(const Container& data, bool closed) :
+ m_container(&data),
+ m_index(-1),
+ m_closed(closed),
+ m_stop(false)
+ {}
+
+ void init(const Container& data, bool closed)
+ {
+ m_container = &data;
+ m_index = m_container->size() - 1;
+ m_closed = closed;
+ m_stop = false;
+ }
+
+ void rewind(unsigned)
+ {
+ m_index = m_container->size() - 1;
+ m_stop = false;
+ }
+
+ unsigned vertex(double* x, double* y)
+ {
+ if(m_index >= 0)
+ {
+ bool first = m_index == int(m_container->size() - 1);
+ const vertex_type& v = (*m_container)[m_index--];
+ *x = v.x;
+ *y = v.y;
+ return first ? path_cmd_move_to : path_cmd_line_to;
+ }
+ *x = *y = 0.0;
+ if(m_closed && !m_stop)
{
- return m_vertex.cmd != i.m_vertex.cmd;
+ m_stop = true;
+ return path_cmd_end_poly | path_flags_close;
}
+ return path_cmd_stop;
+ }
- private:
- const path_storage* m_path;
- unsigned m_vertex_idx;
- vertex_type m_vertex;
- };
+ private:
+ const Container* m_container;
+ int m_index;
+ bool m_closed;
+ bool m_stop;
+ };
- ~path_storage();
- path_storage();
- path_storage(const path_storage& ps);
- void remove_all();
- unsigned last_vertex(double* x, double* y) const;
- unsigned prev_vertex(double* x, double* y) const;
- void rel_to_abs(double* x, double* y) const;
+
+ //--------------------------------------------------------line_adaptor
+ class line_adaptor
+ {
+ public:
+ typedef double value_type;
+
+ line_adaptor() : m_line(m_coord, 2, false) {}
+ line_adaptor(double x1, double y1, double x2, double y2) :
+ m_line(m_coord, 2, false)
+ {
+ m_coord[0] = x1;
+ m_coord[1] = y1;
+ m_coord[2] = x2;
+ m_coord[3] = y2;
+ }
+
+ void init(double x1, double y1, double x2, double y2)
+ {
+ m_coord[0] = x1;
+ m_coord[1] = y1;
+ m_coord[2] = x2;
+ m_coord[3] = y2;
+ m_line.rewind(0);
+ }
+
+ void rewind(unsigned)
+ {
+ m_line.rewind(0);
+ }
+
+ unsigned vertex(double* x, double* y)
+ {
+ return m_line.vertex(x, y);
+ }
+
+ private:
+ double m_coord[4];
+ poly_plain_adaptor<double> m_line;
+ };
+
+
+
+
+
+
+
+
+
+
+
+
+
+ //---------------------------------------------------------------path_base
+ // A container to store vertices with their flags.
+ // A path consists of a number of contours separated with "move_to"
+ // commands. The path storage can keep and maintain more than one
+ // path.
+ // To navigate to the beginning of a particular path, use rewind(path_id);
+ // Where path_id is what start_new_path() returns. So, when you call
+ // start_new_path() you need to store its return value somewhere else
+ // to navigate to the path afterwards.
+ //
+ // See also: vertex_source concept
+ //------------------------------------------------------------------------
+ template<class VertexContainer> class path_base
+ {
+ public:
+ typedef VertexContainer container_type;
+ typedef path_base<VertexContainer> self_type;
+
+ //--------------------------------------------------------------------
+ path_base() : m_vertices(), m_iterator(0) {}
+ void remove_all() { m_vertices.remove_all(); m_iterator = 0; }
+ void free_all() { m_vertices.free_all(); m_iterator = 0; }
+
+ // Make path functions
+ //--------------------------------------------------------------------
+ unsigned start_new_path();
void move_to(double x, double y);
void move_rel(double dx, double dy);
@@ -118,6 +626,12 @@ namespace agg
void line_to(double x, double y);
void line_rel(double dx, double dy);
+ void hline_to(double x);
+ void hline_rel(double dx);
+
+ void vline_to(double y);
+ void vline_rel(double dy);
+
void arc_to(double rx, double ry,
double angle,
bool large_arc_flag,
@@ -156,209 +670,876 @@ namespace agg
void end_poly(unsigned flags = path_flags_close);
+ void close_polygon(unsigned flags = path_flags_none);
- void close_polygon(unsigned flags = path_flags_none)
- {
- end_poly(path_flags_close | flags);
- }
+ // Accessors
+ //--------------------------------------------------------------------
+ const container_type& vertices() const { return m_vertices; }
+ container_type& vertices() { return m_vertices; }
+
+ unsigned total_vertices() const;
+
+ void rel_to_abs(double* x, double* y) const;
+
+ unsigned last_vertex(double* x, double* y) const;
+ unsigned prev_vertex(double* x, double* y) const;
- void add_poly(const double* vertices, unsigned num,
- bool solid_path = false,
- unsigned end_flags = path_flags_none);
+ double last_x() const;
+ double last_y() const;
+ unsigned vertex(unsigned idx, double* x, double* y) const;
+ unsigned command(unsigned idx) const;
+
+ void modify_vertex(unsigned idx, double x, double y);
+ void modify_vertex(unsigned idx, double x, double y, unsigned cmd);
+ void modify_command(unsigned idx, unsigned cmd);
+
+ // VertexSource interface
+ //--------------------------------------------------------------------
+ void rewind(unsigned path_id);
+ unsigned vertex(double* x, double* y);
+
+ // Arrange the orientation of a polygon, all polygons in a path,
+ // or in all paths. After calling arrange_orientations() or
+ // arrange_orientations_all_paths(), all the polygons will have
+ // the same orientation, i.e. path_flags_cw or path_flags_ccw
+ //--------------------------------------------------------------------
+ unsigned arrange_polygon_orientation(unsigned start, path_flags_e orientation);
+ unsigned arrange_orientations(unsigned path_id, path_flags_e orientation);
+ void arrange_orientations_all_paths(path_flags_e orientation);
+ void invert_polygon(unsigned start);
+
+ // Flip all vertices horizontally or vertically,
+ // between x1 and x2, or between y1 and y2 respectively
+ //--------------------------------------------------------------------
+ void flip_x(double x1, double x2);
+ void flip_y(double y1, double y2);
+
+ // Concatenate path. The path is added as is.
+ //--------------------------------------------------------------------
template<class VertexSource>
- void add_path(VertexSource& vs,
- unsigned path_id = 0,
- bool solid_path = true)
+ void concat_path(VertexSource& vs, unsigned path_id = 0)
{
double x, y;
unsigned cmd;
vs.rewind(path_id);
while(!is_stop(cmd = vs.vertex(&x, &y)))
{
- if(is_move_to(cmd) && solid_path && m_total_vertices)
+ m_vertices.add_vertex(x, y, cmd);
+ }
+ }
+
+ //--------------------------------------------------------------------
+ // Join path. The path is joined with the existing one, that is,
+ // it behaves as if the pen of a plotter was always down (drawing)
+ template<class VertexSource>
+ void join_path(VertexSource& vs, unsigned path_id = 0)
+ {
+ double x, y;
+ unsigned cmd;
+ vs.rewind(path_id);
+ cmd = vs.vertex(&x, &y);
+ if(!is_stop(cmd))
+ {
+ if(is_vertex(cmd))
+ {
+ double x0, y0;
+ unsigned cmd0 = last_vertex(&x0, &y0);
+ if(is_vertex(cmd0))
+ {
+ if(calc_distance(x, y, x0, y0) > vertex_dist_epsilon)
+ {
+ if(is_move_to(cmd)) cmd = path_cmd_line_to;
+ m_vertices.add_vertex(x, y, cmd);
+ }
+ }
+ else
+ {
+ if(is_stop(cmd0))
+ {
+ cmd = path_cmd_move_to;
+ }
+ else
+ {
+ if(is_move_to(cmd)) cmd = path_cmd_line_to;
+ }
+ m_vertices.add_vertex(x, y, cmd);
+ }
+ }
+ while(!is_stop(cmd = vs.vertex(&x, &y)))
{
- cmd = path_cmd_line_to;
+ m_vertices.add_vertex(x, y, is_move_to(cmd) ?
+ unsigned(path_cmd_line_to) :
+ cmd);
}
- add_vertex(x, y, cmd);
}
}
- unsigned start_new_path();
+ // Concatenate polygon/polyline.
+ //--------------------------------------------------------------------
+ template<class T> void concat_poly(const T* data,
+ unsigned num_points,
+ bool closed)
+ {
+ poly_plain_adaptor<T> poly(data, num_points, closed);
+ concat_path(poly);
+ }
- void copy_from(const path_storage& ps);
- const path_storage& operator = (const path_storage& ps)
+ // Join polygon/polyline continuously.
+ //--------------------------------------------------------------------
+ template<class T> void join_poly(const T* data,
+ unsigned num_points,
+ bool closed)
{
- copy_from(ps);
- return *this;
+ poly_plain_adaptor<T> poly(data, num_points, closed);
+ join_path(poly);
}
+ //--------------------------------------------------------------------
+ void translate(double dx, double dy, unsigned path_id=0);
+ void translate_all_paths(double dx, double dy);
- unsigned total_vertices() const { return m_total_vertices; }
- unsigned vertex(unsigned idx, double* x, double* y) const
+ //--------------------------------------------------------------------
+ template<class Trans>
+ void transform(const Trans& trans, unsigned path_id=0)
{
- unsigned nb = idx >> block_shift;
- const double* pv = m_coord_blocks[nb] + ((idx & block_mask) << 1);
- *x = *pv++;
- *y = *pv;
- return m_cmd_blocks[nb][idx & block_mask];
+ unsigned num_ver = m_vertices.total_vertices();
+ for(; path_id < num_ver; path_id++)
+ {
+ double x, y;
+ unsigned cmd = m_vertices.vertex(path_id, &x, &y);
+ if(is_stop(cmd)) break;
+ if(is_vertex(cmd))
+ {
+ trans.transform(&x, &y);
+ m_vertices.modify_vertex(path_id, x, y);
+ }
+ }
}
- unsigned command(unsigned idx) const
+
+ //--------------------------------------------------------------------
+ template<class Trans>
+ void transform_all_paths(const Trans& trans)
{
- return m_cmd_blocks[idx >> block_shift][idx & block_mask];
+ unsigned idx;
+ unsigned num_ver = m_vertices.total_vertices();
+ for(idx = 0; idx < num_ver; idx++)
+ {
+ double x, y;
+ if(is_vertex(m_vertices.vertex(idx, &x, &y)))
+ {
+ trans.transform(&x, &y);
+ m_vertices.modify_vertex(idx, x, y);
+ }
+ }
}
- void rewind(unsigned path_id);
- unsigned vertex(double* x, double* y);
- const_iterator begin(unsigned id) const { return const_iterator(*this, id); }
- const_iterator begin() const { return const_iterator(*this, 0); }
- const_iterator end() const { return const_iterator(path_cmd_stop); }
- // Arrange the orientation of all the polygons. After calling this
- // method all the polygons will have the same orientation
- // determined by the new_orientation flag, i.e.,
- // path_flags_cw or path_flags_ccw
- unsigned arrange_orientations(unsigned path_id, path_flags_e new_orientation);
- void arrange_orientations_all_paths(path_flags_e new_orientation);
-
- // Flip all the vertices horizontally or vertically
- void flip_x(double x1, double x2);
- void flip_y(double y1, double y2);
+ private:
+ unsigned perceive_polygon_orientation(unsigned start, unsigned end);
+ void invert_polygon(unsigned start, unsigned end);
- // This function adds a vertex with its flags directly. Since there's no
- // checking for errors, keeping proper path integrity is the responsibility
- // of the caller. It can be said the function is "not very public".
- void add_vertex(double x, double y, unsigned cmd);
+ VertexContainer m_vertices;
+ unsigned m_iterator;
+ };
- // Allows you to modify vertex coordinates. The caller must know
- // the index of the vertex.
- void modify_vertex(unsigned idx, double x, double y)
+ //------------------------------------------------------------------------
+ template<class VC>
+ unsigned path_base<VC>::start_new_path()
+ {
+ if(!is_stop(m_vertices.last_command()))
{
- double* pv = m_coord_blocks[idx >> block_shift] + ((idx & block_mask) << 1);
- *pv++ = x;
- *pv = y;
+ m_vertices.add_vertex(0.0, 0.0, path_cmd_stop);
}
+ return m_vertices.total_vertices();
+ }
- // Allows you to modify vertex command. The caller must know
- // the index of the vertex.
- void modify_command(unsigned idx, unsigned cmd)
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ inline void path_base<VC>::rel_to_abs(double* x, double* y) const
+ {
+ if(m_vertices.total_vertices())
{
- m_cmd_blocks[idx >> block_shift][idx & block_mask] = (unsigned char)cmd;
+ double x2;
+ double y2;
+ if(is_vertex(m_vertices.last_vertex(&x2, &y2)))
+ {
+ *x += x2;
+ *y += y2;
+ }
}
+ }
+ //------------------------------------------------------------------------
+ template<class VC>
+ inline void path_base<VC>::move_to(double x, double y)
+ {
+ m_vertices.add_vertex(x, y, path_cmd_move_to);
+ }
- private:
- void allocate_block(unsigned nb);
- unsigned char* storage_ptrs(double** xy_ptr);
- unsigned perceive_polygon_orientation(unsigned idx,
- double xs, double ys,
- unsigned* orientation);
- void reverse_polygon(unsigned start, unsigned end);
+ //------------------------------------------------------------------------
+ template<class VC>
+ inline void path_base<VC>::move_rel(double dx, double dy)
+ {
+ rel_to_abs(&dx, &dy);
+ m_vertices.add_vertex(dx, dy, path_cmd_move_to);
+ }
- private:
- unsigned m_total_vertices;
- unsigned m_total_blocks;
- unsigned m_max_blocks;
- double** m_coord_blocks;
- unsigned char** m_cmd_blocks;
- unsigned m_iterator;
- };
+ //------------------------------------------------------------------------
+ template<class VC>
+ inline void path_base<VC>::line_to(double x, double y)
+ {
+ m_vertices.add_vertex(x, y, path_cmd_line_to);
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ inline void path_base<VC>::line_rel(double dx, double dy)
+ {
+ rel_to_abs(&dx, &dy);
+ m_vertices.add_vertex(dx, dy, path_cmd_line_to);
+ }
+ //------------------------------------------------------------------------
+ template<class VC>
+ inline void path_base<VC>::hline_to(double x)
+ {
+ m_vertices.add_vertex(x, last_y(), path_cmd_line_to);
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ inline void path_base<VC>::hline_rel(double dx)
+ {
+ double dy = 0;
+ rel_to_abs(&dx, &dy);
+ m_vertices.add_vertex(dx, dy, path_cmd_line_to);
+ }
//------------------------------------------------------------------------
- inline unsigned path_storage::vertex(double* x, double* y)
+ template<class VC>
+ inline void path_base<VC>::vline_to(double y)
{
- if(m_iterator >= m_total_vertices) return path_cmd_stop;
- return vertex(m_iterator++, x, y);
+ m_vertices.add_vertex(last_x(), y, path_cmd_line_to);
}
//------------------------------------------------------------------------
- inline unsigned path_storage::prev_vertex(double* x, double* y) const
+ template<class VC>
+ inline void path_base<VC>::vline_rel(double dy)
{
- if(m_total_vertices > 1)
+ double dx = 0;
+ rel_to_abs(&dx, &dy);
+ m_vertices.add_vertex(dx, dy, path_cmd_line_to);
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ void path_base<VC>::arc_to(double rx, double ry,
+ double angle,
+ bool large_arc_flag,
+ bool sweep_flag,
+ double x, double y)
+ {
+ if(m_vertices.total_vertices() && is_vertex(m_vertices.last_command()))
{
- return vertex(m_total_vertices - 2, x, y);
+ const double epsilon = 1e-30;
+ double x0 = 0.0;
+ double y0 = 0.0;
+ m_vertices.last_vertex(&x0, &y0);
+
+ rx = fabs(rx);
+ ry = fabs(ry);
+
+ // Ensure radii are valid
+ //-------------------------
+ if(rx < epsilon || ry < epsilon)
+ {
+ line_to(x, y);
+ return;
+ }
+
+ if(calc_distance(x0, y0, x, y) < epsilon)
+ {
+ // If the endpoints (x, y) and (x0, y0) are identical, then this
+ // is equivalent to omitting the elliptical arc segment entirely.
+ return;
+ }
+ bezier_arc_svg a(x0, y0, rx, ry, angle, large_arc_flag, sweep_flag, x, y);
+ if(a.radii_ok())
+ {
+ join_path(a);
+ }
+ else
+ {
+ line_to(x, y);
+ }
+ }
+ else
+ {
+ move_to(x, y);
}
- return path_cmd_stop;
}
//------------------------------------------------------------------------
- inline unsigned path_storage::last_vertex(double* x, double* y) const
+ template<class VC>
+ void path_base<VC>::arc_rel(double rx, double ry,
+ double angle,
+ bool large_arc_flag,
+ bool sweep_flag,
+ double dx, double dy)
{
- if(m_total_vertices)
+ rel_to_abs(&dx, &dy);
+ arc_to(rx, ry, angle, large_arc_flag, sweep_flag, dx, dy);
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ void path_base<VC>::curve3(double x_ctrl, double y_ctrl,
+ double x_to, double y_to)
+ {
+ m_vertices.add_vertex(x_ctrl, y_ctrl, path_cmd_curve3);
+ m_vertices.add_vertex(x_to, y_to, path_cmd_curve3);
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ void path_base<VC>::curve3_rel(double dx_ctrl, double dy_ctrl,
+ double dx_to, double dy_to)
+ {
+ rel_to_abs(&dx_ctrl, &dy_ctrl);
+ rel_to_abs(&dx_to, &dy_to);
+ m_vertices.add_vertex(dx_ctrl, dy_ctrl, path_cmd_curve3);
+ m_vertices.add_vertex(dx_to, dy_to, path_cmd_curve3);
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ void path_base<VC>::curve3(double x_to, double y_to)
+ {
+ double x0;
+ double y0;
+ if(is_vertex(m_vertices.last_vertex(&x0, &y0)))
{
- return vertex(m_total_vertices - 1, x, y);
+ double x_ctrl;
+ double y_ctrl;
+ unsigned cmd = m_vertices.prev_vertex(&x_ctrl, &y_ctrl);
+ if(is_curve(cmd))
+ {
+ x_ctrl = x0 + x0 - x_ctrl;
+ y_ctrl = y0 + y0 - y_ctrl;
+ }
+ else
+ {
+ x_ctrl = x0;
+ y_ctrl = y0;
+ }
+ curve3(x_ctrl, y_ctrl, x_to, y_to);
}
- return path_cmd_stop;
}
//------------------------------------------------------------------------
- inline void path_storage::rel_to_abs(double* x, double* y) const
+ template<class VC>
+ void path_base<VC>::curve3_rel(double dx_to, double dy_to)
{
- if(m_total_vertices)
+ rel_to_abs(&dx_to, &dy_to);
+ curve3(dx_to, dy_to);
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ void path_base<VC>::curve4(double x_ctrl1, double y_ctrl1,
+ double x_ctrl2, double y_ctrl2,
+ double x_to, double y_to)
+ {
+ m_vertices.add_vertex(x_ctrl1, y_ctrl1, path_cmd_curve4);
+ m_vertices.add_vertex(x_ctrl2, y_ctrl2, path_cmd_curve4);
+ m_vertices.add_vertex(x_to, y_to, path_cmd_curve4);
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ void path_base<VC>::curve4_rel(double dx_ctrl1, double dy_ctrl1,
+ double dx_ctrl2, double dy_ctrl2,
+ double dx_to, double dy_to)
+ {
+ rel_to_abs(&dx_ctrl1, &dy_ctrl1);
+ rel_to_abs(&dx_ctrl2, &dy_ctrl2);
+ rel_to_abs(&dx_to, &dy_to);
+ m_vertices.add_vertex(dx_ctrl1, dy_ctrl1, path_cmd_curve4);
+ m_vertices.add_vertex(dx_ctrl2, dy_ctrl2, path_cmd_curve4);
+ m_vertices.add_vertex(dx_to, dy_to, path_cmd_curve4);
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ void path_base<VC>::curve4(double x_ctrl2, double y_ctrl2,
+ double x_to, double y_to)
+ {
+ double x0;
+ double y0;
+ if(is_vertex(last_vertex(&x0, &y0)))
{
- double x2;
- double y2;
- if(is_vertex(vertex(m_total_vertices - 1, &x2, &y2)))
+ double x_ctrl1;
+ double y_ctrl1;
+ unsigned cmd = prev_vertex(&x_ctrl1, &y_ctrl1);
+ if(is_curve(cmd))
{
- *x += x2;
- *y += y2;
+ x_ctrl1 = x0 + x0 - x_ctrl1;
+ y_ctrl1 = y0 + y0 - y_ctrl1;
}
+ else
+ {
+ x_ctrl1 = x0;
+ y_ctrl1 = y0;
+ }
+ curve4(x_ctrl1, y_ctrl1, x_ctrl2, y_ctrl2, x_to, y_to);
}
}
//------------------------------------------------------------------------
- inline unsigned char* path_storage::storage_ptrs(double** xy_ptr)
+ template<class VC>
+ void path_base<VC>::curve4_rel(double dx_ctrl2, double dy_ctrl2,
+ double dx_to, double dy_to)
{
- unsigned nb = m_total_vertices >> block_shift;
- if(nb >= m_total_blocks)
+ rel_to_abs(&dx_ctrl2, &dy_ctrl2);
+ rel_to_abs(&dx_to, &dy_to);
+ curve4(dx_ctrl2, dy_ctrl2, dx_to, dy_to);
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ inline void path_base<VC>::end_poly(unsigned flags)
+ {
+ if(is_vertex(m_vertices.last_command()))
{
- allocate_block(nb);
+ m_vertices.add_vertex(0.0, 0.0, path_cmd_end_poly | flags);
}
- *xy_ptr = m_coord_blocks[nb] + ((m_total_vertices & block_mask) << 1);
- return m_cmd_blocks[nb] + (m_total_vertices & block_mask);
}
+ //------------------------------------------------------------------------
+ template<class VC>
+ inline void path_base<VC>::close_polygon(unsigned flags)
+ {
+ end_poly(path_flags_close | flags);
+ }
//------------------------------------------------------------------------
- inline void path_storage::add_vertex(double x, double y, unsigned cmd)
+ template<class VC>
+ inline unsigned path_base<VC>::total_vertices() const
{
- double* coord_ptr = 0;
- unsigned char* cmd_ptr = storage_ptrs(&coord_ptr);
- *cmd_ptr = (unsigned char)cmd;
- *coord_ptr++ = x;
- *coord_ptr = y;
- m_total_vertices++;
+ return m_vertices.total_vertices();
}
//------------------------------------------------------------------------
- inline void path_storage::move_to(double x, double y)
+ template<class VC>
+ inline unsigned path_base<VC>::last_vertex(double* x, double* y) const
{
- add_vertex(x, y, path_cmd_move_to);
+ return m_vertices.last_vertex(x, y);
}
//------------------------------------------------------------------------
- inline void path_storage::move_rel(double dx, double dy)
+ template<class VC>
+ inline unsigned path_base<VC>::prev_vertex(double* x, double* y) const
{
- rel_to_abs(&dx, &dy);
- add_vertex(dx, dy, path_cmd_move_to);
+ return m_vertices.prev_vertex(x, y);
}
//------------------------------------------------------------------------
- inline void path_storage::line_to(double x, double y)
+ template<class VC>
+ inline double path_base<VC>::last_x() const
{
- add_vertex(x, y, path_cmd_line_to);
+ return m_vertices.last_x();
}
//------------------------------------------------------------------------
- inline void path_storage::line_rel(double dx, double dy)
+ template<class VC>
+ inline double path_base<VC>::last_y() const
{
- rel_to_abs(&dx, &dy);
- add_vertex(dx, dy, path_cmd_line_to);
+ return m_vertices.last_y();
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ inline unsigned path_base<VC>::vertex(unsigned idx, double* x, double* y) const
+ {
+ return m_vertices.vertex(idx, x, y);
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ inline unsigned path_base<VC>::command(unsigned idx) const
+ {
+ return m_vertices.command(idx);
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ void path_base<VC>::modify_vertex(unsigned idx, double x, double y)
+ {
+ m_vertices.modify_vertex(idx, x, y);
}
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ void path_base<VC>::modify_vertex(unsigned idx, double x, double y, unsigned cmd)
+ {
+ m_vertices.modify_vertex(idx, x, y, cmd);
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ void path_base<VC>::modify_command(unsigned idx, unsigned cmd)
+ {
+ m_vertices.modify_command(idx, cmd);
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ inline void path_base<VC>::rewind(unsigned path_id)
+ {
+ m_iterator = path_id;
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ inline unsigned path_base<VC>::vertex(double* x, double* y)
+ {
+ if(m_iterator >= m_vertices.total_vertices()) return path_cmd_stop;
+ return m_vertices.vertex(m_iterator++, x, y);
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ unsigned path_base<VC>::perceive_polygon_orientation(unsigned start,
+ unsigned end)
+ {
+ // Calculate signed area (double area to be exact)
+ //---------------------
+ unsigned np = end - start;
+ double area = 0.0;
+ unsigned i;
+ for(i = 0; i < np; i++)
+ {
+ double x1, y1, x2, y2;
+ m_vertices.vertex(start + i, &x1, &y1);
+ m_vertices.vertex(start + (i + 1) % np, &x2, &y2);
+ area += x1 * y2 - y1 * x2;
+ }
+ return (area < 0.0) ? path_flags_cw : path_flags_ccw;
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ void path_base<VC>::invert_polygon(unsigned start, unsigned end)
+ {
+ unsigned i;
+ unsigned tmp_cmd = m_vertices.command(start);
+
+ --end; // Make "end" inclusive
+
+ // Shift all commands to one position
+ for(i = start; i < end; i++)
+ {
+ m_vertices.modify_command(i, m_vertices.command(i + 1));
+ }
+
+ // Assign starting command to the ending command
+ m_vertices.modify_command(end, tmp_cmd);
+
+ // Reverse the polygon
+ while(end > start)
+ {
+ m_vertices.swap_vertices(start++, end--);
+ }
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ void path_base<VC>::invert_polygon(unsigned start)
+ {
+ // Skip all non-vertices at the beginning
+ while(start < m_vertices.total_vertices() &&
+ !is_vertex(m_vertices.command(start))) ++start;
+
+ // Skip all insignificant move_to
+ while(start+1 < m_vertices.total_vertices() &&
+ is_move_to(m_vertices.command(start)) &&
+ is_move_to(m_vertices.command(start+1))) ++start;
+
+ // Find the last vertex
+ unsigned end = start + 1;
+ while(end < m_vertices.total_vertices() &&
+ !is_next_poly(m_vertices.command(end))) ++end;
+
+ invert_polygon(start, end);
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ unsigned path_base<VC>::arrange_polygon_orientation(unsigned start,
+ path_flags_e orientation)
+ {
+ if(orientation == path_flags_none) return start;
+
+ // Skip all non-vertices at the beginning
+ while(start < m_vertices.total_vertices() &&
+ !is_vertex(m_vertices.command(start))) ++start;
+
+ // Skip all insignificant move_to
+ while(start+1 < m_vertices.total_vertices() &&
+ is_move_to(m_vertices.command(start)) &&
+ is_move_to(m_vertices.command(start+1))) ++start;
+
+ // Find the last vertex
+ unsigned end = start + 1;
+ while(end < m_vertices.total_vertices() &&
+ !is_next_poly(m_vertices.command(end))) ++end;
+
+ if(end - start > 2)
+ {
+ if(perceive_polygon_orientation(start, end) != unsigned(orientation))
+ {
+ // Invert polygon, set orientation flag, and skip all end_poly
+ invert_polygon(start, end);
+ unsigned cmd;
+ while(end < m_vertices.total_vertices() &&
+ is_end_poly(cmd = m_vertices.command(end)))
+ {
+ m_vertices.modify_command(end++, set_orientation(cmd, orientation));
+ }
+ }
+ }
+ return end;
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ unsigned path_base<VC>::arrange_orientations(unsigned start,
+ path_flags_e orientation)
+ {
+ if(orientation != path_flags_none)
+ {
+ while(start < m_vertices.total_vertices())
+ {
+ start = arrange_polygon_orientation(start, orientation);
+ if(is_stop(m_vertices.command(start)))
+ {
+ ++start;
+ break;
+ }
+ }
+ }
+ return start;
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ void path_base<VC>::arrange_orientations_all_paths(path_flags_e orientation)
+ {
+ if(orientation != path_flags_none)
+ {
+ unsigned start = 0;
+ while(start < m_vertices.total_vertices())
+ {
+ start = arrange_orientations(start, orientation);
+ }
+ }
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ void path_base<VC>::flip_x(double x1, double x2)
+ {
+ unsigned i;
+ double x, y;
+ for(i = 0; i < m_vertices.total_vertices(); i++)
+ {
+ unsigned cmd = m_vertices.vertex(i, &x, &y);
+ if(is_vertex(cmd))
+ {
+ m_vertices.modify_vertex(i, x2 - x + x1, y);
+ }
+ }
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ void path_base<VC>::flip_y(double y1, double y2)
+ {
+ unsigned i;
+ double x, y;
+ for(i = 0; i < m_vertices.total_vertices(); i++)
+ {
+ unsigned cmd = m_vertices.vertex(i, &x, &y);
+ if(is_vertex(cmd))
+ {
+ m_vertices.modify_vertex(i, x, y2 - y + y1);
+ }
+ }
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ void path_base<VC>::translate(double dx, double dy, unsigned path_id)
+ {
+ unsigned num_ver = m_vertices.total_vertices();
+ for(; path_id < num_ver; path_id++)
+ {
+ double x, y;
+ unsigned cmd = m_vertices.vertex(path_id, &x, &y);
+ if(is_stop(cmd)) break;
+ if(is_vertex(cmd))
+ {
+ x += dx;
+ y += dy;
+ m_vertices.modify_vertex(path_id, x, y);
+ }
+ }
+ }
+
+ //------------------------------------------------------------------------
+ template<class VC>
+ void path_base<VC>::translate_all_paths(double dx, double dy)
+ {
+ unsigned idx;
+ unsigned num_ver = m_vertices.total_vertices();
+ for(idx = 0; idx < num_ver; idx++)
+ {
+ double x, y;
+ if(is_vertex(m_vertices.vertex(idx, &x, &y)))
+ {
+ x += dx;
+ y += dy;
+ m_vertices.modify_vertex(idx, x, y);
+ }
+ }
+ }
+
+ //-----------------------------------------------------vertex_stl_storage
+ template<class Container> class vertex_stl_storage
+ {
+ public:
+ typedef typename Container::value_type vertex_type;
+ typedef typename vertex_type::value_type value_type;
+
+ void remove_all() { m_vertices.clear(); }
+ void free_all() { m_vertices.clear(); }
+
+ void add_vertex(double x, double y, unsigned cmd)
+ {
+ m_vertices.push_back(vertex_type(value_type(x),
+ value_type(y),
+ int8u(cmd)));
+ }
+
+ void modify_vertex(unsigned idx, double x, double y)
+ {
+ vertex_type& v = m_vertices[idx];
+ v.x = value_type(x);
+ v.y = value_type(y);
+ }
+
+ void modify_vertex(unsigned idx, double x, double y, unsigned cmd)
+ {
+ vertex_type& v = m_vertices[idx];
+ v.x = value_type(x);
+ v.y = value_type(y);
+ v.cmd = int8u(cmd);
+ }
+
+ void modify_command(unsigned idx, unsigned cmd)
+ {
+ m_vertices[idx].cmd = int8u(cmd);
+ }
+
+ void swap_vertices(unsigned v1, unsigned v2)
+ {
+ vertex_type t = m_vertices[v1];
+ m_vertices[v1] = m_vertices[v2];
+ m_vertices[v2] = t;
+ }
+
+ unsigned last_command() const
+ {
+ return m_vertices.size() ?
+ m_vertices[m_vertices.size() - 1].cmd :
+ path_cmd_stop;
+ }
+
+ unsigned last_vertex(double* x, double* y) const
+ {
+ if(m_vertices.size() == 0)
+ {
+ *x = *y = 0.0;
+ return path_cmd_stop;
+ }
+ return vertex(m_vertices.size() - 1, x, y);
+ }
+
+ unsigned prev_vertex(double* x, double* y) const
+ {
+ if(m_vertices.size() < 2)
+ {
+ *x = *y = 0.0;
+ return path_cmd_stop;
+ }
+ return vertex(m_vertices.size() - 2, x, y);
+ }
+
+ double last_x() const
+ {
+ return m_vertices.size() ? m_vertices[m_vertices.size() - 1].x : 0.0;
+ }
+
+ double last_y() const
+ {
+ return m_vertices.size() ? m_vertices[m_vertices.size() - 1].y : 0.0;
+ }
+
+ unsigned total_vertices() const
+ {
+ return m_vertices.size();
+ }
+
+ unsigned vertex(unsigned idx, double* x, double* y) const
+ {
+ const vertex_type& v = m_vertices[idx];
+ *x = v.x;
+ *y = v.y;
+ return v.cmd;
+ }
+
+ unsigned command(unsigned idx) const
+ {
+ return m_vertices[idx].cmd;
+ }
+
+ private:
+ Container m_vertices;
+ };
+
+ //-----------------------------------------------------------path_storage
+ typedef path_base<vertex_block_storage<double> > path_storage;
+
+ // Example of declarations path_storage with pod_bvector as a container
+ //-----------------------------------------------------------------------
+ //typedef path_base<vertex_stl_storage<pod_bvector<vertex_d> > > path_storage;
+
}
+// Example of declarations path_storage with std::vector as a container
+//---------------------------------------------------------------------------
+//#include <vector>
+//namespace agg
+//{
+// typedef path_base<vertex_stl_storage<std::vector<vertex_d> > > stl_path_storage;
+//}
+
+
+
+
#endif
diff --git a/agg/inc/agg_path_storage_integer.h b/agg/inc/agg_path_storage_integer.h
index 841bd10aa27a..7254522c2570 100755
--- a/agg/inc/agg_path_storage_integer.h
+++ b/agg/inc/agg_path_storage_integer.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -21,7 +21,6 @@
namespace agg
{
-
//---------------------------------------------------------vertex_integer
template<class T, unsigned CoordShift=6> struct vertex_integer
{
@@ -33,10 +32,10 @@ namespace agg
cmd_curve4 = 3
};
- enum
+ enum coord_scale_e
{
coord_shift = CoordShift,
- coord_mult = 1 << coord_shift
+ coord_scale = 1 << coord_shift
};
T x,y;
@@ -49,8 +48,8 @@ namespace agg
double dx=0, double dy=0,
double scale=1.0) const
{
- *x_ = dx + (double(x >> 1) / coord_mult) * scale;
- *y_ = dy + (double(y >> 1) / coord_mult) * scale;
+ *x_ = dx + (double(x >> 1) / coord_scale) * scale;
+ *y_ = dy + (double(y >> 1) / coord_scale) * scale;
switch(((y & 1) << 1) | (x & 1))
{
case cmd_move_to: return path_cmd_move_to;
@@ -67,6 +66,7 @@ namespace agg
template<class T, unsigned CoordShift=6> class path_storage_integer
{
public:
+ typedef T value_type;
typedef vertex_integer<T, CoordShift> vertex_integer_type;
//--------------------------------------------------------------------
@@ -110,12 +110,9 @@ namespace agg
//--------------------------------------------------------------------
unsigned size() const { return m_storage.size(); }
- unsigned vertex(unsigned idx, T* x, T* y) const
+ unsigned vertex(unsigned idx, double* x, double* y) const
{
- const vertex_integer_type& v = m_storage[idx];
- *x = v.x >> 1;
- *y = v.y >> 1;
- return ((v.y & 1) << 1) | (v.x & 1);
+ return m_storage[idx].vertex(x, y);
}
//--------------------------------------------------------------------
@@ -130,7 +127,6 @@ namespace agg
}
}
-
//--------------------------------------------------------------------
void rewind(unsigned)
{
@@ -191,11 +187,10 @@ namespace agg
return bounds;
}
-
private:
- pod_deque<vertex_integer_type, 6> m_storage;
- unsigned m_vertex_idx;
- bool m_closed;
+ pod_bvector<vertex_integer_type, 6> m_storage;
+ unsigned m_vertex_idx;
+ bool m_closed;
};
diff --git a/agg/inc/agg_pattern_filters_rgba.h b/agg/inc/agg_pattern_filters_rgba.h
index 5d194b2e39ba..7e686f1851a7 100755
--- a/agg/inc/agg_pattern_filters_rgba.h
+++ b/agg/inc/agg_pattern_filters_rgba.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -67,7 +67,7 @@ namespace agg
color_type* p, int x, int y)
{
calc_type r, g, b, a;
- r = g = b = a = line_subpixel_size * line_subpixel_size / 2;
+ r = g = b = a = line_subpixel_scale * line_subpixel_scale / 2;
calc_type weight;
int x_lr = x >> line_subpixel_shift;
@@ -77,8 +77,8 @@ namespace agg
y &= line_subpixel_mask;
const color_type* ptr = buf[y_lr] + x_lr;
- weight = (line_subpixel_size - x) *
- (line_subpixel_size - y);
+ weight = (line_subpixel_scale - x) *
+ (line_subpixel_scale - y);
r += weight * ptr->r;
g += weight * ptr->g;
b += weight * ptr->b;
@@ -86,7 +86,7 @@ namespace agg
++ptr;
- weight = x * (line_subpixel_size - y);
+ weight = x * (line_subpixel_scale - y);
r += weight * ptr->r;
g += weight * ptr->g;
b += weight * ptr->b;
@@ -94,7 +94,7 @@ namespace agg
ptr = buf[y_lr + 1] + x_lr;
- weight = (line_subpixel_size - x) * y;
+ weight = (line_subpixel_scale - x) * y;
r += weight * ptr->r;
g += weight * ptr->g;
b += weight * ptr->b;
diff --git a/agg/inc/agg_pixfmt_amask_adaptor.h b/agg/inc/agg_pixfmt_amask_adaptor.h
index 7f3d5899b1c6..454e1417054e 100755
--- a/agg/inc/agg_pixfmt_amask_adaptor.h
+++ b/agg/inc/agg_pixfmt_amask_adaptor.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -18,6 +18,7 @@
#include <string.h>
+#include "agg_array.h"
#include "agg_rendering_buffer.h"
@@ -29,47 +30,50 @@ namespace agg
public:
typedef PixFmt pixfmt_type;
typedef typename pixfmt_type::color_type color_type;
+ typedef typename pixfmt_type::row_data row_data;
typedef AlphaMask amask_type;
typedef typename amask_type::cover_type cover_type;
private:
- enum { span_extra_tail = 256 };
+ enum span_extra_tail_e { span_extra_tail = 256 };
void realloc_span(unsigned len)
{
- if(len > m_max_len)
+ if(len > m_span.size())
{
- delete [] m_span;
- m_span = new cover_type[m_max_len = len + span_extra_tail];
+ m_span.resize(len + span_extra_tail);
}
}
void init_span(unsigned len)
{
realloc_span(len);
-
- // ATTN! May work incorrectly if cover_type is more that one byte
- memset(m_span, amask_type::cover_full, len * sizeof(cover_type));
+ memset(&m_span[0], amask_type::cover_full, len * sizeof(cover_type));
}
void init_span(unsigned len, const cover_type* covers)
{
realloc_span(len);
- memcpy(m_span, covers, len * sizeof(cover_type));
+ memcpy(&m_span[0], covers, len * sizeof(cover_type));
}
public:
- ~pixfmt_amask_adaptor() { delete [] m_span; }
-
pixfmt_amask_adaptor(pixfmt_type& pixf, const amask_type& mask) :
- m_pixf(&pixf), m_mask(&mask), m_span(0), m_max_len(0)
+ m_pixf(&pixf), m_mask(&mask), m_span()
{}
void attach_pixfmt(pixfmt_type& pixf) { m_pixf = &pixf; }
void attach_alpha_mask(const amask_type& mask) { m_mask = &mask; }
//--------------------------------------------------------------------
+ template<class PixFmt2>
+ bool attach_pixfmt(PixFmt2& pixf, int x1, int y1, int x2, int y2)
+ {
+ return m_pixf->attach(pixf, x1, y1, x2, y2);
+ }
+
+ //--------------------------------------------------------------------
unsigned width() const { return m_pixf->width(); }
unsigned height() const { return m_pixf->height(); }
@@ -97,8 +101,8 @@ namespace agg
const color_type& c)
{
realloc_span(len);
- m_mask->fill_hspan(x, y, m_span, len);
- m_pixf->blend_solid_hspan(x, y, len, c, m_span);
+ m_mask->fill_hspan(x, y, &m_span[0], len);
+ m_pixf->blend_solid_hspan(x, y, len, c, &m_span[0]);
}
//--------------------------------------------------------------------
@@ -108,8 +112,8 @@ namespace agg
cover_type cover)
{
init_span(len);
- m_mask->combine_hspan(x, y, m_span, len);
- m_pixf->blend_solid_hspan(x, y, len, c, m_span);
+ m_mask->combine_hspan(x, y, &m_span[0], len);
+ m_pixf->blend_solid_hspan(x, y, len, c, &m_span[0]);
}
//--------------------------------------------------------------------
@@ -118,8 +122,8 @@ namespace agg
const color_type& c)
{
realloc_span(len);
- m_mask->fill_vspan(x, y, m_span, len);
- m_pixf->blend_solid_vspan(x, y, len, c, m_span);
+ m_mask->fill_vspan(x, y, &m_span[0], len);
+ m_pixf->blend_solid_vspan(x, y, len, c, &m_span[0]);
}
//--------------------------------------------------------------------
@@ -129,8 +133,8 @@ namespace agg
cover_type cover)
{
init_span(len);
- m_mask->combine_vspan(x, y, m_span, len);
- m_pixf->blend_solid_vspan(x, y, len, c, m_span);
+ m_mask->combine_vspan(x, y, &m_span[0], len);
+ m_pixf->blend_solid_vspan(x, y, len, c, &m_span[0]);
}
//--------------------------------------------------------------------
@@ -150,8 +154,8 @@ namespace agg
const cover_type* covers)
{
init_span(len, covers);
- m_mask->combine_hspan(x, y, m_span, len);
- m_pixf->blend_solid_hspan(x, y, len, c, m_span);
+ m_mask->combine_hspan(x, y, &m_span[0], len);
+ m_pixf->blend_solid_hspan(x, y, len, c, &m_span[0]);
}
@@ -162,10 +166,26 @@ namespace agg
const cover_type* covers)
{
init_span(len, covers);
- m_mask->combine_vspan(x, y, m_span, len);
- m_pixf->blend_solid_vspan(x, y, len, c, m_span);
+ m_mask->combine_vspan(x, y, &m_span[0], len);
+ m_pixf->blend_solid_vspan(x, y, len, c, &m_span[0]);
+ }
+
+
+ //--------------------------------------------------------------------
+ void copy_color_hspan(int x, int y, unsigned len, const color_type* colors)
+ {
+ realloc_span(len);
+ m_mask->fill_hspan(x, y, &m_span[0], len);
+ m_pixf->blend_color_hspan(x, y, len, colors, &m_span[0], cover_full);
}
+ //--------------------------------------------------------------------
+ void copy_color_vspan(int x, int y, unsigned len, const color_type* colors)
+ {
+ realloc_span(len);
+ m_mask->fill_vspan(x, y, &m_span[0], len);
+ m_pixf->blend_color_vspan(x, y, len, colors, &m_span[0], cover_full);
+ }
//--------------------------------------------------------------------
void blend_color_hspan(int x, int y,
@@ -177,14 +197,14 @@ namespace agg
if(covers)
{
init_span(len, covers);
- m_mask->combine_hspan(x, y, m_span, len);
+ m_mask->combine_hspan(x, y, &m_span[0], len);
}
else
{
realloc_span(len);
- m_mask->fill_hspan(x, y, m_span, len);
+ m_mask->fill_hspan(x, y, &m_span[0], len);
}
- m_pixf->blend_color_hspan(x, y, len, colors, m_span, cover);
+ m_pixf->blend_color_hspan(x, y, len, colors, &m_span[0], cover);
}
@@ -198,65 +218,20 @@ namespace agg
if(covers)
{
init_span(len, covers);
- m_mask->combine_vspan(x, y, m_span, len);
- }
- else
- {
- realloc_span(len);
- m_mask->fill_vspan(x, y, m_span, len);
- }
- m_pixf->blend_color_vspan(x, y, len, colors, m_span, cover);
- }
-
-
- //--------------------------------------------------------------------
- void blend_opaque_color_hspan(int x, int y,
- unsigned len,
- const color_type* colors,
- const cover_type* covers,
- cover_type cover = cover_full)
- {
- if(covers)
- {
- init_span(len, covers);
- m_mask->combine_hspan(x, y, m_span, len);
- }
- else
- {
- realloc_span(len);
- m_mask->fill_hspan(x, y, m_span, len);
- }
- m_pixf->blend_opaque_color_hspan(x, y, len, colors, m_span, cover);
- }
-
-
- //--------------------------------------------------------------------
- void blend_opaque_color_vspan(int x, int y,
- unsigned len,
- const color_type* colors,
- const cover_type* covers,
- cover_type cover = cover_full)
- {
- if(covers)
- {
- init_span(len, covers);
- m_mask->combine_vspan(x, y, m_span, len);
+ m_mask->combine_vspan(x, y, &m_span[0], len);
}
else
{
realloc_span(len);
- m_mask->fill_vspan(x, y, m_span, len);
+ m_mask->fill_vspan(x, y, &m_span[0], len);
}
- m_pixf->blend_opaque_color_vspan(x, y, len, colors, m_span, cover);
+ m_pixf->blend_color_vspan(x, y, len, colors, &m_span[0], cover);
}
-
private:
- pixfmt_type* m_pixf;
- const amask_type* m_mask;
-
- cover_type* m_span;
- unsigned m_max_len;
+ pixfmt_type* m_pixf;
+ const amask_type* m_mask;
+ pod_array<cover_type> m_span;
};
}
diff --git a/agg/inc/agg_pixfmt_gray.h b/agg/inc/agg_pixfmt_gray.h
index 48f47d1de32e..32774e140b57 100755
--- a/agg/inc/agg_pixfmt_gray.h
+++ b/agg/inc/agg_pixfmt_gray.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -38,10 +38,10 @@ namespace agg
typedef ColorT color_type;
typedef typename color_type::value_type value_type;
typedef typename color_type::calc_type calc_type;
- enum { base_shift = color_type::base_shift };
+ enum base_scale_e { base_shift = color_type::base_shift };
static AGG_INLINE void blend_pix(value_type* p, unsigned cv,
- unsigned alpha, unsigned)
+ unsigned alpha, unsigned cover=0)
{
*p = (value_type)((((cv - calc_type(*p)) * alpha) + (calc_type(*p) << base_shift)) >> base_shift);
}
@@ -54,7 +54,7 @@ namespace agg
typedef ColorT color_type;
typedef typename color_type::value_type value_type;
typedef typename color_type::calc_type calc_type;
- enum { base_shift = color_type::base_shift };
+ enum base_scale_e { base_shift = color_type::base_shift };
static AGG_INLINE void blend_pix(value_type* p, unsigned cv,
unsigned alpha, unsigned cover)
@@ -63,6 +63,12 @@ namespace agg
cover = (cover + 1) << (base_shift - 8);
*p = (value_type)((*p * alpha + cv * cover) >> base_shift);
}
+
+ static AGG_INLINE void blend_pix(value_type* p, unsigned cv,
+ unsigned alpha)
+ {
+ *p = (value_type)(((*p * (color_type::base_mask - alpha)) >> base_shift) + cv);
+ }
};
@@ -105,20 +111,26 @@ namespace agg
- //======================================================pixel_formats_gray
- template<class Blender, unsigned Step=1, unsigned Offset=0>
- class pixel_formats_gray
+ //=================================================pixfmt_alpha_blend_gray
+ template<class Blender, class RenBuf, unsigned Step=1, unsigned Offset=0>
+ class pixfmt_alpha_blend_gray
{
public:
- typedef rendering_buffer::row_data row_data;
- typedef typename Blender::color_type color_type;
- typedef typename color_type::value_type value_type;
- typedef typename color_type::calc_type calc_type;
- enum
+ typedef RenBuf rbuf_type;
+ typedef typename rbuf_type::row_data row_data;
+ typedef Blender blender_type;
+ typedef typename blender_type::color_type color_type;
+ typedef int order_type; // A fake one
+ typedef typename color_type::value_type value_type;
+ typedef typename color_type::calc_type calc_type;
+ enum base_scale_e
{
base_shift = color_type::base_shift,
- base_size = color_type::base_size,
- base_mask = color_type::base_mask
+ base_scale = color_type::base_scale,
+ base_mask = color_type::base_mask,
+ pix_width = sizeof(value_type),
+ pix_step = Step,
+ pix_offset = Offset
};
private:
@@ -141,59 +153,94 @@ namespace agg
}
}
- //--------------------------------------------------------------------
- static AGG_INLINE void copy_or_blend_opaque_pix(value_type* p,
- const color_type& c,
- unsigned cover)
+
+ static AGG_INLINE void copy_or_blend_pix(value_type* p,
+ const color_type& c)
{
- if(cover == 255)
- {
- *p = c.v;
- }
- else
+ if (c.a)
{
- Blender::blend_pix(p, c.v, (cover + 1) << (base_shift - 8), cover);
+ if(c.a == base_mask)
+ {
+ *p = c.v;
+ }
+ else
+ {
+ Blender::blend_pix(p, c.v, c.a);
+ }
}
}
+
public:
//--------------------------------------------------------------------
- pixel_formats_gray(rendering_buffer& rb) :
+ explicit pixfmt_alpha_blend_gray(rbuf_type& rb) :
m_rbuf(&rb)
{}
+ void attach(rbuf_type& rb) { m_rbuf = &rb; }
+ //--------------------------------------------------------------------
+ template<class PixFmt>
+ bool attach(PixFmt& pixf, int x1, int y1, int x2, int y2)
+ {
+ rect_i r(x1, y1, x2, y2);
+ if(r.clip(rect_i(0, 0, pixf.width()-1, pixf.height()-1)))
+ {
+ int stride = pixf.stride();
+ m_rbuf->attach(pixf.pix_ptr(r.x1, stride < 0 ? r.y2 : r.y1),
+ (r.x2 - r.x1) + 1,
+ (r.y2 - r.y1) + 1,
+ stride);
+ return true;
+ }
+ return false;
+ }
//--------------------------------------------------------------------
AGG_INLINE unsigned width() const { return m_rbuf->width(); }
AGG_INLINE unsigned height() const { return m_rbuf->height(); }
+ AGG_INLINE int stride() const { return m_rbuf->stride(); }
//--------------------------------------------------------------------
- AGG_INLINE color_type pixel(int x, int y) const
+ int8u* row_ptr(int y) { return m_rbuf->row_ptr(y); }
+ const int8u* row_ptr(int y) const { return m_rbuf->row_ptr(y); }
+ row_data row(int y) const { return m_rbuf->row(y); }
+
+ const int8u* pix_ptr(int x, int y) const
{
- value_type* p = (value_type*)m_rbuf->row(y) + x * Step + Offset;
- return color_type(*p);
+ return m_rbuf->row_ptr(y) + x * Step + Offset;
+ }
+
+ int8u* pix_ptr(int x, int y)
+ {
+ return m_rbuf->row_ptr(y) + x * Step + Offset;
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE static void make_pix(int8u* p, const color_type& c)
+ {
+ *(value_type*)p = c.v;
}
//--------------------------------------------------------------------
- row_data span(int x, int y) const
+ AGG_INLINE color_type pixel(int x, int y) const
{
- return row_data(x,
- width() - 1,
- m_rbuf->row(y) +
- x * Step * sizeof(value_type) +
- Offset * sizeof(value_type));
+ value_type* p = (value_type*)m_rbuf->row_ptr(y) + x * Step + Offset;
+ return color_type(*p);
}
//--------------------------------------------------------------------
AGG_INLINE void copy_pixel(int x, int y, const color_type& c)
{
- *((value_type*)m_rbuf->row(y) + x * Step + Offset) = c.v;
+ *((value_type*)m_rbuf->row_ptr(x, y, 1) + x * Step + Offset) = c.v;
}
//--------------------------------------------------------------------
AGG_INLINE void blend_pixel(int x, int y, const color_type& c, int8u cover)
{
- copy_or_blend_pix((value_type*)m_rbuf->row(y) + x * Step + Offset, c, cover);
+ copy_or_blend_pix((value_type*)
+ m_rbuf->row_ptr(x, y, 1) + x * Step + Offset,
+ c,
+ cover);
}
@@ -202,7 +249,9 @@ namespace agg
unsigned len,
const color_type& c)
{
- value_type* p = (value_type*)m_rbuf->row(y) + x * Step + Offset;
+ value_type* p = (value_type*)
+ m_rbuf->row_ptr(x, y, len) + x * Step + Offset;
+
do
{
*p = c.v;
@@ -217,11 +266,12 @@ namespace agg
unsigned len,
const color_type& c)
{
- value_type* p = (value_type*)m_rbuf->row(y) + x * Step + Offset;
do
{
+ value_type* p = (value_type*)
+ m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset;
+
*p = c.v;
- p = (value_type*)m_rbuf->next_row(p);
}
while(--len);
}
@@ -235,7 +285,9 @@ namespace agg
{
if (c.a)
{
- value_type* p = (value_type*)m_rbuf->row(y) + x * Step + Offset;
+ value_type* p = (value_type*)
+ m_rbuf->row_ptr(x, y, len) + x * Step + Offset;
+
calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8;
if(alpha == base_mask)
{
@@ -267,14 +319,16 @@ namespace agg
{
if (c.a)
{
- value_type* p = (value_type*)m_rbuf->row(y) + x * Step + Offset;
+ value_type* p;
calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8;
if(alpha == base_mask)
{
do
{
+ p = (value_type*)
+ m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset;
+
*p = c.v;
- p = (value_type*)m_rbuf->next_row(p);
}
while(--len);
}
@@ -282,8 +336,10 @@ namespace agg
{
do
{
+ p = (value_type*)
+ m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset;
+
Blender::blend_pix(p, c.v, alpha, cover);
- p = (value_type*)m_rbuf->next_row(p);
}
while(--len);
}
@@ -299,7 +355,9 @@ namespace agg
{
if (c.a)
{
- value_type* p = (value_type*)m_rbuf->row(y) + x * Step + Offset;
+ value_type* p = (value_type*)
+ m_rbuf->row_ptr(x, y, len) + x * Step + Offset;
+
do
{
calc_type alpha = (calc_type(c.a) * (calc_type(*covers) + 1)) >> 8;
@@ -327,10 +385,13 @@ namespace agg
{
if (c.a)
{
- value_type* p = (value_type*)m_rbuf->row(y) + x * Step + Offset;
do
{
calc_type alpha = (calc_type(c.a) * (calc_type(*covers) + 1)) >> 8;
+
+ value_type* p = (value_type*)
+ m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset;
+
if(alpha == base_mask)
{
*p = c.v;
@@ -339,7 +400,6 @@ namespace agg
{
Blender::blend_pix(p, c.v, alpha, *covers);
}
- p = (value_type*)m_rbuf->next_row(p);
++covers;
}
while(--len);
@@ -348,13 +408,49 @@ namespace agg
//--------------------------------------------------------------------
+ void copy_color_hspan(int x, int y,
+ unsigned len,
+ const color_type* colors)
+ {
+ value_type* p = (value_type*)
+ m_rbuf->row_ptr(x, y, len) + x * Step + Offset;
+
+ do
+ {
+ *p = colors->v;
+ p += Step;
+ ++colors;
+ }
+ while(--len);
+ }
+
+
+ //--------------------------------------------------------------------
+ void copy_color_vspan(int x, int y,
+ unsigned len,
+ const color_type* colors)
+ {
+ do
+ {
+ value_type* p = (value_type*)
+ m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset;
+ *p = colors->v;
+ ++colors;
+ }
+ while(--len);
+ }
+
+
+ //--------------------------------------------------------------------
void blend_color_hspan(int x, int y,
unsigned len,
const color_type* colors,
const int8u* covers,
int8u cover)
{
- value_type* p = (value_type*)m_rbuf->row(y) + x * Step + Offset;
+ value_type* p = (value_type*)
+ m_rbuf->row_ptr(x, y, len) + x * Step + Offset;
+
if(covers)
{
do
@@ -376,7 +472,7 @@ namespace agg
}
else
{
- copy_or_blend_pix(p, *colors, 255);
+ copy_or_blend_pix(p, *colors);
}
p += Step;
++colors;
@@ -404,13 +500,15 @@ namespace agg
const int8u* covers,
int8u cover)
{
- value_type* p = (value_type*)m_rbuf->row(y) + x * Step + Offset;
+ value_type* p;
if(covers)
{
do
{
+ p = (value_type*)
+ m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset;
+
copy_or_blend_pix(p, *colors++, *covers++);
- p = (value_type*)m_rbuf->next_row(p);
}
while(--len);
}
@@ -420,15 +518,17 @@ namespace agg
{
do
{
+ p = (value_type*)
+ m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset;
+
if(colors->a == base_mask)
{
*p = colors->v;
}
else
{
- copy_or_blend_pix(p, *colors, 255);
+ copy_or_blend_pix(p, *colors);
}
- p = (value_type*)m_rbuf->next_row(p);
++colors;
}
while(--len);
@@ -437,8 +537,10 @@ namespace agg
{
do
{
+ p = (value_type*)
+ m_rbuf->row_ptr(x, y++, 1) + x * Step + Offset;
+
copy_or_blend_pix(p, *colors++, cover);
- p = (value_type*)m_rbuf->next_row(p);
}
while(--len);
}
@@ -446,39 +548,22 @@ namespace agg
}
//--------------------------------------------------------------------
- void blend_opaque_color_hspan(int x, int y,
- unsigned len,
- const color_type* colors,
- const int8u* covers,
- int8u cover)
+ template<class Function> void for_each_pixel(Function f)
{
- value_type* p = (value_type*)m_rbuf->row(y) + x * Step + Offset;
- if(covers)
- {
- do
- {
- copy_or_blend_opaque_pix(p, *colors++, *covers++);
- p += Step;
- }
- while(--len);
- }
- else
+ unsigned y;
+ for(y = 0; y < height(); ++y)
{
- if(cover == 255)
- {
- do
- {
- *p = colors->v;
- p += Step;
- ++colors;
- }
- while(--len);
- }
- else
+ row_data r = m_rbuf->row(y);
+ if(r.ptr)
{
+ unsigned len = r.x2 - r.x1 + 1;
+
+ value_type* p = (value_type*)
+ m_rbuf->row_ptr(r.x1, y, len) + r.x1 * Step + Offset;
+
do
{
- copy_or_blend_opaque_pix(p, *colors++, cover);
+ f(p);
p += Step;
}
while(--len);
@@ -486,90 +571,88 @@ namespace agg
}
}
+ //--------------------------------------------------------------------
+ template<class GammaLut> void apply_gamma_dir(const GammaLut& g)
+ {
+ for_each_pixel(apply_gamma_dir_gray<color_type, GammaLut>(g));
+ }
+
+ //--------------------------------------------------------------------
+ template<class GammaLut> void apply_gamma_inv(const GammaLut& g)
+ {
+ for_each_pixel(apply_gamma_inv_gray<color_type, GammaLut>(g));
+ }
//--------------------------------------------------------------------
- void blend_opaque_color_vspan(int x, int y,
- unsigned len,
- const color_type* colors,
- const int8u* covers,
- int8u cover)
+ template<class RenBuf2>
+ void copy_from(const RenBuf2& from,
+ int xdst, int ydst,
+ int xsrc, int ysrc,
+ unsigned len)
{
- value_type* p = (value_type*)m_rbuf->row(y) + x * Step + Offset;
- if(covers)
- {
- do
- {
- copy_or_blend_opaque_pix(p, *colors++, *covers++);
- p = (value_type*)m_rbuf->next_row(p);
- }
- while(--len);
- }
- else
+ const int8u* p = from.row_ptr(ysrc);
+ if(p)
{
- if(cover == 255)
- {
- do
- {
- *p = colors->v;
- p = (value_type*)m_rbuf->next_row(p);
- ++colors;
- }
- while(--len);
- }
- else
- {
- do
- {
- copy_or_blend_opaque_pix(p, *colors++, cover);
- p = (value_type*)m_rbuf->next_row(p);
- }
- while(--len);
- }
+ memmove(m_rbuf->row_ptr(xdst, ydst, len) + xdst * pix_width,
+ p + xsrc * pix_width,
+ len * pix_width);
}
}
//--------------------------------------------------------------------
- template<class Function> void for_each_pixel(Function f)
+ template<class SrcPixelFormatRenderer>
+ void blend_from_color(const SrcPixelFormatRenderer& from,
+ const color_type& color,
+ int xdst, int ydst,
+ int xsrc, int ysrc,
+ unsigned len,
+ int8u cover)
{
- unsigned y;
- for(y = 0; y < height(); ++y)
+ typedef typename SrcPixelFormatRenderer::value_type src_value_type;
+ const src_value_type* psrc = (src_value_type*)from.row_ptr(ysrc);
+ if(psrc)
{
- unsigned len = width();
- value_type* p = (value_type*)m_rbuf->row(y) + Offset;
+ value_type* pdst =
+ (value_type*)m_rbuf->row_ptr(xdst, ydst, len) + xdst;
do
{
- f(p);
- p += Step;
+ copy_or_blend_pix(pdst,
+ color,
+ (*psrc * cover + base_mask) >> base_shift);
+ ++psrc;
+ ++pdst;
}
while(--len);
}
}
//--------------------------------------------------------------------
- template<class GammaLut> void apply_gamma_dir(const GammaLut& g)
- {
- for_each_pixel(apply_gamma_dir_gray<color_type, GammaLut>(g));
- }
-
- //--------------------------------------------------------------------
- template<class GammaLut> void apply_gamma_inv(const GammaLut& g)
- {
- for_each_pixel(apply_gamma_inv_gray<color_type, GammaLut>(g));
- }
-
- //--------------------------------------------------------------------
- void copy_from(const rendering_buffer& from,
- int xdst, int ydst,
- int xsrc, int ysrc,
- unsigned len)
+ template<class SrcPixelFormatRenderer>
+ void blend_from_lut(const SrcPixelFormatRenderer& from,
+ const color_type* color_lut,
+ int xdst, int ydst,
+ int xsrc, int ysrc,
+ unsigned len,
+ int8u cover)
{
- memmove((value_type*)m_rbuf->row(ydst) + xdst,
- (value_type*)from.row(ysrc) + xsrc,
- sizeof(value_type) * len);
+ typedef typename SrcPixelFormatRenderer::value_type src_value_type;
+ const src_value_type* psrc = (src_value_type*)from.row_ptr(ysrc);
+ if(psrc)
+ {
+ value_type* pdst =
+ (value_type*)m_rbuf->row_ptr(xdst, ydst, len) + xdst;
+ do
+ {
+ copy_or_blend_pix(pdst, color_lut[*psrc], cover);
+ ++psrc;
+ ++pdst;
+ }
+ while(--len);
+ }
}
private:
- rendering_buffer* m_rbuf;
+ rbuf_type* m_rbuf;
};
typedef blender_gray<gray8> blender_gray8;
@@ -577,126 +660,10 @@ namespace agg
typedef blender_gray<gray16> blender_gray16;
typedef blender_gray_pre<gray16> blender_gray16_pre;
- typedef pixel_formats_gray<blender_gray8, 1, 0> pixfmt_gray8; //----pixfmt_gray8
-
- typedef pixel_formats_gray<blender_gray8, 3, 0> pixfmt_gray8_rgb24r; //----pixfmt_gray8_rgb24r
- typedef pixel_formats_gray<blender_gray8, 3, 1> pixfmt_gray8_rgb24g; //----pixfmt_gray8_rgb24g
- typedef pixel_formats_gray<blender_gray8, 3, 2> pixfmt_gray8_rgb24b; //----pixfmt_gray8_rgb24b
-
- typedef pixel_formats_gray<blender_gray8, 3, 2> pixfmt_gray8_bgr24r; //----pixfmt_gray8_bgr24r
- typedef pixel_formats_gray<blender_gray8, 3, 1> pixfmt_gray8_bgr24g; //----pixfmt_gray8_bgr24g
- typedef pixel_formats_gray<blender_gray8, 3, 0> pixfmt_gray8_bgr24b; //----pixfmt_gray8_bgr24b
-
- typedef pixel_formats_gray<blender_gray8, 4, 0> pixfmt_gray8_rgba32r; //----pixfmt_gray8_rgba32r
- typedef pixel_formats_gray<blender_gray8, 4, 1> pixfmt_gray8_rgba32g; //----pixfmt_gray8_rgba32g
- typedef pixel_formats_gray<blender_gray8, 4, 2> pixfmt_gray8_rgba32b; //----pixfmt_gray8_rgba32b
- typedef pixel_formats_gray<blender_gray8, 4, 3> pixfmt_gray8_rgba32a; //----pixfmt_gray8_rgba32a
-
- typedef pixel_formats_gray<blender_gray8, 4, 1> pixfmt_gray8_argb32r; //----pixfmt_gray8_argb32r
- typedef pixel_formats_gray<blender_gray8, 4, 2> pixfmt_gray8_argb32g; //----pixfmt_gray8_argb32g
- typedef pixel_formats_gray<blender_gray8, 4, 3> pixfmt_gray8_argb32b; //----pixfmt_gray8_argb32b
- typedef pixel_formats_gray<blender_gray8, 4, 0> pixfmt_gray8_argb32a; //----pixfmt_gray8_argb32a
-
- typedef pixel_formats_gray<blender_gray8, 4, 2> pixfmt_gray8_bgra32r; //----pixfmt_gray8_bgra32r
- typedef pixel_formats_gray<blender_gray8, 4, 1> pixfmt_gray8_bgra32g; //----pixfmt_gray8_bgra32g
- typedef pixel_formats_gray<blender_gray8, 4, 0> pixfmt_gray8_bgra32b; //----pixfmt_gray8_bgra32b
- typedef pixel_formats_gray<blender_gray8, 4, 3> pixfmt_gray8_bgra32a; //----pixfmt_gray8_bgra32a
-
- typedef pixel_formats_gray<blender_gray8, 4, 3> pixfmt_gray8_abgr32r; //----pixfmt_gray8_abgr32r
- typedef pixel_formats_gray<blender_gray8, 4, 2> pixfmt_gray8_abgr32g; //----pixfmt_gray8_abgr32g
- typedef pixel_formats_gray<blender_gray8, 4, 1> pixfmt_gray8_abgr32b; //----pixfmt_gray8_abgr32b
- typedef pixel_formats_gray<blender_gray8, 4, 0> pixfmt_gray8_abgr32a; //----pixfmt_gray8_abgr32a
-
- typedef pixel_formats_gray<blender_gray8_pre, 1, 0> pixfmt_gray8_pre; //----pixfmt_gray8_pre
-
- typedef pixel_formats_gray<blender_gray8_pre, 3, 0> pixfmt_gray8_pre_rgb24r; //----pixfmt_gray8_pre_rgb24r
- typedef pixel_formats_gray<blender_gray8_pre, 3, 1> pixfmt_gray8_pre_rgb24g; //----pixfmt_gray8_pre_rgb24g
- typedef pixel_formats_gray<blender_gray8_pre, 3, 2> pixfmt_gray8_pre_rgb24b; //----pixfmt_gray8_pre_rgb24b
-
- typedef pixel_formats_gray<blender_gray8_pre, 3, 2> pixfmt_gray8_pre_bgr24r; //----pixfmt_gray8_pre_bgr24r
- typedef pixel_formats_gray<blender_gray8_pre, 3, 1> pixfmt_gray8_pre_bgr24g; //----pixfmt_gray8_pre_bgr24g
- typedef pixel_formats_gray<blender_gray8_pre, 3, 0> pixfmt_gray8_pre_bgr24b; //----pixfmt_gray8_pre_bgr24b
-
- typedef pixel_formats_gray<blender_gray8_pre, 4, 0> pixfmt_gray8_pre_rgba32r; //----pixfmt_gray8_pre_rgba32r
- typedef pixel_formats_gray<blender_gray8_pre, 4, 1> pixfmt_gray8_pre_rgba32g; //----pixfmt_gray8_pre_rgba32g
- typedef pixel_formats_gray<blender_gray8_pre, 4, 2> pixfmt_gray8_pre_rgba32b; //----pixfmt_gray8_pre_rgba32b
- typedef pixel_formats_gray<blender_gray8_pre, 4, 3> pixfmt_gray8_pre_rgba32a; //----pixfmt_gray8_pre_rgba32a
-
- typedef pixel_formats_gray<blender_gray8_pre, 4, 1> pixfmt_gray8_pre_argb32r; //----pixfmt_gray8_pre_argb32r
- typedef pixel_formats_gray<blender_gray8_pre, 4, 2> pixfmt_gray8_pre_argb32g; //----pixfmt_gray8_pre_argb32g
- typedef pixel_formats_gray<blender_gray8_pre, 4, 3> pixfmt_gray8_pre_argb32b; //----pixfmt_gray8_pre_argb32b
- typedef pixel_formats_gray<blender_gray8_pre, 4, 0> pixfmt_gray8_pre_argb32a; //----pixfmt_gray8_pre_argb32a
-
- typedef pixel_formats_gray<blender_gray8_pre, 4, 2> pixfmt_gray8_pre_bgra32r; //----pixfmt_gray8_pre_bgra32r
- typedef pixel_formats_gray<blender_gray8_pre, 4, 1> pixfmt_gray8_pre_bgra32g; //----pixfmt_gray8_pre_bgra32g
- typedef pixel_formats_gray<blender_gray8_pre, 4, 0> pixfmt_gray8_pre_bgra32b; //----pixfmt_gray8_pre_bgra32b
- typedef pixel_formats_gray<blender_gray8_pre, 4, 3> pixfmt_gray8_pre_bgra32a; //----pixfmt_gray8_pre_bgra32a
-
- typedef pixel_formats_gray<blender_gray8_pre, 4, 3> pixfmt_gray8_pre_abgr32r; //----pixfmt_gray8_pre_abgr32r
- typedef pixel_formats_gray<blender_gray8_pre, 4, 2> pixfmt_gray8_pre_abgr32g; //----pixfmt_gray8_pre_abgr32g
- typedef pixel_formats_gray<blender_gray8_pre, 4, 1> pixfmt_gray8_pre_abgr32b; //----pixfmt_gray8_pre_abgr32b
- typedef pixel_formats_gray<blender_gray8_pre, 4, 0> pixfmt_gray8_pre_abgr32a; //----pixfmt_gray8_pre_abgr32a
-
- typedef pixel_formats_gray<blender_gray16, 1, 0> pixfmt_gray16; //----pixfmt_gray16
-
- typedef pixel_formats_gray<blender_gray16, 3, 0> pixfmt_gray16_rgb48r; //----pixfmt_gray16_rgb48r
- typedef pixel_formats_gray<blender_gray16, 3, 1> pixfmt_gray16_rgb48g; //----pixfmt_gray16_rgb48g
- typedef pixel_formats_gray<blender_gray16, 3, 2> pixfmt_gray16_rgb48b; //----pixfmt_gray16_rgb48b
-
- typedef pixel_formats_gray<blender_gray16, 3, 2> pixfmt_gray16_bgr48r; //----pixfmt_gray16_bgr48r
- typedef pixel_formats_gray<blender_gray16, 3, 1> pixfmt_gray16_bgr48g; //----pixfmt_gray16_bgr48g
- typedef pixel_formats_gray<blender_gray16, 3, 0> pixfmt_gray16_bgr48b; //----pixfmt_gray16_bgr48b
-
- typedef pixel_formats_gray<blender_gray16, 4, 0> pixfmt_gray16_rgba64r; //----pixfmt_gray16_rgba64r
- typedef pixel_formats_gray<blender_gray16, 4, 1> pixfmt_gray16_rgba64g; //----pixfmt_gray16_rgba64g
- typedef pixel_formats_gray<blender_gray16, 4, 2> pixfmt_gray16_rgba64b; //----pixfmt_gray16_rgba64b
- typedef pixel_formats_gray<blender_gray16, 4, 3> pixfmt_gray16_rgba64a; //----pixfmt_gray16_rgba64a
-
- typedef pixel_formats_gray<blender_gray16, 4, 1> pixfmt_gray16_argb64r; //----pixfmt_gray16_argb64r
- typedef pixel_formats_gray<blender_gray16, 4, 2> pixfmt_gray16_argb64g; //----pixfmt_gray16_argb64g
- typedef pixel_formats_gray<blender_gray16, 4, 3> pixfmt_gray16_argb64b; //----pixfmt_gray16_argb64b
- typedef pixel_formats_gray<blender_gray16, 4, 0> pixfmt_gray16_argb64a; //----pixfmt_gray16_argb64a
-
- typedef pixel_formats_gray<blender_gray16, 4, 2> pixfmt_gray16_bgra64r; //----pixfmt_gray16_bgra64r
- typedef pixel_formats_gray<blender_gray16, 4, 1> pixfmt_gray16_bgra64g; //----pixfmt_gray16_bgra64g
- typedef pixel_formats_gray<blender_gray16, 4, 0> pixfmt_gray16_bgra64b; //----pixfmt_gray16_bgra64b
- typedef pixel_formats_gray<blender_gray16, 4, 3> pixfmt_gray16_bgra64a; //----pixfmt_gray16_bgra64a
-
- typedef pixel_formats_gray<blender_gray16, 4, 3> pixfmt_gray16_abgr64r; //----pixfmt_gray16_abgr64r
- typedef pixel_formats_gray<blender_gray16, 4, 2> pixfmt_gray16_abgr64g; //----pixfmt_gray16_abgr64g
- typedef pixel_formats_gray<blender_gray16, 4, 1> pixfmt_gray16_abgr64b; //----pixfmt_gray16_abgr64b
- typedef pixel_formats_gray<blender_gray16, 4, 0> pixfmt_gray16_abgr64a; //----pixfmt_gray16_abgr64a
-
- typedef pixel_formats_gray<blender_gray16_pre, 1, 0> pixfmt_gray16_pre; //----pixfmt_gray16_pre
-
- typedef pixel_formats_gray<blender_gray16_pre, 3, 0> pixfmt_gray16_pre_rgb48r; //----pixfmt_gray16_pre_rgb48r
- typedef pixel_formats_gray<blender_gray16_pre, 3, 1> pixfmt_gray16_pre_rgb48g; //----pixfmt_gray16_pre_rgb48g
- typedef pixel_formats_gray<blender_gray16_pre, 3, 2> pixfmt_gray16_pre_rgb48b; //----pixfmt_gray16_pre_rgb48b
-
- typedef pixel_formats_gray<blender_gray16_pre, 3, 2> pixfmt_gray16_pre_bgr48r; //----pixfmt_gray16_pre_bgr48r
- typedef pixel_formats_gray<blender_gray16_pre, 3, 1> pixfmt_gray16_pre_bgr48g; //----pixfmt_gray16_pre_bgr48g
- typedef pixel_formats_gray<blender_gray16_pre, 3, 0> pixfmt_gray16_pre_bgr48b; //----pixfmt_gray16_pre_bgr48b
-
- typedef pixel_formats_gray<blender_gray16_pre, 4, 0> pixfmt_gray16_pre_rgba64r; //----pixfmt_gray16_pre_rgba64r
- typedef pixel_formats_gray<blender_gray16_pre, 4, 1> pixfmt_gray16_pre_rgba64g; //----pixfmt_gray16_pre_rgba64g
- typedef pixel_formats_gray<blender_gray16_pre, 4, 2> pixfmt_gray16_pre_rgba64b; //----pixfmt_gray16_pre_rgba64b
- typedef pixel_formats_gray<blender_gray16_pre, 4, 3> pixfmt_gray16_pre_rgba64a; //----pixfmt_gray16_pre_rgba64a
-
- typedef pixel_formats_gray<blender_gray16_pre, 4, 1> pixfmt_gray16_pre_argb64r; //----pixfmt_gray16_pre_argb64r
- typedef pixel_formats_gray<blender_gray16_pre, 4, 2> pixfmt_gray16_pre_argb64g; //----pixfmt_gray16_pre_argb64g
- typedef pixel_formats_gray<blender_gray16_pre, 4, 3> pixfmt_gray16_pre_argb64b; //----pixfmt_gray16_pre_argb64b
- typedef pixel_formats_gray<blender_gray16_pre, 4, 0> pixfmt_gray16_pre_argb64a; //----pixfmt_gray16_pre_argb64a
-
- typedef pixel_formats_gray<blender_gray16_pre, 4, 2> pixfmt_gray16_pre_bgra64r; //----pixfmt_gray16_pre_bgra64r
- typedef pixel_formats_gray<blender_gray16_pre, 4, 1> pixfmt_gray16_pre_bgra64g; //----pixfmt_gray16_pre_bgra64g
- typedef pixel_formats_gray<blender_gray16_pre, 4, 0> pixfmt_gray16_pre_bgra64b; //----pixfmt_gray16_pre_bgra64b
- typedef pixel_formats_gray<blender_gray16_pre, 4, 3> pixfmt_gray16_pre_bgra64a; //----pixfmt_gray16_pre_bgra64a
-
- typedef pixel_formats_gray<blender_gray16_pre, 4, 3> pixfmt_gray16_pre_abgr64r; //----pixfmt_gray16_pre_abgr64r
- typedef pixel_formats_gray<blender_gray16_pre, 4, 2> pixfmt_gray16_pre_abgr64g; //----pixfmt_gray16_pre_abgr64g
- typedef pixel_formats_gray<blender_gray16_pre, 4, 1> pixfmt_gray16_pre_abgr64b; //----pixfmt_gray16_pre_abgr64b
- typedef pixel_formats_gray<blender_gray16_pre, 4, 0> pixfmt_gray16_pre_abgr64a; //----pixfmt_gray16_pre_abgr64a
-
+ typedef pixfmt_alpha_blend_gray<blender_gray8, rendering_buffer> pixfmt_gray8; //----pixfmt_gray8
+ typedef pixfmt_alpha_blend_gray<blender_gray8_pre, rendering_buffer> pixfmt_gray8_pre; //----pixfmt_gray8_pre
+ typedef pixfmt_alpha_blend_gray<blender_gray16, rendering_buffer> pixfmt_gray16; //----pixfmt_gray16
+ typedef pixfmt_alpha_blend_gray<blender_gray16_pre, rendering_buffer> pixfmt_gray16_pre; //----pixfmt_gray16_pre
}
#endif
diff --git a/agg/inc/agg_pixfmt_rgb.h b/agg/inc/agg_pixfmt_rgb.h
index 436dfa4b284f..4c7dbe6d0c1d 100755
--- a/agg/inc/agg_pixfmt_rgb.h
+++ b/agg/inc/agg_pixfmt_rgb.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -80,13 +80,13 @@ namespace agg
typedef Order order_type;
typedef typename color_type::value_type value_type;
typedef typename color_type::calc_type calc_type;
- enum { base_shift = color_type::base_shift };
+ enum base_scale_e { base_shift = color_type::base_shift };
//--------------------------------------------------------------------
static AGG_INLINE void blend_pix(value_type* p,
unsigned cr, unsigned cg, unsigned cb,
unsigned alpha,
- unsigned)
+ unsigned cover=0)
{
p[Order::R] += (value_type)(((cr - p[Order::R]) * alpha) >> base_shift);
p[Order::G] += (value_type)(((cg - p[Order::G]) * alpha) >> base_shift);
@@ -102,7 +102,7 @@ namespace agg
typedef Order order_type;
typedef typename color_type::value_type value_type;
typedef typename color_type::calc_type calc_type;
- enum { base_shift = color_type::base_shift };
+ enum base_scale_e { base_shift = color_type::base_shift };
//--------------------------------------------------------------------
static AGG_INLINE void blend_pix(value_type* p,
@@ -116,6 +116,18 @@ namespace agg
p[Order::G] = (value_type)((p[Order::G] * alpha + cg * cover) >> base_shift);
p[Order::B] = (value_type)((p[Order::B] * alpha + cb * cover) >> base_shift);
}
+
+ //--------------------------------------------------------------------
+ static AGG_INLINE void blend_pix(value_type* p,
+ unsigned cr, unsigned cg, unsigned cb,
+ unsigned alpha)
+ {
+ alpha = color_type::base_mask - alpha;
+ p[Order::R] = (value_type)(((p[Order::R] * alpha) >> base_shift) + cr);
+ p[Order::G] = (value_type)(((p[Order::G] * alpha) >> base_shift) + cg);
+ p[Order::B] = (value_type)(((p[Order::B] * alpha) >> base_shift) + cb);
+ }
+
};
@@ -129,7 +141,7 @@ namespace agg
typedef Gamma gamma_type;
typedef typename color_type::value_type value_type;
typedef typename color_type::calc_type calc_type;
- enum { base_shift = color_type::base_shift };
+ enum base_scale_e { base_shift = color_type::base_shift };
//--------------------------------------------------------------------
blender_rgb_gamma() : m_gamma(0) {}
@@ -139,7 +151,7 @@ namespace agg
AGG_INLINE void blend_pix(value_type* p,
unsigned cr, unsigned cg, unsigned cb,
unsigned alpha,
- unsigned)
+ unsigned cover=0)
{
calc_type r = m_gamma->dir(p[Order::R]);
calc_type g = m_gamma->dir(p[Order::G]);
@@ -156,20 +168,23 @@ namespace agg
- //==================================================pixel_formats_rgb
- template<class Blender> class pixel_formats_rgb
+ //==================================================pixfmt_alpha_blend_rgb
+ template<class Blender, class RenBuf> class pixfmt_alpha_blend_rgb
{
public:
- typedef rendering_buffer::row_data row_data;
- typedef typename Blender::color_type color_type;
- typedef typename Blender::order_type order_type;
+ typedef RenBuf rbuf_type;
+ typedef Blender blender_type;
+ typedef typename rbuf_type::row_data row_data;
+ typedef typename blender_type::color_type color_type;
+ typedef typename blender_type::order_type order_type;
typedef typename color_type::value_type value_type;
typedef typename color_type::calc_type calc_type;
- enum
+ enum base_scale_e
{
base_shift = color_type::base_shift,
- base_size = color_type::base_size,
- base_mask = color_type::base_mask
+ base_scale = color_type::base_scale,
+ base_mask = color_type::base_mask,
+ pix_width = sizeof(value_type) * 3
};
private:
@@ -195,28 +210,48 @@ namespace agg
}
//--------------------------------------------------------------------
- AGG_INLINE void copy_or_blend_opaque_pix(value_type* p,
- const color_type& c,
- unsigned cover)
+ AGG_INLINE void copy_or_blend_pix(value_type* p,
+ const color_type& c)
{
- if(cover == 255)
- {
- p[order_type::R] = c.r;
- p[order_type::G] = c.g;
- p[order_type::B] = c.b;
- }
- else
+ if (c.a)
{
- m_blender.blend_pix(p, c.r, c.g, c.b, (cover + 1) << (base_shift - 8), cover);
+ if(c.a == base_mask)
+ {
+ p[order_type::R] = c.r;
+ p[order_type::G] = c.g;
+ p[order_type::B] = c.b;
+ }
+ else
+ {
+ m_blender.blend_pix(p, c.r, c.g, c.b, c.a);
+ }
}
}
public:
//--------------------------------------------------------------------
- pixel_formats_rgb(rendering_buffer& rb) :
+ explicit pixfmt_alpha_blend_rgb(rbuf_type& rb) :
m_rbuf(&rb)
{}
+ void attach(rbuf_type& rb) { m_rbuf = &rb; }
+
+ //--------------------------------------------------------------------
+ template<class PixFmt>
+ bool attach(PixFmt& pixf, int x1, int y1, int x2, int y2)
+ {
+ rect_i r(x1, y1, x2, y2);
+ if(r.clip(rect_i(0, 0, pixf.width()-1, pixf.height()-1)))
+ {
+ int stride = pixf.stride();
+ m_rbuf->attach(pixf.pix_ptr(r.x1, stride < 0 ? r.y2 : r.y1),
+ (r.x2 - r.x1) + 1,
+ (r.y2 - r.y1) + 1,
+ stride);
+ return true;
+ }
+ return false;
+ }
//--------------------------------------------------------------------
Blender& blender() { return m_blender; }
@@ -224,28 +259,45 @@ namespace agg
//--------------------------------------------------------------------
AGG_INLINE unsigned width() const { return m_rbuf->width(); }
AGG_INLINE unsigned height() const { return m_rbuf->height(); }
+ AGG_INLINE int stride() const { return m_rbuf->stride(); }
//--------------------------------------------------------------------
- AGG_INLINE color_type pixel(int x, int y) const
+ AGG_INLINE int8u* row_ptr(int y) { return m_rbuf->row_ptr(y); }
+ AGG_INLINE const int8u* row_ptr(int y) const { return m_rbuf->row_ptr(y); }
+ AGG_INLINE row_data row(int y) const { return m_rbuf->row(y); }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE int8u* pix_ptr(int x, int y)
{
- value_type* p = (value_type*)m_rbuf->row(y) + x + x + x;
- return color_type(p[order_type::R],
- p[order_type::G],
- p[order_type::B]);
+ return m_rbuf->row_ptr(y) + x * pix_width;
+ }
+
+ AGG_INLINE const int8u* pix_ptr(int x, int y) const
+ {
+ return m_rbuf->row_ptr(y) + x * pix_width;
}
//--------------------------------------------------------------------
- row_data span(int x, int y) const
+ AGG_INLINE static void make_pix(int8u* p, const color_type& c)
{
- return row_data(x,
- width() - 1,
- m_rbuf->row(y) + x * 3 * sizeof(value_type));
+ ((value_type*)p)[order_type::R] = c.r;
+ ((value_type*)p)[order_type::G] = c.g;
+ ((value_type*)p)[order_type::B] = c.b;
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE color_type pixel(int x, int y) const
+ {
+ value_type* p = (value_type*)m_rbuf->row_ptr(y) + x + x + x;
+ return color_type(p[order_type::R],
+ p[order_type::G],
+ p[order_type::B]);
}
//--------------------------------------------------------------------
AGG_INLINE void copy_pixel(int x, int y, const color_type& c)
{
- value_type* p = (value_type*)m_rbuf->row(y) + x + x + x;
+ value_type* p = (value_type*)m_rbuf->row_ptr(x, y, 1) + x + x + x;
p[order_type::R] = c.r;
p[order_type::G] = c.g;
p[order_type::B] = c.b;
@@ -254,7 +306,7 @@ namespace agg
//--------------------------------------------------------------------
AGG_INLINE void blend_pixel(int x, int y, const color_type& c, int8u cover)
{
- copy_or_blend_pix((value_type*)m_rbuf->row(y) + x + x + x, c, cover);
+ copy_or_blend_pix((value_type*)m_rbuf->row_ptr(x, y, 1) + x + x + x, c, cover);
}
@@ -263,7 +315,7 @@ namespace agg
unsigned len,
const color_type& c)
{
- value_type* p = (value_type*)m_rbuf->row(y) + x + x + x;
+ value_type* p = (value_type*)m_rbuf->row_ptr(x, y, len) + x + x + x;
do
{
p[order_type::R] = c.r;
@@ -280,13 +332,13 @@ namespace agg
unsigned len,
const color_type& c)
{
- value_type* p = (value_type*)m_rbuf->row(y) + x + x + x;
do
{
+ value_type* p = (value_type*)
+ m_rbuf->row_ptr(x, y++, 1) + x + x + x;
p[order_type::R] = c.r;
p[order_type::G] = c.g;
p[order_type::B] = c.b;
- p = (value_type*)m_rbuf->next_row(p);
}
while(--len);
}
@@ -300,7 +352,9 @@ namespace agg
{
if (c.a)
{
- value_type* p = (value_type*)m_rbuf->row(y) + x + x + x;
+ value_type* p = (value_type*)
+ m_rbuf->row_ptr(x, y, len) + x + x + x;
+
calc_type alpha = (calc_type(c.a) * (calc_type(cover) + 1)) >> 8;
if(alpha == base_mask)
{
@@ -334,16 +388,18 @@ namespace agg
{
if (c.a)
{
- value_type* p = (value_type*)m_rbuf->row(y) + x + x + x;
+ value_type* p;
calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8;
if(alpha == base_mask)
{
do
{
+ p = (value_type*)
+ m_rbuf->row_ptr(x, y++, 1) + x + x + x;
+
p[order_type::R] = c.r;
p[order_type::G] = c.g;
p[order_type::B] = c.b;
- p = (value_type*)m_rbuf->next_row(p);
}
while(--len);
}
@@ -351,8 +407,10 @@ namespace agg
{
do
{
+ p = (value_type*)
+ m_rbuf->row_ptr(x, y++, 1) + x + x + x;
+
m_blender.blend_pix(p, c.r, c.g, c.b, alpha, cover);
- p = (value_type*)m_rbuf->next_row(p);
}
while(--len);
}
@@ -368,7 +426,9 @@ namespace agg
{
if (c.a)
{
- value_type* p = (value_type*)m_rbuf->row(y) + x + x + x;
+ value_type* p = (value_type*)
+ m_rbuf->row_ptr(x, y, len) + x + x + x;
+
do
{
calc_type alpha = (calc_type(c.a) * (calc_type(*covers) + 1)) >> 8;
@@ -398,9 +458,11 @@ namespace agg
{
if (c.a)
{
- value_type* p = (value_type*)m_rbuf->row(y) + x + x + x;
do
{
+ value_type* p = (value_type*)
+ m_rbuf->row_ptr(x, y++, 1) + x + x + x;
+
calc_type alpha = (calc_type(c.a) * (calc_type(*covers) + 1)) >> 8;
if(alpha == base_mask)
{
@@ -412,7 +474,6 @@ namespace agg
{
m_blender.blend_pix(p, c.r, c.g, c.b, alpha, *covers);
}
- p = (value_type*)m_rbuf->next_row(p);
++covers;
}
while(--len);
@@ -421,13 +482,53 @@ namespace agg
//--------------------------------------------------------------------
+ void copy_color_hspan(int x, int y,
+ unsigned len,
+ const color_type* colors)
+ {
+ value_type* p = (value_type*)
+ m_rbuf->row_ptr(x, y, len) + x + x + x;
+
+ do
+ {
+ p[order_type::R] = colors->r;
+ p[order_type::G] = colors->g;
+ p[order_type::B] = colors->b;
+ ++colors;
+ p += 3;
+ }
+ while(--len);
+ }
+
+
+ //--------------------------------------------------------------------
+ void copy_color_vspan(int x, int y,
+ unsigned len,
+ const color_type* colors)
+ {
+ do
+ {
+ value_type* p = (value_type*)
+ m_rbuf->row_ptr(x, y++, 1) + x + x + x;
+ p[order_type::R] = colors->r;
+ p[order_type::G] = colors->g;
+ p[order_type::B] = colors->b;
+ ++colors;
+ }
+ while(--len);
+ }
+
+
+ //--------------------------------------------------------------------
void blend_color_hspan(int x, int y,
unsigned len,
const color_type* colors,
const int8u* covers,
int8u cover)
{
- value_type* p = (value_type*)m_rbuf->row(y) + x + x + x;
+ value_type* p = (value_type*)
+ m_rbuf->row_ptr(x, y, len) + x + x + x;
+
if(covers)
{
do
@@ -443,18 +544,8 @@ namespace agg
{
do
{
- if(colors->a == base_mask)
- {
- p[order_type::R] = colors->r;
- p[order_type::G] = colors->g;
- p[order_type::B] = colors->b;
- }
- else
- {
- copy_or_blend_pix(p, *colors, 255);
- }
+ copy_or_blend_pix(p, *colors++);
p += 3;
- ++colors;
}
while(--len);
}
@@ -479,13 +570,15 @@ namespace agg
const int8u* covers,
int8u cover)
{
- value_type* p = (value_type*)m_rbuf->row(y) + x + x + x;
+ value_type* p;
if(covers)
{
do
{
+ p = (value_type*)
+ m_rbuf->row_ptr(x, y++, 1) + x + x + x;
+
copy_or_blend_pix(p, *colors++, *covers++);
- p = (value_type*)m_rbuf->next_row(p);
}
while(--len);
}
@@ -495,18 +588,10 @@ namespace agg
{
do
{
- if(colors->a == base_mask)
- {
- p[order_type::R] = colors->r;
- p[order_type::G] = colors->g;
- p[order_type::B] = colors->b;
- }
- else
- {
- copy_or_blend_pix(p, *colors, 255);
- }
- p = (value_type*)m_rbuf->next_row(p);
- ++colors;
+ p = (value_type*)
+ m_rbuf->row_ptr(x, y++, 1) + x + x + x;
+
+ copy_or_blend_pix(p, *colors++);
}
while(--len);
}
@@ -514,51 +599,31 @@ namespace agg
{
do
{
+ p = (value_type*)
+ m_rbuf->row_ptr(x, y++, 1) + x + x + x;
+
copy_or_blend_pix(p, *colors++, cover);
- p = (value_type*)m_rbuf->next_row(p);
}
while(--len);
}
}
}
-
//--------------------------------------------------------------------
- void blend_opaque_color_hspan(int x, int y,
- unsigned len,
- const color_type* colors,
- const int8u* covers,
- int8u cover)
+ template<class Function> void for_each_pixel(Function f)
{
- value_type* p = (value_type*)m_rbuf->row(y) + x + x + x;
- if(covers)
- {
- do
- {
- copy_or_blend_opaque_pix(p, *colors++, *covers++);
- p += 3;
- }
- while(--len);
- }
- else
+ unsigned y;
+ for(y = 0; y < height(); ++y)
{
- if(cover == 255)
+ row_data r = m_rbuf->row(y);
+ if(r.ptr)
{
+ unsigned len = r.x2 - r.x1 + 1;
+ value_type* p = (value_type*)
+ m_rbuf->row_ptr(r.x1, y, len) + r.x1 * 3;
do
{
- p[order_type::R] = colors->r;
- p[order_type::G] = colors->g;
- p[order_type::B] = colors->b;
- p += 3;
- ++colors;
- }
- while(--len);
- }
- else
- {
- do
- {
- copy_or_blend_opaque_pix(p, *colors++, cover);
+ f(p);
p += 3;
}
while(--len);
@@ -566,44 +631,91 @@ namespace agg
}
}
+ //--------------------------------------------------------------------
+ template<class GammaLut> void apply_gamma_dir(const GammaLut& g)
+ {
+ for_each_pixel(apply_gamma_dir_rgb<color_type, order_type, GammaLut>(g));
+ }
//--------------------------------------------------------------------
- void blend_opaque_color_vspan(int x, int y,
- unsigned len,
- const color_type* colors,
- const int8u* covers,
- int8u cover)
+ template<class GammaLut> void apply_gamma_inv(const GammaLut& g)
{
- value_type* p = (value_type*)m_rbuf->row(y) + x + x + x;
- if(covers)
+ for_each_pixel(apply_gamma_inv_rgb<color_type, order_type, GammaLut>(g));
+ }
+
+ //--------------------------------------------------------------------
+ template<class RenBuf2>
+ void copy_from(const RenBuf2& from,
+ int xdst, int ydst,
+ int xsrc, int ysrc,
+ unsigned len)
+ {
+ const int8u* p = from.row_ptr(ysrc);
+ if(p)
{
- do
- {
- copy_or_blend_opaque_pix(p, *colors++, *covers++);
- p = (value_type*)m_rbuf->next_row(p);
- }
- while(--len);
+ memmove(m_rbuf->row_ptr(xdst, ydst, len) + xdst * pix_width,
+ p + xsrc * pix_width,
+ len * pix_width);
}
- else
+ }
+
+
+ //--------------------------------------------------------------------
+ template<class SrcPixelFormatRenderer>
+ void blend_from(const SrcPixelFormatRenderer& from,
+ int xdst, int ydst,
+ int xsrc, int ysrc,
+ unsigned len,
+ int8u cover)
+ {
+ typedef typename SrcPixelFormatRenderer::order_type src_order;
+
+ const value_type* psrc = (const value_type*)from.row_ptr(ysrc);
+ if(psrc)
{
+ psrc += xsrc * 4;
+ value_type* pdst =
+ (value_type*)m_rbuf->row_ptr(xdst, ydst, len) + xdst * 3;
+
if(cover == 255)
{
do
{
- p[order_type::R] = colors->r;
- p[order_type::G] = colors->g;
- p[order_type::B] = colors->b;
- p = (value_type*)m_rbuf->next_row(p);
- ++colors;
+ value_type alpha = psrc[src_order::A];
+ if(alpha)
+ {
+ if(alpha == base_mask)
+ {
+ pdst[order_type::R] = psrc[src_order::R];
+ pdst[order_type::G] = psrc[src_order::G];
+ pdst[order_type::B] = psrc[src_order::B];
+ }
+ else
+ {
+ m_blender.blend_pix(pdst,
+ psrc[src_order::R],
+ psrc[src_order::G],
+ psrc[src_order::B],
+ alpha);
+ }
+ }
+ psrc += 4;
+ pdst += 3;
}
while(--len);
}
else
{
+ color_type color;
do
{
- copy_or_blend_opaque_pix(p, *colors++, cover);
- p = (value_type*)m_rbuf->next_row(p);
+ color.r = psrc[src_order::R];
+ color.g = psrc[src_order::G];
+ color.b = psrc[src_order::B];
+ color.a = psrc[src_order::A];
+ copy_or_blend_pix(pdst, color, cover);
+ psrc += 4;
+ pdst += 3;
}
while(--len);
}
@@ -611,107 +723,95 @@ namespace agg
}
//--------------------------------------------------------------------
- template<class Function> void for_each_pixel(Function f)
+ template<class SrcPixelFormatRenderer>
+ void blend_from_color(const SrcPixelFormatRenderer& from,
+ const color_type& color,
+ int xdst, int ydst,
+ int xsrc, int ysrc,
+ unsigned len,
+ int8u cover)
{
- unsigned y;
- for(y = 0; y < height(); ++y)
+ typedef typename SrcPixelFormatRenderer::value_type src_value_type;
+ const src_value_type* psrc = (src_value_type*)from.row_ptr(ysrc);
+ if(psrc)
{
- unsigned len = width();
- value_type* p = (value_type*)m_rbuf->row(y);
+ value_type* pdst =
+ (value_type*)m_rbuf->row_ptr(xdst, ydst, len) + xdst * 3;
do
{
- f(p);
- p += 3;
+ copy_or_blend_pix(pdst,
+ color,
+ (*psrc * cover + base_mask) >> base_shift);
+ ++psrc;
+ pdst += 3;
}
while(--len);
}
}
//--------------------------------------------------------------------
- template<class GammaLut> void apply_gamma_dir(const GammaLut& g)
- {
- for_each_pixel(apply_gamma_dir_rgb<color_type, order_type, GammaLut>(g));
- }
-
- //--------------------------------------------------------------------
- template<class GammaLut> void apply_gamma_inv(const GammaLut& g)
- {
- for_each_pixel(apply_gamma_inv_rgb<color_type, order_type, GammaLut>(g));
- }
-
- //--------------------------------------------------------------------
- void copy_from(const rendering_buffer& from,
- int xdst, int ydst,
- int xsrc, int ysrc,
- unsigned len)
- {
- memmove((value_type*)m_rbuf->row(ydst) + xdst * 3,
- (const value_type*)from.row(ysrc) + xsrc * 3,
- sizeof(value_type) * 3 * len);
- }
-
-
- //--------------------------------------------------------------------
template<class SrcPixelFormatRenderer>
- void blend_from(const SrcPixelFormatRenderer& from,
- const int8u* psrc_,
- int xdst, int ydst,
- int xsrc, int ysrc,
- unsigned len)
+ void blend_from_lut(const SrcPixelFormatRenderer& from,
+ const color_type* color_lut,
+ int xdst, int ydst,
+ int xsrc, int ysrc,
+ unsigned len,
+ int8u cover)
{
- typedef typename SrcPixelFormatRenderer::order_type src_order;
-
- const value_type* psrc = (const value_type*)psrc_;
- value_type* pdst = (value_type*)m_rbuf->row(ydst) + xdst * 3;
- do
+ typedef typename SrcPixelFormatRenderer::value_type src_value_type;
+ const src_value_type* psrc = (src_value_type*)from.row_ptr(ysrc);
+ if(psrc)
{
- value_type alpha = psrc[src_order::A];
- if(alpha)
+ value_type* pdst =
+ (value_type*)m_rbuf->row_ptr(xdst, ydst, len) + xdst * 3;
+
+ if(cover == 255)
{
- if(alpha == base_mask)
+ do
{
- pdst[order_type::R] = psrc[src_order::R];
- pdst[order_type::G] = psrc[src_order::G];
- pdst[order_type::B] = psrc[src_order::B];
+ const color_type& color = color_lut[*psrc];
+ m_blender.blend_pix(pdst,
+ color.r, color.g, color.b, color.a);
+ ++psrc;
+ pdst += 3;
}
- else
+ while(--len);
+ }
+ else
+ {
+ do
{
- m_blender.blend_pix(pdst,
- psrc[src_order::R],
- psrc[src_order::G],
- psrc[src_order::B],
- alpha,
- 255);
+ copy_or_blend_pix(pdst, color_lut[*psrc], cover);
+ ++psrc;
+ pdst += 3;
}
+ while(--len);
}
- psrc += 4;
- pdst += 3;
}
- while(--len);
}
private:
- rendering_buffer* m_rbuf;
- Blender m_blender;
+ rbuf_type* m_rbuf;
+ Blender m_blender;
};
- typedef pixel_formats_rgb<blender_rgb<rgba8, order_rgb> > pixfmt_rgb24; //----pixfmt_rgb24
- typedef pixel_formats_rgb<blender_rgb<rgba8, order_bgr> > pixfmt_bgr24; //----pixfmt_bgr24
- typedef pixel_formats_rgb<blender_rgb<rgba16, order_rgb> > pixfmt_rgb48; //----pixfmt_rgb48
- typedef pixel_formats_rgb<blender_rgb<rgba16, order_bgr> > pixfmt_bgr48; //----pixfmt_bgr48
+ typedef pixfmt_alpha_blend_rgb<blender_rgb<rgba8, order_rgb>, rendering_buffer> pixfmt_rgb24; //----pixfmt_rgb24
+ typedef pixfmt_alpha_blend_rgb<blender_rgb<rgba8, order_bgr>, rendering_buffer> pixfmt_bgr24; //----pixfmt_bgr24
+ typedef pixfmt_alpha_blend_rgb<blender_rgb<rgba16, order_rgb>, rendering_buffer> pixfmt_rgb48; //----pixfmt_rgb48
+ typedef pixfmt_alpha_blend_rgb<blender_rgb<rgba16, order_bgr>, rendering_buffer> pixfmt_bgr48; //----pixfmt_bgr48
- typedef pixel_formats_rgb<blender_rgb_pre<rgba8, order_rgb> > pixfmt_rgb24_pre; //----pixfmt_rgb24_pre
- typedef pixel_formats_rgb<blender_rgb_pre<rgba8, order_bgr> > pixfmt_bgr24_pre; //----pixfmt_bgr24_pre
- typedef pixel_formats_rgb<blender_rgb_pre<rgba16, order_rgb> > pixfmt_rgb48_pre; //----pixfmt_rgb48_pre
- typedef pixel_formats_rgb<blender_rgb_pre<rgba16, order_bgr> > pixfmt_bgr48_pre; //----pixfmt_bgr48_pre
+ typedef pixfmt_alpha_blend_rgb<blender_rgb_pre<rgba8, order_rgb>, rendering_buffer> pixfmt_rgb24_pre; //----pixfmt_rgb24_pre
+ typedef pixfmt_alpha_blend_rgb<blender_rgb_pre<rgba8, order_bgr>, rendering_buffer> pixfmt_bgr24_pre; //----pixfmt_bgr24_pre
+ typedef pixfmt_alpha_blend_rgb<blender_rgb_pre<rgba16, order_rgb>, rendering_buffer> pixfmt_rgb48_pre; //----pixfmt_rgb48_pre
+ typedef pixfmt_alpha_blend_rgb<blender_rgb_pre<rgba16, order_bgr>, rendering_buffer> pixfmt_bgr48_pre; //----pixfmt_bgr48_pre
//-----------------------------------------------------pixfmt_rgb24_gamma
template<class Gamma> class pixfmt_rgb24_gamma :
- public pixel_formats_rgb<blender_rgb_gamma<rgba8, order_rgb, Gamma> >
+ public pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba8, order_rgb, Gamma>, rendering_buffer>
{
public:
pixfmt_rgb24_gamma(rendering_buffer& rb, const Gamma& g) :
- pixel_formats_rgb<blender_rgb_gamma<rgba8, order_rgb, Gamma> >(rb)
+ pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba8, order_rgb, Gamma>, rendering_buffer>(rb)
{
this->blender().gamma(g);
}
@@ -719,11 +819,11 @@ namespace agg
//-----------------------------------------------------pixfmt_bgr24_gamma
template<class Gamma> class pixfmt_bgr24_gamma :
- public pixel_formats_rgb<blender_rgb_gamma<rgba8, order_bgr, Gamma> >
+ public pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba8, order_bgr, Gamma>, rendering_buffer>
{
public:
pixfmt_bgr24_gamma(rendering_buffer& rb, const Gamma& g) :
- pixel_formats_rgb<blender_rgb_gamma<rgba8, order_bgr, Gamma> >(rb)
+ pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba8, order_bgr, Gamma>, rendering_buffer>(rb)
{
this->blender().gamma(g);
}
@@ -731,11 +831,11 @@ namespace agg
//-----------------------------------------------------pixfmt_rgb48_gamma
template<class Gamma> class pixfmt_rgb48_gamma :
- public pixel_formats_rgb<blender_rgb_gamma<rgba16, order_rgb, Gamma> >
+ public pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba16, order_rgb, Gamma>, rendering_buffer>
{
public:
pixfmt_rgb48_gamma(rendering_buffer& rb, const Gamma& g) :
- pixel_formats_rgb<blender_rgb_gamma<rgba16, order_rgb, Gamma> >(rb)
+ pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba16, order_rgb, Gamma>, rendering_buffer>(rb)
{
this->blender().gamma(g);
}
@@ -743,11 +843,11 @@ namespace agg
//-----------------------------------------------------pixfmt_bgr48_gamma
template<class Gamma> class pixfmt_bgr48_gamma :
- public pixel_formats_rgb<blender_rgb_gamma<rgba16, order_bgr, Gamma> >
+ public pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba16, order_bgr, Gamma>, rendering_buffer>
{
public:
pixfmt_bgr48_gamma(rendering_buffer& rb, const Gamma& g) :
- pixel_formats_rgb<blender_rgb_gamma<rgba16, order_bgr, Gamma> >(rb)
+ pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba16, order_bgr, Gamma>, rendering_buffer>(rb)
{
this->blender().gamma(g);
}
diff --git a/agg/inc/agg_pixfmt_rgb_packed.h b/agg/inc/agg_pixfmt_rgb_packed.h
index 4f582ed59847..63a308a0bff0 100755
--- a/agg/inc/agg_pixfmt_rgb_packed.h
+++ b/agg/inc/agg_pixfmt_rgb_packed.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -788,20 +788,24 @@ namespace agg
- //===============================================pixel_formats_rgb_packed
- template<class Blender> class pixel_formats_rgb_packed
+ //===========================================pixfmt_alpha_blend_rgb_packed
+ template<class Blender, class RenBuf> class pixfmt_alpha_blend_rgb_packed
{
public:
- typedef rendering_buffer::row_data row_data;
- typedef typename Blender::color_type color_type;
- typedef typename Blender::pixel_type pixel_type;
- typedef typename color_type::value_type value_type;
- typedef typename color_type::calc_type calc_type;
- enum
+ typedef RenBuf rbuf_type;
+ typedef typename rbuf_type::row_data row_data;
+ typedef Blender blender_type;
+ typedef typename blender_type::color_type color_type;
+ typedef typename blender_type::pixel_type pixel_type;
+ typedef int order_type; // A fake one
+ typedef typename color_type::value_type value_type;
+ typedef typename color_type::calc_type calc_type;
+ enum base_scale_e
{
base_shift = color_type::base_shift,
- base_size = color_type::base_size,
- base_mask = color_type::base_mask
+ base_scale = color_type::base_scale,
+ base_mask = color_type::base_mask,
+ pix_width = sizeof(pixel_type)
};
private:
@@ -822,67 +826,83 @@ namespace agg
}
}
+ public:
+ //--------------------------------------------------------------------
+ explicit pixfmt_alpha_blend_rgb_packed(rbuf_type& rb) : m_rbuf(&rb) {}
+ void attach(rbuf_type& rb) { m_rbuf = &rb; }
+
//--------------------------------------------------------------------
- AGG_INLINE void copy_or_blend_opaque_pix(pixel_type* p, const color_type& c, unsigned cover)
+ template<class PixFmt>
+ bool attach(PixFmt& pixf, int x1, int y1, int x2, int y2)
{
- if(cover == 255)
- {
- *p = m_blender.make_pix(c.r, c.g, c.b);
- }
- else
+ rect_i r(x1, y1, x2, y2);
+ if(r.clip(rect_i(0, 0, pixf.width()-1, pixf.height()-1)))
{
- m_blender.blend_pix(p, c.r, c.g, c.b, (cover + 1) << (base_shift - 8), cover);
+ int stride = pixf.stride();
+ m_rbuf->attach(pixf.pix_ptr(r.x1, stride < 0 ? r.y2 : r.y1),
+ (r.x2 - r.x1) + 1,
+ (r.y2 - r.y1) + 1,
+ stride);
+ return true;
}
+ return false;
}
+ Blender& blender() { return m_blender; }
- public:
//--------------------------------------------------------------------
- pixel_formats_rgb_packed(rendering_buffer& rb) :
- m_rbuf(&rb)
- {}
+ AGG_INLINE unsigned width() const { return m_rbuf->width(); }
+ AGG_INLINE unsigned height() const { return m_rbuf->height(); }
+ AGG_INLINE int stride() const { return m_rbuf->stride(); }
//--------------------------------------------------------------------
- Blender& blender() { return m_blender; }
+ AGG_INLINE int8u* row_ptr(int y) { return m_rbuf->row_ptr(y); }
+ AGG_INLINE const int8u* row_ptr(int y) const { return m_rbuf->row_ptr(y); }
+ AGG_INLINE row_data row(int y) const { return m_rbuf->row(y); }
//--------------------------------------------------------------------
- AGG_INLINE unsigned width() const { return m_rbuf->width(); }
- AGG_INLINE unsigned height() const { return m_rbuf->height(); }
+ AGG_INLINE int8u* pix_ptr(int x, int y)
+ {
+ return m_rbuf->row_ptr(y) + x * pix_width;
+ }
+
+ AGG_INLINE const int8u* pix_ptr(int x, int y) const
+ {
+ return m_rbuf->row_ptr(y) + x * pix_width;
+ }
//--------------------------------------------------------------------
- AGG_INLINE color_type pixel(int x, int y) const
+ AGG_INLINE void make_pix(int8u* p, const color_type& c)
{
- pixel_type* p = (pixel_type*)m_rbuf->row(y) + x;
- return m_blender.make_color(((pixel_type*)m_rbuf->row(y))[x]);
+ *(pixel_type*)p = m_blender.make_pix(c.r, c.g, c.b);
}
//--------------------------------------------------------------------
- row_data span(int x, int y) const
+ AGG_INLINE color_type pixel(int x, int y) const
{
- return row_data(x,
- width() - 1,
- m_rbuf->row(y) + x * sizeof(pixel_type));
+ return m_blender.make_color(((pixel_type*)m_rbuf->row_ptr(y))[x]);
}
//--------------------------------------------------------------------
AGG_INLINE void copy_pixel(int x, int y, const color_type& c)
{
- ((pixel_type*)m_rbuf->row(y))[x] = m_blender.make_pix(c.r, c.g, c.b);
+ ((pixel_type*)
+ m_rbuf->row_ptr(x, y, 1))[x] =
+ m_blender.make_pix(c.r, c.g, c.b);
}
//--------------------------------------------------------------------
AGG_INLINE void blend_pixel(int x, int y, const color_type& c, int8u cover)
{
- copy_or_blend_pix((pixel_type*)m_rbuf->row(y) + x, c, cover);
+ copy_or_blend_pix((pixel_type*)m_rbuf->row_ptr(x, y, 1) + x, c, cover);
}
-
//--------------------------------------------------------------------
AGG_INLINE void copy_hline(int x, int y,
unsigned len,
const color_type& c)
{
- pixel_type* p = (pixel_type*)m_rbuf->row(y) + x;
+ pixel_type* p = (pixel_type*)m_rbuf->row_ptr(x, y, len) + x;
pixel_type v = m_blender.make_pix(c.r, c.g, c.b);
do
{
@@ -891,23 +911,20 @@ namespace agg
while(--len);
}
-
//--------------------------------------------------------------------
AGG_INLINE void copy_vline(int x, int y,
unsigned len,
const color_type& c)
{
- pixel_type* p = (pixel_type*)m_rbuf->row(y) + x;
pixel_type v = m_blender.make_pix(c.r, c.g, c.b);
do
{
+ pixel_type* p = (pixel_type*)m_rbuf->row_ptr(x, y++, 1) + x;
*p = v;
- p = (pixel_type*)m_rbuf->next_row(p);
}
while(--len);
}
-
//--------------------------------------------------------------------
void blend_hline(int x, int y,
unsigned len,
@@ -916,7 +933,7 @@ namespace agg
{
if (c.a)
{
- pixel_type* p = (pixel_type*)m_rbuf->row(y) + x;
+ pixel_type* p = (pixel_type*)m_rbuf->row_ptr(x, y, len) + x;
calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8;
if(alpha == base_mask)
{
@@ -939,7 +956,6 @@ namespace agg
}
}
-
//--------------------------------------------------------------------
void blend_vline(int x, int y,
unsigned len,
@@ -948,15 +964,13 @@ namespace agg
{
if (c.a)
{
- pixel_type* p = (pixel_type*)m_rbuf->row(y) + x;
calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8;
if(alpha == base_mask)
{
pixel_type v = m_blender.make_pix(c.r, c.g, c.b);
do
{
- *p = v;
- p = (pixel_type*)m_rbuf->next_row(p);
+ ((pixel_type*)m_rbuf->row_ptr(x, y++, 1))[x] = v;
}
while(--len);
}
@@ -964,22 +978,22 @@ namespace agg
{
do
{
- m_blender.blend_pix(p, c.r, c.g, c.b, alpha, cover);
- p = (pixel_type*)m_rbuf->next_row(p);
+ m_blender.blend_pix(
+ (pixel_type*)m_rbuf->row_ptr(x, y++, 1),
+ c.r, c.g, c.b, alpha, cover);
}
while(--len);
}
}
}
-
//--------------------------------------------------------------------
void blend_solid_hspan(int x, int y,
unsigned len,
const color_type& c,
const int8u* covers)
{
- pixel_type* p = (pixel_type*)m_rbuf->row(y) + x;
+ pixel_type* p = (pixel_type*)m_rbuf->row_ptr(x, y, len) + x;
do
{
copy_or_blend_pix(p, c, *covers++);
@@ -988,22 +1002,47 @@ namespace agg
while(--len);
}
-
//--------------------------------------------------------------------
void blend_solid_vspan(int x, int y,
unsigned len,
const color_type& c,
const int8u* covers)
{
- pixel_type* p = (pixel_type*)m_rbuf->row(y) + x;
do
{
- copy_or_blend_pix(p, c, *covers++);
- p = (pixel_type*)m_rbuf->next_row(p);
+ copy_or_blend_pix((pixel_type*)m_rbuf->row_ptr(x, y++, 1) + x,
+ c, *covers++);
+ }
+ while(--len);
+ }
+
+ //--------------------------------------------------------------------
+ void copy_color_hspan(int x, int y,
+ unsigned len,
+ const color_type* colors)
+ {
+ pixel_type* p = (pixel_type*)m_rbuf->row_ptr(x, y, len) + x;
+ do
+ {
+ *p++ = m_blender.make_pix(colors->r, colors->g, colors->b);
+ ++colors;
}
while(--len);
}
+ //--------------------------------------------------------------------
+ void copy_color_vspan(int x, int y,
+ unsigned len,
+ const color_type* colors)
+ {
+ do
+ {
+ pixel_type* p = (pixel_type*)m_rbuf->row_ptr(x, y++, 1) + x;
+ *p = m_blender.make_pix(colors->r, colors->g, colors->b);
+ ++colors;
+ }
+ while(--len);
+ }
//--------------------------------------------------------------------
void blend_color_hspan(int x, int y,
@@ -1012,7 +1051,7 @@ namespace agg
const int8u* covers,
int8u cover)
{
- pixel_type* p = (pixel_type*)m_rbuf->row(y) + x;
+ pixel_type* p = (pixel_type*)m_rbuf->row_ptr(x, y, len) + x;
do
{
copy_or_blend_pix(p++, *colors++, covers ? *covers++ : cover);
@@ -1020,7 +1059,6 @@ namespace agg
while(--len);
}
-
//--------------------------------------------------------------------
void blend_color_vspan(int x, int y,
unsigned len,
@@ -1028,178 +1066,164 @@ namespace agg
const int8u* covers,
int8u cover)
{
- pixel_type* p = (pixel_type*)m_rbuf->row(y) + x;
do
{
- copy_or_blend_pix(p, *colors++, covers ? *covers++ : cover);
- p = (pixel_type*)m_rbuf->next_row(p);
+ copy_or_blend_pix((pixel_type*)m_rbuf->row_ptr(x, y++, 1) + x,
+ *colors++, covers ? *covers++ : cover);
}
while(--len);
}
-
//--------------------------------------------------------------------
- void blend_opaque_color_hspan(int x, int y,
- unsigned len,
- const color_type* colors,
- const int8u* covers,
- int8u cover)
- {
- pixel_type* p = (pixel_type*)m_rbuf->row(y) + x;
- if(covers)
+ template<class RenBuf2>
+ void copy_from(const RenBuf2& from,
+ int xdst, int ydst,
+ int xsrc, int ysrc,
+ unsigned len)
+ {
+ const int8u* p = from.row_ptr(ysrc);
+ if(p)
{
- do
- {
- copy_or_blend_opaque_pix(p++, *colors++, *covers++);
- }
- while(--len);
+ memmove(m_rbuf->row_ptr(xdst, ydst, len) + xdst * pix_width,
+ p + xsrc * pix_width,
+ len * pix_width);
}
- else
+ }
+
+ //--------------------------------------------------------------------
+ template<class SrcPixelFormatRenderer>
+ void blend_from(const SrcPixelFormatRenderer& from,
+ int xdst, int ydst,
+ int xsrc, int ysrc,
+ unsigned len,
+ int8u cover)
+ {
+ typedef typename SrcPixelFormatRenderer::order_type src_order;
+
+ const value_type* psrc = (const value_type*)from.row_ptr(ysrc);
+ if(psrc)
{
- if(cover == 255)
- {
- do
- {
- *p++ = m_blender.make_pix(colors->r, colors->g, colors->b);
- ++colors;
- }
- while(--len);
- }
- else
+ psrc += xsrc * 4;
+ pixel_type* pdst =
+ (pixel_type*)m_rbuf->row_ptr(xdst, ydst, len) + xdst;
+ do
{
- do
+ value_type alpha = psrc[src_order::A];
+ if(alpha)
{
- copy_or_blend_opaque_pix(p++, *colors++, cover);
+ if(alpha == base_mask && cover == 255)
+ {
+ *pdst = m_blender.make_pix(psrc[src_order::R],
+ psrc[src_order::G],
+ psrc[src_order::B]);
+ }
+ else
+ {
+ m_blender.blend_pix(pdst,
+ psrc[src_order::R],
+ psrc[src_order::G],
+ psrc[src_order::B],
+ alpha,
+ cover);
+ }
}
- while(--len);
+ psrc += 4;
+ ++pdst;
}
+ while(--len);
}
}
-
//--------------------------------------------------------------------
- void blend_opaque_color_vspan(int x, int y,
- unsigned len,
- const color_type* colors,
- const int8u* covers,
- int8u cover)
- {
- pixel_type* p = (pixel_type*)m_rbuf->row(y) + x;
- if(covers)
+ template<class SrcPixelFormatRenderer>
+ void blend_from_color(const SrcPixelFormatRenderer& from,
+ const color_type& color,
+ int xdst, int ydst,
+ int xsrc, int ysrc,
+ unsigned len,
+ int8u cover)
+ {
+ typedef typename SrcPixelFormatRenderer::value_type src_value_type;
+ const src_value_type* psrc = (src_value_type*)from.row_ptr(ysrc);
+ if(psrc)
{
+ pixel_type* pdst =
+ (pixel_type*)m_rbuf->row_ptr(xdst, ydst, len) + xdst;
+
do
{
- copy_or_blend_opaque_pix(p, *colors++, *covers++);
- p = (pixel_type*)m_rbuf->next_row(p);
+ m_blender.blend_pix(pdst,
+ color.r, color.g, color.b, color.a,
+ cover);
+ ++psrc;
+ ++pdst;
}
while(--len);
}
- else
- {
- if(cover == 255)
- {
- do
- {
- *p = m_blender.make_pix(colors->r, colors->g, colors->b);
- p = (value_type*)m_rbuf->next_row(p);
- ++colors;
- }
- while(--len);
- }
- else
- {
- do
- {
- copy_or_blend_opaque_pix(p, *colors++, cover);
- p = (value_type*)m_rbuf->next_row(p);
- }
- while(--len);
- }
- }
}
-
- //--------------------------------------------------------------------
- void copy_from(const rendering_buffer& from,
- int xdst, int ydst,
- int xsrc, int ysrc,
- unsigned len)
- {
- memmove((pixel_type*)m_rbuf->row(ydst) + xdst,
- (pixel_type*)from.row(ysrc) + xsrc,
- sizeof(pixel_type) * len);
- }
-
-
//--------------------------------------------------------------------
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;
-
- const value_type* psrc = (const value_type*)psrc_;
- pixel_type* pdst = (pixel_type*)m_rbuf->row(ydst) + xdst;
- do
+ void blend_from_lut(const SrcPixelFormatRenderer& from,
+ const color_type* color_lut,
+ int xdst, int ydst,
+ int xsrc, int ysrc,
+ unsigned len,
+ int8u cover)
+ {
+ typedef typename SrcPixelFormatRenderer::value_type src_value_type;
+ const src_value_type* psrc = (src_value_type*)from.row_ptr(ysrc);
+ if(psrc)
{
- value_type alpha = psrc[src_order::A];
- if(alpha)
+ pixel_type* pdst =
+ (pixel_type*)m_rbuf->row_ptr(xdst, ydst, len) + xdst;
+
+ do
{
- if(alpha == base_mask)
- {
- *pdst = m_blender.make_pix(psrc[src_order::R],
- psrc[src_order::G],
- psrc[src_order::B]);
- }
- else
- {
- m_blender.blend_pix(pdst,
- psrc[src_order::R],
- psrc[src_order::G],
- psrc[src_order::B],
- alpha,
- 255);
- }
+ const color_type& color = color_lut[*psrc];
+ m_blender.blend_pix(pdst,
+ color.r, color.g, color.b, color.a,
+ cover);
+ ++psrc;
+ ++pdst;
}
- psrc += 4;
- ++pdst;
+ while(--len);
}
- while(--len);
}
+
private:
- rendering_buffer* m_rbuf;
- Blender m_blender;
+ rbuf_type* m_rbuf;
+ Blender m_blender;
};
- typedef pixel_formats_rgb_packed<blender_rgb555> pixfmt_rgb555; //----pixfmt_rgb555
- typedef pixel_formats_rgb_packed<blender_rgb565> pixfmt_rgb565; //----pixfmt_rgb565
+ typedef pixfmt_alpha_blend_rgb_packed<blender_rgb555, rendering_buffer> pixfmt_rgb555; //----pixfmt_rgb555
+ typedef pixfmt_alpha_blend_rgb_packed<blender_rgb565, rendering_buffer> pixfmt_rgb565; //----pixfmt_rgb565
- typedef pixel_formats_rgb_packed<blender_rgb555_pre> pixfmt_rgb555_pre; //----pixfmt_rgb555_pre
- typedef pixel_formats_rgb_packed<blender_rgb565_pre> pixfmt_rgb565_pre; //----pixfmt_rgb565_pre
+ typedef pixfmt_alpha_blend_rgb_packed<blender_rgb555_pre, rendering_buffer> pixfmt_rgb555_pre; //----pixfmt_rgb555_pre
+ typedef pixfmt_alpha_blend_rgb_packed<blender_rgb565_pre, rendering_buffer> pixfmt_rgb565_pre; //----pixfmt_rgb565_pre
- typedef pixel_formats_rgb_packed<blender_rgbAAA> pixfmt_rgbAAA; //----pixfmt_rgbAAA
- typedef pixel_formats_rgb_packed<blender_bgrAAA> pixfmt_bgrAAA; //----pixfmt_bgrAAA
- typedef pixel_formats_rgb_packed<blender_rgbBBA> pixfmt_rgbBBA; //----pixfmt_rgbBBA
- typedef pixel_formats_rgb_packed<blender_bgrABB> pixfmt_bgrABB; //----pixfmt_bgrABB
+ typedef pixfmt_alpha_blend_rgb_packed<blender_rgbAAA, rendering_buffer> pixfmt_rgbAAA; //----pixfmt_rgbAAA
+ typedef pixfmt_alpha_blend_rgb_packed<blender_bgrAAA, rendering_buffer> pixfmt_bgrAAA; //----pixfmt_bgrAAA
+ typedef pixfmt_alpha_blend_rgb_packed<blender_rgbBBA, rendering_buffer> pixfmt_rgbBBA; //----pixfmt_rgbBBA
+ typedef pixfmt_alpha_blend_rgb_packed<blender_bgrABB, rendering_buffer> pixfmt_bgrABB; //----pixfmt_bgrABB
- typedef pixel_formats_rgb_packed<blender_rgbAAA_pre> pixfmt_rgbAAA_pre; //----pixfmt_rgbAAA_pre
- typedef pixel_formats_rgb_packed<blender_bgrAAA_pre> pixfmt_bgrAAA_pre; //----pixfmt_bgrAAA_pre
- typedef pixel_formats_rgb_packed<blender_rgbBBA_pre> pixfmt_rgbBBA_pre; //----pixfmt_rgbBBA_pre
- typedef pixel_formats_rgb_packed<blender_bgrABB_pre> pixfmt_bgrABB_pre; //----pixfmt_bgrABB_pre
+ typedef pixfmt_alpha_blend_rgb_packed<blender_rgbAAA_pre, rendering_buffer> pixfmt_rgbAAA_pre; //----pixfmt_rgbAAA_pre
+ typedef pixfmt_alpha_blend_rgb_packed<blender_bgrAAA_pre, rendering_buffer> pixfmt_bgrAAA_pre; //----pixfmt_bgrAAA_pre
+ typedef pixfmt_alpha_blend_rgb_packed<blender_rgbBBA_pre, rendering_buffer> pixfmt_rgbBBA_pre; //----pixfmt_rgbBBA_pre
+ typedef pixfmt_alpha_blend_rgb_packed<blender_bgrABB_pre, rendering_buffer> pixfmt_bgrABB_pre; //----pixfmt_bgrABB_pre
//-----------------------------------------------------pixfmt_rgb555_gamma
template<class Gamma> class pixfmt_rgb555_gamma :
- public pixel_formats_rgb_packed<blender_rgb555_gamma<Gamma> >
+ public pixfmt_alpha_blend_rgb_packed<blender_rgb555_gamma<Gamma>,
+ rendering_buffer>
{
public:
pixfmt_rgb555_gamma(rendering_buffer& rb, const Gamma& g) :
- pixel_formats_rgb_packed<blender_rgb555_gamma<Gamma> >(rb)
+ pixfmt_alpha_blend_rgb_packed<blender_rgb555_gamma<Gamma>,
+ rendering_buffer>(rb)
{
this->blender().gamma(g);
}
@@ -1208,11 +1232,11 @@ namespace agg
//-----------------------------------------------------pixfmt_rgb565_gamma
template<class Gamma> class pixfmt_rgb565_gamma :
- public pixel_formats_rgb_packed<blender_rgb565_gamma<Gamma> >
+ public pixfmt_alpha_blend_rgb_packed<blender_rgb565_gamma<Gamma>, rendering_buffer>
{
public:
pixfmt_rgb565_gamma(rendering_buffer& rb, const Gamma& g) :
- pixel_formats_rgb_packed<blender_rgb565_gamma<Gamma> >(rb)
+ pixfmt_alpha_blend_rgb_packed<blender_rgb565_gamma<Gamma>, rendering_buffer>(rb)
{
this->blender().gamma(g);
}
@@ -1221,11 +1245,13 @@ namespace agg
//-----------------------------------------------------pixfmt_rgbAAA_gamma
template<class Gamma> class pixfmt_rgbAAA_gamma :
- public pixel_formats_rgb_packed<blender_rgbAAA_gamma<Gamma> >
+ public pixfmt_alpha_blend_rgb_packed<blender_rgbAAA_gamma<Gamma>,
+ rendering_buffer>
{
public:
pixfmt_rgbAAA_gamma(rendering_buffer& rb, const Gamma& g) :
- pixel_formats_rgb_packed<blender_rgbAAA_gamma<Gamma> >(rb)
+ pixfmt_alpha_blend_rgb_packed<blender_rgbAAA_gamma<Gamma>,
+ rendering_buffer>(rb)
{
this->blender().gamma(g);
}
@@ -1234,11 +1260,13 @@ namespace agg
//-----------------------------------------------------pixfmt_bgrAAA_gamma
template<class Gamma> class pixfmt_bgrAAA_gamma :
- public pixel_formats_rgb_packed<blender_bgrAAA_gamma<Gamma> >
+ public pixfmt_alpha_blend_rgb_packed<blender_bgrAAA_gamma<Gamma>,
+ rendering_buffer>
{
public:
pixfmt_bgrAAA_gamma(rendering_buffer& rb, const Gamma& g) :
- pixel_formats_rgb_packed<blender_bgrAAA_gamma<Gamma> >(rb)
+ pixfmt_alpha_blend_rgb_packed<blender_bgrAAA_gamma<Gamma>,
+ rendering_buffer>(rb)
{
this->blender().gamma(g);
}
@@ -1247,11 +1275,13 @@ namespace agg
//-----------------------------------------------------pixfmt_rgbBBA_gamma
template<class Gamma> class pixfmt_rgbBBA_gamma :
- public pixel_formats_rgb_packed<blender_rgbBBA_gamma<Gamma> >
+ public pixfmt_alpha_blend_rgb_packed<blender_rgbBBA_gamma<Gamma>,
+ rendering_buffer>
{
public:
pixfmt_rgbBBA_gamma(rendering_buffer& rb, const Gamma& g) :
- pixel_formats_rgb_packed<blender_rgbBBA_gamma<Gamma> >(rb)
+ pixfmt_alpha_blend_rgb_packed<blender_rgbBBA_gamma<Gamma>,
+ rendering_buffer>(rb)
{
this->blender().gamma(g);
}
@@ -1260,11 +1290,13 @@ namespace agg
//-----------------------------------------------------pixfmt_bgrABB_gamma
template<class Gamma> class pixfmt_bgrABB_gamma :
- public pixel_formats_rgb_packed<blender_bgrABB_gamma<Gamma> >
+ public pixfmt_alpha_blend_rgb_packed<blender_bgrABB_gamma<Gamma>,
+ rendering_buffer>
{
public:
pixfmt_bgrABB_gamma(rendering_buffer& rb, const Gamma& g) :
- pixel_formats_rgb_packed<blender_bgrABB_gamma<Gamma> >(rb)
+ pixfmt_alpha_blend_rgb_packed<blender_bgrABB_gamma<Gamma>,
+ rendering_buffer>(rb)
{
this->blender().gamma(g);
}
diff --git a/agg/inc/agg_pixfmt_rgba.h b/agg/inc/agg_pixfmt_rgba.h
index 3716877e04f7..f5723a2f8b99 100755
--- a/agg/inc/agg_pixfmt_rgba.h
+++ b/agg/inc/agg_pixfmt_rgba.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -25,6 +25,7 @@
#define AGG_PIXFMT_RGBA_INCLUDED
#include <string.h>
+#include <math.h>
#include "agg_basics.h"
#include "agg_color_rgba.h"
#include "agg_rendering_buffer.h"
@@ -49,9 +50,9 @@ namespace agg
p[Order::R] = p[Order::G] = p[Order::B] = 0;
return;
}
- p[Order::R] = value_type((p[Order::R] * a) >> ColorT::base_shift);
- p[Order::G] = value_type((p[Order::G] * a) >> ColorT::base_shift);
- p[Order::B] = value_type((p[Order::B] * a) >> ColorT::base_shift);
+ p[Order::R] = value_type((p[Order::R] * a + ColorT::base_mask) >> ColorT::base_shift);
+ p[Order::G] = value_type((p[Order::G] * a + ColorT::base_mask) >> ColorT::base_shift);
+ p[Order::B] = value_type((p[Order::B] * a + ColorT::base_mask) >> ColorT::base_shift);
}
}
@@ -77,7 +78,6 @@ namespace agg
}
};
-
//=====================================================apply_gamma_dir_rgba
template<class ColorT, class Order, class GammaLut> class apply_gamma_dir_rgba
{
@@ -97,8 +97,6 @@ namespace agg
const GammaLut& m_gamma;
};
-
-
//=====================================================apply_gamma_inv_rgba
template<class ColorT, class Order, class GammaLut> class apply_gamma_inv_rgba
{
@@ -120,15 +118,21 @@ namespace agg
+
+
+
+
+
+
+
//=============================================================blender_rgba
- template<class ColorT, class Order, class PixelT> struct blender_rgba
+ template<class ColorT, class Order> struct blender_rgba
{
typedef ColorT color_type;
- typedef PixelT pixel_type;
typedef Order order_type;
typedef typename color_type::value_type value_type;
typedef typename color_type::calc_type calc_type;
- enum
+ enum base_scale_e
{
base_shift = color_type::base_shift,
base_mask = color_type::base_mask
@@ -138,7 +142,7 @@ namespace agg
static AGG_INLINE void blend_pix(value_type* p,
unsigned cr, unsigned cg, unsigned cb,
unsigned alpha,
- unsigned)
+ unsigned cover=0)
{
calc_type r = p[Order::R];
calc_type g = p[Order::G];
@@ -151,16 +155,14 @@ namespace agg
}
};
-
//=========================================================blender_rgba_pre
- template<class ColorT, class Order, class PixelT> struct blender_rgba_pre
+ template<class ColorT, class Order> struct blender_rgba_pre
{
typedef ColorT color_type;
- typedef PixelT pixel_type;
typedef Order order_type;
typedef typename color_type::value_type value_type;
typedef typename color_type::calc_type calc_type;
- enum
+ enum base_scale_e
{
base_shift = color_type::base_shift,
base_mask = color_type::base_mask
@@ -179,25 +181,34 @@ namespace agg
p[Order::B] = (value_type)((p[Order::B] * alpha + cb * cover) >> base_shift);
p[Order::A] = (value_type)(base_mask - ((alpha * (base_mask - p[Order::A])) >> base_shift));
}
- };
-
+ //--------------------------------------------------------------------
+ static AGG_INLINE void blend_pix(value_type* p,
+ unsigned cr, unsigned cg, unsigned cb,
+ unsigned alpha)
+ {
+ alpha = color_type::base_mask - alpha;
+ p[Order::R] = (value_type)(((p[Order::R] * alpha) >> base_shift) + cr);
+ p[Order::G] = (value_type)(((p[Order::G] * alpha) >> base_shift) + cg);
+ p[Order::B] = (value_type)(((p[Order::B] * alpha) >> base_shift) + cb);
+ p[Order::A] = (value_type)(base_mask - ((alpha * (base_mask - p[Order::A])) >> base_shift));
+ }
+ };
//======================================================blender_rgba_plain
- template<class ColorT, class Order, class PixelT> struct blender_rgba_plain
+ template<class ColorT, class Order> struct blender_rgba_plain
{
typedef ColorT color_type;
- typedef PixelT pixel_type;
typedef Order order_type;
typedef typename color_type::value_type value_type;
typedef typename color_type::calc_type calc_type;
- enum { base_shift = color_type::base_shift };
+ enum base_scale_e { base_shift = color_type::base_shift };
//--------------------------------------------------------------------
static AGG_INLINE void blend_pix(value_type* p,
unsigned cr, unsigned cg, unsigned cb,
unsigned alpha,
- unsigned)
+ unsigned cover=0)
{
if(alpha == 0) return;
calc_type a = p[Order::A];
@@ -213,67 +224,1521 @@ namespace agg
};
- //====================================================blender_rgba_wrapper
- template<class Blender> struct blender_rgba_wrapper
+
+
+
+
+
+
+
+
+
+ //=========================================================comp_op_rgba_clear
+ template<class ColorT, class Order> struct comp_op_rgba_clear
{
- typedef typename Blender::color_type color_type;
- typedef typename Blender::order_type order_type;
- typedef typename Blender::pixel_type pixel_type;
+ typedef ColorT color_type;
+ typedef Order order_type;
+ typedef typename color_type::value_type value_type;
+ enum base_scale_e
+ {
+ base_shift = color_type::base_shift,
+ base_mask = color_type::base_mask
+ };
+
+ static AGG_INLINE void blend_pix(value_type* p,
+ unsigned, unsigned, unsigned, unsigned,
+ unsigned cover)
+ {
+ if(cover < 255)
+ {
+ cover = 255 - cover;
+ p[Order::R] = (value_type)((p[Order::R] * cover + 255) >> 8);
+ p[Order::G] = (value_type)((p[Order::G] * cover + 255) >> 8);
+ p[Order::B] = (value_type)((p[Order::B] * cover + 255) >> 8);
+ p[Order::A] = (value_type)((p[Order::A] * cover + 255) >> 8);
+ }
+ else
+ {
+ p[0] = p[1] = p[2] = p[3] = 0;
+ }
+ }
+ };
+
+ //===========================================================comp_op_rgba_src
+ template<class ColorT, class Order> struct comp_op_rgba_src
+ {
+ typedef ColorT color_type;
+ typedef Order order_type;
+ typedef typename color_type::value_type value_type;
+
+ static AGG_INLINE void blend_pix(value_type* p,
+ unsigned sr, unsigned sg, unsigned sb,
+ unsigned sa, unsigned cover)
+ {
+ if(cover < 255)
+ {
+ unsigned alpha = 255 - cover;
+ p[Order::R] = (value_type)(((p[Order::R] * alpha + 255) >> 8) + ((sr * cover + 255) >> 8));
+ p[Order::G] = (value_type)(((p[Order::G] * alpha + 255) >> 8) + ((sg * cover + 255) >> 8));
+ p[Order::B] = (value_type)(((p[Order::B] * alpha + 255) >> 8) + ((sb * cover + 255) >> 8));
+ p[Order::A] = (value_type)(((p[Order::A] * alpha + 255) >> 8) + ((sa * cover + 255) >> 8));
+ }
+ else
+ {
+ p[Order::R] = sr;
+ p[Order::G] = sg;
+ p[Order::B] = sb;
+ p[Order::A] = sa;
+ }
+ }
+ };
+
+ //===========================================================comp_op_rgba_dst
+ template<class ColorT, class Order> struct comp_op_rgba_dst
+ {
+ typedef ColorT color_type;
+ typedef Order order_type;
+ typedef typename color_type::value_type value_type;
+
+ static AGG_INLINE void blend_pix(value_type*,
+ unsigned, unsigned, unsigned,
+ unsigned, unsigned)
+ {
+ }
+ };
+
+ //======================================================comp_op_rgba_src_over
+ template<class ColorT, class Order> struct comp_op_rgba_src_over
+ {
+ typedef ColorT color_type;
+ typedef Order order_type;
typedef typename color_type::value_type value_type;
typedef typename color_type::calc_type calc_type;
- enum
+ enum base_scale_e
{
base_shift = color_type::base_shift,
- base_size = color_type::base_size,
base_mask = color_type::base_mask
};
- //--------------------------------------------------------------------
+ // Dca' = Sca + Dca.(1 - Sa)
+ // Da' = Sa + Da - Sa.Da
+ static AGG_INLINE void blend_pix(value_type* p,
+ unsigned sr, unsigned sg, unsigned sb,
+ unsigned sa, unsigned cover)
+ {
+ if(cover < 255)
+ {
+ sr = (sr * cover + 255) >> 8;
+ sg = (sg * cover + 255) >> 8;
+ sb = (sb * cover + 255) >> 8;
+ sa = (sa * cover + 255) >> 8;
+ }
+ calc_type s1a = base_mask - sa;
+ p[Order::R] = (value_type)(sr + ((p[Order::R] * s1a + base_mask) >> base_shift));
+ p[Order::G] = (value_type)(sg + ((p[Order::G] * s1a + base_mask) >> base_shift));
+ p[Order::B] = (value_type)(sb + ((p[Order::B] * s1a + base_mask) >> base_shift));
+ p[Order::A] = (value_type)(sa + p[Order::A] - ((sa * p[Order::A] + base_mask) >> base_shift));
+ }
+ };
+
+ //======================================================comp_op_rgba_dst_over
+ template<class ColorT, class Order> struct comp_op_rgba_dst_over
+ {
+ typedef ColorT color_type;
+ typedef Order order_type;
+ typedef typename color_type::value_type value_type;
+ typedef typename color_type::calc_type calc_type;
+ enum base_scale_e
+ {
+ base_shift = color_type::base_shift,
+ base_mask = color_type::base_mask
+ };
+
+ // Dca' = Dca + Sca.(1 - Da)
+ // Da' = Sa + Da - Sa.Da
+ static AGG_INLINE void blend_pix(value_type* p,
+ unsigned sr, unsigned sg, unsigned sb,
+ unsigned sa, unsigned cover)
+ {
+ if(cover < 255)
+ {
+ sr = (sr * cover + 255) >> 8;
+ sg = (sg * cover + 255) >> 8;
+ sb = (sb * cover + 255) >> 8;
+ sa = (sa * cover + 255) >> 8;
+ }
+ calc_type d1a = base_mask - p[Order::A];
+ p[Order::R] = (value_type)(p[Order::R] + ((sr * d1a + base_mask) >> base_shift));
+ p[Order::G] = (value_type)(p[Order::G] + ((sg * d1a + base_mask) >> base_shift));
+ p[Order::B] = (value_type)(p[Order::B] + ((sb * d1a + base_mask) >> base_shift));
+ p[Order::A] = (value_type)(sa + p[Order::A] - ((sa * p[Order::A] + base_mask) >> base_shift));
+ }
+ };
+
+ //======================================================comp_op_rgba_src_in
+ template<class ColorT, class Order> struct comp_op_rgba_src_in
+ {
+ typedef ColorT color_type;
+ typedef Order order_type;
+ typedef typename color_type::value_type value_type;
+ typedef typename color_type::calc_type calc_type;
+ enum base_scale_e
+ {
+ base_shift = color_type::base_shift,
+ base_mask = color_type::base_mask
+ };
+
+ // Dca' = Sca.Da
+ // Da' = Sa.Da
+ static AGG_INLINE void blend_pix(value_type* p,
+ unsigned sr, unsigned sg, unsigned sb,
+ unsigned sa, unsigned cover)
+ {
+ calc_type da = p[Order::A];
+ if(cover < 255)
+ {
+ unsigned alpha = 255 - cover;
+ p[Order::R] = (value_type)(((p[Order::R] * alpha + 255) >> 8) + ((((sr * da + base_mask) >> base_shift) * cover + 255) >> 8));
+ p[Order::G] = (value_type)(((p[Order::G] * alpha + 255) >> 8) + ((((sg * da + base_mask) >> base_shift) * cover + 255) >> 8));
+ p[Order::B] = (value_type)(((p[Order::B] * alpha + 255) >> 8) + ((((sb * da + base_mask) >> base_shift) * cover + 255) >> 8));
+ p[Order::A] = (value_type)(((p[Order::A] * alpha + 255) >> 8) + ((((sa * da + base_mask) >> base_shift) * cover + 255) >> 8));
+ }
+ else
+ {
+ p[Order::R] = (value_type)((sr * da + base_mask) >> base_shift);
+ p[Order::G] = (value_type)((sg * da + base_mask) >> base_shift);
+ p[Order::B] = (value_type)((sb * da + base_mask) >> base_shift);
+ p[Order::A] = (value_type)((sa * da + base_mask) >> base_shift);
+ }
+ }
+ };
+
+ //======================================================comp_op_rgba_dst_in
+ template<class ColorT, class Order> struct comp_op_rgba_dst_in
+ {
+ typedef ColorT color_type;
+ typedef Order order_type;
+ typedef typename color_type::value_type value_type;
+ typedef typename color_type::calc_type calc_type;
+ enum base_scale_e
+ {
+ base_shift = color_type::base_shift,
+ base_mask = color_type::base_mask
+ };
+
+ // Dca' = Dca.Sa
+ // Da' = Sa.Da
+ static AGG_INLINE void blend_pix(value_type* p,
+ unsigned, unsigned, unsigned,
+ unsigned sa, unsigned cover)
+ {
+ if(cover < 255)
+ {
+ sa = base_mask - ((cover * (base_mask - sa) + 255) >> 8);
+ }
+ p[Order::R] = (value_type)((p[Order::R] * sa + base_mask) >> base_shift);
+ p[Order::G] = (value_type)((p[Order::G] * sa + base_mask) >> base_shift);
+ p[Order::B] = (value_type)((p[Order::B] * sa + base_mask) >> base_shift);
+ p[Order::A] = (value_type)((p[Order::A] * sa + base_mask) >> base_shift);
+ }
+ };
+
+ //======================================================comp_op_rgba_src_out
+ template<class ColorT, class Order> struct comp_op_rgba_src_out
+ {
+ typedef ColorT color_type;
+ typedef Order order_type;
+ typedef typename color_type::value_type value_type;
+ typedef typename color_type::calc_type calc_type;
+ enum base_scale_e
+ {
+ base_shift = color_type::base_shift,
+ base_mask = color_type::base_mask
+ };
+
+ // Dca' = Sca.(1 - Da)
+ // Da' = Sa.(1 - Da)
+ static AGG_INLINE void blend_pix(value_type* p,
+ unsigned sr, unsigned sg, unsigned sb,
+ unsigned sa, unsigned cover)
+ {
+ calc_type da = base_mask - p[Order::A];
+ if(cover < 255)
+ {
+ unsigned alpha = 255 - cover;
+ p[Order::R] = (value_type)(((p[Order::R] * alpha + 255) >> 8) + ((((sr * da + base_mask) >> base_shift) * cover + 255) >> 8));
+ p[Order::G] = (value_type)(((p[Order::G] * alpha + 255) >> 8) + ((((sg * da + base_mask) >> base_shift) * cover + 255) >> 8));
+ p[Order::B] = (value_type)(((p[Order::B] * alpha + 255) >> 8) + ((((sb * da + base_mask) >> base_shift) * cover + 255) >> 8));
+ p[Order::A] = (value_type)(((p[Order::A] * alpha + 255) >> 8) + ((((sa * da + base_mask) >> base_shift) * cover + 255) >> 8));
+ }
+ else
+ {
+ p[Order::R] = (value_type)((sr * da + base_mask) >> base_shift);
+ p[Order::G] = (value_type)((sg * da + base_mask) >> base_shift);
+ p[Order::B] = (value_type)((sb * da + base_mask) >> base_shift);
+ p[Order::A] = (value_type)((sa * da + base_mask) >> base_shift);
+ }
+ }
+ };
+
+ //======================================================comp_op_rgba_dst_out
+ template<class ColorT, class Order> struct comp_op_rgba_dst_out
+ {
+ typedef ColorT color_type;
+ typedef Order order_type;
+ typedef typename color_type::value_type value_type;
+ typedef typename color_type::calc_type calc_type;
+ enum base_scale_e
+ {
+ base_shift = color_type::base_shift,
+ base_mask = color_type::base_mask
+ };
+
+ // Dca' = Dca.(1 - Sa)
+ // Da' = Da.(1 - Sa)
+ static AGG_INLINE void blend_pix(value_type* p,
+ unsigned, unsigned, unsigned,
+ unsigned sa, unsigned cover)
+ {
+ if(cover < 255)
+ {
+ sa = (sa * cover + 255) >> 8;
+ }
+ sa = base_mask - sa;
+ p[Order::R] = (value_type)((p[Order::R] * sa + base_shift) >> base_shift);
+ p[Order::G] = (value_type)((p[Order::G] * sa + base_shift) >> base_shift);
+ p[Order::B] = (value_type)((p[Order::B] * sa + base_shift) >> base_shift);
+ p[Order::A] = (value_type)((p[Order::A] * sa + base_shift) >> base_shift);
+ }
+ };
+
+ //=====================================================comp_op_rgba_src_atop
+ template<class ColorT, class Order> struct comp_op_rgba_src_atop
+ {
+ typedef ColorT color_type;
+ typedef Order order_type;
+ typedef typename color_type::value_type value_type;
+ typedef typename color_type::calc_type calc_type;
+ enum base_scale_e
+ {
+ base_shift = color_type::base_shift,
+ base_mask = color_type::base_mask
+ };
+
+ // Dca' = Sca.Da + Dca.(1 - Sa)
+ // Da' = Da
+ static AGG_INLINE void blend_pix(value_type* p,
+ unsigned sr, unsigned sg, unsigned sb,
+ unsigned sa, unsigned cover)
+ {
+ if(cover < 255)
+ {
+ sr = (sr * cover + 255) >> 8;
+ sg = (sg * cover + 255) >> 8;
+ sb = (sb * cover + 255) >> 8;
+ sa = (sa * cover + 255) >> 8;
+ }
+ calc_type da = p[Order::A];
+ sa = base_mask - sa;
+ p[Order::R] = (value_type)((sr * da + p[Order::R] * sa + base_mask) >> base_shift);
+ p[Order::G] = (value_type)((sg * da + p[Order::G] * sa + base_mask) >> base_shift);
+ p[Order::B] = (value_type)((sb * da + p[Order::B] * sa + base_mask) >> base_shift);
+ }
+ };
+
+ //=====================================================comp_op_rgba_dst_atop
+ template<class ColorT, class Order> struct comp_op_rgba_dst_atop
+ {
+ typedef ColorT color_type;
+ typedef Order order_type;
+ typedef typename color_type::value_type value_type;
+ typedef typename color_type::calc_type calc_type;
+ enum base_scale_e
+ {
+ base_shift = color_type::base_shift,
+ base_mask = color_type::base_mask
+ };
+
+ // Dca' = Dca.Sa + Sca.(1 - Da)
+ // Da' = Sa
+ static AGG_INLINE void blend_pix(value_type* p,
+ unsigned sr, unsigned sg, unsigned sb,
+ unsigned sa, unsigned cover)
+ {
+ calc_type da = base_mask - p[Order::A];
+ if(cover < 255)
+ {
+ unsigned alpha = 255 - cover;
+ sr = (p[Order::R] * sa + sr * da + base_mask) >> base_shift;
+ sg = (p[Order::G] * sa + sg * da + base_mask) >> base_shift;
+ sb = (p[Order::B] * sa + sb * da + base_mask) >> base_shift;
+ p[Order::R] = (value_type)(((p[Order::R] * alpha + 255) >> 8) + ((sr * cover + 255) >> 8));
+ p[Order::G] = (value_type)(((p[Order::G] * alpha + 255) >> 8) + ((sg * cover + 255) >> 8));
+ p[Order::B] = (value_type)(((p[Order::B] * alpha + 255) >> 8) + ((sb * cover + 255) >> 8));
+ p[Order::A] = (value_type)(((p[Order::A] * alpha + 255) >> 8) + ((sa * cover + 255) >> 8));
+
+ }
+ else
+ {
+ p[Order::R] = (value_type)((p[Order::R] * sa + sr * da + base_mask) >> base_shift);
+ p[Order::G] = (value_type)((p[Order::G] * sa + sg * da + base_mask) >> base_shift);
+ p[Order::B] = (value_type)((p[Order::B] * sa + sb * da + base_mask) >> base_shift);
+ p[Order::A] = (value_type)sa;
+ }
+ }
+ };
+
+ //=========================================================comp_op_rgba_xor
+ template<class ColorT, class Order> struct comp_op_rgba_xor
+ {
+ typedef ColorT color_type;
+ typedef Order order_type;
+ typedef typename color_type::value_type value_type;
+ typedef typename color_type::calc_type calc_type;
+ enum base_scale_e
+ {
+ base_shift = color_type::base_shift,
+ base_mask = color_type::base_mask
+ };
+
+ // Dca' = Sca.(1 - Da) + Dca.(1 - Sa)
+ // Da' = Sa + Da - 2.Sa.Da
+ static AGG_INLINE void blend_pix(value_type* p,
+ unsigned sr, unsigned sg, unsigned sb,
+ unsigned sa, unsigned cover)
+ {
+ if(cover < 255)
+ {
+ sr = (sr * cover + 255) >> 8;
+ sg = (sg * cover + 255) >> 8;
+ sb = (sb * cover + 255) >> 8;
+ sa = (sa * cover + 255) >> 8;
+ }
+ if(sa)
+ {
+ calc_type s1a = base_mask - sa;
+ calc_type d1a = base_mask - p[Order::A];
+ p[Order::R] = (value_type)((p[Order::R] * s1a + sr * d1a + base_mask) >> base_shift);
+ p[Order::G] = (value_type)((p[Order::G] * s1a + sg * d1a + base_mask) >> base_shift);
+ p[Order::B] = (value_type)((p[Order::B] * s1a + sb * d1a + base_mask) >> base_shift);
+ p[Order::A] = (value_type)(sa + p[Order::A] - ((sa * p[Order::A] + base_mask/2) >> (base_shift - 1)));
+ }
+ }
+ };
+
+ //=========================================================comp_op_rgba_plus
+ template<class ColorT, class Order> struct comp_op_rgba_plus
+ {
+ typedef ColorT color_type;
+ typedef Order order_type;
+ typedef typename color_type::value_type value_type;
+ typedef typename color_type::calc_type calc_type;
+ enum base_scale_e
+ {
+ base_shift = color_type::base_shift,
+ base_mask = color_type::base_mask
+ };
+
+ // Dca' = Sca + Dca
+ // Da' = Sa + Da
+ static AGG_INLINE void blend_pix(value_type* p,
+ unsigned sr, unsigned sg, unsigned sb,
+ unsigned sa, unsigned cover)
+ {
+ if(cover < 255)
+ {
+ sr = (sr * cover + 255) >> 8;
+ sg = (sg * cover + 255) >> 8;
+ sb = (sb * cover + 255) >> 8;
+ sa = (sa * cover + 255) >> 8;
+ }
+ if(sa)
+ {
+ calc_type dr = p[Order::R] + sr;
+ calc_type dg = p[Order::G] + sg;
+ calc_type db = p[Order::B] + sb;
+ calc_type da = p[Order::A] + sa;
+ p[Order::R] = (dr > base_mask) ? (value_type)base_mask : dr;
+ p[Order::G] = (dg > base_mask) ? (value_type)base_mask : dg;
+ p[Order::B] = (db > base_mask) ? (value_type)base_mask : db;
+ p[Order::A] = (da > base_mask) ? (value_type)base_mask : da;
+ }
+ }
+ };
+
+ //========================================================comp_op_rgba_minus
+ template<class ColorT, class Order> struct comp_op_rgba_minus
+ {
+ typedef ColorT color_type;
+ typedef Order order_type;
+ typedef typename color_type::value_type value_type;
+ typedef typename color_type::calc_type calc_type;
+ enum base_scale_e
+ {
+ base_shift = color_type::base_shift,
+ base_mask = color_type::base_mask
+ };
+
+ // Dca' = Dca - Sca
+ // Da' = 1 - (1 - Sa).(1 - Da)
+ static AGG_INLINE void blend_pix(value_type* p,
+ unsigned sr, unsigned sg, unsigned sb,
+ unsigned sa, unsigned cover)
+ {
+ if(cover < 255)
+ {
+ sr = (sr * cover + 255) >> 8;
+ sg = (sg * cover + 255) >> 8;
+ sb = (sb * cover + 255) >> 8;
+ sa = (sa * cover + 255) >> 8;
+ }
+ if(sa)
+ {
+ calc_type dr = p[Order::R] - sr;
+ calc_type dg = p[Order::G] - sg;
+ calc_type db = p[Order::B] - sb;
+ p[Order::R] = (dr > base_mask) ? 0 : dr;
+ p[Order::G] = (dg > base_mask) ? 0 : dg;
+ p[Order::B] = (db > base_mask) ? 0 : db;
+ p[Order::A] = (value_type)(sa + p[Order::A] - ((sa * p[Order::A] + base_mask) >> base_shift));
+ //p[Order::A] = (value_type)(base_mask - (((base_mask - sa) * (base_mask - p[Order::A]) + base_mask) >> base_shift));
+ }
+ }
+ };
+
+ //=====================================================comp_op_rgba_multiply
+ template<class ColorT, class Order> struct comp_op_rgba_multiply
+ {
+ typedef ColorT color_type;
+ typedef Order order_type;
+ typedef typename color_type::value_type value_type;
+ typedef typename color_type::calc_type calc_type;
+ enum base_scale_e
+ {
+ base_shift = color_type::base_shift,
+ base_mask = color_type::base_mask
+ };
+
+ // Dca' = Sca.Dca + Sca.(1 - Da) + Dca.(1 - Sa)
+ // Da' = Sa + Da - Sa.Da
+ static AGG_INLINE void blend_pix(value_type* p,
+ unsigned sr, unsigned sg, unsigned sb,
+ unsigned sa, unsigned cover)
+ {
+ if(cover < 255)
+ {
+ sr = (sr * cover + 255) >> 8;
+ sg = (sg * cover + 255) >> 8;
+ sb = (sb * cover + 255) >> 8;
+ sa = (sa * cover + 255) >> 8;
+ }
+ if(sa)
+ {
+ calc_type s1a = base_mask - sa;
+ calc_type d1a = base_mask - p[Order::A];
+ calc_type dr = p[Order::R];
+ calc_type dg = p[Order::G];
+ calc_type db = p[Order::B];
+ p[Order::R] = (value_type)((sr * dr + sr * d1a + dr * s1a + base_mask) >> base_shift);
+ p[Order::G] = (value_type)((sg * dg + sg * d1a + dg * s1a + base_mask) >> base_shift);
+ p[Order::B] = (value_type)((sb * db + sb * d1a + db * s1a + base_mask) >> base_shift);
+ p[Order::A] = (value_type)(sa + p[Order::A] - ((sa * p[Order::A] + base_mask) >> base_shift));
+ }
+ }
+ };
+
+ //=====================================================comp_op_rgba_screen
+ template<class ColorT, class Order> struct comp_op_rgba_screen
+ {
+ typedef ColorT color_type;
+ typedef Order order_type;
+ typedef typename color_type::value_type value_type;
+ typedef typename color_type::calc_type calc_type;
+ enum base_scale_e
+ {
+ base_shift = color_type::base_shift,
+ base_mask = color_type::base_mask
+ };
+
+ // Dca' = Sca + Dca - Sca.Dca
+ // Da' = Sa + Da - Sa.Da
+ static AGG_INLINE void blend_pix(value_type* p,
+ unsigned sr, unsigned sg, unsigned sb,
+ unsigned sa, unsigned cover)
+ {
+ if(cover < 255)
+ {
+ sr = (sr * cover + 255) >> 8;
+ sg = (sg * cover + 255) >> 8;
+ sb = (sb * cover + 255) >> 8;
+ sa = (sa * cover + 255) >> 8;
+ }
+ if(sa)
+ {
+ calc_type dr = p[Order::R];
+ calc_type dg = p[Order::G];
+ calc_type db = p[Order::B];
+ calc_type da = p[Order::A];
+ p[Order::R] = (value_type)(sr + dr - ((sr * dr + base_mask) >> base_shift));
+ p[Order::G] = (value_type)(sg + dg - ((sg * dg + base_mask) >> base_shift));
+ p[Order::B] = (value_type)(sb + db - ((sb * db + base_mask) >> base_shift));
+ p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift));
+ }
+ }
+ };
+
+ //=====================================================comp_op_rgba_overlay
+ template<class ColorT, class Order> struct comp_op_rgba_overlay
+ {
+ typedef ColorT color_type;
+ typedef Order order_type;
+ typedef typename color_type::value_type value_type;
+ typedef typename color_type::calc_type calc_type;
+ enum base_scale_e
+ {
+ base_shift = color_type::base_shift,
+ base_mask = color_type::base_mask
+ };
+
+ // if 2.Dca < Da
+ // Dca' = 2.Sca.Dca + Sca.(1 - Da) + Dca.(1 - Sa)
+ // otherwise
+ // Dca' = Sa.Da - 2.(Da - Dca).(Sa - Sca) + Sca.(1 - Da) + Dca.(1 - Sa)
+ //
+ // Da' = Sa + Da - Sa.Da
+ static AGG_INLINE void blend_pix(value_type* p,
+ unsigned sr, unsigned sg, unsigned sb,
+ unsigned sa, unsigned cover)
+ {
+ if(cover < 255)
+ {
+ sr = (sr * cover + 255) >> 8;
+ sg = (sg * cover + 255) >> 8;
+ sb = (sb * cover + 255) >> 8;
+ sa = (sa * cover + 255) >> 8;
+ }
+ if(sa)
+ {
+ calc_type d1a = base_mask - p[Order::A];
+ calc_type s1a = base_mask - sa;
+ calc_type dr = p[Order::R];
+ calc_type dg = p[Order::G];
+ calc_type db = p[Order::B];
+ calc_type da = p[Order::A];
+ calc_type sada = sa * p[Order::A];
+
+ p[Order::R] = (value_type)(((2*dr < da) ?
+ 2*sr*dr + sr*d1a + dr*s1a :
+ sada - 2*(da - dr)*(sa - sr) + sr*d1a + dr*s1a + base_mask) >> base_shift);
+
+ p[Order::G] = (value_type)(((2*dg < da) ?
+ 2*sg*dg + sg*d1a + dg*s1a :
+ sada - 2*(da - dg)*(sa - sg) + sg*d1a + dg*s1a + base_mask) >> base_shift);
+
+ p[Order::B] = (value_type)(((2*db < da) ?
+ 2*sb*db + sb*d1a + db*s1a :
+ sada - 2*(da - db)*(sa - sb) + sb*d1a + db*s1a + base_mask) >> base_shift);
+
+ p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift));
+ }
+ }
+ };
+
+
+ template<class T> inline T sd_min(T a, T b) { return (a < b) ? a : b; }
+ template<class T> inline T sd_max(T a, T b) { return (a > b) ? a : b; }
+
+ //=====================================================comp_op_rgba_darken
+ template<class ColorT, class Order> struct comp_op_rgba_darken
+ {
+ typedef ColorT color_type;
+ typedef Order order_type;
+ typedef typename color_type::value_type value_type;
+ typedef typename color_type::calc_type calc_type;
+ enum base_scale_e
+ {
+ base_shift = color_type::base_shift,
+ base_mask = color_type::base_mask
+ };
+
+ // Dca' = min(Sca.Da, Dca.Sa) + Sca.(1 - Da) + Dca.(1 - Sa)
+ // Da' = Sa + Da - Sa.Da
+ static AGG_INLINE void blend_pix(value_type* p,
+ unsigned sr, unsigned sg, unsigned sb,
+ unsigned sa, unsigned cover)
+ {
+ if(cover < 255)
+ {
+ sr = (sr * cover + 255) >> 8;
+ sg = (sg * cover + 255) >> 8;
+ sb = (sb * cover + 255) >> 8;
+ sa = (sa * cover + 255) >> 8;
+ }
+ if(sa)
+ {
+ calc_type d1a = base_mask - p[Order::A];
+ calc_type s1a = base_mask - sa;
+ calc_type dr = p[Order::R];
+ calc_type dg = p[Order::G];
+ calc_type db = p[Order::B];
+ calc_type da = p[Order::A];
+
+ p[Order::R] = (value_type)((sd_min(sr * da, dr * sa) + sr * d1a + dr * s1a + base_mask) >> base_shift);
+ p[Order::G] = (value_type)((sd_min(sg * da, dg * sa) + sg * d1a + dg * s1a + base_mask) >> base_shift);
+ p[Order::B] = (value_type)((sd_min(sb * da, db * sa) + sb * d1a + db * s1a + base_mask) >> base_shift);
+ p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift));
+ }
+ }
+ };
+
+ //=====================================================comp_op_rgba_lighten
+ template<class ColorT, class Order> struct comp_op_rgba_lighten
+ {
+ typedef ColorT color_type;
+ typedef Order order_type;
+ typedef typename color_type::value_type value_type;
+ typedef typename color_type::calc_type calc_type;
+ enum base_scale_e
+ {
+ base_shift = color_type::base_shift,
+ base_mask = color_type::base_mask
+ };
+
+ // Dca' = max(Sca.Da, Dca.Sa) + Sca.(1 - Da) + Dca.(1 - Sa)
+ // Da' = Sa + Da - Sa.Da
+ static AGG_INLINE void blend_pix(value_type* p,
+ unsigned sr, unsigned sg, unsigned sb,
+ unsigned sa, unsigned cover)
+ {
+ if(cover < 255)
+ {
+ sr = (sr * cover + 255) >> 8;
+ sg = (sg * cover + 255) >> 8;
+ sb = (sb * cover + 255) >> 8;
+ sa = (sa * cover + 255) >> 8;
+ }
+ if(sa)
+ {
+ calc_type d1a = base_mask - p[Order::A];
+ calc_type s1a = base_mask - sa;
+ calc_type dr = p[Order::R];
+ calc_type dg = p[Order::G];
+ calc_type db = p[Order::B];
+ calc_type da = p[Order::A];
+
+ p[Order::R] = (value_type)((sd_max(sr * da, dr * sa) + sr * d1a + dr * s1a + base_mask) >> base_shift);
+ p[Order::G] = (value_type)((sd_max(sg * da, dg * sa) + sg * d1a + dg * s1a + base_mask) >> base_shift);
+ p[Order::B] = (value_type)((sd_max(sb * da, db * sa) + sb * d1a + db * s1a + base_mask) >> base_shift);
+ p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift));
+ }
+ }
+ };
+
+ //=====================================================comp_op_rgba_color_dodge
+ template<class ColorT, class Order> struct comp_op_rgba_color_dodge
+ {
+ typedef ColorT color_type;
+ typedef Order order_type;
+ typedef typename color_type::value_type value_type;
+ typedef typename color_type::calc_type calc_type;
+ typedef typename color_type::long_type long_type;
+ enum base_scale_e
+ {
+ base_shift = color_type::base_shift,
+ base_mask = color_type::base_mask
+ };
+
+ // if Sca.Da + Dca.Sa >= Sa.Da
+ // Dca' = Sa.Da + Sca.(1 - Da) + Dca.(1 - Sa)
+ // otherwise
+ // Dca' = Dca.Sa/(1-Sca/Sa) + Sca.(1 - Da) + Dca.(1 - Sa)
+ //
+ // Da' = Sa + Da - Sa.Da
+ static AGG_INLINE void blend_pix(value_type* p,
+ unsigned sr, unsigned sg, unsigned sb,
+ unsigned sa, unsigned cover)
+ {
+ if(cover < 255)
+ {
+ sr = (sr * cover + 255) >> 8;
+ sg = (sg * cover + 255) >> 8;
+ sb = (sb * cover + 255) >> 8;
+ sa = (sa * cover + 255) >> 8;
+ }
+ if(sa)
+ {
+ calc_type d1a = base_mask - p[Order::A];
+ calc_type s1a = base_mask - sa;
+ calc_type dr = p[Order::R];
+ calc_type dg = p[Order::G];
+ calc_type db = p[Order::B];
+ calc_type da = p[Order::A];
+ long_type drsa = dr * sa;
+ long_type dgsa = dg * sa;
+ long_type dbsa = db * sa;
+ long_type srda = sr * da;
+ long_type sgda = sg * da;
+ long_type sbda = sb * da;
+ long_type sada = sa * da;
+
+ p[Order::R] = (value_type)((srda + drsa >= sada) ?
+ (sada + sr * d1a + dr * s1a + base_mask) >> base_shift :
+ drsa / (base_mask - (sr << base_shift) / sa) + ((sr * d1a + dr * s1a + base_mask) >> base_shift));
+
+ p[Order::G] = (value_type)((sgda + dgsa >= sada) ?
+ (sada + sg * d1a + dg * s1a + base_mask) >> base_shift :
+ dgsa / (base_mask - (sg << base_shift) / sa) + ((sg * d1a + dg * s1a + base_mask) >> base_shift));
+
+ p[Order::B] = (value_type)((sbda + dbsa >= sada) ?
+ (sada + sb * d1a + db * s1a + base_mask) >> base_shift :
+ dbsa / (base_mask - (sb << base_shift) / sa) + ((sb * d1a + db * s1a + base_mask) >> base_shift));
+
+ p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift));
+ }
+ }
+ };
+
+ //=====================================================comp_op_rgba_color_burn
+ template<class ColorT, class Order> struct comp_op_rgba_color_burn
+ {
+ typedef ColorT color_type;
+ typedef Order order_type;
+ typedef typename color_type::value_type value_type;
+ typedef typename color_type::calc_type calc_type;
+ typedef typename color_type::long_type long_type;
+ enum base_scale_e
+ {
+ base_shift = color_type::base_shift,
+ base_mask = color_type::base_mask
+ };
+
+ // if Sca.Da + Dca.Sa <= Sa.Da
+ // Dca' = Sca.(1 - Da) + Dca.(1 - Sa)
+ // otherwise
+ // Dca' = Sa.(Sca.Da + Dca.Sa - Sa.Da)/Sca + Sca.(1 - Da) + Dca.(1 - Sa)
+ //
+ // Da' = Sa + Da - Sa.Da
+ static AGG_INLINE void blend_pix(value_type* p,
+ unsigned sr, unsigned sg, unsigned sb,
+ unsigned sa, unsigned cover)
+ {
+ if(cover < 255)
+ {
+ sr = (sr * cover + 255) >> 8;
+ sg = (sg * cover + 255) >> 8;
+ sb = (sb * cover + 255) >> 8;
+ sa = (sa * cover + 255) >> 8;
+ }
+ if(sa)
+ {
+ calc_type d1a = base_mask - p[Order::A];
+ calc_type s1a = base_mask - sa;
+ calc_type dr = p[Order::R];
+ calc_type dg = p[Order::G];
+ calc_type db = p[Order::B];
+ calc_type da = p[Order::A];
+ long_type drsa = dr * sa;
+ long_type dgsa = dg * sa;
+ long_type dbsa = db * sa;
+ long_type srda = sr * da;
+ long_type sgda = sg * da;
+ long_type sbda = sb * da;
+ long_type sada = sa * da;
+
+ p[Order::R] = (value_type)(((srda + drsa <= sada) ?
+ sr * d1a + dr * s1a :
+ sa * (srda + drsa - sada) / sr + sr * d1a + dr * s1a + base_mask) >> base_shift);
+
+ p[Order::G] = (value_type)(((sgda + dgsa <= sada) ?
+ sg * d1a + dg * s1a :
+ sa * (sgda + dgsa - sada) / sg + sg * d1a + dg * s1a + base_mask) >> base_shift);
+
+ p[Order::B] = (value_type)(((sbda + dbsa <= sada) ?
+ sb * d1a + db * s1a :
+ sa * (sbda + dbsa - sada) / sb + sb * d1a + db * s1a + base_mask) >> base_shift);
+
+ p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift));
+ }
+ }
+ };
+
+ //=====================================================comp_op_rgba_hard_light
+ template<class ColorT, class Order> struct comp_op_rgba_hard_light
+ {
+ typedef ColorT color_type;
+ typedef Order order_type;
+ typedef typename color_type::value_type value_type;
+ typedef typename color_type::calc_type calc_type;
+ typedef typename color_type::long_type long_type;
+ enum base_scale_e
+ {
+ base_shift = color_type::base_shift,
+ base_mask = color_type::base_mask
+ };
+
+ // if 2.Sca < Sa
+ // Dca' = 2.Sca.Dca + Sca.(1 - Da) + Dca.(1 - Sa)
+ // otherwise
+ // Dca' = Sa.Da - 2.(Da - Dca).(Sa - Sca) + Sca.(1 - Da) + Dca.(1 - Sa)
+ //
+ // Da' = Sa + Da - Sa.Da
+ static AGG_INLINE void blend_pix(value_type* p,
+ unsigned sr, unsigned sg, unsigned sb,
+ unsigned sa, unsigned cover)
+ {
+ if(cover < 255)
+ {
+ sr = (sr * cover + 255) >> 8;
+ sg = (sg * cover + 255) >> 8;
+ sb = (sb * cover + 255) >> 8;
+ sa = (sa * cover + 255) >> 8;
+ }
+ if(sa)
+ {
+ calc_type d1a = base_mask - p[Order::A];
+ calc_type s1a = base_mask - sa;
+ calc_type dr = p[Order::R];
+ calc_type dg = p[Order::G];
+ calc_type db = p[Order::B];
+ calc_type da = p[Order::A];
+ calc_type sada = sa * da;
+
+ p[Order::R] = (value_type)(((2*sr < sa) ?
+ 2*sr*dr + sr*d1a + dr*s1a :
+ sada - 2*(da - dr)*(sa - sr) + sr*d1a + dr*s1a + base_mask) >> base_shift);
+
+ p[Order::G] = (value_type)(((2*sg < sa) ?
+ 2*sg*dg + sg*d1a + dg*s1a :
+ sada - 2*(da - dg)*(sa - sg) + sg*d1a + dg*s1a + base_mask) >> base_shift);
+
+ p[Order::B] = (value_type)(((2*sb < sa) ?
+ 2*sb*db + sb*d1a + db*s1a :
+ sada - 2*(da - db)*(sa - sb) + sb*d1a + db*s1a + base_mask) >> base_shift);
+
+ p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift));
+ }
+ }
+ };
+
+ //=====================================================comp_op_rgba_soft_light
+ template<class ColorT, class Order> struct comp_op_rgba_soft_light
+ {
+ typedef ColorT color_type;
+ typedef Order order_type;
+ typedef typename color_type::value_type value_type;
+ typedef typename color_type::calc_type calc_type;
+ typedef typename color_type::long_type long_type;
+ enum base_scale_e
+ {
+ base_shift = color_type::base_shift,
+ base_mask = color_type::base_mask
+ };
+
+ // if 2.Sca < Sa
+ // Dca' = Dca.(Sa + (1 - Dca/Da).(2.Sca - Sa)) + Sca.(1 - Da) + Dca.(1 - Sa)
+ // otherwise if 8.Dca <= Da
+ // Dca' = Dca.(Sa + (1 - Dca/Da).(2.Sca - Sa).(3 - 8.Dca/Da)) + Sca.(1 - Da) + Dca.(1 - Sa)
+ // otherwise
+ // Dca' = (Dca.Sa + ((Dca/Da)^(0.5).Da - Dca).(2.Sca - Sa)) + Sca.(1 - Da) + Dca.(1 - Sa)
+ //
+ // Da' = Sa + Da - Sa.Da
+
+ static AGG_INLINE void blend_pix(value_type* p,
+ unsigned r, unsigned g, unsigned b,
+ unsigned a, unsigned cover)
+ {
+ double sr = double(r * cover) / (base_mask * 255);
+ double sg = double(g * cover) / (base_mask * 255);
+ double sb = double(b * cover) / (base_mask * 255);
+ double sa = double(a * cover) / (base_mask * 255);
+ if(sa > 0)
+ {
+ double dr = double(p[Order::R]) / base_mask;
+ double dg = double(p[Order::G]) / base_mask;
+ double db = double(p[Order::B]) / base_mask;
+ double da = double(p[Order::A] ? p[Order::A] : 1) / base_mask;
+ if(cover < 255)
+ {
+ a = (a * cover + 255) >> 8;
+ }
+
+ if(2*sr < sa) dr = dr*(sa + (1 - dr/da)*(2*sr - sa)) + sr*(1 - da) + dr*(1 - sa);
+ else if(8*dr <= da) dr = dr*(sa + (1 - dr/da)*(2*sr - sa)*(3 - 8*dr/da)) + sr*(1 - da) + dr*(1 - sa);
+ else dr = (dr*sa + (sqrt(dr/da)*da - dr)*(2*sr - sa)) + sr*(1 - da) + dr*(1 - sa);
+
+ if(2*sg < sa) dg = dg*(sa + (1 - dg/da)*(2*sg - sa)) + sg*(1 - da) + dg*(1 - sa);
+ else if(8*dg <= da) dg = dg*(sa + (1 - dg/da)*(2*sg - sa)*(3 - 8*dg/da)) + sg*(1 - da) + dg*(1 - sa);
+ else dg = (dg*sa + (sqrt(dg/da)*da - dg)*(2*sg - sa)) + sg*(1 - da) + dg*(1 - sa);
+
+ if(2*sb < sa) db = db*(sa + (1 - db/da)*(2*sb - sa)) + sb*(1 - da) + db*(1 - sa);
+ else if(8*db <= da) db = db*(sa + (1 - db/da)*(2*sb - sa)*(3 - 8*db/da)) + sb*(1 - da) + db*(1 - sa);
+ else db = (db*sa + (sqrt(db/da)*da - db)*(2*sb - sa)) + sb*(1 - da) + db*(1 - sa);
+
+ p[Order::R] = (value_type)uround(dr * base_mask);
+ p[Order::G] = (value_type)uround(dg * base_mask);
+ p[Order::B] = (value_type)uround(db * base_mask);
+ p[Order::A] = (value_type)(a + p[Order::A] - ((a * p[Order::A] + base_mask) >> base_shift));
+ }
+ }
+ };
+
+ //=====================================================comp_op_rgba_difference
+ template<class ColorT, class Order> struct comp_op_rgba_difference
+ {
+ typedef ColorT color_type;
+ typedef Order order_type;
+ typedef typename color_type::value_type value_type;
+ typedef typename color_type::calc_type calc_type;
+ typedef typename color_type::long_type long_type;
+ enum base_scale_e
+ {
+ base_shift = color_type::base_shift,
+ base_scale = color_type::base_scale,
+ base_mask = color_type::base_mask
+ };
+
+ // Dca' = Sca + Dca - 2.min(Sca.Da, Dca.Sa)
+ // Da' = Sa + Da - Sa.Da
+ static AGG_INLINE void blend_pix(value_type* p,
+ unsigned sr, unsigned sg, unsigned sb,
+ unsigned sa, unsigned cover)
+ {
+ if(cover < 255)
+ {
+ sr = (sr * cover + 255) >> 8;
+ sg = (sg * cover + 255) >> 8;
+ sb = (sb * cover + 255) >> 8;
+ sa = (sa * cover + 255) >> 8;
+ }
+ if(sa)
+ {
+ calc_type dr = p[Order::R];
+ calc_type dg = p[Order::G];
+ calc_type db = p[Order::B];
+ calc_type da = p[Order::A];
+ p[Order::R] = (value_type)(sr + dr - ((2 * sd_min(sr*da, dr*sa) + base_mask) >> base_shift));
+ p[Order::G] = (value_type)(sg + dg - ((2 * sd_min(sg*da, dg*sa) + base_mask) >> base_shift));
+ p[Order::B] = (value_type)(sb + db - ((2 * sd_min(sb*da, db*sa) + base_mask) >> base_shift));
+ p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift));
+ }
+ }
+ };
+
+ //=====================================================comp_op_rgba_exclusion
+ template<class ColorT, class Order> struct comp_op_rgba_exclusion
+ {
+ typedef ColorT color_type;
+ typedef Order order_type;
+ typedef typename color_type::value_type value_type;
+ typedef typename color_type::calc_type calc_type;
+ typedef typename color_type::long_type long_type;
+ enum base_scale_e
+ {
+ base_shift = color_type::base_shift,
+ base_mask = color_type::base_mask
+ };
+
+ // Dca' = (Sca.Da + Dca.Sa - 2.Sca.Dca) + Sca.(1 - Da) + Dca.(1 - Sa)
+ // Da' = Sa + Da - Sa.Da
+ static AGG_INLINE void blend_pix(value_type* p,
+ unsigned sr, unsigned sg, unsigned sb,
+ unsigned sa, unsigned cover)
+ {
+ if(cover < 255)
+ {
+ sr = (sr * cover + 255) >> 8;
+ sg = (sg * cover + 255) >> 8;
+ sb = (sb * cover + 255) >> 8;
+ sa = (sa * cover + 255) >> 8;
+ }
+ if(sa)
+ {
+ calc_type d1a = base_mask - p[Order::A];
+ calc_type s1a = base_mask - sa;
+ calc_type dr = p[Order::R];
+ calc_type dg = p[Order::G];
+ calc_type db = p[Order::B];
+ calc_type da = p[Order::A];
+ p[Order::R] = (value_type)((sr*da + dr*sa - 2*sr*dr + sr*d1a + dr*s1a + base_mask) >> base_shift);
+ p[Order::G] = (value_type)((sg*da + dg*sa - 2*sg*dg + sg*d1a + dg*s1a + base_mask) >> base_shift);
+ p[Order::B] = (value_type)((sb*da + db*sa - 2*sb*db + sb*d1a + db*s1a + base_mask) >> base_shift);
+ p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift));
+ }
+ }
+ };
+
+ //=====================================================comp_op_rgba_contrast
+ template<class ColorT, class Order> struct comp_op_rgba_contrast
+ {
+ typedef ColorT color_type;
+ typedef Order order_type;
+ typedef typename color_type::value_type value_type;
+ typedef typename color_type::calc_type calc_type;
+ typedef typename color_type::long_type long_type;
+ enum base_scale_e
+ {
+ base_shift = color_type::base_shift,
+ base_mask = color_type::base_mask
+ };
+
+
+ static AGG_INLINE void blend_pix(value_type* p,
+ unsigned sr, unsigned sg, unsigned sb,
+ unsigned sa, unsigned cover)
+ {
+ if(cover < 255)
+ {
+ sr = (sr * cover + 255) >> 8;
+ sg = (sg * cover + 255) >> 8;
+ sb = (sb * cover + 255) >> 8;
+ sa = (sa * cover + 255) >> 8;
+ }
+ long_type dr = p[Order::R];
+ long_type dg = p[Order::G];
+ long_type db = p[Order::B];
+ int da = p[Order::A];
+ long_type d2a = da >> 1;
+ unsigned s2a = sa >> 1;
+
+ int r = (int)((((dr - d2a) * int((sr - s2a)*2 + base_mask)) >> base_shift) + d2a);
+ int g = (int)((((dg - d2a) * int((sg - s2a)*2 + base_mask)) >> base_shift) + d2a);
+ int b = (int)((((db - d2a) * int((sb - s2a)*2 + base_mask)) >> base_shift) + d2a);
+
+ r = (r < 0) ? 0 : r;
+ g = (g < 0) ? 0 : g;
+ b = (b < 0) ? 0 : b;
+
+ p[Order::R] = (value_type)((r > da) ? da : r);
+ p[Order::G] = (value_type)((g > da) ? da : g);
+ p[Order::B] = (value_type)((b > da) ? da : b);
+ }
+ };
+
+ //=====================================================comp_op_rgba_invert
+ template<class ColorT, class Order> struct comp_op_rgba_invert
+ {
+ typedef ColorT color_type;
+ typedef Order order_type;
+ typedef typename color_type::value_type value_type;
+ typedef typename color_type::calc_type calc_type;
+ typedef typename color_type::long_type long_type;
+ enum base_scale_e
+ {
+ base_shift = color_type::base_shift,
+ base_mask = color_type::base_mask
+ };
+
+ // Dca' = (Da - Dca) * Sa + Dca.(1 - Sa)
+ // Da' = Sa + Da - Sa.Da
+ static AGG_INLINE void blend_pix(value_type* p,
+ unsigned sr, unsigned sg, unsigned sb,
+ unsigned sa, unsigned cover)
+ {
+ sa = (sa * cover + 255) >> 8;
+ if(sa)
+ {
+ calc_type da = p[Order::A];
+ calc_type dr = ((da - p[Order::R]) * sa + base_mask) >> base_shift;
+ calc_type dg = ((da - p[Order::G]) * sa + base_mask) >> base_shift;
+ calc_type db = ((da - p[Order::B]) * sa + base_mask) >> base_shift;
+ calc_type s1a = base_mask - sa;
+ p[Order::R] = (value_type)(dr + ((p[Order::R] * s1a + base_mask) >> base_shift));
+ p[Order::G] = (value_type)(dg + ((p[Order::G] * s1a + base_mask) >> base_shift));
+ p[Order::B] = (value_type)(db + ((p[Order::B] * s1a + base_mask) >> base_shift));
+ p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift));
+ }
+ }
+ };
+
+ //=================================================comp_op_rgba_invert_rgb
+ template<class ColorT, class Order> struct comp_op_rgba_invert_rgb
+ {
+ typedef ColorT color_type;
+ typedef Order order_type;
+ typedef typename color_type::value_type value_type;
+ typedef typename color_type::calc_type calc_type;
+ typedef typename color_type::long_type long_type;
+ enum base_scale_e
+ {
+ base_shift = color_type::base_shift,
+ base_mask = color_type::base_mask
+ };
+
+ // Dca' = (Da - Dca) * Sca + Dca.(1 - Sa)
+ // Da' = Sa + Da - Sa.Da
static AGG_INLINE void blend_pix(value_type* p,
+ unsigned sr, unsigned sg, unsigned sb,
+ unsigned sa, unsigned cover)
+ {
+ if(cover < 255)
+ {
+ sr = (sr * cover + 255) >> 8;
+ sg = (sg * cover + 255) >> 8;
+ sb = (sb * cover + 255) >> 8;
+ sa = (sa * cover + 255) >> 8;
+ }
+ if(sa)
+ {
+ calc_type da = p[Order::A];
+ calc_type dr = ((da - p[Order::R]) * sr + base_mask) >> base_shift;
+ calc_type dg = ((da - p[Order::G]) * sg + base_mask) >> base_shift;
+ calc_type db = ((da - p[Order::B]) * sb + base_mask) >> base_shift;
+ calc_type s1a = base_mask - sa;
+ p[Order::R] = (value_type)(dr + ((p[Order::R] * s1a + base_mask) >> base_shift));
+ p[Order::G] = (value_type)(dg + ((p[Order::G] * s1a + base_mask) >> base_shift));
+ p[Order::B] = (value_type)(db + ((p[Order::B] * s1a + base_mask) >> base_shift));
+ p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift));
+ }
+ }
+ };
+
+
+
+
+
+ //======================================================comp_op_table_rgba
+ template<class ColorT, class Order> struct comp_op_table_rgba
+ {
+ typedef typename ColorT::value_type value_type;
+ typedef void (*comp_op_func_type)(value_type* p,
+ unsigned cr,
+ unsigned cg,
+ unsigned cb,
+ unsigned ca,
+ unsigned cover);
+ static comp_op_func_type g_comp_op_func[];
+ };
+
+ //==========================================================g_comp_op_func
+ template<class ColorT, class Order>
+ typename comp_op_table_rgba<ColorT, Order>::comp_op_func_type
+ comp_op_table_rgba<ColorT, Order>::g_comp_op_func[] =
+ {
+ comp_op_rgba_clear <ColorT,Order>::blend_pix,
+ comp_op_rgba_src <ColorT,Order>::blend_pix,
+ comp_op_rgba_dst <ColorT,Order>::blend_pix,
+ comp_op_rgba_src_over <ColorT,Order>::blend_pix,
+ comp_op_rgba_dst_over <ColorT,Order>::blend_pix,
+ comp_op_rgba_src_in <ColorT,Order>::blend_pix,
+ comp_op_rgba_dst_in <ColorT,Order>::blend_pix,
+ comp_op_rgba_src_out <ColorT,Order>::blend_pix,
+ comp_op_rgba_dst_out <ColorT,Order>::blend_pix,
+ comp_op_rgba_src_atop <ColorT,Order>::blend_pix,
+ comp_op_rgba_dst_atop <ColorT,Order>::blend_pix,
+ comp_op_rgba_xor <ColorT,Order>::blend_pix,
+ comp_op_rgba_plus <ColorT,Order>::blend_pix,
+ comp_op_rgba_minus <ColorT,Order>::blend_pix,
+ comp_op_rgba_multiply <ColorT,Order>::blend_pix,
+ comp_op_rgba_screen <ColorT,Order>::blend_pix,
+ comp_op_rgba_overlay <ColorT,Order>::blend_pix,
+ comp_op_rgba_darken <ColorT,Order>::blend_pix,
+ comp_op_rgba_lighten <ColorT,Order>::blend_pix,
+ comp_op_rgba_color_dodge<ColorT,Order>::blend_pix,
+ comp_op_rgba_color_burn <ColorT,Order>::blend_pix,
+ comp_op_rgba_hard_light <ColorT,Order>::blend_pix,
+ comp_op_rgba_soft_light <ColorT,Order>::blend_pix,
+ comp_op_rgba_difference <ColorT,Order>::blend_pix,
+ comp_op_rgba_exclusion <ColorT,Order>::blend_pix,
+ comp_op_rgba_contrast <ColorT,Order>::blend_pix,
+ comp_op_rgba_invert <ColorT,Order>::blend_pix,
+ comp_op_rgba_invert_rgb <ColorT,Order>::blend_pix,
+ 0
+ };
+
+
+ //==============================================================comp_op_e
+ enum comp_op_e
+ {
+ comp_op_clear, //----comp_op_clear
+ comp_op_src, //----comp_op_src
+ comp_op_dst, //----comp_op_dst
+ comp_op_src_over, //----comp_op_src_over
+ comp_op_dst_over, //----comp_op_dst_over
+ comp_op_src_in, //----comp_op_src_in
+ comp_op_dst_in, //----comp_op_dst_in
+ comp_op_src_out, //----comp_op_src_out
+ comp_op_dst_out, //----comp_op_dst_out
+ comp_op_src_atop, //----comp_op_src_atop
+ comp_op_dst_atop, //----comp_op_dst_atop
+ comp_op_xor, //----comp_op_xor
+ comp_op_plus, //----comp_op_plus
+ comp_op_minus, //----comp_op_minus
+ comp_op_multiply, //----comp_op_multiply
+ comp_op_screen, //----comp_op_screen
+ comp_op_overlay, //----comp_op_overlay
+ comp_op_darken, //----comp_op_darken
+ comp_op_lighten, //----comp_op_lighten
+ comp_op_color_dodge, //----comp_op_color_dodge
+ comp_op_color_burn, //----comp_op_color_burn
+ comp_op_hard_light, //----comp_op_hard_light
+ comp_op_soft_light, //----comp_op_soft_light
+ comp_op_difference, //----comp_op_difference
+ comp_op_exclusion, //----comp_op_exclusion
+ comp_op_contrast, //----comp_op_contrast
+ comp_op_invert, //----comp_op_invert
+ comp_op_invert_rgb, //----comp_op_invert_rgb
+
+ end_of_comp_op_e
+ };
+
+
+
+
+
+
+
+ //====================================================comp_op_adaptor_rgba
+ template<class ColorT, class Order> struct comp_op_adaptor_rgba
+ {
+ typedef Order order_type;
+ typedef ColorT color_type;
+ typedef typename color_type::value_type value_type;
+ enum base_scale_e
+ {
+ base_shift = color_type::base_shift,
+ base_mask = color_type::base_mask
+ };
+
+ static AGG_INLINE void blend_pix(unsigned op, value_type* p,
unsigned cr, unsigned cg, unsigned cb,
- unsigned alpha,
+ unsigned ca,
+ unsigned cover)
+ {
+ comp_op_table_rgba<ColorT, Order>::g_comp_op_func[op]
+ (p, (cr * ca + base_mask) >> base_shift,
+ (cg * ca + base_mask) >> base_shift,
+ (cb * ca + base_mask) >> base_shift,
+ ca, cover);
+ }
+ };
+
+ //=========================================comp_op_adaptor_clip_to_dst_rgba
+ template<class ColorT, class Order> struct comp_op_adaptor_clip_to_dst_rgba
+ {
+ typedef Order order_type;
+ typedef ColorT color_type;
+ typedef typename color_type::value_type value_type;
+ enum base_scale_e
+ {
+ base_shift = color_type::base_shift,
+ base_mask = color_type::base_mask
+ };
+
+ static AGG_INLINE void blend_pix(unsigned op, value_type* p,
+ unsigned cr, unsigned cg, unsigned cb,
+ unsigned ca,
+ unsigned cover)
+ {
+ cr = (cr * ca + base_mask) >> base_shift;
+ cg = (cg * ca + base_mask) >> base_shift;
+ cb = (cb * ca + base_mask) >> base_shift;
+ unsigned da = p[Order::A];
+ comp_op_table_rgba<ColorT, Order>::g_comp_op_func[op]
+ (p, (cr * da + base_mask) >> base_shift,
+ (cg * da + base_mask) >> base_shift,
+ (cb * da + base_mask) >> base_shift,
+ (ca * da + base_mask) >> base_shift,
+ cover);
+ }
+ };
+
+ //================================================comp_op_adaptor_rgba_pre
+ template<class ColorT, class Order> struct comp_op_adaptor_rgba_pre
+ {
+ typedef Order order_type;
+ typedef ColorT color_type;
+ typedef typename color_type::value_type value_type;
+ enum base_scale_e
+ {
+ base_shift = color_type::base_shift,
+ base_mask = color_type::base_mask
+ };
+
+ static AGG_INLINE void blend_pix(unsigned op, value_type* p,
+ unsigned cr, unsigned cg, unsigned cb,
+ unsigned ca,
+ unsigned cover)
+ {
+ comp_op_table_rgba<ColorT, Order>::g_comp_op_func[op](p, cr, cg, cb, ca, cover);
+ }
+ };
+
+ //=====================================comp_op_adaptor_clip_to_dst_rgba_pre
+ template<class ColorT, class Order> struct comp_op_adaptor_clip_to_dst_rgba_pre
+ {
+ typedef Order order_type;
+ typedef ColorT color_type;
+ typedef typename color_type::value_type value_type;
+ enum base_scale_e
+ {
+ base_shift = color_type::base_shift,
+ base_mask = color_type::base_mask
+ };
+
+ static AGG_INLINE void blend_pix(unsigned op, value_type* p,
+ unsigned cr, unsigned cg, unsigned cb,
+ unsigned ca,
+ unsigned cover)
+ {
+ unsigned da = p[Order::A];
+ comp_op_table_rgba<ColorT, Order>::g_comp_op_func[op]
+ (p, (cr * da + base_mask) >> base_shift,
+ (cg * da + base_mask) >> base_shift,
+ (cb * da + base_mask) >> base_shift,
+ (ca * da + base_mask) >> base_shift,
+ cover);
+ }
+ };
+
+ //=======================================================comp_adaptor_rgba
+ template<class BlenderPre> struct comp_adaptor_rgba
+ {
+ typedef typename BlenderPre::order_type order_type;
+ typedef typename BlenderPre::color_type color_type;
+ typedef typename color_type::value_type value_type;
+ enum base_scale_e
+ {
+ base_shift = color_type::base_shift,
+ base_mask = color_type::base_mask
+ };
+
+ static AGG_INLINE void blend_pix(unsigned op, value_type* p,
+ unsigned cr, unsigned cg, unsigned cb,
+ unsigned ca,
+ unsigned cover)
+ {
+ BlenderPre::blend_pix(p,
+ (cr * ca + base_mask) >> base_shift,
+ (cg * ca + base_mask) >> base_shift,
+ (cb * ca + base_mask) >> base_shift,
+ ca, cover);
+ }
+ };
+
+ //==========================================comp_adaptor_clip_to_dst_rgba
+ template<class BlenderPre> struct comp_adaptor_clip_to_dst_rgba
+ {
+ typedef typename BlenderPre::order_type order_type;
+ typedef typename BlenderPre::color_type color_type;
+ typedef typename color_type::value_type value_type;
+ enum base_scale_e
+ {
+ base_shift = color_type::base_shift,
+ base_mask = color_type::base_mask
+ };
+
+ static AGG_INLINE void blend_pix(unsigned op, value_type* p,
+ unsigned cr, unsigned cg, unsigned cb,
+ unsigned ca,
unsigned cover)
{
- Blender::blend_pix(p, cr, cg, cb, alpha, cover);
+ cr = (cr * ca + base_mask) >> base_shift;
+ cg = (cg * ca + base_mask) >> base_shift;
+ cb = (cb * ca + base_mask) >> base_shift;
+ unsigned da = p[order_type::A];
+ BlenderPre::blend_pix(p,
+ (cr * da + base_mask) >> base_shift,
+ (cg * da + base_mask) >> base_shift,
+ (cb * da + base_mask) >> base_shift,
+ (ca * da + base_mask) >> base_shift,
+ cover);
}
+ };
+
+ //======================================comp_adaptor_clip_to_dst_rgba_pre
+ template<class BlenderPre> struct comp_adaptor_clip_to_dst_rgba_pre
+ {
+ typedef typename BlenderPre::order_type order_type;
+ typedef typename BlenderPre::color_type color_type;
+ typedef typename color_type::value_type value_type;
+ enum base_scale_e
+ {
+ base_shift = color_type::base_shift,
+ base_mask = color_type::base_mask
+ };
+
+ static AGG_INLINE void blend_pix(unsigned op, value_type* p,
+ unsigned cr, unsigned cg, unsigned cb,
+ unsigned ca,
+ unsigned cover)
+ {
+ unsigned da = p[order_type::A];
+ BlenderPre::blend_pix(p,
+ (cr * da + base_mask) >> base_shift,
+ (cg * da + base_mask) >> base_shift,
+ (cb * da + base_mask) >> base_shift,
+ (ca * da + base_mask) >> base_shift,
+ cover);
+ }
+ };
+
+
+
+
+
+
+ //===============================================copy_or_blend_rgba_wrapper
+ template<class Blender> struct copy_or_blend_rgba_wrapper
+ {
+ typedef typename Blender::color_type color_type;
+ typedef typename Blender::order_type order_type;
+ typedef typename color_type::value_type value_type;
+ typedef typename color_type::calc_type calc_type;
+ enum base_scale_e
+ {
+ base_shift = color_type::base_shift,
+ base_scale = color_type::base_scale,
+ base_mask = color_type::base_mask
+ };
//--------------------------------------------------------------------
static AGG_INLINE void copy_or_blend_pix(value_type* p,
- const color_type& c,
- unsigned cover)
+ unsigned cr, unsigned cg, unsigned cb,
+ unsigned alpha)
{
- if (c.a)
+ if(alpha)
{
- calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8;
if(alpha == base_mask)
{
- p[order_type::R] = c.r;
- p[order_type::G] = c.g;
- p[order_type::B] = c.b;
- p[order_type::A] = c.a;
+ p[order_type::R] = cr;
+ p[order_type::G] = cg;
+ p[order_type::B] = cb;
+ p[order_type::A] = base_mask;
}
else
{
- Blender::blend_pix(p, c.r, c.g, c.b, alpha, cover);
+ Blender::blend_pix(p, cr, cg, cb, alpha);
}
}
}
//--------------------------------------------------------------------
- static AGG_INLINE void copy_or_blend_opaque_pix(value_type* p,
- const color_type& c,
- unsigned cover)
+ static AGG_INLINE void copy_or_blend_pix(value_type* p,
+ unsigned cr, unsigned cg, unsigned cb,
+ unsigned alpha,
+ unsigned cover)
{
if(cover == 255)
{
- p[order_type::R] = c.r;
- p[order_type::G] = c.g;
- p[order_type::B] = c.b;
- p[order_type::A] = base_mask;
+ copy_or_blend_pix(p, cr, cg, cb, alpha);
}
else
{
- Blender::blend_pix(p, c.r, c.g, c.b, (cover + 1) << (base_shift - 8), cover);
+ if(alpha)
+ {
+ alpha = (alpha * (cover + 1)) >> 8;
+ if(alpha == base_mask)
+ {
+ p[order_type::R] = cr;
+ p[order_type::G] = cg;
+ p[order_type::B] = cb;
+ p[order_type::A] = base_mask;
+ }
+ else
+ {
+ Blender::blend_pix(p, cr, cg, cb, alpha, cover);
+ }
+ }
}
}
};
@@ -281,55 +1746,102 @@ namespace agg
- //=======================================================pixel_formats_rgba
- template<class Blender> class pixel_formats_rgba
+
+
+ //=================================================pixfmt_alpha_blend_rgba
+ template<class Blender, class RenBuf, class PixelT = int32u>
+ class pixfmt_alpha_blend_rgba
{
public:
- typedef rendering_buffer::row_data row_data;
- typedef typename Blender::color_type color_type;
- typedef typename Blender::order_type order_type;
- typedef typename Blender::pixel_type pixel_type;
+ typedef RenBuf rbuf_type;
+ typedef typename rbuf_type::row_data row_data;
+ typedef PixelT pixel_type;
+ typedef Blender blender_type;
+ typedef typename blender_type::color_type color_type;
+ typedef typename blender_type::order_type order_type;
typedef typename color_type::value_type value_type;
typedef typename color_type::calc_type calc_type;
- typedef blender_rgba_wrapper<Blender> blender_type;
- enum
+ typedef copy_or_blend_rgba_wrapper<blender_type> cob_type;
+ enum base_scale_e
{
base_shift = color_type::base_shift,
- base_size = color_type::base_size,
- base_mask = color_type::base_mask
+ base_scale = color_type::base_scale,
+ base_mask = color_type::base_mask,
+ pix_width = sizeof(pixel_type)
};
//--------------------------------------------------------------------
- pixel_formats_rgba(rendering_buffer& rb) :
- m_rbuf(&rb)
- {}
+ pixfmt_alpha_blend_rgba() : m_rbuf(0) {}
+ explicit pixfmt_alpha_blend_rgba(rbuf_type& rb) : m_rbuf(&rb) {}
+ void attach(rbuf_type& rb) { m_rbuf = &rb; }
+
+ //--------------------------------------------------------------------
+ template<class PixFmt>
+ bool attach(PixFmt& pixf, int x1, int y1, int x2, int y2)
+ {
+ rect_i r(x1, y1, x2, y2);
+ if(r.clip(rect_i(0, 0, pixf.width()-1, pixf.height()-1)))
+ {
+ int stride = pixf.stride();
+ m_rbuf->attach(pixf.pix_ptr(r.x1, stride < 0 ? r.y2 : r.y1),
+ (r.x2 - r.x1) + 1,
+ (r.y2 - r.y1) + 1,
+ stride);
+ return true;
+ }
+ return false;
+ }
//--------------------------------------------------------------------
AGG_INLINE unsigned width() const { return m_rbuf->width(); }
AGG_INLINE unsigned height() const { return m_rbuf->height(); }
+ AGG_INLINE int stride() const { return m_rbuf->stride(); }
//--------------------------------------------------------------------
- AGG_INLINE color_type pixel(int x, int y) const
+ AGG_INLINE int8u* row_ptr(int y) { return m_rbuf->row_ptr(y); }
+ AGG_INLINE const int8u* row_ptr(int y) const { return m_rbuf->row_ptr(y); }
+ AGG_INLINE row_data row(int y) const { return m_rbuf->row(y); }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE int8u* pix_ptr(int x, int y)
{
- const value_type* p = (value_type*)m_rbuf->row(y) + (x << 2);
- return color_type(p[order_type::R],
- p[order_type::G],
- p[order_type::B],
- p[order_type::A]);
+ return m_rbuf->row_ptr(y) + x * pix_width;
+ }
+
+ AGG_INLINE const int8u* pix_ptr(int x, int y) const
+ {
+ return m_rbuf->row_ptr(y) + x * pix_width;
+ }
+
+
+ //--------------------------------------------------------------------
+ AGG_INLINE static void make_pix(int8u* p, const color_type& c)
+ {
+ ((value_type*)p)[order_type::R] = c.r;
+ ((value_type*)p)[order_type::G] = c.g;
+ ((value_type*)p)[order_type::B] = c.b;
+ ((value_type*)p)[order_type::A] = c.a;
}
//--------------------------------------------------------------------
- row_data span(int x, int y) const
+ AGG_INLINE color_type pixel(int x, int y) const
{
- return row_data(x,
- width() - 1,
- m_rbuf->row(y) + x * 4 * sizeof(value_type));
+ const value_type* p = (const value_type*)m_rbuf->row_ptr(y);
+ if(p)
+ {
+ p += x << 2;
+ return color_type(p[order_type::R],
+ p[order_type::G],
+ p[order_type::B],
+ p[order_type::A]);
+ }
+ return color_type::no_color();
}
//--------------------------------------------------------------------
AGG_INLINE void copy_pixel(int x, int y, const color_type& c)
{
- value_type* p = (value_type*)m_rbuf->row(y) + (x << 2);
+ value_type* p = (value_type*)m_rbuf->row_ptr(x, y, 1) + (x << 2);
p[order_type::R] = c.r;
p[order_type::G] = c.g;
p[order_type::B] = c.b;
@@ -339,7 +1851,10 @@ namespace agg
//--------------------------------------------------------------------
AGG_INLINE void blend_pixel(int x, int y, const color_type& c, int8u cover)
{
- blender_type::copy_or_blend_pix((value_type*)m_rbuf->row(y) + (x << 2), c, cover);
+ cob_type::copy_or_blend_pix(
+ (value_type*)m_rbuf->row_ptr(x, y, 1) + (x << 2),
+ c.r, c.g, c.b, c.a,
+ cover);
}
@@ -348,7 +1863,7 @@ namespace agg
unsigned len,
const color_type& c)
{
- value_type* p = (value_type*)m_rbuf->row(y) + (x << 2);
+ value_type* p = (value_type*)m_rbuf->row_ptr(x, y, len) + (x << 2);
pixel_type v;
((value_type*)&v)[order_type::R] = c.r;
((value_type*)&v)[order_type::G] = c.g;
@@ -368,7 +1883,6 @@ namespace agg
unsigned len,
const color_type& c)
{
- value_type* p = (value_type*)m_rbuf->row(y) + (x << 2);
pixel_type v;
((value_type*)&v)[order_type::R] = c.r;
((value_type*)&v)[order_type::G] = c.g;
@@ -376,8 +1890,8 @@ namespace agg
((value_type*)&v)[order_type::A] = c.a;
do
{
+ value_type* p = (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2);
*(pixel_type*)p = v;
- p = (value_type*)m_rbuf->next_row(p);
}
while(--len);
}
@@ -391,7 +1905,7 @@ namespace agg
{
if (c.a)
{
- value_type* p = (value_type*)m_rbuf->row(y) + (x << 2);
+ value_type* p = (value_type*)m_rbuf->row_ptr(x, y, len) + (x << 2);
calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8;
if(alpha == base_mask)
{
@@ -409,12 +1923,24 @@ namespace agg
}
else
{
- do
+ if(cover == 255)
{
- blender_type::blend_pix(p, c.r, c.g, c.b, alpha, cover);
- p += 4;
+ do
+ {
+ blender_type::blend_pix(p, c.r, c.g, c.b, alpha);
+ p += 4;
+ }
+ while(--len);
+ }
+ else
+ {
+ do
+ {
+ blender_type::blend_pix(p, c.r, c.g, c.b, alpha, cover);
+ p += 4;
+ }
+ while(--len);
}
- while(--len);
}
}
}
@@ -428,7 +1954,7 @@ namespace agg
{
if (c.a)
{
- value_type* p = (value_type*)m_rbuf->row(y) + (x << 2);
+ value_type* p;
calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8;
if(alpha == base_mask)
{
@@ -439,19 +1965,31 @@ namespace agg
((value_type*)&v)[order_type::A] = c.a;
do
{
+ p = (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2);
*(pixel_type*)p = v;
- p = (value_type*)m_rbuf->next_row(p);
}
while(--len);
}
else
{
- do
+ if(cover == 255)
{
- blender_type::blend_pix(p, c.r, c.g, c.b, alpha, cover);
- p = (value_type*)m_rbuf->next_row(p);
+ do
+ {
+ p = (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2);
+ blender_type::blend_pix(p, c.r, c.g, c.b, alpha);
+ }
+ while(--len);
+ }
+ else
+ {
+ do
+ {
+ p = (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2);
+ blender_type::blend_pix(p, c.r, c.g, c.b, alpha, cover);
+ }
+ while(--len);
}
- while(--len);
}
}
}
@@ -465,7 +2003,7 @@ namespace agg
{
if (c.a)
{
- value_type* p = (value_type*)m_rbuf->row(y) + (x << 2);
+ value_type* p = (value_type*)m_rbuf->row_ptr(x, y, len) + (x << 2);
do
{
calc_type alpha = (calc_type(c.a) * (calc_type(*covers) + 1)) >> 8;
@@ -496,9 +2034,9 @@ namespace agg
{
if (c.a)
{
- value_type* p = (value_type*)m_rbuf->row(y) + (x << 2);
do
{
+ value_type* p = (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2);
calc_type alpha = (calc_type(c.a) * (calc_type(*covers) + 1)) >> 8;
if(alpha == base_mask)
{
@@ -511,7 +2049,6 @@ namespace agg
{
blender_type::blend_pix(p, c.r, c.g, c.b, alpha, *covers);
}
- p = (value_type*)m_rbuf->next_row(p);
++covers;
}
while(--len);
@@ -520,124 +2057,62 @@ namespace agg
//--------------------------------------------------------------------
- void blend_color_hspan(int x, int y,
- unsigned len,
- const color_type* colors,
- const int8u* covers,
- int8u cover)
+ void copy_color_hspan(int x, int y,
+ unsigned len,
+ const color_type* colors)
{
- value_type* p = (value_type*)m_rbuf->row(y) + (x << 2);
- if(covers)
- {
- do
- {
- blender_type::copy_or_blend_pix(p, *colors++, *covers++);
- p += 4;
- }
- while(--len);
- }
- else
+ value_type* p = (value_type*)m_rbuf->row_ptr(x, y, len) + (x << 2);
+ do
{
- if(cover == 255)
- {
- do
- {
- if(colors->a == base_mask)
- {
- p[order_type::R] = colors->r;
- p[order_type::G] = colors->g;
- p[order_type::B] = colors->b;
- p[order_type::A] = base_mask;
- }
- else
- {
- blender_type::copy_or_blend_pix(p, *colors, 255);
- }
- p += 4;
- ++colors;
- }
- while(--len);
- }
- else
- {
- do
- {
- blender_type::copy_or_blend_pix(p, *colors++, cover);
- p += 4;
- }
- while(--len);
- }
+ p[order_type::R] = colors->r;
+ p[order_type::G] = colors->g;
+ p[order_type::B] = colors->b;
+ p[order_type::A] = colors->a;
+ ++colors;
+ p += 4;
}
+ while(--len);
}
-
//--------------------------------------------------------------------
- void blend_color_vspan(int x, int y,
- unsigned len,
- const color_type* colors,
- const int8u* covers,
- int8u cover)
+ void copy_color_vspan(int x, int y,
+ unsigned len,
+ const color_type* colors)
{
- value_type* p = (value_type*)m_rbuf->row(y) + (x << 2);
- if(covers)
- {
- do
- {
- blender_type::copy_or_blend_pix(p, *colors++, *covers++);
- p = (value_type*)m_rbuf->next_row(p);
- }
- while(--len);
- }
- else
+ do
{
- if(cover == 255)
- {
- do
- {
- if(colors->a == base_mask)
- {
- p[order_type::R] = colors->r;
- p[order_type::G] = colors->g;
- p[order_type::B] = colors->b;
- p[order_type::A] = base_mask;
- }
- else
- {
- blender_type::copy_or_blend_pix(p, *colors, 255);
- }
- p = (value_type*)m_rbuf->next_row(p);
- ++colors;
- }
- while(--len);
- }
- else
- {
- do
- {
- blender_type::copy_or_blend_pix(p, *colors++, cover);
- p = (value_type*)m_rbuf->next_row(p);
- }
- while(--len);
- }
+ value_type* p = (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2);
+ p[order_type::R] = colors->r;
+ p[order_type::G] = colors->g;
+ p[order_type::B] = colors->b;
+ p[order_type::A] = colors->a;
+ ++colors;
}
+ while(--len);
}
//--------------------------------------------------------------------
- void blend_opaque_color_hspan(int x, int y,
- unsigned len,
- const color_type* colors,
- const int8u* covers,
- int8u cover)
+ void blend_color_hspan(int x, int y,
+ unsigned len,
+ const color_type* colors,
+ const int8u* covers,
+ int8u cover)
{
- value_type* p = (value_type*)m_rbuf->row(y) + (x << 2);
+ value_type* p = (value_type*)m_rbuf->row_ptr(x, y, len) + (x << 2);
if(covers)
{
do
{
- blender_type::copy_or_blend_opaque_pix(p, *colors++, *covers++);
+ cob_type::copy_or_blend_pix(p,
+ colors->r,
+ colors->g,
+ colors->b,
+ colors->a,
+ *covers++);
p += 4;
+ ++colors;
}
while(--len);
}
@@ -647,10 +2122,11 @@ namespace agg
{
do
{
- p[order_type::R] = colors->r;
- p[order_type::G] = colors->g;
- p[order_type::B] = colors->b;
- p[order_type::A] = base_mask;
+ cob_type::copy_or_blend_pix(p,
+ colors->r,
+ colors->g,
+ colors->b,
+ colors->a);
p += 4;
++colors;
}
@@ -660,8 +2136,14 @@ namespace agg
{
do
{
- blender_type::copy_or_blend_opaque_pix(p, *colors++, cover);
+ cob_type::copy_or_blend_pix(p,
+ colors->r,
+ colors->g,
+ colors->b,
+ colors->a,
+ cover);
p += 4;
+ ++colors;
}
while(--len);
}
@@ -669,20 +2151,27 @@ namespace agg
}
+
//--------------------------------------------------------------------
- void blend_opaque_color_vspan(int x, int y,
- unsigned len,
- const color_type* colors,
- const int8u* covers,
- int8u cover)
+ void blend_color_vspan(int x, int y,
+ unsigned len,
+ const color_type* colors,
+ const int8u* covers,
+ int8u cover)
{
- value_type* p = (value_type*)m_rbuf->row(y) + (x << 2);
+ value_type* p;
if(covers)
{
do
{
- blender_type::copy_or_blend_opaque_pix(p, *colors++, *covers++);
- p = (value_type*)m_rbuf->next_row(p);
+ p = (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2);
+ cob_type::copy_or_blend_pix(p,
+ colors->r,
+ colors->g,
+ colors->b,
+ colors->a,
+ *covers++);
+ ++colors;
}
while(--len);
}
@@ -692,11 +2181,12 @@ namespace agg
{
do
{
- p[order_type::R] = colors->r;
- p[order_type::G] = colors->g;
- p[order_type::B] = colors->b;
- p[order_type::A] = base_mask;
- p = (value_type*)m_rbuf->next_row(p);
+ p = (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2);
+ cob_type::copy_or_blend_pix(p,
+ colors->r,
+ colors->g,
+ colors->b,
+ colors->a);
++colors;
}
while(--len);
@@ -705,29 +2195,39 @@ namespace agg
{
do
{
- blender_type::copy_or_blend_opaque_pix(p, *colors++, cover);
- p = (value_type*)m_rbuf->next_row(p);
+ p = (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2);
+ cob_type::copy_or_blend_pix(p,
+ colors->r,
+ colors->g,
+ colors->b,
+ colors->a,
+ cover);
+ ++colors;
}
while(--len);
}
}
}
-
//--------------------------------------------------------------------
template<class Function> void for_each_pixel(Function f)
{
unsigned y;
for(y = 0; y < height(); ++y)
{
- unsigned len = width();
- value_type* p = (value_type*)m_rbuf->row(y);
- do
+ row_data r = m_rbuf->row(y);
+ if(r.ptr)
{
- f(p);
- p += 4;
+ unsigned len = r.x2 - r.x1 + 1;
+ value_type* p =
+ (value_type*)m_rbuf->row_ptr(r.x1, y, len) + (r.x1 << 2);
+ do
+ {
+ f(p);
+ p += 4;
+ }
+ while(--len);
}
- while(--len);
}
}
@@ -756,144 +2256,268 @@ namespace agg
}
//--------------------------------------------------------------------
- void copy_from(const rendering_buffer& from,
- int xdst, int ydst,
- int xsrc, int ysrc,
- unsigned len)
+ template<class RenBuf2> void copy_from(const RenBuf2& from,
+ int xdst, int ydst,
+ int xsrc, int ysrc,
+ unsigned len)
{
- memmove((value_type*)m_rbuf->row(ydst) + xdst * 4,
- (value_type*)from.row(ysrc) + xsrc * 4,
- sizeof(value_type) * 4 * len);
+ const int8u* p = from.row_ptr(ysrc);
+ if(p)
+ {
+ memmove(m_rbuf->row_ptr(xdst, ydst, len) + xdst * pix_width,
+ p + xsrc * pix_width,
+ len * pix_width);
+ }
}
-
//--------------------------------------------------------------------
template<class SrcPixelFormatRenderer>
void blend_from(const SrcPixelFormatRenderer& from,
- const int8u* psrc_,
int xdst, int ydst,
int xsrc, int ysrc,
- unsigned len)
+ unsigned len,
+ int8u cover)
{
typedef typename SrcPixelFormatRenderer::order_type src_order;
+ const value_type* psrc = (value_type*)from.row_ptr(ysrc);
+ if(psrc)
+ {
+ psrc += xsrc << 2;
+ value_type* pdst =
+ (value_type*)m_rbuf->row_ptr(xdst, ydst, len) + (xdst << 2);
+ int incp = 4;
+ if(xdst > xsrc)
+ {
+ psrc += (len-1) << 2;
+ pdst += (len-1) << 2;
+ incp = -4;
+ }
- const value_type* psrc = (const value_type*)psrc_;
- value_type* pdst = (value_type*)m_rbuf->row(ydst) + (xdst << 2);
- int incp = 4;
- if(xdst > xsrc)
+ if(cover == 255)
+ {
+ do
+ {
+ cob_type::copy_or_blend_pix(pdst,
+ psrc[src_order::R],
+ psrc[src_order::G],
+ psrc[src_order::B],
+ psrc[src_order::A]);
+ psrc += incp;
+ pdst += incp;
+ }
+ while(--len);
+ }
+ else
+ {
+ do
+ {
+ cob_type::copy_or_blend_pix(pdst,
+ psrc[src_order::R],
+ psrc[src_order::G],
+ psrc[src_order::B],
+ psrc[src_order::A],
+ cover);
+ psrc += incp;
+ pdst += incp;
+ }
+ while(--len);
+ }
+ }
+ }
+
+ //--------------------------------------------------------------------
+ template<class SrcPixelFormatRenderer>
+ void blend_from_color(const SrcPixelFormatRenderer& from,
+ const color_type& color,
+ int xdst, int ydst,
+ int xsrc, int ysrc,
+ unsigned len,
+ int8u cover)
+ {
+ typedef typename SrcPixelFormatRenderer::value_type src_value_type;
+ const src_value_type* psrc = (src_value_type*)from.row_ptr(ysrc);
+ if(psrc)
{
- psrc += (len-1) << 2;
- pdst += (len-1) << 2;
- incp = -4;
+ value_type* pdst =
+ (value_type*)m_rbuf->row_ptr(xdst, ydst, len) + (xdst << 2);
+ do
+ {
+ cob_type::copy_or_blend_pix(pdst,
+ color.r, color.g, color.b, color.a,
+ (*psrc * cover + base_mask) >> base_shift);
+ ++psrc;
+ pdst += 4;
+ }
+ while(--len);
}
- do
+ }
+
+ //--------------------------------------------------------------------
+ template<class SrcPixelFormatRenderer>
+ void blend_from_lut(const SrcPixelFormatRenderer& from,
+ const color_type* color_lut,
+ int xdst, int ydst,
+ int xsrc, int ysrc,
+ unsigned len,
+ int8u cover)
+ {
+ typedef typename SrcPixelFormatRenderer::value_type src_value_type;
+ const src_value_type* psrc = (src_value_type*)from.row_ptr(ysrc);
+ if(psrc)
{
- value_type alpha = psrc[src_order::A];
+ value_type* pdst =
+ (value_type*)m_rbuf->row_ptr(xdst, ydst, len) + (xdst << 2);
- if(alpha)
+ if(cover == 255)
{
- if(alpha == base_mask)
+ do
{
- pdst[order_type::R] = psrc[src_order::R];
- pdst[order_type::G] = psrc[src_order::G];
- pdst[order_type::B] = psrc[src_order::B];
- pdst[order_type::A] = psrc[src_order::A];
+ const color_type& color = color_lut[*psrc];
+ cob_type::copy_or_blend_pix(pdst,
+ color.r, color.g, color.b, color.a);
+ ++psrc;
+ pdst += 4;
}
- else
+ while(--len);
+ }
+ else
+ {
+ do
{
- blender_type::blend_pix(pdst,
- psrc[src_order::R],
- psrc[src_order::G],
- psrc[src_order::B],
- alpha,
- 255);
+ const color_type& color = color_lut[*psrc];
+ cob_type::copy_or_blend_pix(pdst,
+ color.r, color.g, color.b, color.a,
+ cover);
+ ++psrc;
+ pdst += 4;
}
+ while(--len);
}
- psrc += incp;
- pdst += incp;
}
- while(--len);
}
private:
- rendering_buffer* m_rbuf;
+ rbuf_type* m_rbuf;
};
- //================================================pixfmt_custom_rbuf_rgba
- template<class Blender, class RenBuf> class pixfmt_custom_rbuf_rgba
+ //================================================pixfmt_custom_blend_rgba
+ template<class Blender, class RenBuf> class pixfmt_custom_blend_rgba
{
public:
- typedef typename Blender::color_type color_type;
- typedef typename Blender::order_type order_type;
- typedef typename Blender::pixel_type pixel_type;
+ typedef RenBuf rbuf_type;
+ typedef typename rbuf_type::row_data row_data;
+ typedef Blender blender_type;
+ typedef typename blender_type::color_type color_type;
+ typedef typename blender_type::order_type order_type;
typedef typename color_type::value_type value_type;
typedef typename color_type::calc_type calc_type;
- typedef blender_rgba_wrapper<Blender> blender_type;
- enum
+ enum base_scale_e
{
base_shift = color_type::base_shift,
- base_size = color_type::base_size,
- base_mask = color_type::base_mask
+ base_scale = color_type::base_scale,
+ base_mask = color_type::base_mask,
+ pix_width = sizeof(value_type) * 4
};
- typedef RenBuf rbuf_type;
- typedef typename rbuf_type::row_data row_data;
//--------------------------------------------------------------------
- pixfmt_custom_rbuf_rgba(rbuf_type& rb) : m_rbuf(&rb) {}
+ pixfmt_custom_blend_rgba() : m_rbuf(0), m_comp_op(3) {}
+ explicit pixfmt_custom_blend_rgba(rbuf_type& rb, unsigned comp_op=3) :
+ m_rbuf(&rb),
+ m_comp_op(comp_op)
+ {}
+ void attach(rbuf_type& rb) { m_rbuf = &rb; }
//--------------------------------------------------------------------
- unsigned width() const { return m_rbuf->width(); }
- unsigned height() const { return m_rbuf->height(); }
+ template<class PixFmt>
+ bool attach(PixFmt& pixf, int x1, int y1, int x2, int y2)
+ {
+ rect_i r(x1, y1, x2, y2);
+ if(r.clip(rect_i(0, 0, pixf.width()-1, pixf.height()-1)))
+ {
+ int stride = pixf.stride();
+ m_rbuf->attach(pixf.pix_ptr(r.x1, stride < 0 ? r.y2 : r.y1),
+ (r.x2 - r.x1) + 1,
+ (r.y2 - r.y1) + 1,
+ stride);
+ return true;
+ }
+ return false;
+ }
//--------------------------------------------------------------------
- color_type pixel(int x, int y) const
+ AGG_INLINE unsigned width() const { return m_rbuf->width(); }
+ AGG_INLINE unsigned height() const { return m_rbuf->height(); }
+ AGG_INLINE int stride() const { return m_rbuf->stride(); }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE int8u* row_ptr(int y) { return m_rbuf->row_ptr(y); }
+ AGG_INLINE const int8u* row_ptr(int y) const { return m_rbuf->row_ptr(y); }
+ AGG_INLINE row_data row(int y) const { return m_rbuf->row(y); }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE int8u* pix_ptr(int x, int y)
{
- const value_type* p = m_rbuf->span_ptr(x, y, 1);
- return p ? color_type(p[order_type::R],
- p[order_type::G],
- p[order_type::B],
- p[order_type::A]) :
- color_type::no_color();
+ return m_rbuf->row_ptr(y) + x * pix_width;
+ }
+
+ AGG_INLINE const int8u* pix_ptr(int x, int y) const
+ {
+ return m_rbuf->row_ptr(y) + x * pix_width;
}
//--------------------------------------------------------------------
- row_data span(int x, int y) const
+ void comp_op(unsigned op) { m_comp_op = op; }
+ unsigned comp_op() const { return m_comp_op; }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE static void make_pix(int8u* p, const color_type& c)
+ {
+ ((value_type*)p)[order_type::R] = c.r;
+ ((value_type*)p)[order_type::G] = c.g;
+ ((value_type*)p)[order_type::B] = c.b;
+ ((value_type*)p)[order_type::A] = c.a;
+ }
+
+ //--------------------------------------------------------------------
+ color_type pixel(int x, int y) const
{
- return m_rbuf->span(x, y);
+ const value_type* p = (value_type*)m_rbuf->row_ptr(y) + (x << 2);
+ return color_type(p[order_type::R],
+ p[order_type::G],
+ p[order_type::B],
+ p[order_type::A]);
}
//--------------------------------------------------------------------
void copy_pixel(int x, int y, const color_type& c)
{
- int8u* p = m_rbuf->span_ptr(x, y, 1);
- p[order_type::R] = c.r;
- p[order_type::G] = c.g;
- p[order_type::B] = c.b;
- p[order_type::A] = c.b;
+ blender_type::blend_pix(
+ m_comp_op,
+ (value_type*)m_rbuf->row_ptr(x, y, 1) + (x << 2),
+ c.r, c.g, c.b, c.a, 255);
}
//--------------------------------------------------------------------
void blend_pixel(int x, int y, const color_type& c, int8u cover)
{
- blender_type::copy_or_blend_pix((value_type*)m_rbuf->span_ptr(x, y, 1), c, cover);
+ blender_type::blend_pix(
+ m_comp_op,
+ (value_type*)m_rbuf->row_ptr(x, y, 1) + (x << 2),
+ c.r, c.g, c.b, c.a,
+ cover);
}
//--------------------------------------------------------------------
void copy_hline(int x, int y, unsigned len, const color_type& c)
{
- value_type* p = (value_type*)m_rbuf->span_ptr(x, y, len);
- pixel_type v;
- ((value_type*)&v)[order_type::R] = c.r;
- ((value_type*)&v)[order_type::G] = c.g;
- ((value_type*)&v)[order_type::B] = c.b;
- ((value_type*)&v)[order_type::A] = c.a;
+ value_type* p = (value_type*)m_rbuf->row_ptr(x, y, len) + (x << 2);;
do
{
- *(pixel_type*)p = v;
+ blender_type::blend_pix(m_comp_op, p, c.r, c.g, c.b, c.a, 255);
p += 4;
}
while(--len);
@@ -902,14 +2526,12 @@ namespace agg
//--------------------------------------------------------------------
void copy_vline(int x, int y, unsigned len, const color_type& c)
{
- pixel_type v;
- ((value_type*)&v)[order_type::R] = c.r;
- ((value_type*)&v)[order_type::G] = c.g;
- ((value_type*)&v)[order_type::B] = c.b;
- ((value_type*)&v)[order_type::A] = c.a;
do
{
- *(pixel_type*)(m_rbuf->span_ptr(x, y++, 1)) = v;
+ blender_type::blend_pix(
+ m_comp_op,
+ (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2),
+ c.r, c.g, c.b, c.a, 255);
}
while(--len);
}
@@ -918,218 +2540,141 @@ namespace agg
void blend_hline(int x, int y, unsigned len,
const color_type& c, int8u cover)
{
- if (c.a)
+
+ value_type* p = (value_type*)m_rbuf->row_ptr(x, y, len) + (x << 2);
+ do
{
- value_type* p = (value_type*)m_rbuf->span_ptr(x, y, len);
- calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8;
- if(alpha == base_mask)
- {
- pixel_type v;
- ((value_type*)&v)[order_type::R] = c.r;
- ((value_type*)&v)[order_type::G] = c.g;
- ((value_type*)&v)[order_type::B] = c.b;
- ((value_type*)&v)[order_type::A] = c.a;
- do
- {
- *(pixel_type*)p = v;
- p += 4;
- }
- while(--len);
- }
- else
- {
- do
- {
- blender_type::blend_pix(p, c.r, c.g, c.b, alpha, cover);
- p += 4;
- }
- while(--len);
- }
+ blender_type::blend_pix(m_comp_op, p, c.r, c.g, c.b, c.a, cover);
+ p += 4;
}
+ while(--len);
}
//--------------------------------------------------------------------
void blend_vline(int x, int y, unsigned len,
const color_type& c, int8u cover)
{
- if (c.a)
+
+ do
{
- calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8;
- if(alpha == base_mask)
- {
- pixel_type v;
- ((value_type*)&v)[order_type::R] = c.r;
- ((value_type*)&v)[order_type::G] = c.g;
- ((value_type*)&v)[order_type::B] = c.b;
- ((value_type*)&v)[order_type::A] = c.a;
- do
- {
- *(pixel_type*)(m_rbuf->span_ptr(x, y++, 1)) = v;
- }
- while(--len);
- }
- else
- {
- do
- {
- blender_type::blend_pix(*(pixel_type*)m_rbuf->span_ptr(x, y++, 1),
- c.r, c.g, c.b, alpha, cover);
- }
- while(--len);
- }
+ blender_type::blend_pix(
+ m_comp_op,
+ (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2),
+ c.r, c.g, c.b, c.a,
+ cover);
}
+ while(--len);
}
-
//--------------------------------------------------------------------
void blend_solid_hspan(int x, int y, unsigned len,
const color_type& c, const int8u* covers)
{
- value_type* p = (value_type*)m_rbuf->span_ptr(x, y, len);
+ value_type* p = (value_type*)m_rbuf->row_ptr(x, y, len) + (x << 2);
do
{
- blender_type::copy_or_blend_pix(p, c, *covers++);
+ blender_type::blend_pix(m_comp_op,
+ p, c.r, c.g, c.b, c.a,
+ *covers++);
p += 4;
}
while(--len);
}
-
-
//--------------------------------------------------------------------
void blend_solid_vspan(int x, int y, unsigned len,
const color_type& c, const int8u* covers)
{
do
{
- blender_type::copy_or_blend_pix((value_type*)m_rbuf->span_ptr(x, y++, 1),
- c,
- *covers++);
+ blender_type::blend_pix(
+ m_comp_op,
+ (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2),
+ c.r, c.g, c.b, c.a,
+ *covers++);
}
while(--len);
}
-
//--------------------------------------------------------------------
- void blend_color_hspan(int x, int y, unsigned len,
- const color_type* colors,
- const int8u* covers,
- int8u cover)
+ void copy_color_hspan(int x, int y,
+ unsigned len,
+ const color_type* colors)
{
- value_type* p = (value_type*)m_rbuf->span_ptr(x, y, len);
+
+ value_type* p = (value_type*)m_rbuf->row_ptr(x, y, len) + (x << 2);
do
{
- blender_type::copy_or_blend_pix(p, *colors++, covers ? *covers++ : cover);
+ p[order_type::R] = colors->r;
+ p[order_type::G] = colors->g;
+ p[order_type::B] = colors->b;
+ p[order_type::A] = colors->a;
+ ++colors;
p += 4;
}
while(--len);
}
-
//--------------------------------------------------------------------
- void blend_color_vspan(int x, int y, unsigned len,
- const color_type* colors,
- const int8u* covers,
- int8u cover)
+ void copy_color_vspan(int x, int y,
+ unsigned len,
+ const color_type* colors)
{
do
{
- blender_type::copy_or_blend_pix((value_type*)m_rbuf->span_ptr(x, y++, 1),
- *colors++, covers ? *covers++ : cover);
+ value_type* p = (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2);
+ p[order_type::R] = colors->r;
+ p[order_type::G] = colors->g;
+ p[order_type::B] = colors->b;
+ p[order_type::A] = colors->a;
+ ++colors;
}
while(--len);
}
-
//--------------------------------------------------------------------
- void blend_opaque_color_hspan(int x, int y,
- unsigned len,
- const color_type* colors,
- const int8u* covers,
- int8u cover)
+ void blend_color_hspan(int x, int y, unsigned len,
+ const color_type* colors,
+ const int8u* covers,
+ int8u cover)
{
- value_type* p = (value_type*)m_rbuf->span_ptr(x, y, len);
- if(covers)
- {
- do
- {
- blender_type::copy_or_blend_opaque_pix(p, *colors++, *covers++);
- p += 4;
- }
- while(--len);
- }
- else
+ value_type* p = (value_type*)m_rbuf->row_ptr(x, y, len) + (x << 2);
+ do
{
- if(cover == 255)
- {
- do
- {
- p[order_type::R] = colors->r;
- p[order_type::G] = colors->g;
- p[order_type::B] = colors->b;
- p[order_type::A] = base_mask;
- p += 4;
- ++colors;
- }
- while(--len);
- }
- else
- {
- do
- {
- blender_type::copy_or_blend_opaque_pix(p, *colors++, cover);
- p += 4;
- }
- while(--len);
- }
+ blender_type::blend_pix(m_comp_op,
+ p,
+ colors->r,
+ colors->g,
+ colors->b,
+ colors->a,
+ covers ? *covers++ : cover);
+ p += 4;
+ ++colors;
}
+ while(--len);
}
-
//--------------------------------------------------------------------
- void blend_opaque_color_vspan(int x, int y,
- unsigned len,
- const color_type* colors,
- const int8u* covers,
- int8u cover)
+ void blend_color_vspan(int x, int y, unsigned len,
+ const color_type* colors,
+ const int8u* covers,
+ int8u cover)
{
- if(covers)
- {
- do
- {
- blender_type::copy_or_blend_opaque_pix((value_type*)m_rbuf->span_ptr(x, y++, 1),
- *colors++, *covers++);
- }
- while(--len);
- }
- else
+ do
{
- if(cover == 255)
- {
- do
- {
- value_type* p = (value_type*)m_rbuf->span_ptr(x, y++, 1);
- p[order_type::R] = colors->r;
- p[order_type::G] = colors->g;
- p[order_type::B] = colors->b;
- p[order_type::A] = base_mask;
- ++colors;
- }
- while(--len);
- }
- else
- {
- do
- {
- blender_type::copy_or_blend_opaque_pix((value_type*)m_rbuf->span_ptr(x, y++, 1),
- *colors++, cover);
- }
- while(--len);
- }
+ blender_type::blend_pix(
+ m_comp_op,
+ (value_type*)m_rbuf->row_ptr(x, y++, 1) + (x << 2),
+ colors->r,
+ colors->g,
+ colors->b,
+ colors->a,
+ covers ? *covers++ : cover);
+ ++colors;
}
- }
-
+ while(--len);
+ }
//--------------------------------------------------------------------
template<class Function> void for_each_pixel(Function f)
@@ -1137,21 +2682,22 @@ namespace agg
unsigned y;
for(y = 0; y < height(); ++y)
{
- row_data sp = span(0, y);
- if(sp.ptr)
+ row_data r = m_rbuf->row(y);
+ if(r.ptr)
{
- value_type* p = (value_type*)sp.ptr;
- while(sp.x1 <= sp.x2)
+ unsigned len = r.x2 - r.x1 + 1;
+ value_type* p =
+ (value_type*)m_rbuf->row_ptr(r.x1, y, len) + (r.x1 << 2);
+ do
{
f(p);
p += 4;
- ++sp.x1;
}
+ while(--len);
}
}
}
-
//--------------------------------------------------------------------
void premultiply()
{
@@ -1182,130 +2728,174 @@ namespace agg
int xsrc, int ysrc,
unsigned len)
{
- const int8u* p = from.row(ysrc);
+ const int8u* p = from.row_ptr(ysrc);
if(p)
{
- p += xsrc * 4 * sizeof(value_type);
- memmove(m_rbuf->span_ptr(xdst, ydst, len),
- p,
- len * 4 * sizeof(value_type));
+ memmove(m_rbuf->row_ptr(xdst, ydst, len) + xdst * pix_width,
+ p + xsrc * pix_width,
+ len * pix_width);
}
}
-
-
//--------------------------------------------------------------------
template<class SrcPixelFormatRenderer>
void blend_from(const SrcPixelFormatRenderer& from,
- const int8u* psrc_,
int xdst, int ydst,
int xsrc, int ysrc,
- unsigned len)
+ unsigned len,
+ int8u cover)
{
typedef typename SrcPixelFormatRenderer::order_type src_order;
- const value_type* psrc = (const value_type*)psrc_;
- value_type* pdst = (value_type*)m_rbuf->span_ptr(xdst, ydst, len);
-
- int incp = 4;
- if(xdst > xsrc)
+ const value_type* psrc = (const value_type*)from.row_ptr(ysrc);
+ if(psrc)
{
- psrc += (len-1) << 2;
- pdst += (len-1) << 2;
- incp = -4;
+ psrc += xsrc << 2;
+ value_type* pdst =
+ (value_type*)m_rbuf->row_ptr(xdst, ydst, len) + (xdst << 2);
+
+ int incp = 4;
+ if(xdst > xsrc)
+ {
+ psrc += (len-1) << 2;
+ pdst += (len-1) << 2;
+ incp = -4;
+ }
+
+ do
+ {
+ blender_type::blend_pix(m_comp_op,
+ pdst,
+ psrc[src_order::R],
+ psrc[src_order::G],
+ psrc[src_order::B],
+ psrc[src_order::A],
+ cover);
+ psrc += incp;
+ pdst += incp;
+ }
+ while(--len);
}
- do
- {
- value_type alpha = psrc[src_order::A];
+ }
- if(alpha)
+ //--------------------------------------------------------------------
+ template<class SrcPixelFormatRenderer>
+ void blend_from_color(const SrcPixelFormatRenderer& from,
+ const color_type& color,
+ int xdst, int ydst,
+ int xsrc, int ysrc,
+ unsigned len,
+ int8u cover)
+ {
+ typedef typename SrcPixelFormatRenderer::value_type src_value_type;
+ const src_value_type* psrc = (src_value_type*)from.row_ptr(ysrc);
+ if(psrc)
+ {
+ value_type* pdst =
+ (value_type*)m_rbuf->row_ptr(xdst, ydst, len) + (xdst << 2);
+ do
{
- if(alpha == base_mask)
- {
- pdst[order_type::R] = psrc[src_order::R];
- pdst[order_type::G] = psrc[src_order::G];
- pdst[order_type::B] = psrc[src_order::B];
- pdst[order_type::A] = psrc[src_order::A];
- }
- else
- {
- blender_type::blend_pix(pdst,
- psrc[src_order::R],
- psrc[src_order::G],
- psrc[src_order::B],
- alpha,
- 255);
- }
+ blender_type::blend_pix(m_comp_op,
+ pdst,
+ color.r, color.g, color.b, color.a,
+ (*psrc * cover + base_mask) >> base_shift);
+ ++psrc;
+ pdst += 4;
}
- psrc += incp;
- pdst += incp;
+ while(--len);
}
- while(--len);
}
+ //--------------------------------------------------------------------
+ template<class SrcPixelFormatRenderer>
+ void blend_from_lut(const SrcPixelFormatRenderer& from,
+ const color_type* color_lut,
+ int xdst, int ydst,
+ int xsrc, int ysrc,
+ unsigned len,
+ int8u cover)
+ {
+ typedef typename SrcPixelFormatRenderer::value_type src_value_type;
+ const src_value_type* psrc = (src_value_type*)from.row_ptr(ysrc);
+ if(psrc)
+ {
+ value_type* pdst =
+ (value_type*)m_rbuf->row_ptr(xdst, ydst, len) + (xdst << 2);
+ do
+ {
+ const color_type& color = color_lut[*psrc];
+ blender_type::blend_pix(m_comp_op,
+ pdst,
+ color.r, color.g, color.b, color.a,
+ cover);
+ ++psrc;
+ pdst += 4;
+ }
+ while(--len);
+ }
+ }
private:
rbuf_type* m_rbuf;
+ unsigned m_comp_op;
};
-
-
-
//-----------------------------------------------------------------------
- typedef blender_rgba<rgba8, order_rgba, int32u> blender_rgba32; //----blender_rgba32
- typedef blender_rgba<rgba8, order_argb, int32u> blender_argb32; //----blender_argb32
- typedef blender_rgba<rgba8, order_abgr, int32u> blender_abgr32; //----blender_abgr32
- typedef blender_rgba<rgba8, order_bgra, int32u> blender_bgra32; //----blender_bgra32
+ typedef blender_rgba<rgba8, order_rgba> blender_rgba32; //----blender_rgba32
+ typedef blender_rgba<rgba8, order_argb> blender_argb32; //----blender_argb32
+ typedef blender_rgba<rgba8, order_abgr> blender_abgr32; //----blender_abgr32
+ typedef blender_rgba<rgba8, order_bgra> blender_bgra32; //----blender_bgra32
- typedef blender_rgba_pre<rgba8, order_rgba, int32u> blender_rgba32_pre; //----blender_rgba32_pre
- typedef blender_rgba_pre<rgba8, order_argb, int32u> blender_argb32_pre; //----blender_argb32_pre
- typedef blender_rgba_pre<rgba8, order_abgr, int32u> blender_abgr32_pre; //----blender_abgr32_pre
- typedef blender_rgba_pre<rgba8, order_bgra, int32u> blender_bgra32_pre; //----blender_bgra32_pre
+ typedef blender_rgba_pre<rgba8, order_rgba> blender_rgba32_pre; //----blender_rgba32_pre
+ typedef blender_rgba_pre<rgba8, order_argb> blender_argb32_pre; //----blender_argb32_pre
+ typedef blender_rgba_pre<rgba8, order_abgr> blender_abgr32_pre; //----blender_abgr32_pre
+ typedef blender_rgba_pre<rgba8, order_bgra> blender_bgra32_pre; //----blender_bgra32_pre
- typedef blender_rgba_plain<rgba8, order_rgba, int32u> blender_rgba32_plain; //----blender_rgba32_plain
- typedef blender_rgba_plain<rgba8, order_argb, int32u> blender_argb32_plain; //----blender_argb32_plain
- typedef blender_rgba_plain<rgba8, order_abgr, int32u> blender_abgr32_plain; //----blender_abgr32_plain
- typedef blender_rgba_plain<rgba8, order_bgra, int32u> blender_bgra32_plain; //----blender_bgra32_plain
+ typedef blender_rgba_plain<rgba8, order_rgba> blender_rgba32_plain; //----blender_rgba32_plain
+ typedef blender_rgba_plain<rgba8, order_argb> blender_argb32_plain; //----blender_argb32_plain
+ typedef blender_rgba_plain<rgba8, order_abgr> blender_abgr32_plain; //----blender_abgr32_plain
+ typedef blender_rgba_plain<rgba8, order_bgra> blender_bgra32_plain; //----blender_bgra32_plain
- struct pixel64_type { int16u c[4]; };
- typedef blender_rgba<rgba16, order_rgba, pixel64_type> blender_rgba64; //----blender_rgba64
- typedef blender_rgba<rgba16, order_argb, pixel64_type> blender_argb64; //----blender_argb64
- typedef blender_rgba<rgba16, order_abgr, pixel64_type> blender_abgr64; //----blender_abgr64
- typedef blender_rgba<rgba16, order_bgra, pixel64_type> blender_bgra64; //----blender_bgra64
+ typedef blender_rgba<rgba16, order_rgba> blender_rgba64; //----blender_rgba64
+ typedef blender_rgba<rgba16, order_argb> blender_argb64; //----blender_argb64
+ typedef blender_rgba<rgba16, order_abgr> blender_abgr64; //----blender_abgr64
+ typedef blender_rgba<rgba16, order_bgra> blender_bgra64; //----blender_bgra64
- typedef blender_rgba_pre<rgba16, order_rgba, pixel64_type> blender_rgba64_pre; //----blender_rgba64_pre
- typedef blender_rgba_pre<rgba16, order_argb, pixel64_type> blender_argb64_pre; //----blender_argb64_pre
- typedef blender_rgba_pre<rgba16, order_abgr, pixel64_type> blender_abgr64_pre; //----blender_abgr64_pre
- typedef blender_rgba_pre<rgba16, order_bgra, pixel64_type> blender_bgra64_pre; //----blender_bgra64_pre
+ typedef blender_rgba_pre<rgba16, order_rgba> blender_rgba64_pre; //----blender_rgba64_pre
+ typedef blender_rgba_pre<rgba16, order_argb> blender_argb64_pre; //----blender_argb64_pre
+ typedef blender_rgba_pre<rgba16, order_abgr> blender_abgr64_pre; //----blender_abgr64_pre
+ typedef blender_rgba_pre<rgba16, order_bgra> blender_bgra64_pre; //----blender_bgra64_pre
//-----------------------------------------------------------------------
- typedef pixel_formats_rgba<blender_rgba32> pixfmt_rgba32; //----pixfmt_rgba32
- typedef pixel_formats_rgba<blender_argb32> pixfmt_argb32; //----pixfmt_argb32
- typedef pixel_formats_rgba<blender_abgr32> pixfmt_abgr32; //----pixfmt_abgr32
- typedef pixel_formats_rgba<blender_bgra32> pixfmt_bgra32; //----pixfmt_bgra32
-
- typedef pixel_formats_rgba<blender_rgba32_pre> pixfmt_rgba32_pre; //----pixfmt_rgba32_pre
- typedef pixel_formats_rgba<blender_argb32_pre> pixfmt_argb32_pre; //----pixfmt_argb32_pre
- typedef pixel_formats_rgba<blender_abgr32_pre> pixfmt_abgr32_pre; //----pixfmt_abgr32_pre
- typedef pixel_formats_rgba<blender_bgra32_pre> pixfmt_bgra32_pre; //----pixfmt_bgra32_pre
-
- typedef pixel_formats_rgba<blender_rgba32_plain> pixfmt_rgba32_plain; //----pixfmt_rgba32_plain
- typedef pixel_formats_rgba<blender_argb32_plain> pixfmt_argb32_plain; //----pixfmt_argb32_plain
- typedef pixel_formats_rgba<blender_abgr32_plain> pixfmt_abgr32_plain; //----pixfmt_abgr32_plain
- typedef pixel_formats_rgba<blender_bgra32_plain> pixfmt_bgra32_plain; //----pixfmt_bgra32_plain
-
- typedef pixel_formats_rgba<blender_rgba64> pixfmt_rgba64; //----pixfmt_rgba64
- typedef pixel_formats_rgba<blender_argb64> pixfmt_argb64; //----pixfmt_argb64
- typedef pixel_formats_rgba<blender_abgr64> pixfmt_abgr64; //----pixfmt_abgr64
- typedef pixel_formats_rgba<blender_bgra64> pixfmt_bgra64; //----pixfmt_bgra64
-
- typedef pixel_formats_rgba<blender_rgba64_pre> pixfmt_rgba64_pre; //----pixfmt_rgba64_pre
- typedef pixel_formats_rgba<blender_argb64_pre> pixfmt_argb64_pre; //----pixfmt_argb64_pre
- typedef pixel_formats_rgba<blender_abgr64_pre> pixfmt_abgr64_pre; //----pixfmt_abgr64_pre
- typedef pixel_formats_rgba<blender_bgra64_pre> pixfmt_bgra64_pre; //----pixfmt_bgra64_pre
+ typedef int32u pixel32_type;
+ typedef pixfmt_alpha_blend_rgba<blender_rgba32, rendering_buffer, pixel32_type> pixfmt_rgba32; //----pixfmt_rgba32
+ typedef pixfmt_alpha_blend_rgba<blender_argb32, rendering_buffer, pixel32_type> pixfmt_argb32; //----pixfmt_argb32
+ typedef pixfmt_alpha_blend_rgba<blender_abgr32, rendering_buffer, pixel32_type> pixfmt_abgr32; //----pixfmt_abgr32
+ typedef pixfmt_alpha_blend_rgba<blender_bgra32, rendering_buffer, pixel32_type> pixfmt_bgra32; //----pixfmt_bgra32
+
+ typedef pixfmt_alpha_blend_rgba<blender_rgba32_pre, rendering_buffer, pixel32_type> pixfmt_rgba32_pre; //----pixfmt_rgba32_pre
+ typedef pixfmt_alpha_blend_rgba<blender_argb32_pre, rendering_buffer, pixel32_type> pixfmt_argb32_pre; //----pixfmt_argb32_pre
+ typedef pixfmt_alpha_blend_rgba<blender_abgr32_pre, rendering_buffer, pixel32_type> pixfmt_abgr32_pre; //----pixfmt_abgr32_pre
+ typedef pixfmt_alpha_blend_rgba<blender_bgra32_pre, rendering_buffer, pixel32_type> pixfmt_bgra32_pre; //----pixfmt_bgra32_pre
+
+ typedef pixfmt_alpha_blend_rgba<blender_rgba32_plain, rendering_buffer, pixel32_type> pixfmt_rgba32_plain; //----pixfmt_rgba32_plain
+ typedef pixfmt_alpha_blend_rgba<blender_argb32_plain, rendering_buffer, pixel32_type> pixfmt_argb32_plain; //----pixfmt_argb32_plain
+ typedef pixfmt_alpha_blend_rgba<blender_abgr32_plain, rendering_buffer, pixel32_type> pixfmt_abgr32_plain; //----pixfmt_abgr32_plain
+ typedef pixfmt_alpha_blend_rgba<blender_bgra32_plain, rendering_buffer, pixel32_type> pixfmt_bgra32_plain; //----pixfmt_bgra32_plain
+
+ struct pixel64_type { int16u c[4]; };
+ typedef pixfmt_alpha_blend_rgba<blender_rgba64, rendering_buffer, pixel64_type> pixfmt_rgba64; //----pixfmt_rgba64
+ typedef pixfmt_alpha_blend_rgba<blender_argb64, rendering_buffer, pixel64_type> pixfmt_argb64; //----pixfmt_argb64
+ typedef pixfmt_alpha_blend_rgba<blender_abgr64, rendering_buffer, pixel64_type> pixfmt_abgr64; //----pixfmt_abgr64
+ typedef pixfmt_alpha_blend_rgba<blender_bgra64, rendering_buffer, pixel64_type> pixfmt_bgra64; //----pixfmt_bgra64
+
+ typedef pixfmt_alpha_blend_rgba<blender_rgba64_pre, rendering_buffer, pixel64_type> pixfmt_rgba64_pre; //----pixfmt_rgba64_pre
+ typedef pixfmt_alpha_blend_rgba<blender_argb64_pre, rendering_buffer, pixel64_type> pixfmt_argb64_pre; //----pixfmt_argb64_pre
+ typedef pixfmt_alpha_blend_rgba<blender_abgr64_pre, rendering_buffer, pixel64_type> pixfmt_abgr64_pre; //----pixfmt_abgr64_pre
+ typedef pixfmt_alpha_blend_rgba<blender_bgra64_pre, rendering_buffer, pixel64_type> pixfmt_bgra64_pre; //----pixfmt_bgra64_pre
}
#endif
diff --git a/agg/inc/agg_rasterizer_cells_aa.h b/agg/inc/agg_rasterizer_cells_aa.h
new file mode 100644
index 000000000000..1f99183be103
--- /dev/null
+++ b/agg/inc/agg_rasterizer_cells_aa.h
@@ -0,0 +1,754 @@
+//----------------------------------------------------------------------------
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
+//
+// Permission to copy, use, modify, sell and distribute this software
+// is granted provided this copyright notice appears in all copies.
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+//
+//----------------------------------------------------------------------------
+//
+// The author gratefully acknowleges the support of David Turner,
+// Robert Wilhelm, and Werner Lemberg - the authors of the FreeType
+// libray - in producing this work. See http://www.freetype.org for details.
+//
+//----------------------------------------------------------------------------
+// Contact: mcseem@antigrain.com
+// mcseemagg@yahoo.com
+// http://www.antigrain.com
+//----------------------------------------------------------------------------
+//
+// Adaptation for 32-bit screen coordinates has been sponsored by
+// Liberty Technology Systems, Inc., visit http://lib-sys.com
+//
+// Liberty Technology Systems, Inc. is the provider of
+// PostScript and PDF technology for software developers.
+//
+//----------------------------------------------------------------------------
+#ifndef AGG_RASTERIZER_CELLS_AA_INCLUDED
+#define AGG_RASTERIZER_CELLS_AA_INCLUDED
+
+#include <string.h>
+#include <math.h>
+#include "agg_math.h"
+#include "agg_array.h"
+
+
+namespace agg
+{
+
+ //-----------------------------------------------------rasterizer_cells_aa
+ // An internal class that implements the main rasterization algorithm.
+ // Used in the rasterizer. Should not be used direcly.
+ template<class Cell> class rasterizer_cells_aa
+ {
+ enum cell_block_scale_e
+ {
+ cell_block_shift = 12,
+ cell_block_size = 1 << cell_block_shift,
+ cell_block_mask = cell_block_size - 1,
+ cell_block_pool = 256,
+ cell_block_limit = 1024
+ };
+
+ struct sorted_y
+ {
+ unsigned start;
+ unsigned num;
+ };
+
+ public:
+ typedef Cell cell_type;
+ typedef rasterizer_cells_aa<Cell> self_type;
+
+ ~rasterizer_cells_aa();
+ rasterizer_cells_aa();
+
+ void reset();
+ void style(const cell_type& style_cell);
+ void line(int x1, int y1, int x2, int y2);
+
+ int min_x() const { return m_min_x; }
+ int min_y() const { return m_min_y; }
+ int max_x() const { return m_max_x; }
+ int max_y() const { return m_max_y; }
+
+ void sort_cells();
+
+ unsigned total_cells() const
+ {
+ return m_num_cells;
+ }
+
+ unsigned scanline_num_cells(unsigned y) const
+ {
+ return m_sorted_y[y - m_min_y].num;
+ }
+
+ const cell_type* const* scanline_cells(unsigned y) const
+ {
+ return m_sorted_cells.data() + m_sorted_y[y - m_min_y].start;
+ }
+
+ bool sorted() const { return m_sorted; }
+
+ private:
+ rasterizer_cells_aa(const self_type&);
+ const self_type& operator = (const self_type&);
+
+ void set_curr_cell(int x, int y);
+ void add_curr_cell();
+ void render_hline(int ey, int x1, int y1, int x2, int y2);
+ void allocate_block();
+
+ private:
+ unsigned m_num_blocks;
+ unsigned m_max_blocks;
+ unsigned m_curr_block;
+ unsigned m_num_cells;
+ cell_type** m_cells;
+ cell_type* m_curr_cell_ptr;
+ pod_vector<cell_type*> m_sorted_cells;
+ pod_vector<sorted_y> m_sorted_y;
+ cell_type m_curr_cell;
+ cell_type m_style_cell;
+ int m_min_x;
+ int m_min_y;
+ int m_max_x;
+ int m_max_y;
+ bool m_sorted;
+ };
+
+
+
+
+ //------------------------------------------------------------------------
+ template<class Cell>
+ rasterizer_cells_aa<Cell>::~rasterizer_cells_aa()
+ {
+ if(m_num_blocks)
+ {
+ cell_type** ptr = m_cells + m_num_blocks - 1;
+ while(m_num_blocks--)
+ {
+ pod_allocator<cell_type>::deallocate(*ptr, cell_block_size);
+ ptr--;
+ }
+ pod_allocator<cell_type*>::deallocate(m_cells, m_max_blocks);
+ }
+ }
+
+ //------------------------------------------------------------------------
+ template<class Cell>
+ rasterizer_cells_aa<Cell>::rasterizer_cells_aa() :
+ m_num_blocks(0),
+ m_max_blocks(0),
+ m_curr_block(0),
+ m_num_cells(0),
+ m_cells(0),
+ m_curr_cell_ptr(0),
+ m_sorted_cells(),
+ m_sorted_y(),
+ m_min_x(0x7FFFFFFF),
+ m_min_y(0x7FFFFFFF),
+ m_max_x(-0x7FFFFFFF),
+ m_max_y(-0x7FFFFFFF),
+ m_sorted(false)
+ {
+ m_style_cell.initial();
+ m_curr_cell.initial();
+ }
+
+ //------------------------------------------------------------------------
+ template<class Cell>
+ void rasterizer_cells_aa<Cell>::reset()
+ {
+ m_num_cells = 0;
+ m_curr_block = 0;
+ m_curr_cell.initial();
+ m_style_cell.initial();
+ m_sorted = false;
+ m_min_x = 0x7FFFFFFF;
+ m_min_y = 0x7FFFFFFF;
+ m_max_x = -0x7FFFFFFF;
+ m_max_y = -0x7FFFFFFF;
+ }
+
+ //------------------------------------------------------------------------
+ template<class Cell>
+ AGG_INLINE void rasterizer_cells_aa<Cell>::add_curr_cell()
+ {
+ if(m_curr_cell.area | m_curr_cell.cover)
+ {
+ if((m_num_cells & cell_block_mask) == 0)
+ {
+ if(m_num_blocks >= cell_block_limit) return;
+ allocate_block();
+ }
+ *m_curr_cell_ptr++ = m_curr_cell;
+ ++m_num_cells;
+ }
+ }
+
+ //------------------------------------------------------------------------
+ template<class Cell>
+ AGG_INLINE void rasterizer_cells_aa<Cell>::set_curr_cell(int x, int y)
+ {
+ if(m_curr_cell.not_equal(x, y, m_style_cell))
+ {
+ add_curr_cell();
+ m_curr_cell.style(m_style_cell);
+ m_curr_cell.x = x;
+ m_curr_cell.y = y;
+ m_curr_cell.cover = 0;
+ m_curr_cell.area = 0;
+ }
+ }
+
+ //------------------------------------------------------------------------
+ template<class Cell>
+ AGG_INLINE void rasterizer_cells_aa<Cell>::render_hline(int ey,
+ int x1, int y1,
+ int x2, int y2)
+ {
+ int ex1 = x1 >> poly_subpixel_shift;
+ int ex2 = x2 >> poly_subpixel_shift;
+ int fx1 = x1 & poly_subpixel_mask;
+ int fx2 = x2 & poly_subpixel_mask;
+
+ int delta, p, first, dx;
+ int incr, lift, mod, rem;
+
+ //trivial case. Happens often
+ if(y1 == y2)
+ {
+ set_curr_cell(ex2, ey);
+ return;
+ }
+
+ //everything is located in a single cell. That is easy!
+ if(ex1 == ex2)
+ {
+ delta = y2 - y1;
+ m_curr_cell.cover += delta;
+ m_curr_cell.area += (fx1 + fx2) * delta;
+ return;
+ }
+
+ //ok, we'll have to render a run of adjacent cells on the same
+ //hline...
+ p = (poly_subpixel_scale - fx1) * (y2 - y1);
+ first = poly_subpixel_scale;
+ incr = 1;
+
+ dx = x2 - x1;
+
+ if(dx < 0)
+ {
+ p = fx1 * (y2 - y1);
+ first = 0;
+ incr = -1;
+ dx = -dx;
+ }
+
+ delta = p / dx;
+ mod = p % dx;
+
+ if(mod < 0)
+ {
+ delta--;
+ mod += dx;
+ }
+
+ m_curr_cell.cover += delta;
+ m_curr_cell.area += (fx1 + first) * delta;
+
+ ex1 += incr;
+ set_curr_cell(ex1, ey);
+ y1 += delta;
+
+ if(ex1 != ex2)
+ {
+ p = poly_subpixel_scale * (y2 - y1 + delta);
+ lift = p / dx;
+ rem = p % dx;
+
+ if (rem < 0)
+ {
+ lift--;
+ rem += dx;
+ }
+
+ mod -= dx;
+
+ while (ex1 != ex2)
+ {
+ delta = lift;
+ mod += rem;
+ if(mod >= 0)
+ {
+ mod -= dx;
+ delta++;
+ }
+
+ m_curr_cell.cover += delta;
+ m_curr_cell.area += poly_subpixel_scale * delta;
+ y1 += delta;
+ ex1 += incr;
+ set_curr_cell(ex1, ey);
+ }
+ }
+ delta = y2 - y1;
+ m_curr_cell.cover += delta;
+ m_curr_cell.area += (fx2 + poly_subpixel_scale - first) * delta;
+ }
+
+ //------------------------------------------------------------------------
+ template<class Cell>
+ AGG_INLINE void rasterizer_cells_aa<Cell>::style(const cell_type& style_cell)
+ {
+ m_style_cell.style(style_cell);
+ }
+
+ //------------------------------------------------------------------------
+ template<class Cell>
+ void rasterizer_cells_aa<Cell>::line(int x1, int y1, int x2, int y2)
+ {
+ enum dx_limit_e { dx_limit = 16384 << poly_subpixel_shift };
+
+ int dx = x2 - x1;
+
+ if(dx >= dx_limit || dx <= -dx_limit)
+ {
+ int cx = (x1 + x2) >> 1;
+ int cy = (y1 + y2) >> 1;
+ line(x1, y1, cx, cy);
+ line(cx, cy, x2, y2);
+ }
+
+ int dy = y2 - y1;
+ int ex1 = x1 >> poly_subpixel_shift;
+ int ex2 = x2 >> poly_subpixel_shift;
+ int ey1 = y1 >> poly_subpixel_shift;
+ int ey2 = y2 >> poly_subpixel_shift;
+ int fy1 = y1 & poly_subpixel_mask;
+ int fy2 = y2 & poly_subpixel_mask;
+
+ int x_from, x_to;
+ int p, rem, mod, lift, delta, first, incr;
+
+ if(ex1 < m_min_x) m_min_x = ex1;
+ if(ex1 > m_max_x) m_max_x = ex1;
+ if(ey1 < m_min_y) m_min_y = ey1;
+ if(ey1 > m_max_y) m_max_y = ey1;
+ if(ex2 < m_min_x) m_min_x = ex2;
+ if(ex2 > m_max_x) m_max_x = ex2;
+ if(ey2 < m_min_y) m_min_y = ey2;
+ if(ey2 > m_max_y) m_max_y = ey2;
+
+ set_curr_cell(ex1, ey1);
+
+ //everything is on a single hline
+ if(ey1 == ey2)
+ {
+ render_hline(ey1, x1, fy1, x2, fy2);
+ return;
+ }
+
+ //Vertical line - we have to calculate start and end cells,
+ //and then - the common values of the area and coverage for
+ //all cells of the line. We know exactly there's only one
+ //cell, so, we don't have to call render_hline().
+ incr = 1;
+ if(dx == 0)
+ {
+ int ex = x1 >> poly_subpixel_shift;
+ int two_fx = (x1 - (ex << poly_subpixel_shift)) << 1;
+ int area;
+
+ first = poly_subpixel_scale;
+ if(dy < 0)
+ {
+ first = 0;
+ incr = -1;
+ }
+
+ x_from = x1;
+
+ //render_hline(ey1, x_from, fy1, x_from, first);
+ delta = first - fy1;
+ m_curr_cell.cover += delta;
+ m_curr_cell.area += two_fx * delta;
+
+ ey1 += incr;
+ set_curr_cell(ex, ey1);
+
+ delta = first + first - poly_subpixel_scale;
+ area = two_fx * delta;
+ while(ey1 != ey2)
+ {
+ //render_hline(ey1, x_from, poly_subpixel_scale - first, x_from, first);
+ m_curr_cell.cover = delta;
+ m_curr_cell.area = area;
+ ey1 += incr;
+ set_curr_cell(ex, ey1);
+ }
+ //render_hline(ey1, x_from, poly_subpixel_scale - first, x_from, fy2);
+ delta = fy2 - poly_subpixel_scale + first;
+ m_curr_cell.cover += delta;
+ m_curr_cell.area += two_fx * delta;
+ return;
+ }
+
+ //ok, we have to render several hlines
+ p = (poly_subpixel_scale - fy1) * dx;
+ first = poly_subpixel_scale;
+
+ if(dy < 0)
+ {
+ p = fy1 * dx;
+ first = 0;
+ incr = -1;
+ dy = -dy;
+ }
+
+ delta = p / dy;
+ mod = p % dy;
+
+ if(mod < 0)
+ {
+ delta--;
+ mod += dy;
+ }
+
+ x_from = x1 + delta;
+ render_hline(ey1, x1, fy1, x_from, first);
+
+ ey1 += incr;
+ set_curr_cell(x_from >> poly_subpixel_shift, ey1);
+
+ if(ey1 != ey2)
+ {
+ p = poly_subpixel_scale * dx;
+ lift = p / dy;
+ rem = p % dy;
+
+ if(rem < 0)
+ {
+ lift--;
+ rem += dy;
+ }
+ mod -= dy;
+
+ while(ey1 != ey2)
+ {
+ delta = lift;
+ mod += rem;
+ if (mod >= 0)
+ {
+ mod -= dy;
+ delta++;
+ }
+
+ x_to = x_from + delta;
+ render_hline(ey1, x_from, poly_subpixel_scale - first, x_to, first);
+ x_from = x_to;
+
+ ey1 += incr;
+ set_curr_cell(x_from >> poly_subpixel_shift, ey1);
+ }
+ }
+ render_hline(ey1, x_from, poly_subpixel_scale - first, x2, fy2);
+ }
+
+ //------------------------------------------------------------------------
+ template<class Cell>
+ void rasterizer_cells_aa<Cell>::allocate_block()
+ {
+ if(m_curr_block >= m_num_blocks)
+ {
+ if(m_num_blocks >= m_max_blocks)
+ {
+ cell_type** new_cells =
+ pod_allocator<cell_type*>::allocate(m_max_blocks +
+ cell_block_pool);
+
+ if(m_cells)
+ {
+ memcpy(new_cells, m_cells, m_max_blocks * sizeof(cell_type*));
+ pod_allocator<cell_type*>::deallocate(m_cells, m_max_blocks);
+ }
+ m_cells = new_cells;
+ m_max_blocks += cell_block_pool;
+ }
+
+ m_cells[m_num_blocks++] =
+ pod_allocator<cell_type>::allocate(cell_block_size);
+
+ }
+ m_curr_cell_ptr = m_cells[m_curr_block++];
+ }
+
+
+
+ //------------------------------------------------------------------------
+ template <class T> static AGG_INLINE void swap_cells(T* a, T* b)
+ {
+ T temp = *a;
+ *a = *b;
+ *b = temp;
+ }
+
+
+ //------------------------------------------------------------------------
+ enum
+ {
+ qsort_threshold = 9
+ };
+
+
+ //------------------------------------------------------------------------
+ template<class Cell>
+ void qsort_cells(Cell** start, unsigned num)
+ {
+ Cell** stack[80];
+ Cell*** top;
+ Cell** limit;
+ Cell** base;
+
+ limit = start + num;
+ base = start;
+ top = stack;
+
+ for (;;)
+ {
+ int len = int(limit - base);
+
+ Cell** i;
+ Cell** j;
+ Cell** pivot;
+
+ if(len > qsort_threshold)
+ {
+ // we use base + len/2 as the pivot
+ pivot = base + len / 2;
+ swap_cells(base, pivot);
+
+ i = base + 1;
+ j = limit - 1;
+
+ // now ensure that *i <= *base <= *j
+ if((*j)->x < (*i)->x)
+ {
+ swap_cells(i, j);
+ }
+
+ if((*base)->x < (*i)->x)
+ {
+ swap_cells(base, i);
+ }
+
+ if((*j)->x < (*base)->x)
+ {
+ swap_cells(base, j);
+ }
+
+ for(;;)
+ {
+ int x = (*base)->x;
+ do i++; while( (*i)->x < x );
+ do j--; while( x < (*j)->x );
+
+ if(i > j)
+ {
+ break;
+ }
+
+ swap_cells(i, j);
+ }
+
+ swap_cells(base, j);
+
+ // now, push the largest sub-array
+ if(j - base > limit - i)
+ {
+ top[0] = base;
+ top[1] = j;
+ base = i;
+ }
+ else
+ {
+ top[0] = i;
+ top[1] = limit;
+ limit = j;
+ }
+ top += 2;
+ }
+ else
+ {
+ // the sub-array is small, perform insertion sort
+ j = base;
+ i = j + 1;
+
+ for(; i < limit; j = i, i++)
+ {
+ for(; j[1]->x < (*j)->x; j--)
+ {
+ swap_cells(j + 1, j);
+ if (j == base)
+ {
+ break;
+ }
+ }
+ }
+
+ if(top > stack)
+ {
+ top -= 2;
+ base = top[0];
+ limit = top[1];
+ }
+ else
+ {
+ break;
+ }
+ }
+ }
+ }
+
+
+ //------------------------------------------------------------------------
+ template<class Cell>
+ void rasterizer_cells_aa<Cell>::sort_cells()
+ {
+ if(m_sorted) return; //Perform sort only the first time.
+
+ add_curr_cell();
+ m_curr_cell.x = 0x7FFFFFFF;
+ m_curr_cell.y = 0x7FFFFFFF;
+ m_curr_cell.cover = 0;
+ m_curr_cell.area = 0;
+
+ if(m_num_cells == 0) return;
+
+// DBG: Check to see if min/max works well.
+//for(unsigned nc = 0; nc < m_num_cells; nc++)
+//{
+// cell_type* cell = m_cells[nc >> cell_block_shift] + (nc & cell_block_mask);
+// if(cell->x < m_min_x ||
+// cell->y < m_min_y ||
+// cell->x > m_max_x ||
+// cell->y > m_max_y)
+// {
+// cell = cell; // Breakpoint here
+// }
+//}
+ // Allocate the array of cell pointers
+ m_sorted_cells.allocate(m_num_cells, 16);
+
+ // Allocate and zero the Y array
+ m_sorted_y.allocate(m_max_y - m_min_y + 1, 16);
+ m_sorted_y.zero();
+
+ // Create the Y-histogram (count the numbers of cells for each Y)
+ cell_type** block_ptr = m_cells;
+ cell_type* cell_ptr;
+ unsigned nb = m_num_cells >> cell_block_shift;
+ unsigned i;
+ while(nb--)
+ {
+ cell_ptr = *block_ptr++;
+ i = cell_block_size;
+ while(i--)
+ {
+ m_sorted_y[cell_ptr->y - m_min_y].start++;
+ ++cell_ptr;
+ }
+ }
+
+ cell_ptr = *block_ptr++;
+ i = m_num_cells & cell_block_mask;
+ while(i--)
+ {
+ m_sorted_y[cell_ptr->y - m_min_y].start++;
+ ++cell_ptr;
+ }
+
+ // Convert the Y-histogram into the array of starting indexes
+ unsigned start = 0;
+ for(i = 0; i < m_sorted_y.size(); i++)
+ {
+ unsigned v = m_sorted_y[i].start;
+ m_sorted_y[i].start = start;
+ start += v;
+ }
+
+ // Fill the cell pointer array sorted by Y
+ block_ptr = m_cells;
+ nb = m_num_cells >> cell_block_shift;
+ while(nb--)
+ {
+ cell_ptr = *block_ptr++;
+ i = cell_block_size;
+ while(i--)
+ {
+ sorted_y& curr_y = m_sorted_y[cell_ptr->y - m_min_y];
+ m_sorted_cells[curr_y.start + curr_y.num] = cell_ptr;
+ ++curr_y.num;
+ ++cell_ptr;
+ }
+ }
+
+ cell_ptr = *block_ptr++;
+ i = m_num_cells & cell_block_mask;
+ while(i--)
+ {
+ sorted_y& curr_y = m_sorted_y[cell_ptr->y - m_min_y];
+ m_sorted_cells[curr_y.start + curr_y.num] = cell_ptr;
+ ++curr_y.num;
+ ++cell_ptr;
+ }
+
+ // Finally arrange the X-arrays
+ for(i = 0; i < m_sorted_y.size(); i++)
+ {
+ const sorted_y& curr_y = m_sorted_y[i];
+ if(curr_y.num)
+ {
+ qsort_cells(m_sorted_cells.data() + curr_y.start, curr_y.num);
+ }
+ }
+ m_sorted = true;
+ }
+
+
+
+ //------------------------------------------------------scanline_hit_test
+ class scanline_hit_test
+ {
+ public:
+ scanline_hit_test(int x) : m_x(x), m_hit(false) {}
+
+ void reset_spans() {}
+ void finalize(int) {}
+ void add_cell(int x, int)
+ {
+ if(m_x == x) m_hit = true;
+ }
+ void add_span(int x, int len, int)
+ {
+ if(m_x >= x && m_x < x+len) m_hit = true;
+ }
+ unsigned num_spans() const { return 1; }
+ bool hit() const { return m_hit; }
+
+ private:
+ int m_x;
+ bool m_hit;
+ };
+
+
+}
+
+#endif
diff --git a/agg/inc/agg_rasterizer_compound_aa.h b/agg/inc/agg_rasterizer_compound_aa.h
new file mode 100644
index 000000000000..3025c2909eec
--- /dev/null
+++ b/agg/inc/agg_rasterizer_compound_aa.h
@@ -0,0 +1,698 @@
+//----------------------------------------------------------------------------
+// Anti-Grain Geometry - Version 2.3
+// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
+//
+// Permission to copy, use, modify, sell and distribute this software
+// is granted provided this copyright notice appears in all copies.
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+//
+//----------------------------------------------------------------------------
+//
+// The author gratefully acknowleges the support of David Turner,
+// Robert Wilhelm, and Werner Lemberg - the authors of the FreeType
+// libray - in producing this work. See http://www.freetype.org for details.
+//
+//----------------------------------------------------------------------------
+// Contact: mcseem@antigrain.com
+// mcseemagg@yahoo.com
+// http://www.antigrain.com
+//----------------------------------------------------------------------------
+//
+// Adaptation for 32-bit screen coordinates has been sponsored by
+// Liberty Technology Systems, Inc., visit http://lib-sys.com
+//
+// Liberty Technology Systems, Inc. is the provider of
+// PostScript and PDF technology for software developers.
+//
+//----------------------------------------------------------------------------
+#ifndef AGG_RASTERIZER_COMPOUND_AA_INCLUDED
+#define AGG_RASTERIZER_COMPOUND_AA_INCLUDED
+
+#include "agg_rasterizer_cells_aa.h"
+#include "agg_rasterizer_sl_clip.h"
+
+namespace agg
+{
+
+ //-----------------------------------------------------------cell_style_aa
+ // A pixel cell. There're no constructors defined and it was done
+ // intentionally in order to avoid extra overhead when allocating an
+ // array of cells.
+ struct cell_style_aa
+ {
+ int x;
+ int y;
+ int cover;
+ int area;
+ int16 left, right;
+
+ void initial()
+ {
+ x = 0x7FFFFFFF;
+ y = 0x7FFFFFFF;
+ cover = 0;
+ area = 0;
+ left = -1;
+ right = -1;
+ }
+
+ void style(const cell_style_aa& c)
+ {
+ left = c.left;
+ right = c.right;
+ }
+
+ int not_equal(int ex, int ey, const cell_style_aa& c) const
+ {
+ return (ex - x) | (ey - y) | (left - c.left) | (right - c.right);
+ }
+ };
+
+
+ //===========================================================layer_order_e
+ enum layer_order_e
+ {
+ layer_unsorted, //------layer_unsorted
+ layer_direct, //------layer_direct
+ layer_inverse //------layer_inverse
+ };
+
+
+ //==================================================rasterizer_compound_aa
+ template<class Clip=rasterizer_sl_clip_int> class rasterizer_compound_aa
+ {
+ struct style_info
+ {
+ unsigned start_cell;
+ unsigned num_cells;
+ int last_x;
+ };
+
+ struct cell_info
+ {
+ int x, area, cover;
+ };
+
+ public:
+ typedef Clip clip_type;
+ typedef typename Clip::conv_type conv_type;
+ typedef typename Clip::coord_type coord_type;
+
+ enum aa_scale_e
+ {
+ aa_shift = 8,
+ aa_scale = 1 << aa_shift,
+ aa_mask = aa_scale - 1,
+ aa_scale2 = aa_scale * 2,
+ aa_mask2 = aa_scale2 - 1
+ };
+
+ //--------------------------------------------------------------------
+ rasterizer_compound_aa() :
+ m_outline(),
+ m_clipper(),
+ m_filling_rule(fill_non_zero),
+ m_layer_order(layer_direct),
+ m_styles(), // Active Styles
+ m_ast(), // Active Style Table (unique values)
+ m_asm(), // Active Style Mask
+ m_cells(),
+ m_cover_buf(),
+ m_master_alpha(),
+ m_min_style(0x7FFFFFFF),
+ m_max_style(-0x7FFFFFFF),
+ m_start_x(0),
+ m_start_y(0),
+ m_scan_y(0x7FFFFFFF),
+ m_sl_start(0),
+ m_sl_len(0)
+ {}
+
+ //--------------------------------------------------------------------
+ void reset();
+ void reset_clipping();
+ void clip_box(double x1, double y1, double x2, double y2);
+ void filling_rule(filling_rule_e filling_rule);
+ void layer_order(layer_order_e order);
+ void master_alpha(int style, double alpha);
+
+ //--------------------------------------------------------------------
+ void styles(int left, int right);
+ void move_to(int x, int y);
+ void line_to(int x, int y);
+ void move_to_d(double x, double y);
+ void line_to_d(double x, double y);
+ void add_vertex(double x, double y, unsigned cmd);
+
+ void edge(int x1, int y1, int x2, int y2);
+ void edge_d(double x1, double y1, double x2, double y2);
+
+ //-------------------------------------------------------------------
+ template<class VertexSource>
+ void add_path(VertexSource& vs, unsigned path_id=0)
+ {
+ double x;
+ double y;
+
+ unsigned cmd;
+ vs.rewind(path_id);
+ if(m_outline.sorted()) reset();
+ while(!is_stop(cmd = vs.vertex(&x, &y)))
+ {
+ add_vertex(x, y, cmd);
+ }
+ }
+
+
+ //--------------------------------------------------------------------
+ int min_x() const { return m_outline.min_x(); }
+ int min_y() const { return m_outline.min_y(); }
+ int max_x() const { return m_outline.max_x(); }
+ int max_y() const { return m_outline.max_y(); }
+ int min_style() const { return m_min_style; }
+ int max_style() const { return m_max_style; }
+
+ //--------------------------------------------------------------------
+ void sort();
+ bool rewind_scanlines();
+ unsigned sweep_styles();
+ int scanline_start() const { return m_sl_start; }
+ unsigned scanline_length() const { return m_sl_len; }
+ unsigned style(unsigned style_idx) const;
+
+ cover_type* allocate_cover_buffer(unsigned len);
+
+ //--------------------------------------------------------------------
+ bool navigate_scanline(int y);
+ bool hit_test(int tx, int ty);
+
+ //--------------------------------------------------------------------
+ AGG_INLINE unsigned calculate_alpha(int area, unsigned master_alpha) const
+ {
+ int cover = area >> (poly_subpixel_shift*2 + 1 - aa_shift);
+ if(cover < 0) cover = -cover;
+ if(m_filling_rule == fill_even_odd)
+ {
+ cover &= aa_mask2;
+ if(cover > aa_scale)
+ {
+ cover = aa_scale2 - cover;
+ }
+ }
+ if(cover > aa_mask) cover = aa_mask;
+ return (cover * master_alpha + aa_mask) >> aa_shift;
+ }
+
+ //--------------------------------------------------------------------
+ // Sweeps one scanline with one style index. The style ID can be
+ // determined by calling style().
+ template<class Scanline> bool sweep_scanline(Scanline& sl, int style_idx)
+ {
+ int scan_y = m_scan_y - 1;
+ if(scan_y > m_outline.max_y()) return false;
+
+ sl.reset_spans();
+
+ unsigned master_alpha = aa_mask;
+
+ if(style_idx < 0)
+ {
+ style_idx = 0;
+ }
+ else
+ {
+ style_idx++;
+ master_alpha = m_master_alpha[m_ast[style_idx] + m_min_style - 1];
+ }
+
+ const style_info& st = m_styles[m_ast[style_idx]];
+
+ unsigned num_cells = st.num_cells;
+ cell_info* cell = &m_cells[st.start_cell];
+
+ int cover = 0;
+ while(num_cells--)
+ {
+ unsigned alpha;
+ int x = cell->x;
+ int area = cell->area;
+
+ cover += cell->cover;
+
+ ++cell;
+
+ if(area)
+ {
+ alpha = calculate_alpha((cover << (poly_subpixel_shift + 1)) - area,
+ master_alpha);
+ sl.add_cell(x, alpha);
+ x++;
+ }
+
+ if(num_cells && cell->x > x)
+ {
+ alpha = calculate_alpha(cover << (poly_subpixel_shift + 1),
+ master_alpha);
+ if(alpha)
+ {
+ sl.add_span(x, cell->x - x, alpha);
+ }
+ }
+ }
+
+ if(sl.num_spans() == 0) return false;
+ sl.finalize(scan_y);
+ return true;
+ }
+
+ private:
+ void add_style(int style_id);
+ void allocate_master_alpha();
+
+ //--------------------------------------------------------------------
+ // Disable copying
+ rasterizer_compound_aa(const rasterizer_compound_aa<Clip>&);
+ const rasterizer_compound_aa<Clip>&
+ operator = (const rasterizer_compound_aa<Clip>&);
+
+ private:
+ rasterizer_cells_aa<cell_style_aa> m_outline;
+ clip_type m_clipper;
+ filling_rule_e m_filling_rule;
+ layer_order_e m_layer_order;
+ pod_vector<style_info> m_styles; // Active Styles
+ pod_vector<unsigned> m_ast; // Active Style Table (unique values)
+ pod_vector<int8u> m_asm; // Active Style Mask
+ pod_vector<cell_info> m_cells;
+ pod_vector<cover_type> m_cover_buf;
+ pod_bvector<unsigned> m_master_alpha;
+
+ int m_min_style;
+ int m_max_style;
+ coord_type m_start_x;
+ coord_type m_start_y;
+ int m_scan_y;
+ int m_sl_start;
+ unsigned m_sl_len;
+ };
+
+
+
+
+
+
+
+
+
+
+ //------------------------------------------------------------------------
+ template<class Clip>
+ void rasterizer_compound_aa<Clip>::reset()
+ {
+ m_outline.reset();
+ m_min_style = 0x7FFFFFFF;
+ m_max_style = -0x7FFFFFFF;
+ m_scan_y = 0x7FFFFFFF;
+ m_sl_start = 0;
+ m_sl_len = 0;
+ }
+
+ //------------------------------------------------------------------------
+ template<class Clip>
+ void rasterizer_compound_aa<Clip>::filling_rule(filling_rule_e filling_rule)
+ {
+ m_filling_rule = filling_rule;
+ }
+
+ //------------------------------------------------------------------------
+ template<class Clip>
+ void rasterizer_compound_aa<Clip>::layer_order(layer_order_e order)
+ {
+ m_layer_order = order;
+ }
+
+ //------------------------------------------------------------------------
+ template<class Clip>
+ void rasterizer_compound_aa<Clip>::clip_box(double x1, double y1,
+ double x2, double y2)
+ {
+ reset();
+ m_clipper.clip_box(conv_type::upscale(x1), conv_type::upscale(y1),
+ conv_type::upscale(x2), conv_type::upscale(y2));
+ }
+
+ //------------------------------------------------------------------------
+ template<class Clip>
+ void rasterizer_compound_aa<Clip>::reset_clipping()
+ {
+ reset();
+ m_clipper.reset_clipping();
+ }
+
+ //------------------------------------------------------------------------
+ template<class Clip>
+ void rasterizer_compound_aa<Clip>::styles(int left, int right)
+ {
+ cell_style_aa cell;
+ cell.initial();
+ cell.left = (int16)left;
+ cell.right = (int16)right;
+ m_outline.style(cell);
+ if(left >= 0 && left < m_min_style) m_min_style = left;
+ if(left >= 0 && left > m_max_style) m_max_style = left;
+ if(right >= 0 && right < m_min_style) m_min_style = right;
+ if(right >= 0 && right > m_max_style) m_max_style = right;
+ }
+
+ //------------------------------------------------------------------------
+ template<class Clip>
+ void rasterizer_compound_aa<Clip>::move_to(int x, int y)
+ {
+ if(m_outline.sorted()) reset();
+ m_clipper.move_to(m_start_x = conv_type::downscale(x),
+ m_start_y = conv_type::downscale(y));
+ }
+
+ //------------------------------------------------------------------------
+ template<class Clip>
+ void rasterizer_compound_aa<Clip>::line_to(int x, int y)
+ {
+ m_clipper.line_to(m_outline,
+ conv_type::downscale(x),
+ conv_type::downscale(y));
+ }
+
+ //------------------------------------------------------------------------
+ template<class Clip>
+ void rasterizer_compound_aa<Clip>::move_to_d(double x, double y)
+ {
+ if(m_outline.sorted()) reset();
+ m_clipper.move_to(m_start_x = conv_type::upscale(x),
+ m_start_y = conv_type::upscale(y));
+ }
+
+ //------------------------------------------------------------------------
+ template<class Clip>
+ void rasterizer_compound_aa<Clip>::line_to_d(double x, double y)
+ {
+ m_clipper.line_to(m_outline,
+ conv_type::upscale(x),
+ conv_type::upscale(y));
+ }
+
+ //------------------------------------------------------------------------
+ template<class Clip>
+ void rasterizer_compound_aa<Clip>::add_vertex(double x, double y, unsigned cmd)
+ {
+ if(is_move_to(cmd))
+ {
+ move_to_d(x, y);
+ }
+ else
+ if(is_vertex(cmd))
+ {
+ line_to_d(x, y);
+ }
+ else
+ if(is_close(cmd))
+ {
+ m_clipper.line_to(m_outline, m_start_x, m_start_y);
+ }
+ }
+
+ //------------------------------------------------------------------------
+ template<class Clip>
+ void rasterizer_compound_aa<Clip>::edge(int x1, int y1, int x2, int y2)
+ {
+ if(m_outline.sorted()) reset();
+ m_clipper.move_to(conv_type::downscale(x1), conv_type::downscale(y1));
+ m_clipper.line_to(m_outline,
+ conv_type::downscale(x2),
+ conv_type::downscale(y2));
+ }
+
+ //------------------------------------------------------------------------
+ template<class Clip>
+ void rasterizer_compound_aa<Clip>::edge_d(double x1, double y1,
+ double x2, double y2)
+ {
+ if(m_outline.sorted()) reset();
+ m_clipper.move_to(conv_type::upscale(x1), conv_type::upscale(y1));
+ m_clipper.line_to(m_outline,
+ conv_type::upscale(x2),
+ conv_type::upscale(y2));
+ }
+
+ //------------------------------------------------------------------------
+ template<class Clip>
+ AGG_INLINE void rasterizer_compound_aa<Clip>::sort()
+ {
+ m_outline.sort_cells();
+ }
+
+ //------------------------------------------------------------------------
+ template<class Clip>
+ AGG_INLINE bool rasterizer_compound_aa<Clip>::rewind_scanlines()
+ {
+ m_outline.sort_cells();
+ if(m_outline.total_cells() == 0)
+ {
+ return false;
+ }
+ if(m_max_style < m_min_style)
+ {
+ return false;
+ }
+ m_scan_y = m_outline.min_y();
+ m_styles.allocate(m_max_style - m_min_style + 2, 128);
+ allocate_master_alpha();
+ return true;
+ }
+
+ //------------------------------------------------------------------------
+ template<class Clip>
+ AGG_INLINE void rasterizer_compound_aa<Clip>::add_style(int style_id)
+ {
+ if(style_id < 0) style_id = 0;
+ else style_id -= m_min_style - 1;
+
+ unsigned nbyte = style_id >> 3;
+ unsigned mask = 1 << (style_id & 7);
+
+ style_info* style = &m_styles[style_id];
+ if((m_asm[nbyte] & mask) == 0)
+ {
+ m_ast.add(style_id);
+ m_asm[nbyte] |= mask;
+ style->start_cell = 0;
+ style->num_cells = 0;
+ style->last_x = -0x7FFFFFFF;
+ }
+ ++style->start_cell;
+ }
+
+ //------------------------------------------------------------------------
+ // Returns the number of styles
+ template<class Clip>
+ unsigned rasterizer_compound_aa<Clip>::sweep_styles()
+ {
+ for(;;)
+ {
+ if(m_scan_y > m_outline.max_y()) return 0;
+ unsigned num_cells = m_outline.scanline_num_cells(m_scan_y);
+ const cell_style_aa* const* cells = m_outline.scanline_cells(m_scan_y);
+ unsigned num_styles = m_max_style - m_min_style + 2;
+ const cell_style_aa* curr_cell;
+ unsigned style_id;
+ style_info* style;
+ cell_info* cell;
+
+ m_cells.allocate(num_cells * 2, 256); // Each cell can have two styles
+ m_ast.capacity(num_styles, 64);
+ m_asm.allocate((num_styles + 7) >> 3, 8);
+ m_asm.zero();
+
+ if(num_cells)
+ {
+ // Pre-add zero (for no-fill style, that is, -1).
+ // We need that to ensure that the "-1 style" would go first.
+ m_asm[0] |= 1;
+ m_ast.add(0);
+ style = &m_styles[0];
+ style->start_cell = 0;
+ style->num_cells = 0;
+ style->last_x = -0x7FFFFFFF;
+
+ m_sl_start = cells[0]->x;
+ m_sl_len = cells[num_cells-1]->x - m_sl_start + 1;
+ while(num_cells--)
+ {
+ curr_cell = *cells++;
+ add_style(curr_cell->left);
+ add_style(curr_cell->right);
+ }
+
+ // Convert the Y-histogram into the array of starting indexes
+ unsigned i;
+ unsigned start_cell = 0;
+ for(i = 0; i < m_ast.size(); i++)
+ {
+ style_info& st = m_styles[m_ast[i]];
+ unsigned v = st.start_cell;
+ st.start_cell = start_cell;
+ start_cell += v;
+ }
+
+ cells = m_outline.scanline_cells(m_scan_y);
+ num_cells = m_outline.scanline_num_cells(m_scan_y);
+
+ while(num_cells--)
+ {
+ curr_cell = *cells++;
+ style_id = (curr_cell->left < 0) ? 0 :
+ curr_cell->left - m_min_style + 1;
+
+ style = &m_styles[style_id];
+ if(curr_cell->x == style->last_x)
+ {
+ cell = &m_cells[style->start_cell + style->num_cells - 1];
+ cell->area += curr_cell->area;
+ cell->cover += curr_cell->cover;
+ }
+ else
+ {
+ cell = &m_cells[style->start_cell + style->num_cells];
+ cell->x = curr_cell->x;
+ cell->area = curr_cell->area;
+ cell->cover = curr_cell->cover;
+ style->last_x = curr_cell->x;
+ style->num_cells++;
+ }
+
+ style_id = (curr_cell->right < 0) ? 0 :
+ curr_cell->right - m_min_style + 1;
+
+ style = &m_styles[style_id];
+ if(curr_cell->x == style->last_x)
+ {
+ cell = &m_cells[style->start_cell + style->num_cells - 1];
+ cell->area -= curr_cell->area;
+ cell->cover -= curr_cell->cover;
+ }
+ else
+ {
+ cell = &m_cells[style->start_cell + style->num_cells];
+ cell->x = curr_cell->x;
+ cell->area = -curr_cell->area;
+ cell->cover = -curr_cell->cover;
+ style->last_x = curr_cell->x;
+ style->num_cells++;
+ }
+ }
+ }
+ if(m_ast.size() > 1) break;
+ ++m_scan_y;
+ }
+ ++m_scan_y;
+
+ if(m_layer_order != layer_unsorted)
+ {
+ range_adaptor<pod_vector<unsigned> > ra(m_ast, 1, m_ast.size() - 1);
+ if(m_layer_order == layer_direct) quick_sort(ra, unsigned_greater);
+ else quick_sort(ra, unsigned_less);
+ }
+
+ return m_ast.size() - 1;
+ }
+
+ //------------------------------------------------------------------------
+ // Returns style ID depending of the existing style index
+ template<class Clip>
+ AGG_INLINE
+ unsigned rasterizer_compound_aa<Clip>::style(unsigned style_idx) const
+ {
+ return m_ast[style_idx + 1] + m_min_style - 1;
+ }
+
+ //------------------------------------------------------------------------
+ template<class Clip>
+ AGG_INLINE bool rasterizer_compound_aa<Clip>::navigate_scanline(int y)
+ {
+ m_outline.sort_cells();
+ if(m_outline.total_cells() == 0)
+ {
+ return false;
+ }
+ if(m_max_style < m_min_style)
+ {
+ return false;
+ }
+ if(y < m_outline.min_y() || y > m_outline.max_y())
+ {
+ return false;
+ }
+ m_scan_y = y;
+ m_styles.allocate(m_max_style - m_min_style + 2, 128);
+ allocate_master_alpha();
+ return true;
+ }
+
+ //------------------------------------------------------------------------
+ template<class Clip>
+ bool rasterizer_compound_aa<Clip>::hit_test(int tx, int ty)
+ {
+ if(!navigate_scanline(ty))
+ {
+ return false;
+ }
+
+ unsigned num_styles = sweep_styles();
+ if(num_styles <= 0)
+ {
+ return false;
+ }
+
+ scanline_hit_test sl(tx);
+ sweep_scanline(sl, -1);
+ return sl.hit();
+ }
+
+ //------------------------------------------------------------------------
+ template<class Clip>
+ cover_type* rasterizer_compound_aa<Clip>::allocate_cover_buffer(unsigned len)
+ {
+ m_cover_buf.allocate(len, 256);
+ return &m_cover_buf[0];
+ }
+
+ //------------------------------------------------------------------------
+ template<class Clip>
+ void rasterizer_compound_aa<Clip>::allocate_master_alpha()
+ {
+ while((int)m_master_alpha.size() <= m_max_style)
+ {
+ m_master_alpha.add(aa_mask);
+ }
+ }
+
+ //------------------------------------------------------------------------
+ template<class Clip>
+ void rasterizer_compound_aa<Clip>::master_alpha(int style, double alpha)
+ {
+ if(style >= 0)
+ {
+ while((int)m_master_alpha.size() <= style)
+ {
+ m_master_alpha.add(aa_mask);
+ }
+ m_master_alpha[style] = uround(alpha * aa_mask);
+ }
+ }
+
+}
+
+
+
+#endif
+
diff --git a/agg/inc/agg_rasterizer_outline.h b/agg/inc/agg_rasterizer_outline.h
index 18512e76a1ad..4c7c6804d6d2 100755
--- a/agg/inc/agg_rasterizer_outline.h
+++ b/agg/inc/agg_rasterizer_outline.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -23,13 +23,14 @@ namespace agg
template<class Renderer> class rasterizer_outline
{
public:
- rasterizer_outline(Renderer& ren) :
+ explicit rasterizer_outline(Renderer& ren) :
m_ren(&ren),
m_start_x(0),
m_start_y(0),
m_vertices(0)
- {
- }
+ {}
+ void attach(Renderer& ren) { m_ren = &ren; }
+
//--------------------------------------------------------------------
void move_to(int x, int y)
@@ -90,13 +91,13 @@ namespace agg
//--------------------------------------------------------------------
template<class VertexSource>
- void add_path(VertexSource& vs, unsigned id=0)
+ void add_path(VertexSource& vs, unsigned path_id=0)
{
double x;
double y;
unsigned cmd;
- vs.rewind(id);
+ vs.rewind(path_id);
while(!is_stop(cmd = vs.vertex(&x, &y)))
{
add_vertex(x, y, cmd);
@@ -108,13 +109,13 @@ namespace agg
template<class VertexSource, class ColorStorage, class PathId>
void render_all_paths(VertexSource& vs,
const ColorStorage& colors,
- const PathId& id,
+ const PathId& path_id,
unsigned num_paths)
{
for(unsigned i = 0; i < num_paths; i++)
{
m_ren->line_color(colors[i]);
- add_path(vs, id[i]);
+ add_path(vs, path_id[i]);
}
}
diff --git a/agg/inc/agg_rasterizer_outline_aa.h b/agg/inc/agg_rasterizer_outline_aa.h
index 3f4d6395fafa..0e00c537c240 100755
--- a/agg/inc/agg_rasterizer_outline_aa.h
+++ b/agg/inc/agg_rasterizer_outline_aa.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -49,16 +49,23 @@ namespace agg
{
double dx = val.x - x;
double dy = val.y - y;
- return (len = int(sqrt(dx * dx + dy * dy))) >
- (line_subpixel_size + line_subpixel_size / 2);
+ return (len = uround(sqrt(dx * dx + dy * dy))) >
+ (line_subpixel_scale + line_subpixel_scale / 2);
}
};
-
+ //----------------------------------------------------------outline_aa_join_e
+ enum outline_aa_join_e
+ {
+ outline_no_join, //-----outline_no_join
+ outline_miter_join, //-----outline_miter_join
+ outline_round_join, //-----outline_round_join
+ outline_miter_accurate_join //-----outline_accurate_join
+ };
//=======================================================rasterizer_outline_aa
- template<class Renderer> class rasterizer_outline_aa
+ template<class Renderer, class Coord=line_coord> class rasterizer_outline_aa
{
private:
//------------------------------------------------------------------------
@@ -78,21 +85,25 @@ namespace agg
typedef line_aa_vertex vertex_type;
typedef vertex_sequence<vertex_type, 6> vertex_storage_type;
- rasterizer_outline_aa(Renderer& ren) :
- m_ren(ren),
- m_accurate_join(m_ren.accurate_join_only()),
+ explicit rasterizer_outline_aa(Renderer& ren) :
+ m_ren(&ren),
+ m_line_join(ren.accurate_join_only() ?
+ outline_miter_accurate_join :
+ outline_round_join),
m_round_cap(false),
m_start_x(0),
m_start_y(0)
- {
- }
+ {}
+ void attach(Renderer& ren) { m_ren = &ren; }
//------------------------------------------------------------------------
- void accurate_join(bool v)
+ void line_join(outline_aa_join_e join)
{
- m_accurate_join = m_ren.accurate_join_only() ? true : v;
+ m_line_join = m_ren->accurate_join_only() ?
+ outline_miter_accurate_join :
+ join;
}
- bool accurate_join() const { return m_accurate_join; }
+ bool line_join() const { return m_line_join; }
//------------------------------------------------------------------------
void round_cap(bool v) { m_round_cap = v; }
@@ -113,13 +124,13 @@ namespace agg
//------------------------------------------------------------------------
void move_to_d(double x, double y)
{
- move_to(line_coord(x), line_coord(y));
+ move_to(Coord::conv(x), Coord::conv(y));
}
//------------------------------------------------------------------------
void line_to_d(double x, double y)
{
- line_to(line_coord(x), line_coord(y));
+ line_to(Coord::conv(x), Coord::conv(y));
}
//------------------------------------------------------------------------
@@ -152,13 +163,13 @@ namespace agg
//------------------------------------------------------------------------
template<class VertexSource>
- void add_path(VertexSource& vs, unsigned id=0)
+ void add_path(VertexSource& vs, unsigned path_id=0)
{
double x;
double y;
unsigned cmd;
- vs.rewind(id);
+ vs.rewind(path_id);
while(!is_stop(cmd = vs.vertex(&x, &y)))
{
add_vertex(x, y, cmd);
@@ -171,13 +182,13 @@ namespace agg
template<class VertexSource, class ColorStorage, class PathId>
void render_all_paths(VertexSource& vs,
const ColorStorage& colors,
- const PathId& id,
+ const PathId& path_id,
unsigned num_paths)
{
for(unsigned i = 0; i < num_paths; i++)
{
- m_ren.color(colors[i]);
- add_path(vs, id[i]);
+ m_ren->color(colors[i]);
+ add_path(vs, path_id[i]);
}
}
@@ -188,22 +199,22 @@ namespace agg
unsigned i;
for(i = 0; i < c.num_paths(); i++)
{
- m_ren.color(c.color(i));
+ m_ren->color(c.color(i));
add_path(c, i);
}
}
private:
- rasterizer_outline_aa(const rasterizer_outline_aa<Renderer>&);
- const rasterizer_outline_aa<Renderer>& operator =
- (const rasterizer_outline_aa<Renderer>&);
+ rasterizer_outline_aa(const rasterizer_outline_aa<Renderer, Coord>&);
+ const rasterizer_outline_aa<Renderer, Coord>& operator =
+ (const rasterizer_outline_aa<Renderer, Coord>&);
- Renderer& m_ren;
+ Renderer* m_ren;
vertex_storage_type m_src_vertices;
- bool m_accurate_join;
- bool m_round_cap;
- int m_start_x;
- int m_start_y;
+ outline_aa_join_e m_line_join;
+ bool m_round_cap;
+ int m_start_x;
+ int m_start_y;
};
@@ -214,20 +225,39 @@ namespace agg
//----------------------------------------------------------------------------
- template<class Renderer>
- void rasterizer_outline_aa<Renderer>::draw(draw_vars& dv, unsigned start, unsigned end)
+ template<class Renderer, class Coord>
+ void rasterizer_outline_aa<Renderer, Coord>::draw(draw_vars& dv,
+ unsigned start,
+ unsigned end)
{
unsigned i;
const vertex_storage_type::value_type* v;
for(i = start; i < end; i++)
{
+ if(m_line_join == outline_round_join)
+ {
+ dv.xb1 = dv.curr.x1 + (dv.curr.y2 - dv.curr.y1);
+ dv.yb1 = dv.curr.y1 - (dv.curr.x2 - dv.curr.x1);
+ dv.xb2 = dv.curr.x2 + (dv.curr.y2 - dv.curr.y1);
+ dv.yb2 = dv.curr.y2 - (dv.curr.x2 - dv.curr.x1);
+ }
+
switch(dv.flags)
{
- case 0: m_ren.line3(dv.curr, dv.xb1, dv.yb1, dv.xb2, dv.yb2); break;
- case 1: m_ren.line2(dv.curr, dv.xb2, dv.yb2); break;
- case 2: m_ren.line1(dv.curr, dv.xb1, dv.yb1); break;
- case 3: m_ren.line0(dv.curr); break;
+ case 0: m_ren->line3(dv.curr, dv.xb1, dv.yb1, dv.xb2, dv.yb2); break;
+ case 1: m_ren->line2(dv.curr, dv.xb2, dv.yb2); break;
+ case 2: m_ren->line1(dv.curr, dv.xb1, dv.yb1); break;
+ case 3: m_ren->line0(dv.curr); break;
+ }
+
+ if(m_line_join == outline_round_join && (dv.flags & 2) == 0)
+ {
+ m_ren->pie(dv.curr.x2, dv.curr.y2,
+ dv.curr.x2 + (dv.curr.y2 - dv.curr.y1),
+ dv.curr.y2 - (dv.curr.x2 - dv.curr.x1),
+ dv.curr.x2 + (dv.next.y2 - dv.next.y1),
+ dv.curr.y2 - (dv.next.x2 - dv.next.x1));
}
dv.x1 = dv.x2;
@@ -247,20 +277,32 @@ namespace agg
dv.xb1 = dv.xb2;
dv.yb1 = dv.yb2;
- if(m_accurate_join)
- {
- dv.flags = 0;
- }
- else
+ switch(m_line_join)
{
+ case outline_no_join:
+ dv.flags = 3;
+ break;
+
+ case outline_miter_join:
dv.flags >>= 1;
dv.flags |= ((dv.curr.diagonal_quadrant() ==
dv.next.diagonal_quadrant()) << 1);
- }
+ if((dv.flags & 2) == 0)
+ {
+ bisectrix(dv.curr, dv.next, &dv.xb2, &dv.yb2);
+ }
+ break;
- if((dv.flags & 2) == 0)
- {
+ case outline_round_join:
+ dv.flags >>= 1;
+ dv.flags |= ((dv.curr.diagonal_quadrant() ==
+ dv.next.diagonal_quadrant()) << 1);
+ break;
+
+ case outline_miter_accurate_join:
+ dv.flags = 0;
bisectrix(dv.curr, dv.next, &dv.xb2, &dv.yb2);
+ break;
}
}
}
@@ -269,8 +311,8 @@ namespace agg
//----------------------------------------------------------------------------
- template<class Renderer>
- void rasterizer_outline_aa<Renderer>::render(bool close_polygon)
+ template<class Renderer, class Coord>
+ void rasterizer_outline_aa<Renderer, Coord>::render(bool close_polygon)
{
m_src_vertices.close(close_polygon);
draw_vars dv;
@@ -314,23 +356,30 @@ namespace agg
dv.xb2 = 0;
dv.yb2 = 0;
- if(m_accurate_join)
- {
- dv.flags = 0;
- }
- else
+ switch(m_line_join)
{
+ case outline_no_join:
+ dv.flags = 3;
+ break;
+
+ case outline_miter_join:
+ case outline_round_join:
dv.flags =
(prev.diagonal_quadrant() == dv.curr.diagonal_quadrant()) |
((dv.curr.diagonal_quadrant() == dv.next.diagonal_quadrant()) << 1);
+ break;
+
+ case outline_miter_accurate_join:
+ dv.flags = 0;
+ break;
}
- if((dv.flags & 1) == 0)
+ if((dv.flags & 1) == 0 && m_line_join != outline_round_join)
{
bisectrix(prev, dv.curr, &dv.xb1, &dv.yb1);
}
- if((dv.flags & 2) == 0)
+ if((dv.flags & 2) == 0 && m_line_join != outline_round_join)
{
bisectrix(dv.curr, dv.next, &dv.xb2, &dv.yb2);
}
@@ -357,16 +406,16 @@ namespace agg
line_parameters lp(x1, y1, x2, y2, lprev);
if(m_round_cap)
{
- m_ren.semidot(cmp_dist_start, x1, y1, x1 + (y2 - y1), y1 - (x2 - x1));
+ m_ren->semidot(cmp_dist_start, x1, y1, x1 + (y2 - y1), y1 - (x2 - x1));
}
- m_ren.line3(lp,
- x1 + (y2 - y1),
- y1 - (x2 - x1),
- x2 + (y2 - y1),
- y2 - (x2 - x1));
+ m_ren->line3(lp,
+ x1 + (y2 - y1),
+ y1 - (x2 - x1),
+ x2 + (y2 - y1),
+ y2 - (x2 - x1));
if(m_round_cap)
{
- m_ren.semidot(cmp_dist_end, x2, y2, x2 + (y2 - y1), y2 - (x2 - x1));
+ m_ren->semidot(cmp_dist_end, x2, y2, x2 + (y2 - y1), y2 - (x2 - x1));
}
}
break;
@@ -388,26 +437,35 @@ namespace agg
y3 = v->y;
line_parameters lp1(x1, y1, x2, y2, lprev);
line_parameters lp2(x2, y2, x3, y3, lnext);
- bisectrix(lp1, lp2, &dv.xb1, &dv.yb1);
if(m_round_cap)
{
- m_ren.semidot(cmp_dist_start, x1, y1, x1 + (y2 - y1), y1 - (x2 - x1));
+ m_ren->semidot(cmp_dist_start, x1, y1, x1 + (y2 - y1), y1 - (x2 - x1));
+ }
+
+ if(m_line_join == outline_round_join)
+ {
+ m_ren->line3(lp1, x1 + (y2 - y1), y1 - (x2 - x1),
+ x2 + (y2 - y1), y2 - (x2 - x1));
+
+ m_ren->pie(x2, y2, x2 + (y2 - y1), y2 - (x2 - x1),
+ x2 + (y3 - y2), y2 - (x3 - x2));
+
+ m_ren->line3(lp2, x2 + (y3 - y2), y2 - (x3 - x2),
+ x3 + (y3 - y2), y3 - (x3 - x2));
+ }
+ else
+ {
+ bisectrix(lp1, lp2, &dv.xb1, &dv.yb1);
+ m_ren->line3(lp1, x1 + (y2 - y1), y1 - (x2 - x1),
+ dv.xb1, dv.yb1);
+
+ m_ren->line3(lp2, dv.xb1, dv.yb1,
+ x3 + (y3 - y2), y3 - (x3 - x2));
}
- m_ren.line3(lp1,
- x1 + (y2 - y1),
- y1 - (x2 - x1),
- dv.xb1,
- dv.yb1);
-
- m_ren.line3(lp2,
- dv.xb1,
- dv.yb1,
- x3 + (y3 - y2),
- y3 - (x3 - x2));
if(m_round_cap)
{
- m_ren.semidot(cmp_dist_end, x3, y3, x3 + (y3 - y2), y3 - (x3 - x2));
+ m_ren->semidot(cmp_dist_end, x3, y3, x3 + (y3 - y2), y3 - (x3 - x2));
}
}
break;
@@ -443,37 +501,53 @@ namespace agg
dv.xb2 = 0;
dv.yb2 = 0;
- if(m_accurate_join)
- {
- dv.flags = 0;
- }
- else
+ switch(m_line_join)
{
+ case outline_no_join:
+ dv.flags = 3;
+ break;
+
+ case outline_miter_join:
+ case outline_round_join:
dv.flags =
(prev.diagonal_quadrant() == dv.curr.diagonal_quadrant()) |
((dv.curr.diagonal_quadrant() == dv.next.diagonal_quadrant()) << 1);
+ break;
+
+ case outline_miter_accurate_join:
+ dv.flags = 0;
+ break;
}
- if((dv.flags & 1) == 0)
+ if(m_round_cap)
{
- bisectrix(prev, dv.curr, &dv.xb1, &dv.yb1);
- m_ren.line3(prev,
- x1 + (y2 - y1),
- y1 - (x2 - x1),
- dv.xb1,
- dv.yb1);
+ m_ren->semidot(cmp_dist_start, x1, y1, x1 + (y2 - y1), y1 - (x2 - x1));
}
- else
+ if((dv.flags & 1) == 0)
{
- m_ren.line1(prev,
- x1 + (y2 - y1),
- y1 - (x2 - x1));
+ if(m_line_join == outline_round_join)
+ {
+ m_ren->line3(prev, x1 + (y2 - y1), y1 - (x2 - x1),
+ x2 + (y2 - y1), y2 - (x2 - x1));
+ m_ren->pie(prev.x2, prev.y2,
+ x2 + (y2 - y1), y2 - (x2 - x1),
+ dv.curr.x1 + (dv.curr.y2 - dv.curr.y1),
+ dv.curr.y1 - (dv.curr.x2 - dv.curr.x1));
+ }
+ else
+ {
+ bisectrix(prev, dv.curr, &dv.xb1, &dv.yb1);
+ m_ren->line3(prev, x1 + (y2 - y1), y1 - (x2 - x1),
+ dv.xb1, dv.yb1);
+ }
}
- if(m_round_cap)
+ else
{
- m_ren.semidot(cmp_dist_start, x1, y1, x1 + (y2 - y1), y1 - (x2 - x1));
+ m_ren->line1(prev,
+ x1 + (y2 - y1),
+ y1 - (x2 - x1));
}
- if((dv.flags & 2) == 0)
+ if((dv.flags & 2) == 0 && m_line_join != outline_round_join)
{
bisectrix(dv.curr, dv.next, &dv.xb2, &dv.yb2);
}
@@ -482,23 +556,32 @@ namespace agg
if((dv.flags & 1) == 0)
{
- m_ren.line3(dv.curr,
- dv.xb1,
- dv.yb1,
- dv.curr.x2 + (dv.curr.y2 - dv.curr.y1),
- dv.curr.y2 - (dv.curr.x2 - dv.curr.x1));
+ if(m_line_join == outline_round_join)
+ {
+ m_ren->line3(dv.curr,
+ dv.curr.x1 + (dv.curr.y2 - dv.curr.y1),
+ dv.curr.y1 - (dv.curr.x2 - dv.curr.x1),
+ dv.curr.x2 + (dv.curr.y2 - dv.curr.y1),
+ dv.curr.y2 - (dv.curr.x2 - dv.curr.x1));
+ }
+ else
+ {
+ m_ren->line3(dv.curr, dv.xb1, dv.yb1,
+ dv.curr.x2 + (dv.curr.y2 - dv.curr.y1),
+ dv.curr.y2 - (dv.curr.x2 - dv.curr.x1));
+ }
}
else
{
- m_ren.line2(dv.curr,
- dv.curr.x2 + (dv.curr.y2 - dv.curr.y1),
- dv.curr.y2 - (dv.curr.x2 - dv.curr.x1));
+ m_ren->line2(dv.curr,
+ dv.curr.x2 + (dv.curr.y2 - dv.curr.y1),
+ dv.curr.y2 - (dv.curr.x2 - dv.curr.x1));
}
if(m_round_cap)
{
- m_ren.semidot(cmp_dist_end, dv.curr.x2, dv.curr.y2,
- dv.curr.x2 + (dv.curr.y2 - dv.curr.y1),
- dv.curr.y2 - (dv.curr.x2 - dv.curr.x1));
+ m_ren->semidot(cmp_dist_end, dv.curr.x2, dv.curr.y2,
+ dv.curr.x2 + (dv.curr.y2 - dv.curr.y1),
+ dv.curr.y2 - (dv.curr.x2 - dv.curr.x1));
}
}
diff --git a/agg/inc/agg_rasterizer_scanline_aa.h b/agg/inc/agg_rasterizer_scanline_aa.h
index 03be55dcc62a..d07360e45594 100755
--- a/agg/inc/agg_rasterizer_scanline_aa.h
+++ b/agg/inc/agg_rasterizer_scanline_aa.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -7,6 +7,8 @@
// This software is provided "as is" without express or implied
// warranty, and with no claim as to its suitability for any purpose.
//
+//----------------------------------------------------------------------------
+//
// The author gratefully acknowleges the support of David Turner,
// Robert Wilhelm, and Werner Lemberg - the authors of the FreeType
// libray - in producing this work. See http://www.freetype.org for details.
@@ -17,43 +19,24 @@
// http://www.antigrain.com
//----------------------------------------------------------------------------
//
-// Class rasterizer_scanline_aa
+// Adaptation for 32-bit screen coordinates has been sponsored by
+// Liberty Technology Systems, Inc., visit http://lib-sys.com
//
+// Liberty Technology Systems, Inc. is the provider of
+// PostScript and PDF technology for software developers.
//
//----------------------------------------------------------------------------
#ifndef AGG_RASTERIZER_SCANLINE_AA_INCLUDED
#define AGG_RASTERIZER_SCANLINE_AA_INCLUDED
-#include <string.h>
-#include <math.h>
-#include "agg_basics.h"
-#include "agg_math.h"
+#include "agg_rasterizer_cells_aa.h"
+#include "agg_rasterizer_sl_clip.h"
#include "agg_gamma_functions.h"
-#include "agg_clip_liang_barsky.h"
-#include "agg_render_scanlines.h"
namespace agg
{
- //------------------------------------------------------------------------
- // These constants determine the subpixel accuracy, to be more precise,
- // the number of bits of the fractional part of the coordinates.
- // The possible coordinate capacity in bits can be calculated by formula:
- // sizeof(int) * 8 - poly_base_shift * 2, i.e, for 32-bit integers and
- // 8-bits fractional part the capacity is 16 bits or [-32768...32767].
- enum
- {
- poly_base_shift = 8, //----poly_base_shift
- poly_base_size = 1 << poly_base_shift, //----poly_base_size
- poly_base_mask = poly_base_size - 1 //----poly_base_mask
- };
-
- //--------------------------------------------------------------poly_coord
- inline int poly_coord(double c)
- {
- return int(c * poly_base_size);
- }
//-----------------------------------------------------------------cell_aa
// A pixel cell. There're no constructors defined and it was done
@@ -61,90 +44,25 @@ namespace agg
// array of cells.
struct cell_aa
{
- int16 x;
- int16 y;
- int packed_coord;
- int cover;
- int area;
-
- void set(int x, int y, int c, int a);
- void set_coord(int x, int y);
- void set_cover(int c, int a);
- void add_cover(int c, int a);
- };
-
+ int x;
+ int y;
+ int cover;
+ int area;
- //--------------------------------------------------------------outline_aa
- // An internal class that implements the main rasterization algorithm.
- // Used in the rasterizer. Should not be used direcly.
- class outline_aa
- {
- enum
+ void initial()
{
- cell_block_shift = 12,
- cell_block_size = 1 << cell_block_shift,
- cell_block_mask = cell_block_size - 1,
- cell_block_pool = 256,
- cell_block_limit = 1024
- };
-
- public:
-
- ~outline_aa();
- outline_aa();
-
- void reset();
-
- void move_to(int x, int y);
- void line_to(int x, int y);
-
- int min_x() const { return m_min_x; }
- int min_y() const { return m_min_y; }
- int max_x() const { return m_max_x; }
- int max_y() const { return m_max_y; }
-
- const cell_aa* const* cells();
- unsigned num_cells() { cells(); return m_num_cells; }
- bool sorted() const { return m_sorted; }
-
- private:
- outline_aa(const outline_aa&);
- const outline_aa& operator = (const outline_aa&);
-
- void set_cur_cell(int x, int y);
- void add_cur_cell();
- void sort_cells();
- void render_hline(int ey, int x1, int y1, int x2, int y2);
- void render_line(int x1, int y1, int x2, int y2);
- void allocate_block();
-
- static void qsort_cells(cell_aa** start, unsigned num);
-
- private:
- unsigned m_num_blocks;
- unsigned m_max_blocks;
- unsigned m_cur_block;
- unsigned m_num_cells;
- cell_aa** m_cells;
- cell_aa* m_cur_cell_ptr;
- cell_aa** m_sorted_cells;
- unsigned m_sorted_size;
- cell_aa m_cur_cell;
- int m_cur_x;
- int m_cur_y;
- int m_min_x;
- int m_min_y;
- int m_max_x;
- int m_max_y;
- bool m_sorted;
- };
+ x = 0x7FFFFFFF;
+ y = 0x7FFFFFFF;
+ cover = 0;
+ area = 0;
+ }
+ void style(const cell_aa&) {}
- //----------------------------------------------------------filling_rule_e
- enum filling_rule_e
- {
- fill_non_zero,
- fill_even_odd
+ int not_equal(int ex, int ey, const cell_aa&) const
+ {
+ return (ex - x) | (ey - y);
+ }
};
@@ -152,7 +70,7 @@ namespace agg
// Polygon rasterizer that is used to render filled polygons with
// high-quality Anti-Aliasing. Internally, by default, the class uses
// integer coordinates in format 24.8, i.e. 24 bits for integer part
- // and 8 bits for fractional - see poly_base_shift. This class can be
+ // and 8 bits for fractional - see poly_subpixel_shift. This class can be
// used in the following way:
//
// 1. filling_rule(filling_rule_e ft) - optional.
@@ -179,79 +97,72 @@ namespace agg
//
// filling_rule() and gamma() can be called anytime before "sweeping".
//------------------------------------------------------------------------
- template<unsigned XScale=1, unsigned AA_Shift=8> class rasterizer_scanline_aa
+ template<class Clip=rasterizer_sl_clip_int> class rasterizer_scanline_aa
{
enum status
{
status_initial,
+ status_move_to,
status_line_to,
status_closed
};
- struct iterator
- {
- const cell_aa* const* cells;
- int cover;
- int last_y;
- };
-
public:
- enum
+ typedef Clip clip_type;
+ typedef typename Clip::conv_type conv_type;
+ typedef typename Clip::coord_type coord_type;
+
+ enum aa_scale_e
{
- aa_shift = AA_Shift,
- aa_num = 1 << aa_shift,
- aa_mask = aa_num - 1,
- aa_2num = aa_num * 2,
- aa_2mask = aa_2num - 1
+ aa_shift = 8,
+ aa_scale = 1 << aa_shift,
+ aa_mask = aa_scale - 1,
+ aa_scale2 = aa_scale * 2,
+ aa_mask2 = aa_scale2 - 1
};
//--------------------------------------------------------------------
rasterizer_scanline_aa() :
+ m_outline(),
+ m_clipper(),
m_filling_rule(fill_non_zero),
- m_clipped_start_x(0),
- m_clipped_start_y(0),
+ m_auto_close(true),
m_start_x(0),
m_start_y(0),
- m_prev_x(0),
- m_prev_y(0),
- m_prev_flags(0),
- m_status(status_initial),
- m_clipping(false)
+ m_status(status_initial)
{
int i;
- for(i = 0; i < aa_num; i++) m_gamma[i] = i;
+ for(i = 0; i < aa_scale; i++) m_gamma[i] = i;
}
//--------------------------------------------------------------------
template<class GammaF>
rasterizer_scanline_aa(const GammaF& gamma_function) :
+ m_outline(),
+ m_clipper(m_outline),
m_filling_rule(fill_non_zero),
- m_clipped_start_x(0),
- m_clipped_start_y(0),
+ m_auto_close(true),
m_start_x(0),
m_start_y(0),
- m_prev_x(0),
- m_prev_y(0),
- m_prev_flags(0),
- m_status(status_initial),
- m_clipping(false)
+ m_status(status_initial)
{
gamma(gamma_function);
}
//--------------------------------------------------------------------
void reset();
- void filling_rule(filling_rule_e filling_rule);
- void clip_box(double x1, double y1, double x2, double y2);
void reset_clipping();
+ void clip_box(double x1, double y1, double x2, double y2);
+ void filling_rule(filling_rule_e filling_rule);
+ void auto_close(bool flag) { m_auto_close = flag; }
//--------------------------------------------------------------------
template<class GammaF> void gamma(const GammaF& gamma_function)
{
int i;
- for(i = 0; i < aa_num; i++)
+ for(i = 0; i < aa_scale; i++)
{
- m_gamma[i] = int(floor(gamma_function(double(i) / aa_mask) * aa_mask + 0.5));
+ m_gamma[i] = uround(gamma_function(double(i) / aa_mask) * aa_mask);
}
}
@@ -262,12 +173,31 @@ namespace agg
}
//--------------------------------------------------------------------
- void add_vertex(double x, double y, unsigned cmd);
void move_to(int x, int y);
void line_to(int x, int y);
- void close_polygon();
void move_to_d(double x, double y);
void line_to_d(double x, double y);
+ void close_polygon();
+ void add_vertex(double x, double y, unsigned cmd);
+
+ void edge(int x1, int y1, int x2, int y2);
+ void edge_d(double x1, double y1, double x2, double y2);
+
+ //-------------------------------------------------------------------
+ template<class VertexSource>
+ void add_path(VertexSource& vs, unsigned path_id=0)
+ {
+ double x;
+ double y;
+
+ unsigned cmd;
+ vs.rewind(path_id);
+ if(m_outline.sorted()) reset();
+ while(!is_stop(cmd = vs.vertex(&x, &y)))
+ {
+ add_vertex(x, y, cmd);
+ }
+ }
//--------------------------------------------------------------------
int min_x() const { return m_outline.min_x(); }
@@ -276,17 +206,22 @@ namespace agg
int max_y() const { return m_outline.max_y(); }
//--------------------------------------------------------------------
+ void sort();
+ bool rewind_scanlines();
+ bool navigate_scanline(int y);
+
+ //--------------------------------------------------------------------
AGG_INLINE unsigned calculate_alpha(int area) const
{
- int cover = area >> (poly_base_shift*2 + 1 - aa_shift);
+ int cover = area >> (poly_subpixel_shift*2 + 1 - aa_shift);
if(cover < 0) cover = -cover;
if(m_filling_rule == fill_even_odd)
{
- cover &= aa_2mask;
- if(cover > aa_num)
+ cover &= aa_mask2;
+ if(cover > aa_scale)
{
- cover = aa_2num - cover;
+ cover = aa_scale2 - cover;
}
}
if(cover > aa_mask) cover = aa_mask;
@@ -294,164 +229,84 @@ namespace agg
}
//--------------------------------------------------------------------
- void sort()
- {
- m_outline.cells();
- }
-
-
- //--------------------------------------------------------------------
- bool rewind_scanlines()
- {
- close_polygon();
- m_iterator.cells = m_outline.cells();
- if(m_outline.num_cells() == 0)
- {
- return false;
- }
- m_iterator.cover = 0;
- m_iterator.last_y = (*m_iterator.cells)->y;
- return true;
- }
-
-
- //--------------------------------------------------------------------
template<class Scanline> bool sweep_scanline(Scanline& sl)
{
- sl.reset_spans();
for(;;)
{
- const cell_aa* cur_cell = *m_iterator.cells;
- if(cur_cell == 0) return false;
- ++m_iterator.cells;
- m_iterator.last_y = cur_cell->y;
+ if(m_scan_y > m_outline.max_y()) return false;
+ sl.reset_spans();
+ unsigned num_cells = m_outline.scanline_num_cells(m_scan_y);
+ const cell_aa* const* cells = m_outline.scanline_cells(m_scan_y);
+ int cover = 0;
- for(;;)
+ while(num_cells)
{
- int coord = cur_cell->packed_coord;
- int area = cur_cell->area;
- int last_x = cur_cell->x;
+ const cell_aa* cur_cell = *cells;
+ int x = cur_cell->x;
+ int area = cur_cell->area;
+ unsigned alpha;
- m_iterator.cover += cur_cell->cover;
+ cover += cur_cell->cover;
- //accumulate all cells with the same coordinates
- for(; (cur_cell = *m_iterator.cells) != 0; ++m_iterator.cells)
+ //accumulate all cells with the same X
+ while(--num_cells)
{
- if(cur_cell->packed_coord != coord) break;
- area += cur_cell->area;
- m_iterator.cover += cur_cell->cover;
+ cur_cell = *++cells;
+ if(cur_cell->x != x) break;
+ area += cur_cell->area;
+ cover += cur_cell->cover;
}
- int alpha;
- if(cur_cell == 0 || cur_cell->y != m_iterator.last_y)
- {
-
- if(area)
- {
- alpha = calculate_alpha((m_iterator.cover << (poly_base_shift + 1)) - area);
- if(alpha)
- {
- sl.add_cell(last_x, alpha);
- }
- ++last_x;
- }
- break;
- }
-
- ++m_iterator.cells;
-
if(area)
{
- alpha = calculate_alpha((m_iterator.cover << (poly_base_shift + 1)) - area);
+ alpha = calculate_alpha((cover << (poly_subpixel_shift + 1)) - area);
if(alpha)
{
- sl.add_cell(last_x, alpha);
+ sl.add_cell(x, alpha);
}
- ++last_x;
+ x++;
}
- if(cur_cell->x > last_x)
+ if(num_cells && cur_cell->x > x)
{
- alpha = calculate_alpha(m_iterator.cover << (poly_base_shift + 1));
+ alpha = calculate_alpha(cover << (poly_subpixel_shift + 1));
if(alpha)
{
- sl.add_span(last_x, cur_cell->x - last_x, alpha);
+ sl.add_span(x, cur_cell->x - x, alpha);
}
}
}
- if(sl.num_spans())
- {
- sl.finalize(m_iterator.last_y);
- break;
- }
+
+ if(sl.num_spans()) break;
+ ++m_scan_y;
}
+
+ sl.finalize(m_scan_y);
+ ++m_scan_y;
return true;
}
-
//--------------------------------------------------------------------
bool hit_test(int tx, int ty);
- //--------------------------------------------------------------------
- void add_xy(const double* x, const double* y, unsigned n)
- {
- if(n > 2)
- {
- move_to_d(*x++, *y++);
- --n;
- do
- {
- line_to_d(*x++, *y++);
- }
- while(--n);
- }
- }
-
- //-------------------------------------------------------------------
- template<class VertexSource>
- void add_path(VertexSource& vs, unsigned id=0)
- {
- double x;
- double y;
-
- unsigned cmd;
- vs.rewind(id);
- while(!is_stop(cmd = vs.vertex(&x, &y)))
- {
- add_vertex(x, y, cmd);
- }
- }
-
-
private:
//--------------------------------------------------------------------
// Disable copying
- 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);
- void line_to_no_clip(int x, int y);
- void close_polygon_no_clip();
- void clip_segment(int x, int y);
+ rasterizer_scanline_aa(const rasterizer_scanline_aa<Clip>&);
+ const rasterizer_scanline_aa<Clip>&
+ operator = (const rasterizer_scanline_aa<Clip>&);
private:
- outline_aa m_outline;
- int m_gamma[aa_num];
+ rasterizer_cells_aa<cell_aa> m_outline;
+ clip_type m_clipper;
+ int m_gamma[aa_scale];
filling_rule_e m_filling_rule;
- int m_clipped_start_x;
- int m_clipped_start_y;
- int m_start_x;
- int m_start_y;
- int m_prev_x;
- int m_prev_y;
- unsigned m_prev_flags;
+ bool m_auto_close;
+ coord_type m_start_x;
+ coord_type m_start_y;
unsigned m_status;
- rect m_clip_box;
- bool m_clipping;
- iterator m_iterator;
+ int m_scan_y;
};
@@ -463,277 +318,189 @@ namespace agg
+
+
//------------------------------------------------------------------------
- template<unsigned XScale, unsigned AA_Shift>
- void rasterizer_scanline_aa<XScale, AA_Shift>::reset()
+ template<class Clip>
+ void rasterizer_scanline_aa<Clip>::reset()
{
m_outline.reset();
m_status = status_initial;
}
//------------------------------------------------------------------------
- template<unsigned XScale, unsigned AA_Shift>
- void rasterizer_scanline_aa<XScale, AA_Shift>::filling_rule(filling_rule_e _filling_rule)
+ template<class Clip>
+ void rasterizer_scanline_aa<Clip>::filling_rule(filling_rule_e filling_rule)
{
- m_filling_rule = _filling_rule;
+ m_filling_rule = filling_rule;
}
//------------------------------------------------------------------------
- template<unsigned XScale, unsigned AA_Shift>
- void rasterizer_scanline_aa<XScale, AA_Shift>::clip_box(double x1, double y1, double x2, double y2)
+ template<class Clip>
+ void rasterizer_scanline_aa<Clip>::clip_box(double x1, double y1,
+ double x2, double y2)
{
reset();
- m_clip_box = rect(poly_coord(x1), poly_coord(y1),
- poly_coord(x2), poly_coord(y2));
- m_clip_box.normalize();
- m_clipping = true;
+ m_clipper.clip_box(conv_type::upscale(x1), conv_type::upscale(y1),
+ conv_type::upscale(x2), conv_type::upscale(y2));
}
//------------------------------------------------------------------------
- template<unsigned XScale, unsigned AA_Shift>
- void rasterizer_scanline_aa<XScale, AA_Shift>::reset_clipping()
+ template<class Clip>
+ void rasterizer_scanline_aa<Clip>::reset_clipping()
{
reset();
- m_clipping = false;
+ m_clipper.reset_clipping();
}
-
-
//------------------------------------------------------------------------
- template<unsigned XScale, unsigned AA_Shift>
- void rasterizer_scanline_aa<XScale, AA_Shift>::move_to_no_clip(int x, int y)
+ template<class Clip>
+ void rasterizer_scanline_aa<Clip>::close_polygon()
{
if(m_status == status_line_to)
{
- close_polygon_no_clip();
+ m_clipper.line_to(m_outline, m_start_x, m_start_y);
+ m_status = status_closed;
}
- m_outline.move_to(x * XScale, y);
- m_clipped_start_x = x;
- m_clipped_start_y = y;
- m_status = status_line_to;
}
-
//------------------------------------------------------------------------
- template<unsigned XScale, unsigned AA_Shift>
- void rasterizer_scanline_aa<XScale, AA_Shift>::line_to_no_clip(int x, int y)
+ template<class Clip>
+ void rasterizer_scanline_aa<Clip>::move_to(int x, int y)
{
- if(m_status != status_initial)
- {
- m_outline.line_to(x * XScale, y);
- m_status = status_line_to;
- }
+ if(m_outline.sorted()) reset();
+ if(m_auto_close) close_polygon();
+ m_clipper.move_to(m_start_x = conv_type::downscale(x),
+ m_start_y = conv_type::downscale(y));
+ m_status = status_move_to;
}
-
//------------------------------------------------------------------------
- template<unsigned XScale, unsigned AA_Shift>
- void rasterizer_scanline_aa<XScale, AA_Shift>::close_polygon_no_clip()
+ template<class Clip>
+ void rasterizer_scanline_aa<Clip>::line_to(int x, int y)
{
- if(m_status == status_line_to)
- {
- m_outline.line_to(m_clipped_start_x * XScale, m_clipped_start_y);
- m_status = status_closed;
- }
+ m_clipper.line_to(m_outline,
+ conv_type::downscale(x),
+ conv_type::downscale(y));
+ m_status = status_line_to;
}
-
//------------------------------------------------------------------------
- template<unsigned XScale, unsigned AA_Shift>
- void rasterizer_scanline_aa<XScale, AA_Shift>::clip_segment(int x, int y)
+ template<class Clip>
+ void rasterizer_scanline_aa<Clip>::move_to_d(double x, double y)
{
- unsigned flags = clipping_flags(x, y, m_clip_box);
- if(m_prev_flags == flags)
- {
- if(flags == 0)
- {
- if(m_status == status_initial)
- {
- move_to_no_clip(x, y);
- }
- else
- {
- line_to_no_clip(x, y);
- }
- }
- }
- else
- {
- int cx[4];
- int cy[4];
- unsigned n = clip_liang_barsky(m_prev_x, m_prev_y,
- x, y,
- m_clip_box,
- cx, cy);
- const int* px = cx;
- const int* py = cy;
- while(n--)
- {
- if(m_status == status_initial)
- {
- move_to_no_clip(*px++, *py++);
- }
- else
- {
- line_to_no_clip(*px++, *py++);
- }
- }
- }
- m_prev_flags = flags;
- m_prev_x = x;
- m_prev_y = y;
+ if(m_outline.sorted()) reset();
+ if(m_auto_close) close_polygon();
+ m_clipper.move_to(m_start_x = conv_type::upscale(x),
+ m_start_y = conv_type::upscale(y));
+ m_status = status_move_to;
}
-
-
//------------------------------------------------------------------------
- template<unsigned XScale, unsigned AA_Shift>
- void rasterizer_scanline_aa<XScale, AA_Shift>::add_vertex(double x, double y, unsigned cmd)
+ template<class Clip>
+ void rasterizer_scanline_aa<Clip>::line_to_d(double x, double y)
{
- if(is_close(cmd))
- {
- close_polygon();
- }
- else
- {
- if(is_move_to(cmd))
- {
- move_to(poly_coord(x), poly_coord(y));
- }
- else
- {
- if(is_vertex(cmd))
- {
- line_to(poly_coord(x), poly_coord(y));
- }
- }
- }
+ m_clipper.line_to(m_outline,
+ conv_type::upscale(x),
+ conv_type::upscale(y));
+ m_status = status_line_to;
}
-
-
//------------------------------------------------------------------------
- template<unsigned XScale, unsigned AA_Shift>
- void rasterizer_scanline_aa<XScale, AA_Shift>::move_to(int x, int y)
+ template<class Clip>
+ void rasterizer_scanline_aa<Clip>::add_vertex(double x, double y, unsigned cmd)
{
- if(m_clipping)
+ if(is_move_to(cmd))
{
- if(m_outline.sorted())
- {
- reset();
- }
- if(m_status == status_line_to)
- {
- close_polygon();
- }
- m_prev_x = m_start_x = x;
- m_prev_y = m_start_y = y;
- m_status = status_initial;
- m_prev_flags = clipping_flags(x, y, m_clip_box);
- if(m_prev_flags == 0)
- {
- move_to_no_clip(x, y);
- }
+ move_to_d(x, y);
}
else
+ if(is_vertex(cmd))
{
- move_to_no_clip(x, y);
- }
- }
-
- //------------------------------------------------------------------------
- template<unsigned XScale, unsigned AA_Shift>
- void rasterizer_scanline_aa<XScale, AA_Shift>::line_to(int x, int y)
- {
- if(m_clipping)
- {
- clip_segment(x, y);
+ line_to_d(x, y);
}
else
+ if(is_close(cmd))
{
- line_to_no_clip(x, y);
+ close_polygon();
}
}
//------------------------------------------------------------------------
- template<unsigned XScale, unsigned AA_Shift>
- void rasterizer_scanline_aa<XScale, AA_Shift>::close_polygon()
+ template<class Clip>
+ void rasterizer_scanline_aa<Clip>::edge(int x1, int y1, int x2, int y2)
{
- if(m_clipping)
- {
- clip_segment(m_start_x, m_start_y);
- }
- close_polygon_no_clip();
+ if(m_outline.sorted()) reset();
+ m_clipper.move_to(conv_type::downscale(x1), conv_type::downscale(y1));
+ m_clipper.line_to(m_outline,
+ conv_type::downscale(x2),
+ conv_type::downscale(y2));
+ m_status = status_move_to;
}
//------------------------------------------------------------------------
- template<unsigned XScale, unsigned AA_Shift>
- void rasterizer_scanline_aa<XScale, AA_Shift>::move_to_d(double x, double y)
+ template<class Clip>
+ void rasterizer_scanline_aa<Clip>::edge_d(double x1, double y1,
+ double x2, double y2)
{
- move_to(poly_coord(x), poly_coord(y));
+ if(m_outline.sorted()) reset();
+ m_clipper.move_to(conv_type::upscale(x1), conv_type::upscale(y1));
+ m_clipper.line_to(m_outline,
+ conv_type::upscale(x2),
+ conv_type::upscale(y2));
+ m_status = status_move_to;
}
//------------------------------------------------------------------------
- template<unsigned XScale, unsigned AA_Shift>
- void rasterizer_scanline_aa<XScale, AA_Shift>::line_to_d(double x, double y)
+ template<class Clip>
+ void rasterizer_scanline_aa<Clip>::sort()
{
- line_to(poly_coord(x), poly_coord(y));
+ if(m_auto_close) close_polygon();
+ m_outline.sort_cells();
}
-
//------------------------------------------------------------------------
- template<unsigned XScale, unsigned AA_Shift>
- bool rasterizer_scanline_aa<XScale, AA_Shift>::hit_test(int tx, int ty)
+ template<class Clip>
+ AGG_INLINE bool rasterizer_scanline_aa<Clip>::rewind_scanlines()
{
- close_polygon();
- const cell_aa* const* cells = m_outline.cells();
- if(m_outline.num_cells() == 0) return false;
-
- int cover = 0;
-
- const cell_aa* cur_cell = *cells++;
- for(;;)
+ if(m_auto_close) close_polygon();
+ m_outline.sort_cells();
+ if(m_outline.total_cells() == 0)
{
- int alpha;
- int coord = cur_cell->packed_coord;
- int x = cur_cell->x;
- int y = cur_cell->y;
-
- if(y > ty) return false;
+ return false;
+ }
+ m_scan_y = m_outline.min_y();
+ return true;
+ }
- int area = cur_cell->area;
- cover += cur_cell->cover;
- while((cur_cell = *cells++) != 0)
- {
- if(cur_cell->packed_coord != coord) break;
- area += cur_cell->area;
- cover += cur_cell->cover;
- }
+ //------------------------------------------------------------------------
+ template<class Clip>
+ AGG_INLINE bool rasterizer_scanline_aa<Clip>::navigate_scanline(int y)
+ {
+ if(m_auto_close) close_polygon();
+ m_outline.sort_cells();
+ if(m_outline.total_cells() == 0 ||
+ y < m_outline.min_y() ||
+ y > m_outline.max_y())
+ {
+ return false;
+ }
+ m_scan_y = y;
+ return true;
+ }
- if(area)
- {
- alpha = calculate_alpha((cover << (poly_base_shift + 1)) - area);
- if(alpha)
- {
- if(tx == x && ty == y) return true;
- }
- x++;
- }
+ //------------------------------------------------------------------------
+ template<class Clip>
+ bool rasterizer_scanline_aa<Clip>::hit_test(int tx, int ty)
+ {
+ if(!navigate_scanline(ty)) return false;
+ scanline_hit_test sl(tx);
+ sweep_scanline(sl);
+ return sl.hit();
+ }
- if(!cur_cell) break;
- if(cur_cell->x > x)
- {
- alpha = calculate_alpha(cover << (poly_base_shift + 1));
- if(alpha)
- {
- if(ty == y && tx >= x && tx <= cur_cell->x) return true;
- }
- }
- }
- return false;
- }
}
diff --git a/agg/inc/agg_rasterizer_sl_clip.h b/agg/inc/agg_rasterizer_sl_clip.h
new file mode 100644
index 000000000000..8b00aeed6605
--- /dev/null
+++ b/agg/inc/agg_rasterizer_sl_clip.h
@@ -0,0 +1,351 @@
+//----------------------------------------------------------------------------
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
+//
+// Permission to copy, use, modify, sell and distribute this software
+// is granted provided this copyright notice appears in all copies.
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+//
+//----------------------------------------------------------------------------
+// Contact: mcseem@antigrain.com
+// mcseemagg@yahoo.com
+// http://www.antigrain.com
+//----------------------------------------------------------------------------
+#ifndef AGG_RASTERIZER_SL_CLIP_INCLUDED
+#define AGG_RASTERIZER_SL_CLIP_INCLUDED
+
+#include "agg_clip_liang_barsky.h"
+
+namespace agg
+{
+ //--------------------------------------------------------poly_max_coord_e
+ enum poly_max_coord_e
+ {
+ poly_max_coord = (1 << 30) - 1 //----poly_max_coord
+ };
+
+ //------------------------------------------------------------ras_conv_int
+ struct ras_conv_int
+ {
+ typedef int coord_type;
+ static AGG_INLINE int mul_div(double a, double b, double c)
+ {
+ return iround(a * b / c);
+ }
+ static int xi(int v) { return v; }
+ static int yi(int v) { return v; }
+ static int upscale(double v) { return iround(v * poly_subpixel_scale); }
+ static int downscale(int v) { return v; }
+ };
+
+ //--------------------------------------------------------ras_conv_int_sat
+ struct ras_conv_int_sat
+ {
+ typedef int coord_type;
+ static AGG_INLINE int mul_div(double a, double b, double c)
+ {
+ return saturation<poly_max_coord>::iround(a * b / c);
+ }
+ static int xi(int v) { return v; }
+ static int yi(int v) { return v; }
+ static int upscale(double v)
+ {
+ return saturation<poly_max_coord>::iround(v * poly_subpixel_scale);
+ }
+ static int downscale(int v) { return v; }
+ };
+
+ //---------------------------------------------------------ras_conv_int_3x
+ struct ras_conv_int_3x
+ {
+ typedef int coord_type;
+ static AGG_INLINE int mul_div(double a, double b, double c)
+ {
+ return iround(a * b / c);
+ }
+ static int xi(int v) { return v * 3; }
+ static int yi(int v) { return v; }
+ static int upscale(double v) { return iround(v * poly_subpixel_scale); }
+ static int downscale(int v) { return v; }
+ };
+
+ //-----------------------------------------------------------ras_conv_dbl
+ struct ras_conv_dbl
+ {
+ typedef double coord_type;
+ static AGG_INLINE double mul_div(double a, double b, double c)
+ {
+ return a * b / c;
+ }
+ static int xi(double v) { return iround(v * poly_subpixel_scale); }
+ static int yi(double v) { return iround(v * poly_subpixel_scale); }
+ static double upscale(double v) { return v; }
+ static double downscale(int v) { return v / double(poly_subpixel_scale); }
+ };
+
+ //--------------------------------------------------------ras_conv_dbl_3x
+ struct ras_conv_dbl_3x
+ {
+ typedef double coord_type;
+ static AGG_INLINE double mul_div(double a, double b, double c)
+ {
+ return a * b / c;
+ }
+ static int xi(double v) { return iround(v * poly_subpixel_scale * 3); }
+ static int yi(double v) { return iround(v * poly_subpixel_scale); }
+ static double upscale(double v) { return v; }
+ static double downscale(int v) { return v / double(poly_subpixel_scale); }
+ };
+
+
+
+
+
+ //------------------------------------------------------rasterizer_sl_clip
+ template<class Conv> class rasterizer_sl_clip
+ {
+ public:
+ typedef Conv conv_type;
+ typedef typename Conv::coord_type coord_type;
+ typedef rect_base<coord_type> rect_type;
+
+ //--------------------------------------------------------------------
+ rasterizer_sl_clip() :
+ m_clip_box(0,0,0,0),
+ m_x1(0),
+ m_y1(0),
+ m_f1(0),
+ m_clipping(false)
+ {}
+
+ //--------------------------------------------------------------------
+ void reset_clipping()
+ {
+ m_clipping = false;
+ }
+
+ //--------------------------------------------------------------------
+ void clip_box(coord_type x1, coord_type y1, coord_type x2, coord_type y2)
+ {
+ m_clip_box = rect_type(x1, y1, x2, y2);
+ m_clip_box.normalize();
+ m_clipping = true;
+ }
+
+ //--------------------------------------------------------------------
+ void move_to(coord_type x1, coord_type y1)
+ {
+ m_x1 = x1;
+ m_y1 = y1;
+ if(m_clipping) m_f1 = clipping_flags(x1, y1, m_clip_box);
+ }
+
+ private:
+ //------------------------------------------------------------------------
+ template<class Rasterizer>
+ AGG_INLINE void line_clip_y(Rasterizer& ras,
+ coord_type x1, coord_type y1,
+ coord_type x2, coord_type y2,
+ unsigned f1, unsigned f2) const
+ {
+ f1 &= 10;
+ f2 &= 10;
+ if((f1 | f2) == 0)
+ {
+ // Fully visible
+ ras.line(Conv::xi(x1), Conv::yi(y1), Conv::xi(x2), Conv::yi(y2));
+ }
+ else
+ {
+ if(f1 == f2)
+ {
+ // Invisible by Y
+ return;
+ }
+
+ coord_type tx1 = x1;
+ coord_type ty1 = y1;
+ coord_type tx2 = x2;
+ coord_type ty2 = y2;
+
+ if(f1 & 8) // y1 < clip.y1
+ {
+ tx1 = x1 + Conv::mul_div(m_clip_box.y1-y1, x2-x1, y2-y1);
+ ty1 = m_clip_box.y1;
+ }
+
+ if(f1 & 2) // y1 > clip.y2
+ {
+ tx1 = x1 + Conv::mul_div(m_clip_box.y2-y1, x2-x1, y2-y1);
+ ty1 = m_clip_box.y2;
+ }
+
+ if(f2 & 8) // y2 < clip.y1
+ {
+ tx2 = x1 + Conv::mul_div(m_clip_box.y1-y1, x2-x1, y2-y1);
+ ty2 = m_clip_box.y1;
+ }
+
+ if(f2 & 2) // y2 > clip.y2
+ {
+ tx2 = x1 + Conv::mul_div(m_clip_box.y2-y1, x2-x1, y2-y1);
+ ty2 = m_clip_box.y2;
+ }
+ ras.line(Conv::xi(tx1), Conv::yi(ty1),
+ Conv::xi(tx2), Conv::yi(ty2));
+ }
+ }
+
+
+ public:
+ //--------------------------------------------------------------------
+ template<class Rasterizer>
+ void line_to(Rasterizer& ras, coord_type x2, coord_type y2)
+ {
+ if(m_clipping)
+ {
+ unsigned f2 = clipping_flags(x2, y2, m_clip_box);
+
+ if((m_f1 & 10) == (f2 & 10) && (m_f1 & 10) != 0)
+ {
+ // Invisible by Y
+ m_x1 = x2;
+ m_y1 = y2;
+ m_f1 = f2;
+ return;
+ }
+
+ coord_type x1 = m_x1;
+ coord_type y1 = m_y1;
+ unsigned f1 = m_f1;
+ coord_type y3, y4;
+ unsigned f3, f4;
+
+ switch(((f1 & 5) << 1) | (f2 & 5))
+ {
+ case 0: // Visible by X
+ line_clip_y(ras, x1, y1, x2, y2, f1, f2);
+ break;
+
+ case 1: // x2 > clip.x2
+ y3 = y1 + Conv::mul_div(m_clip_box.x2-x1, y2-y1, x2-x1);
+ f3 = clipping_flags_y(y3, m_clip_box);
+ line_clip_y(ras, x1, y1, m_clip_box.x2, y3, f1, f3);
+ line_clip_y(ras, m_clip_box.x2, y3, m_clip_box.x2, y2, f3, f2);
+ break;
+
+ case 2: // x1 > clip.x2
+ y3 = y1 + Conv::mul_div(m_clip_box.x2-x1, y2-y1, x2-x1);
+ f3 = clipping_flags_y(y3, m_clip_box);
+ line_clip_y(ras, m_clip_box.x2, y1, m_clip_box.x2, y3, f1, f3);
+ line_clip_y(ras, m_clip_box.x2, y3, x2, y2, f3, f2);
+ break;
+
+ case 3: // x1 > clip.x2 && x2 > clip.x2
+ line_clip_y(ras, m_clip_box.x2, y1, m_clip_box.x2, y2, f1, f2);
+ break;
+
+ case 4: // x2 < clip.x1
+ y3 = y1 + Conv::mul_div(m_clip_box.x1-x1, y2-y1, x2-x1);
+ f3 = clipping_flags_y(y3, m_clip_box);
+ line_clip_y(ras, x1, y1, m_clip_box.x1, y3, f1, f3);
+ line_clip_y(ras, m_clip_box.x1, y3, m_clip_box.x1, y2, f3, f2);
+ break;
+
+ case 6: // x1 > clip.x2 && x2 < clip.x1
+ y3 = y1 + Conv::mul_div(m_clip_box.x2-x1, y2-y1, x2-x1);
+ y4 = y1 + Conv::mul_div(m_clip_box.x1-x1, y2-y1, x2-x1);
+ f3 = clipping_flags_y(y3, m_clip_box);
+ f4 = clipping_flags_y(y4, m_clip_box);
+ line_clip_y(ras, m_clip_box.x2, y1, m_clip_box.x2, y3, f1, f3);
+ line_clip_y(ras, m_clip_box.x2, y3, m_clip_box.x1, y4, f3, f4);
+ line_clip_y(ras, m_clip_box.x1, y4, m_clip_box.x1, y2, f4, f2);
+ break;
+
+ case 8: // x1 < clip.x1
+ y3 = y1 + Conv::mul_div(m_clip_box.x1-x1, y2-y1, x2-x1);
+ f3 = clipping_flags_y(y3, m_clip_box);
+ line_clip_y(ras, m_clip_box.x1, y1, m_clip_box.x1, y3, f1, f3);
+ line_clip_y(ras, m_clip_box.x1, y3, x2, y2, f3, f2);
+ break;
+
+ case 9: // x1 < clip.x1 && x2 > clip.x2
+ y3 = y1 + Conv::mul_div(m_clip_box.x1-x1, y2-y1, x2-x1);
+ y4 = y1 + Conv::mul_div(m_clip_box.x2-x1, y2-y1, x2-x1);
+ f3 = clipping_flags_y(y3, m_clip_box);
+ f4 = clipping_flags_y(y4, m_clip_box);
+ line_clip_y(ras, m_clip_box.x1, y1, m_clip_box.x1, y3, f1, f3);
+ line_clip_y(ras, m_clip_box.x1, y3, m_clip_box.x2, y4, f3, f4);
+ line_clip_y(ras, m_clip_box.x2, y4, m_clip_box.x2, y2, f4, f2);
+ break;
+
+ case 12: // x1 < clip.x1 && x2 < clip.x1
+ line_clip_y(ras, m_clip_box.x1, y1, m_clip_box.x1, y2, f1, f2);
+ break;
+ }
+ m_f1 = f2;
+ }
+ else
+ {
+ ras.line(Conv::xi(m_x1), Conv::yi(m_y1),
+ Conv::xi(x2), Conv::yi(y2));
+ }
+ m_x1 = x2;
+ m_y1 = y2;
+ }
+
+
+ private:
+ rect_type m_clip_box;
+ coord_type m_x1;
+ coord_type m_y1;
+ unsigned m_f1;
+ bool m_clipping;
+ };
+
+
+
+
+ //---------------------------------------------------rasterizer_sl_no_clip
+ class rasterizer_sl_no_clip
+ {
+ public:
+ typedef ras_conv_int conv_type;
+ typedef int coord_type;
+
+ rasterizer_sl_no_clip() : m_x1(0), m_y1(0) {}
+
+ void reset_clipping() {}
+ void clip_box(coord_type x1, coord_type y1, coord_type x2, coord_type y2) {}
+ void move_to(coord_type x1, coord_type y1) { m_x1 = x1; m_y1 = y1; }
+
+ template<class Rasterizer>
+ void line_to(Rasterizer& ras, coord_type x2, coord_type y2)
+ {
+ ras.line(m_x1, m_y1, x2, y2);
+ m_x1 = x2;
+ m_y1 = y2;
+ }
+
+ private:
+ int m_x1, m_y1;
+ };
+
+
+ // -----rasterizer_sl_clip_int
+ // -----rasterizer_sl_clip_int_sat
+ // -----rasterizer_sl_clip_int_3x
+ // -----rasterizer_sl_clip_dbl
+ // -----rasterizer_sl_clip_dbl_3x
+ //------------------------------------------------------------------------
+ typedef rasterizer_sl_clip<ras_conv_int> rasterizer_sl_clip_int;
+ typedef rasterizer_sl_clip<ras_conv_int_sat> rasterizer_sl_clip_int_sat;
+ typedef rasterizer_sl_clip<ras_conv_int_3x> rasterizer_sl_clip_int_3x;
+ typedef rasterizer_sl_clip<ras_conv_dbl> rasterizer_sl_clip_dbl;
+ typedef rasterizer_sl_clip<ras_conv_dbl_3x> rasterizer_sl_clip_dbl_3x;
+
+
+}
+
+#endif
diff --git a/agg/inc/agg_render_scanlines.h b/agg/inc/agg_render_scanlines.h
deleted file mode 100755
index 60ddecf5c2d6..000000000000
--- a/agg/inc/agg_render_scanlines.h
+++ /dev/null
@@ -1,66 +0,0 @@
-//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
-// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
-//
-// Permission to copy, use, modify, sell and distribute this software
-// is granted provided this copyright notice appears in all copies.
-// This software is provided "as is" without express or implied
-// warranty, and with no claim as to its suitability for any purpose.
-//
-//----------------------------------------------------------------------------
-// Contact: mcseem@antigrain.com
-// mcseemagg@yahoo.com
-// http://www.antigrain.com
-//----------------------------------------------------------------------------
-
-#ifndef AGG_RENDER_SCANLINES_INCLUDED
-#define AGG_RENDER_SCANLINES_INCLUDED
-
-#include "agg_basics.h"
-
-namespace agg
-{
- //========================================================render_scanlines
- template<class Rasterizer, class Scanline, class Renderer>
- void render_scanlines(Rasterizer& ras, Scanline& sl, Renderer& ren)
- {
- if(ras.rewind_scanlines())
- {
- sl.reset(ras.min_x(), ras.max_x());
- ren.prepare(unsigned(ras.max_x() - ras.min_x() + 2));
-
- while(ras.sweep_scanline(sl))
- {
- ren.render(sl);
- }
- }
- }
-
-
- //========================================================render_all_paths
- template<class Rasterizer, class Scanline, class Renderer,
- class VertexSource, class ColorStorage, class PathId>
- void render_all_paths(Rasterizer& ras,
- Scanline& sl,
- Renderer& r,
- VertexSource& vs,
- const ColorStorage& as,
- const PathId& id,
- unsigned num_paths)
- {
- for(unsigned i = 0; i < num_paths; i++)
- {
- ras.reset();
- ras.add_path(vs, id[i]);
- r.color(as[i]);
- render_scanlines(ras, sl, r);
- }
- }
-
-
-}
-
-#endif
-
-
-
diff --git a/agg/inc/agg_renderer_base.h b/agg/inc/agg_renderer_base.h
index 1ef44fecc6d2..349309d741d1 100755
--- a/agg/inc/agg_renderer_base.h
+++ b/agg/inc/agg_renderer_base.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -32,12 +32,18 @@ namespace agg
public:
typedef PixelFormat pixfmt_type;
typedef typename pixfmt_type::color_type color_type;
+ typedef typename pixfmt_type::row_data row_data;
//--------------------------------------------------------------------
- renderer_base(pixfmt_type& _ren) :
- m_ren(&_ren),
- m_clip_box(0, 0, _ren.width() - 1, _ren.height() - 1)
+ renderer_base() : m_ren(0), m_clip_box(1, 1, 0, 0) {}
+ explicit renderer_base(pixfmt_type& ren) :
+ m_ren(&ren),
+ m_clip_box(0, 0, ren.width() - 1, ren.height() - 1)
+ {}
+ void attach(pixfmt_type& ren)
{
+ m_ren = &ren;
+ m_clip_box = rect_i(0, 0, ren.width() - 1, ren.height() - 1);
}
//--------------------------------------------------------------------
@@ -51,9 +57,9 @@ namespace agg
//--------------------------------------------------------------------
bool clip_box(int x1, int y1, int x2, int y2)
{
- rect cb(x1, y1, x2, y2);
+ rect_i cb(x1, y1, x2, y2);
cb.normalize();
- if(cb.clip(rect(0, 0, width() - 1, height() - 1)))
+ if(cb.clip(rect_i(0, 0, width() - 1, height() - 1)))
{
m_clip_box = cb;
return true;
@@ -101,22 +107,18 @@ namespace agg
}
//--------------------------------------------------------------------
- void first_clip_box() {}
- bool next_clip_box() { return false; }
+ const rect_i& clip_box() const { return m_clip_box; }
+ int xmin() const { return m_clip_box.x1; }
+ int ymin() const { return m_clip_box.y1; }
+ int xmax() const { return m_clip_box.x2; }
+ int ymax() const { return m_clip_box.y2; }
//--------------------------------------------------------------------
- const rect& clip_box() const { return m_clip_box; }
- int xmin() const { return m_clip_box.x1; }
- int ymin() const { return m_clip_box.y1; }
- int xmax() const { return m_clip_box.x2; }
- int ymax() const { return m_clip_box.y2; }
-
- //--------------------------------------------------------------------
- const rect& bounding_clip_box() const { return m_clip_box; }
- int bounding_xmin() const { return m_clip_box.x1; }
- int bounding_ymin() const { return m_clip_box.y1; }
- int bounding_xmax() const { return m_clip_box.x2; }
- int bounding_ymax() const { return m_clip_box.y2; }
+ const rect_i& bounding_clip_box() const { return m_clip_box; }
+ int bounding_xmin() const { return m_clip_box.x1; }
+ int bounding_ymin() const { return m_clip_box.y1; }
+ int bounding_xmax() const { return m_clip_box.x2; }
+ int bounding_ymax() const { return m_clip_box.y2; }
//--------------------------------------------------------------------
void clear(const color_type& c)
@@ -131,6 +133,7 @@ namespace agg
}
}
+
//--------------------------------------------------------------------
void copy_pixel(int x, int y, const color_type& c)
{
@@ -223,7 +226,7 @@ namespace agg
//--------------------------------------------------------------------
void copy_bar(int x1, int y1, int x2, int y2, const color_type& c)
{
- rect rc(x1, y1, x2, y2);
+ rect_i rc(x1, y1, x2, y2);
rc.normalize();
if(rc.clip(clip_box()))
{
@@ -239,7 +242,7 @@ namespace agg
void blend_bar(int x1, int y1, int x2, int y2,
const color_type& c, cover_type cover)
{
- rect rc(x1, y1, x2, y2);
+ rect_i rc(x1, y1, x2, y2);
rc.normalize();
if(rc.clip(clip_box()))
{
@@ -255,7 +258,6 @@ namespace agg
}
}
-
//--------------------------------------------------------------------
void blend_solid_hspan(int x, int y, int len,
const color_type& c,
@@ -302,11 +304,9 @@ namespace agg
m_ren->blend_solid_vspan(x, y, len, c, covers);
}
+
//--------------------------------------------------------------------
- void blend_color_hspan(int x, int y, int len,
- const color_type* colors,
- const cover_type* covers,
- cover_type cover = cover_full)
+ void copy_color_hspan(int x, int y, int len, const color_type* colors)
{
if(y > ymax()) return;
if(y < ymin()) return;
@@ -316,7 +316,6 @@ namespace agg
int d = xmin() - x;
len -= d;
if(len <= 0) return;
- if(covers) covers += d;
colors += d;
x = xmin();
}
@@ -325,14 +324,12 @@ namespace agg
len = xmax() - x + 1;
if(len <= 0) return;
}
- m_ren->blend_color_hspan(x, y, len, colors, covers, cover);
+ m_ren->copy_color_hspan(x, y, len, colors);
}
+
//--------------------------------------------------------------------
- void blend_color_vspan(int x, int y, int len,
- const color_type* colors,
- const cover_type* covers,
- cover_type cover = cover_full)
+ void copy_color_vspan(int x, int y, int len, const color_type* colors)
{
if(x > xmax()) return;
if(x < xmin()) return;
@@ -342,7 +339,6 @@ namespace agg
int d = ymin() - y;
len -= d;
if(len <= 0) return;
- if(covers) covers += d;
colors += d;
y = ymin();
}
@@ -351,15 +347,15 @@ namespace agg
len = ymax() - y + 1;
if(len <= 0) return;
}
- m_ren->blend_color_vspan(x, y, len, colors, covers, cover);
+ m_ren->copy_color_vspan(x, y, len, colors);
}
//--------------------------------------------------------------------
- void blend_opaque_color_hspan(int x, int y, int len,
- const color_type* colors,
- const cover_type* covers,
- cover_type cover = cover_full)
+ void blend_color_hspan(int x, int y, int len,
+ const color_type* colors,
+ const cover_type* covers,
+ cover_type cover = agg::cover_full)
{
if(y > ymax()) return;
if(y < ymin()) return;
@@ -378,14 +374,14 @@ namespace agg
len = xmax() - x + 1;
if(len <= 0) return;
}
- m_ren->blend_opaque_color_hspan(x, y, len, colors, covers, cover);
+ m_ren->blend_color_hspan(x, y, len, colors, covers, cover);
}
//--------------------------------------------------------------------
- void blend_opaque_color_vspan(int x, int y, int len,
- const color_type* colors,
- const cover_type* covers,
- cover_type cover = cover_full)
+ void blend_color_vspan(int x, int y, int len,
+ const color_type* colors,
+ const cover_type* covers,
+ cover_type cover = agg::cover_full)
{
if(x > xmax()) return;
if(x < xmin()) return;
@@ -404,51 +400,14 @@ namespace agg
len = ymax() - y + 1;
if(len <= 0) return;
}
- m_ren->blend_opaque_color_vspan(x, y, len, colors, covers, cover);
- }
-
-
- //--------------------------------------------------------------------
- void blend_color_hspan_no_clip(int x, int y, int len,
- const color_type* colors,
- const cover_type* covers,
- cover_type cover = cover_full)
- {
- m_ren->blend_color_hspan(x, y, len, colors, covers, cover);
- }
-
- //--------------------------------------------------------------------
- void blend_color_vspan_no_clip(int x, int y, int len,
- const color_type* colors,
- const cover_type* covers,
- cover_type cover = cover_full)
- {
m_ren->blend_color_vspan(x, y, len, colors, covers, cover);
}
//--------------------------------------------------------------------
- void blend_opaque_color_hspan_no_clip(int x, int y, int len,
- const color_type* colors,
- const cover_type* covers,
- cover_type cover = cover_full)
+ rect_i clip_rect_area(rect_i& dst, rect_i& src, int wsrc, int hsrc) const
{
- m_ren->blend_opaque_color_hspan(x, y, len, colors, covers, cover);
- }
-
- //--------------------------------------------------------------------
- void blend_opaque_color_vspan_no_clip(int x, int y, int len,
- const color_type* colors,
- const cover_type* covers,
- cover_type cover = cover_full)
- {
- m_ren->blend_opaque_color_vspan(x, y, len, colors, covers, cover);
- }
-
- //--------------------------------------------------------------------
- rect clip_rect_area(rect& dst, rect& src, int wsrc, int hsrc) const
- {
- rect rc(0,0,0,0);
- rect cb = clip_box();
+ rect_i rc(0,0,0,0);
+ rect_i cb = clip_box();
++cb.x2;
++cb.y2;
@@ -488,14 +447,14 @@ namespace agg
return rc;
}
-
//--------------------------------------------------------------------
- void copy_from(const rendering_buffer& src,
- const rect* rect_src_ptr = 0,
+ template<class RenBuf>
+ void copy_from(const RenBuf& src,
+ const rect_i* rect_src_ptr = 0,
int dx = 0,
int dy = 0)
{
- rect rsrc(0, 0, src.width(), src.height());
+ rect_i rsrc(0, 0, src.width(), src.height());
if(rect_src_ptr)
{
rsrc.x1 = rect_src_ptr->x1;
@@ -505,12 +464,12 @@ namespace agg
}
// Version with xdst, ydst (absolute positioning)
- //rect rdst(xdst, ydst, xdst + rsrc.x2 - rsrc.x1, ydst + rsrc.y2 - rsrc.y1);
+ //rect_i 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_i rdst(rsrc.x1 + dx, rsrc.y1 + dy, rsrc.x2 + dx, rsrc.y2 + dy);
- rect rc = clip_rect_area(rdst, rsrc, src.width(), src.height());
+ rect_i rc = clip_rect_area(rdst, rsrc, src.width(), src.height());
if(rc.x2 > 0)
{
@@ -534,16 +493,15 @@ namespace agg
}
}
-
-
//--------------------------------------------------------------------
template<class SrcPixelFormatRenderer>
void blend_from(const SrcPixelFormatRenderer& src,
- const rect* rect_src_ptr = 0,
- int dx = 0,
- int dy = 0)
+ const rect_i* rect_src_ptr = 0,
+ int dx = 0,
+ int dy = 0,
+ cover_type cover = agg::cover_full)
{
- rect rsrc(0, 0, src.width(), src.height());
+ rect_i rsrc(0, 0, src.width(), src.height());
if(rect_src_ptr)
{
rsrc.x1 = rect_src_ptr->x1;
@@ -553,12 +511,11 @@ namespace agg
}
// Version with xdst, ydst (absolute positioning)
- //rect rdst(xdst, ydst, xdst + rsrc.x2 - rsrc.x1, ydst + rsrc.y2 - rsrc.y1);
+ //rect_i 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());
+ rect_i rdst(rsrc.x1 + dx, rsrc.y1 + dy, rsrc.x2 + dx, rsrc.y2 + dy);
+ rect_i rc = clip_rect_area(rdst, rsrc, src.width(), src.height());
if(rc.x2 > 0)
{
@@ -571,30 +528,31 @@ namespace agg
}
while(rc.y2 > 0)
{
- typename SrcPixelFormatRenderer::row_data span = src.span(rsrc.x1, rsrc.y1);
- if(span.ptr)
+ typename SrcPixelFormatRenderer::row_data rw = src.row(rsrc.y1);
+ if(rw.ptr)
{
int x1src = rsrc.x1;
int x1dst = rdst.x1;
int len = rc.x2;
- if(span.x1 > x1src)
+ if(rw.x1 > x1src)
{
- x1dst += span.x1 - x1src;
- len -= span.x1 - x1src;
- x1src = span.x1;
+ x1dst += rw.x1 - x1src;
+ len -= rw.x1 - x1src;
+ x1src = rw.x1;
}
if(len > 0)
{
- if(x1src + len-1 > span.x2)
+ if(x1src + len-1 > rw.x2)
{
- len -= x1src + len - span.x2 - 1;
+ len -= x1src + len - rw.x2 - 1;
}
if(len > 0)
{
- m_ren->blend_from(src, span.ptr,
+ m_ren->blend_from(src,
x1dst, rdst.y1,
x1src, rsrc.y1,
- len);
+ len,
+ cover);
}
}
}
@@ -605,11 +563,153 @@ namespace agg
}
}
+ //--------------------------------------------------------------------
+ template<class SrcPixelFormatRenderer>
+ void blend_from_color(const SrcPixelFormatRenderer& src,
+ const color_type& color,
+ const rect_i* rect_src_ptr = 0,
+ int dx = 0,
+ int dy = 0,
+ cover_type cover = agg::cover_full)
+ {
+ rect_i 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_i rdst(xdst, ydst, xdst + rsrc.x2 - rsrc.x1, ydst + rsrc.y2 - rsrc.y1);
+ // Version with dx, dy (relative positioning)
+ rect_i rdst(rsrc.x1 + dx, rsrc.y1 + dy, rsrc.x2 + dx, rsrc.y2 + dy);
+ rect_i 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 rw = src.row(rsrc.y1);
+ if(rw.ptr)
+ {
+ int x1src = rsrc.x1;
+ int x1dst = rdst.x1;
+ int len = rc.x2;
+ if(rw.x1 > x1src)
+ {
+ x1dst += rw.x1 - x1src;
+ len -= rw.x1 - x1src;
+ x1src = rw.x1;
+ }
+ if(len > 0)
+ {
+ if(x1src + len-1 > rw.x2)
+ {
+ len -= x1src + len - rw.x2 - 1;
+ }
+ if(len > 0)
+ {
+ m_ren->blend_from_color(src,
+ color,
+ x1dst, rdst.y1,
+ x1src, rsrc.y1,
+ len,
+ cover);
+ }
+ }
+ }
+ rdst.y1 += incy;
+ rsrc.y1 += incy;
+ --rc.y2;
+ }
+ }
+ }
+
+ //--------------------------------------------------------------------
+ template<class SrcPixelFormatRenderer>
+ void blend_from_lut(const SrcPixelFormatRenderer& src,
+ const color_type* color_lut,
+ const rect_i* rect_src_ptr = 0,
+ int dx = 0,
+ int dy = 0,
+ cover_type cover = agg::cover_full)
+ {
+ rect_i 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_i rdst(xdst, ydst, xdst + rsrc.x2 - rsrc.x1, ydst + rsrc.y2 - rsrc.y1);
+
+ // Version with dx, dy (relative positioning)
+ rect_i rdst(rsrc.x1 + dx, rsrc.y1 + dy, rsrc.x2 + dx, rsrc.y2 + dy);
+ rect_i 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 rw = src.row(rsrc.y1);
+ if(rw.ptr)
+ {
+ int x1src = rsrc.x1;
+ int x1dst = rdst.x1;
+ int len = rc.x2;
+ if(rw.x1 > x1src)
+ {
+ x1dst += rw.x1 - x1src;
+ len -= rw.x1 - x1src;
+ x1src = rw.x1;
+ }
+ if(len > 0)
+ {
+ if(x1src + len-1 > rw.x2)
+ {
+ len -= x1src + len - rw.x2 - 1;
+ }
+ if(len > 0)
+ {
+ m_ren->blend_from_lut(src,
+ color_lut,
+ x1dst, rdst.y1,
+ x1src, rsrc.y1,
+ len,
+ cover);
+ }
+ }
+ }
+ rdst.y1 += incy;
+ rsrc.y1 += incy;
+ --rc.y2;
+ }
+ }
+ }
private:
pixfmt_type* m_ren;
- rect m_clip_box;
+ rect_i m_clip_box;
};
diff --git a/agg/inc/agg_renderer_markers.h b/agg/inc/agg_renderer_markers.h
index ff47995554d9..72c9b16a2757 100755
--- a/agg/inc/agg_renderer_markers.h
+++ b/agg/inc/agg_renderer_markers.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -65,13 +65,12 @@ namespace agg
//--------------------------------------------------------------------
renderer_markers(base_ren_type& rbuf) :
base_type(rbuf)
- {
- }
+ {}
//--------------------------------------------------------------------
bool visible(int x, int y, int r) const
{
- rect rc(x-r, y-r, x+y, y+r);
+ rect_i rc(x-r, y-r, x+y, y+r);
return rc.clip(base_type::ren().bounding_clip_box());
}
diff --git a/agg/inc/agg_renderer_mclip.h b/agg/inc/agg_renderer_mclip.h
index dc758b9ea72d..834ffb23ffac 100755
--- a/agg/inc/agg_renderer_mclip.h
+++ b/agg/inc/agg_renderer_mclip.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -33,14 +33,19 @@ namespace agg
public:
typedef PixelFormat pixfmt_type;
typedef typename pixfmt_type::color_type color_type;
+ typedef typename pixfmt_type::row_data row_data;
typedef renderer_base<pixfmt_type> base_ren_type;
//--------------------------------------------------------------------
- renderer_mclip(pixfmt_type& ren) :
- m_ren(ren),
+ explicit renderer_mclip(pixfmt_type& pixf) :
+ m_ren(pixf),
m_curr_cb(0),
m_bounds(m_ren.xmin(), m_ren.ymin(), m_ren.xmax(), m_ren.ymax())
+ {}
+ void attach(pixfmt_type& pixf)
{
+ m_ren.attach(pixf);
+ reset_clipping(true);
}
//--------------------------------------------------------------------
@@ -52,18 +57,18 @@ namespace agg
unsigned height() const { return m_ren.height(); }
//--------------------------------------------------------------------
- const rect& clip_box() const { return m_ren.clip_box(); }
- int xmin() const { return m_ren.xmin(); }
- int ymin() const { return m_ren.ymin(); }
- int xmax() const { return m_ren.xmax(); }
- int ymax() const { return m_ren.ymax(); }
+ const rect_i& clip_box() const { return m_ren.clip_box(); }
+ int xmin() const { return m_ren.xmin(); }
+ int ymin() const { return m_ren.ymin(); }
+ int xmax() const { return m_ren.xmax(); }
+ int ymax() const { return m_ren.ymax(); }
//--------------------------------------------------------------------
- const rect& bounding_clip_box() const { return m_bounds; }
- int bounding_xmin() const { return m_bounds.x1; }
- int bounding_ymin() const { return m_bounds.y1; }
- int bounding_xmax() const { return m_bounds.x2; }
- int bounding_ymax() const { return m_bounds.y2; }
+ const rect_i& bounding_clip_box() const { return m_bounds; }
+ int bounding_xmin() const { return m_bounds.x1; }
+ int bounding_ymin() const { return m_bounds.y1; }
+ int bounding_xmax() const { return m_bounds.x2; }
+ int bounding_ymax() const { return m_bounds.y2; }
//--------------------------------------------------------------------
void first_clip_box()
@@ -71,7 +76,7 @@ namespace agg
m_curr_cb = 0;
if(m_clip.size())
{
- const rect& cb = m_clip[0];
+ const rect_i& cb = m_clip[0];
m_ren.clip_box_naked(cb.x1, cb.y1, cb.x2, cb.y2);
}
}
@@ -81,7 +86,7 @@ namespace agg
{
if(++m_curr_cb < m_clip.size())
{
- const rect& cb = m_clip[m_curr_cb];
+ const rect_i& cb = m_clip[m_curr_cb];
m_ren.clip_box_naked(cb.x1, cb.y1, cb.x2, cb.y2);
return true;
}
@@ -100,9 +105,9 @@ namespace agg
//--------------------------------------------------------------------
void add_clip_box(int x1, int y1, int x2, int y2)
{
- rect cb(x1, y1, x2, y2);
+ rect_i cb(x1, y1, x2, y2);
cb.normalize();
- if(cb.clip(rect(0, 0, width() - 1, height() - 1)))
+ if(cb.clip(rect_i(0, 0, width() - 1, height() - 1)))
{
m_clip.add(cb);
if(cb.x1 < m_bounds.x1) m_bounds.x1 = cb.x1;
@@ -232,7 +237,6 @@ namespace agg
while(next_clip_box());
}
-
//--------------------------------------------------------------------
void blend_solid_hspan(int x, int y, int len,
const color_type& c, const cover_type* covers)
@@ -257,22 +261,20 @@ namespace agg
while(next_clip_box());
}
+
//--------------------------------------------------------------------
- void blend_color_hspan(int x, int y, int len,
- const color_type* colors,
- const cover_type* covers,
- cover_type cover = cover_full)
+ void copy_color_hspan(int x, int y, int len, const color_type* colors)
{
first_clip_box();
do
{
- m_ren.blend_color_hspan(x, y, len, colors, covers, cover);
+ m_ren.copy_color_hspan(x, y, len, colors);
}
while(next_clip_box());
}
//--------------------------------------------------------------------
- void blend_color_vspan(int x, int y, int len,
+ void blend_color_hspan(int x, int y, int len,
const color_type* colors,
const cover_type* covers,
cover_type cover = cover_full)
@@ -285,96 +287,60 @@ namespace agg
while(next_clip_box());
}
-
//--------------------------------------------------------------------
- void blend_qpaque_color_hspan(int x, int y, int len,
- const color_type* colors,
- const cover_type* covers,
- cover_type cover = cover_full)
+ void blend_color_vspan(int x, int y, int len,
+ const color_type* colors,
+ const cover_type* covers,
+ cover_type cover = cover_full)
{
first_clip_box();
do
{
- m_ren.blend_opaque_color_hspan(x, y, len, colors, covers, cover);
+ m_ren.blend_color_vspan(x, y, len, colors, covers, cover);
}
while(next_clip_box());
}
//--------------------------------------------------------------------
- void blend_opaque_color_vspan(int x, int y, int len,
- const color_type* colors,
- const cover_type* covers,
- cover_type cover = cover_full)
+ void copy_from(const rendering_buffer& from,
+ const rect_i* rc=0,
+ int x_to=0,
+ int y_to=0)
{
first_clip_box();
do
{
- m_ren.blend_opaque_color_hspan(x, y, len, colors, covers, cover);
+ m_ren.copy_from(from, rc, x_to, y_to);
}
while(next_clip_box());
}
-
//--------------------------------------------------------------------
- void blend_color_hspan_no_clip(int x, int y, int len,
- const color_type* colors,
- const cover_type* covers,
- cover_type cover = cover_full)
- {
- m_ren.blend_color_hspan_no_clip(x, y, len, colors, covers, cover);
- }
-
- //--------------------------------------------------------------------
- void blend_color_vspan_no_clip(int x, int y, int len,
- const color_type* colors,
- const cover_type* covers,
- cover_type cover = cover_full)
- {
- m_ren.blend_color_vspan_no_clip(x, y, len, colors, covers, cover);
- }
-
- //--------------------------------------------------------------------
- void blend_opaque_color_hspan_no_clip(int x, int y, int len,
- const color_type* colors,
- const cover_type* covers,
- cover_type cover = cover_full)
- {
- m_ren.blend_opaque_color_hspan_no_clip(x, y, len, colors, covers, cover);
- }
-
- //--------------------------------------------------------------------
- void blend_opaque_color_vspan_no_clip(int x, int y, int len,
- const color_type* colors,
- const cover_type* covers,
- cover_type cover = cover_full)
- {
- m_ren.blend_opaque_color_vspan_no_clip(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)
+ template<class SrcPixelFormatRenderer>
+ void blend_from(const SrcPixelFormatRenderer& src,
+ const rect_i* rect_src_ptr = 0,
+ int dx = 0,
+ int dy = 0,
+ cover_type cover = cover_full)
{
first_clip_box();
do
{
- m_ren.copy_from(from, rc, x_to, y_to);
+ m_ren.blend_from(src, rect_src_ptr, dx, dy, cover);
}
while(next_clip_box());
}
+
private:
renderer_mclip(const renderer_mclip<PixelFormat>&);
const renderer_mclip<PixelFormat>&
operator = (const renderer_mclip<PixelFormat>&);
- base_ren_type m_ren;
- pod_deque<rect, 4> m_clip;
- unsigned m_curr_cb;
- rect m_bounds;
+ base_ren_type m_ren;
+ pod_bvector<rect_i, 4> m_clip;
+ unsigned m_curr_cb;
+ rect_i m_bounds;
};
diff --git a/agg/inc/agg_renderer_outline_aa.h b/agg/inc/agg_renderer_outline_aa.h
index d2f9484c5a1d..d42ebcb049cd 100755
--- a/agg/inc/agg_renderer_outline_aa.h
+++ b/agg/inc/agg_renderer_outline_aa.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -15,13 +15,14 @@
#ifndef AGG_RENDERER_OUTLINE_AA_INCLUDED
#define AGG_RENDERER_OUTLINE_AA_INCLUDED
-#include "agg_basics.h"
+#include "agg_array.h"
#include "agg_math.h"
#include "agg_line_aa_basics.h"
#include "agg_dda_line.h"
#include "agg_ellipse_bresenham.h"
#include "agg_renderer_base.h"
#include "agg_gamma_functions.h"
+#include "agg_clip_liang_barsky.h"
namespace agg
{
@@ -35,8 +36,8 @@ namespace agg
distance_interpolator0(int x1, int y1, int x2, int y2, int x, int y) :
m_dx(line_mr(x2) - line_mr(x1)),
m_dy(line_mr(y2) - line_mr(y1)),
- m_dist((line_mr(x + line_subpixel_size/2) - line_mr(x2)) * m_dy -
- (line_mr(y + line_subpixel_size/2) - line_mr(y2)) * m_dx)
+ m_dist((line_mr(x + line_subpixel_scale/2) - line_mr(x2)) * m_dy -
+ (line_mr(y + line_subpixel_scale/2) - line_mr(y2)) * m_dx)
{
m_dx <<= line_mr_subpixel_shift;
m_dy <<= line_mr_subpixel_shift;
@@ -44,56 +45,54 @@ namespace agg
//---------------------------------------------------------------------
void inc_x() { m_dist += m_dy; }
- void dec_x() { m_dist -= m_dy; }
- void inc_y() { m_dist -= m_dx; }
- void dec_y() { m_dist += m_dx; }
-
- //---------------------------------------------------------------------
- void inc_x(int _dy)
- {
- m_dist += m_dy;
- if(_dy > 0) m_dist -= m_dx;
- if(_dy < 0) m_dist += m_dx;
- }
-
- //---------------------------------------------------------------------
- void dec_x(int _dy)
- {
- m_dist -= m_dy;
- if(_dy > 0) m_dist -= m_dx;
- if(_dy < 0) m_dist += m_dx;
- }
+ int dist() const { return m_dist; }
+ private:
//---------------------------------------------------------------------
- void inc_y(int _dx)
- {
- m_dist -= m_dx;
- if(_dx > 0) m_dist += m_dy;
- if(_dx < 0) m_dist -= m_dy;
- }
+ int m_dx;
+ int m_dy;
+ int m_dist;
+ };
- void dec_y(int _dx)
+ //==================================================distance_interpolator00
+ class distance_interpolator00
+ {
+ public:
//---------------------------------------------------------------------
+ distance_interpolator00() {}
+ distance_interpolator00(int xc, int yc,
+ int x1, int y1, int x2, int y2,
+ int x, int y) :
+ m_dx1(line_mr(x1) - line_mr(xc)),
+ m_dy1(line_mr(y1) - line_mr(yc)),
+ m_dx2(line_mr(x2) - line_mr(xc)),
+ m_dy2(line_mr(y2) - line_mr(yc)),
+ m_dist1((line_mr(x + line_subpixel_scale/2) - line_mr(x1)) * m_dy1 -
+ (line_mr(y + line_subpixel_scale/2) - line_mr(y1)) * m_dx1),
+ m_dist2((line_mr(x + line_subpixel_scale/2) - line_mr(x2)) * m_dy2 -
+ (line_mr(y + line_subpixel_scale/2) - line_mr(y2)) * m_dx2)
{
- m_dist += m_dx;
- if(_dx > 0) m_dist += m_dy;
- if(_dx < 0) m_dist -= m_dy;
+ m_dx1 <<= line_mr_subpixel_shift;
+ m_dy1 <<= line_mr_subpixel_shift;
+ m_dx2 <<= line_mr_subpixel_shift;
+ m_dy2 <<= line_mr_subpixel_shift;
}
//---------------------------------------------------------------------
- int dist() const { return m_dist; }
- int dx() const { return m_dx; }
- int dy() const { return m_dy; }
+ void inc_x() { m_dist1 += m_dy1; m_dist2 += m_dy2; }
+ int dist1() const { return m_dist1; }
+ int dist2() const { return m_dist2; }
private:
//---------------------------------------------------------------------
- int m_dx;
- int m_dy;
- int m_dist;
+ int m_dx1;
+ int m_dy1;
+ int m_dx2;
+ int m_dy2;
+ int m_dist1;
+ int m_dist2;
};
-
-
//===================================================distance_interpolator1
class distance_interpolator1
{
@@ -103,8 +102,8 @@ namespace agg
distance_interpolator1(int x1, int y1, int x2, int y2, int x, int y) :
m_dx(x2 - x1),
m_dy(y2 - y1),
- m_dist(int(double(x + line_subpixel_size/2 - x2) * double(m_dy) -
- double(y + line_subpixel_size/2 - y2) * double(m_dx)))
+ m_dist(iround(double(x + line_subpixel_scale/2 - x2) * double(m_dy) -
+ double(y + line_subpixel_scale/2 - y2) * double(m_dx)))
{
m_dx <<= line_subpixel_shift;
m_dy <<= line_subpixel_shift;
@@ -117,35 +116,35 @@ namespace agg
void dec_y() { m_dist += m_dx; }
//---------------------------------------------------------------------
- void inc_x(int _dy)
+ void inc_x(int dy)
{
m_dist += m_dy;
- if(_dy > 0) m_dist -= m_dx;
- if(_dy < 0) m_dist += m_dx;
+ if(dy > 0) m_dist -= m_dx;
+ if(dy < 0) m_dist += m_dx;
}
//---------------------------------------------------------------------
- void dec_x(int _dy)
+ void dec_x(int dy)
{
m_dist -= m_dy;
- if(_dy > 0) m_dist -= m_dx;
- if(_dy < 0) m_dist += m_dx;
+ if(dy > 0) m_dist -= m_dx;
+ if(dy < 0) m_dist += m_dx;
}
//---------------------------------------------------------------------
- void inc_y(int _dx)
+ void inc_y(int dx)
{
m_dist -= m_dx;
- if(_dx > 0) m_dist += m_dy;
- if(_dx < 0) m_dist -= m_dy;
+ if(dx > 0) m_dist += m_dy;
+ if(dx < 0) m_dist -= m_dy;
}
- void dec_y(int _dx)
+ void dec_y(int dx)
//---------------------------------------------------------------------
{
m_dist += m_dx;
- if(_dx > 0) m_dist += m_dy;
- if(_dx < 0) m_dist -= m_dy;
+ if(dx > 0) m_dist += m_dy;
+ if(dx < 0) m_dist -= m_dy;
}
//---------------------------------------------------------------------
@@ -177,11 +176,11 @@ namespace agg
m_dx_start(line_mr(sx) - line_mr(x1)),
m_dy_start(line_mr(sy) - line_mr(y1)),
- m_dist(int(double(x + line_subpixel_size/2 - x2) * double(m_dy) -
- double(y + line_subpixel_size/2 - y2) * double(m_dx))),
+ m_dist(iround(double(x + line_subpixel_scale/2 - x2) * double(m_dy) -
+ double(y + line_subpixel_scale/2 - y2) * double(m_dx))),
- m_dist_start((line_mr(x + line_subpixel_size/2) - line_mr(sx)) * m_dy_start -
- (line_mr(y + line_subpixel_size/2) - line_mr(sy)) * m_dx_start)
+ m_dist_start((line_mr(x + line_subpixel_scale/2) - line_mr(sx)) * m_dy_start -
+ (line_mr(y + line_subpixel_scale/2) - line_mr(sy)) * m_dx_start)
{
m_dx <<= line_subpixel_shift;
m_dy <<= line_subpixel_shift;
@@ -196,11 +195,11 @@ namespace agg
m_dx_start(line_mr(ex) - line_mr(x2)),
m_dy_start(line_mr(ey) - line_mr(y2)),
- m_dist(int(double(x + line_subpixel_size/2 - x2) * double(m_dy) -
- double(y + line_subpixel_size/2 - y2) * double(m_dx))),
+ m_dist(iround(double(x + line_subpixel_scale/2 - x2) * double(m_dy) -
+ double(y + line_subpixel_scale/2 - y2) * double(m_dx))),
- m_dist_start((line_mr(x + line_subpixel_size/2) - line_mr(ex)) * m_dy_start -
- (line_mr(y + line_subpixel_size/2) - line_mr(ey)) * m_dx_start)
+ m_dist_start((line_mr(x + line_subpixel_scale/2) - line_mr(ex)) * m_dy_start -
+ (line_mr(y + line_subpixel_scale/2) - line_mr(ey)) * m_dx_start)
{
m_dx <<= line_subpixel_shift;
m_dy <<= line_subpixel_shift;
@@ -216,16 +215,16 @@ namespace agg
void dec_y() { m_dist += m_dx; m_dist_start += m_dx_start; }
//---------------------------------------------------------------------
- void inc_x(int _dy)
+ void inc_x(int dy)
{
m_dist += m_dy;
m_dist_start += m_dy_start;
- if(_dy > 0)
+ if(dy > 0)
{
m_dist -= m_dx;
m_dist_start -= m_dx_start;
}
- if(_dy < 0)
+ if(dy < 0)
{
m_dist += m_dx;
m_dist_start += m_dx_start;
@@ -233,16 +232,16 @@ namespace agg
}
//---------------------------------------------------------------------
- void dec_x(int _dy)
+ void dec_x(int dy)
{
m_dist -= m_dy;
m_dist_start -= m_dy_start;
- if(_dy > 0)
+ if(dy > 0)
{
m_dist -= m_dx;
m_dist_start -= m_dx_start;
}
- if(_dy < 0)
+ if(dy < 0)
{
m_dist += m_dx;
m_dist_start += m_dx_start;
@@ -250,16 +249,16 @@ namespace agg
}
//---------------------------------------------------------------------
- void inc_y(int _dx)
+ void inc_y(int dx)
{
m_dist -= m_dx;
m_dist_start -= m_dx_start;
- if(_dx > 0)
+ if(dx > 0)
{
m_dist += m_dy;
m_dist_start += m_dy_start;
}
- if(_dx < 0)
+ if(dx < 0)
{
m_dist -= m_dy;
m_dist_start -= m_dy_start;
@@ -267,16 +266,16 @@ namespace agg
}
//---------------------------------------------------------------------
- void dec_y(int _dx)
+ void dec_y(int dx)
{
m_dist += m_dx;
m_dist_start += m_dx_start;
- if(_dx > 0)
+ if(dx > 0)
{
m_dist += m_dy;
m_dist_start += m_dy_start;
}
- if(_dx < 0)
+ if(dx < 0)
{
m_dist -= m_dy;
m_dist_start -= m_dy_start;
@@ -327,14 +326,14 @@ namespace agg
m_dx_end(line_mr(ex) - line_mr(x2)),
m_dy_end(line_mr(ey) - line_mr(y2)),
- m_dist(int(double(x + line_subpixel_size/2 - x2) * double(m_dy) -
- double(y + line_subpixel_size/2 - y2) * double(m_dx))),
+ m_dist(iround(double(x + line_subpixel_scale/2 - x2) * double(m_dy) -
+ double(y + line_subpixel_scale/2 - y2) * double(m_dx))),
- m_dist_start((line_mr(x + line_subpixel_size/2) - line_mr(sx)) * m_dy_start -
- (line_mr(y + line_subpixel_size/2) - line_mr(sy)) * m_dx_start),
+ m_dist_start((line_mr(x + line_subpixel_scale/2) - line_mr(sx)) * m_dy_start -
+ (line_mr(y + line_subpixel_scale/2) - line_mr(sy)) * m_dx_start),
- m_dist_end((line_mr(x + line_subpixel_size/2) - line_mr(ex)) * m_dy_end -
- (line_mr(y + line_subpixel_size/2) - line_mr(ey)) * m_dx_end)
+ m_dist_end((line_mr(x + line_subpixel_scale/2) - line_mr(ex)) * m_dy_end -
+ (line_mr(y + line_subpixel_scale/2) - line_mr(ey)) * m_dx_end)
{
m_dx <<= line_subpixel_shift;
m_dy <<= line_subpixel_shift;
@@ -351,18 +350,18 @@ namespace agg
void dec_y() { m_dist += m_dx; m_dist_start += m_dx_start; m_dist_end += m_dx_end; }
//---------------------------------------------------------------------
- void inc_x(int _dy)
+ void inc_x(int dy)
{
m_dist += m_dy;
m_dist_start += m_dy_start;
m_dist_end += m_dy_end;
- if(_dy > 0)
+ if(dy > 0)
{
m_dist -= m_dx;
m_dist_start -= m_dx_start;
m_dist_end -= m_dx_end;
}
- if(_dy < 0)
+ if(dy < 0)
{
m_dist += m_dx;
m_dist_start += m_dx_start;
@@ -371,18 +370,18 @@ namespace agg
}
//---------------------------------------------------------------------
- void dec_x(int _dy)
+ void dec_x(int dy)
{
m_dist -= m_dy;
m_dist_start -= m_dy_start;
m_dist_end -= m_dy_end;
- if(_dy > 0)
+ if(dy > 0)
{
m_dist -= m_dx;
m_dist_start -= m_dx_start;
m_dist_end -= m_dx_end;
}
- if(_dy < 0)
+ if(dy < 0)
{
m_dist += m_dx;
m_dist_start += m_dx_start;
@@ -391,18 +390,18 @@ namespace agg
}
//---------------------------------------------------------------------
- void inc_y(int _dx)
+ void inc_y(int dx)
{
m_dist -= m_dx;
m_dist_start -= m_dx_start;
m_dist_end -= m_dx_end;
- if(_dx > 0)
+ if(dx > 0)
{
m_dist += m_dy;
m_dist_start += m_dy_start;
m_dist_end += m_dy_end;
}
- if(_dx < 0)
+ if(dx < 0)
{
m_dist -= m_dy;
m_dist_start -= m_dy_start;
@@ -411,18 +410,18 @@ namespace agg
}
//---------------------------------------------------------------------
- void dec_y(int _dx)
+ void dec_y(int dx)
{
m_dist += m_dx;
m_dist_start += m_dx_start;
m_dist_end += m_dx_end;
- if(_dx > 0)
+ if(dx > 0)
{
m_dist += m_dy;
m_dist_start += m_dy_start;
m_dist_end += m_dy_end;
}
- if(_dx < 0)
+ if(dx < 0)
{
m_dist -= m_dy;
m_dist_start -= m_dy_start;
@@ -469,7 +468,7 @@ namespace agg
typedef typename Renderer::color_type color_type;
//---------------------------------------------------------------------
- enum
+ enum max_half_width_e
{
max_half_width = 64
};
@@ -490,7 +489,8 @@ namespace agg
m_count((lp.vertical ? abs((lp.y2 >> line_subpixel_shift) - m_y) :
abs((lp.x2 >> line_subpixel_shift) - m_x))),
m_width(ren.subpixel_width()),
- m_max_extent(m_width >> (line_subpixel_shift - 2)),
+ //m_max_extent(m_width >> (line_subpixel_shift - 2)),
+ m_max_extent((m_width + line_subpixel_mask) >> line_subpixel_shift),
m_step(0)
{
agg::dda2_line_interpolator li(0, lp.vertical ?
@@ -499,7 +499,7 @@ namespace agg
lp.len);
unsigned i;
- int stop = m_width + line_subpixel_size * 2;
+ int stop = m_width + line_subpixel_scale * 2;
for(i = 0; i < max_half_width; ++i)
{
m_dist[i] = li.y();
@@ -1259,40 +1259,33 @@ namespace agg
public:
//---------------------------------------------------------------------
typedef int8u value_type;
- enum
+ enum subpixel_scale_e
{
subpixel_shift = line_subpixel_shift,
- subpixel_size = 1 << subpixel_shift,
- subpixel_mask = subpixel_size - 1
+ subpixel_scale = 1 << subpixel_shift,
+ subpixel_mask = subpixel_scale - 1
};
- enum
+ enum aa_scale_e
{
aa_shift = 8,
- aa_num = 1 << aa_shift,
- aa_mask = aa_num - 1
+ aa_scale = 1 << aa_shift,
+ aa_mask = aa_scale - 1
};
//---------------------------------------------------------------------
- ~line_profile_aa() { delete [] m_profile; }
-
- //---------------------------------------------------------------------
line_profile_aa() :
- m_size(0),
- m_profile(0),
m_subpixel_width(0),
m_min_width(1.0),
m_smoother_width(1.0)
{
int i;
- for(i = 0; i < aa_num; i++) m_gamma[i] = (value_type)i;
+ for(i = 0; i < aa_scale; i++) m_gamma[i] = (value_type)i;
}
//---------------------------------------------------------------------
template<class GammaF>
line_profile_aa(double w, const GammaF& gamma_function) :
- m_size(0),
- m_profile(0),
m_subpixel_width(0),
m_min_width(1.0),
m_smoother_width(1.0)
@@ -1309,17 +1302,16 @@ namespace agg
template<class GammaF> void gamma(const GammaF& gamma_function)
{
int i;
- for(i = 0; i < aa_num; i++)
+ for(i = 0; i < aa_scale; i++)
{
m_gamma[i] = value_type(
- floor(
- gamma_function(double(i) / aa_mask) * aa_mask + 0.5));
+ uround(gamma_function(double(i) / aa_mask) * aa_mask));
}
}
void width(double w);
- unsigned profile_size() const { return m_size; }
+ unsigned profile_size() const { return m_profile.size(); }
int subpixel_width() const { return m_subpixel_width; }
//---------------------------------------------------------------------
@@ -1329,7 +1321,7 @@ namespace agg
//---------------------------------------------------------------------
value_type value(int dist) const
{
- return m_profile[dist + subpixel_size*2];
+ return m_profile[dist + subpixel_scale*2];
}
private:
@@ -1340,12 +1332,11 @@ namespace agg
void set(double center_width, double smoother_width);
//---------------------------------------------------------------------
- unsigned m_size;
- value_type* m_profile;
- value_type m_gamma[aa_num];
- int m_subpixel_width;
- double m_min_width;
- double m_smoother_width;
+ pod_array<value_type> m_profile;
+ value_type m_gamma[aa_scale];
+ int m_subpixel_width;
+ double m_min_width;
+ double m_smoother_width;
};
@@ -1361,9 +1352,11 @@ namespace agg
//---------------------------------------------------------------------
renderer_outline_aa(base_ren_type& ren, const line_profile_aa& prof) :
m_ren(&ren),
- m_profile(&prof)
- {
- }
+ m_profile(&prof),
+ m_clip_box(0,0,0,0),
+ m_clipping(false)
+ {}
+ void attach(base_ren_type& ren) { m_ren = &ren; }
//---------------------------------------------------------------------
void color(const color_type& c) { m_color = c; }
@@ -1372,12 +1365,23 @@ namespace agg
//---------------------------------------------------------------------
void profile(const line_profile_aa& prof) { m_profile = &prof; }
const line_profile_aa& profile() const { return *m_profile; }
- line_profile_aa& profile() { return const_cast<line_profile_aa&>(*m_profile); }
+ line_profile_aa& profile() { return *m_profile; }
//---------------------------------------------------------------------
int subpixel_width() const { return m_profile->subpixel_width(); }
//---------------------------------------------------------------------
+ void reset_clipping() { m_clipping = false; }
+ void clip_box(double x1, double y1, double x2, double y2)
+ {
+ m_clip_box.x1 = line_coord_sat::conv(x1);
+ m_clip_box.y1 = line_coord_sat::conv(y1);
+ m_clip_box.x2 = line_coord_sat::conv(x2);
+ m_clip_box.y2 = line_coord_sat::conv(y2);
+ m_clipping = true;
+ }
+
+ //---------------------------------------------------------------------
int cover(int d) const
{
return m_profile->value(d);
@@ -1411,8 +1415,8 @@ namespace agg
int y = y1 << line_subpixel_shift;
int w = subpixel_width();
distance_interpolator0 di(xc1, yc1, xc2, yc2, x, y);
- x += line_subpixel_size/2;
- y += line_subpixel_size/2;
+ x += line_subpixel_scale/2;
+ y += line_subpixel_scale/2;
int x0 = x1;
int dx = x - xc1;
@@ -1426,7 +1430,7 @@ namespace agg
*p1 = (cover_type)cover(d);
}
++p1;
- dx += line_subpixel_size;
+ dx += line_subpixel_scale;
di.inc_x();
}
while(++x1 <= x2);
@@ -1440,6 +1444,8 @@ namespace agg
template<class Cmp>
void semidot(Cmp cmp, int xc1, int yc1, int xc2, int yc2)
{
+ if(m_clipping && clipping_flags(xc1, yc1, m_clip_box)) return;
+
int r = ((subpixel_width() + line_subpixel_mask) >> line_subpixel_shift);
if(r < 1) r = 1;
ellipse_bresenham_interpolator ei(r, r);
@@ -1469,73 +1475,359 @@ namespace agg
}
//-------------------------------------------------------------------------
- void line0(const line_parameters& lp)
+ void pie_hline(int xc, int yc, int xp1, int yp1, int xp2, int yp2,
+ int xh1, int yh1, int xh2)
+ {
+ if(m_clipping && clipping_flags(xc, yc, m_clip_box)) return;
+
+ cover_type covers[line_interpolator_aa_base<self_type>::max_half_width * 2 + 4];
+ cover_type* p0 = covers;
+ cover_type* p1 = covers;
+ int x = xh1 << line_subpixel_shift;
+ int y = yh1 << line_subpixel_shift;
+ int w = subpixel_width();
+
+ distance_interpolator00 di(xc, yc, xp1, yp1, xp2, yp2, x, y);
+ x += line_subpixel_scale/2;
+ y += line_subpixel_scale/2;
+
+ int xh0 = xh1;
+ int dx = x - xc;
+ int dy = y - yc;
+ do
+ {
+ int d = int(fast_sqrt(dx*dx + dy*dy));
+ *p1 = 0;
+ if(di.dist1() <= 0 && di.dist2() > 0 && d <= w)
+ {
+ *p1 = (cover_type)cover(d);
+ }
+ ++p1;
+ dx += line_subpixel_scale;
+ di.inc_x();
+ }
+ while(++xh1 <= xh2);
+ m_ren->blend_solid_hspan(xh0, yh1,
+ unsigned(p1 - p0),
+ color(),
+ p0);
+ }
+
+
+ //-------------------------------------------------------------------------
+ void pie(int xc, int yc, int x1, int y1, int x2, int y2)
+ {
+ int r = ((subpixel_width() + line_subpixel_mask) >> line_subpixel_shift);
+ if(r < 1) r = 1;
+ ellipse_bresenham_interpolator ei(r, r);
+ int dx = 0;
+ int dy = -r;
+ int dy0 = dy;
+ int dx0 = dx;
+ int x = xc >> line_subpixel_shift;
+ int y = yc >> line_subpixel_shift;
+
+ do
+ {
+ dx += ei.dx();
+ dy += ei.dy();
+
+ if(dy != dy0)
+ {
+ pie_hline(xc, yc, x1, y1, x2, y2, x-dx0, y+dy0, x+dx0);
+ pie_hline(xc, yc, x1, y1, x2, y2, x-dx0, y-dy0, x+dx0);
+ }
+ dx0 = dx;
+ dy0 = dy;
+ ++ei;
+ }
+ while(dy < 0);
+ pie_hline(xc, yc, x1, y1, x2, y2, x-dx0, y+dy0, x+dx0);
+ }
+
+ //-------------------------------------------------------------------------
+ void line0_no_clip(const line_parameters& lp)
{
+ if(lp.len > line_max_length)
+ {
+ line_parameters lp1, lp2;
+ lp.divide(lp1, lp2);
+ line0_no_clip(lp1);
+ line0_no_clip(lp2);
+ return;
+ }
+
line_interpolator_aa0<self_type> li(*this, lp);
if(li.count())
{
if(li.vertical())
{
- while(li.step_ver()) ;
+ while(li.step_ver());
}
else
{
- while(li.step_hor()) ;
+ while(li.step_hor());
}
}
}
//-------------------------------------------------------------------------
- void line1(const line_parameters& lp, int sx, int sy)
+ void line0(const line_parameters& lp)
{
+ if(m_clipping)
+ {
+ int x1 = lp.x1;
+ int y1 = lp.y1;
+ int x2 = lp.x2;
+ int y2 = lp.y2;
+ unsigned flags = clip_line_segment(&x1, &y1, &x2, &y2, m_clip_box);
+ if((flags & 4) == 0)
+ {
+ if(flags)
+ {
+ line_parameters lp2(x1, y1, x2, y2,
+ uround(calc_distance(x1, y1, x2, y2)));
+ line0_no_clip(lp2);
+ }
+ else
+ {
+ line0_no_clip(lp);
+ }
+ }
+ }
+ else
+ {
+ line0_no_clip(lp);
+ }
+ }
+
+ //-------------------------------------------------------------------------
+ void line1_no_clip(const line_parameters& lp, int sx, int sy)
+ {
+ if(lp.len > line_max_length)
+ {
+ line_parameters lp1, lp2;
+ lp.divide(lp1, lp2);
+ line1_no_clip(lp1, (lp.x1 + sx) >> 1, (lp.y1 + sy) >> 1);
+ line1_no_clip(lp2, lp1.x2 + (lp1.y2 - lp1.y1), lp1.y2 - (lp1.x2 - lp1.x1));
+ return;
+ }
+
fix_degenerate_bisectrix_start(lp, &sx, &sy);
line_interpolator_aa1<self_type> li(*this, lp, sx, sy);
if(li.vertical())
{
- while(li.step_ver()) ;
+ while(li.step_ver());
}
else
{
- while(li.step_hor()) ;
+ while(li.step_hor());
}
}
+
//-------------------------------------------------------------------------
- void line2(const line_parameters& lp, int ex, int ey)
+ void line1(const line_parameters& lp, int sx, int sy)
+ {
+ if(m_clipping)
+ {
+ int x1 = lp.x1;
+ int y1 = lp.y1;
+ int x2 = lp.x2;
+ int y2 = lp.y2;
+ unsigned flags = clip_line_segment(&x1, &y1, &x2, &y2, m_clip_box);
+ if((flags & 4) == 0)
+ {
+ if(flags)
+ {
+ line_parameters lp2(x1, y1, x2, y2,
+ uround(calc_distance(x1, y1, x2, y2)));
+ if(flags & 1)
+ {
+ sx = x1 + (y2 - y1);
+ sy = y1 - (x2 - x1);
+ }
+ else
+ {
+ while(abs(sx - lp.x1) + abs(sy - lp.y1) > lp2.len)
+ {
+ sx = (lp.x1 + sx) >> 1;
+ sy = (lp.y1 + sy) >> 1;
+ }
+ }
+ line1_no_clip(lp2, sx, sy);
+ }
+ else
+ {
+ line1_no_clip(lp, sx, sy);
+ }
+ }
+ }
+ else
+ {
+ line1_no_clip(lp, sx, sy);
+ }
+ }
+
+ //-------------------------------------------------------------------------
+ void line2_no_clip(const line_parameters& lp, int ex, int ey)
{
+ if(lp.len > line_max_length)
+ {
+ line_parameters lp1, lp2;
+ lp.divide(lp1, lp2);
+ line2_no_clip(lp1, lp1.x2 + (lp1.y2 - lp1.y1), lp1.y2 - (lp1.x2 - lp1.x1));
+ line2_no_clip(lp2, (lp.x2 + ex) >> 1, (lp.y2 + ey) >> 1);
+ return;
+ }
+
fix_degenerate_bisectrix_end(lp, &ex, &ey);
line_interpolator_aa2<self_type> li(*this, lp, ex, ey);
if(li.vertical())
{
- while(li.step_ver()) ;
+ while(li.step_ver());
}
else
{
- while(li.step_hor()) ;
+ while(li.step_hor());
}
}
//-------------------------------------------------------------------------
- void line3(const line_parameters& lp,
- int sx, int sy, int ex, int ey)
+ void line2(const line_parameters& lp, int ex, int ey)
+ {
+ if(m_clipping)
+ {
+ int x1 = lp.x1;
+ int y1 = lp.y1;
+ int x2 = lp.x2;
+ int y2 = lp.y2;
+ unsigned flags = clip_line_segment(&x1, &y1, &x2, &y2, m_clip_box);
+ if((flags & 4) == 0)
+ {
+ if(flags)
+ {
+ line_parameters lp2(x1, y1, x2, y2,
+ uround(calc_distance(x1, y1, x2, y2)));
+ if(flags & 2)
+ {
+ ex = x2 + (y2 - y1);
+ ey = y2 - (x2 - x1);
+ }
+ else
+ {
+ while(abs(ex - lp.x2) + abs(ey - lp.y2) > lp2.len)
+ {
+ ex = (lp.x2 + ex) >> 1;
+ ey = (lp.y2 + ey) >> 1;
+ }
+ }
+ line2_no_clip(lp2, ex, ey);
+ }
+ else
+ {
+ line2_no_clip(lp, ex, ey);
+ }
+ }
+ }
+ else
+ {
+ line2_no_clip(lp, ex, ey);
+ }
+ }
+
+ //-------------------------------------------------------------------------
+ void line3_no_clip(const line_parameters& lp,
+ int sx, int sy, int ex, int ey)
{
+ if(lp.len > line_max_length)
+ {
+ line_parameters lp1, lp2;
+ lp.divide(lp1, lp2);
+ int mx = lp1.x2 + (lp1.y2 - lp1.y1);
+ int my = lp1.y2 - (lp1.x2 - lp1.x1);
+ line3_no_clip(lp1, (lp.x1 + sx) >> 1, (lp.y1 + sy) >> 1, mx, my);
+ line3_no_clip(lp2, mx, my, (lp.x2 + ex) >> 1, (lp.y2 + ey) >> 1);
+ return;
+ }
+
fix_degenerate_bisectrix_start(lp, &sx, &sy);
fix_degenerate_bisectrix_end(lp, &ex, &ey);
line_interpolator_aa3<self_type> li(*this, lp, sx, sy, ex, ey);
if(li.vertical())
{
- while(li.step_ver()) ;
+ while(li.step_ver());
}
else
{
- while(li.step_hor()) ;
+ while(li.step_hor());
}
}
+ //-------------------------------------------------------------------------
+ void line3(const line_parameters& lp,
+ int sx, int sy, int ex, int ey)
+ {
+ if(m_clipping)
+ {
+ int x1 = lp.x1;
+ int y1 = lp.y1;
+ int x2 = lp.x2;
+ int y2 = lp.y2;
+ unsigned flags = clip_line_segment(&x1, &y1, &x2, &y2, m_clip_box);
+ if((flags & 4) == 0)
+ {
+ if(flags)
+ {
+ line_parameters lp2(x1, y1, x2, y2,
+ uround(calc_distance(x1, y1, x2, y2)));
+ if(flags & 1)
+ {
+ sx = x1 + (y2 - y1);
+ sy = y1 - (x2 - x1);
+ }
+ else
+ {
+ while(abs(sx - lp.x1) + abs(sy - lp.y1) > lp2.len)
+ {
+ sx = (lp.x1 + sx) >> 1;
+ sy = (lp.y1 + sy) >> 1;
+ }
+ }
+ if(flags & 2)
+ {
+ ex = x2 + (y2 - y1);
+ ey = y2 - (x2 - x1);
+ }
+ else
+ {
+ while(abs(ex - lp.x2) + abs(ey - lp.y2) > lp2.len)
+ {
+ ex = (lp.x2 + ex) >> 1;
+ ey = (lp.y2 + ey) >> 1;
+ }
+ }
+ line3_no_clip(lp2, sx, sy, ex, ey);
+ }
+ else
+ {
+ line3_no_clip(lp, sx, sy, ex, ey);
+ }
+ }
+ }
+ else
+ {
+ line3_no_clip(lp, sx, sy, ex, ey);
+ }
+ }
+
+
private:
base_ren_type* m_ren;
const line_profile_aa* m_profile;
color_type m_color;
+ rect_i m_clip_box;
+ bool m_clipping;
};
diff --git a/agg/inc/agg_renderer_outline_image.h b/agg/inc/agg_renderer_outline_image.h
index d5cd3992448c..0fd703421dd3 100755
--- a/agg/inc/agg_renderer_outline_image.h
+++ b/agg/inc/agg_renderer_outline_image.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -15,10 +15,12 @@
#ifndef AGG_RENDERER_OUTLINE_IMAGE_INCLUDED
#define AGG_RENDERER_OUTLINE_IMAGE_INCLUDED
-#include <math.h>
+#include "agg_array.h"
+#include "agg_math.h"
#include "agg_line_aa_basics.h"
#include "agg_dda_line.h"
#include "agg_rendering_buffer.h"
+#include "agg_clip_liang_barsky.h"
namespace agg
@@ -42,8 +44,8 @@ namespace agg
color_type pixel(int x, int y) const
{
double src_y = (y + 0.5) * m_scale - 0.5;
- int h = int(m_source.height()) - 1;
- int y1 = int(floor(src_y));
+ int h = m_source.height() - 1;
+ int y1 = ufloor(src_y);
int y2 = y1 + 1;
color_type pix1 = (y1 < 0) ? color_type::no_color() : m_source.pixel(x, y1);
color_type pix2 = (y2 > h) ? color_type::no_color() : m_source.pixel(x, y2);
@@ -69,17 +71,11 @@ namespace agg
typedef typename filter_type::color_type color_type;
//--------------------------------------------------------------------
- ~line_image_pattern()
- {
- delete [] m_data;
- }
-
- //--------------------------------------------------------------------
line_image_pattern(const Filter& filter) :
m_filter(&filter),
m_dilation(filter.dilation() + 1),
m_dilation_hr(m_dilation << line_subpixel_shift),
- m_data(0),
+ m_data(),
m_width(0),
m_height(0),
m_width_hr(0),
@@ -95,7 +91,7 @@ namespace agg
m_filter(&filter),
m_dilation(filter.dilation() + 1),
m_dilation_hr(m_dilation << line_subpixel_shift),
- m_data(0),
+ m_data(),
m_width(0),
m_height(0),
m_width_hr(0),
@@ -109,25 +105,24 @@ namespace agg
//--------------------------------------------------------------------
template<class Source> void create(const Source& src)
{
- m_height = unsigned(ceil((double)src.height()));
- m_width = unsigned(ceil((double)src.width()));
- m_width_hr = int(src.width() * line_subpixel_size);
- m_half_height_hr = int(src.height() * line_subpixel_size/2);
- m_offset_y_hr = m_dilation_hr + m_half_height_hr - line_subpixel_size/2;
- m_half_height_hr += line_subpixel_size/2;
+ m_height = uceil(src.height());
+ m_width = uceil(src.width());
+ m_width_hr = uround(src.width() * line_subpixel_scale);
+ m_half_height_hr = uround(src.height() * line_subpixel_scale/2);
+ m_offset_y_hr = m_dilation_hr + m_half_height_hr - line_subpixel_scale/2;
+ m_half_height_hr += line_subpixel_scale/2;
- delete [] m_data;
- m_data = new color_type [(m_width + m_dilation * 2) * (m_height + m_dilation * 2)];
+ m_data.resize((m_width + m_dilation * 2) * (m_height + m_dilation * 2));
- m_buf.attach(m_data, m_width + m_dilation * 2,
- m_height + m_dilation * 2,
- m_width + m_dilation * 2);
+ m_buf.attach(&m_data[0], m_width + m_dilation * 2,
+ m_height + m_dilation * 2,
+ m_width + m_dilation * 2);
unsigned x, y;
color_type* d1;
color_type* d2;
for(y = 0; y < m_height; y++)
{
- d1 = m_buf.row(y + m_dilation) + m_dilation;
+ d1 = m_buf.row_ptr(y + m_dilation) + m_dilation;
for(x = 0; x < m_width; x++)
{
*d1++ = src.pixel(x, y);
@@ -138,10 +133,10 @@ namespace agg
const color_type* s2;
for(y = 0; y < m_dilation; y++)
{
- //s1 = m_buf.row(m_height + m_dilation - 1) + m_dilation;
- //s2 = m_buf.row(m_dilation) + m_dilation;
- d1 = m_buf.row(m_dilation + m_height + y) + m_dilation;
- d2 = m_buf.row(m_dilation - y - 1) + m_dilation;
+ //s1 = m_buf.row_ptr(m_height + m_dilation - 1) + m_dilation;
+ //s2 = m_buf.row_ptr(m_dilation) + m_dilation;
+ d1 = m_buf.row_ptr(m_dilation + m_height + y) + m_dilation;
+ d2 = m_buf.row_ptr(m_dilation - y - 1) + m_dilation;
for(x = 0; x < m_width; x++)
{
//*d1++ = color_type(*s1++, 0);
@@ -154,10 +149,10 @@ namespace agg
unsigned h = m_height + m_dilation * 2;
for(y = 0; y < h; y++)
{
- s1 = m_buf.row(y) + m_dilation;
- s2 = m_buf.row(y) + m_dilation + m_width;
- d1 = m_buf.row(y) + m_dilation + m_width;
- d2 = m_buf.row(y) + m_dilation;
+ s1 = m_buf.row_ptr(y) + m_dilation;
+ s2 = m_buf.row_ptr(y) + m_dilation + m_width;
+ d1 = m_buf.row_ptr(y) + m_dilation + m_width;
+ d2 = m_buf.row_ptr(y) + m_dilation;
for(x = 0; x < m_dilation; x++)
{
@@ -170,6 +165,7 @@ namespace agg
//--------------------------------------------------------------------
int pattern_width() const { return m_width_hr; }
int line_width() const { return m_half_height_hr; }
+ double width() const { return m_height; }
//--------------------------------------------------------------------
void pixel(color_type* p, int x, int y) const
@@ -193,7 +189,7 @@ namespace agg
const filter_type* m_filter;
unsigned m_dilation;
int m_dilation_hr;
- color_type* m_data;
+ pod_array<color_type> m_data;
unsigned m_width;
unsigned m_height;
int m_width_hr;
@@ -277,23 +273,23 @@ namespace agg
m_dx_end(line_mr(ex) - line_mr(x2)),
m_dy_end(line_mr(ey) - line_mr(y2)),
- m_dist(int(double(x + line_subpixel_size/2 - x2) * double(m_dy) -
- double(y + line_subpixel_size/2 - y2) * double(m_dx))),
+ m_dist(iround(double(x + line_subpixel_scale/2 - x2) * double(m_dy) -
+ double(y + line_subpixel_scale/2 - y2) * double(m_dx))),
- m_dist_start((line_mr(x + line_subpixel_size/2) - line_mr(sx)) * m_dy_start -
- (line_mr(y + line_subpixel_size/2) - line_mr(sy)) * m_dx_start),
+ m_dist_start((line_mr(x + line_subpixel_scale/2) - line_mr(sx)) * m_dy_start -
+ (line_mr(y + line_subpixel_scale/2) - line_mr(sy)) * m_dx_start),
- m_dist_end((line_mr(x + line_subpixel_size/2) - line_mr(ex)) * m_dy_end -
- (line_mr(y + line_subpixel_size/2) - line_mr(ey)) * m_dx_end),
- m_len(int(len / scale))
+ m_dist_end((line_mr(x + line_subpixel_scale/2) - line_mr(ex)) * m_dy_end -
+ (line_mr(y + line_subpixel_scale/2) - line_mr(ey)) * m_dx_end),
+ m_len(uround(len / scale))
{
double d = len * scale;
- int dx = int(((x2 - x1) << line_subpixel_shift) / d);
- int dy = int(((y2 - y1) << line_subpixel_shift) / d);
+ int dx = iround(((x2 - x1) << line_subpixel_shift) / d);
+ int dy = iround(((y2 - y1) << line_subpixel_shift) / d);
m_dx_pict = -dy;
m_dy_pict = dx;
- m_dist_pict = ((x + line_subpixel_size/2 - (x1 - dy)) * m_dy_pict -
- (y + line_subpixel_size/2 - (y1 + dx)) * m_dx_pict) >>
+ m_dist_pict = ((x + line_subpixel_scale/2 - (x1 - dy)) * m_dy_pict -
+ (y + line_subpixel_scale/2 - (y1 + dx)) * m_dx_pict) >>
line_subpixel_shift;
m_dx <<= line_subpixel_shift;
@@ -479,7 +475,7 @@ namespace agg
typedef typename Renderer::color_type color_type;
//---------------------------------------------------------------------
- enum
+ enum max_half_width_e
{
max_half_width = 64
};
@@ -504,7 +500,8 @@ namespace agg
m_count((lp.vertical ? abs((lp.y2 >> line_subpixel_shift) - m_y) :
abs((lp.x2 >> line_subpixel_shift) - m_x))),
m_width(ren.subpixel_width()),
- m_max_extent(m_width >> (line_subpixel_shift - 2)),
+ //m_max_extent(m_width >> (line_subpixel_shift - 2)),
+ m_max_extent((m_width + line_subpixel_scale) >> line_subpixel_shift),
m_start(pattern_start + (m_max_extent + 2) * ren.pattern_width()),
m_step(0)
{
@@ -514,7 +511,7 @@ namespace agg
lp.len);
unsigned i;
- int stop = m_width + line_subpixel_size * 2;
+ int stop = m_width + line_subpixel_scale * 2;
for(i = 0; i < max_half_width; ++i)
{
m_dist_pos[i] = li.y();
@@ -823,25 +820,39 @@ namespace agg
m_ren(&ren),
m_pattern(&patt),
m_start(0),
- m_scale_x(1.0)
- {
- }
+ m_scale_x(1.0),
+ m_clip_box(0,0,0,0),
+ m_clipping(false)
+ {}
+ void attach(base_ren_type& ren) { m_ren = &ren; }
//---------------------------------------------------------------------
void pattern(const pattern_type& p) { m_pattern = &p; }
const pattern_type& pattern() const { return *m_pattern; }
//---------------------------------------------------------------------
+ void reset_clipping() { m_clipping = false; }
+ void clip_box(double x1, double y1, double x2, double y2)
+ {
+ m_clip_box.x1 = line_coord_sat::conv(x1);
+ m_clip_box.y1 = line_coord_sat::conv(y1);
+ m_clip_box.x2 = line_coord_sat::conv(x2);
+ m_clip_box.y2 = line_coord_sat::conv(y2);
+ m_clipping = true;
+ }
+
+ //---------------------------------------------------------------------
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; }
+ void start_x(double s) { m_start = iround(s * line_subpixel_scale); }
+ double start_x() const { return double(m_start) / line_subpixel_scale; }
//---------------------------------------------------------------------
int subpixel_width() const { return m_pattern->line_width(); }
int pattern_width() const { return m_pattern->pattern_width(); }
+ double width() const { return double(subpixel_width()) / line_subpixel_scale; }
//-------------------------------------------------------------------------
void pixel(color_type* p, int x, int y) const
@@ -871,6 +882,11 @@ namespace agg
}
//-------------------------------------------------------------------------
+ void pie(int, int, int, int, int, int)
+ {
+ }
+
+ //-------------------------------------------------------------------------
void line0(const line_parameters&)
{
}
@@ -886,9 +902,20 @@ namespace agg
}
//-------------------------------------------------------------------------
- void line3(const line_parameters& lp,
- int sx, int sy, int ex, int ey)
+ void line3_no_clip(const line_parameters& lp,
+ int sx, int sy, int ex, int ey)
{
+ if(lp.len > line_max_length)
+ {
+ line_parameters lp1, lp2;
+ lp.divide(lp1, lp2);
+ int mx = lp1.x2 + (lp1.y2 - lp1.y1);
+ int my = lp1.y2 - (lp1.x2 - lp1.x1);
+ line3_no_clip(lp1, (lp.x1 + sx) >> 1, (lp.y1 + sy) >> 1, mx, my);
+ line3_no_clip(lp2, mx, my, (lp.x2 + ex) >> 1, (lp.y2 + ey) >> 1);
+ return;
+ }
+
fix_degenerate_bisectrix_start(lp, &sx, &sy);
fix_degenerate_bisectrix_end(lp, &ex, &ey);
line_interpolator_image<self_type> li(*this, lp,
@@ -903,7 +930,67 @@ namespace agg
{
while(li.step_hor());
}
- m_start = li.pattern_end();
+ m_start += uround(lp.len / m_scale_x);
+ }
+
+ //-------------------------------------------------------------------------
+ void line3(const line_parameters& lp,
+ int sx, int sy, int ex, int ey)
+ {
+ if(m_clipping)
+ {
+ int x1 = lp.x1;
+ int y1 = lp.y1;
+ int x2 = lp.x2;
+ int y2 = lp.y2;
+ unsigned flags = clip_line_segment(&x1, &y1, &x2, &y2, m_clip_box);
+ int start = m_start;
+ if((flags & 4) == 0)
+ {
+ if(flags)
+ {
+ line_parameters lp2(x1, y1, x2, y2,
+ uround(calc_distance(x1, y1, x2, y2)));
+ if(flags & 1)
+ {
+ m_start += uround(calc_distance(lp.x1, lp.y1, x1, y1) / m_scale_x);
+ sx = x1 + (y2 - y1);
+ sy = y1 - (x2 - x1);
+ }
+ else
+ {
+ while(abs(sx - lp.x1) + abs(sy - lp.y1) > lp2.len)
+ {
+ sx = (lp.x1 + sx) >> 1;
+ sy = (lp.y1 + sy) >> 1;
+ }
+ }
+ if(flags & 2)
+ {
+ ex = x2 + (y2 - y1);
+ ey = y2 - (x2 - x1);
+ }
+ else
+ {
+ while(abs(ex - lp.x2) + abs(ey - lp.y2) > lp2.len)
+ {
+ ex = (lp.x2 + ex) >> 1;
+ ey = (lp.y2 + ey) >> 1;
+ }
+ }
+ line3_no_clip(lp2, sx, sy, ex, ey);
+ }
+ else
+ {
+ line3_no_clip(lp, sx, sy, ex, ey);
+ }
+ }
+ m_start = start + uround(lp.len / m_scale_x);
+ }
+ else
+ {
+ line3_no_clip(lp, sx, sy, ex, ey);
+ }
}
private:
@@ -911,6 +998,8 @@ namespace agg
const pattern_type* m_pattern;
int m_start;
double m_scale_x;
+ rect_i m_clip_box;
+ bool m_clipping;
};
diff --git a/agg/inc/agg_renderer_primitives.h b/agg/inc/agg_renderer_primitives.h
index 522432c06df6..dc1623e442cf 100755
--- a/agg/inc/agg_renderer_primitives.h
+++ b/agg/inc/agg_renderer_primitives.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -35,19 +35,19 @@ namespace agg
typedef typename base_ren_type::color_type color_type;
//--------------------------------------------------------------------
- renderer_primitives(base_ren_type& ren) :
+ explicit renderer_primitives(base_ren_type& ren) :
m_ren(&ren),
m_fill_color(),
m_line_color(),
m_curr_x(0),
m_curr_y(0)
- {
- }
+ {}
+ void attach(base_ren_type& ren) { m_ren = &ren; }
//--------------------------------------------------------------------
static int coord(double c)
{
- return int(c * line_bresenham_interpolator::subpixel_size);
+ return iround(c * line_bresenham_interpolator::subpixel_scale);
}
//--------------------------------------------------------------------
diff --git a/agg/inc/agg_renderer_raster_text.h b/agg/inc/agg_renderer_raster_text.h
index 957944600332..ea39c0524e14 100755
--- a/agg/inc/agg_renderer_raster_text.h
+++ b/agg/inc/agg_renderer_raster_text.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -34,8 +34,8 @@ namespace agg
renderer_raster_htext_solid(ren_type& ren, glyph_gen_type& glyph) :
m_ren(&ren),
m_glyph(&glyph)
- {
- }
+ {}
+ void attach(ren_type& ren) { m_ren = &ren; }
//--------------------------------------------------------------------
void color(const color_type& c) { m_color = c; }
@@ -219,7 +219,7 @@ namespace agg
m_glyph->prepare(&r, x, y, *str, flip);
if(r.x2 >= r.x1)
{
- m_ren->prepare(r.x2 - r.x1 + 1);
+ m_ren->prepare();
int i;
if(flip)
{
diff --git a/agg/inc/agg_renderer_scanline.h b/agg/inc/agg_renderer_scanline.h
index cc33942a3770..3deada41163d 100755
--- a/agg/inc/agg_renderer_scanline.h
+++ b/agg/inc/agg_renderer_scanline.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -18,195 +18,303 @@
#include "agg_basics.h"
#include "agg_renderer_base.h"
-#include "agg_render_scanlines.h"
namespace agg
{
- //====================================================renderer_scanline_aa
- template<class BaseRenderer, class SpanGenerator> class renderer_scanline_aa
+ //================================================render_scanline_aa_solid
+ template<class Scanline, class BaseRenderer, class ColorT>
+ void render_scanline_aa_solid(const Scanline& sl,
+ BaseRenderer& ren,
+ const ColorT& color)
{
- public:
- typedef BaseRenderer base_ren_type;
-
- //--------------------------------------------------------------------
- renderer_scanline_aa(base_ren_type& ren, SpanGenerator& span_gen) :
- m_ren(&ren),
- m_span_gen(&span_gen)
- {
- }
+ int y = sl.y();
+ unsigned num_spans = sl.num_spans();
+ typename Scanline::const_iterator span = sl.begin();
- //--------------------------------------------------------------------
- void prepare(unsigned max_span_len)
+ for(;;)
{
- m_span_gen->prepare(max_span_len);
+ int x = span->x;
+ if(span->len > 0)
+ {
+ ren.blend_solid_hspan(x, y, (unsigned)span->len,
+ color,
+ span->covers);
+ }
+ else
+ {
+ ren.blend_hline(x, y, (unsigned)(x - span->len - 1),
+ color,
+ *(span->covers));
+ }
+ if(--num_spans == 0) break;
+ ++span;
}
+ }
- //--------------------------------------------------------------------
- template<class Scanline> void render(const Scanline& sl)
+ //===============================================render_scanlines_aa_solid
+ template<class Rasterizer, class Scanline,
+ class BaseRenderer, class ColorT>
+ void render_scanlines_aa_solid(Rasterizer& ras, Scanline& sl,
+ BaseRenderer& ren, const ColorT& color)
+ {
+ if(ras.rewind_scanlines())
{
- int y = sl.y();
- m_ren->first_clip_box();
- do
+ // Explicitly convert "color" to the BaseRenderer color type.
+ // For example, it can be called with color type "rgba", while
+ // "rgba8" is needed. Otherwise it will be implicitly
+ // converted in the loop many times.
+ //----------------------
+ typename BaseRenderer::color_type ren_color(color);
+
+ sl.reset(ras.min_x(), ras.max_x());
+ while(ras.sweep_scanline(sl))
{
- int xmin = m_ren->xmin();
- int xmax = m_ren->xmax();
+ //render_scanline_aa_solid(sl, ren, ren_color);
+
+ // This code is equivalent to the above call (copy/paste).
+ // It's just a "manual" optimization for old compilers,
+ // like Microsoft Visual C++ v6.0
+ //-------------------------------
+ int y = sl.y();
+ unsigned num_spans = sl.num_spans();
+ typename Scanline::const_iterator span = sl.begin();
- if(y >= m_ren->ymin() && y <= m_ren->ymax())
+ for(;;)
{
- unsigned num_spans = sl.num_spans();
- typename Scanline::const_iterator span = sl.begin();
- do
+ int x = span->x;
+ if(span->len > 0)
{
- int x = span->x;
- int len = span->len;
- bool solid = false;
- const typename Scanline::cover_type* covers = span->covers;
-
- if(len < 0)
- {
- solid = true;
- len = -len;
- }
-
- if(x < xmin)
- {
- len -= xmin - x;
- if(!solid)
- {
- covers += xmin - x;
- }
- x = xmin;
- }
-
- if(len > 0)
- {
- if(x + len > xmax)
- {
- len = xmax - x + 1;
- }
- if(len > 0)
- {
- m_ren->blend_color_hspan_no_clip(
- x, y, len,
- m_span_gen->generate(x, y, len),
- solid ? 0 : covers,
- *covers);
- }
- }
- ++span;
+ ren.blend_solid_hspan(x, y, (unsigned)span->len,
+ ren_color,
+ span->covers);
+ }
+ else
+ {
+ ren.blend_hline(x, y, (unsigned)(x - span->len - 1),
+ ren_color,
+ *(span->covers));
}
- while(--num_spans);
+ if(--num_spans == 0) break;
+ ++span;
}
}
- while(m_ren->next_clip_box());
+ }
+ }
+
+ //==============================================renderer_scanline_aa_solid
+ template<class BaseRenderer> class renderer_scanline_aa_solid
+ {
+ public:
+ typedef BaseRenderer base_ren_type;
+ typedef typename base_ren_type::color_type color_type;
+
+ //--------------------------------------------------------------------
+ renderer_scanline_aa_solid() : m_ren(0) {}
+ explicit renderer_scanline_aa_solid(base_ren_type& ren) : m_ren(&ren) {}
+ void attach(base_ren_type& ren)
+ {
+ m_ren = &ren;
+ }
+
+ //--------------------------------------------------------------------
+ void color(const color_type& c) { m_color = c; }
+ const color_type& color() const { return m_color; }
+
+ //--------------------------------------------------------------------
+ void prepare() {}
+
+ //--------------------------------------------------------------------
+ template<class Scanline> void render(const Scanline& sl)
+ {
+ render_scanline_aa_solid(sl, *m_ren, m_color);
}
private:
base_ren_type* m_ren;
- SpanGenerator* m_span_gen;
+ color_type m_color;
};
- //==============================================renderer_scanline_aa_opaque
- template<class BaseRenderer, class SpanGenerator> class renderer_scanline_aa_opaque
+
+
+
+
+
+
+
+
+
+ //======================================================render_scanline_aa
+ template<class Scanline, class BaseRenderer,
+ class SpanAllocator, class SpanGenerator>
+ void render_scanline_aa(const Scanline& sl, BaseRenderer& ren,
+ SpanAllocator& alloc, SpanGenerator& span_gen)
+ {
+ int y = sl.y();
+
+ unsigned num_spans = sl.num_spans();
+ typename Scanline::const_iterator span = sl.begin();
+ for(;;)
+ {
+ int x = span->x;
+ int len = span->len;
+ const typename Scanline::cover_type* covers = span->covers;
+
+ if(len < 0) len = -len;
+ typename BaseRenderer::color_type* colors = alloc.allocate(len);
+ span_gen.generate(colors, x, y, len);
+ ren.blend_color_hspan(x, y, len, colors,
+ (span->len < 0) ? 0 : covers, *covers);
+
+ if(--num_spans == 0) break;
+ ++span;
+ }
+ }
+
+ //=====================================================render_scanlines_aa
+ template<class Rasterizer, class Scanline, class BaseRenderer,
+ class SpanAllocator, class SpanGenerator>
+ void render_scanlines_aa(Rasterizer& ras, Scanline& sl, BaseRenderer& ren,
+ SpanAllocator& alloc, SpanGenerator& span_gen)
+ {
+ if(ras.rewind_scanlines())
+ {
+ sl.reset(ras.min_x(), ras.max_x());
+ span_gen.prepare();
+ while(ras.sweep_scanline(sl))
+ {
+ render_scanline_aa(sl, ren, alloc, span_gen);
+ }
+ }
+ }
+
+ //====================================================renderer_scanline_aa
+ template<class BaseRenderer, class SpanAllocator, class SpanGenerator>
+ class renderer_scanline_aa
{
public:
- typedef BaseRenderer base_ren_type;
+ typedef BaseRenderer base_ren_type;
+ typedef SpanAllocator alloc_type;
+ typedef SpanGenerator span_gen_type;
//--------------------------------------------------------------------
- renderer_scanline_aa_opaque(base_ren_type& ren, SpanGenerator& span_gen) :
+ renderer_scanline_aa() : m_ren(0), m_alloc(0), m_span_gen(0) {}
+ renderer_scanline_aa(base_ren_type& ren,
+ alloc_type& alloc,
+ span_gen_type& span_gen) :
m_ren(&ren),
+ m_alloc(&alloc),
m_span_gen(&span_gen)
+ {}
+ void attach(base_ren_type& ren,
+ alloc_type& alloc,
+ span_gen_type& span_gen)
{
+ m_ren = &ren;
+ m_alloc = &alloc;
+ m_span_gen = &span_gen;
}
//--------------------------------------------------------------------
- void prepare(unsigned max_span_len)
- {
- m_span_gen->prepare(max_span_len);
- }
+ void prepare() { m_span_gen->prepare(); }
//--------------------------------------------------------------------
template<class Scanline> void render(const Scanline& sl)
{
- int y = sl.y();
- m_ren->first_clip_box();
- do
- {
- int xmin = m_ren->xmin();
- int xmax = m_ren->xmax();
-
- if(y >= m_ren->ymin() && y <= m_ren->ymax())
- {
- unsigned num_spans = sl.num_spans();
- typename Scanline::const_iterator span = sl.begin();
- do
- {
- int x = span->x;
- int len = span->len;
- bool solid = false;
- const typename Scanline::cover_type* covers = span->covers;
-
- if(len < 0)
- {
- solid = true;
- len = -len;
- }
-
- if(x < xmin)
- {
- len -= xmin - x;
- if(!solid)
- {
- covers += xmin - x;
- }
- x = xmin;
- }
-
- if(len > 0)
- {
- if(x + len > xmax)
- {
- len = xmax - x + 1;
- }
- if(len > 0)
- {
- m_ren->blend_opaque_color_hspan_no_clip(
- x, y, len,
- m_span_gen->generate(x, y, len),
- solid ? 0 : covers,
- *covers);
- }
- }
- ++span;
- }
- while(--num_spans);
- }
- }
- while(m_ren->next_clip_box());
+ render_scanline_aa(sl, *m_ren, *m_alloc, *m_span_gen);
}
private:
base_ren_type* m_ren;
- SpanGenerator* m_span_gen;
+ alloc_type* m_alloc;
+ span_gen_type* m_span_gen;
};
- //==============================================renderer_scanline_aa_solid
- template<class BaseRenderer> class renderer_scanline_aa_solid
+
+
+
+ //===============================================render_scanline_bin_solid
+ template<class Scanline, class BaseRenderer, class ColorT>
+ void render_scanline_bin_solid(const Scanline& sl,
+ BaseRenderer& ren,
+ const ColorT& color)
+ {
+ unsigned num_spans = sl.num_spans();
+ typename Scanline::const_iterator span = sl.begin();
+ for(;;)
+ {
+ ren.blend_hline(span->x,
+ sl.y(),
+ span->x - 1 + ((span->len < 0) ?
+ -span->len :
+ span->len),
+ color,
+ cover_full);
+ if(--num_spans == 0) break;
+ ++span;
+ }
+ }
+
+ //==============================================render_scanlines_bin_solid
+ template<class Rasterizer, class Scanline,
+ class BaseRenderer, class ColorT>
+ void render_scanlines_bin_solid(Rasterizer& ras, Scanline& sl,
+ BaseRenderer& ren, const ColorT& color)
+ {
+ if(ras.rewind_scanlines())
+ {
+ // Explicitly convert "color" to the BaseRenderer color type.
+ // For example, it can be called with color type "rgba", while
+ // "rgba8" is needed. Otherwise it will be implicitly
+ // converted in the loop many times.
+ //----------------------
+ typename BaseRenderer::color_type ren_color(color);
+
+ sl.reset(ras.min_x(), ras.max_x());
+ while(ras.sweep_scanline(sl))
+ {
+ //render_scanline_bin_solid(sl, ren, ren_color);
+
+ // This code is equivalent to the above call (copy/paste).
+ // It's just a "manual" optimization for old compilers,
+ // like Microsoft Visual C++ v6.0
+ //-------------------------------
+ unsigned num_spans = sl.num_spans();
+ typename Scanline::const_iterator span = sl.begin();
+ for(;;)
+ {
+ ren.blend_hline(span->x,
+ sl.y(),
+ span->x - 1 + ((span->len < 0) ?
+ -span->len :
+ span->len),
+ ren_color,
+ cover_full);
+ if(--num_spans == 0) break;
+ ++span;
+ }
+ }
+ }
+ }
+
+ //=============================================renderer_scanline_bin_solid
+ template<class BaseRenderer> class renderer_scanline_bin_solid
{
public:
typedef BaseRenderer base_ren_type;
typedef typename base_ren_type::color_type color_type;
//--------------------------------------------------------------------
- renderer_scanline_aa_solid(base_ren_type& ren) :
- m_ren(&ren)
+ renderer_scanline_bin_solid() : m_ren(0) {}
+ explicit renderer_scanline_bin_solid(base_ren_type& ren) : m_ren(&ren) {}
+ void attach(base_ren_type& ren)
{
+ m_ren = &ren;
}
//--------------------------------------------------------------------
@@ -214,33 +322,12 @@ namespace agg
const color_type& color() const { return m_color; }
//--------------------------------------------------------------------
- void prepare(unsigned) {}
+ void prepare() {}
//--------------------------------------------------------------------
template<class Scanline> void render(const Scanline& sl)
{
- int y = sl.y();
- unsigned num_spans = sl.num_spans();
- typename Scanline::const_iterator span = sl.begin();
-
- do
- {
- int x = span->x;
- if(span->len > 0)
- {
- m_ren->blend_solid_hspan(x, y, (unsigned)span->len,
- m_color,
- span->covers);
- }
- else
- {
- m_ren->blend_hline(x, y, (unsigned)(x - span->len - 1),
- m_color,
- *(span->covers));
- }
- ++span;
- }
- while(--num_spans);
+ render_scanline_bin_solid(sl, *m_ren, m_color);
}
private:
@@ -254,196 +341,511 @@ namespace agg
- //===================================================renderer_scanline_bin
- template<class BaseRenderer, class SpanGenerator> class renderer_scanline_bin
+
+ //======================================================render_scanline_bin
+ template<class Scanline, class BaseRenderer,
+ class SpanAllocator, class SpanGenerator>
+ void render_scanline_bin(const Scanline& sl, BaseRenderer& ren,
+ SpanAllocator& alloc, SpanGenerator& span_gen)
+ {
+ int y = sl.y();
+
+ unsigned num_spans = sl.num_spans();
+ typename Scanline::const_iterator span = sl.begin();
+ for(;;)
+ {
+ int x = span->x;
+ int len = span->len;
+ if(len < 0) len = -len;
+ typename BaseRenderer::color_type* colors = alloc.allocate(len);
+ span_gen.generate(colors, x, y, len);
+ ren.blend_color_hspan(x, y, len, colors, 0, cover_full);
+ if(--num_spans == 0) break;
+ ++span;
+ }
+ }
+
+ //=====================================================render_scanlines_bin
+ template<class Rasterizer, class Scanline, class BaseRenderer,
+ class SpanAllocator, class SpanGenerator>
+ void render_scanlines_bin(Rasterizer& ras, Scanline& sl, BaseRenderer& ren,
+ SpanAllocator& alloc, SpanGenerator& span_gen)
+ {
+ if(ras.rewind_scanlines())
+ {
+ sl.reset(ras.min_x(), ras.max_x());
+ span_gen.prepare();
+ while(ras.sweep_scanline(sl))
+ {
+ render_scanline_bin(sl, ren, alloc, span_gen);
+ }
+ }
+ }
+
+ //====================================================renderer_scanline_bin
+ template<class BaseRenderer, class SpanAllocator, class SpanGenerator>
+ class renderer_scanline_bin
{
public:
- typedef BaseRenderer base_ren_type;
+ typedef BaseRenderer base_ren_type;
+ typedef SpanAllocator alloc_type;
+ typedef SpanGenerator span_gen_type;
//--------------------------------------------------------------------
- renderer_scanline_bin(base_ren_type& ren, SpanGenerator& span_gen) :
+ renderer_scanline_bin() : m_ren(0), m_alloc(0), m_span_gen(0) {}
+ renderer_scanline_bin(base_ren_type& ren,
+ alloc_type& alloc,
+ span_gen_type& span_gen) :
m_ren(&ren),
+ m_alloc(&alloc),
m_span_gen(&span_gen)
+ {}
+ void attach(base_ren_type& ren,
+ alloc_type& alloc,
+ span_gen_type& span_gen)
{
+ m_ren = &ren;
+ m_alloc = &alloc;
+ m_span_gen = &span_gen;
}
//--------------------------------------------------------------------
- void prepare(unsigned max_span_len)
- {
- m_span_gen->prepare(max_span_len);
- }
+ void prepare() { m_span_gen->prepare(); }
//--------------------------------------------------------------------
template<class Scanline> void render(const Scanline& sl)
{
- int y = sl.y();
- m_ren->first_clip_box();
- do
- {
- int xmin = m_ren->xmin();
- int xmax = m_ren->xmax();
-
- if(y >= m_ren->ymin() && y <= m_ren->ymax())
- {
- unsigned num_spans = sl.num_spans();
- typename Scanline::const_iterator span = sl.begin();
- do
- {
- int x = span->x;
- int len = span->len;
-
- if(len < 0) len = -len;
- if(x < xmin)
- {
- len -= xmin - x;
- x = xmin;
- }
- if(len > 0)
- {
- if(x + len > xmax)
- {
- len = xmax - x + 1;
- }
- if(len > 0)
- {
- m_ren->blend_color_hspan_no_clip(
- x, y, len,
- m_span_gen->generate(x, y, len),
- 0);
- }
- }
- ++span;
- }
- while(--num_spans);
- }
- }
- while(m_ren->next_clip_box());
+ render_scanline_bin(sl, *m_ren, *m_alloc, *m_span_gen);
}
private:
base_ren_type* m_ren;
- SpanGenerator* m_span_gen;
+ alloc_type* m_alloc;
+ span_gen_type* m_span_gen;
};
- //===============================================renderer_scanline_bin_opaque
- template<class BaseRenderer, class SpanGenerator> class renderer_scanline_bin_opaque
- {
- public:
- typedef BaseRenderer base_ren_type;
- //--------------------------------------------------------------------
- renderer_scanline_bin_opaque(base_ren_type& ren, SpanGenerator& span_gen) :
- m_ren(&ren),
- m_span_gen(&span_gen)
+
+
+
+
+
+
+ //========================================================render_scanlines
+ template<class Rasterizer, class Scanline, class Renderer>
+ void render_scanlines(Rasterizer& ras, Scanline& sl, Renderer& ren)
+ {
+ if(ras.rewind_scanlines())
{
+ sl.reset(ras.min_x(), ras.max_x());
+ ren.prepare();
+ while(ras.sweep_scanline(sl))
+ {
+ ren.render(sl);
+ }
}
-
- //--------------------------------------------------------------------
- void prepare(unsigned max_span_len)
+ }
+
+ //========================================================render_all_paths
+ template<class Rasterizer, class Scanline, class Renderer,
+ class VertexSource, class ColorStorage, class PathId>
+ void render_all_paths(Rasterizer& ras,
+ Scanline& sl,
+ Renderer& r,
+ VertexSource& vs,
+ const ColorStorage& as,
+ const PathId& path_id,
+ unsigned num_paths)
+ {
+ for(unsigned i = 0; i < num_paths; i++)
{
- m_span_gen->prepare(max_span_len);
+ ras.reset();
+ ras.add_path(vs, path_id[i]);
+ r.color(as[i]);
+ render_scanlines(ras, sl, r);
}
+ }
- //--------------------------------------------------------------------
- template<class Scanline> void render(const Scanline& sl)
+
+
+
+
+
+ //=============================================render_scanlines_compound
+ template<class Rasterizer,
+ class ScanlineAA,
+ class ScanlineBin,
+ class BaseRenderer,
+ class SpanAllocator,
+ class StyleHandler>
+ void render_scanlines_compound(Rasterizer& ras,
+ ScanlineAA& sl_aa,
+ ScanlineBin& sl_bin,
+ BaseRenderer& ren,
+ SpanAllocator& alloc,
+ StyleHandler& sh)
+ {
+ if(ras.rewind_scanlines())
{
- int y = sl.y();
- m_ren->first_clip_box();
- do
+ int min_x = ras.min_x();
+ int len = ras.max_x() - min_x + 2;
+ sl_aa.reset(min_x, ras.max_x());
+ sl_bin.reset(min_x, ras.max_x());
+
+ typedef typename BaseRenderer::color_type color_type;
+ color_type* color_span = alloc.allocate(len * 2);
+ color_type* mix_buffer = color_span + len;
+ unsigned num_spans;
+
+ unsigned num_styles;
+ unsigned style;
+ bool solid;
+ while((num_styles = ras.sweep_styles()) > 0)
{
- int xmin = m_ren->xmin();
- int xmax = m_ren->xmax();
-
- if(y >= m_ren->ymin() && y <= m_ren->ymax())
+ typename ScanlineAA::const_iterator span_aa;
+ if(num_styles == 1)
{
- unsigned num_spans = sl.num_spans();
- typename Scanline::const_iterator span = sl.begin();
- do
+ // Optimization for a single style. Happens often
+ //-------------------------
+ if(ras.sweep_scanline(sl_aa, 0))
{
- int x = span->x;
- int len = span->len;
-
- if(len < 0) len = -len;
- if(x < xmin)
+ style = ras.style(0);
+ if(sh.is_solid(style))
{
- len -= xmin - x;
- x = xmin;
+ // Just solid fill
+ //-----------------------
+ render_scanline_aa_solid(sl_aa, ren, sh.color(style));
}
- if(len > 0)
+ else
{
- if(x + len > xmax)
- {
- len = xmax - x + 1;
- }
- if(len > 0)
+ // Arbitrary span generator
+ //-----------------------
+ span_aa = sl_aa.begin();
+ num_spans = sl_aa.num_spans();
+ for(;;)
{
- m_ren->blend_opaque_color_hspan_no_clip(
- x, y, len,
- m_span_gen->generate(x, y, len),
- 0);
+ len = span_aa->len;
+ sh.generate_span(color_span,
+ span_aa->x,
+ sl_aa.y(),
+ len,
+ style);
+
+ ren.blend_color_hspan(span_aa->x,
+ sl_aa.y(),
+ span_aa->len,
+ color_span,
+ span_aa->covers);
+ if(--num_spans == 0) break;
+ ++span_aa;
}
}
- ++span;
}
- while(--num_spans);
}
- }
- while(m_ren->next_clip_box());
- }
-
- private:
- base_ren_type* m_ren;
- SpanGenerator* m_span_gen;
- };
+ else
+ {
+ if(ras.sweep_scanline(sl_bin, -1))
+ {
+ // Clear the spans of the mix_buffer
+ //--------------------
+ typename ScanlineBin::const_iterator span_bin = sl_bin.begin();
+ num_spans = sl_bin.num_spans();
+ for(;;)
+ {
+ memset(mix_buffer + span_bin->x - min_x,
+ 0,
+ span_bin->len * sizeof(color_type));
+ if(--num_spans == 0) break;
+ ++span_bin;
+ }
+ unsigned i;
+ for(i = 0; i < num_styles; i++)
+ {
+ style = ras.style(i);
+ solid = sh.is_solid(style);
+ if(ras.sweep_scanline(sl_aa, i))
+ {
+ color_type* colors;
+ color_type* cspan;
+ typename ScanlineAA::cover_type* covers;
+ span_aa = sl_aa.begin();
+ num_spans = sl_aa.num_spans();
+ if(solid)
+ {
+ // Just solid fill
+ //-----------------------
+ for(;;)
+ {
+ color_type c = sh.color(style);
+ len = span_aa->len;
+ colors = mix_buffer + span_aa->x - min_x;
+ covers = span_aa->covers;
+ do
+ {
+ if(*covers == cover_full)
+ {
+ *colors = c;
+ }
+ else
+ {
+ colors->add(c, *covers);
+ }
+ ++colors;
+ ++covers;
+ }
+ while(--len);
+ if(--num_spans == 0) break;
+ ++span_aa;
+ }
+ }
+ else
+ {
+ // Arbitrary span generator
+ //-----------------------
+ for(;;)
+ {
+ len = span_aa->len;
+ colors = mix_buffer + span_aa->x - min_x;
+ cspan = color_span;
+ sh.generate_span(cspan,
+ span_aa->x,
+ sl_aa.y(),
+ len,
+ style);
+ covers = span_aa->covers;
+ do
+ {
+ if(*covers == cover_full)
+ {
+ *colors = *cspan;
+ }
+ else
+ {
+ colors->add(*cspan, *covers);
+ }
+ ++cspan;
+ ++colors;
+ ++covers;
+ }
+ while(--len);
+ if(--num_spans == 0) break;
+ ++span_aa;
+ }
+ }
+ }
+ }
- //=============================================renderer_scanline_bin_solid
- template<class BaseRenderer> class renderer_scanline_bin_solid
+ // Emit the blended result as a color hspan
+ //-------------------------
+ span_bin = sl_bin.begin();
+ num_spans = sl_bin.num_spans();
+ for(;;)
+ {
+ ren.blend_color_hspan(span_bin->x,
+ sl_bin.y(),
+ span_bin->len,
+ mix_buffer + span_bin->x - min_x,
+ 0,
+ cover_full);
+ if(--num_spans == 0) break;
+ ++span_bin;
+ }
+ } // if(ras.sweep_scanline(sl_bin, -1))
+ } // if(num_styles == 1) ... else
+ } // while((num_styles = ras.sweep_styles()) > 0)
+ } // if(ras.rewind_scanlines())
+ }
+
+ //=======================================render_scanlines_compound_layered
+ template<class Rasterizer,
+ class ScanlineAA,
+ class BaseRenderer,
+ class SpanAllocator,
+ class StyleHandler>
+ void render_scanlines_compound_layered(Rasterizer& ras,
+ ScanlineAA& sl_aa,
+ BaseRenderer& ren,
+ SpanAllocator& alloc,
+ StyleHandler& sh)
{
- public:
- typedef BaseRenderer base_ren_type;
- typedef typename base_ren_type::color_type color_type;
-
- //--------------------------------------------------------------------
- renderer_scanline_bin_solid(base_ren_type& ren) :
- m_ren(&ren)
+ if(ras.rewind_scanlines())
{
- }
+ int min_x = ras.min_x();
+ int len = ras.max_x() - min_x + 2;
+ sl_aa.reset(min_x, ras.max_x());
+
+ typedef typename BaseRenderer::color_type color_type;
+ color_type* color_span = alloc.allocate(len * 2);
+ color_type* mix_buffer = color_span + len;
+ cover_type* cover_buffer = ras.allocate_cover_buffer(len);
+ unsigned num_spans;
+
+ unsigned num_styles;
+ unsigned style;
+ bool solid;
+ while((num_styles = ras.sweep_styles()) > 0)
+ {
+ typename ScanlineAA::const_iterator span_aa;
+ if(num_styles == 1)
+ {
+ // Optimization for a single style. Happens often
+ //-------------------------
+ if(ras.sweep_scanline(sl_aa, 0))
+ {
+ style = ras.style(0);
+ if(sh.is_solid(style))
+ {
+ // Just solid fill
+ //-----------------------
+ render_scanline_aa_solid(sl_aa, ren, sh.color(style));
+ }
+ else
+ {
+ // Arbitrary span generator
+ //-----------------------
+ span_aa = sl_aa.begin();
+ num_spans = sl_aa.num_spans();
+ for(;;)
+ {
+ len = span_aa->len;
+ sh.generate_span(color_span,
+ span_aa->x,
+ sl_aa.y(),
+ len,
+ style);
+
+ ren.blend_color_hspan(span_aa->x,
+ sl_aa.y(),
+ span_aa->len,
+ color_span,
+ span_aa->covers);
+ if(--num_spans == 0) break;
+ ++span_aa;
+ }
+ }
+ }
+ }
+ else
+ {
+ int sl_start = ras.scanline_start();
+ unsigned sl_len = ras.scanline_length();
- //--------------------------------------------------------------------
- void color(const color_type& c) { m_color = c; }
- const color_type& color() const { return m_color; }
+ if(sl_len)
+ {
+ memset(mix_buffer + sl_start - min_x,
+ 0,
+ sl_len * sizeof(color_type));
- //--------------------------------------------------------------------
- void prepare(unsigned) {}
+ memset(cover_buffer + sl_start - min_x,
+ 0,
+ sl_len * sizeof(cover_type));
- //--------------------------------------------------------------------
- template<class Scanline> void render(const Scanline& sl)
- {
- unsigned num_spans = sl.num_spans();
- typename Scanline::const_iterator span = sl.begin();
- do
- {
- m_ren->blend_hline(span->x,
- sl.y(),
- span->x - 1 + ((span->len < 0) ?
- -span->len :
- span->len),
- m_color,
- cover_full);
- ++span;
- }
- while(--num_spans);
- }
+ int sl_y = 0x7FFFFFFF;
+ unsigned i;
+ for(i = 0; i < num_styles; i++)
+ {
+ style = ras.style(i);
+ solid = sh.is_solid(style);
+
+ if(ras.sweep_scanline(sl_aa, i))
+ {
+ unsigned cover;
+ color_type* colors;
+ color_type* cspan;
+ cover_type* src_covers;
+ cover_type* dst_covers;
+ span_aa = sl_aa.begin();
+ num_spans = sl_aa.num_spans();
+ sl_y = sl_aa.y();
+ if(solid)
+ {
+ // Just solid fill
+ //-----------------------
+ for(;;)
+ {
+ color_type c = sh.color(style);
+ len = span_aa->len;
+ colors = mix_buffer + span_aa->x - min_x;
+ src_covers = span_aa->covers;
+ dst_covers = cover_buffer + span_aa->x - min_x;
+ do
+ {
+ cover = *src_covers;
+ if(*dst_covers + cover > cover_full)
+ {
+ cover = cover_full - *dst_covers;
+ }
+ if(cover)
+ {
+ colors->add(c, cover);
+ *dst_covers += cover;
+ }
+ ++colors;
+ ++src_covers;
+ ++dst_covers;
+ }
+ while(--len);
+ if(--num_spans == 0) break;
+ ++span_aa;
+ }
+ }
+ else
+ {
+ // Arbitrary span generator
+ //-----------------------
+ for(;;)
+ {
+ len = span_aa->len;
+ colors = mix_buffer + span_aa->x - min_x;
+ cspan = color_span;
+ sh.generate_span(cspan,
+ span_aa->x,
+ sl_aa.y(),
+ len,
+ style);
+ src_covers = span_aa->covers;
+ dst_covers = cover_buffer + span_aa->x - min_x;
+ do
+ {
+ cover = *src_covers;
+ if(*dst_covers + cover > cover_full)
+ {
+ cover = cover_full - *dst_covers;
+ }
+ if(cover)
+ {
+ colors->add(*cspan, cover);
+ *dst_covers += cover;
+ }
+ ++cspan;
+ ++colors;
+ ++src_covers;
+ ++dst_covers;
+ }
+ while(--len);
+ if(--num_spans == 0) break;
+ ++span_aa;
+ }
+ }
+ }
+ }
+ ren.blend_color_hspan(sl_start,
+ sl_y,
+ sl_len,
+ mix_buffer + sl_start - min_x,
+ 0,
+ cover_full);
+ } //if(sl_len)
+ } //if(num_styles == 1) ... else
+ } //while((num_styles = ras.sweep_styles()) > 0)
+ } //if(ras.rewind_scanlines())
+ }
- private:
- base_ren_type* m_ren;
- color_type m_color;
- };
}
diff --git a/agg/inc/agg_rendering_buffer.h b/agg/inc/agg_rendering_buffer.h
index 50b6a46fdfa8..4a73e1a7185a 100755
--- a/agg/inc/agg_rendering_buffer.h
+++ b/agg/inc/agg_rendering_buffer.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -20,119 +20,222 @@
#ifndef AGG_RENDERING_BUFFER_INCLUDED
#define AGG_RENDERING_BUFFER_INCLUDED
-#include "agg_basics.h"
+#include "agg_array.h"
namespace agg
{
- //==========================================================row_ptr_cache
- template<class T> class row_ptr_cache
+ //===========================================================row_accessor
+ template<class T> class row_accessor
{
public:
+ typedef const_row_info<T> row_data;
+
+ //-------------------------------------------------------------------
+ row_accessor() :
+ m_buf(0),
+ m_start(0),
+ m_width(0),
+ m_height(0),
+ m_stride(0)
+ {
+ }
+
//--------------------------------------------------------------------
- struct row_data
+ row_accessor(T* buf, unsigned width, unsigned height, int stride) :
+ m_buf(0),
+ m_start(0),
+ m_width(0),
+ m_height(0),
+ m_stride(0)
{
- int x1, x2;
- const int8u* ptr;
- row_data() {}
- row_data(int x1_, int x2_, const int8u* ptr_) :
- x1(x1_), x2(x2_), ptr(ptr_) {}
- };
+ attach(buf, width, height, stride);
+ }
- //-------------------------------------------------------------------
- ~row_ptr_cache()
+
+ //--------------------------------------------------------------------
+ void attach(T* buf, unsigned width, unsigned height, int stride)
+ {
+ m_buf = m_start = buf;
+ m_width = width;
+ m_height = height;
+ m_stride = stride;
+ if(stride < 0)
+ {
+ m_start = m_buf - int(height - 1) * stride;
+ }
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE T* buf() { return m_buf; }
+ AGG_INLINE const T* buf() const { return m_buf; }
+ AGG_INLINE unsigned width() const { return m_width; }
+ AGG_INLINE unsigned height() const { return m_height; }
+ AGG_INLINE int stride() const { return m_stride; }
+ AGG_INLINE unsigned stride_abs() const
+ {
+ return (m_stride < 0) ? unsigned(-m_stride) : unsigned(m_stride);
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE T* row_ptr(int, int y, unsigned)
+ {
+ return m_start + y * m_stride;
+ }
+ AGG_INLINE T* row_ptr(int y) { return m_start + y * m_stride; }
+ AGG_INLINE const T* row_ptr(int y) const { return m_start + y * m_stride; }
+ AGG_INLINE row_data row (int y) const
+ {
+ return row_data(0, m_width-1, row_ptr(y));
+ }
+
+ //--------------------------------------------------------------------
+ template<class RenBuf>
+ void copy_from(const RenBuf& src)
+ {
+ unsigned h = height();
+ if(src.height() < h) h = src.height();
+
+ unsigned l = stride_abs();
+ if(src.stride_abs() < l) l = src.stride_abs();
+
+ l *= sizeof(T);
+
+ unsigned y;
+ unsigned w = width();
+ for (y = 0; y < h; y++)
+ {
+ memcpy(row_ptr(0, y, w), src.row_ptr(y), l);
+ }
+ }
+
+ //--------------------------------------------------------------------
+ void clear(T value)
{
- delete [] m_rows;
+ unsigned y;
+ unsigned w = width();
+ unsigned stride = stride_abs();
+ for(y = 0; y < height(); y++)
+ {
+ T* p = row_ptr(0, y, w);
+ unsigned x;
+ for(x = 0; x < stride; x++)
+ {
+ *p++ = value;
+ }
+ }
}
+ private:
+ //--------------------------------------------------------------------
+ T* m_buf; // Pointer to renrdering buffer
+ T* m_start; // Pointer to first pixel depending on stride
+ unsigned m_width; // Width in pixels
+ unsigned m_height; // Height in pixels
+ int m_stride; // Number of bytes per row. Can be < 0
+ };
+
+
+
+
+ //==========================================================row_ptr_cache
+ template<class T> class row_ptr_cache
+ {
+ public:
+ typedef const_row_info<T> row_data;
+
//-------------------------------------------------------------------
row_ptr_cache() :
m_buf(0),
- m_rows(0),
+ m_rows(),
m_width(0),
m_height(0),
- m_stride(0),
- m_max_height(0)
+ m_stride(0)
{
}
//--------------------------------------------------------------------
- row_ptr_cache(T* _buf, unsigned _width, unsigned _height, int _stride) :
+ row_ptr_cache(T* buf, unsigned width, unsigned height, int stride) :
m_buf(0),
- m_rows(0),
+ m_rows(),
m_width(0),
m_height(0),
- m_stride(0),
- m_max_height(0)
+ m_stride(0)
{
- attach(_buf, _width, _height, _stride);
+ attach(buf, width, height, stride);
}
//--------------------------------------------------------------------
- void attach(T* _buf, unsigned _width, unsigned _height, int _stride)
+ void attach(T* buf, unsigned width, unsigned height, int stride)
{
- m_buf = _buf;
- m_width = _width;
- m_height = _height;
- m_stride = _stride;
- if(_height > m_max_height)
+ m_buf = buf;
+ m_width = width;
+ m_height = height;
+ m_stride = stride;
+ if(height > m_rows.size())
{
- delete [] m_rows;
- m_rows = new T* [m_max_height = _height];
+ m_rows.resize(height);
}
T* row_ptr = m_buf;
- if(_stride < 0)
+ if(stride < 0)
{
- row_ptr = m_buf - int(_height - 1) * _stride;
+ row_ptr = m_buf - int(height - 1) * stride;
}
- T** _rows = m_rows;
+ T** rows = &m_rows[0];
- while(_height--)
+ while(height--)
{
- *_rows++ = row_ptr;
- row_ptr += _stride;
+ *rows++ = row_ptr;
+ row_ptr += stride;
}
}
//--------------------------------------------------------------------
- const T* buf() const { return m_buf; }
- unsigned width() const { return m_width; }
- unsigned height() const { return m_height; }
- int stride() const { return m_stride; }
- unsigned stride_abs() const
+ AGG_INLINE T* buf() { return m_buf; }
+ AGG_INLINE const T* buf() const { return m_buf; }
+ AGG_INLINE unsigned width() const { return m_width; }
+ AGG_INLINE unsigned height() const { return m_height; }
+ AGG_INLINE int stride() const { return m_stride; }
+ AGG_INLINE unsigned stride_abs() const
{
- return (m_stride < 0) ?
- unsigned(-m_stride) :
- unsigned(m_stride);
+ return (m_stride < 0) ? unsigned(-m_stride) : unsigned(m_stride);
}
//--------------------------------------------------------------------
- T* row(unsigned y) { return m_rows[y]; }
- const T* row(unsigned y) const { return m_rows[y]; }
-
- T* next_row(void* p) { return (T*)p + m_stride; }
- const T* next_row(const void* p) const { return (T*)p + m_stride; }
+ AGG_INLINE T* row_ptr(int, int y, unsigned)
+ {
+ return m_rows[y];
+ }
+ AGG_INLINE T* row_ptr(int y) { return m_rows[y]; }
+ AGG_INLINE const T* row_ptr(int y) const { return m_rows[y]; }
+ AGG_INLINE row_data row (int y) const
+ {
+ return row_data(0, m_width-1, m_rows[y]);
+ }
- T const* const* rows() const { return m_rows; }
+ //--------------------------------------------------------------------
+ T const* const* rows() const { return &m_rows[0]; }
//--------------------------------------------------------------------
- void copy_from(const row_ptr_cache<T>& mtx)
+ template<class RenBuf>
+ void copy_from(const RenBuf& src)
{
unsigned h = height();
- if(mtx.height() < h) h = mtx.height();
+ if(src.height() < h) h = src.height();
unsigned l = stride_abs();
- if(mtx.stride_abs() < l) l = mtx.stride_abs();
+ if(src.stride_abs() < l) l = src.stride_abs();
l *= sizeof(T);
unsigned y;
+ unsigned w = width();
for (y = 0; y < h; y++)
{
- memcpy(row(y), mtx.row(y), l);
+ memcpy(row_ptr(0, y, w), src.row_ptr(y), l);
}
}
@@ -140,38 +243,56 @@ namespace agg
void clear(T value)
{
unsigned y;
+ unsigned w = width();
+ unsigned stride = stride_abs();
for(y = 0; y < height(); y++)
{
- T* p = row(y);
+ T* p = row_ptr(0, y, w);
unsigned x;
- for(x = 0; x < stride_abs(); x++)
+ for(x = 0; x < stride; x++)
{
*p++ = value;
}
}
}
-
private:
//--------------------------------------------------------------------
- // Prohibit copying
- row_ptr_cache(const row_ptr_cache<T>&);
- const row_ptr_cache<T>& operator = (const row_ptr_cache<T>&);
-
- private:
- //--------------------------------------------------------------------
- T* m_buf; // Pointer to renrdering buffer
- T** m_rows; // Pointers to each row of the buffer
- unsigned m_width; // Width in pixels
- unsigned m_height; // Height in pixels
- int m_stride; // Number of bytes per row. Can be < 0
- unsigned m_max_height; // The maximal height (currently allocated)
+ T* m_buf; // Pointer to renrdering buffer
+ pod_array<T*> m_rows; // Pointers to each row of the buffer
+ unsigned m_width; // Width in pixels
+ unsigned m_height; // Height in pixels
+ int m_stride; // Number of bytes per row. Can be < 0
};
+
//========================================================rendering_buffer
- typedef row_ptr_cache<int8u> rendering_buffer;
+ //
+ // The definition of the main type for accessing the rows in the frame
+ // buffer. It provides functionality to navigate to the rows in a
+ // rectangular matrix, from top to bottom or from bottom to top depending
+ // on stride.
+ //
+ // row_accessor is cheap to create/destroy, but performs one multiplication
+ // when calling row_ptr().
+ //
+ // row_ptr_cache creates an array of pointers to rows, so, the access
+ // via row_ptr() may be faster. But it requires memory allocation
+ // when creating. For example, on typical Intel Pentium hardware
+ // row_ptr_cache speeds span_image_filter_rgb_nn up to 10%
+ //
+ // It's used only in short hand typedefs like pixfmt_rgba32 and can be
+ // redefined in agg_config.h
+ // In real applications you can use both, depending on your needs
+ //------------------------------------------------------------------------
+#ifdef AGG_RENDERING_BUFFER
+ typedef AGG_RENDERING_BUFFER rendering_buffer;
+#else
+// typedef row_ptr_cache<int8u> rendering_buffer;
+ typedef row_accessor<int8u> rendering_buffer;
+#endif
}
diff --git a/agg/inc/agg_rendering_buffer_dynarow.h b/agg/inc/agg_rendering_buffer_dynarow.h
index b6724d99ff78..b4332cad5adb 100755
--- a/agg/inc/agg_rendering_buffer_dynarow.h
+++ b/agg/inc/agg_rendering_buffer_dynarow.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -20,7 +20,7 @@
#ifndef AGG_RENDERING_BUFFER_DYNAROW_INCLUDED
#define AGG_RENDERING_BUFFER_DYNAROW_INCLUDED
-#include "agg_basics.h"
+#include "agg_array.h"
namespace agg
{
@@ -32,110 +32,68 @@ namespace agg
// 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
+ class rendering_buffer_dynarow
{
public:
- //-------------------------------------------------------------------
- struct row_data
- {
- int8u* ptr;
- int x1;
- int x2;
- };
+ typedef row_info<int8u> row_data;
//-------------------------------------------------------------------
~rendering_buffer_dynarow()
{
- init(0,0);
+ init(0,0,0);
}
//-------------------------------------------------------------------
rendering_buffer_dynarow() :
- m_rows(0),
+ m_rows(),
m_width(0),
- m_height(0)
+ m_height(0),
+ m_byte_width(0)
{
}
// Allocate and clear the buffer
//--------------------------------------------------------------------
- rendering_buffer_dynarow(unsigned width, unsigned height) :
- m_rows(new row_data[height]),
+ rendering_buffer_dynarow(unsigned width, unsigned height,
+ unsigned byte_width) :
+ m_rows(height),
m_width(width),
- m_height(height)
+ m_height(height),
+ m_byte_width(byte_width)
{
- memset(m_rows, 0, sizeof(row_data) * height);
+ memset(&m_rows[0], 0, sizeof(row_data) * height);
}
// Allocate and clear the buffer
//--------------------------------------------------------------------
- void init(unsigned width, unsigned height)
+ void init(unsigned width, unsigned height, unsigned byte_width)
{
unsigned i;
- for(i = 0; i < m_height; ++i) delete [] m_rows[i].ptr;
- delete [] m_rows;
- m_rows = 0;
+ for(i = 0; i < m_height; ++i)
+ {
+ pod_allocator<int8u>::deallocate((int8u*)m_rows[i].ptr, m_byte_width);
+ }
if(width && height)
{
m_width = width;
m_height = height;
- m_rows = new row_data[height];
- memset(m_rows, 0, sizeof(row_data) * height);
+ m_byte_width = byte_width;
+ m_rows.resize(height);
+ memset(&m_rows[0], 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;
- }
-
+ unsigned width() const { return m_width; }
+ unsigned height() const { return m_height; }
+ unsigned byte_width() const { return m_byte_width; }
// 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)
+ int8u* row_ptr(int x, int y, unsigned len)
{
- row_data* r = m_rows + y;
+ row_data* r = &m_rows[y];
int x2 = x + len - 1;
if(r->ptr)
{
@@ -144,37 +102,32 @@ namespace agg
}
else
{
- r->ptr = new int8u [m_width * PixWidth];
- r->x1 = x;
- r->x2 = x2;
- memset(r->ptr, 0, m_width * PixWidth);
+ int8u* p = pod_allocator<int8u>::allocate(m_byte_width);
+ r->ptr = p;
+ r->x1 = x;
+ r->x2 = x2;
+ memset(p, 0, m_byte_width);
}
- return r->ptr + x * PixWidth;
+ return (int8u*)r->ptr;
}
- // 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;
- }
-
-
+ const int8u* row_ptr(int y) const { return m_rows[y].ptr; }
+ int8u* row_ptr(int y) { return row_ptr(0, y, m_width); }
+ row_data row (int y) const { return m_rows[y]; }
private:
//--------------------------------------------------------------------
// Prohibit copying
- rendering_buffer_dynarow(const rendering_buffer_dynarow<PixWidth>&);
- const rendering_buffer_dynarow<PixWidth>&
- operator = (const rendering_buffer_dynarow<PixWidth>&);
+ rendering_buffer_dynarow(const rendering_buffer_dynarow&);
+ const rendering_buffer_dynarow& operator = (const rendering_buffer_dynarow&);
private:
//--------------------------------------------------------------------
- row_data* m_rows; // Pointers to each row of the buffer
- unsigned m_width; // Width in pixels
- unsigned m_height; // Height in pixels
+ pod_array<row_data> m_rows; // Pointers to each row of the buffer
+ unsigned m_width; // Width in pixels
+ unsigned m_height; // Height in pixels
+ unsigned m_byte_width; // Width in bytes
};
diff --git a/agg/inc/agg_rounded_rect.h b/agg/inc/agg_rounded_rect.h
index d4185dafa5b3..e2e621341ec1 100755
--- a/agg/inc/agg_rounded_rect.h
+++ b/agg/inc/agg_rounded_rect.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -22,8 +22,6 @@
#include "agg_basics.h"
#include "agg_arc.h"
-#include "agg_vertex_iterator.h"
-
namespace agg
{
@@ -51,11 +49,6 @@ namespace agg
void rewind(unsigned);
unsigned vertex(double* x, double* y);
- typedef rounded_rect source_type;
- typedef vertex_iterator<source_type> iterator;
- iterator begin(unsigned id) { return iterator(*this, id); }
- iterator end() { return iterator(path_cmd_stop); }
-
private:
double m_x1;
double m_y1;
diff --git a/agg/inc/agg_scanline_bin.h b/agg/inc/agg_scanline_bin.h
index aa60ed061e07..2836447175cb 100755
--- a/agg/inc/agg_scanline_bin.h
+++ b/agg/inc/agg_scanline_bin.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -16,10 +16,19 @@
// Class scanline_bin - binary scanline.
//
//----------------------------------------------------------------------------
+//
+// Adaptation for 32-bit screen coordinates (scanline32_bin) has been sponsored by
+// Liberty Technology Systems, Inc., visit http://lib-sys.com
+//
+// Liberty Technology Systems, Inc. is the provider of
+// PostScript and PDF technology for software developers.
+//
+//----------------------------------------------------------------------------
+
#ifndef AGG_SCANLINE_BIN_INCLUDED
#define AGG_SCANLINE_BIN_INCLUDED
-#include "agg_basics.h"
+#include "agg_array.h"
namespace agg
{
@@ -30,36 +39,12 @@ namespace agg
// used in the rasterizer::render(). See description of agg_scanline_u8
// for details.
//
- // Rendering:
- //-------------------------------------------------------------------------
- //
- // int y = sl.y();
- //
- // ************************************
- // ...Perform vertical clipping here...
- // ************************************
- //
- // unsigned num_spans = sl.num_spans();
- // const agg::scanline_bin::span* cur_span = sl.spans();
- //
- // do
- // {
- // x = cur_span->x;
- // len = cur_span->len;
- //
- // **************************************
- // ...Perform horizontal clipping here...
- // **************************************
- //
- // hor_line(x, y, len)
- // ++cur_span;
- // }
- // while(--num_spans);
- //
//------------------------------------------------------------------------
class scanline_bin
{
public:
+ typedef int32 coord_type;
+
struct span
{
int16 x;
@@ -68,103 +53,211 @@ namespace agg
typedef const span* const_iterator;
- ~scanline_bin()
+ //--------------------------------------------------------------------
+ scanline_bin() :
+ m_last_x(0x7FFFFFF0),
+ m_spans(),
+ m_cur_span(0)
{
- delete [] m_spans;
}
- scanline_bin() :
- m_max_len(0),
- m_last_x(0x7FFF),
- m_spans(0),
- m_cur_span(0)
+ //--------------------------------------------------------------------
+ void reset(int min_x, int max_x)
{
+ unsigned max_len = max_x - min_x + 3;
+ if(max_len > m_spans.size())
+ {
+ m_spans.resize(max_len);
+ }
+ m_last_x = 0x7FFFFFF0;
+ m_cur_span = &m_spans[0];
}
- void reset(int min_x, int max_x);
- void add_cell(int x, unsigned);
- void add_cells(int x, unsigned len, const void*);
- void add_span(int x, unsigned len, unsigned);
- void finalize(int y) { m_y = y; }
- void reset_spans();
+ //--------------------------------------------------------------------
+ void add_cell(int x, unsigned)
+ {
+ if(x == m_last_x+1)
+ {
+ m_cur_span->len++;
+ }
+ else
+ {
+ ++m_cur_span;
+ m_cur_span->x = (int16)x;
+ m_cur_span->len = 1;
+ }
+ m_last_x = x;
+ }
+ //--------------------------------------------------------------------
+ void add_span(int x, unsigned len, unsigned)
+ {
+ if(x == m_last_x+1)
+ {
+ m_cur_span->len = (int16)(m_cur_span->len + len);
+ }
+ else
+ {
+ ++m_cur_span;
+ m_cur_span->x = (int16)x;
+ m_cur_span->len = (int16)len;
+ }
+ m_last_x = x + len - 1;
+ }
+
+ //--------------------------------------------------------------------
+ void add_cells(int x, unsigned len, const void*)
+ {
+ add_span(x, len, 0);
+ }
+
+ //--------------------------------------------------------------------
+ void finalize(int y)
+ {
+ m_y = y;
+ }
+
+ //--------------------------------------------------------------------
+ void reset_spans()
+ {
+ m_last_x = 0x7FFFFFF0;
+ m_cur_span = &m_spans[0];
+ }
+
+ //--------------------------------------------------------------------
int y() const { return m_y; }
- unsigned num_spans() const { return unsigned(m_cur_span - m_spans); }
- const_iterator begin() const { return m_spans + 1; }
+ unsigned num_spans() const { return unsigned(m_cur_span - &m_spans[0]); }
+ const_iterator begin() const { return &m_spans[1]; }
private:
scanline_bin(const scanline_bin&);
const scanline_bin operator = (const scanline_bin&);
- unsigned m_max_len;
- int m_last_x;
- int m_y;
- span* m_spans;
- span* m_cur_span;
+ int m_last_x;
+ int m_y;
+ pod_array<span> m_spans;
+ span* m_cur_span;
};
- //------------------------------------------------------------------------
- inline void scanline_bin::reset(int min_x, int max_x)
+
+
+
+
+ //===========================================================scanline32_bin
+ class scanline32_bin
{
- unsigned max_len = max_x - min_x + 3;
- if(max_len > m_max_len)
+ public:
+ typedef int32 coord_type;
+
+ //--------------------------------------------------------------------
+ struct span
{
- delete [] m_spans;
- m_spans = new span [max_len];
- m_max_len = max_len;
- }
- m_last_x = 0x7FFF;
- m_cur_span = m_spans;
- }
+ span() {}
+ span(coord_type x_, coord_type len_) : x(x_), len(len_) {}
+ coord_type x;
+ coord_type len;
+ };
+ typedef pod_bvector<span, 4> span_array_type;
- //------------------------------------------------------------------------
- inline void scanline_bin::reset_spans()
- {
- m_last_x = 0x7FFF;
- m_cur_span = m_spans;
- }
+ //--------------------------------------------------------------------
+ class const_iterator
+ {
+ public:
+ const_iterator(const span_array_type& spans) :
+ m_spans(spans),
+ m_span_idx(0)
+ {}
- //------------------------------------------------------------------------
- inline void scanline_bin::add_cell(int x, unsigned)
- {
- if(x == m_last_x+1)
+ const span& operator*() const { return m_spans[m_span_idx]; }
+ const span* operator->() const { return &m_spans[m_span_idx]; }
+
+ void operator ++ () { ++m_span_idx; }
+
+ private:
+ const span_array_type& m_spans;
+ unsigned m_span_idx;
+ };
+
+
+ //--------------------------------------------------------------------
+ scanline32_bin() : m_max_len(0), m_last_x(0x7FFFFFF0) {}
+
+ //--------------------------------------------------------------------
+ void reset(int min_x, int max_x)
+ {
+ m_last_x = 0x7FFFFFF0;
+ m_spans.remove_all();
+ }
+
+ //--------------------------------------------------------------------
+ void add_cell(int x, unsigned)
{
- m_cur_span->len++;
+ if(x == m_last_x+1)
+ {
+ m_spans.last().len++;
+ }
+ else
+ {
+ m_spans.add(span(coord_type(x), 1));
+ }
+ m_last_x = x;
}
- else
+
+ //--------------------------------------------------------------------
+ void add_span(int x, unsigned len, unsigned)
{
- ++m_cur_span;
- m_cur_span->x = (int16)x;
- m_cur_span->len = 1;
+ if(x == m_last_x+1)
+ {
+ m_spans.last().len += coord_type(len);
+ }
+ else
+ {
+ m_spans.add(span(coord_type(x), coord_type(len)));
+ }
+ m_last_x = x + len - 1;
}
- m_last_x = x;
- }
+ //--------------------------------------------------------------------
+ void add_cells(int x, unsigned len, const void*)
+ {
+ add_span(x, len, 0);
+ }
- //------------------------------------------------------------------------
- inline void scanline_bin::add_span(int x, unsigned len, unsigned)
- {
- if(x == m_last_x+1)
+ //--------------------------------------------------------------------
+ void finalize(int y)
{
- m_cur_span->len = (int16)(m_cur_span->len + len);
+ m_y = y;
}
- else
+
+ //--------------------------------------------------------------------
+ void reset_spans()
{
- ++m_cur_span;
- m_cur_span->x = (int16)x;
- m_cur_span->len = (int16)len;
+ m_last_x = 0x7FFFFFF0;
+ m_spans.remove_all();
}
- m_last_x = x + len - 1;
- }
- //------------------------------------------------------------------------
- inline void scanline_bin::add_cells(int x, unsigned len, const void*)
- {
- add_span(x, len, 0);
- }
+ //--------------------------------------------------------------------
+ int y() const { return m_y; }
+ unsigned num_spans() const { return m_spans.size(); }
+ const_iterator begin() const { return const_iterator(m_spans); }
+
+ private:
+ scanline32_bin(const scanline32_bin&);
+ const scanline32_bin operator = (const scanline32_bin&);
+
+ unsigned m_max_len;
+ int m_last_x;
+ int m_y;
+ span_array_type m_spans;
+ };
+
+
+
+
+
}
diff --git a/agg/inc/agg_scanline_boolean_algebra.h b/agg/inc/agg_scanline_boolean_algebra.h
index 7f1a3c5ba774..cad386bac0c4 100755
--- a/agg/inc/agg_scanline_boolean_algebra.h
+++ b/agg/inc/agg_scanline_boolean_algebra.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -141,7 +141,7 @@ namespace agg
unsigned CoverShift = cover_shift>
struct sbool_intersect_spans_aa
{
- enum
+ enum cover_scale_e
{
cover_shift = CoverShift,
cover_size = 1 << cover_shift,
@@ -253,7 +253,7 @@ namespace agg
unsigned CoverShift = cover_shift>
struct sbool_unite_spans_aa
{
- enum
+ enum cover_scale_e
{
cover_shift = CoverShift,
cover_size = 1 << cover_shift,
@@ -362,7 +362,7 @@ namespace agg
template<unsigned CoverShift = cover_shift>
struct sbool_xor_formula_linear
{
- enum
+ enum cover_scale_e
{
cover_shift = CoverShift,
cover_size = 1 << cover_shift,
@@ -382,7 +382,7 @@ namespace agg
template<unsigned CoverShift = cover_shift>
struct sbool_xor_formula_saddle
{
- enum
+ enum cover_scale_e
{
cover_shift = CoverShift,
cover_size = 1 << cover_shift,
@@ -424,7 +424,7 @@ namespace agg
unsigned CoverShift = cover_shift>
struct sbool_xor_spans_aa
{
- enum
+ enum cover_scale_e
{
cover_shift = CoverShift,
cover_size = 1 << cover_shift,
@@ -513,7 +513,7 @@ namespace agg
unsigned CoverShift = cover_shift>
struct sbool_subtract_spans_aa
{
- enum
+ enum cover_scale_e
{
cover_shift = CoverShift,
cover_size = 1 << cover_shift,
@@ -629,14 +629,14 @@ namespace agg
AddSpanFunctor add_span)
{
sl.reset_spans();
- typename Scanline::const_iterator span = sl1.begin();
+ typename Scanline1::const_iterator span = sl1.begin();
unsigned num_spans = sl1.num_spans();
- do
+ for(;;)
{
add_span(span, span->x, abs((int)span->len), sl);
+ if(--num_spans == 0) break;
++span;
}
- while(--num_spans);
sl.finalize(sl1.y());
ren.render(sl);
}
@@ -671,8 +671,8 @@ namespace agg
unsigned num2 = sl2.num_spans();
if(num2 == 0) return;
- typename Scanline::const_iterator span1 = sl1.begin();
- typename Scanline::const_iterator span2 = sl2.begin();
+ typename Scanline1::const_iterator span1 = sl1.begin();
+ typename Scanline2::const_iterator span2 = sl2.begin();
while(num1 && num2)
{
@@ -705,20 +705,20 @@ namespace agg
{
--num1;
--num2;
- ++span1;
- ++span2;
+ if(num1) ++span1;
+ if(num2) ++span2;
}
else
{
if(advance_span1)
{
--num1;
- ++span1;
+ if(num1) ++span1;
}
else
{
--num2;
- ++span2;
+ if(num2) ++span2;
}
}
}
@@ -765,13 +765,13 @@ namespace agg
// Get the bounding boxes
//----------------
- rect r1(sg1.min_x(), sg1.min_y(), sg1.max_x(), sg1.max_y());
- rect r2(sg2.min_x(), sg2.min_y(), sg2.max_x(), sg2.max_y());
+ rect_i r1(sg1.min_x(), sg1.min_y(), sg1.max_x(), sg1.max_y());
+ rect_i r2(sg2.min_x(), sg2.min_y(), sg2.max_x(), sg2.max_y());
// Calculate the intersection of the bounding
// boxes and return if they don't intersect.
//-----------------
- rect ir = intersect_rectangles(r1, r2);
+ rect_i ir = intersect_rectangles(r1, r2);
if(!ir.is_valid()) return;
// Reset the scanlines and get two first ones
@@ -782,7 +782,7 @@ namespace agg
if(!sg1.sweep_scanline(sl1)) return;
if(!sg2.sweep_scanline(sl2)) return;
- ren.prepare(unsigned(ir.x2 - ir.x1 + 2));
+ ren.prepare();
// The main loop
// Here we synchronize the scanlines with
@@ -850,10 +850,14 @@ namespace agg
unsigned num1 = sl1.num_spans();
unsigned num2 = sl2.num_spans();
- typename Scanline::const_iterator span1;
- typename Scanline::const_iterator span2;
+ typename Scanline1::const_iterator span1;// = sl1.begin();
+ typename Scanline2::const_iterator span2;// = sl2.begin();
- enum { invalid_b = 0xFFFFFFF, invalid_e = invalid_b - 1 };
+ enum invalidation_e
+ {
+ invalid_b = 0xFFFFFFF,
+ invalid_e = invalid_b - 1
+ };
// Initialize the spans as invalid
//---------------
@@ -1037,15 +1041,19 @@ namespace agg
// Get the bounding boxes
//----------------
- rect r1(sg1.min_x(), sg1.min_y(), sg1.max_x(), sg1.max_y());
- rect r2(sg2.min_x(), sg2.min_y(), sg2.max_x(), sg2.max_y());
+ rect_i r1(sg1.min_x(), sg1.min_y(), sg1.max_x(), sg1.max_y());
+ rect_i r2(sg2.min_x(), sg2.min_y(), sg2.max_x(), sg2.max_y());
// Calculate the union of the bounding boxes
//-----------------
- rect ur = unite_rectangles(r1, r2);
+ rect_i ur(1,1,0,0);
+ if(flag1 && flag2) ur = unite_rectangles(r1, r2);
+ else if(flag1) ur = r1;
+ else if(flag2) ur = r2;
+
if(!ur.is_valid()) return;
- ren.prepare(unsigned(ur.x2 - ur.x2 + 2));
+ ren.prepare();
// Reset the scanlines and get two first ones
//-----------------
@@ -1158,7 +1166,7 @@ namespace agg
// Get the bounding box
//----------------
- rect r1(sg1.min_x(), sg1.min_y(), sg1.max_x(), sg1.max_y());
+ rect_i r1(sg1.min_x(), sg1.min_y(), sg1.max_x(), sg1.max_y());
// Reset the scanlines and get two first ones
//-----------------
@@ -1169,10 +1177,10 @@ namespace agg
if(flag2) flag2 = sg2.sweep_scanline(sl2);
- ren.prepare(unsigned(sg1.max_x() - sg1.min_x() + 2));
+ ren.prepare();
// A fake span2 processor
- sbool_add_span_empty<Scanline1, Scanline> add_span2;
+ sbool_add_span_empty<Scanline2, Scanline> add_span2;
// The main loop
// Here we synchronize the scanlines with
diff --git a/agg/inc/agg_scanline_p.h b/agg/inc/agg_scanline_p.h
index f217998578a1..19e1e9d5cb59 100755
--- a/agg/inc/agg_scanline_p.h
+++ b/agg/inc/agg_scanline_p.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -16,180 +16,312 @@
// Class scanline_p - a general purpose scanline container with packed spans.
//
//----------------------------------------------------------------------------
+//
+// Adaptation for 32-bit screen coordinates (scanline32_p) has been sponsored by
+// Liberty Technology Systems, Inc., visit http://lib-sys.com
+//
+// Liberty Technology Systems, Inc. is the provider of
+// PostScript and PDF technology for software developers.
+//
+//----------------------------------------------------------------------------
#ifndef AGG_SCANLINE_P_INCLUDED
#define AGG_SCANLINE_P_INCLUDED
-#include "agg_basics.h"
+#include "agg_array.h"
namespace agg
{
- //==============================================================scanline_p
+ //=============================================================scanline_p8
//
// This is a general purpose scaline container which supports the interface
- // used in the rasterizer::render(). See description of agg_scanline_u
+ // used in the rasterizer::render(). See description of scanline_u8
// for details.
//
//------------------------------------------------------------------------
- template<class T> class scanline_p
+ class scanline_p8
{
public:
- typedef T cover_type;
+ typedef scanline_p8 self_type;
+ typedef int8u cover_type;
+ typedef int16 coord_type;
+ //--------------------------------------------------------------------
struct span
{
- int16 x;
- int16 len; // If negative, it's a solid span, covers is valid
- const T* covers;
+ coord_type x;
+ coord_type len; // If negative, it's a solid span, covers is valid
+ const cover_type* covers;
};
typedef span* iterator;
typedef const span* const_iterator;
- ~scanline_p()
- {
- delete [] m_spans;
- delete [] m_covers;
- }
-
- scanline_p() :
- m_max_len(0),
+ scanline_p8() :
m_last_x(0x7FFFFFF0),
- m_covers(0),
+ m_covers(),
m_cover_ptr(0),
- m_spans(0),
+ m_spans(),
m_cur_span(0)
{
}
- void reset(int min_x, int max_x);
- void add_cell(int x, unsigned cover);
- void add_cells(int x, unsigned len, const T* covers);
- void add_span(int x, unsigned len, unsigned cover);
- void finalize(int y_) { m_y = y_; }
- void reset_spans();
+ //--------------------------------------------------------------------
+ void reset(int min_x, int max_x)
+ {
+ unsigned max_len = max_x - min_x + 3;
+ if(max_len > m_spans.size())
+ {
+ m_spans.resize(max_len);
+ m_covers.resize(max_len);
+ }
+ m_last_x = 0x7FFFFFF0;
+ m_cover_ptr = &m_covers[0];
+ m_cur_span = &m_spans[0];
+ m_cur_span->len = 0;
+ }
+
+ //--------------------------------------------------------------------
+ void add_cell(int x, unsigned cover)
+ {
+ *m_cover_ptr = (cover_type)cover;
+ if(x == m_last_x+1 && m_cur_span->len > 0)
+ {
+ m_cur_span->len++;
+ }
+ else
+ {
+ m_cur_span++;
+ m_cur_span->covers = m_cover_ptr;
+ m_cur_span->x = (int16)x;
+ m_cur_span->len = 1;
+ }
+ m_last_x = x;
+ m_cover_ptr++;
+ }
+
+ //--------------------------------------------------------------------
+ void add_cells(int x, unsigned len, const cover_type* covers)
+ {
+ memcpy(m_cover_ptr, covers, len * sizeof(cover_type));
+ if(x == m_last_x+1 && m_cur_span->len > 0)
+ {
+ m_cur_span->len += (int16)len;
+ }
+ else
+ {
+ m_cur_span++;
+ m_cur_span->covers = m_cover_ptr;
+ m_cur_span->x = (int16)x;
+ m_cur_span->len = (int16)len;
+ }
+ m_cover_ptr += len;
+ m_last_x = x + len - 1;
+ }
+ //--------------------------------------------------------------------
+ void add_span(int x, unsigned len, unsigned cover)
+ {
+ if(x == m_last_x+1 &&
+ m_cur_span->len < 0 &&
+ cover == *m_cur_span->covers)
+ {
+ m_cur_span->len -= (int16)len;
+ }
+ else
+ {
+ *m_cover_ptr = (cover_type)cover;
+ m_cur_span++;
+ m_cur_span->covers = m_cover_ptr++;
+ m_cur_span->x = (int16)x;
+ m_cur_span->len = (int16)(-int(len));
+ }
+ m_last_x = x + len - 1;
+ }
+
+ //--------------------------------------------------------------------
+ void finalize(int y)
+ {
+ m_y = y;
+ }
+
+ //--------------------------------------------------------------------
+ void reset_spans()
+ {
+ m_last_x = 0x7FFFFFF0;
+ m_cover_ptr = &m_covers[0];
+ m_cur_span = &m_spans[0];
+ m_cur_span->len = 0;
+ }
+
+ //--------------------------------------------------------------------
int y() const { return m_y; }
- unsigned num_spans() const { return unsigned(m_cur_span - m_spans); }
- const_iterator begin() const { return m_spans + 1; }
+ unsigned num_spans() const { return unsigned(m_cur_span - &m_spans[0]); }
+ const_iterator begin() const { return &m_spans[1]; }
private:
- scanline_p(const scanline_p<T>&);
- const scanline_p<T>& operator = (const scanline_p<T>&);
-
- unsigned m_max_len;
- int m_last_x;
- int m_y;
- T* m_covers;
- T* m_cover_ptr;
- span* m_spans;
- span* m_cur_span;
+ scanline_p8(const self_type&);
+ const self_type& operator = (const self_type&);
+
+ int m_last_x;
+ int m_y;
+ pod_array<cover_type> m_covers;
+ cover_type* m_cover_ptr;
+ pod_array<span> m_spans;
+ span* m_cur_span;
};
- //------------------------------------------------------------------------
- template<class T>
- void scanline_p<T>::reset(int min_x, int max_x)
- {
- unsigned max_len = max_x - min_x + 3;
- if(max_len > m_max_len)
- {
- delete [] m_spans;
- delete [] m_covers;
- m_covers = new T [max_len];
- m_spans = new span [max_len];
- m_max_len = max_len;
- }
- m_last_x = 0x7FFFFFF0;
- m_cover_ptr = m_covers;
- m_cur_span = m_spans;
- m_cur_span->len = 0;
- }
- //------------------------------------------------------------------------
- template<class T>
- void scanline_p<T>::reset_spans()
- {
- m_last_x = 0x7FFFFFF0;
- m_cover_ptr = m_covers;
- m_cur_span = m_spans;
- m_cur_span->len = 0;
- }
- //------------------------------------------------------------------------
- template<class T>
- void scanline_p<T>::add_cell(int x, unsigned cover)
+
+
+ //==========================================================scanline32_p8
+ class scanline32_p8
{
- *m_cover_ptr = (T)cover;
- if(x == m_last_x+1 && m_cur_span->len > 0)
+ public:
+ typedef scanline32_p8 self_type;
+ typedef int8u cover_type;
+ typedef int32 coord_type;
+
+ struct span
{
- m_cur_span->len++;
- }
- else
+ span() {}
+ span(coord_type x_, coord_type len_, const cover_type* covers_) :
+ x(x_), len(len_), covers(covers_) {}
+
+ coord_type x;
+ coord_type len; // If negative, it's a solid span, covers is valid
+ const cover_type* covers;
+ };
+ typedef pod_bvector<span, 4> span_array_type;
+
+
+ //--------------------------------------------------------------------
+ class const_iterator
+ {
+ public:
+ const_iterator(const span_array_type& spans) :
+ m_spans(spans),
+ m_span_idx(0)
+ {}
+
+ const span& operator*() const { return m_spans[m_span_idx]; }
+ const span* operator->() const { return &m_spans[m_span_idx]; }
+
+ void operator ++ () { ++m_span_idx; }
+
+ private:
+ const span_array_type& m_spans;
+ unsigned m_span_idx;
+ };
+
+ //--------------------------------------------------------------------
+ scanline32_p8() :
+ m_max_len(0),
+ m_last_x(0x7FFFFFF0),
+ m_covers(),
+ m_cover_ptr(0)
{
- m_cur_span++;
- m_cur_span->covers = m_cover_ptr;
- m_cur_span->x = (int16)x;
- m_cur_span->len = 1;
}
- m_last_x = x;
- m_cover_ptr++;
- }
+ //--------------------------------------------------------------------
+ void reset(int min_x, int max_x)
+ {
+ unsigned max_len = max_x - min_x + 3;
+ if(max_len > m_covers.size())
+ {
+ m_covers.resize(max_len);
+ }
+ m_last_x = 0x7FFFFFF0;
+ m_cover_ptr = &m_covers[0];
+ m_spans.remove_all();
+ }
- //------------------------------------------------------------------------
- template<class T>
- void scanline_p<T>::add_cells(int x, unsigned len, const T* covers)
- {
- memcpy(m_cover_ptr, covers, len * sizeof(T));
- if(x == m_last_x+1 && m_cur_span->len > 0)
+ //--------------------------------------------------------------------
+ void add_cell(int x, unsigned cover)
{
- m_cur_span->len += (int16)len;
+ *m_cover_ptr = cover_type(cover);
+ if(x == m_last_x+1 && m_spans.size() && m_spans.last().len > 0)
+ {
+ m_spans.last().len++;
+ }
+ else
+ {
+ m_spans.add(span(coord_type(x), 1, m_cover_ptr));
+ }
+ m_last_x = x;
+ m_cover_ptr++;
}
- else
+
+ //--------------------------------------------------------------------
+ void add_cells(int x, unsigned len, const cover_type* covers)
{
- m_cur_span++;
- m_cur_span->covers = m_cover_ptr;
- m_cur_span->x = (int16)x;
- m_cur_span->len = (int16)len;
+ memcpy(m_cover_ptr, covers, len * sizeof(cover_type));
+ if(x == m_last_x+1 && m_spans.size() && m_spans.last().len > 0)
+ {
+ m_spans.last().len += coord_type(len);
+ }
+ else
+ {
+ m_spans.add(span(coord_type(x), coord_type(len), m_cover_ptr));
+ }
+ m_cover_ptr += len;
+ m_last_x = x + len - 1;
}
- m_cover_ptr += len;
- m_last_x = x + len - 1;
- }
+ //--------------------------------------------------------------------
+ void add_span(int x, unsigned len, unsigned cover)
+ {
+ if(x == m_last_x+1 &&
+ m_spans.size() &&
+ m_spans.last().len < 0 &&
+ cover == *m_spans.last().covers)
+ {
+ m_spans.last().len -= coord_type(len);
+ }
+ else
+ {
+ *m_cover_ptr = cover_type(cover);
+ m_spans.add(span(coord_type(x), -coord_type(len), m_cover_ptr++));
+ }
+ m_last_x = x + len - 1;
+ }
- //------------------------------------------------------------------------
- template<class T>
- void scanline_p<T>::add_span(int x, unsigned len, unsigned cover)
- {
- if(x == m_last_x+1 &&
- m_cur_span->len < 0 &&
- cover == *m_cur_span->covers)
+ //--------------------------------------------------------------------
+ void finalize(int y)
{
- m_cur_span->len -= (int16)len;
+ m_y = y;
}
- else
+
+ //--------------------------------------------------------------------
+ void reset_spans()
{
- *m_cover_ptr = (T)cover;
- m_cur_span++;
- m_cur_span->covers = m_cover_ptr++;
- m_cur_span->x = (int16)x;
- m_cur_span->len = -((int16)len);
+ m_last_x = 0x7FFFFFF0;
+ m_cover_ptr = &m_covers[0];
+ m_spans.remove_all();
}
- m_last_x = x + len - 1;
- }
+ //--------------------------------------------------------------------
+ int y() const { return m_y; }
+ unsigned num_spans() const { return m_spans.size(); }
+ const_iterator begin() const { return const_iterator(m_spans); }
+
+ private:
+ scanline32_p8(const self_type&);
+ const self_type& operator = (const self_type&);
- //=============================================================scanline_p8
- typedef scanline_p<int8u> scanline_p8;
+ unsigned m_max_len;
+ int m_last_x;
+ int m_y;
+ pod_array<cover_type> m_covers;
+ cover_type* m_cover_ptr;
+ span_array_type m_spans;
+ };
- //============================================================scanline_p16
- typedef scanline_p<int16u> scanline_p16;
- //============================================================scanline_p32
- typedef scanline_p<int32u> scanline_p32;
}
diff --git a/agg/inc/agg_scanline_storage_aa.h b/agg/inc/agg_scanline_storage_aa.h
index 3d8b5b946cf9..279b9f39bbc1 100755
--- a/agg/inc/agg_scanline_storage_aa.h
+++ b/agg/inc/agg_scanline_storage_aa.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -12,6 +12,14 @@
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
+//
+// Adaptation for 32-bit screen coordinates has been sponsored by
+// Liberty Technology Systems, Inc., visit http://lib-sys.com
+//
+// Liberty Technology Systems, Inc. is the provider of
+// PostScript and PDF technology for software developers.
+//
+//----------------------------------------------------------------------------
#ifndef AGG_SCANLINE_STORAGE_AA_INCLUDED
#define AGG_SCANLINE_STORAGE_AA_INCLUDED
@@ -20,7 +28,6 @@
#include <stdlib.h>
#include <math.h>
#include "agg_array.h"
-#include "agg_render_scanlines.h"
namespace agg
@@ -76,7 +83,8 @@ namespace agg
int i;
for(i = m_extra_storage.size()-1; i >= 0; --i)
{
- delete [] m_extra_storage[(unsigned)i].ptr;
+ pod_allocator<T>::deallocate(m_extra_storage[i].ptr,
+ m_extra_storage[i].len);
}
m_extra_storage.remove_all();
m_cells.remove_all();
@@ -94,7 +102,7 @@ namespace agg
}
extra_span s;
s.len = num_cells;
- s.ptr = new T [num_cells];
+ s.ptr = pod_allocator<T>::allocate(num_cells);
memcpy(s.ptr, cells, sizeof(T) * num_cells);
m_extra_storage.add(s);
return -int(m_extra_storage.size());
@@ -135,14 +143,14 @@ namespace agg
const extra_span& src = v.m_extra_storage[i];
extra_span dst;
dst.len = src.len;
- dst.ptr = new T [dst.len];
+ dst.ptr = pod_allocator<T>::allocate(dst.len);
memcpy(dst.ptr, src.ptr, dst.len * sizeof(T));
m_extra_storage.add(dst);
}
}
- pod_deque<T, 12> m_cells;
- pod_deque<extra_span, 6> m_extra_storage;
+ pod_bvector<T, 12> m_cells;
+ pod_bvector<extra_span, 6> m_extra_storage;
};
@@ -159,8 +167,8 @@ namespace agg
//---------------------------------------------------------------
struct span_data
{
- int16 x;
- int16 len; // If negative, it's a solid span, covers is valid
+ int32 x;
+ int32 len; // If negative, it's a solid span, covers is valid
int covers_id; // The index of the cells in the scanline_cell_storage
};
@@ -184,11 +192,12 @@ namespace agg
public:
struct span
{
- int16 x;
- int16 len; // If negative, it's a solid span, covers is valid
+ int32 x;
+ int32 len; // If negative, it's a solid span, covers is valid
const T* covers;
};
+ const_iterator() : m_storage(0) {}
const_iterator(const embedded_scanline& sl) :
m_storage(sl.m_storage),
m_span_idx(sl.m_scanline.start_span)
@@ -270,7 +279,7 @@ namespace agg
// Renderer Interface
//---------------------------------------------------------------
- void prepare(unsigned)
+ void prepare()
{
m_covers.remove_all();
m_scanlines.remove_all();
@@ -297,7 +306,7 @@ namespace agg
typename Scanline::const_iterator span_iterator = sl.begin();
unsigned num_spans = sl_this.num_spans;
- do
+ for(;;)
{
span_data sp;
@@ -312,9 +321,9 @@ namespace agg
int x2 = sp.x + len - 1;
if(x1 < m_min_x) m_min_x = x1;
if(x2 > m_max_x) m_max_x = x2;
+ if(--num_spans == 0) break;
++span_iterator;
}
- while(--num_spans);
m_scanlines.add(sl_this);
}
@@ -388,11 +397,11 @@ namespace agg
unsigned byte_size() const
{
unsigned i;
- unsigned size = sizeof(int16) * 4; // min_x, min_y, max_x, max_y
+ unsigned size = sizeof(int32) * 4; // min_x, min_y, max_x, max_y
for(i = 0; i < m_scanlines.size(); ++i)
{
- size += sizeof(int16) * 3; // scanline size in bytes, Y, num_spans
+ size += sizeof(int32) * 3; // scanline size in bytes, Y, num_spans
const scanline_data& sl_this = m_scanlines[i];
@@ -402,7 +411,7 @@ namespace agg
{
const span_data& sp = m_spans[span_idx++];
- size += sizeof(int16) * 2; // X, span_len
+ size += sizeof(int32) * 2; // X, span_len
if(sp.len < 0)
{
size += sizeof(T); // cover
@@ -419,10 +428,12 @@ namespace agg
//---------------------------------------------------------------
- static void write_int16(int8u* dst, int16 val)
+ static void write_int32(int8u* dst, int32 val)
{
dst[0] = ((const int8u*)&val)[0];
dst[1] = ((const int8u*)&val)[1];
+ dst[2] = ((const int8u*)&val)[2];
+ dst[3] = ((const int8u*)&val)[3];
}
@@ -431,27 +442,27 @@ namespace agg
{
unsigned i;
- write_int16(data, int16u(min_x())); // min_x
- data += sizeof(int16u);
- write_int16(data, int16u(min_y())); // min_y
- data += sizeof(int16u);
- write_int16(data, int16u(max_x())); // max_x
- data += sizeof(int16u);
- write_int16(data, int16u(max_y())); // max_y
- data += sizeof(int16u);
+ write_int32(data, min_x()); // min_x
+ data += sizeof(int32);
+ write_int32(data, min_y()); // min_y
+ data += sizeof(int32);
+ write_int32(data, max_x()); // max_x
+ data += sizeof(int32);
+ write_int32(data, max_y()); // max_y
+ data += sizeof(int32);
for(i = 0; i < m_scanlines.size(); ++i)
{
const scanline_data& sl_this = m_scanlines[i];
int8u* size_ptr = data;
- data += sizeof(int16); // Reserve space for scanline size in bytes
+ data += sizeof(int32); // Reserve space for scanline size in bytes
- write_int16(data, int16(sl_this.y)); // Y
- data += sizeof(int16);
+ write_int32(data, sl_this.y); // Y
+ data += sizeof(int32);
- write_int16(data, int16(sl_this.num_spans)); // num_spans
- data += sizeof(int16);
+ write_int32(data, sl_this.num_spans); // num_spans
+ data += sizeof(int32);
unsigned num_spans = sl_this.num_spans;
unsigned span_idx = sl_this.start_span;
@@ -460,11 +471,11 @@ namespace agg
const span_data& sp = m_spans[span_idx++];
const T* covers = covers_by_index(sp.covers_id);
- write_int16(data, int16(sp.x)); // X
- data += sizeof(int16);
+ write_int32(data, sp.x); // X
+ data += sizeof(int32);
- write_int16(data, int16(sp.len)); // span_len
- data += sizeof(int16);
+ write_int32(data, sp.len); // span_len
+ data += sizeof(int32);
if(sp.len < 0)
{
@@ -478,7 +489,7 @@ namespace agg
}
}
while(--num_spans);
- write_int16(size_ptr, int16(unsigned(data - size_ptr)));
+ write_int32(size_ptr, int32(unsigned(data - size_ptr)));
}
}
@@ -502,9 +513,9 @@ namespace agg
}
private:
- scanline_cell_storage<T> m_covers;
- pod_deque<span_data, 10> m_spans;
- pod_deque<scanline_data, 8> m_scanlines;
+ scanline_cell_storage<T> m_covers;
+ pod_bvector<span_data, 10> m_spans;
+ pod_bvector<scanline_data, 8> m_scanlines;
span_data m_fake_span;
scanline_data m_fake_scanline;
int m_min_x;
@@ -540,11 +551,12 @@ namespace agg
public:
struct span
{
- int16 x;
- int16 len; // If negative, it's a solid span, "covers" is valid
+ int32 x;
+ int32 len; // If negative, it's a solid span, "covers" is valid
const T* covers;
};
+ const_iterator() : m_ptr(0) {}
const_iterator(const embedded_scanline& sl) :
m_ptr(sl.m_ptr),
m_dx(sl.m_dx)
@@ -569,18 +581,20 @@ namespace agg
}
private:
- int read_int16()
+ int read_int32()
{
- int16 val;
+ int32 val;
((int8u*)&val)[0] = *m_ptr++;
((int8u*)&val)[1] = *m_ptr++;
+ ((int8u*)&val)[2] = *m_ptr++;
+ ((int8u*)&val)[3] = *m_ptr++;
return val;
}
void init_span()
{
- m_span.x = read_int16() + m_dx;
- m_span.len = read_int16();
+ m_span.x = read_int32() + m_dx;
+ m_span.len = read_int32();
m_span.covers = m_ptr;
}
@@ -604,11 +618,13 @@ namespace agg
private:
//-----------------------------------------------------------------
- int read_int16()
+ int read_int32()
{
- int16 val;
+ int32 val;
((int8u*)&val)[0] = *m_ptr++;
((int8u*)&val)[1] = *m_ptr++;
+ ((int8u*)&val)[2] = *m_ptr++;
+ ((int8u*)&val)[3] = *m_ptr++;
return val;
}
@@ -617,8 +633,8 @@ namespace agg
void init(const int8u* ptr, int dx, int dy)
{
m_ptr = ptr;
- m_y = read_int16() + dy;
- m_num_spans = unsigned(read_int16());
+ m_y = read_int32() + dy;
+ m_num_spans = unsigned(read_int32());
m_dx = dx;
}
@@ -651,8 +667,8 @@ namespace agg
m_data(data),
m_end(data + size),
m_ptr(data),
- m_dx(int(floor(dx + 0.5))),
- m_dy(int(floor(dy + 0.5))),
+ m_dx(iround(dx)),
+ m_dy(iround(dy)),
m_min_x(0x7FFFFFFF),
m_min_y(0x7FFFFFFF),
m_max_x(-0x7FFFFFFF),
@@ -665,8 +681,8 @@ namespace agg
m_data = data;
m_end = data + size;
m_ptr = data;
- m_dx = int(floor(dx + 0.5));
- m_dy = int(floor(dy + 0.5));
+ m_dx = iround(dx);
+ m_dy = iround(dy);
m_min_x = 0x7FFFFFFF;
m_min_y = 0x7FFFFFFF;
m_max_x = -0x7FFFFFFF;
@@ -675,20 +691,24 @@ namespace agg
private:
//--------------------------------------------------------------------
- int read_int16()
+ int read_int32()
{
- int16 val;
+ int32 val;
((int8u*)&val)[0] = *m_ptr++;
((int8u*)&val)[1] = *m_ptr++;
+ ((int8u*)&val)[2] = *m_ptr++;
+ ((int8u*)&val)[3] = *m_ptr++;
return val;
}
//--------------------------------------------------------------------
- unsigned read_int16u()
+ unsigned read_int32u()
{
- int16u val;
+ int32u val;
((int8u*)&val)[0] = *m_ptr++;
((int8u*)&val)[1] = *m_ptr++;
+ ((int8u*)&val)[2] = *m_ptr++;
+ ((int8u*)&val)[3] = *m_ptr++;
return val;
}
@@ -700,13 +720,12 @@ namespace agg
m_ptr = m_data;
if(m_ptr < m_end)
{
- m_min_x = read_int16() + m_dx;
- m_min_y = read_int16() + m_dy;
- m_max_x = read_int16() + m_dx;
- m_max_y = read_int16() + m_dy;
- return true;
+ m_min_x = read_int32() + m_dx;
+ m_min_y = read_int32() + m_dy;
+ m_max_x = read_int32() + m_dx;
+ m_max_y = read_int32() + m_dy;
}
- return false;
+ return m_ptr < m_end;
}
//--------------------------------------------------------------------
@@ -723,14 +742,14 @@ namespace agg
{
if(m_ptr >= m_end) return false;
- read_int16(); // Skip scanline size in bytes
- int y = read_int16() + m_dy;
- unsigned num_spans = read_int16();
+ read_int32(); // Skip scanline size in bytes
+ int y = read_int32() + m_dy;
+ unsigned num_spans = read_int32();
do
{
- int x = read_int16() + m_dx;
- int len = read_int16();
+ int x = read_int32() + m_dx;
+ int len = read_int32();
if(len < 0)
{
@@ -763,9 +782,9 @@ namespace agg
{
if(m_ptr >= m_end) return false;
- unsigned byte_size = read_int16u();
+ unsigned byte_size = read_int32u();
sl.init(m_ptr, m_dx, m_dy);
- m_ptr += byte_size - sizeof(int16);
+ m_ptr += byte_size - sizeof(int32);
}
while(sl.num_spans() == 0);
return true;
diff --git a/agg/inc/agg_scanline_storage_bin.h b/agg/inc/agg_scanline_storage_bin.h
index 90fa50e4ee6d..b0a322edc817 100755
--- a/agg/inc/agg_scanline_storage_bin.h
+++ b/agg/inc/agg_scanline_storage_bin.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -12,6 +12,15 @@
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
+//
+// Adaptation for 32-bit screen coordinates has been sponsored by
+// Liberty Technology Systems, Inc., visit http://lib-sys.com
+//
+// Liberty Technology Systems, Inc. is the provider of
+// PostScript and PDF technology for software developers.
+//
+//----------------------------------------------------------------------------
+
#ifndef AGG_SCANLINE_STORAGE_BIN_INCLUDED
#define AGG_SCANLINE_STORAGE_BIN_INCLUDED
@@ -20,7 +29,6 @@
#include <stdlib.h>
#include <math.h>
#include "agg_array.h"
-#include "agg_render_scanlines.h"
namespace agg
@@ -33,8 +41,8 @@ namespace agg
//---------------------------------------------------------------
struct span_data
{
- int16 x;
- int16 len;
+ int32 x;
+ int32 len;
};
//---------------------------------------------------------------
@@ -55,6 +63,7 @@ namespace agg
class const_iterator
{
public:
+ const_iterator() : m_storage(0) {}
const_iterator(const embedded_scanline& sl) :
m_storage(sl.m_storage),
m_span_idx(sl.m_scanline.start_span)
@@ -126,7 +135,7 @@ namespace agg
// Renderer Interface
//---------------------------------------------------------------
- void prepare(unsigned)
+ void prepare()
{
m_scanlines.remove_all();
m_spans.remove_all();
@@ -152,19 +161,19 @@ namespace agg
typename Scanline::const_iterator span_iterator = sl.begin();
unsigned num_spans = sl_this.num_spans;
- do
+ for(;;)
{
span_data sp;
sp.x = span_iterator->x;
- sp.len = (int16)abs((int)(span_iterator->len));
+ sp.len = (int32)abs((int)(span_iterator->len));
m_spans.add(sp);
int x1 = sp.x;
int x2 = sp.x + sp.len - 1;
if(x1 < m_min_x) m_min_x = x1;
if(x2 > m_max_x) m_max_x = x2;
+ if(--num_spans == 0) break;
++span_iterator;
}
- while(--num_spans);
m_scanlines.add(sl_this);
}
@@ -232,22 +241,24 @@ namespace agg
unsigned byte_size() const
{
unsigned i;
- unsigned size = sizeof(int16) * 4; // min_x, min_y, max_x, max_y
+ unsigned size = sizeof(int32) * 4; // min_x, min_y, max_x, max_y
for(i = 0; i < m_scanlines.size(); ++i)
{
- size += sizeof(int16) * 2 + // Y, num_spans
- unsigned(m_scanlines[i].num_spans) * sizeof(int16) * 2; // X, span_len
+ size += sizeof(int32) * 2 + // Y, num_spans
+ unsigned(m_scanlines[i].num_spans) * sizeof(int32) * 2; // X, span_len
}
return size;
}
//---------------------------------------------------------------
- static void write_int16(int8u* dst, int16 val)
+ static void write_int32(int8u* dst, int32 val)
{
dst[0] = ((const int8u*)&val)[0];
dst[1] = ((const int8u*)&val)[1];
+ dst[2] = ((const int8u*)&val)[2];
+ dst[3] = ((const int8u*)&val)[3];
}
@@ -256,24 +267,24 @@ namespace agg
{
unsigned i;
- write_int16(data, int16u(min_x())); // min_x
- data += sizeof(int16u);
- write_int16(data, int16u(min_y())); // min_y
- data += sizeof(int16u);
- write_int16(data, int16u(max_x())); // max_x
- data += sizeof(int16u);
- write_int16(data, int16u(max_y())); // max_y
- data += sizeof(int16u);
+ write_int32(data, min_x()); // min_x
+ data += sizeof(int32);
+ write_int32(data, min_y()); // min_y
+ data += sizeof(int32);
+ write_int32(data, max_x()); // max_x
+ data += sizeof(int32);
+ write_int32(data, max_y()); // max_y
+ data += sizeof(int32);
for(i = 0; i < m_scanlines.size(); ++i)
{
const scanline_data& sl_this = m_scanlines[i];
- write_int16(data, int16(sl_this.y)); // Y
- data += sizeof(int16);
+ write_int32(data, sl_this.y); // Y
+ data += sizeof(int32);
- write_int16(data, int16(sl_this.num_spans)); // num_spans
- data += sizeof(int16);
+ write_int32(data, sl_this.num_spans); // num_spans
+ data += sizeof(int32);
unsigned num_spans = sl_this.num_spans;
unsigned span_idx = sl_this.start_span;
@@ -281,11 +292,11 @@ namespace agg
{
const span_data& sp = m_spans[span_idx++];
- write_int16(data, int16(sp.x)); // X
- data += sizeof(int16);
+ write_int32(data, sp.x); // X
+ data += sizeof(int32);
- write_int16(data, int16(sp.len)); // len
- data += sizeof(int16);
+ write_int32(data, sp.len); // len
+ data += sizeof(int32);
}
while(--num_spans);
}
@@ -306,8 +317,8 @@ namespace agg
private:
- pod_deque<span_data, 10> m_spans;
- pod_deque<scanline_data, 8> m_scanlines;
+ pod_bvector<span_data, 10> m_spans;
+ pod_bvector<scanline_data, 8> m_scanlines;
span_data m_fake_span;
scanline_data m_fake_scanline;
int m_min_x;
@@ -346,16 +357,17 @@ namespace agg
public:
struct span
{
- int16 x;
- int16 len;
+ int32 x;
+ int32 len;
};
+ const_iterator() : m_ptr(0) {}
const_iterator(const embedded_scanline& sl) :
m_ptr(sl.m_ptr),
m_dx(sl.m_dx)
{
- m_span.x = read_int16() + m_dx;
- m_span.len = read_int16();
+ m_span.x = read_int32() + m_dx;
+ m_span.len = read_int32();
}
const span& operator*() const { return m_span; }
@@ -363,16 +375,18 @@ namespace agg
void operator ++ ()
{
- m_span.x = read_int16() + m_dx;
- m_span.len = read_int16();
+ m_span.x = read_int32() + m_dx;
+ m_span.len = read_int32();
}
private:
- int read_int16()
+ int read_int32()
{
- int16 val;
+ int32 val;
((int8u*)&val)[0] = *m_ptr++;
((int8u*)&val)[1] = *m_ptr++;
+ ((int8u*)&val)[2] = *m_ptr++;
+ ((int8u*)&val)[3] = *m_ptr++;
return val;
}
@@ -396,11 +410,13 @@ namespace agg
private:
//----------------------------------------------------------------
- int read_int16()
+ int read_int32()
{
- int16 val;
+ int32 val;
((int8u*)&val)[0] = *m_ptr++;
((int8u*)&val)[1] = *m_ptr++;
+ ((int8u*)&val)[2] = *m_ptr++;
+ ((int8u*)&val)[3] = *m_ptr++;
return val;
}
@@ -409,8 +425,8 @@ namespace agg
void init(const int8u* ptr, int dx, int dy)
{
m_ptr = ptr;
- m_y = read_int16() + dy;
- m_num_spans = unsigned(read_int16());
+ m_y = read_int32() + dy;
+ m_num_spans = unsigned(read_int32());
m_dx = dx;
}
@@ -443,8 +459,8 @@ namespace agg
m_data(data),
m_end(data + size),
m_ptr(data),
- m_dx(int(floor(dx + 0.5))),
- m_dy(int(floor(dy + 0.5))),
+ m_dx(iround(dx)),
+ m_dy(iround(dy)),
m_min_x(0x7FFFFFFF),
m_min_y(0x7FFFFFFF),
m_max_x(-0x7FFFFFFF),
@@ -457,8 +473,8 @@ namespace agg
m_data = data;
m_end = data + size;
m_ptr = data;
- m_dx = int(floor(dx + 0.5));
- m_dy = int(floor(dy + 0.5));
+ m_dx = iround(dx);
+ m_dy = iround(dy);
m_min_x = 0x7FFFFFFF;
m_min_y = 0x7FFFFFFF;
m_max_x = -0x7FFFFFFF;
@@ -467,11 +483,13 @@ namespace agg
private:
//--------------------------------------------------------------------
- int read_int16()
+ int read_int32()
{
- int16 val;
+ int32 val;
((int8u*)&val)[0] = *m_ptr++;
((int8u*)&val)[1] = *m_ptr++;
+ ((int8u*)&val)[2] = *m_ptr++;
+ ((int8u*)&val)[3] = *m_ptr++;
return val;
}
@@ -483,13 +501,12 @@ namespace agg
m_ptr = m_data;
if(m_ptr < m_end)
{
- m_min_x = read_int16() + m_dx;
- m_min_y = read_int16() + m_dy;
- m_max_x = read_int16() + m_dx;
- m_max_y = read_int16() + m_dy;
- return true;
+ m_min_x = read_int32() + m_dx;
+ m_min_y = read_int32() + m_dy;
+ m_max_x = read_int32() + m_dx;
+ m_max_y = read_int32() + m_dy;
}
- return false;
+ return m_ptr < m_end;
}
//--------------------------------------------------------------------
@@ -506,13 +523,13 @@ namespace agg
{
if(m_ptr >= m_end) return false;
- int y = read_int16() + m_dy;
- unsigned num_spans = read_int16();
+ int y = read_int32() + m_dy;
+ unsigned num_spans = read_int32();
do
{
- int x = read_int16() + m_dx;
- int len = read_int16();
+ int x = read_int32() + m_dx;
+ int len = read_int32();
if(len < 0) len = -len;
sl.add_span(x, unsigned(len), cover_full);
@@ -541,9 +558,9 @@ namespace agg
// Jump to the next scanline
//--------------------------
- read_int16(); // Y
- int num_spans = read_int16(); // num_spans
- m_ptr += num_spans * sizeof(int16) * 2;
+ read_int32(); // Y
+ int num_spans = read_int32(); // num_spans
+ m_ptr += num_spans * sizeof(int32) * 2;
}
while(sl.num_spans() == 0);
return true;
diff --git a/agg/inc/agg_scanline_u.h b/agg/inc/agg_scanline_u.h
index 749c5b3c0054..561ae5ca89ac 100755
--- a/agg/inc/agg_scanline_u.h
+++ b/agg/inc/agg_scanline_u.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -12,20 +12,27 @@
// mcseemagg@yahoo.com
// http://www.antigrain.com
//----------------------------------------------------------------------------
+//
+// Adaptation for 32-bit screen coordinates (scanline32_u) has been sponsored by
+// Liberty Technology Systems, Inc., visit http://lib-sys.com
+//
+// Liberty Technology Systems, Inc. is the provider of
+// PostScript and PDF technology for software developers.
+//
+//----------------------------------------------------------------------------
#ifndef AGG_SCANLINE_U_INCLUDED
#define AGG_SCANLINE_U_INCLUDED
-#include <string.h>
-#include "agg_basics.h"
+#include "agg_array.h"
namespace agg
{
- //==============================================================scanline_u
+ //=============================================================scanline_u8
//
// Unpacked scanline container class
//
- // This class is used to transfer data from a scanline rastyerizer
+ // This class is used to transfer data from a scanline rasterizer
// to the rendering buffer. It's organized very simple. The class stores
// information of horizontal spans to render it into a pixel-map buffer.
// Each span has staring X, length, and an array of bytes that determine the
@@ -94,21 +101,23 @@ namespace agg
//
// The question is: why should we accumulate the whole scanline when we
// could render just separate spans when they're ready?
- // That's because using the scaline is generally faster. When is consists
+ // That's because using the scanline is generally faster. When is consists
// of more than one span the conditions for the processor cash system
// are better, because switching between two different areas of memory
- // (that can be very large) occures less frequently.
+ // (that can be very large) occurs less frequently.
//------------------------------------------------------------------------
- template<class T> class scanline_u
+ class scanline_u8
{
public:
- typedef T cover_type;
+ typedef scanline_u8 self_type;
+ typedef int8u cover_type;
+ typedef int16 coord_type;
//--------------------------------------------------------------------
struct span
{
- int16 x;
- int16 len;
+ coord_type x;
+ coord_type len;
cover_type* covers;
};
@@ -116,181 +125,360 @@ namespace agg
typedef const span* const_iterator;
//--------------------------------------------------------------------
- ~scanline_u();
- scanline_u();
+ scanline_u8() :
+ m_min_x(0),
+ m_last_x(0x7FFFFFF0),
+ m_cur_span(0)
+ {}
- void reset(int min_x, int max_x);
- void add_cell(int x, unsigned cover);
- void add_cells(int x, unsigned len, const T* covers);
- void add_span(int x, unsigned len, unsigned cover);
- void finalize(int y) { m_y = y; }
- void reset_spans();
+ //--------------------------------------------------------------------
+ void reset(int min_x, int max_x)
+ {
+ unsigned max_len = max_x - min_x + 2;
+ if(max_len > m_spans.size())
+ {
+ m_spans.resize(max_len);
+ m_covers.resize(max_len);
+ }
+ m_last_x = 0x7FFFFFF0;
+ m_min_x = min_x;
+ m_cur_span = &m_spans[0];
+ }
+ //--------------------------------------------------------------------
+ void add_cell(int x, unsigned cover)
+ {
+ x -= m_min_x;
+ m_covers[x] = (cover_type)cover;
+ if(x == m_last_x+1)
+ {
+ m_cur_span->len++;
+ }
+ else
+ {
+ m_cur_span++;
+ m_cur_span->x = (coord_type)(x + m_min_x);
+ m_cur_span->len = 1;
+ m_cur_span->covers = &m_covers[x];
+ }
+ m_last_x = x;
+ }
+
+ //--------------------------------------------------------------------
+ void add_cells(int x, unsigned len, const cover_type* covers)
+ {
+ x -= m_min_x;
+ memcpy(&m_covers[x], covers, len * sizeof(cover_type));
+ if(x == m_last_x+1)
+ {
+ m_cur_span->len += (coord_type)len;
+ }
+ else
+ {
+ m_cur_span++;
+ m_cur_span->x = (coord_type)(x + m_min_x);
+ m_cur_span->len = (coord_type)len;
+ m_cur_span->covers = &m_covers[x];
+ }
+ m_last_x = x + len - 1;
+ }
+
+ //--------------------------------------------------------------------
+ void add_span(int x, unsigned len, unsigned cover)
+ {
+ x -= m_min_x;
+ memset(&m_covers[x], cover, len);
+ if(x == m_last_x+1)
+ {
+ m_cur_span->len += (coord_type)len;
+ }
+ else
+ {
+ m_cur_span++;
+ m_cur_span->x = (coord_type)(x + m_min_x);
+ m_cur_span->len = (coord_type)len;
+ m_cur_span->covers = &m_covers[x];
+ }
+ m_last_x = x + len - 1;
+ }
+
+ //--------------------------------------------------------------------
+ void finalize(int y)
+ {
+ m_y = y;
+ }
+
+ //--------------------------------------------------------------------
+ void reset_spans()
+ {
+ m_last_x = 0x7FFFFFF0;
+ m_cur_span = &m_spans[0];
+ }
+
+ //--------------------------------------------------------------------
int y() const { return m_y; }
- unsigned num_spans() const { return unsigned(m_cur_span - m_spans); }
- const_iterator begin() const { return m_spans + 1; }
- iterator begin() { return m_spans + 1; }
+ unsigned num_spans() const { return unsigned(m_cur_span - &m_spans[0]); }
+ const_iterator begin() const { return &m_spans[1]; }
+ iterator begin() { return &m_spans[1]; }
private:
- scanline_u<T>(const scanline_u<T>&);
- const scanline_u<T>& operator = (const scanline_u<T>&);
+ scanline_u8(const self_type&);
+ const self_type& operator = (const self_type&);
private:
- int m_min_x;
- unsigned m_max_len;
- int m_last_x;
- int m_y;
- cover_type* m_covers;
- span* m_spans;
- span* m_cur_span;
+ int m_min_x;
+ int m_last_x;
+ int m_y;
+ pod_array<cover_type> m_covers;
+ pod_array<span> m_spans;
+ span* m_cur_span;
};
- //------------------------------------------------------------------------
- template<class T> scanline_u<T>::~scanline_u()
- {
- delete [] m_spans;
- delete [] m_covers;
- }
-
+ //==========================================================scanline_u8_am
+ //
+ // The scanline container with alpha-masking
+ //
//------------------------------------------------------------------------
- template<class T> scanline_u<T>::scanline_u() :
- m_min_x(0),
- m_max_len(0),
- m_last_x(0x7FFFFFF0),
- m_covers(0),
- m_spans(0),
- m_cur_span(0)
+ template<class AlphaMask>
+ class scanline_u8_am : public scanline_u8
{
- }
+ public:
+ typedef scanline_u8 base_type;
+ typedef AlphaMask alpha_mask_type;
+ typedef base_type::cover_type cover_type;
+ typedef base_type::coord_type coord_type;
+ scanline_u8_am() : base_type(), m_alpha_mask(0) {}
+ scanline_u8_am(const AlphaMask& am) : base_type(), m_alpha_mask(&am) {}
- //------------------------------------------------------------------------
- template<class T> void scanline_u<T>::reset(int min_x, int max_x)
- {
- unsigned max_len = max_x - min_x + 2;
- if(max_len > m_max_len)
+ //--------------------------------------------------------------------
+ void finalize(int span_y)
{
- delete [] m_spans;
- delete [] m_covers;
- m_covers = new cover_type [max_len];
- m_spans = new span [max_len];
- m_max_len = max_len;
+ base_type::finalize(span_y);
+ if(m_alpha_mask)
+ {
+ typename base_type::iterator span = base_type::begin();
+ unsigned count = base_type::num_spans();
+ do
+ {
+ m_alpha_mask->combine_hspan(span->x,
+ base_type::y(),
+ span->covers,
+ span->len);
+ ++span;
+ }
+ while(--count);
+ }
}
- m_last_x = 0x7FFFFFF0;
- m_min_x = min_x;
- m_cur_span = m_spans;
- }
+ private:
+ const AlphaMask* m_alpha_mask;
+ };
- //------------------------------------------------------------------------
- template<class T> inline void scanline_u<T>::reset_spans()
- {
- m_last_x = 0x7FFFFFF0;
- m_cur_span = m_spans;
- }
- //------------------------------------------------------------------------
- template<class T> inline void scanline_u<T>::add_cell(int x, unsigned cover)
+
+ //===========================================================scanline32_u8
+ class scanline32_u8
{
- x -= m_min_x;
- m_covers[x] = (unsigned char)cover;
- if(x == m_last_x+1)
+ public:
+ typedef scanline32_u8 self_type;
+ typedef int8u cover_type;
+ typedef int32 coord_type;
+
+ //--------------------------------------------------------------------
+ struct span
{
- m_cur_span->len++;
- }
- else
+ span() {}
+ span(coord_type x_, coord_type len_, cover_type* covers_) :
+ x(x_), len(len_), covers(covers_) {}
+
+ coord_type x;
+ coord_type len;
+ cover_type* covers;
+ };
+
+ typedef pod_bvector<span, 4> span_array_type;
+
+ //--------------------------------------------------------------------
+ class const_iterator
{
- m_cur_span++;
- m_cur_span->x = (int16)(x + m_min_x);
- m_cur_span->len = 1;
- m_cur_span->covers = m_covers + x;
- }
- m_last_x = x;
- }
+ public:
+ const_iterator(const span_array_type& spans) :
+ m_spans(spans),
+ m_span_idx(0)
+ {}
+ const span& operator*() const { return m_spans[m_span_idx]; }
+ const span* operator->() const { return &m_spans[m_span_idx]; }
- //------------------------------------------------------------------------
- template<class T> void scanline_u<T>::add_cells(int x, unsigned len, const T* covers)
- {
- x -= m_min_x;
- memcpy(m_covers + x, covers, len * sizeof(T));
- if(x == m_last_x+1)
+ void operator ++ () { ++m_span_idx; }
+
+ private:
+ const span_array_type& m_spans;
+ unsigned m_span_idx;
+ };
+
+ //--------------------------------------------------------------------
+ class iterator
{
- m_cur_span->len += (int16)len;
+ public:
+ iterator(span_array_type& spans) :
+ m_spans(spans),
+ m_span_idx(0)
+ {}
+
+ span& operator*() { return m_spans[m_span_idx]; }
+ span* operator->() { return &m_spans[m_span_idx]; }
+
+ void operator ++ () { ++m_span_idx; }
+
+ private:
+ span_array_type& m_spans;
+ unsigned m_span_idx;
+ };
+
+
+
+ //--------------------------------------------------------------------
+ scanline32_u8() :
+ m_min_x(0),
+ m_last_x(0x7FFFFFF0),
+ m_covers()
+ {}
+
+ //--------------------------------------------------------------------
+ void reset(int min_x, int max_x)
+ {
+ unsigned max_len = max_x - min_x + 2;
+ if(max_len > m_covers.size())
+ {
+ m_covers.resize(max_len);
+ }
+ m_last_x = 0x7FFFFFF0;
+ m_min_x = min_x;
+ m_spans.remove_all();
}
- else
+
+ //--------------------------------------------------------------------
+ void add_cell(int x, unsigned cover)
{
- m_cur_span++;
- m_cur_span->x = (int16)(x + m_min_x);
- m_cur_span->len = (int16)len;
- m_cur_span->covers = m_covers + x;
+ x -= m_min_x;
+ m_covers[x] = cover_type(cover);
+ if(x == m_last_x+1)
+ {
+ m_spans.last().len++;
+ }
+ else
+ {
+ m_spans.add(span(coord_type(x + m_min_x), 1, &m_covers[x]));
+ }
+ m_last_x = x;
}
- m_last_x = x + len - 1;
- }
+ //--------------------------------------------------------------------
+ void add_cells(int x, unsigned len, const cover_type* covers)
+ {
+ x -= m_min_x;
+ memcpy(&m_covers[x], covers, len * sizeof(cover_type));
+ if(x == m_last_x+1)
+ {
+ m_spans.last().len += coord_type(len);
+ }
+ else
+ {
+ m_spans.add(span(coord_type(x + m_min_x),
+ coord_type(len),
+ &m_covers[x]));
+ }
+ m_last_x = x + len - 1;
+ }
- //------------------------------------------------------------------------
- template<class T> void scanline_u<T>::add_span(int x, unsigned len, unsigned cover)
- {
- x -= m_min_x;
- memset(m_covers + x, cover, len);
- if(x == m_last_x+1)
+ //--------------------------------------------------------------------
+ void add_span(int x, unsigned len, unsigned cover)
+ {
+ x -= m_min_x;
+ memset(&m_covers[x], cover, len);
+ if(x == m_last_x+1)
+ {
+ m_spans.last().len += coord_type(len);
+ }
+ else
+ {
+ m_spans.add(span(coord_type(x + m_min_x),
+ coord_type(len),
+ &m_covers[x]));
+ }
+ m_last_x = x + len - 1;
+ }
+
+ //--------------------------------------------------------------------
+ void finalize(int y)
{
- m_cur_span->len += (int16)len;
+ m_y = y;
}
- else
+
+ //--------------------------------------------------------------------
+ void reset_spans()
{
- m_cur_span++;
- m_cur_span->x = (int16)(x + m_min_x);
- m_cur_span->len = (int16)len;
- m_cur_span->covers = m_covers + x;
+ m_last_x = 0x7FFFFFF0;
+ m_spans.remove_all();
}
- m_last_x = x + len - 1;
- }
+ //--------------------------------------------------------------------
+ int y() const { return m_y; }
+ unsigned num_spans() const { return m_spans.size(); }
+ const_iterator begin() const { return const_iterator(m_spans); }
+ iterator begin() { return iterator(m_spans); }
- //=============================================================scanline_u8
- typedef scanline_u<int8u> scanline_u8;
+ private:
+ scanline32_u8(const self_type&);
+ const self_type& operator = (const self_type&);
+
+ private:
+ int m_min_x;
+ int m_last_x;
+ int m_y;
+ pod_array<cover_type> m_covers;
+ span_array_type m_spans;
+ };
- //============================================================scanline_u16
- typedef scanline_u<int16u> scanline_u16;
- //============================================================scanline_u32
- typedef scanline_u<int32u> scanline_u32;
- //=============================================================scanline_am
+ //========================================================scanline32_u8_am
//
// The scanline container with alpha-masking
//
//------------------------------------------------------------------------
- template<class AlphaMask, class CoverT>
- class scanline_am : public scanline_u<CoverT>
+ template<class AlphaMask>
+ class scanline32_u8_am : public scanline32_u8
{
public:
- typedef AlphaMask alpha_mask_type;
- typedef CoverT cover_type;
- typedef scanline_u<CoverT> scanline_type;
+ typedef scanline_u8 base_type;
+ typedef AlphaMask alpha_mask_type;
+ typedef base_type::cover_type cover_type;
+ typedef base_type::coord_type coord_type;
+
- scanline_am() : scanline_type(), m_alpha_mask(0) {}
- scanline_am(const AlphaMask& am) : scanline_type(), m_alpha_mask(&am) {}
+ scanline32_u8_am() : base_type(), m_alpha_mask(0) {}
+ scanline32_u8_am(const AlphaMask& am) : base_type(), m_alpha_mask(&am) {}
//--------------------------------------------------------------------
void finalize(int span_y)
{
- scanline_u<CoverT>::finalize(span_y);
+ base_type::finalize(span_y);
if(m_alpha_mask)
{
- typename scanline_type::iterator span = scanline_type::begin();
- unsigned count = scanline_type::num_spans();
+ typename base_type::iterator span = base_type::begin();
+ unsigned count = base_type::num_spans();
do
{
m_alpha_mask->combine_hspan(span->x,
- scanline_type::y(),
+ base_type::y(),
span->covers,
span->len);
++span;
@@ -304,18 +492,6 @@ namespace agg
};
- //==========================================================scanline_u8_am
- template<class AlphaMask>
- class scanline_u8_am : public scanline_am<AlphaMask, int8u>
- {
- public:
- typedef AlphaMask alpha_mask_type;
- typedef int8u cover_type;
- typedef scanline_am<alpha_mask_type, cover_type> self_type;
-
- scanline_u8_am() : self_type() {}
- scanline_u8_am(const AlphaMask& am) : self_type(am) {}
- };
}
diff --git a/agg/inc/agg_shorten_path.h b/agg/inc/agg_shorten_path.h
index 271d2a7ec572..574c06cc4834 100755
--- a/agg/inc/agg_shorten_path.h
+++ b/agg/inc/agg_shorten_path.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
diff --git a/agg/inc/agg_simul_eq.h b/agg/inc/agg_simul_eq.h
index f52662e82926..86225ee7efb2 100755
--- a/agg/inc/agg_simul_eq.h
+++ b/agg/inc/agg_simul_eq.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
diff --git a/agg/inc/agg_span_allocator.h b/agg/inc/agg_span_allocator.h
index d99c5b9d8936..811381a44fbe 100755
--- a/agg/inc/agg_span_allocator.h
+++ b/agg/inc/agg_span_allocator.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -16,7 +16,7 @@
#ifndef AGG_SPAN_ALLOCATOR_INCLUDED
#define AGG_SPAN_ALLOCATOR_INCLUDED
-#include "agg_basics.h"
+#include "agg_array.h"
namespace agg
{
@@ -27,42 +27,24 @@ namespace agg
typedef ColorT color_type;
//--------------------------------------------------------------------
- ~span_allocator()
+ AGG_INLINE color_type* allocate(unsigned span_len)
{
- delete [] m_span;
- }
-
- //--------------------------------------------------------------------
- span_allocator() :
- m_max_span_len(0),
- m_span(0)
- {
- }
-
- //--------------------------------------------------------------------
- color_type* allocate(unsigned max_span_len)
- {
- if(max_span_len > m_max_span_len)
+ if(span_len > m_span.size())
{
- delete [] m_span;
- m_span = new color_type[m_max_span_len = max_span_len];
+ // To reduce the number of reallocs we align the
+ // span_len to 256 color elements.
+ // Well, I just like this number and it looks reasonable.
+ //-----------------------
+ m_span.resize(((span_len + 255) >> 8) << 8);
}
- return m_span;
+ return &m_span[0];
}
- //--------------------------------------------------------------------
- color_type* span()
- {
- return m_span;
- }
+ AGG_INLINE color_type* span() { return &m_span[0]; }
+ AGG_INLINE unsigned max_span_len() const { return m_span.size(); }
private:
- //--------------------------------------------------------------------
- span_allocator(const span_allocator<ColorT>&);
- const span_allocator<ColorT>& operator = (const span_allocator<ColorT>&);
-
- unsigned m_max_span_len;
- color_type* m_span;
+ pod_array<color_type> m_span;
};
}
diff --git a/agg/inc/agg_span_converter.h b/agg/inc/agg_span_converter.h
index 104cd7d8e73e..8f80c1919f7e 100755
--- a/agg/inc/agg_span_converter.h
+++ b/agg/inc/agg_span_converter.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -21,31 +21,34 @@
namespace agg
{
//----------------------------------------------------------span_converter
- template<class SpanGenerator, class Conv> class span_converter
+ template<class SpanGenerator, class SpanConverter> class span_converter
{
public:
typedef typename SpanGenerator::color_type color_type;
- span_converter(SpanGenerator& span_gen, Conv& conv) :
- m_span_gen(&span_gen), m_conv(&conv) {}
+ span_converter(SpanGenerator& span_gen, SpanConverter& span_cnv) :
+ m_span_gen(&span_gen), m_span_cnv(&span_cnv) {}
+
+ void attach_generator(SpanGenerator& span_gen) { m_span_gen = &span_gen; }
+ void attach_converter(SpanConverter& span_cnv) { m_span_cnv = &span_cnv; }
//--------------------------------------------------------------------
- void prepare(unsigned max_span_len)
+ void prepare()
{
- m_span_gen->prepare(max_span_len);
+ m_span_gen->prepare();
+ m_span_cnv->prepare();
}
//--------------------------------------------------------------------
- color_type* generate(int x, int y, unsigned len)
+ void generate(color_type* span, int x, int y, unsigned len)
{
- color_type* span = m_span_gen->generate(x, y, len);
- m_conv->convert(span, x, y, len);
- return span;
+ m_span_gen->generate(span, x, y, len);
+ m_span_cnv->generate(span, x, y, len);
}
private:
SpanGenerator* m_span_gen;
- Conv* m_conv;
+ SpanConverter* m_span_cnv;
};
}
diff --git a/agg/inc/agg_span_generator.h b/agg/inc/agg_span_generator.h
deleted file mode 100755
index 82b0ebef95f3..000000000000
--- a/agg/inc/agg_span_generator.h
+++ /dev/null
@@ -1,50 +0,0 @@
-//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
-// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
-//
-// Permission to copy, use, modify, sell and distribute this software
-// is granted provided this copyright notice appears in all copies.
-// This software is provided "as is" without express or implied
-// warranty, and with no claim as to its suitability for any purpose.
-//
-//----------------------------------------------------------------------------
-// Contact: mcseem@antigrain.com
-// mcseemagg@yahoo.com
-// http://www.antigrain.com
-//----------------------------------------------------------------------------
-
-#ifndef AGG_SPAN_GENERATOR_INCLUDED
-#define AGG_SPAN_GENERATOR_INCLUDED
-
-#include "agg_basics.h"
-#include "agg_span_allocator.h"
-
-namespace agg
-{
-
- //==========================================================span_generator
- template<class ColorT, class Allocator> class span_generator
- {
- public:
- typedef ColorT color_type;
- typedef Allocator alloc_type;
-
- //--------------------------------------------------------------------
- span_generator(alloc_type& alloc) : m_alloc(&alloc) {}
-
- //--------------------------------------------------------------------
- void allocator(alloc_type& alloc) { m_alloc = &alloc; }
- alloc_type& allocator() { return *m_alloc; }
-
- //--------------------------------------------------------------------
- void prepare(unsigned max_span_len)
- {
- m_alloc->allocate(max_span_len);
- }
-
- private:
- alloc_type* m_alloc;
- };
-}
-
-#endif
diff --git a/agg/inc/agg_span_gouraud.h b/agg/inc/agg_span_gouraud.h
index 76747899b5fc..87290b7395dd 100755
--- a/agg/inc/agg_span_gouraud.h
+++ b/agg/inc/agg_span_gouraud.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -18,18 +18,15 @@
#include "agg_basics.h"
#include "agg_math.h"
-#include "agg_span_generator.h"
namespace agg
{
//============================================================span_gouraud
- template<class ColorT, class Allocator>
- class span_gouraud : public span_generator<ColorT, Allocator>
+ template<class ColorT> class span_gouraud
{
public:
typedef ColorT color_type;
- typedef Allocator alloc_type;
struct coord_type
{
@@ -39,23 +36,21 @@ namespace agg
};
//--------------------------------------------------------------------
- span_gouraud(alloc_type& alloc) :
- span_generator<color_type, alloc_type>(alloc),
+ span_gouraud() :
m_vertex(0)
{
m_cmd[0] = path_cmd_stop;
}
//--------------------------------------------------------------------
- span_gouraud(alloc_type& alloc,
- const color_type& c1,
+ span_gouraud(const color_type& c1,
const color_type& c2,
const color_type& c3,
double x1, double y1,
double x2, double y2,
double x3, double y3,
double d) :
- span_generator<color_type, alloc_type>(alloc)
+ m_vertex(0)
{
colors(c1, c2, c3);
triangle(x1, y1, x2, y2, x3, y3, d);
@@ -132,8 +127,6 @@ namespace agg
return m_cmd[m_vertex++];
}
-
-
protected:
//--------------------------------------------------------------------
void arrange_vertices(coord_type* coord) const
@@ -164,7 +157,6 @@ namespace agg
}
}
-
private:
//--------------------------------------------------------------------
coord_type m_coord[3];
diff --git a/agg/inc/agg_span_gouraud_gray.h b/agg/inc/agg_span_gouraud_gray.h
index caf288919e93..94efc8380dce 100755
--- a/agg/inc/agg_span_gouraud_gray.h
+++ b/agg/inc/agg_span_gouraud_gray.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -33,15 +33,18 @@ namespace agg
{
//=======================================================span_gouraud_gray
- template<class ColorT, class Allocator = span_allocator<ColorT> >
- class span_gouraud_gray : public span_gouraud<ColorT, Allocator>
+ template<class ColorT> class span_gouraud_gray : public span_gouraud<ColorT>
{
public:
- typedef Allocator alloc_type;
typedef ColorT color_type;
typedef typename color_type::value_type value_type;
- typedef span_gouraud<color_type, alloc_type> base_type;
+ typedef span_gouraud<color_type> base_type;
typedef typename base_type::coord_type coord_type;
+ enum subpixel_scale_e
+ {
+ subpixel_shift = 4,
+ subpixel_scale = 1 << subpixel_shift
+ };
private:
//--------------------------------------------------------------------
@@ -49,30 +52,31 @@ namespace agg
{
void init(const coord_type& c1, const coord_type& c2)
{
- m_x1 = c1.x;
- m_y1 = c1.y;
- m_dx = c2.x - c1.x;
- m_dy = 1.0 / (c2.y - c1.y);
+ m_x1 = c1.x - 0.5;
+ m_y1 = c1.y - 0.5;
+ m_dx = c2.x - c1.x;
+ double dy = c2.y - c1.y;
+ m_1dy = (fabs(dy) < 1e-10) ? 1e10 : 1.0 / dy;
m_v1 = c1.color.v;
m_a1 = c1.color.a;
m_dv = c2.color.v - m_v1;
m_da = c2.color.a - m_a1;
}
- void calc(int y)
+ void calc(double y)
{
- double k = 0.0;
- if(y > m_y1) k = (y - m_y1) * m_dy;
- gray8 c;
- m_v = m_v1 + int(m_dv * k);
- m_a = m_a1 + int(m_da * k);
- m_x = int(m_x1 + m_dx * k);
+ double k = (y - m_y1) * m_1dy;
+ if(k < 0.0) k = 0.0;
+ if(k > 1.0) k = 1.0;
+ m_v = m_v1 + iround(m_dv * k);
+ m_a = m_a1 + iround(m_da * k);
+ m_x = iround((m_x1 + m_dx * k) * subpixel_scale);
}
double m_x1;
double m_y1;
double m_dx;
- double m_dy;
+ double m_1dy;
int m_v1;
int m_a1;
int m_dv;
@@ -85,33 +89,28 @@ namespace agg
public:
//--------------------------------------------------------------------
- span_gouraud_gray(alloc_type& alloc) : base_type(alloc) {}
-
- //--------------------------------------------------------------------
- span_gouraud_gray(alloc_type& alloc,
- const color_type& c1,
+ span_gouraud_gray() {}
+ span_gouraud_gray(const color_type& c1,
const color_type& c2,
const color_type& c3,
double x1, double y1,
double x2, double y2,
double x3, double y3,
double d = 0) :
- base_type(alloc, c1, c2, c3, x1, y1, x2, y2, x3, y3, d)
+ base_type(c1, c2, c3, x1, y1, x2, y2, x3, y3, d)
{}
//--------------------------------------------------------------------
- void prepare(unsigned max_span_len)
+ void prepare()
{
- base_type::prepare(max_span_len);
-
coord_type coord[3];
- arrange_vertices(coord);
+ base_type::arrange_vertices(coord);
m_y2 = int(coord[1].y);
- m_swap = calc_point_location(coord[0].x, coord[0].y,
- coord[2].x, coord[2].y,
- coord[1].x, coord[1].y) < 0.0;
+ m_swap = cross_product(coord[0].x, coord[0].y,
+ coord[2].x, coord[2].y,
+ coord[1].x, coord[1].y) < 0.0;
m_c1.init(coord[0], coord[2]);
m_c2.init(coord[0], coord[1]);
@@ -119,7 +118,7 @@ namespace agg
}
//--------------------------------------------------------------------
- color_type* generate(int x, int y, unsigned len)
+ void generate(color_type* span, int x, int y, unsigned len)
{
m_c1.calc(y);
const gray_calc* pc1 = &m_c1;
@@ -127,47 +126,104 @@ namespace agg
if(y < m_y2)
{
- m_c2.calc(y+1);
+ // Bottom part of the triangle (first subtriangle)
+ //-------------------------
+ m_c2.calc(y + m_c2.m_1dy);
}
else
{
- m_c3.calc(y);
+ // Upper part (second subtriangle)
+ //-------------------------
+ m_c3.calc(y - m_c3.m_1dy);
pc2 = &m_c3;
}
if(m_swap)
{
+ // It means that the triangle is oriented clockwise,
+ // so that we need to swap the controlling structures
+ //-------------------------
const gray_calc* t = pc2;
pc2 = pc1;
pc1 = t;
}
- int nx = pc1->m_x;
- unsigned nlen = pc2->m_x - pc1->m_x + 1;
-
- if(nlen < len) nlen = len;
+ // Get the horizontal length with subpixel accuracy
+ // and protect it from division by zero
+ //-------------------------
+ int nlen = abs(pc2->m_x - pc1->m_x);
+ if(nlen <= 0) nlen = 1;
dda_line_interpolator<14> v(pc1->m_v, pc2->m_v, nlen);
dda_line_interpolator<14> a(pc1->m_a, pc2->m_a, nlen);
- if(nx < x)
+ // Calculate the starting point of the gradient with subpixel
+ // accuracy and correct (roll back) the interpolators.
+ // This operation will also clip the beginning of the span
+ // if necessary.
+ //-------------------------
+ int start = pc1->m_x - (x << subpixel_shift);
+ v -= start;
+ a -= start;
+ nlen += start;
+
+ int vv, va;
+ enum lim_e { lim = color_type::base_mask };
+
+ // Beginning part of the span. Since we rolled back the
+ // interpolators, the color values may have overflow.
+ // So that, we render the beginning part with checking
+ // for overflow. It lasts until "start" is positive;
+ // typically it's 1-2 pixels, but may be more in some cases.
+ //-------------------------
+ while(len && start > 0)
{
- unsigned d = unsigned(x - nx);
- v += d;
- a += d;
+ vv = v.y();
+ va = a.y();
+ if(vv < 0) vv = 0; if(vv > lim) vv = lim;
+ if(va < 0) va = 0; if(va > lim) va = lim;
+ span->v = (value_type)vv;
+ span->a = (value_type)va;
+ v += subpixel_scale;
+ a += subpixel_scale;
+ nlen -= subpixel_scale;
+ start -= subpixel_scale;
+ ++span;
+ --len;
}
- color_type* span = base_type::allocator().span();
- do
+ // Middle part, no checking for overflow.
+ // Actual spans can be longer than the calculated length
+ // because of anti-aliasing, thus, the interpolators can
+ // overflow. But while "nlen" is positive we are safe.
+ //-------------------------
+ while(len && nlen > 0)
{
span->v = (value_type)v.y();
span->a = (value_type)a.y();
- ++v;
- ++a;
+ v += subpixel_scale;
+ a += subpixel_scale;
+ nlen -= subpixel_scale;
+ ++span;
+ --len;
+ }
+
+ // Ending part; checking for overflow.
+ // Typically it's 1-2 pixels, but may be more in some cases.
+ //-------------------------
+ while(len)
+ {
+ vv = v.y();
+ va = a.y();
+ if(vv < 0) vv = 0; if(vv > lim) vv = lim;
+ if(va < 0) va = 0; if(va > lim) va = lim;
+ span->v = (value_type)vv;
+ span->a = (value_type)va;
+ v += subpixel_scale;
+ a += subpixel_scale;
++span;
+ --len;
}
- while(--len);
- return base_type::allocator().span();
}
diff --git a/agg/inc/agg_span_gouraud_rgba.h b/agg/inc/agg_span_gouraud_rgba.h
index 75679a9426c2..dbbe840f2fdd 100755
--- a/agg/inc/agg_span_gouraud_rgba.h
+++ b/agg/inc/agg_span_gouraud_rgba.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -33,15 +33,18 @@ namespace agg
{
//=======================================================span_gouraud_rgba
- template<class ColorT, class Allocator = span_allocator<ColorT> >
- class span_gouraud_rgba : public span_gouraud<ColorT, Allocator>
+ template<class ColorT> class span_gouraud_rgba : public span_gouraud<ColorT>
{
public:
- typedef Allocator alloc_type;
typedef ColorT color_type;
typedef typename ColorT::value_type value_type;
- typedef span_gouraud<color_type, alloc_type> base_type;
+ typedef span_gouraud<color_type> base_type;
typedef typename base_type::coord_type coord_type;
+ enum subpixel_scale_e
+ {
+ subpixel_shift = 4,
+ subpixel_scale = 1 << subpixel_shift
+ };
private:
//--------------------------------------------------------------------
@@ -49,36 +52,37 @@ namespace agg
{
void init(const coord_type& c1, const coord_type& c2)
{
- m_x1 = c1.x;
- m_y1 = c1.y;
- m_dx = c2.x - c1.x;
- m_dy = 1.0 / (c2.y - c1.y);
- m_r1 = c1.color.r;
- m_g1 = c1.color.g;
- m_b1 = c1.color.b;
- m_a1 = c1.color.a;
- m_dr = c2.color.r - m_r1;
- m_dg = c2.color.g - m_g1;
- m_db = c2.color.b - m_b1;
- m_da = c2.color.a - m_a1;
+ m_x1 = c1.x - 0.5;
+ m_y1 = c1.y - 0.5;
+ m_dx = c2.x - c1.x;
+ double dy = c2.y - c1.y;
+ m_1dy = (dy < 1e-5) ? 1e5 : 1.0 / dy;
+ m_r1 = c1.color.r;
+ m_g1 = c1.color.g;
+ m_b1 = c1.color.b;
+ m_a1 = c1.color.a;
+ m_dr = c2.color.r - m_r1;
+ m_dg = c2.color.g - m_g1;
+ m_db = c2.color.b - m_b1;
+ m_da = c2.color.a - m_a1;
}
- void calc(int y)
+ void calc(double y)
{
- double k = 0.0;
- if(y > m_y1) k = (y - m_y1) * m_dy;
- color_type rgba;
- m_r = m_r1 + int(m_dr * k);
- m_g = m_g1 + int(m_dg * k);
- m_b = m_b1 + int(m_db * k);
- m_a = m_a1 + int(m_da * k);
- m_x = int(m_x1 + m_dx * k);
+ double k = (y - m_y1) * m_1dy;
+ if(k < 0.0) k = 0.0;
+ if(k > 1.0) k = 1.0;
+ m_r = m_r1 + iround(m_dr * k);
+ m_g = m_g1 + iround(m_dg * k);
+ m_b = m_b1 + iround(m_db * k);
+ m_a = m_a1 + iround(m_da * k);
+ m_x = iround((m_x1 + m_dx * k) * subpixel_scale);
}
double m_x1;
double m_y1;
double m_dx;
- double m_dy;
+ double m_1dy;
int m_r1;
int m_g1;
int m_b1;
@@ -97,33 +101,28 @@ namespace agg
public:
//--------------------------------------------------------------------
- span_gouraud_rgba(alloc_type& alloc) : base_type(alloc) {}
-
- //--------------------------------------------------------------------
- span_gouraud_rgba(alloc_type& alloc,
- const color_type& c1,
+ span_gouraud_rgba() {}
+ span_gouraud_rgba(const color_type& c1,
const color_type& c2,
const color_type& c3,
double x1, double y1,
double x2, double y2,
double x3, double y3,
double d = 0) :
- base_type(alloc, c1, c2, c3, x1, y1, x2, y2, x3, y3, d)
+ base_type(c1, c2, c3, x1, y1, x2, y2, x3, y3, d)
{}
//--------------------------------------------------------------------
- void prepare(unsigned max_span_len)
+ void prepare()
{
- base_type::prepare(max_span_len);
-
coord_type coord[3];
- arrange_vertices(coord);
+ base_type::arrange_vertices(coord);
m_y2 = int(coord[1].y);
- m_swap = calc_point_location(coord[0].x, coord[0].y,
- coord[2].x, coord[2].y,
- coord[1].x, coord[1].y) < 0.0;
+ m_swap = cross_product(coord[0].x, coord[0].y,
+ coord[2].x, coord[2].y,
+ coord[1].x, coord[1].y) < 0.0;
m_rgba1.init(coord[0], coord[2]);
m_rgba2.init(coord[0], coord[1]);
@@ -131,65 +130,137 @@ namespace agg
}
//--------------------------------------------------------------------
- color_type* generate(int x, int y, unsigned len)
+ void generate(color_type* span, int x, int y, unsigned len)
{
- m_rgba1.calc(y);
+ m_rgba1.calc(y);//(m_rgba1.m_1dy > 2) ? m_rgba1.m_y1 : y);
const rgba_calc* pc1 = &m_rgba1;
const rgba_calc* pc2 = &m_rgba2;
- if(y < m_y2)
+ if(y <= m_y2)
{
- m_rgba2.calc(y+1);
+ // Bottom part of the triangle (first subtriangle)
+ //-------------------------
+ m_rgba2.calc(y + m_rgba2.m_1dy);
}
else
{
- m_rgba3.calc(y);
+ // Upper part (second subtriangle)
+ m_rgba3.calc(y - m_rgba3.m_1dy);
+ //-------------------------
pc2 = &m_rgba3;
}
if(m_swap)
{
+ // It means that the triangle is oriented clockwise,
+ // so that we need to swap the controlling structures
+ //-------------------------
const rgba_calc* t = pc2;
pc2 = pc1;
pc1 = t;
}
- int nx = pc1->m_x;
- unsigned nlen = pc2->m_x - pc1->m_x + 1;
-
- if(nlen < len) nlen = len;
+ // Get the horizontal length with subpixel accuracy
+ // and protect it from division by zero
+ //-------------------------
+ int nlen = abs(pc2->m_x - pc1->m_x);
+ if(nlen <= 0) nlen = 1;
dda_line_interpolator<14> r(pc1->m_r, pc2->m_r, nlen);
dda_line_interpolator<14> g(pc1->m_g, pc2->m_g, nlen);
dda_line_interpolator<14> b(pc1->m_b, pc2->m_b, nlen);
dda_line_interpolator<14> a(pc1->m_a, pc2->m_a, nlen);
- if(nx < x)
+ // Calculate the starting point of the gradient with subpixel
+ // accuracy and correct (roll back) the interpolators.
+ // This operation will also clip the beginning of the span
+ // if necessary.
+ //-------------------------
+ int start = pc1->m_x - (x << subpixel_shift);
+ r -= start;
+ g -= start;
+ b -= start;
+ a -= start;
+ nlen += start;
+
+ int vr, vg, vb, va;
+ enum lim_e { lim = color_type::base_mask };
+
+ // Beginning part of the span. Since we rolled back the
+ // interpolators, the color values may have overflow.
+ // So that, we render the beginning part with checking
+ // for overflow. It lasts until "start" is positive;
+ // typically it's 1-2 pixels, but may be more in some cases.
+ //-------------------------
+ while(len && start > 0)
{
- unsigned d = unsigned(x - nx);
- r += d;
- g += d;
- b += d;
- a += d;
+ vr = r.y();
+ vg = g.y();
+ vb = b.y();
+ va = a.y();
+ if(vr < 0) vr = 0; if(vr > lim) vr = lim;
+ if(vg < 0) vg = 0; if(vg > lim) vg = lim;
+ if(vb < 0) vb = 0; if(vb > lim) vb = lim;
+ if(va < 0) va = 0; if(va > lim) va = lim;
+ span->r = (value_type)vr;
+ span->g = (value_type)vg;
+ span->b = (value_type)vb;
+ span->a = (value_type)va;
+ r += subpixel_scale;
+ g += subpixel_scale;
+ b += subpixel_scale;
+ a += subpixel_scale;
+ nlen -= subpixel_scale;
+ start -= subpixel_scale;
+ ++span;
+ --len;
}
- color_type* span = base_type::allocator().span();
- do
+ // Middle part, no checking for overflow.
+ // Actual spans can be longer than the calculated length
+ // because of anti-aliasing, thus, the interpolators can
+ // overflow. But while "nlen" is positive we are safe.
+ //-------------------------
+ while(len && nlen > 0)
{
span->r = (value_type)r.y();
span->g = (value_type)g.y();
span->b = (value_type)b.y();
span->a = (value_type)a.y();
- ++r;
- ++g;
- ++b;
- ++a;
+ r += subpixel_scale;
+ g += subpixel_scale;
+ b += subpixel_scale;
+ a += subpixel_scale;
+ nlen -= subpixel_scale;
++span;
+ --len;
}
- while(--len);
- return base_type::allocator().span();
- }
+ // Ending part; checking for overflow.
+ // Typically it's 1-2 pixels, but may be more in some cases.
+ //-------------------------
+ while(len)
+ {
+ vr = r.y();
+ vg = g.y();
+ vb = b.y();
+ va = a.y();
+ if(vr < 0) vr = 0; if(vr > lim) vr = lim;
+ if(vg < 0) vg = 0; if(vg > lim) vg = lim;
+ if(vb < 0) vb = 0; if(vb > lim) vb = lim;
+ if(va < 0) va = 0; if(va > lim) va = lim;
+ span->r = (value_type)vr;
+ span->g = (value_type)vg;
+ span->b = (value_type)vb;
+ span->a = (value_type)va;
+ r += subpixel_scale;
+ g += subpixel_scale;
+ b += subpixel_scale;
+ a += subpixel_scale;
+ ++span;
+ --len;
+ }
+ }
private:
bool m_swap;
diff --git a/agg/inc/agg_span_gradient.h b/agg/inc/agg_span_gradient.h
index 6bac1c652a84..fa6e4929855d 100755
--- a/agg/inc/agg_span_gradient.h
+++ b/agg/inc/agg_span_gradient.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -20,7 +20,6 @@
#include <stdlib.h>
#include <string.h>
#include "agg_basics.h"
-#include "agg_span_generator.h"
#include "agg_math.h"
#include "agg_array.h"
@@ -28,11 +27,11 @@
namespace agg
{
- enum
+ enum gradient_subpixel_scale_e
{
gradient_subpixel_shift = 4, //-----gradient_subpixel_shift
- gradient_subpixel_size = 1 << gradient_subpixel_shift, //-----gradient_subpixel_size
- gradient_subpixel_mask = gradient_subpixel_size - 1 //-----gradient_subpixel_mask
+ gradient_subpixel_scale = 1 << gradient_subpixel_shift, //-----gradient_subpixel_scale
+ gradient_subpixel_mask = gradient_subpixel_scale - 1 //-----gradient_subpixel_mask
};
@@ -41,57 +40,54 @@ namespace agg
template<class ColorT,
class Interpolator,
class GradientF,
- class ColorF,
- class Allocator = span_allocator<ColorT> >
- class span_gradient : public span_generator<ColorT, Allocator>
+ class ColorF>
+ class span_gradient
{
public:
typedef Interpolator interpolator_type;
- typedef Allocator alloc_type;
typedef ColorT color_type;
- typedef span_generator<color_type, alloc_type> base_type;
- enum
+ enum downscale_shift_e
{
downscale_shift = interpolator_type::subpixel_shift -
gradient_subpixel_shift
};
//--------------------------------------------------------------------
- span_gradient(alloc_type& alloc) : base_type(alloc) {}
+ span_gradient() {}
//--------------------------------------------------------------------
- span_gradient(alloc_type& alloc,
- interpolator_type& inter,
- const GradientF& gradient_function_,
- const ColorF& color_function_,
- double d1_, double d2_) :
- base_type(alloc),
+ span_gradient(interpolator_type& inter,
+ const GradientF& gradient_function,
+ const ColorF& color_function,
+ double d1, double d2) :
m_interpolator(&inter),
- m_gradient_function(&gradient_function_),
- m_color_function(&color_function_),
- m_d1(int(d1_ * gradient_subpixel_size)),
- m_d2(int(d2_ * gradient_subpixel_size))
+ m_gradient_function(&gradient_function),
+ m_color_function(&color_function),
+ m_d1(iround(d1 * gradient_subpixel_scale)),
+ m_d2(iround(d2 * gradient_subpixel_scale))
{}
//--------------------------------------------------------------------
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_subpixel_size; }
- double d2() const { return double(m_d2) / gradient_subpixel_size; }
+ double d1() const { return double(m_d1) / gradient_subpixel_scale; }
+ double d2() const { return double(m_d2) / gradient_subpixel_scale; }
//--------------------------------------------------------------------
void interpolator(interpolator_type& i) { m_interpolator = &i; }
void gradient_function(const GradientF& gf) { m_gradient_function = &gf; }
void color_function(const ColorF& cf) { m_color_function = &cf; }
- void d1(double v) { m_d1 = int(v * gradient_subpixel_size); }
- void d2(double v) { m_d2 = int(v * gradient_subpixel_size); }
+ void d1(double v) { m_d1 = iround(v * gradient_subpixel_scale); }
+ void d2(double v) { m_d2 = iround(v * gradient_subpixel_scale); }
//--------------------------------------------------------------------
- color_type* generate(int x, int y, unsigned len)
+ void prepare() {}
+
+ //--------------------------------------------------------------------
+ void generate(color_type* span, int x, int y, unsigned len)
{
- color_type* span = base_type::allocator().span();
int dd = m_d2 - m_d1;
if(dd < 1) dd = 1;
m_interpolator->begin(x+0.5, y+0.5, len);
@@ -99,7 +95,7 @@ namespace agg
{
m_interpolator->coordinates(&x, &y);
int d = m_gradient_function->calculate(x >> downscale_shift,
- y >> downscale_shift, dd);
+ y >> downscale_shift, m_d2);
d = ((d - m_d1) * (int)m_color_function->size()) / dd;
if(d < 0) d = 0;
if(d >= (int)m_color_function->size()) d = m_color_function->size() - 1;
@@ -107,7 +103,6 @@ namespace agg
++(*m_interpolator);
}
while(--len);
- return base_type::allocator().span();
}
private:
@@ -151,6 +146,10 @@ namespace agg
};
+
+
+
+
//==========================================================gradient_circle
class gradient_circle
{
@@ -173,36 +172,34 @@ namespace agg
}
};
-
//========================================================gradient_radial_d
class gradient_radial_d
{
public:
static AGG_INLINE int calculate(int x, int y, int)
{
- return int(sqrt(double(x)*double(x) + double(y)*double(y)));
+ return uround(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)
+ m_r(100 * gradient_subpixel_scale),
+ m_fx(0),
+ m_fy(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))
+ m_r (iround(r * gradient_subpixel_scale)),
+ m_fx(iround(fx * gradient_subpixel_scale)),
+ m_fy(iround(fy * gradient_subpixel_scale))
{
update_values();
}
@@ -210,111 +207,62 @@ namespace agg
//---------------------------------------------------------------------
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);
+ m_r = iround(r * gradient_subpixel_scale);
+ m_fx = iround(fx * gradient_subpixel_scale);
+ m_fy = iround(fy * gradient_subpixel_scale);
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; }
+ double radius() const { return double(m_r) / gradient_subpixel_scale; }
+ double focus_x() const { return double(m_fx) / gradient_subpixel_scale; }
+ double focus_y() const { return double(m_fy) / gradient_subpixel_scale; }
//---------------------------------------------------------------------
- int calculate(int x, int y, int d) const
+ int calculate(int x, int y, int) 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);
+ double dx = x - m_fx;
+ double dy = y - m_fy;
+ double d2 = dx * m_fy - dy * m_fx;
+ double d3 = m_r2 * (dx * dx + dy * dy) - d2 * d2;
+ return iround((dx * m_fx + dy * m_fy + sqrt(fabs(d3))) * m_mul);
}
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)
+ // Calculate the invariant values. In case the focal center
+ // lies exactly on the gradient circle the divisor degenerates
+ // into zero. In this case we just move the focal center by
+ // one subpixel unit possibly in the direction to the origin (0,0)
+ // and calculate the values again.
+ //-------------------------
+ m_r2 = double(m_r) * double(m_r);
+ m_fx2 = double(m_fx) * double(m_fx);
+ m_fy2 = double(m_fy) * double(m_fy);
+ double d = (m_r2 - (m_fx2 + m_fy2));
+ if(d == 0)
{
- // 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));
+ if(m_fx) { if(m_fx < 0) ++m_fx; else --m_fx; }
+ if(m_fy) { if(m_fy < 0) ++m_fy; else --m_fy; }
+ m_fx2 = double(m_fx) * double(m_fx);
+ m_fy2 = double(m_fy) * double(m_fy);
+ d = (m_r2 - (m_fx2 + m_fy2));
}
-
- // Calculate the solution to be used in the case where x == focus_x
- //------------------------------
- m_trivial = sqrt(m_radius2 - (m_focus_x * m_focus_x));
+ m_mul = m_r / d;
}
- int m_radius;
- int m_focus_x;
- int m_focus_y;
- double m_radius2;
- double m_trivial;
+ int m_r;
+ int m_fx;
+ int m_fy;
+ double m_r2;
+ double m_fx2;
+ double m_fy2;
+ double m_mul;
};
-
//==============================================================gradient_x
class gradient_x
{
@@ -330,7 +278,6 @@ namespace agg
static int calculate(int, int y, int) { return y; }
};
-
//========================================================gradient_diamond
class gradient_diamond
{
@@ -343,7 +290,6 @@ namespace agg
}
};
-
//=============================================================gradient_xy
class gradient_xy
{
@@ -354,7 +300,6 @@ namespace agg
}
};
-
//========================================================gradient_sqrt_xy
class gradient_sqrt_xy
{
@@ -365,18 +310,16 @@ namespace agg
}
};
-
//==========================================================gradient_conic
class gradient_conic
{
public:
static AGG_INLINE int calculate(int x, int y, int d)
{
- return int(fabs(atan2(double(y), double(x))) * double(d) / pi);
+ return uround(fabs(atan2(double(y), double(x))) * double(d) / pi);
}
};
-
//=================================================gradient_repeat_adaptor
template<class GradientF> class gradient_repeat_adaptor
{
@@ -395,7 +338,6 @@ namespace agg
const GradientF* m_gradient;
};
-
//================================================gradient_reflect_adaptor
template<class GradientF> class gradient_reflect_adaptor
{
diff --git a/agg/inc/agg_span_gradient_alpha.h b/agg/inc/agg_span_gradient_alpha.h
index b1444ed8c4bc..a53d66903b1f 100755
--- a/agg/inc/agg_span_gradient_alpha.h
+++ b/agg/inc/agg_span_gradient_alpha.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -32,7 +32,7 @@ namespace agg
typedef ColorT color_type;
typedef typename color_type::value_type alpha_type;
- enum
+ enum downscale_shift_e
{
downscale_shift = interpolator_type::subpixel_shift - gradient_subpixel_shift
};
@@ -49,26 +49,29 @@ namespace agg
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))
+ m_d1(iround(d1 * gradient_subpixel_scale)),
+ m_d2(iround(d2 * gradient_subpixel_scale))
{}
//--------------------------------------------------------------------
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; }
+ double d1() const { return double(m_d1) / gradient_subpixel_scale; }
+ double d2() const { return double(m_d2) / gradient_subpixel_scale; }
//--------------------------------------------------------------------
void interpolator(interpolator_type& i) { m_interpolator = &i; }
void gradient_function(const GradientF& gf) { m_gradient_function = &gf; }
void alpha_function(const 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 d1(double v) { m_d1 = iround(v * gradient_subpixel_scale); }
+ void d2(double v) { m_d2 = iround(v * gradient_subpixel_scale); }
//--------------------------------------------------------------------
- void convert(color_type* span, int x, int y, unsigned len)
+ void prepare() {}
+
+ //--------------------------------------------------------------------
+ void generate(color_type* span, int x, int y, unsigned len)
{
int dd = m_d2 - m_d1;
if(dd < 1) dd = 1;
@@ -77,7 +80,7 @@ namespace agg
{
m_interpolator->coordinates(&x, &y);
int d = m_gradient_function->calculate(x >> downscale_shift,
- y >> downscale_shift, dd);
+ y >> downscale_shift, m_d2);
d = ((d - m_d1) * (int)m_alpha_function->size()) / dd;
if(d < 0) d = 0;
if(d >= (int)m_alpha_function->size()) d = m_alpha_function->size() - 1;
diff --git a/agg/inc/agg_span_image_filter.h b/agg/inc/agg_span_image_filter.h
index 34163bb29f24..f35c56989258 100755
--- a/agg/inc/agg_span_image_filter.h
+++ b/agg/inc/agg_span_image_filter.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -21,81 +21,63 @@
#include "agg_basics.h"
#include "agg_image_filters.h"
-#include "agg_rendering_buffer.h"
-#include "agg_span_generator.h"
-
+#include "agg_span_interpolator_linear.h"
namespace agg
{
- //--------------------------------------------------span_image_filter
- template<class ColorT, class Interpolator, class Allocator>
- class span_image_filter : public span_generator<ColorT, Allocator>
+ //-------------------------------------------------------span_image_filter
+ template<class Source, class Interpolator> class span_image_filter
{
public:
- typedef ColorT color_type;
- typedef Allocator alloc_type;
+ typedef Source source_type;
typedef Interpolator interpolator_type;
- typedef span_generator<color_type, alloc_type> base_type;
-
- //----------------------------------------------------------------
- span_image_filter(alloc_type& alloc) :
- span_generator<color_type, alloc_type>(alloc)
- {}
- //----------------------------------------------------------------
- span_image_filter(alloc_type& alloc,
- const rendering_buffer& src,
- const color_type& back_color,
- interpolator_type& interpolator_,
- const image_filter_lut* filter_) :
- span_generator<color_type, alloc_type>(alloc),
+ //--------------------------------------------------------------------
+ span_image_filter() {}
+ span_image_filter(source_type& src,
+ interpolator_type& interpolator,
+ const image_filter_lut* filter) :
m_src(&src),
- m_back_color(back_color),
- m_interpolator(&interpolator_),
- m_filter(filter_),
+ m_interpolator(&interpolator),
+ 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)
+ m_dx_int(image_subpixel_scale / 2),
+ m_dy_int(image_subpixel_scale / 2)
{}
+ void attach(source_type& v) { m_src = &v; }
- //----------------------------------------------------------------
- const rendering_buffer& source_image() const { return *m_src; }
- const color_type& background_color() const { return m_back_color; }
- const image_filter_lut& 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_lut& v) { m_filter = &v; }
+ //--------------------------------------------------------------------
+ source_type& source() { return *m_src; }
+ const source_type& source() const { return *m_src; }
+ const image_filter_lut& 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 interpolator(interpolator_type& v) { m_interpolator = &v; }
+ void filter(const image_filter_lut& 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);
+ m_dx_int = iround(dx * image_subpixel_scale);
+ m_dy_int = iround(dy * image_subpixel_scale);
}
void filter_offset(double d) { filter_offset(d, d); }
- //----------------------------------------------------------------
+ //--------------------------------------------------------------------
interpolator_type& interpolator() { return *m_interpolator; }
//--------------------------------------------------------------------
- void prepare(unsigned max_span_len)
- {
- base_type::prepare(max_span_len);
- }
+ void prepare() {}
- //----------------------------------------------------------------
+ //--------------------------------------------------------------------
private:
- const rendering_buffer* m_src;
- color_type m_back_color;
+ source_type* m_src;
interpolator_type* m_interpolator;
const image_filter_lut* m_filter;
double m_dx_dbl;
@@ -105,6 +87,160 @@ namespace agg
};
+
+
+ //==============================================span_image_resample_affine
+ template<class Source>
+ class span_image_resample_affine :
+ public span_image_filter<Source, span_interpolator_linear<trans_affine> >
+ {
+ public:
+ typedef Source source_type;
+ typedef span_interpolator_linear<trans_affine> interpolator_type;
+ typedef span_image_filter<source_type, interpolator_type> base_type;
+
+ //--------------------------------------------------------------------
+ span_image_resample_affine() :
+ m_scale_limit(200.0),
+ m_blur_x(1.0),
+ m_blur_y(1.0)
+ {}
+
+ //--------------------------------------------------------------------
+ span_image_resample_affine(source_type& src,
+ interpolator_type& inter,
+ const image_filter_lut& filter) :
+ base_type(src, inter, &filter),
+ m_scale_limit(200.0),
+ m_blur_x(1.0),
+ m_blur_y(1.0)
+ {}
+
+
+ //--------------------------------------------------------------------
+ int scale_limit() const { return uround(m_scale_limit); }
+ void scale_limit(int v) { m_scale_limit = v; }
+
+ //--------------------------------------------------------------------
+ double blur_x() const { return m_blur_x; }
+ double blur_y() const { return m_blur_y; }
+ void blur_x(double v) { m_blur_x = v; }
+ void blur_y(double v) { m_blur_y = v; }
+ void blur(double v) { m_blur_x = m_blur_y = v; }
+
+ //--------------------------------------------------------------------
+ void prepare()
+ {
+ double scale_x;
+ double scale_y;
+
+ base_type::interpolator().transformer().scaling_abs(&scale_x, &scale_y);
+
+ if(scale_x * scale_y > m_scale_limit)
+ {
+ scale_x = scale_x * m_scale_limit / (scale_x * scale_y);
+ scale_y = scale_y * m_scale_limit / (scale_x * scale_y);
+ }
+
+ if(scale_x < 1) scale_x = 1;
+ if(scale_y < 1) scale_y = 1;
+
+ if(scale_x > m_scale_limit) scale_x = m_scale_limit;
+ if(scale_y > m_scale_limit) scale_y = m_scale_limit;
+
+ scale_x *= m_blur_x;
+ scale_y *= m_blur_y;
+
+ if(scale_x < 1) scale_x = 1;
+ if(scale_y < 1) scale_y = 1;
+
+ m_rx = uround( scale_x * double(image_subpixel_scale));
+ m_rx_inv = uround(1.0/scale_x * double(image_subpixel_scale));
+
+ m_ry = uround( scale_y * double(image_subpixel_scale));
+ m_ry_inv = uround(1.0/scale_y * double(image_subpixel_scale));
+ }
+
+ protected:
+ int m_rx;
+ int m_ry;
+ int m_rx_inv;
+ int m_ry_inv;
+
+ private:
+ double m_scale_limit;
+ double m_blur_x;
+ double m_blur_y;
+ };
+
+
+
+ //=====================================================span_image_resample
+ template<class Source, class Interpolator>
+ class span_image_resample :
+ public span_image_filter<Source, Interpolator>
+ {
+ public:
+ typedef Source source_type;
+ typedef Interpolator interpolator_type;
+ typedef span_image_filter<source_type, interpolator_type> base_type;
+
+ //--------------------------------------------------------------------
+ span_image_resample() :
+ m_scale_limit(20),
+ m_blur_x(image_subpixel_scale),
+ m_blur_y(image_subpixel_scale)
+ {}
+
+ //--------------------------------------------------------------------
+ span_image_resample(source_type& src,
+ interpolator_type& inter,
+ const image_filter_lut& filter) :
+ base_type(src, inter, &filter),
+ m_scale_limit(20),
+ m_blur_x(image_subpixel_scale),
+ m_blur_y(image_subpixel_scale)
+ {}
+
+ //--------------------------------------------------------------------
+ int scale_limit() const { return m_scale_limit; }
+ void scale_limit(int v) { m_scale_limit = v; }
+
+ //--------------------------------------------------------------------
+ double blur_x() const { return double(m_blur_x) / double(image_subpixel_scale); }
+ double blur_y() const { return double(m_blur_y) / double(image_subpixel_scale); }
+ void blur_x(double v) { m_blur_x = uround(v * double(image_subpixel_scale)); }
+ void blur_y(double v) { m_blur_y = uround(v * double(image_subpixel_scale)); }
+ void blur(double v) { m_blur_x =
+ m_blur_y = uround(v * double(image_subpixel_scale)); }
+
+ protected:
+ AGG_INLINE void adjust_scale(int* rx, int* ry)
+ {
+ if(*rx < image_subpixel_scale) *rx = image_subpixel_scale;
+ if(*ry < image_subpixel_scale) *ry = image_subpixel_scale;
+ if(*rx > image_subpixel_scale * m_scale_limit)
+ {
+ *rx = image_subpixel_scale * m_scale_limit;
+ }
+ if(*ry > image_subpixel_scale * m_scale_limit)
+ {
+ *ry = image_subpixel_scale * m_scale_limit;
+ }
+ *rx = (*rx * m_blur_x) >> image_subpixel_shift;
+ *ry = (*ry * m_blur_y) >> image_subpixel_shift;
+ if(*rx < image_subpixel_scale) *rx = image_subpixel_scale;
+ if(*ry < image_subpixel_scale) *ry = image_subpixel_scale;
+ }
+
+ int m_scale_limit;
+ int m_blur_x;
+ int m_blur_y;
+ };
+
+
+
+
}
#endif
diff --git a/agg/inc/agg_span_image_filter_gray.h b/agg/inc/agg_span_image_filter_gray.h
index 3f7ae6fcfa72..89432dbb8dd8 100755
--- a/agg/inc/agg_span_image_filter_gray.h
+++ b/agg/inc/agg_span_image_filter_gray.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -20,7 +20,6 @@
// PostScript and PDF technology for software developers.
//
//----------------------------------------------------------------------------
-
#ifndef AGG_SPAN_IMAGE_FILTER_GRAY_INCLUDED
#define AGG_SPAN_IMAGE_FILTER_GRAY_INCLUDED
@@ -32,132 +31,168 @@
namespace agg
{
-
//==============================================span_image_filter_gray_nn
- template<class ColorT,
- class Interpolator,
- class Allocator = span_allocator<ColorT> >
+ template<class Source, class Interpolator>
class span_image_filter_gray_nn :
- public span_image_filter<ColorT, Interpolator, Allocator>
+ public span_image_filter<Source, Interpolator>
{
public:
- typedef ColorT color_type;
+ typedef Source source_type;
+ typedef typename source_type::color_type color_type;
typedef Interpolator interpolator_type;
- typedef Allocator alloc_type;
- typedef span_image_filter<color_type, interpolator_type, alloc_type> base_type;
+ typedef span_image_filter<source_type, interpolator_type> base_type;
typedef typename color_type::value_type value_type;
typedef typename color_type::calc_type calc_type;
- enum
+ enum base_scale_e
{
base_shift = color_type::base_shift,
base_mask = color_type::base_mask
};
//--------------------------------------------------------------------
- span_image_filter_gray_nn(alloc_type& alloc) : base_type(alloc) {}
-
- //--------------------------------------------------------------------
- span_image_filter_gray_nn(alloc_type& alloc,
- const rendering_buffer& src,
- const color_type& back_color,
+ span_image_filter_gray_nn() {}
+ span_image_filter_gray_nn(source_type& src,
interpolator_type& inter) :
- base_type(alloc, src, back_color, inter, 0)
+ base_type(src, inter, 0)
{}
//--------------------------------------------------------------------
- color_type* generate(int x, int y, unsigned len)
+ void generate(color_type* span, int x, int y, unsigned len)
{
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
y + base_type::filter_dy_dbl(), len);
+ do
+ {
+ base_type::interpolator().coordinates(&x, &y);
+ span->v = *(const value_type*)
+ base_type::source().span(x >> image_subpixel_shift,
+ y >> image_subpixel_shift,
+ 1);
+ span->a = base_mask;
+ ++span;
+ ++base_type::interpolator();
+ } while(--len);
+ }
+ };
- calc_type fg;
- calc_type src_alpha;
- color_type* span = base_type::allocator().span();
- int maxx = base_type::source_image().width() - 1;
- int maxy = base_type::source_image().height() - 1;
+ //=========================================span_image_filter_gray_bilinear
+ template<class Source, class Interpolator>
+ class span_image_filter_gray_bilinear :
+ public span_image_filter<Source, Interpolator>
+ {
+ public:
+ typedef Source source_type;
+ typedef typename source_type::color_type color_type;
+ typedef Interpolator interpolator_type;
+ typedef span_image_filter<source_type, interpolator_type> base_type;
+ typedef typename color_type::value_type value_type;
+ typedef typename color_type::calc_type calc_type;
+ enum base_scale_e
+ {
+ base_shift = color_type::base_shift,
+ base_mask = color_type::base_mask
+ };
+
+ //--------------------------------------------------------------------
+ span_image_filter_gray_bilinear() {}
+ span_image_filter_gray_bilinear(source_type& src,
+ interpolator_type& inter) :
+ base_type(src, inter, 0)
+ {}
+
+ //--------------------------------------------------------------------
+ void generate(color_type* span, int x, int y, unsigned len)
+ {
+ base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
+ y + base_type::filter_dy_dbl(), len);
+ calc_type fg;
+ const value_type *fg_ptr;
do
{
- base_type::interpolator().coordinates(&x, &y);
+ int x_hr;
+ int y_hr;
- x >>= image_subpixel_shift;
- y >>= image_subpixel_shift;
+ base_type::interpolator().coordinates(&x_hr, &y_hr);
- if(x >= 0 && y >= 0 &&
- x <= maxx && y <= maxy)
- {
- fg = *((const value_type*)base_type::source_image().row(y) + x);
- src_alpha = base_mask;
- }
- else
- {
- fg = base_type::background_color().v;
- src_alpha = base_type::background_color().a;
- }
+ x_hr -= base_type::filter_dx_int();
+ y_hr -= base_type::filter_dy_int();
- span->v = (value_type)fg;
- span->a = (value_type)src_alpha;
+ int x_lr = x_hr >> image_subpixel_shift;
+ int y_lr = y_hr >> image_subpixel_shift;
+
+ fg = image_subpixel_scale * image_subpixel_scale / 2;
+
+ x_hr &= image_subpixel_mask;
+ y_hr &= image_subpixel_mask;
+
+ fg_ptr = (const value_type*)base_type::source().span(x_lr, y_lr, 2);
+ fg += *fg_ptr * (image_subpixel_scale - x_hr) * (image_subpixel_scale - y_hr);
+
+ fg_ptr = (const value_type*)base_type::source().next_x();
+ fg += *fg_ptr * x_hr * (image_subpixel_scale - y_hr);
+
+ fg_ptr = (const value_type*)base_type::source().next_y();
+ fg += *fg_ptr * (image_subpixel_scale - x_hr) * y_hr;
+
+ fg_ptr = (const value_type*)base_type::source().next_x();
+ fg += *fg_ptr * x_hr * y_hr;
+
+ span->v = value_type(fg >> (image_subpixel_shift * 2));
+ span->a = base_mask;
++span;
++base_type::interpolator();
} while(--len);
-
- return base_type::allocator().span();
}
};
-
-
- //========================================span_image_filter_gray_bilinear
- template<class ColorT,
- class Interpolator,
- class Allocator = span_allocator<ColorT> >
- class span_image_filter_gray_bilinear :
- public span_image_filter<ColorT, Interpolator, Allocator>
+ //====================================span_image_filter_gray_bilinear_clip
+ template<class Source, class Interpolator>
+ class span_image_filter_gray_bilinear_clip :
+ public span_image_filter<Source, Interpolator>
{
public:
- typedef ColorT color_type;
+ typedef Source source_type;
+ typedef typename source_type::color_type color_type;
typedef Interpolator interpolator_type;
- typedef Allocator alloc_type;
- typedef span_image_filter<color_type, interpolator_type, alloc_type> base_type;
+ typedef span_image_filter<source_type, interpolator_type> base_type;
typedef typename color_type::value_type value_type;
typedef typename color_type::calc_type calc_type;
- enum
+ enum base_scale_e
{
base_shift = color_type::base_shift,
base_mask = color_type::base_mask
};
//--------------------------------------------------------------------
- span_image_filter_gray_bilinear(alloc_type& alloc) : base_type(alloc) {}
-
- //--------------------------------------------------------------------
- span_image_filter_gray_bilinear(alloc_type& alloc,
- const rendering_buffer& src,
- const color_type& back_color,
- interpolator_type& inter) :
- base_type(alloc, src, back_color, inter, 0)
+ span_image_filter_gray_bilinear_clip() {}
+ span_image_filter_gray_bilinear_clip(source_type& src,
+ const color_type& back_color,
+ interpolator_type& inter) :
+ base_type(src, inter, 0),
+ m_back_color(back_color)
{}
+ const color_type& background_color() const { return m_back_color; }
+ void background_color(const color_type& v) { m_back_color = v; }
//--------------------------------------------------------------------
- color_type* generate(int x, int y, unsigned len)
+ void generate(color_type* span, int x, int y, unsigned len)
{
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
y + base_type::filter_dy_dbl(), len);
calc_type fg;
calc_type src_alpha;
- value_type back_v = base_type::background_color().v;
- value_type back_a = base_type::background_color().a;
+ value_type back_v = m_back_color.v;
+ value_type back_a = m_back_color.a;
const value_type *fg_ptr;
- color_type* span = base_type::allocator().span();
-
- int maxx = base_type::source_image().width() - 1;
- int maxy = base_type::source_image().height() - 1;
+ int maxx = base_type::source().width() - 1;
+ int maxy = base_type::source().height() - 1;
do
{
@@ -175,18 +210,19 @@ namespace agg
if(x_lr >= 0 && y_lr >= 0 &&
x_lr < maxx && y_lr < maxy)
{
- fg = image_subpixel_size * image_subpixel_size / 2;
+ fg = image_subpixel_scale * image_subpixel_scale / 2;
x_hr &= image_subpixel_mask;
y_hr &= image_subpixel_mask;
- fg_ptr = (const value_type*)base_type::source_image().row(y_lr) + x_lr;
+ fg_ptr = (const value_type*)base_type::source().row_ptr(y_lr) + x_lr;
- fg += *fg_ptr++ * (image_subpixel_size - x_hr) * (image_subpixel_size - y_hr);
- fg += *fg_ptr++ * (image_subpixel_size - y_hr) * x_hr;
+ fg += *fg_ptr++ * (image_subpixel_scale - x_hr) * (image_subpixel_scale - y_hr);
+ fg += *fg_ptr++ * (image_subpixel_scale - y_hr) * x_hr;
- fg_ptr = (const value_type*)base_type::source_image().next_row(fg_ptr - 2);
+ ++y_lr;
+ fg_ptr = (const value_type*)base_type::source().row_ptr(y_lr) + x_lr;
- fg += *fg_ptr++ * (image_subpixel_size - x_hr) * y_hr;
+ fg += *fg_ptr++ * (image_subpixel_scale - x_hr) * y_hr;
fg += *fg_ptr++ * x_hr * y_hr;
fg >>= image_subpixel_shift * 2;
@@ -204,17 +240,18 @@ namespace agg
else
{
fg =
- src_alpha = image_subpixel_size * image_subpixel_size / 2;
+ src_alpha = image_subpixel_scale * image_subpixel_scale / 2;
x_hr &= image_subpixel_mask;
y_hr &= image_subpixel_mask;
- weight = (image_subpixel_size - x_hr) *
- (image_subpixel_size - y_hr);
+ weight = (image_subpixel_scale - x_hr) *
+ (image_subpixel_scale - y_hr);
if(x_lr >= 0 && y_lr >= 0 &&
x_lr <= maxx && y_lr <= maxy)
{
- fg += weight * *((const value_type*)base_type::source_image().row(y_lr) + x_lr);
+ fg += weight *
+ *((const value_type*)base_type::source().row_ptr(y_lr) + x_lr);
src_alpha += weight * base_mask;
}
else
@@ -225,11 +262,12 @@ namespace agg
x_lr++;
- weight = x_hr * (image_subpixel_size - y_hr);
+ weight = x_hr * (image_subpixel_scale - y_hr);
if(x_lr >= 0 && y_lr >= 0 &&
x_lr <= maxx && y_lr <= maxy)
{
- fg += weight * *((const value_type*)base_type::source_image().row(y_lr) + x_lr);
+ fg += weight *
+ *((const value_type*)base_type::source().row_ptr(y_lr) + x_lr);
src_alpha += weight * base_mask;
}
else
@@ -241,11 +279,12 @@ namespace agg
x_lr--;
y_lr++;
- weight = (image_subpixel_size - x_hr) * y_hr;
+ weight = (image_subpixel_scale - x_hr) * y_hr;
if(x_lr >= 0 && y_lr >= 0 &&
x_lr <= maxx && y_lr <= maxy)
{
- fg += weight * *((const value_type*)base_type::source_image().row(y_lr) + x_lr);
+ fg += weight *
+ *((const value_type*)base_type::source().row_ptr(y_lr) + x_lr);
src_alpha += weight * base_mask;
}
else
@@ -260,7 +299,8 @@ namespace agg
if(x_lr >= 0 && y_lr >= 0 &&
x_lr <= maxx && y_lr <= maxy)
{
- fg += weight * *((const value_type*)base_type::source_image().row(y_lr) + x_lr);
+ fg += weight *
+ *((const value_type*)base_type::source().row_ptr(y_lr) + x_lr);
src_alpha += weight * base_mask;
}
else
@@ -280,69 +320,52 @@ namespace agg
++base_type::interpolator();
} while(--len);
-
- return base_type::allocator().span();
}
+ private:
+ color_type m_back_color;
};
-
-
-
-
- //========================================span_image_filter_gray_2x2
- template<class ColorT,
- class Interpolator,
- class Allocator = span_allocator<ColorT> >
+ //==============================================span_image_filter_gray_2x2
+ template<class Source, class Interpolator>
class span_image_filter_gray_2x2 :
- public span_image_filter<ColorT, Interpolator, Allocator>
+ public span_image_filter<Source, Interpolator>
{
public:
- typedef ColorT color_type;
+ typedef Source source_type;
+ typedef typename source_type::color_type color_type;
typedef Interpolator interpolator_type;
- typedef Allocator alloc_type;
- typedef span_image_filter<color_type, interpolator_type, alloc_type> base_type;
+ typedef span_image_filter<source_type, interpolator_type> base_type;
typedef typename color_type::value_type value_type;
typedef typename color_type::calc_type calc_type;
- enum
+ enum base_scale_e
{
base_shift = color_type::base_shift,
base_mask = color_type::base_mask
};
//--------------------------------------------------------------------
- span_image_filter_gray_2x2(alloc_type& alloc) : base_type(alloc) {}
-
- //--------------------------------------------------------------------
- span_image_filter_gray_2x2(alloc_type& alloc,
- const rendering_buffer& src,
- const color_type& back_color,
+ span_image_filter_gray_2x2() {}
+ span_image_filter_gray_2x2(source_type& src,
interpolator_type& inter,
const image_filter_lut& filter) :
- base_type(alloc, src, back_color, inter, &filter)
+ base_type(src, inter, &filter)
{}
+
//--------------------------------------------------------------------
- color_type* generate(int x, int y, unsigned len)
+ void generate(color_type* span, int x, int y, unsigned len)
{
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
y + base_type::filter_dy_dbl(), len);
+
calc_type fg;
- calc_type src_alpha;
- value_type back_v = base_type::background_color().v;
- value_type back_a = base_type::background_color().a;
const value_type *fg_ptr;
-
- color_type* span = base_type::allocator().span();
const int16* weight_array = base_type::filter().weight_array() +
((base_type::filter().diameter()/2 - 1) <<
image_subpixel_shift);
-
- int maxx = base_type::source_image().width() - 1;
- int maxy = base_type::source_image().height() - 1;
-
do
{
int x_hr;
@@ -356,214 +379,92 @@ namespace agg
int x_lr = x_hr >> image_subpixel_shift;
int y_lr = y_hr >> image_subpixel_shift;
- if(x_lr >= 0 && y_lr >= 0 &&
- x_lr < maxx && y_lr < maxy)
- {
- fg = image_filter_size / 2;
-
- x_hr &= image_subpixel_mask;
- y_hr &= image_subpixel_mask;
- fg_ptr = (const value_type*)base_type::source_image().row(y_lr) + x_lr;
-
- fg += *fg_ptr++ * ((weight_array[x_hr + image_subpixel_size] *
- weight_array[y_hr + image_subpixel_size] +
- image_filter_size / 2) >>
- image_filter_shift);
- fg += *fg_ptr++ * ((weight_array[x_hr] *
- weight_array[y_hr + image_subpixel_size] +
- image_filter_size / 2) >>
- image_filter_shift);
-
- fg_ptr = (const value_type*)base_type::source_image().next_row(fg_ptr - 2);
-
- fg += *fg_ptr++ * ((weight_array[x_hr + image_subpixel_size] *
- weight_array[y_hr] +
- image_filter_size / 2) >>
- image_filter_shift);
- fg += *fg_ptr++ * ((weight_array[x_hr] *
- weight_array[y_hr] +
- image_filter_size / 2) >>
- image_filter_shift);
-
- fg >>= image_filter_shift;
- if(fg > base_mask) fg = base_mask;
- src_alpha = base_mask;
- }
- else
- {
- unsigned weight;
- if(x_lr < -1 || y_lr < -1 ||
- x_lr > maxx || y_lr > maxy)
- {
- fg = back_v;
- src_alpha = back_a;
- }
- else
- {
- fg = src_alpha = image_filter_size / 2;
-
- x_hr &= image_subpixel_mask;
- y_hr &= image_subpixel_mask;
-
- weight = (weight_array[x_hr + image_subpixel_size] *
- weight_array[y_hr + image_subpixel_size] +
- image_filter_size / 2) >>
- image_filter_shift;
- if(x_lr >= 0 && y_lr >= 0 &&
- x_lr <= maxx && y_lr <= maxy)
- {
- fg += weight * *((const value_type*)base_type::source_image().row(y_lr) + x_lr);
- src_alpha += weight * base_mask;
- }
- else
- {
- fg += back_v * weight;
- src_alpha += back_a * weight;
- }
-
- x_lr++;
-
- weight = (weight_array[x_hr] *
- weight_array[y_hr + image_subpixel_size] +
- image_filter_size / 2) >>
- image_filter_shift;
- if(x_lr >= 0 && y_lr >= 0 &&
- x_lr <= maxx && y_lr <= maxy)
- {
- fg += weight * *((const value_type*)base_type::source_image().row(y_lr) + x_lr);
- src_alpha += weight * base_mask;
- }
- else
- {
- fg += back_v * weight;
- src_alpha += back_a * weight;
- }
-
- x_lr--;
- y_lr++;
-
- weight = (weight_array[x_hr + image_subpixel_size] *
- weight_array[y_hr] +
- image_filter_size / 2) >>
- image_filter_shift;
- if(x_lr >= 0 && y_lr >= 0 &&
- x_lr <= maxx && y_lr <= maxy)
- {
- fg += weight * *((const value_type*)base_type::source_image().row(y_lr) + x_lr);
- src_alpha += weight * base_mask;
- }
- else
- {
- fg += back_v * weight;
- src_alpha += back_a * weight;
- }
-
- x_lr++;
-
- weight = (weight_array[x_hr] *
- weight_array[y_hr] +
- image_filter_size / 2) >>
- image_filter_shift;
- if(x_lr >= 0 && y_lr >= 0 &&
- x_lr <= maxx && y_lr <= maxy)
- {
- fg += weight * *((const value_type*)base_type::source_image().row(y_lr) + x_lr);
- src_alpha += weight * base_mask;
- }
- else
- {
- fg += back_v * weight;
- src_alpha += back_a * weight;
- }
- fg >>= image_filter_shift;
- src_alpha >>= image_filter_shift;
-
- if(src_alpha > base_mask) src_alpha = base_mask;
- if(fg > src_alpha) fg = src_alpha;
-
- }
- }
+ unsigned weight;
+ fg = image_filter_scale / 2;
+
+ x_hr &= image_subpixel_mask;
+ y_hr &= image_subpixel_mask;
+
+ fg_ptr = (const value_type*)base_type::source().span(x_lr, y_lr, 2);
+ weight = (weight_array[x_hr + image_subpixel_scale] *
+ weight_array[y_hr + image_subpixel_scale] +
+ image_filter_scale / 2) >>
+ image_filter_shift;
+ fg += weight * *fg_ptr;
+
+ fg_ptr = (const value_type*)base_type::source().next_x();
+ weight = (weight_array[x_hr] *
+ weight_array[y_hr + image_subpixel_scale] +
+ image_filter_scale / 2) >>
+ image_filter_shift;
+ fg += weight * *fg_ptr;
+
+ fg_ptr = (const value_type*)base_type::source().next_y();
+ weight = (weight_array[x_hr + image_subpixel_scale] *
+ weight_array[y_hr] +
+ image_filter_scale / 2) >>
+ image_filter_shift;
+ fg += weight * *fg_ptr;
+
+ fg_ptr = (const value_type*)base_type::source().next_x();
+ weight = (weight_array[x_hr] *
+ weight_array[y_hr] +
+ image_filter_scale / 2) >>
+ image_filter_shift;
+ fg += weight * *fg_ptr;
+
+ fg >>= image_filter_shift;
+ if(fg > base_mask) fg = base_mask;
span->v = (value_type)fg;
- span->a = (value_type)src_alpha;
+ span->a = base_mask;
++span;
++base_type::interpolator();
-
} while(--len);
-
- return base_type::allocator().span();
}
};
-
-
-
-
-
-
-
-
-
- //================================================span_image_filter_gray
- template<class ColorT,
- class Interpolator,
- class Allocator = span_allocator<ColorT> >
+ //==================================================span_image_filter_gray
+ template<class Source, class Interpolator>
class span_image_filter_gray :
- public span_image_filter<ColorT, Interpolator, Allocator>
+ public span_image_filter<Source, Interpolator>
{
public:
- typedef ColorT color_type;
+ typedef Source source_type;
+ typedef typename source_type::color_type color_type;
typedef Interpolator interpolator_type;
- typedef Allocator alloc_type;
- typedef span_image_filter<color_type, interpolator_type, alloc_type> base_type;
+ typedef span_image_filter<source_type, interpolator_type> base_type;
typedef typename color_type::value_type value_type;
typedef typename color_type::calc_type calc_type;
- enum
+ enum base_scale_e
{
base_shift = color_type::base_shift,
base_mask = color_type::base_mask
};
//--------------------------------------------------------------------
- span_image_filter_gray(alloc_type& alloc) : base_type(alloc) {}
-
- //--------------------------------------------------------------------
- span_image_filter_gray(alloc_type& alloc,
- const rendering_buffer& src,
- const color_type& back_color,
+ span_image_filter_gray() {}
+ span_image_filter_gray(source_type& src,
interpolator_type& inter,
const image_filter_lut& filter) :
- base_type(alloc, src, back_color, inter, &filter)
+ base_type(src, inter, &filter)
{}
//--------------------------------------------------------------------
- color_type* generate(int x, int y, unsigned len)
+ void generate(color_type* span, int x, int y, unsigned len)
{
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
y + base_type::filter_dy_dbl(), len);
int fg;
- int src_alpha;
- value_type back_v = base_type::background_color().v;
- value_type back_a = base_type::background_color().a;
-
- const value_type* fg_ptr;
+ const value_type *fg_ptr;
- unsigned diameter = base_type::filter().diameter();
- int start = base_type::filter().start();
- int start1 = start - 1;
+ unsigned diameter = base_type::filter().diameter();
+ int start = base_type::filter().start();
const int16* weight_array = base_type::filter().weight_array();
- color_type* span = base_type::allocator().span();
-
- int maxx = base_type::source_image().width() + start - 2;
- int maxy = base_type::source_image().height() + start - 2;
-
- int maxx2 = base_type::source_image().width() - start - 1;
- int maxy2 = base_type::source_image().height() - start - 1;
-
int x_count;
int weight_y;
@@ -580,118 +481,264 @@ namespace agg
int x_lr = x_hr >> image_subpixel_shift;
int y_lr = y_hr >> image_subpixel_shift;
- fg = image_filter_size / 2;
+ fg = image_filter_scale / 2;
int x_fract = x_hr & image_subpixel_mask;
unsigned y_count = diameter;
- if(x_lr >= -start && y_lr >= -start &&
- x_lr <= maxx && y_lr <= maxy)
+ y_hr = image_subpixel_mask - (y_hr & image_subpixel_mask);
+ fg_ptr = (const value_type*)base_type::source().span(x_lr + start,
+ y_lr + start,
+ diameter);
+ for(;;)
{
- y_hr = image_subpixel_mask - (y_hr & image_subpixel_mask);
- fg_ptr = (const value_type*)base_type::source_image().row(y_lr + start) + x_lr + start;
- do
+ x_count = diameter;
+ weight_y = weight_array[y_hr];
+ x_hr = image_subpixel_mask - x_fract;
+ for(;;)
{
- x_count = diameter;
- weight_y = weight_array[y_hr];
- x_hr = image_subpixel_mask - x_fract;
+ fg += *fg_ptr *
+ ((weight_y * weight_array[x_hr] +
+ image_filter_scale / 2) >>
+ image_filter_shift);
+ if(--x_count == 0) break;
+ x_hr += image_subpixel_scale;
+ fg_ptr = (const value_type*)base_type::source().next_x();
+ }
- do
- {
- fg += *fg_ptr++ * ((weight_y * weight_array[x_hr] +
- image_filter_size / 2) >>
- image_filter_shift);
- x_hr += image_subpixel_size;
+ if(--y_count == 0) break;
+ y_hr += image_subpixel_scale;
+ fg_ptr = (const value_type*)base_type::source().next_y();
+ }
+
+ fg >>= image_filter_shift;
+ if(fg < 0) fg = 0;
+ if(fg > base_mask) fg = base_mask;
+ span->v = (value_type)fg;
+ span->a = base_mask;
- } while(--x_count);
+ ++span;
+ ++base_type::interpolator();
- y_hr += image_subpixel_size;
- fg_ptr = (const value_type*)base_type::source_image().next_row(fg_ptr - diameter);
+ } while(--len);
+ }
+ };
- } while(--y_count);
- fg >>= image_filter_shift;
- if(fg < 0) fg = 0;
- if(fg > base_mask) fg = base_mask;
- src_alpha = base_mask;
- }
- else
+ //=========================================span_image_resample_gray_affine
+ template<class Source>
+ class span_image_resample_gray_affine :
+ public span_image_resample_affine<Source>
+ {
+ public:
+ typedef Source source_type;
+ typedef typename source_type::color_type color_type;
+ typedef span_image_resample_affine<source_type> base_type;
+ typedef typename base_type::interpolator_type interpolator_type;
+ typedef typename color_type::value_type value_type;
+ typedef typename color_type::long_type long_type;
+ enum base_scale_e
+ {
+ base_shift = color_type::base_shift,
+ base_mask = color_type::base_mask,
+ downscale_shift = image_filter_shift
+ };
+
+ //--------------------------------------------------------------------
+ span_image_resample_gray_affine() {}
+ span_image_resample_gray_affine(source_type& src,
+ interpolator_type& inter,
+ const image_filter_lut& filter) :
+ base_type(src, inter, filter)
+ {}
+
+
+ //--------------------------------------------------------------------
+ void generate(color_type* span, int x, int y, unsigned len)
+ {
+ base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
+ y + base_type::filter_dy_dbl(), len);
+
+ long_type fg;
+
+ int diameter = base_type::filter().diameter();
+ int filter_scale = diameter << image_subpixel_shift;
+ int radius_x = (diameter * base_type::m_rx) >> 1;
+ int radius_y = (diameter * base_type::m_ry) >> 1;
+ int len_x_lr =
+ (diameter * base_type::m_rx + image_subpixel_mask) >>
+ image_subpixel_shift;
+
+ const int16* weight_array = base_type::filter().weight_array();
+
+ do
+ {
+ base_type::interpolator().coordinates(&x, &y);
+
+ x += base_type::filter_dx_int() - radius_x;
+ y += base_type::filter_dy_int() - radius_y;
+
+ fg = image_filter_scale / 2;
+
+ int y_lr = y >> image_subpixel_shift;
+ int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) *
+ base_type::m_ry_inv) >>
+ image_subpixel_shift;
+ int total_weight = 0;
+ int x_lr = x >> image_subpixel_shift;
+ int x_hr = ((image_subpixel_mask - (x & image_subpixel_mask)) *
+ base_type::m_rx_inv) >>
+ image_subpixel_shift;
+
+ int x_hr2 = x_hr;
+ const value_type* fg_ptr =
+ (const value_type*)base_type::source().span(x_lr, y_lr, len_x_lr);
+ for(;;)
{
- if(x_lr < start1 || y_lr < start1 ||
- x_lr > maxx2 || y_lr > maxy2)
+ int weight_y = weight_array[y_hr];
+ x_hr = x_hr2;
+ for(;;)
{
- fg = back_v;
- src_alpha = back_a;
+ int weight = (weight_y * weight_array[x_hr] +
+ image_filter_scale / 2) >>
+ downscale_shift;
+
+ fg += *fg_ptr * weight;
+ total_weight += weight;
+ x_hr += base_type::m_rx_inv;
+ if(x_hr >= filter_scale) break;
+ fg_ptr = (const value_type*)base_type::source().next_x();
}
- else
- {
- src_alpha = image_filter_size / 2;
- y_lr = (y >> image_subpixel_shift) + start;
- y_hr = image_subpixel_mask - (y_hr & image_subpixel_mask);
+ y_hr += base_type::m_ry_inv;
+ if(y_hr >= filter_scale) break;
+ fg_ptr = (const value_type*)base_type::source().next_y();
+ }
- do
- {
- x_count = diameter;
- weight_y = weight_array[y_hr];
- x_lr = (x >> image_subpixel_shift) + start;
- x_hr = image_subpixel_mask - x_fract;
-
- do
- {
- int weight = (weight_y * weight_array[x_hr] +
- image_filter_size / 2) >>
- image_filter_shift;
-
- if(x_lr >= 0 && y_lr >= 0 &&
- x_lr < int(base_type::source_image().width()) &&
- y_lr < int(base_type::source_image().height()))
- {
- fg_ptr = (const value_type*)base_type::source_image().row(y_lr) + x_lr;
- fg += *fg_ptr++ * weight;
- src_alpha += base_mask * weight;
- }
- else
- {
- fg += back_v * weight;
- src_alpha += back_a * weight;
- }
- x_hr += image_subpixel_size;
- x_lr++;
-
- } while(--x_count);
-
- y_hr += image_subpixel_size;
- y_lr++;
-
- } while(--y_count);
-
-
- fg >>= image_filter_shift;
- src_alpha >>= image_filter_shift;
-
- if(fg < 0) fg = 0;
- if(src_alpha < 0) src_alpha = 0;
-
- if(src_alpha > base_mask) src_alpha = base_mask;
- if(fg > src_alpha) fg = src_alpha;
+ fg /= total_weight;
+ if(fg < 0) fg = 0;
+ if(fg > base_mask) fg = base_mask;
+
+ span->v = (value_type)fg;
+ span->a = base_mask;
+
+ ++span;
+ ++base_type::interpolator();
+ } while(--len);
+ }
+ };
+
+
+
+ //================================================span_image_resample_gray
+ template<class Source, class Interpolator>
+ class span_image_resample_gray :
+ public span_image_resample<Source, Interpolator>
+ {
+ public:
+ typedef Source source_type;
+ typedef typename source_type::color_type color_type;
+ typedef Interpolator interpolator_type;
+ typedef span_image_resample<source_type, interpolator_type> base_type;
+ typedef typename color_type::value_type value_type;
+ typedef typename color_type::long_type long_type;
+ enum base_scale_e
+ {
+ base_shift = color_type::base_shift,
+ base_mask = color_type::base_mask,
+ downscale_shift = image_filter_shift
+ };
+
+ //--------------------------------------------------------------------
+ span_image_resample_gray() {}
+ span_image_resample_gray(source_type& src,
+ interpolator_type& inter,
+ const image_filter_lut& filter) :
+ base_type(src, inter, filter)
+ {}
+
+ //--------------------------------------------------------------------
+ void generate(color_type* span, int x, int y, unsigned len)
+ {
+ base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
+ y + base_type::filter_dy_dbl(), len);
+ long_type fg;
+
+ int diameter = base_type::filter().diameter();
+ int filter_scale = diameter << image_subpixel_shift;
+
+ const int16* weight_array = base_type::filter().weight_array();
+ do
+ {
+ int rx;
+ int ry;
+ int rx_inv = image_subpixel_scale;
+ int ry_inv = image_subpixel_scale;
+ base_type::interpolator().coordinates(&x, &y);
+ base_type::interpolator().local_scale(&rx, &ry);
+ base_type::adjust_scale(&rx, &ry);
+
+ rx_inv = image_subpixel_scale * image_subpixel_scale / rx;
+ ry_inv = image_subpixel_scale * image_subpixel_scale / ry;
+
+ int radius_x = (diameter * rx) >> 1;
+ int radius_y = (diameter * ry) >> 1;
+ int len_x_lr =
+ (diameter * rx + image_subpixel_mask) >>
+ image_subpixel_shift;
+
+ x += base_type::filter_dx_int() - radius_x;
+ y += base_type::filter_dy_int() - radius_y;
+
+ fg = image_filter_scale / 2;
+
+ int y_lr = y >> image_subpixel_shift;
+ int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) *
+ ry_inv) >>
+ image_subpixel_shift;
+ int total_weight = 0;
+ int x_lr = x >> image_subpixel_shift;
+ int x_hr = ((image_subpixel_mask - (x & image_subpixel_mask)) *
+ rx_inv) >>
+ image_subpixel_shift;
+ int x_hr2 = x_hr;
+ const value_type* fg_ptr =
+ (const value_type*)base_type::source().span(x_lr, y_lr, len_x_lr);
+
+ for(;;)
+ {
+ int weight_y = weight_array[y_hr];
+ x_hr = x_hr2;
+ for(;;)
+ {
+ int weight = (weight_y * weight_array[x_hr] +
+ image_filter_scale / 2) >>
+ downscale_shift;
+ fg += *fg_ptr * weight;
+ total_weight += weight;
+ x_hr += rx_inv;
+ if(x_hr >= filter_scale) break;
+ fg_ptr = (const value_type*)base_type::source().next_x();
}
+ y_hr += ry_inv;
+ if(y_hr >= filter_scale) break;
+ fg_ptr = (const value_type*)base_type::source().next_y();
}
+ fg /= total_weight;
+ if(fg < 0) fg = 0;
+ if(fg > base_mask) fg = base_mask;
+
span->v = (value_type)fg;
- span->a = (value_type)src_alpha;
+ span->a = base_mask;
++span;
++base_type::interpolator();
-
} while(--len);
-
- return base_type::allocator().span();
}
};
-
}
diff --git a/agg/inc/agg_span_image_filter_rgb.h b/agg/inc/agg_span_image_filter_rgb.h
index d8f8142bfffb..dc9295e31542 100755
--- a/agg/inc/agg_span_image_filter_rgb.h
+++ b/agg/inc/agg_span_image_filter_rgb.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -20,7 +20,6 @@
// PostScript and PDF technology for software developers.
//
//----------------------------------------------------------------------------
-
#ifndef AGG_SPAN_IMAGE_FILTER_RGB_INCLUDED
#define AGG_SPAN_IMAGE_FILTER_RGB_INCLUDED
@@ -32,146 +31,198 @@
namespace agg
{
-
- //==============================================span_image_filter_rgb_nn
- template<class ColorT,
- class Order,
- class Interpolator,
- class Allocator = span_allocator<ColorT> >
+ //===============================================span_image_filter_rgb_nn
+ template<class Source, class Interpolator>
class span_image_filter_rgb_nn :
- public span_image_filter<ColorT, Interpolator, Allocator>
+ public span_image_filter<Source, Interpolator>
{
public:
- typedef ColorT color_type;
- typedef Order order_type;
+ typedef Source source_type;
+ typedef typename source_type::color_type color_type;
+ typedef typename source_type::order_type order_type;
typedef Interpolator interpolator_type;
- typedef Allocator alloc_type;
- typedef span_image_filter<color_type, interpolator_type, alloc_type> base_type;
+ typedef span_image_filter<source_type, interpolator_type> base_type;
typedef typename color_type::value_type value_type;
typedef typename color_type::calc_type calc_type;
- enum
+ enum base_scale_e
{
base_shift = color_type::base_shift,
base_mask = color_type::base_mask
};
//--------------------------------------------------------------------
- span_image_filter_rgb_nn(alloc_type& alloc) : base_type(alloc) {}
-
- //--------------------------------------------------------------------
- span_image_filter_rgb_nn(alloc_type& alloc,
- const rendering_buffer& src,
- const color_type& back_color,
+ span_image_filter_rgb_nn() {}
+ span_image_filter_rgb_nn(source_type& src,
interpolator_type& inter) :
- base_type(alloc, src, back_color, inter, 0)
+ base_type(src, inter, 0)
{}
//--------------------------------------------------------------------
- color_type* generate(int x, int y, unsigned len)
+ void generate(color_type* span, int x, int y, unsigned len)
{
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
y + base_type::filter_dy_dbl(), len);
+ do
+ {
+ base_type::interpolator().coordinates(&x, &y);
+ const value_type* fg_ptr = (const value_type*)
+ base_type::source().span(x >> image_subpixel_shift,
+ y >> image_subpixel_shift,
+ 1);
+ span->r = fg_ptr[order_type::R];
+ span->g = fg_ptr[order_type::G];
+ span->b = fg_ptr[order_type::B];
+ span->a = base_mask;
+ ++span;
+ ++base_type::interpolator();
- calc_type fg[3];
- calc_type src_alpha;
+ } while(--len);
+ }
+ };
- const value_type *fg_ptr;
- color_type* span = base_type::allocator().span();
- int maxx = base_type::source_image().width() - 1;
- int maxy = base_type::source_image().height() - 1;
+ //==========================================span_image_filter_rgb_bilinear
+ template<class Source, class Interpolator>
+ class span_image_filter_rgb_bilinear :
+ public span_image_filter<Source, Interpolator>
+ {
+ public:
+ typedef Source source_type;
+ typedef typename source_type::color_type color_type;
+ typedef typename source_type::order_type order_type;
+ typedef Interpolator interpolator_type;
+ typedef span_image_filter<source_type, interpolator_type> base_type;
+ typedef typename color_type::value_type value_type;
+ typedef typename color_type::calc_type calc_type;
+ enum base_scale_e
+ {
+ base_shift = color_type::base_shift,
+ base_mask = color_type::base_mask
+ };
+
+ //--------------------------------------------------------------------
+ span_image_filter_rgb_bilinear() {}
+ span_image_filter_rgb_bilinear(source_type& src,
+ interpolator_type& inter) :
+ base_type(src, inter, 0)
+ {}
+
+
+ //--------------------------------------------------------------------
+ void generate(color_type* span, int x, int y, unsigned len)
+ {
+ base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
+ y + base_type::filter_dy_dbl(), len);
+ calc_type fg[3];
+ const value_type *fg_ptr;
do
{
- base_type::interpolator().coordinates(&x, &y);
+ int x_hr;
+ int y_hr;
- x >>= image_subpixel_shift;
- y >>= image_subpixel_shift;
+ base_type::interpolator().coordinates(&x_hr, &y_hr);
- if(x >= 0 && y >= 0 &&
- x <= maxx && y <= maxy)
- {
- fg_ptr = (const value_type*)base_type::source_image().row(y) + x + x + x;
- fg[0] = *fg_ptr++;
- fg[1] = *fg_ptr++;
- fg[2] = *fg_ptr++;
- src_alpha = base_mask;
- }
- else
- {
- fg[order_type::R] = base_type::background_color().r;
- fg[order_type::G] = base_type::background_color().g;
- fg[order_type::B] = base_type::background_color().b;
- src_alpha = base_type::background_color().a;
- }
+ 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;
+
+ unsigned weight;
+
+ fg[0] =
+ fg[1] =
+ fg[2] = image_subpixel_scale * image_subpixel_scale / 2;
+
+ x_hr &= image_subpixel_mask;
+ y_hr &= image_subpixel_mask;
+
+ fg_ptr = (const value_type*)base_type::source().span(x_lr, y_lr, 2);
+ weight = (image_subpixel_scale - x_hr) *
+ (image_subpixel_scale - y_hr);
+ fg[0] += weight * *fg_ptr++;
+ fg[1] += weight * *fg_ptr++;
+ fg[2] += weight * *fg_ptr;
+
+ fg_ptr = (const value_type*)base_type::source().next_x();
+ weight = x_hr * (image_subpixel_scale - y_hr);
+ fg[0] += weight * *fg_ptr++;
+ fg[1] += weight * *fg_ptr++;
+ fg[2] += weight * *fg_ptr;
+
+ fg_ptr = (const value_type*)base_type::source().next_y();
+ weight = (image_subpixel_scale - x_hr) * y_hr;
+ fg[0] += weight * *fg_ptr++;
+ fg[1] += weight * *fg_ptr++;
+ fg[2] += weight * *fg_ptr;
+
+ fg_ptr = (const value_type*)base_type::source().next_x();
+ weight = x_hr * y_hr;
+ fg[0] += weight * *fg_ptr++;
+ fg[1] += weight * *fg_ptr++;
+ fg[2] += weight * *fg_ptr;
+
+ span->r = value_type(fg[order_type::R] >> (image_subpixel_shift * 2));
+ span->g = value_type(fg[order_type::G] >> (image_subpixel_shift * 2));
+ span->b = value_type(fg[order_type::B] >> (image_subpixel_shift * 2));
+ span->a = base_mask;
- span->r = (value_type)fg[order_type::R];
- span->g = (value_type)fg[order_type::G];
- span->b = (value_type)fg[order_type::B];
- span->a = (value_type)src_alpha;
++span;
++base_type::interpolator();
} while(--len);
-
- return base_type::allocator().span();
}
};
-
- //=========================================span_image_filter_rgb_bilinear
- template<class ColorT,
- class Order,
- class Interpolator,
- class Allocator = span_allocator<ColorT> >
- class span_image_filter_rgb_bilinear :
- public span_image_filter<ColorT, Interpolator, Allocator>
+ //=====================================span_image_filter_rgb_bilinear_clip
+ template<class Source, class Interpolator>
+ class span_image_filter_rgb_bilinear_clip :
+ public span_image_filter<Source, Interpolator>
{
public:
- typedef ColorT color_type;
- typedef Order order_type;
+ typedef Source source_type;
+ typedef typename source_type::color_type color_type;
+ typedef typename source_type::order_type order_type;
typedef Interpolator interpolator_type;
- typedef Allocator alloc_type;
- typedef span_image_filter<color_type, interpolator_type, alloc_type> base_type;
+ typedef span_image_filter<source_type, interpolator_type> base_type;
typedef typename color_type::value_type value_type;
typedef typename color_type::calc_type calc_type;
- enum
+ enum base_scale_e
{
base_shift = color_type::base_shift,
base_mask = color_type::base_mask
};
//--------------------------------------------------------------------
- span_image_filter_rgb_bilinear(alloc_type& alloc) : base_type(alloc) {}
-
- //--------------------------------------------------------------------
- span_image_filter_rgb_bilinear(alloc_type& alloc,
- const rendering_buffer& src,
- const color_type& back_color,
- interpolator_type& inter) :
- base_type(alloc, src, back_color, inter, 0)
+ span_image_filter_rgb_bilinear_clip() {}
+ span_image_filter_rgb_bilinear_clip(source_type& src,
+ const color_type& back_color,
+ interpolator_type& inter) :
+ base_type(src, inter, 0),
+ m_back_color(back_color)
{}
+ const color_type& background_color() const { return m_back_color; }
+ void background_color(const color_type& v) { m_back_color = v; }
//--------------------------------------------------------------------
- color_type* generate(int x, int y, unsigned len)
+ void generate(color_type* span, int x, int y, unsigned len)
{
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
y + base_type::filter_dy_dbl(), len);
calc_type fg[3];
calc_type src_alpha;
- value_type back_r = base_type::background_color().r;
- value_type back_g = base_type::background_color().g;
- value_type back_b = base_type::background_color().b;
- value_type back_a = base_type::background_color().a;
+ value_type back_r = m_back_color.r;
+ value_type back_g = m_back_color.g;
+ value_type back_b = m_back_color.b;
+ value_type back_a = m_back_color.a;
const value_type *fg_ptr;
- color_type* span = base_type::allocator().span();
-
- int maxx = base_type::source_image().width() - 1;
- int maxy = base_type::source_image().height() - 1;
+ int maxx = base_type::source().width() - 1;
+ int maxy = base_type::source().height() - 1;
do
{
@@ -192,26 +243,30 @@ namespace agg
{
fg[0] =
fg[1] =
- fg[2] = image_subpixel_size * image_subpixel_size / 2;
+ fg[2] = image_subpixel_scale * image_subpixel_scale / 2;
x_hr &= image_subpixel_mask;
y_hr &= image_subpixel_mask;
- fg_ptr = (const value_type*)base_type::source_image().row(y_lr) + x_lr + x_lr + x_lr;
- weight = (image_subpixel_size - x_hr) *
- (image_subpixel_size - y_hr);
+ fg_ptr = (const value_type*)
+ base_type::source().row_ptr(y_lr) + x_lr + x_lr + x_lr;
+
+ weight = (image_subpixel_scale - x_hr) *
+ (image_subpixel_scale - y_hr);
fg[0] += weight * *fg_ptr++;
fg[1] += weight * *fg_ptr++;
fg[2] += weight * *fg_ptr++;
- weight = x_hr * (image_subpixel_size - y_hr);
+ weight = x_hr * (image_subpixel_scale - y_hr);
fg[0] += weight * *fg_ptr++;
fg[1] += weight * *fg_ptr++;
fg[2] += weight * *fg_ptr++;
- fg_ptr = (const value_type*)base_type::source_image().next_row(fg_ptr - 6);
+ ++y_lr;
+ fg_ptr = (const value_type*)
+ base_type::source().row_ptr(y_lr) + x_lr + x_lr + x_lr;
- weight = (image_subpixel_size - x_hr) * y_hr;
+ weight = (image_subpixel_scale - x_hr) * y_hr;
fg[0] += weight * *fg_ptr++;
fg[1] += weight * *fg_ptr++;
fg[2] += weight * *fg_ptr++;
@@ -241,17 +296,19 @@ namespace agg
fg[0] =
fg[1] =
fg[2] =
- src_alpha = image_subpixel_size * image_subpixel_size / 2;
+ src_alpha = image_subpixel_scale * image_subpixel_scale / 2;
x_hr &= image_subpixel_mask;
y_hr &= image_subpixel_mask;
- weight = (image_subpixel_size - x_hr) *
- (image_subpixel_size - y_hr);
+ weight = (image_subpixel_scale - x_hr) *
+ (image_subpixel_scale - y_hr);
if(x_lr >= 0 && y_lr >= 0 &&
x_lr <= maxx && y_lr <= maxy)
{
- fg_ptr = (const value_type*)base_type::source_image().row(y_lr) + x_lr + x_lr + x_lr;
+ fg_ptr = (const value_type*)
+ base_type::source().row_ptr(y_lr) + x_lr + x_lr + x_lr;
+
fg[0] += weight * *fg_ptr++;
fg[1] += weight * *fg_ptr++;
fg[2] += weight * *fg_ptr++;
@@ -267,11 +324,13 @@ namespace agg
x_lr++;
- weight = x_hr * (image_subpixel_size - y_hr);
+ weight = x_hr * (image_subpixel_scale - y_hr);
if(x_lr >= 0 && y_lr >= 0 &&
x_lr <= maxx && y_lr <= maxy)
{
- fg_ptr = (const value_type*)base_type::source_image().row(y_lr) + x_lr + x_lr + x_lr;
+ fg_ptr = (const value_type*)
+ base_type::source().row_ptr(y_lr) + x_lr + x_lr + x_lr;
+
fg[0] += weight * *fg_ptr++;
fg[1] += weight * *fg_ptr++;
fg[2] += weight * *fg_ptr++;
@@ -288,11 +347,13 @@ namespace agg
x_lr--;
y_lr++;
- weight = (image_subpixel_size - x_hr) * y_hr;
+ weight = (image_subpixel_scale - x_hr) * y_hr;
if(x_lr >= 0 && y_lr >= 0 &&
x_lr <= maxx && y_lr <= maxy)
{
- fg_ptr = (const value_type*)base_type::source_image().row(y_lr) + x_lr + x_lr + x_lr;
+ fg_ptr = (const value_type*)
+ base_type::source().row_ptr(y_lr) + x_lr + x_lr + x_lr;
+
fg[0] += weight * *fg_ptr++;
fg[1] += weight * *fg_ptr++;
fg[2] += weight * *fg_ptr++;
@@ -312,7 +373,9 @@ namespace agg
if(x_lr >= 0 && y_lr >= 0 &&
x_lr <= maxx && y_lr <= maxy)
{
- fg_ptr = (const value_type*)base_type::source_image().row(y_lr) + x_lr + x_lr + x_lr;
+ fg_ptr = (const value_type*)
+ base_type::source().row_ptr(y_lr) + x_lr + x_lr + x_lr;
+
fg[0] += weight * *fg_ptr++;
fg[1] += weight * *fg_ptr++;
fg[2] += weight * *fg_ptr++;
@@ -341,74 +404,53 @@ namespace agg
++base_type::interpolator();
} while(--len);
-
- return base_type::allocator().span();
}
+ private:
+ color_type m_back_color;
};
-
-
-
-
-
- //=========================================span_image_filter_rgb_2x2
- template<class ColorT,
- class Order,
- class Interpolator,
- class Allocator = span_allocator<ColorT> >
+ //===============================================span_image_filter_rgb_2x2
+ template<class Source, class Interpolator>
class span_image_filter_rgb_2x2 :
- public span_image_filter<ColorT, Interpolator, Allocator>
+ public span_image_filter<Source, Interpolator>
{
public:
- typedef ColorT color_type;
- typedef Order order_type;
+ typedef Source source_type;
+ typedef typename source_type::color_type color_type;
+ typedef typename source_type::order_type order_type;
typedef Interpolator interpolator_type;
- typedef Allocator alloc_type;
- typedef span_image_filter<color_type, interpolator_type, alloc_type> base_type;
+ typedef span_image_filter<source_type, interpolator_type> base_type;
typedef typename color_type::value_type value_type;
typedef typename color_type::calc_type calc_type;
- enum
+ enum base_scale_e
{
base_shift = color_type::base_shift,
base_mask = color_type::base_mask
};
//--------------------------------------------------------------------
- span_image_filter_rgb_2x2(alloc_type& alloc) : base_type(alloc) {}
-
- //--------------------------------------------------------------------
- span_image_filter_rgb_2x2(alloc_type& alloc,
- const rendering_buffer& src,
- const color_type& back_color,
+ span_image_filter_rgb_2x2() {}
+ span_image_filter_rgb_2x2(source_type& src,
interpolator_type& inter,
const image_filter_lut& filter) :
- base_type(alloc, src, back_color, inter, &filter)
+ base_type(src, inter, &filter)
{}
+
//--------------------------------------------------------------------
- color_type* generate(int x, int y, unsigned len)
+ void generate(color_type* span, int x, int y, unsigned len)
{
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
y + base_type::filter_dy_dbl(), len);
+
calc_type fg[3];
- calc_type src_alpha;
- value_type back_r = base_type::background_color().r;
- value_type back_g = base_type::background_color().g;
- value_type back_b = base_type::background_color().b;
- value_type back_a = base_type::background_color().a;
const value_type *fg_ptr;
-
- color_type* span = base_type::allocator().span();
const int16* weight_array = base_type::filter().weight_array() +
((base_type::filter().diameter()/2 - 1) <<
image_subpixel_shift);
-
- int maxx = base_type::source_image().width() - 1;
- int maxy = base_type::source_image().height() - 1;
-
do
{
int x_hr;
@@ -421,262 +463,111 @@ namespace agg
int x_lr = x_hr >> image_subpixel_shift;
int y_lr = y_hr >> image_subpixel_shift;
- unsigned weight;
-
- if(x_lr >= 0 && y_lr >= 0 &&
- x_lr < maxx && y_lr < maxy)
- {
- fg[0] = fg[1] = fg[2] = image_filter_size / 2;
-
- x_hr &= image_subpixel_mask;
- y_hr &= image_subpixel_mask;
- fg_ptr = (const value_type*)base_type::source_image().row(y_lr) + x_lr + x_lr + x_lr;
-
- weight = (weight_array[x_hr + image_subpixel_size] *
- weight_array[y_hr + image_subpixel_size] +
- image_filter_size / 2) >>
- image_filter_shift;
- fg[0] += weight * *fg_ptr++;
- fg[1] += weight * *fg_ptr++;
- fg[2] += weight * *fg_ptr++;
-
- weight = (weight_array[x_hr] *
- weight_array[y_hr + image_subpixel_size] +
- image_filter_size / 2) >>
- image_filter_shift;
- fg[0] += weight * *fg_ptr++;
- fg[1] += weight * *fg_ptr++;
- fg[2] += weight * *fg_ptr++;
-
- fg_ptr = (const value_type*)base_type::source_image().next_row(fg_ptr - 6);
-
- weight = (weight_array[x_hr + image_subpixel_size] *
- weight_array[y_hr] +
- image_filter_size / 2) >>
- image_filter_shift;
- fg[0] += weight * *fg_ptr++;
- fg[1] += weight * *fg_ptr++;
- fg[2] += weight * *fg_ptr++;
-
- weight = (weight_array[x_hr] *
- weight_array[y_hr] +
- image_filter_size / 2) >>
- image_filter_shift;
- fg[0] += weight * *fg_ptr++;
- fg[1] += weight * *fg_ptr++;
- fg[2] += weight * *fg_ptr++;
-
- fg[0] >>= image_filter_shift;
- fg[1] >>= image_filter_shift;
- fg[2] >>= image_filter_shift;
- src_alpha = base_mask;
-
- if(fg[0] > base_mask) fg[0] = base_mask;
- if(fg[1] > base_mask) fg[1] = base_mask;
- if(fg[2] > base_mask) fg[2] = base_mask;
- }
- else
- {
- if(x_lr < -1 || y_lr < -1 ||
- x_lr > maxx || y_lr > maxy)
- {
- fg[order_type::R] = back_r;
- fg[order_type::G] = back_g;
- fg[order_type::B] = back_b;
- src_alpha = back_a;
- }
- else
- {
- fg[0] = fg[1] = fg[2] = src_alpha = image_filter_size / 2;
-
- x_hr &= image_subpixel_mask;
- y_hr &= image_subpixel_mask;
-
- weight = (weight_array[x_hr + image_subpixel_size] *
- weight_array[y_hr + image_subpixel_size] +
- image_filter_size / 2) >>
- image_filter_shift;
- if(x_lr >= 0 && y_lr >= 0 &&
- x_lr <= maxx && y_lr <= maxy)
- {
- fg_ptr = (const value_type*)base_type::source_image().row(y_lr) + x_lr + x_lr + x_lr;
- fg[0] += weight * *fg_ptr++;
- fg[1] += weight * *fg_ptr++;
- fg[2] += weight * *fg_ptr++;
- src_alpha += weight * base_mask;
- }
- else
- {
- fg[order_type::R] += back_r * weight;
- fg[order_type::G] += back_g * weight;
- fg[order_type::B] += back_b * weight;
- src_alpha += back_a * weight;
- }
-
- x_lr++;
-
- weight = (weight_array[x_hr] *
- weight_array[y_hr + image_subpixel_size] +
- image_filter_size / 2) >>
- image_filter_shift;
- if(x_lr >= 0 && y_lr >= 0 &&
- x_lr <= maxx && y_lr <= maxy)
- {
- fg_ptr = (const value_type*)base_type::source_image().row(y_lr) + x_lr + x_lr + x_lr;
- fg[0] += weight * *fg_ptr++;
- fg[1] += weight * *fg_ptr++;
- fg[2] += weight * *fg_ptr++;
- src_alpha += weight * base_mask;
- }
- else
- {
- fg[order_type::R] += back_r * weight;
- fg[order_type::G] += back_g * weight;
- fg[order_type::B] += back_b * weight;
- src_alpha += back_a * weight;
- }
-
- x_lr--;
- y_lr++;
-
- weight = (weight_array[x_hr + image_subpixel_size] *
- weight_array[y_hr] +
- image_filter_size / 2) >>
- image_filter_shift;
- if(x_lr >= 0 && y_lr >= 0 &&
- x_lr <= maxx && y_lr <= maxy)
- {
- fg_ptr = (const value_type*)base_type::source_image().row(y_lr) + x_lr + x_lr + x_lr;
- fg[0] += weight * *fg_ptr++;
- fg[1] += weight * *fg_ptr++;
- fg[2] += weight * *fg_ptr++;
- src_alpha += weight * base_mask;
- }
- else
- {
- fg[order_type::R] += back_r * weight;
- fg[order_type::G] += back_g * weight;
- fg[order_type::B] += back_b * weight;
- src_alpha += back_a * weight;
- }
-
- x_lr++;
-
- weight = (weight_array[x_hr] *
- weight_array[y_hr] +
- image_filter_size / 2) >>
- image_filter_shift;
- if(x_lr >= 0 && y_lr >= 0 &&
- x_lr <= maxx && y_lr <= maxy)
- {
- fg_ptr = (const value_type*)base_type::source_image().row(y_lr) + x_lr + x_lr + x_lr;
- fg[0] += weight * *fg_ptr++;
- fg[1] += weight * *fg_ptr++;
- fg[2] += weight * *fg_ptr++;
- src_alpha += weight * base_mask;
- }
- else
- {
- fg[order_type::R] += back_r * weight;
- fg[order_type::G] += back_g * weight;
- fg[order_type::B] += back_b * weight;
- src_alpha += back_a * weight;
- }
-
- fg[0] >>= image_filter_shift;
- fg[1] >>= image_filter_shift;
- fg[2] >>= image_filter_shift;
- src_alpha >>= image_filter_shift;
- if(src_alpha > base_mask) src_alpha = base_mask;
- 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;
- }
- }
+ unsigned weight;
+ fg[0] = fg[1] = fg[2] = image_filter_scale / 2;
+
+ x_hr &= image_subpixel_mask;
+ y_hr &= image_subpixel_mask;
+
+ fg_ptr = (const value_type*)base_type::source().span(x_lr, y_lr, 2);
+ weight = (weight_array[x_hr + image_subpixel_scale] *
+ weight_array[y_hr + image_subpixel_scale] +
+ image_filter_scale / 2) >>
+ image_filter_shift;
+ fg[0] += weight * *fg_ptr++;
+ fg[1] += weight * *fg_ptr++;
+ fg[2] += weight * *fg_ptr;
+
+ fg_ptr = (const value_type*)base_type::source().next_x();
+ weight = (weight_array[x_hr] *
+ weight_array[y_hr + image_subpixel_scale] +
+ image_filter_scale / 2) >>
+ image_filter_shift;
+ fg[0] += weight * *fg_ptr++;
+ fg[1] += weight * *fg_ptr++;
+ fg[2] += weight * *fg_ptr;
+
+ fg_ptr = (const value_type*)base_type::source().next_y();
+ weight = (weight_array[x_hr + image_subpixel_scale] *
+ weight_array[y_hr] +
+ image_filter_scale / 2) >>
+ image_filter_shift;
+ fg[0] += weight * *fg_ptr++;
+ fg[1] += weight * *fg_ptr++;
+ fg[2] += weight * *fg_ptr;
+
+ fg_ptr = (const value_type*)base_type::source().next_x();
+ weight = (weight_array[x_hr] *
+ weight_array[y_hr] +
+ image_filter_scale / 2) >>
+ image_filter_shift;
+ fg[0] += weight * *fg_ptr++;
+ fg[1] += weight * *fg_ptr++;
+ fg[2] += weight * *fg_ptr;
+
+ fg[0] >>= image_filter_shift;
+ fg[1] >>= image_filter_shift;
+ fg[2] >>= image_filter_shift;
+
+ if(fg[order_type::R] > base_mask) fg[order_type::R] = base_mask;
+ if(fg[order_type::G] > base_mask) fg[order_type::G] = base_mask;
+ if(fg[order_type::B] > base_mask) fg[order_type::B] = base_mask;
span->r = (value_type)fg[order_type::R];
span->g = (value_type)fg[order_type::G];
span->b = (value_type)fg[order_type::B];
- span->a = (value_type)src_alpha;
+ span->a = base_mask;
+
++span;
++base_type::interpolator();
} while(--len);
-
- return base_type::allocator().span();
}
};
-
-
-
-
- //=================================================span_image_filter_rgb
- template<class ColorT,
- class Order,
- class Interpolator,
- class Allocator = span_allocator<ColorT> >
+ //===================================================span_image_filter_rgb
+ template<class Source, class Interpolator>
class span_image_filter_rgb :
- public span_image_filter<ColorT, Interpolator, Allocator>
+ public span_image_filter<Source, Interpolator>
{
public:
- typedef ColorT color_type;
- typedef Order order_type;
+ typedef Source source_type;
+ typedef typename source_type::color_type color_type;
+ typedef typename source_type::order_type order_type;
typedef Interpolator interpolator_type;
- typedef Allocator alloc_type;
- typedef span_image_filter<color_type, interpolator_type, alloc_type> base_type;
+ typedef span_image_filter<source_type, interpolator_type> base_type;
typedef typename color_type::value_type value_type;
typedef typename color_type::calc_type calc_type;
- enum
+ enum base_scale_e
{
base_shift = color_type::base_shift,
base_mask = color_type::base_mask
};
//--------------------------------------------------------------------
- span_image_filter_rgb(alloc_type& alloc) : base_type(alloc) {}
-
- //--------------------------------------------------------------------
- span_image_filter_rgb(alloc_type& alloc,
- const rendering_buffer& src,
- const color_type& back_color,
- interpolator_type& inter,
- const image_filter_lut& filter) :
- base_type(alloc, src, back_color, inter, &filter)
+ span_image_filter_rgb() {}
+ span_image_filter_rgb(source_type& src,
+ interpolator_type& inter,
+ const image_filter_lut& filter) :
+ base_type(src, inter, &filter)
{}
//--------------------------------------------------------------------
- color_type* generate(int x, int y, unsigned len)
+ void generate(color_type* span, int x, int y, unsigned len)
{
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
y + base_type::filter_dy_dbl(), len);
int fg[3];
- int src_alpha;
- value_type back_r = base_type::background_color().r;
- value_type back_g = base_type::background_color().g;
- value_type back_b = base_type::background_color().b;
- value_type back_a = base_type::background_color().a;
-
- const value_type* fg_ptr;
+ const value_type *fg_ptr;
- unsigned diameter = base_type::filter().diameter();
- int start = base_type::filter().start();
- int start1 = start - 1;
+ unsigned diameter = base_type::filter().diameter();
+ int start = base_type::filter().start();
const int16* weight_array = base_type::filter().weight_array();
- unsigned step_back = diameter * 3;
- color_type* span = base_type::allocator().span();
-
- int maxx = base_type::source_image().width() + start - 2;
- int maxy = base_type::source_image().height() + start - 2;
-
- int maxx2 = base_type::source_image().width() - start - 1;
- int maxy2 = base_type::source_image().height() - start - 1;
-
int x_count;
int weight_y;
@@ -693,144 +584,305 @@ namespace agg
int x_lr = x_hr >> image_subpixel_shift;
int y_lr = y_hr >> image_subpixel_shift;
- fg[0] = fg[1] = fg[2] = image_filter_size / 2;
+ fg[0] = fg[1] = fg[2] = image_filter_scale / 2;
int x_fract = x_hr & image_subpixel_mask;
unsigned y_count = diameter;
- if(x_lr >= -start && y_lr >= -start &&
- x_lr <= maxx && y_lr <= maxy)
+ y_hr = image_subpixel_mask - (y_hr & image_subpixel_mask);
+ fg_ptr = (const value_type*)base_type::source().span(x_lr + start,
+ y_lr + start,
+ diameter);
+ for(;;)
{
- y_hr = image_subpixel_mask - (y_hr & image_subpixel_mask);
- fg_ptr = (const value_type*)base_type::source_image().row(y_lr + start) + (x_lr + start) * 3;
- do
+ x_count = diameter;
+ weight_y = weight_array[y_hr];
+ x_hr = image_subpixel_mask - x_fract;
+ for(;;)
{
- x_count = diameter;
- weight_y = weight_array[y_hr];
- x_hr = image_subpixel_mask - x_fract;
+ int weight = (weight_y * weight_array[x_hr] +
+ image_filter_scale / 2) >>
+ image_filter_shift;
- do
- {
- int weight = (weight_y * weight_array[x_hr] +
- image_filter_size / 2) >>
- image_filter_shift;
+ fg[0] += weight * *fg_ptr++;
+ fg[1] += weight * *fg_ptr++;
+ fg[2] += weight * *fg_ptr;
- fg[0] += *fg_ptr++ * weight;
- fg[1] += *fg_ptr++ * weight;
- fg[2] += *fg_ptr++ * weight;
+ if(--x_count == 0) break;
+ x_hr += image_subpixel_scale;
+ fg_ptr = (const value_type*)base_type::source().next_x();
+ }
- x_hr += image_subpixel_size;
+ if(--y_count == 0) break;
+ y_hr += image_subpixel_scale;
+ fg_ptr = (const value_type*)base_type::source().next_y();
+ }
- } while(--x_count);
+ fg[0] >>= image_filter_shift;
+ fg[1] >>= image_filter_shift;
+ fg[2] >>= image_filter_shift;
- y_hr += image_subpixel_size;
- fg_ptr = (const value_type*)base_type::source_image().next_row(fg_ptr - step_back);
+ if(fg[0] < 0) fg[0] = 0;
+ if(fg[1] < 0) fg[1] = 0;
+ if(fg[2] < 0) fg[2] = 0;
- } while(--y_count);
+ if(fg[order_type::R] > base_mask) fg[order_type::R] = base_mask;
+ if(fg[order_type::G] > base_mask) fg[order_type::G] = base_mask;
+ if(fg[order_type::B] > base_mask) fg[order_type::B] = base_mask;
- fg[0] >>= image_filter_shift;
- fg[1] >>= image_filter_shift;
- fg[2] >>= image_filter_shift;
+ span->r = (value_type)fg[order_type::R];
+ span->g = (value_type)fg[order_type::G];
+ span->b = (value_type)fg[order_type::B];
+ span->a = base_mask;
- if(fg[0] < 0) fg[0] = 0;
- if(fg[1] < 0) fg[1] = 0;
- if(fg[2] < 0) fg[2] = 0;
+ ++span;
+ ++base_type::interpolator();
- if(fg[0] > base_mask) fg[0] = base_mask;
- if(fg[1] > base_mask) fg[1] = base_mask;
- if(fg[2] > base_mask) fg[2] = base_mask;
- src_alpha = base_mask;
- }
- else
+ } while(--len);
+ }
+ };
+
+
+
+ //==========================================span_image_resample_rgb_affine
+ template<class Source>
+ class span_image_resample_rgb_affine :
+ public span_image_resample_affine<Source>
+ {
+ public:
+ typedef Source source_type;
+ typedef typename source_type::color_type color_type;
+ typedef typename source_type::order_type order_type;
+ typedef span_image_resample_affine<source_type> base_type;
+ typedef typename base_type::interpolator_type interpolator_type;
+ typedef typename color_type::value_type value_type;
+ typedef typename color_type::long_type long_type;
+ enum base_scale_e
+ {
+ base_shift = color_type::base_shift,
+ base_mask = color_type::base_mask,
+ downscale_shift = image_filter_shift
+ };
+
+ //--------------------------------------------------------------------
+ span_image_resample_rgb_affine() {}
+ span_image_resample_rgb_affine(source_type& src,
+ interpolator_type& inter,
+ const image_filter_lut& filter) :
+ base_type(src, inter, filter)
+ {}
+
+
+ //--------------------------------------------------------------------
+ void generate(color_type* span, int x, int y, unsigned len)
+ {
+ base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
+ y + base_type::filter_dy_dbl(), len);
+
+ long_type fg[3];
+
+ int diameter = base_type::filter().diameter();
+ int filter_scale = diameter << image_subpixel_shift;
+ int radius_x = (diameter * base_type::m_rx) >> 1;
+ int radius_y = (diameter * base_type::m_ry) >> 1;
+ int len_x_lr =
+ (diameter * base_type::m_rx + image_subpixel_mask) >>
+ image_subpixel_shift;
+
+ const int16* weight_array = base_type::filter().weight_array();
+
+ do
+ {
+ base_type::interpolator().coordinates(&x, &y);
+
+ x += base_type::filter_dx_int() - radius_x;
+ y += base_type::filter_dy_int() - radius_y;
+
+ fg[0] = fg[1] = fg[2] = image_filter_scale / 2;
+
+ int y_lr = y >> image_subpixel_shift;
+ int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) *
+ base_type::m_ry_inv) >>
+ image_subpixel_shift;
+ int total_weight = 0;
+ int x_lr = x >> image_subpixel_shift;
+ int x_hr = ((image_subpixel_mask - (x & image_subpixel_mask)) *
+ base_type::m_rx_inv) >>
+ image_subpixel_shift;
+
+ int x_hr2 = x_hr;
+ const value_type* fg_ptr =
+ (const value_type*)base_type::source().span(x_lr, y_lr, len_x_lr);
+ for(;;)
{
- if(x_lr < start1 || y_lr < start1 ||
- x_lr > maxx2 || y_lr > maxy2)
+ int weight_y = weight_array[y_hr];
+ x_hr = x_hr2;
+ for(;;)
{
- fg[order_type::R] = back_r;
- fg[order_type::G] = back_g;
- fg[order_type::B] = back_b;
- src_alpha = back_a;
+ int weight = (weight_y * weight_array[x_hr] +
+ image_filter_scale / 2) >>
+ downscale_shift;
+
+ fg[0] += *fg_ptr++ * weight;
+ fg[1] += *fg_ptr++ * weight;
+ fg[2] += *fg_ptr * weight;
+ total_weight += weight;
+ x_hr += base_type::m_rx_inv;
+ if(x_hr >= filter_scale) break;
+ fg_ptr = (const value_type*)base_type::source().next_x();
}
- else
- {
- src_alpha = image_filter_size / 2;
- y_lr = (y >> image_subpixel_shift) + start;
- y_hr = image_subpixel_mask - (y_hr & image_subpixel_mask);
+ y_hr += base_type::m_ry_inv;
+ if(y_hr >= filter_scale) break;
+ fg_ptr = (const value_type*)base_type::source().next_y();
+ }
- do
- {
- x_count = diameter;
- weight_y = weight_array[y_hr];
- x_lr = (x >> image_subpixel_shift) + start;
- x_hr = image_subpixel_mask - x_fract;
-
- do
- {
- int weight = (weight_y * weight_array[x_hr] +
- image_filter_size / 2) >>
- image_filter_shift;
-
- if(x_lr >= 0 && y_lr >= 0 &&
- x_lr < int(base_type::source_image().width()) &&
- y_lr < int(base_type::source_image().height()))
- {
- fg_ptr = (const value_type*)base_type::source_image().row(y_lr) + x_lr * 3;
- fg[0] += *fg_ptr++ * weight;
- fg[1] += *fg_ptr++ * weight;
- fg[2] += *fg_ptr++ * weight;
- src_alpha += base_mask * weight;
- }
- else
- {
- fg[order_type::R] += back_r * weight;
- fg[order_type::G] += back_g * weight;
- fg[order_type::B] += back_b * weight;
- src_alpha += back_a * weight;
- }
- x_hr += image_subpixel_size;
- x_lr++;
-
- } while(--x_count);
-
- y_hr += image_subpixel_size;
- y_lr++;
-
- } while(--y_count);
-
-
- fg[0] >>= image_filter_shift;
- fg[1] >>= image_filter_shift;
- fg[2] >>= image_filter_shift;
- src_alpha >>= image_filter_shift;
-
- if(fg[0] < 0) fg[0] = 0;
- if(fg[1] < 0) fg[1] = 0;
- if(fg[2] < 0) fg[2] = 0;
- if(src_alpha < 0) src_alpha = 0;
-
- if(src_alpha > base_mask) src_alpha = base_mask;
- 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;
+ fg[0] /= total_weight;
+ fg[1] /= total_weight;
+ fg[2] /= total_weight;
+
+ if(fg[0] < 0) fg[0] = 0;
+ if(fg[1] < 0) fg[1] = 0;
+ if(fg[2] < 0) fg[2] = 0;
+
+ if(fg[order_type::R] > base_mask) fg[order_type::R] = base_mask;
+ if(fg[order_type::G] > base_mask) fg[order_type::G] = base_mask;
+ if(fg[order_type::B] > base_mask) fg[order_type::B] = base_mask;
+
+ span->r = (value_type)fg[order_type::R];
+ span->g = (value_type)fg[order_type::G];
+ span->b = (value_type)fg[order_type::B];
+ span->a = base_mask;
+
+ ++span;
+ ++base_type::interpolator();
+ } while(--len);
+ }
+ };
+
+
+
+ //=================================================span_image_resample_rgb
+ template<class Source, class Interpolator>
+ class span_image_resample_rgb :
+ public span_image_resample<Source, Interpolator>
+ {
+ public:
+ typedef Source source_type;
+ typedef typename source_type::color_type color_type;
+ typedef typename source_type::order_type order_type;
+ typedef Interpolator interpolator_type;
+ typedef span_image_resample<source_type, interpolator_type> base_type;
+ typedef typename color_type::value_type value_type;
+ typedef typename color_type::long_type long_type;
+ enum base_scale_e
+ {
+ base_shift = color_type::base_shift,
+ base_mask = color_type::base_mask,
+ downscale_shift = image_filter_shift
+ };
+
+ //--------------------------------------------------------------------
+ span_image_resample_rgb() {}
+ span_image_resample_rgb(source_type& src,
+ interpolator_type& inter,
+ const image_filter_lut& filter) :
+ base_type(src, inter, filter)
+ {}
+
+ //--------------------------------------------------------------------
+ void generate(color_type* span, int x, int y, unsigned len)
+ {
+ base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
+ y + base_type::filter_dy_dbl(), len);
+ long_type fg[3];
+
+ int diameter = base_type::filter().diameter();
+ int filter_scale = diameter << image_subpixel_shift;
+
+ const int16* weight_array = base_type::filter().weight_array();
+ do
+ {
+ int rx;
+ int ry;
+ int rx_inv = image_subpixel_scale;
+ int ry_inv = image_subpixel_scale;
+ base_type::interpolator().coordinates(&x, &y);
+ base_type::interpolator().local_scale(&rx, &ry);
+ base_type::adjust_scale(&rx, &ry);
+
+ rx_inv = image_subpixel_scale * image_subpixel_scale / rx;
+ ry_inv = image_subpixel_scale * image_subpixel_scale / ry;
+
+ int radius_x = (diameter * rx) >> 1;
+ int radius_y = (diameter * ry) >> 1;
+ int len_x_lr =
+ (diameter * rx + image_subpixel_mask) >>
+ image_subpixel_shift;
+
+ x += base_type::filter_dx_int() - radius_x;
+ y += base_type::filter_dy_int() - radius_y;
+
+ fg[0] = fg[1] = fg[2] = image_filter_scale / 2;
+
+ int y_lr = y >> image_subpixel_shift;
+ int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) *
+ ry_inv) >>
+ image_subpixel_shift;
+ int total_weight = 0;
+ int x_lr = x >> image_subpixel_shift;
+ int x_hr = ((image_subpixel_mask - (x & image_subpixel_mask)) *
+ rx_inv) >>
+ image_subpixel_shift;
+ int x_hr2 = x_hr;
+ const value_type* fg_ptr =
+ (const value_type*)base_type::source().span(x_lr, y_lr, len_x_lr);
+
+ for(;;)
+ {
+ int weight_y = weight_array[y_hr];
+ x_hr = x_hr2;
+ for(;;)
+ {
+ int weight = (weight_y * weight_array[x_hr] +
+ image_filter_scale / 2) >>
+ downscale_shift;
+ fg[0] += *fg_ptr++ * weight;
+ fg[1] += *fg_ptr++ * weight;
+ fg[2] += *fg_ptr * weight;
+ total_weight += weight;
+ x_hr += rx_inv;
+ if(x_hr >= filter_scale) break;
+ fg_ptr = (const value_type*)base_type::source().next_x();
}
+ y_hr += ry_inv;
+ if(y_hr >= filter_scale) break;
+ fg_ptr = (const value_type*)base_type::source().next_y();
}
+ fg[0] /= total_weight;
+ fg[1] /= total_weight;
+ fg[2] /= total_weight;
+
+ if(fg[0] < 0) fg[0] = 0;
+ if(fg[1] < 0) fg[1] = 0;
+ if(fg[2] < 0) fg[2] = 0;
+
+ if(fg[order_type::R] > base_mask) fg[order_type::R] = base_mask;
+ if(fg[order_type::G] > base_mask) fg[order_type::G] = base_mask;
+ if(fg[order_type::B] > base_mask) fg[order_type::B] = base_mask;
+
span->r = (value_type)fg[order_type::R];
span->g = (value_type)fg[order_type::G];
span->b = (value_type)fg[order_type::B];
- span->a = (value_type)src_alpha;
+ span->a = base_mask;
++span;
++base_type::interpolator();
-
} while(--len);
-
- return base_type::allocator().span();
}
};
-
}
diff --git a/agg/inc/agg_span_image_filter_rgba.h b/agg/inc/agg_span_image_filter_rgba.h
index 42b822c99b9b..60d91e47236d 100755
--- a/agg/inc/agg_span_image_filter_rgba.h
+++ b/agg/inc/agg_span_image_filter_rgba.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -20,10 +20,6 @@
// PostScript and PDF technology for software developers.
//
//----------------------------------------------------------------------------
-//
-// classes span_image_filter_rgba32*
-//
-//----------------------------------------------------------------------------
#ifndef AGG_SPAN_IMAGE_FILTER_RGBA_INCLUDED
#define AGG_SPAN_IMAGE_FILTER_RGBA_INCLUDED
@@ -35,149 +31,204 @@
namespace agg
{
- //=============================================span_image_filter_rgba_nn
- template<class ColorT,
- class Order,
- class Interpolator,
- class Allocator = span_allocator<ColorT> >
+ //==============================================span_image_filter_rgba_nn
+ template<class Source, class Interpolator>
class span_image_filter_rgba_nn :
- public span_image_filter<ColorT, Interpolator, Allocator>
+ public span_image_filter<Source, Interpolator>
{
public:
- typedef ColorT color_type;
- typedef Order order_type;
+ typedef Source source_type;
+ typedef typename source_type::color_type color_type;
+ typedef typename source_type::order_type order_type;
typedef Interpolator interpolator_type;
- typedef Allocator alloc_type;
- typedef span_image_filter<color_type, interpolator_type, alloc_type> base_type;
+ typedef span_image_filter<source_type, interpolator_type> base_type;
typedef typename color_type::value_type value_type;
typedef typename color_type::calc_type calc_type;
- enum
+ enum base_scale_e
{
base_shift = color_type::base_shift,
base_mask = color_type::base_mask
};
//--------------------------------------------------------------------
- span_image_filter_rgba_nn(alloc_type& alloc) : base_type(alloc) {}
+ span_image_filter_rgba_nn() {}
+ span_image_filter_rgba_nn(source_type& src,
+ interpolator_type& inter) :
+ base_type(src, inter, 0)
+ {}
//--------------------------------------------------------------------
- span_image_filter_rgba_nn(alloc_type& alloc,
- const rendering_buffer& src,
- const color_type& back_color,
- interpolator_type& inter) :
- base_type(alloc, src, back_color, inter, 0)
+ void generate(color_type* span, int x, int y, unsigned len)
+ {
+ base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
+ y + base_type::filter_dy_dbl(), len);
+ do
+ {
+ base_type::interpolator().coordinates(&x, &y);
+ const value_type* fg_ptr = (const value_type*)
+ base_type::source().span(x >> image_subpixel_shift,
+ y >> image_subpixel_shift,
+ 1);
+ span->r = fg_ptr[order_type::R];
+ span->g = fg_ptr[order_type::G];
+ span->b = fg_ptr[order_type::B];
+ span->a = fg_ptr[order_type::A];
+ ++span;
+ ++base_type::interpolator();
+
+ } while(--len);
+ }
+ };
+
+
+
+ //=========================================span_image_filter_rgba_bilinear
+ template<class Source, class Interpolator>
+ class span_image_filter_rgba_bilinear :
+ public span_image_filter<Source, Interpolator>
+ {
+ public:
+ typedef Source source_type;
+ typedef typename source_type::color_type color_type;
+ typedef typename source_type::order_type order_type;
+ typedef Interpolator interpolator_type;
+ typedef span_image_filter<source_type, interpolator_type> base_type;
+ typedef typename color_type::value_type value_type;
+ typedef typename color_type::calc_type calc_type;
+ enum base_scale_e
+ {
+ base_shift = color_type::base_shift,
+ base_mask = color_type::base_mask
+ };
+
+ //--------------------------------------------------------------------
+ span_image_filter_rgba_bilinear() {}
+ span_image_filter_rgba_bilinear(source_type& src,
+ interpolator_type& inter) :
+ base_type(src, inter, 0)
{}
+
//--------------------------------------------------------------------
- color_type* generate(int x, int y, unsigned len)
+ void generate(color_type* span, int x, int y, unsigned len)
{
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
y + base_type::filter_dy_dbl(), len);
calc_type fg[4];
-
const value_type *fg_ptr;
- color_type* span = base_type::allocator().span();
-
- int maxx = base_type::source_image().width() - 1;
- int maxy = base_type::source_image().height() - 1;
do
{
- base_type::interpolator().coordinates(&x, &y);
+ int x_hr;
+ int y_hr;
- x >>= image_subpixel_shift;
- y >>= image_subpixel_shift;
+ base_type::interpolator().coordinates(&x_hr, &y_hr);
- if(x >= 0 && y >= 0 &&
- x <= maxx && y <= maxy)
- {
- fg_ptr = (const value_type*)base_type::source_image().row(y) + (x << 2);
- fg[0] = *fg_ptr++;
- fg[1] = *fg_ptr++;
- fg[2] = *fg_ptr++;
- fg[3] = *fg_ptr++;
- }
- else
- {
- fg[order_type::R] = base_type::background_color().r;
- fg[order_type::G] = base_type::background_color().g;
- fg[order_type::B] = base_type::background_color().b;
- fg[order_type::A] = base_type::background_color().a;
- }
+ 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;
+
+ unsigned weight;
+
+ fg[0] =
+ fg[1] =
+ fg[2] =
+ fg[3] = image_subpixel_scale * image_subpixel_scale / 2;
+
+ x_hr &= image_subpixel_mask;
+ y_hr &= image_subpixel_mask;
+
+ fg_ptr = (const value_type*)base_type::source().span(x_lr, y_lr, 2);
+ weight = (image_subpixel_scale - x_hr) *
+ (image_subpixel_scale - y_hr);
+ fg[0] += weight * *fg_ptr++;
+ fg[1] += weight * *fg_ptr++;
+ fg[2] += weight * *fg_ptr++;
+ fg[3] += weight * *fg_ptr;
+
+ fg_ptr = (const value_type*)base_type::source().next_x();
+ weight = x_hr * (image_subpixel_scale - y_hr);
+ fg[0] += weight * *fg_ptr++;
+ fg[1] += weight * *fg_ptr++;
+ fg[2] += weight * *fg_ptr++;
+ fg[3] += weight * *fg_ptr;
+
+ fg_ptr = (const value_type*)base_type::source().next_y();
+ weight = (image_subpixel_scale - x_hr) * y_hr;
+ fg[0] += weight * *fg_ptr++;
+ fg[1] += weight * *fg_ptr++;
+ fg[2] += weight * *fg_ptr++;
+ fg[3] += weight * *fg_ptr;
+
+ fg_ptr = (const value_type*)base_type::source().next_x();
+ weight = x_hr * y_hr;
+ fg[0] += weight * *fg_ptr++;
+ fg[1] += weight * *fg_ptr++;
+ fg[2] += weight * *fg_ptr++;
+ fg[3] += weight * *fg_ptr;
+
+ span->r = value_type(fg[order_type::R] >> (image_subpixel_shift * 2));
+ span->g = value_type(fg[order_type::G] >> (image_subpixel_shift * 2));
+ span->b = value_type(fg[order_type::B] >> (image_subpixel_shift * 2));
+ span->a = value_type(fg[order_type::A] >> (image_subpixel_shift * 2));
- span->r = fg[order_type::R];
- span->g = fg[order_type::G];
- span->b = fg[order_type::B];
- span->a = fg[order_type::A];
++span;
++base_type::interpolator();
} while(--len);
-
- return base_type::allocator().span();
}
-
};
-
-
-
-
-
- //=======================================span_image_filter_rgba_bilinear
- template<class ColorT,
- class Order,
- class Interpolator,
- class Allocator = span_allocator<ColorT> >
- class span_image_filter_rgba_bilinear :
- public span_image_filter<ColorT, Interpolator, Allocator>
+ //====================================span_image_filter_rgba_bilinear_clip
+ template<class Source, class Interpolator>
+ class span_image_filter_rgba_bilinear_clip :
+ public span_image_filter<Source, Interpolator>
{
public:
- typedef ColorT color_type;
- typedef Order order_type;
+ typedef Source source_type;
+ typedef typename source_type::color_type color_type;
+ typedef typename source_type::order_type order_type;
typedef Interpolator interpolator_type;
- typedef Allocator alloc_type;
- typedef span_image_filter<color_type, interpolator_type, alloc_type> base_type;
+ typedef span_image_filter<source_type, interpolator_type> base_type;
typedef typename color_type::value_type value_type;
typedef typename color_type::calc_type calc_type;
- enum
+ enum base_scale_e
{
base_shift = color_type::base_shift,
base_mask = color_type::base_mask
};
//--------------------------------------------------------------------
- span_image_filter_rgba_bilinear(alloc_type& alloc) : base_type(alloc) {}
-
- //--------------------------------------------------------------------
- span_image_filter_rgba_bilinear(alloc_type& alloc,
- const rendering_buffer& src,
- const color_type& back_color,
- interpolator_type& inter) :
- base_type(alloc, src, back_color, inter, 0)
+ span_image_filter_rgba_bilinear_clip() {}
+ span_image_filter_rgba_bilinear_clip(source_type& src,
+ const color_type& back_color,
+ interpolator_type& inter) :
+ base_type(src, inter, 0),
+ m_back_color(back_color)
{}
+ const color_type& background_color() const { return m_back_color; }
+ void background_color(const color_type& v) { m_back_color = v; }
//--------------------------------------------------------------------
- color_type* generate(int x, int y, unsigned len)
+ void generate(color_type* span, int x, int y, unsigned len)
{
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
y + base_type::filter_dy_dbl(), len);
calc_type fg[4];
- value_type back_r = base_type::background_color().r;
- value_type back_g = base_type::background_color().g;
- value_type back_b = base_type::background_color().b;
- value_type back_a = base_type::background_color().a;
+ value_type back_r = m_back_color.r;
+ value_type back_g = m_back_color.g;
+ value_type back_b = m_back_color.b;
+ value_type back_a = m_back_color.a;
const value_type *fg_ptr;
-
- color_type* span = base_type::allocator().span();
-
- int maxx = base_type::source_image().width() - 1;
- int maxy = base_type::source_image().height() - 1;
+ int maxx = base_type::source().width() - 1;
+ int maxy = base_type::source().height() - 1;
do
{
@@ -200,29 +251,32 @@ namespace agg
fg[0] =
fg[1] =
fg[2] =
- fg[3] = image_subpixel_size * image_subpixel_size / 2;
+ fg[3] = image_subpixel_scale * image_subpixel_scale / 2;
x_hr &= image_subpixel_mask;
y_hr &= image_subpixel_mask;
- fg_ptr = (const value_type*)base_type::source_image().row(y_lr) + (x_lr << 2);
+ fg_ptr = (const value_type*)
+ base_type::source().row_ptr(y_lr) + (x_lr << 2);
- weight = (image_subpixel_size - x_hr) *
- (image_subpixel_size - y_hr);
+ weight = (image_subpixel_scale - x_hr) *
+ (image_subpixel_scale - y_hr);
fg[0] += weight * *fg_ptr++;
fg[1] += weight * *fg_ptr++;
fg[2] += weight * *fg_ptr++;
fg[3] += weight * *fg_ptr++;
- weight = x_hr * (image_subpixel_size - y_hr);
+ weight = x_hr * (image_subpixel_scale - y_hr);
fg[0] += weight * *fg_ptr++;
fg[1] += weight * *fg_ptr++;
fg[2] += weight * *fg_ptr++;
fg[3] += weight * *fg_ptr++;
- fg_ptr = (const value_type*)base_type::source_image().next_row(fg_ptr - 8);
+ ++y_lr;
+ fg_ptr = (const value_type*)
+ base_type::source().row_ptr(y_lr) + (x_lr << 2);
- weight = (image_subpixel_size - x_hr) * y_hr;
+ weight = (image_subpixel_scale - x_hr) * y_hr;
fg[0] += weight * *fg_ptr++;
fg[1] += weight * *fg_ptr++;
fg[2] += weight * *fg_ptr++;
@@ -254,17 +308,19 @@ namespace agg
fg[0] =
fg[1] =
fg[2] =
- fg[3] = image_subpixel_size * image_subpixel_size / 2;
+ fg[3] = image_subpixel_scale * image_subpixel_scale / 2;
x_hr &= image_subpixel_mask;
y_hr &= image_subpixel_mask;
- weight = (image_subpixel_size - x_hr) *
- (image_subpixel_size - y_hr);
+ weight = (image_subpixel_scale - x_hr) *
+ (image_subpixel_scale - y_hr);
if(x_lr >= 0 && y_lr >= 0 &&
x_lr <= maxx && y_lr <= maxy)
{
- fg_ptr = (const value_type*)base_type::source_image().row(y_lr) + (x_lr << 2);
+ fg_ptr = (const value_type*)
+ base_type::source().row_ptr(y_lr) + (x_lr << 2);
+
fg[0] += weight * *fg_ptr++;
fg[1] += weight * *fg_ptr++;
fg[2] += weight * *fg_ptr++;
@@ -280,11 +336,13 @@ namespace agg
x_lr++;
- weight = x_hr * (image_subpixel_size - y_hr);
+ weight = x_hr * (image_subpixel_scale - y_hr);
if(x_lr >= 0 && y_lr >= 0 &&
x_lr <= maxx && y_lr <= maxy)
{
- fg_ptr = (const value_type*)base_type::source_image().row(y_lr) + (x_lr << 2);
+ fg_ptr = (const value_type*)
+ base_type::source().row_ptr(y_lr) + (x_lr << 2);
+
fg[0] += weight * *fg_ptr++;
fg[1] += weight * *fg_ptr++;
fg[2] += weight * *fg_ptr++;
@@ -301,11 +359,13 @@ namespace agg
x_lr--;
y_lr++;
- weight = (image_subpixel_size - x_hr) * y_hr;
+ weight = (image_subpixel_scale - x_hr) * y_hr;
if(x_lr >= 0 && y_lr >= 0 &&
x_lr <= maxx && y_lr <= maxy)
{
- fg_ptr = (const value_type*)base_type::source_image().row(y_lr) + (x_lr << 2);
+ fg_ptr = (const value_type*)
+ base_type::source().row_ptr(y_lr) + (x_lr << 2);
+
fg[0] += weight * *fg_ptr++;
fg[1] += weight * *fg_ptr++;
fg[2] += weight * *fg_ptr++;
@@ -325,7 +385,9 @@ namespace agg
if(x_lr >= 0 && y_lr >= 0 &&
x_lr <= maxx && y_lr <= maxy)
{
- fg_ptr = (const value_type*)base_type::source_image().row(y_lr) + (x_lr << 2);
+ fg_ptr = (const value_type*)
+ base_type::source().row_ptr(y_lr) + (x_lr << 2);
+
fg[0] += weight * *fg_ptr++;
fg[1] += weight * *fg_ptr++;
fg[2] += weight * *fg_ptr++;
@@ -354,74 +416,53 @@ namespace agg
++base_type::interpolator();
} while(--len);
-
- return base_type::allocator().span();
}
+ private:
+ color_type m_back_color;
};
-
-
-
-
-
- //=======================================span_image_filter_rgba_2x2
- template<class ColorT,
- class Order,
- class Interpolator,
- class Allocator = span_allocator<ColorT> >
+ //==============================================span_image_filter_rgba_2x2
+ template<class Source, class Interpolator>
class span_image_filter_rgba_2x2 :
- public span_image_filter<ColorT, Interpolator, Allocator>
+ public span_image_filter<Source, Interpolator>
{
public:
- typedef ColorT color_type;
- typedef Order order_type;
+ typedef Source source_type;
+ typedef typename source_type::color_type color_type;
+ typedef typename source_type::order_type order_type;
typedef Interpolator interpolator_type;
- typedef Allocator alloc_type;
- typedef span_image_filter<color_type, interpolator_type, alloc_type> base_type;
+ typedef span_image_filter<source_type, interpolator_type> base_type;
typedef typename color_type::value_type value_type;
typedef typename color_type::calc_type calc_type;
- enum
+ enum base_scale_e
{
base_shift = color_type::base_shift,
base_mask = color_type::base_mask
};
//--------------------------------------------------------------------
- span_image_filter_rgba_2x2(alloc_type& alloc) : base_type(alloc) {}
-
- //--------------------------------------------------------------------
- span_image_filter_rgba_2x2(alloc_type& alloc,
- const rendering_buffer& src,
- const color_type& back_color,
+ span_image_filter_rgba_2x2() {}
+ span_image_filter_rgba_2x2(source_type& src,
interpolator_type& inter,
const image_filter_lut& filter) :
- base_type(alloc, src, back_color, inter, &filter)
+ base_type(src, inter, &filter)
{}
//--------------------------------------------------------------------
- color_type* generate(int x, int y, unsigned len)
+ void generate(color_type* span, int x, int y, unsigned len)
{
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
y + base_type::filter_dy_dbl(), len);
calc_type fg[4];
- value_type back_r = base_type::background_color().r;
- value_type back_g = base_type::background_color().g;
- value_type back_b = base_type::background_color().b;
- value_type back_a = base_type::background_color().a;
const value_type *fg_ptr;
-
- color_type* span = base_type::allocator().span();
const int16* weight_array = base_type::filter().weight_array() +
((base_type::filter().diameter()/2 - 1) <<
image_subpixel_shift);
- int maxx = base_type::source_image().width() - 1;
- int maxy = base_type::source_image().height() - 1;
-
do
{
int x_hr;
@@ -436,181 +477,60 @@ namespace agg
int y_lr = y_hr >> image_subpixel_shift;
unsigned weight;
- fg[0] = fg[1] = fg[2] = fg[3] = image_filter_size / 2;
-
- if(x_lr >= 0 && y_lr >= 0 &&
- x_lr < maxx && y_lr < maxy)
- {
- x_hr &= image_subpixel_mask;
- y_hr &= image_subpixel_mask;
-
- fg_ptr = (const value_type*)base_type::source_image().row(y_lr) + (x_lr << 2);
-
- weight = (weight_array[x_hr + image_subpixel_size] *
- weight_array[y_hr + image_subpixel_size] +
- image_filter_size / 2) >>
- image_filter_shift;
- fg[0] += weight * *fg_ptr++;
- fg[1] += weight * *fg_ptr++;
- fg[2] += weight * *fg_ptr++;
- fg[3] += weight * *fg_ptr++;
-
- weight = (weight_array[x_hr] *
- weight_array[y_hr + image_subpixel_size] +
- image_filter_size / 2) >>
- image_filter_shift;
- fg[0] += weight * *fg_ptr++;
- fg[1] += weight * *fg_ptr++;
- fg[2] += weight * *fg_ptr++;
- fg[3] += weight * *fg_ptr++;
-
- fg_ptr = (const value_type*)base_type::source_image().next_row(fg_ptr - 8);
-
- weight = (weight_array[x_hr + image_subpixel_size] *
- weight_array[y_hr] +
- image_filter_size / 2) >>
- image_filter_shift;
- fg[0] += weight * *fg_ptr++;
- fg[1] += weight * *fg_ptr++;
- fg[2] += weight * *fg_ptr++;
- fg[3] += weight * *fg_ptr++;
-
- weight = (weight_array[x_hr] *
- weight_array[y_hr] +
- image_filter_size / 2) >>
- image_filter_shift;
- fg[0] += weight * *fg_ptr++;
- fg[1] += weight * *fg_ptr++;
- fg[2] += weight * *fg_ptr++;
- fg[3] += weight * *fg_ptr++;
-
- fg[0] >>= image_filter_shift;
- fg[1] >>= image_filter_shift;
- fg[2] >>= image_filter_shift;
- fg[3] >>= image_filter_shift;
-
- if(fg[order_type::A] > base_mask) fg[order_type::A] = base_mask;
- if(fg[order_type::R] > fg[order_type::A]) fg[order_type::R] = fg[order_type::A];
- if(fg[order_type::G] > fg[order_type::A]) fg[order_type::G] = fg[order_type::A];
- if(fg[order_type::B] > fg[order_type::A]) fg[order_type::B] = fg[order_type::A];
- }
- else
- {
- if(x_lr < -1 || y_lr < -1 ||
- x_lr > maxx || y_lr > maxy)
- {
- fg[order_type::R] = back_r;
- fg[order_type::G] = back_g;
- fg[order_type::B] = back_b;
- fg[order_type::A] = back_a;
- }
- else
- {
- x_hr &= image_subpixel_mask;
- y_hr &= image_subpixel_mask;
-
- weight = (weight_array[x_hr + image_subpixel_size] *
- weight_array[y_hr + image_subpixel_size] +
- image_filter_size / 2) >>
- image_filter_shift;
- if(x_lr >= 0 && y_lr >= 0 &&
- x_lr <= maxx && y_lr <= maxy)
- {
- fg_ptr = (const value_type*)base_type::source_image().row(y_lr) + (x_lr << 2);
- fg[0] += weight * *fg_ptr++;
- fg[1] += weight * *fg_ptr++;
- fg[2] += weight * *fg_ptr++;
- fg[3] += weight * *fg_ptr++;
- }
- else
- {
- fg[order_type::R] += back_r * weight;
- fg[order_type::G] += back_g * weight;
- fg[order_type::B] += back_b * weight;
- fg[order_type::A] += back_a * weight;
- }
-
- x_lr++;
-
- weight = (weight_array[x_hr] *
- weight_array[y_hr + image_subpixel_size] +
- image_filter_size / 2) >>
- image_filter_shift;
- if(x_lr >= 0 && y_lr >= 0 &&
- x_lr <= maxx && y_lr <= maxy)
- {
- fg_ptr = (const value_type*)base_type::source_image().row(y_lr) + (x_lr << 2);
- fg[0] += weight * *fg_ptr++;
- fg[1] += weight * *fg_ptr++;
- fg[2] += weight * *fg_ptr++;
- fg[3] += weight * *fg_ptr++;
- }
- else
- {
- fg[order_type::R] += back_r * weight;
- fg[order_type::G] += back_g * weight;
- fg[order_type::B] += back_b * weight;
- fg[order_type::A] += back_a * weight;
- }
-
- x_lr--;
- y_lr++;
-
- weight = (weight_array[x_hr + image_subpixel_size] *
- weight_array[y_hr] +
- image_filter_size / 2) >>
- image_filter_shift;
- if(x_lr >= 0 && y_lr >= 0 &&
- x_lr <= maxx && y_lr <= maxy)
- {
- fg_ptr = (const value_type*)base_type::source_image().row(y_lr) + (x_lr << 2);
- fg[0] += weight * *fg_ptr++;
- fg[1] += weight * *fg_ptr++;
- fg[2] += weight * *fg_ptr++;
- fg[3] += weight * *fg_ptr++;
- }
- else
- {
- fg[order_type::R] += back_r * weight;
- fg[order_type::G] += back_g * weight;
- fg[order_type::B] += back_b * weight;
- fg[order_type::A] += back_a * weight;
- }
-
- x_lr++;
-
- weight = (weight_array[x_hr] *
- weight_array[y_hr] +
- image_filter_size / 2) >>
- image_filter_shift;
- if(x_lr >= 0 && y_lr >= 0 &&
- x_lr <= maxx && y_lr <= maxy)
- {
- fg_ptr = (const value_type*)base_type::source_image().row(y_lr) + (x_lr << 2);
- fg[0] += weight * *fg_ptr++;
- fg[1] += weight * *fg_ptr++;
- fg[2] += weight * *fg_ptr++;
- fg[3] += weight * *fg_ptr++;
- }
- else
- {
- fg[order_type::R] += back_r * weight;
- fg[order_type::G] += back_g * weight;
- fg[order_type::B] += back_b * weight;
- fg[order_type::A] += back_a * weight;
- }
-
- fg[0] >>= image_filter_shift;
- fg[1] >>= image_filter_shift;
- fg[2] >>= image_filter_shift;
- fg[3] >>= image_filter_shift;
-
- if(fg[order_type::A] > base_mask) fg[order_type::A] = base_mask;
- if(fg[order_type::R] > fg[order_type::A]) fg[order_type::R] = fg[order_type::A];
- if(fg[order_type::G] > fg[order_type::A]) fg[order_type::G] = fg[order_type::A];
- if(fg[order_type::B] > fg[order_type::A]) fg[order_type::B] = fg[order_type::A];
- }
- }
+ fg[0] = fg[1] = fg[2] = fg[3] = image_filter_scale / 2;
+
+ x_hr &= image_subpixel_mask;
+ y_hr &= image_subpixel_mask;
+
+ fg_ptr = (const value_type*)base_type::source().span(x_lr, y_lr, 2);
+ weight = (weight_array[x_hr + image_subpixel_scale] *
+ weight_array[y_hr + image_subpixel_scale] +
+ image_filter_scale / 2) >>
+ image_filter_shift;
+ fg[0] += weight * *fg_ptr++;
+ fg[1] += weight * *fg_ptr++;
+ fg[2] += weight * *fg_ptr++;
+ fg[3] += weight * *fg_ptr;
+
+ fg_ptr = (const value_type*)base_type::source().next_x();
+ weight = (weight_array[x_hr] *
+ weight_array[y_hr + image_subpixel_scale] +
+ image_filter_scale / 2) >>
+ image_filter_shift;
+ fg[0] += weight * *fg_ptr++;
+ fg[1] += weight * *fg_ptr++;
+ fg[2] += weight * *fg_ptr++;
+ fg[3] += weight * *fg_ptr;
+
+ fg_ptr = (const value_type*)base_type::source().next_y();
+ weight = (weight_array[x_hr + image_subpixel_scale] *
+ weight_array[y_hr] +
+ image_filter_scale / 2) >>
+ image_filter_shift;
+ fg[0] += weight * *fg_ptr++;
+ fg[1] += weight * *fg_ptr++;
+ fg[2] += weight * *fg_ptr++;
+ fg[3] += weight * *fg_ptr;
+
+ fg_ptr = (const value_type*)base_type::source().next_x();
+ weight = (weight_array[x_hr] *
+ weight_array[y_hr] +
+ image_filter_scale / 2) >>
+ image_filter_shift;
+ fg[0] += weight * *fg_ptr++;
+ fg[1] += weight * *fg_ptr++;
+ fg[2] += weight * *fg_ptr++;
+ fg[3] += weight * *fg_ptr;
+
+ fg[0] >>= image_filter_shift;
+ fg[1] >>= image_filter_shift;
+ fg[2] >>= image_filter_shift;
+ fg[3] >>= image_filter_shift;
+
+ if(fg[order_type::A] > base_mask) fg[order_type::A] = base_mask;
+ if(fg[order_type::R] > fg[order_type::A]) fg[order_type::R] = fg[order_type::A];
+ if(fg[order_type::G] > fg[order_type::A]) fg[order_type::G] = fg[order_type::A];
+ if(fg[order_type::B] > fg[order_type::A]) fg[order_type::B] = fg[order_type::A];
span->r = (value_type)fg[order_type::R];
span->g = (value_type)fg[order_type::G];
@@ -620,86 +540,51 @@ namespace agg
++base_type::interpolator();
} while(--len);
-
- return base_type::allocator().span();
}
};
-
-
-
-
-
-
-
-
-
-
- //================================================span_image_filter_rgba
- template<class ColorT,
- class Order,
- class Interpolator,
- class Allocator = span_allocator<ColorT> >
+ //==================================================span_image_filter_rgba
+ template<class Source, class Interpolator>
class span_image_filter_rgba :
- public span_image_filter<ColorT, Interpolator, Allocator>
+ public span_image_filter<Source, Interpolator>
{
public:
- typedef ColorT color_type;
- typedef Order order_type;
+ typedef Source source_type;
+ typedef typename source_type::color_type color_type;
+ typedef typename source_type::order_type order_type;
typedef Interpolator interpolator_type;
- typedef Allocator alloc_type;
- typedef span_image_filter<color_type, interpolator_type, alloc_type> base_type;
+ typedef span_image_filter<source_type, interpolator_type> base_type;
typedef typename color_type::value_type value_type;
typedef typename color_type::calc_type calc_type;
- enum
+ enum base_scale_e
{
base_shift = color_type::base_shift,
base_mask = color_type::base_mask
};
//--------------------------------------------------------------------
- span_image_filter_rgba(alloc_type& alloc) : base_type(alloc) {}
-
- //--------------------------------------------------------------------
- span_image_filter_rgba(alloc_type& alloc,
- const rendering_buffer& src,
- const color_type& back_color,
+ span_image_filter_rgba() {}
+ span_image_filter_rgba(source_type& src,
interpolator_type& inter,
const image_filter_lut& filter) :
- base_type(alloc, src, back_color, inter, &filter)
+ base_type(src, inter, &filter)
{}
//--------------------------------------------------------------------
- color_type* generate(int x, int y, unsigned len)
+ void generate(color_type* span, int x, int y, unsigned len)
{
base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
y + base_type::filter_dy_dbl(), len);
int fg[4];
-
- value_type back_r = base_type::background_color().r;
- value_type back_g = base_type::background_color().g;
- value_type back_b = base_type::background_color().b;
- value_type back_a = base_type::background_color().a;
-
const value_type *fg_ptr;
- unsigned diameter = base_type::filter().diameter();
- int start = base_type::filter().start();
- int start1 = start - 1;
+ unsigned diameter = base_type::filter().diameter();
+ int start = base_type::filter().start();
const int16* weight_array = base_type::filter().weight_array();
- unsigned step_back = diameter << 2;
- color_type* span = base_type::allocator().span();
-
- int maxx = base_type::source_image().width() + start - 2;
- int maxy = base_type::source_image().height() + start - 2;
-
- int maxx2 = base_type::source_image().width() - start - 1;
- int maxy2 = base_type::source_image().height() - start - 1;
-
int x_count;
int weight_y;
@@ -716,142 +601,313 @@ namespace agg
int x_lr = x_hr >> image_subpixel_shift;
int y_lr = y_hr >> image_subpixel_shift;
- fg[0] = fg[1] = fg[2] = fg[3] = image_filter_size / 2;
+ fg[0] = fg[1] = fg[2] = fg[3] = image_filter_scale / 2;
int x_fract = x_hr & image_subpixel_mask;
unsigned y_count = diameter;
- if(x_lr >= -start && y_lr >= -start &&
- x_lr <= maxx && y_lr <= maxy)
+ y_hr = image_subpixel_mask - (y_hr & image_subpixel_mask);
+ fg_ptr = (const value_type*)base_type::source().span(x_lr + start,
+ y_lr + start,
+ diameter);
+ for(;;)
{
- y_hr = image_subpixel_mask - (y_hr & image_subpixel_mask);
- fg_ptr = (const value_type*)base_type::source_image().row(y_lr + start) + ((x_lr + start) << 2);
- do
+ x_count = diameter;
+ weight_y = weight_array[y_hr];
+ x_hr = image_subpixel_mask - x_fract;
+ for(;;)
{
- x_count = diameter;
- weight_y = weight_array[y_hr];
- x_hr = image_subpixel_mask - x_fract;
+ int weight = (weight_y * weight_array[x_hr] +
+ image_filter_scale / 2) >>
+ image_filter_shift;
+
+ fg[0] += weight * *fg_ptr++;
+ fg[1] += weight * *fg_ptr++;
+ fg[2] += weight * *fg_ptr++;
+ fg[3] += weight * *fg_ptr;
+
+ if(--x_count == 0) break;
+ x_hr += image_subpixel_scale;
+ fg_ptr = (const value_type*)base_type::source().next_x();
+ }
- do
- {
- int weight = (weight_y * weight_array[x_hr] +
- image_filter_size / 2) >>
- image_filter_shift;
+ if(--y_count == 0) break;
+ y_hr += image_subpixel_scale;
+ fg_ptr = (const value_type*)base_type::source().next_y();
+ }
- fg[0] += *fg_ptr++ * weight;
- fg[1] += *fg_ptr++ * weight;
- fg[2] += *fg_ptr++ * weight;
- fg[3] += *fg_ptr++ * weight;
+ fg[0] >>= image_filter_shift;
+ fg[1] >>= image_filter_shift;
+ fg[2] >>= image_filter_shift;
+ fg[3] >>= image_filter_shift;
- x_hr += image_subpixel_size;
+ if(fg[0] < 0) fg[0] = 0;
+ if(fg[1] < 0) fg[1] = 0;
+ if(fg[2] < 0) fg[2] = 0;
+ if(fg[3] < 0) fg[3] = 0;
- } while(--x_count);
+ if(fg[order_type::A] > base_mask) fg[order_type::A] = base_mask;
+ if(fg[order_type::R] > fg[order_type::A]) fg[order_type::R] = fg[order_type::A];
+ if(fg[order_type::G] > fg[order_type::A]) fg[order_type::G] = fg[order_type::A];
+ if(fg[order_type::B] > fg[order_type::A]) fg[order_type::B] = fg[order_type::A];
- y_hr += image_subpixel_size;
- fg_ptr = (const value_type*)base_type::source_image().next_row(fg_ptr - step_back);
+ span->r = (value_type)fg[order_type::R];
+ span->g = (value_type)fg[order_type::G];
+ span->b = (value_type)fg[order_type::B];
+ span->a = (value_type)fg[order_type::A];
+ ++span;
+ ++base_type::interpolator();
- } while(--y_count);
+ } while(--len);
+ }
+ };
- fg[0] >>= image_filter_shift;
- fg[1] >>= image_filter_shift;
- fg[2] >>= image_filter_shift;
- fg[3] >>= image_filter_shift;
- if(fg[0] < 0) fg[0] = 0;
- if(fg[1] < 0) fg[1] = 0;
- if(fg[2] < 0) fg[2] = 0;
- if(fg[3] < 0) fg[3] = 0;
- if(fg[order_type::A] > base_mask) fg[order_type::A] = base_mask;
- if(fg[order_type::R] > fg[order_type::A]) fg[order_type::R] = fg[order_type::A];
- if(fg[order_type::G] > fg[order_type::A]) fg[order_type::G] = fg[order_type::A];
- if(fg[order_type::B] > fg[order_type::A]) fg[order_type::B] = fg[order_type::A];
- }
- else
+ //========================================span_image_resample_rgba_affine
+ template<class Source>
+ class span_image_resample_rgba_affine :
+ public span_image_resample_affine<Source>
+ {
+ public:
+ typedef Source source_type;
+ typedef typename source_type::color_type color_type;
+ typedef typename source_type::order_type order_type;
+ typedef span_image_resample_affine<source_type> base_type;
+ typedef typename base_type::interpolator_type interpolator_type;
+ typedef typename color_type::value_type value_type;
+ typedef typename color_type::long_type long_type;
+ enum base_scale_e
+ {
+ base_shift = color_type::base_shift,
+ base_mask = color_type::base_mask,
+ downscale_shift = image_filter_shift
+ };
+
+ //--------------------------------------------------------------------
+ span_image_resample_rgba_affine() {}
+ span_image_resample_rgba_affine(source_type& src,
+ interpolator_type& inter,
+ const image_filter_lut& filter) :
+ base_type(src, inter, filter)
+ {}
+
+
+ //--------------------------------------------------------------------
+ void generate(color_type* span, int x, int y, unsigned len)
+ {
+ base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
+ y + base_type::filter_dy_dbl(), len);
+
+ long_type fg[4];
+
+ int diameter = base_type::filter().diameter();
+ int filter_scale = diameter << image_subpixel_shift;
+ int radius_x = (diameter * base_type::m_rx) >> 1;
+ int radius_y = (diameter * base_type::m_ry) >> 1;
+ int len_x_lr =
+ (diameter * base_type::m_rx + image_subpixel_mask) >>
+ image_subpixel_shift;
+
+ const int16* weight_array = base_type::filter().weight_array();
+
+ do
+ {
+ base_type::interpolator().coordinates(&x, &y);
+
+ x += base_type::filter_dx_int() - radius_x;
+ y += base_type::filter_dy_int() - radius_y;
+
+ fg[0] = fg[1] = fg[2] = fg[3] = image_filter_scale / 2;
+
+ int y_lr = y >> image_subpixel_shift;
+ int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) *
+ base_type::m_ry_inv) >>
+ image_subpixel_shift;
+ int total_weight = 0;
+ int x_lr = x >> image_subpixel_shift;
+ int x_hr = ((image_subpixel_mask - (x & image_subpixel_mask)) *
+ base_type::m_rx_inv) >>
+ image_subpixel_shift;
+
+ int x_hr2 = x_hr;
+ const value_type* fg_ptr =
+ (const value_type*)base_type::source().span(x_lr, y_lr, len_x_lr);
+ for(;;)
{
- if(x_lr < start1 || y_lr < start1 ||
- x_lr > maxx2 || y_lr > maxy2)
+ int weight_y = weight_array[y_hr];
+ x_hr = x_hr2;
+ for(;;)
{
- fg[order_type::R] = back_r;
- fg[order_type::G] = back_g;
- fg[order_type::B] = back_b;
- fg[order_type::A] = back_a;
+ int weight = (weight_y * weight_array[x_hr] +
+ image_filter_scale / 2) >>
+ downscale_shift;
+
+ fg[0] += *fg_ptr++ * weight;
+ fg[1] += *fg_ptr++ * weight;
+ fg[2] += *fg_ptr++ * weight;
+ fg[3] += *fg_ptr++ * weight;
+ total_weight += weight;
+ x_hr += base_type::m_rx_inv;
+ if(x_hr >= filter_scale) break;
+ fg_ptr = (const value_type*)base_type::source().next_x();
}
- else
- {
- y_lr = (y >> image_subpixel_shift) + start;
- y_hr = image_subpixel_mask - (y_hr & image_subpixel_mask);
+ y_hr += base_type::m_ry_inv;
+ if(y_hr >= filter_scale) break;
+ fg_ptr = (const value_type*)base_type::source().next_y();
+ }
- do
- {
- x_count = diameter;
- weight_y = weight_array[y_hr];
- x_lr = (x >> image_subpixel_shift) + start;
- x_hr = image_subpixel_mask - x_fract;
-
- do
- {
- int weight = (weight_y * weight_array[x_hr] +
- image_filter_size / 2) >>
- image_filter_shift;
-
- if(x_lr >= 0 && y_lr >= 0 &&
- x_lr < int(base_type::source_image().width()) &&
- y_lr < int(base_type::source_image().height()))
- {
- fg_ptr = (const value_type*)base_type::source_image().row(y_lr) + (x_lr << 2);
- fg[0] += *fg_ptr++ * weight;
- fg[1] += *fg_ptr++ * weight;
- fg[2] += *fg_ptr++ * weight;
- fg[3] += *fg_ptr++ * weight;
- }
- else
- {
- fg[order_type::R] += back_r * weight;
- fg[order_type::G] += back_g * weight;
- fg[order_type::B] += back_b * weight;
- fg[order_type::A] += back_a * weight;
- }
- x_hr += image_subpixel_size;
- x_lr++;
-
- } while(--x_count);
-
- y_hr += image_subpixel_size;
- y_lr++;
-
- } while(--y_count);
-
-
- fg[0] >>= image_filter_shift;
- fg[1] >>= image_filter_shift;
- fg[2] >>= image_filter_shift;
- fg[3] >>= image_filter_shift;
-
- if(fg[0] < 0) fg[0] = 0;
- if(fg[1] < 0) fg[1] = 0;
- if(fg[2] < 0) fg[2] = 0;
- if(fg[3] < 0) fg[3] = 0;
-
- if(fg[order_type::A] > base_mask) fg[order_type::A] = base_mask;
- if(fg[order_type::R] > fg[order_type::A]) fg[order_type::R] = fg[order_type::A];
- if(fg[order_type::G] > fg[order_type::A]) fg[order_type::G] = fg[order_type::A];
- if(fg[order_type::B] > fg[order_type::A]) fg[order_type::B] = fg[order_type::A];
+ fg[0] /= total_weight;
+ fg[1] /= total_weight;
+ fg[2] /= total_weight;
+ fg[3] /= total_weight;
+
+ if(fg[0] < 0) fg[0] = 0;
+ if(fg[1] < 0) fg[1] = 0;
+ if(fg[2] < 0) fg[2] = 0;
+ if(fg[3] < 0) fg[3] = 0;
+
+ if(fg[order_type::A] > base_mask) fg[order_type::A] = base_mask;
+ if(fg[order_type::R] > fg[order_type::A]) fg[order_type::R] = fg[order_type::A];
+ if(fg[order_type::G] > fg[order_type::A]) fg[order_type::G] = fg[order_type::A];
+ if(fg[order_type::B] > fg[order_type::A]) fg[order_type::B] = fg[order_type::A];
+
+ span->r = (value_type)fg[order_type::R];
+ span->g = (value_type)fg[order_type::G];
+ span->b = (value_type)fg[order_type::B];
+ span->a = (value_type)fg[order_type::A];
+
+ ++span;
+ ++base_type::interpolator();
+ } while(--len);
+ }
+ };
+
+
+
+ //==============================================span_image_resample_rgba
+ template<class Source, class Interpolator>
+ class span_image_resample_rgba :
+ public span_image_resample<Source, Interpolator>
+ {
+ public:
+ typedef Source source_type;
+ typedef typename source_type::color_type color_type;
+ typedef typename source_type::order_type order_type;
+ typedef Interpolator interpolator_type;
+ typedef span_image_resample<source_type, interpolator_type> base_type;
+ typedef typename color_type::value_type value_type;
+ typedef typename color_type::long_type long_type;
+ enum base_scale_e
+ {
+ base_shift = color_type::base_shift,
+ base_mask = color_type::base_mask,
+ downscale_shift = image_filter_shift
+ };
+
+ //--------------------------------------------------------------------
+ span_image_resample_rgba() {}
+ span_image_resample_rgba(source_type& src,
+ interpolator_type& inter,
+ const image_filter_lut& filter) :
+ base_type(src, inter, filter)
+ {}
+
+ //--------------------------------------------------------------------
+ void generate(color_type* span, int x, int y, unsigned len)
+ {
+ base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
+ y + base_type::filter_dy_dbl(), len);
+ long_type fg[4];
+
+ int diameter = base_type::filter().diameter();
+ int filter_scale = diameter << image_subpixel_shift;
+
+ const int16* weight_array = base_type::filter().weight_array();
+ do
+ {
+ int rx;
+ int ry;
+ int rx_inv = image_subpixel_scale;
+ int ry_inv = image_subpixel_scale;
+ base_type::interpolator().coordinates(&x, &y);
+ base_type::interpolator().local_scale(&rx, &ry);
+ base_type::adjust_scale(&rx, &ry);
+
+ rx_inv = image_subpixel_scale * image_subpixel_scale / rx;
+ ry_inv = image_subpixel_scale * image_subpixel_scale / ry;
+
+ int radius_x = (diameter * rx) >> 1;
+ int radius_y = (diameter * ry) >> 1;
+ int len_x_lr =
+ (diameter * rx + image_subpixel_mask) >>
+ image_subpixel_shift;
+
+ x += base_type::filter_dx_int() - radius_x;
+ y += base_type::filter_dy_int() - radius_y;
+
+ fg[0] = fg[1] = fg[2] = fg[3] = image_filter_scale / 2;
+
+ int y_lr = y >> image_subpixel_shift;
+ int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) *
+ ry_inv) >>
+ image_subpixel_shift;
+ int total_weight = 0;
+ int x_lr = x >> image_subpixel_shift;
+ int x_hr = ((image_subpixel_mask - (x & image_subpixel_mask)) *
+ rx_inv) >>
+ image_subpixel_shift;
+ int x_hr2 = x_hr;
+ const value_type* fg_ptr =
+ (const value_type*)base_type::source().span(x_lr, y_lr, len_x_lr);
+
+ for(;;)
+ {
+ int weight_y = weight_array[y_hr];
+ x_hr = x_hr2;
+ for(;;)
+ {
+ int weight = (weight_y * weight_array[x_hr] +
+ image_filter_scale / 2) >>
+ downscale_shift;
+ fg[0] += *fg_ptr++ * weight;
+ fg[1] += *fg_ptr++ * weight;
+ fg[2] += *fg_ptr++ * weight;
+ fg[3] += *fg_ptr++ * weight;
+ total_weight += weight;
+ x_hr += rx_inv;
+ if(x_hr >= filter_scale) break;
+ fg_ptr = (const value_type*)base_type::source().next_x();
}
+ y_hr += ry_inv;
+ if(y_hr >= filter_scale) break;
+ fg_ptr = (const value_type*)base_type::source().next_y();
}
- span->r = fg[order_type::R];
- span->g = fg[order_type::G];
- span->b = fg[order_type::B];
- span->a = fg[order_type::A];
+ fg[0] /= total_weight;
+ fg[1] /= total_weight;
+ fg[2] /= total_weight;
+ fg[3] /= total_weight;
+
+ if(fg[0] < 0) fg[0] = 0;
+ if(fg[1] < 0) fg[1] = 0;
+ if(fg[2] < 0) fg[2] = 0;
+ if(fg[3] < 0) fg[3] = 0;
+
+ if(fg[order_type::A] > base_mask) fg[order_type::A] = base_mask;
+ if(fg[order_type::R] > fg[order_type::R]) fg[order_type::R] = fg[order_type::R];
+ if(fg[order_type::G] > fg[order_type::G]) fg[order_type::G] = fg[order_type::G];
+ if(fg[order_type::B] > fg[order_type::B]) fg[order_type::B] = fg[order_type::B];
+
+ span->r = (value_type)fg[order_type::R];
+ span->g = (value_type)fg[order_type::G];
+ span->b = (value_type)fg[order_type::B];
+ span->a = (value_type)fg[order_type::A];
+
++span;
++base_type::interpolator();
-
} while(--len);
-
- return base_type::allocator().span();
}
-
};
diff --git a/agg/inc/agg_span_image_resample.h b/agg/inc/agg_span_image_resample.h
deleted file mode 100755
index f4dfd57455d7..000000000000
--- a/agg/inc/agg_span_image_resample.h
+++ /dev/null
@@ -1,180 +0,0 @@
-//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
-// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
-//
-// Permission to copy, use, modify, sell and distribute this software
-// is granted provided this copyright notice appears in all copies.
-// This software is provided "as is" without express or implied
-// warranty, and with no claim as to its suitability for any purpose.
-//
-//----------------------------------------------------------------------------
-// Contact: mcseem@antigrain.com
-// mcseemagg@yahoo.com
-// http://www.antigrain.com
-//----------------------------------------------------------------------------
-#ifndef AGG_SPAN_IMAGE_RESAMPLE_INCLUDED
-#define AGG_SPAN_IMAGE_RESAMPLE_INCLUDED
-
-#include "agg_span_image_filter.h"
-#include "agg_span_interpolator_linear.h"
-
-
-namespace agg
-{
-
-
- //=====================================================span_image_resample
- template<class ColorT, class Interpolator, class Allocator>
- class span_image_resample :
- public span_image_filter<ColorT, Interpolator, Allocator>
- {
- public:
- typedef ColorT color_type;
- typedef Interpolator interpolator_type;
- typedef Allocator alloc_type;
- typedef span_image_filter<color_type, interpolator_type, alloc_type> base_type;
-
- //--------------------------------------------------------------------
- span_image_resample(alloc_type& alloc) :
- base_type(alloc),
- m_scale_limit(20),
- m_blur_x(image_subpixel_size),
- m_blur_y(image_subpixel_size)
- {}
-
- //--------------------------------------------------------------------
- span_image_resample(alloc_type& alloc,
- const rendering_buffer& src,
- const color_type& back_color,
- interpolator_type& inter,
- const image_filter_lut& filter) :
- base_type(alloc, src, back_color, inter, &filter),
- m_scale_limit(20),
- m_blur_x(image_subpixel_size),
- m_blur_y(image_subpixel_size)
- {}
-
-
- //--------------------------------------------------------------------
- int scale_limit() const { return m_scale_limit; }
- void scale_limit(int v) { m_scale_limit = v; }
-
- //--------------------------------------------------------------------
- double blur_x() const { return double(m_blur_x) / double(image_subpixel_size); }
- double blur_y() const { return double(m_blur_y) / double(image_subpixel_size); }
- void blur_x(double v) { m_blur_x = int(v * double(image_subpixel_size) + 0.5); }
- void blur_y(double v) { m_blur_y = int(v * double(image_subpixel_size) + 0.5); }
- void blur(double v) { m_blur_x =
- m_blur_y = int(v * double(image_subpixel_size) + 0.5); }
-
- protected:
- int m_scale_limit;
- int m_blur_x;
- int m_blur_y;
- };
-
-
-
-
-
-
-
-
- //==============================================span_image_resample_affine
- template<class ColorT, class Allocator>
- class span_image_resample_affine :
- public span_image_filter<ColorT, span_interpolator_linear<trans_affine>, Allocator>
- {
- public:
- typedef ColorT color_type;
- typedef span_interpolator_linear<trans_affine> interpolator_type;
- typedef Allocator alloc_type;
- typedef span_image_filter<color_type, interpolator_type, alloc_type> base_type;
-
- //--------------------------------------------------------------------
- span_image_resample_affine(alloc_type& alloc) :
- base_type(alloc),
- m_scale_limit(200.0),
- m_blur_x(1.0),
- m_blur_y(1.0)
- {}
-
- //--------------------------------------------------------------------
- span_image_resample_affine(alloc_type& alloc,
- const rendering_buffer& src,
- const color_type& back_color,
- interpolator_type& inter,
- const image_filter_lut& filter_) :
- base_type(alloc, src, back_color, inter, &filter_),
- m_scale_limit(200.0),
- m_blur_x(1.0),
- m_blur_y(1.0)
- {}
-
-
- //--------------------------------------------------------------------
- int scale_limit() const { return int(m_scale_limit); }
- void scale_limit(int v) { m_scale_limit = v; }
-
- //--------------------------------------------------------------------
- double blur_x() const { return m_blur_x; }
- double blur_y() const { return m_blur_y; }
- void blur_x(double v) { m_blur_x = v; }
- void blur_y(double v) { m_blur_y = v; }
- void blur(double v) { m_blur_x = m_blur_y = v; }
-
-
- //--------------------------------------------------------------------
- void prepare(unsigned max_span_len)
- {
- base_type::prepare(max_span_len);
-
- double scale_x;
- double scale_y;
-
- base_type::interpolator().transformer().scaling_abs(&scale_x, &scale_y);
-
- m_rx = image_subpixel_size;
- m_ry = image_subpixel_size;
- m_rx_inv = image_subpixel_size;
- m_ry_inv = image_subpixel_size;
-
- scale_x *= m_blur_x;
- scale_y *= m_blur_y;
-
- if(scale_x * scale_y > m_scale_limit)
- {
- scale_x = scale_x * m_scale_limit / (scale_x * scale_y);
- scale_y = scale_y * m_scale_limit / (scale_x * scale_y);
- }
-
- if(scale_x > 1.0001)
- {
- if(scale_x > m_scale_limit) scale_x = m_scale_limit;
- m_rx = int( scale_x * double(image_subpixel_size) + 0.5);
- m_rx_inv = int(1.0/scale_x * double(image_subpixel_size) + 0.5);
- }
-
- if(scale_y > 1.0001)
- {
- if(scale_y > m_scale_limit) scale_y = m_scale_limit;
- m_ry = int( scale_y * double(image_subpixel_size) + 0.5);
- m_ry_inv = int(1.0/scale_y * double(image_subpixel_size) + 0.5);
- }
- }
-
- protected:
- int m_rx;
- int m_ry;
- int m_rx_inv;
- int m_ry_inv;
-
- private:
- double m_scale_limit;
- double m_blur_x;
- double m_blur_y;
- };
-
-}
-
-#endif
diff --git a/agg/inc/agg_span_image_resample_gray.h b/agg/inc/agg_span_image_resample_gray.h
deleted file mode 100755
index 3d046462cd8c..000000000000
--- a/agg/inc/agg_span_image_resample_gray.h
+++ /dev/null
@@ -1,359 +0,0 @@
-//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
-// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
-//
-// Permission to copy, use, modify, sell and distribute this software
-// is granted provided this copyright notice appears in all copies.
-// This software is provided "as is" without express or implied
-// warranty, and with no claim as to its suitability for any purpose.
-//
-//----------------------------------------------------------------------------
-// Contact: mcseem@antigrain.com
-// mcseemagg@yahoo.com
-// http://www.antigrain.com
-//----------------------------------------------------------------------------
-
-#ifndef AGG_SPAN_IMAGE_RESAMPLE_GRAY_INCLUDED
-#define AGG_SPAN_IMAGE_RESAMPLE_GRAY_INCLUDED
-
-#include "agg_color_gray.h"
-#include "agg_span_image_resample.h"
-
-namespace agg
-{
-
- //========================================span_image_resample_gray_affine
- template<class ColorT,
- class Allocator = span_allocator<ColorT> >
- class span_image_resample_gray_affine :
- public span_image_resample_affine<ColorT, Allocator>
- {
- public:
- typedef ColorT color_type;
- typedef Allocator alloc_type;
- typedef span_image_resample_affine<color_type, alloc_type> base_type;
- typedef typename base_type::interpolator_type interpolator_type;
- typedef typename color_type::value_type value_type;
- typedef typename color_type::long_type long_type;
- enum
- {
- base_shift = color_type::base_shift,
- base_mask = color_type::base_mask,
- downscale_shift = image_filter_shift
- };
-
- //--------------------------------------------------------------------
- span_image_resample_gray_affine(alloc_type& alloc) : base_type(alloc) {}
-
- //--------------------------------------------------------------------
- span_image_resample_gray_affine(alloc_type& alloc,
- const rendering_buffer& src,
- const color_type& back_color,
- interpolator_type& inter,
- const image_filter_lut& filter) :
- base_type(alloc, src, back_color, inter, filter)
- {}
-
-
- //--------------------------------------------------------------------
- color_type* generate(int x, int y, unsigned len)
- {
- base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
- y + base_type::filter_dy_dbl(), len);
-
- long_type fg;
- long_type src_alpha;
- value_type back_v = base_type::background_color().v;
- value_type back_a = base_type::background_color().a;
-
- color_type* span = base_type::allocator().span();
-
- int diameter = base_type::filter().diameter();
- int filter_size = diameter << image_subpixel_shift;
- int radius_x = (diameter * base_type::m_rx) >> 1;
- int radius_y = (diameter * base_type::m_ry) >> 1;
- int maxx = base_type::source_image().width() - 1;
- int maxy = base_type::source_image().height() - 1;
-
- const int16* weight_array = base_type::filter().weight_array();
-
- do
- {
- base_type::interpolator().coordinates(&x, &y);
-
- x += base_type::filter_dx_int() - radius_x;
- y += base_type::filter_dy_int() - radius_y;
-
- fg = src_alpha = image_filter_size / 2;
-
- int y_lr = y >> image_subpixel_shift;
- int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) *
- base_type::m_ry_inv) >>
- image_subpixel_shift;
- int total_weight = 0;
- int x_lr_ini = x >> image_subpixel_shift;
- int x_hr_ini = ((image_subpixel_mask - (x & image_subpixel_mask)) *
- base_type::m_rx_inv) >>
- image_subpixel_shift;
- do
- {
- int weight_y = weight_array[y_hr];
- int x_lr = x_lr_ini;
- int x_hr = x_hr_ini;
- if(y_lr >= 0 && y_lr <= maxy)
- {
- const value_type* fg_ptr = (const value_type*)
- base_type::source_image().row(y_lr) + x_lr;
- do
- {
- int weight = (weight_y * weight_array[x_hr] +
- image_filter_size / 2) >>
- downscale_shift;
-
- if(x_lr >= 0 && x_lr <= maxx)
- {
- fg += *fg_ptr * weight;
- src_alpha += base_mask * weight;
- }
- else
- {
- fg += back_v * weight;
- src_alpha += back_a * weight;
- }
- total_weight += weight;
- x_hr += base_type::m_rx_inv;
- ++fg_ptr;
- ++x_lr;
- }
- while(x_hr < filter_size);
- }
- else
- {
- do
- {
- int weight = (weight_y * weight_array[x_hr] +
- image_filter_size / 2) >>
- downscale_shift;
-
- total_weight += weight;
- fg += back_v * weight;
- src_alpha += back_a * weight;
- x_hr += base_type::m_rx_inv;
- }
- while(x_hr < filter_size);
- }
- y_hr += base_type::m_ry_inv;
- ++y_lr;
- }
- while(y_hr < filter_size);
-
- fg /= total_weight;
- src_alpha /= total_weight;
-
- if(fg < 0) fg = 0;
- if(src_alpha < 0) src_alpha = 0;
-
- if(src_alpha > base_mask) src_alpha = base_mask;
- if(fg > src_alpha) fg = src_alpha;
-
- span->v = (value_type)fg;
- span->a = (value_type)src_alpha;
-
- ++span;
- ++base_type::interpolator();
- } while(--len);
- return base_type::allocator().span();
- }
- };
-
-
-
-
-
-
-
- //==============================================span_image_resample_gray
- template<class ColorT,
- class Interpolator,
- class Allocator = span_allocator<ColorT> >
- class span_image_resample_gray :
- public span_image_resample<ColorT, Interpolator, Allocator>
- {
- public:
- typedef ColorT color_type;
- typedef Interpolator interpolator_type;
- typedef Allocator alloc_type;
- typedef span_image_resample<color_type, interpolator_type, alloc_type> base_type;
- typedef typename color_type::value_type value_type;
- typedef typename color_type::long_type long_type;
- enum
- {
- base_shift = color_type::base_shift,
- base_mask = color_type::base_mask,
- downscale_shift = image_filter_shift
- };
-
- //--------------------------------------------------------------------
- span_image_resample_gray(alloc_type& alloc) :
- base_type(alloc)
- {}
-
- //--------------------------------------------------------------------
- span_image_resample_gray(alloc_type& alloc,
- const rendering_buffer& src,
- const color_type& back_color,
- interpolator_type& inter,
- const image_filter_lut& filter) :
- base_type(alloc, src, back_color, inter, filter)
- {}
-
- //--------------------------------------------------------------------
- color_type* generate(int x, int y, unsigned len)
- {
- color_type* span = base_type::allocator().span();
- base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
- y + base_type::filter_dy_dbl(), len);
- long_type fg;
- long_type src_alpha;
- value_type back_v = base_type::background_color().v;
- value_type back_a = base_type::background_color().a;
-
- int diameter = base_type::filter().diameter();
- int filter_size = diameter << image_subpixel_shift;
-
- const int16* weight_array = base_type::filter().weight_array();
-
- do
- {
- int rx;
- int ry;
- int rx_inv = image_subpixel_size;
- int ry_inv = image_subpixel_size;
- base_type::interpolator().coordinates(&x, &y);
- base_type::interpolator().local_scale(&rx, &ry);
-
- rx = (rx * base_type::m_blur_x) >> image_subpixel_shift;
- ry = (ry * base_type::m_blur_y) >> image_subpixel_shift;
-
- if(rx < image_subpixel_size)
- {
- rx = image_subpixel_size;
- }
- else
- {
- if(rx > image_subpixel_size * base_type::m_scale_limit)
- {
- rx = image_subpixel_size * base_type::m_scale_limit;
- }
- rx_inv = image_subpixel_size * image_subpixel_size / rx;
- }
-
- if(ry < image_subpixel_size)
- {
- ry = image_subpixel_size;
- }
- else
- {
- if(ry > image_subpixel_size * base_type::m_scale_limit)
- {
- ry = image_subpixel_size * base_type::m_scale_limit;
- }
- ry_inv = image_subpixel_size * image_subpixel_size / ry;
- }
-
- int radius_x = (diameter * rx) >> 1;
- int radius_y = (diameter * ry) >> 1;
- int maxx = base_type::source_image().width() - 1;
- int maxy = base_type::source_image().height() - 1;
-
- x += base_type::filter_dx_int() - radius_x;
- y += base_type::filter_dy_int() - radius_y;
-
- fg = src_alpha = image_filter_size / 2;
-
- int y_lr = y >> image_subpixel_shift;
- int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) *
- ry_inv) >>
- image_subpixel_shift;
- int total_weight = 0;
- int x_lr_ini = x >> image_subpixel_shift;
- int x_hr_ini = ((image_subpixel_mask - (x & image_subpixel_mask)) *
- rx_inv) >>
- image_subpixel_shift;
-
- do
- {
- int weight_y = weight_array[y_hr];
- int x_lr = x_lr_ini;
- int x_hr = x_hr_ini;
- if(y_lr >= 0 && y_lr <= maxy)
- {
- const value_type* fg_ptr = (const value_type*)
- base_type::source_image().row(y_lr) + x_lr;
- do
- {
- int weight = (weight_y * weight_array[x_hr] +
- image_filter_size / 2) >>
- downscale_shift;
-
- if(x_lr >= 0 && x_lr <= maxx)
- {
- fg += *fg_ptr * weight;
- src_alpha += base_mask * weight;
- }
- else
- {
- fg += back_v * weight;
- src_alpha += back_a * weight;
- }
- total_weight += weight;
- x_hr += rx_inv;
- ++fg_ptr;
- ++x_lr;
- }
- while(x_hr < filter_size);
- }
- else
- {
- do
- {
- int weight = (weight_y * weight_array[x_hr] +
- image_filter_size / 2) >>
- downscale_shift;
-
- total_weight += weight;
- fg += back_v * weight;
- src_alpha += back_a * weight;
- x_hr += rx_inv;
- }
- while(x_hr < filter_size);
- }
- y_hr += ry_inv;
- ++y_lr;
- }
- while(y_hr < filter_size);
-
- fg /= total_weight;
- src_alpha /= total_weight;
-
- if(fg < 0) fg = 0;
- if(src_alpha < 0) src_alpha = 0;
-
- if(src_alpha > base_mask) src_alpha = base_mask;
- if(fg > src_alpha) fg = src_alpha;
-
- span->v = (value_type)fg;
- span->a = (value_type)src_alpha;
-
- ++span;
- ++base_type::interpolator();
- } while(--len);
- return base_type::allocator().span();
- }
-
- };
-
-}
-
-
-#endif
diff --git a/agg/inc/agg_span_image_resample_rgb.h b/agg/inc/agg_span_image_resample_rgb.h
deleted file mode 100755
index de25dd4b382b..000000000000
--- a/agg/inc/agg_span_image_resample_rgb.h
+++ /dev/null
@@ -1,393 +0,0 @@
-//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
-// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
-//
-// Permission to copy, use, modify, sell and distribute this software
-// is granted provided this copyright notice appears in all copies.
-// This software is provided "as is" without express or implied
-// warranty, and with no claim as to its suitability for any purpose.
-//
-//----------------------------------------------------------------------------
-// Contact: mcseem@antigrain.com
-// mcseemagg@yahoo.com
-// http://www.antigrain.com
-//----------------------------------------------------------------------------
-
-#ifndef AGG_SPAN_IMAGE_RESAMPLE_RGB_INCLUDED
-#define AGG_SPAN_IMAGE_RESAMPLE_RGB_INCLUDED
-
-#include "agg_color_rgba.h"
-#include "agg_span_image_resample.h"
-
-namespace agg
-{
-
- //=========================================span_image_resample_rgb_affine
- template<class ColorT,
- class Order,
- class Allocator = span_allocator<ColorT> >
- class span_image_resample_rgb_affine :
- public span_image_resample_affine<ColorT, Allocator>
- {
- public:
- typedef ColorT color_type;
- typedef Order order_type;
- typedef Allocator alloc_type;
- typedef span_image_resample_affine<color_type, alloc_type> base_type;
- typedef typename base_type::interpolator_type interpolator_type;
- typedef typename color_type::value_type value_type;
- typedef typename color_type::long_type long_type;
- enum
- {
- base_shift = color_type::base_shift,
- base_mask = color_type::base_mask,
- downscale_shift = image_filter_shift
- };
-
- //--------------------------------------------------------------------
- span_image_resample_rgb_affine(alloc_type& alloc) : base_type(alloc) {}
-
- //--------------------------------------------------------------------
- span_image_resample_rgb_affine(alloc_type& alloc,
- const rendering_buffer& src,
- const color_type& back_color,
- interpolator_type& inter,
- const image_filter_lut& filter) :
- base_type(alloc, src, back_color, inter, filter)
- {}
-
-
- //--------------------------------------------------------------------
- color_type* generate(int x, int y, unsigned len)
- {
- base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
- y + base_type::filter_dy_dbl(), len);
-
- long_type fg[4];
- value_type back_r = base_type::background_color().r;
- value_type back_g = base_type::background_color().g;
- value_type back_b = base_type::background_color().b;
- value_type back_a = base_type::background_color().a;
-
- color_type* span = base_type::allocator().span();
-
- int diameter = base_type::filter().diameter();
- int filter_size = diameter << image_subpixel_shift;
- int radius_x = (diameter * base_type::m_rx) >> 1;
- int radius_y = (diameter * base_type::m_ry) >> 1;
- int maxx = base_type::source_image().width() - 1;
- int maxy = base_type::source_image().height() - 1;
-
- const int16* weight_array = base_type::filter().weight_array();
-
- do
- {
- base_type::interpolator().coordinates(&x, &y);
-
- x += base_type::filter_dx_int() - radius_x;
- y += base_type::filter_dy_int() - radius_y;
-
- fg[0] = fg[1] = fg[2] = fg[3] = image_filter_size / 2;
-
- int y_lr = y >> image_subpixel_shift;
- int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) *
- base_type::m_ry_inv) >>
- image_subpixel_shift;
- int total_weight = 0;
- int x_lr_ini = x >> image_subpixel_shift;
- int x_hr_ini = ((image_subpixel_mask - (x & image_subpixel_mask)) *
- base_type::m_rx_inv) >>
- image_subpixel_shift;
- do
- {
- int weight_y = weight_array[y_hr];
- int x_lr = x_lr_ini;
- int x_hr = x_hr_ini;
- if(y_lr >= 0 && y_lr <= maxy)
- {
- const value_type* fg_ptr = (const value_type*)
- base_type::source_image().row(y_lr) + x_lr * 3;
- do
- {
- int weight = (weight_y * weight_array[x_hr] +
- image_filter_size / 2) >>
- downscale_shift;
-
- if(x_lr >= 0 && x_lr <= maxx)
- {
- fg[0] += fg_ptr[0] * weight;
- fg[1] += fg_ptr[1] * weight;
- fg[2] += fg_ptr[2] * weight;
- fg[3] += base_mask * weight;
- }
- else
- {
- fg[order_type::R] += back_r * weight;
- fg[order_type::G] += back_g * weight;
- fg[order_type::B] += back_b * weight;
- fg[3] += back_a * weight;
- }
- total_weight += weight;
- fg_ptr += 3;
- x_hr += base_type::m_rx_inv;
- ++x_lr;
- }
- while(x_hr < filter_size);
- }
- else
- {
- do
- {
- int weight = (weight_y * weight_array[x_hr] +
- image_filter_size / 2) >>
- downscale_shift;
-
- total_weight += weight;
- fg[order_type::R] += back_r * weight;
- fg[order_type::G] += back_g * weight;
- fg[order_type::B] += back_b * weight;
- fg[3] += back_a * weight;
- x_hr += base_type::m_rx_inv;
- }
- while(x_hr < filter_size);
- }
- y_hr += base_type::m_ry_inv;
- ++y_lr;
- }
- while(y_hr < filter_size);
-
- fg[0] /= total_weight;
- fg[1] /= total_weight;
- fg[2] /= total_weight;
- fg[3] /= total_weight;
-
- if(fg[0] < 0) fg[0] = 0;
- if(fg[1] < 0) fg[1] = 0;
- if(fg[2] < 0) fg[2] = 0;
- if(fg[3] < 0) fg[3] = 0;
-
- if(fg[3] > base_mask) fg[3] = base_mask;
- if(fg[0] > fg[3]) fg[0] = fg[3];
- if(fg[1] > fg[3]) fg[1] = fg[3];
- if(fg[2] > fg[3]) fg[2] = fg[3];
-
- span->r = (value_type)fg[order_type::R];
- span->g = (value_type)fg[order_type::G];
- span->b = (value_type)fg[order_type::B];
- span->a = (value_type)fg[3];
-
- ++span;
- ++base_type::interpolator();
- } while(--len);
- return base_type::allocator().span();
- }
- };
-
-
-
-
-
-
-
- //===============================================span_image_resample_rgb
- template<class ColorT,
- class Order,
- class Interpolator,
- class Allocator = span_allocator<ColorT> >
- class span_image_resample_rgb :
- public span_image_resample<ColorT, Interpolator, Allocator>
- {
- public:
- typedef ColorT color_type;
- typedef Order order_type;
- typedef Interpolator interpolator_type;
- typedef Allocator alloc_type;
- typedef span_image_resample<color_type, interpolator_type, alloc_type> base_type;
- typedef typename color_type::value_type value_type;
- typedef typename color_type::long_type long_type;
- enum
- {
- base_shift = color_type::base_shift,
- base_mask = color_type::base_mask,
- downscale_shift = image_filter_shift
- };
-
- //--------------------------------------------------------------------
- span_image_resample_rgb(alloc_type& alloc) :
- base_type(alloc)
- {}
-
- //--------------------------------------------------------------------
- span_image_resample_rgb(alloc_type& alloc,
- const rendering_buffer& src,
- const color_type& back_color,
- interpolator_type& inter,
- const image_filter_lut& filter) :
- base_type(alloc, src, back_color, inter, filter)
- {}
-
- //--------------------------------------------------------------------
- color_type* generate(int x, int y, unsigned len)
- {
- color_type* span = base_type::allocator().span();
- base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
- y + base_type::filter_dy_dbl(), len);
- long_type fg[4];
- value_type back_r = base_type::background_color().r;
- value_type back_g = base_type::background_color().g;
- value_type back_b = base_type::background_color().b;
- value_type back_a = base_type::background_color().a;
-
- int diameter = base_type::filter().diameter();
- int filter_size = diameter << image_subpixel_shift;
-
- const int16* weight_array = base_type::filter().weight_array();
-
- do
- {
- int rx;
- int ry;
- int rx_inv = image_subpixel_size;
- int ry_inv = image_subpixel_size;
- base_type::interpolator().coordinates(&x, &y);
- base_type::interpolator().local_scale(&rx, &ry);
-
- rx = (rx * base_type::m_blur_x) >> image_subpixel_shift;
- ry = (ry * base_type::m_blur_y) >> image_subpixel_shift;
-
- if(rx < image_subpixel_size)
- {
- rx = image_subpixel_size;
- }
- else
- {
- if(rx > image_subpixel_size * base_type::m_scale_limit)
- {
- rx = image_subpixel_size * base_type::m_scale_limit;
- }
- rx_inv = image_subpixel_size * image_subpixel_size / rx;
- }
-
- if(ry < image_subpixel_size)
- {
- ry = image_subpixel_size;
- }
- else
- {
- if(ry > image_subpixel_size * base_type::m_scale_limit)
- {
- ry = image_subpixel_size * base_type::m_scale_limit;
- }
- ry_inv = image_subpixel_size * image_subpixel_size / ry;
- }
-
- int radius_x = (diameter * rx) >> 1;
- int radius_y = (diameter * ry) >> 1;
- int maxx = base_type::source_image().width() - 1;
- int maxy = base_type::source_image().height() - 1;
-
- x += base_type::filter_dx_int() - radius_x;
- y += base_type::filter_dy_int() - radius_y;
-
- fg[0] = fg[1] = fg[2] = fg[3] = image_filter_size / 2;
-
- int y_lr = y >> image_subpixel_shift;
- int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) *
- ry_inv) >>
- image_subpixel_shift;
- int total_weight = 0;
- int x_lr_ini = x >> image_subpixel_shift;
- int x_hr_ini = ((image_subpixel_mask - (x & image_subpixel_mask)) *
- rx_inv) >>
- image_subpixel_shift;
-
- do
- {
- int weight_y = weight_array[y_hr];
- int x_lr = x_lr_ini;
- int x_hr = x_hr_ini;
- if(y_lr >= 0 && y_lr <= maxy)
- {
- const value_type* fg_ptr = (const value_type*)
- base_type::source_image().row(y_lr) + x_lr * 3;
- do
- {
- int weight = (weight_y * weight_array[x_hr] +
- image_filter_size / 2) >>
- downscale_shift;
-
- if(x_lr >= 0 && x_lr <= maxx)
- {
- fg[0] += fg_ptr[0] * weight;
- fg[1] += fg_ptr[1] * weight;
- fg[2] += fg_ptr[2] * weight;
- fg[3] += base_mask * weight;
- }
- else
- {
- fg[order_type::R] += back_r * weight;
- fg[order_type::G] += back_g * weight;
- fg[order_type::B] += back_b * weight;
- fg[3] += back_a * weight;
- }
- total_weight += weight;
- fg_ptr += 3;
- x_hr += rx_inv;
- ++x_lr;
- }
- while(x_hr < filter_size);
- }
- else
- {
- do
- {
- int weight = (weight_y * weight_array[x_hr] +
- image_filter_size / 2) >>
- downscale_shift;
-
- total_weight += weight;
- fg[order_type::R] += back_r * weight;
- fg[order_type::G] += back_g * weight;
- fg[order_type::B] += back_b * weight;
- fg[3] += back_a * weight;
- x_hr += rx_inv;
- }
- while(x_hr < filter_size);
- }
- y_hr += ry_inv;
- ++y_lr;
- }
- while(y_hr < filter_size);
-
- fg[0] /= total_weight;
- fg[1] /= total_weight;
- fg[2] /= total_weight;
- fg[3] /= total_weight;
-
- if(fg[0] < 0) fg[0] = 0;
- if(fg[1] < 0) fg[1] = 0;
- if(fg[2] < 0) fg[2] = 0;
- if(fg[3] < 0) fg[3] = 0;
-
- if(fg[3] > base_mask) fg[3] = base_mask;
- if(fg[0] > fg[3]) fg[0] = fg[3];
- if(fg[1] > fg[3]) fg[1] = fg[3];
- if(fg[2] > fg[3]) fg[2] = fg[3];
-
- span->r = (value_type)fg[order_type::R];
- span->g = (value_type)fg[order_type::G];
- span->b = (value_type)fg[order_type::B];
- span->a = (value_type)fg[3];
-
- ++span;
- ++base_type::interpolator();
- } while(--len);
- return base_type::allocator().span();
- }
-
- };
-
-}
-
-
-#endif
diff --git a/agg/inc/agg_span_image_resample_rgba.h b/agg/inc/agg_span_image_resample_rgba.h
deleted file mode 100755
index 40f7ccb42e00..000000000000
--- a/agg/inc/agg_span_image_resample_rgba.h
+++ /dev/null
@@ -1,393 +0,0 @@
-//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
-// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
-//
-// Permission to copy, use, modify, sell and distribute this software
-// is granted provided this copyright notice appears in all copies.
-// This software is provided "as is" without express or implied
-// warranty, and with no claim as to its suitability for any purpose.
-//
-//----------------------------------------------------------------------------
-// Contact: mcseem@antigrain.com
-// mcseemagg@yahoo.com
-// http://www.antigrain.com
-//----------------------------------------------------------------------------
-
-#ifndef AGG_SPAN_IMAGE_RESAMPLE_RGBA_INCLUDED
-#define AGG_SPAN_IMAGE_RESAMPLE_RGBA_INCLUDED
-
-#include "agg_color_rgba.h"
-#include "agg_span_image_resample.h"
-
-namespace agg
-{
-
- //========================================span_image_resample_rgba_affine
- template<class ColorT,
- class Order,
- class Allocator = span_allocator<ColorT> >
- class span_image_resample_rgba_affine :
- public span_image_resample_affine<ColorT, Allocator>
- {
- public:
- typedef ColorT color_type;
- typedef Order order_type;
- typedef Allocator alloc_type;
- typedef span_image_resample_affine<color_type, alloc_type> base_type;
- typedef typename base_type::interpolator_type interpolator_type;
- typedef typename color_type::value_type value_type;
- typedef typename color_type::long_type long_type;
- enum
- {
- base_shift = color_type::base_shift,
- base_mask = color_type::base_mask,
- downscale_shift = image_filter_shift
- };
-
- //--------------------------------------------------------------------
- span_image_resample_rgba_affine(alloc_type& alloc) : base_type(alloc) {}
-
- //--------------------------------------------------------------------
- span_image_resample_rgba_affine(alloc_type& alloc,
- const rendering_buffer& src,
- const color_type& back_color,
- interpolator_type& inter,
- const image_filter_lut& filter) :
- base_type(alloc, src, back_color, inter, filter)
- {}
-
-
- //--------------------------------------------------------------------
- color_type* generate(int x, int y, unsigned len)
- {
- base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
- y + base_type::filter_dy_dbl(), len);
-
- long_type fg[4];
- value_type back_r = base_type::background_color().r;
- value_type back_g = base_type::background_color().g;
- value_type back_b = base_type::background_color().b;
- value_type back_a = base_type::background_color().a;
-
- color_type* span = base_type::allocator().span();
-
- int diameter = base_type::filter().diameter();
- int filter_size = diameter << image_subpixel_shift;
- int radius_x = (diameter * base_type::m_rx) >> 1;
- int radius_y = (diameter * base_type::m_ry) >> 1;
- int maxx = base_type::source_image().width() - 1;
- int maxy = base_type::source_image().height() - 1;
-
- const int16* weight_array = base_type::filter().weight_array();
-
- do
- {
- base_type::interpolator().coordinates(&x, &y);
-
- x += base_type::filter_dx_int() - radius_x;
- y += base_type::filter_dy_int() - radius_y;
-
- fg[0] = fg[1] = fg[2] = fg[3] = image_filter_size / 2;
-
- int y_lr = y >> image_subpixel_shift;
- int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) *
- base_type::m_ry_inv) >>
- image_subpixel_shift;
- int total_weight = 0;
- int x_lr_ini = x >> image_subpixel_shift;
- int x_hr_ini = ((image_subpixel_mask - (x & image_subpixel_mask)) *
- base_type::m_rx_inv) >>
- image_subpixel_shift;
- do
- {
- int weight_y = weight_array[y_hr];
- int x_lr = x_lr_ini;
- int x_hr = x_hr_ini;
- if(y_lr >= 0 && y_lr <= maxy)
- {
- const value_type* fg_ptr = (const value_type*)
- base_type::source_image().row(y_lr) + (x_lr << 2);
- do
- {
- int weight = (weight_y * weight_array[x_hr] +
- image_filter_size / 2) >>
- downscale_shift;
-
- if(x_lr >= 0 && x_lr <= maxx)
- {
- fg[0] += fg_ptr[0] * weight;
- fg[1] += fg_ptr[1] * weight;
- fg[2] += fg_ptr[2] * weight;
- fg[3] += fg_ptr[3] * weight;
- }
- else
- {
- fg[order_type::R] += back_r * weight;
- fg[order_type::G] += back_g * weight;
- fg[order_type::B] += back_b * weight;
- fg[order_type::A] += back_a * weight;
- }
- total_weight += weight;
- fg_ptr += 4;
- x_hr += base_type::m_rx_inv;
- ++x_lr;
- }
- while(x_hr < filter_size);
- }
- else
- {
- do
- {
- int weight = (weight_y * weight_array[x_hr] +
- image_filter_size / 2) >>
- downscale_shift;
-
- total_weight += weight;
- fg[order_type::R] += back_r * weight;
- fg[order_type::G] += back_g * weight;
- fg[order_type::B] += back_b * weight;
- fg[order_type::A] += back_a * weight;
- x_hr += base_type::m_rx_inv;
- }
- while(x_hr < filter_size);
- }
- y_hr += base_type::m_ry_inv;
- ++y_lr;
- }
- while(y_hr < filter_size);
-
- fg[0] /= total_weight;
- fg[1] /= total_weight;
- fg[2] /= total_weight;
- fg[3] /= total_weight;
-
- if(fg[0] < 0) fg[0] = 0;
- if(fg[1] < 0) fg[1] = 0;
- if(fg[2] < 0) fg[2] = 0;
- if(fg[3] < 0) fg[3] = 0;
-
- if(fg[order_type::A] > base_mask) fg[order_type::A] = base_mask;
- if(fg[order_type::R] > fg[order_type::A]) fg[order_type::R] = fg[order_type::A];
- if(fg[order_type::G] > fg[order_type::A]) fg[order_type::G] = fg[order_type::A];
- if(fg[order_type::B] > fg[order_type::A]) fg[order_type::B] = fg[order_type::A];
-
- span->r = (value_type)fg[order_type::R];
- span->g = (value_type)fg[order_type::G];
- span->b = (value_type)fg[order_type::B];
- span->a = (value_type)fg[order_type::A];
-
- ++span;
- ++base_type::interpolator();
- } while(--len);
- return base_type::allocator().span();
- }
- };
-
-
-
-
-
-
-
- //==============================================span_image_resample_rgba
- template<class ColorT,
- class Order,
- class Interpolator,
- class Allocator = span_allocator<ColorT> >
- class span_image_resample_rgba :
- public span_image_resample<ColorT, Interpolator, Allocator>
- {
- public:
- typedef ColorT color_type;
- typedef Order order_type;
- typedef Interpolator interpolator_type;
- typedef Allocator alloc_type;
- typedef span_image_resample<color_type, interpolator_type, alloc_type> base_type;
- typedef typename color_type::value_type value_type;
- typedef typename color_type::long_type long_type;
- enum
- {
- base_shift = color_type::base_shift,
- base_mask = color_type::base_mask,
- downscale_shift = image_filter_shift
- };
-
- //--------------------------------------------------------------------
- span_image_resample_rgba(alloc_type& alloc) :
- base_type(alloc)
- {}
-
- //--------------------------------------------------------------------
- span_image_resample_rgba(alloc_type& alloc,
- const rendering_buffer& src,
- const color_type& back_color,
- interpolator_type& inter,
- const image_filter_lut& filter) :
- base_type(alloc, src, back_color, inter, filter)
- {}
-
- //--------------------------------------------------------------------
- color_type* generate(int x, int y, unsigned len)
- {
- color_type* span = base_type::allocator().span();
- base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
- y + base_type::filter_dy_dbl(), len);
- long_type fg[4];
- value_type back_r = base_type::background_color().r;
- value_type back_g = base_type::background_color().g;
- value_type back_b = base_type::background_color().b;
- value_type back_a = base_type::background_color().a;
-
- int diameter = base_type::filter().diameter();
- int filter_size = diameter << image_subpixel_shift;
-
- const int16* weight_array = base_type::filter().weight_array();
-
- do
- {
- int rx;
- int ry;
- int rx_inv = image_subpixel_size;
- int ry_inv = image_subpixel_size;
- base_type::interpolator().coordinates(&x, &y);
- base_type::interpolator().local_scale(&rx, &ry);
-
- rx = (rx * base_type::m_blur_x) >> image_subpixel_shift;
- ry = (ry * base_type::m_blur_y) >> image_subpixel_shift;
-
- if(rx < image_subpixel_size)
- {
- rx = image_subpixel_size;
- }
- else
- {
- if(rx > image_subpixel_size * base_type::m_scale_limit)
- {
- rx = image_subpixel_size * base_type::m_scale_limit;
- }
- rx_inv = image_subpixel_size * image_subpixel_size / rx;
- }
-
- if(ry < image_subpixel_size)
- {
- ry = image_subpixel_size;
- }
- else
- {
- if(ry > image_subpixel_size * base_type::m_scale_limit)
- {
- ry = image_subpixel_size * base_type::m_scale_limit;
- }
- ry_inv = image_subpixel_size * image_subpixel_size / ry;
- }
-
- int radius_x = (diameter * rx) >> 1;
- int radius_y = (diameter * ry) >> 1;
- int maxx = base_type::source_image().width() - 1;
- int maxy = base_type::source_image().height() - 1;
-
- x += base_type::filter_dx_int() - radius_x;
- y += base_type::filter_dy_int() - radius_y;
-
- fg[0] = fg[1] = fg[2] = fg[3] = image_filter_size / 2;
-
- int y_lr = y >> image_subpixel_shift;
- int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) *
- ry_inv) >>
- image_subpixel_shift;
- int total_weight = 0;
- int x_lr_ini = x >> image_subpixel_shift;
- int x_hr_ini = ((image_subpixel_mask - (x & image_subpixel_mask)) *
- rx_inv) >>
- image_subpixel_shift;
-
- do
- {
- int weight_y = weight_array[y_hr];
- int x_lr = x_lr_ini;
- int x_hr = x_hr_ini;
- if(y_lr >= 0 && y_lr <= maxy)
- {
- const value_type* fg_ptr = (const value_type*)
- base_type::source_image().row(y_lr) + (x_lr << 2);
- do
- {
- int weight = (weight_y * weight_array[x_hr] +
- image_filter_size / 2) >>
- downscale_shift;
-
- if(x_lr >= 0 && x_lr <= maxx)
- {
- fg[0] += fg_ptr[0] * weight;
- fg[1] += fg_ptr[1] * weight;
- fg[2] += fg_ptr[2] * weight;
- fg[3] += fg_ptr[3] * weight;
- }
- else
- {
- fg[order_type::R] += back_r * weight;
- fg[order_type::G] += back_g * weight;
- fg[order_type::B] += back_b * weight;
- fg[order_type::A] += back_a * weight;
- }
- total_weight += weight;
- fg_ptr += 4;
- x_hr += rx_inv;
- ++x_lr;
- }
- while(x_hr < filter_size);
- }
- else
- {
- do
- {
- int weight = (weight_y * weight_array[x_hr] +
- image_filter_size / 2) >>
- downscale_shift;
-
- total_weight += weight;
- fg[order_type::R] += back_r * weight;
- fg[order_type::G] += back_g * weight;
- fg[order_type::B] += back_b * weight;
- fg[order_type::A] += back_a * weight;
- x_hr += rx_inv;
- }
- while(x_hr < filter_size);
- }
- y_hr += ry_inv;
- ++y_lr;
- }
- while(y_hr < filter_size);
-
- fg[0] /= total_weight;
- fg[1] /= total_weight;
- fg[2] /= total_weight;
- fg[3] /= total_weight;
-
- if(fg[0] < 0) fg[0] = 0;
- if(fg[1] < 0) fg[1] = 0;
- if(fg[2] < 0) fg[2] = 0;
- if(fg[3] < 0) fg[3] = 0;
-
- if(fg[order_type::A] > base_mask) fg[order_type::A] = base_mask;
- if(fg[order_type::R] > fg[order_type::R]) fg[order_type::R] = fg[order_type::R];
- if(fg[order_type::G] > fg[order_type::G]) fg[order_type::G] = fg[order_type::G];
- if(fg[order_type::B] > fg[order_type::B]) fg[order_type::B] = fg[order_type::B];
-
- span->r = (value_type)fg[order_type::R];
- span->g = (value_type)fg[order_type::G];
- span->b = (value_type)fg[order_type::B];
- span->a = (value_type)fg[order_type::A];
-
- ++span;
- ++base_type::interpolator();
- } while(--len);
- return base_type::allocator().span();
- }
-
- };
-
-}
-
-
-#endif
diff --git a/agg/inc/agg_span_interpolator_adaptor.h b/agg/inc/agg_span_interpolator_adaptor.h
index ead42c13590c..5626f9829cda 100755
--- a/agg/inc/agg_span_interpolator_adaptor.h
+++ b/agg/inc/agg_span_interpolator_adaptor.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
diff --git a/agg/inc/agg_span_interpolator_linear.h b/agg/inc/agg_span_interpolator_linear.h
index 3cc2426be450..5bbbdf62d6fd 100755
--- a/agg/inc/agg_span_interpolator_linear.h
+++ b/agg/inc/agg_span_interpolator_linear.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -30,10 +30,10 @@ namespace agg
public:
typedef Transformer trans_type;
- enum
+ enum subpixel_scale_e
{
subpixel_shift = SubpixelShift,
- subpixel_size = 1 << subpixel_shift
+ subpixel_scale = 1 << subpixel_shift
};
//--------------------------------------------------------------------
@@ -59,14 +59,14 @@ namespace agg
tx = x;
ty = y;
m_trans->transform(&tx, &ty);
- int x1 = int(tx * subpixel_size);
- int y1 = int(ty * subpixel_size);
+ int x1 = iround(tx * subpixel_scale);
+ int y1 = iround(ty * subpixel_scale);
tx = x + len;
ty = y;
m_trans->transform(&tx, &ty);
- int x2 = int(tx * subpixel_size);
- int y2 = int(ty * subpixel_size);
+ int x2 = iround(tx * subpixel_scale);
+ int y2 = iround(ty * subpixel_scale);
m_li_x = dda2_line_interpolator(x1, x2, len);
m_li_y = dda2_line_interpolator(y1, y2, len);
@@ -76,8 +76,8 @@ namespace agg
void resynchronize(double xe, double ye, unsigned len)
{
m_trans->transform(&xe, &ye);
- m_li_x = dda2_line_interpolator(m_li_x.y(), int(xe * subpixel_size), len);
- m_li_y = dda2_line_interpolator(m_li_y.y(), int(ye * subpixel_size), len);
+ m_li_x = dda2_line_interpolator(m_li_x.y(), iround(xe * subpixel_scale), len);
+ m_li_y = dda2_line_interpolator(m_li_y.y(), iround(ye * subpixel_scale), len);
}
//----------------------------------------------------------------
@@ -112,10 +112,10 @@ namespace agg
public:
typedef Transformer trans_type;
- enum
+ enum subpixel_scale_e
{
subpixel_shift = SubpixelShift,
- subpixel_size = 1 << subpixel_shift
+ subpixel_scale = 1 << subpixel_shift
};
@@ -162,7 +162,7 @@ namespace agg
double tx;
double ty;
m_pos = 1;
- m_src_x = int(x * subpixel_size) + subpixel_size;
+ m_src_x = iround(x * subpixel_scale) + subpixel_scale;
m_src_y = y;
m_len = len;
@@ -170,15 +170,15 @@ namespace agg
tx = x;
ty = y;
m_trans->transform(&tx, &ty);
- int x1 = int(tx * subpixel_size);
- int y1 = int(ty * subpixel_size);
+ int x1 = iround(tx * subpixel_scale);
+ int y1 = iround(ty * subpixel_scale);
tx = x + len;
ty = y;
m_trans->transform(&tx, &ty);
- m_li_x = dda2_line_interpolator(x1, int(tx * subpixel_size), len);
- m_li_y = dda2_line_interpolator(y1, int(ty * subpixel_size), len);
+ m_li_x = dda2_line_interpolator(x1, iround(tx * subpixel_scale), len);
+ m_li_y = dda2_line_interpolator(y1, iround(ty * subpixel_scale), len);
}
//----------------------------------------------------------------
@@ -190,14 +190,14 @@ namespace agg
{
unsigned len = m_len;
if(len > m_subdiv_size) len = m_subdiv_size;
- double tx = double(m_src_x) / double(subpixel_size) + len;
+ double tx = double(m_src_x) / double(subpixel_scale) + len;
double ty = m_src_y;
m_trans->transform(&tx, &ty);
- m_li_x = dda2_line_interpolator(m_li_x.y(), int(tx * subpixel_size), len);
- m_li_y = dda2_line_interpolator(m_li_y.y(), int(ty * subpixel_size), len);
+ m_li_x = dda2_line_interpolator(m_li_x.y(), iround(tx * subpixel_scale), len);
+ m_li_y = dda2_line_interpolator(m_li_y.y(), iround(ty * subpixel_scale), len);
m_pos = 0;
}
- m_src_x += subpixel_size;
+ m_src_x += subpixel_scale;
++m_pos;
--m_len;
}
diff --git a/agg/inc/agg_span_interpolator_persp.h b/agg/inc/agg_span_interpolator_persp.h
index 632a56449f28..6c43687f11da 100755
--- a/agg/inc/agg_span_interpolator_persp.h
+++ b/agg/inc/agg_span_interpolator_persp.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -30,10 +30,10 @@ namespace agg
public:
typedef trans_perspective trans_type;
typedef trans_perspective::iterator_x iterator_type;
- enum
+ enum subpixel_scale_e
{
subpixel_shift = SubpixelShift,
- subpixel_size = 1 << subpixel_shift
+ subpixel_scale = 1 << subpixel_shift
};
//--------------------------------------------------------------------
@@ -112,19 +112,19 @@ namespace agg
double dx;
double dy;
- const double delta = 1/double(subpixel_size);
+ const double delta = 1/double(subpixel_scale);
dx = xt + delta;
dy = yt;
m_trans_inv.transform(&dx, &dy);
dx -= x;
dy -= y;
- int sx1 = int(subpixel_size/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
+ int sx1 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
dx = xt;
dy = yt + delta;
m_trans_inv.transform(&dx, &dy);
dx -= x;
dy -= y;
- int sy1 = int(subpixel_size/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
+ int sy1 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
x += len;
xt = x;
@@ -136,13 +136,13 @@ namespace agg
m_trans_inv.transform(&dx, &dy);
dx -= x;
dy -= y;
- int sx2 = int(subpixel_size/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
+ int sx2 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
dx = xt;
dy = yt + delta;
m_trans_inv.transform(&dx, &dy);
dx -= x;
dy -= y;
- int sy2 = int(subpixel_size/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
+ int sy2 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
m_scale_x = dda2_line_interpolator(sx1, sx2, len);
m_scale_y = dda2_line_interpolator(sy1, sy2, len);
@@ -161,7 +161,7 @@ namespace agg
double yt = ye;
m_trans_dir.transform(&xt, &yt);
- const double delta = 1/double(subpixel_size);
+ const double delta = 1/double(subpixel_scale);
double dx;
double dy;
@@ -171,7 +171,7 @@ namespace agg
m_trans_inv.transform(&dx, &dy);
dx -= xe;
dy -= ye;
- int sx2 = int(subpixel_size/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
+ int sx2 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
// Calculate scale by Y at x2,y2
dx = xt;
@@ -179,7 +179,7 @@ namespace agg
m_trans_inv.transform(&dx, &dy);
dx -= xe;
dy -= ye;
- int sy2 = int(subpixel_size/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
+ int sy2 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
// Initialize the interpolators
m_scale_x = dda2_line_interpolator(sx1, sx2, len);
@@ -199,8 +199,8 @@ namespace agg
//----------------------------------------------------------------
void coordinates(int* x, int* y) const
{
- *x = int(m_iterator.x * subpixel_size + 0.5);
- *y = int(m_iterator.y * subpixel_size + 0.5);
+ *x = iround(m_iterator.x * subpixel_scale);
+ *y = iround(m_iterator.y * subpixel_scale);
}
//----------------------------------------------------------------
@@ -240,10 +240,10 @@ namespace agg
{
public:
typedef trans_perspective trans_type;
- enum
+ enum subpixel_scale_e
{
subpixel_shift = SubpixelShift,
- subpixel_size = 1 << subpixel_shift
+ subpixel_scale = 1 << subpixel_shift
};
//--------------------------------------------------------------------
@@ -320,12 +320,12 @@ namespace agg
double xt = x;
double yt = y;
m_trans_dir.transform(&xt, &yt);
- int x1 = int(xt * subpixel_size);
- int y1 = int(yt * subpixel_size);
+ int x1 = iround(xt * subpixel_scale);
+ int y1 = iround(yt * subpixel_scale);
double dx;
double dy;
- const double delta = 1/double(subpixel_size);
+ const double delta = 1/double(subpixel_scale);
// Calculate scale by X at x1,y1
dx = xt + delta;
@@ -333,7 +333,7 @@ namespace agg
m_trans_inv.transform(&dx, &dy);
dx -= x;
dy -= y;
- int sx1 = int(subpixel_size/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
+ int sx1 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
// Calculate scale by Y at x1,y1
dx = xt;
@@ -341,15 +341,15 @@ namespace agg
m_trans_inv.transform(&dx, &dy);
dx -= x;
dy -= y;
- int sy1 = int(subpixel_size/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
+ int sy1 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
// Calculate transformed coordinates at x2,y2
x += len;
xt = x;
yt = y;
m_trans_dir.transform(&xt, &yt);
- int x2 = int(xt * subpixel_size);
- int y2 = int(yt * subpixel_size);
+ int x2 = iround(xt * subpixel_scale);
+ int y2 = iround(yt * subpixel_scale);
// Calculate scale by X at x2,y2
dx = xt + delta;
@@ -357,7 +357,7 @@ namespace agg
m_trans_inv.transform(&dx, &dy);
dx -= x;
dy -= y;
- int sx2 = int(subpixel_size/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
+ int sx2 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
// Calculate scale by Y at x2,y2
dx = xt;
@@ -365,7 +365,7 @@ namespace agg
m_trans_inv.transform(&dx, &dy);
dx -= x;
dy -= y;
- int sy2 = int(subpixel_size/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
+ int sy2 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
// Initialize the interpolators
m_coord_x = dda2_line_interpolator(x1, x2, len);
@@ -388,10 +388,10 @@ namespace agg
double xt = xe;
double yt = ye;
m_trans_dir.transform(&xt, &yt);
- int x2 = int(xt * subpixel_size);
- int y2 = int(yt * subpixel_size);
+ int x2 = iround(xt * subpixel_scale);
+ int y2 = iround(yt * subpixel_scale);
- const double delta = 1/double(subpixel_size);
+ const double delta = 1/double(subpixel_scale);
double dx;
double dy;
@@ -401,7 +401,7 @@ namespace agg
m_trans_inv.transform(&dx, &dy);
dx -= xe;
dy -= ye;
- int sx2 = int(subpixel_size/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
+ int sx2 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
// Calculate scale by Y at x2,y2
dx = xt;
@@ -409,7 +409,7 @@ namespace agg
m_trans_inv.transform(&dx, &dy);
dx -= xe;
dy -= ye;
- int sy2 = int(subpixel_size/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
+ int sy2 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
// Initialize the interpolators
m_coord_x = dda2_line_interpolator(x1, x2, len);
diff --git a/agg/inc/agg_span_interpolator_trans.h b/agg/inc/agg_span_interpolator_trans.h
index 5caaffe9e5c0..353be406fdc1 100755
--- a/agg/inc/agg_span_interpolator_trans.h
+++ b/agg/inc/agg_span_interpolator_trans.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -31,10 +31,10 @@ namespace agg
{
public:
typedef Transformer trans_type;
- enum
+ enum subpixel_scale_e
{
subpixel_shift = SubpixelShift,
- subpixel_size = 1 << subpixel_shift
+ subpixel_scale = 1 << subpixel_shift
};
//--------------------------------------------------------------------
@@ -57,13 +57,8 @@ namespace agg
m_x = x;
m_y = y;
m_trans->transform(&x, &y);
- m_ix = int(x * subpixel_size);
- m_iy = int(y * subpixel_size);
- }
-
- //----------------------------------------------------------------
- void next(double, double, unsigned)
- {
+ m_ix = iround(x * subpixel_scale);
+ m_iy = iround(y * subpixel_scale);
}
//----------------------------------------------------------------
@@ -73,8 +68,8 @@ namespace agg
double x = m_x;
double y = m_y;
m_trans->transform(&x, &y);
- m_ix = int(x * subpixel_size);
- m_iy = int(y * subpixel_size);
+ m_ix = iround(x * subpixel_scale);
+ m_iy = iround(y * subpixel_scale);
}
//----------------------------------------------------------------
diff --git a/agg/inc/agg_span_pattern.h b/agg/inc/agg_span_pattern.h
deleted file mode 100755
index b9e9b135ff84..000000000000
--- a/agg/inc/agg_span_pattern.h
+++ /dev/null
@@ -1,278 +0,0 @@
-//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
-// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
-//
-// Permission to copy, use, modify, sell and distribute this software
-// is granted provided this copyright notice appears in all copies.
-// This software is provided "as is" without express or implied
-// warranty, and with no claim as to its suitability for any purpose.
-//
-//----------------------------------------------------------------------------
-// Contact: mcseem@antigrain.com
-// mcseemagg@yahoo.com
-// http://www.antigrain.com
-//----------------------------------------------------------------------------
-//
-// Adaptation for high precision colors has been sponsored by
-// Liberty Technology Systems, Inc., visit http://lib-sys.com
-//
-// Liberty Technology Systems, Inc. is the provider of
-// PostScript and PDF technology for software developers.
-//
-//----------------------------------------------------------------------------
-
-
-#ifndef AGG_SPAN_PATTERN_INCLUDED
-#define AGG_SPAN_PATTERN_INCLUDED
-
-#include "agg_basics.h"
-#include "agg_rendering_buffer.h"
-#include "agg_span_generator.h"
-
-
-namespace agg
-{
-
- //---------------------------------------------------span_pattern_base
- template<class ColorT, class Allocator>
- class span_pattern_base : public span_generator<ColorT, Allocator>
- {
- public:
- typedef ColorT color_type;
- typedef typename ColorT::value_type value_type;
- typedef Allocator alloc_type;
- enum { base_mask = color_type::base_mask };
-
- //----------------------------------------------------------------
- span_pattern_base(alloc_type& alloc) :
- span_generator<color_type, alloc_type>(alloc)
- {}
-
- //----------------------------------------------------------------
- span_pattern_base(alloc_type& alloc,
- const rendering_buffer& src,
- unsigned offset_x, unsigned offset_y,
- double alpha) :
- span_generator<color_type, alloc_type>(alloc),
- m_src(&src),
- m_offset_x(offset_x),
- m_offset_y(offset_y),
- m_alpha(value_type(alpha * double(base_mask)))
- {}
-
- //----------------------------------------------------------------
- const rendering_buffer& source_image() const { return *m_src; }
- unsigned offset_x() const { return m_offset_x; }
- unsigned offset_y() const { return m_offset_y; }
- double alpha() const { return m_alpha / double(base_mask); }
- value_type alpha_int() const { return m_alpha; }
-
- //----------------------------------------------------------------
- void source_image(const rendering_buffer& v) { m_src = &v; }
- void offset_x(unsigned v) { m_offset_x = v; }
- void offset_y(unsigned v) { m_offset_y = v; }
- void alpha(double v) { m_alpha = value_type(v * double(base_mask)); }
-
- //----------------------------------------------------------------
- private:
- const rendering_buffer* m_src;
- unsigned m_offset_x;
- unsigned m_offset_y;
- value_type m_alpha;
- };
-
-
- //---------------------------------------------------wrap_mode_repeat
- class wrap_mode_repeat
- {
- public:
- wrap_mode_repeat(unsigned size) :
- m_size(size),
- m_add(size * (0x3FFFFFFF / size)),
- m_value(0)
- {}
-
- AGG_INLINE unsigned operator() (int v)
- {
- return m_value = (unsigned(v) + m_add) % m_size;
- }
-
- AGG_INLINE unsigned operator++ ()
- {
- ++m_value;
- if(m_value >= m_size) m_value = 0;
- return m_value;
- }
- private:
- unsigned m_size;
- unsigned m_add;
- unsigned m_value;
- };
-
-
- //---------------------------------------------wrap_mode_repeat_pow2
- class wrap_mode_repeat_pow2
- {
- public:
- wrap_mode_repeat_pow2(unsigned size) : m_value(0)
- {
- m_mask = 1;
- while(m_mask < size) m_mask = (m_mask << 1) | 1;
- m_mask >>= 1;
- }
- AGG_INLINE unsigned operator() (int v)
- {
- return m_value = unsigned(v) & m_mask;
- }
- AGG_INLINE unsigned operator++ ()
- {
- ++m_value;
- if(m_value > m_mask) m_value = 0;
- return m_value;
- }
- private:
- unsigned m_mask;
- unsigned m_value;
- };
-
-
- //----------------------------------------wrap_mode_repeat_auto_pow2
- class wrap_mode_repeat_auto_pow2
- {
- public:
- wrap_mode_repeat_auto_pow2(unsigned size) :
- m_size(size),
- m_add(size * (0x3FFFFFFF / size)),
- m_mask((m_size & (m_size-1)) ? 0 : m_size-1),
- m_value(0)
- {}
-
- AGG_INLINE unsigned operator() (int v)
- {
- if(m_mask) return m_value = unsigned(v) & m_mask;
- return m_value = (unsigned(v) + m_add) % m_size;
- }
- AGG_INLINE unsigned operator++ ()
- {
- ++m_value;
- if(m_value >= m_size) m_value = 0;
- return m_value;
- }
-
- private:
- unsigned m_size;
- unsigned m_add;
- unsigned m_mask;
- unsigned m_value;
- };
-
-
- //--------------------------------------------------wrap_mode_reflect
- class wrap_mode_reflect
- {
- public:
- wrap_mode_reflect(unsigned size) :
- m_size(size),
- m_size2(size * 2),
- m_add(m_size2 * (0x3FFFFFFF / m_size2)),
- m_value(0)
- {}
-
- AGG_INLINE unsigned operator() (int v)
- {
- m_value = (unsigned(v) + m_add) % m_size2;
- if(m_value >= m_size) return m_size2 - m_value - 1;
- return m_value;
- }
-
- AGG_INLINE unsigned operator++ ()
- {
- ++m_value;
- if(m_value >= m_size2) m_value = 0;
- if(m_value >= m_size) return m_size2 - m_value - 1;
- return m_value;
- }
- private:
- unsigned m_size;
- unsigned m_size2;
- unsigned m_add;
- unsigned m_value;
- };
-
-
-
- //-------------------------------------------wrap_mode_reflect_pow2
- class wrap_mode_reflect_pow2
- {
- public:
- wrap_mode_reflect_pow2(unsigned size) : m_value(0)
- {
- m_mask = 1;
- m_size = 1;
- while(m_mask < size)
- {
- m_mask = (m_mask << 1) | 1;
- m_size <<= 1;
- }
- }
- AGG_INLINE unsigned operator() (int v)
- {
- m_value = unsigned(v) & m_mask;
- if(m_value >= m_size) return m_mask - m_value;
- return m_value;
- }
- AGG_INLINE unsigned operator++ ()
- {
- ++m_value;
- m_value &= m_mask;
- if(m_value >= m_size) return m_mask - m_value;
- return m_value;
- }
- private:
- unsigned m_size;
- unsigned m_mask;
- unsigned m_value;
- };
-
-
-
- //---------------------------------------wrap_mode_reflect_auto_pow2
- class wrap_mode_reflect_auto_pow2
- {
- public:
- wrap_mode_reflect_auto_pow2(unsigned size) :
- m_size(size),
- m_size2(size * 2),
- m_add(m_size2 * (0x3FFFFFFF / m_size2)),
- m_mask((m_size2 & (m_size2-1)) ? 0 : m_size2-1),
- m_value(0)
- {}
-
- AGG_INLINE unsigned operator() (int v)
- {
- m_value = m_mask ? unsigned(v) & m_mask :
- (unsigned(v) + m_add) % m_size2;
- if(m_value >= m_size) return m_size2 - m_value - 1;
- return m_value;
- }
- AGG_INLINE unsigned operator++ ()
- {
- ++m_value;
- if(m_value >= m_size2) m_value = 0;
- if(m_value >= m_size) return m_size2 - m_value - 1;
- return m_value;
- }
-
- private:
- unsigned m_size;
- unsigned m_size2;
- unsigned m_add;
- unsigned m_mask;
- unsigned m_value;
- };
-
-
-}
-
-#endif
-
diff --git a/agg/inc/agg_span_pattern_filter_gray.h b/agg/inc/agg_span_pattern_filter_gray.h
deleted file mode 100755
index 17a7984be7fe..000000000000
--- a/agg/inc/agg_span_pattern_filter_gray.h
+++ /dev/null
@@ -1,472 +0,0 @@
-//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
-// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
-//
-// Permission to copy, use, modify, sell and distribute this software
-// is granted provided this copyright notice appears in all copies.
-// This software is provided "as is" without express or implied
-// warranty, and with no claim as to its suitability for any purpose.
-//
-//----------------------------------------------------------------------------
-// Contact: mcseem@antigrain.com
-// mcseemagg@yahoo.com
-// http://www.antigrain.com
-//----------------------------------------------------------------------------
-//
-// classes span_pattern_filter_gray*
-//
-//----------------------------------------------------------------------------
-#ifndef AGG_SPAN_PATTERN_FILTER_GRAY_INCLUDED
-#define AGG_SPAN_PATTERN_FILTER_GRAY_INCLUDED
-
-#include "agg_basics.h"
-#include "agg_color_gray.h"
-#include "agg_span_pattern.h"
-#include "agg_span_image_filter.h"
-
-
-namespace agg
-{
-
- //===========================================span_pattern_filter_gray
- template<class ColorT,
- class Interpolator,
- class WrapModeX,
- class WrapModeY,
- class Allocator = span_allocator<ColorT> >
- class span_pattern_filter_gray_nn :
- public span_image_filter<ColorT, Interpolator, Allocator>
- {
- public:
- typedef ColorT color_type;
- typedef Interpolator interpolator_type;
- typedef Allocator alloc_type;
- typedef span_image_filter<color_type, interpolator_type, alloc_type> base_type;
- typedef typename color_type::value_type value_type;
- typedef typename color_type::calc_type calc_type;
- enum
- {
- base_shift = color_type::base_shift,
- base_mask = color_type::base_mask
- };
-
- //--------------------------------------------------------------------
- span_pattern_filter_gray_nn(alloc_type& alloc) :
- base_type(alloc),
- m_wrap_mode_x(1),
- m_wrap_mode_y(1)
- {}
-
- //--------------------------------------------------------------------
- span_pattern_filter_gray_nn(alloc_type& alloc,
- const rendering_buffer& src,
- interpolator_type& inter) :
- base_type(alloc, src, color_type(0,0), inter, 0),
- m_wrap_mode_x(src.width()),
- m_wrap_mode_y(src.height())
- {}
-
- //--------------------------------------------------------------------
- void source_image(const rendering_buffer& src)
- {
- base_type::source_image(src);
- m_wrap_mode_x = WrapModeX(src.width());
- m_wrap_mode_y = WrapModeX(src.height());
- }
-
- //--------------------------------------------------------------------
- color_type* generate(int x, int y, unsigned len)
- {
- base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
- y + base_type::filter_dy_dbl(), len);
- color_type* span = base_type::allocator().span();
- do
- {
- base_type::interpolator().coordinates(&x, &y);
-
- x = m_wrap_mode_x(x >> image_subpixel_shift);
- y = m_wrap_mode_y(y >> image_subpixel_shift);
-
- span->v = *((value_type*)base_type::source_image().row(y) + x);
- span->a = base_mask;
- ++span;
- ++base_type::interpolator();
-
- } while(--len);
-
- return base_type::allocator().span();
- }
-
- private:
- WrapModeX m_wrap_mode_x;
- WrapModeY m_wrap_mode_y;
- };
-
-
-
-
-
-
- //====================================span_pattern_filter_gray_bilinear
- template<class ColorT,
- class Interpolator,
- class WrapModeX,
- class WrapModeY,
- class Allocator = span_allocator<ColorT> >
- class span_pattern_filter_gray_bilinear :
- public span_image_filter<ColorT, Interpolator, Allocator>
- {
- public:
- typedef ColorT color_type;
- typedef Interpolator interpolator_type;
- typedef Allocator alloc_type;
- typedef span_image_filter<color_type, interpolator_type, alloc_type> base_type;
- typedef typename color_type::value_type value_type;
- typedef typename color_type::calc_type calc_type;
- enum
- {
- base_shift = color_type::base_shift,
- base_mask = color_type::base_mask
- };
-
- //--------------------------------------------------------------------
- span_pattern_filter_gray_bilinear(alloc_type& alloc) :
- base_type(alloc),
- m_wrap_mode_x(1),
- m_wrap_mode_y(1)
- {}
-
- //--------------------------------------------------------------------
- span_pattern_filter_gray_bilinear(alloc_type& alloc,
- const rendering_buffer& src,
- interpolator_type& inter) :
- base_type(alloc, src, color_type(0,0), inter, 0),
- m_wrap_mode_x(src.width()),
- m_wrap_mode_y(src.height())
- {}
-
- //-------------------------------------------------------------------
- void source_image(const rendering_buffer& src)
- {
- base_type::source_image(src);
- m_wrap_mode_x = WrapModeX(src.width());
- m_wrap_mode_y = WrapModeX(src.height());
- }
-
- //--------------------------------------------------------------------
- color_type* generate(int x, int y, unsigned len)
- {
- base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
- y + base_type::filter_dy_dbl(), len);
- calc_type fg;
- color_type* span = base_type::allocator().span();
- do
- {
- int x_hr;
- int y_hr;
-
- 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;
-
- unsigned x1 = m_wrap_mode_x(x_lr);
- unsigned x2 = ++m_wrap_mode_x;
-
- unsigned y1 = m_wrap_mode_y(y_lr);
- unsigned y2 = ++m_wrap_mode_y;
- const value_type* ptr1 = (value_type*)base_type::source_image().row(y1);
- const value_type* ptr2 = (value_type*)base_type::source_image().row(y2);
-
- fg = image_subpixel_size * image_subpixel_size / 2;
-
- x_hr &= image_subpixel_mask;
- y_hr &= image_subpixel_mask;
-
- fg += ptr1[x1] * (image_subpixel_size - x_hr) * (image_subpixel_size - y_hr);
- fg += ptr1[x2] * x_hr * (image_subpixel_size - y_hr);
- fg += ptr2[x1] * (image_subpixel_size - x_hr) * y_hr;
- fg += ptr2[x2] * x_hr * y_hr;
-
- span->v = (value_type)(fg >> image_subpixel_shift * 2);
- span->a = base_mask;
- ++span;
- ++base_type::interpolator();
-
- } while(--len);
-
- return base_type::allocator().span();
- }
- private:
- WrapModeX m_wrap_mode_x;
- WrapModeY m_wrap_mode_y;
- };
-
-
-
-
-
-
-
-
-
- //====================================span_pattern_filter_gray_2x2
- template<class ColorT,
- class Interpolator,
- class WrapModeX,
- class WrapModeY,
- class Allocator = span_allocator<ColorT> >
- class span_pattern_filter_gray_2x2 :
- public span_image_filter<ColorT, Interpolator, Allocator>
- {
- public:
- typedef ColorT color_type;
- typedef Interpolator interpolator_type;
- typedef Allocator alloc_type;
- typedef span_image_filter<color_type, interpolator_type, alloc_type> base_type;
- typedef typename color_type::value_type value_type;
- typedef typename color_type::calc_type calc_type;
- enum
- {
- base_shift = color_type::base_shift,
- base_mask = color_type::base_mask
- };
-
- //--------------------------------------------------------------------
- span_pattern_filter_gray_2x2(alloc_type& alloc) :
- base_type(alloc),
- m_wrap_mode_x(1),
- m_wrap_mode_y(1)
- {}
-
- //--------------------------------------------------------------------
- span_pattern_filter_gray_2x2(alloc_type& alloc,
- const rendering_buffer& src,
- interpolator_type& inter,
- const image_filter_lut& filter) :
- base_type(alloc, src, color_type(0,0), inter, &filter),
- m_wrap_mode_x(src.width()),
- m_wrap_mode_y(src.height())
- {}
-
- //-------------------------------------------------------------------
- void source_image(const rendering_buffer& src)
- {
- base_type::source_image(src);
- m_wrap_mode_x = WrapModeX(src.width());
- m_wrap_mode_y = WrapModeX(src.height());
- }
-
- //--------------------------------------------------------------------
- color_type* generate(int x, int y, unsigned len)
- {
- base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
- y + base_type::filter_dy_dbl(), len);
- calc_type fg;
- color_type* span = base_type::allocator().span();
- const int16* weight_array = base_type::filter().weight_array() +
- ((base_type::filter().diameter()/2 - 1) <<
- image_subpixel_shift);
- do
- {
- int x_hr;
- int y_hr;
-
- 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;
-
- unsigned x1 = m_wrap_mode_x(x_lr);
- unsigned x2 = ++m_wrap_mode_x;
-
- unsigned y1 = m_wrap_mode_y(y_lr);
- unsigned y2 = ++m_wrap_mode_y;
- const value_type* ptr1 = (value_type*)base_type::source_image().row(y1);
- const value_type* ptr2 = (value_type*)base_type::source_image().row(y2);
-
- fg = image_filter_size / 2;
-
- x_hr &= image_subpixel_mask;
- y_hr &= image_subpixel_mask;
-
- fg += ptr1[x1] * ((weight_array[x_hr + image_subpixel_size] *
- weight_array[y_hr + image_subpixel_size] +
- image_filter_size / 2) >>
- image_filter_shift);
- fg += ptr1[x2] * ((weight_array[x_hr] *
- weight_array[y_hr + image_subpixel_size] +
- image_filter_size / 2) >>
- image_filter_shift);
- fg += ptr2[x1] * ((weight_array[x_hr + image_subpixel_size] *
- weight_array[y_hr] +
- image_filter_size / 2) >>
- image_filter_shift);
- fg += ptr2[x2] * ((weight_array[x_hr] *
- weight_array[y_hr] +
- image_filter_size / 2) >>
- image_filter_shift);
-
- fg >>= image_filter_shift;
- if(fg > base_mask) fg = base_mask;
-
- span->v = (value_type)fg;
- span->a = base_mask;
- ++span;
- ++base_type::interpolator();
-
- } while(--len);
-
- return base_type::allocator().span();
- }
- private:
- WrapModeX m_wrap_mode_x;
- WrapModeY m_wrap_mode_y;
- };
-
-
-
-
-
-
-
-
-
-
-
-
- //==============================================span_pattern_filter_gray
- template<class ColorT,
- class Interpolator,
- class WrapModeX,
- class WrapModeY,
- class Allocator = span_allocator<ColorT> >
- class span_pattern_filter_gray :
- public span_image_filter<ColorT, Interpolator, Allocator>
- {
- public:
- typedef ColorT color_type;
- typedef Interpolator interpolator_type;
- typedef Allocator alloc_type;
- typedef span_image_filter<color_type, interpolator_type, alloc_type> base_type;
- typedef typename color_type::value_type value_type;
- typedef typename color_type::calc_type calc_type;
- enum
- {
- base_shift = color_type::base_shift,
- base_mask = color_type::base_mask
- };
-
- //--------------------------------------------------------------------
- span_pattern_filter_gray(alloc_type& alloc) :
- base_type(alloc)
- {}
-
- //--------------------------------------------------------------------
- span_pattern_filter_gray(alloc_type& alloc,
- const rendering_buffer& src,
- interpolator_type& inter,
- const image_filter_lut& filter) :
- base_type(alloc, src, color_type(0,0), inter, &filter),
- m_wrap_mode_x(src.width()),
- m_wrap_mode_y(src.height())
- {}
-
- //--------------------------------------------------------------------
- void source_image(const rendering_buffer& src)
- {
- base_type::source_image(src);
- m_wrap_mode_x = WrapModeX(src.width());
- m_wrap_mode_y = WrapModeX(src.height());
- }
-
- //--------------------------------------------------------------------
- color_type* generate(int x, int y, unsigned len)
- {
- base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
- y + base_type::filter_dy_dbl(), len);
- int fg;
-
- unsigned diameter = base_type::filter().diameter();
- int start = base_type::filter().start();
- const int16* weight_array = base_type::filter().weight_array();
-
- color_type* span = base_type::allocator().span();
-
- int x_count;
- int weight_y;
-
- do
- {
- 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;
-
- int x_fract = x_hr & image_subpixel_mask;
- unsigned y_count = diameter;
-
- int y_lr = m_wrap_mode_y((y >> image_subpixel_shift) + start);
- int x_int = (x >> image_subpixel_shift) + start;
- int x_lr;
-
- y_hr = image_subpixel_mask - (y_hr & image_subpixel_mask);
- fg = image_filter_size / 2;
-
- do
- {
- x_count = diameter;
- weight_y = weight_array[y_hr];
- x_hr = image_subpixel_mask - x_fract;
- x_lr = m_wrap_mode_x(x_int);
- const value_type* row_ptr = (value_type*)base_type::source_image().row(y_lr);
- do
- {
- fg += row_ptr[x_lr] * ((weight_y * weight_array[x_hr] +
- image_filter_size / 2) >>
- image_filter_shift);
- x_hr += image_subpixel_size;
- x_lr = ++m_wrap_mode_x;
- } while(--x_count);
-
- y_hr += image_subpixel_size;
- y_lr = ++m_wrap_mode_y;
- } while(--y_count);
-
- fg >>= image_filter_shift;
-
- if(fg < 0) fg = 0;
- if(fg > base_mask) fg = base_mask;
-
- span->v = fg;
- span->a = base_mask;
- ++span;
- ++base_type::interpolator();
-
- } while(--len);
-
- return base_type::allocator().span();
- }
-
- private:
- WrapModeX m_wrap_mode_x;
- WrapModeY m_wrap_mode_y;
- };
-
-
-}
-
-
-#endif
-
-
-
diff --git a/agg/inc/agg_span_pattern_filter_rgb.h b/agg/inc/agg_span_pattern_filter_rgb.h
deleted file mode 100755
index d4dc1c1797eb..000000000000
--- a/agg/inc/agg_span_pattern_filter_rgb.h
+++ /dev/null
@@ -1,568 +0,0 @@
-//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
-// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
-//
-// Permission to copy, use, modify, sell and distribute this software
-// is granted provided this copyright notice appears in all copies.
-// This software is provided "as is" without express or implied
-// warranty, and with no claim as to its suitability for any purpose.
-//
-//----------------------------------------------------------------------------
-// Contact: mcseem@antigrain.com
-// mcseemagg@yahoo.com
-// http://www.antigrain.com
-//----------------------------------------------------------------------------
-//
-// Adaptation for high precision colors has been sponsored by
-// Liberty Technology Systems, Inc., visit http://lib-sys.com
-//
-// Liberty Technology Systems, Inc. is the provider of
-// PostScript and PDF technology for software developers.
-//
-//----------------------------------------------------------------------------
-//
-// classes span_pattern_filter_rgb*
-//
-//----------------------------------------------------------------------------
-#ifndef AGG_SPAN_PATTERN_FILTER_RGB_INCLUDED
-#define AGG_SPAN_PATTERN_FILTER_RGB_INCLUDED
-
-#include "agg_basics.h"
-#include "agg_color_rgba.h"
-#include "agg_span_pattern.h"
-#include "agg_span_image_filter.h"
-
-
-namespace agg
-{
-
- //===========================================span_pattern_filter_rgb
- template<class ColorT,
- class Order,
- class Interpolator,
- class WrapModeX,
- class WrapModeY,
- class Allocator = span_allocator<ColorT> >
- class span_pattern_filter_rgb_nn :
- public span_image_filter<ColorT, Interpolator, Allocator>
- {
- public:
- typedef ColorT color_type;
- typedef Order order_type;
- typedef Interpolator interpolator_type;
- typedef Allocator alloc_type;
- typedef span_image_filter<color_type, interpolator_type, alloc_type> base_type;
- typedef typename color_type::value_type value_type;
- typedef typename color_type::calc_type calc_type;
- enum
- {
- base_shift = color_type::base_shift,
- base_mask = color_type::base_mask
- };
-
- //--------------------------------------------------------------------
- span_pattern_filter_rgb_nn(alloc_type& alloc) :
- base_type(alloc),
- m_wrap_mode_x(1),
- m_wrap_mode_y(1)
- {}
-
- //--------------------------------------------------------------------
- span_pattern_filter_rgb_nn(alloc_type& alloc,
- const rendering_buffer& src,
- interpolator_type& intr) :
- base_type(alloc, src, color_type(0,0,0,0), intr, 0),
- m_wrap_mode_x(src.width()),
- m_wrap_mode_y(src.height())
- {}
-
- //--------------------------------------------------------------------
- void source_image(const rendering_buffer& src)
- {
- base_type::source_image(src);
- m_wrap_mode_x = WrapModeX(src.width());
- m_wrap_mode_y = WrapModeX(src.height());
- }
-
- //--------------------------------------------------------------------
- color_type* generate(int x, int y, unsigned len)
- {
- color_type* span = base_type::allocator().span();
- interpolator_type& intr = base_type::interpolator();
- intr.begin(x + base_type::filter_dx_dbl(),
- y + base_type::filter_dy_dbl(), len);
- const value_type *fg_ptr;
- do
- {
- intr.coordinates(&x, &y);
-
- x = m_wrap_mode_x(x >> image_subpixel_shift);
- y = m_wrap_mode_y(y >> image_subpixel_shift);
-
- fg_ptr = (const value_type*)base_type::source_image().row(y) + x * 3;
- span->r = fg_ptr[order_type::R];
- span->g = fg_ptr[order_type::G];
- span->b = fg_ptr[order_type::B];
- span->a = base_mask;
- ++span;
- ++intr;
-
- } while(--len);
- return base_type::allocator().span();
- }
-
- private:
- WrapModeX m_wrap_mode_x;
- WrapModeY m_wrap_mode_y;
- };
-
-
-
-
-
-
-
-
-
-
- //=====================================span_pattern_filter_rgb_bilinear
- template<class ColorT,
- class Order,
- class Interpolator,
- class WrapModeX,
- class WrapModeY,
- class Allocator = span_allocator<ColorT> >
- class span_pattern_filter_rgb_bilinear :
- public span_image_filter<ColorT, Interpolator, Allocator>
- {
- public:
- typedef ColorT color_type;
- typedef Order order_type;
- typedef Interpolator interpolator_type;
- typedef Allocator alloc_type;
- typedef span_image_filter<color_type, interpolator_type, alloc_type> base_type;
- typedef typename color_type::value_type value_type;
- typedef typename color_type::calc_type calc_type;
- enum
- {
- base_shift = color_type::base_shift,
- base_mask = color_type::base_mask
- };
-
- //--------------------------------------------------------------------
- span_pattern_filter_rgb_bilinear(alloc_type& alloc) :
- base_type(alloc),
- m_wrap_mode_x(1),
- m_wrap_mode_y(1)
- {}
-
- //--------------------------------------------------------------------
- span_pattern_filter_rgb_bilinear(alloc_type& alloc,
- const rendering_buffer& src,
- interpolator_type& intr) :
- base_type(alloc, src, color_type(0,0,0,0), intr, 0),
- m_wrap_mode_x(src.width()),
- m_wrap_mode_y(src.height())
- {}
-
- //-------------------------------------------------------------------
- void source_image(const rendering_buffer& src)
- {
- base_type::source_image(src);
- m_wrap_mode_x = WrapModeX(src.width());
- m_wrap_mode_y = WrapModeX(src.height());
- }
-
- //--------------------------------------------------------------------
- color_type* generate(int x, int y, unsigned len)
- {
- color_type* span = base_type::allocator().span();
- interpolator_type& intr = base_type::interpolator();
- intr.begin(x + base_type::filter_dx_dbl(),
- y + base_type::filter_dy_dbl(), len);
- calc_type fg[3];
- const value_type *fg_ptr;
-
- do
- {
- int x_hr;
- int y_hr;
-
- intr.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;
-
- unsigned x1 = m_wrap_mode_x(x_lr);
- unsigned x2 = ++m_wrap_mode_x;
- x1 *= 3;
- x2 *= 3;
-
- unsigned y1 = m_wrap_mode_y(y_lr);
- unsigned y2 = ++m_wrap_mode_y;
- const value_type* ptr1 = (const value_type*)base_type::source_image().row(y1);
- const value_type* ptr2 = (const value_type*)base_type::source_image().row(y2);
-
- fg[0] =
- fg[1] =
- fg[2] = image_subpixel_size * image_subpixel_size / 2;
-
- x_hr &= image_subpixel_mask;
- y_hr &= image_subpixel_mask;
-
- int weight;
- fg_ptr = ptr1 + x1;
- weight = (image_subpixel_size - x_hr) *
- (image_subpixel_size - y_hr);
- fg[0] += weight * fg_ptr[0];
- fg[1] += weight * fg_ptr[1];
- fg[2] += weight * fg_ptr[2];
-
- fg_ptr = ptr1 + x2;
- weight = x_hr * (image_subpixel_size - y_hr);
- fg[0] += weight * fg_ptr[0];
- fg[1] += weight * fg_ptr[1];
- fg[2] += weight * fg_ptr[2];
-
- fg_ptr = ptr2 + x1;
- weight = (image_subpixel_size - x_hr) * y_hr;
- fg[0] += weight * fg_ptr[0];
- fg[1] += weight * fg_ptr[1];
- fg[2] += weight * fg_ptr[2];
-
- fg_ptr = ptr2 + x2;
- weight = x_hr * y_hr;
- fg[0] += weight * fg_ptr[0];
- fg[1] += weight * fg_ptr[1];
- fg[2] += weight * fg_ptr[2];
-
- span->r = (value_type)(fg[order_type::R] >> image_subpixel_shift * 2);
- span->g = (value_type)(fg[order_type::G] >> image_subpixel_shift * 2);
- span->b = (value_type)(fg[order_type::B] >> image_subpixel_shift * 2);
- span->a = base_mask;
- ++span;
- ++intr;
- } while(--len);
-
- return base_type::allocator().span();
- }
-
- private:
- WrapModeX m_wrap_mode_x;
- WrapModeY m_wrap_mode_y;
- };
-
-
-
-
-
-
-
- //=====================================span_pattern_filter_rgb_2x2
- template<class ColorT,
- class Order,
- class Interpolator,
- class WrapModeX,
- class WrapModeY,
- class Allocator = span_allocator<ColorT> >
- class span_pattern_filter_rgb_2x2 :
- public span_image_filter<ColorT, Interpolator, Allocator>
- {
- public:
- typedef ColorT color_type;
- typedef Order order_type;
- typedef Interpolator interpolator_type;
- typedef Allocator alloc_type;
- typedef span_image_filter<color_type, interpolator_type, alloc_type> base_type;
- typedef typename color_type::value_type value_type;
- typedef typename color_type::calc_type calc_type;
- enum
- {
- base_shift = color_type::base_shift,
- base_mask = color_type::base_mask
- };
-
- //--------------------------------------------------------------------
- span_pattern_filter_rgb_2x2(alloc_type& alloc) :
- base_type(alloc),
- m_wrap_mode_x(1),
- m_wrap_mode_y(1)
- {}
-
- //--------------------------------------------------------------------
- span_pattern_filter_rgb_2x2(alloc_type& alloc,
- const rendering_buffer& src,
- interpolator_type& intr,
- const image_filter_lut& filter) :
- base_type(alloc, src, color_type(0,0,0,0), intr, &filter),
- m_wrap_mode_x(src.width()),
- m_wrap_mode_y(src.height())
- {}
-
- //-------------------------------------------------------------------
- void source_image(const rendering_buffer& src)
- {
- base_type::source_image(src);
- m_wrap_mode_x = WrapModeX(src.width());
- m_wrap_mode_y = WrapModeX(src.height());
- }
-
- //--------------------------------------------------------------------
- color_type* generate(int x, int y, unsigned len)
- {
- color_type* span = base_type::allocator().span();
- interpolator_type& intr = base_type::interpolator();
- intr.begin(x + base_type::filter_dx_dbl(),
- y + base_type::filter_dy_dbl(), len);
- calc_type fg[3];
- const value_type *fg_ptr;
- const int16* weight_array = base_type::filter().weight_array() +
- ((base_type::filter().diameter()/2 - 1) <<
- image_subpixel_shift);
- do
- {
- int x_hr;
- int y_hr;
-
- intr.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;
-
- unsigned x1 = m_wrap_mode_x(x_lr);
- unsigned x2 = ++m_wrap_mode_x;
- x1 *= 3;
- x2 *= 3;
-
- unsigned y1 = m_wrap_mode_y(y_lr);
- unsigned y2 = ++m_wrap_mode_y;
- const value_type* ptr1 = (const value_type*)base_type::source_image().row(y1);
- const value_type* ptr2 = (const value_type*)base_type::source_image().row(y2);
-
- fg[0] = fg[1] = fg[2] = image_filter_size / 2;
-
- x_hr &= image_subpixel_mask;
- y_hr &= image_subpixel_mask;
-
- int weight;
- fg_ptr = ptr1 + x1;
- weight = (weight_array[x_hr + image_subpixel_size] *
- weight_array[y_hr + image_subpixel_size] +
- image_filter_size / 2) >>
- image_filter_shift;
- fg[0] += weight * fg_ptr[0];
- fg[1] += weight * fg_ptr[1];
- fg[2] += weight * fg_ptr[2];
-
- fg_ptr = ptr1 + x2;
- weight = (weight_array[x_hr] *
- weight_array[y_hr + image_subpixel_size] +
- image_filter_size / 2) >>
- image_filter_shift;
- fg[0] += weight * fg_ptr[0];
- fg[1] += weight * fg_ptr[1];
- fg[2] += weight * fg_ptr[2];
-
- fg_ptr = ptr2 + x1;
- weight = (weight_array[x_hr + image_subpixel_size] *
- weight_array[y_hr] +
- image_filter_size / 2) >>
- image_filter_shift;
- fg[0] += weight * fg_ptr[0];
- fg[1] += weight * fg_ptr[1];
- fg[2] += weight * fg_ptr[2];
-
- fg_ptr = ptr2 + x2;
- weight = (weight_array[x_hr] *
- weight_array[y_hr] +
- image_filter_size / 2) >>
- image_filter_shift;
- fg[0] += weight * fg_ptr[0];
- fg[1] += weight * fg_ptr[1];
- fg[2] += weight * fg_ptr[2];
-
- fg[0] >>= image_filter_shift;
- fg[1] >>= image_filter_shift;
- fg[2] >>= image_filter_shift;
-
- if(fg[0] > base_mask) fg[0] = base_mask;
- if(fg[1] > base_mask) fg[1] = base_mask;
- if(fg[2] > base_mask) fg[2] = base_mask;
-
- span->r = (value_type)fg[order_type::R];
- span->g = (value_type)fg[order_type::G];
- span->b = (value_type)fg[order_type::B];
- span->a = base_mask;
- ++span;
- ++intr;
- } while(--len);
-
- return base_type::allocator().span();
- }
-
-
- private:
- WrapModeX m_wrap_mode_x;
- WrapModeY m_wrap_mode_y;
- };
-
-
-
-
-
-
-
-
-
-
- //==============================================span_pattern_filter_rgb
- template<class ColorT,
- class Order,
- class Interpolator,
- class WrapModeX,
- class WrapModeY,
- class Allocator = span_allocator<ColorT> >
- class span_pattern_filter_rgb :
- public span_image_filter<ColorT, Interpolator, Allocator>
- {
- public:
- typedef ColorT color_type;
- typedef Order order_type;
- typedef Interpolator interpolator_type;
- typedef Allocator alloc_type;
- typedef span_image_filter<color_type, interpolator_type, alloc_type> base_type;
- typedef typename color_type::value_type value_type;
- typedef typename color_type::calc_type calc_type;
- enum
- {
- base_shift = color_type::base_shift,
- base_mask = color_type::base_mask
- };
-
- //--------------------------------------------------------------------
- span_pattern_filter_rgb(alloc_type& alloc) :
- base_type(alloc)
- {}
-
- //--------------------------------------------------------------------
- span_pattern_filter_rgb(alloc_type& alloc,
- const rendering_buffer& src,
- interpolator_type& intr,
- const image_filter_lut& filter) :
- base_type(alloc, src, color_type(0,0,0,0), intr, &filter),
- m_wrap_mode_x(src.width()),
- m_wrap_mode_y(src.height())
- {}
-
- //--------------------------------------------------------------------
- void source_image(const rendering_buffer& src)
- {
- base_type::source_image(src);
- m_wrap_mode_x = WrapModeX(src.width());
- m_wrap_mode_y = WrapModeX(src.height());
- }
-
- //--------------------------------------------------------------------
- color_type* generate(int x, int y, unsigned len)
- {
- color_type* span = base_type::allocator().span();
- interpolator_type& intr = base_type::interpolator();
- intr.begin(x + base_type::filter_dx_dbl(),
- y + base_type::filter_dy_dbl(), len);
- int fg[3];
-
- unsigned diameter = base_type::filter().diameter();
- int start = base_type::filter().start();
- const int16* weight_array = base_type::filter().weight_array();
-
- int x_count;
- int weight_y;
-
- do
- {
- intr.coordinates(&x, &y);
-
- x -= base_type::filter_dx_int();
- y -= base_type::filter_dy_int();
-
- int x_hr = x;
- int y_hr = y;
-
- int x_fract = x_hr & image_subpixel_mask;
- unsigned y_count = diameter;
-
- int y_lr = m_wrap_mode_y((y >> image_subpixel_shift) + start);
- int x_int = (x >> image_subpixel_shift) + start;
- int x_lr;
-
- y_hr = image_subpixel_mask - (y_hr & image_subpixel_mask);
- fg[0] = fg[1] = fg[2] = image_filter_size / 2;
-
- do
- {
- x_count = diameter;
- weight_y = weight_array[y_hr];
- x_hr = image_subpixel_mask - x_fract;
- x_lr = m_wrap_mode_x(x_int);
- const value_type* row_ptr = (const value_type*)base_type::source_image().row(y_lr);
- do
- {
- const value_type* fg_ptr = row_ptr + x_lr * 3;
- int weight = (weight_y * weight_array[x_hr] +
- image_filter_size / 2) >>
- image_filter_shift;
-
- fg[0] += fg_ptr[0] * weight;
- fg[1] += fg_ptr[1] * weight;
- fg[2] += fg_ptr[2] * weight;
-
- x_hr += image_subpixel_size;
- x_lr = ++m_wrap_mode_x;
- } while(--x_count);
-
- y_hr += image_subpixel_size;
- y_lr = ++m_wrap_mode_y;
- } while(--y_count);
-
- fg[0] >>= image_filter_shift;
- fg[1] >>= image_filter_shift;
- fg[2] >>= image_filter_shift;
-
- if(fg[0] < 0) fg[0] = 0;
- if(fg[1] < 0) fg[1] = 0;
- if(fg[2] < 0) fg[2] = 0;
-
- if(fg[0] > base_mask) fg[0] = base_mask;
- if(fg[1] > base_mask) fg[1] = base_mask;
- if(fg[2] > base_mask) fg[2] = base_mask;
-
- span->r = (value_type)fg[order_type::R];
- span->g = (value_type)fg[order_type::G];
- span->b = (value_type)fg[order_type::B];
- span->a = base_mask;
- ++span;
- ++intr;
- } while(--len);
-
- return base_type::allocator().span();
- }
-
- private:
- WrapModeX m_wrap_mode_x;
- WrapModeY m_wrap_mode_y;
- };
-
-
-}
-
-
-#endif
-
-
-
diff --git a/agg/inc/agg_span_pattern_filter_rgba.h b/agg/inc/agg_span_pattern_filter_rgba.h
deleted file mode 100755
index 8460880fdb79..000000000000
--- a/agg/inc/agg_span_pattern_filter_rgba.h
+++ /dev/null
@@ -1,584 +0,0 @@
-//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
-// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
-//
-// Permission to copy, use, modify, sell and distribute this software
-// is granted provided this copyright notice appears in all copies.
-// This software is provided "as is" without express or implied
-// warranty, and with no claim as to its suitability for any purpose.
-//
-//----------------------------------------------------------------------------
-// Contact: mcseem@antigrain.com
-// mcseemagg@yahoo.com
-// http://www.antigrain.com
-//----------------------------------------------------------------------------
-//
-// Adaptation for high precision colors has been sponsored by
-// Liberty Technology Systems, Inc., visit http://lib-sys.com
-//
-// Liberty Technology Systems, Inc. is the provider of
-// PostScript and PDF technology for software developers.
-//
-//----------------------------------------------------------------------------
-//
-// classes span_pattern_filter_rgba*
-//
-//----------------------------------------------------------------------------
-#ifndef AGG_SPAN_PATTERN_FILTER_RGBA_INCLUDED
-#define AGG_SPAN_PATTERN_FILTER_RGBA_INCLUDED
-
-#include "agg_basics.h"
-#include "agg_color_rgba.h"
-#include "agg_span_pattern.h"
-#include "agg_span_image_filter.h"
-
-
-namespace agg
-{
-
- //===========================================span_pattern_filter_rgba
- template<class ColorT,
- class Order,
- class Interpolator,
- class WrapModeX,
- class WrapModeY,
- class Allocator = span_allocator<ColorT> >
- class span_pattern_filter_rgba_nn :
- public span_image_filter<ColorT, Interpolator, Allocator>
- {
- public:
- typedef ColorT color_type;
- typedef Order order_type;
- typedef Interpolator interpolator_type;
- typedef Allocator alloc_type;
- typedef span_image_filter<color_type, interpolator_type, alloc_type> base_type;
- typedef typename color_type::value_type value_type;
- typedef typename color_type::calc_type calc_type;
- enum
- {
- base_shift = color_type::base_shift,
- base_mask = color_type::base_mask
- };
-
- //--------------------------------------------------------------------
- span_pattern_filter_rgba_nn(alloc_type& alloc) :
- base_type(alloc),
- m_wrap_mode_x(1),
- m_wrap_mode_y(1)
- {}
-
- //--------------------------------------------------------------------
- span_pattern_filter_rgba_nn(alloc_type& alloc,
- const rendering_buffer& src,
- interpolator_type& inter) :
- base_type(alloc, src, color_type(0,0,0,0), inter, 0),
- m_wrap_mode_x(src.width()),
- m_wrap_mode_y(src.height())
- {}
-
- //--------------------------------------------------------------------
- void source_image(const rendering_buffer& src)
- {
- base_type::source_image(src);
- m_wrap_mode_x = WrapModeX(src.width());
- m_wrap_mode_y = WrapModeX(src.height());
- }
-
- //--------------------------------------------------------------------
- color_type* generate(int x, int y, unsigned len)
- {
- base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
- y + base_type::filter_dy_dbl(), len);
- const value_type *fg_ptr;
- color_type* span = base_type::allocator().span();
- do
- {
- base_type::interpolator().coordinates(&x, &y);
-
- x = m_wrap_mode_x(x >> image_subpixel_shift);
- y = m_wrap_mode_y(y >> image_subpixel_shift);
-
- fg_ptr = (value_type*)base_type::source_image().row(y) + (x << 2);
- span->r = fg_ptr[order_type::R];
- span->g = fg_ptr[order_type::G];
- span->b = fg_ptr[order_type::B];
- span->a = fg_ptr[order_type::A];
- ++span;
- ++base_type::interpolator();
-
- } while(--len);
-
- return base_type::allocator().span();
- }
-
- private:
- WrapModeX m_wrap_mode_x;
- WrapModeY m_wrap_mode_y;
- };
-
-
-
-
-
-
-
-
-
-
- //=====================================span_pattern_filter_rgba_bilinear
- template<class ColorT,
- class Order,
- class Interpolator,
- class WrapModeX,
- class WrapModeY,
- class Allocator = span_allocator<ColorT> >
- class span_pattern_filter_rgba_bilinear :
- public span_image_filter<ColorT, Interpolator, Allocator>
- {
- public:
- typedef ColorT color_type;
- typedef Order order_type;
- typedef Interpolator interpolator_type;
- typedef Allocator alloc_type;
- typedef span_image_filter<color_type, interpolator_type, alloc_type> base_type;
- typedef typename color_type::value_type value_type;
- typedef typename color_type::calc_type calc_type;
- enum
- {
- base_shift = color_type::base_shift,
- base_mask = color_type::base_mask
- };
-
- //--------------------------------------------------------------------
- span_pattern_filter_rgba_bilinear(alloc_type& alloc) :
- base_type(alloc),
- m_wrap_mode_x(1),
- m_wrap_mode_y(1)
- {}
-
- //--------------------------------------------------------------------
- span_pattern_filter_rgba_bilinear(alloc_type& alloc,
- const rendering_buffer& src,
- interpolator_type& inter) :
- base_type(alloc, src, color_type(0,0,0,0), inter, 0),
- m_wrap_mode_x(src.width()),
- m_wrap_mode_y(src.height())
- {}
-
- //-------------------------------------------------------------------
- void source_image(const rendering_buffer& src)
- {
- base_type::source_image(src);
- m_wrap_mode_x = WrapModeX(src.width());
- m_wrap_mode_y = WrapModeX(src.height());
- }
-
- //--------------------------------------------------------------------
- color_type* generate(int x, int y, unsigned len)
- {
- base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
- y + base_type::filter_dy_dbl(), len);
- calc_type fg[4];
- const value_type *fg_ptr;
- color_type* span = base_type::allocator().span();
-
- do
- {
- int x_hr;
- int y_hr;
-
- 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;
-
- unsigned x1 = m_wrap_mode_x(x_lr);
- unsigned x2 = ++m_wrap_mode_x;
- x1 <<= 2;
- x2 <<= 2;
-
- unsigned y1 = m_wrap_mode_y(y_lr);
- unsigned y2 = ++m_wrap_mode_y;
- const value_type* ptr1 = (value_type*)base_type::source_image().row(y1);
- const value_type* ptr2 = (value_type*)base_type::source_image().row(y2);
-
- fg[0] =
- fg[1] =
- fg[2] =
- fg[3] = image_subpixel_size * image_subpixel_size / 2;
-
- x_hr &= image_subpixel_mask;
- y_hr &= image_subpixel_mask;
-
- int weight;
- fg_ptr = ptr1 + x1;
- weight = (image_subpixel_size - x_hr) *
- (image_subpixel_size - y_hr);
- fg[0] += weight * fg_ptr[0];
- fg[1] += weight * fg_ptr[1];
- fg[2] += weight * fg_ptr[2];
- fg[3] += weight * fg_ptr[3];
-
- fg_ptr = ptr1 + x2;
- weight = x_hr * (image_subpixel_size - y_hr);
- fg[0] += weight * fg_ptr[0];
- fg[1] += weight * fg_ptr[1];
- fg[2] += weight * fg_ptr[2];
- fg[3] += weight * fg_ptr[3];
-
- fg_ptr = ptr2 + x1;
- weight = (image_subpixel_size - x_hr) * y_hr;
- fg[0] += weight * fg_ptr[0];
- fg[1] += weight * fg_ptr[1];
- fg[2] += weight * fg_ptr[2];
- fg[3] += weight * fg_ptr[3];
-
- fg_ptr = ptr2 + x2;
- weight = x_hr * y_hr;
- fg[0] += weight * fg_ptr[0];
- fg[1] += weight * fg_ptr[1];
- fg[2] += weight * fg_ptr[2];
- fg[3] += weight * fg_ptr[3];
-
- span->r = (value_type)(fg[order_type::R] >> image_subpixel_shift * 2);
- span->g = (value_type)(fg[order_type::G] >> image_subpixel_shift * 2);
- span->b = (value_type)(fg[order_type::B] >> image_subpixel_shift * 2);
- span->a = (value_type)(fg[order_type::A] >> image_subpixel_shift * 2);
- ++span;
- ++base_type::interpolator();
-
- } while(--len);
-
- return base_type::allocator().span();
- }
- private:
- WrapModeX m_wrap_mode_x;
- WrapModeY m_wrap_mode_y;
- };
-
-
-
-
-
-
-
-
- //=====================================span_pattern_filter_rgba_2x2
- template<class ColorT,
- class Order,
- class Interpolator,
- class WrapModeX,
- class WrapModeY,
- class Allocator = span_allocator<ColorT> >
- class span_pattern_filter_rgba_2x2 :
- public span_image_filter<ColorT, Interpolator, Allocator>
- {
- public:
- typedef ColorT color_type;
- typedef Order order_type;
- typedef Interpolator interpolator_type;
- typedef Allocator alloc_type;
- typedef span_image_filter<color_type, interpolator_type, alloc_type> base_type;
- typedef typename color_type::value_type value_type;
- typedef typename color_type::calc_type calc_type;
- enum
- {
- base_shift = color_type::base_shift,
- base_mask = color_type::base_mask
- };
-
- //--------------------------------------------------------------------
- span_pattern_filter_rgba_2x2(alloc_type& alloc) :
- base_type(alloc),
- m_wrap_mode_x(1),
- m_wrap_mode_y(1)
- {}
-
- //--------------------------------------------------------------------
- span_pattern_filter_rgba_2x2(alloc_type& alloc,
- const rendering_buffer& src,
- interpolator_type& inter,
- const image_filter_lut& filter) :
- base_type(alloc, src, color_type(0,0,0,0), inter, &filter),
- m_wrap_mode_x(src.width()),
- m_wrap_mode_y(src.height())
- {}
-
- //-------------------------------------------------------------------
- void source_image(const rendering_buffer& src)
- {
- base_type::source_image(src);
- m_wrap_mode_x = WrapModeX(src.width());
- m_wrap_mode_y = WrapModeX(src.height());
- }
-
- //--------------------------------------------------------------------
- color_type* generate(int x, int y, unsigned len)
- {
- base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
- y + base_type::filter_dy_dbl(), len);
- calc_type fg[4];
- const value_type *fg_ptr;
- color_type* span = base_type::allocator().span();
- const int16* weight_array = base_type::filter().weight_array() +
- ((base_type::filter().diameter()/2 - 1) <<
- image_subpixel_shift);
- do
- {
- int x_hr;
- int y_hr;
-
- 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;
-
- unsigned x1 = m_wrap_mode_x(x_lr);
- unsigned x2 = ++m_wrap_mode_x;
- x1 <<= 2;
- x2 <<= 2;
-
- unsigned y1 = m_wrap_mode_y(y_lr);
- unsigned y2 = ++m_wrap_mode_y;
- const value_type* ptr1 = (value_type*)base_type::source_image().row(y1);
- const value_type* ptr2 = (value_type*)base_type::source_image().row(y2);
-
- fg[0] = fg[1] = fg[2] = fg[3] = image_filter_size / 2;
-
- x_hr &= image_subpixel_mask;
- y_hr &= image_subpixel_mask;
-
- int weight;
- fg_ptr = ptr1 + x1;
- weight = (weight_array[x_hr + image_subpixel_size] *
- weight_array[y_hr + image_subpixel_size] +
- image_filter_size / 2) >>
- image_filter_shift;
- fg[0] += weight * fg_ptr[0];
- fg[1] += weight * fg_ptr[1];
- fg[2] += weight * fg_ptr[2];
- fg[3] += weight * fg_ptr[3];
-
- fg_ptr = ptr1 + x2;
- weight = (weight_array[x_hr] *
- weight_array[y_hr + image_subpixel_size] +
- image_filter_size / 2) >>
- image_filter_shift;
- fg[0] += weight * fg_ptr[0];
- fg[1] += weight * fg_ptr[1];
- fg[2] += weight * fg_ptr[2];
- fg[3] += weight * fg_ptr[3];
-
- fg_ptr = ptr2 + x1;
- weight = (weight_array[x_hr + image_subpixel_size] *
- weight_array[y_hr] +
- image_filter_size / 2) >>
- image_filter_shift;
- fg[0] += weight * fg_ptr[0];
- fg[1] += weight * fg_ptr[1];
- fg[2] += weight * fg_ptr[2];
- fg[3] += weight * fg_ptr[3];
-
- fg_ptr = ptr2 + x2;
- weight = (weight_array[x_hr] *
- weight_array[y_hr] +
- image_filter_size / 2) >>
- image_filter_shift;
- fg[0] += weight * fg_ptr[0];
- fg[1] += weight * fg_ptr[1];
- fg[2] += weight * fg_ptr[2];
- fg[3] += weight * fg_ptr[3];
-
- fg[0] >>= image_filter_shift;
- fg[1] >>= image_filter_shift;
- fg[2] >>= image_filter_shift;
- fg[3] >>= image_filter_shift;
-
- if(fg[order_type::A] > base_mask) fg[order_type::A] = base_mask;
- if(fg[order_type::R] > fg[order_type::A]) fg[order_type::R] = fg[order_type::A];
- if(fg[order_type::G] > fg[order_type::A]) fg[order_type::G] = fg[order_type::A];
- if(fg[order_type::B] > fg[order_type::A]) fg[order_type::B] = fg[order_type::A];
-
- span->r = (value_type)fg[order_type::R];
- span->g = (value_type)fg[order_type::G];
- span->b = (value_type)fg[order_type::B];
- span->a = (value_type)fg[order_type::A];
- ++span;
- ++base_type::interpolator();
-
- } while(--len);
-
- return base_type::allocator().span();
- }
- private:
- WrapModeX m_wrap_mode_x;
- WrapModeY m_wrap_mode_y;
- };
-
-
-
-
-
-
-
-
-
-
-
-
- //==============================================span_pattern_filter_rgba
- template<class ColorT,
- class Order,
- class Interpolator,
- class WrapModeX,
- class WrapModeY,
- class Allocator = span_allocator<ColorT> >
- class span_pattern_filter_rgba :
- public span_image_filter<ColorT, Interpolator, Allocator>
- {
- public:
- typedef ColorT color_type;
- typedef Order order_type;
- typedef Interpolator interpolator_type;
- typedef Allocator alloc_type;
- typedef span_image_filter<color_type, interpolator_type, alloc_type> base_type;
- typedef typename color_type::value_type value_type;
- typedef typename color_type::calc_type calc_type;
- enum
- {
- base_shift = color_type::base_shift,
- base_mask = color_type::base_mask
- };
-
- //--------------------------------------------------------------------
- span_pattern_filter_rgba(alloc_type& alloc) :
- base_type(alloc)
- {}
-
- //--------------------------------------------------------------------
- span_pattern_filter_rgba(alloc_type& alloc,
- const rendering_buffer& src,
- interpolator_type& inter,
- const image_filter_lut& filter) :
- base_type(alloc, src, color_type(0,0,0,0), inter, &filter),
- m_wrap_mode_x(src.width()),
- m_wrap_mode_y(src.height())
- {}
-
- //--------------------------------------------------------------------
- void source_image(const rendering_buffer& src)
- {
- base_type::source_image(src);
- m_wrap_mode_x = WrapModeX(src.width());
- m_wrap_mode_y = WrapModeX(src.height());
- }
-
- //--------------------------------------------------------------------
- color_type* generate(int x, int y, unsigned len)
- {
- base_type::interpolator().begin(x + base_type::filter_dx_dbl(),
- y + base_type::filter_dy_dbl(), len);
- int fg[4];
-
- unsigned diameter = base_type::filter().diameter();
- int start = base_type::filter().start();
- const int16* weight_array = base_type::filter().weight_array();
-
- color_type* span = base_type::allocator().span();
-
- int x_count;
- int weight_y;
-
- do
- {
- 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;
-
- int x_fract = x_hr & image_subpixel_mask;
- unsigned y_count = diameter;
-
- int y_lr = m_wrap_mode_y((y >> image_subpixel_shift) + start);
- int x_int = (x >> image_subpixel_shift) + start;
- int x_lr;
-
- y_hr = image_subpixel_mask - (y_hr & image_subpixel_mask);
- fg[0] = fg[1] = fg[2] = fg[3] = image_filter_size / 2;
-
- do
- {
- x_count = diameter;
- weight_y = weight_array[y_hr];
- x_hr = image_subpixel_mask - x_fract;
- x_lr = m_wrap_mode_x(x_int);
- const value_type* row_ptr = (value_type*)base_type::source_image().row(y_lr);
- do
- {
- const value_type* fg_ptr = row_ptr + (x_lr << 2);
- int weight = (weight_y * weight_array[x_hr] +
- image_filter_size / 2) >>
- image_filter_shift;
-
- fg[0] += fg_ptr[0] * weight;
- fg[1] += fg_ptr[1] * weight;
- fg[2] += fg_ptr[2] * weight;
- fg[3] += fg_ptr[3] * weight;
-
- x_hr += image_subpixel_size;
- x_lr = ++m_wrap_mode_x;
- } while(--x_count);
-
- y_hr += image_subpixel_size;
- y_lr = ++m_wrap_mode_y;
- } while(--y_count);
-
- fg[0] >>= image_filter_shift;
- fg[1] >>= image_filter_shift;
- fg[2] >>= image_filter_shift;
- fg[3] >>= image_filter_shift;
-
- if(fg[0] < 0) fg[0] = 0;
- if(fg[1] < 0) fg[1] = 0;
- if(fg[2] < 0) fg[2] = 0;
- if(fg[3] < 0) fg[3] = 0;
-
- if(fg[order_type::A] > base_mask) fg[order_type::A] = base_mask;
- if(fg[order_type::R] > fg[order_type::A]) fg[order_type::R] = fg[order_type::A];
- if(fg[order_type::G] > fg[order_type::A]) fg[order_type::G] = fg[order_type::A];
- if(fg[order_type::B] > fg[order_type::A]) fg[order_type::B] = fg[order_type::A];
-
- span->r = fg[order_type::R];
- span->g = fg[order_type::G];
- span->b = fg[order_type::B];
- span->a = fg[order_type::A];
- ++span;
- ++base_type::interpolator();
-
- } while(--len);
-
- return base_type::allocator().span();
- }
-
- private:
- WrapModeX m_wrap_mode_x;
- WrapModeY m_wrap_mode_y;
- };
-
-
-}
-
-
-#endif
-
-
-
diff --git a/agg/inc/agg_span_pattern_gray.h b/agg/inc/agg_span_pattern_gray.h
new file mode 100644
index 000000000000..d0254ef3e122
--- /dev/null
+++ b/agg/inc/agg_span_pattern_gray.h
@@ -0,0 +1,93 @@
+//----------------------------------------------------------------------------
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
+//
+// Permission to copy, use, modify, sell and distribute this software
+// is granted provided this copyright notice appears in all copies.
+// This software is provided "as is" without express or implied
+// warranty, and with no claim as to its suitability for any purpose.
+//
+//----------------------------------------------------------------------------
+// Contact: mcseem@antigrain.com
+// mcseemagg@yahoo.com
+// http://www.antigrain.com
+//----------------------------------------------------------------------------
+//
+// Adaptation for high precision colors has been sponsored by
+// Liberty Technology Systems, Inc., visit http://lib-sys.com
+//
+// Liberty Technology Systems, Inc. is the provider of
+// PostScript and PDF technology for software developers.
+//
+//----------------------------------------------------------------------------
+
+
+#ifndef AGG_SPAN_PATTERN_GRAY_INCLUDED
+#define AGG_SPAN_PATTERN_GRAY_INCLUDED
+
+#include "agg_basics.h"
+
+namespace agg
+{
+
+ //=======================================================span_pattern_gray
+ template<class Source> class span_pattern_gray
+ {
+ public:
+ typedef Source source_type;
+ typedef typename source_type::color_type color_type;
+ typedef typename color_type::value_type value_type;
+ typedef typename color_type::calc_type calc_type;
+
+ //--------------------------------------------------------------------
+ span_pattern_gray() {}
+ span_pattern_gray(source_type& src,
+ unsigned offset_x, unsigned offset_y) :
+ m_src(&src),
+ m_offset_x(offset_x),
+ m_offset_y(offset_y),
+ m_alpha(color_type::base_mask)
+ {}
+
+ //--------------------------------------------------------------------
+ void attach(source_type& v) { m_src = &v; }
+ source_type& source() { return *m_src; }
+ const source_type& source() const { return *m_src; }
+
+ //--------------------------------------------------------------------
+ void offset_x(unsigned v) { m_offset_x = v; }
+ void offset_y(unsigned v) { m_offset_y = v; }
+ unsigned offset_x() const { return m_offset_x; }
+ unsigned offset_y() const { return m_offset_y; }
+ void alpha(value_type v) { m_alpha = v; }
+ value_type alpha() const { return m_alpha; }
+
+ //--------------------------------------------------------------------
+ void prepare() {}
+ void generate(color_type* span, int x, int y, unsigned len)
+ {
+ x += m_offset_x;
+ y += m_offset_y;
+ const value_type* p = (const value_type*)m_src->span(x, y, len);
+ do
+ {
+ span->v = *p;
+ span->a = m_alpha;
+ p = m_src->next_x();
+ ++span;
+ }
+ while(--len);
+ }
+
+ private:
+ source_type* m_src;
+ unsigned m_offset_x;
+ unsigned m_offset_y;
+ value_type m_alpha;
+
+ };
+
+}
+
+#endif
+
diff --git a/agg/inc/agg_span_pattern_resample_gray.h b/agg/inc/agg_span_pattern_resample_gray.h
deleted file mode 100755
index 212209502f5f..000000000000
--- a/agg/inc/agg_span_pattern_resample_gray.h
+++ /dev/null
@@ -1,320 +0,0 @@
-//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
-// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
-//
-// Permission to copy, use, modify, sell and distribute this software
-// is granted provided this copyright notice appears in all copies.
-// This software is provided "as is" without express or implied
-// warranty, and with no claim as to its suitability for any purpose.
-//
-//----------------------------------------------------------------------------
-// Contact: mcseem@antigrain.com
-// mcseemagg@yahoo.com
-// http://www.antigrain.com
-//----------------------------------------------------------------------------
-
-#ifndef AGG_SPAN_PATTERN_RESAMPLE_GRAY_INCLUDED
-#define AGG_SPAN_PATTERN_RESAMPLE_GRAY_INCLUDED
-
-#include "agg_color_gray.h"
-#include "agg_span_image_resample.h"
-
-namespace agg
-{
-
- //=======================================span_pattern_resample_gray_affine
- template<class ColorT,
- class WrapModeX,
- class WrapModeY,
- class Allocator = span_allocator<ColorT> >
- class span_pattern_resample_gray_affine :
- public span_image_resample_affine<ColorT, Allocator>
- {
- public:
- typedef ColorT color_type;
- typedef Allocator alloc_type;
- typedef span_image_resample_affine<color_type, alloc_type> base_type;
- typedef typename base_type::interpolator_type interpolator_type;
- typedef typename color_type::value_type value_type;
- typedef typename color_type::long_type long_type;
- enum
- {
- base_shift = color_type::base_shift,
- base_mask = color_type::base_mask,
- downscale_shift = image_filter_shift
- };
-
- //--------------------------------------------------------------------
- span_pattern_resample_gray_affine(alloc_type& alloc) :
- base_type(alloc),
- m_wrap_mode_x(1),
- m_wrap_mode_y(1)
- {}
-
- //--------------------------------------------------------------------
- span_pattern_resample_gray_affine(alloc_type& alloc,
- const rendering_buffer& src,
- interpolator_type& inter,
- const image_filter_lut& filter) :
- base_type(alloc, src, color_type(0,0), inter, filter),
- m_wrap_mode_x(src.width()),
- m_wrap_mode_y(src.height())
- {}
-
- //--------------------------------------------------------------------
- void source_image(const rendering_buffer& src)
- {
- base_type::source_image(src);
- m_wrap_mode_x = WrapModeX(src.width());
- m_wrap_mode_y = WrapModeX(src.height());
- }
-
- //--------------------------------------------------------------------
- color_type* generate(int x, int y, unsigned len)
- {
- color_type* span = base_type::allocator().span();
- interpolator_type& intr = base_type::interpolator();
- intr.begin(x + base_type::filter_dx_dbl(),
- y + base_type::filter_dy_dbl(), len);
- long_type fg;
-
- int diameter = base_type::filter().diameter();
- int filter_size = diameter << image_subpixel_shift;
- int radius_x = (diameter * base_type::m_rx) >> 1;
- int radius_y = (diameter * base_type::m_ry) >> 1;
- int maxx = base_type::source_image().width() - 1;
- int maxy = base_type::source_image().height() - 1;
- const int16* weight_array = base_type::filter().weight_array();
-
- do
- {
- intr.coordinates(&x, &y);
-
- x += base_type::filter_dx_int() - radius_x;
- y += base_type::filter_dy_int() - radius_y;
-
- fg = image_filter_size / 2;
-
- int y_lr = m_wrap_mode_y(y >> image_subpixel_shift);
- int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) *
- base_type::m_ry_inv) >>
- image_subpixel_shift;
- int total_weight = 0;
- int x_lr_ini = x >> image_subpixel_shift;
- int x_hr_ini = ((image_subpixel_mask - (x & image_subpixel_mask)) *
- base_type::m_rx_inv) >>
- image_subpixel_shift;
- do
- {
- int weight_y = weight_array[y_hr];
- int x_lr = m_wrap_mode_x(x_lr_ini);
- int x_hr = x_hr_ini;
- const value_type* row_ptr = (const value_type*)base_type::source_image().row(y_lr);
- do
- {
- const value_type* fg_ptr = row_ptr + x_lr;
- int weight = (weight_y * weight_array[x_hr] +
- image_filter_size / 2) >>
- downscale_shift;
-
- fg += *fg_ptr * weight;
- total_weight += weight;
- x_hr += base_type::m_rx_inv;
- x_lr = ++m_wrap_mode_x;
- }
- while(x_hr < filter_size);
-
- y_hr += base_type::m_ry_inv;
- y_lr = ++m_wrap_mode_y;
- } while(y_hr < filter_size);
-
- fg /= total_weight;
-
- if(fg < 0) fg = 0;
- if(fg > base_mask) fg = base_mask;
-
- span->v = (value_type)fg;
- span->a = (value_type)base_mask;
-
- ++span;
- ++intr;
- } while(--len);
- return base_type::allocator().span();
- }
-
- private:
- WrapModeX m_wrap_mode_x;
- WrapModeY m_wrap_mode_y;
- };
-
-
-
-
-
-
-
- //============================================span_pattern_resample_gray
- template<class ColorT,
- class Interpolator,
- class WrapModeX,
- class WrapModeY,
- class Allocator = span_allocator<ColorT> >
- class span_pattern_resample_gray :
- public span_image_resample<ColorT, Interpolator, Allocator>
- {
- public:
- typedef ColorT color_type;
- typedef Interpolator interpolator_type;
- typedef Allocator alloc_type;
- typedef span_image_resample<color_type, interpolator_type, alloc_type> base_type;
- typedef typename color_type::value_type value_type;
- typedef typename color_type::long_type long_type;
- enum
- {
- base_shift = color_type::base_shift,
- base_mask = color_type::base_mask,
- downscale_shift = image_filter_shift
- };
-
- //--------------------------------------------------------------------
- span_pattern_resample_gray(alloc_type& alloc) :
- base_type(alloc),
- m_wrap_mode_x(1),
- m_wrap_mode_y(1)
- {}
-
- //--------------------------------------------------------------------
- span_pattern_resample_gray(alloc_type& alloc,
- const rendering_buffer& src,
- interpolator_type& inter,
- const image_filter_lut& filter) :
- base_type(alloc, src, color_type(0,0), inter, filter),
- m_wrap_mode_x(src.width()),
- m_wrap_mode_y(src.height())
- {}
-
- //--------------------------------------------------------------------
- void source_image(const rendering_buffer& src)
- {
- base_type::source_image(src);
- m_wrap_mode_x = WrapModeX(src.width());
- m_wrap_mode_y = WrapModeX(src.height());
- }
-
- //--------------------------------------------------------------------
- color_type* generate(int x, int y, unsigned len)
- {
- color_type* span = base_type::allocator().span();
- interpolator_type& intr = base_type::interpolator();
- intr.begin(x + base_type::filter_dx_dbl(),
- y + base_type::filter_dy_dbl(), len);
- long_type fg;
-
- int diameter = base_type::filter().diameter();
- int filter_size = diameter << image_subpixel_shift;
- const int16* weight_array = base_type::filter().weight_array();
-
- do
- {
- int rx;
- int ry;
- int rx_inv = image_subpixel_size;
- int ry_inv = image_subpixel_size;
- intr.coordinates(&x, &y);
- intr.local_scale(&rx, &ry);
-
- rx = (rx * base_type::m_blur_x) >> image_subpixel_shift;
- ry = (ry * base_type::m_blur_y) >> image_subpixel_shift;
-
- if(rx < image_subpixel_size)
- {
- rx = image_subpixel_size;
- }
- else
- {
- if(rx > image_subpixel_size * base_type::m_scale_limit)
- {
- rx = image_subpixel_size * base_type::m_scale_limit;
- }
- rx_inv = image_subpixel_size * image_subpixel_size / rx;
- }
-
- if(ry < image_subpixel_size)
- {
- ry = image_subpixel_size;
- }
- else
- {
- if(ry > image_subpixel_size * base_type::m_scale_limit)
- {
- ry = image_subpixel_size * base_type::m_scale_limit;
- }
- ry_inv = image_subpixel_size * image_subpixel_size / ry;
- }
-
- int radius_x = (diameter * rx) >> 1;
- int radius_y = (diameter * ry) >> 1;
- int maxx = base_type::source_image().width() - 1;
- int maxy = base_type::source_image().height() - 1;
-
- x += base_type::filter_dx_int() - radius_x;
- y += base_type::filter_dy_int() - radius_y;
-
- fg = image_filter_size / 2;
-
- int y_lr = m_wrap_mode_y(y >> image_subpixel_shift);
- int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) *
- ry_inv) >>
- image_subpixel_shift;
- int total_weight = 0;
- int x_lr_ini = x >> image_subpixel_shift;
- int x_hr_ini = ((image_subpixel_mask - (x & image_subpixel_mask)) *
- rx_inv) >>
- image_subpixel_shift;
-
- do
- {
- int weight_y = weight_array[y_hr];
- int x_lr = m_wrap_mode_x(x_lr_ini);
- int x_hr = x_hr_ini;
- const value_type* row_ptr = (const value_type*)base_type::source_image().row(y_lr);
- do
- {
- const value_type* fg_ptr = row_ptr + x_lr;
- int weight = (weight_y * weight_array[x_hr] +
- image_filter_size / 2) >>
- downscale_shift;
- fg += *fg_ptr * weight;
- total_weight += weight;
- x_hr += rx_inv;
- x_lr = ++m_wrap_mode_x;
- }
- while(x_hr < filter_size);
- y_hr += ry_inv;
- y_lr = ++m_wrap_mode_y;
- }
- while(y_hr < filter_size);
-
- fg /= total_weight;
-
- if(fg < 0) fg = 0;
- if(fg > base_mask) fg = base_mask;
-
- span->v = (value_type)fg;
- span->a = (value_type)base_mask;
-
- ++span;
- ++intr;
- } while(--len);
- return base_type::allocator().span();
- }
-
- private:
- WrapModeX m_wrap_mode_x;
- WrapModeY m_wrap_mode_y;
- };
-
-}
-
-
-#endif
diff --git a/agg/inc/agg_span_pattern_resample_rgb.h b/agg/inc/agg_span_pattern_resample_rgb.h
deleted file mode 100755
index baef860eb472..000000000000
--- a/agg/inc/agg_span_pattern_resample_rgb.h
+++ /dev/null
@@ -1,346 +0,0 @@
-//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
-// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
-//
-// Permission to copy, use, modify, sell and distribute this software
-// is granted provided this copyright notice appears in all copies.
-// This software is provided "as is" without express or implied
-// warranty, and with no claim as to its suitability for any purpose.
-//
-//----------------------------------------------------------------------------
-// Contact: mcseem@antigrain.com
-// mcseemagg@yahoo.com
-// http://www.antigrain.com
-//----------------------------------------------------------------------------
-
-#ifndef AGG_SPAN_PATTERN_RESAMPLE_RGB_INCLUDED
-#define AGG_SPAN_PATTERN_RESAMPLE_RGB_INCLUDED
-
-#include "agg_color_rgba.h"
-#include "agg_span_image_resample.h"
-
-namespace agg
-{
-
- //========================================span_pattern_resample_rgb_affine
- template<class ColorT,
- class Order,
- class WrapModeX,
- class WrapModeY,
- class Allocator = span_allocator<ColorT> >
- class span_pattern_resample_rgb_affine :
- public span_image_resample_affine<ColorT, Allocator>
- {
- public:
- typedef ColorT color_type;
- typedef Order order_type;
- typedef Allocator alloc_type;
- typedef span_image_resample_affine<color_type, alloc_type> base_type;
- typedef typename base_type::interpolator_type interpolator_type;
- typedef typename color_type::value_type value_type;
- typedef typename color_type::long_type long_type;
- enum
- {
- base_shift = color_type::base_shift,
- base_mask = color_type::base_mask,
- downscale_shift = image_filter_shift
- };
-
- //--------------------------------------------------------------------
- span_pattern_resample_rgb_affine(alloc_type& alloc) :
- base_type(alloc),
- m_wrap_mode_x(1),
- m_wrap_mode_y(1)
- {}
-
- //--------------------------------------------------------------------
- span_pattern_resample_rgb_affine(alloc_type& alloc,
- const rendering_buffer& src,
- interpolator_type& inter,
- const image_filter_lut& filter_) :
- base_type(alloc, src, color_type(0,0,0,0), inter, filter_),
- m_wrap_mode_x(src.width()),
- m_wrap_mode_y(src.height())
- {}
-
- //--------------------------------------------------------------------
- void source_image(const rendering_buffer& src)
- {
- base_type::source_image(src);
- m_wrap_mode_x = WrapModeX(src.width());
- m_wrap_mode_y = WrapModeX(src.height());
- }
-
- //--------------------------------------------------------------------
- color_type* generate(int x, int y, unsigned len)
- {
- color_type* span = base_type::allocator().span();
- interpolator_type& intr = base_type::interpolator();
- intr.begin(x + base_type::filter_dx_dbl(),
- y + base_type::filter_dy_dbl(), len);
- long_type fg[3];
-
- int diameter = base_type::filter().diameter();
- int filter_size = diameter << image_subpixel_shift;
- int radius_x = (diameter * base_type::m_rx) >> 1;
- int radius_y = (diameter * base_type::m_ry) >> 1;
- int maxx = base_type::source_image().width() - 1;
- int maxy = base_type::source_image().height() - 1;
- const int16* weight_array = base_type::filter().weight_array();
-
- do
- {
- intr.coordinates(&x, &y);
-
- x += base_type::filter_dx_int() - radius_x;
- y += base_type::filter_dy_int() - radius_y;
-
- fg[0] = fg[1] = fg[2] = image_filter_size / 2;
-
- int y_lr = m_wrap_mode_y(y >> image_subpixel_shift);
- int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) *
- base_type::m_ry_inv) >>
- image_subpixel_shift;
- int total_weight = 0;
- int x_lr_ini = x >> image_subpixel_shift;
- int x_hr_ini = ((image_subpixel_mask - (x & image_subpixel_mask)) *
- base_type::m_rx_inv) >>
- image_subpixel_shift;
- do
- {
- int weight_y = weight_array[y_hr];
- int x_lr = m_wrap_mode_x(x_lr_ini);
- int x_hr = x_hr_ini;
- const value_type* row_ptr = (const value_type*)base_type::source_image().row(y_lr);
- do
- {
- const value_type* fg_ptr = row_ptr + x_lr * 3;
- int weight = (weight_y * weight_array[x_hr] +
- image_filter_size / 2) >>
- downscale_shift;
-
- fg[0] += fg_ptr[0] * weight;
- fg[1] += fg_ptr[1] * weight;
- fg[2] += fg_ptr[2] * weight;
- total_weight += weight;
- x_hr += base_type::m_rx_inv;
- x_lr = ++m_wrap_mode_x;
- }
- while(x_hr < filter_size);
-
- y_hr += base_type::m_ry_inv;
- y_lr = ++m_wrap_mode_y;
- } while(y_hr < filter_size);
-
- fg[0] /= total_weight;
- fg[1] /= total_weight;
- fg[2] /= total_weight;
-
- if(fg[0] < 0) fg[0] = 0;
- if(fg[1] < 0) fg[1] = 0;
- if(fg[2] < 0) fg[2] = 0;
-
- if(fg[0] > base_mask) fg[0] = base_mask;
- if(fg[1] > base_mask) fg[1] = base_mask;
- if(fg[2] > base_mask) fg[2] = base_mask;
-
- span->r = (value_type)fg[order_type::R];
- span->g = (value_type)fg[order_type::G];
- span->b = (value_type)fg[order_type::B];
- span->a = (value_type)base_mask;
-
- ++span;
- ++intr;
- } while(--len);
- return base_type::allocator().span();
- }
-
- private:
- WrapModeX m_wrap_mode_x;
- WrapModeY m_wrap_mode_y;
- };
-
-
-
-
-
-
-
- //=============================================span_pattern_resample_rgb
- template<class ColorT,
- class Order,
- class Interpolator,
- class WrapModeX,
- class WrapModeY,
- class Allocator = span_allocator<ColorT> >
- class span_pattern_resample_rgb :
- public span_image_resample<ColorT, Interpolator, Allocator>
- {
- public:
- typedef ColorT color_type;
- typedef Order order_type;
- typedef Interpolator interpolator_type;
- typedef Allocator alloc_type;
- typedef span_image_resample<color_type, interpolator_type, alloc_type> base_type;
- typedef typename color_type::value_type value_type;
- typedef typename color_type::long_type long_type;
- enum
- {
- base_shift = color_type::base_shift,
- base_mask = color_type::base_mask,
- downscale_shift = image_filter_shift
- };
-
- //--------------------------------------------------------------------
- span_pattern_resample_rgb(alloc_type& alloc) :
- base_type(alloc),
- m_wrap_mode_x(1),
- m_wrap_mode_y(1)
- {}
-
- //--------------------------------------------------------------------
- span_pattern_resample_rgb(alloc_type& alloc,
- const rendering_buffer& src,
- interpolator_type& inter,
- const image_filter_lut& filter) :
- base_type(alloc, src, color_type(0,0,0,0), inter, filter),
- m_wrap_mode_x(src.width()),
- m_wrap_mode_y(src.height())
- {}
-
- //--------------------------------------------------------------------
- void source_image(const rendering_buffer& src)
- {
- base_type::source_image(src);
- m_wrap_mode_x = WrapModeX(src.width());
- m_wrap_mode_y = WrapModeX(src.height());
- }
-
- //--------------------------------------------------------------------
- color_type* generate(int x, int y, unsigned len)
- {
- color_type* span = base_type::allocator().span();
- interpolator_type& intr = base_type::interpolator();
- intr.begin(x + base_type::filter_dx_dbl(),
- y + base_type::filter_dy_dbl(), len);
- long_type fg[3];
-
- int diameter = base_type::filter().diameter();
- int filter_size = diameter << image_subpixel_shift;
- const int16* weight_array = base_type::filter().weight_array();
-
- do
- {
- int rx;
- int ry;
- int rx_inv = image_subpixel_size;
- int ry_inv = image_subpixel_size;
- intr.coordinates(&x, &y);
- intr.local_scale(&rx, &ry);
-
- rx = (rx * base_type::m_blur_x) >> image_subpixel_shift;
- ry = (ry * base_type::m_blur_y) >> image_subpixel_shift;
-
- if(rx < image_subpixel_size)
- {
- rx = image_subpixel_size;
- }
- else
- {
- if(rx > image_subpixel_size * base_type::m_scale_limit)
- {
- rx = image_subpixel_size * base_type::m_scale_limit;
- }
- rx_inv = image_subpixel_size * image_subpixel_size / rx;
- }
-
- if(ry < image_subpixel_size)
- {
- ry = image_subpixel_size;
- }
- else
- {
- if(ry > image_subpixel_size * base_type::m_scale_limit)
- {
- ry = image_subpixel_size * base_type::m_scale_limit;
- }
- ry_inv = image_subpixel_size * image_subpixel_size / ry;
- }
-
- int radius_x = (diameter * rx) >> 1;
- int radius_y = (diameter * ry) >> 1;
- int maxx = base_type::source_image().width() - 1;
- int maxy = base_type::source_image().height() - 1;
-
- x += base_type::filter_dx_int() - radius_x;
- y += base_type::filter_dy_int() - radius_y;
-
- fg[0] = fg[1] = fg[2] = image_filter_size / 2;
-
- int y_lr = m_wrap_mode_y(y >> image_subpixel_shift);
- int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) *
- ry_inv) >>
- image_subpixel_shift;
- int total_weight = 0;
- int x_lr_ini = x >> image_subpixel_shift;
- int x_hr_ini = ((image_subpixel_mask - (x & image_subpixel_mask)) *
- rx_inv) >>
- image_subpixel_shift;
-
- do
- {
- int weight_y = weight_array[y_hr];
- int x_lr = m_wrap_mode_x(x_lr_ini);
- int x_hr = x_hr_ini;
- const value_type* row_ptr = (const value_type*)base_type::source_image().row(y_lr);
- do
- {
- const value_type* fg_ptr = row_ptr + x_lr * 3;
- int weight = (weight_y * weight_array[x_hr] +
- image_filter_size / 2) >>
- downscale_shift;
- fg[0] += fg_ptr[0] * weight;
- fg[1] += fg_ptr[1] * weight;
- fg[2] += fg_ptr[2] * weight;
- total_weight += weight;
- x_hr += rx_inv;
- x_lr = ++m_wrap_mode_x;
- }
- while(x_hr < filter_size);
- y_hr += ry_inv;
- y_lr = ++m_wrap_mode_y;
- }
- while(y_hr < filter_size);
-
- fg[0] /= total_weight;
- fg[1] /= total_weight;
- fg[2] /= total_weight;
-
- if(fg[0] < 0) fg[0] = 0;
- if(fg[1] < 0) fg[1] = 0;
- if(fg[2] < 0) fg[2] = 0;
-
- if(fg[0] > base_mask) fg[0] = base_mask;
- if(fg[1] > base_mask) fg[1] = base_mask;
- if(fg[2] > base_mask) fg[2] = base_mask;
-
- span->r = (value_type)fg[order_type::R];
- span->g = (value_type)fg[order_type::G];
- span->b = (value_type)fg[order_type::B];
- span->a = (value_type)base_mask;
-
- ++span;
- ++intr;
- } while(--len);
- return base_type::allocator().span();
- }
-
- private:
- WrapModeX m_wrap_mode_x;
- WrapModeY m_wrap_mode_y;
- };
-
-}
-
-
-#endif
diff --git a/agg/inc/agg_span_pattern_resample_rgba.h b/agg/inc/agg_span_pattern_resample_rgba.h
deleted file mode 100755
index 37b4dade16f4..000000000000
--- a/agg/inc/agg_span_pattern_resample_rgba.h
+++ /dev/null
@@ -1,354 +0,0 @@
-//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
-// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
-//
-// Permission to copy, use, modify, sell and distribute this software
-// is granted provided this copyright notice appears in all copies.
-// This software is provided "as is" without express or implied
-// warranty, and with no claim as to its suitability for any purpose.
-//
-//----------------------------------------------------------------------------
-// Contact: mcseem@antigrain.com
-// mcseemagg@yahoo.com
-// http://www.antigrain.com
-//----------------------------------------------------------------------------
-
-#ifndef AGG_SPAN_PATTERN_RESAMPLE_RGBA_INCLUDED
-#define AGG_SPAN_PATTERN_RESAMPLE_RGBA_INCLUDED
-
-#include "agg_color_rgba.h"
-#include "agg_span_image_resample.h"
-
-namespace agg
-{
-
- //=======================================span_pattern_resample_rgba_affine
- template<class ColorT,
- class Order,
- class WrapModeX,
- class WrapModeY,
- class Allocator = span_allocator<ColorT> >
- class span_pattern_resample_rgba_affine :
- public span_image_resample_affine<ColorT, Allocator>
- {
- public:
- typedef ColorT color_type;
- typedef Order order_type;
- typedef Allocator alloc_type;
- typedef span_image_resample_affine<color_type, alloc_type> base_type;
- typedef typename base_type::interpolator_type interpolator_type;
- typedef typename color_type::value_type value_type;
- typedef typename color_type::long_type long_type;
- enum
- {
- base_shift = color_type::base_shift,
- base_mask = color_type::base_mask,
- downscale_shift = image_filter_shift
- };
-
- //--------------------------------------------------------------------
- span_pattern_resample_rgba_affine(alloc_type& alloc) :
- base_type(alloc),
- m_wrap_mode_x(1),
- m_wrap_mode_y(1)
- {}
-
- //--------------------------------------------------------------------
- span_pattern_resample_rgba_affine(alloc_type& alloc,
- const rendering_buffer& src,
- interpolator_type& inter,
- const image_filter_lut& filter_) :
- base_type(alloc, src, color_type(0,0,0,0), inter, filter_),
- m_wrap_mode_x(src.width()),
- m_wrap_mode_y(src.height())
- {}
-
- //--------------------------------------------------------------------
- void source_image(const rendering_buffer& src)
- {
- base_type::source_image(src);
- m_wrap_mode_x = WrapModeX(src.width());
- m_wrap_mode_y = WrapModeX(src.height());
- }
-
- //--------------------------------------------------------------------
- color_type* generate(int x, int y, unsigned len)
- {
- color_type* span = base_type::allocator().span();
- interpolator_type& intr = base_type::interpolator();
- intr.begin(x + base_type::filter_dx_dbl(),
- y + base_type::filter_dy_dbl(), len);
- long_type fg[4];
-
- int diameter = base_type::filter().diameter();
- int filter_size = diameter << image_subpixel_shift;
- int radius_x = (diameter * base_type::m_rx) >> 1;
- int radius_y = (diameter * base_type::m_ry) >> 1;
- int maxx = base_type::source_image().width() - 1;
- int maxy = base_type::source_image().height() - 1;
- const int16* weight_array = base_type::filter().weight_array();
-
- do
- {
- intr.coordinates(&x, &y);
-
- x += base_type::filter_dx_int() - radius_x;
- y += base_type::filter_dy_int() - radius_y;
-
- fg[0] = fg[1] = fg[2] = fg[3] = image_filter_size / 2;
-
- int y_lr = m_wrap_mode_y(y >> image_subpixel_shift);
- int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) *
- base_type::m_ry_inv) >>
- image_subpixel_shift;
- int total_weight = 0;
- int x_lr_ini = x >> image_subpixel_shift;
- int x_hr_ini = ((image_subpixel_mask - (x & image_subpixel_mask)) *
- base_type::m_rx_inv) >>
- image_subpixel_shift;
- do
- {
- int weight_y = weight_array[y_hr];
- int x_lr = m_wrap_mode_x(x_lr_ini);
- int x_hr = x_hr_ini;
- const value_type* row_ptr = (const value_type*)base_type::source_image().row(y_lr);
- do
- {
- const value_type* fg_ptr = row_ptr + (x_lr << 2);
- int weight = (weight_y * weight_array[x_hr] +
- image_filter_size / 2) >>
- downscale_shift;
-
- fg[0] += fg_ptr[0] * weight;
- fg[1] += fg_ptr[1] * weight;
- fg[2] += fg_ptr[2] * weight;
- fg[3] += fg_ptr[3] * weight;
- total_weight += weight;
- x_hr += base_type::m_rx_inv;
- x_lr = ++m_wrap_mode_x;
- }
- while(x_hr < filter_size);
-
- y_hr += base_type::m_ry_inv;
- y_lr = ++m_wrap_mode_y;
- } while(y_hr < filter_size);
-
- fg[0] /= total_weight;
- fg[1] /= total_weight;
- fg[2] /= total_weight;
- fg[3] /= total_weight;
-
- if(fg[0] < 0) fg[0] = 0;
- if(fg[1] < 0) fg[1] = 0;
- if(fg[2] < 0) fg[2] = 0;
- if(fg[3] < 0) fg[3] = 0;
-
- if(fg[order_type::A] > base_mask) fg[order_type::A] = base_mask;
- if(fg[order_type::R] > fg[order_type::A]) fg[order_type::R] = fg[order_type::A];
- if(fg[order_type::G] > fg[order_type::A]) fg[order_type::G] = fg[order_type::A];
- if(fg[order_type::B] > fg[order_type::A]) fg[order_type::B] = fg[order_type::A];
-
- span->r = (value_type)fg[order_type::R];
- span->g = (value_type)fg[order_type::G];
- span->b = (value_type)fg[order_type::B];
- span->a = (value_type)fg[order_type::A];
-
- ++span;
- ++intr;
- } while(--len);
- return base_type::allocator().span();
- }
-
- private:
- WrapModeX m_wrap_mode_x;
- WrapModeY m_wrap_mode_y;
- };
-
-
-
-
-
-
-
- //============================================span_pattern_resample_rgba
- template<class ColorT,
- class Order,
- class Interpolator,
- class WrapModeX,
- class WrapModeY,
- class Allocator = span_allocator<ColorT> >
- class span_pattern_resample_rgba :
- public span_image_resample<ColorT, Interpolator, Allocator>
- {
- public:
- typedef ColorT color_type;
- typedef Order order_type;
- typedef Interpolator interpolator_type;
- typedef Allocator alloc_type;
- typedef span_image_resample<color_type, interpolator_type, alloc_type> base_type;
- typedef typename color_type::value_type value_type;
- typedef typename color_type::long_type long_type;
- enum
- {
- base_shift = color_type::base_shift,
- base_mask = color_type::base_mask,
- downscale_shift = image_filter_shift
- };
-
- //--------------------------------------------------------------------
- span_pattern_resample_rgba(alloc_type& alloc) :
- base_type(alloc),
- m_wrap_mode_x(1),
- m_wrap_mode_y(1)
- {}
-
- //--------------------------------------------------------------------
- span_pattern_resample_rgba(alloc_type& alloc,
- const rendering_buffer& src,
- interpolator_type& inter,
- const image_filter_lut& filter) :
- base_type(alloc, src, color_type(0,0,0,0), inter, filter),
- m_wrap_mode_x(src.width()),
- m_wrap_mode_y(src.height())
- {}
-
- //--------------------------------------------------------------------
- void source_image(const rendering_buffer& src)
- {
- base_type::source_image(src);
- m_wrap_mode_x = WrapModeX(src.width());
- m_wrap_mode_y = WrapModeX(src.height());
- }
-
- //--------------------------------------------------------------------
- color_type* generate(int x, int y, unsigned len)
- {
- color_type* span = base_type::allocator().span();
- interpolator_type& intr = base_type::interpolator();
- intr.begin(x + base_type::filter_dx_dbl(),
- y + base_type::filter_dy_dbl(), len);
- long_type fg[4];
-
- int diameter = base_type::filter().diameter();
- int filter_size = diameter << image_subpixel_shift;
- const int16* weight_array = base_type::filter().weight_array();
-
- do
- {
- int rx;
- int ry;
- int rx_inv = image_subpixel_size;
- int ry_inv = image_subpixel_size;
- intr.coordinates(&x, &y);
- intr.local_scale(&rx, &ry);
-
- rx = (rx * base_type::m_blur_x) >> image_subpixel_shift;
- ry = (ry * base_type::m_blur_y) >> image_subpixel_shift;
-
- if(rx < image_subpixel_size)
- {
- rx = image_subpixel_size;
- }
- else
- {
- if(rx > image_subpixel_size * base_type::m_scale_limit)
- {
- rx = image_subpixel_size * base_type::m_scale_limit;
- }
- rx_inv = image_subpixel_size * image_subpixel_size / rx;
- }
-
- if(ry < image_subpixel_size)
- {
- ry = image_subpixel_size;
- }
- else
- {
- if(ry > image_subpixel_size * base_type::m_scale_limit)
- {
- ry = image_subpixel_size * base_type::m_scale_limit;
- }
- ry_inv = image_subpixel_size * image_subpixel_size / ry;
- }
-
- int radius_x = (diameter * rx) >> 1;
- int radius_y = (diameter * ry) >> 1;
- int maxx = base_type::source_image().width() - 1;
- int maxy = base_type::source_image().height() - 1;
-
- x += base_type::filter_dx_int() - radius_x;
- y += base_type::filter_dy_int() - radius_y;
-
- fg[0] = fg[1] = fg[2] = fg[3] = image_filter_size / 2;
-
- int y_lr = m_wrap_mode_y(y >> image_subpixel_shift);
- int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) *
- ry_inv) >>
- image_subpixel_shift;
- int total_weight = 0;
- int x_lr_ini = x >> image_subpixel_shift;
- int x_hr_ini = ((image_subpixel_mask - (x & image_subpixel_mask)) *
- rx_inv) >>
- image_subpixel_shift;
-
- do
- {
- int weight_y = weight_array[y_hr];
- int x_lr = m_wrap_mode_x(x_lr_ini);
- int x_hr = x_hr_ini;
- const value_type* row_ptr = (const value_type*)base_type::source_image().row(y_lr);
- do
- {
- const value_type* fg_ptr = row_ptr + (x_lr << 2);
- int weight = (weight_y * weight_array[x_hr] +
- image_filter_size / 2) >>
- downscale_shift;
- fg[0] += fg_ptr[0] * weight;
- fg[1] += fg_ptr[1] * weight;
- fg[2] += fg_ptr[2] * weight;
- fg[3] += fg_ptr[3] * weight;
- total_weight += weight;
- x_hr += rx_inv;
- x_lr = ++m_wrap_mode_x;
- }
- while(x_hr < filter_size);
- y_hr += ry_inv;
- y_lr = ++m_wrap_mode_y;
- }
- while(y_hr < filter_size);
-
- fg[0] /= total_weight;
- fg[1] /= total_weight;
- fg[2] /= total_weight;
- fg[3] /= total_weight;
-
- if(fg[0] < 0) fg[0] = 0;
- if(fg[1] < 0) fg[1] = 0;
- if(fg[2] < 0) fg[2] = 0;
- if(fg[3] < 0) fg[3] = 0;
-
- if(fg[order_type::A] > base_mask) fg[order_type::A] = base_mask;
- if(fg[order_type::R] > fg[order_type::A]) fg[order_type::R] = fg[order_type::A];
- if(fg[order_type::G] > fg[order_type::A]) fg[order_type::G] = fg[order_type::A];
- if(fg[order_type::B] > fg[order_type::A]) fg[order_type::B] = fg[order_type::A];
-
- span->r = (value_type)fg[order_type::R];
- span->g = (value_type)fg[order_type::G];
- span->b = (value_type)fg[order_type::B];
- span->a = (value_type)fg[order_type::A];
-
- ++span;
- ++intr;
- } while(--len);
- return base_type::allocator().span();
- }
-
- private:
- WrapModeX m_wrap_mode_x;
- WrapModeY m_wrap_mode_y;
- };
-
-}
-
-
-#endif
diff --git a/agg/inc/agg_span_pattern_rgb.h b/agg/inc/agg_span_pattern_rgb.h
index 2e17f11e7c70..91c550e20fe7 100755
--- a/agg/inc/agg_span_pattern_rgb.h
+++ b/agg/inc/agg_span_pattern_rgb.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -26,138 +26,69 @@
#define AGG_SPAN_PATTERN_RGB_INCLUDED
#include "agg_basics.h"
-#include "agg_pixfmt_rgb.h"
-#include "agg_span_pattern.h"
namespace agg
{
- //=======================================================span_pattern_rgb
- template<class ColorT,
- class Order,
- class WrapModeX,
- class WrapModeY,
- class Allocator = span_allocator<ColorT> >
- class span_pattern_rgb : public span_pattern_base<ColorT, Allocator>
+
+ //========================================================span_pattern_rgb
+ template<class Source> class span_pattern_rgb
{
public:
- typedef ColorT color_type;
- typedef Order order_type;
- typedef Allocator alloc_type;
- typedef span_pattern_base<color_type, alloc_type> base_type;
+ typedef Source source_type;
+ typedef typename source_type::color_type color_type;
+ typedef typename source_type::order_type order_type;
typedef typename color_type::value_type value_type;
typedef typename color_type::calc_type calc_type;
- enum
- {
- base_shift = color_type::base_shift,
- base_mask = color_type::base_mask
- };
//--------------------------------------------------------------------
- span_pattern_rgb(alloc_type& alloc) :
- base_type(alloc),
- m_wrap_mode_x(1),
- m_wrap_mode_y(1)
+ span_pattern_rgb() {}
+ span_pattern_rgb(source_type& src,
+ unsigned offset_x, unsigned offset_y) :
+ m_src(&src),
+ m_offset_x(offset_x),
+ m_offset_y(offset_y),
+ m_alpha(color_type::base_mask)
{}
- //----------------------------------------------------------------
- span_pattern_rgb(alloc_type& alloc,
- const rendering_buffer& src,
- unsigned offset_x,
- unsigned offset_y,
- value_type alpha = base_mask) :
- base_type(alloc, src, offset_x, offset_y, alpha),
- m_wrap_mode_x(src.width()),
- m_wrap_mode_y(src.height())
- {}
+ //--------------------------------------------------------------------
+ void attach(source_type& v) { m_src = &v; }
+ source_type& source() { return *m_src; }
+ const source_type& source() const { return *m_src; }
- //-------------------------------------------------------------------
- void source_image(const rendering_buffer& src)
- {
- base_type::source_image(src);
- m_wrap_mode_x = WrapModeX(src.width());
- m_wrap_mode_y = WrapModeY(src.height());
- }
+ //--------------------------------------------------------------------
+ void offset_x(unsigned v) { m_offset_x = v; }
+ void offset_y(unsigned v) { m_offset_y = v; }
+ unsigned offset_x() const { return m_offset_x; }
+ unsigned offset_y() const { return m_offset_y; }
+ void alpha(value_type v) { m_alpha = v; }
+ value_type alpha() const { return m_alpha; }
//--------------------------------------------------------------------
- color_type* generate(int x, int y, unsigned len)
+ void prepare() {}
+ void generate(color_type* span, int x, int y, unsigned len)
{
- color_type* span = base_type::allocator().span();
- unsigned sx = m_wrap_mode_x(base_type::offset_x() + x);
- const value_type* row_ptr =
- (const value_type*)base_type::source_image().row(
- m_wrap_mode_y(
- base_type::offset_y() + y));
+ x += m_offset_x;
+ y += m_offset_y;
+ const value_type* p = (const value_type*)m_src->span(x, y, len);
do
{
- const value_type* p = row_ptr + sx + sx + sx;
span->r = p[order_type::R];
span->g = p[order_type::G];
span->b = p[order_type::B];
- span->a = base_type::alpha_int();
- sx = ++m_wrap_mode_x;
+ span->a = m_alpha;
+ p = m_src->next_x();
++span;
}
while(--len);
- return base_type::allocator().span();
}
private:
- WrapModeX m_wrap_mode_x;
- WrapModeY m_wrap_mode_y;
- };
-
-
-
-/*
- //=========================================================span_pattern_rgb
- template<class ColorT, class Order, class Allocator = span_allocator<ColorT> >
- class span_pattern_rgb : public span_pattern<rgba8, int8u, Allocator>
- {
- public:
- typedef Allocator alloc_type;
- typedef rgba8 color_type;
- typedef span_pattern<color_type, int8u, alloc_type> base_type;
+ source_type* m_src;
+ unsigned m_offset_x;
+ unsigned m_offset_y;
+ value_type m_alpha;
- //--------------------------------------------------------------------
- span_pattern_rgb24(alloc_type& alloc) : base_type(alloc) {}
-
- //----------------------------------------------------------------
- span_pattern_rgb24(alloc_type& alloc,
- const rendering_buffer& src,
- unsigned offset_x, unsigned offset_y,
- int8u alpha = 255) :
- base_type(alloc, src, offset_x, offset_y, alpha)
- {}
-
-
- //--------------------------------------------------------------------
- color_type* generate(int x, int y, unsigned len)
- {
- color_type* span = base_type::allocator().span();
- unsigned sx = (base_type::offset_x() + x) % base_type::source_image().width();
- unsigned wp = base_type::source_image().width() * 3;
- const int8u* p = base_type::source_image().row((base_type::offset_y() + y) % base_type::source_image().height());
- p += sx * 3;
- do
- {
- span->r = p[Order::R];
- span->g = p[Order::G];
- span->b = p[Order::B];
- span->a = base_type::alpha();
- p += 3;
- ++sx;
- ++span;
- if(sx >= base_type::source_image().width())
- {
- sx -= base_type::source_image().width();
- p -= wp;
- }
- }
- while(--len);
- return base_type::allocator().span();
- }
};
-*/
}
diff --git a/agg/inc/agg_span_pattern_rgba.h b/agg/inc/agg_span_pattern_rgba.h
index d952d0733696..ce9e421ae9cc 100755
--- a/agg/inc/agg_span_pattern_rgba.h
+++ b/agg/inc/agg_span_pattern_rgba.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -26,83 +26,66 @@
#define AGG_SPAN_PATTERN_RGBA_INCLUDED
#include "agg_basics.h"
-#include "agg_pixfmt_rgba.h"
-#include "agg_span_pattern.h"
namespace agg
{
//======================================================span_pattern_rgba
- template<class ColorT,
- class Order,
- class WrapModeX,
- class WrapModeY,
- class Allocator = span_allocator<ColorT> >
- class span_pattern_rgba : public span_pattern_base<ColorT, Allocator>
+ template<class Source> class span_pattern_rgba
{
public:
- typedef ColorT color_type;
- typedef Order order_type;
- typedef Allocator alloc_type;
- typedef span_pattern_base<color_type, alloc_type> base_type;
+ typedef Source source_type;
+ typedef typename source_type::color_type color_type;
+ typedef typename source_type::order_type order_type;
typedef typename color_type::value_type value_type;
typedef typename color_type::calc_type calc_type;
- enum
- {
- base_shift = color_type::base_shift,
- base_mask = color_type::base_mask
- };
//--------------------------------------------------------------------
- span_pattern_rgba(alloc_type& alloc) :
- base_type(alloc),
- m_wrap_mode_x(1),
- m_wrap_mode_y(1)
- {}
-
- //----------------------------------------------------------------
- span_pattern_rgba(alloc_type& alloc,
- const rendering_buffer& src,
+ span_pattern_rgba() {}
+ span_pattern_rgba(source_type& src,
unsigned offset_x, unsigned offset_y) :
- base_type(alloc, src, offset_x, offset_y, 0),
- m_wrap_mode_x(src.width()),
- m_wrap_mode_y(src.height())
+ m_src(&src),
+ m_offset_x(offset_x),
+ m_offset_y(offset_y)
{}
- //-------------------------------------------------------------------
- void source_image(const rendering_buffer& src)
- {
- base_type::source_image(src);
- m_wrap_mode_x = WrapModeX(src.width());
- m_wrap_mode_y = WrapModeY(src.height());
- }
+ //--------------------------------------------------------------------
+ void attach(source_type& v) { m_src = &v; }
+ source_type& source() { return *m_src; }
+ const source_type& source() const { return *m_src; }
+
+ //--------------------------------------------------------------------
+ void offset_x(unsigned v) { m_offset_x = v; }
+ void offset_y(unsigned v) { m_offset_y = v; }
+ unsigned offset_x() const { return m_offset_x; }
+ unsigned offset_y() const { return m_offset_y; }
+ void alpha(value_type) {}
+ value_type alpha() const { return 0; }
//--------------------------------------------------------------------
- color_type* generate(int x, int y, unsigned len)
+ void prepare() {}
+ void generate(color_type* span, int x, int y, unsigned len)
{
- color_type* span = base_type::allocator().span();
- unsigned sx = m_wrap_mode_x(base_type::offset_x() + x);
- const value_type* row_ptr =
- (const value_type*)base_type::source_image().row(
- m_wrap_mode_y(
- base_type::offset_y() + y));
+ x += m_offset_x;
+ y += m_offset_y;
+ const value_type* p = (const value_type*)m_src->span(x, y, len);
do
{
- const value_type* p = row_ptr + (sx << 2);
span->r = p[order_type::R];
span->g = p[order_type::G];
span->b = p[order_type::B];
span->a = p[order_type::A];
- sx = ++m_wrap_mode_x;
+ p = (const value_type*)m_src->next_x();
++span;
}
while(--len);
- return base_type::allocator().span();
}
private:
- WrapModeX m_wrap_mode_x;
- WrapModeY m_wrap_mode_y;
+ source_type* m_src;
+ unsigned m_offset_x;
+ unsigned m_offset_y;
+
};
}
diff --git a/agg/inc/agg_span_solid.h b/agg/inc/agg_span_solid.h
index aa8374bfe61f..7955b51cf349 100755
--- a/agg/inc/agg_span_solid.h
+++ b/agg/inc/agg_span_solid.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -21,36 +21,26 @@
#define AGG_SPAN_SOLID_INCLUDED
#include "agg_basics.h"
-#include "agg_span_generator.h"
namespace agg
{
//--------------------------------------------------------------span_solid
- template<class ColorT, class Allocator = span_allocator<ColorT> >
- class span_solid : public span_generator<ColorT, Allocator>
+ template<class ColorT> class span_solid
{
public:
- typedef Allocator alloc_type;
typedef ColorT color_type;
- typedef span_generator<color_type, alloc_type> base_type;
-
- //--------------------------------------------------------------------
- span_solid(alloc_type& alloc) : base_type(alloc) {}
//--------------------------------------------------------------------
void color(const color_type& c) { m_color = c; }
const color_type& color() const { return m_color; }
//--------------------------------------------------------------------
- color_type* generate(int x, int y, unsigned len)
+ void prepare() {}
+
+ //--------------------------------------------------------------------
+ void generate(color_type* span, int x, int y, unsigned len)
{
- color_type* span = base_type::allocator().span();
- do
- {
- *span++ = m_color;
- }
- while(--len);
- return base_type::allocator().span();
+ do { *span++ = m_color; } while(--len);
}
private:
diff --git a/agg/inc/agg_span_subdiv_adaptor.h b/agg/inc/agg_span_subdiv_adaptor.h
index 60196d705bdb..2db106cdce60 100755
--- a/agg/inc/agg_span_subdiv_adaptor.h
+++ b/agg/inc/agg_span_subdiv_adaptor.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -28,10 +28,10 @@ namespace agg
typedef Interpolator interpolator_type;
typedef typename interpolator_type::trans_type trans_type;
- enum
+ enum sublixel_scale_e
{
subpixel_shift = SubpixelShift,
- subpixel_size = 1 << subpixel_shift
+ subpixel_scale = 1 << subpixel_shift
};
@@ -87,7 +87,7 @@ namespace agg
void begin(double x, double y, unsigned len)
{
m_pos = 1;
- m_src_x = int(x * subpixel_size) + subpixel_size;
+ m_src_x = iround(x * subpixel_scale) + subpixel_scale;
m_src_y = y;
m_len = len;
if(len > m_subdiv_size) len = m_subdiv_size;
@@ -102,12 +102,12 @@ namespace agg
{
unsigned len = m_len;
if(len > m_subdiv_size) len = m_subdiv_size;
- m_interpolator->resynchronize(double(m_src_x) / double(subpixel_size) + len,
+ m_interpolator->resynchronize(double(m_src_x) / double(subpixel_scale) + len,
m_src_y,
len);
m_pos = 0;
}
- m_src_x += subpixel_size;
+ m_src_x += subpixel_scale;
++m_pos;
--m_len;
}
diff --git a/agg/inc/agg_trans_affine.h b/agg/inc/agg_trans_affine.h
index 5a4098f904de..70dfbc49007b 100755
--- a/agg/inc/agg_trans_affine.h
+++ b/agg/inc/agg_trans_affine.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -24,7 +24,7 @@
namespace agg
{
- const double affine_epsilon = 1e-14; // About of precision of doubles
+ const double affine_epsilon = 1e-14;
//============================================================trans_affine
//
@@ -84,48 +84,58 @@ namespace agg
// m *= agg::trans_affine_rotation(30.0 * 3.1415926 / 180.0); // rotate
// m *= agg::trans_affine_translation(100.0, 100.0); // move back to (100,100)
//----------------------------------------------------------------------
- class trans_affine
+ struct trans_affine
{
- public:
+ double sx, shy, shx, sy, tx, ty;
+
//------------------------------------------ Construction
- // Construct an identity matrix - it does not transform anything
+ // Identity matrix
trans_affine() :
- m0(1.0), m1(0.0), m2(0.0), m3(1.0), m4(0.0), m5(0.0)
+ sx(1.0), shy(0.0), shx(0.0), sy(1.0), tx(0.0), ty(0.0)
{}
- // Construct a custom matrix. Usually used in derived classes
- trans_affine(double v0, double v1, double v2, double v3, double v4, double v5) :
- m0(v0), m1(v1), m2(v2), m3(v3), m4(v4), m5(v5)
+ // Custom matrix. Usually used in derived classes
+ trans_affine(double v0, double v1, double v2,
+ double v3, double v4, double v5) :
+ sx(v0), shy(v1), shx(v2), sy(v3), tx(v4), ty(v5)
{}
- // Construct a matrix to transform a parallelogram to another one.
- trans_affine(const double* rect, const double* parl)
- {
- parl_to_parl(rect, parl);
- }
+ // Custom matrix from m[6]
+ explicit trans_affine(const double* m) :
+ sx(m[0]), shy(m[1]), shx(m[2]), sy(m[3]), tx(m[4]), ty(m[5])
+ {}
- // Construct a matrix to transform a rectangle to a parallelogram.
+ // Rectangle to a parallelogram.
trans_affine(double x1, double y1, double x2, double y2,
const double* parl)
{
rect_to_parl(x1, y1, x2, y2, parl);
}
- // Construct a matrix to transform a parallelogram to a rectangle.
+ // Parallelogram to a rectangle.
trans_affine(const double* parl,
double x1, double y1, double x2, double y2)
{
parl_to_rect(parl, x1, y1, x2, y2);
}
+ // Arbitrary parallelogram transformation.
+ trans_affine(const double* src, const double* dst)
+ {
+ parl_to_parl(src, dst);
+ }
//---------------------------------- Parellelogram transformations
- // Calculate a matrix to transform a parallelogram to another one.
- // src and dst are pointers to arrays of three points
- // (double[6], x,y,...) that identify three corners of the
- // parallelograms assuming implicit fourth points.
- // There are also transformations rectangtle to parallelogram and
- // parellelogram to rectangle
+ // transform a parallelogram to another one. Src and dst are
+ // pointers to arrays of three points (double[6], x1,y1,...) that
+ // identify three corners of the parallelograms assuming implicit
+ // fourth point. The arguments are arrays of double[6] mapped
+ // to x1,y1, x2,y2, x3,y3 where the coordinates are:
+ // *-----------------*
+ // / (x3,y3)/
+ // / /
+ // /(x1,y1) (x2,y2)/
+ // *-----------------*
const trans_affine& parl_to_parl(const double* src,
const double* dst);
@@ -139,15 +149,27 @@ namespace agg
//------------------------------------------ Operations
- // Reset - actually load an identity matrix
+ // Reset - load an identity matrix
const trans_affine& reset();
+ // Direct transformations operations
+ const trans_affine& translate(double x, double y);
+ const trans_affine& rotate(double a);
+ const trans_affine& scale(double s);
+ const trans_affine& scale(double x, double y);
+
// Multiply matrix to another one
const trans_affine& multiply(const trans_affine& m);
// Multiply "m" to "this" and assign the result to "this"
const trans_affine& premultiply(const trans_affine& m);
+ // Multiply matrix to inverse of another one
+ const trans_affine& multiply_inv(const trans_affine& m);
+
+ // Multiply inverse of "m" to "this" and assign the result to "this"
+ const trans_affine& premultiply_inv(const trans_affine& m);
+
// Invert matrix. Do not try to invert degenerate matrices,
// there's no check for validity. If you set scale to 0 and
// then try to invert matrix, expect unpredictable result.
@@ -163,31 +185,44 @@ namespace agg
// Store matrix to an array [6] of double
void store_to(double* m) const
{
- *m++ = m0; *m++ = m1; *m++ = m2; *m++ = m3; *m++ = m4; *m++ = m5;
+ *m++ = sx; *m++ = shy; *m++ = shx; *m++ = sy; *m++ = tx; *m++ = ty;
}
// Load matrix from an array [6] of double
const trans_affine& load_from(const double* m)
{
- m0 = *m++; m1 = *m++; m2 = *m++; m3 = *m++; m4 = *m++; m5 = *m++;
+ sx = *m++; shy = *m++; shx = *m++; sy = *m++; tx = *m++; ty = *m++;
return *this;
}
//------------------------------------------- Operators
- // Multiply current matrix to another one
+ // Multiply the matrix by another one
const trans_affine& operator *= (const trans_affine& m)
{
return multiply(m);
}
- // Multiply current matrix to another one and return
+ // Multiply the matrix by inverse of another one
+ const trans_affine& operator /= (const trans_affine& m)
+ {
+ return multiply_inv(m);
+ }
+
+ // Multiply the matrix by another one and return
// the result in a separete matrix.
trans_affine operator * (const trans_affine& m)
{
return trans_affine(*this).multiply(m);
}
+ // Multiply the matrix by inverse of another one
+ // and return the result in a separete matrix.
+ trans_affine operator / (const trans_affine& m)
+ {
+ return trans_affine(*this).multiply_inv(m);
+ }
+
// Calculate and return the inverse matrix
trans_affine operator ~ () const
{
@@ -208,19 +243,28 @@ namespace agg
}
//-------------------------------------------- Transformations
- // Direct transformation x and y
+ // Direct transformation of x and y
void transform(double* x, double* y) const;
- // Inverse transformation x and y. It works slower than the
- // direct transformation, so if the performance is critical
- // it's better to invert() the matrix and then use transform()
+ // Direct transformation of x and y, 2x2 matrix only, no translation
+ void transform_2x2(double* x, double* y) const;
+
+ // Inverse transformation of x and y. It works slower than the
+ // direct transformation. For massive operations it's better to
+ // invert() the matrix and then use direct transformations.
void inverse_transform(double* x, double* y) const;
//-------------------------------------------- Auxiliary
// Calculate the determinant of matrix
double determinant() const
{
- return 1.0 / (m0 * m3 - m1 * m2);
+ return sx * sy - shy * shx;
+ }
+
+ // Calculate the reciprocal of the determinant
+ double determinant_reciprocal() const
+ {
+ return 1.0 / (sx * sy - shy * shx);
}
// Get the average scale (by X and Y).
@@ -228,57 +272,108 @@ namespace agg
// decomposinting curves into line segments.
double scale() const;
+ // Check to see if the matrix is not degenerate
+ bool is_valid(double epsilon = affine_epsilon) const;
+
// Check to see if it's an identity matrix
bool is_identity(double epsilon = affine_epsilon) const;
// Check to see if two matrices are equal
bool is_equal(const trans_affine& m, double epsilon = affine_epsilon) const;
- // Determine the major parameters. Use carefully considering degenerate matrices
+ // Determine the major parameters. Use with caution considering
+ // possible degenerate cases.
double rotation() const;
void translation(double* dx, double* dy) const;
- void scaling(double* sx, double* sy) const;
- void scaling_abs(double* sx, double* sy) const
- {
- *sx = sqrt(m0*m0 + m2*m2);
- *sy = sqrt(m1*m1 + m3*m3);
- }
-
- private:
- double m0;
- double m1;
- double m2;
- double m3;
- double m4;
- double m5;
+ void scaling(double* x, double* y) const;
+ void scaling_abs(double* x, double* y) const;
};
//------------------------------------------------------------------------
inline void trans_affine::transform(double* x, double* y) const
{
- register double tx = *x;
- *x = tx * m0 + *y * m2 + m4;
- *y = tx * m1 + *y * m3 + m5;
+ register double tmp = *x;
+ *x = tmp * sx + *y * shx + tx;
+ *y = tmp * shy + *y * sy + ty;
+ }
+
+ //------------------------------------------------------------------------
+ inline void trans_affine::transform_2x2(double* x, double* y) const
+ {
+ register double tmp = *x;
+ *x = tmp * sx + *y * shx;
+ *y = tmp * shy + *y * sy;
}
//------------------------------------------------------------------------
inline void trans_affine::inverse_transform(double* x, double* y) const
{
- register double d = determinant();
- register double a = (*x - m4) * d;
- register double b = (*y - m5) * d;
- *x = a * m3 - b * m2;
- *y = b * m0 - a * m1;
+ register double d = determinant_reciprocal();
+ register double a = (*x - tx) * d;
+ register double b = (*y - ty) * d;
+ *x = a * sy - b * shx;
+ *y = b * sx - a * shy;
}
//------------------------------------------------------------------------
inline double trans_affine::scale() const
{
- double x = 0.707106781 * m0 + 0.707106781 * m2;
- double y = 0.707106781 * m1 + 0.707106781 * m3;
+ double x = 0.707106781 * sx + 0.707106781 * shx;
+ double y = 0.707106781 * shy + 0.707106781 * sy;
return sqrt(x*x + y*y);
}
+ //------------------------------------------------------------------------
+ inline const trans_affine& trans_affine::translate(double x, double y)
+ {
+ tx += x;
+ ty += y;
+ return *this;
+ }
+
+ //------------------------------------------------------------------------
+ inline const trans_affine& trans_affine::rotate(double a)
+ {
+ double ca = cos(a);
+ double sa = sin(a);
+ double t0 = sx * ca - shy * sa;
+ double t2 = shx * ca - sy * sa;
+ double t4 = tx * ca - ty * sa;
+ shy = sx * sa + shy * ca;
+ sy = shx * sa + sy * ca;
+ ty = tx * sa + ty * ca;
+ sx = t0;
+ shx = t2;
+ tx = t4;
+ return *this;
+ }
+
+ //------------------------------------------------------------------------
+ inline const trans_affine& trans_affine::scale(double x, double y)
+ {
+ double mm0 = x; // Possible hint for the optimizer
+ double mm3 = y;
+ sx *= mm0;
+ shx *= mm0;
+ tx *= mm0;
+ shy *= mm3;
+ sy *= mm3;
+ ty *= mm3;
+ return *this;
+ }
+
+ //------------------------------------------------------------------------
+ inline const trans_affine& trans_affine::scale(double s)
+ {
+ double m = s; // Possible hint for the optimizer
+ sx *= m;
+ shx *= m;
+ tx *= m;
+ shy *= m;
+ sy *= m;
+ ty *= m;
+ return *this;
+ }
//------------------------------------------------------------------------
inline const trans_affine& trans_affine::premultiply(const trans_affine& m)
@@ -287,6 +382,31 @@ namespace agg
return *this = t.multiply(*this);
}
+ //------------------------------------------------------------------------
+ inline const trans_affine& trans_affine::multiply_inv(const trans_affine& m)
+ {
+ trans_affine t = m;
+ t.invert();
+ return multiply(t);
+ }
+
+ //------------------------------------------------------------------------
+ inline const trans_affine& trans_affine::premultiply_inv(const trans_affine& m)
+ {
+ trans_affine t = m;
+ t.invert();
+ return *this = t.multiply(*this);
+ }
+
+ //------------------------------------------------------------------------
+ inline void trans_affine::scaling_abs(double* x, double* y) const
+ {
+ // Used to calculate scaling coefficients in image resampling.
+ // When there is considerable shear this method gives us much
+ // better estimation than just sx, sy.
+ *x = sqrt(sx * sx + shx * shx);
+ *y = sqrt(shy * shy + sy * sy);
+ }
//====================================================trans_affine_rotation
// Rotation matrix. sin() and cos() are calculated twice for the same angle.
@@ -302,12 +422,12 @@ namespace agg
};
//====================================================trans_affine_scaling
- // Scaling matrix. sx, sy - scale coefficients by X and Y respectively
+ // Scaling matrix. x, y - scale coefficients by X and Y respectively
class trans_affine_scaling : public trans_affine
{
public:
- trans_affine_scaling(double sx, double sy) :
- trans_affine(sx, 0.0, 0.0, sy, 0.0, 0.0)
+ trans_affine_scaling(double x, double y) :
+ trans_affine(x, 0.0, 0.0, y, 0.0, 0.0)
{}
trans_affine_scaling(double s) :
@@ -320,8 +440,8 @@ namespace agg
class trans_affine_translation : public trans_affine
{
public:
- trans_affine_translation(double tx, double ty) :
- trans_affine(1.0, 0.0, 0.0, 1.0, tx, ty)
+ trans_affine_translation(double x, double y) :
+ trans_affine(1.0, 0.0, 0.0, 1.0, x, y)
{}
};
@@ -330,12 +450,66 @@ namespace agg
class trans_affine_skewing : public trans_affine
{
public:
- trans_affine_skewing(double sx, double sy) :
- trans_affine(1.0, tan(sy), tan(sx), 1.0, 0.0, 0.0)
+ trans_affine_skewing(double x, double y) :
+ trans_affine(1.0, tan(y), tan(x), 1.0, 0.0, 0.0)
+ {}
+ };
+
+
+ //===============================================trans_affine_line_segment
+ // Rotate, Scale and Translate, associating 0...dist with line segment
+ // x1,y1,x2,y2
+ class trans_affine_line_segment : public trans_affine
+ {
+ public:
+ trans_affine_line_segment(double x1, double y1, double x2, double y2,
+ double dist)
+ {
+ double dx = x2 - x1;
+ double dy = y2 - y1;
+ if(dist > 0.0)
+ {
+ multiply(trans_affine_scaling(sqrt(dx * dx + dy * dy) / dist));
+ }
+ multiply(trans_affine_rotation(atan2(dy, dx)));
+ multiply(trans_affine_translation(x1, y1));
+ }
+ };
+
+
+ //============================================trans_affine_reflection_unit
+ // Reflection matrix. Reflect coordinates across the line through
+ // the origin containing the unit vector (ux, uy).
+ // Contributed by John Horigan
+ class trans_affine_reflection_unit : public trans_affine
+ {
+ public:
+ trans_affine_reflection_unit(double ux, double uy) :
+ trans_affine(2.0 * ux * ux - 1.0,
+ 2.0 * ux * uy,
+ 2.0 * ux * uy,
+ 2.0 * uy * uy - 1.0,
+ 0.0, 0.0)
{}
};
+ //=================================================trans_affine_reflection
+ // Reflection matrix. Reflect coordinates across the line through
+ // the origin at the angle a or containing the non-unit vector (x, y).
+ // Contributed by John Horigan
+ class trans_affine_reflection : public trans_affine_reflection_unit
+ {
+ public:
+ trans_affine_reflection(double a) :
+ trans_affine_reflection_unit(cos(a), sin(a))
+ {}
+
+
+ trans_affine_reflection(double x, double y) :
+ trans_affine_reflection_unit(x / sqrt(x * x + y * y), y / sqrt(x * x + y * y))
+ {}
+ };
}
diff --git a/agg/inc/agg_trans_bilinear.h b/agg/inc/agg_trans_bilinear.h
index 7398a866d3b0..e5367bb1f6eb 100755
--- a/agg/inc/agg_trans_bilinear.h
+++ b/agg/inc/agg_trans_bilinear.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
diff --git a/agg/inc/agg_trans_double_path.h b/agg/inc/agg_trans_double_path.h
index 16ea9f7264bd..91478a70ed3b 100755
--- a/agg/inc/agg_trans_double_path.h
+++ b/agg/inc/agg_trans_double_path.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
diff --git a/agg/inc/agg_trans_perspective.h b/agg/inc/agg_trans_perspective.h
index a127c9095ad2..86116625cd8f 100755
--- a/agg/inc/agg_trans_perspective.h
+++ b/agg/inc/agg_trans_perspective.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -19,124 +19,211 @@
#ifndef AGG_TRANS_PERSPECTIVE_INCLUDED
#define AGG_TRANS_PERSPECTIVE_INCLUDED
-#include "agg_basics.h"
-#include "agg_simul_eq.h"
+#include "agg_trans_affine.h"
namespace agg
{
//=======================================================trans_perspective
- class trans_perspective
+ struct trans_perspective
{
- public:
- //--------------------------------------------------------------------
- trans_perspective() : m_valid(false) {}
+ double sx, shy, w0, shx, sy, w1, tx, ty, w2;
+ //------------------------------------------------------- Construction
+ // Identity matrix
+ trans_perspective() :
+ sx (1), shy(0), w0(0),
+ shx(0), sy (1), w1(0),
+ tx (0), ty (0), w2(1) {}
- //--------------------------------------------------------------------
- // Arbitrary quadrangle transformations
- trans_perspective(const double* src, const double* dst)
- {
- quad_to_quad(src, dst);
- }
+ // Custom matrix
+ trans_perspective(double v0, double v1, double v2,
+ double v3, double v4, double v5,
+ double v6, double v7, double v8) :
+ sx (v0), shy(v1), w0(v2),
+ shx(v3), sy (v4), w1(v5),
+ tx (v6), ty (v7), w2(v8) {}
+ // Custom matrix from m[9]
+ explicit trans_perspective(const double* m) :
+ sx (m[0]), shy(m[1]), w0(m[2]),
+ shx(m[3]), sy (m[4]), w1(m[5]),
+ tx (m[6]), ty (m[7]), w2(m[8]) {}
- //--------------------------------------------------------------------
- // Direct transformations
+ // From affine
+ explicit trans_perspective(const trans_affine& a) :
+ sx (a.sx ), shy(a.shy), w0(0),
+ shx(a.shx), sy (a.sy ), w1(0),
+ tx (a.tx ), ty (a.ty ), w2(1) {}
+
+ // Rectangle to quadrilateral
trans_perspective(double x1, double y1, double x2, double y2,
- const double* quad)
+ const double* quad);
+
+ // Quadrilateral to rectangle
+ trans_perspective(const double* quad,
+ double x1, double y1, double x2, double y2);
+
+ // Arbitrary quadrilateral transformations
+ trans_perspective(const double* src, const double* dst);
+
+ //-------------------------------------- Quadrilateral transformations
+ // The arguments are double[8] that are mapped to quadrilaterals:
+ // x1,y1, x2,y2, x3,y3, x4,y4
+ bool quad_to_quad(const double* qs, const double* qd);
+
+ bool rect_to_quad(double x1, double y1,
+ double x2, double y2,
+ const double* q);
+
+ bool quad_to_rect(const double* q,
+ double x1, double y1,
+ double x2, double y2);
+
+ // Map square (0,0,1,1) to the quadrilateral and vice versa
+ bool square_to_quad(const double* q);
+ bool quad_to_square(const double* q);
+
+
+ //--------------------------------------------------------- Operations
+ // Reset - load an identity matrix
+ const trans_perspective& reset();
+
+ // Invert matrix. Returns false in degenerate case
+ bool invert();
+
+ // Direct transformations operations
+ const trans_perspective& translate(double x, double y);
+ const trans_perspective& rotate(double a);
+ const trans_perspective& scale(double s);
+ const trans_perspective& scale(double x, double y);
+
+ // Multiply the matrix by another one
+ const trans_perspective& multiply(const trans_perspective& m);
+
+ // Multiply "m" by "this" and assign the result to "this"
+ const trans_perspective& premultiply(const trans_perspective& m);
+
+ // Multiply matrix to inverse of another one
+ const trans_perspective& multiply_inv(const trans_perspective& m);
+
+ // Multiply inverse of "m" by "this" and assign the result to "this"
+ const trans_perspective& premultiply_inv(const trans_perspective& m);
+
+ // Multiply the matrix by another one
+ const trans_perspective& multiply(const trans_affine& m);
+
+ // Multiply "m" by "this" and assign the result to "this"
+ const trans_perspective& premultiply(const trans_affine& m);
+
+ // Multiply the matrix by inverse of another one
+ const trans_perspective& multiply_inv(const trans_affine& m);
+
+ // Multiply inverse of "m" by "this" and assign the result to "this"
+ const trans_perspective& premultiply_inv(const trans_affine& m);
+
+ //--------------------------------------------------------- Load/Store
+ void store_to(double* m) const;
+ const trans_perspective& load_from(const double* m);
+
+ //---------------------------------------------------------- Operators
+ // Multiply the matrix by another one
+ const trans_perspective& operator *= (const trans_perspective& m)
+ {
+ return multiply(m);
+ }
+ const trans_perspective& operator *= (const trans_affine& m)
{
- rect_to_quad(x1, y1, x2, y2, quad);
+ return multiply(m);
}
+ // Multiply the matrix by inverse of another one
+ const trans_perspective& operator /= (const trans_perspective& m)
+ {
+ return multiply_inv(m);
+ }
+ const trans_perspective& operator /= (const trans_affine& m)
+ {
+ return multiply_inv(m);
+ }
- //--------------------------------------------------------------------
- // Reverse transformations
- trans_perspective(const double* quad,
- double x1, double y1, double x2, double y2)
+ // Multiply the matrix by another one and return
+ // the result in a separete matrix.
+ trans_perspective operator * (const trans_perspective& m)
+ {
+ return trans_perspective(*this).multiply(m);
+ }
+ trans_perspective operator * (const trans_affine& m)
{
- quad_to_rect(quad, x1, y1, x2, y2);
+ return trans_perspective(*this).multiply(m);
}
+ // Multiply the matrix by inverse of another one
+ // and return the result in a separete matrix.
+ trans_perspective operator / (const trans_perspective& m)
+ {
+ return trans_perspective(*this).multiply_inv(m);
+ }
+ trans_perspective operator / (const trans_affine& m)
+ {
+ return trans_perspective(*this).multiply_inv(m);
+ }
- //--------------------------------------------------------------------
- // Set the transformations using two arbitrary quadrangles.
- void quad_to_quad(const double* src, const double* dst)
+ // Calculate and return the inverse matrix
+ trans_perspective operator ~ () const
{
+ trans_perspective ret = *this;
+ ret.invert();
+ return ret;
+ }
- double left[8][8];
- double right[8][1];
+ // Equal operator with default epsilon
+ bool operator == (const trans_perspective& m) const
+ {
+ return is_equal(m, affine_epsilon);
+ }
- unsigned i;
- for (i = 0; i < 4; i++)
- {
- unsigned ix = i * 2;
- unsigned iy = ix + 1;
-
- left[ix][0] = 1.0;
- left[ix][1] = src[ix];
- left[ix][2] = src[iy];
- left[ix][3] = 0.0;
- left[ix][4] = 0.0;
- left[ix][5] = 0.0;
- left[ix][6] = -src[ix] * dst[ix];
- left[ix][7] = -src[iy] * dst[ix];
- right[ix][0] = dst[ix];
-
- left[iy][0] = 0.0;
- left[iy][1] = 0.0;
- left[iy][2] = 0.0;
- left[iy][3] = 1.0;
- left[iy][4] = src[ix];
- left[iy][5] = src[iy];
- left[iy][6] = -src[ix] * dst[iy];
- left[iy][7] = -src[iy] * dst[iy];
- right[iy][0] = dst[iy];
- }
- m_valid = simul_eq<8, 1>::solve(left, right, m_mtx);
+ // Not Equal operator with default epsilon
+ bool operator != (const trans_perspective& m) const
+ {
+ return !is_equal(m, affine_epsilon);
}
+ //---------------------------------------------------- Transformations
+ // Direct transformation of x and y
+ void transform(double* x, double* y) const;
- //--------------------------------------------------------------------
- // Set the direct transformations, i.e., rectangle -> quadrangle
- void rect_to_quad(double x1, double y1, double x2, double y2,
- const double* quad)
- {
- double src[8];
- src[0] = src[6] = x1;
- src[2] = src[4] = x2;
- src[1] = src[3] = y1;
- src[5] = src[7] = y2;
- quad_to_quad(src, quad);
- }
+ // Direct transformation of x and y, affine part only
+ void transform_affine(double* x, double* y) const;
+ // Direct transformation of x and y, 2x2 matrix only, no translation
+ void transform_2x2(double* x, double* y) const;
- //--------------------------------------------------------------------
- // Set the reverse transformations, i.e., quadrangle -> rectangle
- void quad_to_rect(const double* quad,
- double x1, double y1, double x2, double y2)
- {
- double dst[8];
- dst[0] = dst[6] = x1;
- dst[2] = dst[4] = x2;
- dst[1] = dst[3] = y1;
- dst[5] = dst[7] = y2;
- quad_to_quad(quad, dst);
- }
+ // Inverse transformation of x and y. It works slow because
+ // it explicitly inverts the matrix on every call. For massive
+ // operations it's better to invert() the matrix and then use
+ // direct transformations.
+ void inverse_transform(double* x, double* y) const;
+
+
+ //---------------------------------------------------------- Auxiliary
+ const trans_perspective& from_affine(const trans_affine& a);
+ double determinant() const;
+ double determinant_reciprocal() const;
+
+ bool is_valid(double epsilon = affine_epsilon) const;
+ bool is_identity(double epsilon = affine_epsilon) const;
+ bool is_equal(const trans_perspective& m,
+ double epsilon = affine_epsilon) const;
+
+ // Determine the major affine parameters. Use with caution
+ // considering possible degenerate cases.
+ double scale() const;
+ double rotation() const;
+ void translation(double* dx, double* dy) const;
+ void scaling(double* x, double* y) const;
+ void scaling_abs(double* x, double* y) const;
- //--------------------------------------------------------------------
- // Check if the equations were solved successfully
- bool is_valid() const { return m_valid; }
- //--------------------------------------------------------------------
- // Transform a point (x, y)
- void transform(double* x, double* y) const
- {
- double tx = *x;
- double ty = *y;
- double d = 1.0 / (m_mtx[6][0] * tx + m_mtx[7][0] * ty + 1.0);
- *x = (m_mtx[0][0] + m_mtx[1][0] * tx + m_mtx[2][0] * ty) * d;
- *y = (m_mtx[3][0] + m_mtx[4][0] * tx + m_mtx[5][0] * ty) * d;
- }
//--------------------------------------------------------------------
class iterator_x
@@ -153,17 +240,16 @@ namespace agg
double y;
iterator_x() {}
- iterator_x(double tx, double ty, double step, const double m[8][1]) :
- den(m[6][0] * tx + m[7][0] * ty + 1.0),
- den_step(m[6][0] * step),
- nom_x(m[0][0] + m[1][0] * tx + m[2][0] * ty),
- nom_x_step(m[1][0] * step),
- nom_y(m[3][0] + m[4][0] * tx + m[5][0] * ty),
- nom_y_step(m[4][0] * step),
+ iterator_x(double px, double py, double step, const trans_perspective& m) :
+ den(px * m.w0 + py * m.w1 + m.w2),
+ den_step(m.w0 * step),
+ nom_x(px * m.sx + py * m.shx + m.tx),
+ nom_x_step(step * m.sx),
+ nom_y(px * m.shy + py * m.sy + m.ty),
+ nom_y_step(step * m.shy),
x(nom_x / den),
y(nom_y / den)
- {
- }
+ {}
void operator ++ ()
{
@@ -179,14 +265,467 @@ namespace agg
//--------------------------------------------------------------------
iterator_x begin(double x, double y, double step) const
{
- return iterator_x(x, y, step, m_mtx);
+ return iterator_x(x, y, step, *this);
}
-
- private:
- double m_mtx[8][1];
- bool m_valid;
};
+
+
+
+
+
+
+
+
+
+
+
+
+
+ //------------------------------------------------------------------------
+ inline bool trans_perspective::square_to_quad(const double* q)
+ {
+ double dx = q[0] - q[2] + q[4] - q[6];
+ double dy = q[1] - q[3] + q[5] - q[7];
+ if(dx == 0.0 && dy == 0.0)
+ {
+ // Affine case (parallelogram)
+ //---------------
+ sx = q[2] - q[0];
+ shy = q[3] - q[1];
+ w0 = 0.0;
+ shx = q[4] - q[2];
+ sy = q[5] - q[3];
+ w1 = 0.0;
+ tx = q[0];
+ ty = q[1];
+ w2 = 1.0;
+ }
+ else
+ {
+ double dx1 = q[2] - q[4];
+ double dy1 = q[3] - q[5];
+ double dx2 = q[6] - q[4];
+ double dy2 = q[7] - q[5];
+ double den = dx1 * dy2 - dx2 * dy1;
+ if(den == 0.0)
+ {
+ // Singular case
+ //---------------
+ sx = shy = w0 = shx = sy = w1 = tx = ty = w2 = 0.0;
+ return false;
+ }
+ // General case
+ //---------------
+ double u = (dx * dy2 - dy * dx2) / den;
+ double v = (dy * dx1 - dx * dy1) / den;
+ sx = q[2] - q[0] + u * q[2];
+ shy = q[3] - q[1] + u * q[3];
+ w0 = u;
+ shx = q[6] - q[0] + v * q[6];
+ sy = q[7] - q[1] + v * q[7];
+ w1 = v;
+ tx = q[0];
+ ty = q[1];
+ w2 = 1.0;
+ }
+ return true;
+ }
+
+ //------------------------------------------------------------------------
+ inline bool trans_perspective::invert()
+ {
+ double d0 = sy * w2 - w1 * ty;
+ double d1 = w0 * ty - shy * w2;
+ double d2 = shy * w1 - w0 * sy;
+ double d = sx * d0 + shx * d1 + tx * d2;
+ if(d == 0.0)
+ {
+ sx = shy = w0 = shx = sy = w1 = tx = ty = w2 = 0.0;
+ return false;
+ }
+ d = 1.0 / d;
+ trans_perspective a = *this;
+ sx = d * d0;
+ shy = d * d1;
+ w0 = d * d2;
+ shx = d * (a.w1 *a.tx - a.shx*a.w2);
+ sy = d * (a.sx *a.w2 - a.w0 *a.tx);
+ w1 = d * (a.w0 *a.shx - a.sx *a.w1);
+ tx = d * (a.shx*a.ty - a.sy *a.tx);
+ ty = d * (a.shy*a.tx - a.sx *a.ty);
+ w2 = d * (a.sx *a.sy - a.shy*a.shx);
+ return true;
+ }
+
+ //------------------------------------------------------------------------
+ inline bool trans_perspective::quad_to_square(const double* q)
+ {
+ if(!square_to_quad(q)) return false;
+ invert();
+ return true;
+ }
+
+ //------------------------------------------------------------------------
+ inline bool trans_perspective::quad_to_quad(const double* qs,
+ const double* qd)
+ {
+ trans_perspective p;
+ if(! quad_to_square(qs)) return false;
+ if(!p.square_to_quad(qd)) return false;
+ multiply(p);
+ return true;
+ }
+
+ //------------------------------------------------------------------------
+ inline bool trans_perspective::rect_to_quad(double x1, double y1,
+ double x2, double y2,
+ const double* q)
+ {
+ double r[8];
+ r[0] = r[6] = x1;
+ r[2] = r[4] = x2;
+ r[1] = r[3] = y1;
+ r[5] = r[7] = y2;
+ return quad_to_quad(r, q);
+ }
+
+ //------------------------------------------------------------------------
+ inline bool trans_perspective::quad_to_rect(const double* q,
+ double x1, double y1,
+ double x2, double y2)
+ {
+ double r[8];
+ r[0] = r[6] = x1;
+ r[2] = r[4] = x2;
+ r[1] = r[3] = y1;
+ r[5] = r[7] = y2;
+ return quad_to_quad(q, r);
+ }
+
+ //------------------------------------------------------------------------
+ inline trans_perspective::trans_perspective(double x1, double y1,
+ double x2, double y2,
+ const double* quad)
+ {
+ rect_to_quad(x1, y1, x2, y2, quad);
+ }
+
+ //------------------------------------------------------------------------
+ inline trans_perspective::trans_perspective(const double* quad,
+ double x1, double y1,
+ double x2, double y2)
+ {
+ quad_to_rect(quad, x1, y1, x2, y2);
+ }
+
+ //------------------------------------------------------------------------
+ inline trans_perspective::trans_perspective(const double* src,
+ const double* dst)
+ {
+ quad_to_quad(src, dst);
+ }
+
+ //------------------------------------------------------------------------
+ inline const trans_perspective& trans_perspective::reset()
+ {
+ sx = 1; shy = 0; w0 = 0;
+ shx = 0; sy = 1; w1 = 0;
+ tx = 0; ty = 0; w2 = 1;
+ return *this;
+ }
+
+ //------------------------------------------------------------------------
+ inline const trans_perspective&
+ trans_perspective::multiply(const trans_perspective& a)
+ {
+ trans_perspective b = *this;
+ sx = a.sx *b.sx + a.shx*b.shy + a.tx*b.w0;
+ shx = a.sx *b.shx + a.shx*b.sy + a.tx*b.w1;
+ tx = a.sx *b.tx + a.shx*b.ty + a.tx*b.w2;
+ shy = a.shy*b.sx + a.sy *b.shy + a.ty*b.w0;
+ sy = a.shy*b.shx + a.sy *b.sy + a.ty*b.w1;
+ ty = a.shy*b.tx + a.sy *b.ty + a.ty*b.w2;
+ w0 = a.w0 *b.sx + a.w1 *b.shy + a.w2*b.w0;
+ w1 = a.w0 *b.shx + a.w1 *b.sy + a.w2*b.w1;
+ w2 = a.w0 *b.tx + a.w1 *b.ty + a.w2*b.w2;
+ return *this;
+ }
+
+ //------------------------------------------------------------------------
+ inline const trans_perspective&
+ trans_perspective::multiply(const trans_affine& a)
+ {
+ trans_perspective b = *this;
+ sx = a.sx *b.sx + a.shx*b.shy + a.tx*b.w0;
+ shx = a.sx *b.shx + a.shx*b.sy + a.tx*b.w1;
+ tx = a.sx *b.tx + a.shx*b.ty + a.tx*b.w2;
+ shy = a.shy*b.sx + a.sy *b.shy + a.ty*b.w0;
+ sy = a.shy*b.shx + a.sy *b.sy + a.ty*b.w1;
+ ty = a.shy*b.tx + a.sy *b.ty + a.ty*b.w2;
+ return *this;
+ }
+
+ //------------------------------------------------------------------------
+ inline const trans_perspective&
+ trans_perspective::premultiply(const trans_perspective& b)
+ {
+ trans_perspective a = *this;
+ sx = a.sx *b.sx + a.shx*b.shy + a.tx*b.w0;
+ shx = a.sx *b.shx + a.shx*b.sy + a.tx*b.w1;
+ tx = a.sx *b.tx + a.shx*b.ty + a.tx*b.w2;
+ shy = a.shy*b.sx + a.sy *b.shy + a.ty*b.w0;
+ sy = a.shy*b.shx + a.sy *b.sy + a.ty*b.w1;
+ ty = a.shy*b.tx + a.sy *b.ty + a.ty*b.w2;
+ w0 = a.w0 *b.sx + a.w1 *b.shy + a.w2*b.w0;
+ w1 = a.w0 *b.shx + a.w1 *b.sy + a.w2*b.w1;
+ w2 = a.w0 *b.tx + a.w1 *b.ty + a.w2*b.w2;
+ return *this;
+ }
+
+ //------------------------------------------------------------------------
+ inline const trans_perspective&
+ trans_perspective::premultiply(const trans_affine& b)
+ {
+ trans_perspective a = *this;
+ sx = a.sx *b.sx + a.shx*b.shy;
+ shx = a.sx *b.shx + a.shx*b.sy;
+ tx = a.sx *b.tx + a.shx*b.ty + a.tx;
+ shy = a.shy*b.sx + a.sy *b.shy;
+ sy = a.shy*b.shx + a.sy *b.sy;
+ ty = a.shy*b.tx + a.sy *b.ty + a.ty;
+ w0 = a.w0 *b.sx + a.w1 *b.shy;
+ w1 = a.w0 *b.shx + a.w1 *b.sy;
+ w2 = a.w0 *b.tx + a.w1 *b.ty + a.w2;
+ return *this;
+ }
+
+ //------------------------------------------------------------------------
+ const trans_perspective&
+ trans_perspective::multiply_inv(const trans_perspective& m)
+ {
+ trans_perspective t = m;
+ t.invert();
+ return multiply(t);
+ }
+
+ //------------------------------------------------------------------------
+ const trans_perspective&
+ trans_perspective::multiply_inv(const trans_affine& m)
+ {
+ trans_affine t = m;
+ t.invert();
+ return multiply(t);
+ }
+
+ //------------------------------------------------------------------------
+ const trans_perspective&
+ trans_perspective::premultiply_inv(const trans_perspective& m)
+ {
+ trans_perspective t = m;
+ t.invert();
+ return *this = t.multiply(*this);
+ }
+
+ //------------------------------------------------------------------------
+ const trans_perspective&
+ trans_perspective::premultiply_inv(const trans_affine& m)
+ {
+ trans_perspective t(m);
+ t.invert();
+ return *this = t.multiply(*this);
+ }
+
+ //------------------------------------------------------------------------
+ inline const trans_perspective&
+ trans_perspective::translate(double x, double y)
+ {
+ tx += x;
+ ty += y;
+ return *this;
+ }
+
+ //------------------------------------------------------------------------
+ inline const trans_perspective& trans_perspective::rotate(double a)
+ {
+ multiply(trans_affine_rotation(a));
+ return *this;
+ }
+
+ //------------------------------------------------------------------------
+ inline const trans_perspective& trans_perspective::scale(double s)
+ {
+ multiply(trans_affine_scaling(s));
+ return *this;
+ }
+
+ //------------------------------------------------------------------------
+ inline const trans_perspective& trans_perspective::scale(double x, double y)
+ {
+ multiply(trans_affine_scaling(x, y));
+ return *this;
+ }
+
+ //------------------------------------------------------------------------
+ inline void trans_perspective::transform(double* px, double* py) const
+ {
+ double x = *px;
+ double y = *py;
+ double m = 1.0 / (x*w0 + y*w1 + w2);
+ *px = m * (x*sx + y*shx + tx);
+ *py = m * (x*shy + y*sy + ty);
+ }
+
+ //------------------------------------------------------------------------
+ inline void trans_perspective::transform_affine(double* x, double* y) const
+ {
+ double tmp = *x;
+ *x = tmp * sx + *y * shx + tx;
+ *y = tmp * shy + *y * sy + ty;
+ }
+
+ //------------------------------------------------------------------------
+ inline void trans_perspective::transform_2x2(double* x, double* y) const
+ {
+ double tmp = *x;
+ *x = tmp * sx + *y * shx;
+ *y = tmp * shy + *y * sy;
+ }
+
+ //------------------------------------------------------------------------
+ inline void trans_perspective::inverse_transform(double* x, double* y) const
+ {
+ trans_perspective t(*this);
+ if(t.invert()) t.transform(x, y);
+ }
+
+ //------------------------------------------------------------------------
+ inline void trans_perspective::store_to(double* m) const
+ {
+ *m++ = sx; *m++ = shy; *m++ = w0;
+ *m++ = shx; *m++ = sy; *m++ = w1;
+ *m++ = tx; *m++ = ty; *m++ = w2;
+ }
+
+ //------------------------------------------------------------------------
+ inline const trans_perspective& trans_perspective::load_from(const double* m)
+ {
+ sx = *m++; shy = *m++; w0 = *m++;
+ shx = *m++; sy = *m++; w1 = *m++;
+ tx = *m++; ty = *m++; w2 = *m++;
+ return *this;
+ }
+
+ //------------------------------------------------------------------------
+ inline const trans_perspective&
+ trans_perspective::from_affine(const trans_affine& a)
+ {
+ sx = a.sx; shy = a.shy; w0 = 0;
+ shx = a.shx; sy = a.sy; w1 = 0;
+ tx = a.tx; ty = a.ty; w2 = 1;
+ return *this;
+ }
+
+ //------------------------------------------------------------------------
+ inline double trans_perspective::determinant() const
+ {
+ return sx * (sy * w2 - ty * w1) +
+ shx * (ty * w0 - shy * w2) +
+ tx * (shy * w1 - sy * w0);
+ }
+
+ //------------------------------------------------------------------------
+ inline double trans_perspective::determinant_reciprocal() const
+ {
+ return 1.0 / determinant();
+ }
+
+ //------------------------------------------------------------------------
+ inline bool trans_perspective::is_valid(double epsilon) const
+ {
+ return fabs(sx) > epsilon && fabs(sy) > epsilon && fabs(w2) > epsilon;
+ }
+
+ //------------------------------------------------------------------------
+ inline bool trans_perspective::is_identity(double epsilon) const
+ {
+ return is_equal_eps(sx, 1.0, epsilon) &&
+ is_equal_eps(shy, 0.0, epsilon) &&
+ is_equal_eps(w0, 0.0, epsilon) &&
+ is_equal_eps(shx, 0.0, epsilon) &&
+ is_equal_eps(sy, 1.0, epsilon) &&
+ is_equal_eps(w1, 0.0, epsilon) &&
+ is_equal_eps(tx, 0.0, epsilon) &&
+ is_equal_eps(ty, 0.0, epsilon) &&
+ is_equal_eps(w2, 1.0, epsilon);
+ }
+
+ //------------------------------------------------------------------------
+ inline bool trans_perspective::is_equal(const trans_perspective& m,
+ double epsilon) const
+ {
+ return is_equal_eps(sx, m.sx, epsilon) &&
+ is_equal_eps(shy, m.shy, epsilon) &&
+ is_equal_eps(w0, m.w0, epsilon) &&
+ is_equal_eps(shx, m.shx, epsilon) &&
+ is_equal_eps(sy, m.sy, epsilon) &&
+ is_equal_eps(w1, m.w1, epsilon) &&
+ is_equal_eps(tx, m.tx, epsilon) &&
+ is_equal_eps(ty, m.ty, epsilon) &&
+ is_equal_eps(w2, m.w2, epsilon);
+ }
+
+ //------------------------------------------------------------------------
+ inline double trans_perspective::scale() const
+ {
+ double x = 0.707106781 * sx + 0.707106781 * shx;
+ double y = 0.707106781 * shy + 0.707106781 * sy;
+ return sqrt(x*x + y*y);
+ }
+
+ //------------------------------------------------------------------------
+ inline double trans_perspective::rotation() const
+ {
+ double x1 = 0.0;
+ double y1 = 0.0;
+ double x2 = 1.0;
+ double y2 = 0.0;
+ transform(&x1, &y1);
+ transform(&x2, &y2);
+ return atan2(y2-y1, x2-x1);
+ }
+
+ //------------------------------------------------------------------------
+ void trans_perspective::translation(double* dx, double* dy) const
+ {
+ *dx = tx;
+ *dy = ty;
+ }
+
+ //------------------------------------------------------------------------
+ void trans_perspective::scaling(double* x, double* y) const
+ {
+ double x1 = 0.0;
+ double y1 = 0.0;
+ double x2 = 1.0;
+ double y2 = 1.0;
+ trans_perspective t(*this);
+ t *= trans_affine_rotation(-rotation());
+ t.transform(&x1, &y1);
+ t.transform(&x2, &y2);
+ *x = x2 - x1;
+ *y = y2 - y1;
+ }
+
+ //------------------------------------------------------------------------
+ void trans_perspective::scaling_abs(double* x, double* y) const
+ {
+ *x = sqrt(sx * sx + shx * shx);
+ *y = sqrt(shy * shy + sy * sy);
+ }
+
+
}
#endif
+
diff --git a/agg/inc/agg_trans_single_path.h b/agg/inc/agg_trans_single_path.h
index 68369626c396..43bcf836f2da 100755
--- a/agg/inc/agg_trans_single_path.h
+++ b/agg/inc/agg_trans_single_path.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
diff --git a/agg/inc/agg_trans_viewport.h b/agg/inc/agg_trans_viewport.h
index b77a7204feb9..9915df61a432 100755
--- a/agg/inc/agg_trans_viewport.h
+++ b/agg/inc/agg_trans_viewport.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -22,7 +22,7 @@
#define AGG_TRANS_VIEWPORT_INCLUDED
#include <string.h>
-#include "agg_basics.h"
+#include "agg_trans_affine.h"
namespace agg
@@ -51,6 +51,7 @@ namespace agg
m_device_x2(1.0),
m_device_y2(1.0),
m_aspect(aspect_ratio_stretch),
+ m_is_valid(true),
m_align_x(0.5),
m_align_y(0.5),
m_wx1(0.0),
@@ -123,6 +124,7 @@ namespace agg
}
//-------------------------------------------------------------------
+ bool is_valid() const { return m_is_valid; }
double align_x() const { return m_align_x; }
double align_y() const { return m_align_y; }
aspect_ratio_e aspect_ratio() const { return m_aspect; }
@@ -135,6 +137,13 @@ namespace agg
}
//-------------------------------------------------------------------
+ void transform_scale_only(double* x, double* y) const
+ {
+ *x *= m_kx;
+ *y *= m_ky;
+ }
+
+ //-------------------------------------------------------------------
void inverse_transform(double* x, double* y) const
{
*x = (*x - m_dx1) / m_kx + m_wx1;
@@ -142,6 +151,17 @@ namespace agg
}
//-------------------------------------------------------------------
+ void inverse_transform_scale_only(double* x, double* y) const
+ {
+ *x /= m_kx;
+ *y /= m_ky;
+ }
+
+ //-------------------------------------------------------------------
+ double device_dx() const { return m_dx1 - m_wx1 * m_kx; }
+ double device_dy() const { return m_dy1 - m_wy1 * m_ky; }
+
+ //-------------------------------------------------------------------
double scale_x() const
{
return m_kx;
@@ -159,76 +179,35 @@ namespace agg
return (m_kx + m_ky) * 0.5;
}
+ //-------------------------------------------------------------------
+ trans_affine to_affine() const
+ {
+ trans_affine mtx = trans_affine_translation(-m_wx1, -m_wy1);
+ mtx *= trans_affine_scaling(m_kx, m_ky);
+ mtx *= trans_affine_translation(m_dx1, m_dy1);
+ return mtx;
+ }
+
+ //-------------------------------------------------------------------
+ trans_affine to_affine_scale_only() const
+ {
+ return trans_affine_scaling(m_kx, m_ky);
+ }
//-------------------------------------------------------------------
unsigned byte_size() const
{
- return
- sizeof(m_world_x1) +
- sizeof(m_world_y1) +
- sizeof(m_world_x2) +
- sizeof(m_world_y2) +
- sizeof(m_device_x1) +
- sizeof(m_device_y1) +
- sizeof(m_device_x2) +
- sizeof(m_device_y2) +
- sizeof(m_aspect) +
- sizeof(m_align_x) +
- sizeof(m_align_y) +
- sizeof(m_wx1) +
- sizeof(m_wy1) +
- sizeof(m_wx2) +
- sizeof(m_wy2) +
- sizeof(m_dx1) +
- sizeof(m_dy1) +
- sizeof(m_kx) +
- sizeof(m_ky);
+ return sizeof(*this);
}
void serialize(int8u* ptr) const
{
- memcpy(ptr, &m_world_x1, sizeof(m_world_x1)); ptr += sizeof(m_world_x1);
- memcpy(ptr, &m_world_y1, sizeof(m_world_y1)); ptr += sizeof(m_world_y1);
- memcpy(ptr, &m_world_x2, sizeof(m_world_x2)); ptr += sizeof(m_world_x2);
- memcpy(ptr, &m_world_y2, sizeof(m_world_y2)); ptr += sizeof(m_world_y2);
- memcpy(ptr, &m_device_x1, sizeof(m_device_x1)); ptr += sizeof(m_device_x1);
- memcpy(ptr, &m_device_y1, sizeof(m_device_y1)); ptr += sizeof(m_device_y1);
- memcpy(ptr, &m_device_x2, sizeof(m_device_x2)); ptr += sizeof(m_device_x2);
- memcpy(ptr, &m_device_y2, sizeof(m_device_y2)); ptr += sizeof(m_device_y2);
- memcpy(ptr, &m_aspect, sizeof(m_aspect)); ptr += sizeof(m_aspect);
- memcpy(ptr, &m_align_x, sizeof(m_align_x)); ptr += sizeof(m_align_x);
- memcpy(ptr, &m_align_y, sizeof(m_align_y)); ptr += sizeof(m_align_y);
- memcpy(ptr, &m_wx1, sizeof(m_wx1)); ptr += sizeof(m_wx1);
- memcpy(ptr, &m_wy1, sizeof(m_wy1)); ptr += sizeof(m_wy1);
- memcpy(ptr, &m_wx2, sizeof(m_wx2)); ptr += sizeof(m_wx2);
- memcpy(ptr, &m_wy2, sizeof(m_wy2)); ptr += sizeof(m_wy2);
- memcpy(ptr, &m_dx1, sizeof(m_dx1)); ptr += sizeof(m_dx1);
- memcpy(ptr, &m_dy1, sizeof(m_dy1)); ptr += sizeof(m_dy1);
- memcpy(ptr, &m_kx, sizeof(m_kx)); ptr += sizeof(m_kx);
- memcpy(ptr, &m_ky, sizeof(m_ky)); ptr += sizeof(m_ky);
+ memcpy(ptr, this, sizeof(*this));
}
void deserialize(const int8u* ptr)
{
- memcpy(&m_world_x1, ptr, sizeof(m_world_x1)); ptr += sizeof(m_world_x1);
- memcpy(&m_world_y1, ptr, sizeof(m_world_y1)); ptr += sizeof(m_world_y1);
- memcpy(&m_world_x2, ptr, sizeof(m_world_x2)); ptr += sizeof(m_world_x2);
- memcpy(&m_world_y2, ptr, sizeof(m_world_y2)); ptr += sizeof(m_world_y2);
- memcpy(&m_device_x1, ptr, sizeof(m_device_x1)); ptr += sizeof(m_device_x1);
- memcpy(&m_device_y1, ptr, sizeof(m_device_y1)); ptr += sizeof(m_device_y1);
- memcpy(&m_device_x2, ptr, sizeof(m_device_x2)); ptr += sizeof(m_device_x2);
- memcpy(&m_device_y2, ptr, sizeof(m_device_y2)); ptr += sizeof(m_device_y2);
- memcpy(&m_aspect, ptr, sizeof(m_aspect)); ptr += sizeof(m_aspect);
- memcpy(&m_align_x, ptr, sizeof(m_align_x)); ptr += sizeof(m_align_x);
- memcpy(&m_align_y, ptr, sizeof(m_align_y)); ptr += sizeof(m_align_y);
- memcpy(&m_wx1, ptr, sizeof(m_wx1)); ptr += sizeof(m_wx1);
- memcpy(&m_wy1, ptr, sizeof(m_wy1)); ptr += sizeof(m_wy1);
- memcpy(&m_wx2, ptr, sizeof(m_wx2)); ptr += sizeof(m_wx2);
- memcpy(&m_wy2, ptr, sizeof(m_wy2)); ptr += sizeof(m_wy2);
- memcpy(&m_dx1, ptr, sizeof(m_dx1)); ptr += sizeof(m_dx1);
- memcpy(&m_dy1, ptr, sizeof(m_dy1)); ptr += sizeof(m_dy1);
- memcpy(&m_kx, ptr, sizeof(m_kx)); ptr += sizeof(m_kx);
- memcpy(&m_ky, ptr, sizeof(m_ky)); ptr += sizeof(m_ky);
+ memcpy(this, ptr, sizeof(*this));
}
private:
@@ -243,6 +222,7 @@ namespace agg
double m_device_x2;
double m_device_y2;
aspect_ratio_e m_aspect;
+ bool m_is_valid;
double m_align_x;
double m_align_y;
double m_wx1;
@@ -260,6 +240,24 @@ namespace agg
//-----------------------------------------------------------------------
inline void trans_viewport::update()
{
+ const double epsilon = 1e-30;
+ if(fabs(m_world_x1 - m_world_x2) < epsilon ||
+ fabs(m_world_y1 - m_world_y2) < epsilon ||
+ fabs(m_device_x1 - m_device_x2) < epsilon ||
+ fabs(m_device_y1 - m_device_y2) < epsilon)
+ {
+ m_wx1 = m_world_x1;
+ m_wy1 = m_world_y1;
+ m_wx2 = m_world_x1 + 1.0;
+ m_wy2 = m_world_y2 + 1.0;
+ m_dx1 = m_device_x1;
+ m_dy1 = m_device_y1;
+ m_kx = 1.0;
+ m_ky = 1.0;
+ m_is_valid = false;
+ return;
+ }
+
double world_x1 = m_world_x1;
double world_y1 = m_world_y1;
double world_x2 = m_world_x2;
@@ -295,6 +293,7 @@ namespace agg
m_dy1 = device_y1;
m_kx = (device_x2 - device_x1) / (world_x2 - world_x1);
m_ky = (device_y2 - device_y1) / (world_y2 - world_y1);
+ m_is_valid = true;
}
diff --git a/agg/inc/agg_trans_warp_magnifier.h b/agg/inc/agg_trans_warp_magnifier.h
index d71f567af2ca..9b36c94892f1 100755
--- a/agg/inc/agg_trans_warp_magnifier.h
+++ b/agg/inc/agg_trans_warp_magnifier.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -33,6 +33,11 @@ namespace agg
void magnification(double m) { m_magn = m; }
void radius(double r) { m_radius = r; }
+ double xc() const { return m_xc; }
+ double yc() const { return m_yc; }
+ double magnification() const { return m_magn; }
+ double radius() const { return m_radius; }
+
void transform(double* x, double* y) const;
void inverse_transform(double* x, double* y) const;
diff --git a/agg/inc/agg_vcgen_bspline.h b/agg/inc/agg_vcgen_bspline.h
index 7490a50a6764..277dea436000 100755
--- a/agg/inc/agg_vcgen_bspline.h
+++ b/agg/inc/agg_vcgen_bspline.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -37,7 +37,7 @@ namespace agg
};
public:
- typedef pod_deque<point_type, 6> vertex_storage;
+ typedef pod_bvector<point_d, 6> vertex_storage;
vcgen_bspline();
@@ -49,7 +49,7 @@ namespace agg
void add_vertex(double x, double y, unsigned cmd);
// Vertex Source Interface
- void rewind(unsigned id);
+ void rewind(unsigned path_id);
unsigned vertex(double* x, double* y);
private:
diff --git a/agg/inc/agg_vcgen_contour.h b/agg/inc/agg_vcgen_contour.h
index 1c5428206640..bdf15b1a9a26 100755
--- a/agg/inc/agg_vcgen_contour.h
+++ b/agg/inc/agg_vcgen_contour.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -17,7 +17,6 @@
#define AGG_VCGEN_CONTOUR_INCLUDED
#include "agg_math_stroke.h"
-#include "agg_vertex_iterator.h"
namespace agg
{
@@ -40,55 +39,54 @@ namespace agg
public:
typedef vertex_sequence<vertex_dist, 6> vertex_storage;
- typedef pod_deque<point_type, 6> coord_storage;
+ typedef pod_bvector<point_d, 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; }
+ void line_cap(line_cap_e lc) { m_stroker.line_cap(lc); }
+ void line_join(line_join_e lj) { m_stroker.line_join(lj); }
+ void inner_join(inner_join_e ij) { m_stroker.inner_join(ij); }
+
+ line_cap_e line_cap() const { return m_stroker.line_cap(); }
+ line_join_e line_join() const { return m_stroker.line_join(); }
+ inner_join_e inner_join() const { return m_stroker.inner_join(); }
+
+ void width(double w) { m_stroker.width(m_width = w); }
+ void miter_limit(double ml) { m_stroker.miter_limit(ml); }
+ void miter_limit_theta(double t) { m_stroker.miter_limit_theta(t); }
+ void inner_miter_limit(double ml) { m_stroker.inner_miter_limit(ml); }
+ void approximation_scale(double as) { m_stroker.approximation_scale(as); }
- 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; }
+ double width() const { return m_width; }
+ double miter_limit() const { return m_stroker.miter_limit(); }
+ double inner_miter_limit() const { return m_stroker.inner_miter_limit(); }
+ double approximation_scale() const { return m_stroker.approximation_scale(); }
+
+ void auto_detect_orientation(bool v) { m_auto_detect = v; }
+ bool auto_detect_orientation() const { return m_auto_detect; }
// Generator interface
void remove_all();
void add_vertex(double x, double y, unsigned cmd);
// Vertex Source Interface
- void rewind(unsigned id);
+ void rewind(unsigned path_id);
unsigned vertex(double* x, double* y);
private:
vcgen_contour(const vcgen_contour&);
const vcgen_contour& operator = (const vcgen_contour&);
- 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;
+ math_stroke<coord_storage> m_stroker;
+ double m_width;
+ vertex_storage m_src_vertices;
+ coord_storage m_out_vertices;
+ status_e m_status;
+ unsigned m_src_vertex;
+ unsigned m_out_vertex;
+ unsigned m_closed;
+ unsigned m_orientation;
+ bool m_auto_detect;
};
}
diff --git a/agg/inc/agg_vcgen_dash.h b/agg/inc/agg_vcgen_dash.h
index cc4c86dea833..25d23d3ff26e 100755
--- a/agg/inc/agg_vcgen_dash.h
+++ b/agg/inc/agg_vcgen_dash.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -21,7 +21,6 @@
#include "agg_basics.h"
#include "agg_vertex_sequence.h"
-#include "agg_vertex_iterator.h"
namespace agg
{
@@ -32,7 +31,7 @@ namespace agg
//
class vcgen_dash
{
- enum
+ enum max_dashes_e
{
max_dashes = 32
};
@@ -62,14 +61,9 @@ namespace agg
void add_vertex(double x, double y, unsigned cmd);
// Vertex Source Interface
- void rewind(unsigned id);
+ void rewind(unsigned path_id);
unsigned vertex(double* x, double* y);
- typedef vcgen_dash source_type;
- typedef vertex_iterator<source_type> iterator;
- iterator begin(unsigned id) { return iterator(*this, id); }
- iterator end() { return iterator(path_cmd_stop); }
-
private:
vcgen_dash(const vcgen_dash&);
const vcgen_dash& operator = (const vcgen_dash&);
diff --git a/agg/inc/agg_vcgen_markers_term.h b/agg/inc/agg_vcgen_markers_term.h
index 6f213811c290..b069f1d54154 100755
--- a/agg/inc/agg_vcgen_markers_term.h
+++ b/agg/inc/agg_vcgen_markers_term.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -18,7 +18,6 @@
#include "agg_basics.h"
#include "agg_vertex_sequence.h"
-#include "agg_vertex_iterator.h"
namespace agg
{
@@ -39,14 +38,9 @@ namespace agg
void add_vertex(double x, double y, unsigned cmd);
// Vertex Source Interface
- void rewind(unsigned id);
+ void rewind(unsigned path_id);
unsigned vertex(double* x, double* y);
- typedef vcgen_markers_term source_type;
- typedef vertex_iterator<source_type> iterator;
- iterator begin(unsigned id) { return iterator(*this, id); }
- iterator end() { return iterator(path_cmd_stop); }
-
private:
vcgen_markers_term(const vcgen_markers_term&);
const vcgen_markers_term& operator = (const vcgen_markers_term&);
@@ -59,7 +53,7 @@ namespace agg
coord_type(double x_, double y_) : x(x_), y(y_) {}
};
- typedef pod_deque<coord_type, 6> coord_storage;
+ typedef pod_bvector<coord_type, 6> coord_storage;
coord_storage m_markers;
unsigned m_curr_id;
diff --git a/agg/inc/agg_vcgen_smooth_poly1.h b/agg/inc/agg_vcgen_smooth_poly1.h
index 61ca14898328..2c0619e62d76 100755
--- a/agg/inc/agg_vcgen_smooth_poly1.h
+++ b/agg/inc/agg_vcgen_smooth_poly1.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -57,7 +57,7 @@ namespace agg
void add_vertex(double x, double y, unsigned cmd);
// Vertex Source Interface
- void rewind(unsigned id);
+ void rewind(unsigned path_id);
unsigned vertex(double* x, double* y);
private:
diff --git a/agg/inc/agg_vcgen_stroke.h b/agg/inc/agg_vcgen_stroke.h
index a73509acf3d9..b65eddd5c2b7 100755
--- a/agg/inc/agg_vcgen_stroke.h
+++ b/agg/inc/agg_vcgen_stroke.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -17,7 +17,6 @@
#define AGG_VCGEN_STROKE_INCLUDED
#include "agg_math_stroke.h"
-#include "agg_vertex_iterator.h"
namespace agg
@@ -48,28 +47,28 @@ namespace agg
public:
typedef vertex_sequence<vertex_dist, 6> vertex_storage;
- typedef pod_deque<point_type, 6> coord_storage;
+ typedef pod_bvector<point_d, 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; }
+ void line_cap(line_cap_e lc) { m_stroker.line_cap(lc); }
+ void line_join(line_join_e lj) { m_stroker.line_join(lj); }
+ void inner_join(inner_join_e ij) { m_stroker.inner_join(ij); }
- 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; }
+ line_cap_e line_cap() const { return m_stroker.line_cap(); }
+ line_join_e line_join() const { return m_stroker.line_join(); }
+ inner_join_e inner_join() const { return m_stroker.inner_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; }
+ void width(double w) { m_stroker.width(w); }
+ void miter_limit(double ml) { m_stroker.miter_limit(ml); }
+ void miter_limit_theta(double t) { m_stroker.miter_limit_theta(t); }
+ void inner_miter_limit(double ml) { m_stroker.inner_miter_limit(ml); }
+ void approximation_scale(double as) { m_stroker.approximation_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; }
+ double width() const { return m_stroker.width(); }
+ double miter_limit() const { return m_stroker.miter_limit(); }
+ double inner_miter_limit() const { return m_stroker.inner_miter_limit(); }
+ double approximation_scale() const { return m_stroker.approximation_scale(); }
void shorten(double s) { m_shorten = s; }
double shorten() const { return m_shorten; }
@@ -79,33 +78,22 @@ namespace agg
void add_vertex(double x, double y, unsigned cmd);
// Vertex Source Interface
- void rewind(unsigned id);
+ void rewind(unsigned path_id);
unsigned vertex(double* x, double* y);
- typedef vcgen_stroke source_type;
- typedef vertex_iterator<source_type> iterator;
- iterator begin(unsigned id) { return iterator(*this, id); }
- iterator end() { return iterator(path_cmd_stop); }
-
private:
vcgen_stroke(const vcgen_stroke&);
const vcgen_stroke& operator = (const vcgen_stroke&);
- 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;
- unsigned m_src_vertex;
- unsigned m_out_vertex;
+ math_stroke<coord_storage> m_stroker;
+ vertex_storage m_src_vertices;
+ coord_storage m_out_vertices;
+ double m_shorten;
+ unsigned m_closed;
+ status_e m_status;
+ status_e m_prev_status;
+ unsigned m_src_vertex;
+ unsigned m_out_vertex;
};
diff --git a/agg/inc/agg_vcgen_vertex_sequence.h b/agg/inc/agg_vcgen_vertex_sequence.h
index 7c4e9e4253e5..b9cb0b5e45df 100755
--- a/agg/inc/agg_vcgen_vertex_sequence.h
+++ b/agg/inc/agg_vcgen_vertex_sequence.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -43,7 +43,7 @@ namespace agg
void add_vertex(double x, double y, unsigned cmd);
// Vertex Source Interface
- void rewind(unsigned id);
+ void rewind(unsigned path_id);
unsigned vertex(double* x, double* y);
void shorten(double s) { m_shorten = s; }
diff --git a/agg/inc/agg_vertex_sequence.h b/agg/inc/agg_vertex_sequence.h
index 357a3df15fa4..5a14da20c32f 100755
--- a/agg/inc/agg_vertex_sequence.h
+++ b/agg/inc/agg_vertex_sequence.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -27,10 +27,10 @@ namespace agg
{
//----------------------------------------------------------vertex_sequence
- // Modified agg::pod_deque. The data is interpreted as a sequence of vertices.
- // It means that the type T must expose:
+ // Modified agg::pod_bvector. The data is interpreted as a sequence
+ // of vertices. It means that the type T must expose:
//
- // bool operator() (const T& val)
+ // bool T::operator() (const T& val)
//
// that is called every time new vertex is being added. The main purpose
// of this operator is the possibility to calculate some values during
@@ -64,10 +64,10 @@ namespace agg
// necessary.
//------------------------------------------------------------------------
template<class T, unsigned S=6>
- class vertex_sequence : public pod_deque<T, S>
+ class vertex_sequence : public pod_bvector<T, S>
{
public:
- typedef pod_deque<T, S> base_type;
+ typedef pod_bvector<T, S> base_type;
void add(const T& val);
void modify_last(const T& val);
@@ -124,10 +124,6 @@ namespace agg
}
-
- // Coinciding points maximal distance (Epsilon)
- const double vertex_dist_epsilon = 1e-14;
-
//-------------------------------------------------------------vertex_dist
// Vertex (x, y) with the distance to the next one. The last vertex has
// distance between the last and the first points if the polygon is closed
diff --git a/agg/inc/agg_vpgen_clip_polygon.h b/agg/inc/agg_vpgen_clip_polygon.h
index d5da460843e6..1b5780e4e443 100755
--- a/agg/inc/agg_vpgen_clip_polygon.h
+++ b/agg/inc/agg_vpgen_clip_polygon.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -39,12 +39,12 @@ namespace agg
{
}
- void clip_box(double _x1, double _y1, double _x2, double _y2)
+ 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.x1 = x1;
+ m_clip_box.y1 = y1;
+ m_clip_box.x2 = x2;
+ m_clip_box.y2 = y2;
m_clip_box.normalize();
}
diff --git a/agg/inc/agg_vpgen_clip_polyline.h b/agg/inc/agg_vpgen_clip_polyline.h
index f951966a3293..452d3cda4a23 100755
--- a/agg/inc/agg_vpgen_clip_polyline.h
+++ b/agg/inc/agg_vpgen_clip_polyline.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software
@@ -32,25 +32,21 @@ namespace agg
m_clip_box(0, 0, 1, 1),
m_x1(0),
m_y1(0),
- m_f1(0),
- m_x2(0),
- m_y2(0),
- m_f2(0),
m_num_vertices(0),
- m_vertex(0)
+ m_vertex(0),
+ m_move_to(false)
{
}
- void clip_box(double _x1, double _y1, double _x2, double _y2)
+ 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.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; }
@@ -65,54 +61,15 @@ namespace agg
unsigned vertex(double* x, double* y);
private:
- enum clipping_flags_def
- {
- clip_x1 = 1,
- clip_x2 = 2,
- clip_y1 = 4,
- clip_y2 = 8
- };
-
- // Determine the clipping code of the vertex according to the
- // Cyrus-Beck line clipping algorithm
- //--------------------------------------------------------------------
- unsigned clipping_flags_x(double x)
- {
- unsigned f = 0;
- if(x < m_clip_box.x1) f |= clip_x1;
- if(x > m_clip_box.x2) f |= clip_x2;
- return f;
- }
-
- unsigned clipping_flags_y(double y)
- {
- unsigned f = 0;
- if(y < m_clip_box.y1) f |= clip_y1;
- if(y > m_clip_box.y2) f |= clip_y2;
- return f;
- }
-
- unsigned clipping_flags(double x, double y)
- {
- return clipping_flags_x(x) | clipping_flags_y(y);
- }
-
- bool move_point(double& x, double& y, unsigned& flags);
- void clip_line_segment();
-
- private:
rect_d m_clip_box;
double m_x1;
double m_y1;
- unsigned m_f1;
- double m_x2;
- double m_y2;
- unsigned m_f2;
double m_x[2];
double m_y[2];
unsigned m_cmd[2];
unsigned m_num_vertices;
unsigned m_vertex;
+ bool m_move_to;
};
}
diff --git a/agg/inc/agg_vpgen_segmentator.h b/agg/inc/agg_vpgen_segmentator.h
index 1acc3531cc6e..0750c59df508 100755
--- a/agg/inc/agg_vpgen_segmentator.h
+++ b/agg/inc/agg_vpgen_segmentator.h
@@ -1,5 +1,5 @@
//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.3
+// Anti-Grain Geometry - Version 2.4
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
//
// Permission to copy, use, modify, sell and distribute this software