aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python/matplotlib/py3/extern/agg24-svn/include
diff options
context:
space:
mode:
authormaxim-yurchuk <maxim-yurchuk@yandex-team.com>2024-10-09 12:29:46 +0300
committermaxim-yurchuk <maxim-yurchuk@yandex-team.com>2024-10-09 13:14:22 +0300
commit9731d8a4bb7ee2cc8554eaf133bb85498a4c7d80 (patch)
treea8fb3181d5947c0d78cf402aa56e686130179049 /contrib/python/matplotlib/py3/extern/agg24-svn/include
parenta44b779cd359f06c3ebbef4ec98c6b38609d9d85 (diff)
downloadydb-9731d8a4bb7ee2cc8554eaf133bb85498a4c7d80.tar.gz
publishFullContrib: true for ydb
<HIDDEN_URL> commit_hash:c82a80ac4594723cebf2c7387dec9c60217f603e
Diffstat (limited to 'contrib/python/matplotlib/py3/extern/agg24-svn/include')
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_arc.h74
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_arrowhead.h82
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_bitset_iterator.h54
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_blur.h1503
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_bounding_rect.h116
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_bspline.h76
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_bspline.h48
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_clip_polygon.h63
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_clip_polyline.h63
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_close_polygon.h125
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_concat.h73
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_gpc.h432
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_marker.h148
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_marker_adaptor.h51
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_shorten_path.h50
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_smooth_poly1.h80
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_unclose_polygon.h52
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_ellipse.h123
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_ellipse_bresenham.h113
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_embedded_raster_fonts.h59
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_font_cache_manager.h409
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_font_cache_manager2.h311
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_glyph_raster_bin.h155
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_gradient_lut.h244
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_gsv_text.h153
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_line_aa_basics.h189
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_path_length.h65
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_path_storage_integer.h295
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pattern_filters_rgba.h123
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pixfmt_rgb_packed.h1312
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pixfmt_transposer.h157
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rasterizer_compound_aa.h663
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rasterizer_outline.h147
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rasterizer_outline_aa.h599
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_markers.h706
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_mclip.h349
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_outline_aa.h1837
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_outline_image.h1036
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_primitives.h224
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_raster_text.h264
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rendering_buffer_dynarow.h137
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rounded_rect.h72
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_scanline_boolean_algebra.h1567
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_simul_eq.h147
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gouraud_gray.h241
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gradient.h377
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gradient_alpha.h126
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gradient_contour.h362
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gradient_image.h188
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_image_filter_rgb.h861
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_interpolator_persp.h462
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_interpolator_trans.h92
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_pattern_gray.h93
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_pattern_rgb.h96
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_solid.h53
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_subdiv_adaptor.h141
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_bilinear.h166
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_double_path.h131
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_perspective.h731
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_single_path.h97
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_viewport.h303
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_warp_magnifier.h56
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_bspline.h74
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_markers_term.h66
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_smooth_poly1.h87
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_vertex_sequence.h135
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vpgen_clip_polygon.h83
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vpgen_clip_polyline.h78
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_bezier_ctrl.h196
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_cbox_ctrl.h112
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_ctrl.h118
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_gamma_ctrl.h170
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_gamma_spline.h95
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_polygon_ctrl.h166
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_rbox_ctrl.h141
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_scale_ctrl.h146
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_slider_ctrl.h150
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_spline_ctrl.h159
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/platform/agg_platform_support.h686
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/platform/mac/agg_mac_pmap.h87
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/platform/win32/agg_win32_bmp.h117
-rw-r--r--contrib/python/matplotlib/py3/extern/agg24-svn/include/util/agg_color_conv_rgb16.h285
82 files changed, 22273 insertions, 0 deletions
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_arc.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_arc.h
new file mode 100644
index 0000000000..17e1d43473
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_arc.h
@@ -0,0 +1,74 @@
+//----------------------------------------------------------------------------
+// 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
+//----------------------------------------------------------------------------
+//
+// Arc vertex generator
+//
+//----------------------------------------------------------------------------
+
+#ifndef AGG_ARC_INCLUDED
+#define AGG_ARC_INCLUDED
+
+#include <math.h>
+#include "agg_basics.h"
+
+namespace agg
+{
+
+ //=====================================================================arc
+ //
+ // See Implementation agg_arc.cpp
+ //
+ class arc
+ {
+ public:
+ arc() : m_scale(1.0), m_initialized(false) {}
+ arc(double x, double y,
+ double rx, double ry,
+ double a1, double a2,
+ bool ccw=true);
+
+ void init(double x, double y,
+ double rx, double ry,
+ double a1, double a2,
+ bool ccw=true);
+
+ void approximation_scale(double s);
+ double approximation_scale() const { return m_scale; }
+
+ void rewind(unsigned);
+ unsigned vertex(double* x, double* y);
+
+ private:
+ void normalize(double a1, double a2, bool ccw);
+
+ double m_x;
+ double m_y;
+ double m_rx;
+ double m_ry;
+ double m_angle;
+ double m_start;
+ double m_end;
+ double m_scale;
+ double m_da;
+ bool m_ccw;
+ bool m_initialized;
+ unsigned m_path_cmd;
+ };
+
+
+}
+
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_arrowhead.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_arrowhead.h
new file mode 100644
index 0000000000..5e029ddee0
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_arrowhead.h
@@ -0,0 +1,82 @@
+//----------------------------------------------------------------------------
+// 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
+//----------------------------------------------------------------------------
+//
+// Simple arrowhead/arrowtail generator
+//
+//----------------------------------------------------------------------------
+#ifndef AGG_ARROWHEAD_INCLUDED
+#define AGG_ARROWHEAD_INCLUDED
+
+#include "agg_basics.h"
+
+namespace agg
+{
+
+ //===============================================================arrowhead
+ //
+ // See implementation agg_arrowhead.cpp
+ //
+ class arrowhead
+ {
+ public:
+ arrowhead();
+
+ void head(double d1, double d2, double d3, double d4)
+ {
+ m_head_d1 = d1;
+ m_head_d2 = d2;
+ m_head_d3 = d3;
+ m_head_d4 = d4;
+ m_head_flag = true;
+ }
+
+ void head() { m_head_flag = true; }
+ void no_head() { m_head_flag = false; }
+
+ void tail(double d1, double d2, double d3, double d4)
+ {
+ m_tail_d1 = d1;
+ m_tail_d2 = d2;
+ m_tail_d3 = d3;
+ m_tail_d4 = d4;
+ m_tail_flag = true;
+ }
+
+ void tail() { m_tail_flag = true; }
+ void no_tail() { m_tail_flag = false; }
+
+ void rewind(unsigned path_id);
+ unsigned vertex(double* x, double* y);
+
+ private:
+ double m_head_d1;
+ double m_head_d2;
+ double m_head_d3;
+ double m_head_d4;
+ double m_tail_d1;
+ double m_tail_d2;
+ double m_tail_d3;
+ double m_tail_d4;
+ bool m_head_flag;
+ bool m_tail_flag;
+ double m_coord[16];
+ unsigned m_cmd[8];
+ unsigned m_curr_id;
+ unsigned m_curr_coord;
+ };
+
+}
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_bitset_iterator.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_bitset_iterator.h
new file mode 100644
index 0000000000..7382d5c335
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_bitset_iterator.h
@@ -0,0 +1,54 @@
+//----------------------------------------------------------------------------
+// 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_BITSET_ITERATOR_INCLUDED
+#define AGG_BITSET_ITERATOR_INCLUDED
+
+#include "agg_basics.h"
+
+namespace agg
+{
+
+ class bitset_iterator
+ {
+ public:
+ bitset_iterator(const int8u* bits, unsigned offset = 0) :
+ m_bits(bits + (offset >> 3)),
+ m_mask(0x80 >> (offset & 7))
+ {}
+
+ void operator ++ ()
+ {
+ m_mask >>= 1;
+ if(m_mask == 0)
+ {
+ ++m_bits;
+ m_mask = 0x80;
+ }
+ }
+
+ unsigned bit() const
+ {
+ return (*m_bits) & m_mask;
+ }
+
+ private:
+ const int8u* m_bits;
+ int8u m_mask;
+ };
+
+}
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_blur.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_blur.h
new file mode 100644
index 0000000000..cd5713f314
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_blur.h
@@ -0,0 +1,1503 @@
+//----------------------------------------------------------------------------
+// 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
+//----------------------------------------------------------------------------
+//
+// The Stack Blur Algorithm was invented by Mario Klingemann,
+// mario@quasimondo.com and described here:
+// http://incubator.quasimondo.com/processing/fast_blur_deluxe.php
+// (search phrase "Stackblur: Fast But Goodlooking").
+// The major improvement is that there's no more division table
+// that was very expensive to create for large blur radii. Insted,
+// for 8-bit per channel and radius not exceeding 254 the division is
+// replaced by multiplication and shift.
+//
+//----------------------------------------------------------------------------
+
+#ifndef AGG_BLUR_INCLUDED
+#define AGG_BLUR_INCLUDED
+
+#include "agg_array.h"
+#include "agg_pixfmt_base.h"
+#include "agg_pixfmt_transposer.h"
+
+namespace agg
+{
+
+ template<class T> struct stack_blur_tables
+ {
+ static int16u const g_stack_blur8_mul[255];
+ static int8u const g_stack_blur8_shr[255];
+ };
+
+ //------------------------------------------------------------------------
+ template<class T>
+ int16u const stack_blur_tables<T>::g_stack_blur8_mul[255] =
+ {
+ 512,512,456,512,328,456,335,512,405,328,271,456,388,335,292,512,
+ 454,405,364,328,298,271,496,456,420,388,360,335,312,292,273,512,
+ 482,454,428,405,383,364,345,328,312,298,284,271,259,496,475,456,
+ 437,420,404,388,374,360,347,335,323,312,302,292,282,273,265,512,
+ 497,482,468,454,441,428,417,405,394,383,373,364,354,345,337,328,
+ 320,312,305,298,291,284,278,271,265,259,507,496,485,475,465,456,
+ 446,437,428,420,412,404,396,388,381,374,367,360,354,347,341,335,
+ 329,323,318,312,307,302,297,292,287,282,278,273,269,265,261,512,
+ 505,497,489,482,475,468,461,454,447,441,435,428,422,417,411,405,
+ 399,394,389,383,378,373,368,364,359,354,350,345,341,337,332,328,
+ 324,320,316,312,309,305,301,298,294,291,287,284,281,278,274,271,
+ 268,265,262,259,257,507,501,496,491,485,480,475,470,465,460,456,
+ 451,446,442,437,433,428,424,420,416,412,408,404,400,396,392,388,
+ 385,381,377,374,370,367,363,360,357,354,350,347,344,341,338,335,
+ 332,329,326,323,320,318,315,312,310,307,304,302,299,297,294,292,
+ 289,287,285,282,280,278,275,273,271,269,267,265,263,261,259
+ };
+
+ //------------------------------------------------------------------------
+ template<class T>
+ int8u const stack_blur_tables<T>::g_stack_blur8_shr[255] =
+ {
+ 9, 11, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 17,
+ 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20,
+ 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21,
+ 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22,
+ 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23,
+ 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
+ 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24
+ };
+
+
+
+ //==============================================================stack_blur
+ template<class ColorT, class CalculatorT> class stack_blur
+ {
+ public:
+ typedef ColorT color_type;
+ typedef CalculatorT calculator_type;
+
+ //--------------------------------------------------------------------
+ template<class Img> void blur_x(Img& img, unsigned radius)
+ {
+ if(radius < 1) return;
+
+ unsigned x, y, xp, i;
+ unsigned stack_ptr;
+ unsigned stack_start;
+
+ color_type pix;
+ color_type* stack_pix;
+ calculator_type sum;
+ calculator_type sum_in;
+ calculator_type sum_out;
+
+ unsigned w = img.width();
+ unsigned h = img.height();
+ unsigned wm = w - 1;
+ unsigned div = radius * 2 + 1;
+
+ unsigned div_sum = (radius + 1) * (radius + 1);
+ unsigned mul_sum = 0;
+ unsigned shr_sum = 0;
+ unsigned max_val = color_type::base_mask;
+
+ if(max_val <= 255 && radius < 255)
+ {
+ mul_sum = stack_blur_tables<int>::g_stack_blur8_mul[radius];
+ shr_sum = stack_blur_tables<int>::g_stack_blur8_shr[radius];
+ }
+
+ m_buf.allocate(w, 128);
+ m_stack.allocate(div, 32);
+
+ for(y = 0; y < h; y++)
+ {
+ sum.clear();
+ sum_in.clear();
+ sum_out.clear();
+
+ pix = img.pixel(0, y);
+ for(i = 0; i <= radius; i++)
+ {
+ m_stack[i] = pix;
+ sum.add(pix, i + 1);
+ sum_out.add(pix);
+ }
+ for(i = 1; i <= radius; i++)
+ {
+ pix = img.pixel((i > wm) ? wm : i, y);
+ m_stack[i + radius] = pix;
+ sum.add(pix, radius + 1 - i);
+ sum_in.add(pix);
+ }
+
+ stack_ptr = radius;
+ for(x = 0; x < w; x++)
+ {
+ if(mul_sum) sum.calc_pix(m_buf[x], mul_sum, shr_sum);
+ else sum.calc_pix(m_buf[x], div_sum);
+
+ sum.sub(sum_out);
+
+ stack_start = stack_ptr + div - radius;
+ if(stack_start >= div) stack_start -= div;
+ stack_pix = &m_stack[stack_start];
+
+ sum_out.sub(*stack_pix);
+
+ xp = x + radius + 1;
+ if(xp > wm) xp = wm;
+ pix = img.pixel(xp, y);
+
+ *stack_pix = pix;
+
+ sum_in.add(pix);
+ sum.add(sum_in);
+
+ ++stack_ptr;
+ if(stack_ptr >= div) stack_ptr = 0;
+ stack_pix = &m_stack[stack_ptr];
+
+ sum_out.add(*stack_pix);
+ sum_in.sub(*stack_pix);
+ }
+ img.copy_color_hspan(0, y, w, &m_buf[0]);
+ }
+ }
+
+ //--------------------------------------------------------------------
+ template<class Img> void blur_y(Img& img, unsigned radius)
+ {
+ pixfmt_transposer<Img> img2(img);
+ blur_x(img2, radius);
+ }
+
+ //--------------------------------------------------------------------
+ template<class Img> void blur(Img& img, unsigned radius)
+ {
+ blur_x(img, radius);
+ pixfmt_transposer<Img> img2(img);
+ blur_x(img2, radius);
+ }
+
+ private:
+ pod_vector<color_type> m_buf;
+ pod_vector<color_type> m_stack;
+ };
+
+ //====================================================stack_blur_calc_rgba
+ template<class T=unsigned> struct stack_blur_calc_rgba
+ {
+ typedef T value_type;
+ value_type r,g,b,a;
+
+ AGG_INLINE void clear()
+ {
+ r = g = b = a = 0;
+ }
+
+ template<class ArgT> AGG_INLINE void add(const ArgT& v)
+ {
+ r += v.r;
+ g += v.g;
+ b += v.b;
+ a += v.a;
+ }
+
+ template<class ArgT> AGG_INLINE void add(const ArgT& v, unsigned k)
+ {
+ r += v.r * k;
+ g += v.g * k;
+ b += v.b * k;
+ a += v.a * k;
+ }
+
+ template<class ArgT> AGG_INLINE void sub(const ArgT& v)
+ {
+ r -= v.r;
+ g -= v.g;
+ b -= v.b;
+ a -= v.a;
+ }
+
+ template<class ArgT> AGG_INLINE void calc_pix(ArgT& v, unsigned div)
+ {
+ typedef typename ArgT::value_type value_type;
+ v.r = value_type(r / div);
+ v.g = value_type(g / div);
+ v.b = value_type(b / div);
+ v.a = value_type(a / div);
+ }
+
+ template<class ArgT>
+ AGG_INLINE void calc_pix(ArgT& v, unsigned mul, unsigned shr)
+ {
+ typedef typename ArgT::value_type value_type;
+ v.r = value_type((r * mul) >> shr);
+ v.g = value_type((g * mul) >> shr);
+ v.b = value_type((b * mul) >> shr);
+ v.a = value_type((a * mul) >> shr);
+ }
+ };
+
+
+ //=====================================================stack_blur_calc_rgb
+ template<class T=unsigned> struct stack_blur_calc_rgb
+ {
+ typedef T value_type;
+ value_type r,g,b;
+
+ AGG_INLINE void clear()
+ {
+ r = g = b = 0;
+ }
+
+ template<class ArgT> AGG_INLINE void add(const ArgT& v)
+ {
+ r += v.r;
+ g += v.g;
+ b += v.b;
+ }
+
+ template<class ArgT> AGG_INLINE void add(const ArgT& v, unsigned k)
+ {
+ r += v.r * k;
+ g += v.g * k;
+ b += v.b * k;
+ }
+
+ template<class ArgT> AGG_INLINE void sub(const ArgT& v)
+ {
+ r -= v.r;
+ g -= v.g;
+ b -= v.b;
+ }
+
+ template<class ArgT> AGG_INLINE void calc_pix(ArgT& v, unsigned div)
+ {
+ typedef typename ArgT::value_type value_type;
+ v.r = value_type(r / div);
+ v.g = value_type(g / div);
+ v.b = value_type(b / div);
+ }
+
+ template<class ArgT>
+ AGG_INLINE void calc_pix(ArgT& v, unsigned mul, unsigned shr)
+ {
+ typedef typename ArgT::value_type value_type;
+ v.r = value_type((r * mul) >> shr);
+ v.g = value_type((g * mul) >> shr);
+ v.b = value_type((b * mul) >> shr);
+ }
+ };
+
+
+ //====================================================stack_blur_calc_gray
+ template<class T=unsigned> struct stack_blur_calc_gray
+ {
+ typedef T value_type;
+ value_type v;
+
+ AGG_INLINE void clear()
+ {
+ v = 0;
+ }
+
+ template<class ArgT> AGG_INLINE void add(const ArgT& a)
+ {
+ v += a.v;
+ }
+
+ template<class ArgT> AGG_INLINE void add(const ArgT& a, unsigned k)
+ {
+ v += a.v * k;
+ }
+
+ template<class ArgT> AGG_INLINE void sub(const ArgT& a)
+ {
+ v -= a.v;
+ }
+
+ template<class ArgT> AGG_INLINE void calc_pix(ArgT& a, unsigned div)
+ {
+ typedef typename ArgT::value_type value_type;
+ a.v = value_type(v / div);
+ }
+
+ template<class ArgT>
+ AGG_INLINE void calc_pix(ArgT& a, unsigned mul, unsigned shr)
+ {
+ typedef typename ArgT::value_type value_type;
+ a.v = value_type((v * mul) >> shr);
+ }
+ };
+
+
+
+ //========================================================stack_blur_gray8
+ template<class Img>
+ void stack_blur_gray8(Img& img, unsigned rx, unsigned ry)
+ {
+ unsigned x, y, xp, yp, i;
+ unsigned stack_ptr;
+ unsigned stack_start;
+
+ const int8u* src_pix_ptr;
+ int8u* dst_pix_ptr;
+ unsigned pix;
+ unsigned stack_pix;
+ unsigned sum;
+ unsigned sum_in;
+ unsigned sum_out;
+
+ unsigned w = img.width();
+ unsigned h = img.height();
+ unsigned wm = w - 1;
+ unsigned hm = h - 1;
+
+ unsigned div;
+ unsigned mul_sum;
+ unsigned shr_sum;
+
+ pod_vector<int8u> stack;
+
+ if(rx > 0)
+ {
+ if(rx > 254) rx = 254;
+ div = rx * 2 + 1;
+ mul_sum = stack_blur_tables<int>::g_stack_blur8_mul[rx];
+ shr_sum = stack_blur_tables<int>::g_stack_blur8_shr[rx];
+ stack.allocate(div);
+
+ for(y = 0; y < h; y++)
+ {
+ sum = sum_in = sum_out = 0;
+
+ src_pix_ptr = img.pix_ptr(0, y);
+ pix = *src_pix_ptr;
+ for(i = 0; i <= rx; i++)
+ {
+ stack[i] = pix;
+ sum += pix * (i + 1);
+ sum_out += pix;
+ }
+ for(i = 1; i <= rx; i++)
+ {
+ if(i <= wm) src_pix_ptr += Img::pix_width;
+ pix = *src_pix_ptr;
+ stack[i + rx] = pix;
+ sum += pix * (rx + 1 - i);
+ sum_in += pix;
+ }
+
+ stack_ptr = rx;
+ xp = rx;
+ if(xp > wm) xp = wm;
+ src_pix_ptr = img.pix_ptr(xp, y);
+ dst_pix_ptr = img.pix_ptr(0, y);
+ for(x = 0; x < w; x++)
+ {
+ *dst_pix_ptr = (sum * mul_sum) >> shr_sum;
+ dst_pix_ptr += Img::pix_width;
+
+ sum -= sum_out;
+
+ stack_start = stack_ptr + div - rx;
+ if(stack_start >= div) stack_start -= div;
+ sum_out -= stack[stack_start];
+
+ if(xp < wm)
+ {
+ src_pix_ptr += Img::pix_width;
+ pix = *src_pix_ptr;
+ ++xp;
+ }
+
+ stack[stack_start] = pix;
+
+ sum_in += pix;
+ sum += sum_in;
+
+ ++stack_ptr;
+ if(stack_ptr >= div) stack_ptr = 0;
+ stack_pix = stack[stack_ptr];
+
+ sum_out += stack_pix;
+ sum_in -= stack_pix;
+ }
+ }
+ }
+
+ if(ry > 0)
+ {
+ if(ry > 254) ry = 254;
+ div = ry * 2 + 1;
+ mul_sum = stack_blur_tables<int>::g_stack_blur8_mul[ry];
+ shr_sum = stack_blur_tables<int>::g_stack_blur8_shr[ry];
+ stack.allocate(div);
+
+ int stride = img.stride();
+ for(x = 0; x < w; x++)
+ {
+ sum = sum_in = sum_out = 0;
+
+ src_pix_ptr = img.pix_ptr(x, 0);
+ pix = *src_pix_ptr;
+ for(i = 0; i <= ry; i++)
+ {
+ stack[i] = pix;
+ sum += pix * (i + 1);
+ sum_out += pix;
+ }
+ for(i = 1; i <= ry; i++)
+ {
+ if(i <= hm) src_pix_ptr += stride;
+ pix = *src_pix_ptr;
+ stack[i + ry] = pix;
+ sum += pix * (ry + 1 - i);
+ sum_in += pix;
+ }
+
+ stack_ptr = ry;
+ yp = ry;
+ if(yp > hm) yp = hm;
+ src_pix_ptr = img.pix_ptr(x, yp);
+ dst_pix_ptr = img.pix_ptr(x, 0);
+ for(y = 0; y < h; y++)
+ {
+ *dst_pix_ptr = (sum * mul_sum) >> shr_sum;
+ dst_pix_ptr += stride;
+
+ sum -= sum_out;
+
+ stack_start = stack_ptr + div - ry;
+ if(stack_start >= div) stack_start -= div;
+ sum_out -= stack[stack_start];
+
+ if(yp < hm)
+ {
+ src_pix_ptr += stride;
+ pix = *src_pix_ptr;
+ ++yp;
+ }
+
+ stack[stack_start] = pix;
+
+ sum_in += pix;
+ sum += sum_in;
+
+ ++stack_ptr;
+ if(stack_ptr >= div) stack_ptr = 0;
+ stack_pix = stack[stack_ptr];
+
+ sum_out += stack_pix;
+ sum_in -= stack_pix;
+ }
+ }
+ }
+ }
+
+
+
+ //========================================================stack_blur_rgb24
+ template<class Img>
+ void stack_blur_rgb24(Img& img, unsigned rx, unsigned ry)
+ {
+ typedef typename Img::color_type color_type;
+ typedef typename Img::order_type order_type;
+ enum order_e
+ {
+ R = order_type::R,
+ G = order_type::G,
+ B = order_type::B
+ };
+
+ unsigned x, y, xp, yp, i;
+ unsigned stack_ptr;
+ unsigned stack_start;
+
+ const int8u* src_pix_ptr;
+ int8u* dst_pix_ptr;
+ color_type* stack_pix_ptr;
+
+ unsigned sum_r;
+ unsigned sum_g;
+ unsigned sum_b;
+ unsigned sum_in_r;
+ unsigned sum_in_g;
+ unsigned sum_in_b;
+ unsigned sum_out_r;
+ unsigned sum_out_g;
+ unsigned sum_out_b;
+
+ unsigned w = img.width();
+ unsigned h = img.height();
+ unsigned wm = w - 1;
+ unsigned hm = h - 1;
+
+ unsigned div;
+ unsigned mul_sum;
+ unsigned shr_sum;
+
+ pod_vector<color_type> stack;
+
+ if(rx > 0)
+ {
+ if(rx > 254) rx = 254;
+ div = rx * 2 + 1;
+ mul_sum = stack_blur_tables<int>::g_stack_blur8_mul[rx];
+ shr_sum = stack_blur_tables<int>::g_stack_blur8_shr[rx];
+ stack.allocate(div);
+
+ for(y = 0; y < h; y++)
+ {
+ sum_r =
+ sum_g =
+ sum_b =
+ sum_in_r =
+ sum_in_g =
+ sum_in_b =
+ sum_out_r =
+ sum_out_g =
+ sum_out_b = 0;
+
+ src_pix_ptr = img.pix_ptr(0, y);
+ for(i = 0; i <= rx; i++)
+ {
+ stack_pix_ptr = &stack[i];
+ stack_pix_ptr->r = src_pix_ptr[R];
+ stack_pix_ptr->g = src_pix_ptr[G];
+ stack_pix_ptr->b = src_pix_ptr[B];
+ sum_r += src_pix_ptr[R] * (i + 1);
+ sum_g += src_pix_ptr[G] * (i + 1);
+ sum_b += src_pix_ptr[B] * (i + 1);
+ sum_out_r += src_pix_ptr[R];
+ sum_out_g += src_pix_ptr[G];
+ sum_out_b += src_pix_ptr[B];
+ }
+ for(i = 1; i <= rx; i++)
+ {
+ if(i <= wm) src_pix_ptr += Img::pix_width;
+ stack_pix_ptr = &stack[i + rx];
+ stack_pix_ptr->r = src_pix_ptr[R];
+ stack_pix_ptr->g = src_pix_ptr[G];
+ stack_pix_ptr->b = src_pix_ptr[B];
+ sum_r += src_pix_ptr[R] * (rx + 1 - i);
+ sum_g += src_pix_ptr[G] * (rx + 1 - i);
+ sum_b += src_pix_ptr[B] * (rx + 1 - i);
+ sum_in_r += src_pix_ptr[R];
+ sum_in_g += src_pix_ptr[G];
+ sum_in_b += src_pix_ptr[B];
+ }
+
+ stack_ptr = rx;
+ xp = rx;
+ if(xp > wm) xp = wm;
+ src_pix_ptr = img.pix_ptr(xp, y);
+ dst_pix_ptr = img.pix_ptr(0, y);
+ for(x = 0; x < w; x++)
+ {
+ dst_pix_ptr[R] = (sum_r * mul_sum) >> shr_sum;
+ dst_pix_ptr[G] = (sum_g * mul_sum) >> shr_sum;
+ dst_pix_ptr[B] = (sum_b * mul_sum) >> shr_sum;
+ dst_pix_ptr += Img::pix_width;
+
+ sum_r -= sum_out_r;
+ sum_g -= sum_out_g;
+ sum_b -= sum_out_b;
+
+ stack_start = stack_ptr + div - rx;
+ if(stack_start >= div) stack_start -= div;
+ stack_pix_ptr = &stack[stack_start];
+
+ sum_out_r -= stack_pix_ptr->r;
+ sum_out_g -= stack_pix_ptr->g;
+ sum_out_b -= stack_pix_ptr->b;
+
+ if(xp < wm)
+ {
+ src_pix_ptr += Img::pix_width;
+ ++xp;
+ }
+
+ stack_pix_ptr->r = src_pix_ptr[R];
+ stack_pix_ptr->g = src_pix_ptr[G];
+ stack_pix_ptr->b = src_pix_ptr[B];
+
+ sum_in_r += src_pix_ptr[R];
+ sum_in_g += src_pix_ptr[G];
+ sum_in_b += src_pix_ptr[B];
+ sum_r += sum_in_r;
+ sum_g += sum_in_g;
+ sum_b += sum_in_b;
+
+ ++stack_ptr;
+ if(stack_ptr >= div) stack_ptr = 0;
+ stack_pix_ptr = &stack[stack_ptr];
+
+ sum_out_r += stack_pix_ptr->r;
+ sum_out_g += stack_pix_ptr->g;
+ sum_out_b += stack_pix_ptr->b;
+ sum_in_r -= stack_pix_ptr->r;
+ sum_in_g -= stack_pix_ptr->g;
+ sum_in_b -= stack_pix_ptr->b;
+ }
+ }
+ }
+
+ if(ry > 0)
+ {
+ if(ry > 254) ry = 254;
+ div = ry * 2 + 1;
+ mul_sum = stack_blur_tables<int>::g_stack_blur8_mul[ry];
+ shr_sum = stack_blur_tables<int>::g_stack_blur8_shr[ry];
+ stack.allocate(div);
+
+ int stride = img.stride();
+ for(x = 0; x < w; x++)
+ {
+ sum_r =
+ sum_g =
+ sum_b =
+ sum_in_r =
+ sum_in_g =
+ sum_in_b =
+ sum_out_r =
+ sum_out_g =
+ sum_out_b = 0;
+
+ src_pix_ptr = img.pix_ptr(x, 0);
+ for(i = 0; i <= ry; i++)
+ {
+ stack_pix_ptr = &stack[i];
+ stack_pix_ptr->r = src_pix_ptr[R];
+ stack_pix_ptr->g = src_pix_ptr[G];
+ stack_pix_ptr->b = src_pix_ptr[B];
+ sum_r += src_pix_ptr[R] * (i + 1);
+ sum_g += src_pix_ptr[G] * (i + 1);
+ sum_b += src_pix_ptr[B] * (i + 1);
+ sum_out_r += src_pix_ptr[R];
+ sum_out_g += src_pix_ptr[G];
+ sum_out_b += src_pix_ptr[B];
+ }
+ for(i = 1; i <= ry; i++)
+ {
+ if(i <= hm) src_pix_ptr += stride;
+ stack_pix_ptr = &stack[i + ry];
+ stack_pix_ptr->r = src_pix_ptr[R];
+ stack_pix_ptr->g = src_pix_ptr[G];
+ stack_pix_ptr->b = src_pix_ptr[B];
+ sum_r += src_pix_ptr[R] * (ry + 1 - i);
+ sum_g += src_pix_ptr[G] * (ry + 1 - i);
+ sum_b += src_pix_ptr[B] * (ry + 1 - i);
+ sum_in_r += src_pix_ptr[R];
+ sum_in_g += src_pix_ptr[G];
+ sum_in_b += src_pix_ptr[B];
+ }
+
+ stack_ptr = ry;
+ yp = ry;
+ if(yp > hm) yp = hm;
+ src_pix_ptr = img.pix_ptr(x, yp);
+ dst_pix_ptr = img.pix_ptr(x, 0);
+ for(y = 0; y < h; y++)
+ {
+ dst_pix_ptr[R] = (sum_r * mul_sum) >> shr_sum;
+ dst_pix_ptr[G] = (sum_g * mul_sum) >> shr_sum;
+ dst_pix_ptr[B] = (sum_b * mul_sum) >> shr_sum;
+ dst_pix_ptr += stride;
+
+ sum_r -= sum_out_r;
+ sum_g -= sum_out_g;
+ sum_b -= sum_out_b;
+
+ stack_start = stack_ptr + div - ry;
+ if(stack_start >= div) stack_start -= div;
+
+ stack_pix_ptr = &stack[stack_start];
+ sum_out_r -= stack_pix_ptr->r;
+ sum_out_g -= stack_pix_ptr->g;
+ sum_out_b -= stack_pix_ptr->b;
+
+ if(yp < hm)
+ {
+ src_pix_ptr += stride;
+ ++yp;
+ }
+
+ stack_pix_ptr->r = src_pix_ptr[R];
+ stack_pix_ptr->g = src_pix_ptr[G];
+ stack_pix_ptr->b = src_pix_ptr[B];
+
+ sum_in_r += src_pix_ptr[R];
+ sum_in_g += src_pix_ptr[G];
+ sum_in_b += src_pix_ptr[B];
+ sum_r += sum_in_r;
+ sum_g += sum_in_g;
+ sum_b += sum_in_b;
+
+ ++stack_ptr;
+ if(stack_ptr >= div) stack_ptr = 0;
+ stack_pix_ptr = &stack[stack_ptr];
+
+ sum_out_r += stack_pix_ptr->r;
+ sum_out_g += stack_pix_ptr->g;
+ sum_out_b += stack_pix_ptr->b;
+ sum_in_r -= stack_pix_ptr->r;
+ sum_in_g -= stack_pix_ptr->g;
+ sum_in_b -= stack_pix_ptr->b;
+ }
+ }
+ }
+ }
+
+
+
+ //=======================================================stack_blur_rgba32
+ template<class Img>
+ void stack_blur_rgba32(Img& img, unsigned rx, unsigned ry)
+ {
+ typedef typename Img::color_type color_type;
+ typedef typename Img::order_type order_type;
+ enum order_e
+ {
+ R = order_type::R,
+ G = order_type::G,
+ B = order_type::B,
+ A = order_type::A
+ };
+
+ unsigned x, y, xp, yp, i;
+ unsigned stack_ptr;
+ unsigned stack_start;
+
+ const int8u* src_pix_ptr;
+ int8u* dst_pix_ptr;
+ color_type* stack_pix_ptr;
+
+ unsigned sum_r;
+ unsigned sum_g;
+ unsigned sum_b;
+ unsigned sum_a;
+ unsigned sum_in_r;
+ unsigned sum_in_g;
+ unsigned sum_in_b;
+ unsigned sum_in_a;
+ unsigned sum_out_r;
+ unsigned sum_out_g;
+ unsigned sum_out_b;
+ unsigned sum_out_a;
+
+ unsigned w = img.width();
+ unsigned h = img.height();
+ unsigned wm = w - 1;
+ unsigned hm = h - 1;
+
+ unsigned div;
+ unsigned mul_sum;
+ unsigned shr_sum;
+
+ pod_vector<color_type> stack;
+
+ if(rx > 0)
+ {
+ if(rx > 254) rx = 254;
+ div = rx * 2 + 1;
+ mul_sum = stack_blur_tables<int>::g_stack_blur8_mul[rx];
+ shr_sum = stack_blur_tables<int>::g_stack_blur8_shr[rx];
+ stack.allocate(div);
+
+ for(y = 0; y < h; y++)
+ {
+ sum_r =
+ sum_g =
+ sum_b =
+ sum_a =
+ sum_in_r =
+ sum_in_g =
+ sum_in_b =
+ sum_in_a =
+ sum_out_r =
+ sum_out_g =
+ sum_out_b =
+ sum_out_a = 0;
+
+ src_pix_ptr = img.pix_ptr(0, y);
+ for(i = 0; i <= rx; i++)
+ {
+ stack_pix_ptr = &stack[i];
+ stack_pix_ptr->r = src_pix_ptr[R];
+ stack_pix_ptr->g = src_pix_ptr[G];
+ stack_pix_ptr->b = src_pix_ptr[B];
+ stack_pix_ptr->a = src_pix_ptr[A];
+ sum_r += src_pix_ptr[R] * (i + 1);
+ sum_g += src_pix_ptr[G] * (i + 1);
+ sum_b += src_pix_ptr[B] * (i + 1);
+ sum_a += src_pix_ptr[A] * (i + 1);
+ sum_out_r += src_pix_ptr[R];
+ sum_out_g += src_pix_ptr[G];
+ sum_out_b += src_pix_ptr[B];
+ sum_out_a += src_pix_ptr[A];
+ }
+ for(i = 1; i <= rx; i++)
+ {
+ if(i <= wm) src_pix_ptr += Img::pix_width;
+ stack_pix_ptr = &stack[i + rx];
+ stack_pix_ptr->r = src_pix_ptr[R];
+ stack_pix_ptr->g = src_pix_ptr[G];
+ stack_pix_ptr->b = src_pix_ptr[B];
+ stack_pix_ptr->a = src_pix_ptr[A];
+ sum_r += src_pix_ptr[R] * (rx + 1 - i);
+ sum_g += src_pix_ptr[G] * (rx + 1 - i);
+ sum_b += src_pix_ptr[B] * (rx + 1 - i);
+ sum_a += src_pix_ptr[A] * (rx + 1 - i);
+ sum_in_r += src_pix_ptr[R];
+ sum_in_g += src_pix_ptr[G];
+ sum_in_b += src_pix_ptr[B];
+ sum_in_a += src_pix_ptr[A];
+ }
+
+ stack_ptr = rx;
+ xp = rx;
+ if(xp > wm) xp = wm;
+ src_pix_ptr = img.pix_ptr(xp, y);
+ dst_pix_ptr = img.pix_ptr(0, y);
+ for(x = 0; x < w; x++)
+ {
+ dst_pix_ptr[R] = (sum_r * mul_sum) >> shr_sum;
+ dst_pix_ptr[G] = (sum_g * mul_sum) >> shr_sum;
+ dst_pix_ptr[B] = (sum_b * mul_sum) >> shr_sum;
+ dst_pix_ptr[A] = (sum_a * mul_sum) >> shr_sum;
+ dst_pix_ptr += Img::pix_width;
+
+ sum_r -= sum_out_r;
+ sum_g -= sum_out_g;
+ sum_b -= sum_out_b;
+ sum_a -= sum_out_a;
+
+ stack_start = stack_ptr + div - rx;
+ if(stack_start >= div) stack_start -= div;
+ stack_pix_ptr = &stack[stack_start];
+
+ sum_out_r -= stack_pix_ptr->r;
+ sum_out_g -= stack_pix_ptr->g;
+ sum_out_b -= stack_pix_ptr->b;
+ sum_out_a -= stack_pix_ptr->a;
+
+ if(xp < wm)
+ {
+ src_pix_ptr += Img::pix_width;
+ ++xp;
+ }
+
+ stack_pix_ptr->r = src_pix_ptr[R];
+ stack_pix_ptr->g = src_pix_ptr[G];
+ stack_pix_ptr->b = src_pix_ptr[B];
+ stack_pix_ptr->a = src_pix_ptr[A];
+
+ sum_in_r += src_pix_ptr[R];
+ sum_in_g += src_pix_ptr[G];
+ sum_in_b += src_pix_ptr[B];
+ sum_in_a += src_pix_ptr[A];
+ sum_r += sum_in_r;
+ sum_g += sum_in_g;
+ sum_b += sum_in_b;
+ sum_a += sum_in_a;
+
+ ++stack_ptr;
+ if(stack_ptr >= div) stack_ptr = 0;
+ stack_pix_ptr = &stack[stack_ptr];
+
+ sum_out_r += stack_pix_ptr->r;
+ sum_out_g += stack_pix_ptr->g;
+ sum_out_b += stack_pix_ptr->b;
+ sum_out_a += stack_pix_ptr->a;
+ sum_in_r -= stack_pix_ptr->r;
+ sum_in_g -= stack_pix_ptr->g;
+ sum_in_b -= stack_pix_ptr->b;
+ sum_in_a -= stack_pix_ptr->a;
+ }
+ }
+ }
+
+ if(ry > 0)
+ {
+ if(ry > 254) ry = 254;
+ div = ry * 2 + 1;
+ mul_sum = stack_blur_tables<int>::g_stack_blur8_mul[ry];
+ shr_sum = stack_blur_tables<int>::g_stack_blur8_shr[ry];
+ stack.allocate(div);
+
+ int stride = img.stride();
+ for(x = 0; x < w; x++)
+ {
+ sum_r =
+ sum_g =
+ sum_b =
+ sum_a =
+ sum_in_r =
+ sum_in_g =
+ sum_in_b =
+ sum_in_a =
+ sum_out_r =
+ sum_out_g =
+ sum_out_b =
+ sum_out_a = 0;
+
+ src_pix_ptr = img.pix_ptr(x, 0);
+ for(i = 0; i <= ry; i++)
+ {
+ stack_pix_ptr = &stack[i];
+ stack_pix_ptr->r = src_pix_ptr[R];
+ stack_pix_ptr->g = src_pix_ptr[G];
+ stack_pix_ptr->b = src_pix_ptr[B];
+ stack_pix_ptr->a = src_pix_ptr[A];
+ sum_r += src_pix_ptr[R] * (i + 1);
+ sum_g += src_pix_ptr[G] * (i + 1);
+ sum_b += src_pix_ptr[B] * (i + 1);
+ sum_a += src_pix_ptr[A] * (i + 1);
+ sum_out_r += src_pix_ptr[R];
+ sum_out_g += src_pix_ptr[G];
+ sum_out_b += src_pix_ptr[B];
+ sum_out_a += src_pix_ptr[A];
+ }
+ for(i = 1; i <= ry; i++)
+ {
+ if(i <= hm) src_pix_ptr += stride;
+ stack_pix_ptr = &stack[i + ry];
+ stack_pix_ptr->r = src_pix_ptr[R];
+ stack_pix_ptr->g = src_pix_ptr[G];
+ stack_pix_ptr->b = src_pix_ptr[B];
+ stack_pix_ptr->a = src_pix_ptr[A];
+ sum_r += src_pix_ptr[R] * (ry + 1 - i);
+ sum_g += src_pix_ptr[G] * (ry + 1 - i);
+ sum_b += src_pix_ptr[B] * (ry + 1 - i);
+ sum_a += src_pix_ptr[A] * (ry + 1 - i);
+ sum_in_r += src_pix_ptr[R];
+ sum_in_g += src_pix_ptr[G];
+ sum_in_b += src_pix_ptr[B];
+ sum_in_a += src_pix_ptr[A];
+ }
+
+ stack_ptr = ry;
+ yp = ry;
+ if(yp > hm) yp = hm;
+ src_pix_ptr = img.pix_ptr(x, yp);
+ dst_pix_ptr = img.pix_ptr(x, 0);
+ for(y = 0; y < h; y++)
+ {
+ dst_pix_ptr[R] = (sum_r * mul_sum) >> shr_sum;
+ dst_pix_ptr[G] = (sum_g * mul_sum) >> shr_sum;
+ dst_pix_ptr[B] = (sum_b * mul_sum) >> shr_sum;
+ dst_pix_ptr[A] = (sum_a * mul_sum) >> shr_sum;
+ dst_pix_ptr += stride;
+
+ sum_r -= sum_out_r;
+ sum_g -= sum_out_g;
+ sum_b -= sum_out_b;
+ sum_a -= sum_out_a;
+
+ stack_start = stack_ptr + div - ry;
+ if(stack_start >= div) stack_start -= div;
+
+ stack_pix_ptr = &stack[stack_start];
+ sum_out_r -= stack_pix_ptr->r;
+ sum_out_g -= stack_pix_ptr->g;
+ sum_out_b -= stack_pix_ptr->b;
+ sum_out_a -= stack_pix_ptr->a;
+
+ if(yp < hm)
+ {
+ src_pix_ptr += stride;
+ ++yp;
+ }
+
+ stack_pix_ptr->r = src_pix_ptr[R];
+ stack_pix_ptr->g = src_pix_ptr[G];
+ stack_pix_ptr->b = src_pix_ptr[B];
+ stack_pix_ptr->a = src_pix_ptr[A];
+
+ sum_in_r += src_pix_ptr[R];
+ sum_in_g += src_pix_ptr[G];
+ sum_in_b += src_pix_ptr[B];
+ sum_in_a += src_pix_ptr[A];
+ sum_r += sum_in_r;
+ sum_g += sum_in_g;
+ sum_b += sum_in_b;
+ sum_a += sum_in_a;
+
+ ++stack_ptr;
+ if(stack_ptr >= div) stack_ptr = 0;
+ stack_pix_ptr = &stack[stack_ptr];
+
+ sum_out_r += stack_pix_ptr->r;
+ sum_out_g += stack_pix_ptr->g;
+ sum_out_b += stack_pix_ptr->b;
+ sum_out_a += stack_pix_ptr->a;
+ sum_in_r -= stack_pix_ptr->r;
+ sum_in_g -= stack_pix_ptr->g;
+ sum_in_b -= stack_pix_ptr->b;
+ sum_in_a -= stack_pix_ptr->a;
+ }
+ }
+ }
+ }
+
+
+
+ //===========================================================recursive_blur
+ template<class ColorT, class CalculatorT> class recursive_blur
+ {
+ public:
+ typedef ColorT color_type;
+ typedef CalculatorT calculator_type;
+ typedef typename color_type::value_type value_type;
+ typedef typename calculator_type::value_type calc_type;
+
+ //--------------------------------------------------------------------
+ template<class Img> void blur_x(Img& img, double radius)
+ {
+ if(radius < 0.62) return;
+ if(img.width() < 3) return;
+
+ calc_type s = calc_type(radius * 0.5);
+ calc_type q = calc_type((s < 2.5) ?
+ 3.97156 - 4.14554 * sqrt(1 - 0.26891 * s) :
+ 0.98711 * s - 0.96330);
+
+ calc_type q2 = calc_type(q * q);
+ calc_type q3 = calc_type(q2 * q);
+
+ calc_type b0 = calc_type(1.0 / (1.578250 +
+ 2.444130 * q +
+ 1.428100 * q2 +
+ 0.422205 * q3));
+
+ calc_type b1 = calc_type( 2.44413 * q +
+ 2.85619 * q2 +
+ 1.26661 * q3);
+
+ calc_type b2 = calc_type(-1.42810 * q2 +
+ -1.26661 * q3);
+
+ calc_type b3 = calc_type(0.422205 * q3);
+
+ calc_type b = calc_type(1 - (b1 + b2 + b3) * b0);
+
+ b1 *= b0;
+ b2 *= b0;
+ b3 *= b0;
+
+ int w = img.width();
+ int h = img.height();
+ int wm = w-1;
+ int x, y;
+
+ m_sum1.allocate(w);
+ m_sum2.allocate(w);
+ m_buf.allocate(w);
+
+ for(y = 0; y < h; y++)
+ {
+ calculator_type c;
+ c.from_pix(img.pixel(0, y));
+ m_sum1[0].calc(b, b1, b2, b3, c, c, c, c);
+ c.from_pix(img.pixel(1, y));
+ m_sum1[1].calc(b, b1, b2, b3, c, m_sum1[0], m_sum1[0], m_sum1[0]);
+ c.from_pix(img.pixel(2, y));
+ m_sum1[2].calc(b, b1, b2, b3, c, m_sum1[1], m_sum1[0], m_sum1[0]);
+
+ for(x = 3; x < w; ++x)
+ {
+ c.from_pix(img.pixel(x, y));
+ m_sum1[x].calc(b, b1, b2, b3, c, m_sum1[x-1], m_sum1[x-2], m_sum1[x-3]);
+ }
+
+ m_sum2[wm ].calc(b, b1, b2, b3, m_sum1[wm ], m_sum1[wm ], m_sum1[wm], m_sum1[wm]);
+ m_sum2[wm-1].calc(b, b1, b2, b3, m_sum1[wm-1], m_sum2[wm ], m_sum2[wm], m_sum2[wm]);
+ m_sum2[wm-2].calc(b, b1, b2, b3, m_sum1[wm-2], m_sum2[wm-1], m_sum2[wm], m_sum2[wm]);
+ m_sum2[wm ].to_pix(m_buf[wm ]);
+ m_sum2[wm-1].to_pix(m_buf[wm-1]);
+ m_sum2[wm-2].to_pix(m_buf[wm-2]);
+
+ for(x = wm-3; x >= 0; --x)
+ {
+ m_sum2[x].calc(b, b1, b2, b3, m_sum1[x], m_sum2[x+1], m_sum2[x+2], m_sum2[x+3]);
+ m_sum2[x].to_pix(m_buf[x]);
+ }
+ img.copy_color_hspan(0, y, w, &m_buf[0]);
+ }
+ }
+
+ //--------------------------------------------------------------------
+ template<class Img> void blur_y(Img& img, double radius)
+ {
+ pixfmt_transposer<Img> img2(img);
+ blur_x(img2, radius);
+ }
+
+ //--------------------------------------------------------------------
+ template<class Img> void blur(Img& img, double radius)
+ {
+ blur_x(img, radius);
+ pixfmt_transposer<Img> img2(img);
+ blur_x(img2, radius);
+ }
+
+ private:
+ agg::pod_vector<calculator_type> m_sum1;
+ agg::pod_vector<calculator_type> m_sum2;
+ agg::pod_vector<color_type> m_buf;
+ };
+
+
+ //=================================================recursive_blur_calc_rgba
+ template<class T=double> struct recursive_blur_calc_rgba
+ {
+ typedef T value_type;
+ typedef recursive_blur_calc_rgba<T> self_type;
+
+ value_type r,g,b,a;
+
+ template<class ColorT>
+ AGG_INLINE void from_pix(const ColorT& c)
+ {
+ r = c.r;
+ g = c.g;
+ b = c.b;
+ a = c.a;
+ }
+
+ AGG_INLINE void calc(value_type b1,
+ value_type b2,
+ value_type b3,
+ value_type b4,
+ const self_type& c1,
+ const self_type& c2,
+ const self_type& c3,
+ const self_type& c4)
+ {
+ r = b1*c1.r + b2*c2.r + b3*c3.r + b4*c4.r;
+ g = b1*c1.g + b2*c2.g + b3*c3.g + b4*c4.g;
+ b = b1*c1.b + b2*c2.b + b3*c3.b + b4*c4.b;
+ a = b1*c1.a + b2*c2.a + b3*c3.a + b4*c4.a;
+ }
+
+ template<class ColorT>
+ AGG_INLINE void to_pix(ColorT& c) const
+ {
+ typedef typename ColorT::value_type cv_type;
+ c.r = cv_type(r);
+ c.g = cv_type(g);
+ c.b = cv_type(b);
+ c.a = cv_type(a);
+ }
+ };
+
+
+ //=================================================recursive_blur_calc_rgb
+ template<class T=double> struct recursive_blur_calc_rgb
+ {
+ typedef T value_type;
+ typedef recursive_blur_calc_rgb<T> self_type;
+
+ value_type r,g,b;
+
+ template<class ColorT>
+ AGG_INLINE void from_pix(const ColorT& c)
+ {
+ r = c.r;
+ g = c.g;
+ b = c.b;
+ }
+
+ AGG_INLINE void calc(value_type b1,
+ value_type b2,
+ value_type b3,
+ value_type b4,
+ const self_type& c1,
+ const self_type& c2,
+ const self_type& c3,
+ const self_type& c4)
+ {
+ r = b1*c1.r + b2*c2.r + b3*c3.r + b4*c4.r;
+ g = b1*c1.g + b2*c2.g + b3*c3.g + b4*c4.g;
+ b = b1*c1.b + b2*c2.b + b3*c3.b + b4*c4.b;
+ }
+
+ template<class ColorT>
+ AGG_INLINE void to_pix(ColorT& c) const
+ {
+ typedef typename ColorT::value_type cv_type;
+ c.r = cv_type(r);
+ c.g = cv_type(g);
+ c.b = cv_type(b);
+ }
+ };
+
+
+ //================================================recursive_blur_calc_gray
+ template<class T=double> struct recursive_blur_calc_gray
+ {
+ typedef T value_type;
+ typedef recursive_blur_calc_gray<T> self_type;
+
+ value_type v;
+
+ template<class ColorT>
+ AGG_INLINE void from_pix(const ColorT& c)
+ {
+ v = c.v;
+ }
+
+ AGG_INLINE void calc(value_type b1,
+ value_type b2,
+ value_type b3,
+ value_type b4,
+ const self_type& c1,
+ const self_type& c2,
+ const self_type& c3,
+ const self_type& c4)
+ {
+ v = b1*c1.v + b2*c2.v + b3*c3.v + b4*c4.v;
+ }
+
+ template<class ColorT>
+ AGG_INLINE void to_pix(ColorT& c) const
+ {
+ typedef typename ColorT::value_type cv_type;
+ c.v = cv_type(v);
+ }
+ };
+
+ //================================================slight_blur
+ // Special-purpose filter for applying a Gaussian blur with a radius small enough
+ // that the blur only affects adjacent pixels. A Gaussian curve with a standard
+ // deviation of r/2 is used, as per the HTML/CSS spec. At 3 standard deviations,
+ // the contribution drops to less than 0.005, i.e. less than half a percent,
+ // therefore the radius can be at least 1.33 before errors become significant.
+ // This filter is useful for smoothing artifacts caused by detail rendered
+ // at the pixel scale, e.g. single-pixel lines. Note that the filter should
+ // only be used with premultiplied pixel formats (or those without alpha).
+ // See the "line_thickness" example for a demonstration.
+ template<class PixFmt>
+ class slight_blur
+ {
+ public:
+ typedef typename PixFmt::pixel_type pixel_type;
+ typedef typename PixFmt::value_type value_type;
+ typedef typename PixFmt::order_type order_type;
+
+ slight_blur(double r = 1.33)
+ {
+ radius(r);
+ }
+
+ void radius(double r)
+ {
+ if (r > 0)
+ {
+ // Sample the gaussian curve at 0 and r/2 standard deviations.
+ // At 3 standard deviations, the response is < 0.005.
+ double pi = 3.14159;
+ double n = 2 / r;
+ m_g0 = 1 / sqrt(2 * pi);
+ m_g1 = m_g0 * exp(-n * n);
+
+ // Normalize.
+ double sum = m_g0 + 2 * m_g1;
+ m_g0 /= sum;
+ m_g1 /= sum;
+ }
+ else
+ {
+ m_g0 = 1;
+ m_g1 = 0;
+ }
+ }
+
+ void blur(PixFmt& img, rect_i bounds)
+ {
+ // Make sure we stay within the image area.
+ bounds.clip(rect_i(0, 0, img.width() - 1, img.height() - 1));
+
+ int w = bounds.x2 - bounds.x1 + 1;
+ int h = bounds.y2 - bounds.y1 + 1;
+
+ if (w < 3 || h < 3) return;
+
+ // Allocate 3 rows of buffer space.
+ m_buf.allocate(w * 3);
+
+ // Set up row pointers
+ pixel_type * begin = &m_buf[0];
+ pixel_type * r0 = begin;
+ pixel_type * r1 = r0 + w;
+ pixel_type * r2 = r1 + w;
+ pixel_type * end = r2 + w;
+
+ // Horizontally blur the first two input rows.
+ calc_row(img, bounds.x1, bounds.y1, w, r0);
+ memcpy(r1, r0, w * sizeof(pixel_type));
+
+ for (int y = 0; ; )
+ {
+ // Get pointer to first pixel.
+ pixel_type* p = img.pix_value_ptr(bounds.x1, bounds.y1 + y, bounds.x1 + w);
+
+ // Horizontally blur the row below.
+ if (y + 1 < h)
+ {
+ calc_row(img, bounds.x1, bounds.y1 + y + 1, w, r2);
+ }
+ else
+ {
+ memcpy(r2, r1, w * sizeof(pixel_type)); // duplicate bottom row
+ }
+
+ // Combine blurred rows into destination.
+ for (int x = 0; x < w; ++x)
+ {
+ calc_pixel(*r0++, *r1++, *r2++, *p++);
+ }
+
+ if (++y >= h) break;
+
+ // Wrap bottom row pointer around to top of buffer.
+ if (r2 == end) r2 = begin;
+ else if (r1 == end) r1 = begin;
+ else if (r0 == end) r0 = begin;
+ }
+ }
+
+ private:
+ void calc_row(PixFmt& img, int x, int y, int w, pixel_type* row)
+ {
+ const int wm = w - 1;
+
+ pixel_type* p = img.pix_value_ptr(x, y, w);
+
+ pixel_type c[3];
+ pixel_type* p0 = c;
+ pixel_type* p1 = c + 1;
+ pixel_type* p2 = c + 2;
+ pixel_type* end = c + 3;
+ *p0 = *p1 = *p;
+
+ for (int x = 0; x < wm; ++x)
+ {
+ *p2 = *(p = p->next());
+
+ calc_pixel(*p0++, *p1++, *p2++, *row++);
+
+ if (p0 == end) p0 = c;
+ else if (p1 == end) p1 = c;
+ else if (p2 == end) p2 = c;
+ }
+
+ calc_pixel(*p0, *p1, *p1, *row);
+ }
+
+ void calc_pixel(
+ pixel_type const & c1,
+ pixel_type const & c2,
+ pixel_type const & c3,
+ pixel_type & x)
+ {
+ calc_pixel(c1, c2, c3, x, PixFmt::pixfmt_category());
+ }
+
+ void calc_pixel(
+ pixel_type const & c1,
+ pixel_type const & c2,
+ pixel_type const & c3,
+ pixel_type & x,
+ pixfmt_gray_tag)
+ {
+ x.c[0] = calc_value(c1.c[0], c2.c[0], c3.c[0]);
+ }
+
+ void calc_pixel(
+ pixel_type const & c1,
+ pixel_type const & c2,
+ pixel_type const & c3,
+ pixel_type & x,
+ pixfmt_rgb_tag)
+ {
+ enum { R = order_type::R, G = order_type::G, B = order_type::B };
+ x.c[R] = calc_value(c1.c[R], c2.c[R], c3.c[R]);
+ x.c[G] = calc_value(c1.c[G], c2.c[G], c3.c[G]);
+ x.c[B] = calc_value(c1.c[B], c2.c[B], c3.c[B]);
+ }
+
+ void calc_pixel(
+ pixel_type const & c1,
+ pixel_type const & c2,
+ pixel_type const & c3,
+ pixel_type & x,
+ pixfmt_rgba_tag)
+ {
+ enum { R = order_type::R, G = order_type::G, B = order_type::B, A = order_type::A };
+ x.c[R] = calc_value(c1.c[R], c2.c[R], c3.c[R]);
+ x.c[G] = calc_value(c1.c[G], c2.c[G], c3.c[G]);
+ x.c[B] = calc_value(c1.c[B], c2.c[B], c3.c[B]);
+ x.c[A] = calc_value(c1.c[A], c2.c[A], c3.c[A]);
+ }
+
+ value_type calc_value(value_type v1, value_type v2, value_type v3)
+ {
+ return value_type(m_g1 * v1 + m_g0 * v2 + m_g1 * v3);
+ }
+
+ double m_g0, m_g1;
+ pod_vector<pixel_type> m_buf;
+ };
+
+ // Helper functions for applying blur to a surface without having to create an intermediate object.
+
+ template<class PixFmt>
+ void apply_slight_blur(PixFmt& img, const rect_i& bounds, double r = 1)
+ {
+ if (r > 0) slight_blur<PixFmt>(r).blur(img, bounds);
+ }
+
+ template<class PixFmt>
+ void apply_slight_blur(PixFmt& img, double r = 1)
+ {
+ if (r > 0) slight_blur<PixFmt>(r).blur(img, rect_i(0, 0, img.width() - 1, img.height() - 1));
+ }
+
+ template<class PixFmt>
+ void apply_slight_blur(renderer_base<PixFmt>& img, const rect_i& bounds, double r = 1)
+ {
+ if (r > 0) slight_blur<PixFmt>(r).blur(img.ren(), bounds);
+ }
+
+ template<class PixFmt>
+ void apply_slight_blur(renderer_base<PixFmt>& img, double r = 1)
+ {
+ if (r > 0) slight_blur<PixFmt>(r).blur(img.ren(), img.clip_box());
+ }
+}
+
+
+
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_bounding_rect.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_bounding_rect.h
new file mode 100644
index 0000000000..f13b863f0f
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_bounding_rect.h
@@ -0,0 +1,116 @@
+//----------------------------------------------------------------------------
+// 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
+//----------------------------------------------------------------------------
+//
+// bounding_rect function template
+//
+//----------------------------------------------------------------------------
+#ifndef AGG_BOUNDING_RECT_INCLUDED
+#define AGG_BOUNDING_RECT_INCLUDED
+
+#include "agg_basics.h"
+
+namespace agg
+{
+
+ //-----------------------------------------------------------bounding_rect
+ template<class VertexSource, class GetId, class CoordT>
+ bool bounding_rect(VertexSource& vs, GetId& gi,
+ unsigned start, unsigned num,
+ CoordT* x1, CoordT* y1, CoordT* x2, CoordT* y2)
+ {
+ unsigned i;
+ double x;
+ double y;
+ bool first = true;
+
+ *x1 = CoordT(1);
+ *y1 = CoordT(1);
+ *x2 = CoordT(0);
+ *y2 = CoordT(0);
+
+ for(i = 0; i < num; i++)
+ {
+ vs.rewind(gi[start + i]);
+ unsigned cmd;
+ while(!is_stop(cmd = vs.vertex(&x, &y)))
+ {
+ if(is_vertex(cmd))
+ {
+ if(first)
+ {
+ *x1 = CoordT(x);
+ *y1 = CoordT(y);
+ *x2 = CoordT(x);
+ *y2 = CoordT(y);
+ first = false;
+ }
+ else
+ {
+ if(CoordT(x) < *x1) *x1 = CoordT(x);
+ if(CoordT(y) < *y1) *y1 = CoordT(y);
+ if(CoordT(x) > *x2) *x2 = CoordT(x);
+ if(CoordT(y) > *y2) *y2 = CoordT(y);
+ }
+ }
+ }
+ }
+ return *x1 <= *x2 && *y1 <= *y2;
+ }
+
+
+ //-----------------------------------------------------bounding_rect_single
+ template<class VertexSource, class CoordT>
+ bool bounding_rect_single(VertexSource& vs, unsigned path_id,
+ CoordT* x1, CoordT* y1, CoordT* x2, CoordT* y2)
+ {
+ double x;
+ double y;
+ bool first = true;
+
+ *x1 = CoordT(1);
+ *y1 = CoordT(1);
+ *x2 = CoordT(0);
+ *y2 = CoordT(0);
+
+ vs.rewind(path_id);
+ unsigned cmd;
+ while(!is_stop(cmd = vs.vertex(&x, &y)))
+ {
+ if(is_vertex(cmd))
+ {
+ if(first)
+ {
+ *x1 = CoordT(x);
+ *y1 = CoordT(y);
+ *x2 = CoordT(x);
+ *y2 = CoordT(y);
+ first = false;
+ }
+ else
+ {
+ if(CoordT(x) < *x1) *x1 = CoordT(x);
+ if(CoordT(y) < *y1) *y1 = CoordT(y);
+ if(CoordT(x) > *x2) *x2 = CoordT(x);
+ if(CoordT(y) > *y2) *y2 = CoordT(y);
+ }
+ }
+ }
+ return *x1 <= *x2 && *y1 <= *y2;
+ }
+
+
+}
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_bspline.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_bspline.h
new file mode 100644
index 0000000000..2c1ed9a38c
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_bspline.h
@@ -0,0 +1,76 @@
+//----------------------------------------------------------------------------
+// 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
+//----------------------------------------------------------------------------
+//
+// class bspline
+//
+//----------------------------------------------------------------------------
+
+#ifndef AGG_BSPLINE_INCLUDED
+#define AGG_BSPLINE_INCLUDED
+
+#include "agg_array.h"
+
+namespace agg
+{
+ //----------------------------------------------------------------bspline
+ // A very simple class of Bi-cubic Spline interpolation.
+ // First call init(num, x[], y[]) where num - number of source points,
+ // x, y - arrays of X and Y values respectively. Here Y must be a function
+ // of X. It means that all the X-coordinates must be arranged in the ascending
+ // order.
+ // Then call get(x) that calculates a value Y for the respective X.
+ // The class supports extrapolation, i.e. you can call get(x) where x is
+ // outside the given with init() X-range. Extrapolation is a simple linear
+ // function.
+ //
+ // See Implementation agg_bspline.cpp
+ //------------------------------------------------------------------------
+ class bspline
+ {
+ public:
+ bspline();
+ bspline(int num);
+ bspline(int num, const double* x, const double* y);
+
+ void init(int num);
+ void add_point(double x, double y);
+ void prepare();
+
+ void init(int num, const double* x, const double* y);
+
+ double get(double x) const;
+ double get_stateful(double x) const;
+
+ private:
+ bspline(const bspline&);
+ const bspline& operator = (const bspline&);
+
+ static void bsearch(int n, const double *x, double x0, int *i);
+ double extrapolation_left(double x) const;
+ 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;
+ pod_array<double> m_am;
+ mutable int m_last_idx;
+ };
+
+
+}
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_bspline.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_bspline.h
new file mode 100644
index 0000000000..13d22d9297
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_bspline.h
@@ -0,0 +1,48 @@
+//----------------------------------------------------------------------------
+// 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_CONV_BSPLINE_INCLUDED
+#define AGG_CONV_BSPLINE_INCLUDED
+
+#include "agg_basics.h"
+#include "agg_vcgen_bspline.h"
+#include "agg_conv_adaptor_vcgen.h"
+
+
+namespace agg
+{
+
+ //---------------------------------------------------------conv_bspline
+ template<class VertexSource>
+ struct conv_bspline : public conv_adaptor_vcgen<VertexSource, vcgen_bspline>
+ {
+ typedef conv_adaptor_vcgen<VertexSource, vcgen_bspline> base_type;
+
+ conv_bspline(VertexSource& vs) :
+ conv_adaptor_vcgen<VertexSource, vcgen_bspline>(vs) {}
+
+ void interpolation_step(double v) { base_type::generator().interpolation_step(v); }
+ double interpolation_step() const { return base_type::generator().interpolation_step(); }
+
+ private:
+ conv_bspline(const conv_bspline<VertexSource>&);
+ const conv_bspline<VertexSource>&
+ operator = (const conv_bspline<VertexSource>&);
+ };
+
+}
+
+
+#endif
+
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_clip_polygon.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_clip_polygon.h
new file mode 100644
index 0000000000..87537638dc
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_clip_polygon.h
@@ -0,0 +1,63 @@
+//----------------------------------------------------------------------------
+// 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
+//----------------------------------------------------------------------------
+//
+// Polygon clipping converter
+// There an optimized Liang-Basky algorithm is used.
+// The algorithm doesn't optimize the degenerate edges, i.e. it will never
+// break a closed polygon into two or more ones, instead, there will be
+// degenerate edges coinciding with the respective clipping boundaries.
+// This is a sub-optimal solution, because that optimization would require
+// extra, rather expensive math while the rasterizer tolerates it quite well,
+// without any considerable overhead.
+//
+//----------------------------------------------------------------------------
+#ifndef AGG_CONV_CLIP_POLYGON_INCLUDED
+#define AGG_CONV_CLIP_POLYGON_INCLUDED
+
+#include "agg_basics.h"
+#include "agg_conv_adaptor_vpgen.h"
+#include "agg_vpgen_clip_polygon.h"
+
+namespace agg
+{
+
+ //=======================================================conv_clip_polygon
+ template<class VertexSource>
+ struct conv_clip_polygon : public conv_adaptor_vpgen<VertexSource, vpgen_clip_polygon>
+ {
+ typedef conv_adaptor_vpgen<VertexSource, vpgen_clip_polygon> base_type;
+
+ conv_clip_polygon(VertexSource& vs) :
+ conv_adaptor_vpgen<VertexSource, vpgen_clip_polygon>(vs) {}
+
+ void clip_box(double x1, double y1, double x2, double y2)
+ {
+ base_type::vpgen().clip_box(x1, y1, x2, y2);
+ }
+
+ double x1() const { return base_type::vpgen().x1(); }
+ double y1() const { return base_type::vpgen().y1(); }
+ double x2() const { return base_type::vpgen().x2(); }
+ double y2() const { return base_type::vpgen().y2(); }
+
+ private:
+ conv_clip_polygon(const conv_clip_polygon<VertexSource>&);
+ const conv_clip_polygon<VertexSource>&
+ operator = (const conv_clip_polygon<VertexSource>&);
+ };
+
+}
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_clip_polyline.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_clip_polyline.h
new file mode 100644
index 0000000000..f3fc2888c2
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_clip_polyline.h
@@ -0,0 +1,63 @@
+//----------------------------------------------------------------------------
+// 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
+//----------------------------------------------------------------------------
+//
+// polyline clipping converter
+// There an optimized Liang-Basky algorithm is used.
+// The algorithm doesn't optimize the degenerate edges, i.e. it will never
+// break a closed polyline into two or more ones, instead, there will be
+// degenerate edges coinciding with the respective clipping boundaries.
+// This is a sub-optimal solution, because that optimization would require
+// extra, rather expensive math while the rasterizer tolerates it quite well,
+// without any considerable overhead.
+//
+//----------------------------------------------------------------------------
+#ifndef AGG_CONV_CLIP_polyline_INCLUDED
+#define AGG_CONV_CLIP_polyline_INCLUDED
+
+#include "agg_basics.h"
+#include "agg_conv_adaptor_vpgen.h"
+#include "agg_vpgen_clip_polyline.h"
+
+namespace agg
+{
+
+ //=======================================================conv_clip_polyline
+ template<class VertexSource>
+ struct conv_clip_polyline : public conv_adaptor_vpgen<VertexSource, vpgen_clip_polyline>
+ {
+ typedef conv_adaptor_vpgen<VertexSource, vpgen_clip_polyline> base_type;
+
+ conv_clip_polyline(VertexSource& vs) :
+ conv_adaptor_vpgen<VertexSource, vpgen_clip_polyline>(vs) {}
+
+ void clip_box(double x1, double y1, double x2, double y2)
+ {
+ base_type::vpgen().clip_box(x1, y1, x2, y2);
+ }
+
+ double x1() const { return base_type::vpgen().x1(); }
+ double y1() const { return base_type::vpgen().y1(); }
+ double x2() const { return base_type::vpgen().x2(); }
+ double y2() const { return base_type::vpgen().y2(); }
+
+ private:
+ conv_clip_polyline(const conv_clip_polyline<VertexSource>&);
+ const conv_clip_polyline<VertexSource>&
+ operator = (const conv_clip_polyline<VertexSource>&);
+ };
+
+}
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_close_polygon.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_close_polygon.h
new file mode 100644
index 0000000000..c46594fdfb
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_close_polygon.h
@@ -0,0 +1,125 @@
+//----------------------------------------------------------------------------
+// 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_CONV_CLOSE_POLYGON_INCLUDED
+#define AGG_CONV_CLOSE_POLYGON_INCLUDED
+
+#include "agg_basics.h"
+
+namespace agg
+{
+
+ //======================================================conv_close_polygon
+ template<class VertexSource> class conv_close_polygon
+ {
+ public:
+ 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);
+
+ private:
+ conv_close_polygon(const conv_close_polygon<VertexSource>&);
+ const conv_close_polygon<VertexSource>&
+ operator = (const conv_close_polygon<VertexSource>&);
+
+ VertexSource* m_source;
+ unsigned m_cmd[2];
+ double m_x[2];
+ double m_y[2];
+ unsigned m_vertex;
+ bool m_line_to;
+ };
+
+
+
+ //------------------------------------------------------------------------
+ template<class VertexSource>
+ void conv_close_polygon<VertexSource>::rewind(unsigned path_id)
+ {
+ m_source->rewind(path_id);
+ m_vertex = 2;
+ m_line_to = false;
+ }
+
+
+
+ //------------------------------------------------------------------------
+ template<class VertexSource>
+ unsigned conv_close_polygon<VertexSource>::vertex(double* x, double* y)
+ {
+ unsigned cmd = path_cmd_stop;
+ for(;;)
+ {
+ if(m_vertex < 2)
+ {
+ *x = m_x[m_vertex];
+ *y = m_y[m_vertex];
+ cmd = m_cmd[m_vertex];
+ ++m_vertex;
+ break;
+ }
+
+ cmd = m_source->vertex(x, y);
+
+ if(is_end_poly(cmd))
+ {
+ cmd |= path_flags_close;
+ break;
+ }
+
+ if(is_stop(cmd))
+ {
+ if(m_line_to)
+ {
+ m_cmd[0] = path_cmd_end_poly | path_flags_close;
+ m_cmd[1] = path_cmd_stop;
+ m_vertex = 0;
+ m_line_to = false;
+ continue;
+ }
+ break;
+ }
+
+ if(is_move_to(cmd))
+ {
+ if(m_line_to)
+ {
+ m_x[0] = 0.0;
+ m_y[0] = 0.0;
+ m_cmd[0] = path_cmd_end_poly | path_flags_close;
+ m_x[1] = *x;
+ m_y[1] = *y;
+ m_cmd[1] = cmd;
+ m_vertex = 0;
+ m_line_to = false;
+ continue;
+ }
+ break;
+ }
+
+ if(is_vertex(cmd))
+ {
+ m_line_to = true;
+ break;
+ }
+ }
+ return cmd;
+ }
+
+}
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_concat.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_concat.h
new file mode 100644
index 0000000000..745d349c6f
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_concat.h
@@ -0,0 +1,73 @@
+//----------------------------------------------------------------------------
+// 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_CONV_CONCAT_INCLUDED
+#define AGG_CONV_CONCAT_INCLUDED
+
+#include "agg_basics.h"
+
+namespace agg
+{
+ //=============================================================conv_concat
+ // Concatenation of two paths. Usually used to combine lines or curves
+ // with markers such as arrowheads
+ template<class VS1, class VS2> class conv_concat
+ {
+ 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 rewind(unsigned path_id)
+ {
+ m_source1->rewind(path_id);
+ m_source2->rewind(0);
+ m_status = 0;
+ }
+
+ unsigned vertex(double* x, double* y)
+ {
+ unsigned cmd;
+ if(m_status == 0)
+ {
+ cmd = m_source1->vertex(x, y);
+ if(!is_stop(cmd)) return cmd;
+ m_status = 1;
+ }
+ if(m_status == 1)
+ {
+ cmd = m_source2->vertex(x, y);
+ if(!is_stop(cmd)) return cmd;
+ m_status = 2;
+ }
+ return path_cmd_stop;
+ }
+
+ private:
+ conv_concat(const conv_concat<VS1, VS2>&);
+ const conv_concat<VS1, VS2>&
+ operator = (const conv_concat<VS1, VS2>&);
+
+ VS1* m_source1;
+ VS2* m_source2;
+ int m_status;
+
+ };
+}
+
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_gpc.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_gpc.h
new file mode 100644
index 0000000000..2acada342d
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_gpc.h
@@ -0,0 +1,432 @@
+//----------------------------------------------------------------------------
+// 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
+//----------------------------------------------------------------------------
+//
+// General Polygon Clipper based on the GPC library by Alan Murta
+// Union, Intersection, XOR, A-B, B-A
+// Contact the author if you intend to use it in commercial applications!
+// http://www.cs.man.ac.uk/aig/staff/alan/software/
+// Alan Murta (email: gpc@cs.man.ac.uk)
+//
+//----------------------------------------------------------------------------
+
+#ifndef AGG_CONV_GPC_INCLUDED
+#define AGG_CONV_GPC_INCLUDED
+
+#include <math.h>
+#include "agg_basics.h"
+#include "agg_array.h"
+
+extern "C"
+{
+#include "gpc.h"
+}
+
+namespace agg
+{
+ enum gpc_op_e
+ {
+ gpc_or,
+ gpc_and,
+ gpc_xor,
+ gpc_a_minus_b,
+ gpc_b_minus_a
+ };
+
+
+ //================================================================conv_gpc
+ template<class VSA, class VSB> class conv_gpc
+ {
+ enum status
+ {
+ status_move_to,
+ status_line_to,
+ status_stop
+ };
+
+ struct contour_header_type
+ {
+ int num_vertices;
+ int hole_flag;
+ gpc_vertex* vertices;
+ };
+
+ typedef pod_bvector<gpc_vertex, 8> vertex_array_type;
+ typedef pod_bvector<contour_header_type, 6> contour_header_array_type;
+
+
+ public:
+ typedef VSA source_a_type;
+ typedef VSB source_b_type;
+ typedef conv_gpc<source_a_type, source_b_type> self_type;
+
+ ~conv_gpc()
+ {
+ free_gpc_data();
+ }
+
+ conv_gpc(source_a_type& a, source_b_type& b, gpc_op_e op = gpc_or) :
+ m_src_a(&a),
+ m_src_b(&b),
+ m_status(status_move_to),
+ m_vertex(-1),
+ m_contour(-1),
+ m_operation(op)
+ {
+ memset(&m_poly_a, 0, sizeof(m_poly_a));
+ memset(&m_poly_b, 0, sizeof(m_poly_b));
+ memset(&m_result, 0, sizeof(m_result));
+ }
+
+ 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 path_id);
+ unsigned vertex(double* x, double* y);
+
+ private:
+ conv_gpc(const conv_gpc<VSA, VSB>&);
+ const conv_gpc<VSA, VSB>& operator = (const conv_gpc<VSA, VSB>&);
+
+ //--------------------------------------------------------------------
+ void free_polygon(gpc_polygon& p);
+ void free_result();
+ void free_gpc_data();
+ void start_contour();
+ void add_vertex(double x, double y);
+ void end_contour(unsigned orientation);
+ void make_polygon(gpc_polygon& p);
+ void start_extracting();
+ bool next_contour();
+ bool next_vertex(double* x, double* y);
+
+
+ //--------------------------------------------------------------------
+ template<class VS> void add(VS& src, gpc_polygon& p)
+ {
+ unsigned cmd;
+ double x, y;
+ double start_x = 0.0;
+ double start_y = 0.0;
+ bool line_to = false;
+ unsigned orientation = 0;
+
+ m_contour_accumulator.remove_all();
+
+ while(!is_stop(cmd = src.vertex(&x, &y)))
+ {
+ if(is_vertex(cmd))
+ {
+ if(is_move_to(cmd))
+ {
+ if(line_to)
+ {
+ end_contour(orientation);
+ orientation = 0;
+ }
+ start_contour();
+ start_x = x;
+ start_y = y;
+ }
+ add_vertex(x, y);
+ line_to = true;
+ }
+ else
+ {
+ if(is_end_poly(cmd))
+ {
+ orientation = get_orientation(cmd);
+ if(line_to && is_closed(cmd))
+ {
+ add_vertex(start_x, start_y);
+ }
+ }
+ }
+ }
+ if(line_to)
+ {
+ end_contour(orientation);
+ }
+ make_polygon(p);
+ }
+
+
+ private:
+ //--------------------------------------------------------------------
+ source_a_type* m_src_a;
+ source_b_type* m_src_b;
+ status m_status;
+ int m_vertex;
+ int m_contour;
+ gpc_op_e m_operation;
+ vertex_array_type m_vertex_accumulator;
+ contour_header_array_type m_contour_accumulator;
+ gpc_polygon m_poly_a;
+ gpc_polygon m_poly_b;
+ gpc_polygon m_result;
+ };
+
+
+
+
+
+ //------------------------------------------------------------------------
+ template<class VSA, class VSB>
+ void conv_gpc<VSA, VSB>::free_polygon(gpc_polygon& p)
+ {
+ int i;
+ for(i = 0; i < p.num_contours; i++)
+ {
+ pod_allocator<gpc_vertex>::deallocate(p.contour[i].vertex,
+ p.contour[i].num_vertices);
+ }
+ pod_allocator<gpc_vertex_list>::deallocate(p.contour, p.num_contours);
+ memset(&p, 0, sizeof(gpc_polygon));
+ }
+
+
+ //------------------------------------------------------------------------
+ template<class VSA, class VSB>
+ void conv_gpc<VSA, VSB>::free_result()
+ {
+ if(m_result.contour)
+ {
+ gpc_free_polygon(&m_result);
+ }
+ memset(&m_result, 0, sizeof(m_result));
+ }
+
+
+ //------------------------------------------------------------------------
+ template<class VSA, class VSB>
+ void conv_gpc<VSA, VSB>::free_gpc_data()
+ {
+ free_polygon(m_poly_a);
+ free_polygon(m_poly_b);
+ free_result();
+ }
+
+
+ //------------------------------------------------------------------------
+ template<class VSA, class VSB>
+ void conv_gpc<VSA, VSB>::start_contour()
+ {
+ contour_header_type h;
+ memset(&h, 0, sizeof(h));
+ m_contour_accumulator.add(h);
+ m_vertex_accumulator.remove_all();
+ }
+
+
+ //------------------------------------------------------------------------
+ template<class VSA, class VSB>
+ inline void conv_gpc<VSA, VSB>::add_vertex(double x, double y)
+ {
+ gpc_vertex v;
+ v.x = x;
+ v.y = y;
+ m_vertex_accumulator.add(v);
+ }
+
+
+ //------------------------------------------------------------------------
+ template<class VSA, class VSB>
+ void conv_gpc<VSA, VSB>::end_contour(unsigned orientation)
+ {
+ if(m_contour_accumulator.size())
+ {
+ if(m_vertex_accumulator.size() > 2)
+ {
+ contour_header_type& h =
+ m_contour_accumulator[m_contour_accumulator.size() - 1];
+
+ h.num_vertices = m_vertex_accumulator.size();
+ h.hole_flag = 0;
+
+ // TO DO: Clarify the "holes"
+ //if(is_cw(orientation)) h.hole_flag = 1;
+
+ 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++)
+ {
+ const gpc_vertex& s = m_vertex_accumulator[i];
+ d->x = s.x;
+ d->y = s.y;
+ ++d;
+ }
+ }
+ else
+ {
+ m_vertex_accumulator.remove_last();
+ }
+ }
+ }
+
+
+ //------------------------------------------------------------------------
+ template<class VSA, class VSB>
+ void conv_gpc<VSA, VSB>::make_polygon(gpc_polygon& p)
+ {
+ free_polygon(p);
+ if(m_contour_accumulator.size())
+ {
+ p.num_contours = m_contour_accumulator.size();
+
+ p.hole = 0;
+ p.contour = pod_allocator<gpc_vertex_list>::allocate(p.num_contours);
+
+ int i;
+ gpc_vertex_list* pv = p.contour;
+ for(i = 0; i < p.num_contours; i++)
+ {
+ const contour_header_type& h = m_contour_accumulator[i];
+ pv->num_vertices = h.num_vertices;
+ pv->vertex = h.vertices;
+ ++pv;
+ }
+ }
+ }
+
+
+ //------------------------------------------------------------------------
+ template<class VSA, class VSB>
+ void conv_gpc<VSA, VSB>::start_extracting()
+ {
+ m_status = status_move_to;
+ m_contour = -1;
+ m_vertex = -1;
+ }
+
+
+ //------------------------------------------------------------------------
+ template<class VSA, class VSB>
+ bool conv_gpc<VSA, VSB>::next_contour()
+ {
+ if(++m_contour < m_result.num_contours)
+ {
+ m_vertex = -1;
+ return true;
+ }
+ return false;
+ }
+
+
+ //------------------------------------------------------------------------
+ template<class VSA, class VSB>
+ inline bool conv_gpc<VSA, VSB>::next_vertex(double* x, double* y)
+ {
+ const gpc_vertex_list& vlist = m_result.contour[m_contour];
+ if(++m_vertex < vlist.num_vertices)
+ {
+ const gpc_vertex& v = vlist.vertex[m_vertex];
+ *x = v.x;
+ *y = v.y;
+ return true;
+ }
+ return false;
+ }
+
+
+ //------------------------------------------------------------------------
+ template<class VSA, class VSB>
+ void conv_gpc<VSA, VSB>::rewind(unsigned path_id)
+ {
+ free_result();
+ 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)
+ {
+ case gpc_or:
+ gpc_polygon_clip(GPC_UNION,
+ &m_poly_a,
+ &m_poly_b,
+ &m_result);
+ break;
+
+ case gpc_and:
+ gpc_polygon_clip(GPC_INT,
+ &m_poly_a,
+ &m_poly_b,
+ &m_result);
+ break;
+
+ case gpc_xor:
+ gpc_polygon_clip(GPC_XOR,
+ &m_poly_a,
+ &m_poly_b,
+ &m_result);
+ break;
+
+ case gpc_a_minus_b:
+ gpc_polygon_clip(GPC_DIFF,
+ &m_poly_a,
+ &m_poly_b,
+ &m_result);
+ break;
+
+ case gpc_b_minus_a:
+ gpc_polygon_clip(GPC_DIFF,
+ &m_poly_b,
+ &m_poly_a,
+ &m_result);
+ break;
+ }
+ start_extracting();
+ }
+
+
+ //------------------------------------------------------------------------
+ template<class VSA, class VSB>
+ unsigned conv_gpc<VSA, VSB>::vertex(double* x, double* y)
+ {
+ if(m_status == status_move_to)
+ {
+ if(next_contour())
+ {
+ if(next_vertex(x, y))
+ {
+ m_status = status_line_to;
+ return path_cmd_move_to;
+ }
+ m_status = status_stop;
+ return path_cmd_end_poly | path_flags_close;
+ }
+ }
+ else
+ {
+ if(next_vertex(x, y))
+ {
+ return path_cmd_line_to;
+ }
+ else
+ {
+ m_status = status_move_to;
+ }
+ return path_cmd_end_poly | path_flags_close;
+ }
+ return path_cmd_stop;
+ }
+
+
+}
+
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_marker.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_marker.h
new file mode 100644
index 0000000000..2cd3cb403f
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_marker.h
@@ -0,0 +1,148 @@
+//----------------------------------------------------------------------------
+// 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
+//----------------------------------------------------------------------------
+//
+// conv_marker
+//
+//----------------------------------------------------------------------------
+#ifndef AGG_CONV_MARKER_INCLUDED
+#define AGG_CONV_MARKER_INCLUDED
+
+#include "agg_basics.h"
+#include "agg_trans_affine.h"
+
+namespace agg
+{
+ //-------------------------------------------------------------conv_marker
+ template<class MarkerLocator, class MarkerShapes>
+ class conv_marker
+ {
+ public:
+ conv_marker(MarkerLocator& ml, MarkerShapes& ms);
+
+ trans_affine& transform() { return m_transform; }
+ const trans_affine& transform() const { return m_transform; }
+
+ void rewind(unsigned path_id);
+ unsigned vertex(double* x, double* y);
+
+ private:
+ conv_marker(const conv_marker<MarkerLocator, MarkerShapes>&);
+ const conv_marker<MarkerLocator, MarkerShapes>&
+ operator = (const conv_marker<MarkerLocator, MarkerShapes>&);
+
+ enum status_e
+ {
+ initial,
+ markers,
+ polygon,
+ stop
+ };
+
+ MarkerLocator* m_marker_locator;
+ MarkerShapes* m_marker_shapes;
+ trans_affine m_transform;
+ trans_affine m_mtx;
+ status_e m_status;
+ unsigned m_marker;
+ unsigned m_num_markers;
+ };
+
+
+ //------------------------------------------------------------------------
+ template<class MarkerLocator, class MarkerShapes>
+ conv_marker<MarkerLocator, MarkerShapes>::conv_marker(MarkerLocator& ml, MarkerShapes& ms) :
+ m_marker_locator(&ml),
+ m_marker_shapes(&ms),
+ m_status(initial),
+ m_marker(0),
+ m_num_markers(1)
+ {
+ }
+
+
+ //------------------------------------------------------------------------
+ template<class MarkerLocator, class MarkerShapes>
+ void conv_marker<MarkerLocator, MarkerShapes>::rewind(unsigned)
+ {
+ m_status = initial;
+ m_marker = 0;
+ m_num_markers = 1;
+ }
+
+
+ //------------------------------------------------------------------------
+ template<class MarkerLocator, class MarkerShapes>
+ unsigned conv_marker<MarkerLocator, MarkerShapes>::vertex(double* x, double* y)
+ {
+ unsigned cmd = path_cmd_move_to;
+ double x1, y1, x2, y2;
+
+ while(!is_stop(cmd))
+ {
+ switch(m_status)
+ {
+ case initial:
+ if(m_num_markers == 0)
+ {
+ cmd = path_cmd_stop;
+ break;
+ }
+ m_marker_locator->rewind(m_marker);
+ ++m_marker;
+ m_num_markers = 0;
+ m_status = markers;
+
+ case markers:
+ if(is_stop(m_marker_locator->vertex(&x1, &y1)))
+ {
+ m_status = initial;
+ break;
+ }
+ if(is_stop(m_marker_locator->vertex(&x2, &y2)))
+ {
+ m_status = initial;
+ break;
+ }
+ ++m_num_markers;
+ m_mtx = m_transform;
+ m_mtx *= trans_affine_rotation(atan2(y2 - y1, x2 - x1));
+ m_mtx *= trans_affine_translation(x1, y1);
+ m_marker_shapes->rewind(m_marker - 1);
+ m_status = polygon;
+
+ case polygon:
+ cmd = m_marker_shapes->vertex(x, y);
+ if(is_stop(cmd))
+ {
+ cmd = path_cmd_move_to;
+ m_status = markers;
+ break;
+ }
+ m_mtx.transform(x, y);
+ return cmd;
+
+ case stop:
+ cmd = path_cmd_stop;
+ break;
+ }
+ }
+ return cmd;
+ }
+
+}
+
+
+#endif
+
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_marker_adaptor.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_marker_adaptor.h
new file mode 100644
index 0000000000..4486d6ace9
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_marker_adaptor.h
@@ -0,0 +1,51 @@
+//----------------------------------------------------------------------------
+// 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_CONV_MARKER_ADAPTOR_INCLUDED
+#define AGG_CONV_MARKER_ADAPTOR_INCLUDED
+
+#include "agg_basics.h"
+#include "agg_conv_adaptor_vcgen.h"
+#include "agg_vcgen_vertex_sequence.h"
+
+namespace agg
+{
+
+ //=====================================================conv_marker_adaptor
+ template<class VertexSource, class Markers=null_markers>
+ struct conv_marker_adaptor :
+ public conv_adaptor_vcgen<VertexSource, vcgen_vertex_sequence, Markers>
+ {
+ typedef Markers marker_type;
+ typedef conv_adaptor_vcgen<VertexSource, vcgen_vertex_sequence, Markers> base_type;
+
+ conv_marker_adaptor(VertexSource& vs) :
+ conv_adaptor_vcgen<VertexSource, vcgen_vertex_sequence, Markers>(vs)
+ {
+ }
+
+ void shorten(double s) { base_type::generator().shorten(s); }
+ double shorten() const { return base_type::generator().shorten(); }
+
+ private:
+ conv_marker_adaptor(const conv_marker_adaptor<VertexSource, Markers>&);
+ const conv_marker_adaptor<VertexSource, Markers>&
+ operator = (const conv_marker_adaptor<VertexSource, Markers>&);
+ };
+
+
+}
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_shorten_path.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_shorten_path.h
new file mode 100644
index 0000000000..5617e51d17
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_shorten_path.h
@@ -0,0 +1,50 @@
+//----------------------------------------------------------------------------
+// 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_CONV_SHORTEN_PATH_INCLUDED
+#define AGG_CONV_SHORTEN_PATH_INCLUDED
+
+#include "agg_basics.h"
+#include "agg_conv_adaptor_vcgen.h"
+#include "agg_vcgen_vertex_sequence.h"
+
+namespace agg
+{
+
+ //=======================================================conv_shorten_path
+ template<class VertexSource> class conv_shorten_path :
+ public conv_adaptor_vcgen<VertexSource, vcgen_vertex_sequence>
+ {
+ public:
+ typedef conv_adaptor_vcgen<VertexSource, vcgen_vertex_sequence> base_type;
+
+ conv_shorten_path(VertexSource& vs) :
+ conv_adaptor_vcgen<VertexSource, vcgen_vertex_sequence>(vs)
+ {
+ }
+
+ void shorten(double s) { base_type::generator().shorten(s); }
+ double shorten() const { return base_type::generator().shorten(); }
+
+ private:
+ conv_shorten_path(const conv_shorten_path<VertexSource>&);
+ const conv_shorten_path<VertexSource>&
+ operator = (const conv_shorten_path<VertexSource>&);
+ };
+
+
+}
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_smooth_poly1.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_smooth_poly1.h
new file mode 100644
index 0000000000..4ac4e3d6e2
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_smooth_poly1.h
@@ -0,0 +1,80 @@
+//----------------------------------------------------------------------------
+// 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
+//----------------------------------------------------------------------------
+//
+// Smooth polygon generator
+//
+//----------------------------------------------------------------------------
+#ifndef AGG_CONV_SMOOTH_POLY1_INCLUDED
+#define AGG_CONV_SMOOTH_POLY1_INCLUDED
+
+#include "agg_basics.h"
+#include "agg_vcgen_smooth_poly1.h"
+#include "agg_conv_adaptor_vcgen.h"
+#include "agg_conv_curve.h"
+
+
+namespace agg
+{
+
+ //-------------------------------------------------------conv_smooth_poly1
+ template<class VertexSource>
+ struct conv_smooth_poly1 :
+ public conv_adaptor_vcgen<VertexSource, vcgen_smooth_poly1>
+ {
+ typedef conv_adaptor_vcgen<VertexSource, vcgen_smooth_poly1> base_type;
+
+ conv_smooth_poly1(VertexSource& vs) :
+ conv_adaptor_vcgen<VertexSource, vcgen_smooth_poly1>(vs)
+ {
+ }
+
+ void smooth_value(double v) { base_type::generator().smooth_value(v); }
+ double smooth_value() const { return base_type::generator().smooth_value(); }
+
+ private:
+ conv_smooth_poly1(const conv_smooth_poly1<VertexSource>&);
+ const conv_smooth_poly1<VertexSource>&
+ operator = (const conv_smooth_poly1<VertexSource>&);
+ };
+
+
+
+ //-------------------------------------------------conv_smooth_poly1_curve
+ template<class VertexSource>
+ struct conv_smooth_poly1_curve :
+ public conv_curve<conv_smooth_poly1<VertexSource> >
+ {
+ conv_smooth_poly1_curve(VertexSource& vs) :
+ conv_curve<conv_smooth_poly1<VertexSource> >(m_smooth),
+ m_smooth(vs)
+ {
+ }
+
+ void smooth_value(double v) { m_smooth.generator().smooth_value(v); }
+ double smooth_value() const { return m_smooth.generator().smooth_value(); }
+
+ private:
+ conv_smooth_poly1_curve(const conv_smooth_poly1_curve<VertexSource>&);
+ const conv_smooth_poly1_curve<VertexSource>&
+ operator = (const conv_smooth_poly1_curve<VertexSource>&);
+
+ conv_smooth_poly1<VertexSource> m_smooth;
+ };
+
+}
+
+
+#endif
+
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_unclose_polygon.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_unclose_polygon.h
new file mode 100644
index 0000000000..fe5c263810
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_unclose_polygon.h
@@ -0,0 +1,52 @@
+//----------------------------------------------------------------------------
+// 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_CONV_UNCLOSE_POLYGON_INCLUDED
+#define AGG_CONV_UNCLOSE_POLYGON_INCLUDED
+
+#include "agg_basics.h"
+
+namespace agg
+{
+ //====================================================conv_unclose_polygon
+ template<class VertexSource> class conv_unclose_polygon
+ {
+ public:
+ explicit conv_unclose_polygon(VertexSource& vs) : m_source(&vs) {}
+ void attach(VertexSource& source) { m_source = &source; }
+
+ void rewind(unsigned path_id)
+ {
+ m_source->rewind(path_id);
+ }
+
+ unsigned vertex(double* x, double* y)
+ {
+ unsigned cmd = m_source->vertex(x, y);
+ if(is_end_poly(cmd)) cmd &= ~path_flags_close;
+ return cmd;
+ }
+
+ private:
+ conv_unclose_polygon(const conv_unclose_polygon<VertexSource>&);
+ const conv_unclose_polygon<VertexSource>&
+ operator = (const conv_unclose_polygon<VertexSource>&);
+
+ VertexSource* m_source;
+ };
+
+}
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_ellipse.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_ellipse.h
new file mode 100644
index 0000000000..e78ce27dd9
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_ellipse.h
@@ -0,0 +1,123 @@
+//----------------------------------------------------------------------------
+// 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
+//----------------------------------------------------------------------------
+//
+// class ellipse
+//
+//----------------------------------------------------------------------------
+
+#ifndef AGG_ELLIPSE_INCLUDED
+#define AGG_ELLIPSE_INCLUDED
+
+#include "agg_basics.h"
+#include <math.h>
+
+namespace agg
+{
+
+ //----------------------------------------------------------------ellipse
+ class ellipse
+ {
+ public:
+ 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 approximation_scale(double scale);
+ 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, bool cw)
+ {
+ m_x = x;
+ m_y = y;
+ m_rx = rx;
+ 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_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);
+ }
+
+ //------------------------------------------------------------------------
+ inline void ellipse::rewind(unsigned)
+ {
+ m_step = 0;
+ }
+
+ //------------------------------------------------------------------------
+ inline unsigned ellipse::vertex(double* x, double* y)
+ {
+ if(m_step == m_num)
+ {
+ ++m_step;
+ return path_cmd_end_poly | path_flags_close | path_flags_ccw;
+ }
+ 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++;
+ return ((m_step == 1) ? path_cmd_move_to : path_cmd_line_to);
+ }
+
+}
+
+
+
+#endif
+
+
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_ellipse_bresenham.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_ellipse_bresenham.h
new file mode 100644
index 0000000000..ee3b9c4638
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_ellipse_bresenham.h
@@ -0,0 +1,113 @@
+//----------------------------------------------------------------------------
+// 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
+//----------------------------------------------------------------------------
+//
+// Simple Bresenham interpolator for ellipsees
+//
+//----------------------------------------------------------------------------
+
+#ifndef AGG_ELLIPSE_BRESENHAM_INCLUDED
+#define AGG_ELLIPSE_BRESENHAM_INCLUDED
+
+
+#include "agg_basics.h"
+
+
+namespace agg
+{
+
+ //------------------------------------------ellipse_bresenham_interpolator
+ class ellipse_bresenham_interpolator
+ {
+ public:
+ ellipse_bresenham_interpolator(int rx, int ry) :
+ m_rx2(rx * rx),
+ m_ry2(ry * ry),
+ m_two_rx2(m_rx2 << 1),
+ m_two_ry2(m_ry2 << 1),
+ m_dx(0),
+ m_dy(0),
+ m_inc_x(0),
+ m_inc_y(-ry * m_two_rx2),
+ m_cur_f(0)
+ {}
+
+ int dx() const { return m_dx; }
+ int dy() const { return m_dy; }
+
+ void operator++ ()
+ {
+ int mx, my, mxy, min_m;
+ int fx, fy, fxy;
+
+ mx = fx = m_cur_f + m_inc_x + m_ry2;
+ if(mx < 0) mx = -mx;
+
+ my = fy = m_cur_f + m_inc_y + m_rx2;
+ if(my < 0) my = -my;
+
+ mxy = fxy = m_cur_f + m_inc_x + m_ry2 + m_inc_y + m_rx2;
+ if(mxy < 0) mxy = -mxy;
+
+ min_m = mx;
+ bool flag = true;
+
+ if(min_m > my)
+ {
+ min_m = my;
+ flag = false;
+ }
+
+ m_dx = m_dy = 0;
+
+ if(min_m > mxy)
+ {
+ m_inc_x += m_two_ry2;
+ m_inc_y += m_two_rx2;
+ m_cur_f = fxy;
+ m_dx = 1;
+ m_dy = 1;
+ return;
+ }
+
+ if(flag)
+ {
+ m_inc_x += m_two_ry2;
+ m_cur_f = fx;
+ m_dx = 1;
+ return;
+ }
+
+ m_inc_y += m_two_rx2;
+ m_cur_f = fy;
+ m_dy = 1;
+ }
+
+ private:
+ int m_rx2;
+ int m_ry2;
+ int m_two_rx2;
+ int m_two_ry2;
+ int m_dx;
+ int m_dy;
+ int m_inc_x;
+ int m_inc_y;
+ int m_cur_f;
+
+ };
+
+}
+
+#endif
+
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_embedded_raster_fonts.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_embedded_raster_fonts.h
new file mode 100644
index 0000000000..9d522d671c
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_embedded_raster_fonts.h
@@ -0,0 +1,59 @@
+//----------------------------------------------------------------------------
+// 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_EMBEDDED_RASTER_FONTS_INCLUDED
+#define AGG_EMBEDDED_RASTER_FONTS_INCLUDED
+
+#include "agg_basics.h"
+
+namespace agg
+{
+ extern const int8u gse4x6[];
+ extern const int8u gse4x8[];
+ extern const int8u gse5x7[];
+ extern const int8u gse5x9[];
+ extern const int8u gse6x12[];
+ extern const int8u gse6x9[];
+ extern const int8u gse7x11[];
+ extern const int8u gse7x11_bold[];
+ extern const int8u gse7x15[];
+ extern const int8u gse7x15_bold[];
+ extern const int8u gse8x16[];
+ extern const int8u gse8x16_bold[];
+ extern const int8u mcs11_prop[];
+ extern const int8u mcs11_prop_condensed[];
+ extern const int8u mcs12_prop[];
+ extern const int8u mcs13_prop[];
+ extern const int8u mcs5x10_mono[];
+ extern const int8u mcs5x11_mono[];
+ extern const int8u mcs6x10_mono[];
+ extern const int8u mcs6x11_mono[];
+ extern const int8u mcs7x12_mono_high[];
+ extern const int8u mcs7x12_mono_low[];
+ extern const int8u verdana12[];
+ extern const int8u verdana12_bold[];
+ extern const int8u verdana13[];
+ extern const int8u verdana13_bold[];
+ extern const int8u verdana14[];
+ extern const int8u verdana14_bold[];
+ extern const int8u verdana16[];
+ extern const int8u verdana16_bold[];
+ extern const int8u verdana17[];
+ extern const int8u verdana17_bold[];
+ extern const int8u verdana18[];
+ extern const int8u verdana18_bold[];
+}
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_font_cache_manager.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_font_cache_manager.h
new file mode 100644
index 0000000000..fe9a9280fa
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_font_cache_manager.h
@@ -0,0 +1,409 @@
+//----------------------------------------------------------------------------
+// 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_FONT_CACHE_MANAGER_INCLUDED
+#define AGG_FONT_CACHE_MANAGER_INCLUDED
+
+#include <string.h>
+#include "agg_array.h"
+
+namespace agg
+{
+
+ //---------------------------------------------------------glyph_data_type
+ enum glyph_data_type
+ {
+ glyph_data_invalid = 0,
+ glyph_data_mono = 1,
+ glyph_data_gray8 = 2,
+ glyph_data_outline = 3
+ };
+
+
+ //-------------------------------------------------------------glyph_cache
+ struct glyph_cache
+ {
+ unsigned glyph_index;
+ int8u* data;
+ unsigned data_size;
+ glyph_data_type data_type;
+ rect_i bounds;
+ double advance_x;
+ double advance_y;
+ };
+
+
+ //--------------------------------------------------------------font_cache
+ class font_cache
+ {
+ public:
+ enum block_size_e { block_size = 16384-16 };
+
+ //--------------------------------------------------------------------
+ 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);
+ memset(m_glyphs, 0, sizeof(m_glyphs));
+ }
+
+ //--------------------------------------------------------------------
+ bool font_is(const char* font_signature) const
+ {
+ return strcmp(font_signature, m_font_signature) == 0;
+ }
+
+ //--------------------------------------------------------------------
+ const glyph_cache* find_glyph(unsigned glyph_code) const
+ {
+ unsigned msb = (glyph_code >> 8) & 0xFF;
+ if(m_glyphs[msb])
+ {
+ return m_glyphs[msb][glyph_code & 0xFF];
+ }
+ return 0;
+ }
+
+ //--------------------------------------------------------------------
+ glyph_cache* cache_glyph(unsigned glyph_code,
+ unsigned glyph_index,
+ unsigned data_size,
+ glyph_data_type data_type,
+ const rect_i& bounds,
+ double advance_x,
+ double advance_y)
+ {
+ unsigned msb = (glyph_code >> 8) & 0xFF;
+ if(m_glyphs[msb] == 0)
+ {
+ m_glyphs[msb] =
+ (glyph_cache**)m_allocator.allocate(sizeof(glyph_cache*) * 256,
+ sizeof(glyph_cache*));
+ memset(m_glyphs[msb], 0, sizeof(glyph_cache*) * 256);
+ }
+
+ unsigned lsb = glyph_code & 0xFF;
+ if(m_glyphs[msb][lsb]) return 0; // Already exists, do not overwrite
+
+ glyph_cache* glyph =
+ (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;
+ return m_glyphs[msb][lsb] = glyph;
+ }
+
+ private:
+ block_allocator m_allocator;
+ glyph_cache** m_glyphs[256];
+ char* m_font_signature;
+ };
+
+
+
+
+
+
+
+ //---------------------------------------------------------font_cache_pool
+ class font_cache_pool
+ {
+ public:
+ //--------------------------------------------------------------------
+ ~font_cache_pool()
+ {
+ unsigned i;
+ for(i = 0; i < m_num_fonts; ++i)
+ {
+ obj_allocator<font_cache>::deallocate(m_fonts[i]);
+ }
+ pod_allocator<font_cache*>::deallocate(m_fonts, m_max_fonts);
+ }
+
+ //--------------------------------------------------------------------
+ font_cache_pool(unsigned max_fonts=32) :
+ m_fonts(pod_allocator<font_cache*>::allocate(max_fonts)),
+ m_max_fonts(max_fonts),
+ m_num_fonts(0),
+ m_cur_font(0)
+ {}
+
+
+ //--------------------------------------------------------------------
+ void font(const char* font_signature, bool reset_cache = false)
+ {
+ int idx = find_font(font_signature);
+ if(idx >= 0)
+ {
+ if(reset_cache)
+ {
+ 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];
+ }
+ else
+ {
+ if(m_num_fonts >= m_max_fonts)
+ {
+ 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] = obj_allocator<font_cache>::allocate();
+ m_fonts[m_num_fonts]->signature(font_signature);
+ m_cur_font = m_fonts[m_num_fonts];
+ ++m_num_fonts;
+ }
+ }
+
+ //--------------------------------------------------------------------
+ const font_cache* font() const
+ {
+ return m_cur_font;
+ }
+
+ //--------------------------------------------------------------------
+ const glyph_cache* find_glyph(unsigned glyph_code) const
+ {
+ if(m_cur_font) return m_cur_font->find_glyph(glyph_code);
+ return 0;
+ }
+
+ //--------------------------------------------------------------------
+ glyph_cache* cache_glyph(unsigned glyph_code,
+ unsigned glyph_index,
+ unsigned data_size,
+ glyph_data_type data_type,
+ const rect_i& bounds,
+ double advance_x,
+ double advance_y)
+ {
+ if(m_cur_font)
+ {
+ return m_cur_font->cache_glyph(glyph_code,
+ glyph_index,
+ data_size,
+ data_type,
+ bounds,
+ advance_x,
+ advance_y);
+ }
+ return 0;
+ }
+
+
+ //--------------------------------------------------------------------
+ int find_font(const char* font_signature)
+ {
+ unsigned i;
+ for(i = 0; i < m_num_fonts; i++)
+ {
+ if(m_fonts[i]->font_is(font_signature)) return int(i);
+ }
+ return -1;
+ }
+
+ private:
+ font_cache** m_fonts;
+ unsigned m_max_fonts;
+ unsigned m_num_fonts;
+ font_cache* m_cur_font;
+ };
+
+
+
+
+ //------------------------------------------------------------------------
+ enum glyph_rendering
+ {
+ glyph_ren_native_mono,
+ glyph_ren_native_gray8,
+ glyph_ren_outline,
+ glyph_ren_agg_mono,
+ glyph_ren_agg_gray8
+ };
+
+
+
+
+ //------------------------------------------------------font_cache_manager
+ template<class FontEngine> class font_cache_manager
+ {
+ public:
+ typedef FontEngine font_engine_type;
+ typedef font_cache_manager<FontEngine> self_type;
+ typedef typename font_engine_type::path_adaptor_type path_adaptor_type;
+ typedef typename font_engine_type::gray8_adaptor_type gray8_adaptor_type;
+ typedef typename gray8_adaptor_type::embedded_scanline gray8_scanline_type;
+ typedef typename font_engine_type::mono_adaptor_type mono_adaptor_type;
+ typedef typename mono_adaptor_type::embedded_scanline mono_scanline_type;
+
+ //--------------------------------------------------------------------
+ font_cache_manager(font_engine_type& engine, unsigned max_fonts=32) :
+ m_fonts(max_fonts),
+ m_engine(engine),
+ m_change_stamp(-1),
+ m_prev_glyph(0),
+ m_last_glyph(0)
+ {}
+
+ //--------------------------------------------------------------------
+ void reset_last_glyph()
+ {
+ m_prev_glyph = m_last_glyph = 0;
+ }
+
+ //--------------------------------------------------------------------
+ const glyph_cache* glyph(unsigned glyph_code)
+ {
+ synchronize();
+ const glyph_cache* gl = m_fonts.find_glyph(glyph_code);
+ if(gl)
+ {
+ m_prev_glyph = m_last_glyph;
+ return m_last_glyph = gl;
+ }
+ else
+ {
+ if(m_engine.prepare_glyph(glyph_code))
+ {
+ m_prev_glyph = m_last_glyph;
+ m_last_glyph = m_fonts.cache_glyph(glyph_code,
+ m_engine.glyph_index(),
+ m_engine.data_size(),
+ m_engine.data_type(),
+ m_engine.bounds(),
+ m_engine.advance_x(),
+ m_engine.advance_y());
+ m_engine.write_glyph_to(m_last_glyph->data);
+ return m_last_glyph;
+ }
+ }
+ return 0;
+ }
+
+ //--------------------------------------------------------------------
+ void init_embedded_adaptors(const glyph_cache* gl,
+ double x, double y,
+ double scale=1.0)
+ {
+ if(gl)
+ {
+ switch(gl->data_type)
+ {
+ default: return;
+ case glyph_data_mono:
+ m_mono_adaptor.init(gl->data, gl->data_size, x, y);
+ break;
+
+ case glyph_data_gray8:
+ m_gray8_adaptor.init(gl->data, gl->data_size, x, y);
+ break;
+
+ case glyph_data_outline:
+ m_path_adaptor.init(gl->data, gl->data_size, x, y, scale);
+ break;
+ }
+ }
+ }
+
+
+ //--------------------------------------------------------------------
+ path_adaptor_type& path_adaptor() { return m_path_adaptor; }
+ gray8_adaptor_type& gray8_adaptor() { return m_gray8_adaptor; }
+ gray8_scanline_type& gray8_scanline() { return m_gray8_scanline; }
+ mono_adaptor_type& mono_adaptor() { return m_mono_adaptor; }
+ mono_scanline_type& mono_scanline() { return m_mono_scanline; }
+
+ //--------------------------------------------------------------------
+ const glyph_cache* perv_glyph() const { return m_prev_glyph; }
+ const glyph_cache* last_glyph() const { return m_last_glyph; }
+
+ //--------------------------------------------------------------------
+ bool add_kerning(double* x, double* y)
+ {
+ if(m_prev_glyph && m_last_glyph)
+ {
+ return m_engine.add_kerning(m_prev_glyph->glyph_index,
+ m_last_glyph->glyph_index,
+ x, y);
+ }
+ return false;
+ }
+
+ //--------------------------------------------------------------------
+ void precache(unsigned from, unsigned to)
+ {
+ for(; from <= to; ++from) glyph(from);
+ }
+
+ //--------------------------------------------------------------------
+ void reset_cache()
+ {
+ m_fonts.font(m_engine.font_signature(), true);
+ m_change_stamp = m_engine.change_stamp();
+ m_prev_glyph = m_last_glyph = 0;
+ }
+
+ private:
+ //--------------------------------------------------------------------
+ font_cache_manager(const self_type&);
+ const self_type& operator = (const self_type&);
+
+ //--------------------------------------------------------------------
+ void synchronize()
+ {
+ if(m_change_stamp != m_engine.change_stamp())
+ {
+ m_fonts.font(m_engine.font_signature());
+ m_change_stamp = m_engine.change_stamp();
+ m_prev_glyph = m_last_glyph = 0;
+ }
+ }
+
+ font_cache_pool m_fonts;
+ font_engine_type& m_engine;
+ int m_change_stamp;
+ double m_dx;
+ double m_dy;
+ const glyph_cache* m_prev_glyph;
+ const glyph_cache* m_last_glyph;
+ path_adaptor_type m_path_adaptor;
+ gray8_adaptor_type m_gray8_adaptor;
+ gray8_scanline_type m_gray8_scanline;
+ mono_adaptor_type m_mono_adaptor;
+ mono_scanline_type m_mono_scanline;
+ };
+
+}
+
+#endif
+
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_font_cache_manager2.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_font_cache_manager2.h
new file mode 100644
index 0000000000..75d311eff7
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_font_cache_manager2.h
@@ -0,0 +1,311 @@
+//----------------------------------------------------------------------------
+// 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_FONT_CACHE_MANAGER2_INCLUDED
+#define AGG_FONT_CACHE_MANAGER2_INCLUDED
+
+#include <cassert>
+#include <exception>
+#include <string.h>
+#include "agg_array.h"
+
+namespace agg {
+
+namespace fman {
+ //---------------------------------------------------------glyph_data_type
+ enum glyph_data_type
+ {
+ glyph_data_invalid = 0,
+ glyph_data_mono = 1,
+ glyph_data_gray8 = 2,
+ glyph_data_outline = 3
+ };
+
+
+ //-------------------------------------------------------------cached_glyph
+ struct cached_glyph
+ {
+ void * cached_font;
+ unsigned glyph_code;
+ unsigned glyph_index;
+ int8u* data;
+ unsigned data_size;
+ glyph_data_type data_type;
+ rect_i bounds;
+ double advance_x;
+ double advance_y;
+ };
+
+
+ //--------------------------------------------------------------cached_glyphs
+ class cached_glyphs
+ {
+ public:
+ enum block_size_e { block_size = 16384-16 };
+
+ //--------------------------------------------------------------------
+ cached_glyphs()
+ : m_allocator(block_size)
+ { memset(m_glyphs, 0, sizeof(m_glyphs)); }
+
+ //--------------------------------------------------------------------
+ const cached_glyph* find_glyph(unsigned glyph_code) const
+ {
+ unsigned msb = (glyph_code >> 8) & 0xFF;
+ if(m_glyphs[msb])
+ {
+ return m_glyphs[msb][glyph_code & 0xFF];
+ }
+ return 0;
+ }
+
+ //--------------------------------------------------------------------
+ cached_glyph* cache_glyph(
+ void * cached_font,
+ unsigned glyph_code,
+ unsigned glyph_index,
+ unsigned data_size,
+ glyph_data_type data_type,
+ const rect_i& bounds,
+ double advance_x,
+ double advance_y)
+ {
+ unsigned msb = (glyph_code >> 8) & 0xFF;
+ if(m_glyphs[msb] == 0)
+ {
+ m_glyphs[msb] =
+ (cached_glyph**)m_allocator.allocate(sizeof(cached_glyph*) * 256,
+ sizeof(cached_glyph*));
+ memset(m_glyphs[msb], 0, sizeof(cached_glyph*) * 256);
+ }
+
+ unsigned lsb = glyph_code & 0xFF;
+ if(m_glyphs[msb][lsb]) return 0; // Already exists, do not overwrite
+
+ cached_glyph* glyph =
+ (cached_glyph*)m_allocator.allocate(sizeof(cached_glyph),
+ sizeof(double));
+
+ glyph->cached_font = cached_font;
+ glyph->glyph_code = glyph_code;
+ 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:
+ block_allocator m_allocator;
+ cached_glyph** m_glyphs[256];
+ };
+
+
+
+ //------------------------------------------------------------------------
+ enum glyph_rendering
+ {
+ glyph_ren_native_mono,
+ glyph_ren_native_gray8,
+ glyph_ren_outline,
+ glyph_ren_agg_mono,
+ glyph_ren_agg_gray8
+ };
+
+
+
+
+ //------------------------------------------------------font_cache_manager
+ template<class FontEngine> class font_cache_manager
+ {
+ public:
+ typedef FontEngine font_engine_type;
+ typedef font_cache_manager<FontEngine> self_type;
+ typedef typename font_engine_type::path_adaptor_type path_adaptor_type;
+ typedef typename font_engine_type::gray8_adaptor_type gray8_adaptor_type;
+ typedef typename gray8_adaptor_type::embedded_scanline gray8_scanline_type;
+ typedef typename font_engine_type::mono_adaptor_type mono_adaptor_type;
+ typedef typename mono_adaptor_type::embedded_scanline mono_scanline_type;
+
+ struct cached_font
+ {
+ cached_font(
+ font_engine_type& engine,
+ typename FontEngine::loaded_face *face,
+ double height,
+ double width,
+ bool hinting,
+ glyph_rendering rendering )
+ : m_engine( engine )
+ , m_face( face )
+ , m_height( height )
+ , m_width( width )
+ , m_hinting( hinting )
+ , m_rendering( rendering )
+ {
+ select_face();
+ m_face_height=m_face->height();
+ m_face_width=m_face->width();
+ m_face_ascent=m_face->ascent();
+ m_face_descent=m_face->descent();
+ m_face_ascent_b=m_face->ascent_b();
+ m_face_descent_b=m_face->descent_b();
+ }
+
+ double height() const
+ {
+ return m_face_height;
+ }
+
+ double width() const
+ {
+ return m_face_width;
+ }
+
+ double ascent() const
+ {
+ return m_face_ascent;
+ }
+
+ double descent() const
+ {
+ return m_face_descent;
+ }
+
+ double ascent_b() const
+ {
+ return m_face_ascent_b;
+ }
+
+ double descent_b() const
+ {
+ return m_face_descent_b;
+ }
+
+ bool add_kerning( const cached_glyph *first, const cached_glyph *second, double* x, double* y)
+ {
+ if( !first || !second )
+ return false;
+ select_face();
+ return m_face->add_kerning(
+ first->glyph_index, second->glyph_index, x, y );
+ }
+
+ void select_face()
+ {
+ m_face->select_instance( m_height, m_width, m_hinting, m_rendering );
+ }
+
+ const cached_glyph *get_glyph(unsigned cp)
+ {
+ const cached_glyph *glyph=m_glyphs.find_glyph(cp);
+ if( glyph==0 )
+ {
+ typename FontEngine::prepared_glyph prepared;
+ select_face();
+ bool success=m_face->prepare_glyph(cp, &prepared);
+ if( success )
+ {
+ glyph=m_glyphs.cache_glyph(
+ this,
+ prepared.glyph_code,
+ prepared.glyph_index,
+ prepared.data_size,
+ prepared.data_type,
+ prepared.bounds,
+ prepared.advance_x,
+ prepared.advance_y );
+ assert( glyph!=0 );
+ m_face->write_glyph_to(&prepared,glyph->data);
+ }
+ }
+ return glyph;
+ }
+
+ font_engine_type& m_engine;
+ typename FontEngine::loaded_face *m_face;
+ double m_height;
+ double m_width;
+ bool m_hinting;
+ glyph_rendering m_rendering;
+ double m_face_height;
+ double m_face_width;
+ double m_face_ascent;
+ double m_face_descent;
+ double m_face_ascent_b;
+ double m_face_descent_b;
+ cached_glyphs m_glyphs;
+ };
+
+ //--------------------------------------------------------------------
+ font_cache_manager(font_engine_type& engine, unsigned max_fonts=32)
+ :m_engine(engine)
+ { }
+
+ //--------------------------------------------------------------------
+ void init_embedded_adaptors(const cached_glyph* gl,
+ double x, double y,
+ double scale=1.0)
+ {
+ if(gl)
+ {
+ switch(gl->data_type)
+ {
+ default: return;
+ case glyph_data_mono:
+ m_mono_adaptor.init(gl->data, gl->data_size, x, y);
+ break;
+
+ case glyph_data_gray8:
+ m_gray8_adaptor.init(gl->data, gl->data_size, x, y);
+ break;
+
+ case glyph_data_outline:
+ m_path_adaptor.init(gl->data, gl->data_size, x, y, scale);
+ break;
+ }
+ }
+ }
+
+
+ //--------------------------------------------------------------------
+ path_adaptor_type& path_adaptor() { return m_path_adaptor; }
+ gray8_adaptor_type& gray8_adaptor() { return m_gray8_adaptor; }
+ gray8_scanline_type& gray8_scanline() { return m_gray8_scanline; }
+ mono_adaptor_type& mono_adaptor() { return m_mono_adaptor; }
+ mono_scanline_type& mono_scanline() { return m_mono_scanline; }
+
+
+ private:
+ //--------------------------------------------------------------------
+ font_cache_manager(const self_type&);
+ const self_type& operator = (const self_type&);
+
+ font_engine_type& m_engine;
+ path_adaptor_type m_path_adaptor;
+ gray8_adaptor_type m_gray8_adaptor;
+ gray8_scanline_type m_gray8_scanline;
+ mono_adaptor_type m_mono_adaptor;
+ mono_scanline_type m_mono_scanline;
+ };
+
+}
+}
+
+#endif
+
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_glyph_raster_bin.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_glyph_raster_bin.h
new file mode 100644
index 0000000000..b0bf858efd
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_glyph_raster_bin.h
@@ -0,0 +1,155 @@
+//----------------------------------------------------------------------------
+// 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_GLYPH_RASTER_BIN_INCLUDED
+#define AGG_GLYPH_RASTER_BIN_INCLUDED
+
+#include <string.h>
+#include "agg_basics.h"
+
+namespace agg
+{
+
+ //========================================================glyph_raster_bin
+ template<class ColorT> class glyph_raster_bin
+ {
+ public:
+ typedef ColorT color_type;
+
+ //--------------------------------------------------------------------
+ struct glyph_rect
+ {
+ int x1,y1,x2,y2;
+ double dx, dy;
+ };
+
+ //--------------------------------------------------------------------
+ glyph_raster_bin(const int8u* font) :
+ m_font(font),
+ m_big_endian(false)
+ {
+ int t = 1;
+ if(*(char*)&t == 0) m_big_endian = true;
+ memset(m_span, 0, sizeof(m_span));
+ }
+
+ //--------------------------------------------------------------------
+ const int8u* font() const { return m_font; }
+ void font(const int8u* f) { m_font = f; }
+
+ //--------------------------------------------------------------------
+ double height() const { return m_font[0]; }
+ double base_line() const { return m_font[1]; }
+
+ //--------------------------------------------------------------------
+ template<class CharT>
+ double width(const CharT* str) const
+ {
+ unsigned start_char = m_font[2];
+ unsigned num_chars = m_font[3];
+
+ unsigned w = 0;
+ while(*str)
+ {
+ unsigned glyph = *str;
+ const int8u* bits = m_font + 4 + num_chars * 2 +
+ value(m_font + 4 + (glyph - start_char) * 2);
+ w += *bits;
+ ++str;
+ }
+ return w;
+ }
+
+ //--------------------------------------------------------------------
+ void prepare(glyph_rect* r, double x, double y, unsigned glyph, bool flip)
+ {
+ unsigned start_char = m_font[2];
+ unsigned num_chars = m_font[3];
+
+ m_bits = m_font + 4 + num_chars * 2 +
+ value(m_font + 4 + (glyph - start_char) * 2);
+
+ m_glyph_width = *m_bits++;
+ m_glyph_byte_width = (m_glyph_width + 7) >> 3;
+
+ r->x1 = int(x);
+ r->x2 = r->x1 + m_glyph_width - 1;
+ if(flip)
+ {
+ r->y1 = int(y) - m_font[0] + m_font[1];
+ r->y2 = r->y1 + m_font[0] - 1;
+ }
+ else
+ {
+ r->y1 = int(y) - m_font[1] + 1;
+ r->y2 = r->y1 + m_font[0] - 1;
+ }
+ r->dx = m_glyph_width;
+ r->dy = 0;
+ }
+
+ //--------------------------------------------------------------------
+ const cover_type* span(unsigned i)
+ {
+ i = m_font[0] - i - 1;
+ const int8u* bits = m_bits + i * m_glyph_byte_width;
+ unsigned j;
+ unsigned val = *bits;
+ unsigned nb = 0;
+ for(j = 0; j < m_glyph_width; ++j)
+ {
+ m_span[j] = (cover_type)((val & 0x80) ? cover_full : cover_none);
+ val <<= 1;
+ if(++nb >= 8)
+ {
+ val = *++bits;
+ nb = 0;
+ }
+ }
+ return m_span;
+ }
+
+ private:
+ //--------------------------------------------------------------------
+ int16u value(const int8u* p) const
+ {
+ int16u v;
+ if(m_big_endian)
+ {
+ *(int8u*)&v = p[1];
+ *((int8u*)&v + 1) = p[0];
+ }
+ else
+ {
+ *(int8u*)&v = p[0];
+ *((int8u*)&v + 1) = p[1];
+ }
+ return v;
+ }
+
+
+ //--------------------------------------------------------------------
+ const int8u* m_font;
+ bool m_big_endian;
+ cover_type m_span[32];
+ const int8u* m_bits;
+ unsigned m_glyph_width;
+ unsigned m_glyph_byte_width;
+ };
+
+
+}
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_gradient_lut.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_gradient_lut.h
new file mode 100644
index 0000000000..9aaa426815
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_gradient_lut.h
@@ -0,0 +1,244 @@
+//----------------------------------------------------------------------------
+// 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_GRADIENT_LUT_INCLUDED
+#define AGG_GRADIENT_LUT_INCLUDED
+
+#include "agg_array.h"
+#include "agg_dda_line.h"
+#include "agg_color_rgba.h"
+#include "agg_color_gray.h"
+
+namespace agg
+{
+
+ //======================================================color_interpolator
+ template<class ColorT> struct color_interpolator
+ {
+ public:
+ typedef ColorT color_type;
+
+ color_interpolator(const color_type& c1,
+ const color_type& c2,
+ unsigned len) :
+ m_c1(c1),
+ m_c2(c2),
+ m_len(len),
+ m_count(0)
+ {}
+
+ void operator ++ ()
+ {
+ ++m_count;
+ }
+
+ color_type color() const
+ {
+ return m_c1.gradient(m_c2, double(m_count) / m_len);
+ }
+
+ private:
+ color_type m_c1;
+ color_type m_c2;
+ unsigned m_len;
+ unsigned m_count;
+ };
+
+ //========================================================================
+ // Fast specialization for rgba8
+ template<> struct color_interpolator<rgba8>
+ {
+ public:
+ typedef rgba8 color_type;
+
+ color_interpolator(const color_type& c1,
+ const color_type& c2,
+ unsigned len) :
+ r(c1.r, c2.r, len),
+ g(c1.g, c2.g, len),
+ b(c1.b, c2.b, len),
+ a(c1.a, c2.a, len)
+ {}
+
+ void operator ++ ()
+ {
+ ++r; ++g; ++b; ++a;
+ }
+
+ color_type color() const
+ {
+ return color_type(r.y(), g.y(), b.y(), a.y());
+ }
+
+ private:
+ agg::dda_line_interpolator<14> r, g, b, a;
+ };
+
+ //========================================================================
+ // Fast specialization for gray8
+ template<> struct color_interpolator<gray8>
+ {
+ public:
+ typedef gray8 color_type;
+
+ color_interpolator(const color_type& c1,
+ const color_type& c2,
+ unsigned len) :
+ v(c1.v, c2.v, len),
+ a(c1.a, c2.a, len)
+ {}
+
+ void operator ++ ()
+ {
+ ++v; ++a;
+ }
+
+ color_type color() const
+ {
+ return color_type(v.y(), a.y());
+ }
+
+ private:
+ agg::dda_line_interpolator<14> v,a;
+ };
+
+ //============================================================gradient_lut
+ template<class ColorInterpolator,
+ unsigned ColorLutSize=256> class gradient_lut
+ {
+ public:
+ typedef ColorInterpolator interpolator_type;
+ typedef typename interpolator_type::color_type color_type;
+ enum { color_lut_size = ColorLutSize };
+
+ //--------------------------------------------------------------------
+ gradient_lut() : m_color_lut(color_lut_size) {}
+
+ // Build Gradient Lut
+ // First, call remove_all(), then add_color() at least twice,
+ // then build_lut(). Argument "offset" in add_color must be
+ // in range [0...1] and defines a color stop as it is described
+ // in SVG specification, section Gradients and Patterns.
+ // The simplest linear gradient is:
+ // gradient_lut.add_color(0.0, start_color);
+ // gradient_lut.add_color(1.0, end_color);
+ //--------------------------------------------------------------------
+ void remove_all();
+ void add_color(double offset, const color_type& color);
+ void build_lut();
+
+ // Size-index Interface. This class can be used directly as the
+ // ColorF in span_gradient. All it needs is two access methods
+ // size() and operator [].
+ //--------------------------------------------------------------------
+ static unsigned size()
+ {
+ return color_lut_size;
+ }
+ const color_type& operator [] (unsigned i) const
+ {
+ return m_color_lut[i];
+ }
+
+ private:
+ //--------------------------------------------------------------------
+ struct color_point
+ {
+ double offset;
+ color_type color;
+
+ color_point() {}
+ color_point(double off, const color_type& c) :
+ offset(off), color(c)
+ {
+ if(offset < 0.0) offset = 0.0;
+ if(offset > 1.0) offset = 1.0;
+ }
+ };
+ typedef agg::pod_bvector<color_point, 4> color_profile_type;
+ typedef agg::pod_array<color_type> color_lut_type;
+
+ static bool offset_less(const color_point& a, const color_point& b)
+ {
+ return a.offset < b.offset;
+ }
+ static bool offset_equal(const color_point& a, const color_point& b)
+ {
+ return a.offset == b.offset;
+ }
+
+ //--------------------------------------------------------------------
+ color_profile_type m_color_profile;
+ color_lut_type m_color_lut;
+ };
+
+
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S>
+ void gradient_lut<T,S>::remove_all()
+ {
+ m_color_profile.remove_all();
+ }
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S>
+ void gradient_lut<T,S>::add_color(double offset, const color_type& color)
+ {
+ m_color_profile.add(color_point(offset, color));
+ }
+
+ //------------------------------------------------------------------------
+ template<class T, unsigned S>
+ void gradient_lut<T,S>::build_lut()
+ {
+ quick_sort(m_color_profile, offset_less);
+ m_color_profile.cut_at(remove_duplicates(m_color_profile, offset_equal));
+ if(m_color_profile.size() >= 2)
+ {
+ unsigned i;
+ unsigned start = uround(m_color_profile[0].offset * color_lut_size);
+ unsigned end;
+ color_type c = m_color_profile[0].color;
+ for(i = 0; i < start; i++)
+ {
+ m_color_lut[i] = c;
+ }
+ for(i = 1; i < m_color_profile.size(); i++)
+ {
+ end = uround(m_color_profile[i].offset * color_lut_size);
+ interpolator_type ci(m_color_profile[i-1].color,
+ m_color_profile[i ].color,
+ end - start + 1);
+ while(start < end)
+ {
+ m_color_lut[start] = ci.color();
+ ++ci;
+ ++start;
+ }
+ }
+ c = m_color_profile.last().color;
+ for(; end < m_color_lut.size(); end++)
+ {
+ m_color_lut[end] = c;
+ }
+ }
+ }
+}
+
+
+
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_gsv_text.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_gsv_text.h
new file mode 100644
index 0000000000..16b3aeb33d
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_gsv_text.h
@@ -0,0 +1,153 @@
+//----------------------------------------------------------------------------
+// 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
+//----------------------------------------------------------------------------
+//
+// Class gsv_text
+//
+//----------------------------------------------------------------------------
+
+#ifndef AGG_GSV_TEXT_INCLUDED
+#define AGG_GSV_TEXT_INCLUDED
+
+#include "agg_array.h"
+#include "agg_conv_stroke.h"
+#include "agg_conv_transform.h"
+
+namespace agg
+{
+
+
+ //---------------------------------------------------------------gsv_text
+ //
+ // See Implementation agg_gsv_text.cpp
+ //
+ class gsv_text
+ {
+ enum status
+ {
+ initial,
+ next_char,
+ start_glyph,
+ glyph
+ };
+
+ public:
+ gsv_text();
+
+ void font(const void* font);
+ void flip(bool flip_y) { m_flip = flip_y; }
+ void load_font(const char* file);
+ void size(double height, double width=0.0);
+ void space(double space);
+ void line_space(double line_space);
+ void start_point(double x, double y);
+ void text(const char* text);
+
+ double text_width();
+
+ void rewind(unsigned path_id);
+ unsigned vertex(double* x, double* y);
+
+ private:
+ // not supposed to be copied
+ gsv_text(const gsv_text&);
+ const gsv_text& operator = (const gsv_text&);
+
+ int16u value(const int8u* p) const
+ {
+ int16u v;
+ if(m_big_endian)
+ {
+ *(int8u*)&v = p[1];
+ *((int8u*)&v + 1) = p[0];
+ }
+ else
+ {
+ *(int8u*)&v = p[0];
+ *((int8u*)&v + 1) = p[1];
+ }
+ return v;
+ }
+
+ 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;
+ 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;
+ };
+
+
+
+
+ //--------------------------------------------------------gsv_text_outline
+ template<class Transformer = trans_affine> class gsv_text_outline
+ {
+ public:
+ gsv_text_outline(gsv_text& text, Transformer& trans) :
+ m_polyline(text),
+ m_trans(m_polyline, trans)
+ {
+ }
+
+ void width(double w)
+ {
+ m_polyline.width(w);
+ }
+
+ void transformer(const Transformer* trans)
+ {
+ m_trans->transformer(trans);
+ }
+
+ void rewind(unsigned path_id)
+ {
+ m_trans.rewind(path_id);
+ m_polyline.line_join(round_join);
+ m_polyline.line_cap(round_cap);
+ }
+
+ unsigned vertex(double* x, double* y)
+ {
+ return m_trans.vertex(x, y);
+ }
+
+ private:
+ conv_stroke<gsv_text> m_polyline;
+ conv_transform<conv_stroke<gsv_text>, Transformer> m_trans;
+ };
+
+
+
+}
+
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_line_aa_basics.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_line_aa_basics.h
new file mode 100644
index 0000000000..c5acb18e79
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_line_aa_basics.h
@@ -0,0 +1,189 @@
+//----------------------------------------------------------------------------
+// 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_LINE_AA_BASICS_INCLUDED
+#define AGG_LINE_AA_BASICS_INCLUDED
+
+#include <stdlib.h>
+#include "agg_basics.h"
+
+namespace agg
+{
+
+ // See Implementation agg_line_aa_basics.cpp
+
+ //-------------------------------------------------------------------------
+ enum line_subpixel_scale_e
+ {
+ 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 line_mr_subpixel_scale_e
+ {
+ line_mr_subpixel_shift = 4, //----line_mr_subpixel_shift
+ 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
+ AGG_INLINE int line_mr(int x)
+ {
+ return x >> (line_subpixel_shift - line_mr_subpixel_shift);
+ }
+
+ //-------------------------------------------------------------------line_hr
+ AGG_INLINE int line_hr(int x)
+ {
+ return x << (line_subpixel_shift - line_mr_subpixel_shift);
+ }
+
+ //---------------------------------------------------------------line_dbl_hr
+ AGG_INLINE int line_dbl_hr(int x)
+ {
+ return x << line_subpixel_shift;
+ }
+
+ //---------------------------------------------------------------line_coord
+ struct line_coord
+ {
+ 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
+ {
+ //---------------------------------------------------------------------
+ line_parameters() {}
+ line_parameters(int x1_, int y1_, int x2_, int y2_, int len_) :
+ x1(x1_), y1(y1_), x2(x2_), y2(y2_),
+ dx(abs(x2_ - x1_)),
+ dy(abs(y2_ - y1_)),
+ sx((x2_ > x1_) ? 1 : -1),
+ sy((y2_ > y1_) ? 1 : -1),
+ vertical(dy >= dx),
+ inc(vertical ? sy : sx),
+ len(len_),
+ octant((sy & 4) | (sx & 2) | int(vertical))
+ {
+ }
+
+ //---------------------------------------------------------------------
+ unsigned orthogonal_quadrant() const { return s_orthogonal_quadrant[octant]; }
+ unsigned diagonal_quadrant() const { return s_diagonal_quadrant[octant]; }
+
+ //---------------------------------------------------------------------
+ bool same_orthogonal_quadrant(const line_parameters& lp) const
+ {
+ return s_orthogonal_quadrant[octant] == s_orthogonal_quadrant[lp.octant];
+ }
+
+ //---------------------------------------------------------------------
+ bool same_diagonal_quadrant(const line_parameters& lp) const
+ {
+ return s_diagonal_quadrant[octant] == s_diagonal_quadrant[lp.octant];
+ }
+
+ //---------------------------------------------------------------------
+ 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;
+ int len;
+ int octant;
+
+ //---------------------------------------------------------------------
+ static const int8u s_orthogonal_quadrant[8];
+ static const int8u s_diagonal_quadrant[8];
+ };
+
+
+
+ // See Implementation agg_line_aa_basics.cpp
+
+ //----------------------------------------------------------------bisectrix
+ void bisectrix(const line_parameters& l1,
+ const line_parameters& l2,
+ int* x, int* y);
+
+
+ //-------------------------------------------fix_degenerate_bisectrix_start
+ void inline fix_degenerate_bisectrix_start(const line_parameters& lp,
+ int* x, int* y)
+ {
+ 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);
+ }
+ }
+
+
+ //---------------------------------------------fix_degenerate_bisectrix_end
+ void inline fix_degenerate_bisectrix_end(const line_parameters& lp,
+ int* x, int* y)
+ {
+ 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);
+ }
+ }
+
+
+}
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_path_length.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_path_length.h
new file mode 100644
index 0000000000..740ba31df2
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_path_storage_integer.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_path_storage_integer.h
new file mode 100644
index 0000000000..7c48355993
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_path_storage_integer.h
@@ -0,0 +1,295 @@
+//----------------------------------------------------------------------------
+// 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_STORAGE_INTEGER_INCLUDED
+#define AGG_PATH_STORAGE_INTEGER_INCLUDED
+
+#include <string.h>
+#include "agg_array.h"
+
+namespace agg
+{
+ //---------------------------------------------------------vertex_integer
+ template<class T, unsigned CoordShift=6> struct vertex_integer
+ {
+ enum path_cmd
+ {
+ cmd_move_to = 0,
+ cmd_line_to = 1,
+ cmd_curve3 = 2,
+ cmd_curve4 = 3
+ };
+
+ enum coord_scale_e
+ {
+ coord_shift = CoordShift,
+ coord_scale = 1 << coord_shift
+ };
+
+ T x,y;
+ vertex_integer() {}
+ vertex_integer(T x_, T y_, unsigned flag) :
+ x(((x_ << 1) & ~1) | (flag & 1)),
+ y(((y_ << 1) & ~1) | (flag >> 1)) {}
+
+ unsigned vertex(double* x_, double* y_,
+ double dx=0, double dy=0,
+ double scale=1.0) const
+ {
+ *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;
+ case cmd_line_to: return path_cmd_line_to;
+ case cmd_curve3: return path_cmd_curve3;
+ case cmd_curve4: return path_cmd_curve4;
+ }
+ return path_cmd_stop;
+ }
+ };
+
+
+ //---------------------------------------------------path_storage_integer
+ template<class T, unsigned CoordShift=6> class path_storage_integer
+ {
+ public:
+ typedef T value_type;
+ typedef vertex_integer<T, CoordShift> vertex_integer_type;
+
+ //--------------------------------------------------------------------
+ path_storage_integer() : m_storage(), m_vertex_idx(0), m_closed(true) {}
+
+ //--------------------------------------------------------------------
+ void remove_all() { m_storage.remove_all(); }
+
+ //--------------------------------------------------------------------
+ void move_to(T x, T y)
+ {
+ m_storage.add(vertex_integer_type(x, y, vertex_integer_type::cmd_move_to));
+ }
+
+ //--------------------------------------------------------------------
+ void line_to(T x, T y)
+ {
+ m_storage.add(vertex_integer_type(x, y, vertex_integer_type::cmd_line_to));
+ }
+
+ //--------------------------------------------------------------------
+ void curve3(T x_ctrl, T y_ctrl,
+ T x_to, T y_to)
+ {
+ m_storage.add(vertex_integer_type(x_ctrl, y_ctrl, vertex_integer_type::cmd_curve3));
+ m_storage.add(vertex_integer_type(x_to, y_to, vertex_integer_type::cmd_curve3));
+ }
+
+ //--------------------------------------------------------------------
+ void curve4(T x_ctrl1, T y_ctrl1,
+ T x_ctrl2, T y_ctrl2,
+ T x_to, T y_to)
+ {
+ m_storage.add(vertex_integer_type(x_ctrl1, y_ctrl1, vertex_integer_type::cmd_curve4));
+ m_storage.add(vertex_integer_type(x_ctrl2, y_ctrl2, vertex_integer_type::cmd_curve4));
+ m_storage.add(vertex_integer_type(x_to, y_to, vertex_integer_type::cmd_curve4));
+ }
+
+ //--------------------------------------------------------------------
+ void close_polygon() {}
+
+ //--------------------------------------------------------------------
+ unsigned size() const { return m_storage.size(); }
+ unsigned vertex(unsigned idx, double* x, double* y) const
+ {
+ return m_storage[idx].vertex(x, y);
+ }
+
+ //--------------------------------------------------------------------
+ unsigned byte_size() const { return m_storage.size() * sizeof(vertex_integer_type); }
+ void serialize(int8u* ptr) const
+ {
+ unsigned i;
+ for(i = 0; i < m_storage.size(); i++)
+ {
+ memcpy(ptr, &m_storage[i], sizeof(vertex_integer_type));
+ ptr += sizeof(vertex_integer_type);
+ }
+ }
+
+ //--------------------------------------------------------------------
+ void rewind(unsigned)
+ {
+ m_vertex_idx = 0;
+ m_closed = true;
+ }
+
+ //--------------------------------------------------------------------
+ unsigned vertex(double* x, double* y)
+ {
+ if(m_storage.size() < 2 || m_vertex_idx > m_storage.size())
+ {
+ *x = 0;
+ *y = 0;
+ return path_cmd_stop;
+ }
+ if(m_vertex_idx == m_storage.size())
+ {
+ *x = 0;
+ *y = 0;
+ ++m_vertex_idx;
+ return path_cmd_end_poly | path_flags_close;
+ }
+ unsigned cmd = m_storage[m_vertex_idx].vertex(x, y);
+ if(is_move_to(cmd) && !m_closed)
+ {
+ *x = 0;
+ *y = 0;
+ m_closed = true;
+ return path_cmd_end_poly | path_flags_close;
+ }
+ m_closed = false;
+ ++m_vertex_idx;
+ return cmd;
+ }
+
+ //--------------------------------------------------------------------
+ rect_d bounding_rect() const
+ {
+ rect_d bounds(1e100, 1e100, -1e100, -1e100);
+ if(m_storage.size() == 0)
+ {
+ bounds.x1 = bounds.y1 = bounds.x2 = bounds.y2 = 0.0;
+ }
+ else
+ {
+ unsigned i;
+ for(i = 0; i < m_storage.size(); i++)
+ {
+ double x, y;
+ m_storage[i].vertex(&x, &y);
+ if(x < bounds.x1) bounds.x1 = x;
+ if(y < bounds.y1) bounds.y1 = y;
+ if(x > bounds.x2) bounds.x2 = x;
+ if(y > bounds.y2) bounds.y2 = y;
+ }
+ }
+ return bounds;
+ }
+
+ private:
+ pod_bvector<vertex_integer_type, 6> m_storage;
+ unsigned m_vertex_idx;
+ bool m_closed;
+ };
+
+
+
+
+ //-----------------------------------------serialized_integer_path_adaptor
+ template<class T, unsigned CoordShift=6> class serialized_integer_path_adaptor
+ {
+ public:
+ typedef vertex_integer<T, CoordShift> vertex_integer_type;
+
+ //--------------------------------------------------------------------
+ serialized_integer_path_adaptor() :
+ m_data(0),
+ m_end(0),
+ m_ptr(0),
+ m_dx(0.0),
+ m_dy(0.0),
+ m_scale(1.0),
+ m_vertices(0)
+ {}
+
+ //--------------------------------------------------------------------
+ serialized_integer_path_adaptor(const int8u* data, unsigned size,
+ double dx, double dy) :
+ m_data(data),
+ m_end(data + size),
+ m_ptr(data),
+ m_dx(dx),
+ m_dy(dy),
+ m_vertices(0)
+ {}
+
+ //--------------------------------------------------------------------
+ void init(const int8u* data, unsigned size,
+ double dx, double dy, double scale=1.0)
+ {
+ m_data = data;
+ m_end = data + size;
+ m_ptr = data;
+ m_dx = dx;
+ m_dy = dy;
+ m_scale = scale;
+ m_vertices = 0;
+ }
+
+
+ //--------------------------------------------------------------------
+ void rewind(unsigned)
+ {
+ m_ptr = m_data;
+ m_vertices = 0;
+ }
+
+ //--------------------------------------------------------------------
+ unsigned vertex(double* x, double* y)
+ {
+ if(m_data == 0 || m_ptr > m_end)
+ {
+ *x = 0;
+ *y = 0;
+ return path_cmd_stop;
+ }
+
+ if(m_ptr == m_end)
+ {
+ *x = 0;
+ *y = 0;
+ m_ptr += sizeof(vertex_integer_type);
+ return path_cmd_end_poly | path_flags_close;
+ }
+
+ vertex_integer_type v;
+ memcpy(&v, m_ptr, sizeof(vertex_integer_type));
+ unsigned cmd = v.vertex(x, y, m_dx, m_dy, m_scale);
+ if(is_move_to(cmd) && m_vertices > 2)
+ {
+ *x = 0;
+ *y = 0;
+ m_vertices = 0;
+ return path_cmd_end_poly | path_flags_close;
+ }
+ ++m_vertices;
+ m_ptr += sizeof(vertex_integer_type);
+ return cmd;
+ }
+
+ private:
+ const int8u* m_data;
+ const int8u* m_end;
+ const int8u* m_ptr;
+ double m_dx;
+ double m_dy;
+ double m_scale;
+ unsigned m_vertices;
+ };
+
+}
+
+
+#endif
+
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pattern_filters_rgba.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pattern_filters_rgba.h
new file mode 100644
index 0000000000..c1d174cacb
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pattern_filters_rgba.h
@@ -0,0 +1,123 @@
+//----------------------------------------------------------------------------
+// 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_PATTERN_FILTERS_RGBA8_INCLUDED
+#define AGG_PATTERN_FILTERS_RGBA8_INCLUDED
+
+#include "agg_basics.h"
+#include "agg_line_aa_basics.h"
+#include "agg_color_rgba.h"
+
+
+namespace agg
+{
+
+ //=======================================================pattern_filter_nn
+ template<class ColorT> struct pattern_filter_nn
+ {
+ typedef ColorT color_type;
+ static unsigned dilation() { return 0; }
+
+ static void AGG_INLINE pixel_low_res(color_type const* const* buf,
+ color_type* p, int x, int y)
+ {
+ *p = buf[y][x];
+ }
+
+ static void AGG_INLINE pixel_high_res(color_type const* const* buf,
+ color_type* p, int x, int y)
+ {
+ *p = buf[y >> line_subpixel_shift]
+ [x >> line_subpixel_shift];
+ }
+ };
+
+ typedef pattern_filter_nn<rgba8> pattern_filter_nn_rgba8;
+ typedef pattern_filter_nn<rgba16> pattern_filter_nn_rgba16;
+
+
+ //===========================================pattern_filter_bilinear_rgba
+ template<class ColorT> struct pattern_filter_bilinear_rgba
+ {
+ typedef ColorT color_type;
+ typedef typename color_type::value_type value_type;
+ typedef typename color_type::calc_type calc_type;
+
+
+ static unsigned dilation() { return 1; }
+
+ static AGG_INLINE void pixel_low_res(color_type const* const* buf,
+ color_type* p, int x, int y)
+ {
+ *p = buf[y][x];
+ }
+
+ static AGG_INLINE void pixel_high_res(color_type const* const* buf,
+ color_type* p, int x, int y)
+ {
+ calc_type r, g, b, a;
+ r = g = b = a = 0;
+
+ calc_type weight;
+ int x_lr = x >> line_subpixel_shift;
+ int y_lr = y >> line_subpixel_shift;
+
+ x &= line_subpixel_mask;
+ y &= line_subpixel_mask;
+ const color_type* ptr = buf[y_lr] + x_lr;
+
+ weight = (line_subpixel_scale - x) *
+ (line_subpixel_scale - y);
+ r += weight * ptr->r;
+ g += weight * ptr->g;
+ b += weight * ptr->b;
+ a += weight * ptr->a;
+
+ ++ptr;
+
+ weight = x * (line_subpixel_scale - y);
+ r += weight * ptr->r;
+ g += weight * ptr->g;
+ b += weight * ptr->b;
+ a += weight * ptr->a;
+
+ ptr = buf[y_lr + 1] + x_lr;
+
+ weight = (line_subpixel_scale - x) * y;
+ r += weight * ptr->r;
+ g += weight * ptr->g;
+ b += weight * ptr->b;
+ a += weight * ptr->a;
+
+ ++ptr;
+
+ weight = x * y;
+ r += weight * ptr->r;
+ g += weight * ptr->g;
+ b += weight * ptr->b;
+ a += weight * ptr->a;
+
+ p->r = (value_type)color_type::downshift(r, line_subpixel_shift * 2);
+ p->g = (value_type)color_type::downshift(g, line_subpixel_shift * 2);
+ p->b = (value_type)color_type::downshift(b, line_subpixel_shift * 2);
+ p->a = (value_type)color_type::downshift(a, line_subpixel_shift * 2);
+ }
+ };
+
+ typedef pattern_filter_bilinear_rgba<rgba8> pattern_filter_bilinear_rgba8;
+ typedef pattern_filter_bilinear_rgba<rgba16> pattern_filter_bilinear_rgba16;
+ typedef pattern_filter_bilinear_rgba<rgba32> pattern_filter_bilinear_rgba32;
+}
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pixfmt_rgb_packed.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pixfmt_rgb_packed.h
new file mode 100644
index 0000000000..d879517de6
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pixfmt_rgb_packed.h
@@ -0,0 +1,1312 @@
+//----------------------------------------------------------------------------
+// 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_PIXFMT_RGB_PACKED_INCLUDED
+#define AGG_PIXFMT_RGB_PACKED_INCLUDED
+
+#include <string.h>
+#include "agg_basics.h"
+#include "agg_color_rgba.h"
+#include "agg_rendering_buffer.h"
+
+namespace agg
+{
+ //=========================================================blender_rgb555
+ struct blender_rgb555
+ {
+ typedef rgba8 color_type;
+ typedef color_type::value_type value_type;
+ typedef color_type::calc_type calc_type;
+ typedef int16u pixel_type;
+
+ static AGG_INLINE void blend_pix(pixel_type* p,
+ unsigned cr, unsigned cg, unsigned cb,
+ unsigned alpha,
+ unsigned)
+ {
+ pixel_type rgb = *p;
+ calc_type r = (rgb >> 7) & 0xF8;
+ calc_type g = (rgb >> 2) & 0xF8;
+ calc_type b = (rgb << 3) & 0xF8;
+ *p = (pixel_type)
+ (((((cr - r) * alpha + (r << 8)) >> 1) & 0x7C00) |
+ ((((cg - g) * alpha + (g << 8)) >> 6) & 0x03E0) |
+ (((cb - b) * alpha + (b << 8)) >> 11) | 0x8000);
+ }
+
+ static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
+ {
+ return (pixel_type)(((r & 0xF8) << 7) |
+ ((g & 0xF8) << 2) |
+ (b >> 3) | 0x8000);
+ }
+
+ static AGG_INLINE color_type make_color(pixel_type p)
+ {
+ return color_type((p >> 7) & 0xF8,
+ (p >> 2) & 0xF8,
+ (p << 3) & 0xF8);
+ }
+ };
+
+
+ //=====================================================blender_rgb555_pre
+ struct blender_rgb555_pre
+ {
+ typedef rgba8 color_type;
+ typedef color_type::value_type value_type;
+ typedef color_type::calc_type calc_type;
+ typedef int16u pixel_type;
+
+ static AGG_INLINE void blend_pix(pixel_type* p,
+ unsigned cr, unsigned cg, unsigned cb,
+ unsigned alpha,
+ unsigned cover)
+ {
+ alpha = color_type::base_mask - alpha;
+ pixel_type rgb = *p;
+ calc_type r = (rgb >> 7) & 0xF8;
+ calc_type g = (rgb >> 2) & 0xF8;
+ calc_type b = (rgb << 3) & 0xF8;
+ *p = (pixel_type)
+ ((((r * alpha + cr * cover) >> 1) & 0x7C00) |
+ (((g * alpha + cg * cover) >> 6) & 0x03E0) |
+ ((b * alpha + cb * cover) >> 11) | 0x8000);
+ }
+
+ static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
+ {
+ return (pixel_type)(((r & 0xF8) << 7) |
+ ((g & 0xF8) << 2) |
+ (b >> 3) | 0x8000);
+ }
+
+ static AGG_INLINE color_type make_color(pixel_type p)
+ {
+ return color_type((p >> 7) & 0xF8,
+ (p >> 2) & 0xF8,
+ (p << 3) & 0xF8);
+ }
+ };
+
+
+
+
+ //=====================================================blender_rgb555_gamma
+ template<class Gamma> class blender_rgb555_gamma
+ {
+ public:
+ typedef rgba8 color_type;
+ typedef color_type::value_type value_type;
+ typedef color_type::calc_type calc_type;
+ typedef int16u pixel_type;
+ typedef Gamma gamma_type;
+
+ blender_rgb555_gamma() : m_gamma(0) {}
+ void gamma(const gamma_type& g) { m_gamma = &g; }
+
+ AGG_INLINE void blend_pix(pixel_type* p,
+ unsigned cr, unsigned cg, unsigned cb,
+ unsigned alpha,
+ unsigned)
+ {
+ pixel_type rgb = *p;
+ calc_type r = m_gamma->dir((rgb >> 7) & 0xF8);
+ calc_type g = m_gamma->dir((rgb >> 2) & 0xF8);
+ calc_type b = m_gamma->dir((rgb << 3) & 0xF8);
+ *p = (pixel_type)
+ (((m_gamma->inv(((m_gamma->dir(cr) - r) * alpha + (r << 8)) >> 8) << 7) & 0x7C00) |
+ ((m_gamma->inv(((m_gamma->dir(cg) - g) * alpha + (g << 8)) >> 8) << 2) & 0x03E0) |
+ (m_gamma->inv(((m_gamma->dir(cb) - b) * alpha + (b << 8)) >> 8) >> 3) | 0x8000);
+ }
+
+ static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
+ {
+ return (pixel_type)(((r & 0xF8) << 7) |
+ ((g & 0xF8) << 2) |
+ (b >> 3) | 0x8000);
+ }
+
+ static AGG_INLINE color_type make_color(pixel_type p)
+ {
+ return color_type((p >> 7) & 0xF8,
+ (p >> 2) & 0xF8,
+ (p << 3) & 0xF8);
+ }
+
+ private:
+ const Gamma* m_gamma;
+ };
+
+
+
+
+
+ //=========================================================blender_rgb565
+ struct blender_rgb565
+ {
+ typedef rgba8 color_type;
+ typedef color_type::value_type value_type;
+ typedef color_type::calc_type calc_type;
+ typedef int16u pixel_type;
+
+ static AGG_INLINE void blend_pix(pixel_type* p,
+ unsigned cr, unsigned cg, unsigned cb,
+ unsigned alpha,
+ unsigned)
+ {
+ pixel_type rgb = *p;
+ calc_type r = (rgb >> 8) & 0xF8;
+ calc_type g = (rgb >> 3) & 0xFC;
+ calc_type b = (rgb << 3) & 0xF8;
+ *p = (pixel_type)
+ (((((cr - r) * alpha + (r << 8)) ) & 0xF800) |
+ ((((cg - g) * alpha + (g << 8)) >> 5) & 0x07E0) |
+ (((cb - b) * alpha + (b << 8)) >> 11));
+ }
+
+ static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
+ {
+ return (pixel_type)(((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3));
+ }
+
+ static AGG_INLINE color_type make_color(pixel_type p)
+ {
+ return color_type((p >> 8) & 0xF8,
+ (p >> 3) & 0xFC,
+ (p << 3) & 0xF8);
+ }
+ };
+
+
+
+ //=====================================================blender_rgb565_pre
+ struct blender_rgb565_pre
+ {
+ typedef rgba8 color_type;
+ typedef color_type::value_type value_type;
+ typedef color_type::calc_type calc_type;
+ typedef int16u pixel_type;
+
+ static AGG_INLINE void blend_pix(pixel_type* p,
+ unsigned cr, unsigned cg, unsigned cb,
+ unsigned alpha,
+ unsigned cover)
+ {
+ alpha = color_type::base_mask - alpha;
+ pixel_type rgb = *p;
+ calc_type r = (rgb >> 8) & 0xF8;
+ calc_type g = (rgb >> 3) & 0xFC;
+ calc_type b = (rgb << 3) & 0xF8;
+ *p = (pixel_type)
+ ((((r * alpha + cr * cover) ) & 0xF800) |
+ (((g * alpha + cg * cover) >> 5 ) & 0x07E0) |
+ ((b * alpha + cb * cover) >> 11));
+ }
+
+ static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
+ {
+ return (pixel_type)(((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3));
+ }
+
+ static AGG_INLINE color_type make_color(pixel_type p)
+ {
+ return color_type((p >> 8) & 0xF8,
+ (p >> 3) & 0xFC,
+ (p << 3) & 0xF8);
+ }
+ };
+
+
+
+ //=====================================================blender_rgb565_gamma
+ template<class Gamma> class blender_rgb565_gamma
+ {
+ public:
+ typedef rgba8 color_type;
+ typedef color_type::value_type value_type;
+ typedef color_type::calc_type calc_type;
+ typedef int16u pixel_type;
+ typedef Gamma gamma_type;
+
+ blender_rgb565_gamma() : m_gamma(0) {}
+ void gamma(const gamma_type& g) { m_gamma = &g; }
+
+ AGG_INLINE void blend_pix(pixel_type* p,
+ unsigned cr, unsigned cg, unsigned cb,
+ unsigned alpha,
+ unsigned)
+ {
+ pixel_type rgb = *p;
+ calc_type r = m_gamma->dir((rgb >> 8) & 0xF8);
+ calc_type g = m_gamma->dir((rgb >> 3) & 0xFC);
+ calc_type b = m_gamma->dir((rgb << 3) & 0xF8);
+ *p = (pixel_type)
+ (((m_gamma->inv(((m_gamma->dir(cr) - r) * alpha + (r << 8)) >> 8) << 8) & 0xF800) |
+ ((m_gamma->inv(((m_gamma->dir(cg) - g) * alpha + (g << 8)) >> 8) << 3) & 0x07E0) |
+ (m_gamma->inv(((m_gamma->dir(cb) - b) * alpha + (b << 8)) >> 8) >> 3));
+ }
+
+ static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
+ {
+ return (pixel_type)(((r & 0xF8) << 8) | ((g & 0xFC) << 3) | (b >> 3));
+ }
+
+ static AGG_INLINE color_type make_color(pixel_type p)
+ {
+ return color_type((p >> 8) & 0xF8,
+ (p >> 3) & 0xFC,
+ (p << 3) & 0xF8);
+ }
+
+ private:
+ const Gamma* m_gamma;
+ };
+
+
+
+ //=====================================================blender_rgbAAA
+ struct blender_rgbAAA
+ {
+ typedef rgba16 color_type;
+ typedef color_type::value_type value_type;
+ typedef color_type::calc_type calc_type;
+ typedef int32u pixel_type;
+
+ static AGG_INLINE void blend_pix(pixel_type* p,
+ unsigned cr, unsigned cg, unsigned cb,
+ unsigned alpha,
+ unsigned)
+ {
+ pixel_type rgb = *p;
+ calc_type r = (rgb >> 14) & 0xFFC0;
+ calc_type g = (rgb >> 4) & 0xFFC0;
+ calc_type b = (rgb << 6) & 0xFFC0;
+ *p = (pixel_type)
+ (((((cr - r) * alpha + (r << 16)) >> 2) & 0x3FF00000) |
+ ((((cg - g) * alpha + (g << 16)) >> 12) & 0x000FFC00) |
+ (((cb - b) * alpha + (b << 16)) >> 22) | 0xC0000000);
+ }
+
+ static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
+ {
+ return (pixel_type)(((r & 0xFFC0) << 14) |
+ ((g & 0xFFC0) << 4) |
+ (b >> 6) | 0xC0000000);
+ }
+
+ static AGG_INLINE color_type make_color(pixel_type p)
+ {
+ return color_type((p >> 14) & 0xFFC0,
+ (p >> 4) & 0xFFC0,
+ (p << 6) & 0xFFC0);
+ }
+ };
+
+
+
+ //==================================================blender_rgbAAA_pre
+ struct blender_rgbAAA_pre
+ {
+ typedef rgba16 color_type;
+ typedef color_type::value_type value_type;
+ typedef color_type::calc_type calc_type;
+ typedef int32u pixel_type;
+
+ static AGG_INLINE void blend_pix(pixel_type* p,
+ unsigned cr, unsigned cg, unsigned cb,
+ unsigned alpha,
+ unsigned cover)
+ {
+ alpha = color_type::base_mask - alpha;
+ cover = (cover + 1) << (color_type::base_shift - 8);
+ pixel_type rgb = *p;
+ calc_type r = (rgb >> 14) & 0xFFC0;
+ calc_type g = (rgb >> 4) & 0xFFC0;
+ calc_type b = (rgb << 6) & 0xFFC0;
+ *p = (pixel_type)
+ ((((r * alpha + cr * cover) >> 2) & 0x3FF00000) |
+ (((g * alpha + cg * cover) >> 12) & 0x000FFC00) |
+ ((b * alpha + cb * cover) >> 22) | 0xC0000000);
+ }
+
+ static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
+ {
+ return (pixel_type)(((r & 0xFFC0) << 14) |
+ ((g & 0xFFC0) << 4) |
+ (b >> 6) | 0xC0000000);
+ }
+
+ static AGG_INLINE color_type make_color(pixel_type p)
+ {
+ return color_type((p >> 14) & 0xFFC0,
+ (p >> 4) & 0xFFC0,
+ (p << 6) & 0xFFC0);
+ }
+ };
+
+
+
+ //=================================================blender_rgbAAA_gamma
+ template<class Gamma> class blender_rgbAAA_gamma
+ {
+ public:
+ typedef rgba16 color_type;
+ typedef color_type::value_type value_type;
+ typedef color_type::calc_type calc_type;
+ typedef int32u pixel_type;
+ typedef Gamma gamma_type;
+
+ blender_rgbAAA_gamma() : m_gamma(0) {}
+ void gamma(const gamma_type& g) { m_gamma = &g; }
+
+ AGG_INLINE void blend_pix(pixel_type* p,
+ unsigned cr, unsigned cg, unsigned cb,
+ unsigned alpha,
+ unsigned)
+ {
+ pixel_type rgb = *p;
+ calc_type r = m_gamma->dir((rgb >> 14) & 0xFFC0);
+ calc_type g = m_gamma->dir((rgb >> 4) & 0xFFC0);
+ calc_type b = m_gamma->dir((rgb << 6) & 0xFFC0);
+ *p = (pixel_type)
+ (((m_gamma->inv(((m_gamma->dir(cr) - r) * alpha + (r << 16)) >> 16) << 14) & 0x3FF00000) |
+ ((m_gamma->inv(((m_gamma->dir(cg) - g) * alpha + (g << 16)) >> 16) << 4 ) & 0x000FFC00) |
+ (m_gamma->inv(((m_gamma->dir(cb) - b) * alpha + (b << 16)) >> 16) >> 6 ) | 0xC0000000);
+ }
+
+ static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
+ {
+ return (pixel_type)(((r & 0xFFC0) << 14) |
+ ((g & 0xFFC0) << 4) |
+ (b >> 6) | 0xC0000000);
+ }
+
+ static AGG_INLINE color_type make_color(pixel_type p)
+ {
+ return color_type((p >> 14) & 0xFFC0,
+ (p >> 4) & 0xFFC0,
+ (p << 6) & 0xFFC0);
+ }
+ private:
+ const Gamma* m_gamma;
+ };
+
+
+ //=====================================================blender_bgrAAA
+ struct blender_bgrAAA
+ {
+ typedef rgba16 color_type;
+ typedef color_type::value_type value_type;
+ typedef color_type::calc_type calc_type;
+ typedef int32u pixel_type;
+
+ static AGG_INLINE void blend_pix(pixel_type* p,
+ unsigned cr, unsigned cg, unsigned cb,
+ unsigned alpha,
+ unsigned)
+ {
+ pixel_type bgr = *p;
+ calc_type b = (bgr >> 14) & 0xFFC0;
+ calc_type g = (bgr >> 4) & 0xFFC0;
+ calc_type r = (bgr << 6) & 0xFFC0;
+ *p = (pixel_type)
+ (((((cb - b) * alpha + (b << 16)) >> 2) & 0x3FF00000) |
+ ((((cg - g) * alpha + (g << 16)) >> 12) & 0x000FFC00) |
+ (((cr - r) * alpha + (r << 16)) >> 22) | 0xC0000000);
+ }
+
+ static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
+ {
+ return (pixel_type)(((b & 0xFFC0) << 14) |
+ ((g & 0xFFC0) << 4) |
+ (r >> 6) | 0xC0000000);
+ }
+
+ static AGG_INLINE color_type make_color(pixel_type p)
+ {
+ return color_type((p << 6) & 0xFFC0,
+ (p >> 4) & 0xFFC0,
+ (p >> 14) & 0xFFC0);
+ }
+ };
+
+
+
+ //=================================================blender_bgrAAA_pre
+ struct blender_bgrAAA_pre
+ {
+ typedef rgba16 color_type;
+ typedef color_type::value_type value_type;
+ typedef color_type::calc_type calc_type;
+ typedef int32u pixel_type;
+
+ static AGG_INLINE void blend_pix(pixel_type* p,
+ unsigned cr, unsigned cg, unsigned cb,
+ unsigned alpha,
+ unsigned cover)
+ {
+ alpha = color_type::base_mask - alpha;
+ cover = (cover + 1) << (color_type::base_shift - 8);
+ pixel_type bgr = *p;
+ calc_type b = (bgr >> 14) & 0xFFC0;
+ calc_type g = (bgr >> 4) & 0xFFC0;
+ calc_type r = (bgr << 6) & 0xFFC0;
+ *p = (pixel_type)
+ ((((b * alpha + cb * cover) >> 2) & 0x3FF00000) |
+ (((g * alpha + cg * cover) >> 12) & 0x000FFC00) |
+ ((r * alpha + cr * cover) >> 22) | 0xC0000000);
+ }
+
+ static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
+ {
+ return (pixel_type)(((b & 0xFFC0) << 14) |
+ ((g & 0xFFC0) << 4) |
+ (r >> 6) | 0xC0000000);
+ }
+
+ static AGG_INLINE color_type make_color(pixel_type p)
+ {
+ return color_type((p << 6) & 0xFFC0,
+ (p >> 4) & 0xFFC0,
+ (p >> 14) & 0xFFC0);
+ }
+ };
+
+
+
+ //=================================================blender_bgrAAA_gamma
+ template<class Gamma> class blender_bgrAAA_gamma
+ {
+ public:
+ typedef rgba16 color_type;
+ typedef color_type::value_type value_type;
+ typedef color_type::calc_type calc_type;
+ typedef int32u pixel_type;
+ typedef Gamma gamma_type;
+
+ blender_bgrAAA_gamma() : m_gamma(0) {}
+ void gamma(const gamma_type& g) { m_gamma = &g; }
+
+ AGG_INLINE void blend_pix(pixel_type* p,
+ unsigned cr, unsigned cg, unsigned cb,
+ unsigned alpha,
+ unsigned)
+ {
+ pixel_type bgr = *p;
+ calc_type b = m_gamma->dir((bgr >> 14) & 0xFFC0);
+ calc_type g = m_gamma->dir((bgr >> 4) & 0xFFC0);
+ calc_type r = m_gamma->dir((bgr << 6) & 0xFFC0);
+ *p = (pixel_type)
+ (((m_gamma->inv(((m_gamma->dir(cb) - b) * alpha + (b << 16)) >> 16) << 14) & 0x3FF00000) |
+ ((m_gamma->inv(((m_gamma->dir(cg) - g) * alpha + (g << 16)) >> 16) << 4 ) & 0x000FFC00) |
+ (m_gamma->inv(((m_gamma->dir(cr) - r) * alpha + (r << 16)) >> 16) >> 6 ) | 0xC0000000);
+ }
+
+ static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
+ {
+ return (pixel_type)(((b & 0xFFC0) << 14) |
+ ((g & 0xFFC0) << 4) |
+ (r >> 6) | 0xC0000000);
+ }
+
+ static AGG_INLINE color_type make_color(pixel_type p)
+ {
+ return color_type((p << 6) & 0xFFC0,
+ (p >> 4) & 0xFFC0,
+ (p >> 14) & 0xFFC0);
+ }
+
+ private:
+ const Gamma* m_gamma;
+ };
+
+
+
+ //=====================================================blender_rgbBBA
+ struct blender_rgbBBA
+ {
+ typedef rgba16 color_type;
+ typedef color_type::value_type value_type;
+ typedef color_type::calc_type calc_type;
+ typedef int32u pixel_type;
+
+ static AGG_INLINE void blend_pix(pixel_type* p,
+ unsigned cr, unsigned cg, unsigned cb,
+ unsigned alpha,
+ unsigned)
+ {
+ pixel_type rgb = *p;
+ calc_type r = (rgb >> 16) & 0xFFE0;
+ calc_type g = (rgb >> 5) & 0xFFE0;
+ calc_type b = (rgb << 6) & 0xFFC0;
+ *p = (pixel_type)
+ (((((cr - r) * alpha + (r << 16)) ) & 0xFFE00000) |
+ ((((cg - g) * alpha + (g << 16)) >> 11) & 0x001FFC00) |
+ (((cb - b) * alpha + (b << 16)) >> 22));
+ }
+
+ static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
+ {
+ return (pixel_type)(((r & 0xFFE0) << 16) | ((g & 0xFFE0) << 5) | (b >> 6));
+ }
+
+ static AGG_INLINE color_type make_color(pixel_type p)
+ {
+ return color_type((p >> 16) & 0xFFE0,
+ (p >> 5) & 0xFFE0,
+ (p << 6) & 0xFFC0);
+ }
+ };
+
+
+ //=================================================blender_rgbBBA_pre
+ struct blender_rgbBBA_pre
+ {
+ typedef rgba16 color_type;
+ typedef color_type::value_type value_type;
+ typedef color_type::calc_type calc_type;
+ typedef int32u pixel_type;
+
+ static AGG_INLINE void blend_pix(pixel_type* p,
+ unsigned cr, unsigned cg, unsigned cb,
+ unsigned alpha,
+ unsigned cover)
+ {
+ alpha = color_type::base_mask - alpha;
+ cover = (cover + 1) << (color_type::base_shift - 8);
+ pixel_type rgb = *p;
+ calc_type r = (rgb >> 16) & 0xFFE0;
+ calc_type g = (rgb >> 5) & 0xFFE0;
+ calc_type b = (rgb << 6) & 0xFFC0;
+ *p = (pixel_type)
+ ((((r * alpha + cr * cover) ) & 0xFFE00000) |
+ (((g * alpha + cg * cover) >> 11) & 0x001FFC00) |
+ ((b * alpha + cb * cover) >> 22));
+ }
+
+ static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
+ {
+ return (pixel_type)(((r & 0xFFE0) << 16) | ((g & 0xFFE0) << 5) | (b >> 6));
+ }
+
+ static AGG_INLINE color_type make_color(pixel_type p)
+ {
+ return color_type((p >> 16) & 0xFFE0,
+ (p >> 5) & 0xFFE0,
+ (p << 6) & 0xFFC0);
+ }
+ };
+
+
+
+ //=================================================blender_rgbBBA_gamma
+ template<class Gamma> class blender_rgbBBA_gamma
+ {
+ public:
+ typedef rgba16 color_type;
+ typedef color_type::value_type value_type;
+ typedef color_type::calc_type calc_type;
+ typedef int32u pixel_type;
+ typedef Gamma gamma_type;
+
+ blender_rgbBBA_gamma() : m_gamma(0) {}
+ void gamma(const gamma_type& g) { m_gamma = &g; }
+
+ AGG_INLINE void blend_pix(pixel_type* p,
+ unsigned cr, unsigned cg, unsigned cb,
+ unsigned alpha,
+ unsigned)
+ {
+ pixel_type rgb = *p;
+ calc_type r = m_gamma->dir((rgb >> 16) & 0xFFE0);
+ calc_type g = m_gamma->dir((rgb >> 5) & 0xFFE0);
+ calc_type b = m_gamma->dir((rgb << 6) & 0xFFC0);
+ *p = (pixel_type)
+ (((m_gamma->inv(((m_gamma->dir(cr) - r) * alpha + (r << 16)) >> 16) << 16) & 0xFFE00000) |
+ ((m_gamma->inv(((m_gamma->dir(cg) - g) * alpha + (g << 16)) >> 16) << 5 ) & 0x001FFC00) |
+ (m_gamma->inv(((m_gamma->dir(cb) - b) * alpha + (b << 16)) >> 16) >> 6 ));
+ }
+
+ static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
+ {
+ return (pixel_type)(((r & 0xFFE0) << 16) | ((g & 0xFFE0) << 5) | (b >> 6));
+ }
+
+ static AGG_INLINE color_type make_color(pixel_type p)
+ {
+ return color_type((p >> 16) & 0xFFE0,
+ (p >> 5) & 0xFFE0,
+ (p << 6) & 0xFFC0);
+ }
+
+ private:
+ const Gamma* m_gamma;
+ };
+
+
+ //=====================================================blender_bgrABB
+ struct blender_bgrABB
+ {
+ typedef rgba16 color_type;
+ typedef color_type::value_type value_type;
+ typedef color_type::calc_type calc_type;
+ typedef int32u pixel_type;
+
+ static AGG_INLINE void blend_pix(pixel_type* p,
+ unsigned cr, unsigned cg, unsigned cb,
+ unsigned alpha,
+ unsigned)
+ {
+ pixel_type bgr = *p;
+ calc_type b = (bgr >> 16) & 0xFFC0;
+ calc_type g = (bgr >> 6) & 0xFFE0;
+ calc_type r = (bgr << 5) & 0xFFE0;
+ *p = (pixel_type)
+ (((((cb - b) * alpha + (b << 16)) ) & 0xFFC00000) |
+ ((((cg - g) * alpha + (g << 16)) >> 10) & 0x003FF800) |
+ (((cr - r) * alpha + (r << 16)) >> 21));
+ }
+
+ static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
+ {
+ return (pixel_type)(((b & 0xFFC0) << 16) | ((g & 0xFFE0) << 6) | (r >> 5));
+ }
+
+ static AGG_INLINE color_type make_color(pixel_type p)
+ {
+ return color_type((p << 5) & 0xFFE0,
+ (p >> 6) & 0xFFE0,
+ (p >> 16) & 0xFFC0);
+ }
+ };
+
+
+ //=================================================blender_bgrABB_pre
+ struct blender_bgrABB_pre
+ {
+ typedef rgba16 color_type;
+ typedef color_type::value_type value_type;
+ typedef color_type::calc_type calc_type;
+ typedef int32u pixel_type;
+
+ static AGG_INLINE void blend_pix(pixel_type* p,
+ unsigned cr, unsigned cg, unsigned cb,
+ unsigned alpha,
+ unsigned cover)
+ {
+ alpha = color_type::base_mask - alpha;
+ cover = (cover + 1) << (color_type::base_shift - 8);
+ pixel_type bgr = *p;
+ calc_type b = (bgr >> 16) & 0xFFC0;
+ calc_type g = (bgr >> 6) & 0xFFE0;
+ calc_type r = (bgr << 5) & 0xFFE0;
+ *p = (pixel_type)
+ ((((b * alpha + cb * cover) ) & 0xFFC00000) |
+ (((g * alpha + cg * cover) >> 10) & 0x003FF800) |
+ ((r * alpha + cr * cover) >> 21));
+ }
+
+ static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
+ {
+ return (pixel_type)(((b & 0xFFC0) << 16) | ((g & 0xFFE0) << 6) | (r >> 5));
+ }
+
+ static AGG_INLINE color_type make_color(pixel_type p)
+ {
+ return color_type((p << 5) & 0xFFE0,
+ (p >> 6) & 0xFFE0,
+ (p >> 16) & 0xFFC0);
+ }
+ };
+
+
+
+ //=================================================blender_bgrABB_gamma
+ template<class Gamma> class blender_bgrABB_gamma
+ {
+ public:
+ typedef rgba16 color_type;
+ typedef color_type::value_type value_type;
+ typedef color_type::calc_type calc_type;
+ typedef int32u pixel_type;
+ typedef Gamma gamma_type;
+
+ blender_bgrABB_gamma() : m_gamma(0) {}
+ void gamma(const gamma_type& g) { m_gamma = &g; }
+
+ AGG_INLINE void blend_pix(pixel_type* p,
+ unsigned cr, unsigned cg, unsigned cb,
+ unsigned alpha,
+ unsigned)
+ {
+ pixel_type bgr = *p;
+ calc_type b = m_gamma->dir((bgr >> 16) & 0xFFC0);
+ calc_type g = m_gamma->dir((bgr >> 6) & 0xFFE0);
+ calc_type r = m_gamma->dir((bgr << 5) & 0xFFE0);
+ *p = (pixel_type)
+ (((m_gamma->inv(((m_gamma->dir(cb) - b) * alpha + (b << 16)) >> 16) << 16) & 0xFFC00000) |
+ ((m_gamma->inv(((m_gamma->dir(cg) - g) * alpha + (g << 16)) >> 16) << 6 ) & 0x003FF800) |
+ (m_gamma->inv(((m_gamma->dir(cr) - r) * alpha + (r << 16)) >> 16) >> 5 ));
+ }
+
+ static AGG_INLINE pixel_type make_pix(unsigned r, unsigned g, unsigned b)
+ {
+ return (pixel_type)(((b & 0xFFC0) << 16) | ((g & 0xFFE0) << 6) | (r >> 5));
+ }
+
+ static AGG_INLINE color_type make_color(pixel_type p)
+ {
+ return color_type((p << 5) & 0xFFE0,
+ (p >> 6) & 0xFFE0,
+ (p >> 16) & 0xFFC0);
+ }
+
+ private:
+ const Gamma* m_gamma;
+ };
+
+
+
+ //===========================================pixfmt_alpha_blend_rgb_packed
+ template<class Blender, class RenBuf> class pixfmt_alpha_blend_rgb_packed
+ {
+ public:
+ 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_scale = color_type::base_scale,
+ base_mask = color_type::base_mask,
+ pix_width = sizeof(pixel_type),
+ };
+
+ private:
+ //--------------------------------------------------------------------
+ AGG_INLINE void copy_or_blend_pix(pixel_type* p, const color_type& c, unsigned cover)
+ {
+ if (c.a)
+ {
+ calc_type alpha = (calc_type(c.a) * (cover + 1)) >> 8;
+ if(alpha == base_mask)
+ {
+ *p = m_blender.make_pix(c.r, c.g, c.b);
+ }
+ else
+ {
+ m_blender.blend_pix(p, c.r, c.g, c.b, alpha, cover);
+ }
+ }
+ }
+
+ public:
+ //--------------------------------------------------------------------
+ explicit pixfmt_alpha_blend_rgb_packed(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; }
+
+ //--------------------------------------------------------------------
+ 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)
+ {
+ 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 void make_pix(int8u* p, const color_type& c)
+ {
+ *(pixel_type*)p = m_blender.make_pix(c.r, c.g, c.b);
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE color_type pixel(int x, int y) const
+ {
+ 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_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_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_ptr(x, y, len) + x;
+ pixel_type v = m_blender.make_pix(c.r, c.g, c.b);
+ do
+ {
+ *p++ = v;
+ }
+ while(--len);
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE void copy_vline(int x, int y,
+ unsigned len,
+ const color_type& c)
+ {
+ 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;
+ }
+ while(--len);
+ }
+
+ //--------------------------------------------------------------------
+ void blend_hline(int x, int y,
+ unsigned len,
+ const color_type& c,
+ int8u cover)
+ {
+ if (c.a)
+ {
+ 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)
+ {
+ pixel_type v = m_blender.make_pix(c.r, c.g, c.b);
+ do
+ {
+ *p++ = v;
+ }
+ while(--len);
+ }
+ else
+ {
+ do
+ {
+ m_blender.blend_pix(p, c.r, c.g, c.b, alpha, cover);
+ ++p;
+ }
+ while(--len);
+ }
+ }
+ }
+
+ //--------------------------------------------------------------------
+ void blend_vline(int x, int y,
+ unsigned len,
+ const color_type& c,
+ int8u cover)
+ {
+ if (c.a)
+ {
+ 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
+ {
+ ((pixel_type*)m_rbuf->row_ptr(x, y++, 1))[x] = v;
+ }
+ while(--len);
+ }
+ else
+ {
+ do
+ {
+ 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_ptr(x, y, len) + x;
+ do
+ {
+ copy_or_blend_pix(p, c, *covers++);
+ ++p;
+ }
+ while(--len);
+ }
+
+ //--------------------------------------------------------------------
+ void blend_solid_vspan(int x, int y,
+ unsigned len,
+ const color_type& c,
+ const int8u* covers)
+ {
+ do
+ {
+ 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,
+ unsigned len,
+ const color_type* colors,
+ const int8u* covers,
+ int8u cover)
+ {
+ pixel_type* p = (pixel_type*)m_rbuf->row_ptr(x, y, len) + x;
+ do
+ {
+ copy_or_blend_pix(p++, *colors++, covers ? *covers++ : cover);
+ }
+ while(--len);
+ }
+
+ //--------------------------------------------------------------------
+ void blend_color_vspan(int x, int y,
+ unsigned len,
+ const color_type* colors,
+ const int8u* covers,
+ int8u cover)
+ {
+ do
+ {
+ copy_or_blend_pix((pixel_type*)m_rbuf->row_ptr(x, y++, 1) + x,
+ *colors++, covers ? *covers++ : cover);
+ }
+ while(--len);
+ }
+
+ //--------------------------------------------------------------------
+ template<class RenBuf2>
+ void copy_from(const RenBuf2& from,
+ int xdst, int ydst,
+ int xsrc, int ysrc,
+ unsigned len)
+ {
+ const int8u* p = from.row_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,
+ 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;
+ pixel_type* pdst =
+ (pixel_type*)m_rbuf->row_ptr(xdst, ydst, len) + xdst;
+ do
+ {
+ value_type alpha = psrc[src_order::A];
+ if(alpha)
+ {
+ 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);
+ }
+ }
+ psrc += 4;
+ ++pdst;
+ }
+ 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;
+ typedef typename SrcPixelFormatRenderer::color_type src_color_type;
+ const src_value_type* psrc = (src_value_type*)from.row_ptr(ysrc);
+ if(psrc)
+ {
+ psrc += xsrc * SrcPixelFormatRenderer::pix_step + SrcPixelFormatRenderer::pix_offset;
+ pixel_type* pdst =
+ (pixel_type*)m_rbuf->row_ptr(xdst, ydst, len) + xdst;
+
+ do
+ {
+ m_blender.blend_pix(pdst,
+ color.r, color.g, color.b, color.a,
+ cover);
+ psrc += SrcPixelFormatRenderer::pix_step;
+ ++pdst;
+ }
+ 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)
+ {
+ psrc += xsrc * SrcPixelFormatRenderer::pix_step + SrcPixelFormatRenderer::pix_offset;
+ pixel_type* pdst =
+ (pixel_type*)m_rbuf->row_ptr(xdst, ydst, len) + xdst;
+
+ do
+ {
+ const color_type& color = color_lut[*psrc];
+ m_blender.blend_pix(pdst,
+ color.r, color.g, color.b, color.a,
+ cover);
+ psrc += SrcPixelFormatRenderer::pix_step;
+ ++pdst;
+ }
+ while(--len);
+ }
+ }
+
+
+
+ private:
+ rbuf_type* m_rbuf;
+ Blender m_blender;
+ };
+
+ 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 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 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 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 pixfmt_alpha_blend_rgb_packed<blender_rgb555_gamma<Gamma>,
+ rendering_buffer>
+ {
+ public:
+ pixfmt_rgb555_gamma(rendering_buffer& rb, const Gamma& g) :
+ pixfmt_alpha_blend_rgb_packed<blender_rgb555_gamma<Gamma>,
+ rendering_buffer>(rb)
+ {
+ this->blender().gamma(g);
+ }
+ };
+
+
+ //-----------------------------------------------------pixfmt_rgb565_gamma
+ template<class Gamma> class pixfmt_rgb565_gamma :
+ public pixfmt_alpha_blend_rgb_packed<blender_rgb565_gamma<Gamma>, rendering_buffer>
+ {
+ public:
+ pixfmt_rgb565_gamma(rendering_buffer& rb, const Gamma& g) :
+ pixfmt_alpha_blend_rgb_packed<blender_rgb565_gamma<Gamma>, rendering_buffer>(rb)
+ {
+ this->blender().gamma(g);
+ }
+ };
+
+
+ //-----------------------------------------------------pixfmt_rgbAAA_gamma
+ template<class Gamma> class pixfmt_rgbAAA_gamma :
+ public pixfmt_alpha_blend_rgb_packed<blender_rgbAAA_gamma<Gamma>,
+ rendering_buffer>
+ {
+ public:
+ pixfmt_rgbAAA_gamma(rendering_buffer& rb, const Gamma& g) :
+ pixfmt_alpha_blend_rgb_packed<blender_rgbAAA_gamma<Gamma>,
+ rendering_buffer>(rb)
+ {
+ this->blender().gamma(g);
+ }
+ };
+
+
+ //-----------------------------------------------------pixfmt_bgrAAA_gamma
+ template<class Gamma> class pixfmt_bgrAAA_gamma :
+ public pixfmt_alpha_blend_rgb_packed<blender_bgrAAA_gamma<Gamma>,
+ rendering_buffer>
+ {
+ public:
+ pixfmt_bgrAAA_gamma(rendering_buffer& rb, const Gamma& g) :
+ pixfmt_alpha_blend_rgb_packed<blender_bgrAAA_gamma<Gamma>,
+ rendering_buffer>(rb)
+ {
+ this->blender().gamma(g);
+ }
+ };
+
+
+ //-----------------------------------------------------pixfmt_rgbBBA_gamma
+ template<class Gamma> class pixfmt_rgbBBA_gamma :
+ public pixfmt_alpha_blend_rgb_packed<blender_rgbBBA_gamma<Gamma>,
+ rendering_buffer>
+ {
+ public:
+ pixfmt_rgbBBA_gamma(rendering_buffer& rb, const Gamma& g) :
+ pixfmt_alpha_blend_rgb_packed<blender_rgbBBA_gamma<Gamma>,
+ rendering_buffer>(rb)
+ {
+ this->blender().gamma(g);
+ }
+ };
+
+
+ //-----------------------------------------------------pixfmt_bgrABB_gamma
+ template<class Gamma> class pixfmt_bgrABB_gamma :
+ public pixfmt_alpha_blend_rgb_packed<blender_bgrABB_gamma<Gamma>,
+ rendering_buffer>
+ {
+ public:
+ pixfmt_bgrABB_gamma(rendering_buffer& rb, const Gamma& g) :
+ pixfmt_alpha_blend_rgb_packed<blender_bgrABB_gamma<Gamma>,
+ rendering_buffer>(rb)
+ {
+ this->blender().gamma(g);
+ }
+ };
+
+
+}
+
+#endif
+
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pixfmt_transposer.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pixfmt_transposer.h
new file mode 100644
index 0000000000..64738b6c75
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pixfmt_transposer.h
@@ -0,0 +1,157 @@
+//----------------------------------------------------------------------------
+// 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_PIXFMT_TRANSPOSER_INCLUDED
+#define AGG_PIXFMT_TRANSPOSER_INCLUDED
+
+#include "agg_basics.h"
+
+namespace agg
+{
+ //=======================================================pixfmt_transposer
+ template<class PixFmt> class pixfmt_transposer
+ {
+ public:
+ typedef PixFmt pixfmt_type;
+ typedef typename pixfmt_type::color_type color_type;
+ typedef typename pixfmt_type::row_data row_data;
+ typedef typename color_type::value_type value_type;
+ typedef typename color_type::calc_type calc_type;
+
+ //--------------------------------------------------------------------
+ pixfmt_transposer() : m_pixf(0) {}
+ explicit pixfmt_transposer(pixfmt_type& pixf) : m_pixf(&pixf) {}
+ void attach(pixfmt_type& pixf) { m_pixf = &pixf; }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE unsigned width() const { return m_pixf->height(); }
+ AGG_INLINE unsigned height() const { return m_pixf->width(); }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE color_type pixel(int x, int y) const
+ {
+ return m_pixf->pixel(y, x);
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE void copy_pixel(int x, int y, const color_type& c)
+ {
+ m_pixf->copy_pixel(y, x, c);
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE void blend_pixel(int x, int y,
+ const color_type& c,
+ int8u cover)
+ {
+ m_pixf->blend_pixel(y, x, c, cover);
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE void copy_hline(int x, int y,
+ unsigned len,
+ const color_type& c)
+ {
+ m_pixf->copy_vline(y, x, len, c);
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE void copy_vline(int x, int y,
+ unsigned len,
+ const color_type& c)
+ {
+ m_pixf->copy_hline(y, x, len, c);
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE void blend_hline(int x, int y,
+ unsigned len,
+ const color_type& c,
+ int8u cover)
+ {
+ m_pixf->blend_vline(y, x, len, c, cover);
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE void blend_vline(int x, int y,
+ unsigned len,
+ const color_type& c,
+ int8u cover)
+ {
+ m_pixf->blend_hline(y, x, len, c, cover);
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE void blend_solid_hspan(int x, int y,
+ unsigned len,
+ const color_type& c,
+ const int8u* covers)
+ {
+ m_pixf->blend_solid_vspan(y, x, len, c, covers);
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE void blend_solid_vspan(int x, int y,
+ unsigned len,
+ const color_type& c,
+ const int8u* covers)
+ {
+ m_pixf->blend_solid_hspan(y, x, len, c, covers);
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE void copy_color_hspan(int x, int y,
+ unsigned len,
+ const color_type* colors)
+ {
+ m_pixf->copy_color_vspan(y, x, len, colors);
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE void copy_color_vspan(int x, int y,
+ unsigned len,
+ const color_type* colors)
+ {
+ m_pixf->copy_color_hspan(y, x, len, colors);
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE void blend_color_hspan(int x, int y,
+ unsigned len,
+ const color_type* colors,
+ const int8u* covers,
+ int8u cover)
+ {
+ m_pixf->blend_color_vspan(y, x, len, colors, covers, cover);
+ }
+
+ //--------------------------------------------------------------------
+ AGG_INLINE void blend_color_vspan(int x, int y,
+ unsigned len,
+ const color_type* colors,
+ const int8u* covers,
+ int8u cover)
+ {
+ m_pixf->blend_color_hspan(y, x, len, colors, covers, cover);
+ }
+
+ private:
+ pixfmt_type* m_pixf;
+ };
+}
+
+#endif
+
+
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rasterizer_compound_aa.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rasterizer_compound_aa.h
new file mode 100644
index 0000000000..41d508010e
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rasterizer_compound_aa.h
@@ -0,0 +1,663 @@
+//----------------------------------------------------------------------------
+// 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(unsigned cell_block_limit=1024) :
+ m_outline(cell_block_limit),
+ 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_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 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) 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;
+ }
+
+ //--------------------------------------------------------------------
+ // 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();
+
+ if(style_idx < 0)
+ {
+ style_idx = 0;
+ }
+ else
+ {
+ style_idx++;
+ }
+
+ 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);
+ sl.add_cell(x, alpha);
+ x++;
+ }
+
+ if(num_cells && cell->x > x)
+ {
+ alpha = calculate_alpha(cover << (poly_subpixel_shift + 1));
+ 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);
+
+ //--------------------------------------------------------------------
+ // 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;
+
+ 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);
+ 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);
+ 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];
+ }
+
+}
+
+
+
+#endif
+
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rasterizer_outline.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rasterizer_outline.h
new file mode 100644
index 0000000000..65203e34c5
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rasterizer_outline.h
@@ -0,0 +1,147 @@
+//----------------------------------------------------------------------------
+// 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_OUTLINE_INCLUDED
+#define AGG_RASTERIZER_OUTLINE_INCLUDED
+
+#include "agg_basics.h"
+
+namespace agg
+{
+ //======================================================rasterizer_outline
+ template<class Renderer> class rasterizer_outline
+ {
+ public:
+ 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)
+ {
+ m_vertices = 1;
+ m_ren->move_to(m_start_x = x, m_start_y = y);
+ }
+
+ //--------------------------------------------------------------------
+ void line_to(int x, int y)
+ {
+ ++m_vertices;
+ m_ren->line_to(x, y);
+ }
+
+ //--------------------------------------------------------------------
+ void move_to_d(double x, double y)
+ {
+ move_to(m_ren->coord(x), m_ren->coord(y));
+ }
+
+ //--------------------------------------------------------------------
+ void line_to_d(double x, double y)
+ {
+ line_to(m_ren->coord(x), m_ren->coord(y));
+ }
+
+ //--------------------------------------------------------------------
+ void close()
+ {
+ if(m_vertices > 2)
+ {
+ line_to(m_start_x, m_start_y);
+ }
+ m_vertices = 0;
+ }
+
+ //--------------------------------------------------------------------
+ void add_vertex(double x, double y, unsigned cmd)
+ {
+ if(is_move_to(cmd))
+ {
+ move_to_d(x, y);
+ }
+ else
+ {
+ if(is_end_poly(cmd))
+ {
+ if(is_closed(cmd)) close();
+ }
+ else
+ {
+ line_to_d(x, y);
+ }
+ }
+ }
+
+
+ //--------------------------------------------------------------------
+ template<class VertexSource>
+ void add_path(VertexSource& vs, unsigned path_id=0)
+ {
+ double x;
+ double y;
+
+ unsigned cmd;
+ vs.rewind(path_id);
+ while(!is_stop(cmd = vs.vertex(&x, &y)))
+ {
+ add_vertex(x, y, cmd);
+ }
+ }
+
+
+ //--------------------------------------------------------------------
+ template<class VertexSource, class ColorStorage, class PathId>
+ void render_all_paths(VertexSource& vs,
+ const ColorStorage& colors,
+ const PathId& path_id,
+ unsigned num_paths)
+ {
+ for(unsigned i = 0; i < num_paths; i++)
+ {
+ m_ren->line_color(colors[i]);
+ add_path(vs, path_id[i]);
+ }
+ }
+
+
+ //--------------------------------------------------------------------
+ template<class Ctrl> void render_ctrl(Ctrl& c)
+ {
+ unsigned i;
+ for(i = 0; i < c.num_paths(); i++)
+ {
+ m_ren->line_color(c.color(i));
+ add_path(c, i);
+ }
+ }
+
+
+ private:
+ Renderer* m_ren;
+ int m_start_x;
+ int m_start_y;
+ unsigned m_vertices;
+ };
+
+
+}
+
+
+#endif
+
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rasterizer_outline_aa.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rasterizer_outline_aa.h
new file mode 100644
index 0000000000..a06bd1e843
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rasterizer_outline_aa.h
@@ -0,0 +1,599 @@
+//----------------------------------------------------------------------------
+// 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_OUTLINE_AA_INCLUDED
+#define AGG_RASTERIZER_OUTLINE_AA_INCLUDED
+
+#include "agg_basics.h"
+#include "agg_line_aa_basics.h"
+#include "agg_vertex_sequence.h"
+
+namespace agg
+{
+
+ //-------------------------------------------------------------------------
+ inline bool cmp_dist_start(int d) { return d > 0; }
+ inline bool cmp_dist_end(int d) { return d <= 0; }
+
+
+
+ //-----------------------------------------------------------line_aa_vertex
+ // Vertex (x, y) with the distance to the next one. The last vertex has
+ // the distance between the last and the first points
+ struct line_aa_vertex
+ {
+ int x;
+ int y;
+ int len;
+
+ line_aa_vertex() {}
+ line_aa_vertex(int x_, int y_) :
+ x(x_),
+ y(y_),
+ len(0)
+ {
+ }
+
+ bool operator () (const line_aa_vertex& val)
+ {
+ double dx = val.x - x;
+ double dy = val.y - y;
+ 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 Coord=line_coord> class rasterizer_outline_aa
+ {
+ private:
+ //------------------------------------------------------------------------
+ struct draw_vars
+ {
+ unsigned idx;
+ int x1, y1, x2, y2;
+ line_parameters curr, next;
+ int lcurr, lnext;
+ int xb1, yb1, xb2, yb2;
+ unsigned flags;
+ };
+
+ void draw(draw_vars& dv, unsigned start, unsigned end);
+
+ public:
+ typedef line_aa_vertex vertex_type;
+ typedef vertex_sequence<vertex_type, 6> vertex_storage_type;
+
+ 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 line_join(outline_aa_join_e join)
+ {
+ m_line_join = m_ren->accurate_join_only() ?
+ outline_miter_accurate_join :
+ join;
+ }
+ bool line_join() const { return m_line_join; }
+
+ //------------------------------------------------------------------------
+ void round_cap(bool v) { m_round_cap = v; }
+ bool round_cap() const { return m_round_cap; }
+
+ //------------------------------------------------------------------------
+ void move_to(int x, int y)
+ {
+ m_src_vertices.modify_last(vertex_type(m_start_x = x, m_start_y = y));
+ }
+
+ //------------------------------------------------------------------------
+ void line_to(int x, int y)
+ {
+ m_src_vertices.add(vertex_type(x, y));
+ }
+
+ //------------------------------------------------------------------------
+ void move_to_d(double x, double y)
+ {
+ move_to(Coord::conv(x), Coord::conv(y));
+ }
+
+ //------------------------------------------------------------------------
+ void line_to_d(double x, double y)
+ {
+ line_to(Coord::conv(x), Coord::conv(y));
+ }
+
+ //------------------------------------------------------------------------
+ void render(bool close_polygon);
+
+ //------------------------------------------------------------------------
+ void add_vertex(double x, double y, unsigned cmd)
+ {
+ if(is_move_to(cmd))
+ {
+ render(false);
+ move_to_d(x, y);
+ }
+ else
+ {
+ if(is_end_poly(cmd))
+ {
+ render(is_closed(cmd));
+ if(is_closed(cmd))
+ {
+ move_to(m_start_x, m_start_y);
+ }
+ }
+ else
+ {
+ line_to_d(x, y);
+ }
+ }
+ }
+
+ //------------------------------------------------------------------------
+ template<class VertexSource>
+ void add_path(VertexSource& vs, unsigned path_id=0)
+ {
+ double x;
+ double y;
+
+ unsigned cmd;
+ vs.rewind(path_id);
+ while(!is_stop(cmd = vs.vertex(&x, &y)))
+ {
+ add_vertex(x, y, cmd);
+ }
+ render(false);
+ }
+
+
+ //------------------------------------------------------------------------
+ template<class VertexSource, class ColorStorage, class PathId>
+ void render_all_paths(VertexSource& vs,
+ const ColorStorage& colors,
+ const PathId& path_id,
+ unsigned num_paths)
+ {
+ for(unsigned i = 0; i < num_paths; i++)
+ {
+ m_ren->color(colors[i]);
+ add_path(vs, path_id[i]);
+ }
+ }
+
+
+ //------------------------------------------------------------------------
+ template<class Ctrl> void render_ctrl(Ctrl& c)
+ {
+ unsigned i;
+ for(i = 0; i < c.num_paths(); i++)
+ {
+ m_ren->color(c.color(i));
+ add_path(c, i);
+ }
+ }
+
+ private:
+ 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;
+ vertex_storage_type m_src_vertices;
+ outline_aa_join_e m_line_join;
+ bool m_round_cap;
+ int m_start_x;
+ int m_start_y;
+ };
+
+
+
+
+
+
+
+
+ //----------------------------------------------------------------------------
+ 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;
+ }
+
+ 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;
+ dv.y1 = dv.y2;
+ dv.lcurr = dv.lnext;
+ dv.lnext = m_src_vertices[dv.idx].len;
+
+ ++dv.idx;
+ if(dv.idx >= m_src_vertices.size()) dv.idx = 0;
+
+ v = &m_src_vertices[dv.idx];
+ dv.x2 = v->x;
+ dv.y2 = v->y;
+
+ dv.curr = dv.next;
+ dv.next = line_parameters(dv.x1, dv.y1, dv.x2, dv.y2, dv.lnext);
+ dv.xb1 = dv.xb2;
+ dv.yb1 = dv.yb2;
+
+ 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;
+
+ 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;
+ }
+ }
+ }
+
+
+
+
+ //----------------------------------------------------------------------------
+ template<class Renderer, class Coord>
+ void rasterizer_outline_aa<Renderer, Coord>::render(bool close_polygon)
+ {
+ m_src_vertices.close(close_polygon);
+ draw_vars dv;
+ const vertex_storage_type::value_type* v;
+ int x1;
+ int y1;
+ int x2;
+ int y2;
+ int lprev;
+
+ if(close_polygon)
+ {
+ if(m_src_vertices.size() >= 3)
+ {
+ dv.idx = 2;
+
+ v = &m_src_vertices[m_src_vertices.size() - 1];
+ x1 = v->x;
+ y1 = v->y;
+ lprev = v->len;
+
+ v = &m_src_vertices[0];
+ x2 = v->x;
+ y2 = v->y;
+ dv.lcurr = v->len;
+ line_parameters prev(x1, y1, x2, y2, lprev);
+
+ v = &m_src_vertices[1];
+ dv.x1 = v->x;
+ dv.y1 = v->y;
+ dv.lnext = v->len;
+ dv.curr = line_parameters(x2, y2, dv.x1, dv.y1, dv.lcurr);
+
+ v = &m_src_vertices[dv.idx];
+ dv.x2 = v->x;
+ dv.y2 = v->y;
+ dv.next = line_parameters(dv.x1, dv.y1, dv.x2, dv.y2, dv.lnext);
+
+ dv.xb1 = 0;
+ dv.yb1 = 0;
+ dv.xb2 = 0;
+ dv.yb2 = 0;
+
+ 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 && m_line_join != outline_round_join)
+ {
+ bisectrix(prev, dv.curr, &dv.xb1, &dv.yb1);
+ }
+
+ if((dv.flags & 2) == 0 && m_line_join != outline_round_join)
+ {
+ bisectrix(dv.curr, dv.next, &dv.xb2, &dv.yb2);
+ }
+ draw(dv, 0, m_src_vertices.size());
+ }
+ }
+ else
+ {
+ switch(m_src_vertices.size())
+ {
+ case 0:
+ case 1:
+ break;
+
+ case 2:
+ {
+ v = &m_src_vertices[0];
+ x1 = v->x;
+ y1 = v->y;
+ lprev = v->len;
+ v = &m_src_vertices[1];
+ x2 = v->x;
+ y2 = v->y;
+ 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->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));
+ }
+ }
+ break;
+
+ case 3:
+ {
+ int x3, y3;
+ int lnext;
+ v = &m_src_vertices[0];
+ x1 = v->x;
+ y1 = v->y;
+ lprev = v->len;
+ v = &m_src_vertices[1];
+ x2 = v->x;
+ y2 = v->y;
+ lnext = v->len;
+ v = &m_src_vertices[2];
+ x3 = v->x;
+ y3 = v->y;
+ line_parameters lp1(x1, y1, x2, y2, lprev);
+ line_parameters lp2(x2, y2, x3, y3, lnext);
+
+ if(m_round_cap)
+ {
+ 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));
+ }
+ if(m_round_cap)
+ {
+ m_ren->semidot(cmp_dist_end, x3, y3, x3 + (y3 - y2), y3 - (x3 - x2));
+ }
+ }
+ break;
+
+ default:
+ {
+ dv.idx = 3;
+
+ v = &m_src_vertices[0];
+ x1 = v->x;
+ y1 = v->y;
+ lprev = v->len;
+
+ v = &m_src_vertices[1];
+ x2 = v->x;
+ y2 = v->y;
+ dv.lcurr = v->len;
+ line_parameters prev(x1, y1, x2, y2, lprev);
+
+ v = &m_src_vertices[2];
+ dv.x1 = v->x;
+ dv.y1 = v->y;
+ dv.lnext = v->len;
+ dv.curr = line_parameters(x2, y2, dv.x1, dv.y1, dv.lcurr);
+
+ v = &m_src_vertices[dv.idx];
+ dv.x2 = v->x;
+ dv.y2 = v->y;
+ dv.next = line_parameters(dv.x1, dv.y1, dv.x2, dv.y2, dv.lnext);
+
+ dv.xb1 = 0;
+ dv.yb1 = 0;
+ dv.xb2 = 0;
+ dv.yb2 = 0;
+
+ 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(m_round_cap)
+ {
+ m_ren->semidot(cmp_dist_start, x1, y1, x1 + (y2 - y1), y1 - (x2 - x1));
+ }
+ if((dv.flags & 1) == 0)
+ {
+ 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);
+ }
+ }
+ else
+ {
+ m_ren->line1(prev,
+ x1 + (y2 - y1),
+ y1 - (x2 - x1));
+ }
+ if((dv.flags & 2) == 0 && m_line_join != outline_round_join)
+ {
+ bisectrix(dv.curr, dv.next, &dv.xb2, &dv.yb2);
+ }
+
+ draw(dv, 1, m_src_vertices.size() - 2);
+
+ if((dv.flags & 1) == 0)
+ {
+ 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));
+ }
+ 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));
+ }
+
+ }
+ break;
+ }
+ }
+ m_src_vertices.remove_all();
+ }
+
+
+}
+
+
+#endif
+
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_markers.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_markers.h
new file mode 100644
index 0000000000..820f753079
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_markers.h
@@ -0,0 +1,706 @@
+//----------------------------------------------------------------------------
+// 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
+//----------------------------------------------------------------------------
+//
+// class renderer_markers
+//
+//----------------------------------------------------------------------------
+
+#ifndef AGG_RENDERER_MARKERS_INCLUDED
+#define AGG_RENDERER_MARKERS_INCLUDED
+
+#include "agg_basics.h"
+#include "agg_renderer_primitives.h"
+
+namespace agg
+{
+
+ //---------------------------------------------------------------marker_e
+ enum marker_e
+ {
+ marker_square,
+ marker_diamond,
+ marker_circle,
+ marker_crossed_circle,
+ marker_semiellipse_left,
+ marker_semiellipse_right,
+ marker_semiellipse_up,
+ marker_semiellipse_down,
+ marker_triangle_left,
+ marker_triangle_right,
+ marker_triangle_up,
+ marker_triangle_down,
+ marker_four_rays,
+ marker_cross,
+ marker_x,
+ marker_dash,
+ marker_dot,
+ marker_pixel,
+
+ end_of_markers
+ };
+
+
+
+ //--------------------------------------------------------renderer_markers
+ template<class BaseRenderer> class renderer_markers :
+ public renderer_primitives<BaseRenderer>
+ {
+ public:
+ typedef renderer_primitives<BaseRenderer> base_type;
+ typedef BaseRenderer base_ren_type;
+ typedef typename base_ren_type::color_type color_type;
+
+ //--------------------------------------------------------------------
+ renderer_markers(base_ren_type& rbuf) :
+ base_type(rbuf)
+ {}
+
+ //--------------------------------------------------------------------
+ bool visible(int x, int y, int r) const
+ {
+ rect_i rc(x-r, y-r, x+y, y+r);
+ return rc.clip(base_type::ren().bounding_clip_box());
+ }
+
+ //--------------------------------------------------------------------
+ void square(int x, int y, int r)
+ {
+ if(visible(x, y, r))
+ {
+ if(r) base_type::outlined_rectangle(x-r, y-r, x+r, y+r);
+ else base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
+ }
+ }
+
+ //--------------------------------------------------------------------
+ void diamond(int x, int y, int r)
+ {
+ if(visible(x, y, r))
+ {
+ if(r)
+ {
+ int dy = -r;
+ int dx = 0;
+ do
+ {
+ base_type::ren().blend_pixel(x - dx, y + dy, base_type::line_color(), cover_full);
+ base_type::ren().blend_pixel(x + dx, y + dy, base_type::line_color(), cover_full);
+ base_type::ren().blend_pixel(x - dx, y - dy, base_type::line_color(), cover_full);
+ base_type::ren().blend_pixel(x + dx, y - dy, base_type::line_color(), cover_full);
+
+ if(dx)
+ {
+ base_type::ren().blend_hline(x-dx+1, y+dy, x+dx-1, base_type::fill_color(), cover_full);
+ base_type::ren().blend_hline(x-dx+1, y-dy, x+dx-1, base_type::fill_color(), cover_full);
+ }
+ ++dy;
+ ++dx;
+ }
+ while(dy <= 0);
+ }
+ else
+ {
+ base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
+ }
+ }
+ }
+
+ //--------------------------------------------------------------------
+ void circle(int x, int y, int r)
+ {
+ if(visible(x, y, r))
+ {
+ if(r) base_type::outlined_ellipse(x, y, r, r);
+ else base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
+ }
+ }
+
+
+
+ //--------------------------------------------------------------------
+ void crossed_circle(int x, int y, int r)
+ {
+ if(visible(x, y, r))
+ {
+ if(r)
+ {
+ base_type::outlined_ellipse(x, y, r, r);
+ int r6 = r + (r >> 1);
+ if(r <= 2) r6++;
+ r >>= 1;
+ base_type::ren().blend_hline(x-r6, y, x-r, base_type::line_color(), cover_full);
+ base_type::ren().blend_hline(x+r, y, x+r6, base_type::line_color(), cover_full);
+ base_type::ren().blend_vline(x, y-r6, y-r, base_type::line_color(), cover_full);
+ base_type::ren().blend_vline(x, y+r, y+r6, base_type::line_color(), cover_full);
+ }
+ else
+ {
+ base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
+ }
+ }
+ }
+
+
+ //------------------------------------------------------------------------
+ void semiellipse_left(int x, int y, int r)
+ {
+ if(visible(x, y, r))
+ {
+ if(r)
+ {
+ int r8 = r * 4 / 5;
+ int dy = -r;
+ int dx = 0;
+ ellipse_bresenham_interpolator ei(r * 3 / 5, r+r8);
+ do
+ {
+ dx += ei.dx();
+ dy += ei.dy();
+
+ base_type::ren().blend_pixel(x + dy, y + dx, base_type::line_color(), cover_full);
+ base_type::ren().blend_pixel(x + dy, y - dx, base_type::line_color(), cover_full);
+
+ if(ei.dy() && dx)
+ {
+ base_type::ren().blend_vline(x+dy, y-dx+1, y+dx-1, base_type::fill_color(), cover_full);
+ }
+ ++ei;
+ }
+ while(dy < r8);
+ base_type::ren().blend_vline(x+dy, y-dx, y+dx, base_type::line_color(), cover_full);
+ }
+ else
+ {
+ base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
+ }
+ }
+ }
+
+
+ //--------------------------------------------------------------------
+ void semiellipse_right(int x, int y, int r)
+ {
+ if(visible(x, y, r))
+ {
+ if(r)
+ {
+ int r8 = r * 4 / 5;
+ int dy = -r;
+ int dx = 0;
+ ellipse_bresenham_interpolator ei(r * 3 / 5, r+r8);
+ do
+ {
+ dx += ei.dx();
+ dy += ei.dy();
+
+ base_type::ren().blend_pixel(x - dy, y + dx, base_type::line_color(), cover_full);
+ base_type::ren().blend_pixel(x - dy, y - dx, base_type::line_color(), cover_full);
+
+ if(ei.dy() && dx)
+ {
+ base_type::ren().blend_vline(x-dy, y-dx+1, y+dx-1, base_type::fill_color(), cover_full);
+ }
+ ++ei;
+ }
+ while(dy < r8);
+ base_type::ren().blend_vline(x-dy, y-dx, y+dx, base_type::line_color(), cover_full);
+ }
+ else
+ {
+ base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
+ }
+ }
+ }
+
+
+ //--------------------------------------------------------------------
+ void semiellipse_up(int x, int y, int r)
+ {
+ if(visible(x, y, r))
+ {
+ if(r)
+ {
+ int r8 = r * 4 / 5;
+ int dy = -r;
+ int dx = 0;
+ ellipse_bresenham_interpolator ei(r * 3 / 5, r+r8);
+ do
+ {
+ dx += ei.dx();
+ dy += ei.dy();
+
+ base_type::ren().blend_pixel(x + dx, y - dy, base_type::line_color(), cover_full);
+ base_type::ren().blend_pixel(x - dx, y - dy, base_type::line_color(), cover_full);
+
+ if(ei.dy() && dx)
+ {
+ base_type::ren().blend_hline(x-dx+1, y-dy, x+dx-1, base_type::fill_color(), cover_full);
+ }
+ ++ei;
+ }
+ while(dy < r8);
+ base_type::ren().blend_hline(x-dx, y-dy-1, x+dx, base_type::line_color(), cover_full);
+ }
+ else
+ {
+ base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
+ }
+ }
+ }
+
+
+ //--------------------------------------------------------------------
+ void semiellipse_down(int x, int y, int r)
+ {
+ if(visible(x, y, r))
+ {
+ if(r)
+ {
+ int r8 = r * 4 / 5;
+ int dy = -r;
+ int dx = 0;
+ ellipse_bresenham_interpolator ei(r * 3 / 5, r+r8);
+ do
+ {
+ dx += ei.dx();
+ dy += ei.dy();
+
+ base_type::ren().blend_pixel(x + dx, y + dy, base_type::line_color(), cover_full);
+ base_type::ren().blend_pixel(x - dx, y + dy, base_type::line_color(), cover_full);
+
+ if(ei.dy() && dx)
+ {
+ base_type::ren().blend_hline(x-dx+1, y+dy, x+dx-1, base_type::fill_color(), cover_full);
+ }
+ ++ei;
+ }
+ while(dy < r8);
+ base_type::ren().blend_hline(x-dx, y+dy+1, x+dx, base_type::line_color(), cover_full);
+ }
+ else
+ {
+ base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
+ }
+ }
+ }
+
+
+ //--------------------------------------------------------------------
+ void triangle_left(int x, int y, int r)
+ {
+ if(visible(x, y, r))
+ {
+ if(r)
+ {
+ int dy = -r;
+ int dx = 0;
+ int flip = 0;
+ int r6 = r * 3 / 5;
+ do
+ {
+ base_type::ren().blend_pixel(x + dy, y - dx, base_type::line_color(), cover_full);
+ base_type::ren().blend_pixel(x + dy, y + dx, base_type::line_color(), cover_full);
+
+ if(dx)
+ {
+ base_type::ren().blend_vline(x+dy, y-dx+1, y+dx-1, base_type::fill_color(), cover_full);
+ }
+ ++dy;
+ dx += flip;
+ flip ^= 1;
+ }
+ while(dy < r6);
+ base_type::ren().blend_vline(x+dy, y-dx, y+dx, base_type::line_color(), cover_full);
+ }
+ else
+ {
+ base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
+ }
+ }
+ }
+
+
+ //--------------------------------------------------------------------
+ void triangle_right(int x, int y, int r)
+ {
+ if(visible(x, y, r))
+ {
+ if(r)
+ {
+ int dy = -r;
+ int dx = 0;
+ int flip = 0;
+ int r6 = r * 3 / 5;
+ do
+ {
+ base_type::ren().blend_pixel(x - dy, y - dx, base_type::line_color(), cover_full);
+ base_type::ren().blend_pixel(x - dy, y + dx, base_type::line_color(), cover_full);
+
+ if(dx)
+ {
+ base_type::ren().blend_vline(x-dy, y-dx+1, y+dx-1, base_type::fill_color(), cover_full);
+ }
+ ++dy;
+ dx += flip;
+ flip ^= 1;
+ }
+ while(dy < r6);
+ base_type::ren().blend_vline(x-dy, y-dx, y+dx, base_type::line_color(), cover_full);
+ }
+ else
+ {
+ base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
+ }
+ }
+ }
+
+
+ //--------------------------------------------------------------------
+ void triangle_up(int x, int y, int r)
+ {
+ if(visible(x, y, r))
+ {
+ if(r)
+ {
+ int dy = -r;
+ int dx = 0;
+ int flip = 0;
+ int r6 = r * 3 / 5;
+ do
+ {
+ base_type::ren().blend_pixel(x - dx, y - dy, base_type::line_color(), cover_full);
+ base_type::ren().blend_pixel(x + dx, y - dy, base_type::line_color(), cover_full);
+
+ if(dx)
+ {
+ base_type::ren().blend_hline(x-dx+1, y-dy, x+dx-1, base_type::fill_color(), cover_full);
+ }
+ ++dy;
+ dx += flip;
+ flip ^= 1;
+ }
+ while(dy < r6);
+ base_type::ren().blend_hline(x-dx, y-dy, x+dx, base_type::line_color(), cover_full);
+ }
+ else
+ {
+ base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
+ }
+ }
+ }
+
+
+ //--------------------------------------------------------------------
+ void triangle_down(int x, int y, int r)
+ {
+ if(visible(x, y, r))
+ {
+ if(r)
+ {
+ int dy = -r;
+ int dx = 0;
+ int flip = 0;
+ int r6 = r * 3 / 5;
+ do
+ {
+ base_type::ren().blend_pixel(x - dx, y + dy, base_type::line_color(), cover_full);
+ base_type::ren().blend_pixel(x + dx, y + dy, base_type::line_color(), cover_full);
+
+ if(dx)
+ {
+ base_type::ren().blend_hline(x-dx+1, y+dy, x+dx-1, base_type::fill_color(), cover_full);
+ }
+ ++dy;
+ dx += flip;
+ flip ^= 1;
+ }
+ while(dy < r6);
+ base_type::ren().blend_hline(x-dx, y+dy, x+dx, base_type::line_color(), cover_full);
+ }
+ else
+ {
+ base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
+ }
+ }
+ }
+
+
+ //--------------------------------------------------------------------
+ void four_rays(int x, int y, int r)
+ {
+ if(visible(x, y, r))
+ {
+ if(r)
+ {
+ int dy = -r;
+ int dx = 0;
+ int flip = 0;
+ int r3 = -(r / 3);
+ do
+ {
+ base_type::ren().blend_pixel(x - dx, y + dy, base_type::line_color(), cover_full);
+ base_type::ren().blend_pixel(x + dx, y + dy, base_type::line_color(), cover_full);
+ base_type::ren().blend_pixel(x - dx, y - dy, base_type::line_color(), cover_full);
+ base_type::ren().blend_pixel(x + dx, y - dy, base_type::line_color(), cover_full);
+ base_type::ren().blend_pixel(x + dy, y - dx, base_type::line_color(), cover_full);
+ base_type::ren().blend_pixel(x + dy, y + dx, base_type::line_color(), cover_full);
+ base_type::ren().blend_pixel(x - dy, y - dx, base_type::line_color(), cover_full);
+ base_type::ren().blend_pixel(x - dy, y + dx, base_type::line_color(), cover_full);
+
+ if(dx)
+ {
+ base_type::ren().blend_hline(x-dx+1, y+dy, x+dx-1, base_type::fill_color(), cover_full);
+ base_type::ren().blend_hline(x-dx+1, y-dy, x+dx-1, base_type::fill_color(), cover_full);
+ base_type::ren().blend_vline(x+dy, y-dx+1, y+dx-1, base_type::fill_color(), cover_full);
+ base_type::ren().blend_vline(x-dy, y-dx+1, y+dx-1, base_type::fill_color(), cover_full);
+ }
+ ++dy;
+ dx += flip;
+ flip ^= 1;
+ }
+ while(dy <= r3);
+ base_type::solid_rectangle(x+r3+1, y+r3+1, x-r3-1, y-r3-1);
+ }
+ else
+ {
+ base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
+ }
+ }
+ }
+
+
+ //--------------------------------------------------------------------
+ void cross(int x, int y, int r)
+ {
+ if(visible(x, y, r))
+ {
+ if(r)
+ {
+ base_type::ren().blend_vline(x, y-r, y+r, base_type::line_color(), cover_full);
+ base_type::ren().blend_hline(x-r, y, x+r, base_type::line_color(), cover_full);
+ }
+ else
+ {
+ base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
+ }
+ }
+ }
+
+
+ //--------------------------------------------------------------------
+ void xing(int x, int y, int r)
+ {
+ if(visible(x, y, r))
+ {
+ if(r)
+ {
+ int dy = -r * 7 / 10;
+ do
+ {
+ base_type::ren().blend_pixel(x + dy, y + dy, base_type::line_color(), cover_full);
+ base_type::ren().blend_pixel(x - dy, y + dy, base_type::line_color(), cover_full);
+ base_type::ren().blend_pixel(x + dy, y - dy, base_type::line_color(), cover_full);
+ base_type::ren().blend_pixel(x - dy, y - dy, base_type::line_color(), cover_full);
+ ++dy;
+ }
+ while(dy < 0);
+ }
+ base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
+ }
+ }
+
+
+ //--------------------------------------------------------------------
+ void dash(int x, int y, int r)
+ {
+ if(visible(x, y, r))
+ {
+ if(r) base_type::ren().blend_hline(x-r, y, x+r, base_type::line_color(), cover_full);
+ else base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
+ }
+ }
+
+
+ //--------------------------------------------------------------------
+ void dot(int x, int y, int r)
+ {
+ if(visible(x, y, r))
+ {
+ if(r) base_type::solid_ellipse(x, y, r, r);
+ else base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
+ }
+ }
+
+ //--------------------------------------------------------------------
+ void pixel(int x, int y, int)
+ {
+ base_type::ren().blend_pixel(x, y, base_type::fill_color(), cover_full);
+ }
+
+ //--------------------------------------------------------------------
+ void marker(int x, int y, int r, marker_e type)
+ {
+ switch(type)
+ {
+ case marker_square: square(x, y, r); break;
+ case marker_diamond: diamond(x, y, r); break;
+ case marker_circle: circle(x, y, r); break;
+ case marker_crossed_circle: crossed_circle(x, y, r); break;
+ case marker_semiellipse_left: semiellipse_left(x, y, r); break;
+ case marker_semiellipse_right: semiellipse_right(x, y, r); break;
+ case marker_semiellipse_up: semiellipse_up(x, y, r); break;
+ case marker_semiellipse_down: semiellipse_down(x, y, r); break;
+ case marker_triangle_left: triangle_left(x, y, r); break;
+ case marker_triangle_right: triangle_right(x, y, r); break;
+ case marker_triangle_up: triangle_up(x, y, r); break;
+ case marker_triangle_down: triangle_down(x, y, r); break;
+ case marker_four_rays: four_rays(x, y, r); break;
+ case marker_cross: cross(x, y, r); break;
+ case marker_x: xing(x, y, r); break;
+ case marker_dash: dash(x, y, r); break;
+ case marker_dot: dot(x, y, r); break;
+ case marker_pixel: pixel(x, y, r); break;
+ }
+ }
+
+
+ //--------------------------------------------------------------------
+ template<class T>
+ void markers(int n, const T* x, const T* y, T r, marker_e type)
+ {
+ if(n <= 0) return;
+ if(r == 0)
+ {
+ do
+ {
+ base_type::ren().blend_pixel(int(*x), int(*y), base_type::fill_color(), cover_full);
+ ++x;
+ ++y;
+ }
+ while(--n);
+ return;
+ }
+
+ switch(type)
+ {
+ case marker_square: do { square (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
+ case marker_diamond: do { diamond (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
+ case marker_circle: do { circle (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
+ case marker_crossed_circle: do { crossed_circle (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
+ case marker_semiellipse_left: do { semiellipse_left (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
+ case marker_semiellipse_right: do { semiellipse_right(int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
+ case marker_semiellipse_up: do { semiellipse_up (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
+ case marker_semiellipse_down: do { semiellipse_down (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
+ case marker_triangle_left: do { triangle_left (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
+ case marker_triangle_right: do { triangle_right (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
+ case marker_triangle_up: do { triangle_up (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
+ case marker_triangle_down: do { triangle_down (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
+ case marker_four_rays: do { four_rays (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
+ case marker_cross: do { cross (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
+ case marker_x: do { xing (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
+ case marker_dash: do { dash (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
+ case marker_dot: do { dot (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
+ case marker_pixel: do { pixel (int(*x), int(*y), int(r)); ++x; ++y; } while(--n); break;
+ }
+ }
+
+ //--------------------------------------------------------------------
+ template<class T>
+ void markers(int n, const T* x, const T* y, const T* r, marker_e type)
+ {
+ if(n <= 0) return;
+ switch(type)
+ {
+ case marker_square: do { square (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
+ case marker_diamond: do { diamond (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
+ case marker_circle: do { circle (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
+ case marker_crossed_circle: do { crossed_circle (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
+ case marker_semiellipse_left: do { semiellipse_left (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
+ case marker_semiellipse_right: do { semiellipse_right(int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
+ case marker_semiellipse_up: do { semiellipse_up (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
+ case marker_semiellipse_down: do { semiellipse_down (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
+ case marker_triangle_left: do { triangle_left (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
+ case marker_triangle_right: do { triangle_right (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
+ case marker_triangle_up: do { triangle_up (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
+ case marker_triangle_down: do { triangle_down (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
+ case marker_four_rays: do { four_rays (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
+ case marker_cross: do { cross (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
+ case marker_x: do { xing (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
+ case marker_dash: do { dash (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
+ case marker_dot: do { dot (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
+ case marker_pixel: do { pixel (int(*x), int(*y), int(*r)); ++x; ++y; ++r; } while(--n); break;
+ }
+ }
+
+ //--------------------------------------------------------------------
+ template<class T>
+ void markers(int n, const T* x, const T* y, const T* r, const color_type* fc, marker_e type)
+ {
+ if(n <= 0) return;
+ switch(type)
+ {
+ case marker_square: do { base_type::fill_color(*fc); square (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
+ case marker_diamond: do { base_type::fill_color(*fc); diamond (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
+ case marker_circle: do { base_type::fill_color(*fc); circle (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
+ case marker_crossed_circle: do { base_type::fill_color(*fc); crossed_circle (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
+ case marker_semiellipse_left: do { base_type::fill_color(*fc); semiellipse_left (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
+ case marker_semiellipse_right: do { base_type::fill_color(*fc); semiellipse_right(int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
+ case marker_semiellipse_up: do { base_type::fill_color(*fc); semiellipse_up (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
+ case marker_semiellipse_down: do { base_type::fill_color(*fc); semiellipse_down (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
+ case marker_triangle_left: do { base_type::fill_color(*fc); triangle_left (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
+ case marker_triangle_right: do { base_type::fill_color(*fc); triangle_right (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
+ case marker_triangle_up: do { base_type::fill_color(*fc); triangle_up (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
+ case marker_triangle_down: do { base_type::fill_color(*fc); triangle_down (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
+ case marker_four_rays: do { base_type::fill_color(*fc); four_rays (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
+ case marker_cross: do { base_type::fill_color(*fc); cross (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
+ case marker_x: do { base_type::fill_color(*fc); xing (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
+ case marker_dash: do { base_type::fill_color(*fc); dash (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
+ case marker_dot: do { base_type::fill_color(*fc); dot (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
+ case marker_pixel: do { base_type::fill_color(*fc); pixel (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; } while(--n); break;
+ }
+ }
+
+ //--------------------------------------------------------------------
+ template<class T>
+ void markers(int n, const T* x, const T* y, const T* r, const color_type* fc, const color_type* lc, marker_e type)
+ {
+ if(n <= 0) return;
+ switch(type)
+ {
+ case marker_square: do { base_type::fill_color(*fc); base_type::line_color(*lc); square (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
+ case marker_diamond: do { base_type::fill_color(*fc); base_type::line_color(*lc); diamond (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
+ case marker_circle: do { base_type::fill_color(*fc); base_type::line_color(*lc); circle (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
+ case marker_crossed_circle: do { base_type::fill_color(*fc); base_type::line_color(*lc); crossed_circle (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
+ case marker_semiellipse_left: do { base_type::fill_color(*fc); base_type::line_color(*lc); semiellipse_left (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
+ case marker_semiellipse_right: do { base_type::fill_color(*fc); base_type::line_color(*lc); semiellipse_right(int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
+ case marker_semiellipse_up: do { base_type::fill_color(*fc); base_type::line_color(*lc); semiellipse_up (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
+ case marker_semiellipse_down: do { base_type::fill_color(*fc); base_type::line_color(*lc); semiellipse_down (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
+ case marker_triangle_left: do { base_type::fill_color(*fc); base_type::line_color(*lc); triangle_left (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
+ case marker_triangle_right: do { base_type::fill_color(*fc); base_type::line_color(*lc); triangle_right (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
+ case marker_triangle_up: do { base_type::fill_color(*fc); base_type::line_color(*lc); triangle_up (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
+ case marker_triangle_down: do { base_type::fill_color(*fc); base_type::line_color(*lc); triangle_down (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
+ case marker_four_rays: do { base_type::fill_color(*fc); base_type::line_color(*lc); four_rays (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
+ case marker_cross: do { base_type::fill_color(*fc); base_type::line_color(*lc); cross (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
+ case marker_x: do { base_type::fill_color(*fc); base_type::line_color(*lc); xing (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
+ case marker_dash: do { base_type::fill_color(*fc); base_type::line_color(*lc); dash (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
+ case marker_dot: do { base_type::fill_color(*fc); base_type::line_color(*lc); dot (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
+ case marker_pixel: do { base_type::fill_color(*fc); base_type::line_color(*lc); pixel (int(*x), int(*y), int(*r)); ++x; ++y; ++r; ++fc; ++lc; } while(--n); break;
+ }
+ }
+ };
+
+}
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_mclip.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_mclip.h
new file mode 100644
index 0000000000..96a7d4e094
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_mclip.h
@@ -0,0 +1,349 @@
+//----------------------------------------------------------------------------
+// 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
+//----------------------------------------------------------------------------
+//
+// class renderer_mclip
+//
+//----------------------------------------------------------------------------
+
+#ifndef AGG_RENDERER_MCLIP_INCLUDED
+#define AGG_RENDERER_MCLIP_INCLUDED
+
+#include "agg_basics.h"
+#include "agg_array.h"
+#include "agg_renderer_base.h"
+
+namespace agg
+{
+
+ //----------------------------------------------------------renderer_mclip
+ template<class PixelFormat> class renderer_mclip
+ {
+ 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;
+
+ //--------------------------------------------------------------------
+ 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);
+ }
+
+ //--------------------------------------------------------------------
+ const pixfmt_type& ren() const { return m_ren.ren(); }
+ pixfmt_type& ren() { return m_ren.ren(); }
+
+ //--------------------------------------------------------------------
+ unsigned width() const { return m_ren.width(); }
+ unsigned height() const { return m_ren.height(); }
+
+ //--------------------------------------------------------------------
+ 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_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()
+ {
+ m_curr_cb = 0;
+ if(m_clip.size())
+ {
+ const rect_i& cb = m_clip[0];
+ m_ren.clip_box_naked(cb.x1, cb.y1, cb.x2, cb.y2);
+ }
+ }
+
+ //--------------------------------------------------------------------
+ bool next_clip_box()
+ {
+ if(++m_curr_cb < m_clip.size())
+ {
+ const rect_i& cb = m_clip[m_curr_cb];
+ m_ren.clip_box_naked(cb.x1, cb.y1, cb.x2, cb.y2);
+ return true;
+ }
+ return false;
+ }
+
+ //--------------------------------------------------------------------
+ void reset_clipping(bool visibility)
+ {
+ m_ren.reset_clipping(visibility);
+ m_clip.remove_all();
+ m_curr_cb = 0;
+ m_bounds = m_ren.clip_box();
+ }
+
+ //--------------------------------------------------------------------
+ void add_clip_box(int x1, int y1, int x2, int y2)
+ {
+ rect_i cb(x1, y1, x2, y2);
+ cb.normalize();
+ 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;
+ if(cb.y1 < m_bounds.y1) m_bounds.y1 = cb.y1;
+ if(cb.x2 > m_bounds.x2) m_bounds.x2 = cb.x2;
+ if(cb.y2 > m_bounds.y2) m_bounds.y2 = cb.y2;
+ }
+ }
+
+ //--------------------------------------------------------------------
+ void clear(const color_type& c)
+ {
+ m_ren.clear(c);
+ }
+
+ //--------------------------------------------------------------------
+ void copy_pixel(int x, int y, const color_type& c)
+ {
+ first_clip_box();
+ do
+ {
+ if(m_ren.inbox(x, y))
+ {
+ m_ren.ren().copy_pixel(x, y, c);
+ break;
+ }
+ }
+ while(next_clip_box());
+ }
+
+ //--------------------------------------------------------------------
+ void blend_pixel(int x, int y, const color_type& c, cover_type cover)
+ {
+ first_clip_box();
+ do
+ {
+ if(m_ren.inbox(x, y))
+ {
+ m_ren.ren().blend_pixel(x, y, c, cover);
+ break;
+ }
+ }
+ while(next_clip_box());
+ }
+
+ //--------------------------------------------------------------------
+ color_type pixel(int x, int y) const
+ {
+ first_clip_box();
+ do
+ {
+ if(m_ren.inbox(x, y))
+ {
+ return m_ren.ren().pixel(x, y);
+ }
+ }
+ while(next_clip_box());
+ return color_type::no_color();
+ }
+
+ //--------------------------------------------------------------------
+ void copy_hline(int x1, int y, int x2, const color_type& c)
+ {
+ first_clip_box();
+ do
+ {
+ m_ren.copy_hline(x1, y, x2, c);
+ }
+ while(next_clip_box());
+ }
+
+ //--------------------------------------------------------------------
+ void copy_vline(int x, int y1, int y2, const color_type& c)
+ {
+ first_clip_box();
+ do
+ {
+ m_ren.copy_vline(x, y1, y2, c);
+ }
+ while(next_clip_box());
+ }
+
+ //--------------------------------------------------------------------
+ void blend_hline(int x1, int y, int x2,
+ const color_type& c, cover_type cover)
+ {
+ first_clip_box();
+ do
+ {
+ m_ren.blend_hline(x1, y, x2, c, cover);
+ }
+ while(next_clip_box());
+ }
+
+ //--------------------------------------------------------------------
+ void blend_vline(int x, int y1, int y2,
+ const color_type& c, cover_type cover)
+ {
+ first_clip_box();
+ do
+ {
+ m_ren.blend_vline(x, y1, y2, c, cover);
+ }
+ while(next_clip_box());
+ }
+
+ //--------------------------------------------------------------------
+ void copy_bar(int x1, int y1, int x2, int y2, const color_type& c)
+ {
+ first_clip_box();
+ do
+ {
+ m_ren.copy_bar(x1, y1, x2, y2, c);
+ }
+ while(next_clip_box());
+ }
+
+ //--------------------------------------------------------------------
+ void blend_bar(int x1, int y1, int x2, int y2,
+ const color_type& c, cover_type cover)
+ {
+ first_clip_box();
+ do
+ {
+ m_ren.blend_bar(x1, y1, x2, y2, c, cover);
+ }
+ while(next_clip_box());
+ }
+
+ //--------------------------------------------------------------------
+ void blend_solid_hspan(int x, int y, int len,
+ const color_type& c, const cover_type* covers)
+ {
+ first_clip_box();
+ do
+ {
+ m_ren.blend_solid_hspan(x, y, len, c, covers);
+ }
+ while(next_clip_box());
+ }
+
+ //--------------------------------------------------------------------
+ void blend_solid_vspan(int x, int y, int len,
+ const color_type& c, const cover_type* covers)
+ {
+ first_clip_box();
+ do
+ {
+ m_ren.blend_solid_vspan(x, y, len, c, covers);
+ }
+ while(next_clip_box());
+ }
+
+
+ //--------------------------------------------------------------------
+ void copy_color_hspan(int x, int y, int len, const color_type* colors)
+ {
+ first_clip_box();
+ do
+ {
+ m_ren.copy_color_hspan(x, y, len, colors);
+ }
+ 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)
+ {
+ first_clip_box();
+ do
+ {
+ m_ren.blend_color_hspan(x, y, len, colors, covers, cover);
+ }
+ while(next_clip_box());
+ }
+
+ //--------------------------------------------------------------------
+ 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_color_vspan(x, y, len, colors, covers, cover);
+ }
+ while(next_clip_box());
+ }
+
+ //--------------------------------------------------------------------
+ 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.copy_from(from, rc, x_to, y_to);
+ }
+ while(next_clip_box());
+ }
+
+ //--------------------------------------------------------------------
+ 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.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_bvector<rect_i, 4> m_clip;
+ unsigned m_curr_cb;
+ rect_i m_bounds;
+ };
+
+
+}
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_outline_aa.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_outline_aa.h
new file mode 100644
index 0000000000..ee564f04d5
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_outline_aa.h
@@ -0,0 +1,1837 @@
+//----------------------------------------------------------------------------
+// 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_RENDERER_OUTLINE_AA_INCLUDED
+#define AGG_RENDERER_OUTLINE_AA_INCLUDED
+
+#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
+{
+
+ //===================================================distance_interpolator0
+ class distance_interpolator0
+ {
+ public:
+ //---------------------------------------------------------------------
+ distance_interpolator0() {}
+ 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_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;
+ }
+
+ //---------------------------------------------------------------------
+ void inc_x() { m_dist += m_dy; }
+ int dist() const { return m_dist; }
+
+ private:
+ //---------------------------------------------------------------------
+ int m_dx;
+ int m_dy;
+ int m_dist;
+ };
+
+ //==================================================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_dx1 <<= line_mr_subpixel_shift;
+ m_dy1 <<= line_mr_subpixel_shift;
+ m_dx2 <<= line_mr_subpixel_shift;
+ m_dy2 <<= line_mr_subpixel_shift;
+ }
+
+ //---------------------------------------------------------------------
+ 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_dx1;
+ int m_dy1;
+ int m_dx2;
+ int m_dy2;
+ int m_dist1;
+ int m_dist2;
+ };
+
+ //===================================================distance_interpolator1
+ class distance_interpolator1
+ {
+ public:
+ //---------------------------------------------------------------------
+ distance_interpolator1() {}
+ distance_interpolator1(int x1, int y1, int x2, int y2, int x, int y) :
+ m_dx(x2 - x1),
+ m_dy(y2 - y1),
+ 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;
+ }
+
+ //---------------------------------------------------------------------
+ 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;
+ }
+
+ //---------------------------------------------------------------------
+ void inc_y(int dx)
+ {
+ m_dist -= m_dx;
+ if(dx > 0) m_dist += m_dy;
+ if(dx < 0) m_dist -= m_dy;
+ }
+
+ void dec_y(int dx)
+ //---------------------------------------------------------------------
+ {
+ m_dist += m_dx;
+ if(dx > 0) m_dist += m_dy;
+ if(dx < 0) m_dist -= m_dy;
+ }
+
+ //---------------------------------------------------------------------
+ int dist() const { return m_dist; }
+ int dx() const { return m_dx; }
+ int dy() const { return m_dy; }
+
+ private:
+ //---------------------------------------------------------------------
+ int m_dx;
+ int m_dy;
+ int m_dist;
+ };
+
+
+
+
+
+ //===================================================distance_interpolator2
+ class distance_interpolator2
+ {
+ public:
+ //---------------------------------------------------------------------
+ distance_interpolator2() {}
+ distance_interpolator2(int x1, int y1, int x2, int y2,
+ int sx, int sy, int x, int y) :
+ m_dx(x2 - x1),
+ m_dy(y2 - y1),
+ m_dx_start(line_mr(sx) - line_mr(x1)),
+ m_dy_start(line_mr(sy) - line_mr(y1)),
+
+ 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_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;
+ m_dx_start <<= line_mr_subpixel_shift;
+ m_dy_start <<= line_mr_subpixel_shift;
+ }
+
+ distance_interpolator2(int x1, int y1, int x2, int y2,
+ int ex, int ey, int x, int y, int) :
+ m_dx(x2 - x1),
+ m_dy(y2 - y1),
+ m_dx_start(line_mr(ex) - line_mr(x2)),
+ m_dy_start(line_mr(ey) - line_mr(y2)),
+
+ 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_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;
+ m_dx_start <<= line_mr_subpixel_shift;
+ m_dy_start <<= line_mr_subpixel_shift;
+ }
+
+
+ //---------------------------------------------------------------------
+ void inc_x() { m_dist += m_dy; m_dist_start += m_dy_start; }
+ void dec_x() { m_dist -= m_dy; m_dist_start -= m_dy_start; }
+ void inc_y() { m_dist -= m_dx; m_dist_start -= m_dx_start; }
+ void dec_y() { m_dist += m_dx; m_dist_start += m_dx_start; }
+
+ //---------------------------------------------------------------------
+ void inc_x(int dy)
+ {
+ m_dist += m_dy;
+ m_dist_start += m_dy_start;
+ if(dy > 0)
+ {
+ m_dist -= m_dx;
+ m_dist_start -= m_dx_start;
+ }
+ if(dy < 0)
+ {
+ m_dist += m_dx;
+ m_dist_start += m_dx_start;
+ }
+ }
+
+ //---------------------------------------------------------------------
+ void dec_x(int dy)
+ {
+ m_dist -= m_dy;
+ m_dist_start -= m_dy_start;
+ if(dy > 0)
+ {
+ m_dist -= m_dx;
+ m_dist_start -= m_dx_start;
+ }
+ if(dy < 0)
+ {
+ m_dist += m_dx;
+ m_dist_start += m_dx_start;
+ }
+ }
+
+ //---------------------------------------------------------------------
+ void inc_y(int dx)
+ {
+ m_dist -= m_dx;
+ m_dist_start -= m_dx_start;
+ if(dx > 0)
+ {
+ m_dist += m_dy;
+ m_dist_start += m_dy_start;
+ }
+ if(dx < 0)
+ {
+ m_dist -= m_dy;
+ m_dist_start -= m_dy_start;
+ }
+ }
+
+ //---------------------------------------------------------------------
+ void dec_y(int dx)
+ {
+ m_dist += m_dx;
+ m_dist_start += m_dx_start;
+ if(dx > 0)
+ {
+ m_dist += m_dy;
+ m_dist_start += m_dy_start;
+ }
+ if(dx < 0)
+ {
+ m_dist -= m_dy;
+ m_dist_start -= m_dy_start;
+ }
+ }
+
+ //---------------------------------------------------------------------
+ int dist() const { return m_dist; }
+ int dist_start() const { return m_dist_start; }
+ int dist_end() const { return m_dist_start; }
+
+ //---------------------------------------------------------------------
+ int dx() const { return m_dx; }
+ int dy() const { return m_dy; }
+ int dx_start() const { return m_dx_start; }
+ int dy_start() const { return m_dy_start; }
+ int dx_end() const { return m_dx_start; }
+ int dy_end() const { return m_dy_start; }
+
+ private:
+ //---------------------------------------------------------------------
+ int m_dx;
+ int m_dy;
+ int m_dx_start;
+ int m_dy_start;
+
+ int m_dist;
+ int m_dist_start;
+ };
+
+
+
+
+
+ //===================================================distance_interpolator3
+ class distance_interpolator3
+ {
+ public:
+ //---------------------------------------------------------------------
+ distance_interpolator3() {}
+ distance_interpolator3(int x1, int y1, int x2, int y2,
+ int sx, int sy, int ex, int ey,
+ int x, int y) :
+ m_dx(x2 - x1),
+ m_dy(y2 - y1),
+ m_dx_start(line_mr(sx) - line_mr(x1)),
+ m_dy_start(line_mr(sy) - line_mr(y1)),
+ m_dx_end(line_mr(ex) - line_mr(x2)),
+ m_dy_end(line_mr(ey) - line_mr(y2)),
+
+ 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_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_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;
+ m_dx_start <<= line_mr_subpixel_shift;
+ m_dy_start <<= line_mr_subpixel_shift;
+ m_dx_end <<= line_mr_subpixel_shift;
+ m_dy_end <<= line_mr_subpixel_shift;
+ }
+
+ //---------------------------------------------------------------------
+ void inc_x() { m_dist += m_dy; m_dist_start += m_dy_start; m_dist_end += m_dy_end; }
+ void dec_x() { m_dist -= m_dy; m_dist_start -= m_dy_start; m_dist_end -= m_dy_end; }
+ void inc_y() { m_dist -= m_dx; m_dist_start -= m_dx_start; m_dist_end -= m_dx_end; }
+ void dec_y() { m_dist += m_dx; m_dist_start += m_dx_start; m_dist_end += m_dx_end; }
+
+ //---------------------------------------------------------------------
+ void inc_x(int dy)
+ {
+ m_dist += m_dy;
+ m_dist_start += m_dy_start;
+ m_dist_end += m_dy_end;
+ if(dy > 0)
+ {
+ m_dist -= m_dx;
+ m_dist_start -= m_dx_start;
+ m_dist_end -= m_dx_end;
+ }
+ if(dy < 0)
+ {
+ m_dist += m_dx;
+ m_dist_start += m_dx_start;
+ m_dist_end += m_dx_end;
+ }
+ }
+
+ //---------------------------------------------------------------------
+ void dec_x(int dy)
+ {
+ m_dist -= m_dy;
+ m_dist_start -= m_dy_start;
+ m_dist_end -= m_dy_end;
+ if(dy > 0)
+ {
+ m_dist -= m_dx;
+ m_dist_start -= m_dx_start;
+ m_dist_end -= m_dx_end;
+ }
+ if(dy < 0)
+ {
+ m_dist += m_dx;
+ m_dist_start += m_dx_start;
+ m_dist_end += m_dx_end;
+ }
+ }
+
+ //---------------------------------------------------------------------
+ void inc_y(int dx)
+ {
+ m_dist -= m_dx;
+ m_dist_start -= m_dx_start;
+ m_dist_end -= m_dx_end;
+ if(dx > 0)
+ {
+ m_dist += m_dy;
+ m_dist_start += m_dy_start;
+ m_dist_end += m_dy_end;
+ }
+ if(dx < 0)
+ {
+ m_dist -= m_dy;
+ m_dist_start -= m_dy_start;
+ m_dist_end -= m_dy_end;
+ }
+ }
+
+ //---------------------------------------------------------------------
+ void dec_y(int dx)
+ {
+ m_dist += m_dx;
+ m_dist_start += m_dx_start;
+ m_dist_end += m_dx_end;
+ if(dx > 0)
+ {
+ m_dist += m_dy;
+ m_dist_start += m_dy_start;
+ m_dist_end += m_dy_end;
+ }
+ if(dx < 0)
+ {
+ m_dist -= m_dy;
+ m_dist_start -= m_dy_start;
+ m_dist_end -= m_dy_end;
+ }
+ }
+
+ //---------------------------------------------------------------------
+ int dist() const { return m_dist; }
+ int dist_start() const { return m_dist_start; }
+ int dist_end() const { return m_dist_end; }
+
+ //---------------------------------------------------------------------
+ int dx() const { return m_dx; }
+ int dy() const { return m_dy; }
+ int dx_start() const { return m_dx_start; }
+ int dy_start() const { return m_dy_start; }
+ int dx_end() const { return m_dx_end; }
+ int dy_end() const { return m_dy_end; }
+
+ private:
+ //---------------------------------------------------------------------
+ int m_dx;
+ int m_dy;
+ int m_dx_start;
+ int m_dy_start;
+ int m_dx_end;
+ int m_dy_end;
+
+ int m_dist;
+ int m_dist_start;
+ int m_dist_end;
+ };
+
+
+
+
+
+ //================================================line_interpolator_aa_base
+ template<class Renderer> class line_interpolator_aa_base
+ {
+ public:
+ typedef Renderer renderer_type;
+ typedef typename Renderer::color_type color_type;
+
+ //---------------------------------------------------------------------
+ enum max_half_width_e
+ {
+ max_half_width = 64
+ };
+
+ //---------------------------------------------------------------------
+ line_interpolator_aa_base(renderer_type& ren, line_parameters& lp) :
+ m_lp(&lp),
+ m_li(lp.vertical ? line_dbl_hr(lp.x2 - lp.x1) :
+ line_dbl_hr(lp.y2 - lp.y1),
+ lp.vertical ? abs(lp.y2 - lp.y1) :
+ abs(lp.x2 - lp.x1) + 1),
+ m_ren(ren),
+ m_len((lp.vertical == (lp.inc > 0)) ? -lp.len : lp.len),
+ m_x(lp.x1 >> line_subpixel_shift),
+ m_y(lp.y1 >> line_subpixel_shift),
+ m_old_x(m_x),
+ m_old_y(m_y),
+ 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_mask) >> line_subpixel_shift),
+ m_step(0)
+ {
+ agg::dda2_line_interpolator li(0, lp.vertical ?
+ (lp.dy << agg::line_subpixel_shift) :
+ (lp.dx << agg::line_subpixel_shift),
+ lp.len);
+
+ unsigned i;
+ int stop = m_width + line_subpixel_scale * 2;
+ for(i = 0; i < max_half_width; ++i)
+ {
+ m_dist[i] = li.y();
+ if(m_dist[i] >= stop) break;
+ ++li;
+ }
+ m_dist[i++] = 0x7FFF0000;
+ }
+
+ //---------------------------------------------------------------------
+ template<class DI> int step_hor_base(DI& di)
+ {
+ ++m_li;
+ m_x += m_lp->inc;
+ m_y = (m_lp->y1 + m_li.y()) >> line_subpixel_shift;
+
+ if(m_lp->inc > 0) di.inc_x(m_y - m_old_y);
+ else di.dec_x(m_y - m_old_y);
+
+ m_old_y = m_y;
+
+ return di.dist() / m_len;
+ }
+
+ //---------------------------------------------------------------------
+ template<class DI> int step_ver_base(DI& di)
+ {
+ ++m_li;
+ m_y += m_lp->inc;
+ m_x = (m_lp->x1 + m_li.y()) >> line_subpixel_shift;
+
+ if(m_lp->inc > 0) di.inc_y(m_x - m_old_x);
+ else di.dec_y(m_x - m_old_x);
+
+ m_old_x = m_x;
+
+ return di.dist() / m_len;
+ }
+
+ //---------------------------------------------------------------------
+ bool vertical() const { return m_lp->vertical; }
+ int width() const { return m_width; }
+ int count() const { return m_count; }
+
+ private:
+ line_interpolator_aa_base(const line_interpolator_aa_base<Renderer>&);
+ const line_interpolator_aa_base<Renderer>&
+ operator = (const line_interpolator_aa_base<Renderer>&);
+
+ protected:
+ line_parameters* m_lp;
+ dda2_line_interpolator m_li;
+ renderer_type& m_ren;
+ int m_len;
+ int m_x;
+ int m_y;
+ int m_old_x;
+ int m_old_y;
+ int m_count;
+ int m_width;
+ int m_max_extent;
+ int m_step;
+ int m_dist[max_half_width + 1];
+ cover_type m_covers[max_half_width * 2 + 4];
+ };
+
+
+
+
+
+
+
+ //====================================================line_interpolator_aa0
+ template<class Renderer> class line_interpolator_aa0 :
+ public line_interpolator_aa_base<Renderer>
+ {
+ public:
+ typedef Renderer renderer_type;
+ typedef typename Renderer::color_type color_type;
+ typedef line_interpolator_aa_base<Renderer> base_type;
+
+ //---------------------------------------------------------------------
+ line_interpolator_aa0(renderer_type& ren, line_parameters& lp) :
+ line_interpolator_aa_base<Renderer>(ren, lp),
+ m_di(lp.x1, lp.y1, lp.x2, lp.y2,
+ lp.x1 & ~line_subpixel_mask, lp.y1 & ~line_subpixel_mask)
+ {
+ base_type::m_li.adjust_forward();
+ }
+
+ //---------------------------------------------------------------------
+ bool step_hor()
+ {
+ int dist;
+ int dy;
+ int s1 = base_type::step_hor_base(m_di);
+ cover_type* p0 = base_type::m_covers + base_type::max_half_width + 2;
+ cover_type* p1 = p0;
+
+ *p1++ = (cover_type)base_type::m_ren.cover(s1);
+
+ dy = 1;
+ while((dist = base_type::m_dist[dy] - s1) <= base_type::m_width)
+ {
+ *p1++ = (cover_type)base_type::m_ren.cover(dist);
+ ++dy;
+ }
+
+ dy = 1;
+ while((dist = base_type::m_dist[dy] + s1) <= base_type::m_width)
+ {
+ *--p0 = (cover_type)base_type::m_ren.cover(dist);
+ ++dy;
+ }
+ base_type::m_ren.blend_solid_vspan(base_type::m_x,
+ base_type::m_y - dy + 1,
+ unsigned(p1 - p0),
+ p0);
+ return ++base_type::m_step < base_type::m_count;
+ }
+
+ //---------------------------------------------------------------------
+ bool step_ver()
+ {
+ int dist;
+ int dx;
+ int s1 = base_type::step_ver_base(m_di);
+ cover_type* p0 = base_type::m_covers + base_type::max_half_width + 2;
+ cover_type* p1 = p0;
+
+ *p1++ = (cover_type)base_type::m_ren.cover(s1);
+
+ dx = 1;
+ while((dist = base_type::m_dist[dx] - s1) <= base_type::m_width)
+ {
+ *p1++ = (cover_type)base_type::m_ren.cover(dist);
+ ++dx;
+ }
+
+ dx = 1;
+ while((dist = base_type::m_dist[dx] + s1) <= base_type::m_width)
+ {
+ *--p0 = (cover_type)base_type::m_ren.cover(dist);
+ ++dx;
+ }
+ base_type::m_ren.blend_solid_hspan(base_type::m_x - dx + 1,
+ base_type::m_y,
+ unsigned(p1 - p0),
+ p0);
+ return ++base_type::m_step < base_type::m_count;
+ }
+
+ private:
+ line_interpolator_aa0(const line_interpolator_aa0<Renderer>&);
+ const line_interpolator_aa0<Renderer>&
+ operator = (const line_interpolator_aa0<Renderer>&);
+
+ //---------------------------------------------------------------------
+ distance_interpolator1 m_di;
+ };
+
+
+
+
+
+
+ //====================================================line_interpolator_aa1
+ template<class Renderer> class line_interpolator_aa1 :
+ public line_interpolator_aa_base<Renderer>
+ {
+ public:
+ typedef Renderer renderer_type;
+ typedef typename Renderer::color_type color_type;
+ typedef line_interpolator_aa_base<Renderer> base_type;
+
+ //---------------------------------------------------------------------
+ line_interpolator_aa1(renderer_type& ren, line_parameters& lp,
+ int sx, int sy) :
+ line_interpolator_aa_base<Renderer>(ren, lp),
+ m_di(lp.x1, lp.y1, lp.x2, lp.y2, sx, sy,
+ lp.x1 & ~line_subpixel_mask, lp.y1 & ~line_subpixel_mask)
+ {
+ int dist1_start;
+ int dist2_start;
+
+ int npix = 1;
+
+ if(lp.vertical)
+ {
+ do
+ {
+ --base_type::m_li;
+ base_type::m_y -= lp.inc;
+ base_type::m_x = (base_type::m_lp->x1 + base_type::m_li.y()) >> line_subpixel_shift;
+
+ if(lp.inc > 0) m_di.dec_y(base_type::m_x - base_type::m_old_x);
+ else m_di.inc_y(base_type::m_x - base_type::m_old_x);
+
+ base_type::m_old_x = base_type::m_x;
+
+ dist1_start = dist2_start = m_di.dist_start();
+
+ int dx = 0;
+ if(dist1_start < 0) ++npix;
+ do
+ {
+ dist1_start += m_di.dy_start();
+ dist2_start -= m_di.dy_start();
+ if(dist1_start < 0) ++npix;
+ if(dist2_start < 0) ++npix;
+ ++dx;
+ }
+ while(base_type::m_dist[dx] <= base_type::m_width);
+ --base_type::m_step;
+ if(npix == 0) break;
+ npix = 0;
+ }
+ while(base_type::m_step >= -base_type::m_max_extent);
+ }
+ else
+ {
+ do
+ {
+ --base_type::m_li;
+ base_type::m_x -= lp.inc;
+ base_type::m_y = (base_type::m_lp->y1 + base_type::m_li.y()) >> line_subpixel_shift;
+
+ if(lp.inc > 0) m_di.dec_x(base_type::m_y - base_type::m_old_y);
+ else m_di.inc_x(base_type::m_y - base_type::m_old_y);
+
+ base_type::m_old_y = base_type::m_y;
+
+ dist1_start = dist2_start = m_di.dist_start();
+
+ int dy = 0;
+ if(dist1_start < 0) ++npix;
+ do
+ {
+ dist1_start -= m_di.dx_start();
+ dist2_start += m_di.dx_start();
+ if(dist1_start < 0) ++npix;
+ if(dist2_start < 0) ++npix;
+ ++dy;
+ }
+ while(base_type::m_dist[dy] <= base_type::m_width);
+ --base_type::m_step;
+ if(npix == 0) break;
+ npix = 0;
+ }
+ while(base_type::m_step >= -base_type::m_max_extent);
+ }
+ base_type::m_li.adjust_forward();
+ }
+
+ //---------------------------------------------------------------------
+ bool step_hor()
+ {
+ int dist_start;
+ int dist;
+ int dy;
+ int s1 = base_type::step_hor_base(m_di);
+
+ dist_start = m_di.dist_start();
+ cover_type* p0 = base_type::m_covers + base_type::max_half_width + 2;
+ cover_type* p1 = p0;
+
+ *p1 = 0;
+ if(dist_start <= 0)
+ {
+ *p1 = (cover_type)base_type::m_ren.cover(s1);
+ }
+ ++p1;
+
+ dy = 1;
+ while((dist = base_type::m_dist[dy] - s1) <= base_type::m_width)
+ {
+ dist_start -= m_di.dx_start();
+ *p1 = 0;
+ if(dist_start <= 0)
+ {
+ *p1 = (cover_type)base_type::m_ren.cover(dist);
+ }
+ ++p1;
+ ++dy;
+ }
+
+ dy = 1;
+ dist_start = m_di.dist_start();
+ while((dist = base_type::m_dist[dy] + s1) <= base_type::m_width)
+ {
+ dist_start += m_di.dx_start();
+ *--p0 = 0;
+ if(dist_start <= 0)
+ {
+ *p0 = (cover_type)base_type::m_ren.cover(dist);
+ }
+ ++dy;
+ }
+
+ base_type::m_ren.blend_solid_vspan(base_type::m_x,
+ base_type::m_y - dy + 1,
+ unsigned(p1 - p0),
+ p0);
+ return ++base_type::m_step < base_type::m_count;
+ }
+
+ //---------------------------------------------------------------------
+ bool step_ver()
+ {
+ int dist_start;
+ int dist;
+ int dx;
+ int s1 = base_type::step_ver_base(m_di);
+ cover_type* p0 = base_type::m_covers + base_type::max_half_width + 2;
+ cover_type* p1 = p0;
+
+ dist_start = m_di.dist_start();
+
+ *p1 = 0;
+ if(dist_start <= 0)
+ {
+ *p1 = (cover_type)base_type::m_ren.cover(s1);
+ }
+ ++p1;
+
+ dx = 1;
+ while((dist = base_type::m_dist[dx] - s1) <= base_type::m_width)
+ {
+ dist_start += m_di.dy_start();
+ *p1 = 0;
+ if(dist_start <= 0)
+ {
+ *p1 = (cover_type)base_type::m_ren.cover(dist);
+ }
+ ++p1;
+ ++dx;
+ }
+
+ dx = 1;
+ dist_start = m_di.dist_start();
+ while((dist = base_type::m_dist[dx] + s1) <= base_type::m_width)
+ {
+ dist_start -= m_di.dy_start();
+ *--p0 = 0;
+ if(dist_start <= 0)
+ {
+ *p0 = (cover_type)base_type::m_ren.cover(dist);
+ }
+ ++dx;
+ }
+ base_type::m_ren.blend_solid_hspan(base_type::m_x - dx + 1,
+ base_type::m_y,
+ unsigned(p1 - p0),
+ p0);
+ return ++base_type::m_step < base_type::m_count;
+ }
+
+ private:
+ line_interpolator_aa1(const line_interpolator_aa1<Renderer>&);
+ const line_interpolator_aa1<Renderer>&
+ operator = (const line_interpolator_aa1<Renderer>&);
+
+ //---------------------------------------------------------------------
+ distance_interpolator2 m_di;
+ };
+
+
+
+
+
+
+
+
+
+
+
+
+ //====================================================line_interpolator_aa2
+ template<class Renderer> class line_interpolator_aa2 :
+ public line_interpolator_aa_base<Renderer>
+ {
+ public:
+ typedef Renderer renderer_type;
+ typedef typename Renderer::color_type color_type;
+ typedef line_interpolator_aa_base<Renderer> base_type;
+
+ //---------------------------------------------------------------------
+ line_interpolator_aa2(renderer_type& ren, line_parameters& lp,
+ int ex, int ey) :
+ line_interpolator_aa_base<Renderer>(ren, lp),
+ m_di(lp.x1, lp.y1, lp.x2, lp.y2, ex, ey,
+ lp.x1 & ~line_subpixel_mask, lp.y1 & ~line_subpixel_mask,
+ 0)
+ {
+ base_type::m_li.adjust_forward();
+ base_type::m_step -= base_type::m_max_extent;
+ }
+
+ //---------------------------------------------------------------------
+ bool step_hor()
+ {
+ int dist_end;
+ int dist;
+ int dy;
+ int s1 = base_type::step_hor_base(m_di);
+ cover_type* p0 = base_type::m_covers + base_type::max_half_width + 2;
+ cover_type* p1 = p0;
+
+ dist_end = m_di.dist_end();
+
+ int npix = 0;
+ *p1 = 0;
+ if(dist_end > 0)
+ {
+ *p1 = (cover_type)base_type::m_ren.cover(s1);
+ ++npix;
+ }
+ ++p1;
+
+ dy = 1;
+ while((dist = base_type::m_dist[dy] - s1) <= base_type::m_width)
+ {
+ dist_end -= m_di.dx_end();
+ *p1 = 0;
+ if(dist_end > 0)
+ {
+ *p1 = (cover_type)base_type::m_ren.cover(dist);
+ ++npix;
+ }
+ ++p1;
+ ++dy;
+ }
+
+ dy = 1;
+ dist_end = m_di.dist_end();
+ while((dist = base_type::m_dist[dy] + s1) <= base_type::m_width)
+ {
+ dist_end += m_di.dx_end();
+ *--p0 = 0;
+ if(dist_end > 0)
+ {
+ *p0 = (cover_type)base_type::m_ren.cover(dist);
+ ++npix;
+ }
+ ++dy;
+ }
+ base_type::m_ren.blend_solid_vspan(base_type::m_x,
+ base_type::m_y - dy + 1,
+ unsigned(p1 - p0),
+ p0);
+ return npix && ++base_type::m_step < base_type::m_count;
+ }
+
+ //---------------------------------------------------------------------
+ bool step_ver()
+ {
+ int dist_end;
+ int dist;
+ int dx;
+ int s1 = base_type::step_ver_base(m_di);
+ cover_type* p0 = base_type::m_covers + base_type::max_half_width + 2;
+ cover_type* p1 = p0;
+
+ dist_end = m_di.dist_end();
+
+ int npix = 0;
+ *p1 = 0;
+ if(dist_end > 0)
+ {
+ *p1 = (cover_type)base_type::m_ren.cover(s1);
+ ++npix;
+ }
+ ++p1;
+
+ dx = 1;
+ while((dist = base_type::m_dist[dx] - s1) <= base_type::m_width)
+ {
+ dist_end += m_di.dy_end();
+ *p1 = 0;
+ if(dist_end > 0)
+ {
+ *p1 = (cover_type)base_type::m_ren.cover(dist);
+ ++npix;
+ }
+ ++p1;
+ ++dx;
+ }
+
+ dx = 1;
+ dist_end = m_di.dist_end();
+ while((dist = base_type::m_dist[dx] + s1) <= base_type::m_width)
+ {
+ dist_end -= m_di.dy_end();
+ *--p0 = 0;
+ if(dist_end > 0)
+ {
+ *p0 = (cover_type)base_type::m_ren.cover(dist);
+ ++npix;
+ }
+ ++dx;
+ }
+ base_type::m_ren.blend_solid_hspan(base_type::m_x - dx + 1,
+ base_type::m_y,
+ unsigned(p1 - p0),
+ p0);
+ return npix && ++base_type::m_step < base_type::m_count;
+ }
+
+ private:
+ line_interpolator_aa2(const line_interpolator_aa2<Renderer>&);
+ const line_interpolator_aa2<Renderer>&
+ operator = (const line_interpolator_aa2<Renderer>&);
+
+ //---------------------------------------------------------------------
+ distance_interpolator2 m_di;
+ };
+
+
+
+
+
+
+
+
+
+
+ //====================================================line_interpolator_aa3
+ template<class Renderer> class line_interpolator_aa3 :
+ public line_interpolator_aa_base<Renderer>
+ {
+ public:
+ typedef Renderer renderer_type;
+ typedef typename Renderer::color_type color_type;
+ typedef line_interpolator_aa_base<Renderer> base_type;
+
+ //---------------------------------------------------------------------
+ line_interpolator_aa3(renderer_type& ren, line_parameters& lp,
+ int sx, int sy, int ex, int ey) :
+ line_interpolator_aa_base<Renderer>(ren, lp),
+ m_di(lp.x1, lp.y1, lp.x2, lp.y2, sx, sy, ex, ey,
+ lp.x1 & ~line_subpixel_mask, lp.y1 & ~line_subpixel_mask)
+ {
+ int dist1_start;
+ int dist2_start;
+ int npix = 1;
+ if(lp.vertical)
+ {
+ do
+ {
+ --base_type::m_li;
+ base_type::m_y -= lp.inc;
+ base_type::m_x = (base_type::m_lp->x1 + base_type::m_li.y()) >> line_subpixel_shift;
+
+ if(lp.inc > 0) m_di.dec_y(base_type::m_x - base_type::m_old_x);
+ else m_di.inc_y(base_type::m_x - base_type::m_old_x);
+
+ base_type::m_old_x = base_type::m_x;
+
+ dist1_start = dist2_start = m_di.dist_start();
+
+ int dx = 0;
+ if(dist1_start < 0) ++npix;
+ do
+ {
+ dist1_start += m_di.dy_start();
+ dist2_start -= m_di.dy_start();
+ if(dist1_start < 0) ++npix;
+ if(dist2_start < 0) ++npix;
+ ++dx;
+ }
+ while(base_type::m_dist[dx] <= base_type::m_width);
+ if(npix == 0) break;
+ npix = 0;
+ }
+ while(--base_type::m_step >= -base_type::m_max_extent);
+ }
+ else
+ {
+ do
+ {
+ --base_type::m_li;
+ base_type::m_x -= lp.inc;
+ base_type::m_y = (base_type::m_lp->y1 + base_type::m_li.y()) >> line_subpixel_shift;
+
+ if(lp.inc > 0) m_di.dec_x(base_type::m_y - base_type::m_old_y);
+ else m_di.inc_x(base_type::m_y - base_type::m_old_y);
+
+ base_type::m_old_y = base_type::m_y;
+
+ dist1_start = dist2_start = m_di.dist_start();
+
+ int dy = 0;
+ if(dist1_start < 0) ++npix;
+ do
+ {
+ dist1_start -= m_di.dx_start();
+ dist2_start += m_di.dx_start();
+ if(dist1_start < 0) ++npix;
+ if(dist2_start < 0) ++npix;
+ ++dy;
+ }
+ while(base_type::m_dist[dy] <= base_type::m_width);
+ if(npix == 0) break;
+ npix = 0;
+ }
+ while(--base_type::m_step >= -base_type::m_max_extent);
+ }
+ base_type::m_li.adjust_forward();
+ base_type::m_step -= base_type::m_max_extent;
+ }
+
+
+ //---------------------------------------------------------------------
+ bool step_hor()
+ {
+ int dist_start;
+ int dist_end;
+ int dist;
+ int dy;
+ int s1 = base_type::step_hor_base(m_di);
+ cover_type* p0 = base_type::m_covers + base_type::max_half_width + 2;
+ cover_type* p1 = p0;
+
+ dist_start = m_di.dist_start();
+ dist_end = m_di.dist_end();
+
+ int npix = 0;
+ *p1 = 0;
+ if(dist_end > 0)
+ {
+ if(dist_start <= 0)
+ {
+ *p1 = (cover_type)base_type::m_ren.cover(s1);
+ }
+ ++npix;
+ }
+ ++p1;
+
+ dy = 1;
+ while((dist = base_type::m_dist[dy] - s1) <= base_type::m_width)
+ {
+ dist_start -= m_di.dx_start();
+ dist_end -= m_di.dx_end();
+ *p1 = 0;
+ if(dist_end > 0 && dist_start <= 0)
+ {
+ *p1 = (cover_type)base_type::m_ren.cover(dist);
+ ++npix;
+ }
+ ++p1;
+ ++dy;
+ }
+
+ dy = 1;
+ dist_start = m_di.dist_start();
+ dist_end = m_di.dist_end();
+ while((dist = base_type::m_dist[dy] + s1) <= base_type::m_width)
+ {
+ dist_start += m_di.dx_start();
+ dist_end += m_di.dx_end();
+ *--p0 = 0;
+ if(dist_end > 0 && dist_start <= 0)
+ {
+ *p0 = (cover_type)base_type::m_ren.cover(dist);
+ ++npix;
+ }
+ ++dy;
+ }
+ base_type::m_ren.blend_solid_vspan(base_type::m_x,
+ base_type::m_y - dy + 1,
+ unsigned(p1 - p0),
+ p0);
+ return npix && ++base_type::m_step < base_type::m_count;
+ }
+
+ //---------------------------------------------------------------------
+ bool step_ver()
+ {
+ int dist_start;
+ int dist_end;
+ int dist;
+ int dx;
+ int s1 = base_type::step_ver_base(m_di);
+ cover_type* p0 = base_type::m_covers + base_type::max_half_width + 2;
+ cover_type* p1 = p0;
+
+ dist_start = m_di.dist_start();
+ dist_end = m_di.dist_end();
+
+ int npix = 0;
+ *p1 = 0;
+ if(dist_end > 0)
+ {
+ if(dist_start <= 0)
+ {
+ *p1 = (cover_type)base_type::m_ren.cover(s1);
+ }
+ ++npix;
+ }
+ ++p1;
+
+ dx = 1;
+ while((dist = base_type::m_dist[dx] - s1) <= base_type::m_width)
+ {
+ dist_start += m_di.dy_start();
+ dist_end += m_di.dy_end();
+ *p1 = 0;
+ if(dist_end > 0 && dist_start <= 0)
+ {
+ *p1 = (cover_type)base_type::m_ren.cover(dist);
+ ++npix;
+ }
+ ++p1;
+ ++dx;
+ }
+
+ dx = 1;
+ dist_start = m_di.dist_start();
+ dist_end = m_di.dist_end();
+ while((dist = base_type::m_dist[dx] + s1) <= base_type::m_width)
+ {
+ dist_start -= m_di.dy_start();
+ dist_end -= m_di.dy_end();
+ *--p0 = 0;
+ if(dist_end > 0 && dist_start <= 0)
+ {
+ *p0 = (cover_type)base_type::m_ren.cover(dist);
+ ++npix;
+ }
+ ++dx;
+ }
+ base_type::m_ren.blend_solid_hspan(base_type::m_x - dx + 1,
+ base_type::m_y,
+ unsigned(p1 - p0),
+ p0);
+ return npix && ++base_type::m_step < base_type::m_count;
+ }
+
+ private:
+ line_interpolator_aa3(const line_interpolator_aa3<Renderer>&);
+ const line_interpolator_aa3<Renderer>&
+ operator = (const line_interpolator_aa3<Renderer>&);
+
+ //---------------------------------------------------------------------
+ distance_interpolator3 m_di;
+ };
+
+
+
+
+ //==========================================================line_profile_aa
+ //
+ // See Implementation agg_line_profile_aa.cpp
+ //
+ class line_profile_aa
+ {
+ public:
+ //---------------------------------------------------------------------
+ typedef int8u value_type;
+ enum subpixel_scale_e
+ {
+ subpixel_shift = line_subpixel_shift,
+ subpixel_scale = 1 << subpixel_shift,
+ subpixel_mask = subpixel_scale - 1
+ };
+
+ enum aa_scale_e
+ {
+ aa_shift = 8,
+ aa_scale = 1 << aa_shift,
+ aa_mask = aa_scale - 1
+ };
+
+ //---------------------------------------------------------------------
+ line_profile_aa() :
+ m_subpixel_width(0),
+ m_min_width(1.0),
+ m_smoother_width(1.0)
+ {
+ int 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_subpixel_width(0),
+ m_min_width(1.0),
+ m_smoother_width(1.0)
+ {
+ gamma(gamma_function);
+ width(w);
+ }
+
+ //---------------------------------------------------------------------
+ void min_width(double w) { m_min_width = w; }
+ void smoother_width(double w) { m_smoother_width = w; }
+
+ //---------------------------------------------------------------------
+ template<class GammaF> void gamma(const GammaF& gamma_function)
+ {
+ int i;
+ for(i = 0; i < aa_scale; i++)
+ {
+ m_gamma[i] = value_type(
+ uround(gamma_function(double(i) / aa_mask) * aa_mask));
+ }
+ }
+
+ void width(double w);
+
+ unsigned profile_size() const { return m_profile.size(); }
+ int subpixel_width() const { return m_subpixel_width; }
+
+ //---------------------------------------------------------------------
+ double min_width() const { return m_min_width; }
+ double smoother_width() const { return m_smoother_width; }
+
+ //---------------------------------------------------------------------
+ value_type value(int dist) const
+ {
+ return m_profile[dist + subpixel_scale*2];
+ }
+
+ private:
+ line_profile_aa(const line_profile_aa&);
+ const line_profile_aa& operator = (const line_profile_aa&);
+
+ value_type* profile(double w);
+ void set(double center_width, double 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;
+ };
+
+
+ //======================================================renderer_outline_aa
+ template<class BaseRenderer> class renderer_outline_aa
+ {
+ public:
+ //---------------------------------------------------------------------
+ typedef BaseRenderer base_ren_type;
+ typedef renderer_outline_aa<base_ren_type> self_type;
+ typedef typename base_ren_type::color_type color_type;
+
+ //---------------------------------------------------------------------
+ renderer_outline_aa(base_ren_type& ren, line_profile_aa& prof) :
+ m_ren(&ren),
+ 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; }
+ const color_type& color() const { return m_color; }
+
+ //---------------------------------------------------------------------
+ void profile(line_profile_aa& prof) { m_profile = &prof; }
+ line_profile_aa& profile() const { return *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);
+ }
+
+ //-------------------------------------------------------------------------
+ void blend_solid_hspan(int x, int y, unsigned len, const cover_type* covers)
+ {
+ m_ren->blend_solid_hspan(x, y, len, m_color, covers);
+ }
+
+ //-------------------------------------------------------------------------
+ void blend_solid_vspan(int x, int y, unsigned len, const cover_type* covers)
+ {
+ m_ren->blend_solid_vspan(x, y, len, m_color, covers);
+ }
+
+ //-------------------------------------------------------------------------
+ static bool accurate_join_only() { return false; }
+
+ //-------------------------------------------------------------------------
+ template<class Cmp>
+ void semidot_hline(Cmp cmp,
+ int xc1, int yc1, int xc2, int yc2,
+ int x1, int y1, int x2)
+ {
+ cover_type covers[line_interpolator_aa_base<self_type>::max_half_width * 2 + 4];
+ cover_type* p0 = covers;
+ cover_type* p1 = covers;
+ int x = x1 << line_subpixel_shift;
+ int y = y1 << line_subpixel_shift;
+ int w = subpixel_width();
+ distance_interpolator0 di(xc1, yc1, xc2, yc2, x, y);
+ x += line_subpixel_scale/2;
+ y += line_subpixel_scale/2;
+
+ int x0 = x1;
+ int dx = x - xc1;
+ int dy = y - yc1;
+ do
+ {
+ int d = int(fast_sqrt(dx*dx + dy*dy));
+ *p1 = 0;
+ if(cmp(di.dist()) && d <= w)
+ {
+ *p1 = (cover_type)cover(d);
+ }
+ ++p1;
+ dx += line_subpixel_scale;
+ di.inc_x();
+ }
+ while(++x1 <= x2);
+ m_ren->blend_solid_hspan(x0, y1,
+ unsigned(p1 - p0),
+ color(),
+ p0);
+ }
+
+ //-------------------------------------------------------------------------
+ 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);
+ int dx = 0;
+ int dy = -r;
+ int dy0 = dy;
+ int dx0 = dx;
+ int x = xc1 >> line_subpixel_shift;
+ int y = yc1 >> line_subpixel_shift;
+
+ do
+ {
+ dx += ei.dx();
+ dy += ei.dy();
+
+ if(dy != dy0)
+ {
+ semidot_hline(cmp, xc1, yc1, xc2, yc2, x-dx0, y+dy0, x+dx0);
+ semidot_hline(cmp, xc1, yc1, xc2, yc2, x-dx0, y-dy0, x+dx0);
+ }
+ dx0 = dx;
+ dy0 = dy;
+ ++ei;
+ }
+ while(dy < 0);
+ semidot_hline(cmp, xc1, yc1, xc2, yc2, x-dx0, y+dy0, x+dx0);
+ }
+
+ //-------------------------------------------------------------------------
+ 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(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());
+ }
+ else
+ {
+ while(li.step_hor());
+ }
+ }
+ }
+
+ //-------------------------------------------------------------------------
+ void line0(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(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());
+ }
+ else
+ {
+ while(li.step_hor());
+ }
+ }
+
+
+ //-------------------------------------------------------------------------
+ void line1(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(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());
+ }
+ else
+ {
+ while(li.step_hor());
+ }
+ }
+
+ //-------------------------------------------------------------------------
+ void line2(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(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());
+ }
+ else
+ {
+ while(li.step_hor());
+ }
+ }
+
+ //-------------------------------------------------------------------------
+ void line3(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;
+ line_profile_aa* m_profile;
+ color_type m_color;
+ rect_i m_clip_box;
+ bool m_clipping;
+ };
+
+
+
+}
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_outline_image.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_outline_image.h
new file mode 100644
index 0000000000..8abb9fa0bd
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_outline_image.h
@@ -0,0 +1,1036 @@
+//----------------------------------------------------------------------------
+// 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_RENDERER_OUTLINE_IMAGE_INCLUDED
+#define AGG_RENDERER_OUTLINE_IMAGE_INCLUDED
+
+#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
+{
+ //========================================================line_image_scale
+ template<class Source> class line_image_scale
+ {
+ public:
+ typedef typename Source::color_type color_type;
+
+ line_image_scale(const Source& src, double height) :
+ m_source(src),
+ m_height(height),
+ m_scale(src.height() / height),
+ m_scale_inv(height / src.height())
+ {
+ }
+
+ double width() const { return m_source.width(); }
+ double height() const { return m_height; }
+
+ color_type pixel(int x, int y) const
+ {
+ if (m_scale < 1.0)
+ {
+ // Interpolate between nearest source pixels.
+ double src_y = (y + 0.5) * m_scale - 0.5;
+ int h = m_source.height() - 1;
+ int y1 = ifloor(src_y);
+ int y2 = y1 + 1;
+ rgba pix1 = (y1 < 0) ? rgba::no_color() : m_source.pixel(x, y1);
+ rgba pix2 = (y2 > h) ? rgba::no_color() : m_source.pixel(x, y2);
+ return pix1.gradient(pix2, src_y - y1);
+ }
+ else
+ {
+ // Average source pixels between y and y+1.
+ double src_y1 = (y + 0.5) * m_scale - 0.5;
+ double src_y2 = src_y1 + m_scale;
+ int h = m_source.height() - 1;
+ int y1 = ifloor(src_y1);
+ int y2 = ifloor(src_y2);
+ rgba c = rgba::no_color();
+ if (y1 >= 0) c += rgba(m_source.pixel(x, y1)) *= y1 + 1 - src_y1;
+ while (++y1 < y2)
+ {
+ if (y1 <= h) c += m_source.pixel(x, y1);
+ }
+ if (y2 <= h) c += rgba(m_source.pixel(x, y2)) *= src_y2 - y2;
+ return c *= m_scale_inv;
+ }
+ }
+
+ private:
+ line_image_scale(const line_image_scale<Source>&);
+ const line_image_scale<Source>& operator = (const line_image_scale<Source>&);
+
+ const Source& m_source;
+ double m_height;
+ double m_scale;
+ double m_scale_inv;
+ };
+
+
+
+ //======================================================line_image_pattern
+ template<class Filter> class line_image_pattern
+ {
+ public:
+ typedef Filter filter_type;
+ typedef typename filter_type::color_type color_type;
+
+ //--------------------------------------------------------------------
+ line_image_pattern(Filter& filter) :
+ m_filter(&filter),
+ m_dilation(filter.dilation() + 1),
+ m_dilation_hr(m_dilation << line_subpixel_shift),
+ m_data(),
+ m_width(0),
+ m_height(0),
+ m_width_hr(0),
+ m_half_height_hr(0),
+ m_offset_y_hr(0)
+ {
+ }
+
+ // Create
+ //--------------------------------------------------------------------
+ template<class Source>
+ line_image_pattern(Filter& filter, const Source& src) :
+ m_filter(&filter),
+ m_dilation(filter.dilation() + 1),
+ m_dilation_hr(m_dilation << line_subpixel_shift),
+ m_data(),
+ m_width(0),
+ m_height(0),
+ m_width_hr(0),
+ m_half_height_hr(0),
+ m_offset_y_hr(0)
+ {
+ create(src);
+ }
+
+ // Create
+ //--------------------------------------------------------------------
+ template<class Source> void create(const Source& src)
+ {
+ 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;
+
+ m_data.resize((m_width + m_dilation * 2) * (m_height + 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_ptr(y + m_dilation) + m_dilation;
+ for(x = 0; x < m_width; x++)
+ {
+ *d1++ = src.pixel(x, y);
+ }
+ }
+
+ const color_type* s1;
+ const color_type* s2;
+ for(y = 0; y < m_dilation; y++)
+ {
+ //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);
+ //*d2++ = color_type(*s2++, 0);
+ *d1++ = color_type::no_color();
+ *d2++ = color_type::no_color();
+ }
+ }
+
+ unsigned h = m_height + m_dilation * 2;
+ for(y = 0; y < h; y++)
+ {
+ 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++)
+ {
+ *d1++ = *s1++;
+ *--d2 = *--s2;
+ }
+ }
+ }
+
+ //--------------------------------------------------------------------
+ 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
+ {
+ m_filter->pixel_high_res(m_buf.rows(),
+ p,
+ x % m_width_hr + m_dilation_hr,
+ y + m_offset_y_hr);
+ }
+
+ //--------------------------------------------------------------------
+ const filter_type& filter() const { return *m_filter; }
+
+ private:
+ line_image_pattern(const line_image_pattern<filter_type>&);
+ const line_image_pattern<filter_type>&
+ operator = (const line_image_pattern<filter_type>&);
+
+ protected:
+ row_ptr_cache<color_type> m_buf;
+ const filter_type* m_filter;
+ unsigned m_dilation;
+ int m_dilation_hr;
+ pod_array<color_type> m_data;
+ unsigned m_width;
+ unsigned m_height;
+ int m_width_hr;
+ int m_half_height_hr;
+ int m_offset_y_hr;
+ };
+
+
+
+
+
+
+ //=================================================line_image_pattern_pow2
+ template<class Filter> class line_image_pattern_pow2 :
+ public line_image_pattern<Filter>
+ {
+ public:
+ typedef Filter filter_type;
+ typedef typename filter_type::color_type color_type;
+ typedef line_image_pattern<Filter> base_type;
+
+ //--------------------------------------------------------------------
+ line_image_pattern_pow2(Filter& filter) :
+ line_image_pattern<Filter>(filter), m_mask(line_subpixel_mask) {}
+
+ //--------------------------------------------------------------------
+ template<class Source>
+ line_image_pattern_pow2(Filter& filter, const Source& src) :
+ line_image_pattern<Filter>(filter), m_mask(line_subpixel_mask)
+ {
+ create(src);
+ }
+
+ //--------------------------------------------------------------------
+ template<class Source> void create(const Source& src)
+ {
+ line_image_pattern<Filter>::create(src);
+ m_mask = 1;
+ while(m_mask < base_type::m_width)
+ {
+ m_mask <<= 1;
+ m_mask |= 1;
+ }
+ m_mask <<= line_subpixel_shift - 1;
+ m_mask |= line_subpixel_mask;
+ base_type::m_width_hr = m_mask + 1;
+ }
+
+ //--------------------------------------------------------------------
+ void pixel(color_type* p, int x, int y) const
+ {
+ base_type::m_filter->pixel_high_res(
+ base_type::m_buf.rows(),
+ p,
+ (x & m_mask) + base_type::m_dilation_hr,
+ y + base_type::m_offset_y_hr);
+ }
+ private:
+ unsigned m_mask;
+ };
+
+
+
+
+
+
+
+ //===================================================distance_interpolator4
+ class distance_interpolator4
+ {
+ public:
+ //---------------------------------------------------------------------
+ distance_interpolator4() {}
+ distance_interpolator4(int x1, int y1, int x2, int y2,
+ int sx, int sy, int ex, int ey,
+ int len, double scale, int x, int y) :
+ m_dx(x2 - x1),
+ m_dy(y2 - y1),
+ m_dx_start(line_mr(sx) - line_mr(x1)),
+ m_dy_start(line_mr(sy) - line_mr(y1)),
+ m_dx_end(line_mr(ex) - line_mr(x2)),
+ m_dy_end(line_mr(ey) - line_mr(y2)),
+
+ 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_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_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 = 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_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;
+ m_dy <<= line_subpixel_shift;
+ m_dx_start <<= line_mr_subpixel_shift;
+ m_dy_start <<= line_mr_subpixel_shift;
+ m_dx_end <<= line_mr_subpixel_shift;
+ m_dy_end <<= line_mr_subpixel_shift;
+ }
+
+ //---------------------------------------------------------------------
+ void inc_x()
+ {
+ m_dist += m_dy;
+ m_dist_start += m_dy_start;
+ m_dist_pict += m_dy_pict;
+ m_dist_end += m_dy_end;
+ }
+
+ //---------------------------------------------------------------------
+ void dec_x()
+ {
+ m_dist -= m_dy;
+ m_dist_start -= m_dy_start;
+ m_dist_pict -= m_dy_pict;
+ m_dist_end -= m_dy_end;
+ }
+
+ //---------------------------------------------------------------------
+ void inc_y()
+ {
+ m_dist -= m_dx;
+ m_dist_start -= m_dx_start;
+ m_dist_pict -= m_dx_pict;
+ m_dist_end -= m_dx_end;
+ }
+
+ //---------------------------------------------------------------------
+ void dec_y()
+ {
+ m_dist += m_dx;
+ m_dist_start += m_dx_start;
+ m_dist_pict += m_dx_pict;
+ m_dist_end += m_dx_end;
+ }
+
+ //---------------------------------------------------------------------
+ void inc_x(int dy)
+ {
+ m_dist += m_dy;
+ m_dist_start += m_dy_start;
+ m_dist_pict += m_dy_pict;
+ m_dist_end += m_dy_end;
+ if(dy > 0)
+ {
+ m_dist -= m_dx;
+ m_dist_start -= m_dx_start;
+ m_dist_pict -= m_dx_pict;
+ m_dist_end -= m_dx_end;
+ }
+ if(dy < 0)
+ {
+ m_dist += m_dx;
+ m_dist_start += m_dx_start;
+ m_dist_pict += m_dx_pict;
+ m_dist_end += m_dx_end;
+ }
+ }
+
+ //---------------------------------------------------------------------
+ void dec_x(int dy)
+ {
+ m_dist -= m_dy;
+ m_dist_start -= m_dy_start;
+ m_dist_pict -= m_dy_pict;
+ m_dist_end -= m_dy_end;
+ if(dy > 0)
+ {
+ m_dist -= m_dx;
+ m_dist_start -= m_dx_start;
+ m_dist_pict -= m_dx_pict;
+ m_dist_end -= m_dx_end;
+ }
+ if(dy < 0)
+ {
+ m_dist += m_dx;
+ m_dist_start += m_dx_start;
+ m_dist_pict += m_dx_pict;
+ m_dist_end += m_dx_end;
+ }
+ }
+
+ //---------------------------------------------------------------------
+ void inc_y(int dx)
+ {
+ m_dist -= m_dx;
+ m_dist_start -= m_dx_start;
+ m_dist_pict -= m_dx_pict;
+ m_dist_end -= m_dx_end;
+ if(dx > 0)
+ {
+ m_dist += m_dy;
+ m_dist_start += m_dy_start;
+ m_dist_pict += m_dy_pict;
+ m_dist_end += m_dy_end;
+ }
+ if(dx < 0)
+ {
+ m_dist -= m_dy;
+ m_dist_start -= m_dy_start;
+ m_dist_pict -= m_dy_pict;
+ m_dist_end -= m_dy_end;
+ }
+ }
+
+ //---------------------------------------------------------------------
+ void dec_y(int dx)
+ {
+ m_dist += m_dx;
+ m_dist_start += m_dx_start;
+ m_dist_pict += m_dx_pict;
+ m_dist_end += m_dx_end;
+ if(dx > 0)
+ {
+ m_dist += m_dy;
+ m_dist_start += m_dy_start;
+ m_dist_pict += m_dy_pict;
+ m_dist_end += m_dy_end;
+ }
+ if(dx < 0)
+ {
+ m_dist -= m_dy;
+ m_dist_start -= m_dy_start;
+ m_dist_pict -= m_dy_pict;
+ m_dist_end -= m_dy_end;
+ }
+ }
+
+ //---------------------------------------------------------------------
+ int dist() const { return m_dist; }
+ int dist_start() const { return m_dist_start; }
+ int dist_pict() const { return m_dist_pict; }
+ int dist_end() const { return m_dist_end; }
+
+ //---------------------------------------------------------------------
+ int dx() const { return m_dx; }
+ int dy() const { return m_dy; }
+ int dx_start() const { return m_dx_start; }
+ int dy_start() const { return m_dy_start; }
+ int dx_pict() const { return m_dx_pict; }
+ int dy_pict() const { return m_dy_pict; }
+ int dx_end() const { return m_dx_end; }
+ int dy_end() const { return m_dy_end; }
+ int len() const { return m_len; }
+
+ private:
+ //---------------------------------------------------------------------
+ int m_dx;
+ int m_dy;
+ int m_dx_start;
+ int m_dy_start;
+ int m_dx_pict;
+ int m_dy_pict;
+ int m_dx_end;
+ int m_dy_end;
+
+ int m_dist;
+ int m_dist_start;
+ int m_dist_pict;
+ int m_dist_end;
+ int m_len;
+ };
+
+
+
+
+
+ //==================================================line_interpolator_image
+ template<class Renderer> class line_interpolator_image
+ {
+ public:
+ typedef Renderer renderer_type;
+ typedef typename Renderer::color_type color_type;
+
+ //---------------------------------------------------------------------
+ enum max_half_width_e
+ {
+ max_half_width = 64
+ };
+
+ //---------------------------------------------------------------------
+ line_interpolator_image(renderer_type& ren, const line_parameters& lp,
+ int sx, int sy, int ex, int ey,
+ int pattern_start,
+ double scale_x) :
+ m_lp(lp),
+ m_li(lp.vertical ? line_dbl_hr(lp.x2 - lp.x1) :
+ line_dbl_hr(lp.y2 - lp.y1),
+ lp.vertical ? abs(lp.y2 - lp.y1) :
+ abs(lp.x2 - lp.x1) + 1),
+ m_di(lp.x1, lp.y1, lp.x2, lp.y2, sx, sy, ex, ey, lp.len, scale_x,
+ lp.x1 & ~line_subpixel_mask, lp.y1 & ~line_subpixel_mask),
+ m_ren(ren),
+ m_x(lp.x1 >> line_subpixel_shift),
+ m_y(lp.y1 >> line_subpixel_shift),
+ m_old_x(m_x),
+ m_old_y(m_y),
+ 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_scale) >> line_subpixel_shift),
+ m_start(pattern_start + (m_max_extent + 2) * ren.pattern_width()),
+ m_step(0)
+ {
+ agg::dda2_line_interpolator li(0, lp.vertical ?
+ (lp.dy << agg::line_subpixel_shift) :
+ (lp.dx << agg::line_subpixel_shift),
+ lp.len);
+
+ unsigned i;
+ int stop = m_width + line_subpixel_scale * 2;
+ for(i = 0; i < max_half_width; ++i)
+ {
+ m_dist_pos[i] = li.y();
+ if(m_dist_pos[i] >= stop) break;
+ ++li;
+ }
+ m_dist_pos[i] = 0x7FFF0000;
+
+ int dist1_start;
+ int dist2_start;
+ int npix = 1;
+
+ if(lp.vertical)
+ {
+ do
+ {
+ --m_li;
+ m_y -= lp.inc;
+ m_x = (m_lp.x1 + m_li.y()) >> line_subpixel_shift;
+
+ if(lp.inc > 0) m_di.dec_y(m_x - m_old_x);
+ else m_di.inc_y(m_x - m_old_x);
+
+ m_old_x = m_x;
+
+ dist1_start = dist2_start = m_di.dist_start();
+
+ int dx = 0;
+ if(dist1_start < 0) ++npix;
+ do
+ {
+ dist1_start += m_di.dy_start();
+ dist2_start -= m_di.dy_start();
+ if(dist1_start < 0) ++npix;
+ if(dist2_start < 0) ++npix;
+ ++dx;
+ }
+ while(m_dist_pos[dx] <= m_width);
+ if(npix == 0) break;
+
+ npix = 0;
+ }
+ while(--m_step >= -m_max_extent);
+ }
+ else
+ {
+ do
+ {
+ --m_li;
+
+ m_x -= lp.inc;
+ m_y = (m_lp.y1 + m_li.y()) >> line_subpixel_shift;
+
+ if(lp.inc > 0) m_di.dec_x(m_y - m_old_y);
+ else m_di.inc_x(m_y - m_old_y);
+
+ m_old_y = m_y;
+
+ dist1_start = dist2_start = m_di.dist_start();
+
+ int dy = 0;
+ if(dist1_start < 0) ++npix;
+ do
+ {
+ dist1_start -= m_di.dx_start();
+ dist2_start += m_di.dx_start();
+ if(dist1_start < 0) ++npix;
+ if(dist2_start < 0) ++npix;
+ ++dy;
+ }
+ while(m_dist_pos[dy] <= m_width);
+ if(npix == 0) break;
+
+ npix = 0;
+ }
+ while(--m_step >= -m_max_extent);
+ }
+ m_li.adjust_forward();
+ m_step -= m_max_extent;
+ }
+
+ //---------------------------------------------------------------------
+ bool step_hor()
+ {
+ ++m_li;
+ m_x += m_lp.inc;
+ m_y = (m_lp.y1 + m_li.y()) >> line_subpixel_shift;
+
+ if(m_lp.inc > 0) m_di.inc_x(m_y - m_old_y);
+ else m_di.dec_x(m_y - m_old_y);
+
+ m_old_y = m_y;
+
+ int s1 = m_di.dist() / m_lp.len;
+ int s2 = -s1;
+
+ if(m_lp.inc < 0) s1 = -s1;
+
+ int dist_start;
+ int dist_pict;
+ int dist_end;
+ int dy;
+ int dist;
+
+ dist_start = m_di.dist_start();
+ dist_pict = m_di.dist_pict() + m_start;
+ dist_end = m_di.dist_end();
+ color_type* p0 = m_colors + max_half_width + 2;
+ color_type* p1 = p0;
+
+ int npix = 0;
+ p1->clear();
+ if(dist_end > 0)
+ {
+ if(dist_start <= 0)
+ {
+ m_ren.pixel(p1, dist_pict, s2);
+ }
+ ++npix;
+ }
+ ++p1;
+
+ dy = 1;
+ while((dist = m_dist_pos[dy]) - s1 <= m_width)
+ {
+ dist_start -= m_di.dx_start();
+ dist_pict -= m_di.dx_pict();
+ dist_end -= m_di.dx_end();
+ p1->clear();
+ if(dist_end > 0 && dist_start <= 0)
+ {
+ if(m_lp.inc > 0) dist = -dist;
+ m_ren.pixel(p1, dist_pict, s2 - dist);
+ ++npix;
+ }
+ ++p1;
+ ++dy;
+ }
+
+ dy = 1;
+ dist_start = m_di.dist_start();
+ dist_pict = m_di.dist_pict() + m_start;
+ dist_end = m_di.dist_end();
+ while((dist = m_dist_pos[dy]) + s1 <= m_width)
+ {
+ dist_start += m_di.dx_start();
+ dist_pict += m_di.dx_pict();
+ dist_end += m_di.dx_end();
+ --p0;
+ p0->clear();
+ if(dist_end > 0 && dist_start <= 0)
+ {
+ if(m_lp.inc > 0) dist = -dist;
+ m_ren.pixel(p0, dist_pict, s2 + dist);
+ ++npix;
+ }
+ ++dy;
+ }
+ m_ren.blend_color_vspan(m_x,
+ m_y - dy + 1,
+ unsigned(p1 - p0),
+ p0);
+ return npix && ++m_step < m_count;
+ }
+
+
+
+ //---------------------------------------------------------------------
+ bool step_ver()
+ {
+ ++m_li;
+ m_y += m_lp.inc;
+ m_x = (m_lp.x1 + m_li.y()) >> line_subpixel_shift;
+
+ if(m_lp.inc > 0) m_di.inc_y(m_x - m_old_x);
+ else m_di.dec_y(m_x - m_old_x);
+
+ m_old_x = m_x;
+
+ int s1 = m_di.dist() / m_lp.len;
+ int s2 = -s1;
+
+ if(m_lp.inc > 0) s1 = -s1;
+
+ int dist_start;
+ int dist_pict;
+ int dist_end;
+ int dist;
+ int dx;
+
+ dist_start = m_di.dist_start();
+ dist_pict = m_di.dist_pict() + m_start;
+ dist_end = m_di.dist_end();
+ color_type* p0 = m_colors + max_half_width + 2;
+ color_type* p1 = p0;
+
+ int npix = 0;
+ p1->clear();
+ if(dist_end > 0)
+ {
+ if(dist_start <= 0)
+ {
+ m_ren.pixel(p1, dist_pict, s2);
+ }
+ ++npix;
+ }
+ ++p1;
+
+ dx = 1;
+ while((dist = m_dist_pos[dx]) - s1 <= m_width)
+ {
+ dist_start += m_di.dy_start();
+ dist_pict += m_di.dy_pict();
+ dist_end += m_di.dy_end();
+ p1->clear();
+ if(dist_end > 0 && dist_start <= 0)
+ {
+ if(m_lp.inc > 0) dist = -dist;
+ m_ren.pixel(p1, dist_pict, s2 + dist);
+ ++npix;
+ }
+ ++p1;
+ ++dx;
+ }
+
+ dx = 1;
+ dist_start = m_di.dist_start();
+ dist_pict = m_di.dist_pict() + m_start;
+ dist_end = m_di.dist_end();
+ while((dist = m_dist_pos[dx]) + s1 <= m_width)
+ {
+ dist_start -= m_di.dy_start();
+ dist_pict -= m_di.dy_pict();
+ dist_end -= m_di.dy_end();
+ --p0;
+ p0->clear();
+ if(dist_end > 0 && dist_start <= 0)
+ {
+ if(m_lp.inc > 0) dist = -dist;
+ m_ren.pixel(p0, dist_pict, s2 - dist);
+ ++npix;
+ }
+ ++dx;
+ }
+ m_ren.blend_color_hspan(m_x - dx + 1,
+ m_y,
+ unsigned(p1 - p0),
+ p0);
+ return npix && ++m_step < m_count;
+ }
+
+
+ //---------------------------------------------------------------------
+ int pattern_end() const { return m_start + m_di.len(); }
+
+ //---------------------------------------------------------------------
+ bool vertical() const { return m_lp.vertical; }
+ int width() const { return m_width; }
+ int count() const { return m_count; }
+
+ private:
+ line_interpolator_image(const line_interpolator_image<Renderer>&);
+ const line_interpolator_image<Renderer>&
+ operator = (const line_interpolator_image<Renderer>&);
+
+ protected:
+ const line_parameters& m_lp;
+ dda2_line_interpolator m_li;
+ distance_interpolator4 m_di;
+ renderer_type& m_ren;
+ int m_plen;
+ int m_x;
+ int m_y;
+ int m_old_x;
+ int m_old_y;
+ int m_count;
+ int m_width;
+ int m_max_extent;
+ int m_start;
+ int m_step;
+ int m_dist_pos[max_half_width + 1];
+ color_type m_colors[max_half_width * 2 + 4];
+ };
+
+
+
+
+
+
+
+
+ //===================================================renderer_outline_image
+ template<class BaseRenderer, class ImagePattern>
+ class renderer_outline_image
+ {
+ public:
+ //---------------------------------------------------------------------
+ typedef BaseRenderer base_ren_type;
+ typedef renderer_outline_image<BaseRenderer, ImagePattern> self_type;
+ typedef typename base_ren_type::color_type color_type;
+ typedef ImagePattern pattern_type;
+
+
+ //---------------------------------------------------------------------
+ renderer_outline_image(base_ren_type& ren, pattern_type& patt) :
+ m_ren(&ren),
+ m_pattern(&patt),
+ m_start(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(pattern_type& p) { m_pattern = &p; }
+ 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 = 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
+ {
+ m_pattern->pixel(p, x, y);
+ }
+
+ //-------------------------------------------------------------------------
+ void blend_color_hspan(int x, int y, unsigned len, const color_type* colors)
+ {
+ m_ren->blend_color_hspan(x, y, len, colors, 0);
+ }
+
+ //-------------------------------------------------------------------------
+ void blend_color_vspan(int x, int y, unsigned len, const color_type* colors)
+ {
+ m_ren->blend_color_vspan(x, y, len, colors, 0);
+ }
+
+ //-------------------------------------------------------------------------
+ static bool accurate_join_only() { return true; }
+
+ //-------------------------------------------------------------------------
+ template<class Cmp>
+ void semidot(Cmp, int, int, int, int)
+ {
+ }
+
+ //-------------------------------------------------------------------------
+ void pie(int, int, int, int, int, int)
+ {
+ }
+
+ //-------------------------------------------------------------------------
+ void line0(const line_parameters&)
+ {
+ }
+
+ //-------------------------------------------------------------------------
+ void line1(const line_parameters&, int, int)
+ {
+ }
+
+ //-------------------------------------------------------------------------
+ void line2(const line_parameters&, int, int)
+ {
+ }
+
+ //-------------------------------------------------------------------------
+ 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,
+ sx, sy,
+ ex, ey,
+ m_start, m_scale_x);
+ if(li.vertical())
+ {
+ while(li.step_ver());
+ }
+ else
+ {
+ while(li.step_hor());
+ }
+ 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:
+ base_ren_type* m_ren;
+ pattern_type* m_pattern;
+ int m_start;
+ double m_scale_x;
+ rect_i m_clip_box;
+ bool m_clipping;
+ };
+
+
+
+
+
+}
+
+
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_primitives.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_primitives.h
new file mode 100644
index 0000000000..f008db7c94
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_primitives.h
@@ -0,0 +1,224 @@
+//----------------------------------------------------------------------------
+// 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
+//----------------------------------------------------------------------------
+//
+// class renderer_primitives
+//
+//----------------------------------------------------------------------------
+
+#ifndef AGG_RENDERER_PRIMITIVES_INCLUDED
+#define AGG_RENDERER_PRIMITIVES_INCLUDED
+
+#include "agg_basics.h"
+#include "agg_renderer_base.h"
+#include "agg_dda_line.h"
+#include "agg_ellipse_bresenham.h"
+
+namespace agg
+{
+ //-----------------------------------------------------renderer_primitives
+ template<class BaseRenderer> class renderer_primitives
+ {
+ public:
+ typedef BaseRenderer base_ren_type;
+ typedef typename base_ren_type::color_type color_type;
+
+ //--------------------------------------------------------------------
+ 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 iround(c * line_bresenham_interpolator::subpixel_scale);
+ }
+
+ //--------------------------------------------------------------------
+ void fill_color(const color_type& c) { m_fill_color = c; }
+ void line_color(const color_type& c) { m_line_color = c; }
+ const color_type& fill_color() const { return m_fill_color; }
+ const color_type& line_color() const { return m_line_color; }
+
+ //--------------------------------------------------------------------
+ void rectangle(int x1, int y1, int x2, int y2)
+ {
+ m_ren->blend_hline(x1, y1, x2-1, m_line_color, cover_full);
+ m_ren->blend_vline(x2, y1, y2-1, m_line_color, cover_full);
+ m_ren->blend_hline(x1+1, y2, x2, m_line_color, cover_full);
+ m_ren->blend_vline(x1, y1+1, y2, m_line_color, cover_full);
+ }
+
+ //--------------------------------------------------------------------
+ void solid_rectangle(int x1, int y1, int x2, int y2)
+ {
+ m_ren->blend_bar(x1, y1, x2, y2, m_fill_color, cover_full);
+ }
+
+ //--------------------------------------------------------------------
+ void outlined_rectangle(int x1, int y1, int x2, int y2)
+ {
+ rectangle(x1, y1, x2, y2);
+ m_ren->blend_bar(x1+1, y1+1, x2-1, y2-1, m_fill_color, cover_full);
+ }
+
+ //--------------------------------------------------------------------
+ void ellipse(int x, int y, int rx, int ry)
+ {
+ ellipse_bresenham_interpolator ei(rx, ry);
+ int dx = 0;
+ int dy = -ry;
+ do
+ {
+ dx += ei.dx();
+ dy += ei.dy();
+ m_ren->blend_pixel(x + dx, y + dy, m_line_color, cover_full);
+ m_ren->blend_pixel(x + dx, y - dy, m_line_color, cover_full);
+ m_ren->blend_pixel(x - dx, y - dy, m_line_color, cover_full);
+ m_ren->blend_pixel(x - dx, y + dy, m_line_color, cover_full);
+ ++ei;
+ }
+ while(dy < 0);
+ }
+
+ //--------------------------------------------------------------------
+ void solid_ellipse(int x, int y, int rx, int ry)
+ {
+ ellipse_bresenham_interpolator ei(rx, ry);
+ int dx = 0;
+ int dy = -ry;
+ int dy0 = dy;
+ int dx0 = dx;
+
+ do
+ {
+ dx += ei.dx();
+ dy += ei.dy();
+
+ if(dy != dy0)
+ {
+ m_ren->blend_hline(x-dx0, y+dy0, x+dx0, m_fill_color, cover_full);
+ m_ren->blend_hline(x-dx0, y-dy0, x+dx0, m_fill_color, cover_full);
+ }
+ dx0 = dx;
+ dy0 = dy;
+ ++ei;
+ }
+ while(dy < 0);
+ m_ren->blend_hline(x-dx0, y+dy0, x+dx0, m_fill_color, cover_full);
+ }
+
+ //--------------------------------------------------------------------
+ void outlined_ellipse(int x, int y, int rx, int ry)
+ {
+ ellipse_bresenham_interpolator ei(rx, ry);
+ int dx = 0;
+ int dy = -ry;
+
+ do
+ {
+ dx += ei.dx();
+ dy += ei.dy();
+
+ m_ren->blend_pixel(x + dx, y + dy, m_line_color, cover_full);
+ m_ren->blend_pixel(x + dx, y - dy, m_line_color, cover_full);
+ m_ren->blend_pixel(x - dx, y - dy, m_line_color, cover_full);
+ m_ren->blend_pixel(x - dx, y + dy, m_line_color, cover_full);
+
+ if(ei.dy() && dx)
+ {
+ m_ren->blend_hline(x-dx+1, y+dy, x+dx-1, m_fill_color, cover_full);
+ m_ren->blend_hline(x-dx+1, y-dy, x+dx-1, m_fill_color, cover_full);
+ }
+ ++ei;
+ }
+ while(dy < 0);
+ }
+
+ //--------------------------------------------------------------------
+ void line(int x1, int y1, int x2, int y2, bool last=false)
+ {
+ line_bresenham_interpolator li(x1, y1, x2, y2);
+
+ unsigned len = li.len();
+ if(len == 0)
+ {
+ if(last)
+ {
+ m_ren->blend_pixel(li.line_lr(x1), li.line_lr(y1), m_line_color, cover_full);
+ }
+ return;
+ }
+
+ if(last) ++len;
+
+ if(li.is_ver())
+ {
+ do
+ {
+ m_ren->blend_pixel(li.x2(), li.y1(), m_line_color, cover_full);
+ li.vstep();
+ }
+ while(--len);
+ }
+ else
+ {
+ do
+ {
+ m_ren->blend_pixel(li.x1(), li.y2(), m_line_color, cover_full);
+ li.hstep();
+ }
+ while(--len);
+ }
+ }
+
+ //--------------------------------------------------------------------
+ void move_to(int x, int y)
+ {
+ m_curr_x = x;
+ m_curr_y = y;
+ }
+
+ //--------------------------------------------------------------------
+ void line_to(int x, int y, bool last=false)
+ {
+ line(m_curr_x, m_curr_y, x, y, last);
+ m_curr_x = x;
+ m_curr_y = y;
+ }
+
+ //--------------------------------------------------------------------
+ const base_ren_type& ren() const { return *m_ren; }
+ base_ren_type& ren() { return *m_ren; }
+
+ //--------------------------------------------------------------------
+ const rendering_buffer& rbuf() const { return m_ren->rbuf(); }
+ rendering_buffer& rbuf() { return m_ren->rbuf(); }
+
+ private:
+ base_ren_type* m_ren;
+ color_type m_fill_color;
+ color_type m_line_color;
+ int m_curr_x;
+ int m_curr_y;
+ };
+
+}
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_raster_text.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_raster_text.h
new file mode 100644
index 0000000000..87b43f9600
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_raster_text.h
@@ -0,0 +1,264 @@
+//----------------------------------------------------------------------------
+// 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_RENDERER_RASTER_TEXT_INCLUDED
+#define AGG_RENDERER_RASTER_TEXT_INCLUDED
+
+#include "agg_basics.h"
+
+namespace agg
+{
+
+ //==============================================renderer_raster_htext_solid
+ template<class BaseRenderer, class GlyphGenerator>
+ class renderer_raster_htext_solid
+ {
+ public:
+ typedef BaseRenderer ren_type;
+ typedef GlyphGenerator glyph_gen_type;
+ typedef typename glyph_gen_type::glyph_rect glyph_rect;
+ typedef typename ren_type::color_type color_type;
+
+ 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; }
+ const color_type& color() const { return m_color; }
+
+ //--------------------------------------------------------------------
+ template<class CharT>
+ void render_text(double x, double y, const CharT* str, bool flip=false)
+ {
+ glyph_rect r;
+ while(*str)
+ {
+ m_glyph->prepare(&r, x, y, *str, flip);
+ if(r.x2 >= r.x1)
+ {
+ int i;
+ if(flip)
+ {
+ for(i = r.y1; i <= r.y2; i++)
+ {
+ m_ren->blend_solid_hspan(r.x1, i, (r.x2 - r.x1 + 1),
+ m_color,
+ m_glyph->span(r.y2 - i));
+ }
+ }
+ else
+ {
+ for(i = r.y1; i <= r.y2; i++)
+ {
+ m_ren->blend_solid_hspan(r.x1, i, (r.x2 - r.x1 + 1),
+ m_color,
+ m_glyph->span(i - r.y1));
+ }
+ }
+ }
+ x += r.dx;
+ y += r.dy;
+ ++str;
+ }
+ }
+
+ private:
+ ren_type* m_ren;
+ glyph_gen_type* m_glyph;
+ color_type m_color;
+ };
+
+
+
+ //=============================================renderer_raster_vtext_solid
+ template<class BaseRenderer, class GlyphGenerator>
+ class renderer_raster_vtext_solid
+ {
+ public:
+ typedef BaseRenderer ren_type;
+ typedef GlyphGenerator glyph_gen_type;
+ typedef typename glyph_gen_type::glyph_rect glyph_rect;
+ typedef typename ren_type::color_type color_type;
+
+ renderer_raster_vtext_solid(ren_type& ren, glyph_gen_type& glyph) :
+ m_ren(&ren),
+ m_glyph(&glyph)
+ {
+ }
+
+ //--------------------------------------------------------------------
+ void color(const color_type& c) { m_color = c; }
+ const color_type& color() const { return m_color; }
+
+ //--------------------------------------------------------------------
+ template<class CharT>
+ void render_text(double x, double y, const CharT* str, bool flip=false)
+ {
+ glyph_rect r;
+ while(*str)
+ {
+ m_glyph->prepare(&r, x, y, *str, !flip);
+ if(r.x2 >= r.x1)
+ {
+ int i;
+ if(flip)
+ {
+ for(i = r.y1; i <= r.y2; i++)
+ {
+ m_ren->blend_solid_vspan(i, r.x1, (r.x2 - r.x1 + 1),
+ m_color,
+ m_glyph->span(i - r.y1));
+ }
+ }
+ else
+ {
+ for(i = r.y1; i <= r.y2; i++)
+ {
+ m_ren->blend_solid_vspan(i, r.x1, (r.x2 - r.x1 + 1),
+ m_color,
+ m_glyph->span(r.y2 - i));
+ }
+ }
+ }
+ x += r.dx;
+ y += r.dy;
+ ++str;
+ }
+ }
+
+ private:
+ ren_type* m_ren;
+ glyph_gen_type* m_glyph;
+ color_type m_color;
+ };
+
+
+
+
+
+
+ //===================================================renderer_raster_htext
+ template<class ScanlineRenderer, class GlyphGenerator>
+ class renderer_raster_htext
+ {
+ public:
+ typedef ScanlineRenderer ren_type;
+ typedef GlyphGenerator glyph_gen_type;
+ typedef typename glyph_gen_type::glyph_rect glyph_rect;
+
+ class scanline_single_span
+ {
+ public:
+ typedef agg::cover_type cover_type;
+
+ //----------------------------------------------------------------
+ struct const_span
+ {
+ int x;
+ unsigned len;
+ const cover_type* covers;
+
+ const_span() {}
+ const_span(int x_, unsigned len_, const cover_type* covers_) :
+ x(x_), len(len_), covers(covers_)
+ {}
+ };
+
+ typedef const const_span* const_iterator;
+
+ //----------------------------------------------------------------
+ scanline_single_span(int x, int y, unsigned len,
+ const cover_type* covers) :
+ m_y(y),
+ m_span(x, len, covers)
+ {}
+
+ //----------------------------------------------------------------
+ int y() const { return m_y; }
+ unsigned num_spans() const { return 1; }
+ const_iterator begin() const { return &m_span; }
+
+ private:
+ //----------------------------------------------------------------
+ int m_y;
+ const_span m_span;
+ };
+
+
+
+ //--------------------------------------------------------------------
+ renderer_raster_htext(ren_type& ren, glyph_gen_type& glyph) :
+ m_ren(&ren),
+ m_glyph(&glyph)
+ {
+ }
+
+
+ //--------------------------------------------------------------------
+ template<class CharT>
+ void render_text(double x, double y, const CharT* str, bool flip=false)
+ {
+ glyph_rect r;
+ while(*str)
+ {
+ m_glyph->prepare(&r, x, y, *str, flip);
+ if(r.x2 >= r.x1)
+ {
+ m_ren->prepare();
+ int i;
+ if(flip)
+ {
+ for(i = r.y1; i <= r.y2; i++)
+ {
+ m_ren->render(
+ scanline_single_span(r.x1,
+ i,
+ (r.x2 - r.x1 + 1),
+ m_glyph->span(r.y2 - i)));
+ }
+ }
+ else
+ {
+ for(i = r.y1; i <= r.y2; i++)
+ {
+ m_ren->render(
+ scanline_single_span(r.x1,
+ i,
+ (r.x2 - r.x1 + 1),
+ m_glyph->span(i - r.y1)));
+ }
+ }
+ }
+ x += r.dx;
+ y += r.dy;
+ ++str;
+ }
+ }
+
+ private:
+ ren_type* m_ren;
+ glyph_gen_type* m_glyph;
+ };
+
+
+
+
+}
+
+#endif
+
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rendering_buffer_dynarow.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rendering_buffer_dynarow.h
new file mode 100644
index 0000000000..188746f3d3
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rendering_buffer_dynarow.h
@@ -0,0 +1,137 @@
+//----------------------------------------------------------------------------
+// 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
+//----------------------------------------------------------------------------
+//
+// class rendering_buffer_dynarow
+//
+//----------------------------------------------------------------------------
+
+#ifndef AGG_RENDERING_BUFFER_DYNAROW_INCLUDED
+#define AGG_RENDERING_BUFFER_DYNAROW_INCLUDED
+
+#include "agg_array.h"
+
+namespace agg
+{
+
+ //===============================================rendering_buffer_dynarow
+ // Rendering buffer class with dynamic allocation of the rows.
+ // The rows are allocated as needed when requesting for span_ptr().
+ // The class automatically calculates min_x and max_x for each row.
+ // Generally it's more efficient to use this class as a temporary buffer
+ // for rendering a few lines and then to blend it with another buffer.
+ //
+ class rendering_buffer_dynarow
+ {
+ public:
+ typedef row_info<int8u> row_data;
+
+ //-------------------------------------------------------------------
+ ~rendering_buffer_dynarow()
+ {
+ init(0,0,0);
+ }
+
+ //-------------------------------------------------------------------
+ rendering_buffer_dynarow() :
+ m_rows(),
+ m_width(0),
+ m_height(0),
+ m_byte_width(0)
+ {
+ }
+
+ // Allocate and clear the buffer
+ //--------------------------------------------------------------------
+ rendering_buffer_dynarow(unsigned width, unsigned height,
+ unsigned byte_width) :
+ m_rows(height),
+ m_width(width),
+ m_height(height),
+ m_byte_width(byte_width)
+ {
+ memset(&m_rows[0], 0, sizeof(row_data) * height);
+ }
+
+ // Allocate and clear the buffer
+ //--------------------------------------------------------------------
+ void init(unsigned width, unsigned height, unsigned byte_width)
+ {
+ unsigned i;
+ 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_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; }
+ 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* row_ptr(int x, int y, unsigned len)
+ {
+ row_data* r = &m_rows[y];
+ int x2 = x + len - 1;
+ if(r->ptr)
+ {
+ if(x < r->x1) { r->x1 = x; }
+ if(x2 > r->x2) { r->x2 = x2; }
+ }
+ else
+ {
+ 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 (int8u*)r->ptr;
+ }
+
+ //--------------------------------------------------------------------
+ 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&);
+ const rendering_buffer_dynarow& operator = (const rendering_buffer_dynarow&);
+
+ private:
+ //--------------------------------------------------------------------
+ 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
+ };
+
+
+}
+
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rounded_rect.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rounded_rect.h
new file mode 100644
index 0000000000..fe8d26f71b
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rounded_rect.h
@@ -0,0 +1,72 @@
+//----------------------------------------------------------------------------
+// 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
+//----------------------------------------------------------------------------
+//
+// Rounded rectangle vertex generator
+//
+//----------------------------------------------------------------------------
+
+#ifndef AGG_ROUNDED_RECT_INCLUDED
+#define AGG_ROUNDED_RECT_INCLUDED
+
+#include "agg_basics.h"
+#include "agg_arc.h"
+
+namespace agg
+{
+ //------------------------------------------------------------rounded_rect
+ //
+ // See Implemantation agg_rounded_rect.cpp
+ //
+ class rounded_rect
+ {
+ public:
+ rounded_rect() {}
+ rounded_rect(double x1, double y1, double x2, double y2, double r);
+
+ void rect(double x1, double y1, double x2, double y2);
+ void radius(double r);
+ void radius(double rx, double ry);
+ void radius(double rx_bottom, double ry_bottom, double rx_top, double ry_top);
+ void radius(double rx1, double ry1, double rx2, double ry2,
+ double rx3, double ry3, double rx4, double ry4);
+ void normalize_radius();
+
+ void approximation_scale(double s) { m_arc.approximation_scale(s); }
+ double approximation_scale() const { return m_arc.approximation_scale(); }
+
+ void rewind(unsigned);
+ unsigned vertex(double* x, double* y);
+
+ private:
+ double m_x1;
+ double m_y1;
+ double m_x2;
+ double m_y2;
+ double m_rx1;
+ double m_ry1;
+ double m_rx2;
+ double m_ry2;
+ double m_rx3;
+ double m_ry3;
+ double m_rx4;
+ double m_ry4;
+ unsigned m_status;
+ arc m_arc;
+ };
+
+}
+
+#endif
+
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_scanline_boolean_algebra.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_scanline_boolean_algebra.h
new file mode 100644
index 0000000000..bc2e9c9d51
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_scanline_boolean_algebra.h
@@ -0,0 +1,1567 @@
+//----------------------------------------------------------------------------
+// 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_SCANLINE_BOOLEAN_ALGEBRA_INCLUDED
+#define AGG_SCANLINE_BOOLEAN_ALGEBRA_INCLUDED
+
+#include <stdlib.h>
+#include <math.h>
+#include "agg_basics.h"
+
+
+namespace agg
+{
+
+ //-----------------------------------------------sbool_combine_spans_bin
+ // Functor.
+ // Combine two binary encoded spans, i.e., when we don't have any
+ // anti-aliasing information, but only X and Length. The function
+ // is compatible with any type of scanlines.
+ //----------------
+ template<class Scanline1,
+ class Scanline2,
+ class Scanline>
+ struct sbool_combine_spans_bin
+ {
+ void operator () (const typename Scanline1::const_iterator&,
+ const typename Scanline2::const_iterator&,
+ int x, unsigned len,
+ Scanline& sl) const
+ {
+ sl.add_span(x, len, cover_full);
+ }
+ };
+
+
+
+ //---------------------------------------------sbool_combine_spans_empty
+ // Functor.
+ // Combine two spans as empty ones. The functor does nothing
+ // and is used to XOR binary spans.
+ //----------------
+ template<class Scanline1,
+ class Scanline2,
+ class Scanline>
+ struct sbool_combine_spans_empty
+ {
+ void operator () (const typename Scanline1::const_iterator&,
+ const typename Scanline2::const_iterator&,
+ int, unsigned,
+ Scanline&) const
+ {}
+ };
+
+
+
+ //--------------------------------------------------sbool_add_span_empty
+ // Functor.
+ // Add nothing. Used in conbine_shapes_sub
+ //----------------
+ template<class Scanline1,
+ class Scanline>
+ struct sbool_add_span_empty
+ {
+ void operator () (const typename Scanline1::const_iterator&,
+ int, unsigned,
+ Scanline&) const
+ {}
+ };
+
+
+ //----------------------------------------------------sbool_add_span_bin
+ // Functor.
+ // Add a binary span
+ //----------------
+ template<class Scanline1,
+ class Scanline>
+ struct sbool_add_span_bin
+ {
+ void operator () (const typename Scanline1::const_iterator&,
+ int x, unsigned len,
+ Scanline& sl) const
+ {
+ sl.add_span(x, len, cover_full);
+ }
+ };
+
+
+
+
+ //-----------------------------------------------------sbool_add_span_aa
+ // Functor.
+ // Add an anti-aliased span
+ // anti-aliasing information, but only X and Length. The function
+ // is compatible with any type of scanlines.
+ //----------------
+ template<class Scanline1,
+ class Scanline>
+ struct sbool_add_span_aa
+ {
+ void operator () (const typename Scanline1::const_iterator& span,
+ int x, unsigned len,
+ Scanline& sl) const
+ {
+ if(span->len < 0)
+ {
+ sl.add_span(x, len, *span->covers);
+ }
+ else
+ if(span->len > 0)
+ {
+ const typename Scanline1::cover_type* covers = span->covers;
+ if(span->x < x) covers += x - span->x;
+ sl.add_cells(x, len, covers);
+ }
+ }
+ };
+
+
+
+
+ //----------------------------------------------sbool_intersect_spans_aa
+ // Functor.
+ // Intersect two spans preserving the anti-aliasing information.
+ // The result is added to the "sl" scanline.
+ //------------------
+ template<class Scanline1,
+ class Scanline2,
+ class Scanline,
+ unsigned CoverShift = cover_shift>
+ struct sbool_intersect_spans_aa
+ {
+ enum cover_scale_e
+ {
+ cover_shift = CoverShift,
+ cover_size = 1 << cover_shift,
+ cover_mask = cover_size - 1,
+ cover_full = cover_mask
+ };
+
+
+ void operator () (const typename Scanline1::const_iterator& span1,
+ const typename Scanline2::const_iterator& span2,
+ int x, unsigned len,
+ Scanline& sl) const
+ {
+ unsigned cover;
+ const typename Scanline1::cover_type* covers1;
+ const typename Scanline2::cover_type* covers2;
+
+ // Calculate the operation code and choose the
+ // proper combination algorithm.
+ // 0 = Both spans are of AA type
+ // 1 = span1 is solid, span2 is AA
+ // 2 = span1 is AA, span2 is solid
+ // 3 = Both spans are of solid type
+ //-----------------
+ switch((span1->len < 0) | ((span2->len < 0) << 1))
+ {
+ case 0: // Both are AA spans
+ covers1 = span1->covers;
+ covers2 = span2->covers;
+ if(span1->x < x) covers1 += x - span1->x;
+ if(span2->x < x) covers2 += x - span2->x;
+ do
+ {
+ cover = *covers1++ * *covers2++;
+ sl.add_cell(x++,
+ (cover == cover_full * cover_full) ?
+ cover_full :
+ (cover >> cover_shift));
+ }
+ while(--len);
+ break;
+
+ case 1: // span1 is solid, span2 is AA
+ covers2 = span2->covers;
+ if(span2->x < x) covers2 += x - span2->x;
+ if(*(span1->covers) == cover_full)
+ {
+ sl.add_cells(x, len, covers2);
+ }
+ else
+ {
+ do
+ {
+ cover = *(span1->covers) * *covers2++;
+ sl.add_cell(x++,
+ (cover == cover_full * cover_full) ?
+ cover_full :
+ (cover >> cover_shift));
+ }
+ while(--len);
+ }
+ break;
+
+ case 2: // span1 is AA, span2 is solid
+ covers1 = span1->covers;
+ if(span1->x < x) covers1 += x - span1->x;
+ if(*(span2->covers) == cover_full)
+ {
+ sl.add_cells(x, len, covers1);
+ }
+ else
+ {
+ do
+ {
+ cover = *covers1++ * *(span2->covers);
+ sl.add_cell(x++,
+ (cover == cover_full * cover_full) ?
+ cover_full :
+ (cover >> cover_shift));
+ }
+ while(--len);
+ }
+ break;
+
+ case 3: // Both are solid spans
+ cover = *(span1->covers) * *(span2->covers);
+ sl.add_span(x, len,
+ (cover == cover_full * cover_full) ?
+ cover_full :
+ (cover >> cover_shift));
+ break;
+ }
+ }
+ };
+
+
+
+
+
+
+ //--------------------------------------------------sbool_unite_spans_aa
+ // Functor.
+ // Unite two spans preserving the anti-aliasing information.
+ // The result is added to the "sl" scanline.
+ //------------------
+ template<class Scanline1,
+ class Scanline2,
+ class Scanline,
+ unsigned CoverShift = cover_shift>
+ struct sbool_unite_spans_aa
+ {
+ enum cover_scale_e
+ {
+ cover_shift = CoverShift,
+ cover_size = 1 << cover_shift,
+ cover_mask = cover_size - 1,
+ cover_full = cover_mask
+ };
+
+
+ void operator () (const typename Scanline1::const_iterator& span1,
+ const typename Scanline2::const_iterator& span2,
+ int x, unsigned len,
+ Scanline& sl) const
+ {
+ unsigned cover;
+ const typename Scanline1::cover_type* covers1;
+ const typename Scanline2::cover_type* covers2;
+
+ // Calculate the operation code and choose the
+ // proper combination algorithm.
+ // 0 = Both spans are of AA type
+ // 1 = span1 is solid, span2 is AA
+ // 2 = span1 is AA, span2 is solid
+ // 3 = Both spans are of solid type
+ //-----------------
+ switch((span1->len < 0) | ((span2->len < 0) << 1))
+ {
+ case 0: // Both are AA spans
+ covers1 = span1->covers;
+ covers2 = span2->covers;
+ if(span1->x < x) covers1 += x - span1->x;
+ if(span2->x < x) covers2 += x - span2->x;
+ do
+ {
+ cover = cover_mask * cover_mask -
+ (cover_mask - *covers1++) *
+ (cover_mask - *covers2++);
+ sl.add_cell(x++,
+ (cover == cover_full * cover_full) ?
+ cover_full :
+ (cover >> cover_shift));
+ }
+ while(--len);
+ break;
+
+ case 1: // span1 is solid, span2 is AA
+ covers2 = span2->covers;
+ if(span2->x < x) covers2 += x - span2->x;
+ if(*(span1->covers) == cover_full)
+ {
+ sl.add_span(x, len, cover_full);
+ }
+ else
+ {
+ do
+ {
+ cover = cover_mask * cover_mask -
+ (cover_mask - *(span1->covers)) *
+ (cover_mask - *covers2++);
+ sl.add_cell(x++,
+ (cover == cover_full * cover_full) ?
+ cover_full :
+ (cover >> cover_shift));
+ }
+ while(--len);
+ }
+ break;
+
+ case 2: // span1 is AA, span2 is solid
+ covers1 = span1->covers;
+ if(span1->x < x) covers1 += x - span1->x;
+ if(*(span2->covers) == cover_full)
+ {
+ sl.add_span(x, len, cover_full);
+ }
+ else
+ {
+ do
+ {
+ cover = cover_mask * cover_mask -
+ (cover_mask - *covers1++) *
+ (cover_mask - *(span2->covers));
+ sl.add_cell(x++,
+ (cover == cover_full * cover_full) ?
+ cover_full :
+ (cover >> cover_shift));
+ }
+ while(--len);
+ }
+ break;
+
+ case 3: // Both are solid spans
+ cover = cover_mask * cover_mask -
+ (cover_mask - *(span1->covers)) *
+ (cover_mask - *(span2->covers));
+ sl.add_span(x, len,
+ (cover == cover_full * cover_full) ?
+ cover_full :
+ (cover >> cover_shift));
+ break;
+ }
+ }
+ };
+
+
+ //---------------------------------------------sbool_xor_formula_linear
+ template<unsigned CoverShift = cover_shift>
+ struct sbool_xor_formula_linear
+ {
+ enum cover_scale_e
+ {
+ cover_shift = CoverShift,
+ cover_size = 1 << cover_shift,
+ cover_mask = cover_size - 1
+ };
+
+ static AGG_INLINE unsigned calculate(unsigned a, unsigned b)
+ {
+ unsigned cover = a + b;
+ if(cover > cover_mask) cover = cover_mask + cover_mask - cover;
+ return cover;
+ }
+ };
+
+
+ //---------------------------------------------sbool_xor_formula_saddle
+ template<unsigned CoverShift = cover_shift>
+ struct sbool_xor_formula_saddle
+ {
+ enum cover_scale_e
+ {
+ cover_shift = CoverShift,
+ cover_size = 1 << cover_shift,
+ cover_mask = cover_size - 1
+ };
+
+ static AGG_INLINE unsigned calculate(unsigned a, unsigned b)
+ {
+ unsigned k = a * b;
+ if(k == cover_mask * cover_mask) return 0;
+
+ a = (cover_mask * cover_mask - (a << cover_shift) + k) >> cover_shift;
+ b = (cover_mask * cover_mask - (b << cover_shift) + k) >> cover_shift;
+ return cover_mask - ((a * b) >> cover_shift);
+ }
+ };
+
+
+ //-------------------------------------------sbool_xor_formula_abs_diff
+ struct sbool_xor_formula_abs_diff
+ {
+ static AGG_INLINE unsigned calculate(unsigned a, unsigned b)
+ {
+ return unsigned(abs(int(a) - int(b)));
+ }
+ };
+
+
+
+ //----------------------------------------------------sbool_xor_spans_aa
+ // Functor.
+ // XOR two spans preserving the anti-aliasing information.
+ // The result is added to the "sl" scanline.
+ //------------------
+ template<class Scanline1,
+ class Scanline2,
+ class Scanline,
+ class XorFormula,
+ unsigned CoverShift = cover_shift>
+ struct sbool_xor_spans_aa
+ {
+ enum cover_scale_e
+ {
+ cover_shift = CoverShift,
+ cover_size = 1 << cover_shift,
+ cover_mask = cover_size - 1,
+ cover_full = cover_mask
+ };
+
+
+ void operator () (const typename Scanline1::const_iterator& span1,
+ const typename Scanline2::const_iterator& span2,
+ int x, unsigned len,
+ Scanline& sl) const
+ {
+ unsigned cover;
+ const typename Scanline1::cover_type* covers1;
+ const typename Scanline2::cover_type* covers2;
+
+ // Calculate the operation code and choose the
+ // proper combination algorithm.
+ // 0 = Both spans are of AA type
+ // 1 = span1 is solid, span2 is AA
+ // 2 = span1 is AA, span2 is solid
+ // 3 = Both spans are of solid type
+ //-----------------
+ switch((span1->len < 0) | ((span2->len < 0) << 1))
+ {
+ case 0: // Both are AA spans
+ covers1 = span1->covers;
+ covers2 = span2->covers;
+ if(span1->x < x) covers1 += x - span1->x;
+ if(span2->x < x) covers2 += x - span2->x;
+ do
+ {
+ cover = XorFormula::calculate(*covers1++, *covers2++);
+ if(cover) sl.add_cell(x, cover);
+ ++x;
+ }
+ while(--len);
+ break;
+
+ case 1: // span1 is solid, span2 is AA
+ covers2 = span2->covers;
+ if(span2->x < x) covers2 += x - span2->x;
+ do
+ {
+ cover = XorFormula::calculate(*(span1->covers), *covers2++);
+ if(cover) sl.add_cell(x, cover);
+ ++x;
+ }
+ while(--len);
+ break;
+
+ case 2: // span1 is AA, span2 is solid
+ covers1 = span1->covers;
+ if(span1->x < x) covers1 += x - span1->x;
+ do
+ {
+ cover = XorFormula::calculate(*covers1++, *(span2->covers));
+ if(cover) sl.add_cell(x, cover);
+ ++x;
+ }
+ while(--len);
+ break;
+
+ case 3: // Both are solid spans
+ cover = XorFormula::calculate(*(span1->covers), *(span2->covers));
+ if(cover) sl.add_span(x, len, cover);
+ break;
+
+ }
+ }
+ };
+
+
+
+
+
+ //-----------------------------------------------sbool_subtract_spans_aa
+ // Functor.
+ // Unite two spans preserving the anti-aliasing information.
+ // The result is added to the "sl" scanline.
+ //------------------
+ template<class Scanline1,
+ class Scanline2,
+ class Scanline,
+ unsigned CoverShift = cover_shift>
+ struct sbool_subtract_spans_aa
+ {
+ enum cover_scale_e
+ {
+ cover_shift = CoverShift,
+ cover_size = 1 << cover_shift,
+ cover_mask = cover_size - 1,
+ cover_full = cover_mask
+ };
+
+
+ void operator () (const typename Scanline1::const_iterator& span1,
+ const typename Scanline2::const_iterator& span2,
+ int x, unsigned len,
+ Scanline& sl) const
+ {
+ unsigned cover;
+ const typename Scanline1::cover_type* covers1;
+ const typename Scanline2::cover_type* covers2;
+
+ // Calculate the operation code and choose the
+ // proper combination algorithm.
+ // 0 = Both spans are of AA type
+ // 1 = span1 is solid, span2 is AA
+ // 2 = span1 is AA, span2 is solid
+ // 3 = Both spans are of solid type
+ //-----------------
+ switch((span1->len < 0) | ((span2->len < 0) << 1))
+ {
+ case 0: // Both are AA spans
+ covers1 = span1->covers;
+ covers2 = span2->covers;
+ if(span1->x < x) covers1 += x - span1->x;
+ if(span2->x < x) covers2 += x - span2->x;
+ do
+ {
+ cover = *covers1++ * (cover_mask - *covers2++);
+ if(cover)
+ {
+ sl.add_cell(x,
+ (cover == cover_full * cover_full) ?
+ cover_full :
+ (cover >> cover_shift));
+ }
+ ++x;
+ }
+ while(--len);
+ break;
+
+ case 1: // span1 is solid, span2 is AA
+ covers2 = span2->covers;
+ if(span2->x < x) covers2 += x - span2->x;
+ do
+ {
+ cover = *(span1->covers) * (cover_mask - *covers2++);
+ if(cover)
+ {
+ sl.add_cell(x,
+ (cover == cover_full * cover_full) ?
+ cover_full :
+ (cover >> cover_shift));
+ }
+ ++x;
+ }
+ while(--len);
+ break;
+
+ case 2: // span1 is AA, span2 is solid
+ covers1 = span1->covers;
+ if(span1->x < x) covers1 += x - span1->x;
+ if(*(span2->covers) != cover_full)
+ {
+ do
+ {
+ cover = *covers1++ * (cover_mask - *(span2->covers));
+ if(cover)
+ {
+ sl.add_cell(x,
+ (cover == cover_full * cover_full) ?
+ cover_full :
+ (cover >> cover_shift));
+ }
+ ++x;
+ }
+ while(--len);
+ }
+ break;
+
+ case 3: // Both are solid spans
+ cover = *(span1->covers) * (cover_mask - *(span2->covers));
+ if(cover)
+ {
+ sl.add_span(x, len,
+ (cover == cover_full * cover_full) ?
+ cover_full :
+ (cover >> cover_shift));
+ }
+ break;
+ }
+ }
+ };
+
+
+
+
+
+
+ //--------------------------------------------sbool_add_spans_and_render
+ template<class Scanline1,
+ class Scanline,
+ class Renderer,
+ class AddSpanFunctor>
+ void sbool_add_spans_and_render(const Scanline1& sl1,
+ Scanline& sl,
+ Renderer& ren,
+ AddSpanFunctor add_span)
+ {
+ sl.reset_spans();
+ typename Scanline1::const_iterator span = sl1.begin();
+ unsigned num_spans = sl1.num_spans();
+ for(;;)
+ {
+ add_span(span, span->x, abs((int)span->len), sl);
+ if(--num_spans == 0) break;
+ ++span;
+ }
+ sl.finalize(sl1.y());
+ ren.render(sl);
+ }
+
+
+
+
+
+
+
+ //---------------------------------------------sbool_intersect_scanlines
+ // Intersect two scanlines, "sl1" and "sl2" and generate a new "sl" one.
+ // The combine_spans functor can be of type sbool_combine_spans_bin or
+ // sbool_intersect_spans_aa. First is a general functor to combine
+ // two spans without Anti-Aliasing, the second preserves the AA
+ // information, but works slower
+ //
+ template<class Scanline1,
+ class Scanline2,
+ class Scanline,
+ class CombineSpansFunctor>
+ void sbool_intersect_scanlines(const Scanline1& sl1,
+ const Scanline2& sl2,
+ Scanline& sl,
+ CombineSpansFunctor combine_spans)
+ {
+ sl.reset_spans();
+
+ unsigned num1 = sl1.num_spans();
+ if(num1 == 0) return;
+
+ unsigned num2 = sl2.num_spans();
+ if(num2 == 0) return;
+
+ typename Scanline1::const_iterator span1 = sl1.begin();
+ typename Scanline2::const_iterator span2 = sl2.begin();
+
+ while(num1 && num2)
+ {
+ int xb1 = span1->x;
+ int xb2 = span2->x;
+ int xe1 = xb1 + abs((int)span1->len) - 1;
+ int xe2 = xb2 + abs((int)span2->len) - 1;
+
+ // Determine what spans we should advance in the next step
+ // The span with the least ending X should be advanced
+ // advance_both is just an optimization when we ending
+ // coordinates are the same and we can advance both
+ //--------------
+ bool advance_span1 = xe1 < xe2;
+ bool advance_both = xe1 == xe2;
+
+ // Find the intersection of the spans
+ // and check if they intersect
+ //--------------
+ if(xb1 < xb2) xb1 = xb2;
+ if(xe1 > xe2) xe1 = xe2;
+ if(xb1 <= xe1)
+ {
+ combine_spans(span1, span2, xb1, xe1 - xb1 + 1, sl);
+ }
+
+ // Advance the spans
+ //--------------
+ if(advance_both)
+ {
+ --num1;
+ --num2;
+ if(num1) ++span1;
+ if(num2) ++span2;
+ }
+ else
+ {
+ if(advance_span1)
+ {
+ --num1;
+ if(num1) ++span1;
+ }
+ else
+ {
+ --num2;
+ if(num2) ++span2;
+ }
+ }
+ }
+ }
+
+
+
+
+
+
+
+
+ //------------------------------------------------sbool_intersect_shapes
+ // Intersect the scanline shapes. Here the "Scanline Generator"
+ // abstraction is used. ScanlineGen1 and ScanlineGen2 are
+ // the generators, and can be of type rasterizer_scanline_aa<>.
+ // There function requires three scanline containers that can be of
+ // different types.
+ // "sl1" and "sl2" are used to retrieve scanlines from the generators,
+ // "sl" is ised as the resulting scanline to render it.
+ // The external "sl1" and "sl2" are used only for the sake of
+ // optimization and reusing of the scanline objects.
+ // the function calls sbool_intersect_scanlines with CombineSpansFunctor
+ // as the last argument. See sbool_intersect_scanlines for details.
+ //----------
+ template<class ScanlineGen1,
+ class ScanlineGen2,
+ class Scanline1,
+ class Scanline2,
+ class Scanline,
+ class Renderer,
+ class CombineSpansFunctor>
+ void sbool_intersect_shapes(ScanlineGen1& sg1, ScanlineGen2& sg2,
+ Scanline1& sl1, Scanline2& sl2,
+ Scanline& sl, Renderer& ren,
+ CombineSpansFunctor combine_spans)
+ {
+ // Prepare the scanline generators.
+ // If anyone of them doesn't contain
+ // any scanlines, then return.
+ //-----------------
+ if(!sg1.rewind_scanlines()) return;
+ if(!sg2.rewind_scanlines()) return;
+
+ // Get the bounding boxes
+ //----------------
+ 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_i ir = intersect_rectangles(r1, r2);
+ if(!ir.is_valid()) return;
+
+ // Reset the scanlines and get two first ones
+ //-----------------
+ sl.reset(ir.x1, ir.x2);
+ sl1.reset(sg1.min_x(), sg1.max_x());
+ sl2.reset(sg2.min_x(), sg2.max_x());
+ if(!sg1.sweep_scanline(sl1)) return;
+ if(!sg2.sweep_scanline(sl2)) return;
+
+ ren.prepare();
+
+ // The main loop
+ // Here we synchronize the scanlines with
+ // the same Y coordinate, ignoring all other ones.
+ // Only scanlines having the same Y-coordinate
+ // are to be combined.
+ //-----------------
+ for(;;)
+ {
+ while(sl1.y() < sl2.y())
+ {
+ if(!sg1.sweep_scanline(sl1)) return;
+ }
+ while(sl2.y() < sl1.y())
+ {
+ if(!sg2.sweep_scanline(sl2)) return;
+ }
+
+ if(sl1.y() == sl2.y())
+ {
+ // The Y coordinates are the same.
+ // Combine the scanlines, render if they contain any spans,
+ // and advance both generators to the next scanlines
+ //----------------------
+ sbool_intersect_scanlines(sl1, sl2, sl, combine_spans);
+ if(sl.num_spans())
+ {
+ sl.finalize(sl1.y());
+ ren.render(sl);
+ }
+ if(!sg1.sweep_scanline(sl1)) return;
+ if(!sg2.sweep_scanline(sl2)) return;
+ }
+ }
+ }
+
+
+
+
+
+
+
+ //-------------------------------------------------sbool_unite_scanlines
+ // Unite two scanlines, "sl1" and "sl2" and generate a new "sl" one.
+ // The combine_spans functor can be of type sbool_combine_spans_bin or
+ // sbool_intersect_spans_aa. First is a general functor to combine
+ // two spans without Anti-Aliasing, the second preserves the AA
+ // information, but works slower
+ //
+ template<class Scanline1,
+ class Scanline2,
+ class Scanline,
+ class AddSpanFunctor1,
+ class AddSpanFunctor2,
+ class CombineSpansFunctor>
+ void sbool_unite_scanlines(const Scanline1& sl1,
+ const Scanline2& sl2,
+ Scanline& sl,
+ AddSpanFunctor1 add_span1,
+ AddSpanFunctor2 add_span2,
+ CombineSpansFunctor combine_spans)
+ {
+ sl.reset_spans();
+
+ unsigned num1 = sl1.num_spans();
+ unsigned num2 = sl2.num_spans();
+
+ typename Scanline1::const_iterator span1;// = sl1.begin();
+ typename Scanline2::const_iterator span2;// = sl2.begin();
+
+ enum invalidation_e
+ {
+ invalid_b = 0xFFFFFFF,
+ invalid_e = invalid_b - 1
+ };
+
+ // Initialize the spans as invalid
+ //---------------
+ int xb1 = invalid_b;
+ int xb2 = invalid_b;
+ int xe1 = invalid_e;
+ int xe2 = invalid_e;
+
+ // Initialize span1 if there are spans
+ //---------------
+ if(num1)
+ {
+ span1 = sl1.begin();
+ xb1 = span1->x;
+ xe1 = xb1 + abs((int)span1->len) - 1;
+ --num1;
+ }
+
+ // Initialize span2 if there are spans
+ //---------------
+ if(num2)
+ {
+ span2 = sl2.begin();
+ xb2 = span2->x;
+ xe2 = xb2 + abs((int)span2->len) - 1;
+ --num2;
+ }
+
+
+ for(;;)
+ {
+ // Retrieve a new span1 if it's invalid
+ //----------------
+ if(num1 && xb1 > xe1)
+ {
+ --num1;
+ ++span1;
+ xb1 = span1->x;
+ xe1 = xb1 + abs((int)span1->len) - 1;
+ }
+
+ // Retrieve a new span2 if it's invalid
+ //----------------
+ if(num2 && xb2 > xe2)
+ {
+ --num2;
+ ++span2;
+ xb2 = span2->x;
+ xe2 = xb2 + abs((int)span2->len) - 1;
+ }
+
+ if(xb1 > xe1 && xb2 > xe2) break;
+
+ // Calculate the intersection
+ //----------------
+ int xb = xb1;
+ int xe = xe1;
+ if(xb < xb2) xb = xb2;
+ if(xe > xe2) xe = xe2;
+ int len = xe - xb + 1; // The length of the intersection
+ if(len > 0)
+ {
+ // The spans intersect,
+ // add the beginning of the span
+ //----------------
+ if(xb1 < xb2)
+ {
+ add_span1(span1, xb1, xb2 - xb1, sl);
+ xb1 = xb2;
+ }
+ else
+ if(xb2 < xb1)
+ {
+ add_span2(span2, xb2, xb1 - xb2, sl);
+ xb2 = xb1;
+ }
+
+ // Add the combination part of the spans
+ //----------------
+ combine_spans(span1, span2, xb, len, sl);
+
+
+ // Invalidate the fully processed span or both
+ //----------------
+ if(xe1 < xe2)
+ {
+ // Invalidate span1 and eat
+ // the processed part of span2
+ //--------------
+ xb1 = invalid_b;
+ xe1 = invalid_e;
+ xb2 += len;
+ }
+ else
+ if(xe2 < xe1)
+ {
+ // Invalidate span2 and eat
+ // the processed part of span1
+ //--------------
+ xb2 = invalid_b;
+ xe2 = invalid_e;
+ xb1 += len;
+ }
+ else
+ {
+ xb1 = invalid_b; // Invalidate both
+ xb2 = invalid_b;
+ xe1 = invalid_e;
+ xe2 = invalid_e;
+ }
+ }
+ else
+ {
+ // The spans do not intersect
+ //--------------
+ if(xb1 < xb2)
+ {
+ // Advance span1
+ //---------------
+ if(xb1 <= xe1)
+ {
+ add_span1(span1, xb1, xe1 - xb1 + 1, sl);
+ }
+ xb1 = invalid_b; // Invalidate
+ xe1 = invalid_e;
+ }
+ else
+ {
+ // Advance span2
+ //---------------
+ if(xb2 <= xe2)
+ {
+ add_span2(span2, xb2, xe2 - xb2 + 1, sl);
+ }
+ xb2 = invalid_b; // Invalidate
+ xe2 = invalid_e;
+ }
+ }
+ }
+ }
+
+
+
+
+ //----------------------------------------------------sbool_unite_shapes
+ // Unite the scanline shapes. Here the "Scanline Generator"
+ // abstraction is used. ScanlineGen1 and ScanlineGen2 are
+ // the generators, and can be of type rasterizer_scanline_aa<>.
+ // There function requires three scanline containers that can be
+ // of different type.
+ // "sl1" and "sl2" are used to retrieve scanlines from the generators,
+ // "sl" is ised as the resulting scanline to render it.
+ // The external "sl1" and "sl2" are used only for the sake of
+ // optimization and reusing of the scanline objects.
+ // the function calls sbool_unite_scanlines with CombineSpansFunctor
+ // as the last argument. See sbool_unite_scanlines for details.
+ //----------
+ template<class ScanlineGen1,
+ class ScanlineGen2,
+ class Scanline1,
+ class Scanline2,
+ class Scanline,
+ class Renderer,
+ class AddSpanFunctor1,
+ class AddSpanFunctor2,
+ class CombineSpansFunctor>
+ void sbool_unite_shapes(ScanlineGen1& sg1, ScanlineGen2& sg2,
+ Scanline1& sl1, Scanline2& sl2,
+ Scanline& sl, Renderer& ren,
+ AddSpanFunctor1 add_span1,
+ AddSpanFunctor2 add_span2,
+ CombineSpansFunctor combine_spans)
+ {
+ // Prepare the scanline generators.
+ // If anyone of them doesn't contain
+ // any scanlines, then return.
+ //-----------------
+ bool flag1 = sg1.rewind_scanlines();
+ bool flag2 = sg2.rewind_scanlines();
+ if(!flag1 && !flag2) return;
+
+ // Get the bounding boxes
+ //----------------
+ 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_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();
+
+ // Reset the scanlines and get two first ones
+ //-----------------
+ sl.reset(ur.x1, ur.x2);
+ if(flag1)
+ {
+ sl1.reset(sg1.min_x(), sg1.max_x());
+ flag1 = sg1.sweep_scanline(sl1);
+ }
+
+ if(flag2)
+ {
+ sl2.reset(sg2.min_x(), sg2.max_x());
+ flag2 = sg2.sweep_scanline(sl2);
+ }
+
+ // The main loop
+ // Here we synchronize the scanlines with
+ // the same Y coordinate.
+ //-----------------
+ while(flag1 || flag2)
+ {
+ if(flag1 && flag2)
+ {
+ if(sl1.y() == sl2.y())
+ {
+ // The Y coordinates are the same.
+ // Combine the scanlines, render if they contain any spans,
+ // and advance both generators to the next scanlines
+ //----------------------
+ sbool_unite_scanlines(sl1, sl2, sl,
+ add_span1, add_span2, combine_spans);
+ if(sl.num_spans())
+ {
+ sl.finalize(sl1.y());
+ ren.render(sl);
+ }
+ flag1 = sg1.sweep_scanline(sl1);
+ flag2 = sg2.sweep_scanline(sl2);
+ }
+ else
+ {
+ if(sl1.y() < sl2.y())
+ {
+ sbool_add_spans_and_render(sl1, sl, ren, add_span1);
+ flag1 = sg1.sweep_scanline(sl1);
+ }
+ else
+ {
+ sbool_add_spans_and_render(sl2, sl, ren, add_span2);
+ flag2 = sg2.sweep_scanline(sl2);
+ }
+ }
+ }
+ else
+ {
+ if(flag1)
+ {
+ sbool_add_spans_and_render(sl1, sl, ren, add_span1);
+ flag1 = sg1.sweep_scanline(sl1);
+ }
+ if(flag2)
+ {
+ sbool_add_spans_and_render(sl2, sl, ren, add_span2);
+ flag2 = sg2.sweep_scanline(sl2);
+ }
+ }
+ }
+ }
+
+
+
+
+
+
+
+
+ //-------------------------------------------------sbool_subtract_shapes
+ // Subtract the scanline shapes, "sg1-sg2". Here the "Scanline Generator"
+ // abstraction is used. ScanlineGen1 and ScanlineGen2 are
+ // the generators, and can be of type rasterizer_scanline_aa<>.
+ // There function requires three scanline containers that can be of
+ // different types.
+ // "sl1" and "sl2" are used to retrieve scanlines from the generators,
+ // "sl" is ised as the resulting scanline to render it.
+ // The external "sl1" and "sl2" are used only for the sake of
+ // optimization and reusing of the scanline objects.
+ // the function calls sbool_intersect_scanlines with CombineSpansFunctor
+ // as the last argument. See combine_scanlines_sub for details.
+ //----------
+ template<class ScanlineGen1,
+ class ScanlineGen2,
+ class Scanline1,
+ class Scanline2,
+ class Scanline,
+ class Renderer,
+ class AddSpanFunctor1,
+ class CombineSpansFunctor>
+ void sbool_subtract_shapes(ScanlineGen1& sg1, ScanlineGen2& sg2,
+ Scanline1& sl1, Scanline2& sl2,
+ Scanline& sl, Renderer& ren,
+ AddSpanFunctor1 add_span1,
+ CombineSpansFunctor combine_spans)
+ {
+ // Prepare the scanline generators.
+ // Here "sg1" is master, "sg2" is slave.
+ //-----------------
+ if(!sg1.rewind_scanlines()) return;
+ bool flag2 = sg2.rewind_scanlines();
+
+ // Get the bounding box
+ //----------------
+ rect_i r1(sg1.min_x(), sg1.min_y(), sg1.max_x(), sg1.max_y());
+
+ // Reset the scanlines and get two first ones
+ //-----------------
+ sl.reset(sg1.min_x(), sg1.max_x());
+ sl1.reset(sg1.min_x(), sg1.max_x());
+ sl2.reset(sg2.min_x(), sg2.max_x());
+ if(!sg1.sweep_scanline(sl1)) return;
+
+ if(flag2) flag2 = sg2.sweep_scanline(sl2);
+
+ ren.prepare();
+
+ // A fake span2 processor
+ sbool_add_span_empty<Scanline2, Scanline> add_span2;
+
+ // The main loop
+ // Here we synchronize the scanlines with
+ // the same Y coordinate, ignoring all other ones.
+ // Only scanlines having the same Y-coordinate
+ // are to be combined.
+ //-----------------
+ bool flag1 = true;
+ do
+ {
+ // Synchronize "slave" with "master"
+ //-----------------
+ while(flag2 && sl2.y() < sl1.y())
+ {
+ flag2 = sg2.sweep_scanline(sl2);
+ }
+
+
+ if(flag2 && sl2.y() == sl1.y())
+ {
+ // The Y coordinates are the same.
+ // Combine the scanlines and render if they contain any spans.
+ //----------------------
+ sbool_unite_scanlines(sl1, sl2, sl, add_span1, add_span2, combine_spans);
+ if(sl.num_spans())
+ {
+ sl.finalize(sl1.y());
+ ren.render(sl);
+ }
+ }
+ else
+ {
+ sbool_add_spans_and_render(sl1, sl, ren, add_span1);
+ }
+
+ // Advance the "master"
+ flag1 = sg1.sweep_scanline(sl1);
+ }
+ while(flag1);
+ }
+
+
+
+
+
+
+
+ //---------------------------------------------sbool_intersect_shapes_aa
+ // Intersect two anti-aliased scanline shapes.
+ // Here the "Scanline Generator" abstraction is used.
+ // ScanlineGen1 and ScanlineGen2 are the generators, and can be of
+ // type rasterizer_scanline_aa<>. There function requires three
+ // scanline containers that can be of different types.
+ // "sl1" and "sl2" are used to retrieve scanlines from the generators,
+ // "sl" is ised as the resulting scanline to render it.
+ // The external "sl1" and "sl2" are used only for the sake of
+ // optimization and reusing of the scanline objects.
+ //----------
+ template<class ScanlineGen1,
+ class ScanlineGen2,
+ class Scanline1,
+ class Scanline2,
+ class Scanline,
+ class Renderer>
+ void sbool_intersect_shapes_aa(ScanlineGen1& sg1, ScanlineGen2& sg2,
+ Scanline1& sl1, Scanline2& sl2,
+ Scanline& sl, Renderer& ren)
+ {
+ sbool_intersect_spans_aa<Scanline1, Scanline2, Scanline> combine_functor;
+ sbool_intersect_shapes(sg1, sg2, sl1, sl2, sl, ren, combine_functor);
+ }
+
+
+
+
+
+ //--------------------------------------------sbool_intersect_shapes_bin
+ // Intersect two binary scanline shapes (without anti-aliasing).
+ // See intersect_shapes_aa for more comments
+ //----------
+ template<class ScanlineGen1,
+ class ScanlineGen2,
+ class Scanline1,
+ class Scanline2,
+ class Scanline,
+ class Renderer>
+ void sbool_intersect_shapes_bin(ScanlineGen1& sg1, ScanlineGen2& sg2,
+ Scanline1& sl1, Scanline2& sl2,
+ Scanline& sl, Renderer& ren)
+ {
+ sbool_combine_spans_bin<Scanline1, Scanline2, Scanline> combine_functor;
+ sbool_intersect_shapes(sg1, sg2, sl1, sl2, sl, ren, combine_functor);
+ }
+
+
+
+
+
+ //-------------------------------------------------sbool_unite_shapes_aa
+ // Unite two anti-aliased scanline shapes
+ // See intersect_shapes_aa for more comments
+ //----------
+ template<class ScanlineGen1,
+ class ScanlineGen2,
+ class Scanline1,
+ class Scanline2,
+ class Scanline,
+ class Renderer>
+ void sbool_unite_shapes_aa(ScanlineGen1& sg1, ScanlineGen2& sg2,
+ Scanline1& sl1, Scanline2& sl2,
+ Scanline& sl, Renderer& ren)
+ {
+ sbool_add_span_aa<Scanline1, Scanline> add_functor1;
+ sbool_add_span_aa<Scanline2, Scanline> add_functor2;
+ sbool_unite_spans_aa<Scanline1, Scanline2, Scanline> combine_functor;
+ sbool_unite_shapes(sg1, sg2, sl1, sl2, sl, ren,
+ add_functor1, add_functor2, combine_functor);
+ }
+
+
+
+
+
+ //------------------------------------------------sbool_unite_shapes_bin
+ // Unite two binary scanline shapes (without anti-aliasing).
+ // See intersect_shapes_aa for more comments
+ //----------
+ template<class ScanlineGen1,
+ class ScanlineGen2,
+ class Scanline1,
+ class Scanline2,
+ class Scanline,
+ class Renderer>
+ void sbool_unite_shapes_bin(ScanlineGen1& sg1, ScanlineGen2& sg2,
+ Scanline1& sl1, Scanline2& sl2,
+ Scanline& sl, Renderer& ren)
+ {
+ sbool_add_span_bin<Scanline1, Scanline> add_functor1;
+ sbool_add_span_bin<Scanline2, Scanline> add_functor2;
+ sbool_combine_spans_bin<Scanline1, Scanline2, Scanline> combine_functor;
+ sbool_unite_shapes(sg1, sg2, sl1, sl2, sl, ren,
+ add_functor1, add_functor2, combine_functor);
+ }
+
+
+
+
+
+
+
+
+
+ //---------------------------------------------------sbool_xor_shapes_aa
+ // Apply eXclusive OR to two anti-aliased scanline shapes. There's
+ // a modified "Linear" XOR used instead of classical "Saddle" one.
+ // The reason is to have the result absolutely conststent with what
+ // the scanline rasterizer produces.
+ // See intersect_shapes_aa for more comments
+ //----------
+ template<class ScanlineGen1,
+ class ScanlineGen2,
+ class Scanline1,
+ class Scanline2,
+ class Scanline,
+ class Renderer>
+ void sbool_xor_shapes_aa(ScanlineGen1& sg1, ScanlineGen2& sg2,
+ Scanline1& sl1, Scanline2& sl2,
+ Scanline& sl, Renderer& ren)
+ {
+ sbool_add_span_aa<Scanline1, Scanline> add_functor1;
+ sbool_add_span_aa<Scanline2, Scanline> add_functor2;
+ sbool_xor_spans_aa<Scanline1, Scanline2, Scanline,
+ sbool_xor_formula_linear<> > combine_functor;
+ sbool_unite_shapes(sg1, sg2, sl1, sl2, sl, ren,
+ add_functor1, add_functor2, combine_functor);
+ }
+
+
+
+ //------------------------------------------sbool_xor_shapes_saddle_aa
+ // Apply eXclusive OR to two anti-aliased scanline shapes.
+ // There's the classical "Saddle" used to calculate the
+ // Anti-Aliasing values, that is:
+ // a XOR b : 1-((1-a+a*b)*(1-b+a*b))
+ // See intersect_shapes_aa for more comments
+ //----------
+ template<class ScanlineGen1,
+ class ScanlineGen2,
+ class Scanline1,
+ class Scanline2,
+ class Scanline,
+ class Renderer>
+ void sbool_xor_shapes_saddle_aa(ScanlineGen1& sg1, ScanlineGen2& sg2,
+ Scanline1& sl1, Scanline2& sl2,
+ Scanline& sl, Renderer& ren)
+ {
+ sbool_add_span_aa<Scanline1, Scanline> add_functor1;
+ sbool_add_span_aa<Scanline2, Scanline> add_functor2;
+ sbool_xor_spans_aa<Scanline1,
+ Scanline2,
+ Scanline,
+ sbool_xor_formula_saddle<> > combine_functor;
+ sbool_unite_shapes(sg1, sg2, sl1, sl2, sl, ren,
+ add_functor1, add_functor2, combine_functor);
+ }
+
+
+ //--------------------------------------sbool_xor_shapes_abs_diff_aa
+ // Apply eXclusive OR to two anti-aliased scanline shapes.
+ // There's the absolute difference used to calculate
+ // Anti-Aliasing values, that is:
+ // a XOR b : abs(a-b)
+ // See intersect_shapes_aa for more comments
+ //----------
+ template<class ScanlineGen1,
+ class ScanlineGen2,
+ class Scanline1,
+ class Scanline2,
+ class Scanline,
+ class Renderer>
+ void sbool_xor_shapes_abs_diff_aa(ScanlineGen1& sg1, ScanlineGen2& sg2,
+ Scanline1& sl1, Scanline2& sl2,
+ Scanline& sl, Renderer& ren)
+ {
+ sbool_add_span_aa<Scanline1, Scanline> add_functor1;
+ sbool_add_span_aa<Scanline2, Scanline> add_functor2;
+ sbool_xor_spans_aa<Scanline1,
+ Scanline2,
+ Scanline,
+ sbool_xor_formula_abs_diff> combine_functor;
+ sbool_unite_shapes(sg1, sg2, sl1, sl2, sl, ren,
+ add_functor1, add_functor2, combine_functor);
+ }
+
+
+
+ //--------------------------------------------------sbool_xor_shapes_bin
+ // Apply eXclusive OR to two binary scanline shapes (without anti-aliasing).
+ // See intersect_shapes_aa for more comments
+ //----------
+ template<class ScanlineGen1,
+ class ScanlineGen2,
+ class Scanline1,
+ class Scanline2,
+ class Scanline,
+ class Renderer>
+ void sbool_xor_shapes_bin(ScanlineGen1& sg1, ScanlineGen2& sg2,
+ Scanline1& sl1, Scanline2& sl2,
+ Scanline& sl, Renderer& ren)
+ {
+ sbool_add_span_bin<Scanline1, Scanline> add_functor1;
+ sbool_add_span_bin<Scanline2, Scanline> add_functor2;
+ sbool_combine_spans_empty<Scanline1, Scanline2, Scanline> combine_functor;
+ sbool_unite_shapes(sg1, sg2, sl1, sl2, sl, ren,
+ add_functor1, add_functor2, combine_functor);
+ }
+
+
+
+
+
+
+ //----------------------------------------------sbool_subtract_shapes_aa
+ // Subtract shapes "sg1-sg2" with anti-aliasing
+ // See intersect_shapes_aa for more comments
+ //----------
+ template<class ScanlineGen1,
+ class ScanlineGen2,
+ class Scanline1,
+ class Scanline2,
+ class Scanline,
+ class Renderer>
+ void sbool_subtract_shapes_aa(ScanlineGen1& sg1, ScanlineGen2& sg2,
+ Scanline1& sl1, Scanline2& sl2,
+ Scanline& sl, Renderer& ren)
+ {
+ sbool_add_span_aa<Scanline1, Scanline> add_functor;
+ sbool_subtract_spans_aa<Scanline1, Scanline2, Scanline> combine_functor;
+ sbool_subtract_shapes(sg1, sg2, sl1, sl2, sl, ren,
+ add_functor, combine_functor);
+ }
+
+
+
+
+
+ //---------------------------------------------sbool_subtract_shapes_bin
+ // Subtract binary shapes "sg1-sg2" without anti-aliasing
+ // See intersect_shapes_aa for more comments
+ //----------
+ template<class ScanlineGen1,
+ class ScanlineGen2,
+ class Scanline1,
+ class Scanline2,
+ class Scanline,
+ class Renderer>
+ void sbool_subtract_shapes_bin(ScanlineGen1& sg1, ScanlineGen2& sg2,
+ Scanline1& sl1, Scanline2& sl2,
+ Scanline& sl, Renderer& ren)
+ {
+ sbool_add_span_bin<Scanline1, Scanline> add_functor;
+ sbool_combine_spans_empty<Scanline1, Scanline2, Scanline> combine_functor;
+ sbool_subtract_shapes(sg1, sg2, sl1, sl2, sl, ren,
+ add_functor, combine_functor);
+ }
+
+
+
+
+
+
+ //------------------------------------------------------------sbool_op_e
+ enum sbool_op_e
+ {
+ sbool_or, //----sbool_or
+ sbool_and, //----sbool_and
+ sbool_xor, //----sbool_xor
+ sbool_xor_saddle, //----sbool_xor_saddle
+ sbool_xor_abs_diff, //----sbool_xor_abs_diff
+ sbool_a_minus_b, //----sbool_a_minus_b
+ sbool_b_minus_a //----sbool_b_minus_a
+ };
+
+
+
+
+
+
+ //----------------------------------------------sbool_combine_shapes_bin
+ template<class ScanlineGen1,
+ class ScanlineGen2,
+ class Scanline1,
+ class Scanline2,
+ class Scanline,
+ class Renderer>
+ void sbool_combine_shapes_bin(sbool_op_e op,
+ ScanlineGen1& sg1, ScanlineGen2& sg2,
+ Scanline1& sl1, Scanline2& sl2,
+ Scanline& sl, Renderer& ren)
+ {
+ switch(op)
+ {
+ case sbool_or : sbool_unite_shapes_bin (sg1, sg2, sl1, sl2, sl, ren); break;
+ case sbool_and : sbool_intersect_shapes_bin(sg1, sg2, sl1, sl2, sl, ren); break;
+ case sbool_xor :
+ case sbool_xor_saddle :
+ case sbool_xor_abs_diff: sbool_xor_shapes_bin (sg1, sg2, sl1, sl2, sl, ren); break;
+ case sbool_a_minus_b : sbool_subtract_shapes_bin (sg1, sg2, sl1, sl2, sl, ren); break;
+ case sbool_b_minus_a : sbool_subtract_shapes_bin (sg2, sg1, sl2, sl1, sl, ren); break;
+ }
+ }
+
+
+
+
+ //-----------------------------------------------sbool_combine_shapes_aa
+ template<class ScanlineGen1,
+ class ScanlineGen2,
+ class Scanline1,
+ class Scanline2,
+ class Scanline,
+ class Renderer>
+ void sbool_combine_shapes_aa(sbool_op_e op,
+ ScanlineGen1& sg1, ScanlineGen2& sg2,
+ Scanline1& sl1, Scanline2& sl2,
+ Scanline& sl, Renderer& ren)
+ {
+ switch(op)
+ {
+ case sbool_or : sbool_unite_shapes_aa (sg1, sg2, sl1, sl2, sl, ren); break;
+ case sbool_and : sbool_intersect_shapes_aa (sg1, sg2, sl1, sl2, sl, ren); break;
+ case sbool_xor : sbool_xor_shapes_aa (sg1, sg2, sl1, sl2, sl, ren); break;
+ case sbool_xor_saddle : sbool_xor_shapes_saddle_aa (sg1, sg2, sl1, sl2, sl, ren); break;
+ case sbool_xor_abs_diff: sbool_xor_shapes_abs_diff_aa(sg1, sg2, sl1, sl2, sl, ren); break;
+ case sbool_a_minus_b : sbool_subtract_shapes_aa (sg1, sg2, sl1, sl2, sl, ren); break;
+ case sbool_b_minus_a : sbool_subtract_shapes_aa (sg2, sg1, sl2, sl1, sl, ren); break;
+ }
+ }
+
+}
+
+
+#endif
+
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_simul_eq.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_simul_eq.h
new file mode 100644
index 0000000000..3d0dce4b44
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_simul_eq.h
@@ -0,0 +1,147 @@
+//----------------------------------------------------------------------------
+// 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
+//----------------------------------------------------------------------------
+//
+// Solving simultaneous equations
+//
+//----------------------------------------------------------------------------
+#ifndef AGG_SIMUL_EQ_INCLUDED
+#define AGG_SIMUL_EQ_INCLUDED
+
+#include <math.h>
+#include "agg_basics.h"
+
+namespace agg
+{
+
+ //=============================================================swap_arrays
+ template<class T> void swap_arrays(T* a1, T* a2, unsigned n)
+ {
+ unsigned i;
+ for(i = 0; i < n; i++)
+ {
+ T tmp = *a1;
+ *a1++ = *a2;
+ *a2++ = tmp;
+ }
+ }
+
+
+ //============================================================matrix_pivot
+ template<unsigned Rows, unsigned Cols>
+ struct matrix_pivot
+ {
+ static int pivot(double m[Rows][Cols], unsigned row)
+ {
+ int k = int(row);
+ double max_val, tmp;
+
+ max_val = -1.0;
+ unsigned i;
+ for(i = row; i < Rows; i++)
+ {
+ if((tmp = fabs(m[i][row])) > max_val && tmp != 0.0)
+ {
+ max_val = tmp;
+ k = i;
+ }
+ }
+
+ if(m[k][row] == 0.0)
+ {
+ return -1;
+ }
+
+ if(k != int(row))
+ {
+ swap_arrays(m[k], m[row], Cols);
+ return k;
+ }
+ return 0;
+ }
+ };
+
+
+
+ //===============================================================simul_eq
+ template<unsigned Size, unsigned RightCols>
+ struct simul_eq
+ {
+ static bool solve(const double left[Size][Size],
+ const double right[Size][RightCols],
+ double result[Size][RightCols])
+ {
+ unsigned i, j, k;
+ double a1;
+
+ double tmp[Size][Size + RightCols];
+
+ for(i = 0; i < Size; i++)
+ {
+ for(j = 0; j < Size; j++)
+ {
+ tmp[i][j] = left[i][j];
+ }
+ for(j = 0; j < RightCols; j++)
+ {
+ tmp[i][Size + j] = right[i][j];
+ }
+ }
+
+ for(k = 0; k < Size; k++)
+ {
+ if(matrix_pivot<Size, Size + RightCols>::pivot(tmp, k) < 0)
+ {
+ return false; // Singularity....
+ }
+
+ a1 = tmp[k][k];
+
+ for(j = k; j < Size + RightCols; j++)
+ {
+ tmp[k][j] /= a1;
+ }
+
+ for(i = k + 1; i < Size; i++)
+ {
+ a1 = tmp[i][k];
+ for (j = k; j < Size + RightCols; j++)
+ {
+ tmp[i][j] -= a1 * tmp[k][j];
+ }
+ }
+ }
+
+
+ for(k = 0; k < RightCols; k++)
+ {
+ int m;
+ for(m = int(Size - 1); m >= 0; m--)
+ {
+ result[m][k] = tmp[m][Size + k];
+ for(j = m + 1; j < Size; j++)
+ {
+ result[m][k] -= tmp[m][j] * result[j][k];
+ }
+ }
+ }
+ return true;
+ }
+
+ };
+
+
+}
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gouraud_gray.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gouraud_gray.h
new file mode 100644
index 0000000000..d5fc39d102
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gouraud_gray.h
@@ -0,0 +1,241 @@
+//----------------------------------------------------------------------------
+// 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_GOURAUD_GRAY_INCLUDED
+#define AGG_SPAN_GOURAUD_GRAY_INCLUDED
+
+#include "agg_basics.h"
+#include "agg_color_gray.h"
+#include "agg_dda_line.h"
+#include "agg_span_gouraud.h"
+
+namespace agg
+{
+
+ //=======================================================span_gouraud_gray
+ template<class ColorT> class span_gouraud_gray : public span_gouraud<ColorT>
+ {
+ public:
+ typedef ColorT color_type;
+ typedef typename color_type::value_type value_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:
+ //--------------------------------------------------------------------
+ struct gray_calc
+ {
+ void init(const coord_type& c1, const coord_type& c2)
+ {
+ 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(double y)
+ {
+ 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_1dy;
+ int m_v1;
+ int m_a1;
+ int m_dv;
+ int m_da;
+ int m_v;
+ int m_a;
+ int m_x;
+ };
+
+
+ public:
+ //--------------------------------------------------------------------
+ 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(c1, c2, c3, x1, y1, x2, y2, x3, y3, d)
+ {}
+
+ //--------------------------------------------------------------------
+ void prepare()
+ {
+ coord_type coord[3];
+ base_type::arrange_vertices(coord);
+
+ m_y2 = int(coord[1].y);
+
+ 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]);
+ m_c3.init(coord[1], coord[2]);
+ }
+
+ //--------------------------------------------------------------------
+ void generate(color_type* span, int x, int y, unsigned len)
+ {
+ m_c1.calc(y);
+ const gray_calc* pc1 = &m_c1;
+ const gray_calc* pc2 = &m_c2;
+
+ if(y < m_y2)
+ {
+ // Bottom part of the triangle (first subtriangle)
+ //-------------------------
+ m_c2.calc(y + m_c2.m_1dy);
+ }
+ else
+ {
+ // 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;
+ }
+
+ // 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);
+
+ // 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)
+ {
+ 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;
+ }
+
+ // 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 += 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;
+ }
+ }
+
+
+ private:
+ bool m_swap;
+ int m_y2;
+ gray_calc m_c1;
+ gray_calc m_c2;
+ gray_calc m_c3;
+ };
+
+
+}
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gradient.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gradient.h
new file mode 100644
index 0000000000..58b506dcfe
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gradient.h
@@ -0,0 +1,377 @@
+//----------------------------------------------------------------------------
+// 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_SPAN_GRADIENT_INCLUDED
+#define AGG_SPAN_GRADIENT_INCLUDED
+
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include "agg_basics.h"
+#include "agg_math.h"
+#include "agg_array.h"
+
+
+namespace agg
+{
+
+ enum gradient_subpixel_scale_e
+ {
+ gradient_subpixel_shift = 4, //-----gradient_subpixel_shift
+ gradient_subpixel_scale = 1 << gradient_subpixel_shift, //-----gradient_subpixel_scale
+ gradient_subpixel_mask = gradient_subpixel_scale - 1 //-----gradient_subpixel_mask
+ };
+
+
+
+ //==========================================================span_gradient
+ template<class ColorT,
+ class Interpolator,
+ class GradientF,
+ class ColorF>
+ class span_gradient
+ {
+ public:
+ typedef Interpolator interpolator_type;
+ typedef ColorT color_type;
+
+ enum downscale_shift_e
+ {
+ downscale_shift = interpolator_type::subpixel_shift -
+ gradient_subpixel_shift
+ };
+
+ //--------------------------------------------------------------------
+ span_gradient() {}
+
+ //--------------------------------------------------------------------
+ span_gradient(interpolator_type& inter,
+ GradientF& gradient_function,
+ ColorF& color_function,
+ double d1, double d2) :
+ m_interpolator(&inter),
+ 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_scale; }
+ double d2() const { return double(m_d2) / gradient_subpixel_scale; }
+
+ //--------------------------------------------------------------------
+ void interpolator(interpolator_type& i) { m_interpolator = &i; }
+ void gradient_function(GradientF& gf) { m_gradient_function = &gf; }
+ void color_function(ColorF& cf) { m_color_function = &cf; }
+ void d1(double v) { m_d1 = iround(v * gradient_subpixel_scale); }
+ void d2(double v) { m_d2 = iround(v * gradient_subpixel_scale); }
+
+ //--------------------------------------------------------------------
+ void prepare() {}
+
+ //--------------------------------------------------------------------
+ void generate(color_type* span, int x, int y, unsigned len)
+ {
+ int dd = m_d2 - m_d1;
+ if(dd < 1) dd = 1;
+ m_interpolator->begin(x+0.5, y+0.5, len);
+ do
+ {
+ m_interpolator->coordinates(&x, &y);
+ int d = m_gradient_function->calculate(x >> downscale_shift,
+ y >> downscale_shift, 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;
+ *span++ = (*m_color_function)[d];
+ ++(*m_interpolator);
+ }
+ while(--len);
+ }
+
+ private:
+ interpolator_type* m_interpolator;
+ GradientF* m_gradient_function;
+ ColorF* m_color_function;
+ int m_d1;
+ int m_d2;
+ };
+
+
+
+
+ //=====================================================gradient_linear_color
+ template<class ColorT>
+ struct gradient_linear_color
+ {
+ typedef ColorT color_type;
+
+ gradient_linear_color() {}
+ gradient_linear_color(const color_type& c1, const color_type& c2,
+ unsigned size = 256) :
+ m_c1(c1), m_c2(c2), m_size(size)
+ // VFALCO 4/28/09
+ ,m_mult(1/(double(size)-1))
+ // VFALCO
+ {}
+
+ unsigned size() const { return m_size; }
+ color_type operator [] (unsigned v) const
+ {
+ // VFALCO 4/28/09
+ //return m_c1.gradient(m_c2, double(v) / double(m_size - 1));
+ return m_c1.gradient(m_c2, double(v) * m_mult );
+ // VFALCO
+ }
+
+ void colors(const color_type& c1, const color_type& c2, unsigned size = 256)
+ {
+ m_c1 = c1;
+ m_c2 = c2;
+ m_size = size;
+ // VFALCO 4/28/09
+ m_mult=1/(double(size)-1);
+ // VFALCO
+ }
+
+ color_type m_c1;
+ color_type m_c2;
+ unsigned m_size;
+ // VFALCO 4/28/09
+ double m_mult;
+ // VFALCO
+ };
+
+
+
+
+
+
+ //==========================================================gradient_circle
+ class gradient_circle
+ {
+ // Actually the same as radial. Just for compatibility
+ public:
+ static AGG_INLINE int calculate(int x, int y, int)
+ {
+ return int(fast_sqrt(x*x + y*y));
+ }
+ };
+
+
+ //==========================================================gradient_radial
+ class gradient_radial
+ {
+ public:
+ static AGG_INLINE int calculate(int x, int y, int)
+ {
+ return int(fast_sqrt(x*x + y*y));
+ }
+ };
+
+ //========================================================gradient_radial_d
+ class gradient_radial_d
+ {
+ public:
+ static AGG_INLINE int calculate(int x, int y, int)
+ {
+ return uround(sqrt(double(x)*double(x) + double(y)*double(y)));
+ }
+ };
+
+ //====================================================gradient_radial_focus
+ class gradient_radial_focus
+ {
+ public:
+ //---------------------------------------------------------------------
+ gradient_radial_focus() :
+ m_r(100 * gradient_subpixel_scale),
+ m_fx(0),
+ m_fy(0)
+ {
+ update_values();
+ }
+
+ //---------------------------------------------------------------------
+ gradient_radial_focus(double r, double fx, double fy) :
+ m_r (iround(r * gradient_subpixel_scale)),
+ m_fx(iround(fx * gradient_subpixel_scale)),
+ m_fy(iround(fy * gradient_subpixel_scale))
+ {
+ update_values();
+ }
+
+ //---------------------------------------------------------------------
+ void init(double r, double fx, double fy)
+ {
+ 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_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) const
+ {
+ 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()
+ {
+ // 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)
+ {
+ 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));
+ }
+ m_mul = m_r / d;
+ }
+
+ 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
+ {
+ public:
+ static int calculate(int x, int, int) { return x; }
+ };
+
+
+ //==============================================================gradient_y
+ class gradient_y
+ {
+ public:
+ static int calculate(int, int y, int) { return y; }
+ };
+
+ //========================================================gradient_diamond
+ class gradient_diamond
+ {
+ public:
+ static AGG_INLINE int calculate(int x, int y, int)
+ {
+ int ax = abs(x);
+ int ay = abs(y);
+ return ax > ay ? ax : ay;
+ }
+ };
+
+ //=============================================================gradient_xy
+ class gradient_xy
+ {
+ public:
+ static AGG_INLINE int calculate(int x, int y, int d)
+ {
+ return abs(x) * abs(y) / d;
+ }
+ };
+
+ //========================================================gradient_sqrt_xy
+ class gradient_sqrt_xy
+ {
+ public:
+ static AGG_INLINE int calculate(int x, int y, int)
+ {
+ return fast_sqrt(abs(x) * abs(y));
+ }
+ };
+
+ //==========================================================gradient_conic
+ class gradient_conic
+ {
+ public:
+ static AGG_INLINE int calculate(int x, int y, int d)
+ {
+ return uround(fabs(atan2(double(y), double(x))) * double(d) / pi);
+ }
+ };
+
+ //=================================================gradient_repeat_adaptor
+ template<class GradientF> class gradient_repeat_adaptor
+ {
+ public:
+ gradient_repeat_adaptor(const GradientF& gradient) :
+ m_gradient(&gradient) {}
+
+ AGG_INLINE int calculate(int x, int y, int d) const
+ {
+ int ret = m_gradient->calculate(x, y, d) % d;
+ if(ret < 0) ret += d;
+ return ret;
+ }
+
+ private:
+ const GradientF* m_gradient;
+ };
+
+ //================================================gradient_reflect_adaptor
+ template<class GradientF> class gradient_reflect_adaptor
+ {
+ public:
+ gradient_reflect_adaptor(const GradientF& gradient) :
+ m_gradient(&gradient) {}
+
+ AGG_INLINE int calculate(int x, int y, int d) const
+ {
+ int d2 = d << 1;
+ int ret = m_gradient->calculate(x, y, d) % d2;
+ if(ret < 0) ret += d2;
+ if(ret >= d) ret = d2 - ret;
+ return ret;
+ }
+
+ private:
+ const GradientF* m_gradient;
+ };
+
+
+}
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gradient_alpha.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gradient_alpha.h
new file mode 100644
index 0000000000..2ec040e3b9
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gradient_alpha.h
@@ -0,0 +1,126 @@
+//----------------------------------------------------------------------------
+// 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_SPAN_GRADIENT_ALPHA_INCLUDED
+#define AGG_SPAN_GRADIENT_ALPHA_INCLUDED
+
+#include "agg_span_gradient.h"
+
+namespace agg
+{
+ //======================================================span_gradient_alpha
+ template<class ColorT,
+ class Interpolator,
+ class GradientF,
+ class AlphaF>
+ class span_gradient_alpha
+ {
+ public:
+ typedef Interpolator interpolator_type;
+ typedef ColorT color_type;
+ typedef typename color_type::value_type alpha_type;
+
+ enum downscale_shift_e
+ {
+ downscale_shift = interpolator_type::subpixel_shift - gradient_subpixel_shift
+ };
+
+
+ //--------------------------------------------------------------------
+ span_gradient_alpha() {}
+
+ //--------------------------------------------------------------------
+ span_gradient_alpha(interpolator_type& inter,
+ GradientF& gradient_function,
+ AlphaF& alpha_function,
+ double d1, double d2) :
+ m_interpolator(&inter),
+ m_gradient_function(&gradient_function),
+ m_alpha_function(&alpha_function),
+ m_d1(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_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 = iround(v * gradient_subpixel_scale); }
+ void d2(double v) { m_d2 = iround(v * gradient_subpixel_scale); }
+
+ //--------------------------------------------------------------------
+ void prepare() {}
+
+ //--------------------------------------------------------------------
+ void generate(color_type* span, int x, int y, unsigned len)
+ {
+ int dd = m_d2 - m_d1;
+ if(dd < 1) dd = 1;
+ m_interpolator->begin(x+0.5, y+0.5, len);
+ do
+ {
+ m_interpolator->coordinates(&x, &y);
+ int d = m_gradient_function->calculate(x >> downscale_shift,
+ y >> downscale_shift, 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;
+ span->a = (*m_alpha_function)[d];
+ ++span;
+ ++(*m_interpolator);
+ }
+ while(--len);
+ }
+
+ private:
+ interpolator_type* m_interpolator;
+ GradientF* m_gradient_function;
+ AlphaF* m_alpha_function;
+ int m_d1;
+ int m_d2;
+ };
+
+
+ //=======================================================gradient_alpha_x
+ template<class ColorT> struct gradient_alpha_x
+ {
+ typedef typename ColorT::value_type alpha_type;
+ alpha_type operator [] (alpha_type x) const { return x; }
+ };
+
+ //====================================================gradient_alpha_x_u8
+ struct gradient_alpha_x_u8
+ {
+ typedef int8u alpha_type;
+ alpha_type operator [] (alpha_type x) const { return x; }
+ };
+
+ //==========================================gradient_alpha_one_munus_x_u8
+ struct gradient_alpha_one_munus_x_u8
+ {
+ typedef int8u alpha_type;
+ alpha_type operator [] (alpha_type x) const { return 255-x; }
+ };
+
+}
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gradient_contour.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gradient_contour.h
new file mode 100644
index 0000000000..899bb799b6
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gradient_contour.h
@@ -0,0 +1,362 @@
+//----------------------------------------------------------------------------
+// AGG Contribution Pack - Gradients 1 (AGG CP - Gradients 1)
+// http://milan.marusinec.sk/aggcp
+//
+// For Anti-Grain Geometry - Version 2.4
+// http://www.antigrain.org
+//
+// Contribution Created By:
+// Milan Marusinec alias Milano
+// milan@marusinec.sk
+// Copyright (c) 2007-2008
+//
+// 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.
+//
+// [History] -----------------------------------------------------------------
+//
+// 02.02.2008-Milano: Ported from Object Pascal code of AggPas
+//
+#ifndef AGG_SPAN_GRADIENT_CONTOUR_INCLUDED
+#define AGG_SPAN_GRADIENT_CONTOUR_INCLUDED
+
+#include "agg_basics.h"
+#include "agg_trans_affine.h"
+#include "agg_path_storage.h"
+#include "agg_pixfmt_gray.h"
+#include "agg_conv_transform.h"
+#include "agg_conv_curve.h"
+#include "agg_bounding_rect.h"
+#include "agg_renderer_base.h"
+#include "agg_renderer_primitives.h"
+#include "agg_rasterizer_outline.h"
+#include "agg_span_gradient.h"
+
+#define infinity 1E20
+
+namespace agg
+{
+
+ //==========================================================gradient_contour
+ class gradient_contour
+ {
+ private:
+ int8u* m_buffer;
+ int m_width;
+ int m_height;
+ int m_frame;
+
+ double m_d1;
+ double m_d2;
+
+ public:
+ gradient_contour() :
+ m_buffer(NULL),
+ m_width(0),
+ m_height(0),
+ m_frame(10),
+ m_d1(0),
+ m_d2(100)
+ {
+ }
+
+ gradient_contour(double d1, double d2) :
+ m_buffer(NULL),
+ m_width(0),
+ m_height(0),
+ m_frame(10),
+ m_d1(d1),
+ m_d2(d2)
+ {
+ }
+
+ ~gradient_contour()
+ {
+ if (m_buffer)
+ {
+ delete [] m_buffer;
+ }
+ }
+
+ int8u* contour_create(path_storage* ps );
+
+ int contour_width() { return m_width; }
+ int contour_height() { return m_height; }
+
+ void d1(double d ) { m_d1 = d; }
+ void d2(double d ) { m_d2 = d; }
+
+ void frame(int f ) { m_frame = f; }
+ int frame() { return m_frame; }
+
+ int calculate(int x, int y, int d) const
+ {
+ if (m_buffer)
+ {
+ int px = x >> agg::gradient_subpixel_shift;
+ int py = y >> agg::gradient_subpixel_shift;
+
+ px %= m_width;
+
+ if (px < 0)
+ {
+ px += m_width;
+ }
+
+ py %= m_height;
+
+ if (py < 0 )
+ {
+ py += m_height;
+ }
+
+ return iround(m_buffer[py * m_width + px ] * (m_d2 / 256 ) + m_d1 ) << gradient_subpixel_shift;
+
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ };
+
+ static AGG_INLINE int square(int x ) { return x * x; }
+
+ // DT algorithm by: Pedro Felzenszwalb
+ void dt(float* spanf, float* spang, float* spanr, int* spann ,int length )
+ {
+ int k = 0;
+ float s;
+
+ spann[0 ] = 0;
+ spang[0 ] = float(-infinity );
+ spang[1 ] = float(+infinity );
+
+ for (int q = 1; q <= length - 1; q++)
+ {
+ s = ((spanf[q ] + square(q ) ) - (spanf[spann[k ] ] + square(spann[k ] ) ) ) / (2 * q - 2 * spann[k ] );
+
+ while (s <= spang[k ])
+ {
+ k--;
+ s = ((spanf[q ] + square(q ) ) - (spanf[spann[k ] ] + square(spann[k ] ) ) ) / (2 * q - 2 * spann[k ] );
+ }
+
+ k++;
+ spann[k ] = q;
+ spang[k ] = s;
+ spang[k + 1 ] = float(+infinity);
+
+ }
+
+ k = 0;
+
+ for (int q = 0; q <= length - 1; q++)
+ {
+ while (spang[k + 1 ] < q )
+ {
+ k++;
+ }
+
+ spanr[q ] = square(q - spann[k ] ) + spanf[spann[k ] ];
+ }
+ }
+
+ // DT algorithm by: Pedro Felzenszwalb
+ int8u* gradient_contour::contour_create(path_storage* ps )
+ {
+ int8u* result = NULL;
+
+ if (ps)
+ {
+ // I. Render Black And White NonAA Stroke of the Path
+ // Path Bounding Box + Some Frame Space Around [configurable]
+ agg::conv_curve<agg::path_storage> conv(*ps);
+
+ double x1, y1, x2, y2;
+
+ if (agg::bounding_rect_single(conv ,0 ,&x1 ,&y1 ,&x2 ,&y2 ))
+ {
+ // Create BW Rendering Surface
+ int width = int(ceil(x2 - x1 ) ) + m_frame * 2 + 1;
+ int height = int(ceil(y2 - y1 ) ) + m_frame * 2 + 1;
+
+ int8u* buffer = new int8u[width * height];
+
+ if (buffer)
+ {
+ memset(buffer ,255 ,width * height );
+
+ // Setup VG Engine & Render
+ agg::rendering_buffer rb;
+ rb.attach(buffer ,width ,height ,width );
+
+ agg::pixfmt_gray8 pf(rb);
+ agg::renderer_base<agg::pixfmt_gray8> renb(pf );
+
+ agg::renderer_primitives<agg::renderer_base<agg::pixfmt_gray8> > prim(renb );
+ agg::rasterizer_outline<renderer_primitives<agg::renderer_base<agg::pixfmt_gray8> > > ras(prim );
+
+ agg::trans_affine mtx;
+ mtx *= agg::trans_affine_translation(-x1 + m_frame, -y1 + m_frame );
+
+ agg::conv_transform<agg::conv_curve<agg::path_storage> > trans(conv ,mtx );
+
+ prim.line_color(agg::rgba8(0 ,0 ,0 ,255 ) );
+ ras.add_path(trans );
+
+ // II. Distance Transform
+ // Create Float Buffer + 0 vs. infinity (1e20) assignment
+ float* image = new float[width * height];
+
+ if (image)
+ {
+ for (int y = 0, l = 0; y < height; y++ )
+ {
+ for (int x = 0; x < width; x++, l++ )
+ {
+ if (buffer[l ] == 0)
+ {
+ image[l ] = 0.0;
+ }
+ else
+ {
+ image[l ] = float(infinity );
+ }
+ }
+
+ }
+
+ // DT of 2d
+ // SubBuff<float> max width,height
+ int length = width;
+
+ if (height > length)
+ {
+ length = height;
+ }
+
+ float* spanf = new float[length];
+ float* spang = new float[length + 1];
+ float* spanr = new float[length];
+ int* spann = new int[length];
+
+ if ((spanf) && (spang) && (spanr) && (spann))
+ {
+ // Transform along columns
+ for (int x = 0; x < width; x++ )
+ {
+ for (int y = 0; y < height; y++ )
+ {
+ spanf[y] = image[y * width + x];
+ }
+
+ // DT of 1d
+ dt(spanf ,spang ,spanr ,spann ,height );
+
+ for (int y = 0; y < height; y++ )
+ {
+ image[y * width + x] = spanr[y];
+ }
+ }
+
+ // Transform along rows
+ for (int y = 0; y < height; y++ )
+ {
+ for (int x = 0; x < width; x++ )
+ {
+ spanf[x] = image[y * width + x];
+ }
+
+ // DT of 1d
+ dt(spanf ,spang ,spanr ,spann ,width );
+
+ for (int x = 0; x < width; x++ )
+ {
+ image[y * width + x] = spanr[x];
+ }
+ }
+
+ // Take Square Roots, Min & Max
+ float min = sqrt(image[0] );
+ float max = min;
+
+ for (int y = 0, l = 0; y < height; y++ )
+ {
+ for (int x = 0; x < width; x++, l++ )
+ {
+ image[l] = sqrt(image[l]);
+
+ if (min > image[l])
+ {
+ min = image[l];
+ }
+
+ if (max < image[l])
+ {
+ max = image[l];
+ }
+
+ }
+ }
+
+ // III. Convert To Grayscale
+ if (min == max)
+ {
+ memset(buffer ,0 ,width * height );
+ }
+ else
+ {
+ float scale = 255 / (max - min );
+
+ for (int y = 0, l = 0; y < height; y++ )
+ {
+ for (int x = 0; x < width; x++ ,l++ )
+ {
+ buffer[l] = int8u(int((image[l] - min ) * scale ));
+ }
+ }
+ }
+
+ // OK
+ if (m_buffer)
+ {
+ delete [] m_buffer;
+ }
+
+ m_buffer = buffer;
+ m_width = width;
+ m_height = height;
+
+ buffer = NULL;
+ result = m_buffer;
+
+ }
+
+ if (spanf) { delete [] spanf; }
+ if (spang) { delete [] spang; }
+ if (spanr) { delete [] spanr; }
+ if (spann) { delete [] spann; }
+
+ delete [] image;
+
+ }
+ }
+
+ if (buffer)
+ {
+ delete [] buffer;
+ }
+
+ }
+
+ }
+ return result;
+ }
+
+}
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gradient_image.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gradient_image.h
new file mode 100644
index 0000000000..c99eaca166
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gradient_image.h
@@ -0,0 +1,188 @@
+//----------------------------------------------------------------------------
+// AGG Contribution Pack - Gradients 1 (AGG CP - Gradients 1)
+// http://milan.marusinec.sk/aggcp
+//
+// For Anti-Grain Geometry - Version 2.4
+// http://www.antigrain.org
+//
+// Contribution Created By:
+// Milan Marusinec alias Milano
+// milan@marusinec.sk
+// Copyright (c) 2007-2008
+//
+// 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.
+//
+// [History] -----------------------------------------------------------------
+//
+// 03.02.2008-Milano: Ported from Object Pascal code of AggPas
+//
+#ifndef AGG_SPAN_GRADIENT_IMAGE_INCLUDED
+#define AGG_SPAN_GRADIENT_IMAGE_INCLUDED
+
+#include "agg_basics.h"
+#include "agg_span_gradient.h"
+#include "agg_color_rgba.h"
+#include "agg_rendering_buffer.h"
+#include "agg_pixfmt_rgba.h"
+
+namespace agg
+{
+
+ //==========================================================one_color_function
+ template<class ColorT> class one_color_function
+ {
+ public:
+ typedef ColorT color_type;
+
+ color_type m_color;
+
+ one_color_function() :
+ m_color()
+ {
+ }
+
+ static unsigned size() { return 1; }
+
+ const color_type& operator [] (unsigned i) const
+ {
+ return m_color;
+ }
+
+ color_type* operator [] (unsigned i)
+ {
+ return &m_color;
+ }
+ };
+
+ //==========================================================gradient_image
+ template<class ColorT> class gradient_image
+ {
+ private:
+ //------------ fields
+ typedef ColorT color_type;
+ typedef agg::pixfmt_rgba32 pixfmt_type;
+
+ agg::rgba8* m_buffer;
+
+ int m_alocdx;
+ int m_alocdy;
+ int m_width;
+ int m_height;
+
+ color_type* m_color;
+
+ one_color_function<color_type> m_color_function;
+
+ public:
+ gradient_image() :
+ m_color_function(),
+ m_buffer(NULL),
+ m_alocdx(0),
+ m_alocdy(0),
+ m_width(0),
+ m_height(0)
+ {
+ m_color = m_color_function[0 ];
+ }
+
+ ~gradient_image()
+ {
+ if (m_buffer) { delete [] m_buffer; }
+ }
+
+ void* image_create(int width, int height )
+ {
+ void* result = NULL;
+
+ if (width > m_alocdx || height > m_alocdy)
+ {
+ if (m_buffer) { delete [] m_buffer; }
+
+ m_buffer = NULL;
+ m_buffer = new agg::rgba8[width * height];
+
+ if (m_buffer)
+ {
+ m_alocdx = width;
+ m_alocdy = height;
+ }
+ else
+ {
+ m_alocdx = 0;
+ m_alocdy = 0;
+ };
+ };
+
+ if (m_buffer)
+ {
+ m_width = width;
+ m_height = height;
+
+ for (int rows = 0; rows < height; rows++)
+ {
+ agg::rgba8* row = &m_buffer[rows * m_alocdx ];
+ memset(row ,0 ,m_width * 4 );
+ };
+
+ result = m_buffer;
+ };
+ return result;
+ }
+
+ void* image_buffer() { return m_buffer; }
+ int image_width() { return m_width; }
+ int image_height() { return m_height; }
+ int image_stride() { return m_alocdx * 4; }
+
+ int calculate(int x, int y, int d) const
+ {
+ if (m_buffer)
+ {
+ int px = x >> agg::gradient_subpixel_shift;
+ int py = y >> agg::gradient_subpixel_shift;
+
+ px %= m_width;
+
+ if (px < 0)
+ {
+ px += m_width;
+ }
+
+ py %= m_height;
+
+ if (py < 0 )
+ {
+ py += m_height;
+ }
+
+ rgba8* pixel = &m_buffer[py * m_alocdx + px ];
+
+ m_color->r = pixel->r;
+ m_color->g = pixel->g;
+ m_color->b = pixel->b;
+ m_color->a = pixel->a;
+
+ }
+ else
+ {
+ m_color->r = 0;
+ m_color->g = 0;
+ m_color->b = 0;
+ m_color->a = 0;
+ }
+ return 0;
+ }
+
+ const one_color_function<color_type>& color_function() const
+ {
+ return m_color_function;
+ }
+
+ };
+
+}
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_image_filter_rgb.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_image_filter_rgb.h
new file mode 100644
index 0000000000..f78ae19c1b
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_image_filter_rgb.h
@@ -0,0 +1,861 @@
+//----------------------------------------------------------------------------
+// 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_IMAGE_FILTER_RGB_INCLUDED
+#define AGG_SPAN_IMAGE_FILTER_RGB_INCLUDED
+
+#include "agg_basics.h"
+#include "agg_color_rgba.h"
+#include "agg_span_image_filter.h"
+
+
+namespace agg
+{
+
+ //===============================================span_image_filter_rgb_nn
+ template<class Source, class Interpolator>
+ class span_image_filter_rgb_nn :
+ 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;
+ typedef typename color_type::long_type long_type;
+
+ //--------------------------------------------------------------------
+ span_image_filter_rgb_nn() {}
+ span_image_filter_rgb_nn(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);
+ 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 = color_type::full_value();
+ ++span;
+ ++base_type::interpolator();
+
+ } while(--len);
+ }
+ };
+
+
+
+ //==========================================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;
+ typedef typename color_type::long_type long_type;
+
+ //--------------------------------------------------------------------
+ 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);
+ long_type fg[3];
+ const value_type *fg_ptr;
+ 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 weight;
+
+ fg[0] = fg[1] = fg[2] = 0;
+
+ 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 = color_type::downshift(fg[order_type::R], image_subpixel_shift * 2);
+ span->g = color_type::downshift(fg[order_type::G], image_subpixel_shift * 2);
+ span->b = color_type::downshift(fg[order_type::B], image_subpixel_shift * 2);
+ span->a = color_type::full_value();
+
+ ++span;
+ ++base_type::interpolator();
+
+ } while(--len);
+ }
+ };
+
+
+
+ //=====================================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 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;
+ typedef typename color_type::long_type long_type;
+
+ //--------------------------------------------------------------------
+ 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; }
+
+ //--------------------------------------------------------------------
+ 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];
+ long_type src_alpha;
+ 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;
+
+ int maxx = base_type::source().width() - 1;
+ int maxy = base_type::source().height() - 1;
+
+ 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 weight;
+
+ if(x_lr >= 0 && y_lr >= 0 &&
+ x_lr < maxx && y_lr < maxy)
+ {
+ fg[0] = fg[1] = fg[2] = 0;
+
+ x_hr &= image_subpixel_mask;
+ y_hr &= image_subpixel_mask;
+
+ 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_scale - y_hr);
+ fg[0] += weight * *fg_ptr++;
+ fg[1] += weight * *fg_ptr++;
+ fg[2] += weight * *fg_ptr++;
+
+ ++y_lr;
+ fg_ptr = (const value_type*)
+ base_type::source().row_ptr(y_lr) + x_lr + x_lr + x_lr;
+
+ weight = (image_subpixel_scale - x_hr) * y_hr;
+ fg[0] += weight * *fg_ptr++;
+ fg[1] += weight * *fg_ptr++;
+ fg[2] += weight * *fg_ptr++;
+
+ weight = x_hr * y_hr;
+ fg[0] += weight * *fg_ptr++;
+ fg[1] += weight * *fg_ptr++;
+ fg[2] += weight * *fg_ptr++;
+
+ fg[0] = color_type::downshift(fg[0], image_subpixel_shift * 2);
+ fg[1] = color_type::downshift(fg[1], image_subpixel_shift * 2);
+ fg[2] = color_type::downshift(fg[2], image_subpixel_shift * 2);
+ src_alpha = color_type::full_value();
+ }
+ 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 = 0;
+
+ x_hr &= image_subpixel_mask;
+ y_hr &= image_subpixel_mask;
+
+ 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().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++;
+ src_alpha += weight * color_type::full_value();
+ }
+ 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 = 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().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++;
+ src_alpha += weight * color_type::full_value();
+ }
+ 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 = (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().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++;
+ src_alpha += weight * color_type::full_value();
+ }
+ 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 = 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().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++;
+ src_alpha += weight * color_type::full_value();
+ }
+ 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] = color_type::downshift(fg[0], image_subpixel_shift * 2);
+ fg[1] = color_type::downshift(fg[1], image_subpixel_shift * 2);
+ fg[2] = color_type::downshift(fg[2], image_subpixel_shift * 2);
+ src_alpha = color_type::downshift(src_alpha, image_subpixel_shift * 2);
+ }
+ }
+
+ 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);
+ }
+ private:
+ color_type m_back_color;
+ };
+
+
+
+ //===============================================span_image_filter_rgb_2x2
+ template<class Source, class Interpolator>
+ class span_image_filter_rgb_2x2 :
+ 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;
+ typedef typename color_type::long_type long_type;
+
+ //--------------------------------------------------------------------
+ span_image_filter_rgb_2x2() {}
+ span_image_filter_rgb_2x2(source_type& src,
+ interpolator_type& inter,
+ 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];
+
+ 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;
+
+ 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 weight;
+ fg[0] = fg[1] = fg[2] = 0;
+
+ 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] = color_type::downshift(fg[0], image_filter_shift);
+ fg[1] = color_type::downshift(fg[1], image_filter_shift);
+ fg[2] = color_type::downshift(fg[2], image_filter_shift);
+
+ if(fg[order_type::R] > color_type::full_value()) fg[order_type::R] = color_type::full_value();
+ if(fg[order_type::G] > color_type::full_value()) fg[order_type::G] = color_type::full_value();
+ if(fg[order_type::B] > color_type::full_value()) fg[order_type::B] = color_type::full_value();
+
+ 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 = color_type::full_value();
+
+ ++span;
+ ++base_type::interpolator();
+
+ } while(--len);
+ }
+ };
+
+
+
+ //===================================================span_image_filter_rgb
+ template<class Source, class Interpolator>
+ class span_image_filter_rgb :
+ 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;
+ typedef typename color_type::long_type long_type;
+
+ //--------------------------------------------------------------------
+ span_image_filter_rgb() {}
+ span_image_filter_rgb(source_type& src,
+ interpolator_type& inter,
+ 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];
+ const value_type *fg_ptr;
+
+ 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
+ {
+ 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_lr = x_hr >> image_subpixel_shift;
+ int y_lr = y_hr >> image_subpixel_shift;
+
+ fg[0] = fg[1] = fg[2] = 0;
+
+ int x_fract = x_hr & image_subpixel_mask;
+ unsigned y_count = diameter;
+
+ 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(;;)
+ {
+ x_count = diameter;
+ weight_y = weight_array[y_hr];
+ x_hr = image_subpixel_mask - x_fract;
+ for(;;)
+ {
+ 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;
+
+ if(--x_count == 0) break;
+ x_hr += image_subpixel_scale;
+ fg_ptr = (const value_type*)base_type::source().next_x();
+ }
+
+ if(--y_count == 0) break;
+ y_hr += image_subpixel_scale;
+ fg_ptr = (const value_type*)base_type::source().next_y();
+ }
+
+ fg[0] = color_type::downshift(fg[0], image_filter_shift);
+ fg[1] = color_type::downshift(fg[1], image_filter_shift);
+ fg[2] = color_type::downshift(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[order_type::R] > color_type::full_value()) fg[order_type::R] = color_type::full_value();
+ if(fg[order_type::G] > color_type::full_value()) fg[order_type::G] = color_type::full_value();
+ if(fg[order_type::B] > color_type::full_value()) fg[order_type::B] = color_type::full_value();
+
+ 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 = color_type::full_value();
+
+ ++span;
+ ++base_type::interpolator();
+
+ } 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
+ {
+ downscale_shift = image_filter_shift
+ };
+
+ //--------------------------------------------------------------------
+ span_image_resample_rgb_affine() {}
+ span_image_resample_rgb_affine(source_type& src,
+ interpolator_type& inter,
+ 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] = 0;
+
+ 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(;;)
+ {
+ 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 += base_type::m_rx_inv;
+ if(x_hr >= filter_scale) break;
+ fg_ptr = (const value_type*)base_type::source().next_x();
+ }
+ y_hr += base_type::m_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] > color_type::full_value()) fg[order_type::R] = color_type::full_value();
+ if(fg[order_type::G] > color_type::full_value()) fg[order_type::G] = color_type::full_value();
+ if(fg[order_type::B] > color_type::full_value()) fg[order_type::B] = color_type::full_value();
+
+ 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 = color_type::full_value();
+
+ ++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
+ {
+ downscale_shift = image_filter_shift
+ };
+
+ //--------------------------------------------------------------------
+ span_image_resample_rgb() {}
+ span_image_resample_rgb(source_type& src,
+ interpolator_type& inter,
+ 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] = 0;
+
+ 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] > color_type::full_value()) fg[order_type::R] = color_type::full_value();
+ if(fg[order_type::G] > color_type::full_value()) fg[order_type::G] = color_type::full_value();
+ if(fg[order_type::B] > color_type::full_value()) fg[order_type::B] = color_type::full_value();
+
+ 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 = color_type::full_value();
+
+ ++span;
+ ++base_type::interpolator();
+ } while(--len);
+ }
+ };
+
+
+}
+
+
+#endif
+
+
+
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_interpolator_persp.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_interpolator_persp.h
new file mode 100644
index 0000000000..cad437e04f
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_interpolator_persp.h
@@ -0,0 +1,462 @@
+//----------------------------------------------------------------------------
+// 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_SPAN_INTERPOLATOR_PERSP_INCLUDED
+#define AGG_SPAN_INTERPOLATOR_PERSP_INCLUDED
+
+#include "agg_trans_perspective.h"
+#include "agg_dda_line.h"
+
+namespace agg
+{
+
+
+
+ //===========================================span_interpolator_persp_exact
+ template<unsigned SubpixelShift = 8>
+ class span_interpolator_persp_exact
+ {
+ public:
+ typedef trans_perspective trans_type;
+ typedef trans_perspective::iterator_x iterator_type;
+ enum subpixel_scale_e
+ {
+ subpixel_shift = SubpixelShift,
+ subpixel_scale = 1 << subpixel_shift
+ };
+
+ //--------------------------------------------------------------------
+ span_interpolator_persp_exact() {}
+
+ //--------------------------------------------------------------------
+ // Arbitrary quadrangle transformations
+ span_interpolator_persp_exact(const double* src, const double* dst)
+ {
+ quad_to_quad(src, dst);
+ }
+
+ //--------------------------------------------------------------------
+ // Direct transformations
+ span_interpolator_persp_exact(double x1, double y1,
+ double x2, double y2,
+ const double* quad)
+ {
+ rect_to_quad(x1, y1, x2, y2, quad);
+ }
+
+ //--------------------------------------------------------------------
+ // Reverse transformations
+ span_interpolator_persp_exact(const double* quad,
+ double x1, double y1,
+ double x2, double y2)
+ {
+ quad_to_rect(quad, x1, y1, x2, y2);
+ }
+
+ //--------------------------------------------------------------------
+ // Set the transformations using two arbitrary quadrangles.
+ void quad_to_quad(const double* src, const double* dst)
+ {
+ m_trans_dir.quad_to_quad(src, dst);
+ m_trans_inv.quad_to_quad(dst, src);
+ }
+
+ //--------------------------------------------------------------------
+ // 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);
+ }
+
+
+ //--------------------------------------------------------------------
+ // 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);
+ }
+
+ //--------------------------------------------------------------------
+ // Check if the equations were solved successfully
+ bool is_valid() const { return m_trans_dir.is_valid(); }
+
+ //----------------------------------------------------------------
+ void begin(double x, double y, unsigned len)
+ {
+ m_iterator = m_trans_dir.begin(x, y, 1.0);
+ double xt = m_iterator.x;
+ double yt = m_iterator.y;
+
+ double dx;
+ double dy;
+ const double delta = 1/double(subpixel_scale);
+ dx = xt + delta;
+ dy = yt;
+ m_trans_inv.transform(&dx, &dy);
+ dx -= x;
+ dy -= y;
+ 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 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
+
+ x += len;
+ xt = x;
+ yt = y;
+ m_trans_dir.transform(&xt, &yt);
+
+ dx = xt + delta;
+ dy = yt;
+ m_trans_inv.transform(&dx, &dy);
+ dx -= x;
+ dy -= y;
+ 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 = 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);
+ }
+
+
+ //----------------------------------------------------------------
+ void resynchronize(double xe, double ye, unsigned len)
+ {
+ // Assume x1,y1 are equal to the ones at the previous end point
+ int sx1 = m_scale_x.y();
+ int sy1 = m_scale_y.y();
+
+ // Calculate transformed coordinates at x2,y2
+ double xt = xe;
+ double yt = ye;
+ m_trans_dir.transform(&xt, &yt);
+
+ const double delta = 1/double(subpixel_scale);
+ double dx;
+ double dy;
+
+ // Calculate scale by X at x2,y2
+ dx = xt + delta;
+ dy = yt;
+ m_trans_inv.transform(&dx, &dy);
+ dx -= xe;
+ dy -= ye;
+ int sx2 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
+
+ // Calculate scale by Y at x2,y2
+ dx = xt;
+ dy = yt + delta;
+ m_trans_inv.transform(&dx, &dy);
+ dx -= xe;
+ dy -= ye;
+ int sy2 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
+
+ // Initialize the interpolators
+ m_scale_x = dda2_line_interpolator(sx1, sx2, len);
+ m_scale_y = dda2_line_interpolator(sy1, sy2, len);
+ }
+
+
+
+ //----------------------------------------------------------------
+ void operator++()
+ {
+ ++m_iterator;
+ ++m_scale_x;
+ ++m_scale_y;
+ }
+
+ //----------------------------------------------------------------
+ void coordinates(int* x, int* y) const
+ {
+ *x = iround(m_iterator.x * subpixel_scale);
+ *y = iround(m_iterator.y * subpixel_scale);
+ }
+
+ //----------------------------------------------------------------
+ void local_scale(int* x, int* y)
+ {
+ *x = m_scale_x.y();
+ *y = m_scale_y.y();
+ }
+
+ //----------------------------------------------------------------
+ void transform(double* x, double* y) const
+ {
+ m_trans_dir.transform(x, y);
+ }
+
+ private:
+ trans_type m_trans_dir;
+ trans_type m_trans_inv;
+ iterator_type m_iterator;
+ dda2_line_interpolator m_scale_x;
+ dda2_line_interpolator m_scale_y;
+ };
+
+
+
+
+
+
+
+
+
+
+
+ //============================================span_interpolator_persp_lerp
+ template<unsigned SubpixelShift = 8>
+ class span_interpolator_persp_lerp
+ {
+ public:
+ typedef trans_perspective trans_type;
+ enum subpixel_scale_e
+ {
+ subpixel_shift = SubpixelShift,
+ subpixel_scale = 1 << subpixel_shift
+ };
+
+ //--------------------------------------------------------------------
+ span_interpolator_persp_lerp() {}
+
+ //--------------------------------------------------------------------
+ // Arbitrary quadrangle transformations
+ span_interpolator_persp_lerp(const double* src, const double* dst)
+ {
+ quad_to_quad(src, dst);
+ }
+
+ //--------------------------------------------------------------------
+ // Direct transformations
+ span_interpolator_persp_lerp(double x1, double y1,
+ double x2, double y2,
+ const double* quad)
+ {
+ rect_to_quad(x1, y1, x2, y2, quad);
+ }
+
+ //--------------------------------------------------------------------
+ // Reverse transformations
+ span_interpolator_persp_lerp(const double* quad,
+ double x1, double y1,
+ double x2, double y2)
+ {
+ quad_to_rect(quad, x1, y1, x2, y2);
+ }
+
+ //--------------------------------------------------------------------
+ // Set the transformations using two arbitrary quadrangles.
+ void quad_to_quad(const double* src, const double* dst)
+ {
+ m_trans_dir.quad_to_quad(src, dst);
+ m_trans_inv.quad_to_quad(dst, src);
+ }
+
+ //--------------------------------------------------------------------
+ // 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);
+ }
+
+
+ //--------------------------------------------------------------------
+ // 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);
+ }
+
+ //--------------------------------------------------------------------
+ // Check if the equations were solved successfully
+ bool is_valid() const { return m_trans_dir.is_valid(); }
+
+ //----------------------------------------------------------------
+ void begin(double x, double y, unsigned len)
+ {
+ // Calculate transformed coordinates at x1,y1
+ double xt = x;
+ double yt = y;
+ m_trans_dir.transform(&xt, &yt);
+ int x1 = iround(xt * subpixel_scale);
+ int y1 = iround(yt * subpixel_scale);
+
+ double dx;
+ double dy;
+ const double delta = 1/double(subpixel_scale);
+
+ // Calculate scale by X at x1,y1
+ dx = xt + delta;
+ dy = yt;
+ m_trans_inv.transform(&dx, &dy);
+ dx -= x;
+ dy -= y;
+ int sx1 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
+
+ // Calculate scale by Y at x1,y1
+ dx = xt;
+ dy = yt + delta;
+ m_trans_inv.transform(&dx, &dy);
+ dx -= x;
+ dy -= y;
+ 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 = iround(xt * subpixel_scale);
+ int y2 = iround(yt * subpixel_scale);
+
+ // Calculate scale by X at x2,y2
+ dx = xt + delta;
+ dy = yt;
+ m_trans_inv.transform(&dx, &dy);
+ dx -= x;
+ dy -= y;
+ int sx2 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
+
+ // Calculate scale by Y at x2,y2
+ dx = xt;
+ dy = yt + delta;
+ m_trans_inv.transform(&dx, &dy);
+ dx -= x;
+ dy -= y;
+ int sy2 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
+
+ // Initialize the interpolators
+ m_coord_x = dda2_line_interpolator(x1, x2, len);
+ m_coord_y = dda2_line_interpolator(y1, y2, len);
+ m_scale_x = dda2_line_interpolator(sx1, sx2, len);
+ m_scale_y = dda2_line_interpolator(sy1, sy2, len);
+ }
+
+
+ //----------------------------------------------------------------
+ void resynchronize(double xe, double ye, unsigned len)
+ {
+ // Assume x1,y1 are equal to the ones at the previous end point
+ int x1 = m_coord_x.y();
+ int y1 = m_coord_y.y();
+ int sx1 = m_scale_x.y();
+ int sy1 = m_scale_y.y();
+
+ // Calculate transformed coordinates at x2,y2
+ double xt = xe;
+ double yt = ye;
+ m_trans_dir.transform(&xt, &yt);
+ int x2 = iround(xt * subpixel_scale);
+ int y2 = iround(yt * subpixel_scale);
+
+ const double delta = 1/double(subpixel_scale);
+ double dx;
+ double dy;
+
+ // Calculate scale by X at x2,y2
+ dx = xt + delta;
+ dy = yt;
+ m_trans_inv.transform(&dx, &dy);
+ dx -= xe;
+ dy -= ye;
+ int sx2 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
+
+ // Calculate scale by Y at x2,y2
+ dx = xt;
+ dy = yt + delta;
+ m_trans_inv.transform(&dx, &dy);
+ dx -= xe;
+ dy -= ye;
+ int sy2 = uround(subpixel_scale/sqrt(dx*dx + dy*dy)) >> subpixel_shift;
+
+ // Initialize the interpolators
+ m_coord_x = dda2_line_interpolator(x1, x2, len);
+ m_coord_y = dda2_line_interpolator(y1, y2, len);
+ m_scale_x = dda2_line_interpolator(sx1, sx2, len);
+ m_scale_y = dda2_line_interpolator(sy1, sy2, len);
+ }
+
+
+ //----------------------------------------------------------------
+ void operator++()
+ {
+ ++m_coord_x;
+ ++m_coord_y;
+ ++m_scale_x;
+ ++m_scale_y;
+ }
+
+ //----------------------------------------------------------------
+ void coordinates(int* x, int* y) const
+ {
+ *x = m_coord_x.y();
+ *y = m_coord_y.y();
+ }
+
+ //----------------------------------------------------------------
+ void local_scale(int* x, int* y)
+ {
+ *x = m_scale_x.y();
+ *y = m_scale_y.y();
+ }
+
+ //----------------------------------------------------------------
+ void transform(double* x, double* y) const
+ {
+ m_trans_dir.transform(x, y);
+ }
+
+ private:
+ trans_type m_trans_dir;
+ trans_type m_trans_inv;
+ dda2_line_interpolator m_coord_x;
+ dda2_line_interpolator m_coord_y;
+ dda2_line_interpolator m_scale_x;
+ dda2_line_interpolator m_scale_y;
+ };
+
+}
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_interpolator_trans.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_interpolator_trans.h
new file mode 100644
index 0000000000..32bc678a8e
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_interpolator_trans.h
@@ -0,0 +1,92 @@
+//----------------------------------------------------------------------------
+// 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
+//----------------------------------------------------------------------------
+//
+// Horizontal span interpolator for use with an arbitrary transformer
+// The efficiency highly depends on the operations done in the transformer
+//
+//----------------------------------------------------------------------------
+
+#ifndef AGG_SPAN_INTERPOLATOR_TRANS_INCLUDED
+#define AGG_SPAN_INTERPOLATOR_TRANS_INCLUDED
+
+#include "agg_basics.h"
+
+namespace agg
+{
+ //=================================================span_interpolator_trans
+ template<class Transformer, unsigned SubpixelShift = 8>
+ class span_interpolator_trans
+ {
+ public:
+ typedef Transformer trans_type;
+ enum subpixel_scale_e
+ {
+ subpixel_shift = SubpixelShift,
+ subpixel_scale = 1 << subpixel_shift
+ };
+
+ //--------------------------------------------------------------------
+ span_interpolator_trans() {}
+ span_interpolator_trans(trans_type& trans) : m_trans(&trans) {}
+ span_interpolator_trans(trans_type& trans,
+ double x, double y, unsigned) :
+ m_trans(&trans)
+ {
+ begin(x, y, 0);
+ }
+
+ //----------------------------------------------------------------
+ const trans_type& transformer() const { return *m_trans; }
+ void transformer(const trans_type& trans) { m_trans = &trans; }
+
+ //----------------------------------------------------------------
+ void begin(double x, double y, unsigned)
+ {
+ m_x = x;
+ m_y = y;
+ m_trans->transform(&x, &y);
+ m_ix = iround(x * subpixel_scale);
+ m_iy = iround(y * subpixel_scale);
+ }
+
+ //----------------------------------------------------------------
+ void operator++()
+ {
+ m_x += 1.0;
+ double x = m_x;
+ double y = m_y;
+ m_trans->transform(&x, &y);
+ m_ix = iround(x * subpixel_scale);
+ m_iy = iround(y * subpixel_scale);
+ }
+
+ //----------------------------------------------------------------
+ void coordinates(int* x, int* y) const
+ {
+ *x = m_ix;
+ *y = m_iy;
+ }
+
+ private:
+ trans_type* m_trans;
+ double m_x;
+ double m_y;
+ int m_ix;
+ int m_iy;
+ };
+
+}
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_pattern_gray.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_pattern_gray.h
new file mode 100644
index 0000000000..ae1a49f879
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_pattern_rgb.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_pattern_rgb.h
new file mode 100644
index 0000000000..4850508af1
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_pattern_rgb.h
@@ -0,0 +1,96 @@
+//----------------------------------------------------------------------------
+// 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_RGB_INCLUDED
+#define AGG_SPAN_PATTERN_RGB_INCLUDED
+
+#include "agg_basics.h"
+
+namespace agg
+{
+
+ //========================================================span_pattern_rgb
+ template<class Source> class span_pattern_rgb
+ {
+ public:
+ 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;
+
+ //--------------------------------------------------------------------
+ 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)
+ {}
+
+ //--------------------------------------------------------------------
+ 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->r = p[order_type::R];
+ span->g = p[order_type::G];
+ span->b = p[order_type::B];
+ 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_solid.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_solid.h
new file mode 100644
index 0000000000..ee46df9991
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_solid.h
@@ -0,0 +1,53 @@
+//----------------------------------------------------------------------------
+// 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
+//----------------------------------------------------------------------------
+//
+// span_solid_rgba8
+//
+//----------------------------------------------------------------------------
+
+#ifndef AGG_SPAN_SOLID_INCLUDED
+#define AGG_SPAN_SOLID_INCLUDED
+
+#include "agg_basics.h"
+
+namespace agg
+{
+ //--------------------------------------------------------------span_solid
+ template<class ColorT> class span_solid
+ {
+ public:
+ typedef ColorT color_type;
+
+ //--------------------------------------------------------------------
+ void color(const color_type& c) { m_color = c; }
+ const color_type& color() const { return m_color; }
+
+ //--------------------------------------------------------------------
+ void prepare() {}
+
+ //--------------------------------------------------------------------
+ void generate(color_type* span, int x, int y, unsigned len)
+ {
+ do { *span++ = m_color; } while(--len);
+ }
+
+ private:
+ color_type m_color;
+ };
+
+
+}
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_subdiv_adaptor.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_subdiv_adaptor.h
new file mode 100644
index 0000000000..b5b855ec97
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_subdiv_adaptor.h
@@ -0,0 +1,141 @@
+//----------------------------------------------------------------------------
+// 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_SPAN_SUBDIV_ADAPTOR_INCLUDED
+#define AGG_SPAN_SUBDIV_ADAPTOR_INCLUDED
+
+#include "agg_basics.h"
+
+namespace agg
+{
+
+ //=================================================span_subdiv_adaptor
+ template<class Interpolator, unsigned SubpixelShift = 8>
+ class span_subdiv_adaptor
+ {
+ public:
+ typedef Interpolator interpolator_type;
+ typedef typename interpolator_type::trans_type trans_type;
+
+ enum sublixel_scale_e
+ {
+ subpixel_shift = SubpixelShift,
+ subpixel_scale = 1 << subpixel_shift
+ };
+
+
+ //----------------------------------------------------------------
+ span_subdiv_adaptor() :
+ m_subdiv_shift(4),
+ m_subdiv_size(1 << m_subdiv_shift),
+ m_subdiv_mask(m_subdiv_size - 1) {}
+
+ span_subdiv_adaptor(interpolator_type& interpolator,
+ unsigned subdiv_shift = 4) :
+ m_subdiv_shift(subdiv_shift),
+ m_subdiv_size(1 << m_subdiv_shift),
+ m_subdiv_mask(m_subdiv_size - 1),
+ m_interpolator(&interpolator) {}
+
+ span_subdiv_adaptor(interpolator_type& interpolator,
+ double x, double y, unsigned len,
+ unsigned subdiv_shift = 4) :
+ m_subdiv_shift(subdiv_shift),
+ m_subdiv_size(1 << m_subdiv_shift),
+ m_subdiv_mask(m_subdiv_size - 1),
+ m_interpolator(&interpolator)
+ {
+ begin(x, y, len);
+ }
+
+
+ //----------------------------------------------------------------
+ const interpolator_type& interpolator() const { return *m_interpolator; }
+ void interpolator(interpolator_type& intr) { m_interpolator = &intr; }
+
+ //----------------------------------------------------------------
+ const trans_type& transformer() const
+ {
+ return *m_interpolator->transformer();
+ }
+ void transformer(const trans_type& trans)
+ {
+ m_interpolator->transformer(trans);
+ }
+
+ //----------------------------------------------------------------
+ unsigned subdiv_shift() const { return m_subdiv_shift; }
+ void subdiv_shift(unsigned shift)
+ {
+ m_subdiv_shift = shift;
+ m_subdiv_size = 1 << m_subdiv_shift;
+ m_subdiv_mask = m_subdiv_size - 1;
+ }
+
+ //----------------------------------------------------------------
+ void begin(double x, double y, unsigned len)
+ {
+ m_pos = 1;
+ 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;
+ m_interpolator->begin(x, y, len);
+ }
+
+ //----------------------------------------------------------------
+ void operator++()
+ {
+ ++(*m_interpolator);
+ if(m_pos >= m_subdiv_size)
+ {
+ unsigned len = m_len;
+ if(len > m_subdiv_size) len = m_subdiv_size;
+ m_interpolator->resynchronize(double(m_src_x) / double(subpixel_scale) + len,
+ m_src_y,
+ len);
+ m_pos = 0;
+ }
+ m_src_x += subpixel_scale;
+ ++m_pos;
+ --m_len;
+ }
+
+ //----------------------------------------------------------------
+ void coordinates(int* x, int* y) const
+ {
+ m_interpolator->coordinates(x, y);
+ }
+
+ //----------------------------------------------------------------
+ void local_scale(int* x, int* y) const
+ {
+ m_interpolator->local_scale(x, y);
+ }
+
+
+ private:
+ unsigned m_subdiv_shift;
+ unsigned m_subdiv_size;
+ unsigned m_subdiv_mask;
+ interpolator_type* m_interpolator;
+ int m_src_x;
+ double m_src_y;
+ unsigned m_pos;
+ unsigned m_len;
+ };
+
+}
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_bilinear.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_bilinear.h
new file mode 100644
index 0000000000..f3ab596472
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_bilinear.h
@@ -0,0 +1,166 @@
+//----------------------------------------------------------------------------
+// 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
+//----------------------------------------------------------------------------
+//
+// Bilinear 2D transformations
+//
+//----------------------------------------------------------------------------
+#ifndef AGG_TRANS_BILINEAR_INCLUDED
+#define AGG_TRANS_BILINEAR_INCLUDED
+
+#include "agg_basics.h"
+#include "agg_simul_eq.h"
+
+namespace agg
+{
+
+ //==========================================================trans_bilinear
+ class trans_bilinear
+ {
+ public:
+ //--------------------------------------------------------------------
+ trans_bilinear() : m_valid(false) {}
+
+ //--------------------------------------------------------------------
+ // Arbitrary quadrangle transformations
+ trans_bilinear(const double* src, const double* dst)
+ {
+ quad_to_quad(src, dst);
+ }
+
+
+ //--------------------------------------------------------------------
+ // Direct transformations
+ trans_bilinear(double x1, double y1, double x2, double y2,
+ const double* quad)
+ {
+ rect_to_quad(x1, y1, x2, y2, quad);
+ }
+
+
+ //--------------------------------------------------------------------
+ // Reverse transformations
+ trans_bilinear(const double* quad,
+ double x1, double y1, double x2, double y2)
+ {
+ quad_to_rect(quad, x1, y1, x2, y2);
+ }
+
+
+ //--------------------------------------------------------------------
+ // Set the transformations using two arbitrary quadrangles.
+ void quad_to_quad(const double* src, const double* dst)
+ {
+ double left[4][4];
+ double right[4][2];
+
+ unsigned i;
+ for(i = 0; i < 4; i++)
+ {
+ unsigned ix = i * 2;
+ unsigned iy = ix + 1;
+ left[i][0] = 1.0;
+ left[i][1] = src[ix] * src[iy];
+ left[i][2] = src[ix];
+ left[i][3] = src[iy];
+
+ right[i][0] = dst[ix];
+ right[i][1] = dst[iy];
+ }
+ m_valid = simul_eq<4, 2>::solve(left, right, m_mtx);
+ }
+
+
+ //--------------------------------------------------------------------
+ // 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);
+ }
+
+
+ //--------------------------------------------------------------------
+ // 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);
+ }
+
+ //--------------------------------------------------------------------
+ // 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 xy = tx * ty;
+ *x = m_mtx[0][0] + m_mtx[1][0] * xy + m_mtx[2][0] * tx + m_mtx[3][0] * ty;
+ *y = m_mtx[0][1] + m_mtx[1][1] * xy + m_mtx[2][1] * tx + m_mtx[3][1] * ty;
+ }
+
+
+ //--------------------------------------------------------------------
+ class iterator_x
+ {
+ double inc_x;
+ double inc_y;
+
+ public:
+ double x;
+ double y;
+
+ iterator_x() {}
+ iterator_x(double tx, double ty, double step, const double m[4][2]) :
+ inc_x(m[1][0] * step * ty + m[2][0] * step),
+ inc_y(m[1][1] * step * ty + m[2][1] * step),
+ x(m[0][0] + m[1][0] * tx * ty + m[2][0] * tx + m[3][0] * ty),
+ y(m[0][1] + m[1][1] * tx * ty + m[2][1] * tx + m[3][1] * ty)
+ {
+ }
+
+ void operator ++ ()
+ {
+ x += inc_x;
+ y += inc_y;
+ }
+ };
+
+ iterator_x begin(double x, double y, double step) const
+ {
+ return iterator_x(x, y, step, m_mtx);
+ }
+
+ private:
+ double m_mtx[4][2];
+ bool m_valid;
+ };
+
+}
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_double_path.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_double_path.h
new file mode 100644
index 0000000000..c645a7f869
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_double_path.h
@@ -0,0 +1,131 @@
+//----------------------------------------------------------------------------
+// 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_TRANS_DOUBLE_PATH_INCLUDED
+#define AGG_TRANS_DOUBLE_PATH_INCLUDED
+
+#include "agg_basics.h"
+#include "agg_vertex_sequence.h"
+
+namespace agg
+{
+
+ // See also: agg_trans_double_path.cpp
+ //
+ //-------------------------------------------------------trans_double_path
+ class trans_double_path
+ {
+ enum status_e
+ {
+ initial,
+ making_path,
+ ready
+ };
+
+ public:
+ typedef vertex_sequence<vertex_dist, 6> vertex_storage;
+
+ trans_double_path();
+
+ //--------------------------------------------------------------------
+ void base_length(double v) { m_base_length = v; }
+ double base_length() const { return m_base_length; }
+
+ //--------------------------------------------------------------------
+ void base_height(double v) { m_base_height = v; }
+ double base_height() const { return m_base_height; }
+
+ //--------------------------------------------------------------------
+ void preserve_x_scale(bool f) { m_preserve_x_scale = f; }
+ bool preserve_x_scale() const { return m_preserve_x_scale; }
+
+ //--------------------------------------------------------------------
+ void reset();
+ void move_to1(double x, double y);
+ void line_to1(double x, double y);
+ void move_to2(double x, double y);
+ void line_to2(double x, double y);
+ void finalize_paths();
+
+ //--------------------------------------------------------------------
+ template<class VertexSource1, class VertexSource2>
+ void add_paths(VertexSource1& vs1, VertexSource2& vs2,
+ unsigned path1_id=0, unsigned path2_id=0)
+ {
+ double x;
+ double y;
+
+ unsigned cmd;
+
+ vs1.rewind(path1_id);
+ while(!is_stop(cmd = vs1.vertex(&x, &y)))
+ {
+ if(is_move_to(cmd))
+ {
+ move_to1(x, y);
+ }
+ else
+ {
+ if(is_vertex(cmd))
+ {
+ line_to1(x, y);
+ }
+ }
+ }
+
+ vs2.rewind(path2_id);
+ while(!is_stop(cmd = vs2.vertex(&x, &y)))
+ {
+ if(is_move_to(cmd))
+ {
+ move_to2(x, y);
+ }
+ else
+ {
+ if(is_vertex(cmd))
+ {
+ line_to2(x, y);
+ }
+ }
+ }
+ finalize_paths();
+ }
+
+ //--------------------------------------------------------------------
+ double total_length1() const;
+ double total_length2() const;
+ void transform(double *x, double *y) const;
+
+ private:
+ double finalize_path(vertex_storage& vertices);
+ void transform1(const vertex_storage& vertices,
+ double kindex, double kx,
+ double *x, double* y) const;
+
+ vertex_storage m_src_vertices1;
+ vertex_storage m_src_vertices2;
+ double m_base_length;
+ double m_base_height;
+ double m_kindex1;
+ double m_kindex2;
+ status_e m_status1;
+ status_e m_status2;
+ bool m_preserve_x_scale;
+ };
+
+}
+
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_perspective.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_perspective.h
new file mode 100644
index 0000000000..7d4aa26c79
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_perspective.h
@@ -0,0 +1,731 @@
+//----------------------------------------------------------------------------
+// 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
+//----------------------------------------------------------------------------
+//
+// Perspective 2D transformations
+//
+//----------------------------------------------------------------------------
+#ifndef AGG_TRANS_PERSPECTIVE_INCLUDED
+#define AGG_TRANS_PERSPECTIVE_INCLUDED
+
+#include "agg_trans_affine.h"
+
+namespace agg
+{
+ //=======================================================trans_perspective
+ struct trans_perspective
+ {
+ 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) {}
+
+ // 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]) {}
+
+ // 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);
+
+ // 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)
+ {
+ 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);
+ }
+
+ // Multiply the matrix by another one and return
+ // the result in a separete matrix.
+ trans_perspective operator * (const trans_perspective& m) const
+ {
+ return trans_perspective(*this).multiply(m);
+ }
+ trans_perspective operator * (const trans_affine& m) const
+ {
+ 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) const
+ {
+ return trans_perspective(*this).multiply_inv(m);
+ }
+ trans_perspective operator / (const trans_affine& m) const
+ {
+ return trans_perspective(*this).multiply_inv(m);
+ }
+
+ // Calculate and return the inverse matrix
+ trans_perspective operator ~ () const
+ {
+ trans_perspective ret = *this;
+ ret.invert();
+ return ret;
+ }
+
+ // Equal operator with default epsilon
+ bool operator == (const trans_perspective& m) const
+ {
+ return is_equal(m, affine_epsilon);
+ }
+
+ // 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;
+
+ // 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;
+
+ // 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;
+
+
+
+ //--------------------------------------------------------------------
+ class iterator_x
+ {
+ double den;
+ double den_step;
+ double nom_x;
+ double nom_x_step;
+ double nom_y;
+ double nom_y_step;
+
+ public:
+ double x;
+ double y;
+
+ iterator_x() {}
+ 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 ++ ()
+ {
+ den += den_step;
+ nom_x += nom_x_step;
+ nom_y += nom_y_step;
+ double d = 1.0 / den;
+ x = nom_x * d;
+ y = nom_y * d;
+ }
+ };
+
+ //--------------------------------------------------------------------
+ iterator_x begin(double x, double y, double step) const
+ {
+ return iterator_x(x, y, step, *this);
+ }
+ };
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ //------------------------------------------------------------------------
+ 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/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_single_path.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_single_path.h
new file mode 100644
index 0000000000..9f4bf53bdb
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_single_path.h
@@ -0,0 +1,97 @@
+//----------------------------------------------------------------------------
+// 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_TRANS_SINGLE_PATH_INCLUDED
+#define AGG_TRANS_SINGLE_PATH_INCLUDED
+
+#include "agg_basics.h"
+#include "agg_vertex_sequence.h"
+
+namespace agg
+{
+
+ // See also: agg_trans_single_path.cpp
+ //
+ //-------------------------------------------------------trans_single_path
+ class trans_single_path
+ {
+ enum status_e
+ {
+ initial,
+ making_path,
+ ready
+ };
+
+ public:
+ typedef vertex_sequence<vertex_dist, 6> vertex_storage;
+
+ trans_single_path();
+
+ //--------------------------------------------------------------------
+ void base_length(double v) { m_base_length = v; }
+ double base_length() const { return m_base_length; }
+
+ //--------------------------------------------------------------------
+ void preserve_x_scale(bool f) { m_preserve_x_scale = f; }
+ bool preserve_x_scale() const { return m_preserve_x_scale; }
+
+ //--------------------------------------------------------------------
+ void reset();
+ void move_to(double x, double y);
+ void line_to(double x, double y);
+ void finalize_path();
+
+ //--------------------------------------------------------------------
+ template<class VertexSource>
+ void add_path(VertexSource& vs, unsigned path_id=0)
+ {
+ double x;
+ double y;
+
+ unsigned cmd;
+ vs.rewind(path_id);
+ while(!is_stop(cmd = vs.vertex(&x, &y)))
+ {
+ if(is_move_to(cmd))
+ {
+ move_to(x, y);
+ }
+ else
+ {
+ if(is_vertex(cmd))
+ {
+ line_to(x, y);
+ }
+ }
+ }
+ finalize_path();
+ }
+
+ //--------------------------------------------------------------------
+ double total_length() const;
+ void transform(double *x, double *y) const;
+
+ private:
+ vertex_storage m_src_vertices;
+ double m_base_length;
+ double m_kindex;
+ status_e m_status;
+ bool m_preserve_x_scale;
+ };
+
+
+}
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_viewport.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_viewport.h
new file mode 100644
index 0000000000..7088f99078
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_viewport.h
@@ -0,0 +1,303 @@
+//----------------------------------------------------------------------------
+// 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
+//----------------------------------------------------------------------------
+//
+// Viewport transformer - simple orthogonal conversions from world coordinates
+// to screen (device) ones.
+//
+//----------------------------------------------------------------------------
+
+#ifndef AGG_TRANS_VIEWPORT_INCLUDED
+#define AGG_TRANS_VIEWPORT_INCLUDED
+
+#include <string.h>
+#include "agg_trans_affine.h"
+
+
+namespace agg
+{
+
+ enum aspect_ratio_e
+ {
+ aspect_ratio_stretch,
+ aspect_ratio_meet,
+ aspect_ratio_slice
+ };
+
+
+ //----------------------------------------------------------trans_viewport
+ class trans_viewport
+ {
+ public:
+ //-------------------------------------------------------------------
+ trans_viewport() :
+ m_world_x1(0.0),
+ m_world_y1(0.0),
+ m_world_x2(1.0),
+ m_world_y2(1.0),
+ m_device_x1(0.0),
+ m_device_y1(0.0),
+ 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),
+ m_wy1(0.0),
+ m_wx2(1.0),
+ m_wy2(1.0),
+ m_dx1(0.0),
+ m_dy1(0.0),
+ m_kx(1.0),
+ m_ky(1.0)
+ {}
+
+ //-------------------------------------------------------------------
+ void preserve_aspect_ratio(double alignx,
+ double aligny,
+ aspect_ratio_e aspect)
+ {
+ m_align_x = alignx;
+ m_align_y = aligny;
+ m_aspect = aspect;
+ update();
+ }
+
+ //-------------------------------------------------------------------
+ void device_viewport(double x1, double y1, double x2, double y2)
+ {
+ m_device_x1 = x1;
+ m_device_y1 = y1;
+ m_device_x2 = x2;
+ m_device_y2 = y2;
+ update();
+ }
+
+ //-------------------------------------------------------------------
+ void world_viewport(double x1, double y1, double x2, double y2)
+ {
+ m_world_x1 = x1;
+ m_world_y1 = y1;
+ m_world_x2 = x2;
+ m_world_y2 = y2;
+ update();
+ }
+
+ //-------------------------------------------------------------------
+ void device_viewport(double* x1, double* y1, double* x2, double* y2) const
+ {
+ *x1 = m_device_x1;
+ *y1 = m_device_y1;
+ *x2 = m_device_x2;
+ *y2 = m_device_y2;
+ }
+
+ //-------------------------------------------------------------------
+ void world_viewport(double* x1, double* y1, double* x2, double* y2) const
+ {
+ *x1 = m_world_x1;
+ *y1 = m_world_y1;
+ *x2 = m_world_x2;
+ *y2 = m_world_y2;
+ }
+
+ //-------------------------------------------------------------------
+ void world_viewport_actual(double* x1, double* y1,
+ double* x2, double* y2) const
+ {
+ *x1 = m_wx1;
+ *y1 = m_wy1;
+ *x2 = m_wx2;
+ *y2 = m_wy2;
+ }
+
+ //-------------------------------------------------------------------
+ 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; }
+
+ //-------------------------------------------------------------------
+ void transform(double* x, double* y) const
+ {
+ *x = (*x - m_wx1) * m_kx + m_dx1;
+ *y = (*y - m_wy1) * m_ky + m_dy1;
+ }
+
+ //-------------------------------------------------------------------
+ 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;
+ *y = (*y - m_dy1) / m_ky + m_wy1;
+ }
+
+ //-------------------------------------------------------------------
+ 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;
+ }
+
+ //-------------------------------------------------------------------
+ double scale_y() const
+ {
+ return m_ky;
+ }
+
+ //-------------------------------------------------------------------
+ double scale() const
+ {
+ 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(*this);
+ }
+
+ void serialize(int8u* ptr) const
+ {
+ memcpy(ptr, this, sizeof(*this));
+ }
+
+ void deserialize(const int8u* ptr)
+ {
+ memcpy(this, ptr, sizeof(*this));
+ }
+
+ private:
+ void update();
+
+ double m_world_x1;
+ double m_world_y1;
+ double m_world_x2;
+ double m_world_y2;
+ double m_device_x1;
+ double m_device_y1;
+ 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;
+ double m_wy1;
+ double m_wx2;
+ double m_wy2;
+ double m_dx1;
+ double m_dy1;
+ double m_kx;
+ double m_ky;
+ };
+
+
+
+ //-----------------------------------------------------------------------
+ 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;
+ double world_y2 = m_world_y2;
+ double device_x1 = m_device_x1;
+ double device_y1 = m_device_y1;
+ double device_x2 = m_device_x2;
+ double device_y2 = m_device_y2;
+ if(m_aspect != aspect_ratio_stretch)
+ {
+ double d;
+ m_kx = (device_x2 - device_x1) / (world_x2 - world_x1);
+ m_ky = (device_y2 - device_y1) / (world_y2 - world_y1);
+
+ if((m_aspect == aspect_ratio_meet) == (m_kx < m_ky))
+ {
+ d = (world_y2 - world_y1) * m_ky / m_kx;
+ world_y1 += (world_y2 - world_y1 - d) * m_align_y;
+ world_y2 = world_y1 + d;
+ }
+ else
+ {
+ d = (world_x2 - world_x1) * m_kx / m_ky;
+ world_x1 += (world_x2 - world_x1 - d) * m_align_x;
+ world_x2 = world_x1 + d;
+ }
+ }
+ m_wx1 = world_x1;
+ m_wy1 = world_y1;
+ m_wx2 = world_x2;
+ m_wy2 = world_y2;
+ m_dx1 = device_x1;
+ 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;
+ }
+
+
+}
+
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_warp_magnifier.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_warp_magnifier.h
new file mode 100644
index 0000000000..38a92dbec8
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_warp_magnifier.h
@@ -0,0 +1,56 @@
+//----------------------------------------------------------------------------
+// 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_WARP_MAGNIFIER_INCLUDED
+#define AGG_WARP_MAGNIFIER_INCLUDED
+
+
+namespace agg
+{
+
+ //----------------------------------------------------trans_warp_magnifier
+ //
+ // See Inmplementation agg_trans_warp_magnifier.cpp
+ //
+ class trans_warp_magnifier
+ {
+ public:
+ trans_warp_magnifier() : m_xc(0.0), m_yc(0.0), m_magn(1.0), m_radius(1.0) {}
+
+ void center(double x, double y) { m_xc = x; m_yc = y; }
+ 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;
+
+ private:
+ double m_xc;
+ double m_yc;
+ double m_magn;
+ double m_radius;
+ };
+
+
+}
+
+
+#endif
+
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_bspline.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_bspline.h
new file mode 100644
index 0000000000..a2944548c0
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_bspline.h
@@ -0,0 +1,74 @@
+//----------------------------------------------------------------------------
+// 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_VCGEN_BSPLINE_INCLUDED
+#define AGG_VCGEN_BSPLINE_INCLUDED
+
+#include "agg_basics.h"
+#include "agg_array.h"
+#include "agg_bspline.h"
+
+
+namespace agg
+{
+
+ //==========================================================vcgen_bspline
+ class vcgen_bspline
+ {
+ enum status_e
+ {
+ initial,
+ ready,
+ polygon,
+ end_poly,
+ stop
+ };
+
+ public:
+ typedef pod_bvector<point_d, 6> vertex_storage;
+
+ vcgen_bspline();
+
+ void interpolation_step(double v) { m_interpolation_step = v; }
+ double interpolation_step() const { return m_interpolation_step; }
+
+ // Vertex Generator Interface
+ void remove_all();
+ void add_vertex(double x, double y, unsigned cmd);
+
+ // Vertex Source Interface
+ void rewind(unsigned path_id);
+ unsigned vertex(double* x, double* y);
+
+ private:
+ vcgen_bspline(const vcgen_bspline&);
+ const vcgen_bspline& operator = (const vcgen_bspline&);
+
+ vertex_storage m_src_vertices;
+ bspline m_spline_x;
+ bspline m_spline_y;
+ double m_interpolation_step;
+ unsigned m_closed;
+ status_e m_status;
+ unsigned m_src_vertex;
+ double m_cur_abscissa;
+ double m_max_abscissa;
+ };
+
+}
+
+
+#endif
+
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_markers_term.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_markers_term.h
new file mode 100644
index 0000000000..ee1e74e3eb
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_markers_term.h
@@ -0,0 +1,66 @@
+//----------------------------------------------------------------------------
+// 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_VCGEN_MARKERS_TERM_INCLUDED
+#define AGG_VCGEN_MARKERS_TERM_INCLUDED
+
+#include "agg_basics.h"
+#include "agg_vertex_sequence.h"
+
+namespace agg
+{
+
+ //======================================================vcgen_markers_term
+ //
+ // See Implemantation agg_vcgen_markers_term.cpp
+ // Terminal markers generator (arrowhead/arrowtail)
+ //
+ //------------------------------------------------------------------------
+ class vcgen_markers_term
+ {
+ public:
+ vcgen_markers_term() : m_curr_id(0), m_curr_idx(0) {}
+
+ // Vertex Generator Interface
+ void remove_all();
+ void add_vertex(double x, double y, unsigned cmd);
+
+ // Vertex Source Interface
+ void rewind(unsigned path_id);
+ unsigned vertex(double* x, double* y);
+
+ private:
+ vcgen_markers_term(const vcgen_markers_term&);
+ const vcgen_markers_term& operator = (const vcgen_markers_term&);
+
+ struct coord_type
+ {
+ double x, y;
+
+ coord_type() {}
+ coord_type(double x_, double y_) : x(x_), y(y_) {}
+ };
+
+ typedef pod_bvector<coord_type, 6> coord_storage;
+
+ coord_storage m_markers;
+ unsigned m_curr_id;
+ unsigned m_curr_idx;
+ };
+
+
+}
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_smooth_poly1.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_smooth_poly1.h
new file mode 100644
index 0000000000..80fc0fb796
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_smooth_poly1.h
@@ -0,0 +1,87 @@
+//----------------------------------------------------------------------------
+// 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_VCGEN_SMOOTH_POLY1_INCLUDED
+#define AGG_VCGEN_SMOOTH_POLY1_INCLUDED
+
+#include "agg_basics.h"
+#include "agg_vertex_sequence.h"
+
+
+namespace agg
+{
+
+ //======================================================vcgen_smooth_poly1
+ //
+ // See Implementation agg_vcgen_smooth_poly1.cpp
+ // Smooth polygon generator
+ //
+ //------------------------------------------------------------------------
+ class vcgen_smooth_poly1
+ {
+ enum status_e
+ {
+ initial,
+ ready,
+ polygon,
+ ctrl_b,
+ ctrl_e,
+ ctrl1,
+ ctrl2,
+ end_poly,
+ stop
+ };
+
+ public:
+ typedef vertex_sequence<vertex_dist, 6> vertex_storage;
+
+ vcgen_smooth_poly1();
+
+ void smooth_value(double v) { m_smooth_value = v * 0.5; }
+ double smooth_value() const { return m_smooth_value * 2.0; }
+
+ // Vertex Generator Interface
+ void remove_all();
+ void add_vertex(double x, double y, unsigned cmd);
+
+ // Vertex Source Interface
+ void rewind(unsigned path_id);
+ unsigned vertex(double* x, double* y);
+
+ private:
+ vcgen_smooth_poly1(const vcgen_smooth_poly1&);
+ const vcgen_smooth_poly1& operator = (const vcgen_smooth_poly1&);
+
+ void calculate(const vertex_dist& v0,
+ const vertex_dist& v1,
+ const vertex_dist& v2,
+ const vertex_dist& v3);
+
+ vertex_storage m_src_vertices;
+ double m_smooth_value;
+ unsigned m_closed;
+ status_e m_status;
+ unsigned m_src_vertex;
+ double m_ctrl1_x;
+ double m_ctrl1_y;
+ double m_ctrl2_x;
+ double m_ctrl2_y;
+ };
+
+}
+
+
+#endif
+
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_vertex_sequence.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_vertex_sequence.h
new file mode 100644
index 0000000000..5adc671597
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_vertex_sequence.h
@@ -0,0 +1,135 @@
+//----------------------------------------------------------------------------
+// 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_VCGEN_VERTEX_SEQUENCE_INCLUDED
+#define AGG_VCGEN_VERTEX_SEQUENCE_INCLUDED
+
+#include "agg_basics.h"
+#include "agg_vertex_sequence.h"
+#include "agg_shorten_path.h"
+
+namespace agg
+{
+
+ //===================================================vcgen_vertex_sequence
+ class vcgen_vertex_sequence
+ {
+ public:
+ typedef vertex_dist_cmd vertex_type;
+ typedef vertex_sequence<vertex_type, 6> vertex_storage;
+
+ vcgen_vertex_sequence() :
+ m_flags(0),
+ m_cur_vertex(0),
+ m_shorten(0.0),
+ m_ready(false)
+ {
+ }
+
+ // Vertex Generator Interface
+ void remove_all();
+ void add_vertex(double x, double y, unsigned cmd);
+
+ // Vertex Source Interface
+ void rewind(unsigned path_id);
+ unsigned vertex(double* x, double* y);
+
+ void shorten(double s) { m_shorten = s; }
+ double shorten() const { return m_shorten; }
+
+ private:
+ vcgen_vertex_sequence(const vcgen_vertex_sequence&);
+ const vcgen_vertex_sequence& operator = (const vcgen_vertex_sequence&);
+
+ vertex_storage m_src_vertices;
+ unsigned m_flags;
+ unsigned m_cur_vertex;
+ double m_shorten;
+ bool m_ready;
+ };
+
+
+ //------------------------------------------------------------------------
+ inline void vcgen_vertex_sequence::remove_all()
+ {
+ m_ready = false;
+ m_src_vertices.remove_all();
+ m_cur_vertex = 0;
+ m_flags = 0;
+ }
+
+ //------------------------------------------------------------------------
+ inline void vcgen_vertex_sequence::add_vertex(double x, double y, unsigned cmd)
+ {
+ m_ready = false;
+ if(is_move_to(cmd))
+ {
+ m_src_vertices.modify_last(vertex_dist_cmd(x, y, cmd));
+ }
+ else
+ {
+ if(is_vertex(cmd))
+ {
+ m_src_vertices.add(vertex_dist_cmd(x, y, cmd));
+ }
+ else
+ {
+ m_flags = cmd & path_flags_mask;
+ }
+ }
+ }
+
+
+ //------------------------------------------------------------------------
+ inline void vcgen_vertex_sequence::rewind(unsigned)
+ {
+ if(!m_ready)
+ {
+ m_src_vertices.close(is_closed(m_flags));
+ shorten_path(m_src_vertices, m_shorten, get_close_flag(m_flags));
+ }
+ m_ready = true;
+ m_cur_vertex = 0;
+ }
+
+ //------------------------------------------------------------------------
+ inline unsigned vcgen_vertex_sequence::vertex(double* x, double* y)
+ {
+ if(!m_ready)
+ {
+ rewind(0);
+ }
+
+ if(m_cur_vertex == m_src_vertices.size())
+ {
+ ++m_cur_vertex;
+ return path_cmd_end_poly | m_flags;
+ }
+
+ if(m_cur_vertex > m_src_vertices.size())
+ {
+ return path_cmd_stop;
+ }
+
+ vertex_type& v = m_src_vertices[m_cur_vertex++];
+ *x = v.x;
+ *y = v.y;
+ return v.cmd;
+ }
+
+
+}
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vpgen_clip_polygon.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vpgen_clip_polygon.h
new file mode 100644
index 0000000000..ded754e211
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vpgen_clip_polygon.h
@@ -0,0 +1,83 @@
+//----------------------------------------------------------------------------
+// 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_VPGEN_CLIP_POLYGON_INCLUDED
+#define AGG_VPGEN_CLIP_POLYGON_INCLUDED
+
+#include "agg_basics.h"
+
+namespace agg
+{
+
+ //======================================================vpgen_clip_polygon
+ //
+ // See Implementation agg_vpgen_clip_polygon.cpp
+ //
+ class vpgen_clip_polygon
+ {
+ public:
+ vpgen_clip_polygon() :
+ m_clip_box(0, 0, 1, 1),
+ m_x1(0),
+ m_y1(0),
+ m_clip_flags(0),
+ m_num_vertices(0),
+ m_vertex(0),
+ m_cmd(path_cmd_move_to)
+ {
+ }
+
+ void clip_box(double x1, double y1, double x2, double y2)
+ {
+ m_clip_box.x1 = x1;
+ m_clip_box.y1 = y1;
+ m_clip_box.x2 = x2;
+ m_clip_box.y2 = y2;
+ m_clip_box.normalize();
+ }
+
+
+ double x1() const { return m_clip_box.x1; }
+ double y1() const { return m_clip_box.y1; }
+ double x2() const { return m_clip_box.x2; }
+ double y2() const { return m_clip_box.y2; }
+
+ static bool auto_close() { return true; }
+ static bool auto_unclose() { return false; }
+
+ void reset();
+ void move_to(double x, double y);
+ void line_to(double x, double y);
+ unsigned vertex(double* x, double* y);
+
+ private:
+ unsigned clipping_flags(double x, double y);
+
+ private:
+ rect_d m_clip_box;
+ double m_x1;
+ double m_y1;
+ unsigned m_clip_flags;
+ double m_x[4];
+ double m_y[4];
+ unsigned m_num_vertices;
+ unsigned m_vertex;
+ unsigned m_cmd;
+ };
+
+}
+
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vpgen_clip_polyline.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vpgen_clip_polyline.h
new file mode 100644
index 0000000000..b070a7759e
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vpgen_clip_polyline.h
@@ -0,0 +1,78 @@
+//----------------------------------------------------------------------------
+// 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_VPGEN_CLIP_POLYLINE_INCLUDED
+#define AGG_VPGEN_CLIP_POLYLINE_INCLUDED
+
+#include "agg_basics.h"
+
+namespace agg
+{
+
+ //======================================================vpgen_clip_polyline
+ //
+ // See Implementation agg_vpgen_clip_polyline.cpp
+ //
+ class vpgen_clip_polyline
+ {
+ public:
+ vpgen_clip_polyline() :
+ m_clip_box(0, 0, 1, 1),
+ m_x1(0),
+ m_y1(0),
+ m_num_vertices(0),
+ m_vertex(0),
+ m_move_to(false)
+ {
+ }
+
+ void clip_box(double x1, double y1, double x2, double y2)
+ {
+ m_clip_box.x1 = x1;
+ m_clip_box.y1 = y1;
+ m_clip_box.x2 = x2;
+ m_clip_box.y2 = y2;
+ m_clip_box.normalize();
+ }
+
+ double x1() const { return m_clip_box.x1; }
+ double y1() const { return m_clip_box.y1; }
+ double x2() const { return m_clip_box.x2; }
+ double y2() const { return m_clip_box.y2; }
+
+ static bool auto_close() { return false; }
+ static bool auto_unclose() { return true; }
+
+ void reset();
+ void move_to(double x, double y);
+ void line_to(double x, double y);
+ unsigned vertex(double* x, double* y);
+
+ private:
+ rect_d m_clip_box;
+ double m_x1;
+ double m_y1;
+ double m_x[2];
+ double m_y[2];
+ unsigned m_cmd[2];
+ unsigned m_num_vertices;
+ unsigned m_vertex;
+ bool m_move_to;
+ };
+
+}
+
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_bezier_ctrl.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_bezier_ctrl.h
new file mode 100644
index 0000000000..01851eb3e1
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_bezier_ctrl.h
@@ -0,0 +1,196 @@
+//----------------------------------------------------------------------------
+// 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
+//----------------------------------------------------------------------------
+//
+// classes bezier_ctrl_impl, bezier_ctrl
+//
+//----------------------------------------------------------------------------
+
+#ifndef AGG_BEZIER_CTRL_INCLUDED
+#define AGG_BEZIER_CTRL_INCLUDED
+
+#include "agg_math.h"
+#include "agg_ellipse.h"
+#include "agg_trans_affine.h"
+#include "agg_color_rgba.h"
+#include "agg_conv_stroke.h"
+#include "agg_conv_curve.h"
+#include "agg_polygon_ctrl.h"
+
+
+namespace agg
+{
+
+ //--------------------------------------------------------bezier_ctrl_impl
+ class bezier_ctrl_impl : public ctrl
+ {
+ public:
+ bezier_ctrl_impl();
+
+ void curve(double x1, double y1,
+ double x2, double y2,
+ double x3, double y3,
+ double x4, double y4);
+ curve4& curve();
+
+ double x1() const { return m_poly.xn(0); }
+ double y1() const { return m_poly.yn(0); }
+ double x2() const { return m_poly.xn(1); }
+ double y2() const { return m_poly.yn(1); }
+ double x3() const { return m_poly.xn(2); }
+ double y3() const { return m_poly.yn(2); }
+ double x4() const { return m_poly.xn(3); }
+ double y4() const { return m_poly.yn(3); }
+
+ void x1(double x) { m_poly.xn(0) = x; }
+ void y1(double y) { m_poly.yn(0) = y; }
+ void x2(double x) { m_poly.xn(1) = x; }
+ void y2(double y) { m_poly.yn(1) = y; }
+ void x3(double x) { m_poly.xn(2) = x; }
+ void y3(double y) { m_poly.yn(2) = y; }
+ void x4(double x) { m_poly.xn(3) = x; }
+ void y4(double y) { m_poly.yn(3) = y; }
+
+ void line_width(double w) { m_stroke.width(w); }
+ double line_width() const { return m_stroke.width(); }
+
+ void point_radius(double r) { m_poly.point_radius(r); }
+ double point_radius() const { return m_poly.point_radius(); }
+
+ virtual bool in_rect(double x, double y) const;
+ virtual bool on_mouse_button_down(double x, double y);
+ virtual bool on_mouse_button_up(double x, double y);
+ virtual bool on_mouse_move(double x, double y, bool button_flag);
+ virtual bool on_arrow_keys(bool left, bool right, bool down, bool up);
+
+ // Vertex source interface
+ unsigned num_paths() { return 7; };
+ void rewind(unsigned path_id);
+ unsigned vertex(double* x, double* y);
+
+
+ private:
+ curve4 m_curve;
+ ellipse m_ellipse;
+ conv_stroke<curve4> m_stroke;
+ polygon_ctrl_impl m_poly;
+ unsigned m_idx;
+ };
+
+
+
+ //----------------------------------------------------------bezier_ctrl
+ template<class ColorT> class bezier_ctrl : public bezier_ctrl_impl
+ {
+ public:
+ bezier_ctrl() :
+ m_color(rgba(0.0, 0.0, 0.0))
+ {
+ }
+
+ void line_color(const ColorT& c) { m_color = c; }
+ const ColorT& color(unsigned i) const { return m_color; }
+
+ private:
+ bezier_ctrl(const bezier_ctrl<ColorT>&);
+ const bezier_ctrl<ColorT>& operator = (const bezier_ctrl<ColorT>&);
+
+ ColorT m_color;
+ };
+
+
+
+
+
+ //--------------------------------------------------------curve3_ctrl_impl
+ class curve3_ctrl_impl : public ctrl
+ {
+ public:
+ curve3_ctrl_impl();
+
+ void curve(double x1, double y1,
+ double x2, double y2,
+ double x3, double y3);
+ curve3& curve();
+
+ double x1() const { return m_poly.xn(0); }
+ double y1() const { return m_poly.yn(0); }
+ double x2() const { return m_poly.xn(1); }
+ double y2() const { return m_poly.yn(1); }
+ double x3() const { return m_poly.xn(2); }
+ double y3() const { return m_poly.yn(2); }
+
+ void x1(double x) { m_poly.xn(0) = x; }
+ void y1(double y) { m_poly.yn(0) = y; }
+ void x2(double x) { m_poly.xn(1) = x; }
+ void y2(double y) { m_poly.yn(1) = y; }
+ void x3(double x) { m_poly.xn(2) = x; }
+ void y3(double y) { m_poly.yn(2) = y; }
+
+ void line_width(double w) { m_stroke.width(w); }
+ double line_width() const { return m_stroke.width(); }
+
+ void point_radius(double r) { m_poly.point_radius(r); }
+ double point_radius() const { return m_poly.point_radius(); }
+
+ virtual bool in_rect(double x, double y) const;
+ virtual bool on_mouse_button_down(double x, double y);
+ virtual bool on_mouse_button_up(double x, double y);
+ virtual bool on_mouse_move(double x, double y, bool button_flag);
+ virtual bool on_arrow_keys(bool left, bool right, bool down, bool up);
+
+ // Vertex source interface
+ unsigned num_paths() { return 6; };
+ void rewind(unsigned path_id);
+ unsigned vertex(double* x, double* y);
+
+
+ private:
+ curve3 m_curve;
+ ellipse m_ellipse;
+ conv_stroke<curve3> m_stroke;
+ polygon_ctrl_impl m_poly;
+ unsigned m_idx;
+ };
+
+
+
+ //----------------------------------------------------------curve3_ctrl
+ template<class ColorT> class curve3_ctrl : public curve3_ctrl_impl
+ {
+ public:
+ curve3_ctrl() :
+ m_color(rgba(0.0, 0.0, 0.0))
+ {
+ }
+
+ void line_color(const ColorT& c) { m_color = c; }
+ const ColorT& color(unsigned i) const { return m_color; }
+
+ private:
+ curve3_ctrl(const curve3_ctrl<ColorT>&);
+ const curve3_ctrl<ColorT>& operator = (const curve3_ctrl<ColorT>&);
+
+ ColorT m_color;
+ };
+
+
+
+
+}
+
+
+
+#endif
+
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_cbox_ctrl.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_cbox_ctrl.h
new file mode 100644
index 0000000000..7ecbce27f4
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_cbox_ctrl.h
@@ -0,0 +1,112 @@
+//----------------------------------------------------------------------------
+// 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
+//----------------------------------------------------------------------------
+//
+// classes cbox_ctrl_impl, cbox_ctrl
+//
+//----------------------------------------------------------------------------
+
+#ifndef AGG_CBOX_CTRL_INCLUDED
+#define AGG_CBOX_CTRL_INCLUDED
+
+#include "agg_basics.h"
+#include "agg_conv_stroke.h"
+#include "agg_gsv_text.h"
+#include "agg_trans_affine.h"
+#include "agg_color_rgba.h"
+#include "agg_ctrl.h"
+
+
+
+namespace agg
+{
+
+ //----------------------------------------------------------cbox_ctrl_impl
+ class cbox_ctrl_impl : public ctrl
+ {
+ public:
+ cbox_ctrl_impl(double x, double y, const char* label, bool flip_y=false);
+
+ void text_thickness(double t) { m_text_thickness = t; }
+ void text_size(double h, double w=0.0);
+
+ const char* label() { return m_label; }
+ void label(const char* l);
+
+ bool status() const { return m_status; }
+ void status(bool st) { m_status = st; }
+
+ virtual bool in_rect(double x, double y) const;
+ virtual bool on_mouse_button_down(double x, double y);
+ virtual bool on_mouse_button_up(double x, double y);
+ virtual bool on_mouse_move(double x, double y, bool button_flag);
+ virtual bool on_arrow_keys(bool left, bool right, bool down, bool up);
+
+ // Vertex soutce interface
+ unsigned num_paths() { return 3; };
+ void rewind(unsigned path_id);
+ unsigned vertex(double* x, double* y);
+
+ private:
+ double m_text_thickness;
+ double m_text_height;
+ double m_text_width;
+ char m_label[128];
+ bool m_status;
+ double m_vx[32];
+ double m_vy[32];
+
+ gsv_text m_text;
+ conv_stroke<gsv_text> m_text_poly;
+
+ unsigned m_idx;
+ unsigned m_vertex;
+ };
+
+
+ //----------------------------------------------------------cbox_ctrl_impl
+ template<class ColorT> class cbox_ctrl : public cbox_ctrl_impl
+ {
+ public:
+ cbox_ctrl(double x, double y, const char* label, bool flip_y=false) :
+ cbox_ctrl_impl(x, y, label, flip_y),
+ m_text_color(rgba(0.0, 0.0, 0.0)),
+ m_inactive_color(rgba(0.0, 0.0, 0.0)),
+ m_active_color(rgba(0.4, 0.0, 0.0))
+ {
+ m_colors[0] = &m_inactive_color;
+ m_colors[1] = &m_text_color;
+ m_colors[2] = &m_active_color;
+ }
+
+ void text_color(const ColorT& c) { m_text_color = c; }
+ void inactive_color(const ColorT& c) { m_inactive_color = c; }
+ void active_color(const ColorT& c) { m_active_color = c; }
+
+ const ColorT& color(unsigned i) const { return *m_colors[i]; }
+
+ private:
+ cbox_ctrl(const cbox_ctrl<ColorT>&);
+ const cbox_ctrl<ColorT>& operator = (const cbox_ctrl<ColorT>&);
+
+ ColorT m_text_color;
+ ColorT m_inactive_color;
+ ColorT m_active_color;
+ ColorT* m_colors[3];
+ };
+
+
+}
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_ctrl.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_ctrl.h
new file mode 100644
index 0000000000..7e811c63e1
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_ctrl.h
@@ -0,0 +1,118 @@
+//----------------------------------------------------------------------------
+// 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
+//----------------------------------------------------------------------------
+//
+// Function render_ctrl
+//
+//----------------------------------------------------------------------------
+
+#ifndef AGG_CTRL_INCLUDED
+#define AGG_CTRL_INCLUDED
+
+#include "agg_trans_affine.h"
+#include "agg_renderer_scanline.h"
+
+namespace agg
+{
+
+ //--------------------------------------------------------------------ctrl
+ class ctrl
+ {
+ public:
+ //--------------------------------------------------------------------
+ virtual ~ctrl() {}
+ ctrl(double x1, double y1, double x2, double y2, bool flip_y) :
+ m_x1(x1), m_y1(y1), m_x2(x2), m_y2(y2),
+ m_flip_y(flip_y),
+ m_mtx(0)
+ {
+ }
+
+ //--------------------------------------------------------------------
+ virtual bool in_rect(double x, double y) const = 0;
+ virtual bool on_mouse_button_down(double x, double y) = 0;
+ virtual bool on_mouse_button_up(double x, double y) = 0;
+ virtual bool on_mouse_move(double x, double y, bool button_flag) = 0;
+ virtual bool on_arrow_keys(bool left, bool right, bool down, bool up) = 0;
+
+ //--------------------------------------------------------------------
+ void transform(const trans_affine& mtx) { m_mtx = &mtx; }
+ void no_transform() { m_mtx = 0; }
+
+ //--------------------------------------------------------------------
+ void transform_xy(double* x, double* y) const
+ {
+ if(m_flip_y) *y = m_y1 + m_y2 - *y;
+ if(m_mtx) m_mtx->transform(x, y);
+ }
+
+ //--------------------------------------------------------------------
+ void inverse_transform_xy(double* x, double* y) const
+ {
+ if(m_mtx) m_mtx->inverse_transform(x, y);
+ if(m_flip_y) *y = m_y1 + m_y2 - *y;
+ }
+
+ //--------------------------------------------------------------------
+ double scale() const { return m_mtx ? m_mtx->scale() : 1.0; }
+
+ private:
+ ctrl(const ctrl&);
+ const ctrl& operator = (const ctrl&);
+
+ protected:
+ double m_x1;
+ double m_y1;
+ double m_x2;
+ double m_y2;
+
+ private:
+ bool m_flip_y;
+ const trans_affine* m_mtx;
+ };
+
+
+ //--------------------------------------------------------------------
+ template<class Rasterizer, class Scanline, class Renderer, class Ctrl>
+ void render_ctrl(Rasterizer& ras, Scanline& sl, Renderer& r, Ctrl& c)
+ {
+ unsigned i;
+ for(i = 0; i < c.num_paths(); i++)
+ {
+ ras.reset();
+ ras.add_path(c, i);
+ render_scanlines_aa_solid(ras, sl, r, c.color(i));
+ }
+ }
+
+
+ //--------------------------------------------------------------------
+ template<class Rasterizer, class Scanline, class Renderer, class Ctrl>
+ void render_ctrl_rs(Rasterizer& ras, Scanline& sl, Renderer& r, Ctrl& c)
+ {
+ unsigned i;
+ for(i = 0; i < c.num_paths(); i++)
+ {
+ ras.reset();
+ ras.add_path(c, i);
+ r.color(c.color(i));
+ render_scanlines(ras, sl, r);
+ }
+ }
+
+
+}
+
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_gamma_ctrl.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_gamma_ctrl.h
new file mode 100644
index 0000000000..0a645a7146
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_gamma_ctrl.h
@@ -0,0 +1,170 @@
+//----------------------------------------------------------------------------
+// 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
+//----------------------------------------------------------------------------
+//
+// class gamma_ctrl
+//
+//----------------------------------------------------------------------------
+
+#ifndef AGG_GAMMA_CTRL_INCLUDED
+#define AGG_GAMMA_CTRL_INCLUDED
+
+#include "agg_basics.h"
+#include "agg_gamma_spline.h"
+#include "agg_ellipse.h"
+#include "agg_conv_stroke.h"
+#include "agg_gsv_text.h"
+#include "agg_trans_affine.h"
+#include "agg_color_rgba.h"
+#include "agg_ctrl.h"
+
+namespace agg
+{
+ //------------------------------------------------------------------------
+ // Class that can be used to create an interactive control to set up
+ // gamma arrays.
+ //------------------------------------------------------------------------
+ class gamma_ctrl_impl : public ctrl
+ {
+ public:
+ gamma_ctrl_impl(double x1, double y1, double x2, double y2, bool flip_y=false);
+
+ // Set other parameters
+ void border_width(double t, double extra=0.0);
+ void curve_width(double t) { m_curve_width = t; }
+ void grid_width(double t) { m_grid_width = t; }
+ void text_thickness(double t) { m_text_thickness = t; }
+ void text_size(double h, double w=0.0);
+ void point_size(double s) { m_point_size = s; }
+
+ // Event handlers. Just call them if the respective events
+ // in your system occure. The functions return true if redrawing
+ // is required.
+ virtual bool in_rect(double x, double y) const;
+ virtual bool on_mouse_button_down(double x, double y);
+ virtual bool on_mouse_button_up(double x, double y);
+ virtual bool on_mouse_move(double x, double y, bool button_flag);
+ virtual bool on_arrow_keys(bool left, bool right, bool down, bool up);
+
+ void change_active_point();
+
+ // A copy of agg::gamma_spline interface
+ void values(double kx1, double ky1, double kx2, double ky2);
+ void values(double* kx1, double* ky1, double* kx2, double* ky2) const;
+ const unsigned char* gamma() const { return m_gamma_spline.gamma(); }
+ double y(double x) const { return m_gamma_spline.y(x); }
+ double operator() (double x) const { return m_gamma_spline.y(x); }
+ const gamma_spline& get_gamma_spline() const { return m_gamma_spline; }
+
+ // Vertex soutce interface
+ unsigned num_paths() { return 7; }
+ void rewind(unsigned idx);
+ unsigned vertex(double* x, double* y);
+
+ private:
+ void calc_spline_box();
+ void calc_points();
+ void calc_values();
+
+ gamma_spline m_gamma_spline;
+ double m_border_width;
+ double m_border_extra;
+ double m_curve_width;
+ double m_grid_width;
+ double m_text_thickness;
+ double m_point_size;
+ double m_text_height;
+ double m_text_width;
+ double m_xc1;
+ double m_yc1;
+ double m_xc2;
+ double m_yc2;
+ double m_xs1;
+ double m_ys1;
+ double m_xs2;
+ double m_ys2;
+ double m_xt1;
+ double m_yt1;
+ double m_xt2;
+ double m_yt2;
+ conv_stroke<gamma_spline> m_curve_poly;
+ ellipse m_ellipse;
+ gsv_text m_text;
+ conv_stroke<gsv_text> m_text_poly;
+ unsigned m_idx;
+ unsigned m_vertex;
+ double m_vx[32];
+ double m_vy[32];
+ double m_xp1;
+ double m_yp1;
+ double m_xp2;
+ double m_yp2;
+ bool m_p1_active;
+ unsigned m_mouse_point;
+ double m_pdx;
+ double m_pdy;
+ };
+
+
+
+ template<class ColorT> class gamma_ctrl : public gamma_ctrl_impl
+ {
+ public:
+ gamma_ctrl(double x1, double y1, double x2, double y2, bool flip_y=false) :
+ gamma_ctrl_impl(x1, y1, x2, y2, flip_y),
+ m_background_color(rgba(1.0, 1.0, 0.9)),
+ m_border_color(rgba(0.0, 0.0, 0.0)),
+ m_curve_color(rgba(0.0, 0.0, 0.0)),
+ m_grid_color(rgba(0.2, 0.2, 0.0)),
+ m_inactive_pnt_color(rgba(0.0, 0.0, 0.0)),
+ m_active_pnt_color(rgba(1.0, 0.0, 0.0)),
+ m_text_color(rgba(0.0, 0.0, 0.0))
+ {
+ m_colors[0] = &m_background_color;
+ m_colors[1] = &m_border_color;
+ m_colors[2] = &m_curve_color;
+ m_colors[3] = &m_grid_color;
+ m_colors[4] = &m_inactive_pnt_color;
+ m_colors[5] = &m_active_pnt_color;
+ m_colors[6] = &m_text_color;
+ }
+
+ // Set colors
+ void background_color(const ColorT& c) { m_background_color = c; }
+ void border_color(const ColorT& c) { m_border_color = c; }
+ void curve_color(const ColorT& c) { m_curve_color = c; }
+ void grid_color(const ColorT& c) { m_grid_color = c; }
+ void inactive_pnt_color(const ColorT& c) { m_inactive_pnt_color = c; }
+ void active_pnt_color(const ColorT& c) { m_active_pnt_color = c; }
+ void text_color(const ColorT& c) { m_text_color = c; }
+ const ColorT& color(unsigned i) const { return *m_colors[i]; }
+
+ private:
+ gamma_ctrl(const gamma_ctrl<ColorT>&);
+ const gamma_ctrl<ColorT>& operator = (const gamma_ctrl<ColorT>&);
+
+ ColorT m_background_color;
+ ColorT m_border_color;
+ ColorT m_curve_color;
+ ColorT m_grid_color;
+ ColorT m_inactive_pnt_color;
+ ColorT m_active_pnt_color;
+ ColorT m_text_color;
+ ColorT* m_colors[7];
+ };
+
+
+}
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_gamma_spline.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_gamma_spline.h
new file mode 100644
index 0000000000..4f21710d9f
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_gamma_spline.h
@@ -0,0 +1,95 @@
+//----------------------------------------------------------------------------
+// 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
+//----------------------------------------------------------------------------
+//
+// class gamma_spline
+//
+//----------------------------------------------------------------------------
+
+#ifndef AGG_GAMMA_SPLINE_INCLUDED
+#define AGG_GAMMA_SPLINE_INCLUDED
+
+#include "agg_basics.h"
+#include "agg_bspline.h"
+
+namespace agg
+{
+
+ //------------------------------------------------------------------------
+ // Class-helper for calculation gamma-correction arrays. A gamma-correction
+ // array is an array of 256 unsigned chars that determine the actual values
+ // of Anti-Aliasing for each pixel coverage value from 0 to 255. If all the
+ // values in the array are equal to its index, i.e. 0,1,2,3,... there's
+ // no gamma-correction. Class agg::polyfill allows you to use custom
+ // gamma-correction arrays. You can calculate it using any approach, and
+ // class gamma_spline allows you to calculate almost any reasonable shape
+ // of the gamma-curve with using only 4 values - kx1, ky1, kx2, ky2.
+ //
+ // kx2
+ // +----------------------------------+
+ // | | | . |
+ // | | | . | ky2
+ // | | . ------|
+ // | | . |
+ // | | . |
+ // |----------------.|----------------|
+ // | . | |
+ // | . | |
+ // |-------. | |
+ // ky1 | . | | |
+ // | . | | |
+ // +----------------------------------+
+ // kx1
+ //
+ // Each value can be in range [0...2]. Value 1.0 means one quarter of the
+ // bounding rectangle. Function values() calculates the curve by these
+ // 4 values. After calling it one can get the gamma-array with call gamma().
+ // Class also supports the vertex source interface, i.e rewind() and
+ // vertex(). It's made for convinience and used in class gamma_ctrl.
+ // Before calling rewind/vertex one must set the bounding box
+ // box() using pixel coordinates.
+ //------------------------------------------------------------------------
+
+ class gamma_spline
+ {
+ public:
+ gamma_spline();
+
+ void values(double kx1, double ky1, double kx2, double ky2);
+ const unsigned char* gamma() const { return m_gamma; }
+ double y(double x) const;
+ void values(double* kx1, double* ky1, double* kx2, double* ky2) const;
+ void box(double x1, double y1, double x2, double y2);
+
+ void rewind(unsigned);
+ unsigned vertex(double* x, double* y);
+
+ private:
+ unsigned char m_gamma[256];
+ double m_x[4];
+ double m_y[4];
+ bspline m_spline;
+ double m_x1;
+ double m_y1;
+ double m_x2;
+ double m_y2;
+ double m_cur_x;
+ };
+
+
+
+
+}
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_polygon_ctrl.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_polygon_ctrl.h
new file mode 100644
index 0000000000..6f465d96b8
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_polygon_ctrl.h
@@ -0,0 +1,166 @@
+//----------------------------------------------------------------------------
+// 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
+//----------------------------------------------------------------------------
+//
+// classes polygon_ctrl_impl, polygon_ctrl
+//
+//----------------------------------------------------------------------------
+
+#ifndef POLYGON_CTRL_INCLUDED
+#define POLYGON_CTRL_INCLUDED
+
+#include "agg_array.h"
+#include "agg_conv_stroke.h"
+#include "agg_ellipse.h"
+#include "agg_color_rgba.h"
+#include "agg_ctrl.h"
+
+namespace agg
+{
+ class simple_polygon_vertex_source
+ {
+ public:
+ simple_polygon_vertex_source(const double* polygon, unsigned np,
+ bool roundoff = false,
+ bool close = true) :
+ m_polygon(polygon),
+ m_num_points(np),
+ m_vertex(0),
+ m_roundoff(roundoff),
+ m_close(close)
+ {
+ }
+
+ void close(bool f) { m_close = f; }
+ bool close() const { return m_close; }
+
+ void rewind(unsigned)
+ {
+ m_vertex = 0;
+ }
+
+ unsigned vertex(double* x, double* y)
+ {
+ if(m_vertex > m_num_points) return path_cmd_stop;
+ if(m_vertex == m_num_points)
+ {
+ ++m_vertex;
+ return path_cmd_end_poly | (m_close ? path_flags_close : 0);
+ }
+ *x = m_polygon[m_vertex * 2];
+ *y = m_polygon[m_vertex * 2 + 1];
+ if(m_roundoff)
+ {
+ *x = floor(*x) + 0.5;
+ *y = floor(*y) + 0.5;
+ }
+ ++m_vertex;
+ return (m_vertex == 1) ? path_cmd_move_to : path_cmd_line_to;
+ }
+
+ private:
+ const double* m_polygon;
+ unsigned m_num_points;
+ unsigned m_vertex;
+ bool m_roundoff;
+ bool m_close;
+ };
+
+
+
+
+ class polygon_ctrl_impl : public ctrl
+ {
+ public:
+ polygon_ctrl_impl(unsigned np, double point_radius=5);
+
+ unsigned num_points() const { return m_num_points; }
+ double xn(unsigned n) const { return m_polygon[n * 2]; }
+ double yn(unsigned n) const { return m_polygon[n * 2 + 1]; }
+ double& xn(unsigned n) { return m_polygon[n * 2]; }
+ double& yn(unsigned n) { return m_polygon[n * 2 + 1]; }
+
+ const double* polygon() const { return &m_polygon[0]; }
+
+ void line_width(double w) { m_stroke.width(w); }
+ double line_width() const { return m_stroke.width(); }
+
+ void point_radius(double r) { m_point_radius = r; }
+ double point_radius() const { return m_point_radius; }
+
+ void in_polygon_check(bool f) { m_in_polygon_check = f; }
+ bool in_polygon_check() const { return m_in_polygon_check; }
+
+ void close(bool f) { m_vs.close(f); }
+ bool close() const { return m_vs.close(); }
+
+ // Vertex source interface
+ unsigned num_paths() { return 1; }
+ void rewind(unsigned path_id);
+ unsigned vertex(double* x, double* y);
+
+ virtual bool in_rect(double x, double y) const;
+ virtual bool on_mouse_button_down(double x, double y);
+ virtual bool on_mouse_button_up(double x, double y);
+ virtual bool on_mouse_move(double x, double y, bool button_flag);
+ virtual bool on_arrow_keys(bool left, bool right, bool down, bool up);
+
+
+ private:
+ bool check_edge(unsigned i, double x, double y) const;
+ bool point_in_polygon(double x, double y) const;
+
+ pod_array<double> m_polygon;
+ unsigned m_num_points;
+ int m_node;
+ int m_edge;
+ simple_polygon_vertex_source m_vs;
+ conv_stroke<simple_polygon_vertex_source> m_stroke;
+ ellipse m_ellipse;
+ double m_point_radius;
+ unsigned m_status;
+ double m_dx;
+ double m_dy;
+ bool m_in_polygon_check;
+ };
+
+
+
+ //----------------------------------------------------------polygon_ctrl
+ template<class ColorT> class polygon_ctrl : public polygon_ctrl_impl
+ {
+ public:
+ polygon_ctrl(unsigned np, double point_radius=5) :
+ polygon_ctrl_impl(np, point_radius),
+ m_color(rgba(0.0, 0.0, 0.0))
+ {
+ }
+
+ void line_color(const ColorT& c) { m_color = c; }
+ const ColorT& color(unsigned i) const { return m_color; }
+
+ private:
+ polygon_ctrl(const polygon_ctrl<ColorT>&);
+ const polygon_ctrl<ColorT>& operator = (const polygon_ctrl<ColorT>&);
+
+ ColorT m_color;
+ };
+
+
+
+
+}
+
+#endif
+
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_rbox_ctrl.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_rbox_ctrl.h
new file mode 100644
index 0000000000..4d47bccdbb
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_rbox_ctrl.h
@@ -0,0 +1,141 @@
+//----------------------------------------------------------------------------
+// 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
+//----------------------------------------------------------------------------
+//
+// classes rbox_ctrl_impl, rbox_ctrl
+//
+//----------------------------------------------------------------------------
+
+#ifndef AGG_RBOX_CTRL_INCLUDED
+#define AGG_RBOX_CTRL_INCLUDED
+
+#include "agg_array.h"
+#include "agg_ellipse.h"
+#include "agg_conv_stroke.h"
+#include "agg_gsv_text.h"
+#include "agg_trans_affine.h"
+#include "agg_color_rgba.h"
+#include "agg_ctrl.h"
+
+
+
+namespace agg
+{
+
+ //------------------------------------------------------------------------
+ class rbox_ctrl_impl : public ctrl
+ {
+ public:
+ rbox_ctrl_impl(double x1, double y1, double x2, double y2, bool flip_y=false);
+
+ void border_width(double t, double extra=0.0);
+ void text_thickness(double t) { m_text_thickness = t; }
+ void text_size(double h, double w=0.0);
+
+ void add_item(const char* text);
+ int cur_item() const { return m_cur_item; }
+ void cur_item(int i) { m_cur_item = i; }
+
+ virtual bool in_rect(double x, double y) const;
+ virtual bool on_mouse_button_down(double x, double y);
+ virtual bool on_mouse_button_up(double x, double y);
+ virtual bool on_mouse_move(double x, double y, bool button_flag);
+ virtual bool on_arrow_keys(bool left, bool right, bool down, bool up);
+
+ // Vertex soutce interface
+ unsigned num_paths() { return 5; };
+ void rewind(unsigned path_id);
+ unsigned vertex(double* x, double* y);
+
+ private:
+ void calc_rbox();
+
+ double m_border_width;
+ double m_border_extra;
+ double m_text_thickness;
+ double m_text_height;
+ double m_text_width;
+ pod_array<char> m_items[32];
+ unsigned m_num_items;
+ int m_cur_item;
+
+ double m_xs1;
+ double m_ys1;
+ double m_xs2;
+ double m_ys2;
+
+ double m_vx[32];
+ double m_vy[32];
+ unsigned m_draw_item;
+ double m_dy;
+
+ ellipse m_ellipse;
+ conv_stroke<ellipse> m_ellipse_poly;
+ gsv_text m_text;
+ conv_stroke<gsv_text> m_text_poly;
+
+ unsigned m_idx;
+ unsigned m_vertex;
+ };
+
+
+
+ //------------------------------------------------------------------------
+ template<class ColorT> class rbox_ctrl : public rbox_ctrl_impl
+ {
+ public:
+ rbox_ctrl(double x1, double y1, double x2, double y2, bool flip_y=false) :
+ rbox_ctrl_impl(x1, y1, x2, y2, flip_y),
+ m_background_color(rgba(1.0, 1.0, 0.9)),
+ m_border_color(rgba(0.0, 0.0, 0.0)),
+ m_text_color(rgba(0.0, 0.0, 0.0)),
+ m_inactive_color(rgba(0.0, 0.0, 0.0)),
+ m_active_color(rgba(0.4, 0.0, 0.0))
+ {
+ m_colors[0] = &m_background_color;
+ m_colors[1] = &m_border_color;
+ m_colors[2] = &m_text_color;
+ m_colors[3] = &m_inactive_color;
+ m_colors[4] = &m_active_color;
+ }
+
+
+ void background_color(const ColorT& c) { m_background_color = c; }
+ void border_color(const ColorT& c) { m_border_color = c; }
+ void text_color(const ColorT& c) { m_text_color = c; }
+ void inactive_color(const ColorT& c) { m_inactive_color = c; }
+ void active_color(const ColorT& c) { m_active_color = c; }
+
+ const ColorT& color(unsigned i) const { return *m_colors[i]; }
+
+ private:
+ rbox_ctrl(const rbox_ctrl<ColorT>&);
+ const rbox_ctrl<ColorT>& operator = (const rbox_ctrl<ColorT>&);
+
+ ColorT m_background_color;
+ ColorT m_border_color;
+ ColorT m_text_color;
+ ColorT m_inactive_color;
+ ColorT m_active_color;
+ ColorT* m_colors[5];
+ };
+
+
+
+}
+
+
+
+#endif
+
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_scale_ctrl.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_scale_ctrl.h
new file mode 100644
index 0000000000..b1e32c2037
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_scale_ctrl.h
@@ -0,0 +1,146 @@
+//----------------------------------------------------------------------------
+// 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
+//----------------------------------------------------------------------------
+//
+// classes scale_ctrl_impl, scale_ctrl
+//
+//----------------------------------------------------------------------------
+
+#ifndef AGG_SCALE_CTRL_INCLUDED
+#define AGG_SCALE_CTRL_INCLUDED
+
+#include "agg_basics.h"
+#include "agg_math.h"
+#include "agg_ellipse.h"
+#include "agg_trans_affine.h"
+#include "agg_color_rgba.h"
+#include "agg_ctrl.h"
+
+
+namespace agg
+{
+
+ //------------------------------------------------------------------------
+ class scale_ctrl_impl : public ctrl
+ {
+ enum move_e
+ {
+ move_nothing,
+ move_value1,
+ move_value2,
+ move_slider
+ };
+
+ public:
+ scale_ctrl_impl(double x1, double y1, double x2, double y2, bool flip_y=false);
+
+ void border_thickness(double t, double extra=0.0);
+ void resize(double x1, double y1, double x2, double y2);
+
+ double min_delta() const { return m_min_d; }
+ void min_delta(double d) { m_min_d = d; }
+
+ double value1() const { return m_value1; }
+ void value1(double value);
+
+ double value2() const { return m_value2; }
+ void value2(double value);
+
+ void move(double d);
+
+ virtual bool in_rect(double x, double y) const;
+ virtual bool on_mouse_button_down(double x, double y);
+ virtual bool on_mouse_button_up(double x, double y);
+ virtual bool on_mouse_move(double x, double y, bool button_flag);
+ virtual bool on_arrow_keys(bool left, bool right, bool down, bool up);
+
+ // Vertex soutce interface
+ unsigned num_paths() { return 5; };
+ void rewind(unsigned path_id);
+ unsigned vertex(double* x, double* y);
+
+ private:
+ void calc_box();
+
+ double m_border_thickness;
+ double m_border_extra;
+ double m_value1;
+ double m_value2;
+ double m_min_d;
+ double m_xs1;
+ double m_ys1;
+ double m_xs2;
+ double m_ys2;
+ double m_pdx;
+ double m_pdy;
+ move_e m_move_what;
+ double m_vx[32];
+ double m_vy[32];
+
+ ellipse m_ellipse;
+
+ unsigned m_idx;
+ unsigned m_vertex;
+
+ };
+
+
+
+ //------------------------------------------------------------------------
+ template<class ColorT> class scale_ctrl : public scale_ctrl_impl
+ {
+ public:
+ scale_ctrl(double x1, double y1, double x2, double y2, bool flip_y=false) :
+ scale_ctrl_impl(x1, y1, x2, y2, flip_y),
+ m_background_color(rgba(1.0, 0.9, 0.8)),
+ m_border_color(rgba(0.0, 0.0, 0.0)),
+ m_pointers_color(rgba(0.8, 0.0, 0.0, 0.8)),
+ m_slider_color(rgba(0.2, 0.1, 0.0, 0.6))
+ {
+ m_colors[0] = &m_background_color;
+ m_colors[1] = &m_border_color;
+ m_colors[2] = &m_pointers_color;
+ m_colors[3] = &m_pointers_color;
+ m_colors[4] = &m_slider_color;
+ }
+
+
+ void background_color(const ColorT& c) { m_background_color = c; }
+ void border_color(const ColorT& c) { m_border_color = c; }
+ void pointers_color(const ColorT& c) { m_pointers_color = c; }
+ void slider_color(const ColorT& c) { m_slider_color = c; }
+
+ const ColorT& color(unsigned i) const { return *m_colors[i]; }
+
+ private:
+ scale_ctrl(const scale_ctrl<ColorT>&);
+ const scale_ctrl<ColorT>& operator = (const scale_ctrl<ColorT>&);
+
+ ColorT m_background_color;
+ ColorT m_border_color;
+ ColorT m_pointers_color;
+ ColorT m_slider_color;
+ ColorT* m_colors[5];
+ };
+
+
+
+
+
+}
+
+
+
+#endif
+
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_slider_ctrl.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_slider_ctrl.h
new file mode 100644
index 0000000000..b50a95c59d
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_slider_ctrl.h
@@ -0,0 +1,150 @@
+//----------------------------------------------------------------------------
+// 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
+//----------------------------------------------------------------------------
+//
+// classes slider_ctrl_impl, slider_ctrl
+//
+//----------------------------------------------------------------------------
+
+#ifndef AGG_SLIDER_CTRL_INCLUDED
+#define AGG_SLIDER_CTRL_INCLUDED
+
+#include "agg_basics.h"
+#include "agg_math.h"
+#include "agg_ellipse.h"
+#include "agg_trans_affine.h"
+#include "agg_color_rgba.h"
+#include "agg_gsv_text.h"
+#include "agg_conv_stroke.h"
+#include "agg_path_storage.h"
+#include "agg_ctrl.h"
+
+
+namespace agg
+{
+
+ //--------------------------------------------------------slider_ctrl_impl
+ class slider_ctrl_impl : public ctrl
+ {
+ public:
+ slider_ctrl_impl(double x1, double y1, double x2, double y2, bool flip_y=false);
+
+ void border_width(double t, double extra=0.0);
+
+ void range(double min, double max) { m_min = min; m_max = max; }
+ void num_steps(unsigned num) { m_num_steps = num; }
+ void label(const char* fmt);
+ void text_thickness(double t) { m_text_thickness = t; }
+
+ bool descending() const { return m_descending; }
+ void descending(bool v) { m_descending = v; }
+
+ double value() const { return m_value * (m_max - m_min) + m_min; }
+ void value(double value);
+
+ virtual bool in_rect(double x, double y) const;
+ virtual bool on_mouse_button_down(double x, double y);
+ virtual bool on_mouse_button_up(double x, double y);
+ virtual bool on_mouse_move(double x, double y, bool button_flag);
+ virtual bool on_arrow_keys(bool left, bool right, bool down, bool up);
+
+ // Vertex source interface
+ unsigned num_paths() { return 6; };
+ void rewind(unsigned path_id);
+ unsigned vertex(double* x, double* y);
+
+ private:
+ void calc_box();
+ bool normalize_value(bool preview_value_flag);
+
+ double m_border_width;
+ double m_border_extra;
+ double m_text_thickness;
+ double m_value;
+ double m_preview_value;
+ double m_min;
+ double m_max;
+ unsigned m_num_steps;
+ bool m_descending;
+ char m_label[64];
+ double m_xs1;
+ double m_ys1;
+ double m_xs2;
+ double m_ys2;
+ double m_pdx;
+ bool m_mouse_move;
+ double m_vx[32];
+ double m_vy[32];
+
+ ellipse m_ellipse;
+
+ unsigned m_idx;
+ unsigned m_vertex;
+
+ gsv_text m_text;
+ conv_stroke<gsv_text> m_text_poly;
+ path_storage m_storage;
+
+ };
+
+
+
+ //----------------------------------------------------------slider_ctrl
+ template<class ColorT> class slider_ctrl : public slider_ctrl_impl
+ {
+ public:
+ slider_ctrl(double x1, double y1, double x2, double y2, bool flip_y=false) :
+ slider_ctrl_impl(x1, y1, x2, y2, flip_y),
+ m_background_color(rgba(1.0, 0.9, 0.8)),
+ m_triangle_color(rgba(0.7, 0.6, 0.6)),
+ m_text_color(rgba(0.0, 0.0, 0.0)),
+ m_pointer_preview_color(rgba(0.6, 0.4, 0.4, 0.4)),
+ m_pointer_color(rgba(0.8, 0.0, 0.0, 0.6))
+ {
+ m_colors[0] = &m_background_color;
+ m_colors[1] = &m_triangle_color;
+ m_colors[2] = &m_text_color;
+ m_colors[3] = &m_pointer_preview_color;
+ m_colors[4] = &m_pointer_color;
+ m_colors[5] = &m_text_color;
+ }
+
+
+ void background_color(const ColorT& c) { m_background_color = c; }
+ void pointer_color(const ColorT& c) { m_pointer_color = c; }
+
+ const ColorT& color(unsigned i) const { return *m_colors[i]; }
+
+ private:
+ slider_ctrl(const slider_ctrl<ColorT>&);
+ const slider_ctrl<ColorT>& operator = (const slider_ctrl<ColorT>&);
+
+ ColorT m_background_color;
+ ColorT m_triangle_color;
+ ColorT m_text_color;
+ ColorT m_pointer_preview_color;
+ ColorT m_pointer_color;
+ ColorT* m_colors[6];
+ };
+
+
+
+
+
+}
+
+
+
+#endif
+
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_spline_ctrl.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_spline_ctrl.h
new file mode 100644
index 0000000000..8477f27d78
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/ctrl/agg_spline_ctrl.h
@@ -0,0 +1,159 @@
+//----------------------------------------------------------------------------
+// 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
+//----------------------------------------------------------------------------
+//
+// classes spline_ctrl_impl, spline_ctrl
+//
+//----------------------------------------------------------------------------
+
+#ifndef AGG_SPLINE_CTRL_INCLUDED
+#define AGG_SPLINE_CTRL_INCLUDED
+
+#include "agg_basics.h"
+#include "agg_ellipse.h"
+#include "agg_bspline.h"
+#include "agg_conv_stroke.h"
+#include "agg_path_storage.h"
+#include "agg_trans_affine.h"
+#include "agg_color_rgba.h"
+#include "agg_ctrl.h"
+
+namespace agg
+{
+
+ //------------------------------------------------------------------------
+ // Class that can be used to create an interactive control to set up
+ // gamma arrays.
+ //------------------------------------------------------------------------
+ class spline_ctrl_impl : public ctrl
+ {
+ public:
+ spline_ctrl_impl(double x1, double y1, double x2, double y2,
+ unsigned num_pnt, bool flip_y=false);
+
+ // Set other parameters
+ void border_width(double t, double extra=0.0);
+ void curve_width(double t) { m_curve_width = t; }
+ void point_size(double s) { m_point_size = s; }
+
+ // Event handlers. Just call them if the respective events
+ // in your system occure. The functions return true if redrawing
+ // is required.
+ virtual bool in_rect(double x, double y) const;
+ virtual bool on_mouse_button_down(double x, double y);
+ virtual bool on_mouse_button_up(double x, double y);
+ virtual bool on_mouse_move(double x, double y, bool button_flag);
+ virtual bool on_arrow_keys(bool left, bool right, bool down, bool up);
+
+ void active_point(int i);
+
+ const double* spline() const { return m_spline_values; }
+ const int8u* spline8() const { return m_spline_values8; }
+ double value(double x) const;
+ void value(unsigned idx, double y);
+ void point(unsigned idx, double x, double y);
+ void x(unsigned idx, double x) { m_xp[idx] = x; }
+ void y(unsigned idx, double y) { m_yp[idx] = y; }
+ double x(unsigned idx) const { return m_xp[idx]; }
+ double y(unsigned idx) const { return m_yp[idx]; }
+ void update_spline();
+
+ // Vertex soutce interface
+ unsigned num_paths() { return 5; }
+ void rewind(unsigned path_id);
+ unsigned vertex(double* x, double* y);
+
+ private:
+ void calc_spline_box();
+ void calc_curve();
+ double calc_xp(unsigned idx);
+ double calc_yp(unsigned idx);
+ void set_xp(unsigned idx, double val);
+ void set_yp(unsigned idx, double val);
+
+ unsigned m_num_pnt;
+ double m_xp[32];
+ double m_yp[32];
+ bspline m_spline;
+ double m_spline_values[256];
+ int8u m_spline_values8[256];
+ double m_border_width;
+ double m_border_extra;
+ double m_curve_width;
+ double m_point_size;
+ double m_xs1;
+ double m_ys1;
+ double m_xs2;
+ double m_ys2;
+ path_storage m_curve_pnt;
+ conv_stroke<path_storage> m_curve_poly;
+ ellipse m_ellipse;
+ unsigned m_idx;
+ unsigned m_vertex;
+ double m_vx[32];
+ double m_vy[32];
+ int m_active_pnt;
+ int m_move_pnt;
+ double m_pdx;
+ double m_pdy;
+ const trans_affine* m_mtx;
+ };
+
+
+ template<class ColorT> class spline_ctrl : public spline_ctrl_impl
+ {
+ public:
+ spline_ctrl(double x1, double y1, double x2, double y2,
+ unsigned num_pnt, bool flip_y=false) :
+ spline_ctrl_impl(x1, y1, x2, y2, num_pnt, flip_y),
+ m_background_color(rgba(1.0, 1.0, 0.9)),
+ m_border_color(rgba(0.0, 0.0, 0.0)),
+ m_curve_color(rgba(0.0, 0.0, 0.0)),
+ m_inactive_pnt_color(rgba(0.0, 0.0, 0.0)),
+ m_active_pnt_color(rgba(1.0, 0.0, 0.0))
+ {
+ m_colors[0] = &m_background_color;
+ m_colors[1] = &m_border_color;
+ m_colors[2] = &m_curve_color;
+ m_colors[3] = &m_inactive_pnt_color;
+ m_colors[4] = &m_active_pnt_color;
+ }
+
+ // Set colors
+ void background_color(const ColorT& c) { m_background_color = c; }
+ void border_color(const ColorT& c) { m_border_color = c; }
+ void curve_color(const ColorT& c) { m_curve_color = c; }
+ void inactive_pnt_color(const ColorT& c) { m_inactive_pnt_color = c; }
+ void active_pnt_color(const ColorT& c) { m_active_pnt_color = c; }
+ const ColorT& color(unsigned i) const { return *m_colors[i]; }
+
+ private:
+ spline_ctrl(const spline_ctrl<ColorT>&);
+ const spline_ctrl<ColorT>& operator = (const spline_ctrl<ColorT>&);
+
+ ColorT m_background_color;
+ ColorT m_border_color;
+ ColorT m_curve_color;
+ ColorT m_inactive_pnt_color;
+ ColorT m_active_pnt_color;
+ ColorT* m_colors[5];
+ };
+
+
+
+
+}
+
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/platform/agg_platform_support.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/platform/agg_platform_support.h
new file mode 100644
index 0000000000..9a63411e50
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/platform/agg_platform_support.h
@@ -0,0 +1,686 @@
+//----------------------------------------------------------------------------
+// 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
+//----------------------------------------------------------------------------
+//
+// class platform_support
+//
+// It's not a part of the AGG library, it's just a helper class to create
+// interactive demo examples. Since the examples should not be too complex
+// this class is provided to support some very basic interactive graphical
+// functionality, such as putting the rendered image to the window, simple
+// keyboard and mouse input, window resizing, setting the window title,
+// and catching the "idle" events.
+//
+// The idea is to have a single header file that does not depend on any
+// platform (I hate these endless #ifdef/#elif/#elif.../#endif) and a number
+// of different implementations depending on the concrete platform.
+// The most popular platforms are:
+//
+// Windows-32 API
+// X-Window API
+// SDL library (see http://www.libsdl.org/)
+// MacOS C/C++ API
+//
+// This file does not include any system dependent .h files such as
+// windows.h or X11.h, so, your demo applications do not depend on the
+// platform. The only file that can #include system dependend headers
+// is the implementation file agg_platform_support.cpp. Different
+// implementations are placed in different directories, such as
+// ~/agg/src/platform/win32
+// ~/agg/src/platform/sdl
+// ~/agg/src/platform/X11
+// and so on.
+//
+// All the system dependent stuff sits in the platform_specific
+// class which is forward-declared here but not defined.
+// The platform_support class has just a pointer to it and it's
+// the responsibility of the implementation to create/delete it.
+// This class being defined in the implementation file can have
+// any platform dependent stuff such as HWND, X11 Window and so on.
+//
+//----------------------------------------------------------------------------
+
+
+#ifndef AGG_PLATFORM_SUPPORT_INCLUDED
+#define AGG_PLATFORM_SUPPORT_INCLUDED
+
+
+#include "agg_basics.h"
+#include "agg_rendering_buffer.h"
+#include "agg_trans_viewport.h"
+#include "ctrl/agg_ctrl.h"
+
+namespace agg
+{
+
+ //----------------------------------------------------------window_flag_e
+ // These are flags used in method init(). Not all of them are
+ // applicable on different platforms, for example the win32_api
+ // cannot use a hardware buffer (window_hw_buffer).
+ // The implementation should simply ignore unsupported flags.
+ enum window_flag_e
+ {
+ window_resize = 1,
+ window_hw_buffer = 2,
+ window_keep_aspect_ratio = 4,
+ window_process_all_keys = 8
+ };
+
+ //-----------------------------------------------------------pix_format_e
+ // Possible formats of the rendering buffer. Initially I thought that it's
+ // reasonable to create the buffer and the rendering functions in
+ // accordance with the native pixel format of the system because it
+ // would have no overhead for pixel format conersion.
+ // But eventually I came to a conclusion that having a possibility to
+ // convert pixel formats on demand is a good idea. First, it was X11 where
+ // there lots of different formats and visuals and it would be great to
+ // render everything in, say, RGB-24 and display it automatically without
+ // any additional efforts. The second reason is to have a possibility to
+ // debug renderers for different pixel formats and colorspaces having only
+ // one computer and one system.
+ //
+ // This stuff is not included into the basic AGG functionality because the
+ // number of supported pixel formats (and/or colorspaces) can be great and
+ // if one needs to add new format it would be good only to add new
+ // rendering files without having to modify any existing ones (a general
+ // principle of incapsulation and isolation).
+ //
+ // Using a particular pixel format doesn't obligatory mean the necessity
+ // of software conversion. For example, win32 API can natively display
+ // gray8, 15-bit RGB, 24-bit BGR, and 32-bit BGRA formats.
+ // This list can be (and will be!) extended in future.
+ enum pix_format_e
+ {
+ pix_format_undefined = 0, // By default. No conversions are applied
+ pix_format_bw, // 1 bit per color B/W
+ pix_format_gray8, // Simple 256 level grayscale
+ pix_format_sgray8, // Simple 256 level grayscale (sRGB)
+ pix_format_gray16, // Simple 65535 level grayscale
+ pix_format_gray32, // Grayscale, one 32-bit float per pixel
+ pix_format_rgb555, // 15 bit rgb. Depends on the byte ordering!
+ pix_format_rgb565, // 16 bit rgb. Depends on the byte ordering!
+ pix_format_rgbAAA, // 30 bit rgb. Depends on the byte ordering!
+ pix_format_rgbBBA, // 32 bit rgb. Depends on the byte ordering!
+ pix_format_bgrAAA, // 30 bit bgr. Depends on the byte ordering!
+ pix_format_bgrABB, // 32 bit bgr. Depends on the byte ordering!
+ pix_format_rgb24, // R-G-B, one byte per color component
+ pix_format_srgb24, // R-G-B, one byte per color component (sRGB)
+ pix_format_bgr24, // B-G-R, one byte per color component
+ pix_format_sbgr24, // B-G-R, native win32 BMP format (sRGB)
+ pix_format_rgba32, // R-G-B-A, one byte per color component
+ pix_format_srgba32, // R-G-B-A, one byte per color component (sRGB)
+ pix_format_argb32, // A-R-G-B, native MAC format
+ pix_format_sargb32, // A-R-G-B, native MAC format (sRGB)
+ pix_format_abgr32, // A-B-G-R, one byte per color component
+ pix_format_sabgr32, // A-B-G-R, one byte per color component (sRGB)
+ pix_format_bgra32, // B-G-R-A, native win32 BMP format
+ pix_format_sbgra32, // B-G-R-A, native win32 BMP format (sRGB)
+ pix_format_rgb48, // R-G-B, 16 bits per color component
+ pix_format_bgr48, // B-G-R, native win32 BMP format.
+ pix_format_rgb96, // R-G-B, one 32-bit float per color component
+ pix_format_bgr96, // B-G-R, one 32-bit float per color component
+ pix_format_rgba64, // R-G-B-A, 16 bits byte per color component
+ pix_format_argb64, // A-R-G-B, native MAC format
+ pix_format_abgr64, // A-B-G-R, one byte per color component
+ pix_format_bgra64, // B-G-R-A, native win32 BMP format
+ pix_format_rgba128, // R-G-B-A, one 32-bit float per color component
+ pix_format_argb128, // A-R-G-B, one 32-bit float per color component
+ pix_format_abgr128, // A-B-G-R, one 32-bit float per color component
+ pix_format_bgra128, // B-G-R-A, one 32-bit float per color component
+
+ end_of_pix_formats
+ };
+
+ //-------------------------------------------------------------input_flag_e
+ // Mouse and keyboard flags. They can be different on different platforms
+ // and the ways they are obtained are also different. But in any case
+ // the system dependent flags should be mapped into these ones. The meaning
+ // of that is as follows. For example, if kbd_ctrl is set it means that the
+ // ctrl key is pressed and being held at the moment. They are also used in
+ // the overridden methods such as on_mouse_move(), on_mouse_button_down(),
+ // on_mouse_button_dbl_click(), on_mouse_button_up(), on_key().
+ // In the method on_mouse_button_up() the mouse flags have different
+ // meaning. They mean that the respective button is being released, but
+ // the meaning of the keyboard flags remains the same.
+ // There's absolut minimal set of flags is used because they'll be most
+ // probably supported on different platforms. Even the mouse_right flag
+ // is restricted because Mac's mice have only one button, but AFAIK
+ // it can be simulated with holding a special key on the keydoard.
+ enum input_flag_e
+ {
+ mouse_left = 1,
+ mouse_right = 2,
+ kbd_shift = 4,
+ kbd_ctrl = 8
+ };
+
+ //--------------------------------------------------------------key_code_e
+ // Keyboard codes. There's also a restricted set of codes that are most
+ // probably supported on different platforms. Any platform dependent codes
+ // should be converted into these ones. There're only those codes are
+ // defined that cannot be represented as printable ASCII-characters.
+ // All printable ASCII-set can be used in a regular C/C++ manner:
+ // ' ', 'A', '0' '+' and so on.
+ // Since the class is used for creating very simple demo-applications
+ // we don't need very rich possibilities here, just basic ones.
+ // Actually the numeric key codes are taken from the SDL library, so,
+ // the implementation of the SDL support does not require any mapping.
+ enum key_code_e
+ {
+ // ASCII set. Should be supported everywhere
+ key_backspace = 8,
+ key_tab = 9,
+ key_clear = 12,
+ key_return = 13,
+ key_pause = 19,
+ key_escape = 27,
+
+ // Keypad
+ key_delete = 127,
+ key_kp0 = 256,
+ key_kp1 = 257,
+ key_kp2 = 258,
+ key_kp3 = 259,
+ key_kp4 = 260,
+ key_kp5 = 261,
+ key_kp6 = 262,
+ key_kp7 = 263,
+ key_kp8 = 264,
+ key_kp9 = 265,
+ key_kp_period = 266,
+ key_kp_divide = 267,
+ key_kp_multiply = 268,
+ key_kp_minus = 269,
+ key_kp_plus = 270,
+ key_kp_enter = 271,
+ key_kp_equals = 272,
+
+ // Arrow-keys and stuff
+ key_up = 273,
+ key_down = 274,
+ key_right = 275,
+ key_left = 276,
+ key_insert = 277,
+ key_home = 278,
+ key_end = 279,
+ key_page_up = 280,
+ key_page_down = 281,
+
+ // Functional keys. You'd better avoid using
+ // f11...f15 in your applications if you want
+ // the applications to be portable
+ key_f1 = 282,
+ key_f2 = 283,
+ key_f3 = 284,
+ key_f4 = 285,
+ key_f5 = 286,
+ key_f6 = 287,
+ key_f7 = 288,
+ key_f8 = 289,
+ key_f9 = 290,
+ key_f10 = 291,
+ key_f11 = 292,
+ key_f12 = 293,
+ key_f13 = 294,
+ key_f14 = 295,
+ key_f15 = 296,
+
+ // The possibility of using these keys is
+ // very restricted. Actually it's guaranteed
+ // only in win32_api and win32_sdl implementations
+ key_numlock = 300,
+ key_capslock = 301,
+ key_scrollock = 302,
+
+ // Phew!
+ end_of_key_codes
+ };
+
+
+ //------------------------------------------------------------------------
+ // A predeclaration of the platform dependent class. Since we do not
+ // know anything here the only we can have is just a pointer to this
+ // class as a data member. It should be created and destroyed explicitly
+ // in the constructor/destructor of the platform_support class.
+ // Although the pointer to platform_specific is public the application
+ // cannot have access to its members or methods since it does not know
+ // anything about them and it's a perfect incapsulation :-)
+ class platform_specific;
+
+
+ //----------------------------------------------------------ctrl_container
+ // A helper class that contains pointers to a number of controls.
+ // This class is used to ease the event handling with controls.
+ // The implementation should simply call the appropriate methods
+ // of this class when appropriate events occur.
+ class ctrl_container
+ {
+ enum max_ctrl_e { max_ctrl = 64 };
+
+ public:
+ //--------------------------------------------------------------------
+ ctrl_container() : m_num_ctrl(0), m_cur_ctrl(-1) {}
+
+ //--------------------------------------------------------------------
+ void add(ctrl& c)
+ {
+ if(m_num_ctrl < max_ctrl)
+ {
+ m_ctrl[m_num_ctrl++] = &c;
+ }
+ }
+
+ //--------------------------------------------------------------------
+ bool in_rect(double x, double y)
+ {
+ unsigned i;
+ for(i = 0; i < m_num_ctrl; i++)
+ {
+ if(m_ctrl[i]->in_rect(x, y)) return true;
+ }
+ return false;
+ }
+
+ //--------------------------------------------------------------------
+ bool on_mouse_button_down(double x, double y)
+ {
+ unsigned i;
+ for(i = 0; i < m_num_ctrl; i++)
+ {
+ if(m_ctrl[i]->on_mouse_button_down(x, y)) return true;
+ }
+ return false;
+ }
+
+ //--------------------------------------------------------------------
+ bool on_mouse_button_up(double x, double y)
+ {
+ unsigned i;
+ bool flag = false;
+ for(i = 0; i < m_num_ctrl; i++)
+ {
+ if(m_ctrl[i]->on_mouse_button_up(x, y)) flag = true;
+ }
+ return flag;
+ }
+
+ //--------------------------------------------------------------------
+ bool on_mouse_move(double x, double y, bool button_flag)
+ {
+ unsigned i;
+ for(i = 0; i < m_num_ctrl; i++)
+ {
+ if(m_ctrl[i]->on_mouse_move(x, y, button_flag)) return true;
+ }
+ return false;
+ }
+
+ //--------------------------------------------------------------------
+ bool on_arrow_keys(bool left, bool right, bool down, bool up)
+ {
+ if(m_cur_ctrl >= 0)
+ {
+ return m_ctrl[m_cur_ctrl]->on_arrow_keys(left, right, down, up);
+ }
+ return false;
+ }
+
+ //--------------------------------------------------------------------
+ bool set_cur(double x, double y)
+ {
+ unsigned i;
+ for(i = 0; i < m_num_ctrl; i++)
+ {
+ if(m_ctrl[i]->in_rect(x, y))
+ {
+ if(m_cur_ctrl != int(i))
+ {
+ m_cur_ctrl = i;
+ return true;
+ }
+ return false;
+ }
+ }
+ if(m_cur_ctrl != -1)
+ {
+ m_cur_ctrl = -1;
+ return true;
+ }
+ return false;
+ }
+
+ private:
+ ctrl* m_ctrl[max_ctrl];
+ unsigned m_num_ctrl;
+ int m_cur_ctrl;
+ };
+
+
+
+ //---------------------------------------------------------platform_support
+ // This class is a base one to the apllication classes. It can be used
+ // as follows:
+ //
+ // class the_application : public agg::platform_support
+ // {
+ // public:
+ // the_application(unsigned bpp, bool flip_y) :
+ // platform_support(bpp, flip_y)
+ // . . .
+ //
+ // //override stuff . . .
+ // virtual void on_init()
+ // {
+ // . . .
+ // }
+ //
+ // virtual void on_draw()
+ // {
+ // . . .
+ // }
+ //
+ // virtual void on_resize(int sx, int sy)
+ // {
+ // . . .
+ // }
+ // // . . . and so on, see virtual functions
+ //
+ //
+ // //any your own stuff . . .
+ // };
+ //
+ //
+ // int agg_main(int argc, char* argv[])
+ // {
+ // the_application app(pix_format_rgb24, true);
+ // app.caption("AGG Example. Lion");
+ //
+ // if(app.init(500, 400, agg::window_resize))
+ // {
+ // return app.run();
+ // }
+ // return 1;
+ // }
+ //
+ // The reason to have agg_main() instead of just main() is that SDL
+ // for Windows requires including SDL.h if you define main(). Since
+ // the demo applications cannot rely on any platform/library specific
+ // stuff it's impossible to include SDL.h into the application files.
+ // The demo applications are simple and their use is restricted, so,
+ // this approach is quite reasonable.
+ //
+ class platform_support
+ {
+ public:
+ enum max_images_e { max_images = 16 };
+
+ // format - see enum pix_format_e {};
+ // flip_y - true if you want to have the Y-axis flipped vertically.
+ platform_support(pix_format_e format, bool flip_y);
+ virtual ~platform_support();
+
+ // Setting the windows caption (title). Should be able
+ // to be called at least before calling init().
+ // It's perfect if they can be called anytime.
+ void caption(const char* cap);
+ const char* caption() const { return m_caption; }
+
+ //--------------------------------------------------------------------
+ // These 3 methods handle working with images. The image
+ // formats are the simplest ones, such as .BMP in Windows or
+ // .ppm in Linux. In the applications the names of the files
+ // should not have any file extensions. Method load_img() can
+ // be called before init(), so, the application could be able
+ // to determine the initial size of the window depending on
+ // the size of the loaded image.
+ // The argument "idx" is the number of the image 0...max_images-1
+ bool load_img(unsigned idx, const char* file);
+ bool save_img(unsigned idx, const char* file);
+ bool create_img(unsigned idx, unsigned width=0, unsigned height=0);
+
+ //--------------------------------------------------------------------
+ // init() and run(). See description before the class for details.
+ // The necessity of calling init() after creation is that it's
+ // impossible to call the overridden virtual function (on_init())
+ // from the constructor. On the other hand it's very useful to have
+ // some on_init() event handler when the window is created but
+ // not yet displayed. The rbuf_window() method (see below) is
+ // accessible from on_init().
+ bool init(unsigned width, unsigned height, unsigned flags);
+ int run();
+
+ //--------------------------------------------------------------------
+ // The very same parameters that were used in the constructor
+ pix_format_e format() const { return m_format; }
+ bool flip_y() const { return m_flip_y; }
+ unsigned bpp() const { return m_bpp; }
+
+ //--------------------------------------------------------------------
+ // The following provides a very simple mechanism of doing someting
+ // in background. It's not multithreading. When wait_mode is true
+ // the class waits for the events and it does not ever call on_idle().
+ // When it's false it calls on_idle() when the event queue is empty.
+ // The mode can be changed anytime. This mechanism is satisfactory
+ // to create very simple animations.
+ bool wait_mode() const { return m_wait_mode; }
+ void wait_mode(bool wait_mode) { m_wait_mode = wait_mode; }
+
+ //--------------------------------------------------------------------
+ // These two functions control updating of the window.
+ // force_redraw() is an analog of the Win32 InvalidateRect() function.
+ // Being called it sets a flag (or sends a message) which results
+ // in calling on_draw() and updating the content of the window
+ // when the next event cycle comes.
+ // update_window() results in just putting immediately the content
+ // of the currently rendered buffer to the window without calling
+ // on_draw().
+ void force_redraw();
+ void update_window();
+
+ //--------------------------------------------------------------------
+ // So, finally, how to draw anythig with AGG? Very simple.
+ // rbuf_window() returns a reference to the main rendering
+ // buffer which can be attached to any rendering class.
+ // rbuf_img() returns a reference to the previously created
+ // or loaded image buffer (see load_img()). The image buffers
+ // are not displayed directly, they should be copied to or
+ // combined somehow with the rbuf_window(). rbuf_window() is
+ // the only buffer that can be actually displayed.
+ rendering_buffer& rbuf_window() { return m_rbuf_window; }
+ rendering_buffer& rbuf_img(unsigned idx) { return m_rbuf_img[idx]; }
+
+
+ //--------------------------------------------------------------------
+ // Returns file extension used in the implementation for the particular
+ // system.
+ const char* img_ext() const;
+
+ //--------------------------------------------------------------------
+ void copy_img_to_window(unsigned idx)
+ {
+ if(idx < max_images && rbuf_img(idx).buf())
+ {
+ rbuf_window().copy_from(rbuf_img(idx));
+ }
+ }
+
+ //--------------------------------------------------------------------
+ void copy_window_to_img(unsigned idx)
+ {
+ if(idx < max_images)
+ {
+ create_img(idx, rbuf_window().width(), rbuf_window().height());
+ rbuf_img(idx).copy_from(rbuf_window());
+ }
+ }
+
+ //--------------------------------------------------------------------
+ void copy_img_to_img(unsigned idx_to, unsigned idx_from)
+ {
+ if(idx_from < max_images &&
+ idx_to < max_images &&
+ rbuf_img(idx_from).buf())
+ {
+ create_img(idx_to,
+ rbuf_img(idx_from).width(),
+ rbuf_img(idx_from).height());
+ rbuf_img(idx_to).copy_from(rbuf_img(idx_from));
+ }
+ }
+
+ //--------------------------------------------------------------------
+ // Event handlers. They are not pure functions, so you don't have
+ // to override them all.
+ // In my demo applications these functions are defined inside
+ // the the_application class (implicit inlining) which is in general
+ // very bad practice, I mean vitual inline methods. At least it does
+ // not make sense.
+ // But in this case it's quite appropriate bacause we have the only
+ // instance of the the_application class and it is in the same file
+ // where this class is defined.
+ virtual void on_init();
+ virtual void on_resize(int sx, int sy);
+ virtual void on_idle();
+ virtual void on_mouse_move(int x, int y, unsigned flags);
+ virtual void on_mouse_button_down(int x, int y, unsigned flags);
+ virtual void on_mouse_button_up(int x, int y, unsigned flags);
+ virtual void on_key(int x, int y, unsigned key, unsigned flags);
+ virtual void on_ctrl_change();
+ virtual void on_draw();
+ virtual void on_post_draw(void* raw_handler);
+
+ //--------------------------------------------------------------------
+ // Adding control elements. A control element once added will be
+ // working and reacting to the mouse and keyboard events. Still, you
+ // will have to render them in the on_draw() using function
+ // render_ctrl() because platform_support doesn't know anything about
+ // renderers you use. The controls will be also scaled automatically
+ // if they provide a proper scaling mechanism (all the controls
+ // included into the basic AGG package do).
+ // If you don't need a particular control to be scaled automatically
+ // call ctrl::no_transform() after adding.
+ void add_ctrl(ctrl& c) { m_ctrls.add(c); c.transform(m_resize_mtx); }
+
+ //--------------------------------------------------------------------
+ // Auxiliary functions. trans_affine_resizing() modifier sets up the resizing
+ // matrix on the basis of the given width and height and the initial
+ // width and height of the window. The implementation should simply
+ // call this function every time when it catches the resizing event
+ // passing in the new values of width and height of the window.
+ // Nothing prevents you from "cheating" the scaling matrix if you
+ // call this function from somewhere with wrong arguments.
+ // trans_affine_resizing() accessor simply returns current resizing matrix
+ // which can be used to apply additional scaling of any of your
+ // stuff when the window is being resized.
+ // width(), height(), initial_width(), and initial_height() must be
+ // clear to understand with no comments :-)
+ void trans_affine_resizing(int width, int height)
+ {
+ if(m_window_flags & window_keep_aspect_ratio)
+ {
+ //double sx = double(width) / double(m_initial_width);
+ //double sy = double(height) / double(m_initial_height);
+ //if(sy < sx) sx = sy;
+ //m_resize_mtx = trans_affine_scaling(sx, sx);
+ trans_viewport vp;
+ vp.preserve_aspect_ratio(0.5, 0.5, aspect_ratio_meet);
+ vp.device_viewport(0, 0, width, height);
+ vp.world_viewport(0, 0, m_initial_width, m_initial_height);
+ m_resize_mtx = vp.to_affine();
+ }
+ else
+ {
+ m_resize_mtx = trans_affine_scaling(
+ double(width) / double(m_initial_width),
+ double(height) / double(m_initial_height));
+ }
+ }
+ trans_affine& trans_affine_resizing() { return m_resize_mtx; }
+ const trans_affine& trans_affine_resizing() const { return m_resize_mtx; }
+ double width() const { return m_rbuf_window.width(); }
+ double height() const { return m_rbuf_window.height(); }
+ double initial_width() const { return m_initial_width; }
+ double initial_height() const { return m_initial_height; }
+ unsigned window_flags() const { return m_window_flags; }
+
+ //--------------------------------------------------------------------
+ // Get raw display handler depending on the system.
+ // For win32 its an HDC, for other systems it can be a pointer to some
+ // structure. See the implementation files for detals.
+ // It's provided "as is", so, first you should check if it's not null.
+ // If it's null the raw_display_handler is not supported. Also, there's
+ // no guarantee that this function is implemented, so, in some
+ // implementations you may have simply an unresolved symbol when linking.
+ void* raw_display_handler();
+
+ //--------------------------------------------------------------------
+ // display message box or print the message to the console
+ // (depending on implementation)
+ void message(const char* msg);
+
+ //--------------------------------------------------------------------
+ // Stopwatch functions. Function elapsed_time() returns time elapsed
+ // since the latest start_timer() invocation in millisecods.
+ // The resolutoin depends on the implementation.
+ // In Win32 it uses QueryPerformanceFrequency() / QueryPerformanceCounter().
+ void start_timer();
+ double elapsed_time() const;
+
+ //--------------------------------------------------------------------
+ // Get the full file name. In most cases it simply returns
+ // file_name. As it's appropriate in many systems if you open
+ // a file by its name without specifying the path, it tries to
+ // open it in the current directory. The demos usually expect
+ // all the supplementary files to be placed in the current
+ // directory, that is usually coincides with the directory where
+ // the executable is. However, in some systems (BeOS) it's not so.
+ // For those kinds of systems full_file_name() can help access files
+ // preserving commonly used policy.
+ // So, it's a good idea to use in the demos the following:
+ // FILE* fd = fopen(full_file_name("some.file"), "r");
+ // instead of
+ // FILE* fd = fopen("some.file", "r");
+ const char* full_file_name(const char* file_name);
+
+ public:
+ platform_specific* m_specific;
+ ctrl_container m_ctrls;
+
+ // Sorry, I'm too tired to describe the private
+ // data membders. See the implementations for different
+ // platforms for details.
+ private:
+ platform_support(const platform_support&);
+ const platform_support& operator = (const platform_support&);
+
+ pix_format_e m_format;
+ unsigned m_bpp;
+ rendering_buffer m_rbuf_window;
+ rendering_buffer m_rbuf_img[max_images];
+ unsigned m_window_flags;
+ bool m_wait_mode;
+ bool m_flip_y;
+ char m_caption[256];
+ int m_initial_width;
+ int m_initial_height;
+ trans_affine m_resize_mtx;
+ };
+
+
+}
+
+
+
+#endif
+
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/platform/mac/agg_mac_pmap.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/platform/mac/agg_mac_pmap.h
new file mode 100644
index 0000000000..d7860b6fee
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/platform/mac/agg_mac_pmap.h
@@ -0,0 +1,87 @@
+//----------------------------------------------------------------------------
+// Anti-Grain Geometry - Version 2.4
+// Copyright (C) 2002-2005 Maxim Shemanarev (McSeem)
+// Copyright (C) 2002 Hansruedi Baer (MacOS support)
+//
+// 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
+// baer@karto.baug.eth.ch
+//----------------------------------------------------------------------------
+//
+// class pixel_map
+//
+//----------------------------------------------------------------------------
+#ifndef AGG_MAC_PMAP_INCLUDED
+#define AGG_MAC_PMAP_INCLUDED
+
+
+#include <stdio.h>
+#include <Carbon.h>
+
+
+namespace agg
+{
+ enum org_e
+ {
+ org_mono8 = 8,
+ org_color16 = 16,
+ org_color24 = 24,
+ org_color32 = 32
+ };
+
+ class pixel_map
+ {
+ public:
+ ~pixel_map();
+ pixel_map();
+
+ public:
+ void destroy();
+ void create(unsigned width,
+ unsigned height,
+ org_e org,
+ unsigned clear_val=255);
+
+ void clear(unsigned clear_val=255);
+ bool load_from_qt(const char* filename);
+ bool save_as_qt(const char* filename) const;
+
+ void draw(WindowRef window,
+ const Rect* device_rect=0,
+ const Rect* bmp_rect=0) const;
+ void draw(WindowRef window, int x, int y, double scale=1.0) const;
+ void blend(WindowRef window,
+ const Rect* device_rect=0,
+ const Rect* bmp_rect=0) const;
+ void blend(WindowRef window, int x, int y, double scale=1.0) const;
+
+ unsigned char* buf();
+ unsigned width() const;
+ unsigned height() const;
+ int row_bytes() const;
+ unsigned bpp() const { return m_bpp; }
+
+ //Auxiliary static functions
+ static unsigned calc_row_len(unsigned width, unsigned bits_per_pixel);
+ private:
+ pixel_map(const pixel_map&);
+ const pixel_map& operator = (const pixel_map&);
+
+ private:
+ GWorldPtr m_pmap;
+ unsigned char* m_buf;
+ unsigned m_bpp;
+ unsigned m_img_size;
+ };
+
+}
+
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/platform/win32/agg_win32_bmp.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/platform/win32/agg_win32_bmp.h
new file mode 100644
index 0000000000..5391e8bb9b
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/platform/win32/agg_win32_bmp.h
@@ -0,0 +1,117 @@
+//----------------------------------------------------------------------------
+// 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
+//----------------------------------------------------------------------------
+//
+// class pixel_map
+//
+//----------------------------------------------------------------------------
+#ifndef AGG_WIN32_BMP_INCLUDED
+#define AGG_WIN32_BMP_INCLUDED
+
+
+#include <windows.h>
+#include <stdio.h>
+
+
+namespace agg
+{
+ enum org_e
+ {
+ org_mono8 = 8,
+ org_color16 = 16,
+ org_color24 = 24,
+ org_color32 = 32,
+ org_color48 = 48,
+ org_color64 = 64
+ };
+
+ class pixel_map
+ {
+ public:
+ ~pixel_map();
+ pixel_map();
+
+ public:
+ void destroy();
+ void create(unsigned width,
+ unsigned height,
+ org_e org,
+ unsigned clear_val=256);
+ HBITMAP create_dib_section(HDC h_dc,
+ unsigned width,
+ unsigned height,
+ org_e org,
+ unsigned clear_val=256);
+
+ void clear(unsigned clear_val=256);
+ void attach_to_bmp(BITMAPINFO* bmp);
+ BITMAPINFO* bitmap_info() { return m_bmp; }
+ bool load_from_bmp(FILE* fd);
+ bool save_as_bmp(FILE* fd) const;
+ bool load_from_bmp(const char* filename);
+ bool save_as_bmp(const char* filename) const;
+
+ void draw(HDC h_dc,
+ const RECT* device_rect=0,
+ const RECT* bmp_rect=0) const;
+ void draw(HDC h_dc, int x, int y, double scale=1.0) const;
+
+ void blend(HDC h_dc,
+ const RECT* device_rect=0,
+ const RECT* bmp_rect=0) const;
+ void blend(HDC h_dc, int x, int y, double scale=1.0) const;
+
+
+ unsigned char* buf();
+ unsigned width() const;
+ unsigned height() const;
+ int stride() const;
+ unsigned bpp() const { return m_bpp; }
+
+ //Auxiliary static functions
+ static unsigned calc_full_size(BITMAPINFO *bmp);
+ static unsigned calc_header_size(BITMAPINFO *bmp);
+ static unsigned calc_palette_size(unsigned clr_used,
+ unsigned bits_per_pixel);
+ static unsigned calc_palette_size(BITMAPINFO *bmp);
+ static unsigned char* calc_img_ptr(BITMAPINFO *bmp);
+ static BITMAPINFO* create_bitmap_info(unsigned width,
+ unsigned height,
+ unsigned bits_per_pixel);
+ static void create_gray_scale_palette(BITMAPINFO *bmp);
+ static unsigned calc_row_len(unsigned width, unsigned bits_per_pixel);
+
+ private:
+ pixel_map(const pixel_map&);
+ const pixel_map& operator = (const pixel_map&);
+ void create_from_bmp(BITMAPINFO *bmp);
+
+ HBITMAP create_dib_section_from_args(HDC h_dc,
+ unsigned width,
+ unsigned height,
+ unsigned bits_per_pixel);
+
+ private:
+ BITMAPINFO* m_bmp;
+ unsigned char* m_buf;
+ unsigned m_bpp;
+ bool m_is_internal;
+ unsigned m_img_size;
+ unsigned m_full_size;
+ };
+
+}
+
+
+#endif
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/util/agg_color_conv_rgb16.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/util/agg_color_conv_rgb16.h
new file mode 100644
index 0000000000..aaa41322c5
--- /dev/null
+++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/util/agg_color_conv_rgb16.h
@@ -0,0 +1,285 @@
+//----------------------------------------------------------------------------
+// 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
+//----------------------------------------------------------------------------
+//
+// This part of the library 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.
+//
+//----------------------------------------------------------------------------
+//
+// A set of functors used with color_conv(). See file agg_color_conv.h
+// These functors can convert images with up to 8 bits per component.
+// Use convertors in the following way:
+//
+// agg::color_conv(dst, src, agg::color_conv_XXXX_to_YYYY());
+//----------------------------------------------------------------------------
+
+#ifndef AGG_COLOR_CONV_RGB16_INCLUDED
+#define AGG_COLOR_CONV_RGB16_INCLUDED
+
+#include "agg_basics.h"
+#include "agg_color_conv.h"
+
+namespace agg
+{
+
+ //-------------------------------------------------color_conv_gray16_to_gray8
+ class color_conv_gray16_to_gray8
+ {
+ public:
+ void operator () (int8u* dst,
+ const int8u* src,
+ unsigned width) const
+ {
+ int16u* s = (int16u*)src;
+ do
+ {
+ *dst++ = *s++ >> 8;
+ }
+ while(--width);
+ }
+ };
+
+
+ //-----------------------------------------------------color_conv_rgb24_rgb48
+ template<int I1, int I3> class color_conv_rgb24_rgb48
+ {
+ public:
+ void operator () (int8u* dst,
+ const int8u* src,
+ unsigned width) const
+ {
+ int16u* d = (int16u*)dst;
+ do
+ {
+ *d++ = (src[I1] << 8) | src[I1];
+ *d++ = (src[1] << 8) | src[1] ;
+ *d++ = (src[I3] << 8) | src[I3];
+ src += 3;
+ }
+ while(--width);
+ }
+ };
+
+ typedef color_conv_rgb24_rgb48<0,2> color_conv_rgb24_to_rgb48;
+ typedef color_conv_rgb24_rgb48<0,2> color_conv_bgr24_to_bgr48;
+ typedef color_conv_rgb24_rgb48<2,0> color_conv_rgb24_to_bgr48;
+ typedef color_conv_rgb24_rgb48<2,0> color_conv_bgr24_to_rgb48;
+
+
+ //-----------------------------------------------------color_conv_rgb24_rgb48
+ template<int I1, int I3> class color_conv_rgb48_rgb24
+ {
+ public:
+ void operator () (int8u* dst,
+ const int8u* src,
+ unsigned width) const
+ {
+ const int16u* s = (const int16u*)src;
+ do
+ {
+ *dst++ = s[I1] >> 8;
+ *dst++ = s[1] >> 8;
+ *dst++ = s[I3] >> 8;
+ s += 3;
+ }
+ while(--width);
+ }
+ };
+
+ typedef color_conv_rgb48_rgb24<0,2> color_conv_rgb48_to_rgb24;
+ typedef color_conv_rgb48_rgb24<0,2> color_conv_bgr48_to_bgr24;
+ typedef color_conv_rgb48_rgb24<2,0> color_conv_rgb48_to_bgr24;
+ typedef color_conv_rgb48_rgb24<2,0> color_conv_bgr48_to_rgb24;
+
+
+ //----------------------------------------------color_conv_rgbAAA_rgb24
+ template<int R, int B> class color_conv_rgbAAA_rgb24
+ {
+ public:
+ void operator () (int8u* dst,
+ const int8u* src,
+ unsigned width) const
+ {
+ do
+ {
+ int32u rgb = *(int32u*)src;
+ dst[R] = int8u(rgb >> 22);
+ dst[1] = int8u(rgb >> 12);
+ dst[B] = int8u(rgb >> 2);
+ src += 4;
+ dst += 3;
+ }
+ while(--width);
+ }
+ };
+
+ typedef color_conv_rgbAAA_rgb24<0,2> color_conv_rgbAAA_to_rgb24;
+ typedef color_conv_rgbAAA_rgb24<2,0> color_conv_rgbAAA_to_bgr24;
+ typedef color_conv_rgbAAA_rgb24<2,0> color_conv_bgrAAA_to_rgb24;
+ typedef color_conv_rgbAAA_rgb24<0,2> color_conv_bgrAAA_to_bgr24;
+
+
+ //----------------------------------------------color_conv_rgbBBA_rgb24
+ template<int R, int B> class color_conv_rgbBBA_rgb24
+ {
+ public:
+ void operator () (int8u* dst,
+ const int8u* src,
+ unsigned width) const
+ {
+ do
+ {
+ int32u rgb = *(int32u*)src;
+ dst[R] = int8u(rgb >> 24);
+ dst[1] = int8u(rgb >> 13);
+ dst[B] = int8u(rgb >> 2);
+ src += 4;
+ dst += 3;
+ }
+ while(--width);
+ }
+ };
+
+ typedef color_conv_rgbBBA_rgb24<0,2> color_conv_rgbBBA_to_rgb24;
+ typedef color_conv_rgbBBA_rgb24<2,0> color_conv_rgbBBA_to_bgr24;
+
+
+ //----------------------------------------------color_conv_bgrABB_rgb24
+ template<int B, int R> class color_conv_bgrABB_rgb24
+ {
+ public:
+ void operator () (int8u* dst,
+ const int8u* src,
+ unsigned width) const
+ {
+ do
+ {
+ int32u bgr = *(int32u*)src;
+ dst[R] = int8u(bgr >> 3);
+ dst[1] = int8u(bgr >> 14);
+ dst[B] = int8u(bgr >> 24);
+ src += 4;
+ dst += 3;
+ }
+ while(--width);
+ }
+ };
+
+ typedef color_conv_bgrABB_rgb24<2,0> color_conv_bgrABB_to_rgb24;
+ typedef color_conv_bgrABB_rgb24<0,2> color_conv_bgrABB_to_bgr24;
+
+
+ //-------------------------------------------------color_conv_rgba64_rgba32
+ template<int I1, int I2, int I3, int I4> class color_conv_rgba64_rgba32
+ {
+ public:
+ void operator () (int8u* dst,
+ const int8u* src,
+ unsigned width) const
+ {
+ do
+ {
+ *dst++ = int8u(((int16u*)src)[I1] >> 8);
+ *dst++ = int8u(((int16u*)src)[I2] >> 8);
+ *dst++ = int8u(((int16u*)src)[I3] >> 8);
+ *dst++ = int8u(((int16u*)src)[I4] >> 8);
+ src += 8;
+ }
+ while(--width);
+ }
+ };
+
+ //------------------------------------------------------------------------
+ typedef color_conv_rgba64_rgba32<0,1,2,3> color_conv_rgba64_to_rgba32; //----color_conv_rgba64_to_rgba32
+ typedef color_conv_rgba64_rgba32<0,1,2,3> color_conv_argb64_to_argb32; //----color_conv_argb64_to_argb32
+ typedef color_conv_rgba64_rgba32<0,1,2,3> color_conv_bgra64_to_bgra32; //----color_conv_bgra64_to_bgra32
+ typedef color_conv_rgba64_rgba32<0,1,2,3> color_conv_abgr64_to_abgr32; //----color_conv_abgr64_to_abgr32
+ typedef color_conv_rgba64_rgba32<0,3,2,1> color_conv_argb64_to_abgr32; //----color_conv_argb64_to_abgr32
+ typedef color_conv_rgba64_rgba32<3,2,1,0> color_conv_argb64_to_bgra32; //----color_conv_argb64_to_bgra32
+ typedef color_conv_rgba64_rgba32<1,2,3,0> color_conv_argb64_to_rgba32; //----color_conv_argb64_to_rgba32
+ typedef color_conv_rgba64_rgba32<3,0,1,2> color_conv_bgra64_to_abgr32; //----color_conv_bgra64_to_abgr32
+ typedef color_conv_rgba64_rgba32<3,2,1,0> color_conv_bgra64_to_argb32; //----color_conv_bgra64_to_argb32
+ typedef color_conv_rgba64_rgba32<2,1,0,3> color_conv_bgra64_to_rgba32; //----color_conv_bgra64_to_rgba32
+ typedef color_conv_rgba64_rgba32<3,2,1,0> color_conv_rgba64_to_abgr32; //----color_conv_rgba64_to_abgr32
+ typedef color_conv_rgba64_rgba32<3,0,1,2> color_conv_rgba64_to_argb32; //----color_conv_rgba64_to_argb32
+ typedef color_conv_rgba64_rgba32<2,1,0,3> color_conv_rgba64_to_bgra32; //----color_conv_rgba64_to_bgra32
+ typedef color_conv_rgba64_rgba32<0,3,2,1> color_conv_abgr64_to_argb32; //----color_conv_abgr64_to_argb32
+ typedef color_conv_rgba64_rgba32<1,2,3,0> color_conv_abgr64_to_bgra32; //----color_conv_abgr64_to_bgra32
+ typedef color_conv_rgba64_rgba32<3,2,1,0> color_conv_abgr64_to_rgba32; //----color_conv_abgr64_to_rgba32
+
+
+
+ //--------------------------------------------color_conv_rgb24_rgba64
+ template<int I1, int I2, int I3, int A> class color_conv_rgb24_rgba64
+ {
+ public:
+ void operator () (int8u* dst,
+ const int8u* src,
+ unsigned width) const
+ {
+ int16u* d = (int16u*)dst;
+ do
+ {
+ d[I1] = (src[0] << 8) | src[0];
+ d[I2] = (src[1] << 8) | src[1];
+ d[I3] = (src[2] << 8) | src[2];
+ d[A] = 65535;
+ d += 4;
+ src += 3;
+ }
+ while(--width);
+ }
+ };
+
+
+ //------------------------------------------------------------------------
+ typedef color_conv_rgb24_rgba64<1,2,3,0> color_conv_rgb24_to_argb64; //----color_conv_rgb24_to_argb64
+ typedef color_conv_rgb24_rgba64<3,2,1,0> color_conv_rgb24_to_abgr64; //----color_conv_rgb24_to_abgr64
+ typedef color_conv_rgb24_rgba64<2,1,0,3> color_conv_rgb24_to_bgra64; //----color_conv_rgb24_to_bgra64
+ typedef color_conv_rgb24_rgba64<0,1,2,3> color_conv_rgb24_to_rgba64; //----color_conv_rgb24_to_rgba64
+ typedef color_conv_rgb24_rgba64<3,2,1,0> color_conv_bgr24_to_argb64; //----color_conv_bgr24_to_argb64
+ typedef color_conv_rgb24_rgba64<1,2,3,0> color_conv_bgr24_to_abgr64; //----color_conv_bgr24_to_abgr64
+ typedef color_conv_rgb24_rgba64<0,1,2,3> color_conv_bgr24_to_bgra64; //----color_conv_bgr24_to_bgra64
+ typedef color_conv_rgb24_rgba64<2,1,0,3> color_conv_bgr24_to_rgba64; //----color_conv_bgr24_to_rgba64
+
+
+ template<int R, int B> class color_conv_rgb24_gray16
+ {
+ public:
+ void operator () (int8u* dst,
+ const int8u* src,
+ unsigned width) const
+ {
+ int16u* d = (int16u*)dst;
+ do
+ {
+ *d++ = src[R]*77 + src[1]*150 + src[B]*29;
+ src += 3;
+ }
+ while(--width);
+ }
+ };
+
+ typedef color_conv_rgb24_gray16<0,2> color_conv_rgb24_to_gray16;
+ typedef color_conv_rgb24_gray16<2,0> color_conv_bgr24_to_gray16;
+
+
+}
+
+
+#endif