diff options
author | zverevgeny <zverevgeny@yandex-team.com> | 2025-05-13 19:00:02 +0300 |
---|---|---|
committer | zverevgeny <zverevgeny@yandex-team.com> | 2025-05-13 19:13:54 +0300 |
commit | 92e06374736aa28637dc0e706455b65c8268a5e6 (patch) | |
tree | 3df370c199ae25d308e542f02af20f43eab78f8a /contrib/python/matplotlib/py3/extern | |
parent | dc63d5794da99c2ebe3f32914d0351d9707660b0 (diff) | |
download | ydb-92e06374736aa28637dc0e706455b65c8268a5e6.tar.gz |
Import matplotlib
commit_hash:d59c2338025ef8fd1e1f961ed9d8d5fd52d0bd96
Diffstat (limited to 'contrib/python/matplotlib/py3/extern')
197 files changed, 77514 insertions, 0 deletions
diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_alpha_mask_u8.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_alpha_mask_u8.h new file mode 100644 index 00000000000..e301c100880 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_alpha_mask_u8.h @@ -0,0 +1,499 @@ +//---------------------------------------------------------------------------- +// 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 +//---------------------------------------------------------------------------- +// +// scanline_u8 class +// +//---------------------------------------------------------------------------- +#ifndef AGG_ALPHA_MASK_U8_INCLUDED +#define AGG_ALPHA_MASK_U8_INCLUDED + +#include <string.h> +#include "agg_basics.h" +#include "agg_rendering_buffer.h" + +namespace agg +{ + //===================================================one_component_mask_u8 + struct one_component_mask_u8 + { + static unsigned calculate(const int8u* p) { return *p; } + }; + + + //=====================================================rgb_to_gray_mask_u8 + template<unsigned R, unsigned G, unsigned B> + struct rgb_to_gray_mask_u8 + { + static unsigned calculate(const int8u* p) + { + return (p[R]*77 + p[G]*150 + p[B]*29) >> 8; + } + }; + + //==========================================================alpha_mask_u8 + template<unsigned Step=1, unsigned Offset=0, class MaskF=one_component_mask_u8> + class alpha_mask_u8 + { + public: + typedef int8u cover_type; + typedef alpha_mask_u8<Step, Offset, MaskF> self_type; + enum cover_scale_e + { + cover_shift = 8, + cover_none = 0, + cover_full = 255 + }; + + alpha_mask_u8() : m_rbuf(0) {} + explicit alpha_mask_u8(rendering_buffer& rbuf) : m_rbuf(&rbuf) {} + + void attach(rendering_buffer& rbuf) { m_rbuf = &rbuf; } + + MaskF& mask_function() { return m_mask_function; } + const MaskF& mask_function() const { return m_mask_function; } + + + //-------------------------------------------------------------------- + cover_type pixel(int x, int y) const + { + if(x >= 0 && y >= 0 && + x < (int)m_rbuf->width() && + y < (int)m_rbuf->height()) + { + return (cover_type)m_mask_function.calculate( + m_rbuf->row_ptr(y) + x * Step + Offset); + } + return 0; + } + + //-------------------------------------------------------------------- + cover_type combine_pixel(int x, int y, cover_type val) const + { + if(x >= 0 && y >= 0 && + x < (int)m_rbuf->width() && + y < (int)m_rbuf->height()) + { + return (cover_type)((cover_full + val * + m_mask_function.calculate( + m_rbuf->row_ptr(y) + x * Step + Offset)) >> + cover_shift); + } + return 0; + } + + + //-------------------------------------------------------------------- + void fill_hspan(int x, int y, cover_type* dst, int num_pix) const + { + int xmax = m_rbuf->width() - 1; + int ymax = m_rbuf->height() - 1; + + int count = num_pix; + cover_type* covers = dst; + + if(y < 0 || y > ymax) + { + memset(dst, 0, num_pix * sizeof(cover_type)); + return; + } + + if(x < 0) + { + count += x; + if(count <= 0) + { + memset(dst, 0, num_pix * sizeof(cover_type)); + return; + } + memset(covers, 0, -x * sizeof(cover_type)); + covers -= x; + x = 0; + } + + if(x + count > xmax) + { + int rest = x + count - xmax - 1; + count -= rest; + if(count <= 0) + { + memset(dst, 0, num_pix * sizeof(cover_type)); + return; + } + memset(covers + count, 0, rest * sizeof(cover_type)); + } + + const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset; + do + { + *covers++ = (cover_type)m_mask_function.calculate(mask); + mask += Step; + } + while(--count); + } + + + //-------------------------------------------------------------------- + void combine_hspan(int x, int y, cover_type* dst, int num_pix) const + { + int xmax = m_rbuf->width() - 1; + int ymax = m_rbuf->height() - 1; + + int count = num_pix; + cover_type* covers = dst; + + if(y < 0 || y > ymax) + { + memset(dst, 0, num_pix * sizeof(cover_type)); + return; + } + + if(x < 0) + { + count += x; + if(count <= 0) + { + memset(dst, 0, num_pix * sizeof(cover_type)); + return; + } + memset(covers, 0, -x * sizeof(cover_type)); + covers -= x; + x = 0; + } + + if(x + count > xmax) + { + int rest = x + count - xmax - 1; + count -= rest; + if(count <= 0) + { + memset(dst, 0, num_pix * sizeof(cover_type)); + return; + } + memset(covers + count, 0, rest * sizeof(cover_type)); + } + + const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset; + do + { + *covers = (cover_type)((cover_full + (*covers) * + m_mask_function.calculate(mask)) >> + cover_shift); + ++covers; + mask += Step; + } + while(--count); + } + + //-------------------------------------------------------------------- + void fill_vspan(int x, int y, cover_type* dst, int num_pix) const + { + int xmax = m_rbuf->width() - 1; + int ymax = m_rbuf->height() - 1; + + int count = num_pix; + cover_type* covers = dst; + + if(x < 0 || x > xmax) + { + memset(dst, 0, num_pix * sizeof(cover_type)); + return; + } + + if(y < 0) + { + count += y; + if(count <= 0) + { + memset(dst, 0, num_pix * sizeof(cover_type)); + return; + } + memset(covers, 0, -y * sizeof(cover_type)); + covers -= y; + y = 0; + } + + if(y + count > ymax) + { + int rest = y + count - ymax - 1; + count -= rest; + if(count <= 0) + { + memset(dst, 0, num_pix * sizeof(cover_type)); + return; + } + memset(covers + count, 0, rest * sizeof(cover_type)); + } + + const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset; + do + { + *covers++ = (cover_type)m_mask_function.calculate(mask); + mask += m_rbuf->stride(); + } + while(--count); + } + + //-------------------------------------------------------------------- + void combine_vspan(int x, int y, cover_type* dst, int num_pix) const + { + int xmax = m_rbuf->width() - 1; + int ymax = m_rbuf->height() - 1; + + int count = num_pix; + cover_type* covers = dst; + + if(x < 0 || x > xmax) + { + memset(dst, 0, num_pix * sizeof(cover_type)); + return; + } + + if(y < 0) + { + count += y; + if(count <= 0) + { + memset(dst, 0, num_pix * sizeof(cover_type)); + return; + } + memset(covers, 0, -y * sizeof(cover_type)); + covers -= y; + y = 0; + } + + if(y + count > ymax) + { + int rest = y + count - ymax - 1; + count -= rest; + if(count <= 0) + { + memset(dst, 0, num_pix * sizeof(cover_type)); + return; + } + memset(covers + count, 0, rest * sizeof(cover_type)); + } + + const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset; + do + { + *covers = (cover_type)((cover_full + (*covers) * + m_mask_function.calculate(mask)) >> + cover_shift); + ++covers; + mask += m_rbuf->stride(); + } + while(--count); + } + + + private: + alpha_mask_u8(const self_type&); + const self_type& operator = (const self_type&); + + rendering_buffer* m_rbuf; + MaskF m_mask_function; + }; + + + typedef alpha_mask_u8<1, 0> alpha_mask_gray8; //----alpha_mask_gray8 + + typedef alpha_mask_u8<3, 0> alpha_mask_rgb24r; //----alpha_mask_rgb24r + typedef alpha_mask_u8<3, 1> alpha_mask_rgb24g; //----alpha_mask_rgb24g + typedef alpha_mask_u8<3, 2> alpha_mask_rgb24b; //----alpha_mask_rgb24b + + typedef alpha_mask_u8<3, 2> alpha_mask_bgr24r; //----alpha_mask_bgr24r + typedef alpha_mask_u8<3, 1> alpha_mask_bgr24g; //----alpha_mask_bgr24g + typedef alpha_mask_u8<3, 0> alpha_mask_bgr24b; //----alpha_mask_bgr24b + + typedef alpha_mask_u8<4, 0> alpha_mask_rgba32r; //----alpha_mask_rgba32r + typedef alpha_mask_u8<4, 1> alpha_mask_rgba32g; //----alpha_mask_rgba32g + typedef alpha_mask_u8<4, 2> alpha_mask_rgba32b; //----alpha_mask_rgba32b + typedef alpha_mask_u8<4, 3> alpha_mask_rgba32a; //----alpha_mask_rgba32a + + typedef alpha_mask_u8<4, 1> alpha_mask_argb32r; //----alpha_mask_argb32r + typedef alpha_mask_u8<4, 2> alpha_mask_argb32g; //----alpha_mask_argb32g + typedef alpha_mask_u8<4, 3> alpha_mask_argb32b; //----alpha_mask_argb32b + typedef alpha_mask_u8<4, 0> alpha_mask_argb32a; //----alpha_mask_argb32a + + typedef alpha_mask_u8<4, 2> alpha_mask_bgra32r; //----alpha_mask_bgra32r + typedef alpha_mask_u8<4, 1> alpha_mask_bgra32g; //----alpha_mask_bgra32g + typedef alpha_mask_u8<4, 0> alpha_mask_bgra32b; //----alpha_mask_bgra32b + typedef alpha_mask_u8<4, 3> alpha_mask_bgra32a; //----alpha_mask_bgra32a + + typedef alpha_mask_u8<4, 3> alpha_mask_abgr32r; //----alpha_mask_abgr32r + typedef alpha_mask_u8<4, 2> alpha_mask_abgr32g; //----alpha_mask_abgr32g + typedef alpha_mask_u8<4, 1> alpha_mask_abgr32b; //----alpha_mask_abgr32b + typedef alpha_mask_u8<4, 0> alpha_mask_abgr32a; //----alpha_mask_abgr32a + + typedef alpha_mask_u8<3, 0, rgb_to_gray_mask_u8<0, 1, 2> > alpha_mask_rgb24gray; //----alpha_mask_rgb24gray + typedef alpha_mask_u8<3, 0, rgb_to_gray_mask_u8<2, 1, 0> > alpha_mask_bgr24gray; //----alpha_mask_bgr24gray + typedef alpha_mask_u8<4, 0, rgb_to_gray_mask_u8<0, 1, 2> > alpha_mask_rgba32gray; //----alpha_mask_rgba32gray + typedef alpha_mask_u8<4, 1, rgb_to_gray_mask_u8<0, 1, 2> > alpha_mask_argb32gray; //----alpha_mask_argb32gray + typedef alpha_mask_u8<4, 0, rgb_to_gray_mask_u8<2, 1, 0> > alpha_mask_bgra32gray; //----alpha_mask_bgra32gray + typedef alpha_mask_u8<4, 1, rgb_to_gray_mask_u8<2, 1, 0> > alpha_mask_abgr32gray; //----alpha_mask_abgr32gray + + + + //==========================================================amask_no_clip_u8 + template<unsigned Step=1, unsigned Offset=0, class MaskF=one_component_mask_u8> + class amask_no_clip_u8 + { + public: + typedef int8u cover_type; + typedef amask_no_clip_u8<Step, Offset, MaskF> self_type; + enum cover_scale_e + { + cover_shift = 8, + cover_none = 0, + cover_full = 255 + }; + + amask_no_clip_u8() : m_rbuf(0) {} + explicit amask_no_clip_u8(rendering_buffer& rbuf) : m_rbuf(&rbuf) {} + + void attach(rendering_buffer& rbuf) { m_rbuf = &rbuf; } + + MaskF& mask_function() { return m_mask_function; } + const MaskF& mask_function() const { return m_mask_function; } + + + //-------------------------------------------------------------------- + cover_type pixel(int x, int y) const + { + return (cover_type)m_mask_function.calculate( + m_rbuf->row_ptr(y) + x * Step + Offset); + } + + + //-------------------------------------------------------------------- + cover_type combine_pixel(int x, int y, cover_type val) const + { + return (cover_type)((cover_full + val * + m_mask_function.calculate( + m_rbuf->row_ptr(y) + x * Step + Offset)) >> + cover_shift); + } + + + //-------------------------------------------------------------------- + void fill_hspan(int x, int y, cover_type* dst, int num_pix) const + { + const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset; + do + { + *dst++ = (cover_type)m_mask_function.calculate(mask); + mask += Step; + } + while(--num_pix); + } + + + + //-------------------------------------------------------------------- + void combine_hspan(int x, int y, cover_type* dst, int num_pix) const + { + const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset; + do + { + *dst = (cover_type)((cover_full + (*dst) * + m_mask_function.calculate(mask)) >> + cover_shift); + ++dst; + mask += Step; + } + while(--num_pix); + } + + + //-------------------------------------------------------------------- + void fill_vspan(int x, int y, cover_type* dst, int num_pix) const + { + const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset; + do + { + *dst++ = (cover_type)m_mask_function.calculate(mask); + mask += m_rbuf->stride(); + } + while(--num_pix); + } + + + //-------------------------------------------------------------------- + void combine_vspan(int x, int y, cover_type* dst, int num_pix) const + { + const int8u* mask = m_rbuf->row_ptr(y) + x * Step + Offset; + do + { + *dst = (cover_type)((cover_full + (*dst) * + m_mask_function.calculate(mask)) >> + cover_shift); + ++dst; + mask += m_rbuf->stride(); + } + while(--num_pix); + } + + private: + amask_no_clip_u8(const self_type&); + const self_type& operator = (const self_type&); + + rendering_buffer* m_rbuf; + MaskF m_mask_function; + }; + + + typedef amask_no_clip_u8<1, 0> amask_no_clip_gray8; //----amask_no_clip_gray8 + + typedef amask_no_clip_u8<3, 0> amask_no_clip_rgb24r; //----amask_no_clip_rgb24r + typedef amask_no_clip_u8<3, 1> amask_no_clip_rgb24g; //----amask_no_clip_rgb24g + typedef amask_no_clip_u8<3, 2> amask_no_clip_rgb24b; //----amask_no_clip_rgb24b + + typedef amask_no_clip_u8<3, 2> amask_no_clip_bgr24r; //----amask_no_clip_bgr24r + typedef amask_no_clip_u8<3, 1> amask_no_clip_bgr24g; //----amask_no_clip_bgr24g + typedef amask_no_clip_u8<3, 0> amask_no_clip_bgr24b; //----amask_no_clip_bgr24b + + typedef amask_no_clip_u8<4, 0> amask_no_clip_rgba32r; //----amask_no_clip_rgba32r + typedef amask_no_clip_u8<4, 1> amask_no_clip_rgba32g; //----amask_no_clip_rgba32g + typedef amask_no_clip_u8<4, 2> amask_no_clip_rgba32b; //----amask_no_clip_rgba32b + typedef amask_no_clip_u8<4, 3> amask_no_clip_rgba32a; //----amask_no_clip_rgba32a + + typedef amask_no_clip_u8<4, 1> amask_no_clip_argb32r; //----amask_no_clip_argb32r + typedef amask_no_clip_u8<4, 2> amask_no_clip_argb32g; //----amask_no_clip_argb32g + typedef amask_no_clip_u8<4, 3> amask_no_clip_argb32b; //----amask_no_clip_argb32b + typedef amask_no_clip_u8<4, 0> amask_no_clip_argb32a; //----amask_no_clip_argb32a + + typedef amask_no_clip_u8<4, 2> amask_no_clip_bgra32r; //----amask_no_clip_bgra32r + typedef amask_no_clip_u8<4, 1> amask_no_clip_bgra32g; //----amask_no_clip_bgra32g + typedef amask_no_clip_u8<4, 0> amask_no_clip_bgra32b; //----amask_no_clip_bgra32b + typedef amask_no_clip_u8<4, 3> amask_no_clip_bgra32a; //----amask_no_clip_bgra32a + + typedef amask_no_clip_u8<4, 3> amask_no_clip_abgr32r; //----amask_no_clip_abgr32r + typedef amask_no_clip_u8<4, 2> amask_no_clip_abgr32g; //----amask_no_clip_abgr32g + typedef amask_no_clip_u8<4, 1> amask_no_clip_abgr32b; //----amask_no_clip_abgr32b + typedef amask_no_clip_u8<4, 0> amask_no_clip_abgr32a; //----amask_no_clip_abgr32a + + typedef amask_no_clip_u8<3, 0, rgb_to_gray_mask_u8<0, 1, 2> > amask_no_clip_rgb24gray; //----amask_no_clip_rgb24gray + typedef amask_no_clip_u8<3, 0, rgb_to_gray_mask_u8<2, 1, 0> > amask_no_clip_bgr24gray; //----amask_no_clip_bgr24gray + typedef amask_no_clip_u8<4, 0, rgb_to_gray_mask_u8<0, 1, 2> > amask_no_clip_rgba32gray; //----amask_no_clip_rgba32gray + typedef amask_no_clip_u8<4, 1, rgb_to_gray_mask_u8<0, 1, 2> > amask_no_clip_argb32gray; //----amask_no_clip_argb32gray + typedef amask_no_clip_u8<4, 0, rgb_to_gray_mask_u8<2, 1, 0> > amask_no_clip_bgra32gray; //----amask_no_clip_bgra32gray + typedef amask_no_clip_u8<4, 1, rgb_to_gray_mask_u8<2, 1, 0> > amask_no_clip_abgr32gray; //----amask_no_clip_abgr32gray + + +} + + + +#endif 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 00000000000..17e1d434735 --- /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_array.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_array.h new file mode 100644 index 00000000000..8d56683840d --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_array.h @@ -0,0 +1,1119 @@ +//---------------------------------------------------------------------------- +// 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_ARRAY_INCLUDED +#define AGG_ARRAY_INCLUDED + +#include <stddef.h> +#include <string.h> +#include "agg_basics.h" + +namespace agg +{ + + //-------------------------------------------------------pod_array_adaptor + template<class T> class pod_array_adaptor + { + public: + typedef T value_type; + pod_array_adaptor(T* array, unsigned size) : + m_array(array), m_size(size) {} + + unsigned size() const { return m_size; } + const T& operator [] (unsigned i) const { return m_array[i]; } + T& operator [] (unsigned i) { return m_array[i]; } + const T& at(unsigned i) const { return m_array[i]; } + T& at(unsigned i) { return m_array[i]; } + T value_at(unsigned i) const { return m_array[i]; } + + private: + T* m_array; + unsigned m_size; + }; + + + //---------------------------------------------------------pod_auto_array + template<class T, unsigned Size> class pod_auto_array + { + public: + typedef T value_type; + typedef pod_auto_array<T, Size> self_type; + + pod_auto_array() {} + explicit pod_auto_array(const T* c) + { + memcpy(m_array, c, sizeof(T) * Size); + } + + const self_type& operator = (const T* c) + { + memcpy(m_array, c, sizeof(T) * Size); + return *this; + } + + static unsigned size() { return Size; } + const T& operator [] (unsigned i) const { return m_array[i]; } + T& operator [] (unsigned i) { return m_array[i]; } + const T& at(unsigned i) const { return m_array[i]; } + T& at(unsigned i) { return m_array[i]; } + T value_at(unsigned i) const { return m_array[i]; } + + private: + T m_array[Size]; + }; + + + //--------------------------------------------------------pod_auto_vector + template<class T, unsigned Size> class pod_auto_vector + { + public: + typedef T value_type; + typedef pod_auto_vector<T, Size> self_type; + + pod_auto_vector() : m_size(0) {} + + void remove_all() { m_size = 0; } + void clear() { m_size = 0; } + void add(const T& v) { m_array[m_size++] = v; } + void push_back(const T& v) { m_array[m_size++] = v; } + void inc_size(unsigned size) { m_size += size; } + + unsigned size() const { return m_size; } + const T& operator [] (unsigned i) const { return m_array[i]; } + T& operator [] (unsigned i) { return m_array[i]; } + const T& at(unsigned i) const { return m_array[i]; } + T& at(unsigned i) { return m_array[i]; } + T value_at(unsigned i) const { return m_array[i]; } + + private: + T m_array[Size]; + unsigned m_size; + }; + + + //---------------------------------------------------------------pod_array + template<class T> class pod_array + { + public: + typedef T value_type; + typedef pod_array<T> self_type; + + ~pod_array() { pod_allocator<T>::deallocate(m_array, m_size); } + pod_array() : m_array(0), m_size(0) {} + + pod_array(unsigned size) : + m_array(pod_allocator<T>::allocate(size)), + m_size(size) + {} + + pod_array(const self_type& v) : + m_array(pod_allocator<T>::allocate(v.m_size)), + m_size(v.m_size) + { + memcpy(m_array, v.m_array, sizeof(T) * m_size); + } + + void resize(unsigned size) + { + if(size != m_size) + { + pod_allocator<T>::deallocate(m_array, m_size); + m_array = pod_allocator<T>::allocate(m_size = size); + } + } + const self_type& operator = (const self_type& v) + { + resize(v.size()); + memcpy(m_array, v.m_array, sizeof(T) * m_size); + return *this; + } + + unsigned size() const { return m_size; } + const T& operator [] (unsigned i) const { return m_array[i]; } + T& operator [] (unsigned i) { return m_array[i]; } + const T& at(unsigned i) const { return m_array[i]; } + T& at(unsigned i) { return m_array[i]; } + T value_at(unsigned i) const { return m_array[i]; } + + const T* data() const { return m_array; } + T* data() { return m_array; } + private: + T* m_array; + unsigned m_size; + }; + + + + //--------------------------------------------------------------pod_vector + // A simple class template to store Plain Old Data, a vector + // of a fixed size. The data is continous in memory + //------------------------------------------------------------------------ + template<class T> class pod_vector + { + public: + typedef T value_type; + + ~pod_vector() { pod_allocator<T>::deallocate(m_array, m_capacity); } + pod_vector() : m_size(0), m_capacity(0), m_array(0) {} + pod_vector(unsigned cap, unsigned extra_tail=0); + + // Copying + pod_vector(const pod_vector<T>&); + const pod_vector<T>& operator = (const pod_vector<T>&); + + // Set new capacity. All data is lost, size is set to zero. + void capacity(unsigned cap, unsigned extra_tail=0); + unsigned capacity() const { return m_capacity; } + + // Allocate n elements. All data is lost, + // but elements can be accessed in range 0...size-1. + void allocate(unsigned size, unsigned extra_tail=0); + + // Resize keeping the content. + void resize(unsigned new_size); + + void zero() + { + memset(m_array, 0, sizeof(T) * m_size); + } + + void add(const T& v) { m_array[m_size++] = v; } + void push_back(const T& v) { m_array[m_size++] = v; } + void insert_at(unsigned pos, const T& val); + void inc_size(unsigned size) { m_size += size; } + unsigned size() const { return m_size; } + unsigned byte_size() const { return m_size * sizeof(T); } + void serialize(int8u* ptr) const; + void deserialize(const int8u* data, unsigned byte_size); + const T& operator [] (unsigned i) const { return m_array[i]; } + T& operator [] (unsigned i) { return m_array[i]; } + const T& at(unsigned i) const { return m_array[i]; } + T& at(unsigned i) { return m_array[i]; } + T value_at(unsigned i) const { return m_array[i]; } + + const T* data() const { return m_array; } + T* data() { return m_array; } + + void remove_all() { m_size = 0; } + void clear() { m_size = 0; } + void cut_at(unsigned num) { if(num < m_size) m_size = num; } + + private: + unsigned m_size; + unsigned m_capacity; + T* m_array; + }; + + //------------------------------------------------------------------------ + template<class T> + void pod_vector<T>::capacity(unsigned cap, unsigned extra_tail) + { + m_size = 0; + if(cap > m_capacity) + { + pod_allocator<T>::deallocate(m_array, m_capacity); + m_capacity = cap + extra_tail; + m_array = m_capacity ? pod_allocator<T>::allocate(m_capacity) : 0; + } + } + + //------------------------------------------------------------------------ + template<class T> + void pod_vector<T>::allocate(unsigned size, unsigned extra_tail) + { + capacity(size, extra_tail); + m_size = size; + } + + + //------------------------------------------------------------------------ + template<class T> + void pod_vector<T>::resize(unsigned new_size) + { + if(new_size > m_size) + { + if(new_size > m_capacity) + { + T* data = pod_allocator<T>::allocate(new_size); + memcpy(data, m_array, m_size * sizeof(T)); + pod_allocator<T>::deallocate(m_array, m_capacity); + m_array = data; + } + } + else + { + m_size = new_size; + } + } + + //------------------------------------------------------------------------ + template<class T> pod_vector<T>::pod_vector(unsigned cap, unsigned extra_tail) : + m_size(0), + m_capacity(cap + extra_tail), + m_array(pod_allocator<T>::allocate(m_capacity)) {} + + //------------------------------------------------------------------------ + template<class T> pod_vector<T>::pod_vector(const pod_vector<T>& v) : + m_size(v.m_size), + m_capacity(v.m_capacity), + m_array(v.m_capacity ? pod_allocator<T>::allocate(v.m_capacity) : 0) + { + memcpy(m_array, v.m_array, sizeof(T) * v.m_size); + } + + //------------------------------------------------------------------------ + template<class T> const pod_vector<T>& + pod_vector<T>::operator = (const pod_vector<T>&v) + { + allocate(v.m_size); + if(v.m_size) memcpy(m_array, v.m_array, sizeof(T) * v.m_size); + return *this; + } + + //------------------------------------------------------------------------ + template<class T> void pod_vector<T>::serialize(int8u* ptr) const + { + if(m_size) memcpy(ptr, m_array, m_size * sizeof(T)); + } + + //------------------------------------------------------------------------ + template<class T> + void pod_vector<T>::deserialize(const int8u* data, unsigned byte_size) + { + byte_size /= sizeof(T); + allocate(byte_size); + if(byte_size) memcpy(m_array, data, byte_size * sizeof(T)); + } + + //------------------------------------------------------------------------ + template<class T> + void pod_vector<T>::insert_at(unsigned pos, const T& val) + { + if(pos >= m_size) + { + m_array[m_size] = val; + } + else + { + memmove(m_array + pos + 1, m_array + pos, (m_size - pos) * sizeof(T)); + m_array[pos] = val; + } + ++m_size; + } + + //---------------------------------------------------------------pod_bvector + // A simple class template to store Plain Old Data, similar to std::deque + // It doesn't reallocate memory but instead, uses blocks of data of size + // of (1 << S), that is, power of two. The data is NOT contiguous in memory, + // so the only valid access method is operator [] or curr(), prev(), next() + // + // There reallocs occure only when the pool of pointers to blocks needs + // to be extended (it happens very rarely). You can control the value + // of increment to reallocate the pointer buffer. See the second constructor. + // By default, the incremeent value equals (1 << S), i.e., the block size. + //------------------------------------------------------------------------ + template<class T, unsigned S=6> class pod_bvector + { + public: + enum block_scale_e + { + block_shift = S, + block_size = 1 << block_shift, + block_mask = block_size - 1 + }; + + typedef T value_type; + + ~pod_bvector(); + pod_bvector(); + pod_bvector(unsigned block_ptr_inc); + + // Copying + pod_bvector(const pod_bvector<T, S>& v); + const pod_bvector<T, S>& operator = (const pod_bvector<T, S>& v); + + void remove_all() { m_size = 0; } + void clear() { m_size = 0; } + void free_all() { free_tail(0); } + void free_tail(unsigned size); + void add(const T& val); + void push_back(const T& val) { add(val); } + void modify_last(const T& val); + void remove_last(); + + int allocate_continuous_block(unsigned num_elements); + + void add_array(const T* ptr, unsigned num_elem) + { + while(num_elem--) + { + add(*ptr++); + } + } + + template<class DataAccessor> void add_data(DataAccessor& data) + { + while(data.size()) + { + add(*data); + ++data; + } + } + + void cut_at(unsigned size) + { + if(size < m_size) m_size = size; + } + + unsigned size() const { return m_size; } + + const T& operator [] (unsigned i) const + { + return m_blocks[i >> block_shift][i & block_mask]; + } + + T& operator [] (unsigned i) + { + return m_blocks[i >> block_shift][i & block_mask]; + } + + const T& at(unsigned i) const + { + return m_blocks[i >> block_shift][i & block_mask]; + } + + T& at(unsigned i) + { + return m_blocks[i >> block_shift][i & block_mask]; + } + + T value_at(unsigned i) const + { + return m_blocks[i >> block_shift][i & block_mask]; + } + + const T& curr(unsigned idx) const + { + return (*this)[idx]; + } + + T& curr(unsigned idx) + { + return (*this)[idx]; + } + + const T& prev(unsigned idx) const + { + return (*this)[(idx + m_size - 1) % m_size]; + } + + T& prev(unsigned idx) + { + return (*this)[(idx + m_size - 1) % m_size]; + } + + const T& next(unsigned idx) const + { + return (*this)[(idx + 1) % m_size]; + } + + T& next(unsigned idx) + { + return (*this)[(idx + 1) % m_size]; + } + + const T& last() const + { + return (*this)[m_size - 1]; + } + + T& last() + { + return (*this)[m_size - 1]; + } + + unsigned byte_size() const; + void serialize(int8u* ptr) const; + void deserialize(const int8u* data, unsigned byte_size); + void deserialize(unsigned start, const T& empty_val, + const int8u* data, unsigned byte_size); + + template<class ByteAccessor> + void deserialize(ByteAccessor data) + { + remove_all(); + unsigned elem_size = data.size() / sizeof(T); + + for(unsigned i = 0; i < elem_size; ++i) + { + int8u* ptr = (int8u*)data_ptr(); + for(unsigned j = 0; j < sizeof(T); ++j) + { + *ptr++ = *data; + ++data; + } + ++m_size; + } + } + + template<class ByteAccessor> + void deserialize(unsigned start, const T& empty_val, ByteAccessor data) + { + while(m_size < start) + { + add(empty_val); + } + + unsigned elem_size = data.size() / sizeof(T); + for(unsigned i = 0; i < elem_size; ++i) + { + int8u* ptr; + if(start + i < m_size) + { + ptr = (int8u*)(&((*this)[start + i])); + } + else + { + ptr = (int8u*)data_ptr(); + ++m_size; + } + for(unsigned j = 0; j < sizeof(T); ++j) + { + *ptr++ = *data; + ++data; + } + } + } + + const T* block(unsigned nb) const { return m_blocks[nb]; } + + private: + void allocate_block(unsigned nb); + T* data_ptr(); + + unsigned m_size; + unsigned m_num_blocks; + unsigned m_max_blocks; + T** m_blocks; + unsigned m_block_ptr_inc; + }; + + + //------------------------------------------------------------------------ + template<class T, unsigned S> pod_bvector<T, S>::~pod_bvector() + { + if(m_num_blocks) + { + T** blk = m_blocks + m_num_blocks - 1; + while(m_num_blocks--) + { + pod_allocator<T>::deallocate(*blk, block_size); + --blk; + } + } + pod_allocator<T*>::deallocate(m_blocks, m_max_blocks); + } + + + //------------------------------------------------------------------------ + template<class T, unsigned S> + void pod_bvector<T, S>::free_tail(unsigned size) + { + if(size < m_size) + { + unsigned nb = (size + block_mask) >> block_shift; + while(m_num_blocks > nb) + { + pod_allocator<T>::deallocate(m_blocks[--m_num_blocks], block_size); + } + if(m_num_blocks == 0) + { + pod_allocator<T*>::deallocate(m_blocks, m_max_blocks); + m_blocks = 0; + m_max_blocks = 0; + } + m_size = size; + } + } + + + //------------------------------------------------------------------------ + template<class T, unsigned S> pod_bvector<T, S>::pod_bvector() : + m_size(0), + m_num_blocks(0), + m_max_blocks(0), + m_blocks(0), + m_block_ptr_inc(block_size) + { + } + + + //------------------------------------------------------------------------ + template<class T, unsigned S> + pod_bvector<T, S>::pod_bvector(unsigned block_ptr_inc) : + m_size(0), + m_num_blocks(0), + m_max_blocks(0), + m_blocks(0), + m_block_ptr_inc(block_ptr_inc) + { + } + + + //------------------------------------------------------------------------ + template<class T, unsigned S> + pod_bvector<T, S>::pod_bvector(const pod_bvector<T, S>& v) : + m_size(v.m_size), + m_num_blocks(v.m_num_blocks), + m_max_blocks(v.m_max_blocks), + m_blocks(v.m_max_blocks ? + pod_allocator<T*>::allocate(v.m_max_blocks) : + 0), + m_block_ptr_inc(v.m_block_ptr_inc) + { + unsigned i; + for(i = 0; i < v.m_num_blocks; ++i) + { + m_blocks[i] = pod_allocator<T>::allocate(block_size); + memcpy(m_blocks[i], v.m_blocks[i], block_size * sizeof(T)); + } + } + + + //------------------------------------------------------------------------ + template<class T, unsigned S> + const pod_bvector<T, S>& + pod_bvector<T, S>::operator = (const pod_bvector<T, S>& v) + { + unsigned i; + for(i = m_num_blocks; i < v.m_num_blocks; ++i) + { + allocate_block(i); + } + for(i = 0; i < v.m_num_blocks; ++i) + { + memcpy(m_blocks[i], v.m_blocks[i], block_size * sizeof(T)); + } + m_size = v.m_size; + return *this; + } + + + //------------------------------------------------------------------------ + template<class T, unsigned S> + void pod_bvector<T, S>::allocate_block(unsigned nb) + { + if(nb >= m_max_blocks) + { + T** new_blocks = pod_allocator<T*>::allocate(m_max_blocks + m_block_ptr_inc); + + if(m_blocks) + { + memcpy(new_blocks, + m_blocks, + m_num_blocks * sizeof(T*)); + + pod_allocator<T*>::deallocate(m_blocks, m_max_blocks); + } + m_blocks = new_blocks; + m_max_blocks += m_block_ptr_inc; + } + m_blocks[nb] = pod_allocator<T>::allocate(block_size); + m_num_blocks++; + } + + + + //------------------------------------------------------------------------ + template<class T, unsigned S> + inline T* pod_bvector<T, S>::data_ptr() + { + unsigned nb = m_size >> block_shift; + if(nb >= m_num_blocks) + { + allocate_block(nb); + } + return m_blocks[nb] + (m_size & block_mask); + } + + + + //------------------------------------------------------------------------ + template<class T, unsigned S> + inline void pod_bvector<T, S>::add(const T& val) + { + *data_ptr() = val; + ++m_size; + } + + + //------------------------------------------------------------------------ + template<class T, unsigned S> + inline void pod_bvector<T, S>::remove_last() + { + if(m_size) --m_size; + } + + + //------------------------------------------------------------------------ + template<class T, unsigned S> + void pod_bvector<T, S>::modify_last(const T& val) + { + remove_last(); + add(val); + } + + + //------------------------------------------------------------------------ + template<class T, unsigned S> + int pod_bvector<T, S>::allocate_continuous_block(unsigned num_elements) + { + if(num_elements < block_size) + { + data_ptr(); // Allocate initial block if necessary + unsigned rest = block_size - (m_size & block_mask); + unsigned index; + if(num_elements <= rest) + { + // The rest of the block is good, we can use it + //----------------- + index = m_size; + m_size += num_elements; + return index; + } + + // New block + //--------------- + m_size += rest; + data_ptr(); + index = m_size; + m_size += num_elements; + return index; + } + return -1; // Impossible to allocate + } + + + //------------------------------------------------------------------------ + template<class T, unsigned S> + unsigned pod_bvector<T, S>::byte_size() const + { + return m_size * sizeof(T); + } + + + //------------------------------------------------------------------------ + template<class T, unsigned S> + void pod_bvector<T, S>::serialize(int8u* ptr) const + { + unsigned i; + for(i = 0; i < m_size; i++) + { + memcpy(ptr, &(*this)[i], sizeof(T)); + ptr += sizeof(T); + } + } + + //------------------------------------------------------------------------ + template<class T, unsigned S> + void pod_bvector<T, S>::deserialize(const int8u* data, unsigned byte_size) + { + remove_all(); + byte_size /= sizeof(T); + for(unsigned i = 0; i < byte_size; ++i) + { + T* ptr = data_ptr(); + memcpy(ptr, data, sizeof(T)); + ++m_size; + data += sizeof(T); + } + } + + + // Replace or add a number of elements starting from "start" position + //------------------------------------------------------------------------ + template<class T, unsigned S> + void pod_bvector<T, S>::deserialize(unsigned start, const T& empty_val, + const int8u* data, unsigned byte_size) + { + while(m_size < start) + { + add(empty_val); + } + + byte_size /= sizeof(T); + for(unsigned i = 0; i < byte_size; ++i) + { + if(start + i < m_size) + { + memcpy(&((*this)[start + i]), data, sizeof(T)); + } + else + { + T* ptr = data_ptr(); + memcpy(ptr, data, sizeof(T)); + ++m_size; + } + data += sizeof(T); + } + } + + + //---------------------------------------------------------block_allocator + // Allocator for arbitrary POD data. Most usable in different cache + // systems for efficient memory allocations. + // Memory is allocated with blocks of fixed size ("block_size" in + // the constructor). If required size exceeds the block size the allocator + // creates a new block of the required size. However, the most efficient + // use is when the average reqired size is much less than the block size. + //------------------------------------------------------------------------ + class block_allocator + { + struct block_type + { + int8u* data; + unsigned size; + }; + + public: + void remove_all() + { + if(m_num_blocks) + { + block_type* blk = m_blocks + m_num_blocks - 1; + while(m_num_blocks--) + { + pod_allocator<int8u>::deallocate(blk->data, blk->size); + --blk; + } + pod_allocator<block_type>::deallocate(m_blocks, m_max_blocks); + } + m_num_blocks = 0; + m_max_blocks = 0; + m_blocks = 0; + m_buf_ptr = 0; + m_rest = 0; + } + + ~block_allocator() + { + remove_all(); + } + + block_allocator(unsigned block_size, unsigned block_ptr_inc=256-8) : + m_block_size(block_size), + m_block_ptr_inc(block_ptr_inc), + m_num_blocks(0), + m_max_blocks(0), + m_blocks(0), + m_buf_ptr(0), + m_rest(0) + { + } + + + int8u* allocate(unsigned size, unsigned alignment=1) + { + if(size == 0) return 0; + if(size <= m_rest) + { + int8u* ptr = m_buf_ptr; + if(alignment > 1) + { + unsigned align = + (alignment - unsigned((size_t)ptr) % alignment) % alignment; + + size += align; + ptr += align; + if(size <= m_rest) + { + m_rest -= size; + m_buf_ptr += size; + return ptr; + } + allocate_block(size); + return allocate(size - align, alignment); + } + m_rest -= size; + m_buf_ptr += size; + return ptr; + } + allocate_block(size + alignment - 1); + return allocate(size, alignment); + } + + + private: + void allocate_block(unsigned size) + { + if(size < m_block_size) size = m_block_size; + if(m_num_blocks >= m_max_blocks) + { + block_type* new_blocks = + pod_allocator<block_type>::allocate(m_max_blocks + m_block_ptr_inc); + + if(m_blocks) + { + memcpy(new_blocks, + m_blocks, + m_num_blocks * sizeof(block_type)); + pod_allocator<block_type>::deallocate(m_blocks, m_max_blocks); + } + m_blocks = new_blocks; + m_max_blocks += m_block_ptr_inc; + } + + m_blocks[m_num_blocks].size = size; + m_blocks[m_num_blocks].data = + m_buf_ptr = + pod_allocator<int8u>::allocate(size); + + m_num_blocks++; + m_rest = size; + } + + unsigned m_block_size; + unsigned m_block_ptr_inc; + unsigned m_num_blocks; + unsigned m_max_blocks; + block_type* m_blocks; + int8u* m_buf_ptr; + unsigned m_rest; + }; + + + + + + + + + //------------------------------------------------------------------------ + enum quick_sort_threshold_e + { + quick_sort_threshold = 9 + }; + + + //-----------------------------------------------------------swap_elements + template<class T> inline void swap_elements(T& a, T& b) + { + T temp = a; + a = b; + b = temp; + } + + + //--------------------------------------------------------------quick_sort + template<class Array, class Less> + void quick_sort(Array& arr, Less less) + { + if(arr.size() < 2) return; + + typename Array::value_type* e1; + typename Array::value_type* e2; + + int stack[80]; + int* top = stack; + int limit = arr.size(); + int base = 0; + + for(;;) + { + int len = limit - base; + + int i; + int j; + int pivot; + + if(len > quick_sort_threshold) + { + // we use base + len/2 as the pivot + pivot = base + len / 2; + swap_elements(arr[base], arr[pivot]); + + i = base + 1; + j = limit - 1; + + // now ensure that *i <= *base <= *j + e1 = &(arr[j]); + e2 = &(arr[i]); + if(less(*e1, *e2)) swap_elements(*e1, *e2); + + e1 = &(arr[base]); + e2 = &(arr[i]); + if(less(*e1, *e2)) swap_elements(*e1, *e2); + + e1 = &(arr[j]); + e2 = &(arr[base]); + if(less(*e1, *e2)) swap_elements(*e1, *e2); + + for(;;) + { + do i++; while( less(arr[i], arr[base]) ); + do j--; while( less(arr[base], arr[j]) ); + + if( i > j ) + { + break; + } + + swap_elements(arr[i], arr[j]); + } + + swap_elements(arr[base], arr[j]); + + // now, push the largest sub-array + if(j - base > limit - i) + { + top[0] = base; + top[1] = j; + base = i; + } + else + { + top[0] = i; + top[1] = limit; + limit = j; + } + top += 2; + } + else + { + // the sub-array is small, perform insertion sort + j = base; + i = j + 1; + + for(; i < limit; j = i, i++) + { + for(; less(*(e1 = &(arr[j + 1])), *(e2 = &(arr[j]))); j--) + { + swap_elements(*e1, *e2); + if(j == base) + { + break; + } + } + } + if(top > stack) + { + top -= 2; + base = top[0]; + limit = top[1]; + } + else + { + break; + } + } + } + } + + + + + //------------------------------------------------------remove_duplicates + // Remove duplicates from a sorted array. It doesn't cut the + // tail of the array, it just returns the number of remaining elements. + //----------------------------------------------------------------------- + template<class Array, class Equal> + unsigned remove_duplicates(Array& arr, Equal equal) + { + if(arr.size() < 2) return arr.size(); + + unsigned i, j; + for(i = 1, j = 1; i < arr.size(); i++) + { + typename Array::value_type& e = arr[i]; + if(!equal(e, arr[i - 1])) + { + arr[j++] = e; + } + } + return j; + } + + //--------------------------------------------------------invert_container + template<class Array> void invert_container(Array& arr) + { + int i = 0; + int j = arr.size() - 1; + while(i < j) + { + swap_elements(arr[i++], arr[j--]); + } + } + + //------------------------------------------------------binary_search_pos + template<class Array, class Value, class Less> + unsigned binary_search_pos(const Array& arr, const Value& val, Less less) + { + if(arr.size() == 0) return 0; + + unsigned beg = 0; + unsigned end = arr.size() - 1; + + if(less(val, arr[0])) return 0; + if(less(arr[end], val)) return end + 1; + + while(end - beg > 1) + { + unsigned mid = (end + beg) >> 1; + if(less(val, arr[mid])) end = mid; + else beg = mid; + } + + //if(beg <= 0 && less(val, arr[0])) return 0; + //if(end >= arr.size() - 1 && less(arr[end], val)) ++end; + + return end; + } + + //----------------------------------------------------------range_adaptor + template<class Array> class range_adaptor + { + public: + typedef typename Array::value_type value_type; + + range_adaptor(Array& array, unsigned start, unsigned size) : + m_array(array), m_start(start), m_size(size) + {} + + unsigned size() const { return m_size; } + const value_type& operator [] (unsigned i) const { return m_array[m_start + i]; } + value_type& operator [] (unsigned i) { return m_array[m_start + i]; } + const value_type& at(unsigned i) const { return m_array[m_start + i]; } + value_type& at(unsigned i) { return m_array[m_start + i]; } + value_type value_at(unsigned i) const { return m_array[m_start + i]; } + + private: + Array& m_array; + unsigned m_start; + unsigned m_size; + }; + + //---------------------------------------------------------------int_less + inline bool int_less(int a, int b) { return a < b; } + + //------------------------------------------------------------int_greater + inline bool int_greater(int a, int b) { return a > b; } + + //----------------------------------------------------------unsigned_less + inline bool unsigned_less(unsigned a, unsigned b) { return a < b; } + + //-------------------------------------------------------unsigned_greater + inline bool unsigned_greater(unsigned a, unsigned b) { return a > b; } +} + +#endif diff --git a/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 00000000000..5e029ddee03 --- /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_basics.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_basics.h new file mode 100644 index 00000000000..309713002b3 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_basics.h @@ -0,0 +1,560 @@ +//---------------------------------------------------------------------------- +// 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_BASICS_INCLUDED +#define AGG_BASICS_INCLUDED + +#include <math.h> +#include "agg_config.h" + +//---------------------------------------------------------AGG_CUSTOM_ALLOCATOR +#ifdef AGG_CUSTOM_ALLOCATOR +#include "agg_allocator.h" +#else +namespace agg +{ + // The policy of all AGG containers and memory allocation strategy + // in general is that no allocated data requires explicit construction. + // It means that the allocator can be really simple; you can even + // replace new/delete to malloc/free. The constructors and destructors + // won't be called in this case, however everything will remain working. + // The second argument of deallocate() is the size of the allocated + // block. You can use this information if you wish. + //------------------------------------------------------------pod_allocator + template<class T> struct pod_allocator + { + static T* allocate(unsigned num) { return new T [num]; } + static void deallocate(T* ptr, unsigned) { delete [] ptr; } + }; + + // Single object allocator. It's also can be replaced with your custom + // allocator. The difference is that it can only allocate a single + // object and the constructor and destructor must be called. + // In AGG there is no need to allocate an array of objects with + // calling their constructors (only single ones). So that, if you + // replace these new/delete to malloc/free make sure that the in-place + // new is called and take care of calling the destructor too. + //------------------------------------------------------------obj_allocator + template<class T> struct obj_allocator + { + static T* allocate() { return new T; } + static void deallocate(T* ptr) { delete ptr; } + }; +} +#endif + + +//-------------------------------------------------------- Default basic types +// +// If the compiler has different capacity of the basic types you can redefine +// them via the compiler command line or by generating agg_config.h that is +// empty by default. +// +#ifndef AGG_INT8 +#define AGG_INT8 signed char +#endif + +#ifndef AGG_INT8U +#define AGG_INT8U unsigned char +#endif + +#ifndef AGG_INT16 +#define AGG_INT16 short +#endif + +#ifndef AGG_INT16U +#define AGG_INT16U unsigned short +#endif + +#ifndef AGG_INT32 +#define AGG_INT32 int +#endif + +#ifndef AGG_INT32U +#define AGG_INT32U unsigned +#endif + +#ifndef AGG_INT64 +#if defined(_MSC_VER) || defined(__BORLANDC__) +#define AGG_INT64 signed __int64 +#else +#define AGG_INT64 signed long long +#endif +#endif + +#ifndef AGG_INT64U +#if defined(_MSC_VER) || defined(__BORLANDC__) +#define AGG_INT64U unsigned __int64 +#else +#define AGG_INT64U unsigned long long +#endif +#endif + +//------------------------------------------------ Some fixes for MS Visual C++ +#if defined(_MSC_VER) +#pragma warning(disable:4786) // Identifier was truncated... +#endif + +#if defined(_MSC_VER) +#define AGG_INLINE __forceinline +#else +#define AGG_INLINE inline +#endif + +namespace agg +{ + //------------------------------------------------------------------------- + typedef AGG_INT8 int8; //----int8 + typedef AGG_INT8U int8u; //----int8u + typedef AGG_INT16 int16; //----int16 + typedef AGG_INT16U int16u; //----int16u + typedef AGG_INT32 int32; //----int32 + typedef AGG_INT32U int32u; //----int32u + typedef AGG_INT64 int64; //----int64 + typedef AGG_INT64U int64u; //----int64u + +#if defined(AGG_FISTP) +#pragma warning(push) +#pragma warning(disable : 4035) //Disable warning "no return value" + AGG_INLINE int iround(double v) //-------iround + { + int t; + __asm fld qword ptr [v] + __asm fistp dword ptr [t] + __asm mov eax, dword ptr [t] + } + AGG_INLINE unsigned uround(double v) //-------uround + { + unsigned t; + __asm fld qword ptr [v] + __asm fistp dword ptr [t] + __asm mov eax, dword ptr [t] + } +#pragma warning(pop) + AGG_INLINE int ifloor(double v) + { + return int(floor(v)); + } + AGG_INLINE unsigned ufloor(double v) //-------ufloor + { + return unsigned(floor(v)); + } + AGG_INLINE int iceil(double v) + { + return int(ceil(v)); + } + AGG_INLINE unsigned uceil(double v) //--------uceil + { + return unsigned(ceil(v)); + } +#elif defined(AGG_QIFIST) + AGG_INLINE int iround(double v) + { + return int(v); + } + AGG_INLINE int uround(double v) + { + return unsigned(v); + } + AGG_INLINE int ifloor(double v) + { + return int(floor(v)); + } + AGG_INLINE unsigned ufloor(double v) + { + return unsigned(floor(v)); + } + AGG_INLINE int iceil(double v) + { + return int(ceil(v)); + } + AGG_INLINE unsigned uceil(double v) + { + return unsigned(ceil(v)); + } +#else + AGG_INLINE int iround(double v) + { + return int((v < 0.0) ? v - 0.5 : v + 0.5); + } + AGG_INLINE int uround(double v) + { + return unsigned(v + 0.5); + } + AGG_INLINE int ifloor(double v) + { + int i = int(v); + return i - (i > v); + } + AGG_INLINE unsigned ufloor(double v) + { + return unsigned(v); + } + AGG_INLINE int iceil(double v) + { + return int(ceil(v)); + } + AGG_INLINE unsigned uceil(double v) + { + return unsigned(ceil(v)); + } +#endif + + //---------------------------------------------------------------saturation + template<int Limit> struct saturation + { + AGG_INLINE static int iround(double v) + { + if(v < double(-Limit)) return -Limit; + if(v > double( Limit)) return Limit; + return agg::iround(v); + } + }; + + //------------------------------------------------------------------mul_one + template<unsigned Shift> struct mul_one + { + AGG_INLINE static unsigned mul(unsigned a, unsigned b) + { + unsigned q = a * b + (1 << (Shift-1)); + return (q + (q >> Shift)) >> Shift; + } + }; + + //------------------------------------------------------------------------- + typedef unsigned char cover_type; //----cover_type + enum cover_scale_e + { + cover_shift = 8, //----cover_shift + cover_size = 1 << cover_shift, //----cover_size + cover_mask = cover_size - 1, //----cover_mask + cover_none = 0, //----cover_none + cover_full = cover_mask //----cover_full + }; + + //----------------------------------------------------poly_subpixel_scale_e + // These constants determine the subpixel accuracy, to be more precise, + // the number of bits of the fractional part of the coordinates. + // The possible coordinate capacity in bits can be calculated by formula: + // sizeof(int) * 8 - poly_subpixel_shift, i.e, for 32-bit integers and + // 8-bits fractional part the capacity is 24 bits. + enum poly_subpixel_scale_e + { + poly_subpixel_shift = 8, //----poly_subpixel_shift + poly_subpixel_scale = 1<<poly_subpixel_shift, //----poly_subpixel_scale + poly_subpixel_mask = poly_subpixel_scale-1 //----poly_subpixel_mask + }; + + //----------------------------------------------------------filling_rule_e + enum filling_rule_e + { + fill_non_zero, + fill_even_odd + }; + + //-----------------------------------------------------------------------pi + const double pi = 3.14159265358979323846; + + //------------------------------------------------------------------deg2rad + inline double deg2rad(double deg) + { + return deg * pi / 180.0; + } + + //------------------------------------------------------------------rad2deg + inline double rad2deg(double rad) + { + return rad * 180.0 / pi; + } + + //----------------------------------------------------------------rect_base + template<class T> struct rect_base + { + typedef T value_type; + typedef rect_base<T> self_type; + T x1, y1, x2, y2; + + rect_base() {} + rect_base(T x1_, T y1_, T x2_, T y2_) : + x1(x1_), y1(y1_), x2(x2_), y2(y2_) {} + + void init(T x1_, T y1_, T x2_, T y2_) + { + x1 = x1_; y1 = y1_; x2 = x2_; y2 = y2_; + } + + const self_type& normalize() + { + T t; + if(x1 > x2) { t = x1; x1 = x2; x2 = t; } + if(y1 > y2) { t = y1; y1 = y2; y2 = t; } + return *this; + } + + bool clip(const self_type& r) + { + if(x2 > r.x2) x2 = r.x2; + if(y2 > r.y2) y2 = r.y2; + if(x1 < r.x1) x1 = r.x1; + if(y1 < r.y1) y1 = r.y1; + return x1 <= x2 && y1 <= y2; + } + + bool is_valid() const + { + return x1 <= x2 && y1 <= y2; + } + + bool hit_test(T x, T y) const + { + return (x >= x1 && x <= x2 && y >= y1 && y <= y2); + } + + bool overlaps(const self_type& r) const + { + return !(r.x1 > x2 || r.x2 < x1 + || r.y1 > y2 || r.y2 < y1); + } + }; + + //-----------------------------------------------------intersect_rectangles + template<class Rect> + inline Rect intersect_rectangles(const Rect& r1, const Rect& r2) + { + Rect r = r1; + + // First process x2,y2 because the other order + // results in Internal Compiler Error under + // Microsoft Visual C++ .NET 2003 69462-335-0000007-18038 in + // case of "Maximize Speed" optimization option. + //----------------- + if(r.x2 > r2.x2) r.x2 = r2.x2; + if(r.y2 > r2.y2) r.y2 = r2.y2; + if(r.x1 < r2.x1) r.x1 = r2.x1; + if(r.y1 < r2.y1) r.y1 = r2.y1; + return r; + } + + + //---------------------------------------------------------unite_rectangles + template<class Rect> + inline Rect unite_rectangles(const Rect& r1, const Rect& r2) + { + Rect r = r1; + if(r.x2 < r2.x2) r.x2 = r2.x2; + if(r.y2 < r2.y2) r.y2 = r2.y2; + if(r.x1 > r2.x1) r.x1 = r2.x1; + if(r.y1 > r2.y1) r.y1 = r2.y1; + return r; + } + + typedef rect_base<int> rect_i; //----rect_i + typedef rect_base<float> rect_f; //----rect_f + typedef rect_base<double> rect_d; //----rect_d + + //---------------------------------------------------------path_commands_e + enum path_commands_e + { + path_cmd_stop = 0, //----path_cmd_stop + path_cmd_move_to = 1, //----path_cmd_move_to + path_cmd_line_to = 2, //----path_cmd_line_to + path_cmd_curve3 = 3, //----path_cmd_curve3 + path_cmd_curve4 = 4, //----path_cmd_curve4 + path_cmd_curveN = 5, //----path_cmd_curveN + path_cmd_catrom = 6, //----path_cmd_catrom + path_cmd_ubspline = 7, //----path_cmd_ubspline + path_cmd_end_poly = 0x0F, //----path_cmd_end_poly + path_cmd_mask = 0x0F //----path_cmd_mask + }; + + //------------------------------------------------------------path_flags_e + enum path_flags_e + { + path_flags_none = 0, //----path_flags_none + path_flags_ccw = 0x10, //----path_flags_ccw + path_flags_cw = 0x20, //----path_flags_cw + path_flags_close = 0x40, //----path_flags_close + path_flags_mask = 0xF0 //----path_flags_mask + }; + + //---------------------------------------------------------------is_vertex + inline bool is_vertex(unsigned c) + { + return c >= path_cmd_move_to && c < path_cmd_end_poly; + } + + //--------------------------------------------------------------is_drawing + inline bool is_drawing(unsigned c) + { + return c >= path_cmd_line_to && c < path_cmd_end_poly; + } + + //-----------------------------------------------------------------is_stop + inline bool is_stop(unsigned c) + { + return c == path_cmd_stop; + } + + //--------------------------------------------------------------is_move_to + inline bool is_move_to(unsigned c) + { + return c == path_cmd_move_to; + } + + //--------------------------------------------------------------is_line_to + inline bool is_line_to(unsigned c) + { + return c == path_cmd_line_to; + } + + //----------------------------------------------------------------is_curve + inline bool is_curve(unsigned c) + { + return c == path_cmd_curve3 || c == path_cmd_curve4; + } + + //---------------------------------------------------------------is_curve3 + inline bool is_curve3(unsigned c) + { + return c == path_cmd_curve3; + } + + //---------------------------------------------------------------is_curve4 + inline bool is_curve4(unsigned c) + { + return c == path_cmd_curve4; + } + + //-------------------------------------------------------------is_end_poly + inline bool is_end_poly(unsigned c) + { + return (c & path_cmd_mask) == path_cmd_end_poly; + } + + //----------------------------------------------------------------is_close + inline bool is_close(unsigned c) + { + return (c & ~(path_flags_cw | path_flags_ccw)) == + (path_cmd_end_poly | path_flags_close); + } + + //------------------------------------------------------------is_next_poly + inline bool is_next_poly(unsigned c) + { + return is_stop(c) || is_move_to(c) || is_end_poly(c); + } + + //-------------------------------------------------------------------is_cw + inline bool is_cw(unsigned c) + { + return (c & path_flags_cw) != 0; + } + + //------------------------------------------------------------------is_ccw + inline bool is_ccw(unsigned c) + { + return (c & path_flags_ccw) != 0; + } + + //-------------------------------------------------------------is_oriented + inline bool is_oriented(unsigned c) + { + return (c & (path_flags_cw | path_flags_ccw)) != 0; + } + + //---------------------------------------------------------------is_closed + inline bool is_closed(unsigned c) + { + return (c & path_flags_close) != 0; + } + + //----------------------------------------------------------get_close_flag + inline unsigned get_close_flag(unsigned c) + { + return c & path_flags_close; + } + + //-------------------------------------------------------clear_orientation + inline unsigned clear_orientation(unsigned c) + { + return c & ~(path_flags_cw | path_flags_ccw); + } + + //---------------------------------------------------------get_orientation + inline unsigned get_orientation(unsigned c) + { + return c & (path_flags_cw | path_flags_ccw); + } + + //---------------------------------------------------------set_orientation + inline unsigned set_orientation(unsigned c, unsigned o) + { + return clear_orientation(c) | o; + } + + //--------------------------------------------------------------point_base + template<class T> struct point_base + { + typedef T value_type; + T x,y; + point_base() {} + point_base(T x_, T y_) : x(x_), y(y_) {} + }; + typedef point_base<int> point_i; //-----point_i + typedef point_base<float> point_f; //-----point_f + typedef point_base<double> point_d; //-----point_d + + //-------------------------------------------------------------vertex_base + template<class T> struct vertex_base + { + typedef T value_type; + T x,y; + unsigned cmd; + vertex_base() {} + vertex_base(T x_, T y_, unsigned cmd_) : x(x_), y(y_), cmd(cmd_) {} + }; + typedef vertex_base<int> vertex_i; //-----vertex_i + typedef vertex_base<float> vertex_f; //-----vertex_f + typedef vertex_base<double> vertex_d; //-----vertex_d + + //----------------------------------------------------------------row_info + template<class T> struct row_info + { + int x1, x2; + T* ptr; + row_info() {} + row_info(int x1_, int x2_, T* ptr_) : x1(x1_), x2(x2_), ptr(ptr_) {} + }; + + //----------------------------------------------------------const_row_info + template<class T> struct const_row_info + { + int x1, x2; + const T* ptr; + const_row_info() {} + const_row_info(int x1_, int x2_, const T* ptr_) : + x1(x1_), x2(x2_), ptr(ptr_) {} + }; + + //------------------------------------------------------------is_equal_eps + template<class T> inline bool is_equal_eps(T v1, T v2, T epsilon) + { + return fabs(v1 - v2) <= double(epsilon); + } +} + + +#endif + diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_bezier_arc.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_bezier_arc.h new file mode 100644 index 00000000000..6d98d1a9f0d --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_bezier_arc.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 +//---------------------------------------------------------------------------- +// +// Arc generator. Produces at most 4 consecutive cubic bezier curves, i.e., +// 4, 7, 10, or 13 vertices. +// +//---------------------------------------------------------------------------- + +#ifndef AGG_BEZIER_ARC_INCLUDED +#define AGG_BEZIER_ARC_INCLUDED + +#include "agg_conv_transform.h" + +namespace agg +{ + + //----------------------------------------------------------------------- + void arc_to_bezier(double cx, double cy, double rx, double ry, + double start_angle, double sweep_angle, + double* curve); + + + //==============================================================bezier_arc + // + // See implemantaion agg_bezier_arc.cpp + // + class bezier_arc + { + public: + //-------------------------------------------------------------------- + bezier_arc() : m_vertex(26), m_num_vertices(0), m_cmd(path_cmd_line_to) {} + bezier_arc(double x, double y, + double rx, double ry, + double start_angle, + double sweep_angle) + { + init(x, y, rx, ry, start_angle, sweep_angle); + } + + //-------------------------------------------------------------------- + void init(double x, double y, + double rx, double ry, + double start_angle, + double sweep_angle); + + //-------------------------------------------------------------------- + void rewind(unsigned) + { + m_vertex = 0; + } + + //-------------------------------------------------------------------- + unsigned vertex(double* x, double* y) + { + if(m_vertex >= m_num_vertices) return path_cmd_stop; + *x = m_vertices[m_vertex]; + *y = m_vertices[m_vertex + 1]; + m_vertex += 2; + return (m_vertex == 2) ? path_cmd_move_to : m_cmd; + } + + // Supplemantary functions. num_vertices() actually returns doubled + // number of vertices. That is, for 1 vertex it returns 2. + //-------------------------------------------------------------------- + unsigned num_vertices() const { return m_num_vertices; } + const double* vertices() const { return m_vertices; } + double* vertices() { return m_vertices; } + + private: + unsigned m_vertex; + unsigned m_num_vertices; + double m_vertices[26]; + unsigned m_cmd; + }; + + + + //==========================================================bezier_arc_svg + // Compute an SVG-style bezier arc. + // + // Computes an elliptical arc from (x1, y1) to (x2, y2). The size and + // orientation of the ellipse are defined by two radii (rx, ry) + // and an x-axis-rotation, which indicates how the ellipse as a whole + // is rotated relative to the current coordinate system. The center + // (cx, cy) of the ellipse is calculated automatically to satisfy the + // constraints imposed by the other parameters. + // large-arc-flag and sweep-flag contribute to the automatic calculations + // and help determine how the arc is drawn. + class bezier_arc_svg + { + public: + //-------------------------------------------------------------------- + bezier_arc_svg() : m_arc(), m_radii_ok(false) {} + + bezier_arc_svg(double x1, double y1, + double rx, double ry, + double angle, + bool large_arc_flag, + bool sweep_flag, + double x2, double y2) : + m_arc(), m_radii_ok(false) + { + init(x1, y1, rx, ry, angle, large_arc_flag, sweep_flag, x2, y2); + } + + //-------------------------------------------------------------------- + void init(double x1, double y1, + double rx, double ry, + double angle, + bool large_arc_flag, + bool sweep_flag, + double x2, double y2); + + //-------------------------------------------------------------------- + bool radii_ok() const { return m_radii_ok; } + + //-------------------------------------------------------------------- + void rewind(unsigned) + { + m_arc.rewind(0); + } + + //-------------------------------------------------------------------- + unsigned vertex(double* x, double* y) + { + return m_arc.vertex(x, y); + } + + // Supplemantary functions. num_vertices() actually returns doubled + // number of vertices. That is, for 1 vertex it returns 2. + //-------------------------------------------------------------------- + unsigned num_vertices() const { return m_arc.num_vertices(); } + const double* vertices() const { return m_arc.vertices(); } + double* vertices() { return m_arc.vertices(); } + + private: + bezier_arc m_arc; + bool m_radii_ok; + }; + + + + +} + + +#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 00000000000..7382d5c3359 --- /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 00000000000..cd5713f314f --- /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 00000000000..f13b863f0fc --- /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 00000000000..2c1ed9a38cc --- /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_clip_liang_barsky.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_clip_liang_barsky.h new file mode 100644 index 00000000000..4b5fedbab5f --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_clip_liang_barsky.h @@ -0,0 +1,333 @@ +//---------------------------------------------------------------------------- +// 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 +//---------------------------------------------------------------------------- +// +// Liang-Barsky clipping +// +//---------------------------------------------------------------------------- +#ifndef AGG_CLIP_LIANG_BARSKY_INCLUDED +#define AGG_CLIP_LIANG_BARSKY_INCLUDED + +#include "agg_basics.h" + +namespace agg +{ + + //------------------------------------------------------------------------ + enum clipping_flags_e + { + clipping_flags_x1_clipped = 4, + clipping_flags_x2_clipped = 1, + clipping_flags_y1_clipped = 8, + clipping_flags_y2_clipped = 2, + clipping_flags_x_clipped = clipping_flags_x1_clipped | clipping_flags_x2_clipped, + clipping_flags_y_clipped = clipping_flags_y1_clipped | clipping_flags_y2_clipped + }; + + //----------------------------------------------------------clipping_flags + // Determine the clipping code of the vertex according to the + // Cyrus-Beck line clipping algorithm + // + // | | + // 0110 | 0010 | 0011 + // | | + // -------+--------+-------- clip_box.y2 + // | | + // 0100 | 0000 | 0001 + // | | + // -------+--------+-------- clip_box.y1 + // | | + // 1100 | 1000 | 1001 + // | | + // clip_box.x1 clip_box.x2 + // + // + template<class T> + inline unsigned clipping_flags(T x, T y, const rect_base<T>& clip_box) + { + return (x > clip_box.x2) | + ((y > clip_box.y2) << 1) | + ((x < clip_box.x1) << 2) | + ((y < clip_box.y1) << 3); + } + + //--------------------------------------------------------clipping_flags_x + template<class T> + inline unsigned clipping_flags_x(T x, const rect_base<T>& clip_box) + { + return (x > clip_box.x2) | ((x < clip_box.x1) << 2); + } + + + //--------------------------------------------------------clipping_flags_y + template<class T> + inline unsigned clipping_flags_y(T y, const rect_base<T>& clip_box) + { + return ((y > clip_box.y2) << 1) | ((y < clip_box.y1) << 3); + } + + + //-------------------------------------------------------clip_liang_barsky + template<class T> + inline unsigned clip_liang_barsky(T x1, T y1, T x2, T y2, + const rect_base<T>& clip_box, + T* x, T* y) + { + const double nearzero = 1e-30; + + double deltax = x2 - x1; + double deltay = y2 - y1; + double xin; + double xout; + double yin; + double yout; + double tinx; + double tiny; + double toutx; + double touty; + double tin1; + double tin2; + double tout1; + unsigned np = 0; + + if(deltax == 0.0) + { + // bump off of the vertical + deltax = (x1 > clip_box.x1) ? -nearzero : nearzero; + } + + if(deltay == 0.0) + { + // bump off of the horizontal + deltay = (y1 > clip_box.y1) ? -nearzero : nearzero; + } + + if(deltax > 0.0) + { + // points to right + xin = clip_box.x1; + xout = clip_box.x2; + } + else + { + xin = clip_box.x2; + xout = clip_box.x1; + } + + if(deltay > 0.0) + { + // points up + yin = clip_box.y1; + yout = clip_box.y2; + } + else + { + yin = clip_box.y2; + yout = clip_box.y1; + } + + tinx = (xin - x1) / deltax; + tiny = (yin - y1) / deltay; + + if (tinx < tiny) + { + // hits x first + tin1 = tinx; + tin2 = tiny; + } + else + { + // hits y first + tin1 = tiny; + tin2 = tinx; + } + + if(tin1 <= 1.0) + { + if(0.0 < tin1) + { + *x++ = (T)xin; + *y++ = (T)yin; + ++np; + } + + if(tin2 <= 1.0) + { + toutx = (xout - x1) / deltax; + touty = (yout - y1) / deltay; + + tout1 = (toutx < touty) ? toutx : touty; + + if(tin2 > 0.0 || tout1 > 0.0) + { + if(tin2 <= tout1) + { + if(tin2 > 0.0) + { + if(tinx > tiny) + { + *x++ = (T)xin; + *y++ = (T)(y1 + tinx * deltay); + } + else + { + *x++ = (T)(x1 + tiny * deltax); + *y++ = (T)yin; + } + ++np; + } + + if(tout1 < 1.0) + { + if(toutx < touty) + { + *x++ = (T)xout; + *y++ = (T)(y1 + toutx * deltay); + } + else + { + *x++ = (T)(x1 + touty * deltax); + *y++ = (T)yout; + } + } + else + { + *x++ = x2; + *y++ = y2; + } + ++np; + } + else + { + if(tinx > tiny) + { + *x++ = (T)xin; + *y++ = (T)yout; + } + else + { + *x++ = (T)xout; + *y++ = (T)yin; + } + ++np; + } + } + } + } + return np; + } + + + //---------------------------------------------------------------------------- + template<class T> + bool clip_move_point(T x1, T y1, T x2, T y2, + const rect_base<T>& clip_box, + T* x, T* y, unsigned flags) + { + T bound; + + if(flags & clipping_flags_x_clipped) + { + if(x1 == x2) + { + return false; + } + bound = (flags & clipping_flags_x1_clipped) ? clip_box.x1 : clip_box.x2; + *y = (T)(double(bound - x1) * (y2 - y1) / (x2 - x1) + y1); + *x = bound; + } + + flags = clipping_flags_y(*y, clip_box); + if(flags & clipping_flags_y_clipped) + { + if(y1 == y2) + { + return false; + } + bound = (flags & clipping_flags_y1_clipped) ? clip_box.y1 : clip_box.y2; + *x = (T)(double(bound - y1) * (x2 - x1) / (y2 - y1) + x1); + *y = bound; + } + return true; + } + + //-------------------------------------------------------clip_line_segment + // Returns: ret >= 4 - Fully clipped + // (ret & 1) != 0 - First point has been moved + // (ret & 2) != 0 - Second point has been moved + // + template<class T> + unsigned clip_line_segment(T* x1, T* y1, T* x2, T* y2, + const rect_base<T>& clip_box) + { + unsigned f1 = clipping_flags(*x1, *y1, clip_box); + unsigned f2 = clipping_flags(*x2, *y2, clip_box); + unsigned ret = 0; + + if((f2 | f1) == 0) + { + // Fully visible + return 0; + } + + if((f1 & clipping_flags_x_clipped) != 0 && + (f1 & clipping_flags_x_clipped) == (f2 & clipping_flags_x_clipped)) + { + // Fully clipped + return 4; + } + + if((f1 & clipping_flags_y_clipped) != 0 && + (f1 & clipping_flags_y_clipped) == (f2 & clipping_flags_y_clipped)) + { + // Fully clipped + return 4; + } + + T tx1 = *x1; + T ty1 = *y1; + T tx2 = *x2; + T ty2 = *y2; + if(f1) + { + if(!clip_move_point(tx1, ty1, tx2, ty2, clip_box, x1, y1, f1)) + { + return 4; + } + if(*x1 == *x2 && *y1 == *y2) + { + return 4; + } + ret |= 1; + } + if(f2) + { + if(!clip_move_point(tx1, ty1, tx2, ty2, clip_box, x2, y2, f2)) + { + return 4; + } + if(*x1 == *x2 && *y1 == *y2) + { + return 4; + } + ret |= 2; + } + return ret; + } + + +} + + +#endif diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_color_gray.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_color_gray.h new file mode 100644 index 00000000000..8d5f2ed8d04 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_color_gray.h @@ -0,0 +1,1047 @@ +//---------------------------------------------------------------------------- +// 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. +// +//---------------------------------------------------------------------------- +// +// color types gray8, gray16 +// +//---------------------------------------------------------------------------- + +#ifndef AGG_COLOR_GRAY_INCLUDED +#define AGG_COLOR_GRAY_INCLUDED + +#include "agg_basics.h" +#include "agg_color_rgba.h" + +namespace agg +{ + + //===================================================================gray8 + template<class Colorspace> + struct gray8T + { + typedef int8u value_type; + typedef int32u calc_type; + typedef int32 long_type; + enum base_scale_e + { + base_shift = 8, + base_scale = 1 << base_shift, + base_mask = base_scale - 1, + base_MSB = 1 << (base_shift - 1) + }; + typedef gray8T self_type; + + value_type v; + value_type a; + + static value_type luminance(const rgba& c) + { + // Calculate grayscale value as per ITU-R BT.709. + return value_type(uround((0.2126 * c.r + 0.7152 * c.g + 0.0722 * c.b) * base_mask)); + } + + static value_type luminance(const rgba8& c) + { + // Calculate grayscale value as per ITU-R BT.709. + return value_type((55u * c.r + 184u * c.g + 18u * c.b) >> 8); + } + + static void convert(gray8T<linear>& dst, const gray8T<sRGB>& src) + { + dst.v = sRGB_conv<value_type>::rgb_from_sRGB(src.v); + dst.a = src.a; + } + + static void convert(gray8T<sRGB>& dst, const gray8T<linear>& src) + { + dst.v = sRGB_conv<value_type>::rgb_to_sRGB(src.v); + dst.a = src.a; + } + + static void convert(gray8T<linear>& dst, const rgba8& src) + { + dst.v = luminance(src); + dst.a = src.a; + } + + static void convert(gray8T<linear>& dst, const srgba8& src) + { + // The RGB weights are only valid for linear values. + convert(dst, rgba8(src)); + } + + static void convert(gray8T<sRGB>& dst, const rgba8& src) + { + dst.v = sRGB_conv<value_type>::rgb_to_sRGB(luminance(src)); + dst.a = src.a; + } + + static void convert(gray8T<sRGB>& dst, const srgba8& src) + { + // The RGB weights are only valid for linear values. + convert(dst, rgba8(src)); + } + + //-------------------------------------------------------------------- + gray8T() {} + + //-------------------------------------------------------------------- + explicit gray8T(unsigned v_, unsigned a_ = base_mask) : + v(int8u(v_)), a(int8u(a_)) {} + + //-------------------------------------------------------------------- + gray8T(const self_type& c, unsigned a_) : + v(c.v), a(value_type(a_)) {} + + //-------------------------------------------------------------------- + gray8T(const rgba& c) : + v(luminance(c)), + a(value_type(uround(c.a * base_mask))) {} + + //-------------------------------------------------------------------- + template<class T> + gray8T(const gray8T<T>& c) + { + convert(*this, c); + } + + //-------------------------------------------------------------------- + template<class T> + gray8T(const rgba8T<T>& c) + { + convert(*this, c); + } + + //-------------------------------------------------------------------- + template<class T> + T convert_from_sRGB() const + { + typename T::value_type y = sRGB_conv<typename T::value_type>::rgb_from_sRGB(v); + return T(y, y, y, sRGB_conv<typename T::value_type>::alpha_from_sRGB(a)); + } + + template<class T> + T convert_to_sRGB() const + { + typename T::value_type y = sRGB_conv<typename T::value_type>::rgb_to_sRGB(v); + return T(y, y, y, sRGB_conv<typename T::value_type>::alpha_to_sRGB(a)); + } + + //-------------------------------------------------------------------- + rgba8 make_rgba8(const linear&) const + { + return rgba8(v, v, v, a); + } + + rgba8 make_rgba8(const sRGB&) const + { + return convert_from_sRGB<srgba8>(); + } + + operator rgba8() const + { + return make_rgba8(Colorspace()); + } + + //-------------------------------------------------------------------- + srgba8 make_srgba8(const linear&) const + { + return convert_to_sRGB<rgba8>(); + } + + srgba8 make_srgba8(const sRGB&) const + { + return srgba8(v, v, v, a); + } + + operator srgba8() const + { + return make_rgba8(Colorspace()); + } + + //-------------------------------------------------------------------- + rgba16 make_rgba16(const linear&) const + { + rgba16::value_type rgb = (v << 8) | v; + return rgba16(rgb, rgb, rgb, (a << 8) | a); + } + + rgba16 make_rgba16(const sRGB&) const + { + return convert_from_sRGB<rgba16>(); + } + + operator rgba16() const + { + return make_rgba16(Colorspace()); + } + + //-------------------------------------------------------------------- + rgba32 make_rgba32(const linear&) const + { + rgba32::value_type v32 = v / 255.0f; + return rgba32(v32, v32, v32, a / 255.0f); + } + + rgba32 make_rgba32(const sRGB&) const + { + return convert_from_sRGB<rgba32>(); + } + + operator rgba32() const + { + return make_rgba32(Colorspace()); + } + + //-------------------------------------------------------------------- + static AGG_INLINE double to_double(value_type a) + { + return double(a) / base_mask; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type from_double(double a) + { + return value_type(uround(a * base_mask)); + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type empty_value() + { + return 0; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type full_value() + { + return base_mask; + } + + //-------------------------------------------------------------------- + AGG_INLINE bool is_transparent() const + { + return a == 0; + } + + //-------------------------------------------------------------------- + AGG_INLINE bool is_opaque() const + { + return a == base_mask; + } + + //-------------------------------------------------------------------- + // Fixed-point multiply, exact over int8u. + static AGG_INLINE value_type multiply(value_type a, value_type b) + { + calc_type t = a * b + base_MSB; + return value_type(((t >> base_shift) + t) >> base_shift); + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type demultiply(value_type a, value_type b) + { + if (a * b == 0) + { + return 0; + } + else if (a >= b) + { + return base_mask; + } + else return value_type((a * base_mask + (b >> 1)) / b); + } + + //-------------------------------------------------------------------- + template<typename T> + static AGG_INLINE T downscale(T a) + { + return a >> base_shift; + } + + //-------------------------------------------------------------------- + template<typename T> + static AGG_INLINE T downshift(T a, unsigned n) + { + return a >> n; + } + + //-------------------------------------------------------------------- + // Fixed-point multiply, exact over int8u. + // Specifically for multiplying a color component by a cover. + static AGG_INLINE value_type mult_cover(value_type a, value_type b) + { + return multiply(a, b); + } + + //-------------------------------------------------------------------- + static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) + { + return multiply(b, a); + } + + //-------------------------------------------------------------------- + // Interpolate p to q by a, assuming q is premultiplied by a. + static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a) + { + return p + q - multiply(p, a); + } + + //-------------------------------------------------------------------- + // Interpolate p to q by a. + static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a) + { + int t = (q - p) * a + base_MSB - (p > q); + return value_type(p + (((t >> base_shift) + t) >> base_shift)); + } + + //-------------------------------------------------------------------- + self_type& clear() + { + v = a = 0; + return *this; + } + + //-------------------------------------------------------------------- + self_type& transparent() + { + a = 0; + return *this; + } + + //-------------------------------------------------------------------- + self_type& opacity(double a_) + { + if (a_ < 0) a = 0; + else if (a_ > 1) a = 1; + else a = (value_type)uround(a_ * double(base_mask)); + return *this; + } + + //-------------------------------------------------------------------- + double opacity() const + { + return double(a) / double(base_mask); + } + + //-------------------------------------------------------------------- + self_type& premultiply() + { + if (a < base_mask) + { + if (a == 0) v = 0; + else v = multiply(v, a); + } + return *this; + } + + //-------------------------------------------------------------------- + self_type& demultiply() + { + if (a < base_mask) + { + if (a == 0) + { + v = 0; + } + else + { + calc_type v_ = (calc_type(v) * base_mask) / a; + v = value_type((v_ > base_mask) ? (value_type)base_mask : v_); + } + } + return *this; + } + + //-------------------------------------------------------------------- + self_type gradient(self_type c, double k) const + { + self_type ret; + calc_type ik = uround(k * base_scale); + ret.v = lerp(v, c.v, ik); + ret.a = lerp(a, c.a, ik); + return ret; + } + + //-------------------------------------------------------------------- + AGG_INLINE void add(const self_type& c, unsigned cover) + { + calc_type cv, ca; + if (cover == cover_mask) + { + if (c.a == base_mask) + { + *this = c; + return; + } + else + { + cv = v + c.v; + ca = a + c.a; + } + } + else + { + cv = v + mult_cover(c.v, cover); + ca = a + mult_cover(c.a, cover); + } + v = (value_type)((cv > calc_type(base_mask)) ? calc_type(base_mask) : cv); + a = (value_type)((ca > calc_type(base_mask)) ? calc_type(base_mask) : ca); + } + + //-------------------------------------------------------------------- + static self_type no_color() { return self_type(0,0); } + }; + + typedef gray8T<linear> gray8; + typedef gray8T<sRGB> sgray8; + + + //==================================================================gray16 + struct gray16 + { + typedef int16u value_type; + typedef int32u calc_type; + typedef int64 long_type; + enum base_scale_e + { + base_shift = 16, + base_scale = 1 << base_shift, + base_mask = base_scale - 1, + base_MSB = 1 << (base_shift - 1) + }; + typedef gray16 self_type; + + value_type v; + value_type a; + + static value_type luminance(const rgba& c) + { + // Calculate grayscale value as per ITU-R BT.709. + return value_type(uround((0.2126 * c.r + 0.7152 * c.g + 0.0722 * c.b) * base_mask)); + } + + static value_type luminance(const rgba16& c) + { + // Calculate grayscale value as per ITU-R BT.709. + return value_type((13933u * c.r + 46872u * c.g + 4732u * c.b) >> 16); + } + + static value_type luminance(const rgba8& c) + { + return luminance(rgba16(c)); + } + + static value_type luminance(const srgba8& c) + { + return luminance(rgba16(c)); + } + + static value_type luminance(const rgba32& c) + { + return luminance(rgba(c)); + } + + //-------------------------------------------------------------------- + gray16() {} + + //-------------------------------------------------------------------- + explicit gray16(unsigned v_, unsigned a_ = base_mask) : + v(int16u(v_)), a(int16u(a_)) {} + + //-------------------------------------------------------------------- + gray16(const self_type& c, unsigned a_) : + v(c.v), a(value_type(a_)) {} + + //-------------------------------------------------------------------- + gray16(const rgba& c) : + v(luminance(c)), + a((value_type)uround(c.a * double(base_mask))) {} + + //-------------------------------------------------------------------- + gray16(const rgba8& c) : + v(luminance(c)), + a((value_type(c.a) << 8) | c.a) {} + + //-------------------------------------------------------------------- + gray16(const srgba8& c) : + v(luminance(c)), + a((value_type(c.a) << 8) | c.a) {} + + //-------------------------------------------------------------------- + gray16(const rgba16& c) : + v(luminance(c)), + a(c.a) {} + + //-------------------------------------------------------------------- + gray16(const gray8& c) : + v((value_type(c.v) << 8) | c.v), + a((value_type(c.a) << 8) | c.a) {} + + //-------------------------------------------------------------------- + gray16(const sgray8& c) : + v(sRGB_conv<value_type>::rgb_from_sRGB(c.v)), + a(sRGB_conv<value_type>::alpha_from_sRGB(c.a)) {} + + //-------------------------------------------------------------------- + operator rgba8() const + { + return rgba8(v >> 8, v >> 8, v >> 8, a >> 8); + } + + //-------------------------------------------------------------------- + operator srgba8() const + { + value_type y = sRGB_conv<value_type>::rgb_to_sRGB(v); + return srgba8(y, y, y, sRGB_conv<value_type>::alpha_to_sRGB(a)); + } + + //-------------------------------------------------------------------- + operator rgba16() const + { + return rgba16(v, v, v, a); + } + + //-------------------------------------------------------------------- + operator rgba32() const + { + rgba32::value_type v32 = v / 65535.0f; + return rgba32(v32, v32, v32, a / 65535.0f); + } + + //-------------------------------------------------------------------- + operator gray8() const + { + return gray8(v >> 8, a >> 8); + } + + //-------------------------------------------------------------------- + operator sgray8() const + { + return sgray8( + sRGB_conv<value_type>::rgb_to_sRGB(v), + sRGB_conv<value_type>::alpha_to_sRGB(a)); + } + + //-------------------------------------------------------------------- + static AGG_INLINE double to_double(value_type a) + { + return double(a) / base_mask; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type from_double(double a) + { + return value_type(uround(a * base_mask)); + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type empty_value() + { + return 0; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type full_value() + { + return base_mask; + } + + //-------------------------------------------------------------------- + AGG_INLINE bool is_transparent() const + { + return a == 0; + } + + //-------------------------------------------------------------------- + AGG_INLINE bool is_opaque() const + { + return a == base_mask; + } + + //-------------------------------------------------------------------- + // Fixed-point multiply, exact over int16u. + static AGG_INLINE value_type multiply(value_type a, value_type b) + { + calc_type t = a * b + base_MSB; + return value_type(((t >> base_shift) + t) >> base_shift); + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type demultiply(value_type a, value_type b) + { + if (a * b == 0) + { + return 0; + } + else if (a >= b) + { + return base_mask; + } + else return value_type((a * base_mask + (b >> 1)) / b); + } + + //-------------------------------------------------------------------- + template<typename T> + static AGG_INLINE T downscale(T a) + { + return a >> base_shift; + } + + //-------------------------------------------------------------------- + template<typename T> + static AGG_INLINE T downshift(T a, unsigned n) + { + return a >> n; + } + + //-------------------------------------------------------------------- + // Fixed-point multiply, almost exact over int16u. + // Specifically for multiplying a color component by a cover. + static AGG_INLINE value_type mult_cover(value_type a, cover_type b) + { + return multiply(a, b << 8 | b); + } + + //-------------------------------------------------------------------- + static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) + { + return mult_cover(b, a) >> 8; + } + + //-------------------------------------------------------------------- + // Interpolate p to q by a, assuming q is premultiplied by a. + static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a) + { + return p + q - multiply(p, a); + } + + //-------------------------------------------------------------------- + // Interpolate p to q by a. + static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a) + { + int t = (q - p) * a + base_MSB - (p > q); + return value_type(p + (((t >> base_shift) + t) >> base_shift)); + } + + //-------------------------------------------------------------------- + self_type& clear() + { + v = a = 0; + return *this; + } + + //-------------------------------------------------------------------- + self_type& transparent() + { + a = 0; + return *this; + } + + //-------------------------------------------------------------------- + self_type& opacity(double a_) + { + if (a_ < 0) a = 0; + else if(a_ > 1) a = 1; + else a = (value_type)uround(a_ * double(base_mask)); + return *this; + } + + //-------------------------------------------------------------------- + double opacity() const + { + return double(a) / double(base_mask); + } + + + //-------------------------------------------------------------------- + self_type& premultiply() + { + if (a < base_mask) + { + if(a == 0) v = 0; + else v = multiply(v, a); + } + return *this; + } + + //-------------------------------------------------------------------- + self_type& demultiply() + { + if (a < base_mask) + { + if (a == 0) + { + v = 0; + } + else + { + calc_type v_ = (calc_type(v) * base_mask) / a; + v = value_type((v_ > base_mask) ? base_mask : v_); + } + } + return *this; + } + + //-------------------------------------------------------------------- + self_type gradient(self_type c, double k) const + { + self_type ret; + calc_type ik = uround(k * base_scale); + ret.v = lerp(v, c.v, ik); + ret.a = lerp(a, c.a, ik); + return ret; + } + + //-------------------------------------------------------------------- + AGG_INLINE void add(const self_type& c, unsigned cover) + { + calc_type cv, ca; + if (cover == cover_mask) + { + if (c.a == base_mask) + { + *this = c; + return; + } + else + { + cv = v + c.v; + ca = a + c.a; + } + } + else + { + cv = v + mult_cover(c.v, cover); + ca = a + mult_cover(c.a, cover); + } + v = (value_type)((cv > calc_type(base_mask)) ? calc_type(base_mask) : cv); + a = (value_type)((ca > calc_type(base_mask)) ? calc_type(base_mask) : ca); + } + + //-------------------------------------------------------------------- + static self_type no_color() { return self_type(0,0); } + }; + + + //===================================================================gray32 + struct gray32 + { + typedef float value_type; + typedef double calc_type; + typedef double long_type; + typedef gray32 self_type; + + value_type v; + value_type a; + + // Calculate grayscale value as per ITU-R BT.709. + static value_type luminance(double r, double g, double b) + { + return value_type(0.2126 * r + 0.7152 * g + 0.0722 * b); + } + + static value_type luminance(const rgba& c) + { + return luminance(c.r, c.g, c.b); + } + + static value_type luminance(const rgba32& c) + { + return luminance(c.r, c.g, c.b); + } + + static value_type luminance(const rgba8& c) + { + return luminance(c.r / 255.0, c.g / 255.0, c.g / 255.0); + } + + static value_type luminance(const rgba16& c) + { + return luminance(c.r / 65535.0, c.g / 65535.0, c.g / 65535.0); + } + + //-------------------------------------------------------------------- + gray32() {} + + //-------------------------------------------------------------------- + explicit gray32(value_type v_, value_type a_ = 1) : + v(v_), a(a_) {} + + //-------------------------------------------------------------------- + gray32(const self_type& c, value_type a_) : + v(c.v), a(a_) {} + + //-------------------------------------------------------------------- + gray32(const rgba& c) : + v(luminance(c)), + a(value_type(c.a)) {} + + //-------------------------------------------------------------------- + gray32(const rgba8& c) : + v(luminance(c)), + a(value_type(c.a / 255.0)) {} + + //-------------------------------------------------------------------- + gray32(const srgba8& c) : + v(luminance(rgba32(c))), + a(value_type(c.a / 255.0)) {} + + //-------------------------------------------------------------------- + gray32(const rgba16& c) : + v(luminance(c)), + a(value_type(c.a / 65535.0)) {} + + //-------------------------------------------------------------------- + gray32(const rgba32& c) : + v(luminance(c)), + a(value_type(c.a)) {} + + //-------------------------------------------------------------------- + gray32(const gray8& c) : + v(value_type(c.v / 255.0)), + a(value_type(c.a / 255.0)) {} + + //-------------------------------------------------------------------- + gray32(const sgray8& c) : + v(sRGB_conv<value_type>::rgb_from_sRGB(c.v)), + a(sRGB_conv<value_type>::alpha_from_sRGB(c.a)) {} + + //-------------------------------------------------------------------- + gray32(const gray16& c) : + v(value_type(c.v / 65535.0)), + a(value_type(c.a / 65535.0)) {} + + //-------------------------------------------------------------------- + operator rgba() const + { + return rgba(v, v, v, a); + } + + //-------------------------------------------------------------------- + operator gray8() const + { + return gray8(uround(v * 255.0), uround(a * 255.0)); + } + + //-------------------------------------------------------------------- + operator sgray8() const + { + // Return (non-premultiplied) sRGB values. + return sgray8( + sRGB_conv<value_type>::rgb_to_sRGB(v), + sRGB_conv<value_type>::alpha_to_sRGB(a)); + } + + //-------------------------------------------------------------------- + operator gray16() const + { + return gray16(uround(v * 65535.0), uround(a * 65535.0)); + } + + //-------------------------------------------------------------------- + operator rgba8() const + { + rgba8::value_type y = uround(v * 255.0); + return rgba8(y, y, y, uround(a * 255.0)); + } + + //-------------------------------------------------------------------- + operator srgba8() const + { + srgba8::value_type y = sRGB_conv<value_type>::rgb_to_sRGB(v); + return srgba8(y, y, y, sRGB_conv<value_type>::alpha_to_sRGB(a)); + } + + //-------------------------------------------------------------------- + operator rgba16() const + { + rgba16::value_type y = uround(v * 65535.0); + return rgba16(y, y, y, uround(a * 65535.0)); + } + + //-------------------------------------------------------------------- + operator rgba32() const + { + return rgba32(v, v, v, a); + } + + //-------------------------------------------------------------------- + static AGG_INLINE double to_double(value_type a) + { + return a; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type from_double(double a) + { + return value_type(a); + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type empty_value() + { + return 0; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type full_value() + { + return 1; + } + + //-------------------------------------------------------------------- + AGG_INLINE bool is_transparent() const + { + return a <= 0; + } + + //-------------------------------------------------------------------- + AGG_INLINE bool is_opaque() const + { + return a >= 1; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type invert(value_type x) + { + return 1 - x; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type multiply(value_type a, value_type b) + { + return value_type(a * b); + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type demultiply(value_type a, value_type b) + { + return (b == 0) ? 0 : value_type(a / b); + } + + //-------------------------------------------------------------------- + template<typename T> + static AGG_INLINE T downscale(T a) + { + return a; + } + + //-------------------------------------------------------------------- + template<typename T> + static AGG_INLINE T downshift(T a, unsigned n) + { + return n > 0 ? a / (1 << n) : a; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type mult_cover(value_type a, cover_type b) + { + return value_type(a * b / cover_mask); + } + + //-------------------------------------------------------------------- + static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) + { + return cover_type(uround(a * b)); + } + + //-------------------------------------------------------------------- + // Interpolate p to q by a, assuming q is premultiplied by a. + static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a) + { + return (1 - a) * p + q; // more accurate than "p + q - p * a" + } + + //-------------------------------------------------------------------- + // Interpolate p to q by a. + static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a) + { + // The form "p + a * (q - p)" avoids a multiplication, but may produce an + // inaccurate result. For example, "p + (q - p)" may not be exactly equal + // to q. Therefore, stick to the basic expression, which at least produces + // the correct result at either extreme. + return (1 - a) * p + a * q; + } + + //-------------------------------------------------------------------- + self_type& clear() + { + v = a = 0; + return *this; + } + + //-------------------------------------------------------------------- + self_type& transparent() + { + a = 0; + return *this; + } + + //-------------------------------------------------------------------- + self_type& opacity(double a_) + { + if (a_ < 0) a = 0; + else if (a_ > 1) a = 1; + else a = value_type(a_); + return *this; + } + + //-------------------------------------------------------------------- + double opacity() const + { + return a; + } + + + //-------------------------------------------------------------------- + self_type& premultiply() + { + if (a < 0) v = 0; + else if(a < 1) v *= a; + return *this; + } + + //-------------------------------------------------------------------- + self_type& demultiply() + { + if (a < 0) v = 0; + else if (a < 1) v /= a; + return *this; + } + + //-------------------------------------------------------------------- + self_type gradient(self_type c, double k) const + { + return self_type( + value_type(v + (c.v - v) * k), + value_type(a + (c.a - a) * k)); + } + + //-------------------------------------------------------------------- + static self_type no_color() { return self_type(0,0); } + }; +} + + + + +#endif diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_color_rgba.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_color_rgba.h new file mode 100644 index 00000000000..74f871be17b --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_color_rgba.h @@ -0,0 +1,1353 @@ +//---------------------------------------------------------------------------- +// 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. +// +//---------------------------------------------------------------------------- +// +// 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. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- + +#ifndef AGG_COLOR_RGBA_INCLUDED +#define AGG_COLOR_RGBA_INCLUDED + +#include <math.h> +#include "agg_basics.h" +#include "agg_gamma_lut.h" + +namespace agg +{ + // Supported component orders for RGB and RGBA pixel formats + //======================================================================= + struct order_rgb { enum rgb_e { R=0, G=1, B=2, N=3 }; }; + struct order_bgr { enum bgr_e { B=0, G=1, R=2, N=3 }; }; + struct order_rgba { enum rgba_e { R=0, G=1, B=2, A=3, N=4 }; }; + struct order_argb { enum argb_e { A=0, R=1, G=2, B=3, N=4 }; }; + struct order_abgr { enum abgr_e { A=0, B=1, G=2, R=3, N=4 }; }; + struct order_bgra { enum bgra_e { B=0, G=1, R=2, A=3, N=4 }; }; + + // Colorspace tag types. + struct linear {}; + struct sRGB {}; + + //====================================================================rgba + struct rgba + { + typedef double value_type; + + double r; + double g; + double b; + double a; + + //-------------------------------------------------------------------- + rgba() {} + + //-------------------------------------------------------------------- + rgba(double r_, double g_, double b_, double a_=1.0) : + r(r_), g(g_), b(b_), a(a_) {} + + //-------------------------------------------------------------------- + rgba(const rgba& c, double a_) : r(c.r), g(c.g), b(c.b), a(a_) {} + + //-------------------------------------------------------------------- + rgba& clear() + { + r = g = b = a = 0; + return *this; + } + + //-------------------------------------------------------------------- + rgba& transparent() + { + a = 0; + return *this; + } + + //-------------------------------------------------------------------- + rgba& opacity(double a_) + { + if (a_ < 0) a = 0; + else if (a_ > 1) a = 1; + else a = a_; + return *this; + } + + //-------------------------------------------------------------------- + double opacity() const + { + return a; + } + + //-------------------------------------------------------------------- + rgba& premultiply() + { + r *= a; + g *= a; + b *= a; + return *this; + } + + //-------------------------------------------------------------------- + rgba& premultiply(double a_) + { + if (a <= 0 || a_ <= 0) + { + r = g = b = a = 0; + } + else + { + a_ /= a; + r *= a_; + g *= a_; + b *= a_; + a = a_; + } + return *this; + } + + //-------------------------------------------------------------------- + rgba& demultiply() + { + if (a == 0) + { + r = g = b = 0; + } + else + { + double a_ = 1.0 / a; + r *= a_; + g *= a_; + b *= a_; + } + return *this; + } + + + //-------------------------------------------------------------------- + rgba gradient(rgba c, double k) const + { + rgba ret; + ret.r = r + (c.r - r) * k; + ret.g = g + (c.g - g) * k; + ret.b = b + (c.b - b) * k; + ret.a = a + (c.a - a) * k; + return ret; + } + + rgba& operator+=(const rgba& c) + { + r += c.r; + g += c.g; + b += c.b; + a += c.a; + return *this; + } + + rgba& operator*=(double k) + { + r *= k; + g *= k; + b *= k; + a *= k; + return *this; + } + + //-------------------------------------------------------------------- + static rgba no_color() { return rgba(0,0,0,0); } + + //-------------------------------------------------------------------- + static rgba from_wavelength(double wl, double gamma = 1.0); + + //-------------------------------------------------------------------- + explicit rgba(double wavelen, double gamma=1.0) + { + *this = from_wavelength(wavelen, gamma); + } + + }; + + inline rgba operator+(const rgba& a, const rgba& b) + { + return rgba(a) += b; + } + + inline rgba operator*(const rgba& a, double b) + { + return rgba(a) *= b; + } + + //------------------------------------------------------------------------ + inline rgba rgba::from_wavelength(double wl, double gamma) + { + rgba t(0.0, 0.0, 0.0); + + if (wl >= 380.0 && wl <= 440.0) + { + t.r = -1.0 * (wl - 440.0) / (440.0 - 380.0); + t.b = 1.0; + } + else if (wl >= 440.0 && wl <= 490.0) + { + t.g = (wl - 440.0) / (490.0 - 440.0); + t.b = 1.0; + } + else if (wl >= 490.0 && wl <= 510.0) + { + t.g = 1.0; + t.b = -1.0 * (wl - 510.0) / (510.0 - 490.0); + } + else if (wl >= 510.0 && wl <= 580.0) + { + t.r = (wl - 510.0) / (580.0 - 510.0); + t.g = 1.0; + } + else if (wl >= 580.0 && wl <= 645.0) + { + t.r = 1.0; + t.g = -1.0 * (wl - 645.0) / (645.0 - 580.0); + } + else if (wl >= 645.0 && wl <= 780.0) + { + t.r = 1.0; + } + + double s = 1.0; + if (wl > 700.0) s = 0.3 + 0.7 * (780.0 - wl) / (780.0 - 700.0); + else if (wl < 420.0) s = 0.3 + 0.7 * (wl - 380.0) / (420.0 - 380.0); + + t.r = pow(t.r * s, gamma); + t.g = pow(t.g * s, gamma); + t.b = pow(t.b * s, gamma); + return t; + } + + inline rgba rgba_pre(double r, double g, double b, double a) + { + return rgba(r, g, b, a).premultiply(); + } + + + //===================================================================rgba8 + template<class Colorspace> + struct rgba8T + { + typedef int8u value_type; + typedef int32u calc_type; + typedef int32 long_type; + enum base_scale_e + { + base_shift = 8, + base_scale = 1 << base_shift, + base_mask = base_scale - 1, + base_MSB = 1 << (base_shift - 1) + }; + typedef rgba8T self_type; + + + value_type r; + value_type g; + value_type b; + value_type a; + + static void convert(rgba8T<linear>& dst, const rgba8T<sRGB>& src) + { + dst.r = sRGB_conv<value_type>::rgb_from_sRGB(src.r); + dst.g = sRGB_conv<value_type>::rgb_from_sRGB(src.g); + dst.b = sRGB_conv<value_type>::rgb_from_sRGB(src.b); + dst.a = src.a; + } + + static void convert(rgba8T<sRGB>& dst, const rgba8T<linear>& src) + { + dst.r = sRGB_conv<value_type>::rgb_to_sRGB(src.r); + dst.g = sRGB_conv<value_type>::rgb_to_sRGB(src.g); + dst.b = sRGB_conv<value_type>::rgb_to_sRGB(src.b); + dst.a = src.a; + } + + static void convert(rgba8T<linear>& dst, const rgba& src) + { + dst.r = value_type(uround(src.r * base_mask)); + dst.g = value_type(uround(src.g * base_mask)); + dst.b = value_type(uround(src.b * base_mask)); + dst.a = value_type(uround(src.a * base_mask)); + } + + static void convert(rgba8T<sRGB>& dst, const rgba& src) + { + // Use the "float" table. + dst.r = sRGB_conv<float>::rgb_to_sRGB(float(src.r)); + dst.g = sRGB_conv<float>::rgb_to_sRGB(float(src.g)); + dst.b = sRGB_conv<float>::rgb_to_sRGB(float(src.b)); + dst.a = sRGB_conv<float>::alpha_to_sRGB(float(src.a)); + } + + static void convert(rgba& dst, const rgba8T<linear>& src) + { + dst.r = src.r / 255.0; + dst.g = src.g / 255.0; + dst.b = src.b / 255.0; + dst.a = src.a / 255.0; + } + + static void convert(rgba& dst, const rgba8T<sRGB>& src) + { + // Use the "float" table. + dst.r = sRGB_conv<float>::rgb_from_sRGB(src.r); + dst.g = sRGB_conv<float>::rgb_from_sRGB(src.g); + dst.b = sRGB_conv<float>::rgb_from_sRGB(src.b); + dst.a = sRGB_conv<float>::alpha_from_sRGB(src.a); + } + + //-------------------------------------------------------------------- + rgba8T() {} + + //-------------------------------------------------------------------- + rgba8T(unsigned r_, unsigned g_, unsigned b_, unsigned a_ = base_mask) : + r(value_type(r_)), + g(value_type(g_)), + b(value_type(b_)), + a(value_type(a_)) {} + + //-------------------------------------------------------------------- + rgba8T(const rgba& c) + { + convert(*this, c); + } + + //-------------------------------------------------------------------- + rgba8T(const self_type& c, unsigned a_) : + r(c.r), g(c.g), b(c.b), a(value_type(a_)) {} + + //-------------------------------------------------------------------- + template<class T> + rgba8T(const rgba8T<T>& c) + { + convert(*this, c); + } + + //-------------------------------------------------------------------- + operator rgba() const + { + rgba c; + convert(c, *this); + return c; + } + + //-------------------------------------------------------------------- + static AGG_INLINE double to_double(value_type a) + { + return double(a) / base_mask; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type from_double(double a) + { + return value_type(uround(a * base_mask)); + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type empty_value() + { + return 0; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type full_value() + { + return base_mask; + } + + //-------------------------------------------------------------------- + AGG_INLINE bool is_transparent() const + { + return a == 0; + } + + //-------------------------------------------------------------------- + AGG_INLINE bool is_opaque() const + { + return a == base_mask; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type invert(value_type x) + { + return base_mask - x; + } + + //-------------------------------------------------------------------- + // Fixed-point multiply, exact over int8u. + static AGG_INLINE value_type multiply(value_type a, value_type b) + { + calc_type t = a * b + base_MSB; + return value_type(((t >> base_shift) + t) >> base_shift); + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type demultiply(value_type a, value_type b) + { + if (a * b == 0) + { + return 0; + } + else if (a >= b) + { + return base_mask; + } + else return value_type((a * base_mask + (b >> 1)) / b); + } + + //-------------------------------------------------------------------- + template<typename T> + static AGG_INLINE T downscale(T a) + { + return a >> base_shift; + } + + //-------------------------------------------------------------------- + template<typename T> + static AGG_INLINE T downshift(T a, unsigned n) + { + return a >> n; + } + + //-------------------------------------------------------------------- + // Fixed-point multiply, exact over int8u. + // Specifically for multiplying a color component by a cover. + static AGG_INLINE value_type mult_cover(value_type a, cover_type b) + { + return multiply(a, b); + } + + //-------------------------------------------------------------------- + static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) + { + return multiply(b, a); + } + + //-------------------------------------------------------------------- + // Interpolate p to q by a, assuming q is premultiplied by a. + static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a) + { + return p + q - multiply(p, a); + } + + //-------------------------------------------------------------------- + // Interpolate p to q by a. + static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a) + { + int t = (q - p) * a + base_MSB - (p > q); + return value_type(p + (((t >> base_shift) + t) >> base_shift)); + } + + //-------------------------------------------------------------------- + self_type& clear() + { + r = g = b = a = 0; + return *this; + } + + //-------------------------------------------------------------------- + self_type& transparent() + { + a = 0; + return *this; + } + + //-------------------------------------------------------------------- + self_type& opacity(double a_) + { + if (a_ < 0) a = 0; + else if (a_ > 1) a = 1; + else a = (value_type)uround(a_ * double(base_mask)); + return *this; + } + + //-------------------------------------------------------------------- + double opacity() const + { + return double(a) / double(base_mask); + } + + //-------------------------------------------------------------------- + AGG_INLINE self_type& premultiply() + { + if (a != base_mask) + { + if (a == 0) + { + r = g = b = 0; + } + else + { + r = multiply(r, a); + g = multiply(g, a); + b = multiply(b, a); + } + } + return *this; + } + + //-------------------------------------------------------------------- + AGG_INLINE self_type& premultiply(unsigned a_) + { + if (a != base_mask || a_ < base_mask) + { + if (a == 0 || a_ == 0) + { + r = g = b = a = 0; + } + else + { + calc_type r_ = (calc_type(r) * a_) / a; + calc_type g_ = (calc_type(g) * a_) / a; + calc_type b_ = (calc_type(b) * a_) / a; + r = value_type((r_ > a_) ? a_ : r_); + g = value_type((g_ > a_) ? a_ : g_); + b = value_type((b_ > a_) ? a_ : b_); + a = value_type(a_); + } + } + return *this; + } + + //-------------------------------------------------------------------- + AGG_INLINE self_type& demultiply() + { + if (a < base_mask) + { + if (a == 0) + { + r = g = b = 0; + } + else + { + calc_type r_ = (calc_type(r) * base_mask) / a; + calc_type g_ = (calc_type(g) * base_mask) / a; + calc_type b_ = (calc_type(b) * base_mask) / a; + r = value_type((r_ > calc_type(base_mask)) ? calc_type(base_mask) : r_); + g = value_type((g_ > calc_type(base_mask)) ? calc_type(base_mask) : g_); + b = value_type((b_ > calc_type(base_mask)) ? calc_type(base_mask) : b_); + } + } + return *this; + } + + //-------------------------------------------------------------------- + AGG_INLINE self_type gradient(const self_type& c, double k) const + { + self_type ret; + calc_type ik = uround(k * base_mask); + ret.r = lerp(r, c.r, ik); + ret.g = lerp(g, c.g, ik); + ret.b = lerp(b, c.b, ik); + ret.a = lerp(a, c.a, ik); + return ret; + } + + //-------------------------------------------------------------------- + AGG_INLINE void add(const self_type& c, unsigned cover) + { + calc_type cr, cg, cb, ca; + if (cover == cover_mask) + { + if (c.a == base_mask) + { + *this = c; + return; + } + else + { + cr = r + c.r; + cg = g + c.g; + cb = b + c.b; + ca = a + c.a; + } + } + else + { + cr = r + mult_cover(c.r, cover); + cg = g + mult_cover(c.g, cover); + cb = b + mult_cover(c.b, cover); + ca = a + mult_cover(c.a, cover); + } + r = (value_type)((cr > calc_type(base_mask)) ? calc_type(base_mask) : cr); + g = (value_type)((cg > calc_type(base_mask)) ? calc_type(base_mask) : cg); + b = (value_type)((cb > calc_type(base_mask)) ? calc_type(base_mask) : cb); + a = (value_type)((ca > calc_type(base_mask)) ? calc_type(base_mask) : ca); + } + + //-------------------------------------------------------------------- + template<class GammaLUT> + AGG_INLINE void apply_gamma_dir(const GammaLUT& gamma) + { + r = gamma.dir(r); + g = gamma.dir(g); + b = gamma.dir(b); + } + + //-------------------------------------------------------------------- + template<class GammaLUT> + AGG_INLINE void apply_gamma_inv(const GammaLUT& gamma) + { + r = gamma.inv(r); + g = gamma.inv(g); + b = gamma.inv(b); + } + + //-------------------------------------------------------------------- + static self_type no_color() { return self_type(0,0,0,0); } + + //-------------------------------------------------------------------- + static self_type from_wavelength(double wl, double gamma = 1.0) + { + return self_type(rgba::from_wavelength(wl, gamma)); + } + }; + + typedef rgba8T<linear> rgba8; + typedef rgba8T<sRGB> srgba8; + + + //-------------------------------------------------------------rgb8_packed + inline rgba8 rgb8_packed(unsigned v) + { + return rgba8((v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF); + } + + //-------------------------------------------------------------bgr8_packed + inline rgba8 bgr8_packed(unsigned v) + { + return rgba8(v & 0xFF, (v >> 8) & 0xFF, (v >> 16) & 0xFF); + } + + //------------------------------------------------------------argb8_packed + inline rgba8 argb8_packed(unsigned v) + { + return rgba8((v >> 16) & 0xFF, (v >> 8) & 0xFF, v & 0xFF, v >> 24); + } + + //---------------------------------------------------------rgba8_gamma_dir + template<class GammaLUT> + rgba8 rgba8_gamma_dir(rgba8 c, const GammaLUT& gamma) + { + return rgba8(gamma.dir(c.r), gamma.dir(c.g), gamma.dir(c.b), c.a); + } + + //---------------------------------------------------------rgba8_gamma_inv + template<class GammaLUT> + rgba8 rgba8_gamma_inv(rgba8 c, const GammaLUT& gamma) + { + return rgba8(gamma.inv(c.r), gamma.inv(c.g), gamma.inv(c.b), c.a); + } + + + + //==================================================================rgba16 + struct rgba16 + { + typedef int16u value_type; + typedef int32u calc_type; + typedef int64 long_type; + enum base_scale_e + { + base_shift = 16, + base_scale = 1 << base_shift, + base_mask = base_scale - 1, + base_MSB = 1 << (base_shift - 1) + }; + typedef rgba16 self_type; + + value_type r; + value_type g; + value_type b; + value_type a; + + //-------------------------------------------------------------------- + rgba16() {} + + //-------------------------------------------------------------------- + rgba16(unsigned r_, unsigned g_, unsigned b_, unsigned a_=base_mask) : + r(value_type(r_)), + g(value_type(g_)), + b(value_type(b_)), + a(value_type(a_)) {} + + //-------------------------------------------------------------------- + rgba16(const self_type& c, unsigned a_) : + r(c.r), g(c.g), b(c.b), a(value_type(a_)) {} + + //-------------------------------------------------------------------- + rgba16(const rgba& c) : + r((value_type)uround(c.r * double(base_mask))), + g((value_type)uround(c.g * double(base_mask))), + b((value_type)uround(c.b * double(base_mask))), + a((value_type)uround(c.a * double(base_mask))) {} + + //-------------------------------------------------------------------- + rgba16(const rgba8& c) : + r(value_type((value_type(c.r) << 8) | c.r)), + g(value_type((value_type(c.g) << 8) | c.g)), + b(value_type((value_type(c.b) << 8) | c.b)), + a(value_type((value_type(c.a) << 8) | c.a)) {} + + //-------------------------------------------------------------------- + rgba16(const srgba8& c) : + r(sRGB_conv<value_type>::rgb_from_sRGB(c.r)), + g(sRGB_conv<value_type>::rgb_from_sRGB(c.g)), + b(sRGB_conv<value_type>::rgb_from_sRGB(c.b)), + a(sRGB_conv<value_type>::alpha_from_sRGB(c.a)) {} + + //-------------------------------------------------------------------- + operator rgba() const + { + return rgba( + r / 65535.0, + g / 65535.0, + b / 65535.0, + a / 65535.0); + } + + //-------------------------------------------------------------------- + operator rgba8() const + { + return rgba8(r >> 8, g >> 8, b >> 8, a >> 8); + } + + //-------------------------------------------------------------------- + operator srgba8() const + { + // Return (non-premultiplied) sRGB values. + return srgba8( + sRGB_conv<value_type>::rgb_to_sRGB(r), + sRGB_conv<value_type>::rgb_to_sRGB(g), + sRGB_conv<value_type>::rgb_to_sRGB(b), + sRGB_conv<value_type>::alpha_to_sRGB(a)); + } + + //-------------------------------------------------------------------- + static AGG_INLINE double to_double(value_type a) + { + return double(a) / base_mask; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type from_double(double a) + { + return value_type(uround(a * base_mask)); + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type empty_value() + { + return 0; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type full_value() + { + return base_mask; + } + + //-------------------------------------------------------------------- + AGG_INLINE bool is_transparent() const + { + return a == 0; + } + + //-------------------------------------------------------------------- + AGG_INLINE bool is_opaque() const + { + return a == base_mask; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type invert(value_type x) + { + return base_mask - x; + } + + //-------------------------------------------------------------------- + // Fixed-point multiply, exact over int16u. + static AGG_INLINE value_type multiply(value_type a, value_type b) + { + calc_type t = a * b + base_MSB; + return value_type(((t >> base_shift) + t) >> base_shift); + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type demultiply(value_type a, value_type b) + { + if (a * b == 0) + { + return 0; + } + else if (a >= b) + { + return base_mask; + } + else return value_type((a * base_mask + (b >> 1)) / b); + } + + //-------------------------------------------------------------------- + template<typename T> + static AGG_INLINE T downscale(T a) + { + return a >> base_shift; + } + + //-------------------------------------------------------------------- + template<typename T> + static AGG_INLINE T downshift(T a, unsigned n) + { + return a >> n; + } + + //-------------------------------------------------------------------- + // Fixed-point multiply, almost exact over int16u. + // Specifically for multiplying a color component by a cover. + static AGG_INLINE value_type mult_cover(value_type a, cover_type b) + { + return multiply(a, (b << 8) | b); + } + + //-------------------------------------------------------------------- + static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) + { + return multiply((a << 8) | a, b) >> 8; + } + + //-------------------------------------------------------------------- + // Interpolate p to q by a, assuming q is premultiplied by a. + static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a) + { + return p + q - multiply(p, a); + } + + //-------------------------------------------------------------------- + // Interpolate p to q by a. + static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a) + { + int t = (q - p) * a + base_MSB - (p > q); + return value_type(p + (((t >> base_shift) + t) >> base_shift)); + } + + //-------------------------------------------------------------------- + self_type& clear() + { + r = g = b = a = 0; + return *this; + } + + //-------------------------------------------------------------------- + self_type& transparent() + { + a = 0; + return *this; + } + + //-------------------------------------------------------------------- + AGG_INLINE self_type& opacity(double a_) + { + if (a_ < 0) a = 0; + if (a_ > 1) a = 1; + a = value_type(uround(a_ * double(base_mask))); + return *this; + } + + //-------------------------------------------------------------------- + double opacity() const + { + return double(a) / double(base_mask); + } + + //-------------------------------------------------------------------- + AGG_INLINE self_type& premultiply() + { + if (a != base_mask) + { + if (a == 0) + { + r = g = b = 0; + } + else + { + r = multiply(r, a); + g = multiply(g, a); + b = multiply(b, a); + } + } + return *this; + } + + //-------------------------------------------------------------------- + AGG_INLINE self_type& premultiply(unsigned a_) + { + if (a < base_mask || a_ < base_mask) + { + if (a == 0 || a_ == 0) + { + r = g = b = a = 0; + } + else + { + calc_type r_ = (calc_type(r) * a_) / a; + calc_type g_ = (calc_type(g) * a_) / a; + calc_type b_ = (calc_type(b) * a_) / a; + r = value_type((r_ > a_) ? a_ : r_); + g = value_type((g_ > a_) ? a_ : g_); + b = value_type((b_ > a_) ? a_ : b_); + a = value_type(a_); + } + } + return *this; + } + + //-------------------------------------------------------------------- + AGG_INLINE self_type& demultiply() + { + if (a < base_mask) + { + if (a == 0) + { + r = g = b = 0; + } + else + { + calc_type r_ = (calc_type(r) * base_mask) / a; + calc_type g_ = (calc_type(g) * base_mask) / a; + calc_type b_ = (calc_type(b) * base_mask) / a; + r = value_type((r_ > calc_type(base_mask)) ? calc_type(base_mask) : r_); + g = value_type((g_ > calc_type(base_mask)) ? calc_type(base_mask) : g_); + b = value_type((b_ > calc_type(base_mask)) ? calc_type(base_mask) : b_); + } + } + return *this; + } + + //-------------------------------------------------------------------- + AGG_INLINE self_type gradient(const self_type& c, double k) const + { + self_type ret; + calc_type ik = uround(k * base_mask); + ret.r = lerp(r, c.r, ik); + ret.g = lerp(g, c.g, ik); + ret.b = lerp(b, c.b, ik); + ret.a = lerp(a, c.a, ik); + return ret; + } + + //-------------------------------------------------------------------- + AGG_INLINE void add(const self_type& c, unsigned cover) + { + calc_type cr, cg, cb, ca; + if (cover == cover_mask) + { + if (c.a == base_mask) + { + *this = c; + return; + } + else + { + cr = r + c.r; + cg = g + c.g; + cb = b + c.b; + ca = a + c.a; + } + } + else + { + cr = r + mult_cover(c.r, cover); + cg = g + mult_cover(c.g, cover); + cb = b + mult_cover(c.b, cover); + ca = a + mult_cover(c.a, cover); + } + r = (value_type)((cr > calc_type(base_mask)) ? calc_type(base_mask) : cr); + g = (value_type)((cg > calc_type(base_mask)) ? calc_type(base_mask) : cg); + b = (value_type)((cb > calc_type(base_mask)) ? calc_type(base_mask) : cb); + a = (value_type)((ca > calc_type(base_mask)) ? calc_type(base_mask) : ca); + } + + //-------------------------------------------------------------------- + template<class GammaLUT> + AGG_INLINE void apply_gamma_dir(const GammaLUT& gamma) + { + r = gamma.dir(r); + g = gamma.dir(g); + b = gamma.dir(b); + } + + //-------------------------------------------------------------------- + template<class GammaLUT> + AGG_INLINE void apply_gamma_inv(const GammaLUT& gamma) + { + r = gamma.inv(r); + g = gamma.inv(g); + b = gamma.inv(b); + } + + //-------------------------------------------------------------------- + static self_type no_color() { return self_type(0,0,0,0); } + + //-------------------------------------------------------------------- + static self_type from_wavelength(double wl, double gamma = 1.0) + { + return self_type(rgba::from_wavelength(wl, gamma)); + } + }; + + + //------------------------------------------------------rgba16_gamma_dir + template<class GammaLUT> + rgba16 rgba16_gamma_dir(rgba16 c, const GammaLUT& gamma) + { + return rgba16(gamma.dir(c.r), gamma.dir(c.g), gamma.dir(c.b), c.a); + } + + //------------------------------------------------------rgba16_gamma_inv + template<class GammaLUT> + rgba16 rgba16_gamma_inv(rgba16 c, const GammaLUT& gamma) + { + return rgba16(gamma.inv(c.r), gamma.inv(c.g), gamma.inv(c.b), c.a); + } + + //====================================================================rgba32 + struct rgba32 + { + typedef float value_type; + typedef double calc_type; + typedef double long_type; + typedef rgba32 self_type; + + value_type r; + value_type g; + value_type b; + value_type a; + + //-------------------------------------------------------------------- + rgba32() {} + + //-------------------------------------------------------------------- + rgba32(value_type r_, value_type g_, value_type b_, value_type a_= 1) : + r(r_), g(g_), b(b_), a(a_) {} + + //-------------------------------------------------------------------- + rgba32(const self_type& c, float a_) : + r(c.r), g(c.g), b(c.b), a(a_) {} + + //-------------------------------------------------------------------- + rgba32(const rgba& c) : + r(value_type(c.r)), g(value_type(c.g)), b(value_type(c.b)), a(value_type(c.a)) {} + + //-------------------------------------------------------------------- + rgba32(const rgba8& c) : + r(value_type(c.r / 255.0)), + g(value_type(c.g / 255.0)), + b(value_type(c.b / 255.0)), + a(value_type(c.a / 255.0)) {} + + //-------------------------------------------------------------------- + rgba32(const srgba8& c) : + r(sRGB_conv<value_type>::rgb_from_sRGB(c.r)), + g(sRGB_conv<value_type>::rgb_from_sRGB(c.g)), + b(sRGB_conv<value_type>::rgb_from_sRGB(c.b)), + a(sRGB_conv<value_type>::alpha_from_sRGB(c.a)) {} + + //-------------------------------------------------------------------- + rgba32(const rgba16& c) : + r(value_type(c.r / 65535.0)), + g(value_type(c.g / 65535.0)), + b(value_type(c.b / 65535.0)), + a(value_type(c.a / 65535.0)) {} + + //-------------------------------------------------------------------- + operator rgba() const + { + return rgba(r, g, b, a); + } + + //-------------------------------------------------------------------- + operator rgba8() const + { + return rgba8( + uround(r * 255.0), + uround(g * 255.0), + uround(b * 255.0), + uround(a * 255.0)); + } + + //-------------------------------------------------------------------- + operator srgba8() const + { + return srgba8( + sRGB_conv<value_type>::rgb_to_sRGB(r), + sRGB_conv<value_type>::rgb_to_sRGB(g), + sRGB_conv<value_type>::rgb_to_sRGB(b), + sRGB_conv<value_type>::alpha_to_sRGB(a)); + } + + //-------------------------------------------------------------------- + operator rgba16() const + { + return rgba8( + uround(r * 65535.0), + uround(g * 65535.0), + uround(b * 65535.0), + uround(a * 65535.0)); + } + + //-------------------------------------------------------------------- + static AGG_INLINE double to_double(value_type a) + { + return a; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type from_double(double a) + { + return value_type(a); + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type empty_value() + { + return 0; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type full_value() + { + return 1; + } + + //-------------------------------------------------------------------- + AGG_INLINE bool is_transparent() const + { + return a <= 0; + } + + //-------------------------------------------------------------------- + AGG_INLINE bool is_opaque() const + { + return a >= 1; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type invert(value_type x) + { + return 1 - x; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type multiply(value_type a, value_type b) + { + return value_type(a * b); + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type demultiply(value_type a, value_type b) + { + return (b == 0) ? 0 : value_type(a / b); + } + + //-------------------------------------------------------------------- + template<typename T> + static AGG_INLINE T downscale(T a) + { + return a; + } + + //-------------------------------------------------------------------- + template<typename T> + static AGG_INLINE T downshift(T a, unsigned n) + { + return n > 0 ? a / (1 << n) : a; + } + + //-------------------------------------------------------------------- + static AGG_INLINE value_type mult_cover(value_type a, cover_type b) + { + return value_type(a * b / cover_mask); + } + + //-------------------------------------------------------------------- + static AGG_INLINE cover_type scale_cover(cover_type a, value_type b) + { + return cover_type(uround(a * b)); + } + + //-------------------------------------------------------------------- + // Interpolate p to q by a, assuming q is premultiplied by a. + static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a) + { + return (1 - a) * p + q; // more accurate than "p + q - p * a" + } + + //-------------------------------------------------------------------- + // Interpolate p to q by a. + static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a) + { + // The form "p + a * (q - p)" avoids a multiplication, but may produce an + // inaccurate result. For example, "p + (q - p)" may not be exactly equal + // to q. Therefore, stick to the basic expression, which at least produces + // the correct result at either extreme. + return (1 - a) * p + a * q; + } + + //-------------------------------------------------------------------- + self_type& clear() + { + r = g = b = a = 0; + return *this; + } + + //-------------------------------------------------------------------- + self_type& transparent() + { + a = 0; + return *this; + } + + //-------------------------------------------------------------------- + AGG_INLINE self_type& opacity(double a_) + { + if (a_ < 0) a = 0; + else if (a_ > 1) a = 1; + else a = value_type(a_); + return *this; + } + + //-------------------------------------------------------------------- + double opacity() const + { + return a; + } + + //-------------------------------------------------------------------- + AGG_INLINE self_type& premultiply() + { + if (a < 1) + { + if (a <= 0) + { + r = g = b = 0; + } + else + { + r *= a; + g *= a; + b *= a; + } + } + return *this; + } + + //-------------------------------------------------------------------- + AGG_INLINE self_type& demultiply() + { + if (a < 1) + { + if (a <= 0) + { + r = g = b = 0; + } + else + { + r /= a; + g /= a; + b /= a; + } + } + return *this; + } + + //-------------------------------------------------------------------- + AGG_INLINE self_type gradient(const self_type& c, double k) const + { + self_type ret; + ret.r = value_type(r + (c.r - r) * k); + ret.g = value_type(g + (c.g - g) * k); + ret.b = value_type(b + (c.b - b) * k); + ret.a = value_type(a + (c.a - a) * k); + return ret; + } + + //-------------------------------------------------------------------- + AGG_INLINE void add(const self_type& c, unsigned cover) + { + if (cover == cover_mask) + { + if (c.is_opaque()) + { + *this = c; + return; + } + else + { + r += c.r; + g += c.g; + b += c.b; + a += c.a; + } + } + else + { + r += mult_cover(c.r, cover); + g += mult_cover(c.g, cover); + b += mult_cover(c.b, cover); + a += mult_cover(c.a, cover); + } + if (a > 1) a = 1; + if (r > a) r = a; + if (g > a) g = a; + if (b > a) b = a; + } + + //-------------------------------------------------------------------- + template<class GammaLUT> + AGG_INLINE void apply_gamma_dir(const GammaLUT& gamma) + { + r = gamma.dir(r); + g = gamma.dir(g); + b = gamma.dir(b); + } + + //-------------------------------------------------------------------- + template<class GammaLUT> + AGG_INLINE void apply_gamma_inv(const GammaLUT& gamma) + { + r = gamma.inv(r); + g = gamma.inv(g); + b = gamma.inv(b); + } + + //-------------------------------------------------------------------- + static self_type no_color() { return self_type(0,0,0,0); } + + //-------------------------------------------------------------------- + static self_type from_wavelength(double wl, double gamma = 1) + { + return self_type(rgba::from_wavelength(wl, gamma)); + } + }; +} + + + +#endif diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_config.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_config.h new file mode 100644 index 00000000000..fa1dae2ba7b --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_config.h @@ -0,0 +1,44 @@ +#ifndef AGG_CONFIG_INCLUDED +#define AGG_CONFIG_INCLUDED + +// This file can be used to redefine certain data types. + +//--------------------------------------- +// 1. Default basic types such as: +// +// AGG_INT8 +// AGG_INT8U +// AGG_INT16 +// AGG_INT16U +// AGG_INT32 +// AGG_INT32U +// AGG_INT64 +// AGG_INT64U +// +// Just replace this file with new defines if necessary. +// For example, if your compiler doesn't have a 64 bit integer type +// you can still use AGG if you define the follows: +// +// #define AGG_INT64 int +// #define AGG_INT64U unsigned +// +// It will result in overflow in 16 bit-per-component image/pattern resampling +// but it won't result any crash and the rest of the library will remain +// fully functional. + + +//--------------------------------------- +// 2. Default rendering_buffer type. Can be: +// +// Provides faster access for massive pixel operations, +// such as blur, image filtering: +// #define AGG_RENDERING_BUFFER row_ptr_cache<int8u> +// +// Provides cheaper creation and destruction (no mem allocs): +// #define AGG_RENDERING_BUFFER row_accessor<int8u> +// +// You can still use both of them simultaneously in your applications +// This #define is used only for default rendering_buffer type, +// in short hand typedefs like pixfmt_rgba32. + +#endif diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_adaptor_vcgen.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_adaptor_vcgen.h new file mode 100644 index 00000000000..a79f2208c61 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_adaptor_vcgen.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_CONV_ADAPTOR_VCGEN_INCLUDED +#define AGG_CONV_ADAPTOR_VCGEN_INCLUDED + +#include "agg_basics.h" + +namespace agg +{ + //------------------------------------------------------------null_markers + struct null_markers + { + void remove_all() {} + void add_vertex(double, double, unsigned) {} + void prepare_src() {} + + void rewind(unsigned) {} + unsigned vertex(double*, double*) { return path_cmd_stop; } + }; + + + //------------------------------------------------------conv_adaptor_vcgen + template<class VertexSource, + class Generator, + class Markers=null_markers> class conv_adaptor_vcgen + { + enum status + { + initial, + accumulate, + generate + }; + + public: + explicit conv_adaptor_vcgen(VertexSource& source) : + m_source(&source), + m_status(initial) + {} + void attach(VertexSource& source) { m_source = &source; } + + Generator& generator() { return m_generator; } + const Generator& generator() const { return m_generator; } + + Markers& markers() { return m_markers; } + const Markers& markers() const { return m_markers; } + + void rewind(unsigned path_id) + { + m_source->rewind(path_id); + m_status = initial; + } + + unsigned vertex(double* x, double* y); + + private: + // Prohibit copying + conv_adaptor_vcgen(const conv_adaptor_vcgen<VertexSource, Generator, Markers>&); + const conv_adaptor_vcgen<VertexSource, Generator, Markers>& + operator = (const conv_adaptor_vcgen<VertexSource, Generator, Markers>&); + + VertexSource* m_source; + Generator m_generator; + Markers m_markers; + status m_status; + unsigned m_last_cmd; + double m_start_x; + double m_start_y; + }; + + + + + + //------------------------------------------------------------------------ + template<class VertexSource, class Generator, class Markers> + unsigned conv_adaptor_vcgen<VertexSource, Generator, Markers>::vertex(double* x, double* y) + { + unsigned cmd = path_cmd_stop; + bool done = false; + while(!done) + { + switch(m_status) + { + case initial: + m_markers.remove_all(); + m_last_cmd = m_source->vertex(&m_start_x, &m_start_y); + m_status = accumulate; + + case accumulate: + if(is_stop(m_last_cmd)) return path_cmd_stop; + + m_generator.remove_all(); + m_generator.add_vertex(m_start_x, m_start_y, path_cmd_move_to); + m_markers.add_vertex(m_start_x, m_start_y, path_cmd_move_to); + + for(;;) + { + cmd = m_source->vertex(x, y); + if(is_vertex(cmd)) + { + m_last_cmd = cmd; + if(is_move_to(cmd)) + { + m_start_x = *x; + m_start_y = *y; + break; + } + m_generator.add_vertex(*x, *y, cmd); + m_markers.add_vertex(*x, *y, path_cmd_line_to); + } + else + { + if(is_stop(cmd)) + { + m_last_cmd = path_cmd_stop; + break; + } + if(is_end_poly(cmd)) + { + m_generator.add_vertex(*x, *y, cmd); + break; + } + } + } + m_generator.rewind(0); + m_status = generate; + + case generate: + cmd = m_generator.vertex(x, y); + if(is_stop(cmd)) + { + m_status = accumulate; + break; + } + done = true; + break; + } + } + return cmd; + } + +} + +#endif diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_adaptor_vpgen.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_adaptor_vpgen.h new file mode 100644 index 00000000000..d6b545ef1f2 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_adaptor_vpgen.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 +//---------------------------------------------------------------------------- + +#ifndef AGG_CONV_ADAPTOR_VPGEN_INCLUDED +#define AGG_CONV_ADAPTOR_VPGEN_INCLUDED + +#include "agg_basics.h" + +namespace agg +{ + + //======================================================conv_adaptor_vpgen + template<class VertexSource, class VPGen> class conv_adaptor_vpgen + { + public: + explicit conv_adaptor_vpgen(VertexSource& source) : m_source(&source) {} + void attach(VertexSource& source) { m_source = &source; } + + VPGen& vpgen() { return m_vpgen; } + const VPGen& vpgen() const { return m_vpgen; } + + void rewind(unsigned path_id); + unsigned vertex(double* x, double* y); + + private: + conv_adaptor_vpgen(const conv_adaptor_vpgen<VertexSource, VPGen>&); + const conv_adaptor_vpgen<VertexSource, VPGen>& + operator = (const conv_adaptor_vpgen<VertexSource, VPGen>&); + + VertexSource* m_source; + VPGen m_vpgen; + double m_start_x; + double m_start_y; + unsigned m_poly_flags; + int m_vertices; + }; + + + + //------------------------------------------------------------------------ + template<class VertexSource, class VPGen> + void conv_adaptor_vpgen<VertexSource, VPGen>::rewind(unsigned path_id) + { + m_source->rewind(path_id); + m_vpgen.reset(); + m_start_x = 0; + m_start_y = 0; + m_poly_flags = 0; + m_vertices = 0; + } + + + //------------------------------------------------------------------------ + template<class VertexSource, class VPGen> + unsigned conv_adaptor_vpgen<VertexSource, VPGen>::vertex(double* x, double* y) + { + unsigned cmd = path_cmd_stop; + for(;;) + { + cmd = m_vpgen.vertex(x, y); + if(!is_stop(cmd)) break; + + if(m_poly_flags && !m_vpgen.auto_unclose()) + { + *x = 0.0; + *y = 0.0; + cmd = m_poly_flags; + m_poly_flags = 0; + break; + } + + if(m_vertices < 0) + { + if(m_vertices < -1) + { + m_vertices = 0; + return path_cmd_stop; + } + m_vpgen.move_to(m_start_x, m_start_y); + m_vertices = 1; + continue; + } + + double tx, ty; + cmd = m_source->vertex(&tx, &ty); + if(is_vertex(cmd)) + { + if(is_move_to(cmd)) + { + if(m_vpgen.auto_close() && m_vertices > 2) + { + m_vpgen.line_to(m_start_x, m_start_y); + m_poly_flags = path_cmd_end_poly | path_flags_close; + m_start_x = tx; + m_start_y = ty; + m_vertices = -1; + continue; + } + m_vpgen.move_to(tx, ty); + m_start_x = tx; + m_start_y = ty; + m_vertices = 1; + } + else + { + m_vpgen.line_to(tx, ty); + ++m_vertices; + } + } + else + { + if(is_end_poly(cmd)) + { + m_poly_flags = cmd; + if(is_closed(cmd) || m_vpgen.auto_close()) + { + if(m_vpgen.auto_close()) m_poly_flags |= path_flags_close; + if(m_vertices > 2) + { + m_vpgen.line_to(m_start_x, m_start_y); + } + m_vertices = 0; + } + } + else + { + // path_cmd_stop + if(m_vpgen.auto_close() && m_vertices > 2) + { + m_vpgen.line_to(m_start_x, m_start_y); + m_poly_flags = path_cmd_end_poly | path_flags_close; + m_vertices = -2; + continue; + } + break; + } + } + } + return cmd; + } + + +} + + +#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 00000000000..13d22d92979 --- /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 00000000000..87537638dce --- /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 00000000000..f3fc2888c23 --- /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 00000000000..c46594fdfbe --- /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 00000000000..745d349c6f7 --- /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_contour.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_contour.h new file mode 100644 index 00000000000..b4b5a9047e9 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_contour.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 +//---------------------------------------------------------------------------- +// +// conv_stroke +// +//---------------------------------------------------------------------------- +#ifndef AGG_CONV_CONTOUR_INCLUDED +#define AGG_CONV_CONTOUR_INCLUDED + +#include "agg_basics.h" +#include "agg_vcgen_contour.h" +#include "agg_conv_adaptor_vcgen.h" + +namespace agg +{ + + //-----------------------------------------------------------conv_contour + template<class VertexSource> + struct conv_contour : public conv_adaptor_vcgen<VertexSource, vcgen_contour> + { + typedef conv_adaptor_vcgen<VertexSource, vcgen_contour> base_type; + + conv_contour(VertexSource& vs) : + conv_adaptor_vcgen<VertexSource, vcgen_contour>(vs) + { + } + + void line_join(line_join_e lj) { base_type::generator().line_join(lj); } + void inner_join(inner_join_e ij) { base_type::generator().inner_join(ij); } + void width(double w) { base_type::generator().width(w); } + void miter_limit(double ml) { base_type::generator().miter_limit(ml); } + void miter_limit_theta(double t) { base_type::generator().miter_limit_theta(t); } + void inner_miter_limit(double ml) { base_type::generator().inner_miter_limit(ml); } + void approximation_scale(double as) { base_type::generator().approximation_scale(as); } + void auto_detect_orientation(bool v) { base_type::generator().auto_detect_orientation(v); } + + line_join_e line_join() const { return base_type::generator().line_join(); } + inner_join_e inner_join() const { return base_type::generator().inner_join(); } + double width() const { return base_type::generator().width(); } + double miter_limit() const { return base_type::generator().miter_limit(); } + double inner_miter_limit() const { return base_type::generator().inner_miter_limit(); } + double approximation_scale() const { return base_type::generator().approximation_scale(); } + bool auto_detect_orientation() const { return base_type::generator().auto_detect_orientation(); } + + private: + conv_contour(const conv_contour<VertexSource>&); + const conv_contour<VertexSource>& + operator = (const conv_contour<VertexSource>&); + }; + +} + +#endif diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_curve.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_curve.h new file mode 100644 index 00000000000..d5b475de7a1 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_curve.h @@ -0,0 +1,201 @@ +//---------------------------------------------------------------------------- +// 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 conv_curve +// +//---------------------------------------------------------------------------- + +#ifndef AGG_CONV_CURVE_INCLUDED +#define AGG_CONV_CURVE_INCLUDED + +#include "agg_basics.h" +#include "agg_curves.h" + +namespace agg +{ + + + //---------------------------------------------------------------conv_curve + // Curve converter class. Any path storage can have Bezier curves defined + // by their control points. There're two types of curves supported: curve3 + // and curve4. Curve3 is a conic Bezier curve with 2 endpoints and 1 control + // point. Curve4 has 2 control points (4 points in total) and can be used + // to interpolate more complicated curves. Curve4, unlike curve3 can be used + // to approximate arcs, both circular and elliptical. Curves are approximated + // with straight lines and one of the approaches is just to store the whole + // sequence of vertices that approximate our curve. It takes additional + // memory, and at the same time the consecutive vertices can be calculated + // on demand. + // + // Initially, path storages are not suppose to keep all the vertices of the + // curves (although, nothing prevents us from doing so). Instead, path_storage + // keeps only vertices, needed to calculate a curve on demand. Those vertices + // are marked with special commands. So, if the path_storage contains curves + // (which are not real curves yet), and we render this storage directly, + // all we will see is only 2 or 3 straight line segments (for curve3 and + // curve4 respectively). If we need to see real curves drawn we need to + // include this class into the conversion pipeline. + // + // Class conv_curve recognizes commands path_cmd_curve3 and path_cmd_curve4 + // and converts these vertices into a move_to/line_to sequence. + //----------------------------------------------------------------------- + template<class VertexSource, + class Curve3=curve3, + class Curve4=curve4> class conv_curve + { + public: + typedef Curve3 curve3_type; + typedef Curve4 curve4_type; + typedef conv_curve<VertexSource, Curve3, Curve4> self_type; + + explicit conv_curve(VertexSource& source) : + m_source(&source), m_last_x(0.0), m_last_y(0.0) {} + void attach(VertexSource& source) { m_source = &source; } + + void approximation_method(curve_approximation_method_e v) + { + m_curve3.approximation_method(v); + m_curve4.approximation_method(v); + } + + curve_approximation_method_e approximation_method() const + { + return m_curve4.approximation_method(); + } + + void approximation_scale(double s) + { + m_curve3.approximation_scale(s); + m_curve4.approximation_scale(s); + } + + double approximation_scale() const + { + return m_curve4.approximation_scale(); + } + + void angle_tolerance(double v) + { + m_curve3.angle_tolerance(v); + m_curve4.angle_tolerance(v); + } + + double angle_tolerance() const + { + return m_curve4.angle_tolerance(); + } + + void cusp_limit(double v) + { + m_curve3.cusp_limit(v); + m_curve4.cusp_limit(v); + } + + double cusp_limit() const + { + return m_curve4.cusp_limit(); + } + + void rewind(unsigned path_id); + unsigned vertex(double* x, double* y); + + private: + conv_curve(const self_type&); + const self_type& operator = (const self_type&); + + VertexSource* m_source; + double m_last_x; + double m_last_y; + curve3_type m_curve3; + curve4_type m_curve4; + }; + + + + //------------------------------------------------------------------------ + template<class VertexSource, class Curve3, class Curve4> + void conv_curve<VertexSource, Curve3, Curve4>::rewind(unsigned path_id) + { + m_source->rewind(path_id); + m_last_x = 0.0; + m_last_y = 0.0; + m_curve3.reset(); + m_curve4.reset(); + } + + + //------------------------------------------------------------------------ + template<class VertexSource, class Curve3, class Curve4> + unsigned conv_curve<VertexSource, Curve3, Curve4>::vertex(double* x, double* y) + { + if(!is_stop(m_curve3.vertex(x, y))) + { + m_last_x = *x; + m_last_y = *y; + return path_cmd_line_to; + } + + if(!is_stop(m_curve4.vertex(x, y))) + { + m_last_x = *x; + m_last_y = *y; + return path_cmd_line_to; + } + + double ct2_x; + double ct2_y; + double end_x; + double end_y; + + unsigned cmd = m_source->vertex(x, y); + switch(cmd) + { + case path_cmd_curve3: + m_source->vertex(&end_x, &end_y); + + m_curve3.init(m_last_x, m_last_y, + *x, *y, + end_x, end_y); + + m_curve3.vertex(x, y); // First call returns path_cmd_move_to + m_curve3.vertex(x, y); // This is the first vertex of the curve + cmd = path_cmd_line_to; + break; + + case path_cmd_curve4: + m_source->vertex(&ct2_x, &ct2_y); + m_source->vertex(&end_x, &end_y); + + m_curve4.init(m_last_x, m_last_y, + *x, *y, + ct2_x, ct2_y, + end_x, end_y); + + m_curve4.vertex(x, y); // First call returns path_cmd_move_to + m_curve4.vertex(x, y); // This is the first vertex of the curve + cmd = path_cmd_line_to; + break; + } + m_last_x = *x; + m_last_y = *y; + return cmd; + } + + +} + + + +#endif diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_dash.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_dash.h new file mode 100644 index 00000000000..23c13ad0ab3 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_dash.h @@ -0,0 +1,68 @@ +//---------------------------------------------------------------------------- +// 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_dash +// +//---------------------------------------------------------------------------- +#ifndef AGG_CONV_DASH_INCLUDED +#define AGG_CONV_DASH_INCLUDED + +#include "agg_basics.h" +#include "agg_vcgen_dash.h" +#include "agg_conv_adaptor_vcgen.h" + +namespace agg +{ + + //---------------------------------------------------------------conv_dash + template<class VertexSource, class Markers=null_markers> + struct conv_dash : public conv_adaptor_vcgen<VertexSource, vcgen_dash, Markers> + { + typedef Markers marker_type; + typedef conv_adaptor_vcgen<VertexSource, vcgen_dash, Markers> base_type; + + conv_dash(VertexSource& vs) : + conv_adaptor_vcgen<VertexSource, vcgen_dash, Markers>(vs) + { + } + + void remove_all_dashes() + { + base_type::generator().remove_all_dashes(); + } + + void add_dash(double dash_len, double gap_len) + { + base_type::generator().add_dash(dash_len, gap_len); + } + + void dash_start(double ds) + { + base_type::generator().dash_start(ds); + } + + void shorten(double s) { base_type::generator().shorten(s); } + double shorten() const { return base_type::generator().shorten(); } + + private: + conv_dash(const conv_dash<VertexSource, Markers>&); + const conv_dash<VertexSource, Markers>& + operator = (const conv_dash<VertexSource, Markers>&); + }; + + +} + +#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 00000000000..2acada342d8 --- /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 00000000000..2cd3cb403f4 --- /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 00000000000..4486d6ace9d --- /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_segmentator.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_segmentator.h new file mode 100644 index 00000000000..e69a9e7d7d0 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_segmentator.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_SEGMENTATOR_INCLUDED +#define AGG_CONV_SEGMENTATOR_INCLUDED + +#include "agg_basics.h" +#include "agg_conv_adaptor_vpgen.h" +#include "agg_vpgen_segmentator.h" + +namespace agg +{ + + //========================================================conv_segmentator + template<class VertexSource> + struct conv_segmentator : public conv_adaptor_vpgen<VertexSource, vpgen_segmentator> + { + typedef conv_adaptor_vpgen<VertexSource, vpgen_segmentator> base_type; + + conv_segmentator(VertexSource& vs) : + conv_adaptor_vpgen<VertexSource, vpgen_segmentator>(vs) {} + + void approximation_scale(double s) { base_type::vpgen().approximation_scale(s); } + double approximation_scale() const { return base_type::vpgen().approximation_scale(); } + + private: + conv_segmentator(const conv_segmentator<VertexSource>&); + const conv_segmentator<VertexSource>& + operator = (const conv_segmentator<VertexSource>&); + }; + + +} + +#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 00000000000..5617e51d17e --- /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 00000000000..4ac4e3d6e29 --- /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_stroke.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_stroke.h new file mode 100644 index 00000000000..e19a6b61f40 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_stroke.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 +//---------------------------------------------------------------------------- +// +// conv_stroke +// +//---------------------------------------------------------------------------- +#ifndef AGG_CONV_STROKE_INCLUDED +#define AGG_CONV_STROKE_INCLUDED + +#include "agg_basics.h" +#include "agg_vcgen_stroke.h" +#include "agg_conv_adaptor_vcgen.h" + +namespace agg +{ + + //-------------------------------------------------------------conv_stroke + template<class VertexSource, class Markers=null_markers> + struct conv_stroke : + public conv_adaptor_vcgen<VertexSource, vcgen_stroke, Markers> + { + typedef Markers marker_type; + typedef conv_adaptor_vcgen<VertexSource, vcgen_stroke, Markers> base_type; + + conv_stroke(VertexSource& vs) : + conv_adaptor_vcgen<VertexSource, vcgen_stroke, Markers>(vs) + { + } + + void line_cap(line_cap_e lc) { base_type::generator().line_cap(lc); } + void line_join(line_join_e lj) { base_type::generator().line_join(lj); } + void inner_join(inner_join_e ij) { base_type::generator().inner_join(ij); } + + line_cap_e line_cap() const { return base_type::generator().line_cap(); } + line_join_e line_join() const { return base_type::generator().line_join(); } + inner_join_e inner_join() const { return base_type::generator().inner_join(); } + + void width(double w) { base_type::generator().width(w); } + void miter_limit(double ml) { base_type::generator().miter_limit(ml); } + void miter_limit_theta(double t) { base_type::generator().miter_limit_theta(t); } + void inner_miter_limit(double ml) { base_type::generator().inner_miter_limit(ml); } + void approximation_scale(double as) { base_type::generator().approximation_scale(as); } + + double width() const { return base_type::generator().width(); } + double miter_limit() const { return base_type::generator().miter_limit(); } + double inner_miter_limit() const { return base_type::generator().inner_miter_limit(); } + double approximation_scale() const { return base_type::generator().approximation_scale(); } + + void shorten(double s) { base_type::generator().shorten(s); } + double shorten() const { return base_type::generator().shorten(); } + + private: + conv_stroke(const conv_stroke<VertexSource, Markers>&); + const conv_stroke<VertexSource, Markers>& + operator = (const conv_stroke<VertexSource, Markers>&); + + }; + +} + +#endif diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_transform.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_transform.h new file mode 100644 index 00000000000..0c88a245bda --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_conv_transform.h @@ -0,0 +1,68 @@ +//---------------------------------------------------------------------------- +// 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 conv_transform +// +//---------------------------------------------------------------------------- +#ifndef AGG_CONV_TRANSFORM_INCLUDED +#define AGG_CONV_TRANSFORM_INCLUDED + +#include "agg_basics.h" +#include "agg_trans_affine.h" + +namespace agg +{ + + //----------------------------------------------------------conv_transform + template<class VertexSource, class Transformer=trans_affine> class conv_transform + { + public: + conv_transform(VertexSource& source, Transformer& tr) : + m_source(&source), m_trans(&tr) {} + 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_vertex(cmd)) + { + m_trans->transform(x, y); + } + return cmd; + } + + void transformer(Transformer& tr) + { + m_trans = &tr; + } + + private: + conv_transform(const conv_transform<VertexSource>&); + const conv_transform<VertexSource>& + operator = (const conv_transform<VertexSource>&); + + VertexSource* m_source; + Transformer* m_trans; + }; + + +} + +#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 00000000000..fe5c263810e --- /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_curves.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_curves.h new file mode 100644 index 00000000000..1ef02e87834 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_curves.h @@ -0,0 +1,693 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) +// Copyright (C) 2005 Tony Juricic (tonygeek@yahoo.com) +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// 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_CURVES_INCLUDED +#define AGG_CURVES_INCLUDED + +#include "agg_array.h" + +namespace agg +{ + + // See Implementation agg_curves.cpp + + //--------------------------------------------curve_approximation_method_e + enum curve_approximation_method_e + { + curve_inc, + curve_div + }; + + //--------------------------------------------------------------curve3_inc + class curve3_inc + { + public: + curve3_inc() : + m_num_steps(0), m_step(0), m_scale(1.0) { } + + curve3_inc(double x1, double y1, + double x2, double y2, + double x3, double y3) : + m_num_steps(0), m_step(0), m_scale(1.0) + { + init(x1, y1, x2, y2, x3, y3); + } + + void reset() { m_num_steps = 0; m_step = -1; } + void init(double x1, double y1, + double x2, double y2, + double x3, double y3); + + void approximation_method(curve_approximation_method_e) {} + curve_approximation_method_e approximation_method() const { return curve_inc; } + + void approximation_scale(double s); + double approximation_scale() const; + + void angle_tolerance(double) {} + double angle_tolerance() const { return 0.0; } + + void cusp_limit(double) {} + double cusp_limit() const { return 0.0; } + + void rewind(unsigned path_id); + unsigned vertex(double* x, double* y); + + private: + int m_num_steps; + int m_step; + double m_scale; + double m_start_x; + double m_start_y; + double m_end_x; + double m_end_y; + double m_fx; + double m_fy; + double m_dfx; + double m_dfy; + double m_ddfx; + double m_ddfy; + double m_saved_fx; + double m_saved_fy; + double m_saved_dfx; + double m_saved_dfy; + }; + + + + + + //-------------------------------------------------------------curve3_div + class curve3_div + { + public: + curve3_div() : + m_approximation_scale(1.0), + m_angle_tolerance(0.0), + m_count(0) + {} + + curve3_div(double x1, double y1, + double x2, double y2, + double x3, double y3) : + m_approximation_scale(1.0), + m_angle_tolerance(0.0), + m_count(0) + { + init(x1, y1, x2, y2, x3, y3); + } + + void reset() { m_points.remove_all(); m_count = 0; } + void init(double x1, double y1, + double x2, double y2, + double x3, double y3); + + void approximation_method(curve_approximation_method_e) {} + curve_approximation_method_e approximation_method() const { return curve_div; } + + void approximation_scale(double s) { m_approximation_scale = s; } + double approximation_scale() const { return m_approximation_scale; } + + void angle_tolerance(double a) { m_angle_tolerance = a; } + double angle_tolerance() const { return m_angle_tolerance; } + + void cusp_limit(double) {} + double cusp_limit() const { return 0.0; } + + void rewind(unsigned) + { + m_count = 0; + } + + unsigned vertex(double* x, double* y) + { + if(m_count >= m_points.size()) return path_cmd_stop; + const point_d& p = m_points[m_count++]; + *x = p.x; + *y = p.y; + return (m_count == 1) ? path_cmd_move_to : path_cmd_line_to; + } + + private: + void bezier(double x1, double y1, + double x2, double y2, + double x3, double y3); + void recursive_bezier(double x1, double y1, + double x2, double y2, + double x3, double y3, + unsigned level); + + double m_approximation_scale; + double m_distance_tolerance_square; + double m_angle_tolerance; + unsigned m_count; + pod_bvector<point_d> m_points; + }; + + + + + + + + //-------------------------------------------------------------curve4_points + struct curve4_points + { + double cp[8]; + curve4_points() {} + curve4_points(double x1, double y1, + double x2, double y2, + double x3, double y3, + double x4, double y4) + { + cp[0] = x1; cp[1] = y1; cp[2] = x2; cp[3] = y2; + cp[4] = x3; cp[5] = y3; cp[6] = x4; cp[7] = y4; + } + void init(double x1, double y1, + double x2, double y2, + double x3, double y3, + double x4, double y4) + { + cp[0] = x1; cp[1] = y1; cp[2] = x2; cp[3] = y2; + cp[4] = x3; cp[5] = y3; cp[6] = x4; cp[7] = y4; + } + double operator [] (unsigned i) const { return cp[i]; } + double& operator [] (unsigned i) { return cp[i]; } + }; + + + + //-------------------------------------------------------------curve4_inc + class curve4_inc + { + public: + curve4_inc() : + m_num_steps(0), m_step(0), m_scale(1.0) { } + + curve4_inc(double x1, double y1, + double x2, double y2, + double x3, double y3, + double x4, double y4) : + m_num_steps(0), m_step(0), m_scale(1.0) + { + init(x1, y1, x2, y2, x3, y3, x4, y4); + } + + curve4_inc(const curve4_points& cp) : + m_num_steps(0), m_step(0), m_scale(1.0) + { + init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]); + } + + void reset() { m_num_steps = 0; m_step = -1; } + void init(double x1, double y1, + double x2, double y2, + double x3, double y3, + double x4, double y4); + + void init(const curve4_points& cp) + { + init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]); + } + + void approximation_method(curve_approximation_method_e) {} + curve_approximation_method_e approximation_method() const { return curve_inc; } + + void approximation_scale(double s); + double approximation_scale() const; + + void angle_tolerance(double) {} + double angle_tolerance() const { return 0.0; } + + void cusp_limit(double) {} + double cusp_limit() const { return 0.0; } + + void rewind(unsigned path_id); + unsigned vertex(double* x, double* y); + + private: + int m_num_steps; + int m_step; + double m_scale; + double m_start_x; + double m_start_y; + double m_end_x; + double m_end_y; + double m_fx; + double m_fy; + double m_dfx; + double m_dfy; + double m_ddfx; + double m_ddfy; + double m_dddfx; + double m_dddfy; + double m_saved_fx; + double m_saved_fy; + double m_saved_dfx; + double m_saved_dfy; + double m_saved_ddfx; + double m_saved_ddfy; + }; + + + + //-------------------------------------------------------catrom_to_bezier + inline curve4_points catrom_to_bezier(double x1, double y1, + double x2, double y2, + double x3, double y3, + double x4, double y4) + { + // Trans. matrix Catmull-Rom to Bezier + // + // 0 1 0 0 + // -1/6 1 1/6 0 + // 0 1/6 1 -1/6 + // 0 0 1 0 + // + return curve4_points( + x2, + y2, + (-x1 + 6*x2 + x3) / 6, + (-y1 + 6*y2 + y3) / 6, + ( x2 + 6*x3 - x4) / 6, + ( y2 + 6*y3 - y4) / 6, + x3, + y3); + } + + + //----------------------------------------------------------------------- + inline curve4_points + catrom_to_bezier(const curve4_points& cp) + { + return catrom_to_bezier(cp[0], cp[1], cp[2], cp[3], + cp[4], cp[5], cp[6], cp[7]); + } + + + + //-----------------------------------------------------ubspline_to_bezier + inline curve4_points ubspline_to_bezier(double x1, double y1, + double x2, double y2, + double x3, double y3, + double x4, double y4) + { + // Trans. matrix Uniform BSpline to Bezier + // + // 1/6 4/6 1/6 0 + // 0 4/6 2/6 0 + // 0 2/6 4/6 0 + // 0 1/6 4/6 1/6 + // + return curve4_points( + (x1 + 4*x2 + x3) / 6, + (y1 + 4*y2 + y3) / 6, + (4*x2 + 2*x3) / 6, + (4*y2 + 2*y3) / 6, + (2*x2 + 4*x3) / 6, + (2*y2 + 4*y3) / 6, + (x2 + 4*x3 + x4) / 6, + (y2 + 4*y3 + y4) / 6); + } + + + //----------------------------------------------------------------------- + inline curve4_points + ubspline_to_bezier(const curve4_points& cp) + { + return ubspline_to_bezier(cp[0], cp[1], cp[2], cp[3], + cp[4], cp[5], cp[6], cp[7]); + } + + + + + //------------------------------------------------------hermite_to_bezier + inline curve4_points hermite_to_bezier(double x1, double y1, + double x2, double y2, + double x3, double y3, + double x4, double y4) + { + // Trans. matrix Hermite to Bezier + // + // 1 0 0 0 + // 1 0 1/3 0 + // 0 1 0 -1/3 + // 0 1 0 0 + // + return curve4_points( + x1, + y1, + (3*x1 + x3) / 3, + (3*y1 + y3) / 3, + (3*x2 - x4) / 3, + (3*y2 - y4) / 3, + x2, + y2); + } + + + + //----------------------------------------------------------------------- + inline curve4_points + hermite_to_bezier(const curve4_points& cp) + { + return hermite_to_bezier(cp[0], cp[1], cp[2], cp[3], + cp[4], cp[5], cp[6], cp[7]); + } + + + //-------------------------------------------------------------curve4_div + class curve4_div + { + public: + curve4_div() : + m_approximation_scale(1.0), + m_angle_tolerance(0.0), + m_cusp_limit(0.0), + m_count(0) + {} + + curve4_div(double x1, double y1, + double x2, double y2, + double x3, double y3, + double x4, double y4) : + m_approximation_scale(1.0), + m_angle_tolerance(0.0), + m_cusp_limit(0.0), + m_count(0) + { + init(x1, y1, x2, y2, x3, y3, x4, y4); + } + + curve4_div(const curve4_points& cp) : + m_approximation_scale(1.0), + m_angle_tolerance(0.0), + m_count(0) + { + init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]); + } + + void reset() { m_points.remove_all(); m_count = 0; } + void init(double x1, double y1, + double x2, double y2, + double x3, double y3, + double x4, double y4); + + void init(const curve4_points& cp) + { + init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]); + } + + void approximation_method(curve_approximation_method_e) {} + + curve_approximation_method_e approximation_method() const + { + return curve_div; + } + + void approximation_scale(double s) { m_approximation_scale = s; } + double approximation_scale() const { return m_approximation_scale; } + + void angle_tolerance(double a) { m_angle_tolerance = a; } + double angle_tolerance() const { return m_angle_tolerance; } + + void cusp_limit(double v) + { + m_cusp_limit = (v == 0.0) ? 0.0 : pi - v; + } + + double cusp_limit() const + { + return (m_cusp_limit == 0.0) ? 0.0 : pi - m_cusp_limit; + } + + void rewind(unsigned) + { + m_count = 0; + } + + unsigned vertex(double* x, double* y) + { + if(m_count >= m_points.size()) return path_cmd_stop; + const point_d& p = m_points[m_count++]; + *x = p.x; + *y = p.y; + return (m_count == 1) ? path_cmd_move_to : path_cmd_line_to; + } + + private: + void bezier(double x1, double y1, + double x2, double y2, + double x3, double y3, + double x4, double y4); + + void recursive_bezier(double x1, double y1, + double x2, double y2, + double x3, double y3, + double x4, double y4, + unsigned level); + + double m_approximation_scale; + double m_distance_tolerance_square; + double m_angle_tolerance; + double m_cusp_limit; + unsigned m_count; + pod_bvector<point_d> m_points; + }; + + + //-----------------------------------------------------------------curve3 + class curve3 + { + public: + curve3() : m_approximation_method(curve_div) {} + curve3(double x1, double y1, + double x2, double y2, + double x3, double y3) : + m_approximation_method(curve_div) + { + init(x1, y1, x2, y2, x3, y3); + } + + void reset() + { + m_curve_inc.reset(); + m_curve_div.reset(); + } + + void init(double x1, double y1, + double x2, double y2, + double x3, double y3) + { + if(m_approximation_method == curve_inc) + { + m_curve_inc.init(x1, y1, x2, y2, x3, y3); + } + else + { + m_curve_div.init(x1, y1, x2, y2, x3, y3); + } + } + + void approximation_method(curve_approximation_method_e v) + { + m_approximation_method = v; + } + + curve_approximation_method_e approximation_method() const + { + return m_approximation_method; + } + + void approximation_scale(double s) + { + m_curve_inc.approximation_scale(s); + m_curve_div.approximation_scale(s); + } + + double approximation_scale() const + { + return m_curve_inc.approximation_scale(); + } + + void angle_tolerance(double a) + { + m_curve_div.angle_tolerance(a); + } + + double angle_tolerance() const + { + return m_curve_div.angle_tolerance(); + } + + void cusp_limit(double v) + { + m_curve_div.cusp_limit(v); + } + + double cusp_limit() const + { + return m_curve_div.cusp_limit(); + } + + void rewind(unsigned path_id) + { + if(m_approximation_method == curve_inc) + { + m_curve_inc.rewind(path_id); + } + else + { + m_curve_div.rewind(path_id); + } + } + + unsigned vertex(double* x, double* y) + { + if(m_approximation_method == curve_inc) + { + return m_curve_inc.vertex(x, y); + } + return m_curve_div.vertex(x, y); + } + + private: + curve3_inc m_curve_inc; + curve3_div m_curve_div; + curve_approximation_method_e m_approximation_method; + }; + + + + + + //-----------------------------------------------------------------curve4 + class curve4 + { + public: + curve4() : m_approximation_method(curve_div) {} + curve4(double x1, double y1, + double x2, double y2, + double x3, double y3, + double x4, double y4) : + m_approximation_method(curve_div) + { + init(x1, y1, x2, y2, x3, y3, x4, y4); + } + + curve4(const curve4_points& cp) : + m_approximation_method(curve_div) + { + init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]); + } + + void reset() + { + m_curve_inc.reset(); + m_curve_div.reset(); + } + + void init(double x1, double y1, + double x2, double y2, + double x3, double y3, + double x4, double y4) + { + if(m_approximation_method == curve_inc) + { + m_curve_inc.init(x1, y1, x2, y2, x3, y3, x4, y4); + } + else + { + m_curve_div.init(x1, y1, x2, y2, x3, y3, x4, y4); + } + } + + void init(const curve4_points& cp) + { + init(cp[0], cp[1], cp[2], cp[3], cp[4], cp[5], cp[6], cp[7]); + } + + void approximation_method(curve_approximation_method_e v) + { + m_approximation_method = v; + } + + curve_approximation_method_e approximation_method() const + { + return m_approximation_method; + } + + void approximation_scale(double s) + { + m_curve_inc.approximation_scale(s); + m_curve_div.approximation_scale(s); + } + double approximation_scale() const { return m_curve_inc.approximation_scale(); } + + void angle_tolerance(double v) + { + m_curve_div.angle_tolerance(v); + } + + double angle_tolerance() const + { + return m_curve_div.angle_tolerance(); + } + + void cusp_limit(double v) + { + m_curve_div.cusp_limit(v); + } + + double cusp_limit() const + { + return m_curve_div.cusp_limit(); + } + + void rewind(unsigned path_id) + { + if(m_approximation_method == curve_inc) + { + m_curve_inc.rewind(path_id); + } + else + { + m_curve_div.rewind(path_id); + } + } + + unsigned vertex(double* x, double* y) + { + if(m_approximation_method == curve_inc) + { + return m_curve_inc.vertex(x, y); + } + return m_curve_div.vertex(x, y); + } + + private: + curve4_inc m_curve_inc; + curve4_div m_curve_div; + curve_approximation_method_e m_approximation_method; + }; + + + + +} + +#endif diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_dda_line.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_dda_line.h new file mode 100644 index 00000000000..f589e76b83d --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_dda_line.h @@ -0,0 +1,290 @@ +//---------------------------------------------------------------------------- +// 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 dda_line_interpolator, dda2_line_interpolator +// +//---------------------------------------------------------------------------- + +#ifndef AGG_DDA_LINE_INCLUDED +#define AGG_DDA_LINE_INCLUDED + +#include <stdlib.h> +#include "agg_basics.h" + +namespace agg +{ + + //===================================================dda_line_interpolator + template<int FractionShift, int YShift=0> class dda_line_interpolator + { + public: + //-------------------------------------------------------------------- + dda_line_interpolator() {} + + //-------------------------------------------------------------------- + dda_line_interpolator(int y1, int y2, unsigned count) : + m_y(y1), + m_inc(((y2 - y1) << FractionShift) / int(count)), + m_dy(0) + { + } + + //-------------------------------------------------------------------- + void operator ++ () + { + m_dy += m_inc; + } + + //-------------------------------------------------------------------- + void operator -- () + { + m_dy -= m_inc; + } + + //-------------------------------------------------------------------- + void operator += (unsigned n) + { + m_dy += m_inc * n; + } + + //-------------------------------------------------------------------- + void operator -= (unsigned n) + { + m_dy -= m_inc * n; + } + + + //-------------------------------------------------------------------- + int y() const { return m_y + (m_dy >> (FractionShift-YShift)); } + int dy() const { return m_dy; } + + + private: + int m_y; + int m_inc; + int m_dy; + }; + + + + + + //=================================================dda2_line_interpolator + class dda2_line_interpolator + { + public: + typedef int save_data_type; + enum save_size_e { save_size = 2 }; + + //-------------------------------------------------------------------- + dda2_line_interpolator() {} + + //-------------------------------------------- Forward-adjusted line + dda2_line_interpolator(int y1, int y2, int count) : + m_cnt(count <= 0 ? 1 : count), + m_lft((y2 - y1) / m_cnt), + m_rem((y2 - y1) % m_cnt), + m_mod(m_rem), + m_y(y1) + { + if(m_mod <= 0) + { + m_mod += count; + m_rem += count; + m_lft--; + } + m_mod -= count; + } + + //-------------------------------------------- Backward-adjusted line + dda2_line_interpolator(int y1, int y2, int count, int) : + m_cnt(count <= 0 ? 1 : count), + m_lft((y2 - y1) / m_cnt), + m_rem((y2 - y1) % m_cnt), + m_mod(m_rem), + m_y(y1) + { + if(m_mod <= 0) + { + m_mod += count; + m_rem += count; + m_lft--; + } + } + + //-------------------------------------------- Backward-adjusted line + dda2_line_interpolator(int y, int count) : + m_cnt(count <= 0 ? 1 : count), + m_lft(y / m_cnt), + m_rem(y % m_cnt), + m_mod(m_rem), + m_y(0) + { + if(m_mod <= 0) + { + m_mod += count; + m_rem += count; + m_lft--; + } + } + + + //-------------------------------------------------------------------- + void save(save_data_type* data) const + { + data[0] = m_mod; + data[1] = m_y; + } + + //-------------------------------------------------------------------- + void load(const save_data_type* data) + { + m_mod = data[0]; + m_y = data[1]; + } + + //-------------------------------------------------------------------- + void operator++() + { + m_mod += m_rem; + m_y += m_lft; + if(m_mod > 0) + { + m_mod -= m_cnt; + m_y++; + } + } + + //-------------------------------------------------------------------- + void operator--() + { + if(m_mod <= m_rem) + { + m_mod += m_cnt; + m_y--; + } + m_mod -= m_rem; + m_y -= m_lft; + } + + //-------------------------------------------------------------------- + void adjust_forward() + { + m_mod -= m_cnt; + } + + //-------------------------------------------------------------------- + void adjust_backward() + { + m_mod += m_cnt; + } + + //-------------------------------------------------------------------- + int mod() const { return m_mod; } + int rem() const { return m_rem; } + int lft() const { return m_lft; } + + //-------------------------------------------------------------------- + int y() const { return m_y; } + + private: + int m_cnt; + int m_lft; + int m_rem; + int m_mod; + int m_y; + }; + + + + + + + + //---------------------------------------------line_bresenham_interpolator + class line_bresenham_interpolator + { + public: + enum subpixel_scale_e + { + subpixel_shift = 8, + subpixel_scale = 1 << subpixel_shift, + subpixel_mask = subpixel_scale - 1 + }; + + //-------------------------------------------------------------------- + static int line_lr(int v) { return v >> subpixel_shift; } + + //-------------------------------------------------------------------- + line_bresenham_interpolator(int x1, int y1, int x2, int y2) : + m_x1_lr(line_lr(x1)), + m_y1_lr(line_lr(y1)), + m_x2_lr(line_lr(x2)), + m_y2_lr(line_lr(y2)), + m_ver(abs(m_x2_lr - m_x1_lr) < abs(m_y2_lr - m_y1_lr)), + m_len(m_ver ? abs(m_y2_lr - m_y1_lr) : + abs(m_x2_lr - m_x1_lr)), + m_inc(m_ver ? ((y2 > y1) ? 1 : -1) : ((x2 > x1) ? 1 : -1)), + m_interpolator(m_ver ? x1 : y1, + m_ver ? x2 : y2, + m_len) + { + } + + //-------------------------------------------------------------------- + bool is_ver() const { return m_ver; } + unsigned len() const { return m_len; } + int inc() const { return m_inc; } + + //-------------------------------------------------------------------- + void hstep() + { + ++m_interpolator; + m_x1_lr += m_inc; + } + + //-------------------------------------------------------------------- + void vstep() + { + ++m_interpolator; + m_y1_lr += m_inc; + } + + //-------------------------------------------------------------------- + int x1() const { return m_x1_lr; } + int y1() const { return m_y1_lr; } + int x2() const { return line_lr(m_interpolator.y()); } + int y2() const { return line_lr(m_interpolator.y()); } + int x2_hr() const { return m_interpolator.y(); } + int y2_hr() const { return m_interpolator.y(); } + + private: + int m_x1_lr; + int m_y1_lr; + int m_x2_lr; + int m_y2_lr; + bool m_ver; + unsigned m_len; + int m_inc; + dda2_line_interpolator m_interpolator; + + }; + + +} + + + +#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 00000000000..e78ce27dd94 --- /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 00000000000..ee3b9c4638f --- /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 00000000000..9d522d671c7 --- /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 00000000000..fe9a9280faa --- /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 00000000000..75d311eff79 --- /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_gamma_functions.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_gamma_functions.h new file mode 100644 index 00000000000..5d720daa9a7 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_gamma_functions.h @@ -0,0 +1,132 @@ +//---------------------------------------------------------------------------- +// 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_GAMMA_FUNCTIONS_INCLUDED +#define AGG_GAMMA_FUNCTIONS_INCLUDED + +#include <math.h> +#include "agg_basics.h" + +namespace agg +{ + //===============================================================gamma_none + struct gamma_none + { + double operator()(double x) const { return x; } + }; + + + //==============================================================gamma_power + class gamma_power + { + public: + gamma_power() : m_gamma(1.0) {} + gamma_power(double g) : m_gamma(g) {} + + void gamma(double g) { m_gamma = g; } + double gamma() const { return m_gamma; } + + double operator() (double x) const + { + return pow(x, m_gamma); + } + + private: + double m_gamma; + }; + + + //==========================================================gamma_threshold + class gamma_threshold + { + public: + gamma_threshold() : m_threshold(0.5) {} + gamma_threshold(double t) : m_threshold(t) {} + + void threshold(double t) { m_threshold = t; } + double threshold() const { return m_threshold; } + + double operator() (double x) const + { + return (x < m_threshold) ? 0.0 : 1.0; + } + + private: + double m_threshold; + }; + + + //============================================================gamma_linear + class gamma_linear + { + public: + gamma_linear() : m_start(0.0), m_end(1.0) {} + gamma_linear(double s, double e) : m_start(s), m_end(e) {} + + void set(double s, double e) { m_start = s; m_end = e; } + void start(double s) { m_start = s; } + void end(double e) { m_end = e; } + double start() const { return m_start; } + double end() const { return m_end; } + + double operator() (double x) const + { + if(x < m_start) return 0.0; + if(x > m_end) return 1.0; + return (x - m_start) / (m_end - m_start); + } + + private: + double m_start; + double m_end; + }; + + + //==========================================================gamma_multiply + class gamma_multiply + { + public: + gamma_multiply() : m_mul(1.0) {} + gamma_multiply(double v) : m_mul(v) {} + + void value(double v) { m_mul = v; } + double value() const { return m_mul; } + + double operator() (double x) const + { + double y = x * m_mul; + if(y > 1.0) y = 1.0; + return y; + } + + private: + double m_mul; + }; + + inline double sRGB_to_linear(double x) + { + return (x <= 0.04045) ? (x / 12.92) : pow((x + 0.055) / (1.055), 2.4); + } + + inline double linear_to_sRGB(double x) + { + return (x <= 0.0031308) ? (x * 12.92) : (1.055 * pow(x, 1 / 2.4) - 0.055); + } +} + +#endif + + + diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_gamma_lut.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_gamma_lut.h new file mode 100644 index 00000000000..ef1e38d8092 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_gamma_lut.h @@ -0,0 +1,305 @@ +//---------------------------------------------------------------------------- +// 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_GAMMA_LUT_INCLUDED +#define AGG_GAMMA_LUT_INCLUDED + +#include <math.h> +#include "agg_basics.h" +#include "agg_gamma_functions.h" + +namespace agg +{ + template<class LoResT=int8u, + class HiResT=int8u, + unsigned GammaShift=8, + unsigned HiResShift=8> class gamma_lut + { + public: + typedef gamma_lut<LoResT, HiResT, GammaShift, HiResShift> self_type; + + enum gamma_scale_e + { + gamma_shift = GammaShift, + gamma_size = 1 << gamma_shift, + gamma_mask = gamma_size - 1 + }; + + enum hi_res_scale_e + { + hi_res_shift = HiResShift, + hi_res_size = 1 << hi_res_shift, + hi_res_mask = hi_res_size - 1 + }; + + ~gamma_lut() + { + pod_allocator<LoResT>::deallocate(m_inv_gamma, hi_res_size); + pod_allocator<HiResT>::deallocate(m_dir_gamma, gamma_size); + } + + gamma_lut() : + m_gamma(1.0), + m_dir_gamma(pod_allocator<HiResT>::allocate(gamma_size)), + m_inv_gamma(pod_allocator<LoResT>::allocate(hi_res_size)) + { + unsigned i; + for(i = 0; i < gamma_size; i++) + { + m_dir_gamma[i] = HiResT(i << (hi_res_shift - gamma_shift)); + } + + for(i = 0; i < hi_res_size; i++) + { + m_inv_gamma[i] = LoResT(i >> (hi_res_shift - gamma_shift)); + } + } + + gamma_lut(double g) : + m_gamma(1.0), + m_dir_gamma(pod_allocator<HiResT>::allocate(gamma_size)), + m_inv_gamma(pod_allocator<LoResT>::allocate(hi_res_size)) + { + gamma(g); + } + + void gamma(double g) + { + m_gamma = g; + + unsigned i; + for(i = 0; i < gamma_size; i++) + { + m_dir_gamma[i] = (HiResT) + uround(pow(i / double(gamma_mask), m_gamma) * double(hi_res_mask)); + } + + double inv_g = 1.0 / g; + for(i = 0; i < hi_res_size; i++) + { + m_inv_gamma[i] = (LoResT) + uround(pow(i / double(hi_res_mask), inv_g) * double(gamma_mask)); + } + } + + double gamma() const + { + return m_gamma; + } + + HiResT dir(LoResT v) const + { + return m_dir_gamma[unsigned(v)]; + } + + LoResT inv(HiResT v) const + { + return m_inv_gamma[unsigned(v)]; + } + + private: + gamma_lut(const self_type&); + const self_type& operator = (const self_type&); + + double m_gamma; + HiResT* m_dir_gamma; + LoResT* m_inv_gamma; + }; + + // + // sRGB support classes + // + + // Optimized sRGB lookup table. The direct conversion (sRGB to linear) + // is a straightforward lookup. The inverse conversion (linear to sRGB) + // is implemented using binary search. + template<class LinearType> + class sRGB_lut_base + { + public: + LinearType dir(int8u v) const + { + return m_dir_table[v]; + } + + int8u inv(LinearType v) const + { + // Unrolled binary search. + int8u x = 0; + if (v > m_inv_table[128]) x = 128; + if (v > m_inv_table[x + 64]) x += 64; + if (v > m_inv_table[x + 32]) x += 32; + if (v > m_inv_table[x + 16]) x += 16; + if (v > m_inv_table[x + 8]) x += 8; + if (v > m_inv_table[x + 4]) x += 4; + if (v > m_inv_table[x + 2]) x += 2; + if (v > m_inv_table[x + 1]) x += 1; + return x; + } + + protected: + LinearType m_dir_table[256]; + LinearType m_inv_table[256]; + + // Only derived classes may instantiate. + sRGB_lut_base() + { + } + }; + + // sRGB_lut - implements sRGB conversion for the various types. + // Base template is undefined, specializations are provided below. + template<class LinearType> + class sRGB_lut; + + template<> + class sRGB_lut<float> : public sRGB_lut_base<float> + { + public: + sRGB_lut() + { + // Generate lookup tables. + m_dir_table[0] = 0; + m_inv_table[0] = 0; + for (unsigned i = 1; i <= 255; ++i) + { + // Floating-point RGB is in range [0,1]. + m_dir_table[i] = float(sRGB_to_linear(i / 255.0)); + m_inv_table[i] = float(sRGB_to_linear((i - 0.5) / 255.0)); + } + } + }; + + template<> + class sRGB_lut<int16u> : public sRGB_lut_base<int16u> + { + public: + sRGB_lut() + { + // Generate lookup tables. + m_dir_table[0] = 0; + m_inv_table[0] = 0; + for (unsigned i = 1; i <= 255; ++i) + { + // 16-bit RGB is in range [0,65535]. + m_dir_table[i] = uround(65535.0 * sRGB_to_linear(i / 255.0)); + m_inv_table[i] = uround(65535.0 * sRGB_to_linear((i - 0.5) / 255.0)); + } + } + }; + + template<> + class sRGB_lut<int8u> : public sRGB_lut_base<int8u> + { + public: + sRGB_lut() + { + // Generate lookup tables. + m_dir_table[0] = 0; + m_inv_table[0] = 0; + for (unsigned i = 1; i <= 255; ++i) + { + // 8-bit RGB is handled with simple bidirectional lookup tables. + m_dir_table[i] = uround(255.0 * sRGB_to_linear(i / 255.0)); + m_inv_table[i] = uround(255.0 * linear_to_sRGB(i / 255.0)); + } + } + + int8u inv(int8u v) const + { + // In this case, the inverse transform is a simple lookup. + return m_inv_table[v]; + } + }; + + // Common base class for sRGB_conv objects. Defines an internal + // sRGB_lut object so that users don't have to. + template<class T> + class sRGB_conv_base + { + public: + static T rgb_from_sRGB(int8u x) + { + return lut.dir(x); + } + + static int8u rgb_to_sRGB(T x) + { + return lut.inv(x); + } + + private: + static sRGB_lut<T> lut; + }; + + // Definition of sRGB_conv_base::lut. Due to the fact that this a template, + // we don't need to place the definition in a cpp file. Hurrah. + template<class T> + sRGB_lut<T> sRGB_conv_base<T>::lut; + + // Wrapper for sRGB-linear conversion. + // Base template is undefined, specializations are provided below. + template<class T> + class sRGB_conv; + + template<> + class sRGB_conv<float> : public sRGB_conv_base<float> + { + public: + static float alpha_from_sRGB(int8u x) + { + return float(x / 255.0); + } + + static int8u alpha_to_sRGB(float x) + { + if (x <= 0) return 0; + else if (x >= 1) return 255; + else return int8u(0.5 + x * 255); + } + }; + + template<> + class sRGB_conv<int16u> : public sRGB_conv_base<int16u> + { + public: + static int16u alpha_from_sRGB(int8u x) + { + return (x << 8) | x; + } + + static int8u alpha_to_sRGB(int16u x) + { + return x >> 8; + } + }; + + template<> + class sRGB_conv<int8u> : public sRGB_conv_base<int8u> + { + public: + static int8u alpha_from_sRGB(int8u x) + { + return x; + } + + static int8u alpha_to_sRGB(int8u x) + { + return x; + } + }; +} + +#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 00000000000..b0bf858efd6 --- /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 00000000000..9aaa426815e --- /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 00000000000..16b3aeb33d8 --- /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_image_accessors.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_image_accessors.h new file mode 100644 index 00000000000..c651d6d2e8d --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_image_accessors.h @@ -0,0 +1,481 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- + +#ifndef AGG_IMAGE_ACCESSORS_INCLUDED +#define AGG_IMAGE_ACCESSORS_INCLUDED + +#include "agg_basics.h" + +namespace agg +{ + + //-----------------------------------------------------image_accessor_clip + template<class PixFmt> class image_accessor_clip + { + public: + typedef PixFmt pixfmt_type; + typedef typename pixfmt_type::color_type color_type; + typedef typename pixfmt_type::order_type order_type; + typedef typename pixfmt_type::value_type value_type; + enum pix_width_e { pix_width = pixfmt_type::pix_width }; + + image_accessor_clip() {} + explicit image_accessor_clip(pixfmt_type& pixf, + const color_type& bk) : + m_pixf(&pixf) + { + pixfmt_type::make_pix(m_bk_buf, bk); + } + + void attach(pixfmt_type& pixf) + { + m_pixf = &pixf; + } + + void background_color(const color_type& bk) + { + pixfmt_type::make_pix(m_bk_buf, bk); + } + + private: + AGG_INLINE const int8u* pixel() const + { + if(m_y >= 0 && m_y < (int)m_pixf->height() && + m_x >= 0 && m_x < (int)m_pixf->width()) + { + return m_pixf->pix_ptr(m_x, m_y); + } + return m_bk_buf; + } + + public: + AGG_INLINE const int8u* span(int x, int y, unsigned len) + { + m_x = m_x0 = x; + m_y = y; + if(y >= 0 && y < (int)m_pixf->height() && + x >= 0 && x+(int)len <= (int)m_pixf->width()) + { + return m_pix_ptr = m_pixf->pix_ptr(x, y); + } + m_pix_ptr = 0; + return pixel(); + } + + AGG_INLINE const int8u* next_x() + { + if(m_pix_ptr) return m_pix_ptr += pix_width; + ++m_x; + return pixel(); + } + + AGG_INLINE const int8u* next_y() + { + ++m_y; + m_x = m_x0; + if(m_pix_ptr && + m_y >= 0 && m_y < (int)m_pixf->height()) + { + return m_pix_ptr = m_pixf->pix_ptr(m_x, m_y); + } + m_pix_ptr = 0; + return pixel(); + } + + private: + const pixfmt_type* m_pixf; + int8u m_bk_buf[pix_width]; + int m_x, m_x0, m_y; + const int8u* m_pix_ptr; + }; + + + + + //--------------------------------------------------image_accessor_no_clip + template<class PixFmt> class image_accessor_no_clip + { + public: + typedef PixFmt pixfmt_type; + typedef typename pixfmt_type::color_type color_type; + typedef typename pixfmt_type::order_type order_type; + typedef typename pixfmt_type::value_type value_type; + enum pix_width_e { pix_width = pixfmt_type::pix_width }; + + image_accessor_no_clip() {} + explicit image_accessor_no_clip(pixfmt_type& pixf) : + m_pixf(&pixf) + {} + + void attach(pixfmt_type& pixf) + { + m_pixf = &pixf; + } + + AGG_INLINE const int8u* span(int x, int y, unsigned) + { + m_x = x; + m_y = y; + return m_pix_ptr = m_pixf->pix_ptr(x, y); + } + + AGG_INLINE const int8u* next_x() + { + return m_pix_ptr += pix_width; + } + + AGG_INLINE const int8u* next_y() + { + ++m_y; + return m_pix_ptr = m_pixf->pix_ptr(m_x, m_y); + } + + private: + const pixfmt_type* m_pixf; + int m_x, m_y; + const int8u* m_pix_ptr; + }; + + + + + //----------------------------------------------------image_accessor_clone + template<class PixFmt> class image_accessor_clone + { + public: + typedef PixFmt pixfmt_type; + typedef typename pixfmt_type::color_type color_type; + typedef typename pixfmt_type::order_type order_type; + typedef typename pixfmt_type::value_type value_type; + enum pix_width_e { pix_width = pixfmt_type::pix_width }; + + image_accessor_clone() {} + explicit image_accessor_clone(pixfmt_type& pixf) : + m_pixf(&pixf) + {} + + void attach(pixfmt_type& pixf) + { + m_pixf = &pixf; + } + + private: + AGG_INLINE const int8u* pixel() const + { + int x = m_x; + int y = m_y; + if(x < 0) x = 0; + if(y < 0) y = 0; + if(x >= (int)m_pixf->width()) x = m_pixf->width() - 1; + if(y >= (int)m_pixf->height()) y = m_pixf->height() - 1; + return m_pixf->pix_ptr(x, y); + } + + public: + AGG_INLINE const int8u* span(int x, int y, unsigned len) + { + m_x = m_x0 = x; + m_y = y; + if(y >= 0 && y < (int)m_pixf->height() && + x >= 0 && x+len <= (int)m_pixf->width()) + { + return m_pix_ptr = m_pixf->pix_ptr(x, y); + } + m_pix_ptr = 0; + return pixel(); + } + + AGG_INLINE const int8u* next_x() + { + if(m_pix_ptr) return m_pix_ptr += pix_width; + ++m_x; + return pixel(); + } + + AGG_INLINE const int8u* next_y() + { + ++m_y; + m_x = m_x0; + if(m_pix_ptr && + m_y >= 0 && m_y < (int)m_pixf->height()) + { + return m_pix_ptr = m_pixf->pix_ptr(m_x, m_y); + } + m_pix_ptr = 0; + return pixel(); + } + + private: + const pixfmt_type* m_pixf; + int m_x, m_x0, m_y; + const int8u* m_pix_ptr; + }; + + + + + + //-----------------------------------------------------image_accessor_wrap + template<class PixFmt, class WrapX, class WrapY> class image_accessor_wrap + { + public: + typedef PixFmt pixfmt_type; + typedef typename pixfmt_type::color_type color_type; + typedef typename pixfmt_type::order_type order_type; + typedef typename pixfmt_type::value_type value_type; + enum pix_width_e { pix_width = pixfmt_type::pix_width }; + + image_accessor_wrap() {} + explicit image_accessor_wrap(pixfmt_type& pixf) : + m_pixf(&pixf), + m_wrap_x(pixf.width()), + m_wrap_y(pixf.height()) + {} + + void attach(pixfmt_type& pixf) + { + m_pixf = &pixf; + } + + AGG_INLINE const int8u* span(int x, int y, unsigned) + { + m_x = x; + m_row_ptr = m_pixf->pix_ptr(0, m_wrap_y(y)); + return m_row_ptr + m_wrap_x(x) * pix_width; + } + + AGG_INLINE const int8u* next_x() + { + int x = ++m_wrap_x; + return m_row_ptr + x * pix_width; + } + + AGG_INLINE const int8u* next_y() + { + m_row_ptr = m_pixf->pix_ptr(0, ++m_wrap_y); + return m_row_ptr + m_wrap_x(m_x) * pix_width; + } + + private: + const pixfmt_type* m_pixf; + const int8u* m_row_ptr; + int m_x; + WrapX m_wrap_x; + WrapY m_wrap_y; + }; + + + + + //--------------------------------------------------------wrap_mode_repeat + class wrap_mode_repeat + { + public: + wrap_mode_repeat() {} + wrap_mode_repeat(unsigned size) : + m_size(size), + m_add(size * (0x3FFFFFFF / size)), + m_value(0) + {} + + AGG_INLINE unsigned operator() (int v) + { + return m_value = (unsigned(v) + m_add) % m_size; + } + + AGG_INLINE unsigned operator++ () + { + ++m_value; + if(m_value >= m_size) m_value = 0; + return m_value; + } + private: + unsigned m_size; + unsigned m_add; + unsigned m_value; + }; + + + //---------------------------------------------------wrap_mode_repeat_pow2 + class wrap_mode_repeat_pow2 + { + public: + wrap_mode_repeat_pow2() {} + wrap_mode_repeat_pow2(unsigned size) : m_value(0) + { + m_mask = 1; + while(m_mask < size) m_mask = (m_mask << 1) | 1; + m_mask >>= 1; + } + AGG_INLINE unsigned operator() (int v) + { + return m_value = unsigned(v) & m_mask; + } + AGG_INLINE unsigned operator++ () + { + ++m_value; + if(m_value > m_mask) m_value = 0; + return m_value; + } + private: + unsigned m_mask; + unsigned m_value; + }; + + + //----------------------------------------------wrap_mode_repeat_auto_pow2 + class wrap_mode_repeat_auto_pow2 + { + public: + wrap_mode_repeat_auto_pow2() {} + wrap_mode_repeat_auto_pow2(unsigned size) : + m_size(size), + m_add(size * (0x3FFFFFFF / size)), + m_mask((m_size & (m_size-1)) ? 0 : m_size-1), + m_value(0) + {} + + AGG_INLINE unsigned operator() (int v) + { + if(m_mask) return m_value = unsigned(v) & m_mask; + return m_value = (unsigned(v) + m_add) % m_size; + } + AGG_INLINE unsigned operator++ () + { + ++m_value; + if(m_value >= m_size) m_value = 0; + return m_value; + } + + private: + unsigned m_size; + unsigned m_add; + unsigned m_mask; + unsigned m_value; + }; + + + //-------------------------------------------------------wrap_mode_reflect + class wrap_mode_reflect + { + public: + wrap_mode_reflect() {} + wrap_mode_reflect(unsigned size) : + m_size(size), + m_size2(size * 2), + m_add(m_size2 * (0x3FFFFFFF / m_size2)), + m_value(0) + {} + + AGG_INLINE unsigned operator() (int v) + { + m_value = (unsigned(v) + m_add) % m_size2; + if(m_value >= m_size) return m_size2 - m_value - 1; + return m_value; + } + + AGG_INLINE unsigned operator++ () + { + ++m_value; + if(m_value >= m_size2) m_value = 0; + if(m_value >= m_size) return m_size2 - m_value - 1; + return m_value; + } + private: + unsigned m_size; + unsigned m_size2; + unsigned m_add; + unsigned m_value; + }; + + + + //--------------------------------------------------wrap_mode_reflect_pow2 + class wrap_mode_reflect_pow2 + { + public: + wrap_mode_reflect_pow2() {} + wrap_mode_reflect_pow2(unsigned size) : m_value(0) + { + m_mask = 1; + m_size = 1; + while(m_mask < size) + { + m_mask = (m_mask << 1) | 1; + m_size <<= 1; + } + } + AGG_INLINE unsigned operator() (int v) + { + m_value = unsigned(v) & m_mask; + if(m_value >= m_size) return m_mask - m_value; + return m_value; + } + AGG_INLINE unsigned operator++ () + { + ++m_value; + m_value &= m_mask; + if(m_value >= m_size) return m_mask - m_value; + return m_value; + } + private: + unsigned m_size; + unsigned m_mask; + unsigned m_value; + }; + + + + //---------------------------------------------wrap_mode_reflect_auto_pow2 + class wrap_mode_reflect_auto_pow2 + { + public: + wrap_mode_reflect_auto_pow2() {} + wrap_mode_reflect_auto_pow2(unsigned size) : + m_size(size), + m_size2(size * 2), + m_add(m_size2 * (0x3FFFFFFF / m_size2)), + m_mask((m_size2 & (m_size2-1)) ? 0 : m_size2-1), + m_value(0) + {} + + AGG_INLINE unsigned operator() (int v) + { + m_value = m_mask ? unsigned(v) & m_mask : + (unsigned(v) + m_add) % m_size2; + if(m_value >= m_size) return m_size2 - m_value - 1; + return m_value; + } + AGG_INLINE unsigned operator++ () + { + ++m_value; + if(m_value >= m_size2) m_value = 0; + if(m_value >= m_size) return m_size2 - m_value - 1; + return m_value; + } + + private: + unsigned m_size; + unsigned m_size2; + unsigned m_add; + unsigned m_mask; + unsigned m_value; + }; + + +} + + +#endif diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_image_filters.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_image_filters.h new file mode 100644 index 00000000000..8e1bc8f0dba --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_image_filters.h @@ -0,0 +1,448 @@ +//---------------------------------------------------------------------------- +// 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 +//---------------------------------------------------------------------------- +// +// Image transformation filters, +// Filtering classes (image_filter_lut, image_filter), +// Basic filter shape classes +//---------------------------------------------------------------------------- +#ifndef AGG_IMAGE_FILTERS_INCLUDED +#define AGG_IMAGE_FILTERS_INCLUDED + +#include "agg_array.h" +#include "agg_math.h" + +namespace agg +{ + + // See Implementation agg_image_filters.cpp + + enum image_filter_scale_e + { + image_filter_shift = 14, //----image_filter_shift + image_filter_scale = 1 << image_filter_shift, //----image_filter_scale + image_filter_mask = image_filter_scale - 1 //----image_filter_mask + }; + + enum image_subpixel_scale_e + { + image_subpixel_shift = 8, //----image_subpixel_shift + image_subpixel_scale = 1 << image_subpixel_shift, //----image_subpixel_scale + image_subpixel_mask = image_subpixel_scale - 1 //----image_subpixel_mask + }; + + + //-----------------------------------------------------image_filter_lut + class image_filter_lut + { + public: + template<class FilterF> void calculate(const FilterF& filter, + bool normalization=true) + { + double r = filter.radius(); + realloc_lut(r); + unsigned i; + unsigned pivot = diameter() << (image_subpixel_shift - 1); + for(i = 0; i < pivot; i++) + { + double x = double(i) / double(image_subpixel_scale); + double y = filter.calc_weight(x); + m_weight_array[pivot + i] = + m_weight_array[pivot - i] = (int16)iround(y * image_filter_scale); + } + unsigned end = (diameter() << image_subpixel_shift) - 1; + m_weight_array[0] = m_weight_array[end]; + if(normalization) + { + normalize(); + } + } + + image_filter_lut() : m_radius(0), m_diameter(0), m_start(0) {} + + template<class FilterF> image_filter_lut(const FilterF& filter, + bool normalization=true) + { + calculate(filter, normalization); + } + + double radius() const { return m_radius; } + unsigned diameter() const { return m_diameter; } + int start() const { return m_start; } + const int16* weight_array() const { return &m_weight_array[0]; } + void normalize(); + + private: + void realloc_lut(double radius); + image_filter_lut(const image_filter_lut&); + const image_filter_lut& operator = (const image_filter_lut&); + + double m_radius; + unsigned m_diameter; + int m_start; + pod_array<int16> m_weight_array; + }; + + + + //--------------------------------------------------------image_filter + template<class FilterF> class image_filter : public image_filter_lut + { + public: + image_filter() + { + calculate(m_filter_function); + } + private: + FilterF m_filter_function; + }; + + + //-----------------------------------------------image_filter_bilinear + struct image_filter_bilinear + { + static double radius() { return 1.0; } + static double calc_weight(double x) + { + return 1.0 - x; + } + }; + + + //-----------------------------------------------image_filter_hanning + struct image_filter_hanning + { + static double radius() { return 1.0; } + static double calc_weight(double x) + { + return 0.5 + 0.5 * cos(pi * x); + } + }; + + + //-----------------------------------------------image_filter_hamming + struct image_filter_hamming + { + static double radius() { return 1.0; } + static double calc_weight(double x) + { + return 0.54 + 0.46 * cos(pi * x); + } + }; + + //-----------------------------------------------image_filter_hermite + struct image_filter_hermite + { + static double radius() { return 1.0; } + static double calc_weight(double x) + { + return (2.0 * x - 3.0) * x * x + 1.0; + } + }; + + //------------------------------------------------image_filter_quadric + struct image_filter_quadric + { + static double radius() { return 1.5; } + static double calc_weight(double x) + { + double t; + if(x < 0.5) return 0.75 - x * x; + if(x < 1.5) {t = x - 1.5; return 0.5 * t * t;} + return 0.0; + } + }; + + //------------------------------------------------image_filter_bicubic + class image_filter_bicubic + { + static double pow3(double x) + { + return (x <= 0.0) ? 0.0 : x * x * x; + } + + public: + static double radius() { return 2.0; } + static double calc_weight(double x) + { + return + (1.0/6.0) * + (pow3(x + 2) - 4 * pow3(x + 1) + 6 * pow3(x) - 4 * pow3(x - 1)); + } + }; + + //-------------------------------------------------image_filter_kaiser + class image_filter_kaiser + { + double a; + double i0a; + double epsilon; + + public: + image_filter_kaiser(double b = 6.33) : + a(b), epsilon(1e-12) + { + i0a = 1.0 / bessel_i0(b); + } + + static double radius() { return 1.0; } + double calc_weight(double x) const + { + return bessel_i0(a * sqrt(1. - x * x)) * i0a; + } + + private: + double bessel_i0(double x) const + { + int i; + double sum, y, t; + + sum = 1.; + y = x * x / 4.; + t = y; + + for(i = 2; t > epsilon; i++) + { + sum += t; + t *= (double)y / (i * i); + } + return sum; + } + }; + + //----------------------------------------------image_filter_catrom + struct image_filter_catrom + { + static double radius() { return 2.0; } + static double calc_weight(double x) + { + if(x < 1.0) return 0.5 * (2.0 + x * x * (-5.0 + x * 3.0)); + if(x < 2.0) return 0.5 * (4.0 + x * (-8.0 + x * (5.0 - x))); + return 0.; + } + }; + + //---------------------------------------------image_filter_mitchell + class image_filter_mitchell + { + double p0, p2, p3; + double q0, q1, q2, q3; + + public: + image_filter_mitchell(double b = 1.0/3.0, double c = 1.0/3.0) : + p0((6.0 - 2.0 * b) / 6.0), + p2((-18.0 + 12.0 * b + 6.0 * c) / 6.0), + p3((12.0 - 9.0 * b - 6.0 * c) / 6.0), + q0((8.0 * b + 24.0 * c) / 6.0), + q1((-12.0 * b - 48.0 * c) / 6.0), + q2((6.0 * b + 30.0 * c) / 6.0), + q3((-b - 6.0 * c) / 6.0) + {} + + static double radius() { return 2.0; } + double calc_weight(double x) const + { + if(x < 1.0) return p0 + x * x * (p2 + x * p3); + if(x < 2.0) return q0 + x * (q1 + x * (q2 + x * q3)); + return 0.0; + } + }; + + + //----------------------------------------------image_filter_spline16 + struct image_filter_spline16 + { + static double radius() { return 2.0; } + static double calc_weight(double x) + { + if(x < 1.0) + { + return ((x - 9.0/5.0 ) * x - 1.0/5.0 ) * x + 1.0; + } + return ((-1.0/3.0 * (x-1) + 4.0/5.0) * (x-1) - 7.0/15.0 ) * (x-1); + } + }; + + + //---------------------------------------------image_filter_spline36 + struct image_filter_spline36 + { + static double radius() { return 3.0; } + static double calc_weight(double x) + { + if(x < 1.0) + { + return ((13.0/11.0 * x - 453.0/209.0) * x - 3.0/209.0) * x + 1.0; + } + if(x < 2.0) + { + return ((-6.0/11.0 * (x-1) + 270.0/209.0) * (x-1) - 156.0/ 209.0) * (x-1); + } + return ((1.0/11.0 * (x-2) - 45.0/209.0) * (x-2) + 26.0/209.0) * (x-2); + } + }; + + + //----------------------------------------------image_filter_gaussian + struct image_filter_gaussian + { + static double radius() { return 2.0; } + static double calc_weight(double x) + { + return exp(-2.0 * x * x) * sqrt(2.0 / pi); + } + }; + + + //------------------------------------------------image_filter_bessel + struct image_filter_bessel + { + static double radius() { return 3.2383; } + static double calc_weight(double x) + { + return (x == 0.0) ? pi / 4.0 : besj(pi * x, 1) / (2.0 * x); + } + }; + + + //-------------------------------------------------image_filter_sinc + class image_filter_sinc + { + public: + image_filter_sinc(double r) : m_radius(r < 2.0 ? 2.0 : r) {} + double radius() const { return m_radius; } + double calc_weight(double x) const + { + if(x == 0.0) return 1.0; + x *= pi; + return sin(x) / x; + } + private: + double m_radius; + }; + + + //-----------------------------------------------image_filter_lanczos + class image_filter_lanczos + { + public: + image_filter_lanczos(double r) : m_radius(r < 2.0 ? 2.0 : r) {} + double radius() const { return m_radius; } + double calc_weight(double x) const + { + if(x == 0.0) return 1.0; + if(x > m_radius) return 0.0; + x *= pi; + double xr = x / m_radius; + return (sin(x) / x) * (sin(xr) / xr); + } + private: + double m_radius; + }; + + + //----------------------------------------------image_filter_blackman + class image_filter_blackman + { + public: + image_filter_blackman(double r) : m_radius(r < 2.0 ? 2.0 : r) {} + double radius() const { return m_radius; } + double calc_weight(double x) const + { + if(x == 0.0) return 1.0; + if(x > m_radius) return 0.0; + x *= pi; + double xr = x / m_radius; + return (sin(x) / x) * (0.42 + 0.5*cos(xr) + 0.08*cos(2*xr)); + } + private: + double m_radius; + }; + + //------------------------------------------------image_filter_sinc36 + class image_filter_sinc36 : public image_filter_sinc + { public: image_filter_sinc36() : image_filter_sinc(3.0){} }; + + //------------------------------------------------image_filter_sinc64 + class image_filter_sinc64 : public image_filter_sinc + { public: image_filter_sinc64() : image_filter_sinc(4.0){} }; + + //-----------------------------------------------image_filter_sinc100 + class image_filter_sinc100 : public image_filter_sinc + { public: image_filter_sinc100() : image_filter_sinc(5.0){} }; + + //-----------------------------------------------image_filter_sinc144 + class image_filter_sinc144 : public image_filter_sinc + { public: image_filter_sinc144() : image_filter_sinc(6.0){} }; + + //-----------------------------------------------image_filter_sinc196 + class image_filter_sinc196 : public image_filter_sinc + { public: image_filter_sinc196() : image_filter_sinc(7.0){} }; + + //-----------------------------------------------image_filter_sinc256 + class image_filter_sinc256 : public image_filter_sinc + { public: image_filter_sinc256() : image_filter_sinc(8.0){} }; + + //---------------------------------------------image_filter_lanczos36 + class image_filter_lanczos36 : public image_filter_lanczos + { public: image_filter_lanczos36() : image_filter_lanczos(3.0){} }; + + //---------------------------------------------image_filter_lanczos64 + class image_filter_lanczos64 : public image_filter_lanczos + { public: image_filter_lanczos64() : image_filter_lanczos(4.0){} }; + + //--------------------------------------------image_filter_lanczos100 + class image_filter_lanczos100 : public image_filter_lanczos + { public: image_filter_lanczos100() : image_filter_lanczos(5.0){} }; + + //--------------------------------------------image_filter_lanczos144 + class image_filter_lanczos144 : public image_filter_lanczos + { public: image_filter_lanczos144() : image_filter_lanczos(6.0){} }; + + //--------------------------------------------image_filter_lanczos196 + class image_filter_lanczos196 : public image_filter_lanczos + { public: image_filter_lanczos196() : image_filter_lanczos(7.0){} }; + + //--------------------------------------------image_filter_lanczos256 + class image_filter_lanczos256 : public image_filter_lanczos + { public: image_filter_lanczos256() : image_filter_lanczos(8.0){} }; + + //--------------------------------------------image_filter_blackman36 + class image_filter_blackman36 : public image_filter_blackman + { public: image_filter_blackman36() : image_filter_blackman(3.0){} }; + + //--------------------------------------------image_filter_blackman64 + class image_filter_blackman64 : public image_filter_blackman + { public: image_filter_blackman64() : image_filter_blackman(4.0){} }; + + //-------------------------------------------image_filter_blackman100 + class image_filter_blackman100 : public image_filter_blackman + { public: image_filter_blackman100() : image_filter_blackman(5.0){} }; + + //-------------------------------------------image_filter_blackman144 + class image_filter_blackman144 : public image_filter_blackman + { public: image_filter_blackman144() : image_filter_blackman(6.0){} }; + + //-------------------------------------------image_filter_blackman196 + class image_filter_blackman196 : public image_filter_blackman + { public: image_filter_blackman196() : image_filter_blackman(7.0){} }; + + //-------------------------------------------image_filter_blackman256 + class image_filter_blackman256 : public image_filter_blackman + { public: image_filter_blackman256() : image_filter_blackman(8.0){} }; + + +} + +#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 00000000000..c5acb18e796 --- /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_math.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_math.h new file mode 100644 index 00000000000..2ec49cf3ff8 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_math.h @@ -0,0 +1,437 @@ +//---------------------------------------------------------------------------- +// 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 +//---------------------------------------------------------------------------- +// Bessel function (besj) was adapted for use in AGG library by Andy Wilk +// Contact: castor.vulgaris@gmail.com +//---------------------------------------------------------------------------- + +#ifndef AGG_MATH_INCLUDED +#define AGG_MATH_INCLUDED + +#include <math.h> +#include "agg_basics.h" + +namespace agg +{ + + //------------------------------------------------------vertex_dist_epsilon + // Coinciding points maximal distance (Epsilon) + const double vertex_dist_epsilon = 1e-14; + + //-----------------------------------------------------intersection_epsilon + // See calc_intersection + const double intersection_epsilon = 1.0e-30; + + //------------------------------------------------------------cross_product + AGG_INLINE double cross_product(double x1, double y1, + double x2, double y2, + double x, double y) + { + return (x - x2) * (y2 - y1) - (y - y2) * (x2 - x1); + } + + //--------------------------------------------------------point_in_triangle + AGG_INLINE bool point_in_triangle(double x1, double y1, + double x2, double y2, + double x3, double y3, + double x, double y) + { + bool cp1 = cross_product(x1, y1, x2, y2, x, y) < 0.0; + bool cp2 = cross_product(x2, y2, x3, y3, x, y) < 0.0; + bool cp3 = cross_product(x3, y3, x1, y1, x, y) < 0.0; + return cp1 == cp2 && cp2 == cp3 && cp3 == cp1; + } + + //-----------------------------------------------------------calc_distance + AGG_INLINE double calc_distance(double x1, double y1, double x2, double y2) + { + double dx = x2-x1; + double dy = y2-y1; + return sqrt(dx * dx + dy * dy); + } + + //--------------------------------------------------------calc_sq_distance + AGG_INLINE double calc_sq_distance(double x1, double y1, double x2, double y2) + { + double dx = x2-x1; + double dy = y2-y1; + return dx * dx + dy * dy; + } + + //------------------------------------------------calc_line_point_distance + AGG_INLINE double calc_line_point_distance(double x1, double y1, + double x2, double y2, + double x, double y) + { + double dx = x2-x1; + double dy = y2-y1; + double d = sqrt(dx * dx + dy * dy); + if(d < vertex_dist_epsilon) + { + return calc_distance(x1, y1, x, y); + } + return ((x - x2) * dy - (y - y2) * dx) / d; + } + + //-------------------------------------------------------calc_line_point_u + AGG_INLINE double calc_segment_point_u(double x1, double y1, + double x2, double y2, + double x, double y) + { + double dx = x2 - x1; + double dy = y2 - y1; + + if(dx == 0 && dy == 0) + { + return 0; + } + + double pdx = x - x1; + double pdy = y - y1; + + return (pdx * dx + pdy * dy) / (dx * dx + dy * dy); + } + + //---------------------------------------------calc_line_point_sq_distance + AGG_INLINE double calc_segment_point_sq_distance(double x1, double y1, + double x2, double y2, + double x, double y, + double u) + { + if(u <= 0) + { + return calc_sq_distance(x, y, x1, y1); + } + else + if(u >= 1) + { + return calc_sq_distance(x, y, x2, y2); + } + return calc_sq_distance(x, y, x1 + u * (x2 - x1), y1 + u * (y2 - y1)); + } + + //---------------------------------------------calc_line_point_sq_distance + AGG_INLINE double calc_segment_point_sq_distance(double x1, double y1, + double x2, double y2, + double x, double y) + { + return + calc_segment_point_sq_distance( + x1, y1, x2, y2, x, y, + calc_segment_point_u(x1, y1, x2, y2, x, y)); + } + + //-------------------------------------------------------calc_intersection + AGG_INLINE bool calc_intersection(double ax, double ay, double bx, double by, + double cx, double cy, double dx, double dy, + double* x, double* y) + { + double num = (ay-cy) * (dx-cx) - (ax-cx) * (dy-cy); + double den = (bx-ax) * (dy-cy) - (by-ay) * (dx-cx); + if(fabs(den) < intersection_epsilon) return false; + double r = num / den; + *x = ax + r * (bx-ax); + *y = ay + r * (by-ay); + return true; + } + + //-----------------------------------------------------intersection_exists + AGG_INLINE bool intersection_exists(double x1, double y1, double x2, double y2, + double x3, double y3, double x4, double y4) + { + // It's less expensive but you can't control the + // boundary conditions: Less or LessEqual + double dx1 = x2 - x1; + double dy1 = y2 - y1; + double dx2 = x4 - x3; + double dy2 = y4 - y3; + return ((x3 - x2) * dy1 - (y3 - y2) * dx1 < 0.0) != + ((x4 - x2) * dy1 - (y4 - y2) * dx1 < 0.0) && + ((x1 - x4) * dy2 - (y1 - y4) * dx2 < 0.0) != + ((x2 - x4) * dy2 - (y2 - y4) * dx2 < 0.0); + + // It's is more expensive but more flexible + // in terms of boundary conditions. + //-------------------- + //double den = (x2-x1) * (y4-y3) - (y2-y1) * (x4-x3); + //if(fabs(den) < intersection_epsilon) return false; + //double nom1 = (x4-x3) * (y1-y3) - (y4-y3) * (x1-x3); + //double nom2 = (x2-x1) * (y1-y3) - (y2-y1) * (x1-x3); + //double ua = nom1 / den; + //double ub = nom2 / den; + //return ua >= 0.0 && ua <= 1.0 && ub >= 0.0 && ub <= 1.0; + } + + //--------------------------------------------------------calc_orthogonal + AGG_INLINE void calc_orthogonal(double thickness, + double x1, double y1, + double x2, double y2, + double* x, double* y) + { + double dx = x2 - x1; + double dy = y2 - y1; + double d = sqrt(dx*dx + dy*dy); + *x = thickness * dy / d; + *y = -thickness * dx / d; + } + + //--------------------------------------------------------dilate_triangle + AGG_INLINE void dilate_triangle(double x1, double y1, + double x2, double y2, + double x3, double y3, + double *x, double* y, + double d) + { + double dx1=0.0; + double dy1=0.0; + double dx2=0.0; + double dy2=0.0; + double dx3=0.0; + double dy3=0.0; + double loc = cross_product(x1, y1, x2, y2, x3, y3); + if(fabs(loc) > intersection_epsilon) + { + if(cross_product(x1, y1, x2, y2, x3, y3) > 0.0) + { + d = -d; + } + calc_orthogonal(d, x1, y1, x2, y2, &dx1, &dy1); + calc_orthogonal(d, x2, y2, x3, y3, &dx2, &dy2); + calc_orthogonal(d, x3, y3, x1, y1, &dx3, &dy3); + } + *x++ = x1 + dx1; *y++ = y1 + dy1; + *x++ = x2 + dx1; *y++ = y2 + dy1; + *x++ = x2 + dx2; *y++ = y2 + dy2; + *x++ = x3 + dx2; *y++ = y3 + dy2; + *x++ = x3 + dx3; *y++ = y3 + dy3; + *x++ = x1 + dx3; *y++ = y1 + dy3; + } + + //------------------------------------------------------calc_triangle_area + AGG_INLINE double calc_triangle_area(double x1, double y1, + double x2, double y2, + double x3, double y3) + { + return (x1*y2 - x2*y1 + x2*y3 - x3*y2 + x3*y1 - x1*y3) * 0.5; + } + + //-------------------------------------------------------calc_polygon_area + template<class Storage> double calc_polygon_area(const Storage& st) + { + unsigned i; + double sum = 0.0; + double x = st[0].x; + double y = st[0].y; + double xs = x; + double ys = y; + + for(i = 1; i < st.size(); i++) + { + const typename Storage::value_type& v = st[i]; + sum += x * v.y - y * v.x; + x = v.x; + y = v.y; + } + return (sum + x * ys - y * xs) * 0.5; + } + + //------------------------------------------------------------------------ + // Tables for fast sqrt + extern int16u g_sqrt_table[1024]; + extern int8 g_elder_bit_table[256]; + + + //---------------------------------------------------------------fast_sqrt + //Fast integer Sqrt - really fast: no cycles, divisions or multiplications + #if defined(_MSC_VER) + #pragma warning(push) + #pragma warning(disable : 4035) //Disable warning "no return value" + #endif + AGG_INLINE unsigned fast_sqrt(unsigned val) + { + #if defined(_M_IX86) && defined(_MSC_VER) && !defined(AGG_NO_ASM) + //For Ix86 family processors this assembler code is used. + //The key command here is bsr - determination the number of the most + //significant bit of the value. For other processors + //(and maybe compilers) the pure C "#else" section is used. + __asm + { + mov ebx, val + mov edx, 11 + bsr ecx, ebx + sub ecx, 9 + jle less_than_9_bits + shr ecx, 1 + adc ecx, 0 + sub edx, ecx + shl ecx, 1 + shr ebx, cl + less_than_9_bits: + xor eax, eax + mov ax, g_sqrt_table[ebx*2] + mov ecx, edx + shr eax, cl + } + #else + + //This code is actually pure C and portable to most + //arcitectures including 64bit ones. + unsigned t = val; + int bit=0; + unsigned shift = 11; + + //The following piece of code is just an emulation of the + //Ix86 assembler command "bsr" (see above). However on old + //Intels (like Intel MMX 233MHz) this code is about twice + //faster (sic!) then just one "bsr". On PIII and PIV the + //bsr is optimized quite well. + bit = t >> 24; + if(bit) + { + bit = g_elder_bit_table[bit] + 24; + } + else + { + bit = (t >> 16) & 0xFF; + if(bit) + { + bit = g_elder_bit_table[bit] + 16; + } + else + { + bit = (t >> 8) & 0xFF; + if(bit) + { + bit = g_elder_bit_table[bit] + 8; + } + else + { + bit = g_elder_bit_table[t]; + } + } + } + + //This code calculates the sqrt. + bit -= 9; + if(bit > 0) + { + bit = (bit >> 1) + (bit & 1); + shift -= bit; + val >>= (bit << 1); + } + return g_sqrt_table[val] >> shift; + #endif + } + #if defined(_MSC_VER) + #pragma warning(pop) + #endif + + + + + //--------------------------------------------------------------------besj + // Function BESJ calculates Bessel function of first kind of order n + // Arguments: + // n - an integer (>=0), the order + // x - value at which the Bessel function is required + //-------------------- + // C++ Mathematical Library + // Convereted from equivalent FORTRAN library + // Converetd by Gareth Walker for use by course 392 computational project + // All functions tested and yield the same results as the corresponding + // FORTRAN versions. + // + // If you have any problems using these functions please report them to + // M.Muldoon@UMIST.ac.uk + // + // Documentation available on the web + // http://www.ma.umist.ac.uk/mrm/Teaching/392/libs/392.html + // Version 1.0 8/98 + // 29 October, 1999 + //-------------------- + // Adapted for use in AGG library by Andy Wilk (castor.vulgaris@gmail.com) + //------------------------------------------------------------------------ + inline double besj(double x, int n) + { + if(n < 0) + { + return 0; + } + double d = 1E-6; + double b = 0; + if(fabs(x) <= d) + { + if(n != 0) return 0; + return 1; + } + double b1 = 0; // b1 is the value from the previous iteration + // Set up a starting order for recurrence + int m1 = (int)fabs(x) + 6; + if(fabs(x) > 5) + { + m1 = (int)(fabs(1.4 * x + 60 / x)); + } + int m2 = (int)(n + 2 + fabs(x) / 4); + if (m1 > m2) + { + m2 = m1; + } + + // Apply recurrence down from curent max order + for(;;) + { + double c3 = 0; + double c2 = 1E-30; + double c4 = 0; + int m8 = 1; + if (m2 / 2 * 2 == m2) + { + m8 = -1; + } + int imax = m2 - 2; + for (int i = 1; i <= imax; i++) + { + double c6 = 2 * (m2 - i) * c2 / x - c3; + c3 = c2; + c2 = c6; + if(m2 - i - 1 == n) + { + b = c6; + } + m8 = -1 * m8; + if (m8 > 0) + { + c4 = c4 + 2 * c6; + } + } + double c6 = 2 * c2 / x - c3; + if(n == 0) + { + b = c6; + } + c4 += c6; + b /= c4; + if(fabs(b - b1) < d) + { + return b; + } + b1 = b; + m2 += 3; + } + } + +} + + +#endif diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_math_stroke.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_math_stroke.h new file mode 100644 index 00000000000..4871d96cef6 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_math_stroke.h @@ -0,0 +1,527 @@ +//---------------------------------------------------------------------------- +// 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 +//---------------------------------------------------------------------------- +// +// Stroke math +// +//---------------------------------------------------------------------------- + +#ifndef AGG_STROKE_MATH_INCLUDED +#define AGG_STROKE_MATH_INCLUDED + +#include "agg_math.h" +#include "agg_vertex_sequence.h" + +namespace agg +{ + //-------------------------------------------------------------line_cap_e + enum line_cap_e + { + butt_cap, + square_cap, + round_cap + }; + + //------------------------------------------------------------line_join_e + enum line_join_e + { + miter_join = 0, + miter_join_revert = 1, + round_join = 2, + bevel_join = 3, + miter_join_round = 4 + }; + + + //-----------------------------------------------------------inner_join_e + enum inner_join_e + { + inner_bevel, + inner_miter, + inner_jag, + inner_round + }; + + //------------------------------------------------------------math_stroke + template<class VertexConsumer> class math_stroke + { + public: + typedef typename VertexConsumer::value_type coord_type; + + math_stroke(); + + void line_cap(line_cap_e lc) { m_line_cap = lc; } + void line_join(line_join_e lj) { m_line_join = lj; } + void inner_join(inner_join_e ij) { m_inner_join = ij; } + + line_cap_e line_cap() const { return m_line_cap; } + line_join_e line_join() const { return m_line_join; } + inner_join_e inner_join() const { return m_inner_join; } + + void width(double w); + void miter_limit(double ml) { m_miter_limit = ml; } + void miter_limit_theta(double t); + void inner_miter_limit(double ml) { m_inner_miter_limit = ml; } + void approximation_scale(double as) { m_approx_scale = as; } + + double width() const { return m_width * 2.0; } + double miter_limit() const { return m_miter_limit; } + double inner_miter_limit() const { return m_inner_miter_limit; } + double approximation_scale() const { return m_approx_scale; } + + void calc_cap(VertexConsumer& vc, + const vertex_dist& v0, + const vertex_dist& v1, + double len); + + void calc_join(VertexConsumer& vc, + const vertex_dist& v0, + const vertex_dist& v1, + const vertex_dist& v2, + double len1, + double len2); + + private: + AGG_INLINE void add_vertex(VertexConsumer& vc, double x, double y) + { + vc.add(coord_type(x, y)); + } + + void calc_arc(VertexConsumer& vc, + double x, double y, + double dx1, double dy1, + double dx2, double dy2); + + void calc_miter(VertexConsumer& vc, + const vertex_dist& v0, + const vertex_dist& v1, + const vertex_dist& v2, + double dx1, double dy1, + double dx2, double dy2, + line_join_e lj, + double mlimit, + double dbevel); + + double m_width; + double m_width_abs; + double m_width_eps; + int m_width_sign; + double m_miter_limit; + double m_inner_miter_limit; + double m_approx_scale; + line_cap_e m_line_cap; + line_join_e m_line_join; + inner_join_e m_inner_join; + }; + + //----------------------------------------------------------------------- + template<class VC> math_stroke<VC>::math_stroke() : + m_width(0.5), + m_width_abs(0.5), + m_width_eps(0.5/1024.0), + m_width_sign(1), + m_miter_limit(4.0), + m_inner_miter_limit(1.01), + m_approx_scale(1.0), + m_line_cap(butt_cap), + m_line_join(miter_join), + m_inner_join(inner_miter) + { + } + + //----------------------------------------------------------------------- + template<class VC> void math_stroke<VC>::width(double w) + { + m_width = w * 0.5; + if(m_width < 0) + { + m_width_abs = -m_width; + m_width_sign = -1; + } + else + { + m_width_abs = m_width; + m_width_sign = 1; + } + m_width_eps = m_width / 1024.0; + } + + //----------------------------------------------------------------------- + template<class VC> void math_stroke<VC>::miter_limit_theta(double t) + { + m_miter_limit = 1.0 / sin(t * 0.5) ; + } + + //----------------------------------------------------------------------- + template<class VC> + void math_stroke<VC>::calc_arc(VC& vc, + double x, double y, + double dx1, double dy1, + double dx2, double dy2) + { + double a1 = atan2(dy1 * m_width_sign, dx1 * m_width_sign); + double a2 = atan2(dy2 * m_width_sign, dx2 * m_width_sign); + double da = a1 - a2; + int i, n; + + da = acos(m_width_abs / (m_width_abs + 0.125 / m_approx_scale)) * 2; + + add_vertex(vc, x + dx1, y + dy1); + if(m_width_sign > 0) + { + if(a1 > a2) a2 += 2 * pi; + n = int((a2 - a1) / da); + da = (a2 - a1) / (n + 1); + a1 += da; + for(i = 0; i < n; i++) + { + add_vertex(vc, x + cos(a1) * m_width, y + sin(a1) * m_width); + a1 += da; + } + } + else + { + if(a1 < a2) a2 -= 2 * pi; + n = int((a1 - a2) / da); + da = (a1 - a2) / (n + 1); + a1 -= da; + for(i = 0; i < n; i++) + { + add_vertex(vc, x + cos(a1) * m_width, y + sin(a1) * m_width); + a1 -= da; + } + } + add_vertex(vc, x + dx2, y + dy2); + } + + //----------------------------------------------------------------------- + template<class VC> + void math_stroke<VC>::calc_miter(VC& vc, + const vertex_dist& v0, + const vertex_dist& v1, + const vertex_dist& v2, + double dx1, double dy1, + double dx2, double dy2, + line_join_e lj, + double mlimit, + double dbevel) + { + double xi = v1.x; + double yi = v1.y; + double di = 1; + double lim = m_width_abs * mlimit; + bool miter_limit_exceeded = true; // Assume the worst + bool intersection_failed = true; // Assume the worst + + if(calc_intersection(v0.x + dx1, v0.y - dy1, + v1.x + dx1, v1.y - dy1, + v1.x + dx2, v1.y - dy2, + v2.x + dx2, v2.y - dy2, + &xi, &yi)) + { + // Calculation of the intersection succeeded + //--------------------- + di = calc_distance(v1.x, v1.y, xi, yi); + if(di <= lim) + { + // Inside the miter limit + //--------------------- + add_vertex(vc, xi, yi); + miter_limit_exceeded = false; + } + intersection_failed = false; + } + else + { + // Calculation of the intersection failed, most probably + // the three points lie one straight line. + // First check if v0 and v2 lie on the opposite sides of vector: + // (v1.x, v1.y) -> (v1.x+dx1, v1.y-dy1), that is, the perpendicular + // to the line determined by vertices v0 and v1. + // This condition determines whether the next line segments continues + // the previous one or goes back. + //---------------- + double x2 = v1.x + dx1; + double y2 = v1.y - dy1; + if((cross_product(v0.x, v0.y, v1.x, v1.y, x2, y2) < 0.0) == + (cross_product(v1.x, v1.y, v2.x, v2.y, x2, y2) < 0.0)) + { + // This case means that the next segment continues + // the previous one (straight line) + //----------------- + add_vertex(vc, v1.x + dx1, v1.y - dy1); + miter_limit_exceeded = false; + } + } + + if(miter_limit_exceeded) + { + // Miter limit exceeded + //------------------------ + switch(lj) + { + case miter_join_revert: + // For the compatibility with SVG, PDF, etc, + // we use a simple bevel join instead of + // "smart" bevel + //------------------- + add_vertex(vc, v1.x + dx1, v1.y - dy1); + add_vertex(vc, v1.x + dx2, v1.y - dy2); + break; + + case miter_join_round: + calc_arc(vc, v1.x, v1.y, dx1, -dy1, dx2, -dy2); + break; + + default: + // If no miter-revert, calculate new dx1, dy1, dx2, dy2 + //---------------- + if(intersection_failed) + { + mlimit *= m_width_sign; + add_vertex(vc, v1.x + dx1 + dy1 * mlimit, + v1.y - dy1 + dx1 * mlimit); + add_vertex(vc, v1.x + dx2 - dy2 * mlimit, + v1.y - dy2 - dx2 * mlimit); + } + else + { + double x1 = v1.x + dx1; + double y1 = v1.y - dy1; + double x2 = v1.x + dx2; + double y2 = v1.y - dy2; + di = (lim - dbevel) / (di - dbevel); + add_vertex(vc, x1 + (xi - x1) * di, + y1 + (yi - y1) * di); + add_vertex(vc, x2 + (xi - x2) * di, + y2 + (yi - y2) * di); + } + break; + } + } + } + + //--------------------------------------------------------stroke_calc_cap + template<class VC> + void math_stroke<VC>::calc_cap(VC& vc, + const vertex_dist& v0, + const vertex_dist& v1, + double len) + { + vc.remove_all(); + + double dx1 = (v1.y - v0.y) / len; + double dy1 = (v1.x - v0.x) / len; + double dx2 = 0; + double dy2 = 0; + + dx1 *= m_width; + dy1 *= m_width; + + if(m_line_cap != round_cap) + { + if(m_line_cap == square_cap) + { + dx2 = dy1 * m_width_sign; + dy2 = dx1 * m_width_sign; + } + add_vertex(vc, v0.x - dx1 - dx2, v0.y + dy1 - dy2); + add_vertex(vc, v0.x + dx1 - dx2, v0.y - dy1 - dy2); + } + else + { + double da = acos(m_width_abs / (m_width_abs + 0.125 / m_approx_scale)) * 2; + double a1; + int i; + int n = int(pi / da); + + da = pi / (n + 1); + add_vertex(vc, v0.x - dx1, v0.y + dy1); + if(m_width_sign > 0) + { + a1 = atan2(dy1, -dx1); + a1 += da; + for(i = 0; i < n; i++) + { + add_vertex(vc, v0.x + cos(a1) * m_width, + v0.y + sin(a1) * m_width); + a1 += da; + } + } + else + { + a1 = atan2(-dy1, dx1); + a1 -= da; + for(i = 0; i < n; i++) + { + add_vertex(vc, v0.x + cos(a1) * m_width, + v0.y + sin(a1) * m_width); + a1 -= da; + } + } + add_vertex(vc, v0.x + dx1, v0.y - dy1); + } + } + + //----------------------------------------------------------------------- + template<class VC> + void math_stroke<VC>::calc_join(VC& vc, + const vertex_dist& v0, + const vertex_dist& v1, + const vertex_dist& v2, + double len1, + double len2) + { + double dx1 = m_width * (v1.y - v0.y) / len1; + double dy1 = m_width * (v1.x - v0.x) / len1; + double dx2 = m_width * (v2.y - v1.y) / len2; + double dy2 = m_width * (v2.x - v1.x) / len2; + + vc.remove_all(); + + double cp = cross_product(v0.x, v0.y, v1.x, v1.y, v2.x, v2.y); + if ((cp > agg::vertex_dist_epsilon && m_width > 0) || + (cp < -agg::vertex_dist_epsilon && m_width < 0)) + { + // Inner join + //--------------- + double limit = ((len1 < len2) ? len1 : len2) / m_width_abs; + if(limit < m_inner_miter_limit) + { + limit = m_inner_miter_limit; + } + + switch(m_inner_join) + { + default: // inner_bevel + add_vertex(vc, v1.x + dx1, v1.y - dy1); + add_vertex(vc, v1.x + dx2, v1.y - dy2); + break; + + case inner_miter: + calc_miter(vc, + v0, v1, v2, dx1, dy1, dx2, dy2, + miter_join_revert, + limit, 0); + break; + + case inner_jag: + case inner_round: + cp = (dx1-dx2) * (dx1-dx2) + (dy1-dy2) * (dy1-dy2); + if(cp < len1 * len1 && cp < len2 * len2) + { + calc_miter(vc, + v0, v1, v2, dx1, dy1, dx2, dy2, + miter_join_revert, + limit, 0); + } + else + { + if(m_inner_join == inner_jag) + { + add_vertex(vc, v1.x + dx1, v1.y - dy1); + add_vertex(vc, v1.x, v1.y ); + add_vertex(vc, v1.x + dx2, v1.y - dy2); + } + else + { + add_vertex(vc, v1.x + dx1, v1.y - dy1); + add_vertex(vc, v1.x, v1.y ); + calc_arc(vc, v1.x, v1.y, dx2, -dy2, dx1, -dy1); + add_vertex(vc, v1.x, v1.y ); + add_vertex(vc, v1.x + dx2, v1.y - dy2); + } + } + break; + } + } + else + { + // Outer join + //--------------- + + // Calculate the distance between v1 and + // the central point of the bevel line segment + //--------------- + double dx = (dx1 + dx2) / 2; + double dy = (dy1 + dy2) / 2; + double dbevel = sqrt(dx * dx + dy * dy); + + if(m_line_join == round_join || m_line_join == bevel_join) + { + // This is an optimization that reduces the number of points + // in cases of almost collinear segments. If there's no + // visible difference between bevel and miter joins we'd rather + // use miter join because it adds only one point instead of two. + // + // Here we calculate the middle point between the bevel points + // and then, the distance between v1 and this middle point. + // At outer joins this distance always less than stroke width, + // because it's actually the height of an isosceles triangle of + // v1 and its two bevel points. If the difference between this + // width and this value is small (no visible bevel) we can + // add just one point. + // + // The constant in the expression makes the result approximately + // the same as in round joins and caps. You can safely comment + // out this entire "if". + //------------------- + if(m_approx_scale * (m_width_abs - dbevel) < m_width_eps) + { + if(calc_intersection(v0.x + dx1, v0.y - dy1, + v1.x + dx1, v1.y - dy1, + v1.x + dx2, v1.y - dy2, + v2.x + dx2, v2.y - dy2, + &dx, &dy)) + { + add_vertex(vc, dx, dy); + } + else + { + add_vertex(vc, v1.x + dx1, v1.y - dy1); + } + return; + } + } + + switch(m_line_join) + { + case miter_join: + case miter_join_revert: + case miter_join_round: + calc_miter(vc, + v0, v1, v2, dx1, dy1, dx2, dy2, + m_line_join, + m_miter_limit, + dbevel); + break; + + case round_join: + calc_arc(vc, v1.x, v1.y, dx1, -dy1, dx2, -dy2); + break; + + default: // Bevel join + add_vertex(vc, v1.x + dx1, v1.y - dy1); + add_vertex(vc, v1.x + dx2, v1.y - dy2); + break; + } + } + } + + + + +} + +#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 00000000000..740ba31df27 --- /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.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_path_storage.h new file mode 100644 index 00000000000..c01b867f26c --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_path_storage.h @@ -0,0 +1,1545 @@ +//---------------------------------------------------------------------------- +// 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_INCLUDED +#define AGG_PATH_STORAGE_INCLUDED + +#include <string.h> +#include <math.h> +#include "agg_math.h" +#include "agg_array.h" +#include "agg_bezier_arc.h" + +namespace agg +{ + + + //----------------------------------------------------vertex_block_storage + template<class T, unsigned BlockShift=8, unsigned BlockPool=256> + class vertex_block_storage + { + public: + // Allocation parameters + enum block_scale_e + { + block_shift = BlockShift, + block_size = 1 << block_shift, + block_mask = block_size - 1, + block_pool = BlockPool + }; + + typedef T value_type; + typedef vertex_block_storage<T, BlockShift, BlockPool> self_type; + + ~vertex_block_storage(); + vertex_block_storage(); + vertex_block_storage(const self_type& v); + const self_type& operator = (const self_type& ps); + + void remove_all(); + void free_all(); + + void add_vertex(double x, double y, unsigned cmd); + void modify_vertex(unsigned idx, double x, double y); + void modify_vertex(unsigned idx, double x, double y, unsigned cmd); + void modify_command(unsigned idx, unsigned cmd); + void swap_vertices(unsigned v1, unsigned v2); + + unsigned last_command() const; + unsigned last_vertex(double* x, double* y) const; + unsigned prev_vertex(double* x, double* y) const; + + double last_x() const; + double last_y() const; + + unsigned total_vertices() const; + unsigned vertex(unsigned idx, double* x, double* y) const; + unsigned command(unsigned idx) const; + + private: + void allocate_block(unsigned nb); + int8u* storage_ptrs(T** xy_ptr); + + private: + unsigned m_total_vertices; + unsigned m_total_blocks; + unsigned m_max_blocks; + T** m_coord_blocks; + int8u** m_cmd_blocks; + }; + + + //------------------------------------------------------------------------ + template<class T, unsigned S, unsigned P> + void vertex_block_storage<T,S,P>::free_all() + { + if(m_total_blocks) + { + T** coord_blk = m_coord_blocks + m_total_blocks - 1; + while(m_total_blocks--) + { + pod_allocator<T>::deallocate( + *coord_blk, + block_size * 2 + + block_size / (sizeof(T) / sizeof(unsigned char))); + --coord_blk; + } + pod_allocator<T*>::deallocate(m_coord_blocks, m_max_blocks * 2); + m_total_blocks = 0; + m_max_blocks = 0; + m_coord_blocks = 0; + m_cmd_blocks = 0; + m_total_vertices = 0; + } + } + + //------------------------------------------------------------------------ + template<class T, unsigned S, unsigned P> + vertex_block_storage<T,S,P>::~vertex_block_storage() + { + free_all(); + } + + //------------------------------------------------------------------------ + template<class T, unsigned S, unsigned P> + vertex_block_storage<T,S,P>::vertex_block_storage() : + m_total_vertices(0), + m_total_blocks(0), + m_max_blocks(0), + m_coord_blocks(0), + m_cmd_blocks(0) + { + } + + //------------------------------------------------------------------------ + template<class T, unsigned S, unsigned P> + vertex_block_storage<T,S,P>::vertex_block_storage(const vertex_block_storage<T,S,P>& v) : + m_total_vertices(0), + m_total_blocks(0), + m_max_blocks(0), + m_coord_blocks(0), + m_cmd_blocks(0) + { + *this = v; + } + + //------------------------------------------------------------------------ + template<class T, unsigned S, unsigned P> + const vertex_block_storage<T,S,P>& + vertex_block_storage<T,S,P>::operator = (const vertex_block_storage<T,S,P>& v) + { + remove_all(); + unsigned i; + for(i = 0; i < v.total_vertices(); i++) + { + double x, y; + unsigned cmd = v.vertex(i, &x, &y); + add_vertex(x, y, cmd); + } + return *this; + } + + //------------------------------------------------------------------------ + template<class T, unsigned S, unsigned P> + inline void vertex_block_storage<T,S,P>::remove_all() + { + m_total_vertices = 0; + } + + //------------------------------------------------------------------------ + template<class T, unsigned S, unsigned P> + inline void vertex_block_storage<T,S,P>::add_vertex(double x, double y, + unsigned cmd) + { + T* coord_ptr = 0; + *storage_ptrs(&coord_ptr) = (int8u)cmd; + coord_ptr[0] = T(x); + coord_ptr[1] = T(y); + m_total_vertices++; + } + + //------------------------------------------------------------------------ + template<class T, unsigned S, unsigned P> + inline void vertex_block_storage<T,S,P>::modify_vertex(unsigned idx, + double x, double y) + { + T* pv = m_coord_blocks[idx >> block_shift] + ((idx & block_mask) << 1); + pv[0] = T(x); + pv[1] = T(y); + } + + //------------------------------------------------------------------------ + template<class T, unsigned S, unsigned P> + inline void vertex_block_storage<T,S,P>::modify_vertex(unsigned idx, + double x, double y, + unsigned cmd) + { + unsigned block = idx >> block_shift; + unsigned offset = idx & block_mask; + T* pv = m_coord_blocks[block] + (offset << 1); + pv[0] = T(x); + pv[1] = T(y); + m_cmd_blocks[block][offset] = (int8u)cmd; + } + + //------------------------------------------------------------------------ + template<class T, unsigned S, unsigned P> + inline void vertex_block_storage<T,S,P>::modify_command(unsigned idx, + unsigned cmd) + { + m_cmd_blocks[idx >> block_shift][idx & block_mask] = (int8u)cmd; + } + + //------------------------------------------------------------------------ + template<class T, unsigned S, unsigned P> + inline void vertex_block_storage<T,S,P>::swap_vertices(unsigned v1, unsigned v2) + { + unsigned b1 = v1 >> block_shift; + unsigned b2 = v2 >> block_shift; + unsigned o1 = v1 & block_mask; + unsigned o2 = v2 & block_mask; + T* pv1 = m_coord_blocks[b1] + (o1 << 1); + T* pv2 = m_coord_blocks[b2] + (o2 << 1); + T val; + val = pv1[0]; pv1[0] = pv2[0]; pv2[0] = val; + val = pv1[1]; pv1[1] = pv2[1]; pv2[1] = val; + int8u cmd = m_cmd_blocks[b1][o1]; + m_cmd_blocks[b1][o1] = m_cmd_blocks[b2][o2]; + m_cmd_blocks[b2][o2] = cmd; + } + + //------------------------------------------------------------------------ + template<class T, unsigned S, unsigned P> + inline unsigned vertex_block_storage<T,S,P>::last_command() const + { + if(m_total_vertices) return command(m_total_vertices - 1); + return path_cmd_stop; + } + + //------------------------------------------------------------------------ + template<class T, unsigned S, unsigned P> + inline unsigned vertex_block_storage<T,S,P>::last_vertex(double* x, double* y) const + { + if(m_total_vertices) return vertex(m_total_vertices - 1, x, y); + return path_cmd_stop; + } + + //------------------------------------------------------------------------ + template<class T, unsigned S, unsigned P> + inline unsigned vertex_block_storage<T,S,P>::prev_vertex(double* x, double* y) const + { + if(m_total_vertices > 1) return vertex(m_total_vertices - 2, x, y); + return path_cmd_stop; + } + + //------------------------------------------------------------------------ + template<class T, unsigned S, unsigned P> + inline double vertex_block_storage<T,S,P>::last_x() const + { + if(m_total_vertices) + { + unsigned idx = m_total_vertices - 1; + return m_coord_blocks[idx >> block_shift][(idx & block_mask) << 1]; + } + return 0.0; + } + + //------------------------------------------------------------------------ + template<class T, unsigned S, unsigned P> + inline double vertex_block_storage<T,S,P>::last_y() const + { + if(m_total_vertices) + { + unsigned idx = m_total_vertices - 1; + return m_coord_blocks[idx >> block_shift][((idx & block_mask) << 1) + 1]; + } + return 0.0; + } + + //------------------------------------------------------------------------ + template<class T, unsigned S, unsigned P> + inline unsigned vertex_block_storage<T,S,P>::total_vertices() const + { + return m_total_vertices; + } + + //------------------------------------------------------------------------ + template<class T, unsigned S, unsigned P> + inline unsigned vertex_block_storage<T,S,P>::vertex(unsigned idx, + double* x, double* y) const + { + unsigned nb = idx >> block_shift; + const T* pv = m_coord_blocks[nb] + ((idx & block_mask) << 1); + *x = pv[0]; + *y = pv[1]; + return m_cmd_blocks[nb][idx & block_mask]; + } + + //------------------------------------------------------------------------ + template<class T, unsigned S, unsigned P> + inline unsigned vertex_block_storage<T,S,P>::command(unsigned idx) const + { + return m_cmd_blocks[idx >> block_shift][idx & block_mask]; + } + + //------------------------------------------------------------------------ + template<class T, unsigned S, unsigned P> + void vertex_block_storage<T,S,P>::allocate_block(unsigned nb) + { + if(nb >= m_max_blocks) + { + T** new_coords = + pod_allocator<T*>::allocate((m_max_blocks + block_pool) * 2); + + unsigned char** new_cmds = + (unsigned char**)(new_coords + m_max_blocks + block_pool); + + if(m_coord_blocks) + { + memcpy(new_coords, + m_coord_blocks, + m_max_blocks * sizeof(T*)); + + memcpy(new_cmds, + m_cmd_blocks, + m_max_blocks * sizeof(unsigned char*)); + + pod_allocator<T*>::deallocate(m_coord_blocks, m_max_blocks * 2); + } + m_coord_blocks = new_coords; + m_cmd_blocks = new_cmds; + m_max_blocks += block_pool; + } + m_coord_blocks[nb] = + pod_allocator<T>::allocate(block_size * 2 + + block_size / (sizeof(T) / sizeof(unsigned char))); + + m_cmd_blocks[nb] = + (unsigned char*)(m_coord_blocks[nb] + block_size * 2); + + m_total_blocks++; + } + + //------------------------------------------------------------------------ + template<class T, unsigned S, unsigned P> + int8u* vertex_block_storage<T,S,P>::storage_ptrs(T** xy_ptr) + { + unsigned nb = m_total_vertices >> block_shift; + if(nb >= m_total_blocks) + { + allocate_block(nb); + } + *xy_ptr = m_coord_blocks[nb] + ((m_total_vertices & block_mask) << 1); + return m_cmd_blocks[nb] + (m_total_vertices & block_mask); + } + + + + + //-----------------------------------------------------poly_plain_adaptor + template<class T> class poly_plain_adaptor + { + public: + typedef T value_type; + + poly_plain_adaptor() : + m_data(0), + m_ptr(0), + m_end(0), + m_closed(false), + m_stop(false) + {} + + poly_plain_adaptor(const T* data, unsigned num_points, bool closed) : + m_data(data), + m_ptr(data), + m_end(data + num_points * 2), + m_closed(closed), + m_stop(false) + {} + + void init(const T* data, unsigned num_points, bool closed) + { + m_data = data; + m_ptr = data; + m_end = data + num_points * 2; + m_closed = closed; + m_stop = false; + } + + void rewind(unsigned) + { + m_ptr = m_data; + m_stop = false; + } + + unsigned vertex(double* x, double* y) + { + if(m_ptr < m_end) + { + bool first = m_ptr == m_data; + *x = *m_ptr++; + *y = *m_ptr++; + return first ? path_cmd_move_to : path_cmd_line_to; + } + *x = *y = 0.0; + if(m_closed && !m_stop) + { + m_stop = true; + return path_cmd_end_poly | path_flags_close; + } + return path_cmd_stop; + } + + private: + const T* m_data; + const T* m_ptr; + const T* m_end; + bool m_closed; + bool m_stop; + }; + + + + + + //-------------------------------------------------poly_container_adaptor + template<class Container> class poly_container_adaptor + { + public: + typedef typename Container::value_type vertex_type; + + poly_container_adaptor() : + m_container(0), + m_index(0), + m_closed(false), + m_stop(false) + {} + + poly_container_adaptor(const Container& data, bool closed) : + m_container(&data), + m_index(0), + m_closed(closed), + m_stop(false) + {} + + void init(const Container& data, bool closed) + { + m_container = &data; + m_index = 0; + m_closed = closed; + m_stop = false; + } + + void rewind(unsigned) + { + m_index = 0; + m_stop = false; + } + + unsigned vertex(double* x, double* y) + { + if(m_index < m_container->size()) + { + bool first = m_index == 0; + const vertex_type& v = (*m_container)[m_index++]; + *x = v.x; + *y = v.y; + return first ? path_cmd_move_to : path_cmd_line_to; + } + *x = *y = 0.0; + if(m_closed && !m_stop) + { + m_stop = true; + return path_cmd_end_poly | path_flags_close; + } + return path_cmd_stop; + } + + private: + const Container* m_container; + unsigned m_index; + bool m_closed; + bool m_stop; + }; + + + + //-----------------------------------------poly_container_reverse_adaptor + template<class Container> class poly_container_reverse_adaptor + { + public: + typedef typename Container::value_type vertex_type; + + poly_container_reverse_adaptor() : + m_container(0), + m_index(-1), + m_closed(false), + m_stop(false) + {} + + poly_container_reverse_adaptor(Container& data, bool closed) : + m_container(&data), + m_index(-1), + m_closed(closed), + m_stop(false) + {} + + void init(Container& data, bool closed) + { + m_container = &data; + m_index = m_container->size() - 1; + m_closed = closed; + m_stop = false; + } + + void rewind(unsigned) + { + m_index = m_container->size() - 1; + m_stop = false; + } + + unsigned vertex(double* x, double* y) + { + if(m_index >= 0) + { + bool first = m_index == int(m_container->size() - 1); + const vertex_type& v = (*m_container)[m_index--]; + *x = v.x; + *y = v.y; + return first ? path_cmd_move_to : path_cmd_line_to; + } + *x = *y = 0.0; + if(m_closed && !m_stop) + { + m_stop = true; + return path_cmd_end_poly | path_flags_close; + } + return path_cmd_stop; + } + + private: + Container* m_container; + int m_index; + bool m_closed; + bool m_stop; + }; + + + + + + //--------------------------------------------------------line_adaptor + class line_adaptor + { + public: + typedef double value_type; + + line_adaptor() : m_line(m_coord, 2, false) {} + line_adaptor(double x1, double y1, double x2, double y2) : + m_line(m_coord, 2, false) + { + m_coord[0] = x1; + m_coord[1] = y1; + m_coord[2] = x2; + m_coord[3] = y2; + } + + void init(double x1, double y1, double x2, double y2) + { + m_coord[0] = x1; + m_coord[1] = y1; + m_coord[2] = x2; + m_coord[3] = y2; + m_line.rewind(0); + } + + void rewind(unsigned) + { + m_line.rewind(0); + } + + unsigned vertex(double* x, double* y) + { + return m_line.vertex(x, y); + } + + private: + double m_coord[4]; + poly_plain_adaptor<double> m_line; + }; + + + + + + + + + + + + + + //---------------------------------------------------------------path_base + // A container to store vertices with their flags. + // A path consists of a number of contours separated with "move_to" + // commands. The path storage can keep and maintain more than one + // path. + // To navigate to the beginning of a particular path, use rewind(path_id); + // Where path_id is what start_new_path() returns. So, when you call + // start_new_path() you need to store its return value somewhere else + // to navigate to the path afterwards. + // + // See also: vertex_source concept + //------------------------------------------------------------------------ + template<class VertexContainer> class path_base + { + public: + typedef VertexContainer container_type; + typedef path_base<VertexContainer> self_type; + + //-------------------------------------------------------------------- + path_base() : m_vertices(), m_iterator(0) {} + void remove_all() { m_vertices.remove_all(); m_iterator = 0; } + void free_all() { m_vertices.free_all(); m_iterator = 0; } + + // Make path functions + //-------------------------------------------------------------------- + unsigned start_new_path(); + + void move_to(double x, double y); + void move_rel(double dx, double dy); + + void line_to(double x, double y); + void line_rel(double dx, double dy); + + void hline_to(double x); + void hline_rel(double dx); + + void vline_to(double y); + void vline_rel(double dy); + + void arc_to(double rx, double ry, + double angle, + bool large_arc_flag, + bool sweep_flag, + double x, double y); + + void arc_rel(double rx, double ry, + double angle, + bool large_arc_flag, + bool sweep_flag, + double dx, double dy); + + void curve3(double x_ctrl, double y_ctrl, + double x_to, double y_to); + + void curve3_rel(double dx_ctrl, double dy_ctrl, + double dx_to, double dy_to); + + void curve3(double x_to, double y_to); + + void curve3_rel(double dx_to, double dy_to); + + void curve4(double x_ctrl1, double y_ctrl1, + double x_ctrl2, double y_ctrl2, + double x_to, double y_to); + + void curve4_rel(double dx_ctrl1, double dy_ctrl1, + double dx_ctrl2, double dy_ctrl2, + double dx_to, double dy_to); + + void curve4(double x_ctrl2, double y_ctrl2, + double x_to, double y_to); + + void curve4_rel(double x_ctrl2, double y_ctrl2, + double x_to, double y_to); + + + void end_poly(unsigned flags = path_flags_close); + void close_polygon(unsigned flags = path_flags_none); + + // Accessors + //-------------------------------------------------------------------- + const container_type& vertices() const { return m_vertices; } + container_type& vertices() { return m_vertices; } + + unsigned total_vertices() const; + + void rel_to_abs(double* x, double* y) const; + + unsigned last_vertex(double* x, double* y) const; + unsigned prev_vertex(double* x, double* y) const; + + double last_x() const; + double last_y() const; + + unsigned vertex(unsigned idx, double* x, double* y) const; + unsigned command(unsigned idx) const; + + void modify_vertex(unsigned idx, double x, double y); + void modify_vertex(unsigned idx, double x, double y, unsigned cmd); + void modify_command(unsigned idx, unsigned cmd); + + // VertexSource interface + //-------------------------------------------------------------------- + void rewind(unsigned path_id); + unsigned vertex(double* x, double* y); + + // Arrange the orientation of a polygon, all polygons in a path, + // or in all paths. After calling arrange_orientations() or + // arrange_orientations_all_paths(), all the polygons will have + // the same orientation, i.e. path_flags_cw or path_flags_ccw + //-------------------------------------------------------------------- + unsigned arrange_polygon_orientation(unsigned start, path_flags_e orientation); + unsigned arrange_orientations(unsigned path_id, path_flags_e orientation); + void arrange_orientations_all_paths(path_flags_e orientation); + void invert_polygon(unsigned start); + + // Flip all vertices horizontally or vertically, + // between x1 and x2, or between y1 and y2 respectively + //-------------------------------------------------------------------- + void flip_x(double x1, double x2); + void flip_y(double y1, double y2); + + // Concatenate path. The path is added as is. + //-------------------------------------------------------------------- + template<class VertexSource> + void concat_path(VertexSource& vs, unsigned path_id = 0) + { + double x, y; + unsigned cmd; + vs.rewind(path_id); + while(!is_stop(cmd = vs.vertex(&x, &y))) + { + m_vertices.add_vertex(x, y, cmd); + } + } + + //-------------------------------------------------------------------- + // Join path. The path is joined with the existing one, that is, + // it behaves as if the pen of a plotter was always down (drawing) + template<class VertexSource> + void join_path(VertexSource& vs, unsigned path_id = 0) + { + double x, y; + unsigned cmd; + vs.rewind(path_id); + cmd = vs.vertex(&x, &y); + if(!is_stop(cmd)) + { + if(is_vertex(cmd)) + { + double x0, y0; + unsigned cmd0 = last_vertex(&x0, &y0); + if(is_vertex(cmd0)) + { + if(calc_distance(x, y, x0, y0) > vertex_dist_epsilon) + { + if(is_move_to(cmd)) cmd = path_cmd_line_to; + m_vertices.add_vertex(x, y, cmd); + } + } + else + { + if(is_stop(cmd0)) + { + cmd = path_cmd_move_to; + } + else + { + if(is_move_to(cmd)) cmd = path_cmd_line_to; + } + m_vertices.add_vertex(x, y, cmd); + } + } + while(!is_stop(cmd = vs.vertex(&x, &y))) + { + m_vertices.add_vertex(x, y, is_move_to(cmd) ? + unsigned(path_cmd_line_to) : + cmd); + } + } + } + + // Concatenate polygon/polyline. + //-------------------------------------------------------------------- + template<class T> void concat_poly(const T* data, + unsigned num_points, + bool closed) + { + poly_plain_adaptor<T> poly(data, num_points, closed); + concat_path(poly); + } + + // Join polygon/polyline continuously. + //-------------------------------------------------------------------- + template<class T> void join_poly(const T* data, + unsigned num_points, + bool closed) + { + poly_plain_adaptor<T> poly(data, num_points, closed); + join_path(poly); + } + + //-------------------------------------------------------------------- + void translate(double dx, double dy, unsigned path_id=0); + void translate_all_paths(double dx, double dy); + + //-------------------------------------------------------------------- + template<class Trans> + void transform(const Trans& trans, unsigned path_id=0) + { + unsigned num_ver = m_vertices.total_vertices(); + for(; path_id < num_ver; path_id++) + { + double x, y; + unsigned cmd = m_vertices.vertex(path_id, &x, &y); + if(is_stop(cmd)) break; + if(is_vertex(cmd)) + { + trans.transform(&x, &y); + m_vertices.modify_vertex(path_id, x, y); + } + } + } + + //-------------------------------------------------------------------- + template<class Trans> + void transform_all_paths(const Trans& trans) + { + unsigned idx; + unsigned num_ver = m_vertices.total_vertices(); + for(idx = 0; idx < num_ver; idx++) + { + double x, y; + if(is_vertex(m_vertices.vertex(idx, &x, &y))) + { + trans.transform(&x, &y); + m_vertices.modify_vertex(idx, x, y); + } + } + } + + + + private: + unsigned perceive_polygon_orientation(unsigned start, unsigned end); + void invert_polygon(unsigned start, unsigned end); + + VertexContainer m_vertices; + unsigned m_iterator; + }; + + //------------------------------------------------------------------------ + template<class VC> + unsigned path_base<VC>::start_new_path() + { + if(!is_stop(m_vertices.last_command())) + { + m_vertices.add_vertex(0.0, 0.0, path_cmd_stop); + } + return m_vertices.total_vertices(); + } + + + //------------------------------------------------------------------------ + template<class VC> + inline void path_base<VC>::rel_to_abs(double* x, double* y) const + { + if(m_vertices.total_vertices()) + { + double x2; + double y2; + if(is_vertex(m_vertices.last_vertex(&x2, &y2))) + { + *x += x2; + *y += y2; + } + } + } + + //------------------------------------------------------------------------ + template<class VC> + inline void path_base<VC>::move_to(double x, double y) + { + m_vertices.add_vertex(x, y, path_cmd_move_to); + } + + //------------------------------------------------------------------------ + template<class VC> + inline void path_base<VC>::move_rel(double dx, double dy) + { + rel_to_abs(&dx, &dy); + m_vertices.add_vertex(dx, dy, path_cmd_move_to); + } + + //------------------------------------------------------------------------ + template<class VC> + inline void path_base<VC>::line_to(double x, double y) + { + m_vertices.add_vertex(x, y, path_cmd_line_to); + } + + //------------------------------------------------------------------------ + template<class VC> + inline void path_base<VC>::line_rel(double dx, double dy) + { + rel_to_abs(&dx, &dy); + m_vertices.add_vertex(dx, dy, path_cmd_line_to); + } + + //------------------------------------------------------------------------ + template<class VC> + inline void path_base<VC>::hline_to(double x) + { + m_vertices.add_vertex(x, last_y(), path_cmd_line_to); + } + + //------------------------------------------------------------------------ + template<class VC> + inline void path_base<VC>::hline_rel(double dx) + { + double dy = 0; + rel_to_abs(&dx, &dy); + m_vertices.add_vertex(dx, dy, path_cmd_line_to); + } + + //------------------------------------------------------------------------ + template<class VC> + inline void path_base<VC>::vline_to(double y) + { + m_vertices.add_vertex(last_x(), y, path_cmd_line_to); + } + + //------------------------------------------------------------------------ + template<class VC> + inline void path_base<VC>::vline_rel(double dy) + { + double dx = 0; + rel_to_abs(&dx, &dy); + m_vertices.add_vertex(dx, dy, path_cmd_line_to); + } + + //------------------------------------------------------------------------ + template<class VC> + void path_base<VC>::arc_to(double rx, double ry, + double angle, + bool large_arc_flag, + bool sweep_flag, + double x, double y) + { + if(m_vertices.total_vertices() && is_vertex(m_vertices.last_command())) + { + const double epsilon = 1e-30; + double x0 = 0.0; + double y0 = 0.0; + m_vertices.last_vertex(&x0, &y0); + + rx = fabs(rx); + ry = fabs(ry); + + // Ensure radii are valid + //------------------------- + if(rx < epsilon || ry < epsilon) + { + line_to(x, y); + return; + } + + if(calc_distance(x0, y0, x, y) < epsilon) + { + // If the endpoints (x, y) and (x0, y0) are identical, then this + // is equivalent to omitting the elliptical arc segment entirely. + return; + } + bezier_arc_svg a(x0, y0, rx, ry, angle, large_arc_flag, sweep_flag, x, y); + if(a.radii_ok()) + { + join_path(a); + } + else + { + line_to(x, y); + } + } + else + { + move_to(x, y); + } + } + + //------------------------------------------------------------------------ + template<class VC> + void path_base<VC>::arc_rel(double rx, double ry, + double angle, + bool large_arc_flag, + bool sweep_flag, + double dx, double dy) + { + rel_to_abs(&dx, &dy); + arc_to(rx, ry, angle, large_arc_flag, sweep_flag, dx, dy); + } + + //------------------------------------------------------------------------ + template<class VC> + void path_base<VC>::curve3(double x_ctrl, double y_ctrl, + double x_to, double y_to) + { + m_vertices.add_vertex(x_ctrl, y_ctrl, path_cmd_curve3); + m_vertices.add_vertex(x_to, y_to, path_cmd_curve3); + } + + //------------------------------------------------------------------------ + template<class VC> + void path_base<VC>::curve3_rel(double dx_ctrl, double dy_ctrl, + double dx_to, double dy_to) + { + rel_to_abs(&dx_ctrl, &dy_ctrl); + rel_to_abs(&dx_to, &dy_to); + m_vertices.add_vertex(dx_ctrl, dy_ctrl, path_cmd_curve3); + m_vertices.add_vertex(dx_to, dy_to, path_cmd_curve3); + } + + //------------------------------------------------------------------------ + template<class VC> + void path_base<VC>::curve3(double x_to, double y_to) + { + double x0; + double y0; + if(is_vertex(m_vertices.last_vertex(&x0, &y0))) + { + double x_ctrl; + double y_ctrl; + unsigned cmd = m_vertices.prev_vertex(&x_ctrl, &y_ctrl); + if(is_curve(cmd)) + { + x_ctrl = x0 + x0 - x_ctrl; + y_ctrl = y0 + y0 - y_ctrl; + } + else + { + x_ctrl = x0; + y_ctrl = y0; + } + curve3(x_ctrl, y_ctrl, x_to, y_to); + } + } + + //------------------------------------------------------------------------ + template<class VC> + void path_base<VC>::curve3_rel(double dx_to, double dy_to) + { + rel_to_abs(&dx_to, &dy_to); + curve3(dx_to, dy_to); + } + + //------------------------------------------------------------------------ + template<class VC> + void path_base<VC>::curve4(double x_ctrl1, double y_ctrl1, + double x_ctrl2, double y_ctrl2, + double x_to, double y_to) + { + m_vertices.add_vertex(x_ctrl1, y_ctrl1, path_cmd_curve4); + m_vertices.add_vertex(x_ctrl2, y_ctrl2, path_cmd_curve4); + m_vertices.add_vertex(x_to, y_to, path_cmd_curve4); + } + + //------------------------------------------------------------------------ + template<class VC> + void path_base<VC>::curve4_rel(double dx_ctrl1, double dy_ctrl1, + double dx_ctrl2, double dy_ctrl2, + double dx_to, double dy_to) + { + rel_to_abs(&dx_ctrl1, &dy_ctrl1); + rel_to_abs(&dx_ctrl2, &dy_ctrl2); + rel_to_abs(&dx_to, &dy_to); + m_vertices.add_vertex(dx_ctrl1, dy_ctrl1, path_cmd_curve4); + m_vertices.add_vertex(dx_ctrl2, dy_ctrl2, path_cmd_curve4); + m_vertices.add_vertex(dx_to, dy_to, path_cmd_curve4); + } + + //------------------------------------------------------------------------ + template<class VC> + void path_base<VC>::curve4(double x_ctrl2, double y_ctrl2, + double x_to, double y_to) + { + double x0; + double y0; + if(is_vertex(last_vertex(&x0, &y0))) + { + double x_ctrl1; + double y_ctrl1; + unsigned cmd = prev_vertex(&x_ctrl1, &y_ctrl1); + if(is_curve(cmd)) + { + x_ctrl1 = x0 + x0 - x_ctrl1; + y_ctrl1 = y0 + y0 - y_ctrl1; + } + else + { + x_ctrl1 = x0; + y_ctrl1 = y0; + } + curve4(x_ctrl1, y_ctrl1, x_ctrl2, y_ctrl2, x_to, y_to); + } + } + + //------------------------------------------------------------------------ + template<class VC> + void path_base<VC>::curve4_rel(double dx_ctrl2, double dy_ctrl2, + double dx_to, double dy_to) + { + rel_to_abs(&dx_ctrl2, &dy_ctrl2); + rel_to_abs(&dx_to, &dy_to); + curve4(dx_ctrl2, dy_ctrl2, dx_to, dy_to); + } + + //------------------------------------------------------------------------ + template<class VC> + inline void path_base<VC>::end_poly(unsigned flags) + { + if(is_vertex(m_vertices.last_command())) + { + m_vertices.add_vertex(0.0, 0.0, path_cmd_end_poly | flags); + } + } + + //------------------------------------------------------------------------ + template<class VC> + inline void path_base<VC>::close_polygon(unsigned flags) + { + end_poly(path_flags_close | flags); + } + + //------------------------------------------------------------------------ + template<class VC> + inline unsigned path_base<VC>::total_vertices() const + { + return m_vertices.total_vertices(); + } + + //------------------------------------------------------------------------ + template<class VC> + inline unsigned path_base<VC>::last_vertex(double* x, double* y) const + { + return m_vertices.last_vertex(x, y); + } + + //------------------------------------------------------------------------ + template<class VC> + inline unsigned path_base<VC>::prev_vertex(double* x, double* y) const + { + return m_vertices.prev_vertex(x, y); + } + + //------------------------------------------------------------------------ + template<class VC> + inline double path_base<VC>::last_x() const + { + return m_vertices.last_x(); + } + + //------------------------------------------------------------------------ + template<class VC> + inline double path_base<VC>::last_y() const + { + return m_vertices.last_y(); + } + + //------------------------------------------------------------------------ + template<class VC> + inline unsigned path_base<VC>::vertex(unsigned idx, double* x, double* y) const + { + return m_vertices.vertex(idx, x, y); + } + + //------------------------------------------------------------------------ + template<class VC> + inline unsigned path_base<VC>::command(unsigned idx) const + { + return m_vertices.command(idx); + } + + //------------------------------------------------------------------------ + template<class VC> + void path_base<VC>::modify_vertex(unsigned idx, double x, double y) + { + m_vertices.modify_vertex(idx, x, y); + } + + //------------------------------------------------------------------------ + template<class VC> + void path_base<VC>::modify_vertex(unsigned idx, double x, double y, unsigned cmd) + { + m_vertices.modify_vertex(idx, x, y, cmd); + } + + //------------------------------------------------------------------------ + template<class VC> + void path_base<VC>::modify_command(unsigned idx, unsigned cmd) + { + m_vertices.modify_command(idx, cmd); + } + + //------------------------------------------------------------------------ + template<class VC> + inline void path_base<VC>::rewind(unsigned path_id) + { + m_iterator = path_id; + } + + //------------------------------------------------------------------------ + template<class VC> + inline unsigned path_base<VC>::vertex(double* x, double* y) + { + if(m_iterator >= m_vertices.total_vertices()) return path_cmd_stop; + return m_vertices.vertex(m_iterator++, x, y); + } + + //------------------------------------------------------------------------ + template<class VC> + unsigned path_base<VC>::perceive_polygon_orientation(unsigned start, + unsigned end) + { + // Calculate signed area (double area to be exact) + //--------------------- + unsigned np = end - start; + double area = 0.0; + unsigned i; + for(i = 0; i < np; i++) + { + double x1, y1, x2, y2; + m_vertices.vertex(start + i, &x1, &y1); + m_vertices.vertex(start + (i + 1) % np, &x2, &y2); + area += x1 * y2 - y1 * x2; + } + return (area < 0.0) ? path_flags_cw : path_flags_ccw; + } + + //------------------------------------------------------------------------ + template<class VC> + void path_base<VC>::invert_polygon(unsigned start, unsigned end) + { + unsigned i; + unsigned tmp_cmd = m_vertices.command(start); + + --end; // Make "end" inclusive + + // Shift all commands to one position + for(i = start; i < end; i++) + { + m_vertices.modify_command(i, m_vertices.command(i + 1)); + } + + // Assign starting command to the ending command + m_vertices.modify_command(end, tmp_cmd); + + // Reverse the polygon + while(end > start) + { + m_vertices.swap_vertices(start++, end--); + } + } + + //------------------------------------------------------------------------ + template<class VC> + void path_base<VC>::invert_polygon(unsigned start) + { + // Skip all non-vertices at the beginning + while(start < m_vertices.total_vertices() && + !is_vertex(m_vertices.command(start))) ++start; + + // Skip all insignificant move_to + while(start+1 < m_vertices.total_vertices() && + is_move_to(m_vertices.command(start)) && + is_move_to(m_vertices.command(start+1))) ++start; + + // Find the last vertex + unsigned end = start + 1; + while(end < m_vertices.total_vertices() && + !is_next_poly(m_vertices.command(end))) ++end; + + invert_polygon(start, end); + } + + //------------------------------------------------------------------------ + template<class VC> + unsigned path_base<VC>::arrange_polygon_orientation(unsigned start, + path_flags_e orientation) + { + if(orientation == path_flags_none) return start; + + // Skip all non-vertices at the beginning + while(start < m_vertices.total_vertices() && + !is_vertex(m_vertices.command(start))) ++start; + + // Skip all insignificant move_to + while(start+1 < m_vertices.total_vertices() && + is_move_to(m_vertices.command(start)) && + is_move_to(m_vertices.command(start+1))) ++start; + + // Find the last vertex + unsigned end = start + 1; + while(end < m_vertices.total_vertices() && + !is_next_poly(m_vertices.command(end))) ++end; + + if(end - start > 2) + { + if(perceive_polygon_orientation(start, end) != unsigned(orientation)) + { + // Invert polygon, set orientation flag, and skip all end_poly + invert_polygon(start, end); + unsigned cmd; + while(end < m_vertices.total_vertices() && + is_end_poly(cmd = m_vertices.command(end))) + { + m_vertices.modify_command(end++, set_orientation(cmd, orientation)); + } + } + } + return end; + } + + //------------------------------------------------------------------------ + template<class VC> + unsigned path_base<VC>::arrange_orientations(unsigned start, + path_flags_e orientation) + { + if(orientation != path_flags_none) + { + while(start < m_vertices.total_vertices()) + { + start = arrange_polygon_orientation(start, orientation); + if(is_stop(m_vertices.command(start))) + { + ++start; + break; + } + } + } + return start; + } + + //------------------------------------------------------------------------ + template<class VC> + void path_base<VC>::arrange_orientations_all_paths(path_flags_e orientation) + { + if(orientation != path_flags_none) + { + unsigned start = 0; + while(start < m_vertices.total_vertices()) + { + start = arrange_orientations(start, orientation); + } + } + } + + //------------------------------------------------------------------------ + template<class VC> + void path_base<VC>::flip_x(double x1, double x2) + { + unsigned i; + double x, y; + for(i = 0; i < m_vertices.total_vertices(); i++) + { + unsigned cmd = m_vertices.vertex(i, &x, &y); + if(is_vertex(cmd)) + { + m_vertices.modify_vertex(i, x2 - x + x1, y); + } + } + } + + //------------------------------------------------------------------------ + template<class VC> + void path_base<VC>::flip_y(double y1, double y2) + { + unsigned i; + double x, y; + for(i = 0; i < m_vertices.total_vertices(); i++) + { + unsigned cmd = m_vertices.vertex(i, &x, &y); + if(is_vertex(cmd)) + { + m_vertices.modify_vertex(i, x, y2 - y + y1); + } + } + } + + //------------------------------------------------------------------------ + template<class VC> + void path_base<VC>::translate(double dx, double dy, unsigned path_id) + { + unsigned num_ver = m_vertices.total_vertices(); + for(; path_id < num_ver; path_id++) + { + double x, y; + unsigned cmd = m_vertices.vertex(path_id, &x, &y); + if(is_stop(cmd)) break; + if(is_vertex(cmd)) + { + x += dx; + y += dy; + m_vertices.modify_vertex(path_id, x, y); + } + } + } + + //------------------------------------------------------------------------ + template<class VC> + void path_base<VC>::translate_all_paths(double dx, double dy) + { + unsigned idx; + unsigned num_ver = m_vertices.total_vertices(); + for(idx = 0; idx < num_ver; idx++) + { + double x, y; + if(is_vertex(m_vertices.vertex(idx, &x, &y))) + { + x += dx; + y += dy; + m_vertices.modify_vertex(idx, x, y); + } + } + } + + //-----------------------------------------------------vertex_stl_storage + template<class Container> class vertex_stl_storage + { + public: + typedef typename Container::value_type vertex_type; + typedef typename vertex_type::value_type value_type; + + void remove_all() { m_vertices.clear(); } + void free_all() { m_vertices.clear(); } + + void add_vertex(double x, double y, unsigned cmd) + { + m_vertices.push_back(vertex_type(value_type(x), + value_type(y), + int8u(cmd))); + } + + void modify_vertex(unsigned idx, double x, double y) + { + vertex_type& v = m_vertices[idx]; + v.x = value_type(x); + v.y = value_type(y); + } + + void modify_vertex(unsigned idx, double x, double y, unsigned cmd) + { + vertex_type& v = m_vertices[idx]; + v.x = value_type(x); + v.y = value_type(y); + v.cmd = int8u(cmd); + } + + void modify_command(unsigned idx, unsigned cmd) + { + m_vertices[idx].cmd = int8u(cmd); + } + + void swap_vertices(unsigned v1, unsigned v2) + { + vertex_type t = m_vertices[v1]; + m_vertices[v1] = m_vertices[v2]; + m_vertices[v2] = t; + } + + unsigned last_command() const + { + return m_vertices.size() ? + m_vertices[m_vertices.size() - 1].cmd : + path_cmd_stop; + } + + unsigned last_vertex(double* x, double* y) const + { + if(m_vertices.size() == 0) + { + *x = *y = 0.0; + return path_cmd_stop; + } + return vertex(m_vertices.size() - 1, x, y); + } + + unsigned prev_vertex(double* x, double* y) const + { + if(m_vertices.size() < 2) + { + *x = *y = 0.0; + return path_cmd_stop; + } + return vertex(m_vertices.size() - 2, x, y); + } + + double last_x() const + { + return m_vertices.size() ? m_vertices[m_vertices.size() - 1].x : 0.0; + } + + double last_y() const + { + return m_vertices.size() ? m_vertices[m_vertices.size() - 1].y : 0.0; + } + + unsigned total_vertices() const + { + return m_vertices.size(); + } + + unsigned vertex(unsigned idx, double* x, double* y) const + { + const vertex_type& v = m_vertices[idx]; + *x = v.x; + *y = v.y; + return v.cmd; + } + + unsigned command(unsigned idx) const + { + return m_vertices[idx].cmd; + } + + private: + Container m_vertices; + }; + + //-----------------------------------------------------------path_storage + typedef path_base<vertex_block_storage<double> > path_storage; + + // Example of declarations path_storage with pod_bvector as a container + //----------------------------------------------------------------------- + //typedef path_base<vertex_stl_storage<pod_bvector<vertex_d> > > path_storage; + +} + + + +// Example of declarations path_storage with std::vector as a container +//--------------------------------------------------------------------------- +//#include <vector> +//namespace agg +//{ +// typedef path_base<vertex_stl_storage<std::vector<vertex_d> > > stl_path_storage; +//} + + + + +#endif diff --git a/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 00000000000..7c48355993b --- /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 00000000000..c1d174cacbf --- /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_amask_adaptor.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pixfmt_amask_adaptor.h new file mode 100644 index 00000000000..cf39c54ad55 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pixfmt_amask_adaptor.h @@ -0,0 +1,240 @@ +//---------------------------------------------------------------------------- +// 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_AMASK_ADAPTOR_INCLUDED +#define AGG_PIXFMT_AMASK_ADAPTOR_INCLUDED + + +#include <string.h> +#include "agg_array.h" +#include "agg_rendering_buffer.h" + + +namespace agg +{ + //==================================================pixfmt_amask_adaptor + template<class PixFmt, class AlphaMask> class pixfmt_amask_adaptor + { + public: + typedef PixFmt pixfmt_type; + typedef typename pixfmt_type::color_type color_type; + typedef typename pixfmt_type::row_data row_data; + typedef AlphaMask amask_type; + typedef typename amask_type::cover_type cover_type; + + private: + enum span_extra_tail_e { span_extra_tail = 256 }; + + void realloc_span(unsigned len) + { + if(len > m_span.size()) + { + m_span.resize(len + span_extra_tail); + } + } + + void init_span(unsigned len) + { + realloc_span(len); + memset(&m_span[0], amask_type::cover_full, len * sizeof(cover_type)); + } + + void init_span(unsigned len, const cover_type* covers) + { + realloc_span(len); + memcpy(&m_span[0], covers, len * sizeof(cover_type)); + } + + + public: + pixfmt_amask_adaptor(pixfmt_type& pixf, amask_type& mask) : + m_pixf(&pixf), m_mask(&mask), m_span() + {} + + void attach_pixfmt(pixfmt_type& pixf) { m_pixf = &pixf; } + void attach_alpha_mask(amask_type& mask) { m_mask = &mask; } + + //-------------------------------------------------------------------- + template<class PixFmt2> + bool attach_pixfmt(PixFmt2& pixf, int x1, int y1, int x2, int y2) + { + return m_pixf->attach(pixf, x1, y1, x2, y2); + } + + //-------------------------------------------------------------------- + unsigned width() const { return m_pixf->width(); } + unsigned height() const { return m_pixf->height(); } + + //-------------------------------------------------------------------- + color_type pixel(int x, int y) + { + return m_pixf->pixel(x, y); + } + + //-------------------------------------------------------------------- + void copy_pixel(int x, int y, const color_type& c) + { + m_pixf->blend_pixel(x, y, c, m_mask->pixel(x, y)); + } + + //-------------------------------------------------------------------- + void blend_pixel(int x, int y, const color_type& c, cover_type cover) + { + m_pixf->blend_pixel(x, y, c, m_mask->combine_pixel(x, y, cover)); + } + + //-------------------------------------------------------------------- + void copy_hline(int x, int y, + unsigned len, + const color_type& c) + { + realloc_span(len); + m_mask->fill_hspan(x, y, &m_span[0], len); + m_pixf->blend_solid_hspan(x, y, len, c, &m_span[0]); + } + + //-------------------------------------------------------------------- + void blend_hline(int x, int y, + unsigned len, + const color_type& c, + cover_type cover) + { + init_span(len); + m_mask->combine_hspan(x, y, &m_span[0], len); + m_pixf->blend_solid_hspan(x, y, len, c, &m_span[0]); + } + + //-------------------------------------------------------------------- + void copy_vline(int x, int y, + unsigned len, + const color_type& c) + { + realloc_span(len); + m_mask->fill_vspan(x, y, &m_span[0], len); + m_pixf->blend_solid_vspan(x, y, len, c, &m_span[0]); + } + + //-------------------------------------------------------------------- + void blend_vline(int x, int y, + unsigned len, + const color_type& c, + cover_type cover) + { + init_span(len); + m_mask->combine_vspan(x, y, &m_span[0], len); + m_pixf->blend_solid_vspan(x, y, len, c, &m_span[0]); + } + + //-------------------------------------------------------------------- + void copy_from(const rendering_buffer& from, + int xdst, int ydst, + int xsrc, int ysrc, + unsigned len) + { + m_pixf->copy_from(from, xdst, ydst, xsrc, ysrc, len); + } + + + //-------------------------------------------------------------------- + void blend_solid_hspan(int x, int y, + unsigned len, + const color_type& c, + const cover_type* covers) + { + init_span(len, covers); + m_mask->combine_hspan(x, y, &m_span[0], len); + m_pixf->blend_solid_hspan(x, y, len, c, &m_span[0]); + } + + + //-------------------------------------------------------------------- + void blend_solid_vspan(int x, int y, + unsigned len, + const color_type& c, + const cover_type* covers) + { + init_span(len, covers); + m_mask->combine_vspan(x, y, &m_span[0], len); + m_pixf->blend_solid_vspan(x, y, len, c, &m_span[0]); + } + + + //-------------------------------------------------------------------- + void copy_color_hspan(int x, int y, unsigned len, const color_type* colors) + { + realloc_span(len); + m_mask->fill_hspan(x, y, &m_span[0], len); + m_pixf->blend_color_hspan(x, y, len, colors, &m_span[0], cover_full); + } + + //-------------------------------------------------------------------- + void copy_color_vspan(int x, int y, unsigned len, const color_type* colors) + { + realloc_span(len); + m_mask->fill_vspan(x, y, &m_span[0], len); + m_pixf->blend_color_vspan(x, y, len, colors, &m_span[0], cover_full); + } + + //-------------------------------------------------------------------- + void blend_color_hspan(int x, int y, + unsigned len, + const color_type* colors, + const cover_type* covers, + cover_type cover = cover_full) + { + if(covers) + { + init_span(len, covers); + m_mask->combine_hspan(x, y, &m_span[0], len); + } + else + { + realloc_span(len); + m_mask->fill_hspan(x, y, &m_span[0], len); + } + m_pixf->blend_color_hspan(x, y, len, colors, &m_span[0], cover); + } + + + //-------------------------------------------------------------------- + void blend_color_vspan(int x, int y, + unsigned len, + const color_type* colors, + const cover_type* covers, + cover_type cover = cover_full) + { + if(covers) + { + init_span(len, covers); + m_mask->combine_vspan(x, y, &m_span[0], len); + } + else + { + realloc_span(len); + m_mask->fill_vspan(x, y, &m_span[0], len); + } + m_pixf->blend_color_vspan(x, y, len, colors, &m_span[0], cover); + } + + private: + pixfmt_type* m_pixf; + const amask_type* m_mask; + pod_array<cover_type> m_span; + }; + +} + +#endif + diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pixfmt_base.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pixfmt_base.h new file mode 100644 index 00000000000..57ae19cfe04 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pixfmt_base.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_PIXFMT_BASE_INCLUDED +#define AGG_PIXFMT_BASE_INCLUDED + +#include "agg_basics.h" +#include "agg_color_gray.h" +#include "agg_color_rgba.h" + +namespace agg +{ + struct pixfmt_gray_tag + { + }; + + struct pixfmt_rgb_tag + { + }; + + struct pixfmt_rgba_tag + { + }; + + //--------------------------------------------------------------blender_base + template<class ColorT, class Order = void> + struct blender_base + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + + static rgba get(value_type r, value_type g, value_type b, value_type a, cover_type cover = cover_full) + { + if (cover > cover_none) + { + rgba c( + color_type::to_double(r), + color_type::to_double(g), + color_type::to_double(b), + color_type::to_double(a)); + + if (cover < cover_full) + { + double x = double(cover) / cover_full; + c.r *= x; + c.g *= x; + c.b *= x; + c.a *= x; + } + + return c; + } + else return rgba::no_color(); + } + + static rgba get(const value_type* p, cover_type cover = cover_full) + { + return get( + p[order_type::R], + p[order_type::G], + p[order_type::B], + p[order_type::A], + cover); + } + + static void set(value_type* p, value_type r, value_type g, value_type b, value_type a) + { + p[order_type::R] = r; + p[order_type::G] = g; + p[order_type::B] = b; + p[order_type::A] = a; + } + + static void set(value_type* p, const rgba& c) + { + p[order_type::R] = color_type::from_double(c.r); + p[order_type::G] = color_type::from_double(c.g); + p[order_type::B] = color_type::from_double(c.b); + p[order_type::A] = color_type::from_double(c.a); + } + }; +} + +#endif diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pixfmt_gray.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pixfmt_gray.h new file mode 100644 index 00000000000..438f04d33d4 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pixfmt_gray.h @@ -0,0 +1,737 @@ +//---------------------------------------------------------------------------- +// 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_GRAY_INCLUDED +#define AGG_PIXFMT_GRAY_INCLUDED + +#include <string.h> +#include "agg_pixfmt_base.h" +#include "agg_rendering_buffer.h" + +namespace agg +{ + + //============================================================blender_gray + template<class ColorT> struct blender_gray + { + typedef ColorT color_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; + + // Blend pixels using the non-premultiplied form of Alvy-Ray Smith's + // compositing function. Since the render buffer is opaque we skip the + // initial premultiply and final demultiply. + + static AGG_INLINE void blend_pix(value_type* p, + value_type cv, value_type alpha, cover_type cover) + { + blend_pix(p, cv, color_type::mult_cover(alpha, cover)); + } + + static AGG_INLINE void blend_pix(value_type* p, + value_type cv, value_type alpha) + { + *p = color_type::lerp(*p, cv, alpha); + } + }; + + + //======================================================blender_gray_pre + template<class ColorT> struct blender_gray_pre + { + typedef ColorT color_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; + + // Blend pixels using the premultiplied form of Alvy-Ray Smith's + // compositing function. + + static AGG_INLINE void blend_pix(value_type* p, + value_type cv, value_type alpha, cover_type cover) + { + blend_pix(p, color_type::mult_cover(cv, cover), color_type::mult_cover(alpha, cover)); + } + + static AGG_INLINE void blend_pix(value_type* p, + value_type cv, value_type alpha) + { + *p = color_type::prelerp(*p, cv, alpha); + } + }; + + + + //=====================================================apply_gamma_dir_gray + template<class ColorT, class GammaLut> class apply_gamma_dir_gray + { + public: + typedef typename ColorT::value_type value_type; + + apply_gamma_dir_gray(const GammaLut& gamma) : m_gamma(gamma) {} + + AGG_INLINE void operator () (value_type* p) + { + *p = m_gamma.dir(*p); + } + + private: + const GammaLut& m_gamma; + }; + + + + //=====================================================apply_gamma_inv_gray + template<class ColorT, class GammaLut> class apply_gamma_inv_gray + { + public: + typedef typename ColorT::value_type value_type; + + apply_gamma_inv_gray(const GammaLut& gamma) : m_gamma(gamma) {} + + AGG_INLINE void operator () (value_type* p) + { + *p = m_gamma.inv(*p); + } + + private: + const GammaLut& m_gamma; + }; + + + + //=================================================pixfmt_alpha_blend_gray + template<class Blender, class RenBuf, unsigned Step = 1, unsigned Offset = 0> + class pixfmt_alpha_blend_gray + { + public: + typedef pixfmt_gray_tag pixfmt_category; + typedef RenBuf rbuf_type; + typedef typename rbuf_type::row_data row_data; + typedef Blender blender_type; + typedef typename blender_type::color_type color_type; + typedef int order_type; // A fake one + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + enum + { + pix_width = sizeof(value_type) * Step, + pix_step = Step, + pix_offset = Offset, + }; + struct pixel_type + { + value_type c[pix_step]; + + void set(value_type v) + { + c[0] = v; + } + + void set(const color_type& color) + { + set(color.v); + } + + void get(value_type& v) const + { + v = c[0]; + } + + color_type get() const + { + return color_type(c[0]); + } + + pixel_type* next() + { + return this + 1; + } + + const pixel_type* next() const + { + return this + 1; + } + + pixel_type* advance(int n) + { + return this + n; + } + + const pixel_type* advance(int n) const + { + return this + n; + } + }; + + private: + //-------------------------------------------------------------------- + AGG_INLINE void blend_pix(pixel_type* p, + value_type v, value_type a, + unsigned cover) + { + blender_type::blend_pix(p->c, v, a, cover); + } + + //-------------------------------------------------------------------- + AGG_INLINE void blend_pix(pixel_type* p, value_type v, value_type a) + { + blender_type::blend_pix(p->c, v, a); + } + + //-------------------------------------------------------------------- + AGG_INLINE void blend_pix(pixel_type* p, const color_type& c, unsigned cover) + { + blender_type::blend_pix(p->c, c.v, c.a, cover); + } + + //-------------------------------------------------------------------- + AGG_INLINE void blend_pix(pixel_type* p, const color_type& c) + { + blender_type::blend_pix(p->c, c.v, c.a); + } + + //-------------------------------------------------------------------- + AGG_INLINE void copy_or_blend_pix(pixel_type* p, const color_type& c, unsigned cover) + { + if (!c.is_transparent()) + { + if (c.is_opaque() && cover == cover_mask) + { + p->set(c); + } + else + { + blend_pix(p, c, cover); + } + } + } + + //-------------------------------------------------------------------- + AGG_INLINE void copy_or_blend_pix(pixel_type* p, const color_type& c) + { + if (!c.is_transparent()) + { + if (c.is_opaque()) + { + p->set(c); + } + else + { + blend_pix(p, c); + } + } + } + + public: + //-------------------------------------------------------------------- + explicit pixfmt_alpha_blend_gray(rbuf_type& rb) : + m_rbuf(&rb) + {} + void attach(rbuf_type& rb) { m_rbuf = &rb; } + //-------------------------------------------------------------------- + + template<class PixFmt> + bool attach(PixFmt& pixf, int x1, int y1, int x2, int y2) + { + rect_i r(x1, y1, x2, y2); + if (r.clip(rect_i(0, 0, pixf.width()-1, pixf.height()-1))) + { + int stride = pixf.stride(); + m_rbuf->attach(pixf.pix_ptr(r.x1, stride < 0 ? r.y2 : r.y1), + (r.x2 - r.x1) + 1, + (r.y2 - r.y1) + 1, + stride); + return true; + } + return false; + } + + //-------------------------------------------------------------------- + AGG_INLINE unsigned width() const { return m_rbuf->width(); } + AGG_INLINE unsigned height() const { return m_rbuf->height(); } + AGG_INLINE int stride() const { return m_rbuf->stride(); } + + //-------------------------------------------------------------------- + int8u* row_ptr(int y) { return m_rbuf->row_ptr(y); } + const int8u* row_ptr(int y) const { return m_rbuf->row_ptr(y); } + row_data row(int y) const { return m_rbuf->row(y); } + + //-------------------------------------------------------------------- + AGG_INLINE int8u* pix_ptr(int x, int y) + { + return m_rbuf->row_ptr(y) + sizeof(value_type) * (x * pix_step + pix_offset); + } + + AGG_INLINE const int8u* pix_ptr(int x, int y) const + { + return m_rbuf->row_ptr(y) + sizeof(value_type) * (x * pix_step + pix_offset); + } + + // Return pointer to pixel value, forcing row to be allocated. + AGG_INLINE pixel_type* pix_value_ptr(int x, int y, unsigned len) + { + return (pixel_type*)(m_rbuf->row_ptr(x, y, len) + sizeof(value_type) * (x * pix_step + pix_offset)); + } + + // Return pointer to pixel value, or null if row not allocated. + AGG_INLINE const pixel_type* pix_value_ptr(int x, int y) const + { + int8u* p = m_rbuf->row_ptr(y); + return p ? (pixel_type*)(p + sizeof(value_type) * (x * pix_step + pix_offset)) : 0; + } + + // Get pixel pointer from raw buffer pointer. + AGG_INLINE static pixel_type* pix_value_ptr(void* p) + { + return (pixel_type*)((value_type*)p + pix_offset); + } + + // Get pixel pointer from raw buffer pointer. + AGG_INLINE static const pixel_type* pix_value_ptr(const void* p) + { + return (const pixel_type*)((const value_type*)p + pix_offset); + } + + //-------------------------------------------------------------------- + AGG_INLINE static void write_plain_color(void* p, color_type c) + { + // Grayscale formats are implicitly premultiplied. + c.premultiply(); + pix_value_ptr(p)->set(c); + } + + //-------------------------------------------------------------------- + AGG_INLINE static color_type read_plain_color(const void* p) + { + return pix_value_ptr(p)->get(); + } + + //-------------------------------------------------------------------- + AGG_INLINE static void make_pix(int8u* p, const color_type& c) + { + ((pixel_type*)p)->set(c); + } + + //-------------------------------------------------------------------- + AGG_INLINE color_type pixel(int x, int y) const + { + if (const pixel_type* p = pix_value_ptr(x, y)) + { + return p->get(); + } + return color_type::no_color(); + } + + //-------------------------------------------------------------------- + AGG_INLINE void copy_pixel(int x, int y, const color_type& c) + { + pix_value_ptr(x, y, 1)->set(c); + } + + //-------------------------------------------------------------------- + AGG_INLINE void blend_pixel(int x, int y, const color_type& c, int8u cover) + { + copy_or_blend_pix(pix_value_ptr(x, y, 1), c, cover); + } + + //-------------------------------------------------------------------- + AGG_INLINE void copy_hline(int x, int y, + unsigned len, + const color_type& c) + { + pixel_type* p = pix_value_ptr(x, y, len); + do + { + p->set(c); + p = p->next(); + } + while(--len); + } + + + //-------------------------------------------------------------------- + AGG_INLINE void copy_vline(int x, int y, + unsigned len, + const color_type& c) + { + do + { + pix_value_ptr(x, y++, 1)->set(c); + } + while (--len); + } + + + //-------------------------------------------------------------------- + void blend_hline(int x, int y, + unsigned len, + const color_type& c, + int8u cover) + { + if (!c.is_transparent()) + { + pixel_type* p = pix_value_ptr(x, y, len); + + if (c.is_opaque() && cover == cover_mask) + { + do + { + p->set(c); + p = p->next(); + } + while (--len); + } + else + { + do + { + blend_pix(p, c, cover); + p = p->next(); + } + while (--len); + } + } + } + + + //-------------------------------------------------------------------- + void blend_vline(int x, int y, + unsigned len, + const color_type& c, + int8u cover) + { + if (!c.is_transparent()) + { + if (c.is_opaque() && cover == cover_mask) + { + do + { + pix_value_ptr(x, y++, 1)->set(c); + } + while (--len); + } + else + { + do + { + blend_pix(pix_value_ptr(x, y++, 1), c, cover); + } + while (--len); + } + } + } + + + //-------------------------------------------------------------------- + void blend_solid_hspan(int x, int y, + unsigned len, + const color_type& c, + const int8u* covers) + { + if (!c.is_transparent()) + { + pixel_type* p = pix_value_ptr(x, y, len); + + do + { + if (c.is_opaque() && *covers == cover_mask) + { + p->set(c); + } + else + { + blend_pix(p, c, *covers); + } + p = p->next(); + ++covers; + } + while (--len); + } + } + + + //-------------------------------------------------------------------- + void blend_solid_vspan(int x, int y, + unsigned len, + const color_type& c, + const int8u* covers) + { + if (!c.is_transparent()) + { + do + { + pixel_type* p = pix_value_ptr(x, y++, 1); + + if (c.is_opaque() && *covers == cover_mask) + { + p->set(c); + } + else + { + blend_pix(p, c, *covers); + } + ++covers; + } + while (--len); + } + } + + + //-------------------------------------------------------------------- + void copy_color_hspan(int x, int y, + unsigned len, + const color_type* colors) + { + pixel_type* p = pix_value_ptr(x, y, len); + + do + { + p->set(*colors++); + p = p->next(); + } + while (--len); + } + + + //-------------------------------------------------------------------- + void copy_color_vspan(int x, int y, + unsigned len, + const color_type* colors) + { + do + { + pix_value_ptr(x, y++, 1)->set(*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 = pix_value_ptr(x, y, len); + + if (covers) + { + do + { + copy_or_blend_pix(p, *colors++, *covers++); + p = p->next(); + } + while (--len); + } + else + { + if (cover == cover_mask) + { + do + { + copy_or_blend_pix(p, *colors++); + p = p->next(); + } + while (--len); + } + else + { + do + { + copy_or_blend_pix(p, *colors++, cover); + p = p->next(); + } + while (--len); + } + } + } + + + //-------------------------------------------------------------------- + void blend_color_vspan(int x, int y, + unsigned len, + const color_type* colors, + const int8u* covers, + int8u cover) + { + if (covers) + { + do + { + copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++, *covers++); + } + while (--len); + } + else + { + if (cover == cover_mask) + { + do + { + copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++); + } + while (--len); + } + else + { + do + { + copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++, cover); + } + while (--len); + } + } + } + + //-------------------------------------------------------------------- + template<class Function> void for_each_pixel(Function f) + { + unsigned y; + for (y = 0; y < height(); ++y) + { + row_data r = m_rbuf->row(y); + if (r.ptr) + { + unsigned len = r.x2 - r.x1 + 1; + pixel_type* p = pix_value_ptr(r.x1, y, len); + do + { + f(p->c); + p = p->next(); + } + while (--len); + } + } + } + + //-------------------------------------------------------------------- + template<class GammaLut> void apply_gamma_dir(const GammaLut& g) + { + for_each_pixel(apply_gamma_dir_gray<color_type, GammaLut>(g)); + } + + //-------------------------------------------------------------------- + template<class GammaLut> void apply_gamma_inv(const GammaLut& g) + { + for_each_pixel(apply_gamma_inv_gray<color_type, GammaLut>(g)); + } + + //-------------------------------------------------------------------- + template<class RenBuf2> + void copy_from(const RenBuf2& from, + int xdst, int ydst, + int xsrc, int ysrc, + unsigned len) + { + if (const int8u* p = from.row_ptr(ysrc)) + { + memmove(m_rbuf->row_ptr(xdst, ydst, len) + xdst * pix_width, + p + xsrc * pix_width, + len * pix_width); + } + } + + //-------------------------------------------------------------------- + // Blend from single color, using grayscale surface as alpha channel. + 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::pixel_type src_pixel_type; + typedef typename SrcPixelFormatRenderer::color_type src_color_type; + + if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc)) + { + pixel_type* pdst = pix_value_ptr(xdst, ydst, len); + + do + { + copy_or_blend_pix(pdst, color, src_color_type::scale_cover(cover, psrc->c[0])); + psrc = psrc->next(); + pdst = pdst->next(); + } + while (--len); + } + } + + //-------------------------------------------------------------------- + // Blend from color table, using grayscale surface as indexes into table. + // Obviously, this only works for integer value types. + 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::pixel_type src_pixel_type; + + if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc)) + { + pixel_type* pdst = pix_value_ptr(xdst, ydst, len); + + do + { + copy_or_blend_pix(pdst, color_lut[psrc->c[0]], cover); + psrc = psrc->next(); + pdst = pdst->next(); + } + while (--len); + } + } + + private: + rbuf_type* m_rbuf; + }; + + typedef blender_gray<gray8> blender_gray8; + typedef blender_gray<sgray8> blender_sgray8; + typedef blender_gray<gray16> blender_gray16; + typedef blender_gray<gray32> blender_gray32; + + typedef blender_gray_pre<gray8> blender_gray8_pre; + typedef blender_gray_pre<sgray8> blender_sgray8_pre; + typedef blender_gray_pre<gray16> blender_gray16_pre; + typedef blender_gray_pre<gray32> blender_gray32_pre; + + typedef pixfmt_alpha_blend_gray<blender_gray8, rendering_buffer> pixfmt_gray8; + typedef pixfmt_alpha_blend_gray<blender_sgray8, rendering_buffer> pixfmt_sgray8; + typedef pixfmt_alpha_blend_gray<blender_gray16, rendering_buffer> pixfmt_gray16; + typedef pixfmt_alpha_blend_gray<blender_gray32, rendering_buffer> pixfmt_gray32; + + typedef pixfmt_alpha_blend_gray<blender_gray8_pre, rendering_buffer> pixfmt_gray8_pre; + typedef pixfmt_alpha_blend_gray<blender_sgray8_pre, rendering_buffer> pixfmt_sgray8_pre; + typedef pixfmt_alpha_blend_gray<blender_gray16_pre, rendering_buffer> pixfmt_gray16_pre; + typedef pixfmt_alpha_blend_gray<blender_gray32_pre, rendering_buffer> pixfmt_gray32_pre; +} + +#endif + diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pixfmt_rgb.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pixfmt_rgb.h new file mode 100644 index 00000000000..7095fbce58d --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pixfmt_rgb.h @@ -0,0 +1,994 @@ +//---------------------------------------------------------------------------- +// 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_INCLUDED +#define AGG_PIXFMT_RGB_INCLUDED + +#include <string.h> +#include "agg_pixfmt_base.h" +#include "agg_rendering_buffer.h" + +namespace agg +{ + + //=====================================================apply_gamma_dir_rgb + template<class ColorT, class Order, class GammaLut> class apply_gamma_dir_rgb + { + public: + typedef typename ColorT::value_type value_type; + + apply_gamma_dir_rgb(const GammaLut& gamma) : m_gamma(gamma) {} + + AGG_INLINE void operator () (value_type* p) + { + p[Order::R] = m_gamma.dir(p[Order::R]); + p[Order::G] = m_gamma.dir(p[Order::G]); + p[Order::B] = m_gamma.dir(p[Order::B]); + } + + private: + const GammaLut& m_gamma; + }; + + + + //=====================================================apply_gamma_inv_rgb + template<class ColorT, class Order, class GammaLut> class apply_gamma_inv_rgb + { + public: + typedef typename ColorT::value_type value_type; + + apply_gamma_inv_rgb(const GammaLut& gamma) : m_gamma(gamma) {} + + AGG_INLINE void operator () (value_type* p) + { + p[Order::R] = m_gamma.inv(p[Order::R]); + p[Order::G] = m_gamma.inv(p[Order::G]); + p[Order::B] = m_gamma.inv(p[Order::B]); + } + + private: + const GammaLut& m_gamma; + }; + + + //=========================================================blender_rgb + template<class ColorT, class Order> + struct blender_rgb + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + // Blend pixels using the non-premultiplied form of Alvy-Ray Smith's + // compositing function. Since the render buffer is opaque we skip the + // initial premultiply and final demultiply. + + //-------------------------------------------------------------------- + static AGG_INLINE void blend_pix(value_type* p, + value_type cr, value_type cg, value_type cb, value_type alpha, cover_type cover) + { + blend_pix(p, cr, cg, cb, color_type::mult_cover(alpha, cover)); + } + + //-------------------------------------------------------------------- + static AGG_INLINE void blend_pix(value_type* p, + value_type cr, value_type cg, value_type cb, value_type alpha) + { + p[Order::R] = color_type::lerp(p[Order::R], cr, alpha); + p[Order::G] = color_type::lerp(p[Order::G], cg, alpha); + p[Order::B] = color_type::lerp(p[Order::B], cb, alpha); + } + }; + + //======================================================blender_rgb_pre + template<class ColorT, class Order> + struct blender_rgb_pre + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + // Blend pixels using the premultiplied form of Alvy-Ray Smith's + // compositing function. + + //-------------------------------------------------------------------- + static AGG_INLINE void blend_pix(value_type* p, + value_type cr, value_type cg, value_type cb, value_type alpha, cover_type cover) + { + blend_pix(p, + color_type::mult_cover(cr, cover), + color_type::mult_cover(cg, cover), + color_type::mult_cover(cb, cover), + color_type::mult_cover(alpha, cover)); + } + + //-------------------------------------------------------------------- + static AGG_INLINE void blend_pix(value_type* p, + value_type cr, value_type cg, value_type cb, value_type alpha) + { + p[Order::R] = color_type::prelerp(p[Order::R], cr, alpha); + p[Order::G] = color_type::prelerp(p[Order::G], cg, alpha); + p[Order::B] = color_type::prelerp(p[Order::B], cb, alpha); + } + }; + + //===================================================blender_rgb_gamma + template<class ColorT, class Order, class Gamma> + class blender_rgb_gamma : public blender_base<ColorT, Order> + { + public: + typedef ColorT color_type; + typedef Order order_type; + typedef Gamma gamma_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; + + //-------------------------------------------------------------------- + blender_rgb_gamma() : m_gamma(0) {} + void gamma(const gamma_type& g) { m_gamma = &g; } + + //-------------------------------------------------------------------- + AGG_INLINE void blend_pix(value_type* p, + value_type cr, value_type cg, value_type cb, value_type alpha, cover_type cover) + { + blend_pix(p, cr, cg, cb, color_type::mult_cover(alpha, cover)); + } + + //-------------------------------------------------------------------- + AGG_INLINE void blend_pix(value_type* p, + value_type cr, value_type cg, value_type cb, value_type alpha) + { + calc_type r = m_gamma->dir(p[Order::R]); + calc_type g = m_gamma->dir(p[Order::G]); + calc_type b = m_gamma->dir(p[Order::B]); + p[Order::R] = m_gamma->inv(color_type::downscale((m_gamma->dir(cr) - r) * alpha) + r); + p[Order::G] = m_gamma->inv(color_type::downscale((m_gamma->dir(cg) - g) * alpha) + g); + p[Order::B] = m_gamma->inv(color_type::downscale((m_gamma->dir(cb) - b) * alpha) + b); + } + + private: + const gamma_type* m_gamma; + }; + + + //==================================================pixfmt_alpha_blend_rgb + template<class Blender, class RenBuf, unsigned Step, unsigned Offset = 0> + class pixfmt_alpha_blend_rgb + { + public: + typedef pixfmt_rgb_tag pixfmt_category; + typedef RenBuf rbuf_type; + typedef Blender blender_type; + typedef typename rbuf_type::row_data row_data; + typedef typename blender_type::color_type color_type; + typedef typename blender_type::order_type order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + enum + { + pix_step = Step, + pix_offset = Offset, + pix_width = sizeof(value_type) * pix_step + }; + struct pixel_type + { + value_type c[pix_step]; + + void set(value_type r, value_type g, value_type b) + { + c[order_type::R] = r; + c[order_type::G] = g; + c[order_type::B] = b; + } + + void set(const color_type& color) + { + set(color.r, color.g, color.b); + } + + void get(value_type& r, value_type& g, value_type& b) const + { + r = c[order_type::R]; + g = c[order_type::G]; + b = c[order_type::B]; + } + + color_type get() const + { + return color_type( + c[order_type::R], + c[order_type::G], + c[order_type::B]); + } + + pixel_type* next() + { + return this + 1; + } + + const pixel_type* next() const + { + return this + 1; + } + + pixel_type* advance(int n) + { + return this + n; + } + + const pixel_type* advance(int n) const + { + return this + n; + } + }; + + private: + //-------------------------------------------------------------------- + AGG_INLINE void blend_pix(pixel_type* p, + value_type r, value_type g, value_type b, value_type a, + unsigned cover) + { + m_blender.blend_pix(p->c, r, g, b, a, cover); + } + + //-------------------------------------------------------------------- + AGG_INLINE void blend_pix(pixel_type* p, + value_type r, value_type g, value_type b, value_type a) + { + m_blender.blend_pix(p->c, r, g, b, a); + } + + //-------------------------------------------------------------------- + AGG_INLINE void blend_pix(pixel_type* p, const color_type& c, unsigned cover) + { + m_blender.blend_pix(p->c, c.r, c.g, c.b, c.a, cover); + } + + //-------------------------------------------------------------------- + AGG_INLINE void blend_pix(pixel_type* p, const color_type& c) + { + m_blender.blend_pix(p->c, c.r, c.g, c.b, c.a); + } + + //-------------------------------------------------------------------- + AGG_INLINE void copy_or_blend_pix(pixel_type* p, const color_type& c, unsigned cover) + { + if (!c.is_transparent()) + { + if (c.is_opaque() && cover == cover_mask) + { + p->set(c); + } + else + { + blend_pix(p, c, cover); + } + } + } + + //-------------------------------------------------------------------- + AGG_INLINE void copy_or_blend_pix(pixel_type* p, const color_type& c) + { + if (!c.is_transparent()) + { + if (c.is_opaque()) + { + p->set(c); + } + else + { + blend_pix(p, c); + } + } + } + + public: + //-------------------------------------------------------------------- + explicit pixfmt_alpha_blend_rgb(rbuf_type& rb) : + m_rbuf(&rb) + {} + void attach(rbuf_type& rb) { m_rbuf = &rb; } + + //-------------------------------------------------------------------- + template<class PixFmt> + bool attach(PixFmt& pixf, int x1, int y1, int x2, int y2) + { + rect_i r(x1, y1, x2, y2); + if (r.clip(rect_i(0, 0, pixf.width()-1, pixf.height()-1))) + { + int stride = pixf.stride(); + m_rbuf->attach(pixf.pix_ptr(r.x1, stride < 0 ? r.y2 : r.y1), + (r.x2 - r.x1) + 1, + (r.y2 - r.y1) + 1, + stride); + return true; + } + return false; + } + + //-------------------------------------------------------------------- + Blender& blender() { return m_blender; } + + //-------------------------------------------------------------------- + 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) + sizeof(value_type) * (x * pix_step + pix_offset); + } + + AGG_INLINE const int8u* pix_ptr(int x, int y) const + { + return m_rbuf->row_ptr(y) + sizeof(value_type) * (x * pix_step + pix_offset); + } + + // Return pointer to pixel value, forcing row to be allocated. + AGG_INLINE pixel_type* pix_value_ptr(int x, int y, unsigned len) + { + return (pixel_type*)(m_rbuf->row_ptr(x, y, len) + sizeof(value_type) * (x * pix_step + pix_offset)); + } + + // Return pointer to pixel value, or null if row not allocated. + AGG_INLINE const pixel_type* pix_value_ptr(int x, int y) const + { + int8u* p = m_rbuf->row_ptr(y); + return p ? (pixel_type*)(p + sizeof(value_type) * (x * pix_step + pix_offset)) : 0; + } + + // Get pixel pointer from raw buffer pointer. + AGG_INLINE static pixel_type* pix_value_ptr(void* p) + { + return (pixel_type*)((value_type*)p + pix_offset); + } + + // Get pixel pointer from raw buffer pointer. + AGG_INLINE static const pixel_type* pix_value_ptr(const void* p) + { + return (const pixel_type*)((const value_type*)p + pix_offset); + } + + //-------------------------------------------------------------------- + AGG_INLINE static void write_plain_color(void* p, color_type c) + { + // RGB formats are implicitly premultiplied. + c.premultiply(); + pix_value_ptr(p)->set(c); + } + + //-------------------------------------------------------------------- + AGG_INLINE static color_type read_plain_color(const void* p) + { + return pix_value_ptr(p)->get(); + } + + //-------------------------------------------------------------------- + AGG_INLINE static void make_pix(int8u* p, const color_type& c) + { + ((pixel_type*)p)->set(c); + } + + //-------------------------------------------------------------------- + AGG_INLINE color_type pixel(int x, int y) const + { + if (const pixel_type* p = pix_value_ptr(x, y)) + { + return p->get(); + } + return color_type::no_color(); + } + + //-------------------------------------------------------------------- + AGG_INLINE void copy_pixel(int x, int y, const color_type& c) + { + pix_value_ptr(x, y, 1)->set(c); + } + + //-------------------------------------------------------------------- + AGG_INLINE void blend_pixel(int x, int y, const color_type& c, int8u cover) + { + copy_or_blend_pix(pix_value_ptr(x, y, 1), c, cover); + } + + //-------------------------------------------------------------------- + AGG_INLINE void copy_hline(int x, int y, + unsigned len, + const color_type& c) + { + pixel_type* p = pix_value_ptr(x, y, len); + do + { + p->set(c); + p = p->next(); + } + while(--len); + } + + + //-------------------------------------------------------------------- + AGG_INLINE void copy_vline(int x, int y, + unsigned len, + const color_type& c) + { + do + { + pix_value_ptr(x, y++, 1)->set(c); + } + while (--len); + } + + //-------------------------------------------------------------------- + void blend_hline(int x, int y, + unsigned len, + const color_type& c, + int8u cover) + { + if (!c.is_transparent()) + { + pixel_type* p = pix_value_ptr(x, y, len); + + if (c.is_opaque() && cover == cover_mask) + { + do + { + p->set(c); + p = p->next(); + } + while (--len); + } + else + { + do + { + blend_pix(p, c, cover); + p = p->next(); + } + while (--len); + } + } + } + + + //-------------------------------------------------------------------- + void blend_vline(int x, int y, + unsigned len, + const color_type& c, + int8u cover) + { + if (!c.is_transparent()) + { + if (c.is_opaque() && cover == cover_mask) + { + do + { + pix_value_ptr(x, y++, 1)->set(c); + } + while (--len); + } + else + { + do + { + blend_pix(pix_value_ptr(x, y++, 1), c, cover); + } + while (--len); + } + } + } + + //-------------------------------------------------------------------- + void blend_solid_hspan(int x, int y, + unsigned len, + const color_type& c, + const int8u* covers) + { + if (!c.is_transparent()) + { + pixel_type* p = pix_value_ptr(x, y, len); + + do + { + if (c.is_opaque() && *covers == cover_mask) + { + p->set(c); + } + else + { + blend_pix(p, c, *covers); + } + p = p->next(); + ++covers; + } + while (--len); + } + } + + + //-------------------------------------------------------------------- + void blend_solid_vspan(int x, int y, + unsigned len, + const color_type& c, + const int8u* covers) + { + if (!c.is_transparent()) + { + do + { + pixel_type* p = pix_value_ptr(x, y++, 1); + + if (c.is_opaque() && *covers == cover_mask) + { + p->set(c); + } + else + { + blend_pix(p, c, *covers); + } + ++covers; + } + while (--len); + } + } + + //-------------------------------------------------------------------- + void copy_color_hspan(int x, int y, + unsigned len, + const color_type* colors) + { + pixel_type* p = pix_value_ptr(x, y, len); + + do + { + p->set(*colors++); + p = p->next(); + } + while (--len); + } + + + //-------------------------------------------------------------------- + void copy_color_vspan(int x, int y, + unsigned len, + const color_type* colors) + { + do + { + pix_value_ptr(x, y++, 1)->set(*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 = pix_value_ptr(x, y, len); + + if (covers) + { + do + { + copy_or_blend_pix(p, *colors++, *covers++); + p = p->next(); + } + while (--len); + } + else + { + if (cover == cover_mask) + { + do + { + copy_or_blend_pix(p, *colors++); + p = p->next(); + } + while (--len); + } + else + { + do + { + copy_or_blend_pix(p, *colors++, cover); + p = p->next(); + } + while (--len); + } + } + } + + //-------------------------------------------------------------------- + void blend_color_vspan(int x, int y, + unsigned len, + const color_type* colors, + const int8u* covers, + int8u cover) + { + if (covers) + { + do + { + copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++, *covers++); + } + while (--len); + } + else + { + if (cover == cover_mask) + { + do + { + copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++); + } + while (--len); + } + else + { + do + { + copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++, cover); + } + while (--len); + } + } + } + + //-------------------------------------------------------------------- + template<class Function> void for_each_pixel(Function f) + { + for (unsigned y = 0; y < height(); ++y) + { + row_data r = m_rbuf->row(y); + if (r.ptr) + { + unsigned len = r.x2 - r.x1 + 1; + pixel_type* p = pix_value_ptr(r.x1, y, len); + do + { + f(p->c); + p = p->next(); + } + while (--len); + } + } + } + + //-------------------------------------------------------------------- + template<class GammaLut> void apply_gamma_dir(const GammaLut& g) + { + for_each_pixel(apply_gamma_dir_rgb<color_type, order_type, GammaLut>(g)); + } + + //-------------------------------------------------------------------- + template<class GammaLut> void apply_gamma_inv(const GammaLut& g) + { + for_each_pixel(apply_gamma_inv_rgb<color_type, order_type, GammaLut>(g)); + } + + //-------------------------------------------------------------------- + template<class RenBuf2> + void copy_from(const RenBuf2& from, + int xdst, int ydst, + int xsrc, int ysrc, + unsigned len) + { + if (const int8u* p = from.row_ptr(ysrc)) + { + memmove(m_rbuf->row_ptr(xdst, ydst, len) + xdst * pix_width, + p + xsrc * pix_width, + len * pix_width); + } + } + + //-------------------------------------------------------------------- + // Blend from an RGBA surface. + template<class SrcPixelFormatRenderer> + void blend_from(const SrcPixelFormatRenderer& from, + int xdst, int ydst, + int xsrc, int ysrc, + unsigned len, + int8u cover) + { + typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type; + typedef typename SrcPixelFormatRenderer::order_type src_order; + + if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc)) + { + pixel_type* pdst = pix_value_ptr(xdst, ydst, len); + + if (cover == cover_mask) + { + do + { + value_type alpha = psrc->c[src_order::A]; + if (alpha <= color_type::empty_value()) + { + if (alpha >= color_type::full_value()) + { + pdst->c[order_type::R] = psrc->c[src_order::R]; + pdst->c[order_type::G] = psrc->c[src_order::G]; + pdst->c[order_type::B] = psrc->c[src_order::B]; + } + else + { + blend_pix(pdst, + psrc->c[src_order::R], + psrc->c[src_order::G], + psrc->c[src_order::B], + alpha); + } + } + psrc = psrc->next(); + pdst = pdst->next(); + } + while(--len); + } + else + { + do + { + copy_or_blend_pix(pdst, psrc->get(), cover); + psrc = psrc->next(); + pdst = pdst->next(); + } + while (--len); + } + } + } + + //-------------------------------------------------------------------- + // Blend from single color, using grayscale surface as alpha channel. + 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::pixel_type src_pixel_type; + typedef typename SrcPixelFormatRenderer::color_type src_color_type; + + if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc)) + { + pixel_type* pdst = pix_value_ptr(xdst, ydst, len); + + do + { + copy_or_blend_pix(pdst, color, src_color_type::scale_cover(cover, psrc->c[0])); + psrc = psrc->next(); + pdst = pdst->next(); + } + while (--len); + } + } + + //-------------------------------------------------------------------- + // Blend from color table, using grayscale surface as indexes into table. + // Obviously, this only works for integer value types. + 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::pixel_type src_pixel_type; + + if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc)) + { + pixel_type* pdst = pix_value_ptr(xdst, ydst, len); + + if (cover == cover_mask) + { + do + { + const color_type& color = color_lut[psrc->c[0]]; + blend_pix(pdst, color); + psrc = psrc->next(); + pdst = pdst->next(); + } + while(--len); + } + else + { + do + { + copy_or_blend_pix(pdst, color_lut[psrc->c[0]], cover); + psrc = psrc->next(); + pdst = pdst->next(); + } + while(--len); + } + } + } + + private: + rbuf_type* m_rbuf; + Blender m_blender; + }; + + //----------------------------------------------------------------------- + typedef blender_rgb<rgba8, order_rgb> blender_rgb24; + typedef blender_rgb<rgba8, order_bgr> blender_bgr24; + typedef blender_rgb<srgba8, order_rgb> blender_srgb24; + typedef blender_rgb<srgba8, order_bgr> blender_sbgr24; + typedef blender_rgb<rgba16, order_rgb> blender_rgb48; + typedef blender_rgb<rgba16, order_bgr> blender_bgr48; + typedef blender_rgb<rgba32, order_rgb> blender_rgb96; + typedef blender_rgb<rgba32, order_bgr> blender_bgr96; + + typedef blender_rgb_pre<rgba8, order_rgb> blender_rgb24_pre; + typedef blender_rgb_pre<rgba8, order_bgr> blender_bgr24_pre; + typedef blender_rgb_pre<srgba8, order_rgb> blender_srgb24_pre; + typedef blender_rgb_pre<srgba8, order_bgr> blender_sbgr24_pre; + typedef blender_rgb_pre<rgba16, order_rgb> blender_rgb48_pre; + typedef blender_rgb_pre<rgba16, order_bgr> blender_bgr48_pre; + typedef blender_rgb_pre<rgba32, order_rgb> blender_rgb96_pre; + typedef blender_rgb_pre<rgba32, order_bgr> blender_bgr96_pre; + + typedef pixfmt_alpha_blend_rgb<blender_rgb24, rendering_buffer, 3> pixfmt_rgb24; + typedef pixfmt_alpha_blend_rgb<blender_bgr24, rendering_buffer, 3> pixfmt_bgr24; + typedef pixfmt_alpha_blend_rgb<blender_srgb24, rendering_buffer, 3> pixfmt_srgb24; + typedef pixfmt_alpha_blend_rgb<blender_sbgr24, rendering_buffer, 3> pixfmt_sbgr24; + typedef pixfmt_alpha_blend_rgb<blender_rgb48, rendering_buffer, 3> pixfmt_rgb48; + typedef pixfmt_alpha_blend_rgb<blender_bgr48, rendering_buffer, 3> pixfmt_bgr48; + typedef pixfmt_alpha_blend_rgb<blender_rgb96, rendering_buffer, 3> pixfmt_rgb96; + typedef pixfmt_alpha_blend_rgb<blender_bgr96, rendering_buffer, 3> pixfmt_bgr96; + + typedef pixfmt_alpha_blend_rgb<blender_rgb24_pre, rendering_buffer, 3> pixfmt_rgb24_pre; + typedef pixfmt_alpha_blend_rgb<blender_bgr24_pre, rendering_buffer, 3> pixfmt_bgr24_pre; + typedef pixfmt_alpha_blend_rgb<blender_srgb24_pre, rendering_buffer, 3> pixfmt_srgb24_pre; + typedef pixfmt_alpha_blend_rgb<blender_sbgr24_pre, rendering_buffer, 3> pixfmt_sbgr24_pre; + typedef pixfmt_alpha_blend_rgb<blender_rgb48_pre, rendering_buffer, 3> pixfmt_rgb48_pre; + typedef pixfmt_alpha_blend_rgb<blender_bgr48_pre, rendering_buffer, 3> pixfmt_bgr48_pre; + typedef pixfmt_alpha_blend_rgb<blender_rgb96_pre, rendering_buffer, 3> pixfmt_rgb96_pre; + typedef pixfmt_alpha_blend_rgb<blender_bgr96_pre, rendering_buffer, 3> pixfmt_bgr96_pre; + + typedef pixfmt_alpha_blend_rgb<blender_rgb24, rendering_buffer, 4, 0> pixfmt_rgbx32; + typedef pixfmt_alpha_blend_rgb<blender_rgb24, rendering_buffer, 4, 1> pixfmt_xrgb32; + typedef pixfmt_alpha_blend_rgb<blender_bgr24, rendering_buffer, 4, 1> pixfmt_xbgr32; + typedef pixfmt_alpha_blend_rgb<blender_bgr24, rendering_buffer, 4, 0> pixfmt_bgrx32; + typedef pixfmt_alpha_blend_rgb<blender_srgb24, rendering_buffer, 4, 0> pixfmt_srgbx32; + typedef pixfmt_alpha_blend_rgb<blender_srgb24, rendering_buffer, 4, 1> pixfmt_sxrgb32; + typedef pixfmt_alpha_blend_rgb<blender_sbgr24, rendering_buffer, 4, 1> pixfmt_sxbgr32; + typedef pixfmt_alpha_blend_rgb<blender_sbgr24, rendering_buffer, 4, 0> pixfmt_sbgrx32; + typedef pixfmt_alpha_blend_rgb<blender_rgb48, rendering_buffer, 4, 0> pixfmt_rgbx64; + typedef pixfmt_alpha_blend_rgb<blender_rgb48, rendering_buffer, 4, 1> pixfmt_xrgb64; + typedef pixfmt_alpha_blend_rgb<blender_bgr48, rendering_buffer, 4, 1> pixfmt_xbgr64; + typedef pixfmt_alpha_blend_rgb<blender_bgr48, rendering_buffer, 4, 0> pixfmt_bgrx64; + typedef pixfmt_alpha_blend_rgb<blender_rgb96, rendering_buffer, 4, 0> pixfmt_rgbx128; + typedef pixfmt_alpha_blend_rgb<blender_rgb96, rendering_buffer, 4, 1> pixfmt_xrgb128; + typedef pixfmt_alpha_blend_rgb<blender_bgr96, rendering_buffer, 4, 1> pixfmt_xbgr128; + typedef pixfmt_alpha_blend_rgb<blender_bgr96, rendering_buffer, 4, 0> pixfmt_bgrx128; + + typedef pixfmt_alpha_blend_rgb<blender_rgb24_pre, rendering_buffer, 4, 0> pixfmt_rgbx32_pre; + typedef pixfmt_alpha_blend_rgb<blender_rgb24_pre, rendering_buffer, 4, 1> pixfmt_xrgb32_pre; + typedef pixfmt_alpha_blend_rgb<blender_bgr24_pre, rendering_buffer, 4, 1> pixfmt_xbgr32_pre; + typedef pixfmt_alpha_blend_rgb<blender_bgr24_pre, rendering_buffer, 4, 0> pixfmt_bgrx32_pre; + typedef pixfmt_alpha_blend_rgb<blender_srgb24_pre, rendering_buffer, 4, 0> pixfmt_srgbx32_pre; + typedef pixfmt_alpha_blend_rgb<blender_srgb24_pre, rendering_buffer, 4, 1> pixfmt_sxrgb32_pre; + typedef pixfmt_alpha_blend_rgb<blender_sbgr24_pre, rendering_buffer, 4, 1> pixfmt_sxbgr32_pre; + typedef pixfmt_alpha_blend_rgb<blender_sbgr24_pre, rendering_buffer, 4, 0> pixfmt_sbgrx32_pre; + typedef pixfmt_alpha_blend_rgb<blender_rgb48_pre, rendering_buffer, 4, 0> pixfmt_rgbx64_pre; + typedef pixfmt_alpha_blend_rgb<blender_rgb48_pre, rendering_buffer, 4, 1> pixfmt_xrgb64_pre; + typedef pixfmt_alpha_blend_rgb<blender_bgr48_pre, rendering_buffer, 4, 1> pixfmt_xbgr64_pre; + typedef pixfmt_alpha_blend_rgb<blender_bgr48_pre, rendering_buffer, 4, 0> pixfmt_bgrx64_pre; + typedef pixfmt_alpha_blend_rgb<blender_rgb96_pre, rendering_buffer, 4, 0> pixfmt_rgbx128_pre; + typedef pixfmt_alpha_blend_rgb<blender_rgb96_pre, rendering_buffer, 4, 1> pixfmt_xrgb128_pre; + typedef pixfmt_alpha_blend_rgb<blender_bgr96_pre, rendering_buffer, 4, 1> pixfmt_xbgr128_pre; + typedef pixfmt_alpha_blend_rgb<blender_bgr96_pre, rendering_buffer, 4, 0> pixfmt_bgrx128_pre; + + + //-----------------------------------------------------pixfmt_rgb24_gamma + template<class Gamma> class pixfmt_rgb24_gamma : + public pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba8, order_rgb, Gamma>, rendering_buffer, 3> + { + public: + pixfmt_rgb24_gamma(rendering_buffer& rb, const Gamma& g) : + pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba8, order_rgb, Gamma>, rendering_buffer, 3>(rb) + { + this->blender().gamma(g); + } + }; + + //-----------------------------------------------------pixfmt_srgb24_gamma + template<class Gamma> class pixfmt_srgb24_gamma : + public pixfmt_alpha_blend_rgb<blender_rgb_gamma<srgba8, order_rgb, Gamma>, rendering_buffer, 3> + { + public: + pixfmt_srgb24_gamma(rendering_buffer& rb, const Gamma& g) : + pixfmt_alpha_blend_rgb<blender_rgb_gamma<srgba8, order_rgb, Gamma>, rendering_buffer, 3>(rb) + { + this->blender().gamma(g); + } + }; + + //-----------------------------------------------------pixfmt_bgr24_gamma + template<class Gamma> class pixfmt_bgr24_gamma : + public pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba8, order_bgr, Gamma>, rendering_buffer, 3> + { + public: + pixfmt_bgr24_gamma(rendering_buffer& rb, const Gamma& g) : + pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba8, order_bgr, Gamma>, rendering_buffer, 3>(rb) + { + this->blender().gamma(g); + } + }; + + //-----------------------------------------------------pixfmt_sbgr24_gamma + template<class Gamma> class pixfmt_sbgr24_gamma : + public pixfmt_alpha_blend_rgb<blender_rgb_gamma<srgba8, order_bgr, Gamma>, rendering_buffer, 3> + { + public: + pixfmt_sbgr24_gamma(rendering_buffer& rb, const Gamma& g) : + pixfmt_alpha_blend_rgb<blender_rgb_gamma<srgba8, order_bgr, Gamma>, rendering_buffer, 3>(rb) + { + this->blender().gamma(g); + } + }; + + //-----------------------------------------------------pixfmt_rgb48_gamma + template<class Gamma> class pixfmt_rgb48_gamma : + public pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba16, order_rgb, Gamma>, rendering_buffer, 3> + { + public: + pixfmt_rgb48_gamma(rendering_buffer& rb, const Gamma& g) : + pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba16, order_rgb, Gamma>, rendering_buffer, 3>(rb) + { + this->blender().gamma(g); + } + }; + + //-----------------------------------------------------pixfmt_bgr48_gamma + template<class Gamma> class pixfmt_bgr48_gamma : + public pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba16, order_bgr, Gamma>, rendering_buffer, 3> + { + public: + pixfmt_bgr48_gamma(rendering_buffer& rb, const Gamma& g) : + pixfmt_alpha_blend_rgb<blender_rgb_gamma<rgba16, order_bgr, Gamma>, rendering_buffer, 3>(rb) + { + this->blender().gamma(g); + } + }; + +} + +#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 00000000000..d879517de6e --- /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_rgba.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pixfmt_rgba.h new file mode 100644 index 00000000000..e9cd523b375 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_pixfmt_rgba.h @@ -0,0 +1,2801 @@ +//---------------------------------------------------------------------------- +// 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_RGBA_INCLUDED +#define AGG_PIXFMT_RGBA_INCLUDED + +#include <string.h> +#include <math.h> +#include "agg_pixfmt_base.h" +#include "agg_rendering_buffer.h" + +namespace agg +{ + template<class T> inline T sd_min(T a, T b) { return (a < b) ? a : b; } + template<class T> inline T sd_max(T a, T b) { return (a > b) ? a : b; } + + inline rgba & clip(rgba & c) + { + if (c.a > 1) c.a = 1; else if (c.a < 0) c.a = 0; + if (c.r > c.a) c.r = c.a; else if (c.r < 0) c.r = 0; + if (c.g > c.a) c.g = c.a; else if (c.g < 0) c.g = 0; + if (c.b > c.a) c.b = c.a; else if (c.b < 0) c.b = 0; + return c; + } + + //=========================================================multiplier_rgba + template<class ColorT, class Order> + struct multiplier_rgba + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + + //-------------------------------------------------------------------- + static AGG_INLINE void premultiply(value_type* p) + { + value_type a = p[Order::A]; + p[Order::R] = color_type::multiply(p[Order::R], a); + p[Order::G] = color_type::multiply(p[Order::G], a); + p[Order::B] = color_type::multiply(p[Order::B], a); + } + + + //-------------------------------------------------------------------- + static AGG_INLINE void demultiply(value_type* p) + { + value_type a = p[Order::A]; + p[Order::R] = color_type::demultiply(p[Order::R], a); + p[Order::G] = color_type::demultiply(p[Order::G], a); + p[Order::B] = color_type::demultiply(p[Order::B], a); + } + }; + + //=====================================================apply_gamma_dir_rgba + template<class ColorT, class Order, class GammaLut> + class apply_gamma_dir_rgba + { + public: + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + + apply_gamma_dir_rgba(const GammaLut& gamma) : m_gamma(gamma) {} + + AGG_INLINE void operator () (value_type* p) + { + p[Order::R] = m_gamma.dir(p[Order::R]); + p[Order::G] = m_gamma.dir(p[Order::G]); + p[Order::B] = m_gamma.dir(p[Order::B]); + } + + private: + const GammaLut& m_gamma; + }; + + //=====================================================apply_gamma_inv_rgba + template<class ColorT, class Order, class GammaLut> class apply_gamma_inv_rgba + { + public: + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + + apply_gamma_inv_rgba(const GammaLut& gamma) : m_gamma(gamma) {} + + AGG_INLINE void operator () (value_type* p) + { + p[Order::R] = m_gamma.inv(p[Order::R]); + p[Order::G] = m_gamma.inv(p[Order::G]); + p[Order::B] = m_gamma.inv(p[Order::B]); + } + + private: + const GammaLut& m_gamma; + }; + + + template<class ColorT, class Order> + struct conv_rgba_pre + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + + //-------------------------------------------------------------------- + static AGG_INLINE void set_plain_color(value_type* p, color_type c) + { + c.premultiply(); + p[Order::R] = c.r; + p[Order::G] = c.g; + p[Order::B] = c.b; + p[Order::A] = c.a; + } + + //-------------------------------------------------------------------- + static AGG_INLINE color_type get_plain_color(const value_type* p) + { + return color_type( + p[Order::R], + p[Order::G], + p[Order::B], + p[Order::A]).demultiply(); + } + }; + + template<class ColorT, class Order> + struct conv_rgba_plain + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + + //-------------------------------------------------------------------- + static AGG_INLINE void set_plain_color(value_type* p, color_type c) + { + p[Order::R] = c.r; + p[Order::G] = c.g; + p[Order::B] = c.b; + p[Order::A] = c.a; + } + + //-------------------------------------------------------------------- + static AGG_INLINE color_type get_plain_color(const value_type* p) + { + return color_type( + p[Order::R], + p[Order::G], + p[Order::B], + p[Order::A]); + } + }; + + //=============================================================blender_rgba + // Blends "plain" (i.e. non-premultiplied) colors into a premultiplied buffer. + template<class ColorT, class Order> + struct blender_rgba : conv_rgba_pre<ColorT, Order> + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + // Blend pixels using the non-premultiplied form of Alvy-Ray Smith's + // compositing function. Since the render buffer is in fact premultiplied + // we omit the initial premultiplication and final demultiplication. + + //-------------------------------------------------------------------- + static AGG_INLINE void blend_pix(value_type* p, + value_type cr, value_type cg, value_type cb, value_type alpha, cover_type cover) + { + blend_pix(p, cr, cg, cb, color_type::mult_cover(alpha, cover)); + } + + //-------------------------------------------------------------------- + static AGG_INLINE void blend_pix(value_type* p, + value_type cr, value_type cg, value_type cb, value_type alpha) + { + p[Order::R] = color_type::lerp(p[Order::R], cr, alpha); + p[Order::G] = color_type::lerp(p[Order::G], cg, alpha); + p[Order::B] = color_type::lerp(p[Order::B], cb, alpha); + p[Order::A] = color_type::prelerp(p[Order::A], alpha, alpha); + } + }; + + + //========================================================blender_rgba_pre + // Blends premultiplied colors into a premultiplied buffer. + template<class ColorT, class Order> + struct blender_rgba_pre : conv_rgba_pre<ColorT, Order> + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + // Blend pixels using the premultiplied form of Alvy-Ray Smith's + // compositing function. + + //-------------------------------------------------------------------- + static AGG_INLINE void blend_pix(value_type* p, + value_type cr, value_type cg, value_type cb, value_type alpha, cover_type cover) + { + blend_pix(p, + color_type::mult_cover(cr, cover), + color_type::mult_cover(cg, cover), + color_type::mult_cover(cb, cover), + color_type::mult_cover(alpha, cover)); + } + + //-------------------------------------------------------------------- + static AGG_INLINE void blend_pix(value_type* p, + value_type cr, value_type cg, value_type cb, value_type alpha) + { + p[Order::R] = color_type::prelerp(p[Order::R], cr, alpha); + p[Order::G] = color_type::prelerp(p[Order::G], cg, alpha); + p[Order::B] = color_type::prelerp(p[Order::B], cb, alpha); + p[Order::A] = color_type::prelerp(p[Order::A], alpha, alpha); + } + }; + + //======================================================blender_rgba_plain + // Blends "plain" (non-premultiplied) colors into a plain (non-premultiplied) buffer. + template<class ColorT, class Order> + struct blender_rgba_plain : conv_rgba_plain<ColorT, Order> + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + // Blend pixels using the non-premultiplied form of Alvy-Ray Smith's + // compositing function. + + //-------------------------------------------------------------------- + static AGG_INLINE void blend_pix(value_type* p, + value_type cr, value_type cg, value_type cb, value_type alpha, cover_type cover) + { + blend_pix(p, cr, cg, cb, color_type::mult_cover(alpha, cover)); + } + + //-------------------------------------------------------------------- + static AGG_INLINE void blend_pix(value_type* p, + value_type cr, value_type cg, value_type cb, value_type alpha) + { + if (alpha > color_type::empty_value()) + { + calc_type a = p[Order::A]; + calc_type r = color_type::multiply(p[Order::R], a); + calc_type g = color_type::multiply(p[Order::G], a); + calc_type b = color_type::multiply(p[Order::B], a); + p[Order::R] = color_type::lerp(r, cr, alpha); + p[Order::G] = color_type::lerp(g, cg, alpha); + p[Order::B] = color_type::lerp(b, cb, alpha); + p[Order::A] = color_type::prelerp(a, alpha, alpha); + multiplier_rgba<ColorT, Order>::demultiply(p); + } + } + }; + + // SVG compositing operations. + // For specifications, see http://www.w3.org/TR/SVGCompositing/ + + //=========================================================comp_op_rgba_clear + template<class ColorT, class Order> + struct comp_op_rgba_clear : blender_base<ColorT, Order> + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + using blender_base<ColorT, Order>::get; + using blender_base<ColorT, Order>::set; + + // Dca' = 0 + // Da' = 0 + static AGG_INLINE void blend_pix(value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + if (cover >= cover_full) + { + p[0] = p[1] = p[2] = p[3] = color_type::empty_value(); + } + else if (cover > cover_none) + { + set(p, get(p, cover_full - cover)); + } + } + }; + + //===========================================================comp_op_rgba_src + template<class ColorT, class Order> + struct comp_op_rgba_src : blender_base<ColorT, Order> + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + using blender_base<ColorT, Order>::get; + using blender_base<ColorT, Order>::set; + + // Dca' = Sca + // Da' = Sa + static AGG_INLINE void blend_pix(value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + if (cover >= cover_full) + { + set(p, r, g, b, a); + } + else + { + rgba s = get(r, g, b, a, cover); + rgba d = get(p, cover_full - cover); + d.r += s.r; + d.g += s.g; + d.b += s.b; + d.a += s.a; + set(p, d); + } + } + }; + + //===========================================================comp_op_rgba_dst + template<class ColorT, class Order> + struct comp_op_rgba_dst : blender_base<ColorT, Order> + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + + // Dca' = Dca.Sa + Dca.(1 - Sa) = Dca + // Da' = Da.Sa + Da.(1 - Sa) = Da + static AGG_INLINE void blend_pix(value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + // Well, that was easy! + } + }; + + //======================================================comp_op_rgba_src_over + template<class ColorT, class Order> + struct comp_op_rgba_src_over : blender_base<ColorT, Order> + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + using blender_base<ColorT, Order>::get; + using blender_base<ColorT, Order>::set; + + // Dca' = Sca + Dca.(1 - Sa) = Dca + Sca - Dca.Sa + // Da' = Sa + Da - Sa.Da + static AGG_INLINE void blend_pix(value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { +#if 1 + blender_rgba_pre<ColorT, Order>::blend_pix(p, r, g, b, a, cover); +#else + rgba s = get(r, g, b, a, cover); + rgba d = get(p); + d.r += s.r - d.r * s.a; + d.g += s.g - d.g * s.a; + d.b += s.b - d.b * s.a; + d.a += s.a - d.a * s.a; + set(p, d); +#endif + } + }; + + //======================================================comp_op_rgba_dst_over + template<class ColorT, class Order> + struct comp_op_rgba_dst_over : blender_base<ColorT, Order> + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + using blender_base<ColorT, Order>::get; + using blender_base<ColorT, Order>::set; + + // Dca' = Dca + Sca.(1 - Da) + // Da' = Sa + Da - Sa.Da = Da + Sa.(1 - Da) + static AGG_INLINE void blend_pix(value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + rgba s = get(r, g, b, a, cover); + rgba d = get(p); + double d1a = 1 - d.a; + d.r += s.r * d1a; + d.g += s.g * d1a; + d.b += s.b * d1a; + d.a += s.a * d1a; + set(p, d); + } + }; + + //======================================================comp_op_rgba_src_in + template<class ColorT, class Order> + struct comp_op_rgba_src_in : blender_base<ColorT, Order> + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + using blender_base<ColorT, Order>::get; + using blender_base<ColorT, Order>::set; + + // Dca' = Sca.Da + // Da' = Sa.Da + static AGG_INLINE void blend_pix(value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + double da = ColorT::to_double(p[Order::A]); + if (da > 0) + { + rgba s = get(r, g, b, a, cover); + rgba d = get(p, cover_full - cover); + d.r += s.r * da; + d.g += s.g * da; + d.b += s.b * da; + d.a += s.a * da; + set(p, d); + } + } + }; + + //======================================================comp_op_rgba_dst_in + template<class ColorT, class Order> + struct comp_op_rgba_dst_in : blender_base<ColorT, Order> + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + using blender_base<ColorT, Order>::get; + using blender_base<ColorT, Order>::set; + + // Dca' = Dca.Sa + // Da' = Sa.Da + static AGG_INLINE void blend_pix(value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + double sa = ColorT::to_double(a); + rgba d = get(p, cover_full - cover); + rgba d2 = get(p, cover); + d.r += d2.r * sa; + d.g += d2.g * sa; + d.b += d2.b * sa; + d.a += d2.a * sa; + set(p, d); + } + }; + + //======================================================comp_op_rgba_src_out + template<class ColorT, class Order> + struct comp_op_rgba_src_out : blender_base<ColorT, Order> + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + using blender_base<ColorT, Order>::get; + using blender_base<ColorT, Order>::set; + + // Dca' = Sca.(1 - Da) + // Da' = Sa.(1 - Da) + static AGG_INLINE void blend_pix(value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + rgba s = get(r, g, b, a, cover); + rgba d = get(p, cover_full - cover); + double d1a = 1 - ColorT::to_double(p[Order::A]); + d.r += s.r * d1a; + d.g += s.g * d1a; + d.b += s.b * d1a; + d.a += s.a * d1a; + set(p, d); + } + }; + + //======================================================comp_op_rgba_dst_out + template<class ColorT, class Order> + struct comp_op_rgba_dst_out : blender_base<ColorT, Order> + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + using blender_base<ColorT, Order>::get; + using blender_base<ColorT, Order>::set; + + // Dca' = Dca.(1 - Sa) + // Da' = Da.(1 - Sa) + static AGG_INLINE void blend_pix(value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + rgba d = get(p, cover_full - cover); + rgba dc = get(p, cover); + double s1a = 1 - ColorT::to_double(a); + d.r += dc.r * s1a; + d.g += dc.g * s1a; + d.b += dc.b * s1a; + d.a += dc.a * s1a; + set(p, d); + } + }; + + //=====================================================comp_op_rgba_src_atop + template<class ColorT, class Order> + struct comp_op_rgba_src_atop : blender_base<ColorT, Order> + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + using blender_base<ColorT, Order>::get; + using blender_base<ColorT, Order>::set; + + // Dca' = Sca.Da + Dca.(1 - Sa) + // Da' = Da + static AGG_INLINE void blend_pix(value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + rgba s = get(r, g, b, a, cover); + rgba d = get(p); + double s1a = 1 - s.a; + d.r = s.r * d.a + d.r * s1a; + d.g = s.g * d.a + d.g * s1a; + d.b = s.b * d.a + d.g * s1a; + set(p, d); + } + }; + + //=====================================================comp_op_rgba_dst_atop + template<class ColorT, class Order> + struct comp_op_rgba_dst_atop : blender_base<ColorT, Order> + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + using blender_base<ColorT, Order>::get; + using blender_base<ColorT, Order>::set; + + // Dca' = Dca.Sa + Sca.(1 - Da) + // Da' = Sa + static AGG_INLINE void blend_pix(value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + rgba sc = get(r, g, b, a, cover); + rgba dc = get(p, cover); + rgba d = get(p, cover_full - cover); + double sa = ColorT::to_double(a); + double d1a = 1 - ColorT::to_double(p[Order::A]); + d.r += dc.r * sa + sc.r * d1a; + d.g += dc.g * sa + sc.g * d1a; + d.b += dc.b * sa + sc.b * d1a; + d.a += sc.a; + set(p, d); + } + }; + + //=========================================================comp_op_rgba_xor + template<class ColorT, class Order> + struct comp_op_rgba_xor : blender_base<ColorT, Order> + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + using blender_base<ColorT, Order>::get; + using blender_base<ColorT, Order>::set; + + // Dca' = Sca.(1 - Da) + Dca.(1 - Sa) + // Da' = Sa + Da - 2.Sa.Da + static AGG_INLINE void blend_pix(value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + rgba s = get(r, g, b, a, cover); + rgba d = get(p); + double s1a = 1 - s.a; + double d1a = 1 - ColorT::to_double(p[Order::A]); + d.r = s.r * d1a + d.r * s1a; + d.g = s.g * d1a + d.g * s1a; + d.b = s.b * d1a + d.b * s1a; + d.a = s.a + d.a - 2 * s.a * d.a; + set(p, d); + } + }; + + //=========================================================comp_op_rgba_plus + template<class ColorT, class Order> + struct comp_op_rgba_plus : blender_base<ColorT, Order> + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + using blender_base<ColorT, Order>::get; + using blender_base<ColorT, Order>::set; + + // Dca' = Sca + Dca + // Da' = Sa + Da + static AGG_INLINE void blend_pix(value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + rgba s = get(r, g, b, a, cover); + if (s.a > 0) + { + rgba d = get(p); + d.a = sd_min(d.a + s.a, 1.0); + d.r = sd_min(d.r + s.r, d.a); + d.g = sd_min(d.g + s.g, d.a); + d.b = sd_min(d.b + s.b, d.a); + set(p, clip(d)); + } + } + }; + + //========================================================comp_op_rgba_minus + // Note: not included in SVG spec. + template<class ColorT, class Order> + struct comp_op_rgba_minus : blender_base<ColorT, Order> + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + using blender_base<ColorT, Order>::get; + using blender_base<ColorT, Order>::set; + + // Dca' = Dca - Sca + // Da' = 1 - (1 - Sa).(1 - Da) = Da + Sa - Sa.Da + static AGG_INLINE void blend_pix(value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + rgba s = get(r, g, b, a, cover); + if (s.a > 0) + { + rgba d = get(p); + d.a += s.a - s.a * d.a; + d.r = sd_max(d.r - s.r, 0.0); + d.g = sd_max(d.g - s.g, 0.0); + d.b = sd_max(d.b - s.b, 0.0); + set(p, clip(d)); + } + } + }; + + //=====================================================comp_op_rgba_multiply + template<class ColorT, class Order> + struct comp_op_rgba_multiply : blender_base<ColorT, Order> + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + using blender_base<ColorT, Order>::get; + using blender_base<ColorT, Order>::set; + + // Dca' = Sca.Dca + Sca.(1 - Da) + Dca.(1 - Sa) + // Da' = Sa + Da - Sa.Da + static AGG_INLINE void blend_pix(value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + rgba s = get(r, g, b, a, cover); + if (s.a > 0) + { + rgba d = get(p); + double s1a = 1 - s.a; + double d1a = 1 - d.a; + d.r = s.r * d.r + s.r * d1a + d.r * s1a; + d.g = s.g * d.g + s.g * d1a + d.g * s1a; + d.b = s.b * d.b + s.b * d1a + d.b * s1a; + d.a += s.a - s.a * d.a; + set(p, clip(d)); + } + } + }; + + //=====================================================comp_op_rgba_screen + template<class ColorT, class Order> + struct comp_op_rgba_screen : blender_base<ColorT, Order> + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + using blender_base<ColorT, Order>::get; + using blender_base<ColorT, Order>::set; + + // Dca' = Sca + Dca - Sca.Dca + // Da' = Sa + Da - Sa.Da + static AGG_INLINE void blend_pix(value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + rgba s = get(r, g, b, a, cover); + if (s.a > 0) + { + rgba d = get(p); + d.r += s.r - s.r * d.r; + d.g += s.g - s.g * d.g; + d.b += s.b - s.b * d.b; + d.a += s.a - s.a * d.a; + set(p, clip(d)); + } + } + }; + + //=====================================================comp_op_rgba_overlay + template<class ColorT, class Order> + struct comp_op_rgba_overlay : blender_base<ColorT, Order> + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + using blender_base<ColorT, Order>::get; + using blender_base<ColorT, Order>::set; + + // if 2.Dca <= Da + // Dca' = 2.Sca.Dca + Sca.(1 - Da) + Dca.(1 - Sa) + // otherwise + // Dca' = Sa.Da - 2.(Da - Dca).(Sa - Sca) + Sca.(1 - Da) + Dca.(1 - Sa) + // + // Da' = Sa + Da - Sa.Da + static AGG_INLINE double calc(double dca, double sca, double da, double sa, double sada, double d1a, double s1a) + { + return (2 * dca <= da) ? + 2 * sca * dca + sca * d1a + dca * s1a : + sada - 2 * (da - dca) * (sa - sca) + sca * d1a + dca * s1a; + } + + static AGG_INLINE void blend_pix(value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + rgba s = get(r, g, b, a, cover); + if (s.a > 0) + { + rgba d = get(p); + double d1a = 1 - d.a; + double s1a = 1 - s.a; + double sada = s.a * d.a; + d.r = calc(d.r, s.r, d.a, s.a, sada, d1a, s1a); + d.g = calc(d.g, s.g, d.a, s.a, sada, d1a, s1a); + d.b = calc(d.b, s.b, d.a, s.a, sada, d1a, s1a); + d.a += s.a - s.a * d.a; + set(p, clip(d)); + } + } + }; + + //=====================================================comp_op_rgba_darken + template<class ColorT, class Order> + struct comp_op_rgba_darken : blender_base<ColorT, Order> + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + using blender_base<ColorT, Order>::get; + using blender_base<ColorT, Order>::set; + + // Dca' = min(Sca.Da, Dca.Sa) + Sca.(1 - Da) + Dca.(1 - Sa) + // Da' = Sa + Da - Sa.Da + static AGG_INLINE void blend_pix(value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + rgba s = get(r, g, b, a, cover); + if (s.a > 0) + { + rgba d = get(p); + double d1a = 1 - d.a; + double s1a = 1 - s.a; + d.r = sd_min(s.r * d.a, d.r * s.a) + s.r * d1a + d.r * s1a; + d.g = sd_min(s.g * d.a, d.g * s.a) + s.g * d1a + d.g * s1a; + d.b = sd_min(s.b * d.a, d.b * s.a) + s.b * d1a + d.b * s1a; + d.a += s.a - s.a * d.a; + set(p, clip(d)); + } + } + }; + + //=====================================================comp_op_rgba_lighten + template<class ColorT, class Order> + struct comp_op_rgba_lighten : blender_base<ColorT, Order> + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + using blender_base<ColorT, Order>::get; + using blender_base<ColorT, Order>::set; + + // Dca' = max(Sca.Da, Dca.Sa) + Sca.(1 - Da) + Dca.(1 - Sa) + // Da' = Sa + Da - Sa.Da + static AGG_INLINE void blend_pix(value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + rgba s = get(r, g, b, a, cover); + if (s.a > 0) + { + rgba d = get(p); + double d1a = 1 - d.a; + double s1a = 1 - s.a; + d.r = sd_max(s.r * d.a, d.r * s.a) + s.r * d1a + d.r * s1a; + d.g = sd_max(s.g * d.a, d.g * s.a) + s.g * d1a + d.g * s1a; + d.b = sd_max(s.b * d.a, d.b * s.a) + s.b * d1a + d.b * s1a; + d.a += s.a - s.a * d.a; + set(p, clip(d)); + } + } + }; + + //=====================================================comp_op_rgba_color_dodge + template<class ColorT, class Order> + struct comp_op_rgba_color_dodge : blender_base<ColorT, Order> + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + using blender_base<ColorT, Order>::get; + using blender_base<ColorT, Order>::set; + + // if Sca == Sa and Dca == 0 + // Dca' = Sca.(1 - Da) + Dca.(1 - Sa) = Sca.(1 - Da) + // otherwise if Sca == Sa + // Dca' = Sa.Da + Sca.(1 - Da) + Dca.(1 - Sa) + // otherwise if Sca < Sa + // Dca' = Sa.Da.min(1, Dca/Da.Sa/(Sa - Sca)) + Sca.(1 - Da) + Dca.(1 - Sa) + // + // Da' = Sa + Da - Sa.Da + static AGG_INLINE double calc(double dca, double sca, double da, double sa, double sada, double d1a, double s1a) + { + if (sca < sa) return sada * sd_min(1.0, (dca / da) * sa / (sa - sca)) + sca * d1a + dca * s1a; + if (dca > 0) return sada + sca * d1a + dca * s1a; + return sca * d1a; + } + + static AGG_INLINE void blend_pix(value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + rgba s = get(r, g, b, a, cover); + if (s.a > 0) + { + rgba d = get(p); + if (d.a > 0) + { + double sada = s.a * d.a; + double s1a = 1 - s.a; + double d1a = 1 - d.a; + d.r = calc(d.r, s.r, d.a, s.a, sada, d1a, s1a); + d.g = calc(d.g, s.g, d.a, s.a, sada, d1a, s1a); + d.b = calc(d.b, s.b, d.a, s.a, sada, d1a, s1a); + d.a += s.a - s.a * d.a; + set(p, clip(d)); + } + else set(p, s); + } + } + }; + + //=====================================================comp_op_rgba_color_burn + template<class ColorT, class Order> + struct comp_op_rgba_color_burn : blender_base<ColorT, Order> + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + using blender_base<ColorT, Order>::get; + using blender_base<ColorT, Order>::set; + + // if Sca == 0 and Dca == Da + // Dca' = Sa.Da + Dca.(1 - Sa) + // otherwise if Sca == 0 + // Dca' = Dca.(1 - Sa) + // otherwise if Sca > 0 + // Dca' = Sa.Da.(1 - min(1, (1 - Dca/Da).Sa/Sca)) + Sca.(1 - Da) + Dca.(1 - Sa) + static AGG_INLINE double calc(double dca, double sca, double da, double sa, double sada, double d1a, double s1a) + { + if (sca > 0) return sada * (1 - sd_min(1.0, (1 - dca / da) * sa / sca)) + sca * d1a + dca * s1a; + if (dca > da) return sada + dca * s1a; + return dca * s1a; + } + + static AGG_INLINE void blend_pix(value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + rgba s = get(r, g, b, a, cover); + if (s.a > 0) + { + rgba d = get(p); + if (d.a > 0) + { + double sada = s.a * d.a; + double s1a = 1 - s.a; + double d1a = 1 - d.a; + d.r = calc(d.r, s.r, d.a, s.a, sada, d1a, s1a); + d.g = calc(d.g, s.g, d.a, s.a, sada, d1a, s1a); + d.b = calc(d.b, s.b, d.a, s.a, sada, d1a, s1a); + d.a += s.a - sada; + set(p, clip(d)); + } + else set(p, s); + } + } + }; + + //=====================================================comp_op_rgba_hard_light + template<class ColorT, class Order> + struct comp_op_rgba_hard_light : blender_base<ColorT, Order> + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + using blender_base<ColorT, Order>::get; + using blender_base<ColorT, Order>::set; + + // if 2.Sca < Sa + // Dca' = 2.Sca.Dca + Sca.(1 - Da) + Dca.(1 - Sa) + // otherwise + // Dca' = Sa.Da - 2.(Da - Dca).(Sa - Sca) + Sca.(1 - Da) + Dca.(1 - Sa) + // + // Da' = Sa + Da - Sa.Da + static AGG_INLINE double calc(double dca, double sca, double da, double sa, double sada, double d1a, double s1a) + { + return (2 * sca < sa) ? + 2 * sca * dca + sca * d1a + dca * s1a : + sada - 2 * (da - dca) * (sa - sca) + sca * d1a + dca * s1a; + } + + static AGG_INLINE void blend_pix(value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + rgba s = get(r, g, b, a, cover); + if (s.a > 0) + { + rgba d = get(p); + double d1a = 1 - d.a; + double s1a = 1 - s.a; + double sada = s.a * d.a; + d.r = calc(d.r, s.r, d.a, s.a, sada, d1a, s1a); + d.g = calc(d.g, s.g, d.a, s.a, sada, d1a, s1a); + d.b = calc(d.b, s.b, d.a, s.a, sada, d1a, s1a); + d.a += s.a - sada; + set(p, clip(d)); + } + } + }; + + //=====================================================comp_op_rgba_soft_light + template<class ColorT, class Order> + struct comp_op_rgba_soft_light : blender_base<ColorT, Order> + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + using blender_base<ColorT, Order>::get; + using blender_base<ColorT, Order>::set; + + // if 2.Sca <= Sa + // Dca' = Dca.Sa - (Sa.Da - 2.Sca.Da).Dca.Sa.(Sa.Da - Dca.Sa) + Sca.(1 - Da) + Dca.(1 - Sa) + // otherwise if 2.Sca > Sa and 4.Dca <= Da + // Dca' = Dca.Sa + (2.Sca.Da - Sa.Da).((((16.Dsa.Sa - 12).Dsa.Sa + 4).Dsa.Da) - Dsa.Da) + Sca.(1 - Da) + Dca.(1 - Sa) + // otherwise if 2.Sca > Sa and 4.Dca > Da + // Dca' = Dca.Sa + (2.Sca.Da - Sa.Da).((Dca.Sa)^0.5 - Dca.Sa) + Sca.(1 - Da) + Dca.(1 - Sa) + // + // Da' = Sa + Da - Sa.Da + static AGG_INLINE double calc(double dca, double sca, double da, double sa, double sada, double d1a, double s1a) + { + double dcasa = dca * sa; + if (2 * sca <= sa) return dcasa - (sada - 2 * sca * da) * dcasa * (sada - dcasa) + sca * d1a + dca * s1a; + if (4 * dca <= da) return dcasa + (2 * sca * da - sada) * ((((16 * dcasa - 12) * dcasa + 4) * dca * da) - dca * da) + sca * d1a + dca * s1a; + return dcasa + (2 * sca * da - sada) * (sqrt(dcasa) - dcasa) + sca * d1a + dca * s1a; + } + + static AGG_INLINE void blend_pix(value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + rgba s = get(r, g, b, a, cover); + if (s.a > 0) + { + rgba d = get(p); + if (d.a > 0) + { + double sada = s.a * d.a; + double s1a = 1 - s.a; + double d1a = 1 - d.a; + d.r = calc(d.r, s.r, d.a, s.a, sada, d1a, s1a); + d.g = calc(d.g, s.g, d.a, s.a, sada, d1a, s1a); + d.b = calc(d.b, s.b, d.a, s.a, sada, d1a, s1a); + d.a += s.a - sada; + set(p, clip(d)); + } + else set(p, s); + } + } + }; + + //=====================================================comp_op_rgba_difference + template<class ColorT, class Order> + struct comp_op_rgba_difference : blender_base<ColorT, Order> + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + using blender_base<ColorT, Order>::get; + using blender_base<ColorT, Order>::set; + + // Dca' = Sca + Dca - 2.min(Sca.Da, Dca.Sa) + // Da' = Sa + Da - Sa.Da + static AGG_INLINE void blend_pix(value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + rgba s = get(r, g, b, a, cover); + if (s.a > 0) + { + rgba d = get(p); + d.r += s.r - 2 * sd_min(s.r * d.a, d.r * s.a); + d.g += s.g - 2 * sd_min(s.g * d.a, d.g * s.a); + d.b += s.b - 2 * sd_min(s.b * d.a, d.b * s.a); + d.a += s.a - s.a * d.a; + set(p, clip(d)); + } + } + }; + + //=====================================================comp_op_rgba_exclusion + template<class ColorT, class Order> + struct comp_op_rgba_exclusion : blender_base<ColorT, Order> + { + typedef ColorT color_type; + typedef typename color_type::value_type value_type; + using blender_base<ColorT, Order>::get; + using blender_base<ColorT, Order>::set; + + // Dca' = (Sca.Da + Dca.Sa - 2.Sca.Dca) + Sca.(1 - Da) + Dca.(1 - Sa) + // Da' = Sa + Da - Sa.Da + static AGG_INLINE void blend_pix(value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + rgba s = get(r, g, b, a, cover); + if (s.a > 0) + { + rgba d = get(p); + double d1a = 1 - d.a; + double s1a = 1 - s.a; + d.r = (s.r * d.a + d.r * s.a - 2 * s.r * d.r) + s.r * d1a + d.r * s1a; + d.g = (s.g * d.a + d.g * s.a - 2 * s.g * d.g) + s.g * d1a + d.g * s1a; + d.b = (s.b * d.a + d.b * s.a - 2 * s.b * d.b) + s.b * d1a + d.b * s1a; + d.a += s.a - s.a * d.a; + set(p, clip(d)); + } + } + }; + +#if 0 + //=====================================================comp_op_rgba_contrast + template<class ColorT, class Order> struct comp_op_rgba_contrast + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + enum base_scale_e + { + base_shift = color_type::base_shift, + base_mask = color_type::base_mask + }; + + + static AGG_INLINE void blend_pix(value_type* p, + unsigned sr, unsigned sg, unsigned sb, + unsigned sa, unsigned cover) + { + if (cover < 255) + { + sr = (sr * cover + 255) >> 8; + sg = (sg * cover + 255) >> 8; + sb = (sb * cover + 255) >> 8; + sa = (sa * cover + 255) >> 8; + } + long_type dr = p[Order::R]; + long_type dg = p[Order::G]; + long_type db = p[Order::B]; + int da = p[Order::A]; + long_type d2a = da >> 1; + unsigned s2a = sa >> 1; + + int r = (int)((((dr - d2a) * int((sr - s2a)*2 + base_mask)) >> base_shift) + d2a); + int g = (int)((((dg - d2a) * int((sg - s2a)*2 + base_mask)) >> base_shift) + d2a); + int b = (int)((((db - d2a) * int((sb - s2a)*2 + base_mask)) >> base_shift) + d2a); + + r = (r < 0) ? 0 : r; + g = (g < 0) ? 0 : g; + b = (b < 0) ? 0 : b; + + p[Order::R] = (value_type)((r > da) ? da : r); + p[Order::G] = (value_type)((g > da) ? da : g); + p[Order::B] = (value_type)((b > da) ? da : b); + } + }; + + //=====================================================comp_op_rgba_invert + template<class ColorT, class Order> struct comp_op_rgba_invert + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + enum base_scale_e + { + base_shift = color_type::base_shift, + base_mask = color_type::base_mask + }; + + // Dca' = (Da - Dca) * Sa + Dca.(1 - Sa) + // Da' = Sa + Da - Sa.Da + static AGG_INLINE void blend_pix(value_type* p, + unsigned sr, unsigned sg, unsigned sb, + unsigned sa, unsigned cover) + { + sa = (sa * cover + 255) >> 8; + if (sa) + { + calc_type da = p[Order::A]; + calc_type dr = ((da - p[Order::R]) * sa + base_mask) >> base_shift; + calc_type dg = ((da - p[Order::G]) * sa + base_mask) >> base_shift; + calc_type db = ((da - p[Order::B]) * sa + base_mask) >> base_shift; + calc_type s1a = base_mask - sa; + p[Order::R] = (value_type)(dr + ((p[Order::R] * s1a + base_mask) >> base_shift)); + p[Order::G] = (value_type)(dg + ((p[Order::G] * s1a + base_mask) >> base_shift)); + p[Order::B] = (value_type)(db + ((p[Order::B] * s1a + base_mask) >> base_shift)); + p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift)); + } + } + }; + + //=================================================comp_op_rgba_invert_rgb + template<class ColorT, class Order> struct comp_op_rgba_invert_rgb + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + enum base_scale_e + { + base_shift = color_type::base_shift, + base_mask = color_type::base_mask + }; + + // Dca' = (Da - Dca) * Sca + Dca.(1 - Sa) + // Da' = Sa + Da - Sa.Da + static AGG_INLINE void blend_pix(value_type* p, + unsigned sr, unsigned sg, unsigned sb, + unsigned sa, unsigned cover) + { + if (cover < 255) + { + sr = (sr * cover + 255) >> 8; + sg = (sg * cover + 255) >> 8; + sb = (sb * cover + 255) >> 8; + sa = (sa * cover + 255) >> 8; + } + if (sa) + { + calc_type da = p[Order::A]; + calc_type dr = ((da - p[Order::R]) * sr + base_mask) >> base_shift; + calc_type dg = ((da - p[Order::G]) * sg + base_mask) >> base_shift; + calc_type db = ((da - p[Order::B]) * sb + base_mask) >> base_shift; + calc_type s1a = base_mask - sa; + p[Order::R] = (value_type)(dr + ((p[Order::R] * s1a + base_mask) >> base_shift)); + p[Order::G] = (value_type)(dg + ((p[Order::G] * s1a + base_mask) >> base_shift)); + p[Order::B] = (value_type)(db + ((p[Order::B] * s1a + base_mask) >> base_shift)); + p[Order::A] = (value_type)(sa + da - ((sa * da + base_mask) >> base_shift)); + } + } + }; +#endif + + + //======================================================comp_op_table_rgba + template<class ColorT, class Order> struct comp_op_table_rgba + { + typedef typename ColorT::value_type value_type; + typedef typename ColorT::calc_type calc_type; + typedef void (*comp_op_func_type)(value_type* p, + value_type cr, + value_type cg, + value_type cb, + value_type ca, + cover_type cover); + static comp_op_func_type g_comp_op_func[]; + }; + + //==========================================================g_comp_op_func + template<class ColorT, class Order> + typename comp_op_table_rgba<ColorT, Order>::comp_op_func_type + comp_op_table_rgba<ColorT, Order>::g_comp_op_func[] = + { + comp_op_rgba_clear <ColorT,Order>::blend_pix, + comp_op_rgba_src <ColorT,Order>::blend_pix, + comp_op_rgba_dst <ColorT,Order>::blend_pix, + comp_op_rgba_src_over <ColorT,Order>::blend_pix, + comp_op_rgba_dst_over <ColorT,Order>::blend_pix, + comp_op_rgba_src_in <ColorT,Order>::blend_pix, + comp_op_rgba_dst_in <ColorT,Order>::blend_pix, + comp_op_rgba_src_out <ColorT,Order>::blend_pix, + comp_op_rgba_dst_out <ColorT,Order>::blend_pix, + comp_op_rgba_src_atop <ColorT,Order>::blend_pix, + comp_op_rgba_dst_atop <ColorT,Order>::blend_pix, + comp_op_rgba_xor <ColorT,Order>::blend_pix, + comp_op_rgba_plus <ColorT,Order>::blend_pix, + //comp_op_rgba_minus <ColorT,Order>::blend_pix, + comp_op_rgba_multiply <ColorT,Order>::blend_pix, + comp_op_rgba_screen <ColorT,Order>::blend_pix, + comp_op_rgba_overlay <ColorT,Order>::blend_pix, + comp_op_rgba_darken <ColorT,Order>::blend_pix, + comp_op_rgba_lighten <ColorT,Order>::blend_pix, + comp_op_rgba_color_dodge<ColorT,Order>::blend_pix, + comp_op_rgba_color_burn <ColorT,Order>::blend_pix, + comp_op_rgba_hard_light <ColorT,Order>::blend_pix, + comp_op_rgba_soft_light <ColorT,Order>::blend_pix, + comp_op_rgba_difference <ColorT,Order>::blend_pix, + comp_op_rgba_exclusion <ColorT,Order>::blend_pix, + //comp_op_rgba_contrast <ColorT,Order>::blend_pix, + //comp_op_rgba_invert <ColorT,Order>::blend_pix, + //comp_op_rgba_invert_rgb <ColorT,Order>::blend_pix, + 0 + }; + + + //==============================================================comp_op_e + enum comp_op_e + { + comp_op_clear, //----comp_op_clear + comp_op_src, //----comp_op_src + comp_op_dst, //----comp_op_dst + comp_op_src_over, //----comp_op_src_over + comp_op_dst_over, //----comp_op_dst_over + comp_op_src_in, //----comp_op_src_in + comp_op_dst_in, //----comp_op_dst_in + comp_op_src_out, //----comp_op_src_out + comp_op_dst_out, //----comp_op_dst_out + comp_op_src_atop, //----comp_op_src_atop + comp_op_dst_atop, //----comp_op_dst_atop + comp_op_xor, //----comp_op_xor + comp_op_plus, //----comp_op_plus + //comp_op_minus, //----comp_op_minus + comp_op_multiply, //----comp_op_multiply + comp_op_screen, //----comp_op_screen + comp_op_overlay, //----comp_op_overlay + comp_op_darken, //----comp_op_darken + comp_op_lighten, //----comp_op_lighten + comp_op_color_dodge, //----comp_op_color_dodge + comp_op_color_burn, //----comp_op_color_burn + comp_op_hard_light, //----comp_op_hard_light + comp_op_soft_light, //----comp_op_soft_light + comp_op_difference, //----comp_op_difference + comp_op_exclusion, //----comp_op_exclusion + //comp_op_contrast, //----comp_op_contrast + //comp_op_invert, //----comp_op_invert + //comp_op_invert_rgb, //----comp_op_invert_rgb + + end_of_comp_op_e + }; + + + + + + + + //====================================================comp_op_adaptor_rgba + template<class ColorT, class Order> + struct comp_op_adaptor_rgba + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + static AGG_INLINE void blend_pix(unsigned op, value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + comp_op_table_rgba<ColorT, Order>::g_comp_op_func[op](p, + color_type::multiply(r, a), + color_type::multiply(g, a), + color_type::multiply(b, a), + a, cover); + } + }; + + //=========================================comp_op_adaptor_clip_to_dst_rgba + template<class ColorT, class Order> + struct comp_op_adaptor_clip_to_dst_rgba + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + static AGG_INLINE void blend_pix(unsigned op, value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + r = color_type::multiply(r, a); + g = color_type::multiply(g, a); + b = color_type::multiply(b, a); + value_type da = p[Order::A]; + comp_op_table_rgba<ColorT, Order>::g_comp_op_func[op](p, + color_type::multiply(r, da), + color_type::multiply(g, da), + color_type::multiply(b, da), + color_type::multiply(a, da), cover); + } + }; + + //================================================comp_op_adaptor_rgba_pre + template<class ColorT, class Order> + struct comp_op_adaptor_rgba_pre + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + static AGG_INLINE void blend_pix(unsigned op, value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + comp_op_table_rgba<ColorT, Order>::g_comp_op_func[op](p, r, g, b, a, cover); + } + }; + + //=====================================comp_op_adaptor_clip_to_dst_rgba_pre + template<class ColorT, class Order> + struct comp_op_adaptor_clip_to_dst_rgba_pre + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + static AGG_INLINE void blend_pix(unsigned op, value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + value_type da = p[Order::A]; + comp_op_table_rgba<ColorT, Order>::g_comp_op_func[op](p, + color_type::multiply(r, da), + color_type::multiply(g, da), + color_type::multiply(b, da), + color_type::multiply(a, da), cover); + } + }; + + //====================================================comp_op_adaptor_rgba_plain + template<class ColorT, class Order> + struct comp_op_adaptor_rgba_plain + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + static AGG_INLINE void blend_pix(unsigned op, value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + multiplier_rgba<ColorT, Order>::premultiply(p); + comp_op_adaptor_rgba<ColorT, Order>::blend_pix(op, p, r, g, b, a, cover); + multiplier_rgba<ColorT, Order>::demultiply(p); + } + }; + + //=========================================comp_op_adaptor_clip_to_dst_rgba_plain + template<class ColorT, class Order> + struct comp_op_adaptor_clip_to_dst_rgba_plain + { + typedef ColorT color_type; + typedef Order order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + static AGG_INLINE void blend_pix(unsigned op, value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + multiplier_rgba<ColorT, Order>::premultiply(p); + comp_op_adaptor_clip_to_dst_rgba<ColorT, Order>::blend_pix(op, p, r, g, b, a, cover); + multiplier_rgba<ColorT, Order>::demultiply(p); + } + }; + + //=======================================================comp_adaptor_rgba + template<class BlenderPre> + struct comp_adaptor_rgba + { + typedef typename BlenderPre::color_type color_type; + typedef typename BlenderPre::order_type order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + static AGG_INLINE void blend_pix(unsigned op, value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + BlenderPre::blend_pix(p, + color_type::multiply(r, a), + color_type::multiply(g, a), + color_type::multiply(b, a), + a, cover); + } + }; + + //==========================================comp_adaptor_clip_to_dst_rgba + template<class BlenderPre> + struct comp_adaptor_clip_to_dst_rgba + { + typedef typename BlenderPre::color_type color_type; + typedef typename BlenderPre::order_type order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + static AGG_INLINE void blend_pix(unsigned op, value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + r = color_type::multiply(r, a); + g = color_type::multiply(g, a); + b = color_type::multiply(b, a); + value_type da = p[order_type::A]; + BlenderPre::blend_pix(p, + color_type::multiply(r, da), + color_type::multiply(g, da), + color_type::multiply(b, da), + color_type::multiply(a, da), cover); + } + }; + + //=======================================================comp_adaptor_rgba_pre + template<class BlenderPre> + struct comp_adaptor_rgba_pre + { + typedef typename BlenderPre::color_type color_type; + typedef typename BlenderPre::order_type order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + static AGG_INLINE void blend_pix(unsigned op, value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + BlenderPre::blend_pix(p, r, g, b, a, cover); + } + }; + + //======================================comp_adaptor_clip_to_dst_rgba_pre + template<class BlenderPre> + struct comp_adaptor_clip_to_dst_rgba_pre + { + typedef typename BlenderPre::color_type color_type; + typedef typename BlenderPre::order_type order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + static AGG_INLINE void blend_pix(unsigned op, value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + unsigned da = p[order_type::A]; + BlenderPre::blend_pix(p, + color_type::multiply(r, da), + color_type::multiply(g, da), + color_type::multiply(b, da), + color_type::multiply(a, da), + cover); + } + }; + + //=======================================================comp_adaptor_rgba_plain + template<class BlenderPre> + struct comp_adaptor_rgba_plain + { + typedef typename BlenderPre::color_type color_type; + typedef typename BlenderPre::order_type order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + static AGG_INLINE void blend_pix(unsigned op, value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + multiplier_rgba<color_type, order_type>::premultiply(p); + comp_adaptor_rgba<BlenderPre>::blend_pix(op, p, r, g, b, a, cover); + multiplier_rgba<color_type, order_type>::demultiply(p); + } + }; + + //==========================================comp_adaptor_clip_to_dst_rgba_plain + template<class BlenderPre> + struct comp_adaptor_clip_to_dst_rgba_plain + { + typedef typename BlenderPre::color_type color_type; + typedef typename BlenderPre::order_type order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + static AGG_INLINE void blend_pix(unsigned op, value_type* p, + value_type r, value_type g, value_type b, value_type a, cover_type cover) + { + multiplier_rgba<color_type, order_type>::premultiply(p); + comp_adaptor_clip_to_dst_rgba<BlenderPre>::blend_pix(op, p, r, g, b, a, cover); + multiplier_rgba<color_type, order_type>::demultiply(p); + } + }; + + + //=================================================pixfmt_alpha_blend_rgba + template<class Blender, class RenBuf> + class pixfmt_alpha_blend_rgba + { + public: + typedef pixfmt_rgba_tag pixfmt_category; + typedef RenBuf rbuf_type; + typedef typename rbuf_type::row_data row_data; + typedef Blender blender_type; + typedef typename blender_type::color_type color_type; + typedef typename blender_type::order_type order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + enum + { + pix_step = 4, + pix_width = sizeof(value_type) * pix_step, + }; + struct pixel_type + { + value_type c[pix_step]; + + void set(value_type r, value_type g, value_type b, value_type a) + { + c[order_type::R] = r; + c[order_type::G] = g; + c[order_type::B] = b; + c[order_type::A] = a; + } + + void set(const color_type& color) + { + set(color.r, color.g, color.b, color.a); + } + + void get(value_type& r, value_type& g, value_type& b, value_type& a) const + { + r = c[order_type::R]; + g = c[order_type::G]; + b = c[order_type::B]; + a = c[order_type::A]; + } + + color_type get() const + { + return color_type( + c[order_type::R], + c[order_type::G], + c[order_type::B], + c[order_type::A]); + } + + pixel_type* next() + { + return this + 1; + } + + const pixel_type* next() const + { + return this + 1; + } + + pixel_type* advance(int n) + { + return this + n; + } + + const pixel_type* advance(int n) const + { + return this + n; + } + }; + + private: + //-------------------------------------------------------------------- + AGG_INLINE void blend_pix(pixel_type* p, const color_type& c, unsigned cover) + { + m_blender.blend_pix(p->c, c.r, c.g, c.b, c.a, cover); + } + + //-------------------------------------------------------------------- + AGG_INLINE void blend_pix(pixel_type* p, const color_type& c) + { + m_blender.blend_pix(p->c, c.r, c.g, c.b, c.a); + } + + //-------------------------------------------------------------------- + AGG_INLINE void copy_or_blend_pix(pixel_type* p, const color_type& c, unsigned cover) + { + if (!c.is_transparent()) + { + if (c.is_opaque() && cover == cover_mask) + { + p->set(c.r, c.g, c.b, c.a); + } + else + { + m_blender.blend_pix(p->c, c.r, c.g, c.b, c.a, cover); + } + } + } + + //-------------------------------------------------------------------- + AGG_INLINE void copy_or_blend_pix(pixel_type* p, const color_type& c) + { + if (!c.is_transparent()) + { + if (c.is_opaque()) + { + p->set(c.r, c.g, c.b, c.a); + } + else + { + m_blender.blend_pix(p->c, c.r, c.g, c.b, c.a); + } + } + } + + public: + //-------------------------------------------------------------------- + pixfmt_alpha_blend_rgba() : m_rbuf(0) {} + explicit pixfmt_alpha_blend_rgba(rbuf_type& rb) : m_rbuf(&rb) {} + void attach(rbuf_type& rb) { m_rbuf = &rb; } + + //-------------------------------------------------------------------- + template<class PixFmt> + bool attach(PixFmt& pixf, int x1, int y1, int x2, int y2) + { + rect_i r(x1, y1, x2, y2); + if (r.clip(rect_i(0, 0, pixf.width()-1, pixf.height()-1))) + { + int stride = pixf.stride(); + m_rbuf->attach(pixf.pix_ptr(r.x1, stride < 0 ? r.y2 : r.y1), + (r.x2 - r.x1) + 1, + (r.y2 - r.y1) + 1, + stride); + return true; + } + return false; + } + + //-------------------------------------------------------------------- + AGG_INLINE unsigned width() const { return m_rbuf->width(); } + AGG_INLINE unsigned height() const { return m_rbuf->height(); } + AGG_INLINE int stride() const { return m_rbuf->stride(); } + + //-------------------------------------------------------------------- + AGG_INLINE 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) + sizeof(value_type) * (x * pix_step); + } + + AGG_INLINE const int8u* pix_ptr(int x, int y) const + { + return m_rbuf->row_ptr(y) + sizeof(value_type) * (x * pix_step); + } + + // Return pointer to pixel value, forcing row to be allocated. + AGG_INLINE pixel_type* pix_value_ptr(int x, int y, unsigned len) + { + return (pixel_type*)(m_rbuf->row_ptr(x, y, len) + sizeof(value_type) * (x * pix_step)); + } + + // Return pointer to pixel value, or null if row not allocated. + AGG_INLINE const pixel_type* pix_value_ptr(int x, int y) const + { + int8u* p = m_rbuf->row_ptr(y); + return p ? (pixel_type*)(p + sizeof(value_type) * (x * pix_step)) : 0; + } + + // Get pixel pointer from raw buffer pointer. + AGG_INLINE static pixel_type* pix_value_ptr(void* p) + { + return (pixel_type*)p; + } + + // Get pixel pointer from raw buffer pointer. + AGG_INLINE static const pixel_type* pix_value_ptr(const void* p) + { + return (const pixel_type*)p; + } + + //-------------------------------------------------------------------- + AGG_INLINE static void write_plain_color(void* p, color_type c) + { + blender_type::set_plain_color(pix_value_ptr(p)->c, c); + } + + //-------------------------------------------------------------------- + AGG_INLINE static color_type read_plain_color(const void* p) + { + return blender_type::get_plain_color(pix_value_ptr(p)->c); + } + + //-------------------------------------------------------------------- + AGG_INLINE static void make_pix(int8u* p, const color_type& c) + { + ((pixel_type*)p)->set(c); + } + + //-------------------------------------------------------------------- + AGG_INLINE color_type pixel(int x, int y) const + { + if (const pixel_type* p = pix_value_ptr(x, y)) + { + return p->get(); + } + return color_type::no_color(); + } + + //-------------------------------------------------------------------- + AGG_INLINE void copy_pixel(int x, int y, const color_type& c) + { + pix_value_ptr(x, y, 1)->set(c); + } + + //-------------------------------------------------------------------- + AGG_INLINE void blend_pixel(int x, int y, const color_type& c, int8u cover) + { + copy_or_blend_pix(pix_value_ptr(x, y, 1), c, cover); + } + + //-------------------------------------------------------------------- + AGG_INLINE void copy_hline(int x, int y, + unsigned len, + const color_type& c) + { + pixel_type v; + v.set(c); + pixel_type* p = pix_value_ptr(x, y, len); + do + { + *p = v; + p = p->next(); + } + while (--len); + } + + + //-------------------------------------------------------------------- + AGG_INLINE void copy_vline(int x, int y, + unsigned len, + const color_type& c) + { + pixel_type v; + v.set(c); + do + { + *pix_value_ptr(x, y++, 1) = v; + } + while (--len); + } + + //-------------------------------------------------------------------- + void blend_hline(int x, int y, + unsigned len, + const color_type& c, + int8u cover) + { + if (!c.is_transparent()) + { + pixel_type* p = pix_value_ptr(x, y, len); + if (c.is_opaque() && cover == cover_mask) + { + pixel_type v; + v.set(c); + do + { + *p = v; + p = p->next(); + } + while (--len); + } + else + { + if (cover == cover_mask) + { + do + { + blend_pix(p, c); + p = p->next(); + } + while (--len); + } + else + { + do + { + blend_pix(p, c, cover); + p = p->next(); + } + while (--len); + } + } + } + } + + + //-------------------------------------------------------------------- + void blend_vline(int x, int y, + unsigned len, + const color_type& c, + int8u cover) + { + if (!c.is_transparent()) + { + if (c.is_opaque() && cover == cover_mask) + { + pixel_type v; + v.set(c); + do + { + *pix_value_ptr(x, y++, 1) = v; + } + while (--len); + } + else + { + if (cover == cover_mask) + { + do + { + blend_pix(pix_value_ptr(x, y++, 1), c, c.a); + } + while (--len); + } + else + { + do + { + blend_pix(pix_value_ptr(x, y++, 1), c, cover); + } + while (--len); + } + } + } + } + + + //-------------------------------------------------------------------- + void blend_solid_hspan(int x, int y, + unsigned len, + const color_type& c, + const int8u* covers) + { + if (!c.is_transparent()) + { + pixel_type* p = pix_value_ptr(x, y, len); + do + { + if (c.is_opaque() && *covers == cover_mask) + { + p->set(c); + } + else + { + blend_pix(p, c, *covers); + } + p = p->next(); + ++covers; + } + while (--len); + } + } + + + //-------------------------------------------------------------------- + void blend_solid_vspan(int x, int y, + unsigned len, + const color_type& c, + const int8u* covers) + { + if (!c.is_transparent()) + { + do + { + pixel_type* p = pix_value_ptr(x, y++, 1); + if (c.is_opaque() && *covers == cover_mask) + { + p->set(c); + } + else + { + blend_pix(p, c, *covers); + } + ++covers; + } + while (--len); + } + } + + //-------------------------------------------------------------------- + void copy_color_hspan(int x, int y, + unsigned len, + const color_type* colors) + { + pixel_type* p = pix_value_ptr(x, y, len); + do + { + p->set(*colors++); + p = p->next(); + } + while (--len); + } + + + //-------------------------------------------------------------------- + void copy_color_vspan(int x, int y, + unsigned len, + const color_type* colors) + { + do + { + pix_value_ptr(x, y++, 1)->set(*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 = pix_value_ptr(x, y, len); + if (covers) + { + do + { + copy_or_blend_pix(p, *colors++, *covers++); + p = p->next(); + } + while (--len); + } + else + { + if (cover == cover_mask) + { + do + { + copy_or_blend_pix(p, *colors++); + p = p->next(); + } + while (--len); + } + else + { + do + { + copy_or_blend_pix(p, *colors++, cover); + p = p->next(); + } + while (--len); + } + } + } + + //-------------------------------------------------------------------- + void blend_color_vspan(int x, int y, + unsigned len, + const color_type* colors, + const int8u* covers, + int8u cover) + { + if (covers) + { + do + { + copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++, *covers++); + } + while (--len); + } + else + { + if (cover == cover_mask) + { + do + { + copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++); + } + while (--len); + } + else + { + do + { + copy_or_blend_pix(pix_value_ptr(x, y++, 1), *colors++, cover); + } + while (--len); + } + } + } + + //-------------------------------------------------------------------- + template<class Function> void for_each_pixel(Function f) + { + for (unsigned y = 0; y < height(); ++y) + { + row_data r = m_rbuf->row(y); + if (r.ptr) + { + unsigned len = r.x2 - r.x1 + 1; + pixel_type* p = pix_value_ptr(r.x1, y, len); + do + { + f(p->c); + p = p->next(); + } + while (--len); + } + } + } + + //-------------------------------------------------------------------- + void premultiply() + { + for_each_pixel(multiplier_rgba<color_type, order_type>::premultiply); + } + + //-------------------------------------------------------------------- + void demultiply() + { + for_each_pixel(multiplier_rgba<color_type, order_type>::demultiply); + } + + //-------------------------------------------------------------------- + template<class GammaLut> void apply_gamma_dir(const GammaLut& g) + { + for_each_pixel(apply_gamma_dir_rgba<color_type, order_type, GammaLut>(g)); + } + + //-------------------------------------------------------------------- + template<class GammaLut> void apply_gamma_inv(const GammaLut& g) + { + for_each_pixel(apply_gamma_inv_rgba<color_type, order_type, GammaLut>(g)); + } + + //-------------------------------------------------------------------- + template<class RenBuf2> void copy_from(const RenBuf2& from, + int xdst, int ydst, + int xsrc, int ysrc, + unsigned len) + { + if (const int8u* p = from.row_ptr(ysrc)) + { + memmove(m_rbuf->row_ptr(xdst, ydst, len) + xdst * pix_width, + p + xsrc * pix_width, + len * pix_width); + } + } + + //-------------------------------------------------------------------- + // Blend from another RGBA surface. + template<class SrcPixelFormatRenderer> + void blend_from(const SrcPixelFormatRenderer& from, + int xdst, int ydst, + int xsrc, int ysrc, + unsigned len, + int8u cover) + { + typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type; + + if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc)) + { + pixel_type* pdst = pix_value_ptr(xdst, ydst, len); + int srcinc = 1; + int dstinc = 1; + + if (xdst > xsrc) + { + psrc = psrc->advance(len - 1); + pdst = pdst->advance(len - 1); + srcinc = -1; + dstinc = -1; + } + + if (cover == cover_mask) + { + do + { + copy_or_blend_pix(pdst, psrc->get()); + psrc = psrc->advance(srcinc); + pdst = pdst->advance(dstinc); + } + while (--len); + } + else + { + do + { + copy_or_blend_pix(pdst, psrc->get(), cover); + psrc = psrc->advance(srcinc); + pdst = pdst->advance(dstinc); + } + while (--len); + } + } + } + + //-------------------------------------------------------------------- + // Combine single color with grayscale surface and blend. + 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::pixel_type src_pixel_type; + typedef typename SrcPixelFormatRenderer::color_type src_color_type; + + if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc)) + { + pixel_type* pdst = pix_value_ptr(xdst, ydst, len); + + do + { + copy_or_blend_pix(pdst, color, + src_color_type::scale_cover(cover, psrc->c[0])); + psrc = psrc->next(); + pdst = pdst->next(); + } + while (--len); + } + } + + //-------------------------------------------------------------------- + // Blend from color table, using grayscale surface as indexes into table. + // Obviously, this only works for integer value types. + 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::pixel_type src_pixel_type; + + if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc)) + { + pixel_type* pdst = pix_value_ptr(xdst, ydst, len); + + if (cover == cover_mask) + { + do + { + copy_or_blend_pix(pdst, color_lut[psrc->c[0]]); + psrc = psrc->next(); + pdst = pdst->next(); + } + while (--len); + } + else + { + do + { + copy_or_blend_pix(pdst, color_lut[psrc->c[0]], cover); + psrc = psrc->next(); + pdst = pdst->next(); + } + while (--len); + } + } + } + + private: + rbuf_type* m_rbuf; + Blender m_blender; + }; + + //================================================pixfmt_custom_blend_rgba + template<class Blender, class RenBuf> class pixfmt_custom_blend_rgba + { + public: + typedef pixfmt_rgba_tag pixfmt_category; + typedef RenBuf rbuf_type; + typedef typename rbuf_type::row_data row_data; + typedef Blender blender_type; + typedef typename blender_type::color_type color_type; + typedef typename blender_type::order_type order_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + enum + { + pix_step = 4, + pix_width = sizeof(value_type) * pix_step, + }; + struct pixel_type + { + value_type c[pix_step]; + + void set(value_type r, value_type g, value_type b, value_type a) + { + c[order_type::R] = r; + c[order_type::G] = g; + c[order_type::B] = b; + c[order_type::A] = a; + } + + void set(const color_type& color) + { + set(color.r, color.g, color.b, color.a); + } + + void get(value_type& r, value_type& g, value_type& b, value_type& a) const + { + r = c[order_type::R]; + g = c[order_type::G]; + b = c[order_type::B]; + a = c[order_type::A]; + } + + color_type get() const + { + return color_type( + c[order_type::R], + c[order_type::G], + c[order_type::B], + c[order_type::A]); + } + + pixel_type* next() + { + return this + 1; + } + + const pixel_type* next() const + { + return this + 1; + } + + pixel_type* advance(int n) + { + return this + n; + } + + const pixel_type* advance(int n) const + { + return this + n; + } + }; + + + private: + //-------------------------------------------------------------------- + AGG_INLINE void blend_pix(pixel_type* p, const color_type& c, unsigned cover = cover_full) + { + m_blender.blend_pix(m_comp_op, p->c, c.r, c.g, c.b, c.a, cover); + } + + //-------------------------------------------------------------------- + AGG_INLINE void copy_or_blend_pix(pixel_type* p, const color_type& c, unsigned cover = cover_full) + { + if (!c.is_transparent()) + { + if (c.is_opaque() && cover == cover_mask) + { + p->set(c.r, c.g, c.b, c.a); + } + else + { + blend_pix(p, c, cover); + } + } + } + + public: + //-------------------------------------------------------------------- + pixfmt_custom_blend_rgba() : m_rbuf(0), m_comp_op(3) {} + explicit pixfmt_custom_blend_rgba(rbuf_type& rb, unsigned comp_op=3) : + m_rbuf(&rb), + m_comp_op(comp_op) + {} + void attach(rbuf_type& rb) { m_rbuf = &rb; } + + //-------------------------------------------------------------------- + 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; + } + + //-------------------------------------------------------------------- + void comp_op(unsigned op) { m_comp_op = op; } + unsigned comp_op() const { return m_comp_op; } + + //-------------------------------------------------------------------- + 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) + sizeof(value_type) * (x * pix_step); + } + + AGG_INLINE const int8u* pix_ptr(int x, int y) const + { + return m_rbuf->row_ptr(y) + sizeof(value_type) * (x * pix_step); + } + + // Return pointer to pixel value, forcing row to be allocated. + AGG_INLINE pixel_type* pix_value_ptr(int x, int y, unsigned len) + { + return (pixel_type*)(m_rbuf->row_ptr(x, y, len) + sizeof(value_type) * (x * pix_step)); + } + + // Return pointer to pixel value, or null if row not allocated. + AGG_INLINE const pixel_type* pix_value_ptr(int x, int y) const + { + int8u* p = m_rbuf->row_ptr(y); + return p ? (pixel_type*)(p + sizeof(value_type) * (x * pix_step)) : 0; + } + + // Get pixel pointer from raw buffer pointer. + AGG_INLINE static pixel_type* pix_value_ptr(void* p) + { + return (pixel_type*)p; + } + + // Get pixel pointer from raw buffer pointer. + AGG_INLINE static const pixel_type* pix_value_ptr(const void* p) + { + return (const pixel_type*)p; + } + + //-------------------------------------------------------------------- + AGG_INLINE static void make_pix(int8u* p, const color_type& c) + { + ((pixel_type*)p)->set(c); + } + + //-------------------------------------------------------------------- + AGG_INLINE color_type pixel(int x, int y) const + { + if (const pixel_type* p = pix_value_ptr(x, y)) + { + return p->get(); + } + return color_type::no_color(); + } + + //-------------------------------------------------------------------- + AGG_INLINE void copy_pixel(int x, int y, const color_type& c) + { + make_pix(pix_value_ptr(x, y, 1), c); + } + + //-------------------------------------------------------------------- + AGG_INLINE void blend_pixel(int x, int y, const color_type& c, int8u cover) + { + blend_pix(pix_value_ptr(x, y, 1), c, cover); + } + + //-------------------------------------------------------------------- + AGG_INLINE void copy_hline(int x, int y, + unsigned len, + const color_type& c) + { + pixel_type v; + v.set(c); + pixel_type* p = pix_value_ptr(x, y, len); + do + { + *p = v; + p = p->next(); + } + while (--len); + } + + + //-------------------------------------------------------------------- + AGG_INLINE void copy_vline(int x, int y, + unsigned len, + const color_type& c) + { + pixel_type v; + v.set(c); + do + { + *pix_value_ptr(x, y++, 1) = v; + } + while (--len); + } + + //-------------------------------------------------------------------- + void blend_hline(int x, int y, unsigned len, + const color_type& c, int8u cover) + { + + pixel_type* p = pix_value_ptr(x, y, len); + do + { + blend_pix(p, c, cover); + p = p->next(); + } + while (--len); + } + + //-------------------------------------------------------------------- + void blend_vline(int x, int y, unsigned len, + const color_type& c, int8u cover) + { + do + { + blend_pix(pix_value_ptr(x, y++, 1), c, cover); + } + while (--len); + } + + //-------------------------------------------------------------------- + void blend_solid_hspan(int x, int y, unsigned len, + const color_type& c, const int8u* covers) + { + pixel_type* p = pix_value_ptr(x, y, len); + + do + { + blend_pix(p, c, *covers++); + p = p->next(); + } + while (--len); + } + + //-------------------------------------------------------------------- + void blend_solid_vspan(int x, int y, unsigned len, + const color_type& c, const int8u* covers) + { + do + { + blend_pix(pix_value_ptr(x, y++, 1), c, *covers++); + } + while (--len); + } + + //-------------------------------------------------------------------- + void copy_color_hspan(int x, int y, + unsigned len, + const color_type* colors) + { + pixel_type* p = pix_value_ptr(x, y, len); + + do + { + p->set(*colors++); + p = p->next(); + } + while (--len); + } + + //-------------------------------------------------------------------- + void copy_color_vspan(int x, int y, + unsigned len, + const color_type* colors) + { + do + { + pix_value_ptr(x, y++, 1)->set(*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 = pix_value_ptr(x, y, len); + + do + { + blend_pix(p, *colors++, covers ? *covers++ : cover); + p = p->next(); + } + while (--len); + } + + //-------------------------------------------------------------------- + void blend_color_vspan(int x, int y, unsigned len, + const color_type* colors, + const int8u* covers, + int8u cover) + { + do + { + blend_pix(pix_value_ptr(x, y++, 1), *colors++, covers ? *covers++ : cover); + } + while (--len); + + } + + //-------------------------------------------------------------------- + template<class Function> void for_each_pixel(Function f) + { + unsigned y; + for (y = 0; y < height(); ++y) + { + row_data r = m_rbuf->row(y); + if (r.ptr) + { + unsigned len = r.x2 - r.x1 + 1; + pixel_type* p = pix_value_ptr(r.x1, y, len); + do + { + f(p->c); + p = p->next(); + } + while (--len); + } + } + } + + //-------------------------------------------------------------------- + void premultiply() + { + for_each_pixel(multiplier_rgba<color_type, order_type>::premultiply); + } + + //-------------------------------------------------------------------- + void demultiply() + { + for_each_pixel(multiplier_rgba<color_type, order_type>::demultiply); + } + + //-------------------------------------------------------------------- + template<class GammaLut> void apply_gamma_dir(const GammaLut& g) + { + for_each_pixel(apply_gamma_dir_rgba<color_type, order_type, GammaLut>(g)); + } + + //-------------------------------------------------------------------- + template<class GammaLut> void apply_gamma_inv(const GammaLut& g) + { + for_each_pixel(apply_gamma_inv_rgba<color_type, order_type, GammaLut>(g)); + } + + //-------------------------------------------------------------------- + template<class RenBuf2> void copy_from(const RenBuf2& from, + int xdst, int ydst, + int xsrc, int ysrc, + unsigned len) + { + if (const int8u* p = from.row_ptr(ysrc)) + { + memmove(m_rbuf->row_ptr(xdst, ydst, len) + xdst * pix_width, + p + xsrc * pix_width, + len * pix_width); + } + } + + //-------------------------------------------------------------------- + // Blend from another RGBA surface. + template<class SrcPixelFormatRenderer> + void blend_from(const SrcPixelFormatRenderer& from, + int xdst, int ydst, + int xsrc, int ysrc, + unsigned len, + int8u cover) + { + typedef typename SrcPixelFormatRenderer::pixel_type src_pixel_type; + + if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc)) + { + pixel_type* pdst = pix_value_ptr(xdst, ydst, len); + int srcinc = 1; + int dstinc = 1; + + if (xdst > xsrc) + { + psrc = psrc->advance(len - 1); + pdst = pdst->advance(len - 1); + srcinc = -1; + dstinc = -1; + } + + do + { + blend_pix(pdst, psrc->get(), cover); + psrc = psrc->advance(srcinc); + pdst = pdst->advance(dstinc); + } + while (--len); + } + } + + //-------------------------------------------------------------------- + // Blend from single color, using grayscale surface as alpha channel. + 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::pixel_type src_pixel_type; + typedef typename SrcPixelFormatRenderer::color_type src_color_type; + + if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc)) + { + pixel_type* pdst = pix_value_ptr(xdst, ydst, len); + + do + { + blend_pix(pdst, color, + src_color_type::scale_cover(cover, psrc->c[0])); + psrc = psrc->next(); + pdst = pdst->next(); + } + while (--len); + } + } + + //-------------------------------------------------------------------- + // Blend from color table, using grayscale surface as indexes into table. + // Obviously, this only works for integer value types. + 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::pixel_type src_pixel_type; + + if (const src_pixel_type* psrc = from.pix_value_ptr(xsrc, ysrc)) + { + pixel_type* pdst = pix_value_ptr(xdst, ydst, len); + + do + { + blend_pix(pdst, color_lut[psrc->c[0]], cover); + psrc = psrc->next(); + pdst = pdst->next(); + } + while (--len); + } + } + + private: + rbuf_type* m_rbuf; + Blender m_blender; + unsigned m_comp_op; + }; + + + //----------------------------------------------------------------------- + typedef blender_rgba<rgba8, order_rgba> blender_rgba32; + typedef blender_rgba<rgba8, order_argb> blender_argb32; + typedef blender_rgba<rgba8, order_abgr> blender_abgr32; + typedef blender_rgba<rgba8, order_bgra> blender_bgra32; + + typedef blender_rgba<srgba8, order_rgba> blender_srgba32; + typedef blender_rgba<srgba8, order_argb> blender_sargb32; + typedef blender_rgba<srgba8, order_abgr> blender_sabgr32; + typedef blender_rgba<srgba8, order_bgra> blender_sbgra32; + + typedef blender_rgba_pre<rgba8, order_rgba> blender_rgba32_pre; + typedef blender_rgba_pre<rgba8, order_argb> blender_argb32_pre; + typedef blender_rgba_pre<rgba8, order_abgr> blender_abgr32_pre; + typedef blender_rgba_pre<rgba8, order_bgra> blender_bgra32_pre; + + typedef blender_rgba_pre<srgba8, order_rgba> blender_srgba32_pre; + typedef blender_rgba_pre<srgba8, order_argb> blender_sargb32_pre; + typedef blender_rgba_pre<srgba8, order_abgr> blender_sabgr32_pre; + typedef blender_rgba_pre<srgba8, order_bgra> blender_sbgra32_pre; + + typedef blender_rgba_plain<rgba8, order_rgba> blender_rgba32_plain; + typedef blender_rgba_plain<rgba8, order_argb> blender_argb32_plain; + typedef blender_rgba_plain<rgba8, order_abgr> blender_abgr32_plain; + typedef blender_rgba_plain<rgba8, order_bgra> blender_bgra32_plain; + + typedef blender_rgba_plain<srgba8, order_rgba> blender_srgba32_plain; + typedef blender_rgba_plain<srgba8, order_argb> blender_sargb32_plain; + typedef blender_rgba_plain<srgba8, order_abgr> blender_sabgr32_plain; + typedef blender_rgba_plain<srgba8, order_bgra> blender_sbgra32_plain; + + typedef blender_rgba<rgba16, order_rgba> blender_rgba64; + typedef blender_rgba<rgba16, order_argb> blender_argb64; + typedef blender_rgba<rgba16, order_abgr> blender_abgr64; + typedef blender_rgba<rgba16, order_bgra> blender_bgra64; + + typedef blender_rgba_pre<rgba16, order_rgba> blender_rgba64_pre; + typedef blender_rgba_pre<rgba16, order_argb> blender_argb64_pre; + typedef blender_rgba_pre<rgba16, order_abgr> blender_abgr64_pre; + typedef blender_rgba_pre<rgba16, order_bgra> blender_bgra64_pre; + + typedef blender_rgba_plain<rgba16, order_rgba> blender_rgba64_plain; + typedef blender_rgba_plain<rgba16, order_argb> blender_argb64_plain; + typedef blender_rgba_plain<rgba16, order_abgr> blender_abgr64_plain; + typedef blender_rgba_plain<rgba16, order_bgra> blender_bgra64_plain; + + typedef blender_rgba<rgba32, order_rgba> blender_rgba128; + typedef blender_rgba<rgba32, order_argb> blender_argb128; + typedef blender_rgba<rgba32, order_abgr> blender_abgr128; + typedef blender_rgba<rgba32, order_bgra> blender_bgra128; + + typedef blender_rgba_pre<rgba32, order_rgba> blender_rgba128_pre; + typedef blender_rgba_pre<rgba32, order_argb> blender_argb128_pre; + typedef blender_rgba_pre<rgba32, order_abgr> blender_abgr128_pre; + typedef blender_rgba_pre<rgba32, order_bgra> blender_bgra128_pre; + + typedef blender_rgba_plain<rgba32, order_rgba> blender_rgba128_plain; + typedef blender_rgba_plain<rgba32, order_argb> blender_argb128_plain; + typedef blender_rgba_plain<rgba32, order_abgr> blender_abgr128_plain; + typedef blender_rgba_plain<rgba32, order_bgra> blender_bgra128_plain; + + + //----------------------------------------------------------------------- + typedef pixfmt_alpha_blend_rgba<blender_rgba32, rendering_buffer> pixfmt_rgba32; + typedef pixfmt_alpha_blend_rgba<blender_argb32, rendering_buffer> pixfmt_argb32; + typedef pixfmt_alpha_blend_rgba<blender_abgr32, rendering_buffer> pixfmt_abgr32; + typedef pixfmt_alpha_blend_rgba<blender_bgra32, rendering_buffer> pixfmt_bgra32; + + typedef pixfmt_alpha_blend_rgba<blender_srgba32, rendering_buffer> pixfmt_srgba32; + typedef pixfmt_alpha_blend_rgba<blender_sargb32, rendering_buffer> pixfmt_sargb32; + typedef pixfmt_alpha_blend_rgba<blender_sabgr32, rendering_buffer> pixfmt_sabgr32; + typedef pixfmt_alpha_blend_rgba<blender_sbgra32, rendering_buffer> pixfmt_sbgra32; + + typedef pixfmt_alpha_blend_rgba<blender_rgba32_pre, rendering_buffer> pixfmt_rgba32_pre; + typedef pixfmt_alpha_blend_rgba<blender_argb32_pre, rendering_buffer> pixfmt_argb32_pre; + typedef pixfmt_alpha_blend_rgba<blender_abgr32_pre, rendering_buffer> pixfmt_abgr32_pre; + typedef pixfmt_alpha_blend_rgba<blender_bgra32_pre, rendering_buffer> pixfmt_bgra32_pre; + + typedef pixfmt_alpha_blend_rgba<blender_srgba32_pre, rendering_buffer> pixfmt_srgba32_pre; + typedef pixfmt_alpha_blend_rgba<blender_sargb32_pre, rendering_buffer> pixfmt_sargb32_pre; + typedef pixfmt_alpha_blend_rgba<blender_sabgr32_pre, rendering_buffer> pixfmt_sabgr32_pre; + typedef pixfmt_alpha_blend_rgba<blender_sbgra32_pre, rendering_buffer> pixfmt_sbgra32_pre; + + typedef pixfmt_alpha_blend_rgba<blender_rgba32_plain, rendering_buffer> pixfmt_rgba32_plain; + typedef pixfmt_alpha_blend_rgba<blender_argb32_plain, rendering_buffer> pixfmt_argb32_plain; + typedef pixfmt_alpha_blend_rgba<blender_abgr32_plain, rendering_buffer> pixfmt_abgr32_plain; + typedef pixfmt_alpha_blend_rgba<blender_bgra32_plain, rendering_buffer> pixfmt_bgra32_plain; + + typedef pixfmt_alpha_blend_rgba<blender_srgba32_plain, rendering_buffer> pixfmt_srgba32_plain; + typedef pixfmt_alpha_blend_rgba<blender_sargb32_plain, rendering_buffer> pixfmt_sargb32_plain; + typedef pixfmt_alpha_blend_rgba<blender_sabgr32_plain, rendering_buffer> pixfmt_sabgr32_plain; + typedef pixfmt_alpha_blend_rgba<blender_sbgra32_plain, rendering_buffer> pixfmt_sbgra32_plain; + + typedef pixfmt_alpha_blend_rgba<blender_rgba64, rendering_buffer> pixfmt_rgba64; + typedef pixfmt_alpha_blend_rgba<blender_argb64, rendering_buffer> pixfmt_argb64; + typedef pixfmt_alpha_blend_rgba<blender_abgr64, rendering_buffer> pixfmt_abgr64; + typedef pixfmt_alpha_blend_rgba<blender_bgra64, rendering_buffer> pixfmt_bgra64; + + typedef pixfmt_alpha_blend_rgba<blender_rgba64_pre, rendering_buffer> pixfmt_rgba64_pre; + typedef pixfmt_alpha_blend_rgba<blender_argb64_pre, rendering_buffer> pixfmt_argb64_pre; + typedef pixfmt_alpha_blend_rgba<blender_abgr64_pre, rendering_buffer> pixfmt_abgr64_pre; + typedef pixfmt_alpha_blend_rgba<blender_bgra64_pre, rendering_buffer> pixfmt_bgra64_pre; + + typedef pixfmt_alpha_blend_rgba<blender_rgba64_plain, rendering_buffer> pixfmt_rgba64_plain; + typedef pixfmt_alpha_blend_rgba<blender_argb64_plain, rendering_buffer> pixfmt_argb64_plain; + typedef pixfmt_alpha_blend_rgba<blender_abgr64_plain, rendering_buffer> pixfmt_abgr64_plain; + typedef pixfmt_alpha_blend_rgba<blender_bgra64_plain, rendering_buffer> pixfmt_bgra64_plain; + + typedef pixfmt_alpha_blend_rgba<blender_rgba128, rendering_buffer> pixfmt_rgba128; + typedef pixfmt_alpha_blend_rgba<blender_argb128, rendering_buffer> pixfmt_argb128; + typedef pixfmt_alpha_blend_rgba<blender_abgr128, rendering_buffer> pixfmt_abgr128; + typedef pixfmt_alpha_blend_rgba<blender_bgra128, rendering_buffer> pixfmt_bgra128; + + typedef pixfmt_alpha_blend_rgba<blender_rgba128_pre, rendering_buffer> pixfmt_rgba128_pre; + typedef pixfmt_alpha_blend_rgba<blender_argb128_pre, rendering_buffer> pixfmt_argb128_pre; + typedef pixfmt_alpha_blend_rgba<blender_abgr128_pre, rendering_buffer> pixfmt_abgr128_pre; + typedef pixfmt_alpha_blend_rgba<blender_bgra128_pre, rendering_buffer> pixfmt_bgra128_pre; + + typedef pixfmt_alpha_blend_rgba<blender_rgba128_plain, rendering_buffer> pixfmt_rgba128_plain; + typedef pixfmt_alpha_blend_rgba<blender_argb128_plain, rendering_buffer> pixfmt_argb128_plain; + typedef pixfmt_alpha_blend_rgba<blender_abgr128_plain, rendering_buffer> pixfmt_abgr128_plain; + typedef pixfmt_alpha_blend_rgba<blender_bgra128_plain, rendering_buffer> pixfmt_bgra128_plain; + +} + +#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 00000000000..64738b6c755 --- /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_cells_aa.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rasterizer_cells_aa.h new file mode 100644 index 00000000000..d1cc705405d --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rasterizer_cells_aa.h @@ -0,0 +1,743 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +//---------------------------------------------------------------------------- +// +// The author gratefully acknowleges the support of David Turner, +// Robert Wilhelm, and Werner Lemberg - the authors of the FreeType +// libray - in producing this work. See http://www.freetype.org for details. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- +// +// Adaptation for 32-bit screen coordinates has been sponsored by +// Liberty Technology Systems, Inc., visit http://lib-sys.com +// +// Liberty Technology Systems, Inc. is the provider of +// PostScript and PDF technology for software developers. +// +//---------------------------------------------------------------------------- +#ifndef AGG_RASTERIZER_CELLS_AA_INCLUDED +#define AGG_RASTERIZER_CELLS_AA_INCLUDED + +#include <stdexcept> +#include <string.h> +#include <math.h> +#include "agg_math.h" +#include "agg_array.h" + + +namespace agg +{ + + //-----------------------------------------------------rasterizer_cells_aa + // An internal class that implements the main rasterization algorithm. + // Used in the rasterizer. Should not be used direcly. + template<class Cell> class rasterizer_cells_aa + { + enum cell_block_scale_e + { + cell_block_shift = 12, + cell_block_size = 1 << cell_block_shift, + cell_block_mask = cell_block_size - 1, + cell_block_pool = 256 + }; + + struct sorted_y + { + unsigned start; + unsigned num; + }; + + public: + typedef Cell cell_type; + typedef rasterizer_cells_aa<Cell> self_type; + + ~rasterizer_cells_aa(); + rasterizer_cells_aa(unsigned cell_block_limit=1024); + + void reset(); + void style(const cell_type& style_cell); + void line(int x1, int y1, int x2, int y2); + + int min_x() const { return m_min_x; } + int min_y() const { return m_min_y; } + int max_x() const { return m_max_x; } + int max_y() const { return m_max_y; } + + void sort_cells(); + + unsigned total_cells() const + { + return m_num_cells; + } + + unsigned scanline_num_cells(unsigned y) const + { + return m_sorted_y[y - m_min_y].num; + } + + const cell_type* const* scanline_cells(unsigned y) const + { + return m_sorted_cells.data() + m_sorted_y[y - m_min_y].start; + } + + bool sorted() const { return m_sorted; } + + private: + rasterizer_cells_aa(const self_type&); + const self_type& operator = (const self_type&); + + void set_curr_cell(int x, int y); + void add_curr_cell(); + void render_hline(int ey, int x1, int y1, int x2, int y2); + void allocate_block(); + + private: + unsigned m_num_blocks; + unsigned m_max_blocks; + unsigned m_curr_block; + unsigned m_num_cells; + unsigned m_cell_block_limit; + cell_type** m_cells; + cell_type* m_curr_cell_ptr; + pod_vector<cell_type*> m_sorted_cells; + pod_vector<sorted_y> m_sorted_y; + cell_type m_curr_cell; + cell_type m_style_cell; + int m_min_x; + int m_min_y; + int m_max_x; + int m_max_y; + bool m_sorted; + }; + + + + + //------------------------------------------------------------------------ + template<class Cell> + rasterizer_cells_aa<Cell>::~rasterizer_cells_aa() + { + if(m_num_blocks) + { + cell_type** ptr = m_cells + m_num_blocks - 1; + while(m_num_blocks--) + { + pod_allocator<cell_type>::deallocate(*ptr, cell_block_size); + ptr--; + } + pod_allocator<cell_type*>::deallocate(m_cells, m_max_blocks); + } + } + + //------------------------------------------------------------------------ + template<class Cell> + rasterizer_cells_aa<Cell>::rasterizer_cells_aa(unsigned cell_block_limit) : + m_num_blocks(0), + m_max_blocks(0), + m_curr_block(0), + m_num_cells(0), + m_cell_block_limit(cell_block_limit), + m_cells(0), + m_curr_cell_ptr(0), + m_sorted_cells(), + m_sorted_y(), + m_min_x(0x7FFFFFFF), + m_min_y(0x7FFFFFFF), + m_max_x(-0x7FFFFFFF), + m_max_y(-0x7FFFFFFF), + m_sorted(false) + { + m_style_cell.initial(); + m_curr_cell.initial(); + } + + //------------------------------------------------------------------------ + template<class Cell> + void rasterizer_cells_aa<Cell>::reset() + { + m_num_cells = 0; + m_curr_block = 0; + m_curr_cell.initial(); + m_style_cell.initial(); + m_sorted = false; + m_min_x = 0x7FFFFFFF; + m_min_y = 0x7FFFFFFF; + m_max_x = -0x7FFFFFFF; + m_max_y = -0x7FFFFFFF; + } + + //------------------------------------------------------------------------ + template<class Cell> + AGG_INLINE void rasterizer_cells_aa<Cell>::add_curr_cell() + { + if(m_curr_cell.area | m_curr_cell.cover) + { + if((m_num_cells & cell_block_mask) == 0) + { + if(m_num_blocks >= m_cell_block_limit) { + throw std::overflow_error("Exceeded cell block limit"); + } + allocate_block(); + } + *m_curr_cell_ptr++ = m_curr_cell; + ++m_num_cells; + } + } + + //------------------------------------------------------------------------ + template<class Cell> + AGG_INLINE void rasterizer_cells_aa<Cell>::set_curr_cell(int x, int y) + { + if(m_curr_cell.not_equal(x, y, m_style_cell)) + { + add_curr_cell(); + m_curr_cell.style(m_style_cell); + m_curr_cell.x = x; + m_curr_cell.y = y; + m_curr_cell.cover = 0; + m_curr_cell.area = 0; + } + } + + //------------------------------------------------------------------------ + template<class Cell> + AGG_INLINE void rasterizer_cells_aa<Cell>::render_hline(int ey, + int x1, int y1, + int x2, int y2) + { + int ex1 = x1 >> poly_subpixel_shift; + int ex2 = x2 >> poly_subpixel_shift; + int fx1 = x1 & poly_subpixel_mask; + int fx2 = x2 & poly_subpixel_mask; + + int delta, p, first, dx; + int incr, lift, mod, rem; + + //trivial case. Happens often + if(y1 == y2) + { + set_curr_cell(ex2, ey); + return; + } + + //everything is located in a single cell. That is easy! + if(ex1 == ex2) + { + delta = y2 - y1; + m_curr_cell.cover += delta; + m_curr_cell.area += (fx1 + fx2) * delta; + return; + } + + //ok, we'll have to render a run of adjacent cells on the same + //hline... + p = (poly_subpixel_scale - fx1) * (y2 - y1); + first = poly_subpixel_scale; + incr = 1; + + dx = x2 - x1; + + if(dx < 0) + { + p = fx1 * (y2 - y1); + first = 0; + incr = -1; + dx = -dx; + } + + delta = p / dx; + mod = p % dx; + + if(mod < 0) + { + delta--; + mod += dx; + } + + m_curr_cell.cover += delta; + m_curr_cell.area += (fx1 + first) * delta; + + ex1 += incr; + set_curr_cell(ex1, ey); + y1 += delta; + + if(ex1 != ex2) + { + p = poly_subpixel_scale * (y2 - y1 + delta); + lift = p / dx; + rem = p % dx; + + if (rem < 0) + { + lift--; + rem += dx; + } + + mod -= dx; + + while (ex1 != ex2) + { + delta = lift; + mod += rem; + if(mod >= 0) + { + mod -= dx; + delta++; + } + + m_curr_cell.cover += delta; + m_curr_cell.area += poly_subpixel_scale * delta; + y1 += delta; + ex1 += incr; + set_curr_cell(ex1, ey); + } + } + delta = y2 - y1; + m_curr_cell.cover += delta; + m_curr_cell.area += (fx2 + poly_subpixel_scale - first) * delta; + } + + //------------------------------------------------------------------------ + template<class Cell> + AGG_INLINE void rasterizer_cells_aa<Cell>::style(const cell_type& style_cell) + { + m_style_cell.style(style_cell); + } + + //------------------------------------------------------------------------ + template<class Cell> + void rasterizer_cells_aa<Cell>::line(int x1, int y1, int x2, int y2) + { + enum dx_limit_e { dx_limit = 16384 << poly_subpixel_shift }; + + int dx = x2 - x1; + + if(dx >= dx_limit || dx <= -dx_limit) + { + int cx = (x1 + x2) >> 1; + int cy = (y1 + y2) >> 1; + line(x1, y1, cx, cy); + line(cx, cy, x2, y2); + return; + } + + int dy = y2 - y1; + int ex1 = x1 >> poly_subpixel_shift; + int ex2 = x2 >> poly_subpixel_shift; + int ey1 = y1 >> poly_subpixel_shift; + int ey2 = y2 >> poly_subpixel_shift; + int fy1 = y1 & poly_subpixel_mask; + int fy2 = y2 & poly_subpixel_mask; + + int x_from, x_to; + int p, rem, mod, lift, delta, first, incr; + + if(ex1 < m_min_x) m_min_x = ex1; + if(ex1 > m_max_x) m_max_x = ex1; + if(ey1 < m_min_y) m_min_y = ey1; + if(ey1 > m_max_y) m_max_y = ey1; + if(ex2 < m_min_x) m_min_x = ex2; + if(ex2 > m_max_x) m_max_x = ex2; + if(ey2 < m_min_y) m_min_y = ey2; + if(ey2 > m_max_y) m_max_y = ey2; + + set_curr_cell(ex1, ey1); + + //everything is on a single hline + if(ey1 == ey2) + { + render_hline(ey1, x1, fy1, x2, fy2); + return; + } + + //Vertical line - we have to calculate start and end cells, + //and then - the common values of the area and coverage for + //all cells of the line. We know exactly there's only one + //cell, so, we don't have to call render_hline(). + incr = 1; + if(dx == 0) + { + int ex = x1 >> poly_subpixel_shift; + int two_fx = (x1 - (ex << poly_subpixel_shift)) << 1; + int area; + + first = poly_subpixel_scale; + if(dy < 0) + { + first = 0; + incr = -1; + } + + x_from = x1; + + //render_hline(ey1, x_from, fy1, x_from, first); + delta = first - fy1; + m_curr_cell.cover += delta; + m_curr_cell.area += two_fx * delta; + + ey1 += incr; + set_curr_cell(ex, ey1); + + delta = first + first - poly_subpixel_scale; + area = two_fx * delta; + while(ey1 != ey2) + { + //render_hline(ey1, x_from, poly_subpixel_scale - first, x_from, first); + m_curr_cell.cover = delta; + m_curr_cell.area = area; + ey1 += incr; + set_curr_cell(ex, ey1); + } + //render_hline(ey1, x_from, poly_subpixel_scale - first, x_from, fy2); + delta = fy2 - poly_subpixel_scale + first; + m_curr_cell.cover += delta; + m_curr_cell.area += two_fx * delta; + return; + } + + //ok, we have to render several hlines + p = (poly_subpixel_scale - fy1) * dx; + first = poly_subpixel_scale; + + if(dy < 0) + { + p = fy1 * dx; + first = 0; + incr = -1; + dy = -dy; + } + + delta = p / dy; + mod = p % dy; + + if(mod < 0) + { + delta--; + mod += dy; + } + + x_from = x1 + delta; + render_hline(ey1, x1, fy1, x_from, first); + + ey1 += incr; + set_curr_cell(x_from >> poly_subpixel_shift, ey1); + + if(ey1 != ey2) + { + p = poly_subpixel_scale * dx; + lift = p / dy; + rem = p % dy; + + if(rem < 0) + { + lift--; + rem += dy; + } + mod -= dy; + + while(ey1 != ey2) + { + delta = lift; + mod += rem; + if (mod >= 0) + { + mod -= dy; + delta++; + } + + x_to = x_from + delta; + render_hline(ey1, x_from, poly_subpixel_scale - first, x_to, first); + x_from = x_to; + + ey1 += incr; + set_curr_cell(x_from >> poly_subpixel_shift, ey1); + } + } + render_hline(ey1, x_from, poly_subpixel_scale - first, x2, fy2); + } + + //------------------------------------------------------------------------ + template<class Cell> + void rasterizer_cells_aa<Cell>::allocate_block() + { + if(m_curr_block >= m_num_blocks) + { + if(m_num_blocks >= m_max_blocks) + { + cell_type** new_cells = + pod_allocator<cell_type*>::allocate(m_max_blocks + + cell_block_pool); + + if(m_cells) + { + memcpy(new_cells, m_cells, m_max_blocks * sizeof(cell_type*)); + pod_allocator<cell_type*>::deallocate(m_cells, m_max_blocks); + } + m_cells = new_cells; + m_max_blocks += cell_block_pool; + } + + m_cells[m_num_blocks++] = + pod_allocator<cell_type>::allocate(cell_block_size); + + } + m_curr_cell_ptr = m_cells[m_curr_block++]; + } + + + + //------------------------------------------------------------------------ + template <class T> static AGG_INLINE void swap_cells(T* a, T* b) + { + T temp = *a; + *a = *b; + *b = temp; + } + + + //------------------------------------------------------------------------ + enum + { + qsort_threshold = 9 + }; + + + //------------------------------------------------------------------------ + template<class Cell> + void qsort_cells(Cell** start, unsigned num) + { + Cell** stack[80]; + Cell*** top; + Cell** limit; + Cell** base; + + limit = start + num; + base = start; + top = stack; + + for (;;) + { + int len = int(limit - base); + + Cell** i; + Cell** j; + Cell** pivot; + + if(len > qsort_threshold) + { + // we use base + len/2 as the pivot + pivot = base + len / 2; + swap_cells(base, pivot); + + i = base + 1; + j = limit - 1; + + // now ensure that *i <= *base <= *j + if((*j)->x < (*i)->x) + { + swap_cells(i, j); + } + + if((*base)->x < (*i)->x) + { + swap_cells(base, i); + } + + if((*j)->x < (*base)->x) + { + swap_cells(base, j); + } + + for(;;) + { + int x = (*base)->x; + do i++; while( (*i)->x < x ); + do j--; while( x < (*j)->x ); + + if(i > j) + { + break; + } + + swap_cells(i, j); + } + + swap_cells(base, j); + + // now, push the largest sub-array + if(j - base > limit - i) + { + top[0] = base; + top[1] = j; + base = i; + } + else + { + top[0] = i; + top[1] = limit; + limit = j; + } + top += 2; + } + else + { + // the sub-array is small, perform insertion sort + j = base; + i = j + 1; + + for(; i < limit; j = i, i++) + { + for(; j[1]->x < (*j)->x; j--) + { + swap_cells(j + 1, j); + if (j == base) + { + break; + } + } + } + + if(top > stack) + { + top -= 2; + base = top[0]; + limit = top[1]; + } + else + { + break; + } + } + } + } + + + //------------------------------------------------------------------------ + template<class Cell> + void rasterizer_cells_aa<Cell>::sort_cells() + { + if(m_sorted) return; //Perform sort only the first time. + + add_curr_cell(); + m_curr_cell.x = 0x7FFFFFFF; + m_curr_cell.y = 0x7FFFFFFF; + m_curr_cell.cover = 0; + m_curr_cell.area = 0; + + if(m_num_cells == 0) return; + +// DBG: Check to see if min/max works well. +//for(unsigned nc = 0; nc < m_num_cells; nc++) +//{ +// cell_type* cell = m_cells[nc >> cell_block_shift] + (nc & cell_block_mask); +// if(cell->x < m_min_x || +// cell->y < m_min_y || +// cell->x > m_max_x || +// cell->y > m_max_y) +// { +// cell = cell; // Breakpoint here +// } +//} + // Allocate the array of cell pointers + m_sorted_cells.allocate(m_num_cells, 16); + + // Allocate and zero the Y array + m_sorted_y.allocate(m_max_y - m_min_y + 1, 16); + m_sorted_y.zero(); + + // Create the Y-histogram (count the numbers of cells for each Y) + cell_type** block_ptr = m_cells; + cell_type* cell_ptr; + unsigned nb = m_num_cells; + unsigned i; + while(nb) + { + cell_ptr = *block_ptr++; + i = (nb > cell_block_size) ? cell_block_size : nb; + nb -= i; + while(i--) + { + m_sorted_y[cell_ptr->y - m_min_y].start++; + ++cell_ptr; + } + } + + // Convert the Y-histogram into the array of starting indexes + unsigned start = 0; + for(i = 0; i < m_sorted_y.size(); i++) + { + unsigned v = m_sorted_y[i].start; + m_sorted_y[i].start = start; + start += v; + } + + // Fill the cell pointer array sorted by Y + block_ptr = m_cells; + nb = m_num_cells; + while(nb) + { + cell_ptr = *block_ptr++; + i = (nb > cell_block_size) ? cell_block_size : nb; + nb -= i; + while(i--) + { + sorted_y& curr_y = m_sorted_y[cell_ptr->y - m_min_y]; + m_sorted_cells[curr_y.start + curr_y.num] = cell_ptr; + ++curr_y.num; + ++cell_ptr; + } + } + + // Finally arrange the X-arrays + for(i = 0; i < m_sorted_y.size(); i++) + { + const sorted_y& curr_y = m_sorted_y[i]; + if(curr_y.num) + { + qsort_cells(m_sorted_cells.data() + curr_y.start, curr_y.num); + } + } + m_sorted = true; + } + + + + //------------------------------------------------------scanline_hit_test + class scanline_hit_test + { + public: + scanline_hit_test(int x) : m_x(x), m_hit(false) {} + + void reset_spans() {} + void finalize(int) {} + void add_cell(int x, int) + { + if(m_x == x) m_hit = true; + } + void add_span(int x, int len, int) + { + if(m_x >= x && m_x < x+len) m_hit = true; + } + unsigned num_spans() const { return 1; } + bool hit() const { return m_hit; } + + private: + int m_x; + bool m_hit; + }; + + +} + +#endif diff --git a/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 00000000000..41d508010e8 --- /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 00000000000..65203e34c5b --- /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 00000000000..a06bd1e843e --- /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_rasterizer_scanline_aa.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rasterizer_scanline_aa.h new file mode 100644 index 00000000000..15832166462 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rasterizer_scanline_aa.h @@ -0,0 +1,481 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +//---------------------------------------------------------------------------- +// +// 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_SCANLINE_AA_INCLUDED +#define AGG_RASTERIZER_SCANLINE_AA_INCLUDED + +#include "agg_rasterizer_cells_aa.h" +#include "agg_rasterizer_sl_clip.h" +#include "agg_rasterizer_scanline_aa_nogamma.h" +#include "agg_gamma_functions.h" + + +namespace agg +{ + //==================================================rasterizer_scanline_aa + // Polygon rasterizer that is used to render filled polygons with + // high-quality Anti-Aliasing. Internally, by default, the class uses + // integer coordinates in format 24.8, i.e. 24 bits for integer part + // and 8 bits for fractional - see poly_subpixel_shift. This class can be + // used in the following way: + // + // 1. filling_rule(filling_rule_e ft) - optional. + // + // 2. gamma() - optional. + // + // 3. reset() + // + // 4. move_to(x, y) / line_to(x, y) - make the polygon. One can create + // more than one contour, but each contour must consist of at least 3 + // vertices, i.e. move_to(x1, y1); line_to(x2, y2); line_to(x3, y3); + // is the absolute minimum of vertices that define a triangle. + // The algorithm does not check either the number of vertices nor + // coincidence of their coordinates, but in the worst case it just + // won't draw anything. + // The orger of the vertices (clockwise or counterclockwise) + // is important when using the non-zero filling rule (fill_non_zero). + // In this case the vertex order of all the contours must be the same + // if you want your intersecting polygons to be without "holes". + // You actually can use different vertices order. If the contours do not + // intersect each other the order is not important anyway. If they do, + // contours with the same vertex order will be rendered without "holes" + // while the intersecting contours with different orders will have "holes". + // + // filling_rule() and gamma() can be called anytime before "sweeping". + //------------------------------------------------------------------------ + template<class Clip=rasterizer_sl_clip_int> class rasterizer_scanline_aa + { + enum status + { + status_initial, + status_move_to, + status_line_to, + status_closed + }; + + 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_scanline_aa(unsigned cell_block_limit=1024) : + m_outline(cell_block_limit), + m_clipper(), + m_filling_rule(fill_non_zero), + m_auto_close(true), + m_start_x(0), + m_start_y(0), + m_status(status_initial) + { + int i; + for(i = 0; i < aa_scale; i++) m_gamma[i] = i; + } + + //-------------------------------------------------------------------- + template<class GammaF> + rasterizer_scanline_aa(const GammaF& gamma_function, unsigned cell_block_limit) : + m_outline(cell_block_limit), + m_clipper(m_outline), + m_filling_rule(fill_non_zero), + m_auto_close(true), + m_start_x(0), + m_start_y(0), + m_status(status_initial) + { + gamma(gamma_function); + } + + //-------------------------------------------------------------------- + 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 auto_close(bool flag) { m_auto_close = flag; } + + //-------------------------------------------------------------------- + template<class GammaF> void gamma(const GammaF& gamma_function) + { + int i; + for(i = 0; i < aa_scale; i++) + { + m_gamma[i] = uround(gamma_function(double(i) / aa_mask) * aa_mask); + } + } + + //-------------------------------------------------------------------- + unsigned apply_gamma(unsigned cover) const + { + return m_gamma[cover]; + } + + //-------------------------------------------------------------------- + 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 close_polygon(); + void add_vertex(double x, double y, unsigned cmd); + + void edge(int x1, int y1, int x2, int y2); + void edge_d(double x1, double y1, double x2, double y2); + + //------------------------------------------------------------------- + template<class VertexSource> + void add_path(VertexSource& vs, unsigned path_id=0) + { + double x; + double y; + + unsigned cmd; + vs.rewind(path_id); + if(m_outline.sorted()) reset(); + while(!is_stop(cmd = vs.vertex(&x, &y))) + { + add_vertex(x, y, cmd); + } + } + + //-------------------------------------------------------------------- + int min_x() const { return m_outline.min_x(); } + 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(); } + + //-------------------------------------------------------------------- + void sort(); + bool rewind_scanlines(); + bool navigate_scanline(int y); + + //-------------------------------------------------------------------- + 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 m_gamma[cover]; + } + + //-------------------------------------------------------------------- + template<class Scanline> bool sweep_scanline(Scanline& sl) + { + for(;;) + { + if(m_scan_y > m_outline.max_y()) return false; + sl.reset_spans(); + unsigned num_cells = m_outline.scanline_num_cells(m_scan_y); + const cell_aa* const* cells = m_outline.scanline_cells(m_scan_y); + int cover = 0; + + while(num_cells) + { + const cell_aa* cur_cell = *cells; + int x = cur_cell->x; + int area = cur_cell->area; + unsigned alpha; + + cover += cur_cell->cover; + + //accumulate all cells with the same X + while(--num_cells) + { + cur_cell = *++cells; + if(cur_cell->x != x) break; + area += cur_cell->area; + cover += cur_cell->cover; + } + + if(area) + { + alpha = calculate_alpha((cover << (poly_subpixel_shift + 1)) - area); + if(alpha) + { + sl.add_cell(x, alpha); + } + x++; + } + + if(num_cells && cur_cell->x > x) + { + alpha = calculate_alpha(cover << (poly_subpixel_shift + 1)); + if(alpha) + { + sl.add_span(x, cur_cell->x - x, alpha); + } + } + } + + if(sl.num_spans()) break; + ++m_scan_y; + } + + sl.finalize(m_scan_y); + ++m_scan_y; + return true; + } + + //-------------------------------------------------------------------- + bool hit_test(int tx, int ty); + + + private: + //-------------------------------------------------------------------- + // Disable copying + rasterizer_scanline_aa(const rasterizer_scanline_aa<Clip>&); + const rasterizer_scanline_aa<Clip>& + operator = (const rasterizer_scanline_aa<Clip>&); + + private: + rasterizer_cells_aa<cell_aa> m_outline; + clip_type m_clipper; + int m_gamma[aa_scale]; + filling_rule_e m_filling_rule; + bool m_auto_close; + coord_type m_start_x; + coord_type m_start_y; + unsigned m_status; + int m_scan_y; + }; + + + + + + + + + + + + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_scanline_aa<Clip>::reset() + { + m_outline.reset(); + m_status = status_initial; + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_scanline_aa<Clip>::filling_rule(filling_rule_e filling_rule) + { + m_filling_rule = filling_rule; + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_scanline_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_scanline_aa<Clip>::reset_clipping() + { + reset(); + m_clipper.reset_clipping(); + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_scanline_aa<Clip>::close_polygon() + { + if(m_status == status_line_to) + { + m_clipper.line_to(m_outline, m_start_x, m_start_y); + m_status = status_closed; + } + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_scanline_aa<Clip>::move_to(int x, int y) + { + if(m_outline.sorted()) reset(); + if(m_auto_close) close_polygon(); + m_clipper.move_to(m_start_x = conv_type::downscale(x), + m_start_y = conv_type::downscale(y)); + m_status = status_move_to; + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_scanline_aa<Clip>::line_to(int x, int y) + { + m_clipper.line_to(m_outline, + conv_type::downscale(x), + conv_type::downscale(y)); + m_status = status_line_to; + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_scanline_aa<Clip>::move_to_d(double x, double y) + { + if(m_outline.sorted()) reset(); + if(m_auto_close) close_polygon(); + m_clipper.move_to(m_start_x = conv_type::upscale(x), + m_start_y = conv_type::upscale(y)); + m_status = status_move_to; + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_scanline_aa<Clip>::line_to_d(double x, double y) + { + m_clipper.line_to(m_outline, + conv_type::upscale(x), + conv_type::upscale(y)); + m_status = status_line_to; + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_scanline_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)) + { + close_polygon(); + } + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_scanline_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)); + m_status = status_move_to; + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_scanline_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)); + m_status = status_move_to; + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_scanline_aa<Clip>::sort() + { + if(m_auto_close) close_polygon(); + m_outline.sort_cells(); + } + + //------------------------------------------------------------------------ + template<class Clip> + AGG_INLINE bool rasterizer_scanline_aa<Clip>::rewind_scanlines() + { + if(m_auto_close) close_polygon(); + m_outline.sort_cells(); + if(m_outline.total_cells() == 0) + { + return false; + } + m_scan_y = m_outline.min_y(); + return true; + } + + + //------------------------------------------------------------------------ + template<class Clip> + AGG_INLINE bool rasterizer_scanline_aa<Clip>::navigate_scanline(int y) + { + if(m_auto_close) close_polygon(); + m_outline.sort_cells(); + if(m_outline.total_cells() == 0 || + y < m_outline.min_y() || + y > m_outline.max_y()) + { + return false; + } + m_scan_y = y; + return true; + } + + //------------------------------------------------------------------------ + template<class Clip> + bool rasterizer_scanline_aa<Clip>::hit_test(int tx, int ty) + { + if(!navigate_scanline(ty)) return false; + scanline_hit_test sl(tx); + sweep_scanline(sl); + return sl.hit(); + } + + + +} + + + +#endif + diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rasterizer_scanline_aa_nogamma.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rasterizer_scanline_aa_nogamma.h new file mode 100644 index 00000000000..7729b3359a1 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rasterizer_scanline_aa_nogamma.h @@ -0,0 +1,482 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +//---------------------------------------------------------------------------- +// +// The author gratefully acknowleges the support of David Turner, +// Robert Wilhelm, and Werner Lemberg - the authors of the FreeType +// libray - in producing this work. See http://www.freetype.org for details. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- +// +// Adaptation for 32-bit screen coordinates has been sponsored by +// Liberty Technology Systems, Inc., visit http://lib-sys.com +// +// Liberty Technology Systems, Inc. is the provider of +// PostScript and PDF technology for software developers. +// +//---------------------------------------------------------------------------- +#ifndef AGG_RASTERIZER_SCANLINE_AA_NOGAMMA_INCLUDED +#define AGG_RASTERIZER_SCANLINE_AA_NOGAMMA_INCLUDED + +#include "agg_rasterizer_cells_aa.h" +#include "agg_rasterizer_sl_clip.h" + + +namespace agg +{ + + + //-----------------------------------------------------------------cell_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_aa + { + int x; + int y; + int cover; + int area; + + void initial() + { + x = 0x7FFFFFFF; + y = 0x7FFFFFFF; + cover = 0; + area = 0; + } + + void style(const cell_aa&) {} + + int not_equal(int ex, int ey, const cell_aa&) const + { + return ex != x || ey != y; + } + }; + + + //==================================================rasterizer_scanline_aa_nogamma + // Polygon rasterizer that is used to render filled polygons with + // high-quality Anti-Aliasing. Internally, by default, the class uses + // integer coordinates in format 24.8, i.e. 24 bits for integer part + // and 8 bits for fractional - see poly_subpixel_shift. This class can be + // used in the following way: + // + // 1. filling_rule(filling_rule_e ft) - optional. + // + // 2. gamma() - optional. + // + // 3. reset() + // + // 4. move_to(x, y) / line_to(x, y) - make the polygon. One can create + // more than one contour, but each contour must consist of at least 3 + // vertices, i.e. move_to(x1, y1); line_to(x2, y2); line_to(x3, y3); + // is the absolute minimum of vertices that define a triangle. + // The algorithm does not check either the number of vertices nor + // coincidence of their coordinates, but in the worst case it just + // won't draw anything. + // The orger of the vertices (clockwise or counterclockwise) + // is important when using the non-zero filling rule (fill_non_zero). + // In this case the vertex order of all the contours must be the same + // if you want your intersecting polygons to be without "holes". + // You actually can use different vertices order. If the contours do not + // intersect each other the order is not important anyway. If they do, + // contours with the same vertex order will be rendered without "holes" + // while the intersecting contours with different orders will have "holes". + // + // filling_rule() and gamma() can be called anytime before "sweeping". + //------------------------------------------------------------------------ + template<class Clip=rasterizer_sl_clip_int> class rasterizer_scanline_aa_nogamma + { + enum status + { + status_initial, + status_move_to, + status_line_to, + status_closed + }; + + 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_scanline_aa_nogamma(unsigned cell_block_limit=1024) : + m_outline(cell_block_limit), + m_clipper(), + m_filling_rule(fill_non_zero), + m_auto_close(true), + m_start_x(0), + m_start_y(0), + m_status(status_initial) + { + } + + //-------------------------------------------------------------------- + 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 auto_close(bool flag) { m_auto_close = flag; } + + //-------------------------------------------------------------------- + unsigned apply_gamma(unsigned cover) const + { + return cover; + } + + //-------------------------------------------------------------------- + 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 close_polygon(); + void add_vertex(double x, double y, unsigned cmd); + + void edge(int x1, int y1, int x2, int y2); + void edge_d(double x1, double y1, double x2, double y2); + + //------------------------------------------------------------------- + template<class VertexSource> + void add_path(VertexSource& vs, unsigned path_id=0) + { + double x; + double y; + + unsigned cmd; + vs.rewind(path_id); + if(m_outline.sorted()) reset(); + while(!is_stop(cmd = vs.vertex(&x, &y))) + { + add_vertex(x, y, cmd); + } + } + + //-------------------------------------------------------------------- + int min_x() const { return m_outline.min_x(); } + 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(); } + + //-------------------------------------------------------------------- + void sort(); + bool rewind_scanlines(); + bool navigate_scanline(int y); + + //-------------------------------------------------------------------- + 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; + } + + //-------------------------------------------------------------------- + template<class Scanline> bool sweep_scanline(Scanline& sl) + { + for(;;) + { + if(m_scan_y > m_outline.max_y()) return false; + sl.reset_spans(); + unsigned num_cells = m_outline.scanline_num_cells(m_scan_y); + const cell_aa* const* cells = m_outline.scanline_cells(m_scan_y); + int cover = 0; + + while(num_cells) + { + const cell_aa* cur_cell = *cells; + int x = cur_cell->x; + int area = cur_cell->area; + unsigned alpha; + + cover += cur_cell->cover; + + //accumulate all cells with the same X + while(--num_cells) + { + cur_cell = *++cells; + if(cur_cell->x != x) break; + area += cur_cell->area; + cover += cur_cell->cover; + } + + if(area) + { + alpha = calculate_alpha((cover << (poly_subpixel_shift + 1)) - area); + if(alpha) + { + sl.add_cell(x, alpha); + } + x++; + } + + if(num_cells && cur_cell->x > x) + { + alpha = calculate_alpha(cover << (poly_subpixel_shift + 1)); + if(alpha) + { + sl.add_span(x, cur_cell->x - x, alpha); + } + } + } + + if(sl.num_spans()) break; + ++m_scan_y; + } + + sl.finalize(m_scan_y); + ++m_scan_y; + return true; + } + + //-------------------------------------------------------------------- + bool hit_test(int tx, int ty); + + + private: + //-------------------------------------------------------------------- + // Disable copying + rasterizer_scanline_aa_nogamma(const rasterizer_scanline_aa_nogamma<Clip>&); + const rasterizer_scanline_aa_nogamma<Clip>& + operator = (const rasterizer_scanline_aa_nogamma<Clip>&); + + private: + rasterizer_cells_aa<cell_aa> m_outline; + clip_type m_clipper; + filling_rule_e m_filling_rule; + bool m_auto_close; + coord_type m_start_x; + coord_type m_start_y; + unsigned m_status; + int m_scan_y; + }; + + + + + + + + + + + + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_scanline_aa_nogamma<Clip>::reset() + { + m_outline.reset(); + m_status = status_initial; + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_scanline_aa_nogamma<Clip>::filling_rule(filling_rule_e filling_rule) + { + m_filling_rule = filling_rule; + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_scanline_aa_nogamma<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_scanline_aa_nogamma<Clip>::reset_clipping() + { + reset(); + m_clipper.reset_clipping(); + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_scanline_aa_nogamma<Clip>::close_polygon() + { + if(m_status == status_line_to) + { + m_clipper.line_to(m_outline, m_start_x, m_start_y); + m_status = status_closed; + } + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_scanline_aa_nogamma<Clip>::move_to(int x, int y) + { + if(m_outline.sorted()) reset(); + if(m_auto_close) close_polygon(); + m_clipper.move_to(m_start_x = conv_type::downscale(x), + m_start_y = conv_type::downscale(y)); + m_status = status_move_to; + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_scanline_aa_nogamma<Clip>::line_to(int x, int y) + { + m_clipper.line_to(m_outline, + conv_type::downscale(x), + conv_type::downscale(y)); + m_status = status_line_to; + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_scanline_aa_nogamma<Clip>::move_to_d(double x, double y) + { + if(m_outline.sorted()) reset(); + if(m_auto_close) close_polygon(); + m_clipper.move_to(m_start_x = conv_type::upscale(x), + m_start_y = conv_type::upscale(y)); + m_status = status_move_to; + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_scanline_aa_nogamma<Clip>::line_to_d(double x, double y) + { + m_clipper.line_to(m_outline, + conv_type::upscale(x), + conv_type::upscale(y)); + m_status = status_line_to; + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_scanline_aa_nogamma<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)) + { + close_polygon(); + } + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_scanline_aa_nogamma<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)); + m_status = status_move_to; + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_scanline_aa_nogamma<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)); + m_status = status_move_to; + } + + //------------------------------------------------------------------------ + template<class Clip> + void rasterizer_scanline_aa_nogamma<Clip>::sort() + { + if(m_auto_close) close_polygon(); + m_outline.sort_cells(); + } + + //------------------------------------------------------------------------ + template<class Clip> + AGG_INLINE bool rasterizer_scanline_aa_nogamma<Clip>::rewind_scanlines() + { + if(m_auto_close) close_polygon(); + m_outline.sort_cells(); + if(m_outline.total_cells() == 0) + { + return false; + } + m_scan_y = m_outline.min_y(); + return true; + } + + + //------------------------------------------------------------------------ + template<class Clip> + AGG_INLINE bool rasterizer_scanline_aa_nogamma<Clip>::navigate_scanline(int y) + { + if(m_auto_close) close_polygon(); + m_outline.sort_cells(); + if(m_outline.total_cells() == 0 || + y < m_outline.min_y() || + y > m_outline.max_y()) + { + return false; + } + m_scan_y = y; + return true; + } + + //------------------------------------------------------------------------ + template<class Clip> + bool rasterizer_scanline_aa_nogamma<Clip>::hit_test(int tx, int ty) + { + if(!navigate_scanline(ty)) return false; + scanline_hit_test sl(tx); + sweep_scanline(sl); + return sl.hit(); + } + + + +} + + + +#endif + diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rasterizer_sl_clip.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rasterizer_sl_clip.h new file mode 100644 index 00000000000..e7ba065acce --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rasterizer_sl_clip.h @@ -0,0 +1,351 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com) +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- +#ifndef AGG_RASTERIZER_SL_CLIP_INCLUDED +#define AGG_RASTERIZER_SL_CLIP_INCLUDED + +#include "agg_clip_liang_barsky.h" + +namespace agg +{ + //--------------------------------------------------------poly_max_coord_e + enum poly_max_coord_e + { + poly_max_coord = (1 << 30) - 1 //----poly_max_coord + }; + + //------------------------------------------------------------ras_conv_int + struct ras_conv_int + { + typedef int coord_type; + static AGG_INLINE int mul_div(double a, double b, double c) + { + return iround(a * b / c); + } + static int xi(int v) { return v; } + static int yi(int v) { return v; } + static int upscale(double v) { return iround(v * poly_subpixel_scale); } + static int downscale(int v) { return v; } + }; + + //--------------------------------------------------------ras_conv_int_sat + struct ras_conv_int_sat + { + typedef int coord_type; + static AGG_INLINE int mul_div(double a, double b, double c) + { + return saturation<poly_max_coord>::iround(a * b / c); + } + static int xi(int v) { return v; } + static int yi(int v) { return v; } + static int upscale(double v) + { + return saturation<poly_max_coord>::iround(v * poly_subpixel_scale); + } + static int downscale(int v) { return v; } + }; + + //---------------------------------------------------------ras_conv_int_3x + struct ras_conv_int_3x + { + typedef int coord_type; + static AGG_INLINE int mul_div(double a, double b, double c) + { + return iround(a * b / c); + } + static int xi(int v) { return v * 3; } + static int yi(int v) { return v; } + static int upscale(double v) { return iround(v * poly_subpixel_scale); } + static int downscale(int v) { return v; } + }; + + //-----------------------------------------------------------ras_conv_dbl + struct ras_conv_dbl + { + typedef double coord_type; + static AGG_INLINE double mul_div(double a, double b, double c) + { + return a * b / c; + } + static int xi(double v) { return iround(v * poly_subpixel_scale); } + static int yi(double v) { return iround(v * poly_subpixel_scale); } + static double upscale(double v) { return v; } + static double downscale(int v) { return v / double(poly_subpixel_scale); } + }; + + //--------------------------------------------------------ras_conv_dbl_3x + struct ras_conv_dbl_3x + { + typedef double coord_type; + static AGG_INLINE double mul_div(double a, double b, double c) + { + return a * b / c; + } + static int xi(double v) { return iround(v * poly_subpixel_scale * 3); } + static int yi(double v) { return iround(v * poly_subpixel_scale); } + static double upscale(double v) { return v; } + static double downscale(int v) { return v / double(poly_subpixel_scale); } + }; + + + + + + //------------------------------------------------------rasterizer_sl_clip + template<class Conv> class rasterizer_sl_clip + { + public: + typedef Conv conv_type; + typedef typename Conv::coord_type coord_type; + typedef rect_base<coord_type> rect_type; + + //-------------------------------------------------------------------- + rasterizer_sl_clip() : + m_clip_box(0,0,0,0), + m_x1(0), + m_y1(0), + m_f1(0), + m_clipping(false) + {} + + //-------------------------------------------------------------------- + void reset_clipping() + { + m_clipping = false; + } + + //-------------------------------------------------------------------- + void clip_box(coord_type x1, coord_type y1, coord_type x2, coord_type y2) + { + m_clip_box = rect_type(x1, y1, x2, y2); + m_clip_box.normalize(); + m_clipping = true; + } + + //-------------------------------------------------------------------- + void move_to(coord_type x1, coord_type y1) + { + m_x1 = x1; + m_y1 = y1; + if(m_clipping) m_f1 = clipping_flags(x1, y1, m_clip_box); + } + + private: + //------------------------------------------------------------------------ + template<class Rasterizer> + AGG_INLINE void line_clip_y(Rasterizer& ras, + coord_type x1, coord_type y1, + coord_type x2, coord_type y2, + unsigned f1, unsigned f2) const + { + f1 &= 10; + f2 &= 10; + if((f1 | f2) == 0) + { + // Fully visible + ras.line(Conv::xi(x1), Conv::yi(y1), Conv::xi(x2), Conv::yi(y2)); + } + else + { + if(f1 == f2) + { + // Invisible by Y + return; + } + + coord_type tx1 = x1; + coord_type ty1 = y1; + coord_type tx2 = x2; + coord_type ty2 = y2; + + if(f1 & 8) // y1 < clip.y1 + { + tx1 = x1 + Conv::mul_div(m_clip_box.y1-y1, x2-x1, y2-y1); + ty1 = m_clip_box.y1; + } + + if(f1 & 2) // y1 > clip.y2 + { + tx1 = x1 + Conv::mul_div(m_clip_box.y2-y1, x2-x1, y2-y1); + ty1 = m_clip_box.y2; + } + + if(f2 & 8) // y2 < clip.y1 + { + tx2 = x1 + Conv::mul_div(m_clip_box.y1-y1, x2-x1, y2-y1); + ty2 = m_clip_box.y1; + } + + if(f2 & 2) // y2 > clip.y2 + { + tx2 = x1 + Conv::mul_div(m_clip_box.y2-y1, x2-x1, y2-y1); + ty2 = m_clip_box.y2; + } + ras.line(Conv::xi(tx1), Conv::yi(ty1), + Conv::xi(tx2), Conv::yi(ty2)); + } + } + + + public: + //-------------------------------------------------------------------- + template<class Rasterizer> + void line_to(Rasterizer& ras, coord_type x2, coord_type y2) + { + if(m_clipping) + { + unsigned f2 = clipping_flags(x2, y2, m_clip_box); + + if((m_f1 & 10) == (f2 & 10) && (m_f1 & 10) != 0) + { + // Invisible by Y + m_x1 = x2; + m_y1 = y2; + m_f1 = f2; + return; + } + + coord_type x1 = m_x1; + coord_type y1 = m_y1; + unsigned f1 = m_f1; + coord_type y3, y4; + unsigned f3, f4; + + switch(((f1 & 5) << 1) | (f2 & 5)) + { + case 0: // Visible by X + line_clip_y(ras, x1, y1, x2, y2, f1, f2); + break; + + case 1: // x2 > clip.x2 + y3 = y1 + Conv::mul_div(m_clip_box.x2-x1, y2-y1, x2-x1); + f3 = clipping_flags_y(y3, m_clip_box); + line_clip_y(ras, x1, y1, m_clip_box.x2, y3, f1, f3); + line_clip_y(ras, m_clip_box.x2, y3, m_clip_box.x2, y2, f3, f2); + break; + + case 2: // x1 > clip.x2 + y3 = y1 + Conv::mul_div(m_clip_box.x2-x1, y2-y1, x2-x1); + f3 = clipping_flags_y(y3, m_clip_box); + line_clip_y(ras, m_clip_box.x2, y1, m_clip_box.x2, y3, f1, f3); + line_clip_y(ras, m_clip_box.x2, y3, x2, y2, f3, f2); + break; + + case 3: // x1 > clip.x2 && x2 > clip.x2 + line_clip_y(ras, m_clip_box.x2, y1, m_clip_box.x2, y2, f1, f2); + break; + + case 4: // x2 < clip.x1 + y3 = y1 + Conv::mul_div(m_clip_box.x1-x1, y2-y1, x2-x1); + f3 = clipping_flags_y(y3, m_clip_box); + line_clip_y(ras, x1, y1, m_clip_box.x1, y3, f1, f3); + line_clip_y(ras, m_clip_box.x1, y3, m_clip_box.x1, y2, f3, f2); + break; + + case 6: // x1 > clip.x2 && x2 < clip.x1 + y3 = y1 + Conv::mul_div(m_clip_box.x2-x1, y2-y1, x2-x1); + y4 = y1 + Conv::mul_div(m_clip_box.x1-x1, y2-y1, x2-x1); + f3 = clipping_flags_y(y3, m_clip_box); + f4 = clipping_flags_y(y4, m_clip_box); + line_clip_y(ras, m_clip_box.x2, y1, m_clip_box.x2, y3, f1, f3); + line_clip_y(ras, m_clip_box.x2, y3, m_clip_box.x1, y4, f3, f4); + line_clip_y(ras, m_clip_box.x1, y4, m_clip_box.x1, y2, f4, f2); + break; + + case 8: // x1 < clip.x1 + y3 = y1 + Conv::mul_div(m_clip_box.x1-x1, y2-y1, x2-x1); + f3 = clipping_flags_y(y3, m_clip_box); + line_clip_y(ras, m_clip_box.x1, y1, m_clip_box.x1, y3, f1, f3); + line_clip_y(ras, m_clip_box.x1, y3, x2, y2, f3, f2); + break; + + case 9: // x1 < clip.x1 && x2 > clip.x2 + y3 = y1 + Conv::mul_div(m_clip_box.x1-x1, y2-y1, x2-x1); + y4 = y1 + Conv::mul_div(m_clip_box.x2-x1, y2-y1, x2-x1); + f3 = clipping_flags_y(y3, m_clip_box); + f4 = clipping_flags_y(y4, m_clip_box); + line_clip_y(ras, m_clip_box.x1, y1, m_clip_box.x1, y3, f1, f3); + line_clip_y(ras, m_clip_box.x1, y3, m_clip_box.x2, y4, f3, f4); + line_clip_y(ras, m_clip_box.x2, y4, m_clip_box.x2, y2, f4, f2); + break; + + case 12: // x1 < clip.x1 && x2 < clip.x1 + line_clip_y(ras, m_clip_box.x1, y1, m_clip_box.x1, y2, f1, f2); + break; + } + m_f1 = f2; + } + else + { + ras.line(Conv::xi(m_x1), Conv::yi(m_y1), + Conv::xi(x2), Conv::yi(y2)); + } + m_x1 = x2; + m_y1 = y2; + } + + + private: + rect_type m_clip_box; + coord_type m_x1; + coord_type m_y1; + unsigned m_f1; + bool m_clipping; + }; + + + + + //---------------------------------------------------rasterizer_sl_no_clip + class rasterizer_sl_no_clip + { + public: + typedef ras_conv_int conv_type; + typedef int coord_type; + + rasterizer_sl_no_clip() : m_x1(0), m_y1(0) {} + + void reset_clipping() {} + void clip_box(coord_type x1, coord_type y1, coord_type x2, coord_type y2) {} + void move_to(coord_type x1, coord_type y1) { m_x1 = x1; m_y1 = y1; } + + template<class Rasterizer> + void line_to(Rasterizer& ras, coord_type x2, coord_type y2) + { + ras.line(m_x1, m_y1, x2, y2); + m_x1 = x2; + m_y1 = y2; + } + + private: + int m_x1, m_y1; + }; + + + // -----rasterizer_sl_clip_int + // -----rasterizer_sl_clip_int_sat + // -----rasterizer_sl_clip_int_3x + // -----rasterizer_sl_clip_dbl + // -----rasterizer_sl_clip_dbl_3x + //------------------------------------------------------------------------ + typedef rasterizer_sl_clip<ras_conv_int> rasterizer_sl_clip_int; + typedef rasterizer_sl_clip<ras_conv_int_sat> rasterizer_sl_clip_int_sat; + typedef rasterizer_sl_clip<ras_conv_int_3x> rasterizer_sl_clip_int_3x; + typedef rasterizer_sl_clip<ras_conv_dbl> rasterizer_sl_clip_dbl; + typedef rasterizer_sl_clip<ras_conv_dbl_3x> rasterizer_sl_clip_dbl_3x; + + +} + +#endif diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_base.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_base.h new file mode 100644 index 00000000000..527c62f7891 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_base.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 +//---------------------------------------------------------------------------- +// +// class renderer_base +// +//---------------------------------------------------------------------------- + +#ifndef AGG_RENDERER_BASE_INCLUDED +#define AGG_RENDERER_BASE_INCLUDED + +#include "agg_basics.h" +#include "agg_rendering_buffer.h" + +namespace agg +{ + + //-----------------------------------------------------------renderer_base + template<class PixelFormat> class renderer_base + { + public: + typedef PixelFormat pixfmt_type; + typedef typename pixfmt_type::color_type color_type; + typedef typename pixfmt_type::row_data row_data; + + //-------------------------------------------------------------------- + renderer_base() : m_ren(0), m_clip_box(1, 1, 0, 0) {} + explicit renderer_base(pixfmt_type& ren) : + m_ren(&ren), + m_clip_box(0, 0, ren.width() - 1, ren.height() - 1) + {} + void attach(pixfmt_type& ren) + { + m_ren = &ren; + m_clip_box = rect_i(0, 0, ren.width() - 1, ren.height() - 1); + } + + //-------------------------------------------------------------------- + const pixfmt_type& ren() const { return *m_ren; } + pixfmt_type& ren() { return *m_ren; } + + //-------------------------------------------------------------------- + unsigned width() const { return m_ren->width(); } + unsigned height() const { return m_ren->height(); } + + //-------------------------------------------------------------------- + bool 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_box = cb; + return true; + } + m_clip_box.x1 = 1; + m_clip_box.y1 = 1; + m_clip_box.x2 = 0; + m_clip_box.y2 = 0; + return false; + } + + //-------------------------------------------------------------------- + void reset_clipping(bool visibility) + { + if(visibility) + { + m_clip_box.x1 = 0; + m_clip_box.y1 = 0; + m_clip_box.x2 = width() - 1; + m_clip_box.y2 = height() - 1; + } + else + { + m_clip_box.x1 = 1; + m_clip_box.y1 = 1; + m_clip_box.x2 = 0; + m_clip_box.y2 = 0; + } + } + + //-------------------------------------------------------------------- + void clip_box_naked(int x1, int y1, int x2, int y2) + { + m_clip_box.x1 = x1; + m_clip_box.y1 = y1; + m_clip_box.x2 = x2; + m_clip_box.y2 = y2; + } + + //-------------------------------------------------------------------- + bool inbox(int x, int y) const + { + return x >= m_clip_box.x1 && y >= m_clip_box.y1 && + x <= m_clip_box.x2 && y <= m_clip_box.y2; + } + + //-------------------------------------------------------------------- + const rect_i& clip_box() const { return m_clip_box; } + int xmin() const { return m_clip_box.x1; } + int ymin() const { return m_clip_box.y1; } + int xmax() const { return m_clip_box.x2; } + int ymax() const { return m_clip_box.y2; } + + //-------------------------------------------------------------------- + const rect_i& bounding_clip_box() const { return m_clip_box; } + int bounding_xmin() const { return m_clip_box.x1; } + int bounding_ymin() const { return m_clip_box.y1; } + int bounding_xmax() const { return m_clip_box.x2; } + int bounding_ymax() const { return m_clip_box.y2; } + + //-------------------------------------------------------------------- + void clear(const color_type& c) + { + unsigned y; + if(width()) + { + for(y = 0; y < height(); y++) + { + m_ren->copy_hline(0, y, width(), c); + } + } + } + + + //-------------------------------------------------------------------- + void fill(const color_type& c) + { + unsigned y; + if(width()) + { + for(y = 0; y < height(); y++) + { + m_ren->blend_hline(0, y, width(), c, cover_mask); + } + } + } + + //-------------------------------------------------------------------- + void copy_pixel(int x, int y, const color_type& c) + { + if(inbox(x, y)) + { + m_ren->copy_pixel(x, y, c); + } + } + + //-------------------------------------------------------------------- + void blend_pixel(int x, int y, const color_type& c, cover_type cover) + { + if(inbox(x, y)) + { + m_ren->blend_pixel(x, y, c, cover); + } + } + + //-------------------------------------------------------------------- + color_type pixel(int x, int y) const + { + return inbox(x, y) ? + m_ren->pixel(x, y) : + color_type::no_color(); + } + + //-------------------------------------------------------------------- + void copy_hline(int x1, int y, int x2, const color_type& c) + { + if(x1 > x2) { int t = x2; x2 = x1; x1 = t; } + if(y > ymax()) return; + if(y < ymin()) return; + if(x1 > xmax()) return; + if(x2 < xmin()) return; + + if(x1 < xmin()) x1 = xmin(); + if(x2 > xmax()) x2 = xmax(); + + m_ren->copy_hline(x1, y, x2 - x1 + 1, c); + } + + //-------------------------------------------------------------------- + void copy_vline(int x, int y1, int y2, const color_type& c) + { + if(y1 > y2) { int t = y2; y2 = y1; y1 = t; } + if(x > xmax()) return; + if(x < xmin()) return; + if(y1 > ymax()) return; + if(y2 < ymin()) return; + + if(y1 < ymin()) y1 = ymin(); + if(y2 > ymax()) y2 = ymax(); + + m_ren->copy_vline(x, y1, y2 - y1 + 1, c); + } + + //-------------------------------------------------------------------- + void blend_hline(int x1, int y, int x2, + const color_type& c, cover_type cover) + { + if(x1 > x2) { int t = x2; x2 = x1; x1 = t; } + if(y > ymax()) return; + if(y < ymin()) return; + if(x1 > xmax()) return; + if(x2 < xmin()) return; + + if(x1 < xmin()) x1 = xmin(); + if(x2 > xmax()) x2 = xmax(); + + m_ren->blend_hline(x1, y, x2 - x1 + 1, c, cover); + } + + //-------------------------------------------------------------------- + void blend_vline(int x, int y1, int y2, + const color_type& c, cover_type cover) + { + if(y1 > y2) { int t = y2; y2 = y1; y1 = t; } + if(x > xmax()) return; + if(x < xmin()) return; + if(y1 > ymax()) return; + if(y2 < ymin()) return; + + if(y1 < ymin()) y1 = ymin(); + if(y2 > ymax()) y2 = ymax(); + + m_ren->blend_vline(x, y1, y2 - y1 + 1, c, cover); + } + + + //-------------------------------------------------------------------- + void copy_bar(int x1, int y1, int x2, int y2, const color_type& c) + { + rect_i rc(x1, y1, x2, y2); + rc.normalize(); + if(rc.clip(clip_box())) + { + int y; + for(y = rc.y1; y <= rc.y2; y++) + { + m_ren->copy_hline(rc.x1, y, unsigned(rc.x2 - rc.x1 + 1), c); + } + } + } + + //-------------------------------------------------------------------- + void blend_bar(int x1, int y1, int x2, int y2, + const color_type& c, cover_type cover) + { + rect_i rc(x1, y1, x2, y2); + rc.normalize(); + if(rc.clip(clip_box())) + { + int y; + for(y = rc.y1; y <= rc.y2; y++) + { + m_ren->blend_hline(rc.x1, + y, + unsigned(rc.x2 - rc.x1 + 1), + c, + cover); + } + } + } + + //-------------------------------------------------------------------- + void blend_solid_hspan(int x, int y, int len, + const color_type& c, + const cover_type* covers) + { + if(y > ymax()) return; + if(y < ymin()) return; + + if(x < xmin()) + { + len -= xmin() - x; + if(len <= 0) return; + covers += xmin() - x; + x = xmin(); + } + if(x + len > xmax()) + { + len = xmax() - x + 1; + if(len <= 0) return; + } + m_ren->blend_solid_hspan(x, y, len, c, covers); + } + + //-------------------------------------------------------------------- + void blend_solid_vspan(int x, int y, int len, + const color_type& c, + const cover_type* covers) + { + if(x > xmax()) return; + if(x < xmin()) return; + + if(y < ymin()) + { + len -= ymin() - y; + if(len <= 0) return; + covers += ymin() - y; + y = ymin(); + } + if(y + len > ymax()) + { + len = ymax() - y + 1; + if(len <= 0) return; + } + m_ren->blend_solid_vspan(x, y, len, c, covers); + } + + + //-------------------------------------------------------------------- + void copy_color_hspan(int x, int y, int len, const color_type* colors) + { + if(y > ymax()) return; + if(y < ymin()) return; + + if(x < xmin()) + { + int d = xmin() - x; + len -= d; + if(len <= 0) return; + colors += d; + x = xmin(); + } + if(x + len > xmax()) + { + len = xmax() - x + 1; + if(len <= 0) return; + } + m_ren->copy_color_hspan(x, y, len, colors); + } + + + //-------------------------------------------------------------------- + void copy_color_vspan(int x, int y, int len, const color_type* colors) + { + if(x > xmax()) return; + if(x < xmin()) return; + + if(y < ymin()) + { + int d = ymin() - y; + len -= d; + if(len <= 0) return; + colors += d; + y = ymin(); + } + if(y + len > ymax()) + { + len = ymax() - y + 1; + if(len <= 0) return; + } + m_ren->copy_color_vspan(x, y, len, colors); + } + + + //-------------------------------------------------------------------- + void blend_color_hspan(int x, int y, int len, + const color_type* colors, + const cover_type* covers, + cover_type cover = agg::cover_full) + { + if(y > ymax()) return; + if(y < ymin()) return; + + if(x < xmin()) + { + int d = xmin() - x; + len -= d; + if(len <= 0) return; + if(covers) covers += d; + colors += d; + x = xmin(); + } + if(x + len > xmax()) + { + len = xmax() - x + 1; + if(len <= 0) return; + } + m_ren->blend_color_hspan(x, y, len, colors, covers, cover); + } + + //-------------------------------------------------------------------- + void blend_color_vspan(int x, int y, int len, + const color_type* colors, + const cover_type* covers, + cover_type cover = agg::cover_full) + { + if(x > xmax()) return; + if(x < xmin()) return; + + if(y < ymin()) + { + int d = ymin() - y; + len -= d; + if(len <= 0) return; + if(covers) covers += d; + colors += d; + y = ymin(); + } + if(y + len > ymax()) + { + len = ymax() - y + 1; + if(len <= 0) return; + } + m_ren->blend_color_vspan(x, y, len, colors, covers, cover); + } + + //-------------------------------------------------------------------- + rect_i clip_rect_area(rect_i& dst, rect_i& src, int wsrc, int hsrc) const + { + rect_i rc(0,0,0,0); + rect_i cb = clip_box(); + ++cb.x2; + ++cb.y2; + + if(src.x1 < 0) + { + dst.x1 -= src.x1; + src.x1 = 0; + } + if(src.y1 < 0) + { + dst.y1 -= src.y1; + src.y1 = 0; + } + + if(src.x2 > wsrc) src.x2 = wsrc; + if(src.y2 > hsrc) src.y2 = hsrc; + + if(dst.x1 < cb.x1) + { + src.x1 += cb.x1 - dst.x1; + dst.x1 = cb.x1; + } + if(dst.y1 < cb.y1) + { + src.y1 += cb.y1 - dst.y1; + dst.y1 = cb.y1; + } + + if(dst.x2 > cb.x2) dst.x2 = cb.x2; + if(dst.y2 > cb.y2) dst.y2 = cb.y2; + + rc.x2 = dst.x2 - dst.x1; + rc.y2 = dst.y2 - dst.y1; + + if(rc.x2 > src.x2 - src.x1) rc.x2 = src.x2 - src.x1; + if(rc.y2 > src.y2 - src.y1) rc.y2 = src.y2 - src.y1; + return rc; + } + + //-------------------------------------------------------------------- + template<class RenBuf> + void copy_from(const RenBuf& src, + const rect_i* rect_src_ptr = 0, + int dx = 0, + int dy = 0) + { + rect_i rsrc(0, 0, src.width(), src.height()); + if(rect_src_ptr) + { + rsrc.x1 = rect_src_ptr->x1; + rsrc.y1 = rect_src_ptr->y1; + rsrc.x2 = rect_src_ptr->x2 + 1; + rsrc.y2 = rect_src_ptr->y2 + 1; + } + + // Version with xdst, ydst (absolute positioning) + //rect_i rdst(xdst, ydst, xdst + rsrc.x2 - rsrc.x1, ydst + rsrc.y2 - rsrc.y1); + + // Version with dx, dy (relative positioning) + rect_i rdst(rsrc.x1 + dx, rsrc.y1 + dy, rsrc.x2 + dx, rsrc.y2 + dy); + + rect_i rc = clip_rect_area(rdst, rsrc, src.width(), src.height()); + + if(rc.x2 > 0) + { + int incy = 1; + if(rdst.y1 > rsrc.y1) + { + rsrc.y1 += rc.y2 - 1; + rdst.y1 += rc.y2 - 1; + incy = -1; + } + while(rc.y2 > 0) + { + m_ren->copy_from(src, + rdst.x1, rdst.y1, + rsrc.x1, rsrc.y1, + rc.x2); + rdst.y1 += incy; + rsrc.y1 += incy; + --rc.y2; + } + } + } + + //-------------------------------------------------------------------- + template<class SrcPixelFormatRenderer> + void blend_from(const SrcPixelFormatRenderer& src, + const rect_i* rect_src_ptr = 0, + int dx = 0, + int dy = 0, + cover_type cover = agg::cover_full) + { + rect_i rsrc(0, 0, src.width(), src.height()); + if(rect_src_ptr) + { + rsrc.x1 = rect_src_ptr->x1; + rsrc.y1 = rect_src_ptr->y1; + rsrc.x2 = rect_src_ptr->x2 + 1; + rsrc.y2 = rect_src_ptr->y2 + 1; + } + + // Version with xdst, ydst (absolute positioning) + //rect_i rdst(xdst, ydst, xdst + rsrc.x2 - rsrc.x1, ydst + rsrc.y2 - rsrc.y1); + + // Version with dx, dy (relative positioning) + rect_i rdst(rsrc.x1 + dx, rsrc.y1 + dy, rsrc.x2 + dx, rsrc.y2 + dy); + rect_i rc = clip_rect_area(rdst, rsrc, src.width(), src.height()); + + if(rc.x2 > 0) + { + int incy = 1; + if(rdst.y1 > rsrc.y1) + { + rsrc.y1 += rc.y2 - 1; + rdst.y1 += rc.y2 - 1; + incy = -1; + } + while(rc.y2 > 0) + { + typename SrcPixelFormatRenderer::row_data rw = src.row(rsrc.y1); + if(rw.ptr) + { + int x1src = rsrc.x1; + int x1dst = rdst.x1; + int len = rc.x2; + if(rw.x1 > x1src) + { + x1dst += rw.x1 - x1src; + len -= rw.x1 - x1src; + x1src = rw.x1; + } + if(len > 0) + { + if(x1src + len-1 > rw.x2) + { + len -= x1src + len - rw.x2 - 1; + } + if(len > 0) + { + m_ren->blend_from(src, + x1dst, rdst.y1, + x1src, rsrc.y1, + len, + cover); + } + } + } + rdst.y1 += incy; + rsrc.y1 += incy; + --rc.y2; + } + } + } + + //-------------------------------------------------------------------- + template<class SrcPixelFormatRenderer> + void blend_from_color(const SrcPixelFormatRenderer& src, + const color_type& color, + const rect_i* rect_src_ptr = 0, + int dx = 0, + int dy = 0, + cover_type cover = agg::cover_full) + { + rect_i rsrc(0, 0, src.width(), src.height()); + if(rect_src_ptr) + { + rsrc.x1 = rect_src_ptr->x1; + rsrc.y1 = rect_src_ptr->y1; + rsrc.x2 = rect_src_ptr->x2 + 1; + rsrc.y2 = rect_src_ptr->y2 + 1; + } + + // Version with xdst, ydst (absolute positioning) + //rect_i rdst(xdst, ydst, xdst + rsrc.x2 - rsrc.x1, ydst + rsrc.y2 - rsrc.y1); + + // Version with dx, dy (relative positioning) + rect_i rdst(rsrc.x1 + dx, rsrc.y1 + dy, rsrc.x2 + dx, rsrc.y2 + dy); + rect_i rc = clip_rect_area(rdst, rsrc, src.width(), src.height()); + + if(rc.x2 > 0) + { + int incy = 1; + if(rdst.y1 > rsrc.y1) + { + rsrc.y1 += rc.y2 - 1; + rdst.y1 += rc.y2 - 1; + incy = -1; + } + while(rc.y2 > 0) + { + typename SrcPixelFormatRenderer::row_data rw = src.row(rsrc.y1); + if(rw.ptr) + { + int x1src = rsrc.x1; + int x1dst = rdst.x1; + int len = rc.x2; + if(rw.x1 > x1src) + { + x1dst += rw.x1 - x1src; + len -= rw.x1 - x1src; + x1src = rw.x1; + } + if(len > 0) + { + if(x1src + len-1 > rw.x2) + { + len -= x1src + len - rw.x2 - 1; + } + if(len > 0) + { + m_ren->blend_from_color(src, + color, + x1dst, rdst.y1, + x1src, rsrc.y1, + len, + cover); + } + } + } + rdst.y1 += incy; + rsrc.y1 += incy; + --rc.y2; + } + } + } + + //-------------------------------------------------------------------- + template<class SrcPixelFormatRenderer> + void blend_from_lut(const SrcPixelFormatRenderer& src, + const color_type* color_lut, + const rect_i* rect_src_ptr = 0, + int dx = 0, + int dy = 0, + cover_type cover = agg::cover_full) + { + rect_i rsrc(0, 0, src.width(), src.height()); + if(rect_src_ptr) + { + rsrc.x1 = rect_src_ptr->x1; + rsrc.y1 = rect_src_ptr->y1; + rsrc.x2 = rect_src_ptr->x2 + 1; + rsrc.y2 = rect_src_ptr->y2 + 1; + } + + // Version with xdst, ydst (absolute positioning) + //rect_i rdst(xdst, ydst, xdst + rsrc.x2 - rsrc.x1, ydst + rsrc.y2 - rsrc.y1); + + // Version with dx, dy (relative positioning) + rect_i rdst(rsrc.x1 + dx, rsrc.y1 + dy, rsrc.x2 + dx, rsrc.y2 + dy); + rect_i rc = clip_rect_area(rdst, rsrc, src.width(), src.height()); + + if(rc.x2 > 0) + { + int incy = 1; + if(rdst.y1 > rsrc.y1) + { + rsrc.y1 += rc.y2 - 1; + rdst.y1 += rc.y2 - 1; + incy = -1; + } + while(rc.y2 > 0) + { + typename SrcPixelFormatRenderer::row_data rw = src.row(rsrc.y1); + if(rw.ptr) + { + int x1src = rsrc.x1; + int x1dst = rdst.x1; + int len = rc.x2; + if(rw.x1 > x1src) + { + x1dst += rw.x1 - x1src; + len -= rw.x1 - x1src; + x1src = rw.x1; + } + if(len > 0) + { + if(x1src + len-1 > rw.x2) + { + len -= x1src + len - rw.x2 - 1; + } + if(len > 0) + { + m_ren->blend_from_lut(src, + color_lut, + x1dst, rdst.y1, + x1src, rsrc.y1, + len, + cover); + } + } + } + rdst.y1 += incy; + rsrc.y1 += incy; + --rc.y2; + } + } + } + + private: + pixfmt_type* m_ren; + rect_i m_clip_box; + }; + + +} + +#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 00000000000..820f7530793 --- /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 00000000000..96a7d4e094e --- /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 00000000000..ee564f04d50 --- /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 00000000000..8abb9fa0bdd --- /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 00000000000..f008db7c947 --- /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 00000000000..87b43f96005 --- /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_renderer_scanline.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_scanline.h new file mode 100644 index 00000000000..6d65056c537 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_renderer_scanline.h @@ -0,0 +1,852 @@ +//---------------------------------------------------------------------------- +// 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_SCANLINE_INCLUDED +#define AGG_RENDERER_SCANLINE_INCLUDED + +#include "agg_basics.h" +#include "agg_renderer_base.h" + +namespace agg +{ + + //================================================render_scanline_aa_solid + template<class Scanline, class BaseRenderer, class ColorT> + void render_scanline_aa_solid(const Scanline& sl, + BaseRenderer& ren, + const ColorT& color) + { + int y = sl.y(); + unsigned num_spans = sl.num_spans(); + typename Scanline::const_iterator span = sl.begin(); + + for(;;) + { + int x = span->x; + if(span->len > 0) + { + ren.blend_solid_hspan(x, y, (unsigned)span->len, + color, + span->covers); + } + else + { + ren.blend_hline(x, y, (unsigned)(x - span->len - 1), + color, + *(span->covers)); + } + if(--num_spans == 0) break; + ++span; + } + } + + //===============================================render_scanlines_aa_solid + template<class Rasterizer, class Scanline, + class BaseRenderer, class ColorT> + void render_scanlines_aa_solid(Rasterizer& ras, Scanline& sl, + BaseRenderer& ren, const ColorT& color) + { + if(ras.rewind_scanlines()) + { + // Explicitly convert "color" to the BaseRenderer color type. + // For example, it can be called with color type "rgba", while + // "rgba8" is needed. Otherwise it will be implicitly + // converted in the loop many times. + //---------------------- + typename BaseRenderer::color_type ren_color(color); + + sl.reset(ras.min_x(), ras.max_x()); + while(ras.sweep_scanline(sl)) + { + //render_scanline_aa_solid(sl, ren, ren_color); + + // This code is equivalent to the above call (copy/paste). + // It's just a "manual" optimization for old compilers, + // like Microsoft Visual C++ v6.0 + //------------------------------- + int y = sl.y(); + unsigned num_spans = sl.num_spans(); + typename Scanline::const_iterator span = sl.begin(); + + for(;;) + { + int x = span->x; + if(span->len > 0) + { + ren.blend_solid_hspan(x, y, (unsigned)span->len, + ren_color, + span->covers); + } + else + { + ren.blend_hline(x, y, (unsigned)(x - span->len - 1), + ren_color, + *(span->covers)); + } + if(--num_spans == 0) break; + ++span; + } + } + } + } + + //==============================================renderer_scanline_aa_solid + template<class BaseRenderer> class renderer_scanline_aa_solid + { + public: + typedef BaseRenderer base_ren_type; + typedef typename base_ren_type::color_type color_type; + + //-------------------------------------------------------------------- + renderer_scanline_aa_solid() : m_ren(0) {} + explicit renderer_scanline_aa_solid(base_ren_type& ren) : m_ren(&ren) {} + void attach(base_ren_type& ren) + { + m_ren = &ren; + } + + //-------------------------------------------------------------------- + void color(const color_type& c) { m_color = c; } + const color_type& color() const { return m_color; } + + //-------------------------------------------------------------------- + void prepare() {} + + //-------------------------------------------------------------------- + template<class Scanline> void render(const Scanline& sl) + { + render_scanline_aa_solid(sl, *m_ren, m_color); + } + + private: + base_ren_type* m_ren; + color_type m_color; + }; + + + + + + + + + + + + + + //======================================================render_scanline_aa + template<class Scanline, class BaseRenderer, + class SpanAllocator, class SpanGenerator> + void render_scanline_aa(const Scanline& sl, BaseRenderer& ren, + SpanAllocator& alloc, SpanGenerator& span_gen) + { + int y = sl.y(); + + unsigned num_spans = sl.num_spans(); + typename Scanline::const_iterator span = sl.begin(); + for(;;) + { + int x = span->x; + int len = span->len; + const typename Scanline::cover_type* covers = span->covers; + + if(len < 0) len = -len; + typename BaseRenderer::color_type* colors = alloc.allocate(len); + span_gen.generate(colors, x, y, len); + ren.blend_color_hspan(x, y, len, colors, + (span->len < 0) ? 0 : covers, *covers); + + if(--num_spans == 0) break; + ++span; + } + } + + //=====================================================render_scanlines_aa + template<class Rasterizer, class Scanline, class BaseRenderer, + class SpanAllocator, class SpanGenerator> + void render_scanlines_aa(Rasterizer& ras, Scanline& sl, BaseRenderer& ren, + SpanAllocator& alloc, SpanGenerator& span_gen) + { + if(ras.rewind_scanlines()) + { + sl.reset(ras.min_x(), ras.max_x()); + span_gen.prepare(); + while(ras.sweep_scanline(sl)) + { + render_scanline_aa(sl, ren, alloc, span_gen); + } + } + } + + //====================================================renderer_scanline_aa + template<class BaseRenderer, class SpanAllocator, class SpanGenerator> + class renderer_scanline_aa + { + public: + typedef BaseRenderer base_ren_type; + typedef SpanAllocator alloc_type; + typedef SpanGenerator span_gen_type; + + //-------------------------------------------------------------------- + renderer_scanline_aa() : m_ren(0), m_alloc(0), m_span_gen(0) {} + renderer_scanline_aa(base_ren_type& ren, + alloc_type& alloc, + span_gen_type& span_gen) : + m_ren(&ren), + m_alloc(&alloc), + m_span_gen(&span_gen) + {} + void attach(base_ren_type& ren, + alloc_type& alloc, + span_gen_type& span_gen) + { + m_ren = &ren; + m_alloc = &alloc; + m_span_gen = &span_gen; + } + + //-------------------------------------------------------------------- + void prepare() { m_span_gen->prepare(); } + + //-------------------------------------------------------------------- + template<class Scanline> void render(const Scanline& sl) + { + render_scanline_aa(sl, *m_ren, *m_alloc, *m_span_gen); + } + + private: + base_ren_type* m_ren; + alloc_type* m_alloc; + span_gen_type* m_span_gen; + }; + + + + + + + //===============================================render_scanline_bin_solid + template<class Scanline, class BaseRenderer, class ColorT> + void render_scanline_bin_solid(const Scanline& sl, + BaseRenderer& ren, + const ColorT& color) + { + unsigned num_spans = sl.num_spans(); + typename Scanline::const_iterator span = sl.begin(); + for(;;) + { + ren.blend_hline(span->x, + sl.y(), + span->x - 1 + ((span->len < 0) ? + -span->len : + span->len), + color, + cover_full); + if(--num_spans == 0) break; + ++span; + } + } + + //==============================================render_scanlines_bin_solid + template<class Rasterizer, class Scanline, + class BaseRenderer, class ColorT> + void render_scanlines_bin_solid(Rasterizer& ras, Scanline& sl, + BaseRenderer& ren, const ColorT& color) + { + if(ras.rewind_scanlines()) + { + // Explicitly convert "color" to the BaseRenderer color type. + // For example, it can be called with color type "rgba", while + // "rgba8" is needed. Otherwise it will be implicitly + // converted in the loop many times. + //---------------------- + typename BaseRenderer::color_type ren_color(color); + + sl.reset(ras.min_x(), ras.max_x()); + while(ras.sweep_scanline(sl)) + { + //render_scanline_bin_solid(sl, ren, ren_color); + + // This code is equivalent to the above call (copy/paste). + // It's just a "manual" optimization for old compilers, + // like Microsoft Visual C++ v6.0 + //------------------------------- + unsigned num_spans = sl.num_spans(); + typename Scanline::const_iterator span = sl.begin(); + for(;;) + { + ren.blend_hline(span->x, + sl.y(), + span->x - 1 + ((span->len < 0) ? + -span->len : + span->len), + ren_color, + cover_full); + if(--num_spans == 0) break; + ++span; + } + } + } + } + + //=============================================renderer_scanline_bin_solid + template<class BaseRenderer> class renderer_scanline_bin_solid + { + public: + typedef BaseRenderer base_ren_type; + typedef typename base_ren_type::color_type color_type; + + //-------------------------------------------------------------------- + renderer_scanline_bin_solid() : m_ren(0) {} + explicit renderer_scanline_bin_solid(base_ren_type& ren) : m_ren(&ren) {} + void attach(base_ren_type& ren) + { + m_ren = &ren; + } + + //-------------------------------------------------------------------- + void color(const color_type& c) { m_color = c; } + const color_type& color() const { return m_color; } + + //-------------------------------------------------------------------- + void prepare() {} + + //-------------------------------------------------------------------- + template<class Scanline> void render(const Scanline& sl) + { + render_scanline_bin_solid(sl, *m_ren, m_color); + } + + private: + base_ren_type* m_ren; + color_type m_color; + }; + + + + + + + + + //======================================================render_scanline_bin + template<class Scanline, class BaseRenderer, + class SpanAllocator, class SpanGenerator> + void render_scanline_bin(const Scanline& sl, BaseRenderer& ren, + SpanAllocator& alloc, SpanGenerator& span_gen) + { + int y = sl.y(); + + unsigned num_spans = sl.num_spans(); + typename Scanline::const_iterator span = sl.begin(); + for(;;) + { + int x = span->x; + int len = span->len; + if(len < 0) len = -len; + typename BaseRenderer::color_type* colors = alloc.allocate(len); + span_gen.generate(colors, x, y, len); + ren.blend_color_hspan(x, y, len, colors, 0, cover_full); + if(--num_spans == 0) break; + ++span; + } + } + + //=====================================================render_scanlines_bin + template<class Rasterizer, class Scanline, class BaseRenderer, + class SpanAllocator, class SpanGenerator> + void render_scanlines_bin(Rasterizer& ras, Scanline& sl, BaseRenderer& ren, + SpanAllocator& alloc, SpanGenerator& span_gen) + { + if(ras.rewind_scanlines()) + { + sl.reset(ras.min_x(), ras.max_x()); + span_gen.prepare(); + while(ras.sweep_scanline(sl)) + { + render_scanline_bin(sl, ren, alloc, span_gen); + } + } + } + + //====================================================renderer_scanline_bin + template<class BaseRenderer, class SpanAllocator, class SpanGenerator> + class renderer_scanline_bin + { + public: + typedef BaseRenderer base_ren_type; + typedef SpanAllocator alloc_type; + typedef SpanGenerator span_gen_type; + + //-------------------------------------------------------------------- + renderer_scanline_bin() : m_ren(0), m_alloc(0), m_span_gen(0) {} + renderer_scanline_bin(base_ren_type& ren, + alloc_type& alloc, + span_gen_type& span_gen) : + m_ren(&ren), + m_alloc(&alloc), + m_span_gen(&span_gen) + {} + void attach(base_ren_type& ren, + alloc_type& alloc, + span_gen_type& span_gen) + { + m_ren = &ren; + m_alloc = &alloc; + m_span_gen = &span_gen; + } + + //-------------------------------------------------------------------- + void prepare() { m_span_gen->prepare(); } + + //-------------------------------------------------------------------- + template<class Scanline> void render(const Scanline& sl) + { + render_scanline_bin(sl, *m_ren, *m_alloc, *m_span_gen); + } + + private: + base_ren_type* m_ren; + alloc_type* m_alloc; + span_gen_type* m_span_gen; + }; + + + + + + + + + + + //========================================================render_scanlines + template<class Rasterizer, class Scanline, class Renderer> + void render_scanlines(Rasterizer& ras, Scanline& sl, Renderer& ren) + { + if(ras.rewind_scanlines()) + { + sl.reset(ras.min_x(), ras.max_x()); + ren.prepare(); + while(ras.sweep_scanline(sl)) + { + ren.render(sl); + } + } + } + + //========================================================render_all_paths + template<class Rasterizer, class Scanline, class Renderer, + class VertexSource, class ColorStorage, class PathId> + void render_all_paths(Rasterizer& ras, + Scanline& sl, + Renderer& r, + VertexSource& vs, + const ColorStorage& as, + const PathId& path_id, + unsigned num_paths) + { + for(unsigned i = 0; i < num_paths; i++) + { + ras.reset(); + ras.add_path(vs, path_id[i]); + r.color(as[i]); + render_scanlines(ras, sl, r); + } + } + + + + + + + //=============================================render_scanlines_compound + template<class Rasterizer, + class ScanlineAA, + class ScanlineBin, + class BaseRenderer, + class SpanAllocator, + class StyleHandler> + void render_scanlines_compound(Rasterizer& ras, + ScanlineAA& sl_aa, + ScanlineBin& sl_bin, + BaseRenderer& ren, + SpanAllocator& alloc, + StyleHandler& sh) + { + if(ras.rewind_scanlines()) + { + int min_x = ras.min_x(); + int len = ras.max_x() - min_x + 2; + sl_aa.reset(min_x, ras.max_x()); + sl_bin.reset(min_x, ras.max_x()); + + typedef typename BaseRenderer::color_type color_type; + color_type* color_span = alloc.allocate(len * 2); + color_type* mix_buffer = color_span + len; + unsigned num_spans; + + unsigned num_styles; + unsigned style; + bool solid; + while((num_styles = ras.sweep_styles()) > 0) + { + typename ScanlineAA::const_iterator span_aa; + if(num_styles == 1) + { + // Optimization for a single style. Happens often + //------------------------- + if(ras.sweep_scanline(sl_aa, 0)) + { + style = ras.style(0); + if(sh.is_solid(style)) + { + // Just solid fill + //----------------------- + render_scanline_aa_solid(sl_aa, ren, sh.color(style)); + } + else + { + // Arbitrary span generator + //----------------------- + span_aa = sl_aa.begin(); + num_spans = sl_aa.num_spans(); + for(;;) + { + len = span_aa->len; + sh.generate_span(color_span, + span_aa->x, + sl_aa.y(), + len, + style); + + ren.blend_color_hspan(span_aa->x, + sl_aa.y(), + span_aa->len, + color_span, + span_aa->covers); + if(--num_spans == 0) break; + ++span_aa; + } + } + } + } + else + { + if(ras.sweep_scanline(sl_bin, -1)) + { + // Clear the spans of the mix_buffer + //-------------------- + typename ScanlineBin::const_iterator span_bin = sl_bin.begin(); + num_spans = sl_bin.num_spans(); + for(;;) + { + memset(mix_buffer + span_bin->x - min_x, + 0, + span_bin->len * sizeof(color_type)); + + if(--num_spans == 0) break; + ++span_bin; + } + + unsigned i; + for(i = 0; i < num_styles; i++) + { + style = ras.style(i); + solid = sh.is_solid(style); + + if(ras.sweep_scanline(sl_aa, i)) + { + color_type* colors; + color_type* cspan; + typename ScanlineAA::cover_type* covers; + span_aa = sl_aa.begin(); + num_spans = sl_aa.num_spans(); + if(solid) + { + // Just solid fill + //----------------------- + for(;;) + { + color_type c = sh.color(style); + len = span_aa->len; + colors = mix_buffer + span_aa->x - min_x; + covers = span_aa->covers; + do + { + if(*covers == cover_full) + { + *colors = c; + } + else + { + colors->add(c, *covers); + } + ++colors; + ++covers; + } + while(--len); + if(--num_spans == 0) break; + ++span_aa; + } + } + else + { + // Arbitrary span generator + //----------------------- + for(;;) + { + len = span_aa->len; + colors = mix_buffer + span_aa->x - min_x; + cspan = color_span; + sh.generate_span(cspan, + span_aa->x, + sl_aa.y(), + len, + style); + covers = span_aa->covers; + do + { + if(*covers == cover_full) + { + *colors = *cspan; + } + else + { + colors->add(*cspan, *covers); + } + ++cspan; + ++colors; + ++covers; + } + while(--len); + if(--num_spans == 0) break; + ++span_aa; + } + } + } + } + + // Emit the blended result as a color hspan + //------------------------- + span_bin = sl_bin.begin(); + num_spans = sl_bin.num_spans(); + for(;;) + { + ren.blend_color_hspan(span_bin->x, + sl_bin.y(), + span_bin->len, + mix_buffer + span_bin->x - min_x, + 0, + cover_full); + if(--num_spans == 0) break; + ++span_bin; + } + } // if(ras.sweep_scanline(sl_bin, -1)) + } // if(num_styles == 1) ... else + } // while((num_styles = ras.sweep_styles()) > 0) + } // if(ras.rewind_scanlines()) + } + + //=======================================render_scanlines_compound_layered + template<class Rasterizer, + class ScanlineAA, + class BaseRenderer, + class SpanAllocator, + class StyleHandler> + void render_scanlines_compound_layered(Rasterizer& ras, + ScanlineAA& sl_aa, + BaseRenderer& ren, + SpanAllocator& alloc, + StyleHandler& sh) + { + if(ras.rewind_scanlines()) + { + int min_x = ras.min_x(); + int len = ras.max_x() - min_x + 2; + sl_aa.reset(min_x, ras.max_x()); + + typedef typename BaseRenderer::color_type color_type; + color_type* color_span = alloc.allocate(len * 2); + color_type* mix_buffer = color_span + len; + cover_type* cover_buffer = ras.allocate_cover_buffer(len); + unsigned num_spans; + + unsigned num_styles; + unsigned style; + bool solid; + while((num_styles = ras.sweep_styles()) > 0) + { + typename ScanlineAA::const_iterator span_aa; + if(num_styles == 1) + { + // Optimization for a single style. Happens often + //------------------------- + if(ras.sweep_scanline(sl_aa, 0)) + { + style = ras.style(0); + if(sh.is_solid(style)) + { + // Just solid fill + //----------------------- + render_scanline_aa_solid(sl_aa, ren, sh.color(style)); + } + else + { + // Arbitrary span generator + //----------------------- + span_aa = sl_aa.begin(); + num_spans = sl_aa.num_spans(); + for(;;) + { + len = span_aa->len; + sh.generate_span(color_span, + span_aa->x, + sl_aa.y(), + len, + style); + + ren.blend_color_hspan(span_aa->x, + sl_aa.y(), + span_aa->len, + color_span, + span_aa->covers); + if(--num_spans == 0) break; + ++span_aa; + } + } + } + } + else + { + int sl_start = ras.scanline_start(); + unsigned sl_len = ras.scanline_length(); + + if(sl_len) + { + memset(mix_buffer + sl_start - min_x, + 0, + sl_len * sizeof(color_type)); + + memset(cover_buffer + sl_start - min_x, + 0, + sl_len * sizeof(cover_type)); + + int sl_y = 0x7FFFFFFF; + unsigned i; + for(i = 0; i < num_styles; i++) + { + style = ras.style(i); + solid = sh.is_solid(style); + + if(ras.sweep_scanline(sl_aa, i)) + { + unsigned cover; + color_type* colors; + color_type* cspan; + cover_type* src_covers; + cover_type* dst_covers; + span_aa = sl_aa.begin(); + num_spans = sl_aa.num_spans(); + sl_y = sl_aa.y(); + if(solid) + { + // Just solid fill + //----------------------- + for(;;) + { + color_type c = sh.color(style); + len = span_aa->len; + colors = mix_buffer + span_aa->x - min_x; + src_covers = span_aa->covers; + dst_covers = cover_buffer + span_aa->x - min_x; + do + { + cover = *src_covers; + if(*dst_covers + cover > cover_full) + { + cover = cover_full - *dst_covers; + } + if(cover) + { + colors->add(c, cover); + *dst_covers += cover; + } + ++colors; + ++src_covers; + ++dst_covers; + } + while(--len); + if(--num_spans == 0) break; + ++span_aa; + } + } + else + { + // Arbitrary span generator + //----------------------- + for(;;) + { + len = span_aa->len; + colors = mix_buffer + span_aa->x - min_x; + cspan = color_span; + sh.generate_span(cspan, + span_aa->x, + sl_aa.y(), + len, + style); + src_covers = span_aa->covers; + dst_covers = cover_buffer + span_aa->x - min_x; + do + { + cover = *src_covers; + if(*dst_covers + cover > cover_full) + { + cover = cover_full - *dst_covers; + } + if(cover) + { + colors->add(*cspan, cover); + *dst_covers += cover; + } + ++cspan; + ++colors; + ++src_covers; + ++dst_covers; + } + while(--len); + if(--num_spans == 0) break; + ++span_aa; + } + } + } + } + ren.blend_color_hspan(sl_start, + sl_y, + sl_len, + mix_buffer + sl_start - min_x, + 0, + cover_full); + } //if(sl_len) + } //if(num_styles == 1) ... else + } //while((num_styles = ras.sweep_styles()) > 0) + } //if(ras.rewind_scanlines()) + } + + +} + +#endif diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rendering_buffer.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rendering_buffer.h new file mode 100644 index 00000000000..191347f63e2 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_rendering_buffer.h @@ -0,0 +1,300 @@ +//---------------------------------------------------------------------------- +// 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 +// +//---------------------------------------------------------------------------- + +#ifndef AGG_RENDERING_BUFFER_INCLUDED +#define AGG_RENDERING_BUFFER_INCLUDED + +#include "agg_array.h" + +namespace agg +{ + + //===========================================================row_accessor + template<class T> class row_accessor + { + public: + typedef const_row_info<T> row_data; + + //------------------------------------------------------------------- + row_accessor() : + m_buf(0), + m_start(0), + m_width(0), + m_height(0), + m_stride(0) + { + } + + //-------------------------------------------------------------------- + row_accessor(T* buf, unsigned width, unsigned height, int stride) : + m_buf(0), + m_start(0), + m_width(0), + m_height(0), + m_stride(0) + { + attach(buf, width, height, stride); + } + + + //-------------------------------------------------------------------- + void attach(T* buf, unsigned width, unsigned height, int stride) + { + m_buf = m_start = buf; + m_width = width; + m_height = height; + m_stride = stride; + if(stride < 0) + { + m_start = m_buf - (AGG_INT64)(height - 1) * stride; + } + } + + //-------------------------------------------------------------------- + AGG_INLINE T* buf() { return m_buf; } + AGG_INLINE const T* buf() const { return m_buf; } + AGG_INLINE unsigned width() const { return m_width; } + AGG_INLINE unsigned height() const { return m_height; } + AGG_INLINE int stride() const { return m_stride; } + AGG_INLINE unsigned stride_abs() const + { + return (m_stride < 0) ? unsigned(-m_stride) : unsigned(m_stride); + } + + //-------------------------------------------------------------------- + AGG_INLINE T* row_ptr(int, int y, unsigned) + { + return m_start + y * (AGG_INT64)m_stride; + } + AGG_INLINE T* row_ptr(int y) { return m_start + y * (AGG_INT64)m_stride; } + AGG_INLINE const T* row_ptr(int y) const { return m_start + y * (AGG_INT64)m_stride; } + AGG_INLINE row_data row (int y) const + { + return row_data(0, m_width-1, row_ptr(y)); + } + + //-------------------------------------------------------------------- + template<class RenBuf> + void copy_from(const RenBuf& src) + { + unsigned h = height(); + if(src.height() < h) h = src.height(); + + unsigned l = stride_abs(); + if(src.stride_abs() < l) l = src.stride_abs(); + + l *= sizeof(T); + + unsigned y; + unsigned w = width(); + for (y = 0; y < h; y++) + { + memcpy(row_ptr(0, y, w), src.row_ptr(y), l); + } + } + + //-------------------------------------------------------------------- + void clear(T value) + { + unsigned y; + unsigned w = width(); + unsigned stride = stride_abs(); + for(y = 0; y < height(); y++) + { + T* p = row_ptr(0, y, w); + unsigned x; + for(x = 0; x < stride; x++) + { + *p++ = value; + } + } + } + + private: + //-------------------------------------------------------------------- + T* m_buf; // Pointer to renrdering buffer + T* m_start; // Pointer to first pixel depending on stride + unsigned m_width; // Width in pixels + unsigned m_height; // Height in pixels + int m_stride; // Number of bytes per row. Can be < 0 + }; + + + + + //==========================================================row_ptr_cache + template<class T> class row_ptr_cache + { + public: + typedef const_row_info<T> row_data; + + //------------------------------------------------------------------- + row_ptr_cache() : + m_buf(0), + m_rows(), + m_width(0), + m_height(0), + m_stride(0) + { + } + + //-------------------------------------------------------------------- + row_ptr_cache(T* buf, unsigned width, unsigned height, int stride) : + m_buf(0), + m_rows(), + m_width(0), + m_height(0), + m_stride(0) + { + attach(buf, width, height, stride); + } + + //-------------------------------------------------------------------- + void attach(T* buf, unsigned width, unsigned height, int stride) + { + m_buf = buf; + m_width = width; + m_height = height; + m_stride = stride; + if(height > m_rows.size()) + { + m_rows.resize(height); + } + + T* row_ptr = m_buf; + + if(stride < 0) + { + row_ptr = m_buf - (AGG_INT64)(height - 1) * stride; + } + + T** rows = &m_rows[0]; + + while(height--) + { + *rows++ = row_ptr; + row_ptr += stride; + } + } + + //-------------------------------------------------------------------- + AGG_INLINE T* buf() { return m_buf; } + AGG_INLINE const T* buf() const { return m_buf; } + AGG_INLINE unsigned width() const { return m_width; } + AGG_INLINE unsigned height() const { return m_height; } + AGG_INLINE int stride() const { return m_stride; } + AGG_INLINE unsigned stride_abs() const + { + return (m_stride < 0) ? unsigned(-m_stride) : unsigned(m_stride); + } + + //-------------------------------------------------------------------- + AGG_INLINE T* row_ptr(int, int y, unsigned) + { + return m_rows[y]; + } + AGG_INLINE T* row_ptr(int y) { return m_rows[y]; } + AGG_INLINE const T* row_ptr(int y) const { return m_rows[y]; } + AGG_INLINE row_data row (int y) const + { + return row_data(0, m_width-1, m_rows[y]); + } + + //-------------------------------------------------------------------- + T const* const* rows() const { return &m_rows[0]; } + + //-------------------------------------------------------------------- + template<class RenBuf> + void copy_from(const RenBuf& src) + { + unsigned h = height(); + if(src.height() < h) h = src.height(); + + unsigned l = stride_abs(); + if(src.stride_abs() < l) l = src.stride_abs(); + + l *= sizeof(T); + + unsigned y; + unsigned w = width(); + for (y = 0; y < h; y++) + { + memcpy(row_ptr(0, y, w), src.row_ptr(y), l); + } + } + + //-------------------------------------------------------------------- + void clear(T value) + { + unsigned y; + unsigned w = width(); + unsigned stride = stride_abs(); + for(y = 0; y < height(); y++) + { + T* p = row_ptr(0, y, w); + unsigned x; + for(x = 0; x < stride; x++) + { + *p++ = value; + } + } + } + + private: + //-------------------------------------------------------------------- + T* m_buf; // Pointer to renrdering buffer + pod_array<T*> m_rows; // Pointers to each row of the buffer + unsigned m_width; // Width in pixels + unsigned m_height; // Height in pixels + int m_stride; // Number of bytes per row. Can be < 0 + }; + + + + + //========================================================rendering_buffer + // + // The definition of the main type for accessing the rows in the frame + // buffer. It provides functionality to navigate to the rows in a + // rectangular matrix, from top to bottom or from bottom to top depending + // on stride. + // + // row_accessor is cheap to create/destroy, but performs one multiplication + // when calling row_ptr(). + // + // row_ptr_cache creates an array of pointers to rows, so, the access + // via row_ptr() may be faster. But it requires memory allocation + // when creating. For example, on typical Intel Pentium hardware + // row_ptr_cache speeds span_image_filter_rgb_nn up to 10% + // + // It's used only in short hand typedefs like pixfmt_rgba32 and can be + // redefined in agg_config.h + // In real applications you can use both, depending on your needs + //------------------------------------------------------------------------ +#ifdef AGG_RENDERING_BUFFER + typedef AGG_RENDERING_BUFFER rendering_buffer; +#else +// typedef row_ptr_cache<int8u> rendering_buffer; + typedef row_accessor<int8u> rendering_buffer; +#endif + +} + + +#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 00000000000..188746f3d39 --- /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 00000000000..fe8d26f71b6 --- /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_bin.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_scanline_bin.h new file mode 100644 index 00000000000..660292b6136 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_scanline_bin.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 +//---------------------------------------------------------------------------- +// +// Class scanline_bin - binary scanline. +// +//---------------------------------------------------------------------------- +// +// Adaptation for 32-bit screen coordinates (scanline32_bin) has been sponsored by +// Liberty Technology Systems, Inc., visit http://lib-sys.com +// +// Liberty Technology Systems, Inc. is the provider of +// PostScript and PDF technology for software developers. +// +//---------------------------------------------------------------------------- + +#ifndef AGG_SCANLINE_BIN_INCLUDED +#define AGG_SCANLINE_BIN_INCLUDED + +#include "agg_array.h" + +namespace agg +{ + + //=============================================================scanline_bin + // + // This is binary scaline container which supports the interface + // used in the rasterizer::render(). See description of agg_scanline_u8 + // for details. + // + //------------------------------------------------------------------------ + class scanline_bin + { + public: + typedef int32 coord_type; + + struct span + { + int16 x; + int16 len; + }; + + typedef const span* const_iterator; + + //-------------------------------------------------------------------- + scanline_bin() : + m_last_x(0x7FFFFFF0), + m_spans(), + m_cur_span(0) + { + } + + //-------------------------------------------------------------------- + void reset(int min_x, int max_x) + { + unsigned max_len = max_x - min_x + 3; + if(max_len > m_spans.size()) + { + m_spans.resize(max_len); + } + m_last_x = 0x7FFFFFF0; + m_cur_span = &m_spans[0]; + } + + //-------------------------------------------------------------------- + void add_cell(int x, unsigned) + { + if(x == m_last_x+1) + { + m_cur_span->len++; + } + else + { + ++m_cur_span; + m_cur_span->x = (int16)x; + m_cur_span->len = 1; + } + m_last_x = x; + } + + //-------------------------------------------------------------------- + void add_span(int x, unsigned len, unsigned) + { + if(x == m_last_x+1) + { + m_cur_span->len = (int16)(m_cur_span->len + len); + } + else + { + ++m_cur_span; + m_cur_span->x = (int16)x; + m_cur_span->len = (int16)len; + } + m_last_x = x + len - 1; + } + + //-------------------------------------------------------------------- + void add_cells(int x, unsigned len, const void*) + { + add_span(x, len, 0); + } + + //-------------------------------------------------------------------- + void finalize(int y) + { + m_y = y; + } + + //-------------------------------------------------------------------- + void reset_spans() + { + m_last_x = 0x7FFFFFF0; + m_cur_span = &m_spans[0]; + } + + //-------------------------------------------------------------------- + int y() const { return m_y; } + unsigned num_spans() const { return unsigned(m_cur_span - &m_spans[0]); } + const_iterator begin() const { return &m_spans[1]; } + + private: + scanline_bin(const scanline_bin&); + const scanline_bin operator = (const scanline_bin&); + + int m_last_x; + int m_y; + pod_array<span> m_spans; + span* m_cur_span; + }; + + + + + + + //===========================================================scanline32_bin + class scanline32_bin + { + public: + typedef int32 coord_type; + + //-------------------------------------------------------------------- + struct span + { + span() {} + span(coord_type x_, coord_type len_) : x(x_), len(len_) {} + + coord_type x; + coord_type len; + }; + typedef pod_bvector<span, 4> span_array_type; + + + //-------------------------------------------------------------------- + class const_iterator + { + public: + const_iterator(const span_array_type& spans) : + m_spans(spans), + m_span_idx(0) + {} + + const span& operator*() const { return m_spans[m_span_idx]; } + const span* operator->() const { return &m_spans[m_span_idx]; } + + void operator ++ () { ++m_span_idx; } + + private: + const span_array_type& m_spans; + unsigned m_span_idx; + }; + + + //-------------------------------------------------------------------- + scanline32_bin() : m_max_len(0), m_last_x(0x7FFFFFF0) {} + + //-------------------------------------------------------------------- + void reset(int min_x, int max_x) + { + m_last_x = 0x7FFFFFF0; + m_spans.remove_all(); + } + + //-------------------------------------------------------------------- + void add_cell(int x, unsigned) + { + if(x == m_last_x+1) + { + m_spans.last().len++; + } + else + { + m_spans.add(span(coord_type(x), 1)); + } + m_last_x = x; + } + + //-------------------------------------------------------------------- + void add_span(int x, unsigned len, unsigned) + { + if(x == m_last_x+1) + { + m_spans.last().len += coord_type(len); + } + else + { + m_spans.add(span(coord_type(x), coord_type(len))); + } + m_last_x = x + len - 1; + } + + //-------------------------------------------------------------------- + void add_cells(int x, unsigned len, const void*) + { + add_span(x, len, 0); + } + + //-------------------------------------------------------------------- + void finalize(int y) + { + m_y = y; + } + + //-------------------------------------------------------------------- + void reset_spans() + { + m_last_x = 0x7FFFFFF0; + m_spans.remove_all(); + } + + //-------------------------------------------------------------------- + int y() const { return m_y; } + unsigned num_spans() const { return m_spans.size(); } + const_iterator begin() const { return const_iterator(m_spans); } + + private: + scanline32_bin(const scanline32_bin&); + const scanline32_bin operator = (const scanline32_bin&); + + unsigned m_max_len; + int m_last_x; + int m_y; + span_array_type m_spans; + }; + + + + + +} + + +#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 00000000000..bc2e9c9d51f --- /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_scanline_p.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_scanline_p.h new file mode 100644 index 00000000000..1d1cbe72f1e --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_scanline_p.h @@ -0,0 +1,329 @@ +//---------------------------------------------------------------------------- +// 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 scanline_p - a general purpose scanline container with packed spans. +// +//---------------------------------------------------------------------------- +// +// Adaptation for 32-bit screen coordinates (scanline32_p) has been sponsored by +// Liberty Technology Systems, Inc., visit http://lib-sys.com +// +// Liberty Technology Systems, Inc. is the provider of +// PostScript and PDF technology for software developers. +// +//---------------------------------------------------------------------------- +#ifndef AGG_SCANLINE_P_INCLUDED +#define AGG_SCANLINE_P_INCLUDED + +#include "agg_array.h" + +namespace agg +{ + + //=============================================================scanline_p8 + // + // This is a general purpose scaline container which supports the interface + // used in the rasterizer::render(). See description of scanline_u8 + // for details. + // + //------------------------------------------------------------------------ + class scanline_p8 + { + public: + typedef scanline_p8 self_type; + typedef int8u cover_type; + typedef int16 coord_type; + + //-------------------------------------------------------------------- + struct span + { + coord_type x; + coord_type len; // If negative, it's a solid span, covers is valid + const cover_type* covers; + }; + + typedef span* iterator; + typedef const span* const_iterator; + + scanline_p8() : + m_last_x(0x7FFFFFF0), + m_covers(), + m_cover_ptr(0), + m_spans(), + m_cur_span(0) + { + } + + //-------------------------------------------------------------------- + void reset(int min_x, int max_x) + { + unsigned max_len = max_x - min_x + 3; + if(max_len > m_spans.size()) + { + m_spans.resize(max_len); + m_covers.resize(max_len); + } + m_last_x = 0x7FFFFFF0; + m_cover_ptr = &m_covers[0]; + m_cur_span = &m_spans[0]; + m_cur_span->len = 0; + } + + //-------------------------------------------------------------------- + void add_cell(int x, unsigned cover) + { + *m_cover_ptr = (cover_type)cover; + if(x == m_last_x+1 && m_cur_span->len > 0) + { + m_cur_span->len++; + } + else + { + m_cur_span++; + m_cur_span->covers = m_cover_ptr; + m_cur_span->x = (int16)x; + m_cur_span->len = 1; + } + m_last_x = x; + m_cover_ptr++; + } + + //-------------------------------------------------------------------- + void add_cells(int x, unsigned len, const cover_type* covers) + { + memcpy(m_cover_ptr, covers, len * sizeof(cover_type)); + if(x == m_last_x+1 && m_cur_span->len > 0) + { + m_cur_span->len += (int16)len; + } + else + { + m_cur_span++; + m_cur_span->covers = m_cover_ptr; + m_cur_span->x = (int16)x; + m_cur_span->len = (int16)len; + } + m_cover_ptr += len; + m_last_x = x + len - 1; + } + + //-------------------------------------------------------------------- + void add_span(int x, unsigned len, unsigned cover) + { + if(x == m_last_x+1 && + m_cur_span->len < 0 && + cover == *m_cur_span->covers) + { + m_cur_span->len -= (int16)len; + } + else + { + *m_cover_ptr = (cover_type)cover; + m_cur_span++; + m_cur_span->covers = m_cover_ptr++; + m_cur_span->x = (int16)x; + m_cur_span->len = (int16)(-int(len)); + } + m_last_x = x + len - 1; + } + + //-------------------------------------------------------------------- + void finalize(int y) + { + m_y = y; + } + + //-------------------------------------------------------------------- + void reset_spans() + { + m_last_x = 0x7FFFFFF0; + m_cover_ptr = &m_covers[0]; + m_cur_span = &m_spans[0]; + m_cur_span->len = 0; + } + + //-------------------------------------------------------------------- + int y() const { return m_y; } + unsigned num_spans() const { return unsigned(m_cur_span - &m_spans[0]); } + const_iterator begin() const { return &m_spans[1]; } + + private: + scanline_p8(const self_type&); + const self_type& operator = (const self_type&); + + int m_last_x; + int m_y; + pod_array<cover_type> m_covers; + cover_type* m_cover_ptr; + pod_array<span> m_spans; + span* m_cur_span; + }; + + + + + + + + + //==========================================================scanline32_p8 + class scanline32_p8 + { + public: + typedef scanline32_p8 self_type; + typedef int8u cover_type; + typedef int32 coord_type; + + struct span + { + span() {} + span(coord_type x_, coord_type len_, const cover_type* covers_) : + x(x_), len(len_), covers(covers_) {} + + coord_type x; + coord_type len; // If negative, it's a solid span, covers is valid + const cover_type* covers; + }; + typedef pod_bvector<span, 4> span_array_type; + + + //-------------------------------------------------------------------- + class const_iterator + { + public: + const_iterator(const span_array_type& spans) : + m_spans(spans), + m_span_idx(0) + {} + + const span& operator*() const { return m_spans[m_span_idx]; } + const span* operator->() const { return &m_spans[m_span_idx]; } + + void operator ++ () { ++m_span_idx; } + + private: + const span_array_type& m_spans; + unsigned m_span_idx; + }; + + //-------------------------------------------------------------------- + scanline32_p8() : + m_max_len(0), + m_last_x(0x7FFFFFF0), + m_covers(), + m_cover_ptr(0) + { + } + + //-------------------------------------------------------------------- + void reset(int min_x, int max_x) + { + unsigned max_len = max_x - min_x + 3; + if(max_len > m_covers.size()) + { + m_covers.resize(max_len); + } + m_last_x = 0x7FFFFFF0; + m_cover_ptr = &m_covers[0]; + m_spans.remove_all(); + } + + //-------------------------------------------------------------------- + void add_cell(int x, unsigned cover) + { + *m_cover_ptr = cover_type(cover); + if(x == m_last_x+1 && m_spans.size() && m_spans.last().len > 0) + { + m_spans.last().len++; + } + else + { + m_spans.add(span(coord_type(x), 1, m_cover_ptr)); + } + m_last_x = x; + m_cover_ptr++; + } + + //-------------------------------------------------------------------- + void add_cells(int x, unsigned len, const cover_type* covers) + { + memcpy(m_cover_ptr, covers, len * sizeof(cover_type)); + if(x == m_last_x+1 && m_spans.size() && m_spans.last().len > 0) + { + m_spans.last().len += coord_type(len); + } + else + { + m_spans.add(span(coord_type(x), coord_type(len), m_cover_ptr)); + } + m_cover_ptr += len; + m_last_x = x + len - 1; + } + + //-------------------------------------------------------------------- + void add_span(int x, unsigned len, unsigned cover) + { + if(x == m_last_x+1 && + m_spans.size() && + m_spans.last().len < 0 && + cover == *m_spans.last().covers) + { + m_spans.last().len -= coord_type(len); + } + else + { + *m_cover_ptr = cover_type(cover); + m_spans.add(span(coord_type(x), -coord_type(len), m_cover_ptr++)); + } + m_last_x = x + len - 1; + } + + //-------------------------------------------------------------------- + void finalize(int y) + { + m_y = y; + } + + //-------------------------------------------------------------------- + void reset_spans() + { + m_last_x = 0x7FFFFFF0; + m_cover_ptr = &m_covers[0]; + m_spans.remove_all(); + } + + //-------------------------------------------------------------------- + int y() const { return m_y; } + unsigned num_spans() const { return m_spans.size(); } + const_iterator begin() const { return const_iterator(m_spans); } + + private: + scanline32_p8(const self_type&); + const self_type& operator = (const self_type&); + + unsigned m_max_len; + int m_last_x; + int m_y; + pod_array<cover_type> m_covers; + cover_type* m_cover_ptr; + span_array_type m_spans; + }; + + +} + + +#endif + diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_scanline_storage_aa.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_scanline_storage_aa.h new file mode 100644 index 00000000000..b3471fce768 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_scanline_storage_aa.h @@ -0,0 +1,815 @@ +//---------------------------------------------------------------------------- +// 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 32-bit screen coordinates has been sponsored by +// Liberty Technology Systems, Inc., visit http://lib-sys.com +// +// Liberty Technology Systems, Inc. is the provider of +// PostScript and PDF technology for software developers. +// +//---------------------------------------------------------------------------- + +#ifndef AGG_SCANLINE_STORAGE_AA_INCLUDED +#define AGG_SCANLINE_STORAGE_AA_INCLUDED + +#include <string.h> +#include <stdlib.h> +#include <math.h> +#include "agg_array.h" + + +namespace agg +{ + + //----------------------------------------------scanline_cell_storage + template<class T> class scanline_cell_storage + { + struct extra_span + { + unsigned len; + T* ptr; + }; + + public: + typedef T value_type; + + //--------------------------------------------------------------- + ~scanline_cell_storage() + { + remove_all(); + } + + //--------------------------------------------------------------- + scanline_cell_storage() : + m_cells(128-2), + m_extra_storage() + {} + + + // Copying + //--------------------------------------------------------------- + scanline_cell_storage(const scanline_cell_storage<T>& v) : + m_cells(v.m_cells), + m_extra_storage() + { + copy_extra_storage(v); + } + + //--------------------------------------------------------------- + const scanline_cell_storage<T>& + operator = (const scanline_cell_storage<T>& v) + { + remove_all(); + m_cells = v.m_cells; + copy_extra_storage(v); + return *this; + } + + //--------------------------------------------------------------- + void remove_all() + { + int i; + for(i = m_extra_storage.size()-1; i >= 0; --i) + { + pod_allocator<T>::deallocate(m_extra_storage[i].ptr, + m_extra_storage[i].len); + } + m_extra_storage.remove_all(); + m_cells.remove_all(); + } + + //--------------------------------------------------------------- + int add_cells(const T* cells, unsigned num_cells) + { + int idx = m_cells.allocate_continuous_block(num_cells); + if(idx >= 0) + { + T* ptr = &m_cells[idx]; + memcpy(ptr, cells, sizeof(T) * num_cells); + return idx; + } + extra_span s; + s.len = num_cells; + s.ptr = pod_allocator<T>::allocate(num_cells); + memcpy(s.ptr, cells, sizeof(T) * num_cells); + m_extra_storage.add(s); + return -int(m_extra_storage.size()); + } + + //--------------------------------------------------------------- + const T* operator [] (int idx) const + { + if(idx >= 0) + { + if((unsigned)idx >= m_cells.size()) return 0; + return &m_cells[(unsigned)idx]; + } + unsigned i = unsigned(-idx - 1); + if(i >= m_extra_storage.size()) return 0; + return m_extra_storage[i].ptr; + } + + //--------------------------------------------------------------- + T* operator [] (int idx) + { + if(idx >= 0) + { + if((unsigned)idx >= m_cells.size()) return 0; + return &m_cells[(unsigned)idx]; + } + unsigned i = unsigned(-idx - 1); + if(i >= m_extra_storage.size()) return 0; + return m_extra_storage[i].ptr; + } + + private: + void copy_extra_storage(const scanline_cell_storage<T>& v) + { + unsigned i; + for(i = 0; i < v.m_extra_storage.size(); ++i) + { + const extra_span& src = v.m_extra_storage[i]; + extra_span dst; + dst.len = src.len; + dst.ptr = pod_allocator<T>::allocate(dst.len); + memcpy(dst.ptr, src.ptr, dst.len * sizeof(T)); + m_extra_storage.add(dst); + } + } + + pod_bvector<T, 12> m_cells; + pod_bvector<extra_span, 6> m_extra_storage; + }; + + + + + + + //-----------------------------------------------scanline_storage_aa + template<class T> class scanline_storage_aa + { + public: + typedef T cover_type; + + //--------------------------------------------------------------- + struct span_data + { + int32 x; + int32 len; // If negative, it's a solid span, covers is valid + int covers_id; // The index of the cells in the scanline_cell_storage + }; + + //--------------------------------------------------------------- + struct scanline_data + { + int y; + unsigned num_spans; + unsigned start_span; + }; + + + //--------------------------------------------------------------- + class embedded_scanline + { + public: + + //----------------------------------------------------------- + class const_iterator + { + public: + struct span + { + int32 x; + int32 len; // If negative, it's a solid span, covers is valid + const T* covers; + }; + + const_iterator() : m_storage(0) {} + const_iterator(embedded_scanline& sl) : + m_storage(sl.m_storage), + m_span_idx(sl.m_scanline.start_span) + { + init_span(); + } + + const span& operator*() const { return m_span; } + const span* operator->() const { return &m_span; } + + void operator ++ () + { + ++m_span_idx; + init_span(); + } + + private: + void init_span() + { + const span_data& s = m_storage->span_by_index(m_span_idx); + m_span.x = s.x; + m_span.len = s.len; + m_span.covers = m_storage->covers_by_index(s.covers_id); + } + + scanline_storage_aa* m_storage; + unsigned m_span_idx; + span m_span; + }; + + friend class const_iterator; + + + //----------------------------------------------------------- + embedded_scanline(const scanline_storage_aa& storage) : + m_storage(&storage) + { + init(0); + } + + //----------------------------------------------------------- + void reset(int, int) {} + unsigned num_spans() const { return m_scanline.num_spans; } + int y() const { return m_scanline.y; } + const_iterator begin() const { return const_iterator(*this); } + + //----------------------------------------------------------- + void init(unsigned scanline_idx) + { + m_scanline_idx = scanline_idx; + m_scanline = m_storage->scanline_by_index(m_scanline_idx); + } + + private: + const scanline_storage_aa* m_storage; + scanline_data m_scanline; + unsigned m_scanline_idx; + }; + + + //--------------------------------------------------------------- + scanline_storage_aa() : + m_covers(), + m_spans(256-2), // Block increment size + m_scanlines(), + m_min_x( 0x7FFFFFFF), + m_min_y( 0x7FFFFFFF), + m_max_x(-0x7FFFFFFF), + m_max_y(-0x7FFFFFFF), + m_cur_scanline(0) + { + m_fake_scanline.y = 0; + m_fake_scanline.num_spans = 0; + m_fake_scanline.start_span = 0; + m_fake_span.x = 0; + m_fake_span.len = 0; + m_fake_span.covers_id = 0; + } + + // Renderer Interface + //--------------------------------------------------------------- + void prepare() + { + m_covers.remove_all(); + m_scanlines.remove_all(); + m_spans.remove_all(); + m_min_x = 0x7FFFFFFF; + m_min_y = 0x7FFFFFFF; + m_max_x = -0x7FFFFFFF; + m_max_y = -0x7FFFFFFF; + m_cur_scanline = 0; + } + + //--------------------------------------------------------------- + template<class Scanline> void render(const Scanline& sl) + { + scanline_data sl_this; + + int y = sl.y(); + if(y < m_min_y) m_min_y = y; + if(y > m_max_y) m_max_y = y; + + sl_this.y = y; + sl_this.num_spans = sl.num_spans(); + sl_this.start_span = m_spans.size(); + typename Scanline::const_iterator span_iterator = sl.begin(); + + unsigned num_spans = sl_this.num_spans; + for(;;) + { + span_data sp; + + sp.x = span_iterator->x; + sp.len = span_iterator->len; + int len = abs(int(sp.len)); + sp.covers_id = + m_covers.add_cells(span_iterator->covers, + unsigned(len)); + m_spans.add(sp); + int x1 = sp.x; + int x2 = sp.x + len - 1; + if(x1 < m_min_x) m_min_x = x1; + if(x2 > m_max_x) m_max_x = x2; + if(--num_spans == 0) break; + ++span_iterator; + } + m_scanlines.add(sl_this); + } + + + //--------------------------------------------------------------- + // Iterate scanlines interface + int min_x() const { return m_min_x; } + int min_y() const { return m_min_y; } + int max_x() const { return m_max_x; } + int max_y() const { return m_max_y; } + + //--------------------------------------------------------------- + bool rewind_scanlines() + { + m_cur_scanline = 0; + return m_scanlines.size() > 0; + } + + + //--------------------------------------------------------------- + template<class Scanline> bool sweep_scanline(Scanline& sl) + { + sl.reset_spans(); + for(;;) + { + if(m_cur_scanline >= m_scanlines.size()) return false; + const scanline_data& sl_this = m_scanlines[m_cur_scanline]; + + unsigned num_spans = sl_this.num_spans; + unsigned span_idx = sl_this.start_span; + do + { + const span_data& sp = m_spans[span_idx++]; + const T* covers = covers_by_index(sp.covers_id); + if(sp.len < 0) + { + sl.add_span(sp.x, unsigned(-sp.len), *covers); + } + else + { + sl.add_cells(sp.x, sp.len, covers); + } + } + while(--num_spans); + ++m_cur_scanline; + if(sl.num_spans()) + { + sl.finalize(sl_this.y); + break; + } + } + return true; + } + + + //--------------------------------------------------------------- + // Specialization for embedded_scanline + bool sweep_scanline(embedded_scanline& sl) + { + do + { + if(m_cur_scanline >= m_scanlines.size()) return false; + sl.init(m_cur_scanline); + ++m_cur_scanline; + } + while(sl.num_spans() == 0); + return true; + } + + //--------------------------------------------------------------- + unsigned byte_size() const + { + unsigned i; + unsigned size = sizeof(int32) * 4; // min_x, min_y, max_x, max_y + + for(i = 0; i < m_scanlines.size(); ++i) + { + size += sizeof(int32) * 3; // scanline size in bytes, Y, num_spans + + const scanline_data& sl_this = m_scanlines[i]; + + unsigned num_spans = sl_this.num_spans; + unsigned span_idx = sl_this.start_span; + do + { + const span_data& sp = m_spans[span_idx++]; + + size += sizeof(int32) * 2; // X, span_len + if(sp.len < 0) + { + size += sizeof(T); // cover + } + else + { + size += sizeof(T) * unsigned(sp.len); // covers + } + } + while(--num_spans); + } + return size; + } + + + //--------------------------------------------------------------- + static void write_int32(int8u* dst, int32 val) + { + dst[0] = ((const int8u*)&val)[0]; + dst[1] = ((const int8u*)&val)[1]; + dst[2] = ((const int8u*)&val)[2]; + dst[3] = ((const int8u*)&val)[3]; + } + + + //--------------------------------------------------------------- + void serialize(int8u* data) const + { + unsigned i; + + write_int32(data, min_x()); // min_x + data += sizeof(int32); + write_int32(data, min_y()); // min_y + data += sizeof(int32); + write_int32(data, max_x()); // max_x + data += sizeof(int32); + write_int32(data, max_y()); // max_y + data += sizeof(int32); + + for(i = 0; i < m_scanlines.size(); ++i) + { + const scanline_data& sl_this = m_scanlines[i]; + + int8u* size_ptr = data; + data += sizeof(int32); // Reserve space for scanline size in bytes + + write_int32(data, sl_this.y); // Y + data += sizeof(int32); + + write_int32(data, sl_this.num_spans); // num_spans + data += sizeof(int32); + + unsigned num_spans = sl_this.num_spans; + unsigned span_idx = sl_this.start_span; + do + { + const span_data& sp = m_spans[span_idx++]; + const T* covers = covers_by_index(sp.covers_id); + + write_int32(data, sp.x); // X + data += sizeof(int32); + + write_int32(data, sp.len); // span_len + data += sizeof(int32); + + if(sp.len < 0) + { + memcpy(data, covers, sizeof(T)); + data += sizeof(T); + } + else + { + memcpy(data, covers, unsigned(sp.len) * sizeof(T)); + data += sizeof(T) * unsigned(sp.len); + } + } + while(--num_spans); + write_int32(size_ptr, int32(unsigned(data - size_ptr))); + } + } + + + //--------------------------------------------------------------- + const scanline_data& scanline_by_index(unsigned i) const + { + return (i < m_scanlines.size()) ? m_scanlines[i] : m_fake_scanline; + } + + //--------------------------------------------------------------- + const span_data& span_by_index(unsigned i) const + { + return (i < m_spans.size()) ? m_spans[i] : m_fake_span; + } + + //--------------------------------------------------------------- + const T* covers_by_index(int i) const + { + return m_covers[i]; + } + + private: + scanline_cell_storage<T> m_covers; + pod_bvector<span_data, 10> m_spans; + pod_bvector<scanline_data, 8> m_scanlines; + span_data m_fake_span; + scanline_data m_fake_scanline; + int m_min_x; + int m_min_y; + int m_max_x; + int m_max_y; + unsigned m_cur_scanline; + }; + + + typedef scanline_storage_aa<int8u> scanline_storage_aa8; //--------scanline_storage_aa8 + typedef scanline_storage_aa<int16u> scanline_storage_aa16; //--------scanline_storage_aa16 + typedef scanline_storage_aa<int32u> scanline_storage_aa32; //--------scanline_storage_aa32 + + + + + //------------------------------------------serialized_scanlines_adaptor_aa + template<class T> class serialized_scanlines_adaptor_aa + { + public: + typedef T cover_type; + + //--------------------------------------------------------------------- + class embedded_scanline + { + public: + typedef T cover_type; + + //----------------------------------------------------------------- + class const_iterator + { + public: + struct span + { + int32 x; + int32 len; // If negative, it's a solid span, "covers" is valid + const T* covers; + }; + + const_iterator() : m_ptr(0) {} + const_iterator(const embedded_scanline* sl) : + m_ptr(sl->m_ptr), + m_dx(sl->m_dx) + { + init_span(); + } + + const span& operator*() const { return m_span; } + const span* operator->() const { return &m_span; } + + void operator ++ () + { + if(m_span.len < 0) + { + m_ptr += sizeof(T); + } + else + { + m_ptr += m_span.len * sizeof(T); + } + init_span(); + } + + private: + int read_int32() + { + int32 val; + ((int8u*)&val)[0] = *m_ptr++; + ((int8u*)&val)[1] = *m_ptr++; + ((int8u*)&val)[2] = *m_ptr++; + ((int8u*)&val)[3] = *m_ptr++; + return val; + } + + void init_span() + { + m_span.x = read_int32() + m_dx; + m_span.len = read_int32(); + m_span.covers = m_ptr; + } + + const int8u* m_ptr; + span m_span; + int m_dx; + }; + + friend class const_iterator; + + + //----------------------------------------------------------------- + embedded_scanline() : m_ptr(0), m_y(0), m_num_spans(0) {} + + //----------------------------------------------------------------- + void reset(int, int) {} + unsigned num_spans() const { return m_num_spans; } + int y() const { return m_y; } + const_iterator begin() const { return const_iterator(this); } + + + private: + //----------------------------------------------------------------- + int read_int32() + { + int32 val; + ((int8u*)&val)[0] = *m_ptr++; + ((int8u*)&val)[1] = *m_ptr++; + ((int8u*)&val)[2] = *m_ptr++; + ((int8u*)&val)[3] = *m_ptr++; + return val; + } + + public: + //----------------------------------------------------------------- + void init(const int8u* ptr, int dx, int dy) + { + m_ptr = ptr; + m_y = read_int32() + dy; + m_num_spans = unsigned(read_int32()); + m_dx = dx; + } + + private: + const int8u* m_ptr; + int m_y; + unsigned m_num_spans; + int m_dx; + }; + + + + public: + //-------------------------------------------------------------------- + serialized_scanlines_adaptor_aa() : + m_data(0), + m_end(0), + m_ptr(0), + m_dx(0), + m_dy(0), + m_min_x(0x7FFFFFFF), + m_min_y(0x7FFFFFFF), + m_max_x(-0x7FFFFFFF), + m_max_y(-0x7FFFFFFF) + {} + + //-------------------------------------------------------------------- + serialized_scanlines_adaptor_aa(const int8u* data, unsigned size, + double dx, double dy) : + m_data(data), + m_end(data + size), + m_ptr(data), + m_dx(iround(dx)), + m_dy(iround(dy)), + m_min_x(0x7FFFFFFF), + m_min_y(0x7FFFFFFF), + m_max_x(-0x7FFFFFFF), + m_max_y(-0x7FFFFFFF) + {} + + //-------------------------------------------------------------------- + void init(const int8u* data, unsigned size, double dx, double dy) + { + m_data = data; + m_end = data + size; + m_ptr = data; + m_dx = iround(dx); + m_dy = iround(dy); + m_min_x = 0x7FFFFFFF; + m_min_y = 0x7FFFFFFF; + m_max_x = -0x7FFFFFFF; + m_max_y = -0x7FFFFFFF; + } + + private: + //-------------------------------------------------------------------- + int read_int32() + { + int32 val; + ((int8u*)&val)[0] = *m_ptr++; + ((int8u*)&val)[1] = *m_ptr++; + ((int8u*)&val)[2] = *m_ptr++; + ((int8u*)&val)[3] = *m_ptr++; + return val; + } + + //-------------------------------------------------------------------- + unsigned read_int32u() + { + int32u val; + ((int8u*)&val)[0] = *m_ptr++; + ((int8u*)&val)[1] = *m_ptr++; + ((int8u*)&val)[2] = *m_ptr++; + ((int8u*)&val)[3] = *m_ptr++; + return val; + } + + public: + // Iterate scanlines interface + //-------------------------------------------------------------------- + bool rewind_scanlines() + { + m_ptr = m_data; + if(m_ptr < m_end) + { + m_min_x = read_int32u() + m_dx; + m_min_y = read_int32u() + m_dy; + m_max_x = read_int32u() + m_dx; + m_max_y = read_int32u() + m_dy; + } + return m_ptr < m_end; + } + + //-------------------------------------------------------------------- + int min_x() const { return m_min_x; } + int min_y() const { return m_min_y; } + int max_x() const { return m_max_x; } + int max_y() const { return m_max_y; } + + //-------------------------------------------------------------------- + template<class Scanline> bool sweep_scanline(Scanline& sl) + { + sl.reset_spans(); + for(;;) + { + if(m_ptr >= m_end) return false; + + read_int32(); // Skip scanline size in bytes + int y = read_int32() + m_dy; + unsigned num_spans = read_int32(); + + do + { + int x = read_int32() + m_dx; + int len = read_int32(); + + if(len < 0) + { + sl.add_span(x, unsigned(-len), *m_ptr); + m_ptr += sizeof(T); + } + else + { + sl.add_cells(x, len, m_ptr); + m_ptr += len * sizeof(T); + } + } + while(--num_spans); + + if(sl.num_spans()) + { + sl.finalize(y); + break; + } + } + return true; + } + + + //-------------------------------------------------------------------- + // Specialization for embedded_scanline + bool sweep_scanline(embedded_scanline& sl) + { + do + { + if(m_ptr >= m_end) return false; + + unsigned byte_size = read_int32u(); + sl.init(m_ptr, m_dx, m_dy); + m_ptr += byte_size - sizeof(int32); + } + while(sl.num_spans() == 0); + return true; + } + + private: + const int8u* m_data; + const int8u* m_end; + const int8u* m_ptr; + int m_dx; + int m_dy; + int m_min_x; + int m_min_y; + int m_max_x; + int m_max_y; + }; + + + + typedef serialized_scanlines_adaptor_aa<int8u> serialized_scanlines_adaptor_aa8; //----serialized_scanlines_adaptor_aa8 + typedef serialized_scanlines_adaptor_aa<int16u> serialized_scanlines_adaptor_aa16; //----serialized_scanlines_adaptor_aa16 + typedef serialized_scanlines_adaptor_aa<int32u> serialized_scanlines_adaptor_aa32; //----serialized_scanlines_adaptor_aa32 + +} + + +#endif + diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_scanline_storage_bin.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_scanline_storage_bin.h new file mode 100644 index 00000000000..3ab1adca516 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_scanline_storage_bin.h @@ -0,0 +1,586 @@ +//---------------------------------------------------------------------------- +// 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 32-bit screen coordinates has been sponsored by +// Liberty Technology Systems, Inc., visit http://lib-sys.com +// +// Liberty Technology Systems, Inc. is the provider of +// PostScript and PDF technology for software developers. +// +//---------------------------------------------------------------------------- + + +#ifndef AGG_SCANLINE_STORAGE_BIN_INCLUDED +#define AGG_SCANLINE_STORAGE_BIN_INCLUDED + +#include <string.h> +#include <stdlib.h> +#include <math.h> +#include "agg_array.h" + + +namespace agg +{ + + //-----------------------------------------------scanline_storage_bin + class scanline_storage_bin + { + public: + //--------------------------------------------------------------- + struct span_data + { + int32 x; + int32 len; + }; + + //--------------------------------------------------------------- + struct scanline_data + { + int y; + unsigned num_spans; + unsigned start_span; + }; + + + //--------------------------------------------------------------- + class embedded_scanline + { + public: + + //----------------------------------------------------------- + class const_iterator + { + public: + const_iterator() : m_storage(0) {} + const_iterator(const embedded_scanline* sl) : + m_storage(sl->m_storage), + m_span_idx(sl->m_scanline.start_span) + { + m_span = m_storage->span_by_index(m_span_idx); + } + + const span_data& operator*() const { return m_span; } + const span_data* operator->() const { return &m_span; } + + void operator ++ () + { + ++m_span_idx; + m_span = m_storage->span_by_index(m_span_idx); + } + + private: + const scanline_storage_bin* m_storage; + unsigned m_span_idx; + span_data m_span; + }; + + friend class const_iterator; + + + //----------------------------------------------------------- + embedded_scanline(scanline_storage_bin& storage) : + m_storage(&storage) + { + setup(0); + } + + //----------------------------------------------------------- + void reset(int, int) {} + unsigned num_spans() const { return m_scanline.num_spans; } + int y() const { return m_scanline.y; } + const_iterator begin() const { return const_iterator(this); } + + //----------------------------------------------------------- + void setup(unsigned scanline_idx) + { + m_scanline_idx = scanline_idx; + m_scanline = m_storage->scanline_by_index(m_scanline_idx); + } + + private: + scanline_storage_bin* m_storage; + scanline_data m_scanline; + unsigned m_scanline_idx; + }; + + + //--------------------------------------------------------------- + scanline_storage_bin() : + m_spans(256-2), // Block increment size + m_scanlines(), + m_min_x( 0x7FFFFFFF), + m_min_y( 0x7FFFFFFF), + m_max_x(-0x7FFFFFFF), + m_max_y(-0x7FFFFFFF), + m_cur_scanline(0) + { + m_fake_scanline.y = 0; + m_fake_scanline.num_spans = 0; + m_fake_scanline.start_span = 0; + m_fake_span.x = 0; + m_fake_span.len = 0; + } + + // Renderer Interface + //--------------------------------------------------------------- + void prepare() + { + m_scanlines.remove_all(); + m_spans.remove_all(); + m_min_x = 0x7FFFFFFF; + m_min_y = 0x7FFFFFFF; + m_max_x = -0x7FFFFFFF; + m_max_y = -0x7FFFFFFF; + m_cur_scanline = 0; + } + + //--------------------------------------------------------------- + template<class Scanline> void render(const Scanline& sl) + { + scanline_data sl_this; + + int y = sl.y(); + if(y < m_min_y) m_min_y = y; + if(y > m_max_y) m_max_y = y; + + sl_this.y = y; + sl_this.num_spans = sl.num_spans(); + sl_this.start_span = m_spans.size(); + typename Scanline::const_iterator span_iterator = sl.begin(); + + unsigned num_spans = sl_this.num_spans; + for(;;) + { + span_data sp; + sp.x = span_iterator->x; + sp.len = (int32)abs((int)(span_iterator->len)); + m_spans.add(sp); + int x1 = sp.x; + int x2 = sp.x + sp.len - 1; + if(x1 < m_min_x) m_min_x = x1; + if(x2 > m_max_x) m_max_x = x2; + if(--num_spans == 0) break; + ++span_iterator; + } + m_scanlines.add(sl_this); + } + + + //--------------------------------------------------------------- + // Iterate scanlines interface + int min_x() const { return m_min_x; } + int min_y() const { return m_min_y; } + int max_x() const { return m_max_x; } + int max_y() const { return m_max_y; } + + //--------------------------------------------------------------- + bool rewind_scanlines() + { + m_cur_scanline = 0; + return m_scanlines.size() > 0; + } + + + //--------------------------------------------------------------- + template<class Scanline> bool sweep_scanline(Scanline& sl) + { + sl.reset_spans(); + for(;;) + { + if(m_cur_scanline >= m_scanlines.size()) return false; + const scanline_data& sl_this = m_scanlines[m_cur_scanline]; + + unsigned num_spans = sl_this.num_spans; + unsigned span_idx = sl_this.start_span; + do + { + const span_data& sp = m_spans[span_idx++]; + sl.add_span(sp.x, sp.len, cover_full); + } + while(--num_spans); + + ++m_cur_scanline; + if(sl.num_spans()) + { + sl.finalize(sl_this.y); + break; + } + } + return true; + } + + + //--------------------------------------------------------------- + // Specialization for embedded_scanline + bool sweep_scanline(embedded_scanline& sl) + { + do + { + if(m_cur_scanline >= m_scanlines.size()) return false; + sl.setup(m_cur_scanline); + ++m_cur_scanline; + } + while(sl.num_spans() == 0); + return true; + } + + + //--------------------------------------------------------------- + unsigned byte_size() const + { + unsigned i; + unsigned size = sizeof(int32) * 4; // min_x, min_y, max_x, max_y + + for(i = 0; i < m_scanlines.size(); ++i) + { + size += sizeof(int32) * 2 + // Y, num_spans + unsigned(m_scanlines[i].num_spans) * sizeof(int32) * 2; // X, span_len + } + return size; + } + + + //--------------------------------------------------------------- + static void write_int32(int8u* dst, int32 val) + { + dst[0] = ((const int8u*)&val)[0]; + dst[1] = ((const int8u*)&val)[1]; + dst[2] = ((const int8u*)&val)[2]; + dst[3] = ((const int8u*)&val)[3]; + } + + + //--------------------------------------------------------------- + void serialize(int8u* data) const + { + unsigned i; + + write_int32(data, min_x()); // min_x + data += sizeof(int32); + write_int32(data, min_y()); // min_y + data += sizeof(int32); + write_int32(data, max_x()); // max_x + data += sizeof(int32); + write_int32(data, max_y()); // max_y + data += sizeof(int32); + + for(i = 0; i < m_scanlines.size(); ++i) + { + const scanline_data& sl_this = m_scanlines[i]; + + write_int32(data, sl_this.y); // Y + data += sizeof(int32); + + write_int32(data, sl_this.num_spans); // num_spans + data += sizeof(int32); + + unsigned num_spans = sl_this.num_spans; + unsigned span_idx = sl_this.start_span; + do + { + const span_data& sp = m_spans[span_idx++]; + + write_int32(data, sp.x); // X + data += sizeof(int32); + + write_int32(data, sp.len); // len + data += sizeof(int32); + } + while(--num_spans); + } + } + + + //--------------------------------------------------------------- + const scanline_data& scanline_by_index(unsigned i) const + { + return (i < m_scanlines.size()) ? m_scanlines[i] : m_fake_scanline; + } + + //--------------------------------------------------------------- + const span_data& span_by_index(unsigned i) const + { + return (i < m_spans.size()) ? m_spans[i] : m_fake_span; + } + + + private: + pod_bvector<span_data, 10> m_spans; + pod_bvector<scanline_data, 8> m_scanlines; + span_data m_fake_span; + scanline_data m_fake_scanline; + int m_min_x; + int m_min_y; + int m_max_x; + int m_max_y; + unsigned m_cur_scanline; + }; + + + + + + + + + + + + + + //---------------------------------------serialized_scanlines_adaptor_bin + class serialized_scanlines_adaptor_bin + { + public: + typedef bool cover_type; + + //-------------------------------------------------------------------- + class embedded_scanline + { + public: + + //---------------------------------------------------------------- + class const_iterator + { + public: + struct span + { + int32 x; + int32 len; + }; + + const_iterator() : m_ptr(0) {} + const_iterator(const embedded_scanline* sl) : + m_ptr(sl->m_ptr), + m_dx(sl->m_dx) + { + m_span.x = read_int32() + m_dx; + m_span.len = read_int32(); + } + + const span& operator*() const { return m_span; } + const span* operator->() const { return &m_span; } + + void operator ++ () + { + m_span.x = read_int32() + m_dx; + m_span.len = read_int32(); + } + + private: + int read_int32() + { + int32 val; + ((int8u*)&val)[0] = *m_ptr++; + ((int8u*)&val)[1] = *m_ptr++; + ((int8u*)&val)[2] = *m_ptr++; + ((int8u*)&val)[3] = *m_ptr++; + return val; + } + + const int8u* m_ptr; + span m_span; + int m_dx; + }; + + friend class const_iterator; + + + //---------------------------------------------------------------- + embedded_scanline() : m_ptr(0), m_y(0), m_num_spans(0) {} + + //---------------------------------------------------------------- + void reset(int, int) {} + unsigned num_spans() const { return m_num_spans; } + int y() const { return m_y; } + const_iterator begin() const { return const_iterator(this); } + + + private: + //---------------------------------------------------------------- + int read_int32() + { + int32 val; + ((int8u*)&val)[0] = *m_ptr++; + ((int8u*)&val)[1] = *m_ptr++; + ((int8u*)&val)[2] = *m_ptr++; + ((int8u*)&val)[3] = *m_ptr++; + return val; + } + + public: + //---------------------------------------------------------------- + void init(const int8u* ptr, int dx, int dy) + { + m_ptr = ptr; + m_y = read_int32() + dy; + m_num_spans = unsigned(read_int32()); + m_dx = dx; + } + + private: + const int8u* m_ptr; + int m_y; + unsigned m_num_spans; + int m_dx; + }; + + + + public: + //-------------------------------------------------------------------- + serialized_scanlines_adaptor_bin() : + m_data(0), + m_end(0), + m_ptr(0), + m_dx(0), + m_dy(0), + m_min_x(0x7FFFFFFF), + m_min_y(0x7FFFFFFF), + m_max_x(-0x7FFFFFFF), + m_max_y(-0x7FFFFFFF) + {} + + //-------------------------------------------------------------------- + serialized_scanlines_adaptor_bin(const int8u* data, unsigned size, + double dx, double dy) : + m_data(data), + m_end(data + size), + m_ptr(data), + m_dx(iround(dx)), + m_dy(iround(dy)), + m_min_x(0x7FFFFFFF), + m_min_y(0x7FFFFFFF), + m_max_x(-0x7FFFFFFF), + m_max_y(-0x7FFFFFFF) + {} + + //-------------------------------------------------------------------- + void init(const int8u* data, unsigned size, double dx, double dy) + { + m_data = data; + m_end = data + size; + m_ptr = data; + m_dx = iround(dx); + m_dy = iround(dy); + m_min_x = 0x7FFFFFFF; + m_min_y = 0x7FFFFFFF; + m_max_x = -0x7FFFFFFF; + m_max_y = -0x7FFFFFFF; + } + + private: + //-------------------------------------------------------------------- + int read_int32() + { + int32 val; + ((int8u*)&val)[0] = *m_ptr++; + ((int8u*)&val)[1] = *m_ptr++; + ((int8u*)&val)[2] = *m_ptr++; + ((int8u*)&val)[3] = *m_ptr++; + return val; + } + + public: + // Iterate scanlines interface + //-------------------------------------------------------------------- + bool rewind_scanlines() + { + m_ptr = m_data; + if(m_ptr < m_end) + { + m_min_x = read_int32() + m_dx; + m_min_y = read_int32() + m_dy; + m_max_x = read_int32() + m_dx; + m_max_y = read_int32() + m_dy; + } + return m_ptr < m_end; + } + + //-------------------------------------------------------------------- + int min_x() const { return m_min_x; } + int min_y() const { return m_min_y; } + int max_x() const { return m_max_x; } + int max_y() const { return m_max_y; } + + //-------------------------------------------------------------------- + template<class Scanline> bool sweep_scanline(Scanline& sl) + { + sl.reset_spans(); + for(;;) + { + if(m_ptr >= m_end) return false; + + int y = read_int32() + m_dy; + unsigned num_spans = read_int32(); + + do + { + int x = read_int32() + m_dx; + int len = read_int32(); + + if(len < 0) len = -len; + sl.add_span(x, unsigned(len), cover_full); + } + while(--num_spans); + + if(sl.num_spans()) + { + sl.finalize(y); + break; + } + } + return true; + } + + + //-------------------------------------------------------------------- + // Specialization for embedded_scanline + bool sweep_scanline(embedded_scanline& sl) + { + do + { + if(m_ptr >= m_end) return false; + + sl.init(m_ptr, m_dx, m_dy); + + // Jump to the next scanline + //-------------------------- + read_int32(); // Y + int num_spans = read_int32(); // num_spans + m_ptr += num_spans * sizeof(int32) * 2; + } + while(sl.num_spans() == 0); + return true; + } + + private: + const int8u* m_data; + const int8u* m_end; + const int8u* m_ptr; + int m_dx; + int m_dy; + int m_min_x; + int m_min_y; + int m_max_x; + int m_max_y; + }; + + + +} + +#endif + diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_scanline_u.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_scanline_u.h new file mode 100644 index 00000000000..2628f55f47b --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_scanline_u.h @@ -0,0 +1,499 @@ +//---------------------------------------------------------------------------- +// 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 32-bit screen coordinates (scanline32_u) has been sponsored by +// Liberty Technology Systems, Inc., visit http://lib-sys.com +// +// Liberty Technology Systems, Inc. is the provider of +// PostScript and PDF technology for software developers. +// +//---------------------------------------------------------------------------- + +#ifndef AGG_SCANLINE_U_INCLUDED +#define AGG_SCANLINE_U_INCLUDED + +#include "agg_array.h" + +namespace agg +{ + //=============================================================scanline_u8 + // + // Unpacked scanline container class + // + // This class is used to transfer data from a scanline rasterizer + // to the rendering buffer. It's organized very simple. The class stores + // information of horizontal spans to render it into a pixel-map buffer. + // Each span has staring X, length, and an array of bytes that determine the + // cover-values for each pixel. + // Before using this class you should know the minimal and maximal pixel + // coordinates of your scanline. The protocol of using is: + // 1. reset(min_x, max_x) + // 2. add_cell() / add_span() - accumulate scanline. + // When forming one scanline the next X coordinate must be always greater + // than the last stored one, i.e. it works only with ordered coordinates. + // 3. Call finalize(y) and render the scanline. + // 3. Call reset_spans() to prepare for the new scanline. + // + // 4. Rendering: + // + // Scanline provides an iterator class that allows you to extract + // the spans and the cover values for each pixel. Be aware that clipping + // has not been done yet, so you should perform it yourself. + // Use scanline_u8::iterator to render spans: + //------------------------------------------------------------------------- + // + // int y = sl.y(); // Y-coordinate of the scanline + // + // ************************************ + // ...Perform vertical clipping here... + // ************************************ + // + // scanline_u8::const_iterator span = sl.begin(); + // + // unsigned char* row = m_rbuf->row(y); // The address of the beginning + // // of the current row + // + // unsigned num_spans = sl.num_spans(); // Number of spans. It's guaranteed that + // // num_spans is always greater than 0. + // + // do + // { + // const scanline_u8::cover_type* covers = + // span->covers; // The array of the cover values + // + // int num_pix = span->len; // Number of pixels of the span. + // // Always greater than 0, still it's + // // better to use "int" instead of + // // "unsigned" because it's more + // // convenient for clipping + // int x = span->x; + // + // ************************************** + // ...Perform horizontal clipping here... + // ...you have x, covers, and pix_count.. + // ************************************** + // + // unsigned char* dst = row + x; // Calculate the start address of the row. + // // In this case we assume a simple + // // grayscale image 1-byte per pixel. + // do + // { + // *dst++ = *covers++; // Hypotetical rendering. + // } + // while(--num_pix); + // + // ++span; + // } + // while(--num_spans); // num_spans cannot be 0, so this loop is quite safe + //------------------------------------------------------------------------ + // + // The question is: why should we accumulate the whole scanline when we + // could render just separate spans when they're ready? + // That's because using the scanline is generally faster. When is consists + // of more than one span the conditions for the processor cash system + // are better, because switching between two different areas of memory + // (that can be very large) occurs less frequently. + //------------------------------------------------------------------------ + class scanline_u8 + { + public: + typedef scanline_u8 self_type; + typedef int8u cover_type; + typedef int16 coord_type; + + //-------------------------------------------------------------------- + struct span + { + coord_type x; + coord_type len; + cover_type* covers; + }; + + typedef span* iterator; + typedef const span* const_iterator; + + //-------------------------------------------------------------------- + scanline_u8() : + m_min_x(0), + m_last_x(0x7FFFFFF0), + m_cur_span(0) + {} + + //-------------------------------------------------------------------- + void reset(int min_x, int max_x) + { + unsigned max_len = max_x - min_x + 2; + if(max_len > m_spans.size()) + { + m_spans.resize(max_len); + m_covers.resize(max_len); + } + m_last_x = 0x7FFFFFF0; + m_min_x = min_x; + m_cur_span = &m_spans[0]; + } + + //-------------------------------------------------------------------- + void add_cell(int x, unsigned cover) + { + x -= m_min_x; + m_covers[x] = (cover_type)cover; + if(x == m_last_x+1) + { + m_cur_span->len++; + } + else + { + m_cur_span++; + m_cur_span->x = (coord_type)(x + m_min_x); + m_cur_span->len = 1; + m_cur_span->covers = &m_covers[x]; + } + m_last_x = x; + } + + //-------------------------------------------------------------------- + void add_cells(int x, unsigned len, const cover_type* covers) + { + x -= m_min_x; + memcpy(&m_covers[x], covers, len * sizeof(cover_type)); + if(x == m_last_x+1) + { + m_cur_span->len += (coord_type)len; + } + else + { + m_cur_span++; + m_cur_span->x = (coord_type)(x + m_min_x); + m_cur_span->len = (coord_type)len; + m_cur_span->covers = &m_covers[x]; + } + m_last_x = x + len - 1; + } + + //-------------------------------------------------------------------- + void add_span(int x, unsigned len, unsigned cover) + { + x -= m_min_x; + memset(&m_covers[x], cover, len); + if(x == m_last_x+1) + { + m_cur_span->len += (coord_type)len; + } + else + { + m_cur_span++; + m_cur_span->x = (coord_type)(x + m_min_x); + m_cur_span->len = (coord_type)len; + m_cur_span->covers = &m_covers[x]; + } + m_last_x = x + len - 1; + } + + //-------------------------------------------------------------------- + void finalize(int y) + { + m_y = y; + } + + //-------------------------------------------------------------------- + void reset_spans() + { + m_last_x = 0x7FFFFFF0; + m_cur_span = &m_spans[0]; + } + + //-------------------------------------------------------------------- + int y() const { return m_y; } + unsigned num_spans() const { return unsigned(m_cur_span - &m_spans[0]); } + const_iterator begin() const { return &m_spans[1]; } + iterator begin() { return &m_spans[1]; } + + private: + scanline_u8(const self_type&); + const self_type& operator = (const self_type&); + + private: + int m_min_x; + int m_last_x; + int m_y; + pod_array<cover_type> m_covers; + pod_array<span> m_spans; + span* m_cur_span; + }; + + + + + //==========================================================scanline_u8_am + // + // The scanline container with alpha-masking + // + //------------------------------------------------------------------------ + template<class AlphaMask> + class scanline_u8_am : public scanline_u8 + { + public: + typedef scanline_u8 base_type; + typedef AlphaMask alpha_mask_type; + typedef base_type::cover_type cover_type; + typedef base_type::coord_type coord_type; + + scanline_u8_am() : base_type(), m_alpha_mask(0) {} + scanline_u8_am(AlphaMask& am) : base_type(), m_alpha_mask(&am) {} + + //-------------------------------------------------------------------- + void finalize(int span_y) + { + base_type::finalize(span_y); + if(m_alpha_mask) + { + typename base_type::iterator span = base_type::begin(); + unsigned count = base_type::num_spans(); + do + { + m_alpha_mask->combine_hspan(span->x, + base_type::y(), + span->covers, + span->len); + ++span; + } + while(--count); + } + } + + private: + AlphaMask* m_alpha_mask; + }; + + + + + //===========================================================scanline32_u8 + class scanline32_u8 + { + public: + typedef scanline32_u8 self_type; + typedef int8u cover_type; + typedef int32 coord_type; + + //-------------------------------------------------------------------- + struct span + { + span() {} + span(coord_type x_, coord_type len_, cover_type* covers_) : + x(x_), len(len_), covers(covers_) {} + + coord_type x; + coord_type len; + cover_type* covers; + }; + + typedef pod_bvector<span, 4> span_array_type; + + //-------------------------------------------------------------------- + class const_iterator + { + public: + const_iterator(const span_array_type& spans) : + m_spans(spans), + m_span_idx(0) + {} + + const span& operator*() const { return m_spans[m_span_idx]; } + const span* operator->() const { return &m_spans[m_span_idx]; } + + void operator ++ () { ++m_span_idx; } + + private: + const span_array_type& m_spans; + unsigned m_span_idx; + }; + + //-------------------------------------------------------------------- + class iterator + { + public: + iterator(span_array_type& spans) : + m_spans(spans), + m_span_idx(0) + {} + + span& operator*() { return m_spans[m_span_idx]; } + span* operator->() { return &m_spans[m_span_idx]; } + + void operator ++ () { ++m_span_idx; } + + private: + span_array_type& m_spans; + unsigned m_span_idx; + }; + + + + //-------------------------------------------------------------------- + scanline32_u8() : + m_min_x(0), + m_last_x(0x7FFFFFF0), + m_covers() + {} + + //-------------------------------------------------------------------- + void reset(int min_x, int max_x) + { + unsigned max_len = max_x - min_x + 2; + if(max_len > m_covers.size()) + { + m_covers.resize(max_len); + } + m_last_x = 0x7FFFFFF0; + m_min_x = min_x; + m_spans.remove_all(); + } + + //-------------------------------------------------------------------- + void add_cell(int x, unsigned cover) + { + x -= m_min_x; + m_covers[x] = cover_type(cover); + if(x == m_last_x+1) + { + m_spans.last().len++; + } + else + { + m_spans.add(span(coord_type(x + m_min_x), 1, &m_covers[x])); + } + m_last_x = x; + } + + //-------------------------------------------------------------------- + void add_cells(int x, unsigned len, const cover_type* covers) + { + x -= m_min_x; + memcpy(&m_covers[x], covers, len * sizeof(cover_type)); + if(x == m_last_x+1) + { + m_spans.last().len += coord_type(len); + } + else + { + m_spans.add(span(coord_type(x + m_min_x), + coord_type(len), + &m_covers[x])); + } + m_last_x = x + len - 1; + } + + //-------------------------------------------------------------------- + void add_span(int x, unsigned len, unsigned cover) + { + x -= m_min_x; + memset(&m_covers[x], cover, len); + if(x == m_last_x+1) + { + m_spans.last().len += coord_type(len); + } + else + { + m_spans.add(span(coord_type(x + m_min_x), + coord_type(len), + &m_covers[x])); + } + m_last_x = x + len - 1; + } + + //-------------------------------------------------------------------- + void finalize(int y) + { + m_y = y; + } + + //-------------------------------------------------------------------- + void reset_spans() + { + m_last_x = 0x7FFFFFF0; + m_spans.remove_all(); + } + + //-------------------------------------------------------------------- + int y() const { return m_y; } + unsigned num_spans() const { return m_spans.size(); } + const_iterator begin() const { return const_iterator(m_spans); } + iterator begin() { return iterator(m_spans); } + + private: + scanline32_u8(const self_type&); + const self_type& operator = (const self_type&); + + private: + int m_min_x; + int m_last_x; + int m_y; + pod_array<cover_type> m_covers; + span_array_type m_spans; + }; + + + + + //========================================================scanline32_u8_am + // + // The scanline container with alpha-masking + // + //------------------------------------------------------------------------ + template<class AlphaMask> + class scanline32_u8_am : public scanline32_u8 + { + public: + typedef scanline32_u8 base_type; + typedef AlphaMask alpha_mask_type; + typedef base_type::cover_type cover_type; + typedef base_type::coord_type coord_type; + + + scanline32_u8_am() : base_type(), m_alpha_mask(0) {} + scanline32_u8_am(AlphaMask& am) : base_type(), m_alpha_mask(&am) {} + + //-------------------------------------------------------------------- + void finalize(int span_y) + { + base_type::finalize(span_y); + if(m_alpha_mask) + { + typename base_type::iterator span = base_type::begin(); + unsigned count = base_type::num_spans(); + do + { + m_alpha_mask->combine_hspan(span->x, + base_type::y(), + span->covers, + span->len); + ++span; + } + while(--count); + } + } + + private: + AlphaMask* m_alpha_mask; + }; + + + +} + +#endif + diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_shorten_path.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_shorten_path.h new file mode 100644 index 00000000000..dd9929ff974 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_shorten_path.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_SHORTEN_PATH_INCLUDED +#define AGG_SHORTEN_PATH_INCLUDED + +#include "agg_basics.h" +#include "agg_vertex_sequence.h" + +namespace agg +{ + + //===========================================================shorten_path + template<class VertexSequence> + void shorten_path(VertexSequence& vs, double s, unsigned closed = 0) + { + typedef typename VertexSequence::value_type vertex_type; + + if(s > 0.0 && vs.size() > 1) + { + double d; + int n = int(vs.size() - 2); + while(n) + { + d = vs[n].dist; + if(d > s) break; + vs.remove_last(); + s -= d; + --n; + } + if(vs.size() < 2) + { + vs.remove_all(); + } + else + { + n = vs.size() - 1; + vertex_type& prev = vs[n-1]; + vertex_type& last = vs[n]; + d = (prev.dist - s) / prev.dist; + double x = prev.x + (last.x - prev.x) * d; + double y = prev.y + (last.y - prev.y) * d; + last.x = x; + last.y = y; + if(!prev(last)) vs.remove_last(); + vs.close(closed != 0); + } + } + } + + +} + +#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 00000000000..3d0dce4b447 --- /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_allocator.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_allocator.h new file mode 100644 index 00000000000..201b69bb01e --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_allocator.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_SPAN_ALLOCATOR_INCLUDED +#define AGG_SPAN_ALLOCATOR_INCLUDED + +#include "agg_array.h" + +namespace agg +{ + //----------------------------------------------------------span_allocator + template<class ColorT> class span_allocator + { + public: + typedef ColorT color_type; + + //-------------------------------------------------------------------- + AGG_INLINE color_type* allocate(unsigned span_len) + { + if(span_len > m_span.size()) + { + // To reduce the number of reallocs we align the + // span_len to 256 color elements. + // Well, I just like this number and it looks reasonable. + //----------------------- + m_span.resize(((span_len + 255) >> 8) << 8); + } + return &m_span[0]; + } + + AGG_INLINE color_type* span() { return &m_span[0]; } + AGG_INLINE unsigned max_span_len() const { return m_span.size(); } + + private: + pod_array<color_type> m_span; + }; +} + + +#endif + + diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_converter.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_converter.h new file mode 100644 index 00000000000..91d0f87c256 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_converter.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_SPAN_CONVERTER_INCLUDED +#define AGG_SPAN_CONVERTER_INCLUDED + +#include "agg_basics.h" + +namespace agg +{ + //----------------------------------------------------------span_converter + template<class SpanGenerator, class SpanConverter> class span_converter + { + public: + typedef typename SpanGenerator::color_type color_type; + + span_converter(SpanGenerator& span_gen, SpanConverter& span_cnv) : + m_span_gen(&span_gen), m_span_cnv(&span_cnv) {} + + void attach_generator(SpanGenerator& span_gen) { m_span_gen = &span_gen; } + void attach_converter(SpanConverter& span_cnv) { m_span_cnv = &span_cnv; } + + //-------------------------------------------------------------------- + void prepare() + { + m_span_gen->prepare(); + m_span_cnv->prepare(); + } + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + m_span_gen->generate(span, x, y, len); + m_span_cnv->generate(span, x, y, len); + } + + private: + SpanGenerator* m_span_gen; + SpanConverter* m_span_cnv; + }; + +} + +#endif diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gouraud.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gouraud.h new file mode 100644 index 00000000000..2986c88feec --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gouraud.h @@ -0,0 +1,172 @@ +//---------------------------------------------------------------------------- +// 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_GOURAUD_INCLUDED +#define AGG_SPAN_GOURAUD_INCLUDED + +#include "agg_basics.h" +#include "agg_math.h" + +namespace agg +{ + + //============================================================span_gouraud + template<class ColorT> class span_gouraud + { + public: + typedef ColorT color_type; + + struct coord_type + { + double x; + double y; + color_type color; + }; + + //-------------------------------------------------------------------- + span_gouraud() : + m_vertex(0) + { + m_cmd[0] = path_cmd_stop; + } + + //-------------------------------------------------------------------- + span_gouraud(const color_type& c1, + const color_type& c2, + const color_type& c3, + double x1, double y1, + double x2, double y2, + double x3, double y3, + double d) : + m_vertex(0) + { + colors(c1, c2, c3); + triangle(x1, y1, x2, y2, x3, y3, d); + } + + //-------------------------------------------------------------------- + void colors(ColorT c1, ColorT c2, ColorT c3) + { + m_coord[0].color = c1; + m_coord[1].color = c2; + m_coord[2].color = c3; + } + + //-------------------------------------------------------------------- + // Sets the triangle and dilates it if needed. + // The trick here is to calculate beveled joins in the vertices of the + // triangle and render it as a 6-vertex polygon. + // It's necessary to achieve numerical stability. + // However, the coordinates to interpolate colors are calculated + // as miter joins (calc_intersection). + void triangle(double x1, double y1, + double x2, double y2, + double x3, double y3, + double d) + { + m_coord[0].x = m_x[0] = x1; + m_coord[0].y = m_y[0] = y1; + m_coord[1].x = m_x[1] = x2; + m_coord[1].y = m_y[1] = y2; + m_coord[2].x = m_x[2] = x3; + m_coord[2].y = m_y[2] = y3; + m_cmd[0] = path_cmd_move_to; + m_cmd[1] = path_cmd_line_to; + m_cmd[2] = path_cmd_line_to; + m_cmd[3] = path_cmd_stop; + + if(d != 0.0) + { + dilate_triangle(m_coord[0].x, m_coord[0].y, + m_coord[1].x, m_coord[1].y, + m_coord[2].x, m_coord[2].y, + m_x, m_y, d); + + calc_intersection(m_x[4], m_y[4], m_x[5], m_y[5], + m_x[0], m_y[0], m_x[1], m_y[1], + &m_coord[0].x, &m_coord[0].y); + + calc_intersection(m_x[0], m_y[0], m_x[1], m_y[1], + m_x[2], m_y[2], m_x[3], m_y[3], + &m_coord[1].x, &m_coord[1].y); + + calc_intersection(m_x[2], m_y[2], m_x[3], m_y[3], + m_x[4], m_y[4], m_x[5], m_y[5], + &m_coord[2].x, &m_coord[2].y); + m_cmd[3] = path_cmd_line_to; + m_cmd[4] = path_cmd_line_to; + m_cmd[5] = path_cmd_line_to; + m_cmd[6] = path_cmd_stop; + } + } + + //-------------------------------------------------------------------- + // Vertex Source Interface to feed the coordinates to the rasterizer + void rewind(unsigned) + { + m_vertex = 0; + } + + //-------------------------------------------------------------------- + unsigned vertex(double* x, double* y) + { + *x = m_x[m_vertex]; + *y = m_y[m_vertex]; + return m_cmd[m_vertex++]; + } + + protected: + //-------------------------------------------------------------------- + void arrange_vertices(coord_type* coord) const + { + coord[0] = m_coord[0]; + coord[1] = m_coord[1]; + coord[2] = m_coord[2]; + + if(m_coord[0].y > m_coord[2].y) + { + coord[0] = m_coord[2]; + coord[2] = m_coord[0]; + } + + coord_type tmp; + if(coord[0].y > coord[1].y) + { + tmp = coord[1]; + coord[1] = coord[0]; + coord[0] = tmp; + } + + if(coord[1].y > coord[2].y) + { + tmp = coord[2]; + coord[2] = coord[1]; + coord[1] = tmp; + } + } + + private: + //-------------------------------------------------------------------- + coord_type m_coord[3]; + double m_x[8]; + double m_y[8]; + unsigned m_cmd[8]; + unsigned m_vertex; + }; + +} + +#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 00000000000..d5fc39d1023 --- /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_gouraud_rgba.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gouraud_rgba.h new file mode 100644 index 00000000000..1b285720297 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_gouraud_rgba.h @@ -0,0 +1,277 @@ +//---------------------------------------------------------------------------- +// 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_RGBA_INCLUDED +#define AGG_SPAN_GOURAUD_RGBA_INCLUDED + +#include "agg_basics.h" +#include "agg_color_rgba.h" +#include "agg_dda_line.h" +#include "agg_span_gouraud.h" + +namespace agg +{ + + //=======================================================span_gouraud_rgba + template<class ColorT> class span_gouraud_rgba : public span_gouraud<ColorT> + { + public: + typedef ColorT color_type; + typedef typename ColorT::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 rgba_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 = (dy < 1e-5) ? 1e5 : 1.0 / dy; + m_r1 = c1.color.r; + m_g1 = c1.color.g; + m_b1 = c1.color.b; + m_a1 = c1.color.a; + m_dr = c2.color.r - m_r1; + m_dg = c2.color.g - m_g1; + m_db = c2.color.b - m_b1; + m_da = c2.color.a - m_a1; + } + + void calc(double y) + { + double k = (y - m_y1) * m_1dy; + if(k < 0.0) k = 0.0; + if(k > 1.0) k = 1.0; + m_r = m_r1 + iround(m_dr * k); + m_g = m_g1 + iround(m_dg * k); + m_b = m_b1 + iround(m_db * k); + m_a = m_a1 + iround(m_da * k); + m_x = iround((m_x1 + m_dx * k) * subpixel_scale); + } + + double m_x1; + double m_y1; + double m_dx; + double m_1dy; + int m_r1; + int m_g1; + int m_b1; + int m_a1; + int m_dr; + int m_dg; + int m_db; + int m_da; + int m_r; + int m_g; + int m_b; + int m_a; + int m_x; + }; + + public: + + //-------------------------------------------------------------------- + span_gouraud_rgba() {} + span_gouraud_rgba(const color_type& c1, + const color_type& c2, + const color_type& c3, + double x1, double y1, + double x2, double y2, + double x3, double y3, + double d = 0) : + base_type(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_rgba1.init(coord[0], coord[2]); + m_rgba2.init(coord[0], coord[1]); + m_rgba3.init(coord[1], coord[2]); + } + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + m_rgba1.calc(y);//(m_rgba1.m_1dy > 2) ? m_rgba1.m_y1 : y); + const rgba_calc* pc1 = &m_rgba1; + const rgba_calc* pc2 = &m_rgba2; + + if(y <= m_y2) + { + // Bottom part of the triangle (first subtriangle) + //------------------------- + m_rgba2.calc(y + m_rgba2.m_1dy); + } + else + { + // Upper part (second subtriangle) + m_rgba3.calc(y - m_rgba3.m_1dy); + //------------------------- + pc2 = &m_rgba3; + } + + if(m_swap) + { + // It means that the triangle is oriented clockwise, + // so that we need to swap the controlling structures + //------------------------- + const rgba_calc* t = pc2; + pc2 = pc1; + pc1 = t; + } + + // Get the horizontal length with subpixel accuracy + // and protect it from division by zero + //------------------------- + int nlen = abs(pc2->m_x - pc1->m_x); + if(nlen <= 0) nlen = 1; + + dda_line_interpolator<14> r(pc1->m_r, pc2->m_r, nlen); + dda_line_interpolator<14> g(pc1->m_g, pc2->m_g, nlen); + dda_line_interpolator<14> b(pc1->m_b, pc2->m_b, nlen); + dda_line_interpolator<14> a(pc1->m_a, pc2->m_a, nlen); + + // Calculate the starting point of the gradient with subpixel + // accuracy and correct (roll back) the interpolators. + // This operation will also clip the beginning of the span + // if necessary. + //------------------------- + int start = pc1->m_x - (x << subpixel_shift); + r -= start; + g -= start; + b -= start; + a -= start; + nlen += start; + + int vr, vg, vb, va; + enum lim_e { lim = color_type::base_mask }; + + // Beginning part of the span. Since we rolled back the + // interpolators, the color values may have overflow. + // So that, we render the beginning part with checking + // for overflow. It lasts until "start" is positive; + // typically it's 1-2 pixels, but may be more in some cases. + //------------------------- + while(len && start > 0) + { + vr = r.y(); + vg = g.y(); + vb = b.y(); + va = a.y(); + if(vr < 0) { vr = 0; }; if(vr > lim) { vr = lim; }; + if(vg < 0) { vg = 0; }; if(vg > lim) { vg = lim; }; + if(vb < 0) { vb = 0; }; if(vb > lim) { vb = lim; }; + if(va < 0) { va = 0; }; if(va > lim) { va = lim; }; + span->r = (value_type)vr; + span->g = (value_type)vg; + span->b = (value_type)vb; + span->a = (value_type)va; + r += subpixel_scale; + g += subpixel_scale; + b += subpixel_scale; + a += subpixel_scale; + nlen -= subpixel_scale; + start -= subpixel_scale; + ++span; + --len; + } + + // Middle part, no checking for overflow. + // Actual spans can be longer than the calculated length + // because of anti-aliasing, thus, the interpolators can + // overflow. But while "nlen" is positive we are safe. + //------------------------- + while(len && nlen > 0) + { + span->r = (value_type)r.y(); + span->g = (value_type)g.y(); + span->b = (value_type)b.y(); + span->a = (value_type)a.y(); + r += subpixel_scale; + g += subpixel_scale; + b += 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) + { + vr = r.y(); + vg = g.y(); + vb = b.y(); + va = a.y(); + if(vr < 0) { vr = 0; }; if(vr > lim) { vr = lim; }; + if(vg < 0) { vg = 0; }; if(vg > lim) { vg = lim; }; + if(vb < 0) { vb = 0; }; if(vb > lim) { vb = lim; }; + if(va < 0) { va = 0; }; if(va > lim) { va = lim; }; + span->r = (value_type)vr; + span->g = (value_type)vg; + span->b = (value_type)vb; + span->a = (value_type)va; + r += subpixel_scale; + g += subpixel_scale; + b += subpixel_scale; + a += subpixel_scale; + ++span; + --len; + } + } + + private: + bool m_swap; + int m_y2; + rgba_calc m_rgba1; + rgba_calc m_rgba2; + rgba_calc m_rgba3; + }; + + + +} + +#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 00000000000..58b506dcfe6 --- /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 00000000000..2ec040e3b93 --- /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 = ⁡ } + 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 00000000000..899bb799b6c --- /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 00000000000..c99eaca166b --- /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.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_image_filter.h new file mode 100644 index 00000000000..2f613e5d86c --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_image_filter.h @@ -0,0 +1,246 @@ +//---------------------------------------------------------------------------- +// 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 +//---------------------------------------------------------------------------- +// +// Image transformations with filtering. Span generator base class +// +//---------------------------------------------------------------------------- +#ifndef AGG_SPAN_IMAGE_FILTER_INCLUDED +#define AGG_SPAN_IMAGE_FILTER_INCLUDED + +#include "agg_basics.h" +#include "agg_image_filters.h" +#include "agg_span_interpolator_linear.h" + +namespace agg +{ + + //-------------------------------------------------------span_image_filter + template<class Source, class Interpolator> class span_image_filter + { + public: + typedef Source source_type; + typedef Interpolator interpolator_type; + + //-------------------------------------------------------------------- + span_image_filter() {} + span_image_filter(source_type& src, + interpolator_type& interpolator, + image_filter_lut* filter) : + m_src(&src), + m_interpolator(&interpolator), + m_filter(filter), + m_dx_dbl(0.5), + m_dy_dbl(0.5), + m_dx_int(image_subpixel_scale / 2), + m_dy_int(image_subpixel_scale / 2) + {} + void attach(source_type& v) { m_src = &v; } + + //-------------------------------------------------------------------- + source_type& source() { return *m_src; } + const source_type& source() const { return *m_src; } + const image_filter_lut& filter() const { return *m_filter; } + int filter_dx_int() const { return m_dx_int; } + int filter_dy_int() const { return m_dy_int; } + double filter_dx_dbl() const { return m_dx_dbl; } + double filter_dy_dbl() const { return m_dy_dbl; } + + //-------------------------------------------------------------------- + void interpolator(interpolator_type& v) { m_interpolator = &v; } + void filter(image_filter_lut& v) { m_filter = &v; } + void filter_offset(double dx, double dy) + { + m_dx_dbl = dx; + m_dy_dbl = dy; + m_dx_int = iround(dx * image_subpixel_scale); + m_dy_int = iround(dy * image_subpixel_scale); + } + void filter_offset(double d) { filter_offset(d, d); } + + //-------------------------------------------------------------------- + interpolator_type& interpolator() { return *m_interpolator; } + + //-------------------------------------------------------------------- + void prepare() {} + + //-------------------------------------------------------------------- + private: + source_type* m_src; + interpolator_type* m_interpolator; + image_filter_lut* m_filter; + double m_dx_dbl; + double m_dy_dbl; + unsigned m_dx_int; + unsigned m_dy_int; + }; + + + + + //==============================================span_image_resample_affine + template<class Source> + class span_image_resample_affine : + public span_image_filter<Source, span_interpolator_linear<trans_affine> > + { + public: + typedef Source source_type; + typedef span_interpolator_linear<trans_affine> interpolator_type; + typedef span_image_filter<source_type, interpolator_type> base_type; + + //-------------------------------------------------------------------- + span_image_resample_affine() : + m_scale_limit(200.0), + m_blur_x(1.0), + m_blur_y(1.0) + {} + + //-------------------------------------------------------------------- + span_image_resample_affine(source_type& src, + interpolator_type& inter, + image_filter_lut& filter) : + base_type(src, inter, &filter), + m_scale_limit(200.0), + m_blur_x(1.0), + m_blur_y(1.0) + {} + + + //-------------------------------------------------------------------- + int scale_limit() const { return uround(m_scale_limit); } + void scale_limit(int v) { m_scale_limit = v; } + + //-------------------------------------------------------------------- + double blur_x() const { return m_blur_x; } + double blur_y() const { return m_blur_y; } + void blur_x(double v) { m_blur_x = v; } + void blur_y(double v) { m_blur_y = v; } + void blur(double v) { m_blur_x = m_blur_y = v; } + + //-------------------------------------------------------------------- + void prepare() + { + double scale_x; + double scale_y; + + base_type::interpolator().transformer().scaling_abs(&scale_x, &scale_y); + + if(scale_x * scale_y > m_scale_limit) + { + scale_x = scale_x * m_scale_limit / (scale_x * scale_y); + scale_y = scale_y * m_scale_limit / (scale_x * scale_y); + } + + if(scale_x < 1) scale_x = 1; + if(scale_y < 1) scale_y = 1; + + if(scale_x > m_scale_limit) scale_x = m_scale_limit; + if(scale_y > m_scale_limit) scale_y = m_scale_limit; + + scale_x *= m_blur_x; + scale_y *= m_blur_y; + + if(scale_x < 1) scale_x = 1; + if(scale_y < 1) scale_y = 1; + + m_rx = uround( scale_x * double(image_subpixel_scale)); + m_rx_inv = uround(1.0/scale_x * double(image_subpixel_scale)); + + m_ry = uround( scale_y * double(image_subpixel_scale)); + m_ry_inv = uround(1.0/scale_y * double(image_subpixel_scale)); + } + + protected: + int m_rx; + int m_ry; + int m_rx_inv; + int m_ry_inv; + + private: + double m_scale_limit; + double m_blur_x; + double m_blur_y; + }; + + + + //=====================================================span_image_resample + template<class Source, class Interpolator> + class span_image_resample : + public span_image_filter<Source, Interpolator> + { + public: + typedef Source source_type; + typedef Interpolator interpolator_type; + typedef span_image_filter<source_type, interpolator_type> base_type; + + //-------------------------------------------------------------------- + span_image_resample() : + m_scale_limit(20), + m_blur_x(image_subpixel_scale), + m_blur_y(image_subpixel_scale) + {} + + //-------------------------------------------------------------------- + span_image_resample(source_type& src, + interpolator_type& inter, + image_filter_lut& filter) : + base_type(src, inter, &filter), + m_scale_limit(20), + m_blur_x(image_subpixel_scale), + m_blur_y(image_subpixel_scale) + {} + + //-------------------------------------------------------------------- + int scale_limit() const { return m_scale_limit; } + void scale_limit(int v) { m_scale_limit = v; } + + //-------------------------------------------------------------------- + double blur_x() const { return double(m_blur_x) / double(image_subpixel_scale); } + double blur_y() const { return double(m_blur_y) / double(image_subpixel_scale); } + void blur_x(double v) { m_blur_x = uround(v * double(image_subpixel_scale)); } + void blur_y(double v) { m_blur_y = uround(v * double(image_subpixel_scale)); } + void blur(double v) { m_blur_x = + m_blur_y = uround(v * double(image_subpixel_scale)); } + + protected: + AGG_INLINE void adjust_scale(int* rx, int* ry) + { + if(*rx < image_subpixel_scale) *rx = image_subpixel_scale; + if(*ry < image_subpixel_scale) *ry = image_subpixel_scale; + if(*rx > image_subpixel_scale * m_scale_limit) + { + *rx = image_subpixel_scale * m_scale_limit; + } + if(*ry > image_subpixel_scale * m_scale_limit) + { + *ry = image_subpixel_scale * m_scale_limit; + } + *rx = (*rx * m_blur_x) >> image_subpixel_shift; + *ry = (*ry * m_blur_y) >> image_subpixel_shift; + if(*rx < image_subpixel_scale) *rx = image_subpixel_scale; + if(*ry < image_subpixel_scale) *ry = image_subpixel_scale; + } + + int m_scale_limit; + int m_blur_x; + int m_blur_y; + }; + + + + +} + +#endif diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_image_filter_gray.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_image_filter_gray.h new file mode 100644 index 00000000000..e2c688e004c --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_image_filter_gray.h @@ -0,0 +1,723 @@ +//---------------------------------------------------------------------------- +// 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_GRAY_INCLUDED +#define AGG_SPAN_IMAGE_FILTER_GRAY_INCLUDED + +#include "agg_basics.h" +#include "agg_color_gray.h" +#include "agg_span_image_filter.h" + + +namespace agg +{ + + //==============================================span_image_filter_gray_nn + template<class Source, class Interpolator> + class span_image_filter_gray_nn : + public span_image_filter<Source, Interpolator> + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef Interpolator interpolator_type; + typedef span_image_filter<source_type, interpolator_type> base_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + //-------------------------------------------------------------------- + span_image_filter_gray_nn() {} + span_image_filter_gray_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); + span->v = *(const value_type*) + base_type::source().span(x >> image_subpixel_shift, + y >> image_subpixel_shift, + 1); + span->a = color_type::full_value(); + ++span; + ++base_type::interpolator(); + } while(--len); + } + }; + + + + //=========================================span_image_filter_gray_bilinear + template<class Source, class Interpolator> + class span_image_filter_gray_bilinear : + public span_image_filter<Source, Interpolator> + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef Interpolator interpolator_type; + typedef span_image_filter<source_type, interpolator_type> base_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + //-------------------------------------------------------------------- + span_image_filter_gray_bilinear() {} + span_image_filter_gray_bilinear(source_type& src, + interpolator_type& inter) : + base_type(src, inter, 0) + {} + + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + base_type::interpolator().begin(x + base_type::filter_dx_dbl(), + y + base_type::filter_dy_dbl(), len); + long_type fg; + 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; + + fg = 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); + fg += *fg_ptr * (image_subpixel_scale - x_hr) * (image_subpixel_scale - y_hr); + + fg_ptr = (const value_type*)base_type::source().next_x(); + fg += *fg_ptr * x_hr * (image_subpixel_scale - y_hr); + + fg_ptr = (const value_type*)base_type::source().next_y(); + fg += *fg_ptr * (image_subpixel_scale - x_hr) * y_hr; + + fg_ptr = (const value_type*)base_type::source().next_x(); + fg += *fg_ptr * x_hr * y_hr; + + span->v = color_type::downshift(fg, image_subpixel_shift * 2); + span->a = color_type::full_value(); + ++span; + ++base_type::interpolator(); + + } while(--len); + } + }; + + + //====================================span_image_filter_gray_bilinear_clip + template<class Source, class Interpolator> + class span_image_filter_gray_bilinear_clip : + public span_image_filter<Source, Interpolator> + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef Interpolator interpolator_type; + typedef span_image_filter<source_type, interpolator_type> base_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + //-------------------------------------------------------------------- + span_image_filter_gray_bilinear_clip() {} + span_image_filter_gray_bilinear_clip(source_type& src, + const color_type& back_color, + interpolator_type& inter) : + base_type(src, inter, 0), + m_back_color(back_color) + {} + const color_type& background_color() const { return m_back_color; } + void background_color(const color_type& v) { m_back_color = v; } + + //-------------------------------------------------------------------- + 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; + long_type src_alpha; + value_type back_v = m_back_color.v; + 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; + + if(x_lr >= 0 && y_lr >= 0 && + x_lr < maxx && y_lr < maxy) + { + fg = 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; + + fg += *fg_ptr++ * (image_subpixel_scale - x_hr) * (image_subpixel_scale - y_hr); + fg += *fg_ptr++ * (image_subpixel_scale - y_hr) * x_hr; + + ++y_lr; + fg_ptr = (const value_type*)base_type::source().row_ptr(y_lr) + x_lr; + + fg += *fg_ptr++ * (image_subpixel_scale - x_hr) * y_hr; + fg += *fg_ptr++ * x_hr * y_hr; + + fg = color_type::downshift(fg, image_subpixel_shift * 2); + src_alpha = color_type::full_value(); + } + else + { + unsigned weight; + if(x_lr < -1 || y_lr < -1 || + x_lr > maxx || y_lr > maxy) + { + fg = back_v; + src_alpha = back_a; + } + else + { + fg = src_alpha = 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 += weight * + *((const value_type*)base_type::source().row_ptr(y_lr) + x_lr); + src_alpha += weight * color_type::full_value(); + } + else + { + fg += back_v * 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 += weight * + *((const value_type*)base_type::source().row_ptr(y_lr) + x_lr); + src_alpha += weight * color_type::full_value(); + } + else + { + fg += back_v * 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 += weight * + *((const value_type*)base_type::source().row_ptr(y_lr) + x_lr); + src_alpha += weight * color_type::full_value(); + } + else + { + fg += back_v * 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 += weight * + *((const value_type*)base_type::source().row_ptr(y_lr) + x_lr); + src_alpha += weight * color_type::full_value(); + } + else + { + fg += back_v * weight; + src_alpha += back_a * weight; + } + + fg = color_type::downshift(fg, image_subpixel_shift * 2); + src_alpha = color_type::downshift(src_alpha, image_subpixel_shift * 2); + } + } + + span->v = (value_type)fg; + span->a = (value_type)src_alpha; + ++span; + ++base_type::interpolator(); + + } while(--len); + } + private: + color_type m_back_color; + }; + + + + //==============================================span_image_filter_gray_2x2 + template<class Source, class Interpolator> + class span_image_filter_gray_2x2 : + public span_image_filter<Source, Interpolator> + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef Interpolator interpolator_type; + typedef span_image_filter<source_type, interpolator_type> base_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + //-------------------------------------------------------------------- + span_image_filter_gray_2x2() {} + span_image_filter_gray_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; + + 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; + + x_hr &= image_subpixel_mask; + y_hr &= image_subpixel_mask; + + fg_ptr = (const value_type*)base_type::source().span(x_lr, y_lr, 2); + weight = (weight_array[x_hr + image_subpixel_scale] * + weight_array[y_hr + image_subpixel_scale] + + image_filter_scale / 2) >> + image_filter_shift; + fg += weight * *fg_ptr; + + fg_ptr = (const value_type*)base_type::source().next_x(); + weight = (weight_array[x_hr] * + weight_array[y_hr + image_subpixel_scale] + + image_filter_scale / 2) >> + image_filter_shift; + fg += weight * *fg_ptr; + + fg_ptr = (const value_type*)base_type::source().next_y(); + weight = (weight_array[x_hr + image_subpixel_scale] * + weight_array[y_hr] + + image_filter_scale / 2) >> + image_filter_shift; + fg += weight * *fg_ptr; + + fg_ptr = (const value_type*)base_type::source().next_x(); + weight = (weight_array[x_hr] * + weight_array[y_hr] + + image_filter_scale / 2) >> + image_filter_shift; + fg += weight * *fg_ptr; + + fg >>= image_filter_shift; + if(fg > color_type::full_value()) fg = color_type::full_value(); + + span->v = (value_type)fg; + span->a = color_type::full_value(); + ++span; + ++base_type::interpolator(); + } while(--len); + } + }; + + + + //==================================================span_image_filter_gray + template<class Source, class Interpolator> + class span_image_filter_gray : + public span_image_filter<Source, Interpolator> + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef Interpolator interpolator_type; + typedef span_image_filter<source_type, interpolator_type> base_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + //-------------------------------------------------------------------- + span_image_filter_gray() {} + span_image_filter_gray(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; + 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; + + 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(;;) + { + fg += *fg_ptr * + ((weight_y * weight_array[x_hr] + + image_filter_scale / 2) >> + image_filter_shift); + if(--x_count == 0) break; + x_hr += image_subpixel_scale; + fg_ptr = (const value_type*)base_type::source().next_x(); + } + + if(--y_count == 0) break; + y_hr += image_subpixel_scale; + fg_ptr = (const value_type*)base_type::source().next_y(); + } + + fg = color_type::downshift(fg, image_filter_shift); + if(fg < 0) fg = 0; + if(fg > color_type::full_value()) fg = color_type::full_value(); + span->v = (value_type)fg; + span->a = color_type::full_value(); + + ++span; + ++base_type::interpolator(); + + } while(--len); + } + }; + + + + //=========================================span_image_resample_gray_affine + template<class Source> + class span_image_resample_gray_affine : + public span_image_resample_affine<Source> + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef span_image_resample_affine<source_type> base_type; + typedef typename base_type::interpolator_type interpolator_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::long_type long_type; + enum base_scale_e + { + downscale_shift = image_filter_shift + }; + + //-------------------------------------------------------------------- + span_image_resample_gray_affine() {} + span_image_resample_gray_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; + + 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; + + 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 += *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 /= total_weight; + if(fg < 0) fg = 0; + if(fg > color_type::full_value()) fg = color_type::full_value(); + + span->v = (value_type)fg; + span->a = color_type::full_value(); + + ++span; + ++base_type::interpolator(); + } while(--len); + } + }; + + + + //================================================span_image_resample_gray + template<class Source, class Interpolator> + class span_image_resample_gray : + public span_image_resample<Source, Interpolator> + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef Interpolator interpolator_type; + typedef span_image_resample<source_type, interpolator_type> base_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::long_type long_type; + enum base_scale_e + { + downscale_shift = image_filter_shift + }; + + //-------------------------------------------------------------------- + span_image_resample_gray() {} + span_image_resample_gray(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; + + 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; + + int y_lr = y >> image_subpixel_shift; + int y_hr = ((image_subpixel_mask - (y & image_subpixel_mask)) * + ry_inv) >> + image_subpixel_shift; + int total_weight = 0; + int x_lr = x >> image_subpixel_shift; + int x_hr = ((image_subpixel_mask - (x & image_subpixel_mask)) * + rx_inv) >> + image_subpixel_shift; + int x_hr2 = x_hr; + const value_type* fg_ptr = + (const value_type*)base_type::source().span(x_lr, y_lr, len_x_lr); + + for(;;) + { + int weight_y = weight_array[y_hr]; + x_hr = x_hr2; + for(;;) + { + int weight = (weight_y * weight_array[x_hr] + + image_filter_scale / 2) >> + downscale_shift; + fg += *fg_ptr * weight; + total_weight += weight; + x_hr += rx_inv; + if(x_hr >= filter_scale) break; + fg_ptr = (const value_type*)base_type::source().next_x(); + } + y_hr += ry_inv; + if(y_hr >= filter_scale) break; + fg_ptr = (const value_type*)base_type::source().next_y(); + } + + fg /= total_weight; + if(fg < 0) fg = 0; + if(fg > color_type::full_value()) fg = color_type::full_value(); + + span->v = (value_type)fg; + 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_image_filter_rgb.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_image_filter_rgb.h new file mode 100644 index 00000000000..f78ae19c1b4 --- /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_image_filter_rgba.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_image_filter_rgba.h new file mode 100644 index 00000000000..af7a1a2ef0d --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_image_filter_rgba.h @@ -0,0 +1,890 @@ +//---------------------------------------------------------------------------- +// 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_RGBA_INCLUDED +#define AGG_SPAN_IMAGE_FILTER_RGBA_INCLUDED + +#include "agg_basics.h" +#include "agg_color_rgba.h" +#include "agg_span_image_filter.h" + + +namespace agg +{ + + //==============================================span_image_filter_rgba_nn + template<class Source, class Interpolator> + class span_image_filter_rgba_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_rgba_nn() {} + span_image_filter_rgba_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 = fg_ptr[order_type::A]; + ++span; + ++base_type::interpolator(); + + } while(--len); + } + }; + + + + //=========================================span_image_filter_rgba_bilinear + template<class Source, class Interpolator> + class span_image_filter_rgba_bilinear : + public span_image_filter<Source, Interpolator> + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef typename source_type::order_type order_type; + typedef Interpolator interpolator_type; + typedef span_image_filter<source_type, interpolator_type> base_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::calc_type calc_type; + typedef typename color_type::long_type long_type; + + //-------------------------------------------------------------------- + span_image_filter_rgba_bilinear() {} + span_image_filter_rgba_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[4]; + 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] = + fg[3] = image_subpixel_scale * image_subpixel_scale / 2; + + x_hr &= image_subpixel_mask; + y_hr &= image_subpixel_mask; + + fg_ptr = (const value_type*)base_type::source().span(x_lr, y_lr, 2); + weight = (image_subpixel_scale - x_hr) * + (image_subpixel_scale - y_hr); + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + fg[3] += weight * *fg_ptr; + + fg_ptr = (const value_type*)base_type::source().next_x(); + weight = x_hr * (image_subpixel_scale - y_hr); + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + fg[3] += weight * *fg_ptr; + + fg_ptr = (const value_type*)base_type::source().next_y(); + weight = (image_subpixel_scale - x_hr) * y_hr; + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + fg[3] += weight * *fg_ptr; + + fg_ptr = (const value_type*)base_type::source().next_x(); + weight = x_hr * y_hr; + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + fg[3] += weight * *fg_ptr; + + span->r = value_type(color_type::downshift(fg[order_type::R], image_subpixel_shift * 2)); + span->g = value_type(color_type::downshift(fg[order_type::G], image_subpixel_shift * 2)); + span->b = value_type(color_type::downshift(fg[order_type::B], image_subpixel_shift * 2)); + span->a = value_type(color_type::downshift(fg[order_type::A], image_subpixel_shift * 2)); + + ++span; + ++base_type::interpolator(); + + } while(--len); + } + }; + + + //====================================span_image_filter_rgba_bilinear_clip + template<class Source, class Interpolator> + class span_image_filter_rgba_bilinear_clip : + public span_image_filter<Source, Interpolator> + { + public: + typedef 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_rgba_bilinear_clip() {} + span_image_filter_rgba_bilinear_clip(source_type& src, + const color_type& back_color, + interpolator_type& inter) : + base_type(src, inter, 0), + m_back_color(back_color) + {} + const color_type& background_color() const { return m_back_color; } + void background_color(const color_type& v) { m_back_color = v; } + + + //-------------------------------------------------------------------- + void generate(color_type* span, int x, int y, unsigned len) + { + base_type::interpolator().begin(x + base_type::filter_dx_dbl(), + y + base_type::filter_dy_dbl(), len); + + long_type fg[4]; + 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] = fg[3] = 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 << 2); + + weight = (image_subpixel_scale - x_hr) * + (image_subpixel_scale - y_hr); + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + fg[3] += weight * *fg_ptr++; + + weight = x_hr * (image_subpixel_scale - y_hr); + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + fg[3] += weight * *fg_ptr++; + + ++y_lr; + fg_ptr = (const value_type*) + base_type::source().row_ptr(y_lr) + (x_lr << 2); + + weight = (image_subpixel_scale - x_hr) * y_hr; + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + fg[3] += weight * *fg_ptr++; + + weight = x_hr * y_hr; + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + fg[3] += weight * *fg_ptr++; + + 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); + fg[3] = color_type::downshift(fg[3], image_subpixel_shift * 2); + } + else + { + if(x_lr < -1 || y_lr < -1 || + x_lr > maxx || y_lr > maxy) + { + fg[order_type::R] = back_r; + fg[order_type::G] = back_g; + fg[order_type::B] = back_b; + fg[order_type::A] = back_a; + } + else + { + fg[0] = fg[1] = fg[2] = fg[3] = 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 << 2); + + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + fg[3] += weight * *fg_ptr++; + } + else + { + fg[order_type::R] += back_r * weight; + fg[order_type::G] += back_g * weight; + fg[order_type::B] += back_b * weight; + fg[order_type::A] += back_a * weight; + } + + x_lr++; + + weight = 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 << 2); + + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + fg[3] += weight * *fg_ptr++; + } + else + { + fg[order_type::R] += back_r * weight; + fg[order_type::G] += back_g * weight; + fg[order_type::B] += back_b * weight; + fg[order_type::A] += back_a * weight; + } + + x_lr--; + y_lr++; + + weight = (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 << 2); + + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + fg[3] += weight * *fg_ptr++; + } + else + { + fg[order_type::R] += back_r * weight; + fg[order_type::G] += back_g * weight; + fg[order_type::B] += back_b * weight; + fg[order_type::A] += back_a * weight; + } + + x_lr++; + + weight = 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 << 2); + + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + fg[3] += weight * *fg_ptr++; + } + else + { + fg[order_type::R] += back_r * weight; + fg[order_type::G] += back_g * weight; + fg[order_type::B] += back_b * weight; + fg[order_type::A] += back_a * weight; + } + + fg[0] = 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); + fg[3] = color_type::downshift(fg[3], 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)fg[order_type::A]; + ++span; + ++base_type::interpolator(); + + } while(--len); + } + private: + color_type m_back_color; + }; + + + //==============================================span_image_filter_rgba_2x2 + template<class Source, class Interpolator> + class span_image_filter_rgba_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_rgba_2x2() {} + span_image_filter_rgba_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[4]; + + 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] = fg[3] = 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[3] += weight * *fg_ptr; + + fg_ptr = (const value_type*)base_type::source().next_x(); + weight = (weight_array[x_hr] * + weight_array[y_hr + image_subpixel_scale] + + image_filter_scale / 2) >> + image_filter_shift; + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + fg[3] += weight * *fg_ptr; + + fg_ptr = (const value_type*)base_type::source().next_y(); + weight = (weight_array[x_hr + image_subpixel_scale] * + weight_array[y_hr] + + image_filter_scale / 2) >> + image_filter_shift; + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + fg[3] += weight * *fg_ptr; + + fg_ptr = (const value_type*)base_type::source().next_x(); + weight = (weight_array[x_hr] * + weight_array[y_hr] + + image_filter_scale / 2) >> + image_filter_shift; + fg[0] += weight * *fg_ptr++; + fg[1] += weight * *fg_ptr++; + fg[2] += weight * *fg_ptr++; + fg[3] += weight * *fg_ptr; + + fg[0] = 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); + fg[3] = color_type::downshift(fg[3], image_filter_shift); + + if(fg[order_type::A] > color_type::full_value()) fg[order_type::A] = color_type::full_value(); + if(fg[order_type::R] > fg[order_type::A]) fg[order_type::R] = fg[order_type::A]; + if(fg[order_type::G] > fg[order_type::A]) fg[order_type::G] = fg[order_type::A]; + if(fg[order_type::B] > fg[order_type::A]) fg[order_type::B] = fg[order_type::A]; + + span->r = (value_type)fg[order_type::R]; + span->g = (value_type)fg[order_type::G]; + span->b = (value_type)fg[order_type::B]; + span->a = (value_type)fg[order_type::A]; + ++span; + ++base_type::interpolator(); + + } while(--len); + } + }; + + + + //==================================================span_image_filter_rgba + template<class Source, class Interpolator> + class span_image_filter_rgba : + 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_rgba() {} + span_image_filter_rgba(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[4]; + 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] = fg[3] = 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++; + fg[3] += weight * *fg_ptr; + + if(--x_count == 0) break; + x_hr += image_subpixel_scale; + fg_ptr = (const value_type*)base_type::source().next_x(); + } + + 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); + fg[3] = color_type::downshift(fg[3], image_filter_shift); + + if(fg[0] < 0) fg[0] = 0; + if(fg[1] < 0) fg[1] = 0; + if(fg[2] < 0) fg[2] = 0; + if(fg[3] < 0) fg[3] = 0; + + if(fg[order_type::A] > color_type::full_value()) fg[order_type::A] = color_type::full_value(); + if(fg[order_type::R] > fg[order_type::A]) fg[order_type::R] = fg[order_type::A]; + if(fg[order_type::G] > fg[order_type::A]) fg[order_type::G] = fg[order_type::A]; + if(fg[order_type::B] > fg[order_type::A]) fg[order_type::B] = fg[order_type::A]; + + span->r = (value_type)fg[order_type::R]; + span->g = (value_type)fg[order_type::G]; + span->b = (value_type)fg[order_type::B]; + span->a = (value_type)fg[order_type::A]; + ++span; + ++base_type::interpolator(); + + } while(--len); + } + }; + + + + //========================================span_image_resample_rgba_affine + template<class Source> + class span_image_resample_rgba_affine : + public span_image_resample_affine<Source> + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef typename source_type::order_type order_type; + typedef span_image_resample_affine<source_type> base_type; + typedef typename base_type::interpolator_type interpolator_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::long_type long_type; + enum base_scale_e + { + downscale_shift = image_filter_shift + }; + + //-------------------------------------------------------------------- + span_image_resample_rgba_affine() {} + span_image_resample_rgba_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[4]; + + int diameter = base_type::filter().diameter(); + int filter_scale = diameter << image_subpixel_shift; + int radius_x = (diameter * base_type::m_rx) >> 1; + int radius_y = (diameter * base_type::m_ry) >> 1; + int len_x_lr = + (diameter * base_type::m_rx + image_subpixel_mask) >> + image_subpixel_shift; + + const int16* weight_array = base_type::filter().weight_array(); + + do + { + base_type::interpolator().coordinates(&x, &y); + + x += base_type::filter_dx_int() - radius_x; + y += base_type::filter_dy_int() - radius_y; + + fg[0] = fg[1] = fg[2] = fg[3] = 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; + fg[3] += *fg_ptr++ * weight; + total_weight += weight; + x_hr += base_type::m_rx_inv; + if(x_hr >= filter_scale) break; + fg_ptr = (const value_type*)base_type::source().next_x(); + } + 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; + fg[3] /= total_weight; + + if(fg[0] < 0) fg[0] = 0; + if(fg[1] < 0) fg[1] = 0; + if(fg[2] < 0) fg[2] = 0; + if(fg[3] < 0) fg[3] = 0; + + if(fg[order_type::A] > color_type::full_value()) fg[order_type::A] = color_type::full_value(); + if(fg[order_type::R] > fg[order_type::A]) fg[order_type::R] = fg[order_type::A]; + if(fg[order_type::G] > fg[order_type::A]) fg[order_type::G] = fg[order_type::A]; + if(fg[order_type::B] > fg[order_type::A]) fg[order_type::B] = fg[order_type::A]; + + span->r = (value_type)fg[order_type::R]; + span->g = (value_type)fg[order_type::G]; + span->b = (value_type)fg[order_type::B]; + span->a = (value_type)fg[order_type::A]; + + ++span; + ++base_type::interpolator(); + } while(--len); + } + }; + + + + //==============================================span_image_resample_rgba + template<class Source, class Interpolator> + class span_image_resample_rgba : + public span_image_resample<Source, Interpolator> + { + public: + typedef Source source_type; + typedef typename source_type::color_type color_type; + typedef typename source_type::order_type order_type; + typedef Interpolator interpolator_type; + typedef span_image_resample<source_type, interpolator_type> base_type; + typedef typename color_type::value_type value_type; + typedef typename color_type::long_type long_type; + enum base_scale_e + { + downscale_shift = image_filter_shift + }; + + //-------------------------------------------------------------------- + span_image_resample_rgba() {} + span_image_resample_rgba(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[4]; + + int diameter = base_type::filter().diameter(); + int filter_scale = diameter << image_subpixel_shift; + + const int16* weight_array = base_type::filter().weight_array(); + do + { + int rx; + int ry; + int rx_inv = image_subpixel_scale; + int ry_inv = image_subpixel_scale; + base_type::interpolator().coordinates(&x, &y); + base_type::interpolator().local_scale(&rx, &ry); + base_type::adjust_scale(&rx, &ry); + + rx_inv = image_subpixel_scale * image_subpixel_scale / rx; + ry_inv = image_subpixel_scale * image_subpixel_scale / ry; + + int radius_x = (diameter * rx) >> 1; + int radius_y = (diameter * ry) >> 1; + int len_x_lr = + (diameter * rx + image_subpixel_mask) >> + image_subpixel_shift; + + x += base_type::filter_dx_int() - radius_x; + y += base_type::filter_dy_int() - radius_y; + + fg[0] = fg[1] = fg[2] = fg[3] = 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; + fg[3] += *fg_ptr++ * weight; + total_weight += weight; + x_hr += rx_inv; + if(x_hr >= filter_scale) break; + fg_ptr = (const value_type*)base_type::source().next_x(); + } + y_hr += ry_inv; + if(y_hr >= filter_scale) break; + fg_ptr = (const value_type*)base_type::source().next_y(); + } + + fg[0] /= total_weight; + fg[1] /= total_weight; + fg[2] /= total_weight; + fg[3] /= total_weight; + + if(fg[0] < 0) fg[0] = 0; + if(fg[1] < 0) fg[1] = 0; + if(fg[2] < 0) fg[2] = 0; + if(fg[3] < 0) fg[3] = 0; + + if(fg[order_type::A] > color_type::full_value()) fg[order_type::A] = color_type::full_value(); + if(fg[order_type::R] > fg[order_type::R]) fg[order_type::R] = fg[order_type::R]; + if(fg[order_type::G] > fg[order_type::G]) fg[order_type::G] = fg[order_type::G]; + if(fg[order_type::B] > fg[order_type::B]) fg[order_type::B] = fg[order_type::B]; + + span->r = (value_type)fg[order_type::R]; + span->g = (value_type)fg[order_type::G]; + span->b = (value_type)fg[order_type::B]; + span->a = (value_type)fg[order_type::A]; + + ++span; + ++base_type::interpolator(); + } while(--len); + } + }; + + +} + + +#endif + + + diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_interpolator_adaptor.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_interpolator_adaptor.h new file mode 100644 index 00000000000..0fdfa774796 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_interpolator_adaptor.h @@ -0,0 +1,77 @@ +//---------------------------------------------------------------------------- +// 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_ADAPTOR_INCLUDED +#define AGG_SPAN_INTERPOLATOR_ADAPTOR_INCLUDED + +#include "agg_basics.h" + +namespace agg +{ + + //===============================================span_interpolator_adaptor + template<class Interpolator, class Distortion> + class span_interpolator_adaptor : public Interpolator + { + public: + typedef Interpolator base_type; + typedef typename base_type::trans_type trans_type; + typedef Distortion distortion_type; + + //-------------------------------------------------------------------- + span_interpolator_adaptor() {} + span_interpolator_adaptor(trans_type& trans, + distortion_type& dist) : + base_type(trans), + m_distortion(&dist) + { + } + + //-------------------------------------------------------------------- + span_interpolator_adaptor(trans_type& trans, + distortion_type& dist, + double x, double y, unsigned len) : + base_type(trans, x, y, len), + m_distortion(&dist) + { + } + + //-------------------------------------------------------------------- + distortion_type& distortion() const + { + return *m_distortion; + } + + //-------------------------------------------------------------------- + void distortion(distortion_type& dist) + { + m_distortion = dist; + } + + //-------------------------------------------------------------------- + void coordinates(int* x, int* y) const + { + base_type::coordinates(x, y); + m_distortion->calculate(x, y); + } + + private: + //-------------------------------------------------------------------- + distortion_type* m_distortion; + }; +} + + +#endif diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_interpolator_linear.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_interpolator_linear.h new file mode 100644 index 00000000000..ef10505ce11 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_interpolator_linear.h @@ -0,0 +1,232 @@ +//---------------------------------------------------------------------------- +// 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_LINEAR_INCLUDED +#define AGG_SPAN_INTERPOLATOR_LINEAR_INCLUDED + +#include "agg_basics.h" +#include "agg_dda_line.h" +#include "agg_trans_affine.h" + +namespace agg +{ + + //================================================span_interpolator_linear + template<class Transformer = trans_affine, unsigned SubpixelShift = 8> + class span_interpolator_linear + { + public: + typedef Transformer trans_type; + + enum subpixel_scale_e + { + subpixel_shift = SubpixelShift, + subpixel_scale = 1 << subpixel_shift + }; + + //-------------------------------------------------------------------- + span_interpolator_linear() {} + span_interpolator_linear(trans_type& trans) : m_trans(&trans) {} + span_interpolator_linear(trans_type& trans, + double x, double y, unsigned len) : + m_trans(&trans) + { + begin(x, y, len); + } + + //---------------------------------------------------------------- + const trans_type& transformer() const { return *m_trans; } + void transformer(trans_type& trans) { m_trans = &trans; } + + //---------------------------------------------------------------- + void begin(double x, double y, unsigned len) + { + double tx; + double ty; + + tx = x; + ty = y; + m_trans->transform(&tx, &ty); + int x1 = iround(tx * subpixel_scale); + int y1 = iround(ty * subpixel_scale); + + tx = x + len; + ty = y; + m_trans->transform(&tx, &ty); + int x2 = iround(tx * subpixel_scale); + int y2 = iround(ty * subpixel_scale); + + m_li_x = dda2_line_interpolator(x1, x2, len); + m_li_y = dda2_line_interpolator(y1, y2, len); + } + + //---------------------------------------------------------------- + void resynchronize(double xe, double ye, unsigned len) + { + m_trans->transform(&xe, &ye); + m_li_x = dda2_line_interpolator(m_li_x.y(), iround(xe * subpixel_scale), len); + m_li_y = dda2_line_interpolator(m_li_y.y(), iround(ye * subpixel_scale), len); + } + + //---------------------------------------------------------------- + void operator++() + { + ++m_li_x; + ++m_li_y; + } + + //---------------------------------------------------------------- + void coordinates(int* x, int* y) const + { + *x = m_li_x.y(); + *y = m_li_y.y(); + } + + private: + trans_type* m_trans; + dda2_line_interpolator m_li_x; + dda2_line_interpolator m_li_y; + }; + + + + + + + //=====================================span_interpolator_linear_subdiv + template<class Transformer = trans_affine, unsigned SubpixelShift = 8> + class span_interpolator_linear_subdiv + { + public: + typedef Transformer trans_type; + + enum subpixel_scale_e + { + subpixel_shift = SubpixelShift, + subpixel_scale = 1 << subpixel_shift + }; + + + //---------------------------------------------------------------- + span_interpolator_linear_subdiv() : + m_subdiv_shift(4), + m_subdiv_size(1 << m_subdiv_shift), + m_subdiv_mask(m_subdiv_size - 1) {} + + span_interpolator_linear_subdiv(trans_type& trans, + unsigned subdiv_shift = 4) : + m_subdiv_shift(subdiv_shift), + m_subdiv_size(1 << m_subdiv_shift), + m_subdiv_mask(m_subdiv_size - 1), + m_trans(&trans) {} + + span_interpolator_linear_subdiv(trans_type& trans, + 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_trans(&trans) + { + begin(x, y, len); + } + + //---------------------------------------------------------------- + const trans_type& transformer() const { return *m_trans; } + void transformer(const trans_type& trans) { m_trans = &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) + { + double tx; + double ty; + 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; + tx = x; + ty = y; + m_trans->transform(&tx, &ty); + int x1 = iround(tx * subpixel_scale); + int y1 = iround(ty * subpixel_scale); + + tx = x + len; + ty = y; + m_trans->transform(&tx, &ty); + + m_li_x = dda2_line_interpolator(x1, iround(tx * subpixel_scale), len); + m_li_y = dda2_line_interpolator(y1, iround(ty * subpixel_scale), len); + } + + //---------------------------------------------------------------- + void operator++() + { + ++m_li_x; + ++m_li_y; + if(m_pos >= m_subdiv_size) + { + unsigned len = m_len; + if(len > m_subdiv_size) len = m_subdiv_size; + double tx = double(m_src_x) / double(subpixel_scale) + len; + double ty = m_src_y; + m_trans->transform(&tx, &ty); + m_li_x = dda2_line_interpolator(m_li_x.y(), iround(tx * subpixel_scale), len); + m_li_y = dda2_line_interpolator(m_li_y.y(), iround(ty * subpixel_scale), len); + m_pos = 0; + } + m_src_x += subpixel_scale; + ++m_pos; + --m_len; + } + + //---------------------------------------------------------------- + void coordinates(int* x, int* y) const + { + *x = m_li_x.y(); + *y = m_li_y.y(); + } + + private: + unsigned m_subdiv_shift; + unsigned m_subdiv_size; + unsigned m_subdiv_mask; + trans_type* m_trans; + dda2_line_interpolator m_li_x; + dda2_line_interpolator m_li_y; + 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_span_interpolator_persp.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_interpolator_persp.h new file mode 100644 index 00000000000..cad437e04f5 --- /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 00000000000..32bc678a8e4 --- /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 00000000000..ae1a49f879e --- /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 00000000000..4850508af1e --- /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_pattern_rgba.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_pattern_rgba.h new file mode 100644 index 00000000000..d47d2a6c022 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_span_pattern_rgba.h @@ -0,0 +1,94 @@ +//---------------------------------------------------------------------------- +// 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_RGBA_INCLUDED +#define AGG_SPAN_PATTERN_RGBA_INCLUDED + +#include "agg_basics.h" + +namespace agg +{ + + //======================================================span_pattern_rgba + template<class Source> class span_pattern_rgba + { + 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_rgba() {} + span_pattern_rgba(source_type& src, + unsigned offset_x, unsigned offset_y) : + m_src(&src), + m_offset_x(offset_x), + m_offset_y(offset_y) + {} + + //-------------------------------------------------------------------- + void attach(source_type& v) { m_src = &v; } + source_type& source() { return *m_src; } + const source_type& source() const { return *m_src; } + + //-------------------------------------------------------------------- + void offset_x(unsigned v) { m_offset_x = v; } + void offset_y(unsigned v) { m_offset_y = v; } + unsigned offset_x() const { return m_offset_x; } + unsigned offset_y() const { return m_offset_y; } + void alpha(value_type) {} + value_type alpha() const { return 0; } + + //-------------------------------------------------------------------- + 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 = p[order_type::A]; + p = (const value_type*)m_src->next_x(); + ++span; + } + while(--len); + } + + private: + source_type* m_src; + unsigned m_offset_x; + unsigned m_offset_y; + + }; + +} + +#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 00000000000..ee46df99913 --- /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 00000000000..b5b855ec977 --- /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_affine.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_affine.h new file mode 100644 index 00000000000..1a611638833 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_trans_affine.h @@ -0,0 +1,518 @@ +//---------------------------------------------------------------------------- +// 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 +//---------------------------------------------------------------------------- +// +// Affine transformation classes. +// +//---------------------------------------------------------------------------- +#ifndef AGG_TRANS_AFFINE_INCLUDED +#define AGG_TRANS_AFFINE_INCLUDED + +#include <math.h> +#include "agg_basics.h" + +namespace agg +{ + const double affine_epsilon = 1e-14; + + //============================================================trans_affine + // + // See Implementation agg_trans_affine.cpp + // + // Affine transformation are linear transformations in Cartesian coordinates + // (strictly speaking not only in Cartesian, but for the beginning we will + // think so). They are rotation, scaling, translation and skewing. + // After any affine transformation a line segment remains a line segment + // and it will never become a curve. + // + // There will be no math about matrix calculations, since it has been + // described many times. Ask yourself a very simple question: + // "why do we need to understand and use some matrix stuff instead of just + // rotating, scaling and so on". The answers are: + // + // 1. Any combination of transformations can be done by only 4 multiplications + // and 4 additions in floating point. + // 2. One matrix transformation is equivalent to the number of consecutive + // discrete transformations, i.e. the matrix "accumulates" all transformations + // in the order of their settings. Suppose we have 4 transformations: + // * rotate by 30 degrees, + // * scale X to 2.0, + // * scale Y to 1.5, + // * move to (100, 100). + // The result will depend on the order of these transformations, + // and the advantage of matrix is that the sequence of discret calls: + // rotate(30), scaleX(2.0), scaleY(1.5), move(100,100) + // will have exactly the same result as the following matrix transformations: + // + // affine_matrix m; + // m *= rotate_matrix(30); + // m *= scaleX_matrix(2.0); + // m *= scaleY_matrix(1.5); + // m *= move_matrix(100,100); + // + // m.transform_my_point_at_last(x, y); + // + // What is the good of it? In real life we will set-up the matrix only once + // and then transform many points, let alone the convenience to set any + // combination of transformations. + // + // So, how to use it? Very easy - literally as it's shown above. Not quite, + // let us write a correct example: + // + // agg::trans_affine m; + // m *= agg::trans_affine_rotation(30.0 * 3.1415926 / 180.0); + // m *= agg::trans_affine_scaling(2.0, 1.5); + // m *= agg::trans_affine_translation(100.0, 100.0); + // m.transform(&x, &y); + // + // The affine matrix is all you need to perform any linear transformation, + // but all transformations have origin point (0,0). It means that we need to + // use 2 translations if we want to rotate someting around (100,100): + // + // m *= agg::trans_affine_translation(-100.0, -100.0); // move to (0,0) + // m *= agg::trans_affine_rotation(30.0 * 3.1415926 / 180.0); // rotate + // m *= agg::trans_affine_translation(100.0, 100.0); // move back to (100,100) + //---------------------------------------------------------------------- + struct trans_affine + { + double sx, shy, shx, sy, tx, ty; + + //------------------------------------------ Construction + // Identity matrix + trans_affine() : + sx(1.0), shy(0.0), shx(0.0), sy(1.0), tx(0.0), ty(0.0) + {} + + // Custom matrix. Usually used in derived classes + trans_affine(double v0, double v1, double v2, + double v3, double v4, double v5) : + sx(v0), shy(v1), shx(v2), sy(v3), tx(v4), ty(v5) + {} + + // Custom matrix from m[6] + explicit trans_affine(const double* m) : + sx(m[0]), shy(m[1]), shx(m[2]), sy(m[3]), tx(m[4]), ty(m[5]) + {} + + // Rectangle to a parallelogram. + trans_affine(double x1, double y1, double x2, double y2, + const double* parl) + { + rect_to_parl(x1, y1, x2, y2, parl); + } + + // Parallelogram to a rectangle. + trans_affine(const double* parl, + double x1, double y1, double x2, double y2) + { + parl_to_rect(parl, x1, y1, x2, y2); + } + + // Arbitrary parallelogram transformation. + trans_affine(const double* src, const double* dst) + { + parl_to_parl(src, dst); + } + + //---------------------------------- Parellelogram transformations + // transform a parallelogram to another one. Src and dst are + // pointers to arrays of three points (double[6], x1,y1,...) that + // identify three corners of the parallelograms assuming implicit + // fourth point. The arguments are arrays of double[6] mapped + // to x1,y1, x2,y2, x3,y3 where the coordinates are: + // *-----------------* + // / (x3,y3)/ + // / / + // /(x1,y1) (x2,y2)/ + // *-----------------* + const trans_affine& parl_to_parl(const double* src, + const double* dst); + + const trans_affine& rect_to_parl(double x1, double y1, + double x2, double y2, + const double* parl); + + const trans_affine& parl_to_rect(const double* parl, + double x1, double y1, + double x2, double y2); + + + //------------------------------------------ Operations + // Reset - load an identity matrix + const trans_affine& reset(); + + // Direct transformations operations + const trans_affine& translate(double x, double y); + const trans_affine& rotate(double a); + const trans_affine& scale(double s); + const trans_affine& scale(double x, double y); + + // Multiply matrix to another one + const trans_affine& multiply(const trans_affine& m); + + // Multiply "m" to "this" and assign the result to "this" + const trans_affine& premultiply(const trans_affine& m); + + // Multiply matrix to inverse of another one + const trans_affine& multiply_inv(const trans_affine& m); + + // Multiply inverse of "m" to "this" and assign the result to "this" + const trans_affine& premultiply_inv(const trans_affine& m); + + // Invert matrix. Do not try to invert degenerate matrices, + // there's no check for validity. If you set scale to 0 and + // then try to invert matrix, expect unpredictable result. + const trans_affine& invert(); + + // Mirroring around X + const trans_affine& flip_x(); + + // Mirroring around Y + const trans_affine& flip_y(); + + //------------------------------------------- Load/Store + // Store matrix to an array [6] of double + void store_to(double* m) const + { + *m++ = sx; *m++ = shy; *m++ = shx; *m++ = sy; *m++ = tx; *m++ = ty; + } + + // Load matrix from an array [6] of double + const trans_affine& load_from(const double* m) + { + sx = *m++; shy = *m++; shx = *m++; sy = *m++; tx = *m++; ty = *m++; + return *this; + } + + //------------------------------------------- Operators + + // Multiply the matrix by another one + const trans_affine& operator *= (const trans_affine& m) + { + return multiply(m); + } + + // Multiply the matrix by inverse of another one + const trans_affine& operator /= (const trans_affine& m) + { + return multiply_inv(m); + } + + // Multiply the matrix by another one and return + // the result in a separete matrix. + trans_affine operator * (const trans_affine& m) const + { + return trans_affine(*this).multiply(m); + } + + // Multiply the matrix by inverse of another one + // and return the result in a separete matrix. + trans_affine operator / (const trans_affine& m) const + { + return trans_affine(*this).multiply_inv(m); + } + + // Calculate and return the inverse matrix + trans_affine operator ~ () const + { + trans_affine ret = *this; + return ret.invert(); + } + + // Equal operator with default epsilon + bool operator == (const trans_affine& m) const + { + return is_equal(m, affine_epsilon); + } + + // Not Equal operator with default epsilon + bool operator != (const trans_affine& 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, 2x2 matrix only, no translation + void transform_2x2(double* x, double* y) const; + + // Inverse transformation of x and y. It works slower than the + // direct transformation. For massive operations it's better to + // invert() the matrix and then use direct transformations. + void inverse_transform(double* x, double* y) const; + + //-------------------------------------------- Auxiliary + // Calculate the determinant of matrix + double determinant() const + { + return sx * sy - shy * shx; + } + + // Calculate the reciprocal of the determinant + double determinant_reciprocal() const + { + return 1.0 / (sx * sy - shy * shx); + } + + // Get the average scale (by X and Y). + // Basically used to calculate the approximation_scale when + // decomposinting curves into line segments. + double scale() const; + + // Check to see if the matrix is not degenerate + bool is_valid(double epsilon = affine_epsilon) const; + + // Check to see if it's an identity matrix + bool is_identity(double epsilon = affine_epsilon) const; + + // Check to see if two matrices are equal + bool is_equal(const trans_affine& m, double epsilon = affine_epsilon) const; + + // Determine the major parameters. Use with caution considering + // possible degenerate cases. + 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; + }; + + //------------------------------------------------------------------------ + inline void trans_affine::transform(double* x, double* y) const + { + double tmp = *x; + *x = tmp * sx + *y * shx + tx; + *y = tmp * shy + *y * sy + ty; + } + + //------------------------------------------------------------------------ + inline void trans_affine::transform_2x2(double* x, double* y) const + { + double tmp = *x; + *x = tmp * sx + *y * shx; + *y = tmp * shy + *y * sy; + } + + //------------------------------------------------------------------------ + inline void trans_affine::inverse_transform(double* x, double* y) const + { + double d = determinant_reciprocal(); + double a = (*x - tx) * d; + double b = (*y - ty) * d; + *x = a * sy - b * shx; + *y = b * sx - a * shy; + } + + //------------------------------------------------------------------------ + inline double trans_affine::scale() const + { + double x = 0.707106781 * sx + 0.707106781 * shx; + double y = 0.707106781 * shy + 0.707106781 * sy; + return sqrt(x*x + y*y); + } + + //------------------------------------------------------------------------ + inline const trans_affine& trans_affine::translate(double x, double y) + { + tx += x; + ty += y; + return *this; + } + + //------------------------------------------------------------------------ + inline const trans_affine& trans_affine::rotate(double a) + { + double ca = cos(a); + double sa = sin(a); + double t0 = sx * ca - shy * sa; + double t2 = shx * ca - sy * sa; + double t4 = tx * ca - ty * sa; + shy = sx * sa + shy * ca; + sy = shx * sa + sy * ca; + ty = tx * sa + ty * ca; + sx = t0; + shx = t2; + tx = t4; + return *this; + } + + //------------------------------------------------------------------------ + inline const trans_affine& trans_affine::scale(double x, double y) + { + double mm0 = x; // Possible hint for the optimizer + double mm3 = y; + sx *= mm0; + shx *= mm0; + tx *= mm0; + shy *= mm3; + sy *= mm3; + ty *= mm3; + return *this; + } + + //------------------------------------------------------------------------ + inline const trans_affine& trans_affine::scale(double s) + { + double m = s; // Possible hint for the optimizer + sx *= m; + shx *= m; + tx *= m; + shy *= m; + sy *= m; + ty *= m; + return *this; + } + + //------------------------------------------------------------------------ + inline const trans_affine& trans_affine::premultiply(const trans_affine& m) + { + trans_affine t = m; + return *this = t.multiply(*this); + } + + //------------------------------------------------------------------------ + inline const trans_affine& trans_affine::multiply_inv(const trans_affine& m) + { + trans_affine t = m; + t.invert(); + return multiply(t); + } + + //------------------------------------------------------------------------ + inline const trans_affine& trans_affine::premultiply_inv(const trans_affine& m) + { + trans_affine t = m; + t.invert(); + return *this = t.multiply(*this); + } + + //------------------------------------------------------------------------ + inline void trans_affine::scaling_abs(double* x, double* y) const + { + // Used to calculate scaling coefficients in image resampling. + // When there is considerable shear this method gives us much + // better estimation than just sx, sy. + *x = sqrt(sx * sx + shx * shx); + *y = sqrt(shy * shy + sy * sy); + } + + //====================================================trans_affine_rotation + // Rotation matrix. sin() and cos() are calculated twice for the same angle. + // There's no harm because the performance of sin()/cos() is very good on all + // modern processors. Besides, this operation is not going to be invoked too + // often. + class trans_affine_rotation : public trans_affine + { + public: + trans_affine_rotation(double a) : + trans_affine(cos(a), sin(a), -sin(a), cos(a), 0.0, 0.0) + {} + }; + + //====================================================trans_affine_scaling + // Scaling matrix. x, y - scale coefficients by X and Y respectively + class trans_affine_scaling : public trans_affine + { + public: + trans_affine_scaling(double x, double y) : + trans_affine(x, 0.0, 0.0, y, 0.0, 0.0) + {} + + trans_affine_scaling(double s) : + trans_affine(s, 0.0, 0.0, s, 0.0, 0.0) + {} + }; + + //================================================trans_affine_translation + // Translation matrix + class trans_affine_translation : public trans_affine + { + public: + trans_affine_translation(double x, double y) : + trans_affine(1.0, 0.0, 0.0, 1.0, x, y) + {} + }; + + //====================================================trans_affine_skewing + // Sckewing (shear) matrix + class trans_affine_skewing : public trans_affine + { + public: + trans_affine_skewing(double x, double y) : + trans_affine(1.0, tan(y), tan(x), 1.0, 0.0, 0.0) + {} + }; + + + //===============================================trans_affine_line_segment + // Rotate, Scale and Translate, associating 0...dist with line segment + // x1,y1,x2,y2 + class trans_affine_line_segment : public trans_affine + { + public: + trans_affine_line_segment(double x1, double y1, double x2, double y2, + double dist) + { + double dx = x2 - x1; + double dy = y2 - y1; + if(dist > 0.0) + { + multiply(trans_affine_scaling(sqrt(dx * dx + dy * dy) / dist)); + } + multiply(trans_affine_rotation(atan2(dy, dx))); + multiply(trans_affine_translation(x1, y1)); + } + }; + + + //============================================trans_affine_reflection_unit + // Reflection matrix. Reflect coordinates across the line through + // the origin containing the unit vector (ux, uy). + // Contributed by John Horigan + class trans_affine_reflection_unit : public trans_affine + { + public: + trans_affine_reflection_unit(double ux, double uy) : + trans_affine(2.0 * ux * ux - 1.0, + 2.0 * ux * uy, + 2.0 * ux * uy, + 2.0 * uy * uy - 1.0, + 0.0, 0.0) + {} + }; + + + //=================================================trans_affine_reflection + // Reflection matrix. Reflect coordinates across the line through + // the origin at the angle a or containing the non-unit vector (x, y). + // Contributed by John Horigan + class trans_affine_reflection : public trans_affine_reflection_unit + { + public: + trans_affine_reflection(double a) : + trans_affine_reflection_unit(cos(a), sin(a)) + {} + + + trans_affine_reflection(double x, double y) : + trans_affine_reflection_unit(x / sqrt(x * x + y * y), y / sqrt(x * x + y * y)) + {} + }; + +} + + +#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 00000000000..f3ab5964725 --- /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 00000000000..c645a7f8690 --- /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 00000000000..7d4aa26c798 --- /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 00000000000..9f4bf53bdbc --- /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 00000000000..7088f990780 --- /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 00000000000..38a92dbec8d --- /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 00000000000..a2944548c02 --- /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_contour.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_contour.h new file mode 100644 index 00000000000..8c25da13f5a --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_contour.h @@ -0,0 +1,94 @@ +//---------------------------------------------------------------------------- +// 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_CONTOUR_INCLUDED +#define AGG_VCGEN_CONTOUR_INCLUDED + +#include "agg_math_stroke.h" + +namespace agg +{ + + //----------------------------------------------------------vcgen_contour + // + // See Implementation agg_vcgen_contour.cpp + // + class vcgen_contour + { + enum status_e + { + initial, + ready, + outline, + out_vertices, + end_poly, + stop + }; + + public: + typedef vertex_sequence<vertex_dist, 6> vertex_storage; + typedef pod_bvector<point_d, 6> coord_storage; + + vcgen_contour(); + + void line_cap(line_cap_e lc) { m_stroker.line_cap(lc); } + void line_join(line_join_e lj) { m_stroker.line_join(lj); } + void inner_join(inner_join_e ij) { m_stroker.inner_join(ij); } + + line_cap_e line_cap() const { return m_stroker.line_cap(); } + line_join_e line_join() const { return m_stroker.line_join(); } + inner_join_e inner_join() const { return m_stroker.inner_join(); } + + void width(double w) { m_stroker.width(m_width = w); } + void miter_limit(double ml) { m_stroker.miter_limit(ml); } + void miter_limit_theta(double t) { m_stroker.miter_limit_theta(t); } + void inner_miter_limit(double ml) { m_stroker.inner_miter_limit(ml); } + void approximation_scale(double as) { m_stroker.approximation_scale(as); } + + double width() const { return m_width; } + double miter_limit() const { return m_stroker.miter_limit(); } + double inner_miter_limit() const { return m_stroker.inner_miter_limit(); } + double approximation_scale() const { return m_stroker.approximation_scale(); } + + void auto_detect_orientation(bool v) { m_auto_detect = v; } + bool auto_detect_orientation() const { return m_auto_detect; } + + // Generator interface + void remove_all(); + void add_vertex(double x, double y, unsigned cmd); + + // Vertex Source Interface + void rewind(unsigned path_id); + unsigned vertex(double* x, double* y); + + private: + vcgen_contour(const vcgen_contour&); + const vcgen_contour& operator = (const vcgen_contour&); + + math_stroke<coord_storage> m_stroker; + double m_width; + vertex_storage m_src_vertices; + coord_storage m_out_vertices; + status_e m_status; + unsigned m_src_vertex; + unsigned m_out_vertex; + unsigned m_closed; + unsigned m_orientation; + bool m_auto_detect; + }; + +} + +#endif diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_dash.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_dash.h new file mode 100644 index 00000000000..c87dce4c815 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_dash.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 +//---------------------------------------------------------------------------- +// +// Line dash generator +// +//---------------------------------------------------------------------------- +#ifndef AGG_VCGEN_DASH_INCLUDED +#define AGG_VCGEN_DASH_INCLUDED + +#include "agg_basics.h" +#include "agg_vertex_sequence.h" + +namespace agg +{ + + //---------------------------------------------------------------vcgen_dash + // + // See Implementation agg_vcgen_dash.cpp + // + class vcgen_dash + { + enum max_dashes_e + { + max_dashes = 32 + }; + + enum status_e + { + initial, + ready, + polyline, + stop + }; + + public: + typedef vertex_sequence<vertex_dist, 6> vertex_storage; + + vcgen_dash(); + + void remove_all_dashes(); + void add_dash(double dash_len, double gap_len); + void dash_start(double ds); + + void shorten(double s) { m_shorten = s; } + double shorten() const { return m_shorten; } + + // 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_dash(const vcgen_dash&); + const vcgen_dash& operator = (const vcgen_dash&); + + void calc_dash_start(double ds); + + double m_dashes[max_dashes]; + double m_total_dash_len; + unsigned m_num_dashes; + double m_dash_start; + double m_shorten; + double m_curr_dash_start; + unsigned m_curr_dash; + double m_curr_rest; + const vertex_dist* m_v1; + const vertex_dist* m_v2; + + vertex_storage m_src_vertices; + unsigned m_closed; + status_e m_status; + unsigned m_src_vertex; + }; + + +} + +#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 00000000000..ee1e74e3eb4 --- /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 00000000000..80fc0fb7969 --- /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_stroke.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_stroke.h new file mode 100644 index 00000000000..778223fe40e --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vcgen_stroke.h @@ -0,0 +1,102 @@ +//---------------------------------------------------------------------------- +// 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_STROKE_INCLUDED +#define AGG_VCGEN_STROKE_INCLUDED + +#include "agg_math_stroke.h" + + +namespace agg +{ + + //============================================================vcgen_stroke + // + // See Implementation agg_vcgen_stroke.cpp + // Stroke generator + // + //------------------------------------------------------------------------ + class vcgen_stroke + { + enum status_e + { + initial, + ready, + cap1, + cap2, + outline1, + close_first, + outline2, + out_vertices, + end_poly1, + end_poly2, + stop + }; + + public: + typedef vertex_sequence<vertex_dist, 6> vertex_storage; + typedef pod_bvector<point_d, 6> coord_storage; + + vcgen_stroke(); + + void line_cap(line_cap_e lc) { m_stroker.line_cap(lc); } + void line_join(line_join_e lj) { m_stroker.line_join(lj); } + void inner_join(inner_join_e ij) { m_stroker.inner_join(ij); } + + line_cap_e line_cap() const { return m_stroker.line_cap(); } + line_join_e line_join() const { return m_stroker.line_join(); } + inner_join_e inner_join() const { return m_stroker.inner_join(); } + + void width(double w) { m_stroker.width(w); } + void miter_limit(double ml) { m_stroker.miter_limit(ml); } + void miter_limit_theta(double t) { m_stroker.miter_limit_theta(t); } + void inner_miter_limit(double ml) { m_stroker.inner_miter_limit(ml); } + void approximation_scale(double as) { m_stroker.approximation_scale(as); } + + double width() const { return m_stroker.width(); } + double miter_limit() const { return m_stroker.miter_limit(); } + double inner_miter_limit() const { return m_stroker.inner_miter_limit(); } + double approximation_scale() const { return m_stroker.approximation_scale(); } + + void shorten(double s) { m_shorten = s; } + double shorten() const { return m_shorten; } + + // 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_stroke(const vcgen_stroke&); + const vcgen_stroke& operator = (const vcgen_stroke&); + + math_stroke<coord_storage> m_stroker; + vertex_storage m_src_vertices; + coord_storage m_out_vertices; + double m_shorten; + unsigned m_closed; + status_e m_status; + status_e m_prev_status; + unsigned m_src_vertex; + unsigned m_out_vertex; + }; + + +} + +#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 00000000000..5adc6715970 --- /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_vertex_sequence.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vertex_sequence.h new file mode 100644 index 00000000000..2ad0701b37a --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vertex_sequence.h @@ -0,0 +1,172 @@ +//---------------------------------------------------------------------------- +// 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 +//---------------------------------------------------------------------------- +// +// vertex_sequence container and vertex_dist struct +// +//---------------------------------------------------------------------------- +#ifndef AGG_VERTEX_SEQUENCE_INCLUDED +#define AGG_VERTEX_SEQUENCE_INCLUDED + +#include "agg_basics.h" +#include "agg_array.h" +#include "agg_math.h" + +namespace agg +{ + + //----------------------------------------------------------vertex_sequence + // Modified agg::pod_bvector. The data is interpreted as a sequence + // of vertices. It means that the type T must expose: + // + // bool T::operator() (const T& val) + // + // that is called every time new vertex is being added. The main purpose + // of this operator is the possibility to calculate some values during + // adding and to return true if the vertex fits some criteria or false if + // it doesn't. In the last case the new vertex is not added. + // + // The simple example is filtering coinciding vertices with calculation + // of the distance between the current and previous ones: + // + // struct vertex_dist + // { + // double x; + // double y; + // double dist; + // + // vertex_dist() {} + // vertex_dist(double x_, double y_) : + // x(x_), + // y(y_), + // dist(0.0) + // { + // } + // + // bool operator () (const vertex_dist& val) + // { + // return (dist = calc_distance(x, y, val.x, val.y)) > EPSILON; + // } + // }; + // + // Function close() calls this operator and removes the last vertex if + // necessary. + //------------------------------------------------------------------------ + template<class T, unsigned S=6> + class vertex_sequence : public pod_bvector<T, S> + { + public: + typedef pod_bvector<T, S> base_type; + + void add(const T& val); + void modify_last(const T& val); + void close(bool remove_flag); + }; + + + + //------------------------------------------------------------------------ + template<class T, unsigned S> + void vertex_sequence<T, S>::add(const T& val) + { + if(base_type::size() > 1) + { + if(!(*this)[base_type::size() - 2]((*this)[base_type::size() - 1])) + { + base_type::remove_last(); + } + } + base_type::add(val); + } + + + //------------------------------------------------------------------------ + template<class T, unsigned S> + void vertex_sequence<T, S>::modify_last(const T& val) + { + base_type::remove_last(); + add(val); + } + + + + //------------------------------------------------------------------------ + template<class T, unsigned S> + void vertex_sequence<T, S>::close(bool closed) + { + while(base_type::size() > 1) + { + if((*this)[base_type::size() - 2]((*this)[base_type::size() - 1])) break; + T t = (*this)[base_type::size() - 1]; + base_type::remove_last(); + modify_last(t); + } + + if(closed) + { + while(base_type::size() > 1) + { + if((*this)[base_type::size() - 1]((*this)[0])) break; + base_type::remove_last(); + } + } + } + + + //-------------------------------------------------------------vertex_dist + // Vertex (x, y) with the distance to the next one. The last vertex has + // distance between the last and the first points if the polygon is closed + // and 0.0 if it's a polyline. + struct vertex_dist + { + double x; + double y; + double dist; + + vertex_dist() {} + vertex_dist(double x_, double y_) : + x(x_), + y(y_), + dist(0.0) + { + } + + bool operator () (const vertex_dist& val) + { + bool ret = (dist = calc_distance(x, y, val.x, val.y)) > vertex_dist_epsilon; + if(!ret) dist = 1.0 / vertex_dist_epsilon; + return ret; + } + }; + + + + //--------------------------------------------------------vertex_dist_cmd + // Save as the above but with additional "command" value + struct vertex_dist_cmd : public vertex_dist + { + unsigned cmd; + + vertex_dist_cmd() {} + vertex_dist_cmd(double x_, double y_, unsigned cmd_) : + vertex_dist(x_, y_), + cmd(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 00000000000..ded754e2114 --- /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 00000000000..b070a7759e5 --- /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/agg_vpgen_segmentator.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vpgen_segmentator.h new file mode 100644 index 00000000000..29b3c9fa6f0 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/agg_vpgen_segmentator.h @@ -0,0 +1,61 @@ +//---------------------------------------------------------------------------- +// 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_SEGMENTATOR_INCLUDED +#define AGG_VPGEN_SEGMENTATOR_INCLUDED + +#include <math.h> +#include "agg_basics.h" + +namespace agg +{ + + //=======================================================vpgen_segmentator + // + // See Implementation agg_vpgen_segmentator.cpp + // + class vpgen_segmentator + { + public: + vpgen_segmentator() : m_approximation_scale(1.0) {} + + void approximation_scale(double s) { m_approximation_scale = s; } + double approximation_scale() const { return m_approximation_scale; } + + static bool auto_close() { return false; } + static bool auto_unclose() { return false; } + + void reset() { m_cmd = path_cmd_stop; } + void move_to(double x, double y); + void line_to(double x, double y); + unsigned vertex(double* x, double* y); + + private: + double m_approximation_scale; + double m_x1; + double m_y1; + double m_dx; + double m_dy; + double m_dl; + double m_ddl; + unsigned m_cmd; + }; + + + +} + +#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 00000000000..01851eb3e18 --- /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 00000000000..7ecbce27f42 --- /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 00000000000..7e811c63e17 --- /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 00000000000..0a645a71468 --- /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 00000000000..4f21710d9f2 --- /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 00000000000..6f465d96b81 --- /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 00000000000..4d47bccdbb3 --- /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 00000000000..b1e32c20372 --- /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 00000000000..b50a95c59d4 --- /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 00000000000..8477f27d782 --- /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 00000000000..9a63411e508 --- /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 00000000000..d7860b6fee9 --- /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 00000000000..5391e8bb9bc --- /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.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/util/agg_color_conv.h new file mode 100644 index 00000000000..8b8a0a55d2b --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/util/agg_color_conv.h @@ -0,0 +1,128 @@ +//---------------------------------------------------------------------------- +// 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 +//---------------------------------------------------------------------------- +// +// Conversion from one colorspace/pixel format to another +// +//---------------------------------------------------------------------------- + +#ifndef AGG_COLOR_CONV_INCLUDED +#define AGG_COLOR_CONV_INCLUDED + +#include <string.h> +#include "agg_basics.h" +#include "agg_rendering_buffer.h" + + + + +namespace agg +{ + + //--------------------------------------------------------------color_conv + template<class RenBuf, class CopyRow> + void color_conv(RenBuf* dst, const RenBuf* src, CopyRow copy_row_functor) + { + unsigned width = src->width(); + unsigned height = src->height(); + + if(dst->width() < width) width = dst->width(); + if(dst->height() < height) height = dst->height(); + + if(width) + { + unsigned y; + for(y = 0; y < height; y++) + { + copy_row_functor(dst->row_ptr(0, y, width), + src->row_ptr(y), + width); + } + } + } + + + //---------------------------------------------------------color_conv_row + template<class CopyRow> + void color_conv_row(int8u* dst, + const int8u* src, + unsigned width, + CopyRow copy_row_functor) + { + copy_row_functor(dst, src, width); + } + + + //---------------------------------------------------------color_conv_same + template<int BPP> class color_conv_same + { + public: + void operator () (int8u* dst, + const int8u* src, + unsigned width) const + { + memmove(dst, src, width*BPP); + } + }; + + + // Generic pixel converter. + template<class DstFormat, class SrcFormat> + struct conv_pixel + { + void operator()(void* dst, const void* src) const + { + // Read a pixel from the source format and write it to the destination format. + DstFormat::write_plain_color(dst, SrcFormat::read_plain_color(src)); + } + }; + + // Generic row converter. Uses conv_pixel to convert individual pixels. + template<class DstFormat, class SrcFormat> + struct conv_row + { + void operator()(void* dst, const void* src, unsigned width) const + { + conv_pixel<DstFormat, SrcFormat> conv; + do + { + conv(dst, src); + dst = (int8u*)dst + DstFormat::pix_width; + src = (int8u*)src + SrcFormat::pix_width; + } + while (--width); + } + }; + + // Specialization for case where source and destination formats are identical. + template<class Format> + struct conv_row<Format, Format> + { + void operator()(void* dst, const void* src, unsigned width) const + { + memmove(dst, src, width * Format::pix_width); + } + }; + + // Top-level conversion function, converts one pixel format to any other. + template<class DstFormat, class SrcFormat, class RenBuf> + void convert(RenBuf* dst, const RenBuf* src) + { + color_conv(dst, src, conv_row<DstFormat, SrcFormat>()); + } +} + + + +#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 00000000000..aaa41322c5b --- /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 diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/include/util/agg_color_conv_rgb8.h b/contrib/python/matplotlib/py3/extern/agg24-svn/include/util/agg_color_conv_rgb8.h new file mode 100644 index 00000000000..609460dba41 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/include/util/agg_color_conv_rgb8.h @@ -0,0 +1,476 @@ +//---------------------------------------------------------------------------- +// 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 +//---------------------------------------------------------------------------- +// +// 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()); +// whare XXXX and YYYY can be any of: +// rgb24 +// bgr24 +// rgba32 +// abgr32 +// argb32 +// bgra32 +// rgb555 +// rgb565 +//---------------------------------------------------------------------------- + +#ifndef AGG_COLOR_CONV_RGB8_INCLUDED +#define AGG_COLOR_CONV_RGB8_INCLUDED + +#include "agg_basics.h" +#include "agg_color_conv.h" + +namespace agg +{ + + //-----------------------------------------------------color_conv_rgb24 + class color_conv_rgb24 + { + public: + void operator () (int8u* dst, + const int8u* src, + unsigned width) const + { + do + { + int8u tmp[3]; + tmp[0] = *src++; + tmp[1] = *src++; + tmp[2] = *src++; + *dst++ = tmp[2]; + *dst++ = tmp[1]; + *dst++ = tmp[0]; + } + while(--width); + } + }; + + typedef color_conv_rgb24 color_conv_rgb24_to_bgr24; + typedef color_conv_rgb24 color_conv_bgr24_to_rgb24; + + typedef color_conv_same<3> color_conv_bgr24_to_bgr24; + typedef color_conv_same<3> color_conv_rgb24_to_rgb24; + + + + //------------------------------------------------------color_conv_rgba32 + template<int I1, int I2, int I3, int I4> class color_conv_rgba32 + { + public: + void operator () (int8u* dst, + const int8u* src, + unsigned width) const + { + do + { + int8u tmp[4]; + tmp[0] = *src++; + tmp[1] = *src++; + tmp[2] = *src++; + tmp[3] = *src++; + *dst++ = tmp[I1]; + *dst++ = tmp[I2]; + *dst++ = tmp[I3]; + *dst++ = tmp[I4]; + } + while(--width); + } + }; + + + //------------------------------------------------------------------------ + typedef color_conv_rgba32<0,3,2,1> color_conv_argb32_to_abgr32; //----color_conv_argb32_to_abgr32 + typedef color_conv_rgba32<3,2,1,0> color_conv_argb32_to_bgra32; //----color_conv_argb32_to_bgra32 + typedef color_conv_rgba32<1,2,3,0> color_conv_argb32_to_rgba32; //----color_conv_argb32_to_rgba32 + typedef color_conv_rgba32<3,0,1,2> color_conv_bgra32_to_abgr32; //----color_conv_bgra32_to_abgr32 + typedef color_conv_rgba32<3,2,1,0> color_conv_bgra32_to_argb32; //----color_conv_bgra32_to_argb32 + typedef color_conv_rgba32<2,1,0,3> color_conv_bgra32_to_rgba32; //----color_conv_bgra32_to_rgba32 + typedef color_conv_rgba32<3,2,1,0> color_conv_rgba32_to_abgr32; //----color_conv_rgba32_to_abgr32 + typedef color_conv_rgba32<3,0,1,2> color_conv_rgba32_to_argb32; //----color_conv_rgba32_to_argb32 + typedef color_conv_rgba32<2,1,0,3> color_conv_rgba32_to_bgra32; //----color_conv_rgba32_to_bgra32 + typedef color_conv_rgba32<0,3,2,1> color_conv_abgr32_to_argb32; //----color_conv_abgr32_to_argb32 + typedef color_conv_rgba32<1,2,3,0> color_conv_abgr32_to_bgra32; //----color_conv_abgr32_to_bgra32 + typedef color_conv_rgba32<3,2,1,0> color_conv_abgr32_to_rgba32; //----color_conv_abgr32_to_rgba32 + + //------------------------------------------------------------------------ + typedef color_conv_same<4> color_conv_rgba32_to_rgba32; //----color_conv_rgba32_to_rgba32 + typedef color_conv_same<4> color_conv_argb32_to_argb32; //----color_conv_argb32_to_argb32 + typedef color_conv_same<4> color_conv_bgra32_to_bgra32; //----color_conv_bgra32_to_bgra32 + typedef color_conv_same<4> color_conv_abgr32_to_abgr32; //----color_conv_abgr32_to_abgr32 + + + //--------------------------------------------color_conv_rgb24_rgba32 + template<int I1, int I2, int I3, int A> class color_conv_rgb24_rgba32 + { + public: + void operator () (int8u* dst, + const int8u* src, + unsigned width) const + { + do + { + dst[I1] = *src++; + dst[I2] = *src++; + dst[I3] = *src++; + dst[A] = 255; + dst += 4; + } + while(--width); + } + }; + + + //------------------------------------------------------------------------ + typedef color_conv_rgb24_rgba32<1,2,3,0> color_conv_rgb24_to_argb32; //----color_conv_rgb24_to_argb32 + typedef color_conv_rgb24_rgba32<3,2,1,0> color_conv_rgb24_to_abgr32; //----color_conv_rgb24_to_abgr32 + typedef color_conv_rgb24_rgba32<2,1,0,3> color_conv_rgb24_to_bgra32; //----color_conv_rgb24_to_bgra32 + typedef color_conv_rgb24_rgba32<0,1,2,3> color_conv_rgb24_to_rgba32; //----color_conv_rgb24_to_rgba32 + typedef color_conv_rgb24_rgba32<3,2,1,0> color_conv_bgr24_to_argb32; //----color_conv_bgr24_to_argb32 + typedef color_conv_rgb24_rgba32<1,2,3,0> color_conv_bgr24_to_abgr32; //----color_conv_bgr24_to_abgr32 + typedef color_conv_rgb24_rgba32<0,1,2,3> color_conv_bgr24_to_bgra32; //----color_conv_bgr24_to_bgra32 + typedef color_conv_rgb24_rgba32<2,1,0,3> color_conv_bgr24_to_rgba32; //----color_conv_bgr24_to_rgba32 + + + + //-------------------------------------------------color_conv_rgba32_rgb24 + template<int I1, int I2, int I3> class color_conv_rgba32_rgb24 + { + public: + void operator () (int8u* dst, + const int8u* src, + unsigned width) const + { + do + { + *dst++ = src[I1]; + *dst++ = src[I2]; + *dst++ = src[I3]; + src += 4; + } + while(--width); + } + }; + + + + //------------------------------------------------------------------------ + typedef color_conv_rgba32_rgb24<1,2,3> color_conv_argb32_to_rgb24; //----color_conv_argb32_to_rgb24 + typedef color_conv_rgba32_rgb24<3,2,1> color_conv_abgr32_to_rgb24; //----color_conv_abgr32_to_rgb24 + typedef color_conv_rgba32_rgb24<2,1,0> color_conv_bgra32_to_rgb24; //----color_conv_bgra32_to_rgb24 + typedef color_conv_rgba32_rgb24<0,1,2> color_conv_rgba32_to_rgb24; //----color_conv_rgba32_to_rgb24 + typedef color_conv_rgba32_rgb24<3,2,1> color_conv_argb32_to_bgr24; //----color_conv_argb32_to_bgr24 + typedef color_conv_rgba32_rgb24<1,2,3> color_conv_abgr32_to_bgr24; //----color_conv_abgr32_to_bgr24 + typedef color_conv_rgba32_rgb24<0,1,2> color_conv_bgra32_to_bgr24; //----color_conv_bgra32_to_bgr24 + typedef color_conv_rgba32_rgb24<2,1,0> color_conv_rgba32_to_bgr24; //----color_conv_rgba32_to_bgr24 + + + //------------------------------------------------color_conv_rgb555_rgb24 + template<int R, int B> class color_conv_rgb555_rgb24 + { + public: + void operator () (int8u* dst, + const int8u* src, + unsigned width) const + { + do + { + unsigned rgb = *(int16u*)src; + dst[R] = (int8u)((rgb >> 7) & 0xF8); + dst[1] = (int8u)((rgb >> 2) & 0xF8); + dst[B] = (int8u)((rgb << 3) & 0xF8); + src += 2; + dst += 3; + } + while(--width); + } + }; + + + //------------------------------------------------------------------------ + typedef color_conv_rgb555_rgb24<2,0> color_conv_rgb555_to_bgr24; //----color_conv_rgb555_to_bgr24 + typedef color_conv_rgb555_rgb24<0,2> color_conv_rgb555_to_rgb24; //----color_conv_rgb555_to_rgb24 + + + //-------------------------------------------------color_conv_rgb24_rgb555 + template<int R, int B> class color_conv_rgb24_rgb555 + { + public: + void operator () (int8u* dst, + const int8u* src, + unsigned width) const + { + do + { + *(int16u*)dst = (int16u)(((unsigned(src[R]) << 7) & 0x7C00) | + ((unsigned(src[1]) << 2) & 0x3E0) | + ((unsigned(src[B]) >> 3))); + src += 3; + dst += 2; + } + while(--width); + } + }; + + + //------------------------------------------------------------------------ + typedef color_conv_rgb24_rgb555<2,0> color_conv_bgr24_to_rgb555; //----color_conv_bgr24_to_rgb555 + typedef color_conv_rgb24_rgb555<0,2> color_conv_rgb24_to_rgb555; //----color_conv_rgb24_to_rgb555 + + + //-------------------------------------------------color_conv_rgb565_rgb24 + template<int R, int B> class color_conv_rgb565_rgb24 + { + public: + void operator () (int8u* dst, + const int8u* src, + unsigned width) const + { + do + { + unsigned rgb = *(int16u*)src; + dst[R] = (rgb >> 8) & 0xF8; + dst[1] = (rgb >> 3) & 0xFC; + dst[B] = (rgb << 3) & 0xF8; + src += 2; + dst += 3; + } + while(--width); + } + }; + + + //------------------------------------------------------------------------ + typedef color_conv_rgb565_rgb24<2,0> color_conv_rgb565_to_bgr24; //----color_conv_rgb565_to_bgr24 + typedef color_conv_rgb565_rgb24<0,2> color_conv_rgb565_to_rgb24; //----color_conv_rgb565_to_rgb24 + + + //-------------------------------------------------color_conv_rgb24_rgb565 + template<int R, int B> class color_conv_rgb24_rgb565 + { + public: + void operator () (int8u* dst, + const int8u* src, + unsigned width) const + { + do + { + *(int16u*)dst = (int16u)(((unsigned(src[R]) << 8) & 0xF800) | + ((unsigned(src[1]) << 3) & 0x7E0) | + ((unsigned(src[B]) >> 3))); + src += 3; + dst += 2; + } + while(--width); + } + }; + + + //------------------------------------------------------------------------ + typedef color_conv_rgb24_rgb565<2,0> color_conv_bgr24_to_rgb565; //----color_conv_bgr24_to_rgb565 + typedef color_conv_rgb24_rgb565<0,2> color_conv_rgb24_to_rgb565; //----color_conv_rgb24_to_rgb565 + + + + //-------------------------------------------------color_conv_rgb555_rgba32 + template<int R, int G, int B, int A> class color_conv_rgb555_rgba32 + { + public: + void operator () (int8u* dst, + const int8u* src, + unsigned width) const + { + do + { + int rgb = *(int16*)src; + dst[R] = (int8u)((rgb >> 7) & 0xF8); + dst[G] = (int8u)((rgb >> 2) & 0xF8); + dst[B] = (int8u)((rgb << 3) & 0xF8); + dst[A] = (int8u)(rgb >> 15); + src += 2; + dst += 4; + } + while(--width); + } + }; + + + //------------------------------------------------------------------------ + typedef color_conv_rgb555_rgba32<1,2,3,0> color_conv_rgb555_to_argb32; //----color_conv_rgb555_to_argb32 + typedef color_conv_rgb555_rgba32<3,2,1,0> color_conv_rgb555_to_abgr32; //----color_conv_rgb555_to_abgr32 + typedef color_conv_rgb555_rgba32<2,1,0,3> color_conv_rgb555_to_bgra32; //----color_conv_rgb555_to_bgra32 + typedef color_conv_rgb555_rgba32<0,1,2,3> color_conv_rgb555_to_rgba32; //----color_conv_rgb555_to_rgba32 + + + //------------------------------------------------color_conv_rgba32_rgb555 + template<int R, int G, int B, int A> class color_conv_rgba32_rgb555 + { + public: + void operator () (int8u* dst, + const int8u* src, + unsigned width) const + { + do + { + *(int16u*)dst = (int16u)(((unsigned(src[R]) << 7) & 0x7C00) | + ((unsigned(src[G]) << 2) & 0x3E0) | + ((unsigned(src[B]) >> 3)) | + ((unsigned(src[A]) << 8) & 0x8000)); + src += 4; + dst += 2; + } + while(--width); + } + }; + + + //------------------------------------------------------------------------ + typedef color_conv_rgba32_rgb555<1,2,3,0> color_conv_argb32_to_rgb555; //----color_conv_argb32_to_rgb555 + typedef color_conv_rgba32_rgb555<3,2,1,0> color_conv_abgr32_to_rgb555; //----color_conv_abgr32_to_rgb555 + typedef color_conv_rgba32_rgb555<2,1,0,3> color_conv_bgra32_to_rgb555; //----color_conv_bgra32_to_rgb555 + typedef color_conv_rgba32_rgb555<0,1,2,3> color_conv_rgba32_to_rgb555; //----color_conv_rgba32_to_rgb555 + + + + //------------------------------------------------color_conv_rgb565_rgba32 + template<int R, int G, int B, int A> class color_conv_rgb565_rgba32 + { + public: + void operator () (int8u* dst, + const int8u* src, + unsigned width) const + { + do + { + int rgb = *(int16*)src; + dst[R] = (rgb >> 8) & 0xF8; + dst[G] = (rgb >> 3) & 0xFC; + dst[B] = (rgb << 3) & 0xF8; + dst[A] = 255; + src += 2; + dst += 4; + } + while(--width); + } + }; + + + //------------------------------------------------------------------------ + typedef color_conv_rgb565_rgba32<1,2,3,0> color_conv_rgb565_to_argb32; //----color_conv_rgb565_to_argb32 + typedef color_conv_rgb565_rgba32<3,2,1,0> color_conv_rgb565_to_abgr32; //----color_conv_rgb565_to_abgr32 + typedef color_conv_rgb565_rgba32<2,1,0,3> color_conv_rgb565_to_bgra32; //----color_conv_rgb565_to_bgra32 + typedef color_conv_rgb565_rgba32<0,1,2,3> color_conv_rgb565_to_rgba32; //----color_conv_rgb565_to_rgba32 + + + //------------------------------------------------color_conv_rgba32_rgb565 + template<int R, int G, int B> class color_conv_rgba32_rgb565 + { + public: + void operator () (int8u* dst, + const int8u* src, + unsigned width) const + { + do + { + *(int16u*)dst = (int16u)(((unsigned(src[R]) << 8) & 0xF800) | + ((unsigned(src[G]) << 3) & 0x7E0) | + ((unsigned(src[B]) >> 3))); + src += 4; + dst += 2; + } + while(--width); + } + }; + + + //------------------------------------------------------------------------ + typedef color_conv_rgba32_rgb565<1,2,3> color_conv_argb32_to_rgb565; //----color_conv_argb32_to_rgb565 + typedef color_conv_rgba32_rgb565<3,2,1> color_conv_abgr32_to_rgb565; //----color_conv_abgr32_to_rgb565 + typedef color_conv_rgba32_rgb565<2,1,0> color_conv_bgra32_to_rgb565; //----color_conv_bgra32_to_rgb565 + typedef color_conv_rgba32_rgb565<0,1,2> color_conv_rgba32_to_rgb565; //----color_conv_rgba32_to_rgb565 + + + //---------------------------------------------color_conv_rgb555_to_rgb565 + class color_conv_rgb555_to_rgb565 + { + public: + void operator () (int8u* dst, + const int8u* src, + unsigned width) const + { + do + { + unsigned rgb = *(int16u*)src; + *(int16u*)dst = (int16u)(((rgb << 1) & 0xFFC0) | (rgb & 0x1F)); + src += 2; + dst += 2; + } + while(--width); + } + }; + + + //----------------------------------------------color_conv_rgb565_to_rgb555 + class color_conv_rgb565_to_rgb555 + { + public: + void operator () (int8u* dst, + const int8u* src, + unsigned width) const + { + do + { + unsigned rgb = *(int16u*)src; + *(int16u*)dst = (int16u)(((rgb >> 1) & 0x7FE0) | (rgb & 0x1F)); + src += 2; + dst += 2; + } + while(--width); + } + }; + + + //------------------------------------------------------------------------ + typedef color_conv_same<2> color_conv_rgb555_to_rgb555; //----color_conv_rgb555_to_rgb555 + typedef color_conv_same<2> color_conv_rgb565_to_rgb565; //----color_conv_rgb565_to_rgb565 + + + template<int R, int B> class color_conv_rgb24_gray8 + { + public: + void operator () (int8u* dst, + const int8u* src, + unsigned width) const + { + do + { + *dst++ = (src[R]*77 + src[1]*150 + src[B]*29) >> 8; + src += 3; + } + while(--width); + } + }; + + typedef color_conv_rgb24_gray8<0,2> color_conv_rgb24_to_gray8; //----color_conv_rgb24_to_gray8 + typedef color_conv_rgb24_gray8<2,0> color_conv_bgr24_to_gray8; //----color_conv_bgr24_to_gray8 + + +} + + + +#endif diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/src/ChangeLog b/contrib/python/matplotlib/py3/extern/agg24-svn/src/ChangeLog new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/src/ChangeLog diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_arc.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_arc.cpp new file mode 100644 index 00000000000..df2c43a5596 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_arc.cpp @@ -0,0 +1,106 @@ +//---------------------------------------------------------------------------- +// 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 +// +//---------------------------------------------------------------------------- + +#include <math.h> +#include "agg_arc.h" + + +namespace agg +{ + //------------------------------------------------------------------------ + arc::arc(double x, double y, + double rx, double ry, + double a1, double a2, + bool ccw) : + m_x(x), m_y(y), m_rx(rx), m_ry(ry), m_scale(1.0) + { + normalize(a1, a2, ccw); + } + + //------------------------------------------------------------------------ + void arc::init(double x, double y, + double rx, double ry, + double a1, double a2, + bool ccw) + { + m_x = x; m_y = y; + m_rx = rx; m_ry = ry; + normalize(a1, a2, ccw); + } + + //------------------------------------------------------------------------ + void arc::approximation_scale(double s) + { + m_scale = s; + if(m_initialized) + { + normalize(m_start, m_end, m_ccw); + } + } + + //------------------------------------------------------------------------ + void arc::rewind(unsigned) + { + m_path_cmd = path_cmd_move_to; + m_angle = m_start; + } + + //------------------------------------------------------------------------ + unsigned arc::vertex(double* x, double* y) + { + if(is_stop(m_path_cmd)) return path_cmd_stop; + if((m_angle < m_end - m_da/4) != m_ccw) + { + *x = m_x + cos(m_end) * m_rx; + *y = m_y + sin(m_end) * m_ry; + m_path_cmd = path_cmd_stop; + return path_cmd_line_to; + } + + *x = m_x + cos(m_angle) * m_rx; + *y = m_y + sin(m_angle) * m_ry; + + m_angle += m_da; + + unsigned pf = m_path_cmd; + m_path_cmd = path_cmd_line_to; + return pf; + } + + //------------------------------------------------------------------------ + void arc::normalize(double a1, double a2, bool ccw) + { + double ra = (fabs(m_rx) + fabs(m_ry)) / 2; + m_da = acos(ra / (ra + 0.125 / m_scale)) * 2; + if(ccw) + { + while(a2 < a1) a2 += pi * 2.0; + } + else + { + while(a1 < a2) a1 += pi * 2.0; + m_da = -m_da; + } + m_ccw = ccw; + m_start = a1; + m_end = a2; + m_initialized = true; + } + +} diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_arrowhead.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_arrowhead.cpp new file mode 100644 index 00000000000..1a6f8b41005 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_arrowhead.cpp @@ -0,0 +1,110 @@ +//---------------------------------------------------------------------------- +// 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 +// +//---------------------------------------------------------------------------- + +#include "agg_arrowhead.h" + +namespace agg +{ + + //------------------------------------------------------------------------ + arrowhead::arrowhead() : + m_head_d1(1.0), + m_head_d2(1.0), + m_head_d3(1.0), + m_head_d4(0.0), + m_tail_d1(1.0), + m_tail_d2(1.0), + m_tail_d3(1.0), + m_tail_d4(0.0), + m_head_flag(false), + m_tail_flag(false), + m_curr_id(0), + m_curr_coord(0) + { + } + + + + //------------------------------------------------------------------------ + void arrowhead::rewind(unsigned path_id) + { + m_curr_id = path_id; + m_curr_coord = 0; + if(path_id == 0) + { + if(!m_tail_flag) + { + m_cmd[0] = path_cmd_stop; + return; + } + m_coord[0] = m_tail_d1; m_coord[1] = 0.0; + m_coord[2] = m_tail_d1 - m_tail_d4; m_coord[3] = m_tail_d3; + m_coord[4] = -m_tail_d2 - m_tail_d4; m_coord[5] = m_tail_d3; + m_coord[6] = -m_tail_d2; m_coord[7] = 0.0; + m_coord[8] = -m_tail_d2 - m_tail_d4; m_coord[9] = -m_tail_d3; + m_coord[10] = m_tail_d1 - m_tail_d4; m_coord[11] = -m_tail_d3; + + m_cmd[0] = path_cmd_move_to; + m_cmd[1] = path_cmd_line_to; + m_cmd[2] = path_cmd_line_to; + m_cmd[3] = path_cmd_line_to; + m_cmd[4] = path_cmd_line_to; + m_cmd[5] = path_cmd_line_to; + m_cmd[7] = path_cmd_end_poly | path_flags_close | path_flags_ccw; + m_cmd[6] = path_cmd_stop; + return; + } + + if(path_id == 1) + { + if(!m_head_flag) + { + m_cmd[0] = path_cmd_stop; + return; + } + m_coord[0] = -m_head_d1; m_coord[1] = 0.0; + m_coord[2] = m_head_d2 + m_head_d4; m_coord[3] = -m_head_d3; + m_coord[4] = m_head_d2; m_coord[5] = 0.0; + m_coord[6] = m_head_d2 + m_head_d4; m_coord[7] = m_head_d3; + + m_cmd[0] = path_cmd_move_to; + m_cmd[1] = path_cmd_line_to; + m_cmd[2] = path_cmd_line_to; + m_cmd[3] = path_cmd_line_to; + m_cmd[4] = path_cmd_end_poly | path_flags_close | path_flags_ccw; + m_cmd[5] = path_cmd_stop; + return; + } + } + + + //------------------------------------------------------------------------ + unsigned arrowhead::vertex(double* x, double* y) + { + if(m_curr_id < 2) + { + unsigned curr_idx = m_curr_coord * 2; + *x = m_coord[curr_idx]; + *y = m_coord[curr_idx + 1]; + return m_cmd[m_curr_coord++]; + } + return path_cmd_stop; + } + +} diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_bezier_arc.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_bezier_arc.cpp new file mode 100644 index 00000000000..844d300c091 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_bezier_arc.cpp @@ -0,0 +1,258 @@ +//---------------------------------------------------------------------------- +// 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 generator. Produces at most 4 consecutive cubic bezier curves, i.e., +// 4, 7, 10, or 13 vertices. +// +//---------------------------------------------------------------------------- + + +#include <math.h> +#include "agg_bezier_arc.h" + + +namespace agg +{ + + // This epsilon is used to prevent us from adding degenerate curves + // (converging to a single point). + // The value isn't very critical. Function arc_to_bezier() has a limit + // of the sweep_angle. If fabs(sweep_angle) exceeds pi/2 the curve + // becomes inaccurate. But slight exceeding is quite appropriate. + //-------------------------------------------------bezier_arc_angle_epsilon + const double bezier_arc_angle_epsilon = 0.01; + + //------------------------------------------------------------arc_to_bezier + void arc_to_bezier(double cx, double cy, double rx, double ry, + double start_angle, double sweep_angle, + double* curve) + { + double x0 = cos(sweep_angle / 2.0); + double y0 = sin(sweep_angle / 2.0); + double tx = (1.0 - x0) * 4.0 / 3.0; + double ty = y0 - tx * x0 / y0; + double px[4]; + double py[4]; + px[0] = x0; + py[0] = -y0; + px[1] = x0 + tx; + py[1] = -ty; + px[2] = x0 + tx; + py[2] = ty; + px[3] = x0; + py[3] = y0; + + double sn = sin(start_angle + sweep_angle / 2.0); + double cs = cos(start_angle + sweep_angle / 2.0); + + unsigned i; + for(i = 0; i < 4; i++) + { + curve[i * 2] = cx + rx * (px[i] * cs - py[i] * sn); + curve[i * 2 + 1] = cy + ry * (px[i] * sn + py[i] * cs); + } + } + + + + //------------------------------------------------------------------------ + void bezier_arc::init(double x, double y, + double rx, double ry, + double start_angle, + double sweep_angle) + { + start_angle = fmod(start_angle, 2.0 * pi); + if(sweep_angle >= 2.0 * pi) sweep_angle = 2.0 * pi; + if(sweep_angle <= -2.0 * pi) sweep_angle = -2.0 * pi; + + if(fabs(sweep_angle) < 1e-10) + { + m_num_vertices = 4; + m_cmd = path_cmd_line_to; + m_vertices[0] = x + rx * cos(start_angle); + m_vertices[1] = y + ry * sin(start_angle); + m_vertices[2] = x + rx * cos(start_angle + sweep_angle); + m_vertices[3] = y + ry * sin(start_angle + sweep_angle); + return; + } + + double total_sweep = 0.0; + double local_sweep = 0.0; + double prev_sweep; + m_num_vertices = 2; + m_cmd = path_cmd_curve4; + bool done = false; + do + { + if(sweep_angle < 0.0) + { + prev_sweep = total_sweep; + local_sweep = -pi * 0.5; + total_sweep -= pi * 0.5; + if(total_sweep <= sweep_angle + bezier_arc_angle_epsilon) + { + local_sweep = sweep_angle - prev_sweep; + done = true; + } + } + else + { + prev_sweep = total_sweep; + local_sweep = pi * 0.5; + total_sweep += pi * 0.5; + if(total_sweep >= sweep_angle - bezier_arc_angle_epsilon) + { + local_sweep = sweep_angle - prev_sweep; + done = true; + } + } + + arc_to_bezier(x, y, rx, ry, + start_angle, + local_sweep, + m_vertices + m_num_vertices - 2); + + m_num_vertices += 6; + start_angle += local_sweep; + } + while(!done && m_num_vertices < 26); + } + + + + + //-------------------------------------------------------------------- + void bezier_arc_svg::init(double x0, double y0, + double rx, double ry, + double angle, + bool large_arc_flag, + bool sweep_flag, + double x2, double y2) + { + m_radii_ok = true; + + if(rx < 0.0) rx = -rx; + if(ry < 0.0) ry = -rx; + + // Calculate the middle point between + // the current and the final points + //------------------------ + double dx2 = (x0 - x2) / 2.0; + double dy2 = (y0 - y2) / 2.0; + + double cos_a = cos(angle); + double sin_a = sin(angle); + + // Calculate (x1, y1) + //------------------------ + double x1 = cos_a * dx2 + sin_a * dy2; + double y1 = -sin_a * dx2 + cos_a * dy2; + + // Ensure radii are large enough + //------------------------ + double prx = rx * rx; + double pry = ry * ry; + double px1 = x1 * x1; + double py1 = y1 * y1; + + // Check that radii are large enough + //------------------------ + double radii_check = px1/prx + py1/pry; + if(radii_check > 1.0) + { + rx = sqrt(radii_check) * rx; + ry = sqrt(radii_check) * ry; + prx = rx * rx; + pry = ry * ry; + if(radii_check > 10.0) m_radii_ok = false; + } + + // Calculate (cx1, cy1) + //------------------------ + double sign = (large_arc_flag == sweep_flag) ? -1.0 : 1.0; + double sq = (prx*pry - prx*py1 - pry*px1) / (prx*py1 + pry*px1); + double coef = sign * sqrt((sq < 0) ? 0 : sq); + double cx1 = coef * ((rx * y1) / ry); + double cy1 = coef * -((ry * x1) / rx); + + // + // Calculate (cx, cy) from (cx1, cy1) + //------------------------ + double sx2 = (x0 + x2) / 2.0; + double sy2 = (y0 + y2) / 2.0; + double cx = sx2 + (cos_a * cx1 - sin_a * cy1); + double cy = sy2 + (sin_a * cx1 + cos_a * cy1); + + // Calculate the start_angle (angle1) and the sweep_angle (dangle) + //------------------------ + double ux = (x1 - cx1) / rx; + double uy = (y1 - cy1) / ry; + double vx = (-x1 - cx1) / rx; + double vy = (-y1 - cy1) / ry; + double p, n; + + // Calculate the angle start + //------------------------ + n = sqrt(ux*ux + uy*uy); + p = ux; // (1 * ux) + (0 * uy) + sign = (uy < 0) ? -1.0 : 1.0; + double v = p / n; + if(v < -1.0) v = -1.0; + if(v > 1.0) v = 1.0; + double start_angle = sign * acos(v); + + // Calculate the sweep angle + //------------------------ + n = sqrt((ux*ux + uy*uy) * (vx*vx + vy*vy)); + p = ux * vx + uy * vy; + sign = (ux * vy - uy * vx < 0) ? -1.0 : 1.0; + v = p / n; + if(v < -1.0) v = -1.0; + if(v > 1.0) v = 1.0; + double sweep_angle = sign * acos(v); + if(!sweep_flag && sweep_angle > 0) + { + sweep_angle -= pi * 2.0; + } + else + if (sweep_flag && sweep_angle < 0) + { + sweep_angle += pi * 2.0; + } + + // We can now build and transform the resulting arc + //------------------------ + m_arc.init(0.0, 0.0, rx, ry, start_angle, sweep_angle); + trans_affine mtx = trans_affine_rotation(angle); + mtx *= trans_affine_translation(cx, cy); + + for(unsigned i = 2; i < m_arc.num_vertices()-2; i += 2) + { + mtx.transform(m_arc.vertices() + i, m_arc.vertices() + i + 1); + } + + // We must make sure that the starting and ending points + // exactly coincide with the initial (x0,y0) and (x2,y2) + m_arc.vertices()[0] = x0; + m_arc.vertices()[1] = y0; + if(m_arc.num_vertices() > 2) + { + m_arc.vertices()[m_arc.num_vertices() - 2] = x2; + m_arc.vertices()[m_arc.num_vertices() - 1] = y2; + } + } + + +} diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_bspline.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_bspline.cpp new file mode 100644 index 00000000000..e1fda9f51f2 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_bspline.cpp @@ -0,0 +1,284 @@ +//---------------------------------------------------------------------------- +// 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 +// +//---------------------------------------------------------------------------- + +#include "agg_bspline.h" + +namespace agg +{ + //------------------------------------------------------------------------ + bspline::bspline() : + m_max(0), + m_num(0), + m_x(0), + m_y(0), + m_last_idx(-1) + { + } + + //------------------------------------------------------------------------ + bspline::bspline(int num) : + m_max(0), + m_num(0), + m_x(0), + m_y(0), + m_last_idx(-1) + { + init(num); + } + + //------------------------------------------------------------------------ + bspline::bspline(int num, const double* x, const double* y) : + m_max(0), + m_num(0), + m_x(0), + m_y(0), + m_last_idx(-1) + { + init(num, x, y); + } + + + //------------------------------------------------------------------------ + void bspline::init(int max) + { + if(max > 2 && max > m_max) + { + m_am.resize(max * 3); + m_max = max; + m_x = &m_am[m_max]; + m_y = &m_am[m_max * 2]; + } + m_num = 0; + m_last_idx = -1; + } + + + //------------------------------------------------------------------------ + void bspline::add_point(double x, double y) + { + if(m_num < m_max) + { + m_x[m_num] = x; + m_y[m_num] = y; + ++m_num; + } + } + + + //------------------------------------------------------------------------ + void bspline::prepare() + { + if(m_num > 2) + { + int i, k, n1; + double* temp; + double* r; + double* s; + double h, p, d, f, e; + + for(k = 0; k < m_num; k++) + { + m_am[k] = 0.0; + } + + n1 = 3 * m_num; + + pod_array<double> al(n1); + temp = &al[0]; + + for(k = 0; k < n1; k++) + { + temp[k] = 0.0; + } + + r = temp + m_num; + s = temp + m_num * 2; + + n1 = m_num - 1; + d = m_x[1] - m_x[0]; + e = (m_y[1] - m_y[0]) / d; + + for(k = 1; k < n1; k++) + { + h = d; + d = m_x[k + 1] - m_x[k]; + f = e; + e = (m_y[k + 1] - m_y[k]) / d; + al[k] = d / (d + h); + r[k] = 1.0 - al[k]; + s[k] = 6.0 * (e - f) / (h + d); + } + + for(k = 1; k < n1; k++) + { + p = 1.0 / (r[k] * al[k - 1] + 2.0); + al[k] *= -p; + s[k] = (s[k] - r[k] * s[k - 1]) * p; + } + + m_am[n1] = 0.0; + al[n1 - 1] = s[n1 - 1]; + m_am[n1 - 1] = al[n1 - 1]; + + for(k = n1 - 2, i = 0; i < m_num - 2; i++, k--) + { + al[k] = al[k] * al[k + 1] + s[k]; + m_am[k] = al[k]; + } + } + m_last_idx = -1; + } + + + + //------------------------------------------------------------------------ + void bspline::init(int num, const double* x, const double* y) + { + if(num > 2) + { + init(num); + int i; + for(i = 0; i < num; i++) + { + add_point(*x++, *y++); + } + prepare(); + } + m_last_idx = -1; + } + + + //------------------------------------------------------------------------ + void bspline::bsearch(int n, const double *x, double x0, int *i) + { + int j = n - 1; + int k; + + for(*i = 0; (j - *i) > 1; ) + { + if(x0 < x[k = (*i + j) >> 1]) j = k; + else *i = k; + } + } + + + + //------------------------------------------------------------------------ + double bspline::interpolation(double x, int i) const + { + int j = i + 1; + double d = m_x[i] - m_x[j]; + double h = x - m_x[j]; + double r = m_x[i] - x; + double p = d * d / 6.0; + return (m_am[j] * r * r * r + m_am[i] * h * h * h) / 6.0 / d + + ((m_y[j] - m_am[j] * p) * r + (m_y[i] - m_am[i] * p) * h) / d; + } + + + //------------------------------------------------------------------------ + double bspline::extrapolation_left(double x) const + { + double d = m_x[1] - m_x[0]; + return (-d * m_am[1] / 6 + (m_y[1] - m_y[0]) / d) * + (x - m_x[0]) + + m_y[0]; + } + + //------------------------------------------------------------------------ + double bspline::extrapolation_right(double x) const + { + double d = m_x[m_num - 1] - m_x[m_num - 2]; + return (d * m_am[m_num - 2] / 6 + (m_y[m_num - 1] - m_y[m_num - 2]) / d) * + (x - m_x[m_num - 1]) + + m_y[m_num - 1]; + } + + //------------------------------------------------------------------------ + double bspline::get(double x) const + { + if(m_num > 2) + { + int i; + + // Extrapolation on the left + if(x < m_x[0]) return extrapolation_left(x); + + // Extrapolation on the right + if(x >= m_x[m_num - 1]) return extrapolation_right(x); + + // Interpolation + bsearch(m_num, m_x, x, &i); + return interpolation(x, i); + } + return 0.0; + } + + + //------------------------------------------------------------------------ + double bspline::get_stateful(double x) const + { + if(m_num > 2) + { + // Extrapolation on the left + if(x < m_x[0]) return extrapolation_left(x); + + // Extrapolation on the right + if(x >= m_x[m_num - 1]) return extrapolation_right(x); + + if(m_last_idx >= 0) + { + // Check if x is not in current range + if(x < m_x[m_last_idx] || x > m_x[m_last_idx + 1]) + { + // Check if x between next points (most probably) + if(m_last_idx < m_num - 2 && + x >= m_x[m_last_idx + 1] && + x <= m_x[m_last_idx + 2]) + { + ++m_last_idx; + } + else + if(m_last_idx > 0 && + x >= m_x[m_last_idx - 1] && + x <= m_x[m_last_idx]) + { + // x is between pevious points + --m_last_idx; + } + else + { + // Else perform full search + bsearch(m_num, m_x, x, &m_last_idx); + } + } + return interpolation(x, m_last_idx); + } + else + { + // Interpolation + bsearch(m_num, m_x, x, &m_last_idx); + return interpolation(x, m_last_idx); + } + } + return 0.0; + } + +} + diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_color_rgba.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_color_rgba.cpp new file mode 100644 index 00000000000..9fe1534b033 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_color_rgba.cpp @@ -0,0 +1,17 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2009 John Horigan (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: john@glyphic.com.com +// http://www.antigrain.com +//---------------------------------------------------------------------------- + +// rgbaN construction from grayN types is no longer required, +// as grayN types now define their own conversions to rgbaN. diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_curves.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_curves.cpp new file mode 100644 index 00000000000..47017347188 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_curves.cpp @@ -0,0 +1,613 @@ +//---------------------------------------------------------------------------- +// 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 +//---------------------------------------------------------------------------- + +#include <math.h> +#include "agg_curves.h" +#include "agg_math.h" + +namespace agg +{ + + //------------------------------------------------------------------------ + const double curve_distance_epsilon = 1e-30; + const double curve_collinearity_epsilon = 1e-30; + const double curve_angle_tolerance_epsilon = 0.01; + enum curve_recursion_limit_e { curve_recursion_limit = 32 }; + + + + //------------------------------------------------------------------------ + void curve3_inc::approximation_scale(double s) + { + m_scale = s; + } + + //------------------------------------------------------------------------ + double curve3_inc::approximation_scale() const + { + return m_scale; + } + + //------------------------------------------------------------------------ + void curve3_inc::init(double x1, double y1, + double x2, double y2, + double x3, double y3) + { + m_start_x = x1; + m_start_y = y1; + m_end_x = x3; + m_end_y = y3; + + double dx1 = x2 - x1; + double dy1 = y2 - y1; + double dx2 = x3 - x2; + double dy2 = y3 - y2; + + double len = sqrt(dx1 * dx1 + dy1 * dy1) + sqrt(dx2 * dx2 + dy2 * dy2); + + m_num_steps = uround(len * 0.25 * m_scale); + + if(m_num_steps < 4) + { + m_num_steps = 4; + } + + double subdivide_step = 1.0 / m_num_steps; + double subdivide_step2 = subdivide_step * subdivide_step; + + double tmpx = (x1 - x2 * 2.0 + x3) * subdivide_step2; + double tmpy = (y1 - y2 * 2.0 + y3) * subdivide_step2; + + m_saved_fx = m_fx = x1; + m_saved_fy = m_fy = y1; + + m_saved_dfx = m_dfx = tmpx + (x2 - x1) * (2.0 * subdivide_step); + m_saved_dfy = m_dfy = tmpy + (y2 - y1) * (2.0 * subdivide_step); + + m_ddfx = tmpx * 2.0; + m_ddfy = tmpy * 2.0; + + m_step = m_num_steps; + } + + //------------------------------------------------------------------------ + void curve3_inc::rewind(unsigned) + { + if(m_num_steps == 0) + { + m_step = -1; + return; + } + m_step = m_num_steps; + m_fx = m_saved_fx; + m_fy = m_saved_fy; + m_dfx = m_saved_dfx; + m_dfy = m_saved_dfy; + } + + //------------------------------------------------------------------------ + unsigned curve3_inc::vertex(double* x, double* y) + { + if(m_step < 0) return path_cmd_stop; + if(m_step == m_num_steps) + { + *x = m_start_x; + *y = m_start_y; + --m_step; + return path_cmd_move_to; + } + if(m_step == 0) + { + *x = m_end_x; + *y = m_end_y; + --m_step; + return path_cmd_line_to; + } + m_fx += m_dfx; + m_fy += m_dfy; + m_dfx += m_ddfx; + m_dfy += m_ddfy; + *x = m_fx; + *y = m_fy; + --m_step; + return path_cmd_line_to; + } + + //------------------------------------------------------------------------ + void curve3_div::init(double x1, double y1, + double x2, double y2, + double x3, double y3) + { + m_points.remove_all(); + m_distance_tolerance_square = 0.5 / m_approximation_scale; + m_distance_tolerance_square *= m_distance_tolerance_square; + bezier(x1, y1, x2, y2, x3, y3); + m_count = 0; + } + + //------------------------------------------------------------------------ + void curve3_div::recursive_bezier(double x1, double y1, + double x2, double y2, + double x3, double y3, + unsigned level) + { + if(level > curve_recursion_limit) + { + return; + } + + // Calculate all the mid-points of the line segments + //---------------------- + double x12 = (x1 + x2) / 2; + double y12 = (y1 + y2) / 2; + double x23 = (x2 + x3) / 2; + double y23 = (y2 + y3) / 2; + double x123 = (x12 + x23) / 2; + double y123 = (y12 + y23) / 2; + + double dx = x3-x1; + double dy = y3-y1; + double d = fabs(((x2 - x3) * dy - (y2 - y3) * dx)); + double da; + + if(d > curve_collinearity_epsilon) + { + // Regular case + //----------------- + if(d * d <= m_distance_tolerance_square * (dx*dx + dy*dy)) + { + // If the curvature doesn't exceed the distance_tolerance value + // we tend to finish subdivisions. + //---------------------- + if(m_angle_tolerance < curve_angle_tolerance_epsilon) + { + m_points.add(point_d(x123, y123)); + return; + } + + // Angle & Cusp Condition + //---------------------- + da = fabs(atan2(y3 - y2, x3 - x2) - atan2(y2 - y1, x2 - x1)); + if(da >= pi) da = 2*pi - da; + + if(da < m_angle_tolerance) + { + // Finally we can stop the recursion + //---------------------- + m_points.add(point_d(x123, y123)); + return; + } + } + } + else + { + // Collinear case + //------------------ + da = dx*dx + dy*dy; + if(da == 0) + { + d = calc_sq_distance(x1, y1, x2, y2); + } + else + { + d = ((x2 - x1)*dx + (y2 - y1)*dy) / da; + if(d > 0 && d < 1) + { + // Simple collinear case, 1---2---3 + // We can leave just two endpoints + return; + } + if(d <= 0) d = calc_sq_distance(x2, y2, x1, y1); + else if(d >= 1) d = calc_sq_distance(x2, y2, x3, y3); + else d = calc_sq_distance(x2, y2, x1 + d*dx, y1 + d*dy); + } + if(d < m_distance_tolerance_square) + { + m_points.add(point_d(x2, y2)); + return; + } + } + + // Continue subdivision + //---------------------- + recursive_bezier(x1, y1, x12, y12, x123, y123, level + 1); + recursive_bezier(x123, y123, x23, y23, x3, y3, level + 1); + } + + //------------------------------------------------------------------------ + void curve3_div::bezier(double x1, double y1, + double x2, double y2, + double x3, double y3) + { + m_points.add(point_d(x1, y1)); + recursive_bezier(x1, y1, x2, y2, x3, y3, 0); + m_points.add(point_d(x3, y3)); + } + + + + + + //------------------------------------------------------------------------ + void curve4_inc::approximation_scale(double s) + { + m_scale = s; + } + + //------------------------------------------------------------------------ + double curve4_inc::approximation_scale() const + { + return m_scale; + } + +#if defined(_MSC_VER) && _MSC_VER <= 1200 + //------------------------------------------------------------------------ + static double MSC60_fix_ICE(double v) { return v; } +#endif + + //------------------------------------------------------------------------ + void curve4_inc::init(double x1, double y1, + double x2, double y2, + double x3, double y3, + double x4, double y4) + { + m_start_x = x1; + m_start_y = y1; + m_end_x = x4; + m_end_y = y4; + + double dx1 = x2 - x1; + double dy1 = y2 - y1; + double dx2 = x3 - x2; + double dy2 = y3 - y2; + double dx3 = x4 - x3; + double dy3 = y4 - y3; + + double len = (sqrt(dx1 * dx1 + dy1 * dy1) + + sqrt(dx2 * dx2 + dy2 * dy2) + + sqrt(dx3 * dx3 + dy3 * dy3)) * 0.25 * m_scale; + +#if defined(_MSC_VER) && _MSC_VER <= 1200 + m_num_steps = uround(MSC60_fix_ICE(len)); +#else + m_num_steps = uround(len); +#endif + + if(m_num_steps < 4) + { + m_num_steps = 4; + } + + double subdivide_step = 1.0 / m_num_steps; + double subdivide_step2 = subdivide_step * subdivide_step; + double subdivide_step3 = subdivide_step * subdivide_step * subdivide_step; + + double pre1 = 3.0 * subdivide_step; + double pre2 = 3.0 * subdivide_step2; + double pre4 = 6.0 * subdivide_step2; + double pre5 = 6.0 * subdivide_step3; + + double tmp1x = x1 - x2 * 2.0 + x3; + double tmp1y = y1 - y2 * 2.0 + y3; + + double tmp2x = (x2 - x3) * 3.0 - x1 + x4; + double tmp2y = (y2 - y3) * 3.0 - y1 + y4; + + m_saved_fx = m_fx = x1; + m_saved_fy = m_fy = y1; + + m_saved_dfx = m_dfx = (x2 - x1) * pre1 + tmp1x * pre2 + tmp2x * subdivide_step3; + m_saved_dfy = m_dfy = (y2 - y1) * pre1 + tmp1y * pre2 + tmp2y * subdivide_step3; + + m_saved_ddfx = m_ddfx = tmp1x * pre4 + tmp2x * pre5; + m_saved_ddfy = m_ddfy = tmp1y * pre4 + tmp2y * pre5; + + m_dddfx = tmp2x * pre5; + m_dddfy = tmp2y * pre5; + + m_step = m_num_steps; + } + + //------------------------------------------------------------------------ + void curve4_inc::rewind(unsigned) + { + if(m_num_steps == 0) + { + m_step = -1; + return; + } + m_step = m_num_steps; + m_fx = m_saved_fx; + m_fy = m_saved_fy; + m_dfx = m_saved_dfx; + m_dfy = m_saved_dfy; + m_ddfx = m_saved_ddfx; + m_ddfy = m_saved_ddfy; + } + + //------------------------------------------------------------------------ + unsigned curve4_inc::vertex(double* x, double* y) + { + if(m_step < 0) return path_cmd_stop; + if(m_step == m_num_steps) + { + *x = m_start_x; + *y = m_start_y; + --m_step; + return path_cmd_move_to; + } + + if(m_step == 0) + { + *x = m_end_x; + *y = m_end_y; + --m_step; + return path_cmd_line_to; + } + + m_fx += m_dfx; + m_fy += m_dfy; + m_dfx += m_ddfx; + m_dfy += m_ddfy; + m_ddfx += m_dddfx; + m_ddfy += m_dddfy; + + *x = m_fx; + *y = m_fy; + --m_step; + return path_cmd_line_to; + } + + + + + //------------------------------------------------------------------------ + void curve4_div::init(double x1, double y1, + double x2, double y2, + double x3, double y3, + double x4, double y4) + { + m_points.remove_all(); + m_distance_tolerance_square = 0.5 / m_approximation_scale; + m_distance_tolerance_square *= m_distance_tolerance_square; + bezier(x1, y1, x2, y2, x3, y3, x4, y4); + m_count = 0; + } + + //------------------------------------------------------------------------ + void curve4_div::recursive_bezier(double x1, double y1, + double x2, double y2, + double x3, double y3, + double x4, double y4, + unsigned level) + { + if(level > curve_recursion_limit) + { + return; + } + + // Calculate all the mid-points of the line segments + //---------------------- + double x12 = (x1 + x2) / 2; + double y12 = (y1 + y2) / 2; + double x23 = (x2 + x3) / 2; + double y23 = (y2 + y3) / 2; + double x34 = (x3 + x4) / 2; + double y34 = (y3 + y4) / 2; + double x123 = (x12 + x23) / 2; + double y123 = (y12 + y23) / 2; + double x234 = (x23 + x34) / 2; + double y234 = (y23 + y34) / 2; + double x1234 = (x123 + x234) / 2; + double y1234 = (y123 + y234) / 2; + + + // Try to approximate the full cubic curve by a single straight line + //------------------ + double dx = x4-x1; + double dy = y4-y1; + + double d2 = fabs(((x2 - x4) * dy - (y2 - y4) * dx)); + double d3 = fabs(((x3 - x4) * dy - (y3 - y4) * dx)); + double da1, da2, k; + + switch((int(d2 > curve_collinearity_epsilon) << 1) + + int(d3 > curve_collinearity_epsilon)) + { + case 0: + // All collinear OR p1==p4 + //---------------------- + k = dx*dx + dy*dy; + if(k == 0) + { + d2 = calc_sq_distance(x1, y1, x2, y2); + d3 = calc_sq_distance(x4, y4, x3, y3); + } + else + { + k = 1 / k; + da1 = x2 - x1; + da2 = y2 - y1; + d2 = k * (da1*dx + da2*dy); + da1 = x3 - x1; + da2 = y3 - y1; + d3 = k * (da1*dx + da2*dy); + if(d2 > 0 && d2 < 1 && d3 > 0 && d3 < 1) + { + // Simple collinear case, 1---2---3---4 + // We can leave just two endpoints + return; + } + if(d2 <= 0) d2 = calc_sq_distance(x2, y2, x1, y1); + else if(d2 >= 1) d2 = calc_sq_distance(x2, y2, x4, y4); + else d2 = calc_sq_distance(x2, y2, x1 + d2*dx, y1 + d2*dy); + + if(d3 <= 0) d3 = calc_sq_distance(x3, y3, x1, y1); + else if(d3 >= 1) d3 = calc_sq_distance(x3, y3, x4, y4); + else d3 = calc_sq_distance(x3, y3, x1 + d3*dx, y1 + d3*dy); + } + if(d2 > d3) + { + if(d2 < m_distance_tolerance_square) + { + m_points.add(point_d(x2, y2)); + return; + } + } + else + { + if(d3 < m_distance_tolerance_square) + { + m_points.add(point_d(x3, y3)); + return; + } + } + break; + + case 1: + // p1,p2,p4 are collinear, p3 is significant + //---------------------- + if(d3 * d3 <= m_distance_tolerance_square * (dx*dx + dy*dy)) + { + if(m_angle_tolerance < curve_angle_tolerance_epsilon) + { + m_points.add(point_d(x23, y23)); + return; + } + + // Angle Condition + //---------------------- + da1 = fabs(atan2(y4 - y3, x4 - x3) - atan2(y3 - y2, x3 - x2)); + if(da1 >= pi) da1 = 2*pi - da1; + + if(da1 < m_angle_tolerance) + { + m_points.add(point_d(x2, y2)); + m_points.add(point_d(x3, y3)); + return; + } + + if(m_cusp_limit != 0.0) + { + if(da1 > m_cusp_limit) + { + m_points.add(point_d(x3, y3)); + return; + } + } + } + break; + + case 2: + // p1,p3,p4 are collinear, p2 is significant + //---------------------- + if(d2 * d2 <= m_distance_tolerance_square * (dx*dx + dy*dy)) + { + if(m_angle_tolerance < curve_angle_tolerance_epsilon) + { + m_points.add(point_d(x23, y23)); + return; + } + + // Angle Condition + //---------------------- + da1 = fabs(atan2(y3 - y2, x3 - x2) - atan2(y2 - y1, x2 - x1)); + if(da1 >= pi) da1 = 2*pi - da1; + + if(da1 < m_angle_tolerance) + { + m_points.add(point_d(x2, y2)); + m_points.add(point_d(x3, y3)); + return; + } + + if(m_cusp_limit != 0.0) + { + if(da1 > m_cusp_limit) + { + m_points.add(point_d(x2, y2)); + return; + } + } + } + break; + + case 3: + // Regular case + //----------------- + if((d2 + d3)*(d2 + d3) <= m_distance_tolerance_square * (dx*dx + dy*dy)) + { + // If the curvature doesn't exceed the distance_tolerance value + // we tend to finish subdivisions. + //---------------------- + if(m_angle_tolerance < curve_angle_tolerance_epsilon) + { + m_points.add(point_d(x23, y23)); + return; + } + + // Angle & Cusp Condition + //---------------------- + k = atan2(y3 - y2, x3 - x2); + da1 = fabs(k - atan2(y2 - y1, x2 - x1)); + da2 = fabs(atan2(y4 - y3, x4 - x3) - k); + if(da1 >= pi) da1 = 2*pi - da1; + if(da2 >= pi) da2 = 2*pi - da2; + + if(da1 + da2 < m_angle_tolerance) + { + // Finally we can stop the recursion + //---------------------- + m_points.add(point_d(x23, y23)); + return; + } + + if(m_cusp_limit != 0.0) + { + if(da1 > m_cusp_limit) + { + m_points.add(point_d(x2, y2)); + return; + } + + if(da2 > m_cusp_limit) + { + m_points.add(point_d(x3, y3)); + return; + } + } + } + break; + } + + // Continue subdivision + //---------------------- + recursive_bezier(x1, y1, x12, y12, x123, y123, x1234, y1234, level + 1); + recursive_bezier(x1234, y1234, x234, y234, x34, y34, x4, y4, level + 1); + } + + //------------------------------------------------------------------------ + void curve4_div::bezier(double x1, double y1, + double x2, double y2, + double x3, double y3, + double x4, double y4) + { + m_points.add(point_d(x1, y1)); + recursive_bezier(x1, y1, x2, y2, x3, y3, x4, y4, 0); + m_points.add(point_d(x4, y4)); + } + +} + diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_embedded_raster_fonts.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_embedded_raster_fonts.cpp new file mode 100644 index 00000000000..ee4dc65ee44 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_embedded_raster_fonts.cpp @@ -0,0 +1,10426 @@ +//---------------------------------------------------------------------------- +// 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 +//---------------------------------------------------------------------------- + +#include "agg_embedded_raster_fonts.h" + +namespace agg +{ + + const int8u gse4x6[] = + { + 6, 0, 32, 128-32, + + 0x00,0x00,0x07,0x00,0x0e,0x00,0x15,0x00,0x1c,0x00,0x23,0x00,0x2a,0x00,0x31,0x00,0x38,0x00, + 0x3f,0x00,0x46,0x00,0x4d,0x00,0x54,0x00,0x5b,0x00,0x62,0x00,0x69,0x00,0x70,0x00,0x77,0x00, + 0x7e,0x00,0x85,0x00,0x8c,0x00,0x93,0x00,0x9a,0x00,0xa1,0x00,0xa8,0x00,0xaf,0x00,0xb6,0x00, + 0xbd,0x00,0xc4,0x00,0xcb,0x00,0xd2,0x00,0xd9,0x00,0xe0,0x00,0xe7,0x00,0xee,0x00,0xf5,0x00, + 0xfc,0x00,0x03,0x01,0x0a,0x01,0x11,0x01,0x18,0x01,0x1f,0x01,0x26,0x01,0x2d,0x01,0x34,0x01, + 0x3b,0x01,0x42,0x01,0x49,0x01,0x50,0x01,0x57,0x01,0x5e,0x01,0x65,0x01,0x6c,0x01,0x73,0x01, + 0x7a,0x01,0x81,0x01,0x88,0x01,0x8f,0x01,0x96,0x01,0x9d,0x01,0xa4,0x01,0xab,0x01,0xb2,0x01, + 0xb9,0x01,0xc0,0x01,0xc7,0x01,0xce,0x01,0xd5,0x01,0xdc,0x01,0xe3,0x01,0xea,0x01,0xf1,0x01, + 0xf8,0x01,0xff,0x01,0x06,0x02,0x0d,0x02,0x14,0x02,0x1b,0x02,0x22,0x02,0x29,0x02,0x30,0x02, + 0x37,0x02,0x3e,0x02,0x45,0x02,0x4c,0x02,0x53,0x02,0x5a,0x02,0x61,0x02,0x68,0x02,0x6f,0x02, + 0x76,0x02,0x7d,0x02,0x84,0x02,0x8b,0x02,0x92,0x02,0x99,0x02, + + 4, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x21 '!' + 0x40,0x40,0x40,0x00,0x40,0x00, + + 4, // 0x22 '"' + 0xa0,0xa0,0x00,0x00,0x00,0x00, + + 4, // 0x23 '#' + 0x60,0xf0,0x60,0xf0,0x60,0x00, + + 4, // 0x24 '$' + 0x40,0x60,0xc0,0x60,0xc0,0x40, + + 4, // 0x25 '%' + 0xa0,0x20,0x40,0x80,0xa0,0x00, + + 4, // 0x26 '&' + 0xe0,0xa0,0x50,0xa0,0xd0,0x00, + + 4, // 0x27 ''' + 0x40,0x40,0x00,0x00,0x00,0x00, + + 4, // 0x28 '(' + 0x20,0x40,0x40,0x40,0x20,0x00, + + 4, // 0x29 ')' + 0x40,0x20,0x20,0x20,0x40,0x00, + + 4, // 0x2a '*' + 0xa0,0x40,0xe0,0x40,0xa0,0x00, + + 4, // 0x2b '+' + 0x40,0x40,0xe0,0x40,0x40,0x00, + + 4, // 0x2c ',' + 0x00,0x00,0x00,0x40,0x40,0x80, + + 4, // 0x2d '-' + 0x00,0x00,0xe0,0x00,0x00,0x00, + + 4, // 0x2e '.' + 0x00,0x00,0x00,0x00,0x40,0x00, + + 4, // 0x2f '/' + 0x10,0x20,0x20,0x40,0x40,0x80, + + 4, // 0x30 '0' + 0xe0,0xa0,0xa0,0xa0,0xe0,0x00, + + 4, // 0x31 '1' + 0x40,0xc0,0x40,0x40,0xe0,0x00, + + 4, // 0x32 '2' + 0xe0,0xa0,0x20,0x40,0xe0,0x00, + + 4, // 0x33 '3' + 0xe0,0x20,0x40,0x20,0xe0,0x00, + + 4, // 0x34 '4' + 0xa0,0xa0,0xe0,0x20,0x20,0x00, + + 4, // 0x35 '5' + 0xe0,0x80,0xc0,0x20,0xc0,0x00, + + 4, // 0x36 '6' + 0x40,0x80,0xe0,0xa0,0xe0,0x00, + + 4, // 0x37 '7' + 0xe0,0xa0,0x20,0x40,0x40,0x00, + + 4, // 0x38 '8' + 0xe0,0xa0,0x40,0xa0,0xe0,0x00, + + 4, // 0x39 '9' + 0xe0,0xa0,0xe0,0x20,0xc0,0x00, + + 4, // 0x3a ':' + 0x00,0x40,0x00,0x40,0x00,0x00, + + 4, // 0x3b ';' + 0x00,0x40,0x00,0x40,0x40,0x80, + + 4, // 0x3c '<' + 0x20,0x40,0x80,0x40,0x20,0x00, + + 4, // 0x3d '=' + 0x00,0xe0,0x00,0xe0,0x00,0x00, + + 4, // 0x3e '>' + 0x80,0x40,0x20,0x40,0x80,0x00, + + 4, // 0x3f '?' + 0xc0,0x20,0x40,0x00,0x40,0x00, + + 4, // 0x40 '@' + 0x40,0xa0,0xe0,0xe0,0x80,0x60, + + 4, // 0x41 'A' + 0x40,0xa0,0xe0,0xa0,0xa0,0x00, + + 4, // 0x42 'B' + 0xc0,0xa0,0xc0,0xa0,0xc0,0x00, + + 4, // 0x43 'C' + 0x60,0x80,0x80,0x80,0x60,0x00, + + 4, // 0x44 'D' + 0xc0,0xa0,0xa0,0xa0,0xc0,0x00, + + 4, // 0x45 'E' + 0xe0,0x80,0xc0,0x80,0xe0,0x00, + + 4, // 0x46 'F' + 0xe0,0x80,0xc0,0x80,0x80,0x00, + + 4, // 0x47 'G' + 0x60,0x80,0xa0,0xa0,0x40,0x00, + + 4, // 0x48 'H' + 0xa0,0xa0,0xe0,0xa0,0xa0,0x00, + + 4, // 0x49 'I' + 0xe0,0x40,0x40,0x40,0xe0,0x00, + + 4, // 0x4a 'J' + 0x20,0x20,0x20,0x20,0xa0,0x40, + + 4, // 0x4b 'K' + 0xa0,0xa0,0xc0,0xc0,0xa0,0x00, + + 4, // 0x4c 'L' + 0x80,0x80,0x80,0x80,0xe0,0x00, + + 4, // 0x4d 'M' + 0xa0,0xe0,0xa0,0xa0,0xa0,0x00, + + 4, // 0x4e 'N' + 0x90,0xd0,0xb0,0x90,0x90,0x00, + + 4, // 0x4f 'O' + 0x40,0xa0,0xa0,0xa0,0x40,0x00, + + 4, // 0x50 'P' + 0xc0,0xa0,0xa0,0xc0,0x80,0x00, + + 4, // 0x51 'Q' + 0x40,0xa0,0xa0,0xa0,0x60,0x00, + + 4, // 0x52 'R' + 0xc0,0xa0,0xa0,0xc0,0xa0,0x00, + + 4, // 0x53 'S' + 0x60,0x80,0x40,0x20,0xc0,0x00, + + 4, // 0x54 'T' + 0xe0,0x40,0x40,0x40,0x40,0x00, + + 4, // 0x55 'U' + 0xa0,0xa0,0xa0,0xa0,0xe0,0x00, + + 4, // 0x56 'V' + 0xa0,0xa0,0xa0,0xa0,0x40,0x00, + + 4, // 0x57 'W' + 0xa0,0xa0,0xa0,0xe0,0xa0,0x00, + + 4, // 0x58 'X' + 0xa0,0xa0,0x40,0xa0,0xa0,0x00, + + 4, // 0x59 'Y' + 0xa0,0xa0,0x40,0x40,0x40,0x00, + + 4, // 0x5a 'Z' + 0xe0,0x20,0x40,0x80,0xe0,0x00, + + 4, // 0x5b '[' + 0xc0,0x80,0x80,0x80,0xc0,0x00, + + 4, // 0x5c '\' + 0x80,0x40,0x40,0x20,0x20,0x10, + + 4, // 0x5d ']' + 0xc0,0x40,0x40,0x40,0xc0,0x00, + + 4, // 0x5e '^' + 0x40,0xa0,0x00,0x00,0x00,0x00, + + 4, // 0x5f '_' + 0x00,0x00,0x00,0x00,0x00,0xf0, + + 4, // 0x60 '`' + 0x40,0x20,0x00,0x00,0x00,0x00, + + 4, // 0x61 'a' + 0x00,0x60,0xa0,0xa0,0x70,0x00, + + 4, // 0x62 'b' + 0x80,0x80,0xc0,0xa0,0xc0,0x00, + + 4, // 0x63 'c' + 0x00,0x60,0x80,0x80,0x60,0x00, + + 4, // 0x64 'd' + 0x20,0x20,0x60,0xa0,0x60,0x00, + + 4, // 0x65 'e' + 0x00,0x40,0xe0,0x80,0x60,0x00, + + 4, // 0x66 'f' + 0x20,0x40,0xe0,0x40,0x40,0x00, + + 4, // 0x67 'g' + 0x00,0x60,0xa0,0x60,0x20,0xc0, + + 4, // 0x68 'h' + 0x80,0x80,0xc0,0xa0,0xa0,0x00, + + 4, // 0x69 'i' + 0x40,0x00,0xc0,0x40,0xe0,0x00, + + 4, // 0x6a 'j' + 0x40,0x00,0xc0,0x40,0x40,0x80, + + 4, // 0x6b 'k' + 0x80,0x80,0xa0,0xc0,0xa0,0x00, + + 4, // 0x6c 'l' + 0xc0,0x40,0x40,0x40,0xe0,0x00, + + 4, // 0x6d 'm' + 0x00,0xa0,0xf0,0xf0,0x90,0x00, + + 4, // 0x6e 'n' + 0x00,0xc0,0xa0,0xa0,0xa0,0x00, + + 4, // 0x6f 'o' + 0x00,0x40,0xa0,0xa0,0x40,0x00, + + 4, // 0x70 'p' + 0x00,0xc0,0xa0,0xc0,0x80,0x80, + + 4, // 0x71 'q' + 0x00,0x60,0xa0,0x60,0x20,0x20, + + 4, // 0x72 'r' + 0x00,0xa0,0x50,0x40,0x40,0x00, + + 4, // 0x73 's' + 0x00,0x60,0xc0,0x20,0xc0,0x00, + + 4, // 0x74 't' + 0x40,0x40,0xe0,0x40,0x60,0x00, + + 4, // 0x75 'u' + 0x00,0xa0,0xa0,0xa0,0x60,0x00, + + 4, // 0x76 'v' + 0x00,0xa0,0xa0,0xa0,0x40,0x00, + + 4, // 0x77 'w' + 0x00,0xa0,0xa0,0xe0,0xa0,0x00, + + 4, // 0x78 'x' + 0x00,0xa0,0x40,0xa0,0xa0,0x00, + + 4, // 0x79 'y' + 0x00,0xa0,0xa0,0x60,0x20,0xc0, + + 4, // 0x7a 'z' + 0x00,0xe0,0x40,0x80,0xe0,0x00, + + 4, // 0x7b '{' + 0x30,0x20,0xc0,0x20,0x30,0x00, + + 4, // 0x7c '|' + 0x40,0x40,0x00,0x40,0x40,0x40, + + 4, // 0x7d '}' + 0xc0,0x40,0x30,0x40,0xc0,0x00, + + 4, // 0x7e '~' + 0x50,0xa0,0x00,0x00,0x00,0x00, + + 4, // 0x7f '' + 0x00,0x60,0x90,0xf0,0x00,0x00, + 0 + }; + + const int8u gse4x8[] = + { + 8, 0, 32, 128-32, + + 0x00,0x00,0x09,0x00,0x12,0x00,0x1b,0x00,0x24,0x00,0x2d,0x00,0x36,0x00,0x3f,0x00,0x48,0x00, + 0x51,0x00,0x5a,0x00,0x63,0x00,0x6c,0x00,0x75,0x00,0x7e,0x00,0x87,0x00,0x90,0x00,0x99,0x00, + 0xa2,0x00,0xab,0x00,0xb4,0x00,0xbd,0x00,0xc6,0x00,0xcf,0x00,0xd8,0x00,0xe1,0x00,0xea,0x00, + 0xf3,0x00,0xfc,0x00,0x05,0x01,0x0e,0x01,0x17,0x01,0x20,0x01,0x29,0x01,0x32,0x01,0x3b,0x01, + 0x44,0x01,0x4d,0x01,0x56,0x01,0x5f,0x01,0x68,0x01,0x71,0x01,0x7a,0x01,0x83,0x01,0x8c,0x01, + 0x95,0x01,0x9e,0x01,0xa7,0x01,0xb0,0x01,0xb9,0x01,0xc2,0x01,0xcb,0x01,0xd4,0x01,0xdd,0x01, + 0xe6,0x01,0xef,0x01,0xf8,0x01,0x01,0x02,0x0a,0x02,0x13,0x02,0x1c,0x02,0x25,0x02,0x2e,0x02, + 0x37,0x02,0x40,0x02,0x49,0x02,0x52,0x02,0x5b,0x02,0x64,0x02,0x6d,0x02,0x76,0x02,0x7f,0x02, + 0x88,0x02,0x91,0x02,0x9a,0x02,0xa3,0x02,0xac,0x02,0xb5,0x02,0xbe,0x02,0xc7,0x02,0xd0,0x02, + 0xd9,0x02,0xe2,0x02,0xeb,0x02,0xf4,0x02,0xfd,0x02,0x06,0x03,0x0f,0x03,0x18,0x03,0x21,0x03, + 0x2a,0x03,0x33,0x03,0x3c,0x03,0x45,0x03,0x4e,0x03,0x57,0x03, + + 4, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x21 '!' + 0x00,0x40,0x40,0x40,0x40,0x00,0x40,0x00, + + 4, // 0x22 '"' + 0x00,0xa0,0xa0,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x23 '#' + 0x60,0x60,0xf0,0x60,0x60,0xf0,0x60,0x60, + + 4, // 0x24 '$' + 0x40,0x60,0xc0,0xc0,0x60,0x60,0xc0,0x40, + + 4, // 0x25 '%' + 0x00,0xa0,0x20,0x40,0x40,0x80,0xa0,0x00, + + 4, // 0x26 '&' + 0x00,0x40,0xa0,0xa0,0x40,0xb0,0xa0,0x70, + + 4, // 0x27 ''' + 0x00,0x40,0x40,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x28 '(' + 0x20,0x40,0x80,0x80,0x80,0x80,0x40,0x20, + + 4, // 0x29 ')' + 0x80,0x40,0x20,0x20,0x20,0x20,0x40,0x80, + + 4, // 0x2a '*' + 0x00,0xa0,0x40,0xe0,0x40,0xa0,0x00,0x00, + + 4, // 0x2b '+' + 0x00,0x40,0x40,0xe0,0x40,0x40,0x00,0x00, + + 4, // 0x2c ',' + 0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x80, + + 4, // 0x2d '-' + 0x00,0x00,0x00,0xe0,0x00,0x00,0x00,0x00, + + 4, // 0x2e '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00, + + 4, // 0x2f '/' + 0x10,0x10,0x20,0x20,0x40,0x40,0x80,0x80, + + 4, // 0x30 '0' + 0x00,0xe0,0xa0,0xa0,0xa0,0xa0,0xe0,0x00, + + 4, // 0x31 '1' + 0x00,0x40,0xc0,0x40,0x40,0x40,0xe0,0x00, + + 4, // 0x32 '2' + 0x00,0xe0,0xa0,0x20,0x40,0x80,0xe0,0x00, + + 4, // 0x33 '3' + 0x00,0xe0,0x20,0x40,0x20,0x20,0xe0,0x00, + + 4, // 0x34 '4' + 0x00,0x60,0xa0,0xa0,0xf0,0x20,0x20,0x00, + + 4, // 0x35 '5' + 0x00,0xe0,0x80,0xc0,0x20,0x20,0xc0,0x00, + + 4, // 0x36 '6' + 0x00,0x40,0x80,0xe0,0xa0,0xa0,0xe0,0x00, + + 4, // 0x37 '7' + 0x00,0xe0,0xa0,0x20,0x40,0x40,0x40,0x00, + + 4, // 0x38 '8' + 0x00,0xe0,0xa0,0x40,0xa0,0xa0,0xe0,0x00, + + 4, // 0x39 '9' + 0x00,0xe0,0xa0,0xe0,0x20,0x20,0x40,0x00, + + 4, // 0x3a ':' + 0x00,0x00,0x40,0x00,0x00,0x40,0x00,0x00, + + 4, // 0x3b ';' + 0x00,0x00,0x40,0x00,0x00,0x40,0x40,0x80, + + 4, // 0x3c '<' + 0x00,0x20,0x40,0x80,0x40,0x20,0x00,0x00, + + 4, // 0x3d '=' + 0x00,0x00,0xe0,0x00,0xe0,0x00,0x00,0x00, + + 4, // 0x3e '>' + 0x00,0x80,0x40,0x20,0x40,0x80,0x00,0x00, + + 4, // 0x3f '?' + 0x00,0x40,0xa0,0x20,0x40,0x00,0x40,0x00, + + 4, // 0x40 '@' + 0x00,0x40,0xa0,0xe0,0xe0,0x80,0x60,0x00, + + 4, // 0x41 'A' + 0x00,0x40,0xa0,0xa0,0xe0,0xa0,0xa0,0x00, + + 4, // 0x42 'B' + 0x00,0xc0,0xa0,0xc0,0xa0,0xa0,0xc0,0x00, + + 4, // 0x43 'C' + 0x00,0x40,0xa0,0x80,0x80,0xa0,0x40,0x00, + + 4, // 0x44 'D' + 0x00,0xc0,0xa0,0xa0,0xa0,0xa0,0xc0,0x00, + + 4, // 0x45 'E' + 0x00,0xe0,0x80,0xc0,0x80,0x80,0xe0,0x00, + + 4, // 0x46 'F' + 0x00,0xe0,0x80,0xc0,0x80,0x80,0x80,0x00, + + 4, // 0x47 'G' + 0x00,0x60,0x80,0xa0,0xa0,0xa0,0x40,0x00, + + 4, // 0x48 'H' + 0x00,0xa0,0xa0,0xe0,0xa0,0xa0,0xa0,0x00, + + 4, // 0x49 'I' + 0x00,0xe0,0x40,0x40,0x40,0x40,0xe0,0x00, + + 4, // 0x4a 'J' + 0x00,0x20,0x20,0x20,0x20,0xa0,0x40,0x00, + + 4, // 0x4b 'K' + 0x00,0xa0,0xa0,0xc0,0xc0,0xa0,0xa0,0x00, + + 4, // 0x4c 'L' + 0x00,0x80,0x80,0x80,0x80,0x80,0xe0,0x00, + + 4, // 0x4d 'M' + 0x00,0xa0,0xe0,0xa0,0xa0,0xa0,0xa0,0x00, + + 4, // 0x4e 'N' + 0x00,0x90,0x90,0xd0,0xb0,0x90,0x90,0x00, + + 4, // 0x4f 'O' + 0x00,0x40,0xa0,0xa0,0xa0,0xa0,0x40,0x00, + + 4, // 0x50 'P' + 0x00,0xc0,0xa0,0xa0,0xc0,0x80,0x80,0x00, + + 4, // 0x51 'Q' + 0x00,0x40,0xa0,0xa0,0xa0,0xa0,0x60,0x00, + + 4, // 0x52 'R' + 0x00,0xc0,0xa0,0xa0,0xc0,0xc0,0xa0,0x00, + + 4, // 0x53 'S' + 0x00,0x60,0x80,0x40,0x20,0x20,0xc0,0x00, + + 4, // 0x54 'T' + 0x00,0xe0,0x40,0x40,0x40,0x40,0x40,0x00, + + 4, // 0x55 'U' + 0x00,0xa0,0xa0,0xa0,0xa0,0xa0,0x40,0x00, + + 4, // 0x56 'V' + 0x00,0xa0,0xa0,0xa0,0xa0,0x40,0x40,0x00, + + 4, // 0x57 'W' + 0x00,0xa0,0xa0,0xa0,0xa0,0xe0,0xa0,0x00, + + 4, // 0x58 'X' + 0x00,0xa0,0xa0,0x40,0xa0,0xa0,0xa0,0x00, + + 4, // 0x59 'Y' + 0x00,0xa0,0xa0,0x40,0x40,0x40,0x40,0x00, + + 4, // 0x5a 'Z' + 0x00,0xe0,0x20,0x40,0x40,0x80,0xe0,0x00, + + 4, // 0x5b '[' + 0xc0,0x80,0x80,0x80,0x80,0x80,0x80,0xc0, + + 4, // 0x5c '\' + 0x80,0x80,0x40,0x40,0x20,0x20,0x10,0x10, + + 4, // 0x5d ']' + 0xc0,0x40,0x40,0x40,0x40,0x40,0x40,0xc0, + + 4, // 0x5e '^' + 0x00,0x40,0xa0,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x5f '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf0, + + 4, // 0x60 '`' + 0x00,0x40,0x20,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x61 'a' + 0x00,0x00,0x60,0xa0,0xa0,0xa0,0x70,0x00, + + 4, // 0x62 'b' + 0x00,0x80,0x80,0xc0,0xa0,0xa0,0xc0,0x00, + + 4, // 0x63 'c' + 0x00,0x00,0x40,0xa0,0x80,0xa0,0x40,0x00, + + 4, // 0x64 'd' + 0x00,0x20,0x20,0x60,0xa0,0xa0,0x60,0x00, + + 4, // 0x65 'e' + 0x00,0x00,0x40,0xa0,0xe0,0x80,0x60,0x00, + + 4, // 0x66 'f' + 0x00,0x20,0x40,0x40,0xe0,0x40,0x40,0x00, + + 4, // 0x67 'g' + 0x00,0x00,0x60,0xa0,0xa0,0x60,0x20,0xc0, + + 4, // 0x68 'h' + 0x00,0x80,0x80,0xc0,0xa0,0xa0,0xa0,0x00, + + 4, // 0x69 'i' + 0x00,0x40,0x00,0xc0,0x40,0x40,0xe0,0x00, + + 4, // 0x6a 'j' + 0x00,0x40,0x00,0xc0,0x40,0x40,0x40,0x80, + + 4, // 0x6b 'k' + 0x00,0x80,0x80,0xa0,0xc0,0xc0,0xa0,0x00, + + 4, // 0x6c 'l' + 0x00,0xc0,0x40,0x40,0x40,0x40,0xe0,0x00, + + 4, // 0x6d 'm' + 0x00,0x00,0xa0,0xf0,0xf0,0xf0,0x90,0x00, + + 4, // 0x6e 'n' + 0x00,0x00,0xc0,0xa0,0xa0,0xa0,0xa0,0x00, + + 4, // 0x6f 'o' + 0x00,0x00,0x40,0xa0,0xa0,0xa0,0x40,0x00, + + 4, // 0x70 'p' + 0x00,0x00,0xc0,0xa0,0xa0,0xc0,0x80,0x80, + + 4, // 0x71 'q' + 0x00,0x00,0x60,0xa0,0xa0,0x60,0x20,0x20, + + 4, // 0x72 'r' + 0x00,0x00,0xa0,0x50,0x40,0x40,0x40,0x00, + + 4, // 0x73 's' + 0x00,0x00,0x60,0x80,0x40,0x20,0xc0,0x00, + + 4, // 0x74 't' + 0x00,0x40,0x40,0xe0,0x40,0x40,0x20,0x00, + + 4, // 0x75 'u' + 0x00,0x00,0xa0,0xa0,0xa0,0xa0,0x60,0x00, + + 4, // 0x76 'v' + 0x00,0x00,0xa0,0xa0,0xa0,0x40,0x40,0x00, + + 4, // 0x77 'w' + 0x00,0x00,0xa0,0xa0,0xa0,0xe0,0xa0,0x00, + + 4, // 0x78 'x' + 0x00,0x00,0xa0,0xa0,0x40,0xa0,0xa0,0x00, + + 4, // 0x79 'y' + 0x00,0x00,0xa0,0xa0,0xa0,0x60,0x20,0xc0, + + 4, // 0x7a 'z' + 0x00,0x00,0xe0,0x20,0x40,0x80,0xe0,0x00, + + 4, // 0x7b '{' + 0x10,0x20,0x20,0xc0,0x20,0x20,0x10,0x00, + + 4, // 0x7c '|' + 0x00,0x40,0x40,0x40,0x00,0x40,0x40,0x40, + + 4, // 0x7d '}' + 0x80,0x40,0x40,0x30,0x40,0x40,0x80,0x00, + + 4, // 0x7e '~' + 0x00,0x50,0xa0,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x7f '' + 0x00,0x00,0x00,0x60,0x90,0xf0,0x00,0x00, + 0 + }; + + const int8u gse5x7[] = + { + 7, 0, 32, 128-32, + + 0x00,0x00,0x08,0x00,0x10,0x00,0x18,0x00,0x20,0x00,0x28,0x00,0x30,0x00,0x38,0x00,0x40,0x00, + 0x48,0x00,0x50,0x00,0x58,0x00,0x60,0x00,0x68,0x00,0x70,0x00,0x78,0x00,0x80,0x00,0x88,0x00, + 0x90,0x00,0x98,0x00,0xa0,0x00,0xa8,0x00,0xb0,0x00,0xb8,0x00,0xc0,0x00,0xc8,0x00,0xd0,0x00, + 0xd8,0x00,0xe0,0x00,0xe8,0x00,0xf0,0x00,0xf8,0x00,0x00,0x01,0x08,0x01,0x10,0x01,0x18,0x01, + 0x20,0x01,0x28,0x01,0x30,0x01,0x38,0x01,0x40,0x01,0x48,0x01,0x50,0x01,0x58,0x01,0x60,0x01, + 0x68,0x01,0x70,0x01,0x78,0x01,0x80,0x01,0x88,0x01,0x90,0x01,0x98,0x01,0xa0,0x01,0xa8,0x01, + 0xb0,0x01,0xb8,0x01,0xc0,0x01,0xc8,0x01,0xd0,0x01,0xd8,0x01,0xe0,0x01,0xe8,0x01,0xf0,0x01, + 0xf8,0x01,0x00,0x02,0x08,0x02,0x10,0x02,0x18,0x02,0x20,0x02,0x28,0x02,0x30,0x02,0x38,0x02, + 0x40,0x02,0x48,0x02,0x50,0x02,0x58,0x02,0x60,0x02,0x68,0x02,0x70,0x02,0x78,0x02,0x80,0x02, + 0x88,0x02,0x90,0x02,0x98,0x02,0xa0,0x02,0xa8,0x02,0xb0,0x02,0xb8,0x02,0xc0,0x02,0xc8,0x02, + 0xd0,0x02,0xd8,0x02,0xe0,0x02,0xe8,0x02,0xf0,0x02,0xf8,0x02, + + 5, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x21 '!' + 0x00,0x20,0x20,0x20,0x00,0x20,0x00, + + 5, // 0x22 '"' + 0x00,0x50,0x50,0x00,0x00,0x00,0x00, + + 5, // 0x23 '#' + 0x00,0x50,0xf8,0x50,0xf8,0x50,0x00, + + 5, // 0x24 '$' + 0x20,0x78,0xa0,0x70,0x28,0xf0,0x20, + + 5, // 0x25 '%' + 0x00,0x88,0x10,0x20,0x40,0x88,0x00, + + 5, // 0x26 '&' + 0x00,0x40,0xa0,0x68,0x90,0x68,0x00, + + 5, // 0x27 ''' + 0x00,0x20,0x20,0x00,0x00,0x00,0x00, + + 5, // 0x28 '(' + 0x10,0x20,0x40,0x40,0x40,0x20,0x10, + + 5, // 0x29 ')' + 0x80,0x40,0x20,0x20,0x20,0x40,0x80, + + 5, // 0x2a '*' + 0x00,0x20,0xa8,0x70,0xa8,0x20,0x00, + + 5, // 0x2b '+' + 0x00,0x20,0x20,0xf8,0x20,0x20,0x00, + + 5, // 0x2c ',' + 0x00,0x00,0x00,0x00,0x20,0x20,0x40, + + 5, // 0x2d '-' + 0x00,0x00,0x00,0xf0,0x00,0x00,0x00, + + 5, // 0x2e '.' + 0x00,0x00,0x00,0x00,0x00,0x40,0x00, + + 5, // 0x2f '/' + 0x00,0x08,0x10,0x20,0x40,0x80,0x00, + + 5, // 0x30 '0' + 0x00,0x60,0x90,0x90,0x90,0x60,0x00, + + 5, // 0x31 '1' + 0x00,0x20,0x60,0x20,0x20,0x70,0x00, + + 5, // 0x32 '2' + 0x00,0x60,0x90,0x20,0x40,0xf0,0x00, + + 5, // 0x33 '3' + 0x00,0xf0,0x20,0x60,0x10,0xe0,0x00, + + 5, // 0x34 '4' + 0x00,0x30,0x50,0x90,0xf0,0x10,0x00, + + 5, // 0x35 '5' + 0x00,0xf0,0x80,0xe0,0x10,0xe0,0x00, + + 5, // 0x36 '6' + 0x00,0x60,0x80,0xe0,0x90,0x60,0x00, + + 5, // 0x37 '7' + 0x00,0xf0,0x90,0x20,0x40,0x40,0x00, + + 5, // 0x38 '8' + 0x00,0x60,0x90,0x60,0x90,0x60,0x00, + + 5, // 0x39 '9' + 0x00,0x60,0x90,0x70,0x10,0x60,0x00, + + 5, // 0x3a ':' + 0x00,0x00,0x20,0x00,0x20,0x00,0x00, + + 5, // 0x3b ';' + 0x00,0x00,0x20,0x00,0x20,0x20,0x40, + + 5, // 0x3c '<' + 0x00,0x10,0x20,0x40,0x20,0x10,0x00, + + 5, // 0x3d '=' + 0x00,0x00,0xf0,0x00,0xf0,0x00,0x00, + + 5, // 0x3e '>' + 0x00,0x80,0x40,0x20,0x40,0x80,0x00, + + 5, // 0x3f '?' + 0x00,0x60,0x90,0x20,0x00,0x20,0x00, + + 5, // 0x40 '@' + 0x00,0x60,0x90,0xb0,0x80,0x70,0x00, + + 5, // 0x41 'A' + 0x00,0x60,0x90,0xf0,0x90,0x90,0x00, + + 5, // 0x42 'B' + 0x00,0xe0,0x90,0xe0,0x90,0xe0,0x00, + + 5, // 0x43 'C' + 0x00,0x60,0x90,0x80,0x90,0x60,0x00, + + 5, // 0x44 'D' + 0x00,0xe0,0x90,0x90,0x90,0xe0,0x00, + + 5, // 0x45 'E' + 0x00,0xf0,0x80,0xe0,0x80,0xf0,0x00, + + 5, // 0x46 'F' + 0x00,0xf0,0x80,0xe0,0x80,0x80,0x00, + + 5, // 0x47 'G' + 0x00,0x70,0x80,0xb0,0x90,0x60,0x00, + + 5, // 0x48 'H' + 0x00,0x90,0x90,0xf0,0x90,0x90,0x00, + + 5, // 0x49 'I' + 0x00,0x70,0x20,0x20,0x20,0x70,0x00, + + 5, // 0x4a 'J' + 0x00,0x70,0x20,0x20,0xa0,0x40,0x00, + + 5, // 0x4b 'K' + 0x00,0x90,0xa0,0xc0,0xa0,0x90,0x00, + + 5, // 0x4c 'L' + 0x00,0x80,0x80,0x80,0x80,0xf0,0x00, + + 5, // 0x4d 'M' + 0x00,0x90,0xf0,0x90,0x90,0x90,0x00, + + 5, // 0x4e 'N' + 0x00,0x90,0xd0,0xb0,0x90,0x90,0x00, + + 5, // 0x4f 'O' + 0x00,0x60,0x90,0x90,0x90,0x60,0x00, + + 5, // 0x50 'P' + 0x00,0xe0,0x90,0xe0,0x80,0x80,0x00, + + 5, // 0x51 'Q' + 0x00,0x60,0x90,0x90,0xa0,0x50,0x00, + + 5, // 0x52 'R' + 0x00,0xe0,0x90,0xe0,0xa0,0x90,0x00, + + 5, // 0x53 'S' + 0x00,0x70,0x80,0x60,0x10,0xe0,0x00, + + 5, // 0x54 'T' + 0x00,0x70,0x20,0x20,0x20,0x20,0x00, + + 5, // 0x55 'U' + 0x00,0x90,0x90,0x90,0x90,0x60,0x00, + + 5, // 0x56 'V' + 0x00,0x50,0x50,0x50,0x20,0x20,0x00, + + 5, // 0x57 'W' + 0x00,0x90,0x90,0x90,0xf0,0x90,0x00, + + 5, // 0x58 'X' + 0x00,0x90,0x90,0x60,0x90,0x90,0x00, + + 5, // 0x59 'Y' + 0x00,0x50,0x50,0x20,0x20,0x20,0x00, + + 5, // 0x5a 'Z' + 0x00,0xf0,0x10,0x20,0x40,0xf0,0x00, + + 5, // 0x5b '[' + 0x70,0x40,0x40,0x40,0x40,0x40,0x70, + + 5, // 0x5c '\' + 0x00,0x80,0x40,0x20,0x10,0x08,0x00, + + 5, // 0x5d ']' + 0xe0,0x20,0x20,0x20,0x20,0x20,0xe0, + + 5, // 0x5e '^' + 0x00,0x20,0x50,0x00,0x00,0x00,0x00, + + 5, // 0x5f '_' + 0x00,0x00,0x00,0x00,0x00,0xf8,0x00, + + 5, // 0x60 '`' + 0x00,0x40,0x20,0x00,0x00,0x00,0x00, + + 5, // 0x61 'a' + 0x00,0x00,0x60,0xa0,0xa0,0x50,0x00, + + 5, // 0x62 'b' + 0x00,0x80,0x80,0xe0,0x90,0xe0,0x00, + + 5, // 0x63 'c' + 0x00,0x00,0x70,0x80,0x80,0x70,0x00, + + 5, // 0x64 'd' + 0x00,0x10,0x10,0x70,0x90,0x70,0x00, + + 5, // 0x65 'e' + 0x00,0x00,0x60,0xf0,0x80,0x70,0x00, + + 5, // 0x66 'f' + 0x00,0x30,0x40,0xe0,0x40,0x40,0x00, + + 5, // 0x67 'g' + 0x00,0x00,0x70,0x90,0x70,0x10,0x60, + + 5, // 0x68 'h' + 0x00,0x80,0x80,0xe0,0x90,0x90,0x00, + + 5, // 0x69 'i' + 0x20,0x00,0x60,0x20,0x20,0x70,0x00, + + 5, // 0x6a 'j' + 0x20,0x00,0x60,0x20,0x20,0xa0,0x40, + + 5, // 0x6b 'k' + 0x80,0x80,0x90,0xa0,0xe0,0x90,0x00, + + 5, // 0x6c 'l' + 0x00,0x60,0x20,0x20,0x20,0x70,0x00, + + 5, // 0x6d 'm' + 0x00,0x00,0xa0,0xf0,0xf0,0x90,0x00, + + 5, // 0x6e 'n' + 0x00,0x00,0xa0,0xd0,0x90,0x90,0x00, + + 5, // 0x6f 'o' + 0x00,0x00,0x60,0x90,0x90,0x60,0x00, + + 5, // 0x70 'p' + 0x00,0x00,0xe0,0x90,0xe0,0x80,0x80, + + 5, // 0x71 'q' + 0x00,0x00,0x70,0x90,0x70,0x10,0x10, + + 5, // 0x72 'r' + 0x00,0x00,0xe0,0x90,0x80,0x80,0x00, + + 5, // 0x73 's' + 0x00,0x00,0x70,0xe0,0x10,0xe0,0x00, + + 5, // 0x74 't' + 0x40,0x40,0xe0,0x40,0x40,0x70,0x00, + + 5, // 0x75 'u' + 0x00,0x00,0x90,0x90,0x90,0x70,0x00, + + 5, // 0x76 'v' + 0x00,0x00,0x50,0x50,0x50,0x20,0x00, + + 5, // 0x77 'w' + 0x00,0x00,0x90,0x90,0xf0,0x90,0x00, + + 5, // 0x78 'x' + 0x00,0x00,0x90,0x60,0x60,0x90,0x00, + + 5, // 0x79 'y' + 0x00,0x00,0x90,0x90,0x70,0x10,0x60, + + 5, // 0x7a 'z' + 0x00,0x00,0xf0,0x20,0x40,0xf0,0x00, + + 5, // 0x7b '{' + 0x10,0x20,0x20,0xc0,0x20,0x20,0x10, + + 5, // 0x7c '|' + 0x20,0x20,0x20,0x00,0x20,0x20,0x20, + + 5, // 0x7d '}' + 0x40,0x20,0x20,0x18,0x20,0x20,0x40, + + 5, // 0x7e '~' + 0x00,0x40,0xa8,0x10,0x00,0x00,0x00, + + 5, // 0x7f '' + 0x00,0x00,0x20,0x50,0x88,0xf8,0x00, + 0 + }; + + const int8u gse5x9[] = + { + 9, 0, 32, 128-32, + + 0x00,0x00,0x0a,0x00,0x14,0x00,0x1e,0x00,0x28,0x00,0x32,0x00,0x3c,0x00,0x46,0x00,0x50,0x00, + 0x5a,0x00,0x64,0x00,0x6e,0x00,0x78,0x00,0x82,0x00,0x8c,0x00,0x96,0x00,0xa0,0x00,0xaa,0x00, + 0xb4,0x00,0xbe,0x00,0xc8,0x00,0xd2,0x00,0xdc,0x00,0xe6,0x00,0xf0,0x00,0xfa,0x00,0x04,0x01, + 0x0e,0x01,0x18,0x01,0x22,0x01,0x2c,0x01,0x36,0x01,0x40,0x01,0x4a,0x01,0x54,0x01,0x5e,0x01, + 0x68,0x01,0x72,0x01,0x7c,0x01,0x86,0x01,0x90,0x01,0x9a,0x01,0xa4,0x01,0xae,0x01,0xb8,0x01, + 0xc2,0x01,0xcc,0x01,0xd6,0x01,0xe0,0x01,0xea,0x01,0xf4,0x01,0xfe,0x01,0x08,0x02,0x12,0x02, + 0x1c,0x02,0x26,0x02,0x30,0x02,0x3a,0x02,0x44,0x02,0x4e,0x02,0x58,0x02,0x62,0x02,0x6c,0x02, + 0x76,0x02,0x80,0x02,0x8a,0x02,0x94,0x02,0x9e,0x02,0xa8,0x02,0xb2,0x02,0xbc,0x02,0xc6,0x02, + 0xd0,0x02,0xda,0x02,0xe4,0x02,0xee,0x02,0xf8,0x02,0x02,0x03,0x0c,0x03,0x16,0x03,0x20,0x03, + 0x2a,0x03,0x34,0x03,0x3e,0x03,0x48,0x03,0x52,0x03,0x5c,0x03,0x66,0x03,0x70,0x03,0x7a,0x03, + 0x84,0x03,0x8e,0x03,0x98,0x03,0xa2,0x03,0xac,0x03,0xb6,0x03, + + 5, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x21 '!' + 0x00,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00, + + 5, // 0x22 '"' + 0x00,0x50,0x50,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x23 '#' + 0x00,0x50,0x50,0xf8,0x50,0xf8,0x50,0x50,0x00, + + 5, // 0x24 '$' + 0x00,0x20,0x78,0xa0,0x70,0x28,0xf0,0x20,0x00, + + 5, // 0x25 '%' + 0x00,0xc8,0xc8,0x10,0x20,0x40,0x98,0x98,0x00, + + 5, // 0x26 '&' + 0x00,0x40,0xa0,0xa0,0x40,0xa8,0x90,0x68,0x00, + + 5, // 0x27 ''' + 0x00,0x20,0x20,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x28 '(' + 0x10,0x20,0x40,0x40,0x40,0x40,0x40,0x20,0x10, + + 5, // 0x29 ')' + 0x80,0x40,0x20,0x20,0x20,0x20,0x20,0x40,0x80, + + 5, // 0x2a '*' + 0x00,0x00,0x20,0xa8,0x70,0xa8,0x20,0x00,0x00, + + 5, // 0x2b '+' + 0x00,0x00,0x20,0x20,0xf8,0x20,0x20,0x00,0x00, + + 5, // 0x2c ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x40, + + 5, // 0x2d '-' + 0x00,0x00,0x00,0x00,0xf0,0x00,0x00,0x00,0x00, + + 5, // 0x2e '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00, + + 5, // 0x2f '/' + 0x00,0x10,0x10,0x20,0x20,0x40,0x40,0x80,0x80, + + 5, // 0x30 '0' + 0x00,0x60,0x90,0xb0,0xd0,0x90,0x90,0x60,0x00, + + 5, // 0x31 '1' + 0x00,0x20,0x60,0x20,0x20,0x20,0x20,0x70,0x00, + + 5, // 0x32 '2' + 0x00,0x60,0x90,0x10,0x20,0x40,0x80,0xf0,0x00, + + 5, // 0x33 '3' + 0x00,0xf0,0x10,0x20,0x60,0x10,0x90,0x60,0x00, + + 5, // 0x34 '4' + 0x00,0x30,0x50,0x90,0x90,0xf8,0x10,0x10,0x00, + + 5, // 0x35 '5' + 0x00,0xf0,0x80,0xe0,0x10,0x10,0x10,0xe0,0x00, + + 5, // 0x36 '6' + 0x00,0x60,0x80,0xe0,0x90,0x90,0x90,0x60,0x00, + + 5, // 0x37 '7' + 0x00,0xf0,0x90,0x10,0x20,0x40,0x40,0x40,0x00, + + 5, // 0x38 '8' + 0x00,0x60,0x90,0x90,0x60,0x90,0x90,0x60,0x00, + + 5, // 0x39 '9' + 0x00,0x60,0x90,0x90,0x70,0x10,0x90,0x60,0x00, + + 5, // 0x3a ':' + 0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x00,0x00, + + 5, // 0x3b ';' + 0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x20,0x40, + + 5, // 0x3c '<' + 0x00,0x10,0x20,0x40,0x80,0x40,0x20,0x10,0x00, + + 5, // 0x3d '=' + 0x00,0x00,0x00,0xf0,0x00,0xf0,0x00,0x00,0x00, + + 5, // 0x3e '>' + 0x00,0x80,0x40,0x20,0x10,0x20,0x40,0x80,0x00, + + 5, // 0x3f '?' + 0x00,0x60,0x90,0x10,0x20,0x20,0x00,0x20,0x00, + + 5, // 0x40 '@' + 0x00,0x60,0x90,0xb0,0xb0,0xb0,0x80,0x70,0x00, + + 5, // 0x41 'A' + 0x00,0x60,0x90,0x90,0xf0,0x90,0x90,0x90,0x00, + + 5, // 0x42 'B' + 0x00,0xe0,0x90,0x90,0xe0,0x90,0x90,0xe0,0x00, + + 5, // 0x43 'C' + 0x00,0x60,0x90,0x80,0x80,0x80,0x90,0x60,0x00, + + 5, // 0x44 'D' + 0x00,0xe0,0x90,0x90,0x90,0x90,0x90,0xe0,0x00, + + 5, // 0x45 'E' + 0x00,0xf0,0x80,0x80,0xe0,0x80,0x80,0xf0,0x00, + + 5, // 0x46 'F' + 0x00,0xf0,0x80,0x80,0xe0,0x80,0x80,0x80,0x00, + + 5, // 0x47 'G' + 0x00,0x60,0x90,0x80,0xb0,0x90,0x90,0x60,0x00, + + 5, // 0x48 'H' + 0x00,0x90,0x90,0x90,0xf0,0x90,0x90,0x90,0x00, + + 5, // 0x49 'I' + 0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x70,0x00, + + 5, // 0x4a 'J' + 0x00,0x70,0x20,0x20,0x20,0x20,0xa0,0x40,0x00, + + 5, // 0x4b 'K' + 0x00,0x90,0x90,0xa0,0xc0,0xa0,0x90,0x90,0x00, + + 5, // 0x4c 'L' + 0x00,0x80,0x80,0x80,0x80,0x80,0x80,0xf0,0x00, + + 5, // 0x4d 'M' + 0x00,0x90,0xf0,0x90,0x90,0x90,0x90,0x90,0x00, + + 5, // 0x4e 'N' + 0x00,0x90,0x90,0xd0,0xb0,0x90,0x90,0x90,0x00, + + 5, // 0x4f 'O' + 0x00,0x60,0x90,0x90,0x90,0x90,0x90,0x60,0x00, + + 5, // 0x50 'P' + 0x00,0xe0,0x90,0x90,0xe0,0x80,0x80,0x80,0x00, + + 5, // 0x51 'Q' + 0x00,0x60,0x90,0x90,0x90,0x90,0xa0,0x50,0x00, + + 5, // 0x52 'R' + 0x00,0xe0,0x90,0x90,0xe0,0xa0,0x90,0x90,0x00, + + 5, // 0x53 'S' + 0x00,0x60,0x90,0x80,0x60,0x10,0x90,0x60,0x00, + + 5, // 0x54 'T' + 0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x00, + + 5, // 0x55 'U' + 0x00,0x90,0x90,0x90,0x90,0x90,0x90,0x60,0x00, + + 5, // 0x56 'V' + 0x00,0x50,0x50,0x50,0x50,0x50,0x20,0x20,0x00, + + 5, // 0x57 'W' + 0x00,0x90,0x90,0x90,0x90,0x90,0xf0,0x90,0x00, + + 5, // 0x58 'X' + 0x00,0x90,0x90,0x60,0x60,0x90,0x90,0x90,0x00, + + 5, // 0x59 'Y' + 0x00,0x50,0x50,0x50,0x20,0x20,0x20,0x20,0x00, + + 5, // 0x5a 'Z' + 0x00,0xf0,0x10,0x10,0x20,0x40,0x80,0xf0,0x00, + + 5, // 0x5b '[' + 0x70,0x40,0x40,0x40,0x40,0x40,0x40,0x70,0x00, + + 5, // 0x5c '\' + 0x80,0x80,0x40,0x40,0x20,0x20,0x10,0x10,0x00, + + 5, // 0x5d ']' + 0xe0,0x20,0x20,0x20,0x20,0x20,0x20,0xe0,0x00, + + 5, // 0x5e '^' + 0x00,0x20,0x50,0x88,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x5f '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x00, + + 5, // 0x60 '`' + 0x00,0x40,0x20,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x61 'a' + 0x00,0x00,0x60,0x10,0x70,0x90,0x90,0x70,0x00, + + 5, // 0x62 'b' + 0x00,0x80,0x80,0xe0,0x90,0x90,0x90,0xe0,0x00, + + 5, // 0x63 'c' + 0x00,0x00,0x60,0x90,0x80,0x80,0x90,0x60,0x00, + + 5, // 0x64 'd' + 0x00,0x10,0x10,0x70,0x90,0x90,0x90,0x70,0x00, + + 5, // 0x65 'e' + 0x00,0x00,0x60,0x90,0xf0,0x80,0x80,0x70,0x00, + + 5, // 0x66 'f' + 0x00,0x30,0x40,0x40,0xe0,0x40,0x40,0x40,0x00, + + 5, // 0x67 'g' + 0x00,0x00,0x70,0x90,0x90,0x70,0x10,0x90,0x60, + + 5, // 0x68 'h' + 0x00,0x80,0x80,0xe0,0x90,0x90,0x90,0x90,0x00, + + 5, // 0x69 'i' + 0x00,0x20,0x00,0x60,0x20,0x20,0x20,0x70,0x00, + + 5, // 0x6a 'j' + 0x00,0x20,0x00,0x60,0x20,0x20,0x20,0xa0,0x40, + + 5, // 0x6b 'k' + 0x00,0x80,0x80,0x90,0xa0,0xc0,0xa0,0x90,0x00, + + 5, // 0x6c 'l' + 0x00,0x60,0x20,0x20,0x20,0x20,0x20,0x70,0x00, + + 5, // 0x6d 'm' + 0x00,0x00,0xa0,0xf0,0xf0,0xf0,0x90,0x90,0x00, + + 5, // 0x6e 'n' + 0x00,0x00,0xa0,0xd0,0x90,0x90,0x90,0x90,0x00, + + 5, // 0x6f 'o' + 0x00,0x00,0x60,0x90,0x90,0x90,0x90,0x60,0x00, + + 5, // 0x70 'p' + 0x00,0x00,0xe0,0x90,0x90,0x90,0xe0,0x80,0x80, + + 5, // 0x71 'q' + 0x00,0x00,0x70,0x90,0x90,0x90,0x70,0x10,0x10, + + 5, // 0x72 'r' + 0x00,0x00,0xe0,0x90,0x80,0x80,0x80,0x80,0x00, + + 5, // 0x73 's' + 0x00,0x00,0x60,0x90,0x40,0x20,0x90,0x60,0x00, + + 5, // 0x74 't' + 0x00,0x40,0x40,0xe0,0x40,0x40,0x50,0x20,0x00, + + 5, // 0x75 'u' + 0x00,0x00,0x90,0x90,0x90,0x90,0x90,0x70,0x00, + + 5, // 0x76 'v' + 0x00,0x00,0x50,0x50,0x50,0x50,0x20,0x20,0x00, + + 5, // 0x77 'w' + 0x00,0x00,0x90,0x90,0x90,0x90,0xf0,0x90,0x00, + + 5, // 0x78 'x' + 0x00,0x00,0x90,0x90,0x60,0x60,0x90,0x90,0x00, + + 5, // 0x79 'y' + 0x00,0x00,0x90,0x90,0x90,0x90,0x70,0x10,0xe0, + + 5, // 0x7a 'z' + 0x00,0x00,0xf0,0x10,0x20,0x40,0x80,0xf0,0x00, + + 5, // 0x7b '{' + 0x10,0x20,0x20,0x20,0xc0,0x20,0x20,0x20,0x10, + + 5, // 0x7c '|' + 0x00,0x20,0x20,0x20,0x00,0x20,0x20,0x20,0x00, + + 5, // 0x7d '}' + 0x80,0x40,0x40,0x40,0x30,0x40,0x40,0x40,0x80, + + 5, // 0x7e '~' + 0x00,0x40,0xa8,0x10,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x7f '' + 0x00,0x00,0x00,0x20,0x50,0x88,0xf8,0x00,0x00, + 0 + }; + + const int8u gse6x12[] = + { + 12, 0, 32, 128-32, + + 0x00,0x00,0x0d,0x00,0x1a,0x00,0x27,0x00,0x34,0x00,0x41,0x00,0x4e,0x00,0x5b,0x00,0x68,0x00, + 0x75,0x00,0x82,0x00,0x8f,0x00,0x9c,0x00,0xa9,0x00,0xb6,0x00,0xc3,0x00,0xd0,0x00,0xdd,0x00, + 0xea,0x00,0xf7,0x00,0x04,0x01,0x11,0x01,0x1e,0x01,0x2b,0x01,0x38,0x01,0x45,0x01,0x52,0x01, + 0x5f,0x01,0x6c,0x01,0x79,0x01,0x86,0x01,0x93,0x01,0xa0,0x01,0xad,0x01,0xba,0x01,0xc7,0x01, + 0xd4,0x01,0xe1,0x01,0xee,0x01,0xfb,0x01,0x08,0x02,0x15,0x02,0x22,0x02,0x2f,0x02,0x3c,0x02, + 0x49,0x02,0x56,0x02,0x63,0x02,0x70,0x02,0x7d,0x02,0x8a,0x02,0x97,0x02,0xa4,0x02,0xb1,0x02, + 0xbe,0x02,0xcb,0x02,0xd8,0x02,0xe5,0x02,0xf2,0x02,0xff,0x02,0x0c,0x03,0x19,0x03,0x26,0x03, + 0x33,0x03,0x40,0x03,0x4d,0x03,0x5a,0x03,0x67,0x03,0x74,0x03,0x81,0x03,0x8e,0x03,0x9b,0x03, + 0xa8,0x03,0xb5,0x03,0xc2,0x03,0xcf,0x03,0xdc,0x03,0xe9,0x03,0xf6,0x03,0x03,0x04,0x10,0x04, + 0x1d,0x04,0x2a,0x04,0x37,0x04,0x44,0x04,0x51,0x04,0x5e,0x04,0x6b,0x04,0x78,0x04,0x85,0x04, + 0x92,0x04,0x9f,0x04,0xac,0x04,0xb9,0x04,0xc6,0x04,0xd3,0x04, + + 6, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x21 '!' + 0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00,0x00, + + 6, // 0x22 '"' + 0x00,0x50,0x50,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x23 '#' + 0x00,0x50,0x50,0xf8,0x50,0x50,0x50,0xf8,0x50,0x50,0x00,0x00, + + 6, // 0x24 '$' + 0x00,0x20,0x70,0xa8,0xa0,0x70,0x28,0xa8,0x70,0x20,0x00,0x00, + + 6, // 0x25 '%' + 0x00,0xc8,0xd8,0x10,0x30,0x20,0x60,0x40,0xd8,0x98,0x00,0x00, + + 6, // 0x26 '&' + 0x00,0x60,0x90,0x90,0x90,0x60,0xa8,0x90,0x90,0x68,0x00,0x00, + + 6, // 0x27 ''' + 0x00,0x20,0x20,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x28 '(' + 0x00,0x10,0x20,0x40,0x40,0x40,0x40,0x40,0x20,0x10,0x00,0x00, + + 6, // 0x29 ')' + 0x00,0x40,0x20,0x10,0x10,0x10,0x10,0x10,0x20,0x40,0x00,0x00, + + 6, // 0x2a '*' + 0x00,0x00,0x00,0x50,0x20,0xf8,0x20,0x50,0x00,0x00,0x00,0x00, + + 6, // 0x2b '+' + 0x00,0x00,0x20,0x20,0x20,0xf8,0x20,0x20,0x20,0x00,0x00,0x00, + + 6, // 0x2c ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x20,0x40, + + 6, // 0x2d '-' + 0x00,0x00,0x00,0x00,0x00,0xf8,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x2e '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x00, + + 6, // 0x2f '/' + 0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x80,0x80,0x00,0x00, + + 6, // 0x30 '0' + 0x00,0x70,0x88,0x88,0x98,0xa8,0xc8,0x88,0x88,0x70,0x00,0x00, + + 6, // 0x31 '1' + 0x00,0x20,0x20,0x60,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, + + 6, // 0x32 '2' + 0x00,0x70,0x88,0x88,0x08,0x10,0x20,0x40,0x80,0xf8,0x00,0x00, + + 6, // 0x33 '3' + 0x00,0xf8,0x10,0x20,0x70,0x08,0x08,0x08,0x88,0x70,0x00,0x00, + + 6, // 0x34 '4' + 0x00,0x10,0x20,0x40,0x90,0x90,0xf8,0x10,0x10,0x10,0x00,0x00, + + 6, // 0x35 '5' + 0x00,0xf8,0x80,0x80,0xf0,0x08,0x08,0x08,0x88,0x70,0x00,0x00, + + 6, // 0x36 '6' + 0x00,0x70,0x88,0x80,0x80,0xf0,0x88,0x88,0x88,0x70,0x00,0x00, + + 6, // 0x37 '7' + 0x00,0xf8,0x88,0x08,0x08,0x10,0x20,0x20,0x20,0x20,0x00,0x00, + + 6, // 0x38 '8' + 0x00,0x70,0x88,0x88,0x88,0x70,0x88,0x88,0x88,0x70,0x00,0x00, + + 6, // 0x39 '9' + 0x00,0x70,0x88,0x88,0x88,0x78,0x08,0x08,0x88,0x70,0x00,0x00, + + 6, // 0x3a ':' + 0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x00,0x00,0x00, + + 6, // 0x3b ';' + 0x00,0x00,0x00,0x00,0x20,0x00,0x00,0x00,0x20,0x20,0x20,0x40, + + 6, // 0x3c '<' + 0x00,0x08,0x10,0x20,0x40,0x80,0x40,0x20,0x10,0x08,0x00,0x00, + + 6, // 0x3d '=' + 0x00,0x00,0x00,0x00,0xf8,0x00,0xf8,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x3e '>' + 0x00,0x80,0x40,0x20,0x10,0x08,0x10,0x20,0x40,0x80,0x00,0x00, + + 6, // 0x3f '?' + 0x00,0x70,0x88,0x88,0x08,0x10,0x20,0x20,0x00,0x20,0x00,0x00, + + 6, // 0x40 '@' + 0x00,0x70,0x88,0x88,0xb8,0xb8,0xb0,0x80,0x88,0x70,0x00,0x00, + + 6, // 0x41 'A' + 0x00,0x20,0x50,0x88,0x88,0x88,0xf8,0x88,0x88,0x88,0x00,0x00, + + 6, // 0x42 'B' + 0x00,0xf0,0x88,0x88,0x88,0xf0,0x88,0x88,0x88,0xf0,0x00,0x00, + + 6, // 0x43 'C' + 0x00,0x70,0x88,0x88,0x80,0x80,0x80,0x88,0x88,0x70,0x00,0x00, + + 6, // 0x44 'D' + 0x00,0xe0,0x90,0x88,0x88,0x88,0x88,0x88,0x90,0xe0,0x00,0x00, + + 6, // 0x45 'E' + 0x00,0xf8,0x80,0x80,0x80,0xf0,0x80,0x80,0x80,0xf8,0x00,0x00, + + 6, // 0x46 'F' + 0x00,0xf8,0x80,0x80,0x80,0xf0,0x80,0x80,0x80,0x80,0x00,0x00, + + 6, // 0x47 'G' + 0x00,0x70,0x88,0x80,0x80,0xb8,0x88,0x88,0x88,0x70,0x00,0x00, + + 6, // 0x48 'H' + 0x00,0x88,0x88,0x88,0x88,0xf8,0x88,0x88,0x88,0x88,0x00,0x00, + + 6, // 0x49 'I' + 0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, + + 6, // 0x4a 'J' + 0x00,0x38,0x10,0x10,0x10,0x10,0x10,0x10,0x90,0x60,0x00,0x00, + + 6, // 0x4b 'K' + 0x00,0x88,0x88,0x90,0xa0,0xc0,0xa0,0x90,0x88,0x88,0x00,0x00, + + 6, // 0x4c 'L' + 0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xf8,0x00,0x00, + + 6, // 0x4d 'M' + 0x00,0x88,0x88,0xd8,0xa8,0x88,0x88,0x88,0x88,0x88,0x00,0x00, + + 6, // 0x4e 'N' + 0x00,0x88,0x88,0xc8,0xa8,0x98,0x88,0x88,0x88,0x88,0x00,0x00, + + 6, // 0x4f 'O' + 0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00, + + 6, // 0x50 'P' + 0x00,0xf0,0x88,0x88,0x88,0xf0,0x80,0x80,0x80,0x80,0x00,0x00, + + 6, // 0x51 'Q' + 0x00,0x70,0x88,0x88,0x88,0x88,0x88,0xa8,0x90,0x68,0x00,0x00, + + 6, // 0x52 'R' + 0x00,0xf0,0x88,0x88,0x88,0x88,0xf0,0xa0,0x90,0x88,0x00,0x00, + + 6, // 0x53 'S' + 0x00,0x70,0x88,0x80,0x80,0x70,0x08,0x08,0x88,0x70,0x00,0x00, + + 6, // 0x54 'T' + 0x00,0xf8,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00, + + 6, // 0x55 'U' + 0x00,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00, + + 6, // 0x56 'V' + 0x00,0x88,0x88,0x88,0x88,0x88,0x50,0x50,0x20,0x20,0x00,0x00, + + 6, // 0x57 'W' + 0x00,0x88,0x88,0x88,0x88,0x88,0xa8,0xa8,0xd8,0x88,0x00,0x00, + + 6, // 0x58 'X' + 0x00,0x88,0x88,0x88,0x50,0x20,0x50,0x88,0x88,0x88,0x00,0x00, + + 6, // 0x59 'Y' + 0x00,0x88,0x88,0x88,0x50,0x20,0x20,0x20,0x20,0x20,0x00,0x00, + + 6, // 0x5a 'Z' + 0x00,0xf8,0x08,0x08,0x10,0x20,0x40,0x80,0x80,0xf8,0x00,0x00, + + 6, // 0x5b '[' + 0x70,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x70,0x00, + + 6, // 0x5c '\' + 0x80,0x80,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x00,0x00, + + 6, // 0x5d ']' + 0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x70,0x00, + + 6, // 0x5e '^' + 0x00,0x00,0x20,0x50,0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x5f '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x00,0x00, + + 6, // 0x60 '`' + 0x00,0x40,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x61 'a' + 0x00,0x00,0x00,0x70,0x88,0x08,0x78,0x88,0x88,0x78,0x00,0x00, + + 6, // 0x62 'b' + 0x00,0x80,0x80,0x80,0xf0,0x88,0x88,0x88,0x88,0xf0,0x00,0x00, + + 6, // 0x63 'c' + 0x00,0x00,0x00,0x70,0x88,0x80,0x80,0x80,0x88,0x70,0x00,0x00, + + 6, // 0x64 'd' + 0x00,0x08,0x08,0x08,0x78,0x88,0x88,0x88,0x88,0x78,0x00,0x00, + + 6, // 0x65 'e' + 0x00,0x00,0x00,0x70,0x88,0x88,0xf8,0x80,0x80,0x78,0x00,0x00, + + 6, // 0x66 'f' + 0x00,0x18,0x20,0x20,0xf8,0x20,0x20,0x20,0x20,0x20,0x00,0x00, + + 6, // 0x67 'g' + 0x00,0x00,0x00,0x78,0x88,0x88,0x88,0x88,0x78,0x08,0x08,0xf0, + + 6, // 0x68 'h' + 0x00,0x80,0x80,0x80,0xf0,0x88,0x88,0x88,0x88,0x88,0x00,0x00, + + 6, // 0x69 'i' + 0x00,0x20,0x00,0x00,0x60,0x20,0x20,0x20,0x20,0x70,0x00,0x00, + + 6, // 0x6a 'j' + 0x00,0x10,0x00,0x00,0x30,0x10,0x10,0x10,0x10,0x10,0x90,0x60, + + 6, // 0x6b 'k' + 0x00,0x80,0x80,0x80,0x88,0x90,0xa0,0xd0,0x88,0x88,0x00,0x00, + + 6, // 0x6c 'l' + 0x00,0x60,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, + + 6, // 0x6d 'm' + 0x00,0x00,0x00,0xd0,0xa8,0xa8,0xa8,0xa8,0xa8,0xa8,0x00,0x00, + + 6, // 0x6e 'n' + 0x00,0x00,0x00,0xb0,0xc8,0x88,0x88,0x88,0x88,0x88,0x00,0x00, + + 6, // 0x6f 'o' + 0x00,0x00,0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x00,0x00, + + 6, // 0x70 'p' + 0x00,0x00,0x00,0xf0,0x88,0x88,0x88,0x88,0xf0,0x80,0x80,0x80, + + 6, // 0x71 'q' + 0x00,0x00,0x00,0x78,0x88,0x88,0x88,0x88,0x78,0x08,0x08,0x08, + + 6, // 0x72 'r' + 0x00,0x00,0x00,0xb0,0xc8,0x88,0x80,0x80,0x80,0x80,0x00,0x00, + + 6, // 0x73 's' + 0x00,0x00,0x00,0x70,0x88,0x80,0x70,0x08,0x88,0x70,0x00,0x00, + + 6, // 0x74 't' + 0x00,0x40,0x40,0x40,0xe0,0x40,0x40,0x40,0x48,0x30,0x00,0x00, + + 6, // 0x75 'u' + 0x00,0x00,0x00,0x88,0x88,0x88,0x88,0x88,0x88,0x78,0x00,0x00, + + 6, // 0x76 'v' + 0x00,0x00,0x00,0x88,0x88,0x88,0x50,0x50,0x20,0x20,0x00,0x00, + + 6, // 0x77 'w' + 0x00,0x00,0x00,0x88,0x88,0x88,0xa8,0xa8,0xd8,0x88,0x00,0x00, + + 6, // 0x78 'x' + 0x00,0x00,0x00,0x88,0x88,0x50,0x20,0x50,0x88,0x88,0x00,0x00, + + 6, // 0x79 'y' + 0x00,0x00,0x00,0x88,0x88,0x88,0x88,0x88,0x78,0x08,0x10,0xe0, + + 6, // 0x7a 'z' + 0x00,0x00,0x00,0xf8,0x08,0x10,0x20,0x40,0x80,0xf8,0x00,0x00, + + 6, // 0x7b '{' + 0x18,0x20,0x20,0x20,0x20,0xc0,0x20,0x20,0x20,0x20,0x18,0x00, + + 6, // 0x7c '|' + 0x00,0x20,0x20,0x20,0x20,0x00,0x20,0x20,0x20,0x20,0x00,0x00, + + 6, // 0x7d '}' + 0xc0,0x20,0x20,0x20,0x20,0x18,0x20,0x20,0x20,0x20,0xc0,0x00, + + 6, // 0x7e '~' + 0x00,0x00,0x40,0xa8,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x7f '' + 0x00,0x00,0x00,0x00,0x20,0x50,0x88,0xf8,0x00,0x00,0x00,0x00, + 0 + }; + + const int8u gse6x9[] = + { + 9, 0, 32, 128-32, + + 0x00,0x00,0x0a,0x00,0x14,0x00,0x1e,0x00,0x28,0x00,0x32,0x00,0x3c,0x00,0x46,0x00,0x50,0x00, + 0x5a,0x00,0x64,0x00,0x6e,0x00,0x78,0x00,0x82,0x00,0x8c,0x00,0x96,0x00,0xa0,0x00,0xaa,0x00, + 0xb4,0x00,0xbe,0x00,0xc8,0x00,0xd2,0x00,0xdc,0x00,0xe6,0x00,0xf0,0x00,0xfa,0x00,0x04,0x01, + 0x0e,0x01,0x18,0x01,0x22,0x01,0x2c,0x01,0x36,0x01,0x40,0x01,0x4a,0x01,0x54,0x01,0x5e,0x01, + 0x68,0x01,0x72,0x01,0x7c,0x01,0x86,0x01,0x90,0x01,0x9a,0x01,0xa4,0x01,0xae,0x01,0xb8,0x01, + 0xc2,0x01,0xcc,0x01,0xd6,0x01,0xe0,0x01,0xea,0x01,0xf4,0x01,0xfe,0x01,0x08,0x02,0x12,0x02, + 0x1c,0x02,0x26,0x02,0x30,0x02,0x3a,0x02,0x44,0x02,0x4e,0x02,0x58,0x02,0x62,0x02,0x6c,0x02, + 0x76,0x02,0x80,0x02,0x8a,0x02,0x94,0x02,0x9e,0x02,0xa8,0x02,0xb2,0x02,0xbc,0x02,0xc6,0x02, + 0xd0,0x02,0xda,0x02,0xe4,0x02,0xee,0x02,0xf8,0x02,0x02,0x03,0x0c,0x03,0x16,0x03,0x20,0x03, + 0x2a,0x03,0x34,0x03,0x3e,0x03,0x48,0x03,0x52,0x03,0x5c,0x03,0x66,0x03,0x70,0x03,0x7a,0x03, + 0x84,0x03,0x8e,0x03,0x98,0x03,0xa2,0x03,0xac,0x03,0xb6,0x03, + + 6, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x21 '!' + 0x00,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00, + + 6, // 0x22 '"' + 0x00,0x50,0x50,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x23 '#' + 0x00,0x50,0x50,0xf8,0x50,0xf8,0x50,0x50,0x00, + + 6, // 0x24 '$' + 0x00,0x70,0xa8,0xa0,0x70,0x28,0xa8,0x70,0x00, + + 6, // 0x25 '%' + 0x00,0xc8,0xc8,0x10,0x20,0x40,0x98,0x98,0x00, + + 6, // 0x26 '&' + 0x00,0x60,0x90,0x90,0x60,0xa8,0x90,0x68,0x00, + + 6, // 0x27 ''' + 0x00,0x20,0x20,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x28 '(' + 0x10,0x20,0x40,0x40,0x40,0x40,0x40,0x20,0x10, + + 6, // 0x29 ')' + 0x40,0x20,0x10,0x10,0x10,0x10,0x10,0x20,0x40, + + 6, // 0x2a '*' + 0x00,0x00,0x20,0xa8,0x70,0xa8,0x20,0x00,0x00, + + 6, // 0x2b '+' + 0x00,0x00,0x20,0x20,0xf8,0x20,0x20,0x00,0x00, + + 6, // 0x2c ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x40, + + 6, // 0x2d '-' + 0x00,0x00,0x00,0x00,0xf8,0x00,0x00,0x00,0x00, + + 6, // 0x2e '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00, + + 6, // 0x2f '/' + 0x00,0x08,0x08,0x10,0x20,0x40,0x80,0x80,0x00, + + 6, // 0x30 '0' + 0x00,0x70,0x88,0x98,0xa8,0xc8,0x88,0x70,0x00, + + 6, // 0x31 '1' + 0x00,0x20,0x60,0x20,0x20,0x20,0x20,0x70,0x00, + + 6, // 0x32 '2' + 0x00,0x70,0x88,0x08,0x10,0x20,0x40,0xf8,0x00, + + 6, // 0x33 '3' + 0x00,0xf8,0x10,0x20,0x70,0x08,0x88,0x70,0x00, + + 6, // 0x34 '4' + 0x00,0x10,0x20,0x40,0x90,0xf8,0x10,0x10,0x00, + + 6, // 0x35 '5' + 0x00,0xf8,0x80,0xf0,0x08,0x08,0x88,0x70,0x00, + + 6, // 0x36 '6' + 0x00,0x70,0x88,0x80,0xf0,0x88,0x88,0x70,0x00, + + 6, // 0x37 '7' + 0x00,0xf8,0x08,0x08,0x10,0x20,0x40,0x40,0x00, + + 6, // 0x38 '8' + 0x00,0x70,0x88,0x88,0x70,0x88,0x88,0x70,0x00, + + 6, // 0x39 '9' + 0x00,0x70,0x88,0x88,0x78,0x08,0x88,0x70,0x00, + + 6, // 0x3a ':' + 0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x00,0x00, + + 6, // 0x3b ';' + 0x00,0x00,0x00,0x20,0x00,0x00,0x20,0x20,0x40, + + 6, // 0x3c '<' + 0x00,0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x00, + + 6, // 0x3d '=' + 0x00,0x00,0x00,0xf8,0x00,0xf8,0x00,0x00,0x00, + + 6, // 0x3e '>' + 0x00,0x80,0x40,0x20,0x10,0x20,0x40,0x80,0x00, + + 6, // 0x3f '?' + 0x00,0x70,0x88,0x08,0x10,0x20,0x00,0x20,0x00, + + 6, // 0x40 '@' + 0x00,0x70,0x88,0x88,0xb8,0xb8,0x80,0x70,0x00, + + 6, // 0x41 'A' + 0x00,0x20,0x50,0x88,0x88,0xf8,0x88,0x88,0x00, + + 6, // 0x42 'B' + 0x00,0xf0,0x88,0x88,0xf0,0x88,0x88,0xf0,0x00, + + 6, // 0x43 'C' + 0x00,0x70,0x88,0x80,0x80,0x80,0x88,0x70,0x00, + + 6, // 0x44 'D' + 0x00,0xe0,0x90,0x88,0x88,0x88,0x90,0xe0,0x00, + + 6, // 0x45 'E' + 0x00,0xf8,0x80,0x80,0xf0,0x80,0x80,0xf8,0x00, + + 6, // 0x46 'F' + 0x00,0xf8,0x80,0x80,0xf0,0x80,0x80,0x80,0x00, + + 6, // 0x47 'G' + 0x00,0x70,0x88,0x80,0xb8,0x88,0x88,0x70,0x00, + + 6, // 0x48 'H' + 0x00,0x88,0x88,0x88,0xf8,0x88,0x88,0x88,0x00, + + 6, // 0x49 'I' + 0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x70,0x00, + + 6, // 0x4a 'J' + 0x00,0x38,0x10,0x10,0x10,0x10,0x90,0x60,0x00, + + 6, // 0x4b 'K' + 0x00,0x88,0x90,0xa0,0xc0,0xa0,0x90,0x88,0x00, + + 6, // 0x4c 'L' + 0x00,0x80,0x80,0x80,0x80,0x80,0x80,0xf8,0x00, + + 6, // 0x4d 'M' + 0x00,0x88,0xd8,0xa8,0x88,0x88,0x88,0x88,0x00, + + 6, // 0x4e 'N' + 0x00,0x88,0x88,0xc8,0xa8,0x98,0x88,0x88,0x00, + + 6, // 0x4f 'O' + 0x00,0x70,0x88,0x88,0x88,0x88,0x88,0x70,0x00, + + 6, // 0x50 'P' + 0x00,0xf0,0x88,0x88,0xf0,0x80,0x80,0x80,0x00, + + 6, // 0x51 'Q' + 0x00,0x70,0x88,0x88,0x88,0xa8,0x90,0x68,0x00, + + 6, // 0x52 'R' + 0x00,0xf0,0x88,0x88,0x88,0xf0,0x90,0x88,0x00, + + 6, // 0x53 'S' + 0x00,0x70,0x88,0x80,0x70,0x08,0x88,0x70,0x00, + + 6, // 0x54 'T' + 0x00,0xf8,0x20,0x20,0x20,0x20,0x20,0x20,0x00, + + 6, // 0x55 'U' + 0x00,0x88,0x88,0x88,0x88,0x88,0x88,0x70,0x00, + + 6, // 0x56 'V' + 0x00,0x88,0x88,0x88,0x50,0x50,0x20,0x20,0x00, + + 6, // 0x57 'W' + 0x00,0x88,0x88,0x88,0xa8,0xa8,0xd8,0x88,0x00, + + 6, // 0x58 'X' + 0x00,0x88,0x88,0x50,0x20,0x50,0x88,0x88,0x00, + + 6, // 0x59 'Y' + 0x00,0x88,0x88,0x50,0x20,0x20,0x20,0x20,0x00, + + 6, // 0x5a 'Z' + 0x00,0xf8,0x08,0x10,0x20,0x40,0x80,0xf8,0x00, + + 6, // 0x5b '[' + 0x70,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x70, + + 6, // 0x5c '\' + 0x00,0x80,0x80,0x40,0x20,0x10,0x08,0x08,0x00, + + 6, // 0x5d ']' + 0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x70, + + 6, // 0x5e '^' + 0x00,0x00,0x20,0x50,0x88,0x00,0x00,0x00,0x00, + + 6, // 0x5f '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xf8,0x00, + + 6, // 0x60 '`' + 0x00,0x40,0x20,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x61 'a' + 0x00,0x00,0x00,0x70,0x08,0x78,0x88,0x78,0x00, + + 6, // 0x62 'b' + 0x00,0x80,0x80,0xf0,0x88,0x88,0x88,0xf0,0x00, + + 6, // 0x63 'c' + 0x00,0x00,0x00,0x70,0x88,0x80,0x88,0x70,0x00, + + 6, // 0x64 'd' + 0x00,0x08,0x08,0x78,0x88,0x88,0x88,0x78,0x00, + + 6, // 0x65 'e' + 0x00,0x00,0x00,0x70,0x88,0xf8,0x80,0x78,0x00, + + 6, // 0x66 'f' + 0x00,0x18,0x20,0x20,0xf8,0x20,0x20,0x20,0x00, + + 6, // 0x67 'g' + 0x00,0x00,0x00,0x78,0x88,0x88,0x78,0x08,0x70, + + 6, // 0x68 'h' + 0x00,0x80,0x80,0xf0,0x88,0x88,0x88,0x88,0x00, + + 6, // 0x69 'i' + 0x00,0x20,0x00,0x60,0x20,0x20,0x20,0x70,0x00, + + 6, // 0x6a 'j' + 0x00,0x10,0x00,0x30,0x10,0x10,0x10,0x90,0x60, + + 6, // 0x6b 'k' + 0x00,0x00,0x80,0x88,0x90,0xa0,0xd0,0x88,0x00, + + 6, // 0x6c 'l' + 0x00,0x60,0x20,0x20,0x20,0x20,0x20,0x70,0x00, + + 6, // 0x6d 'm' + 0x00,0x00,0x00,0xd0,0xa8,0xa8,0xa8,0xa8,0x00, + + 6, // 0x6e 'n' + 0x00,0x00,0x00,0xb0,0xc8,0x88,0x88,0x88,0x00, + + 6, // 0x6f 'o' + 0x00,0x00,0x00,0x70,0x88,0x88,0x88,0x70,0x00, + + 6, // 0x70 'p' + 0x00,0x00,0x00,0xf0,0x88,0x88,0xf0,0x80,0x80, + + 6, // 0x71 'q' + 0x00,0x00,0x00,0x78,0x88,0x88,0x78,0x08,0x08, + + 6, // 0x72 'r' + 0x00,0x00,0x00,0xb8,0xc0,0x80,0x80,0x80,0x00, + + 6, // 0x73 's' + 0x00,0x00,0x00,0x78,0x80,0x70,0x08,0xf0,0x00, + + 6, // 0x74 't' + 0x00,0x40,0x40,0xe0,0x40,0x40,0x48,0x30,0x00, + + 6, // 0x75 'u' + 0x00,0x00,0x00,0x88,0x88,0x88,0x88,0x78,0x00, + + 6, // 0x76 'v' + 0x00,0x00,0x00,0x88,0x88,0x88,0x50,0x20,0x00, + + 6, // 0x77 'w' + 0x00,0x00,0x00,0x88,0x88,0xa8,0xd8,0x88,0x00, + + 6, // 0x78 'x' + 0x00,0x00,0x00,0x88,0x50,0x20,0x50,0x88,0x00, + + 6, // 0x79 'y' + 0x00,0x00,0x00,0x88,0x88,0x88,0x78,0x08,0x70, + + 6, // 0x7a 'z' + 0x00,0x00,0x00,0xf8,0x10,0x20,0x40,0xf8,0x00, + + 6, // 0x7b '{' + 0x18,0x20,0x20,0x20,0xc0,0x20,0x20,0x20,0x18, + + 6, // 0x7c '|' + 0x00,0x20,0x20,0x20,0x00,0x20,0x20,0x20,0x00, + + 6, // 0x7d '}' + 0xc0,0x20,0x20,0x20,0x18,0x20,0x20,0x20,0xc0, + + 6, // 0x7e '~' + 0x00,0x40,0xa8,0x10,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x7f '' + 0x00,0x00,0x00,0x20,0x50,0x88,0xf8,0x00,0x00, + 0 + }; + + const int8u gse7x11[] = + { + 11, 0, 32, 128-32, + + 0x00,0x00,0x0c,0x00,0x18,0x00,0x24,0x00,0x30,0x00,0x3c,0x00,0x48,0x00,0x54,0x00,0x60,0x00, + 0x6c,0x00,0x78,0x00,0x84,0x00,0x90,0x00,0x9c,0x00,0xa8,0x00,0xb4,0x00,0xc0,0x00,0xcc,0x00, + 0xd8,0x00,0xe4,0x00,0xf0,0x00,0xfc,0x00,0x08,0x01,0x14,0x01,0x20,0x01,0x2c,0x01,0x38,0x01, + 0x44,0x01,0x50,0x01,0x5c,0x01,0x68,0x01,0x74,0x01,0x80,0x01,0x8c,0x01,0x98,0x01,0xa4,0x01, + 0xb0,0x01,0xbc,0x01,0xc8,0x01,0xd4,0x01,0xe0,0x01,0xec,0x01,0xf8,0x01,0x04,0x02,0x10,0x02, + 0x1c,0x02,0x28,0x02,0x34,0x02,0x40,0x02,0x4c,0x02,0x58,0x02,0x64,0x02,0x70,0x02,0x7c,0x02, + 0x88,0x02,0x94,0x02,0xa0,0x02,0xac,0x02,0xb8,0x02,0xc4,0x02,0xd0,0x02,0xdc,0x02,0xe8,0x02, + 0xf4,0x02,0x00,0x03,0x0c,0x03,0x18,0x03,0x24,0x03,0x30,0x03,0x3c,0x03,0x48,0x03,0x54,0x03, + 0x60,0x03,0x6c,0x03,0x78,0x03,0x84,0x03,0x90,0x03,0x9c,0x03,0xa8,0x03,0xb4,0x03,0xc0,0x03, + 0xcc,0x03,0xd8,0x03,0xe4,0x03,0xf0,0x03,0xfc,0x03,0x08,0x04,0x14,0x04,0x20,0x04,0x2c,0x04, + 0x38,0x04,0x44,0x04,0x50,0x04,0x5c,0x04,0x68,0x04,0x74,0x04, + + 7, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x21 '!' + 0x00,0x10,0x38,0x38,0x38,0x10,0x10,0x00,0x10,0x00,0x00, + + 7, // 0x22 '"' + 0x00,0x00,0x24,0x24,0x24,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x23 '#' + 0x00,0x48,0x48,0xfc,0x48,0x48,0xfc,0x48,0x48,0x00,0x00, + + 7, // 0x24 '$' + 0x00,0x10,0x38,0x54,0x50,0x38,0x14,0x54,0x38,0x10,0x00, + + 7, // 0x25 '%' + 0x00,0x00,0x42,0xa4,0x48,0x10,0x24,0x4a,0x84,0x00,0x00, + + 7, // 0x26 '&' + 0x00,0x30,0x48,0x48,0x30,0x60,0x94,0x98,0x6c,0x00,0x00, + + 7, // 0x27 ''' + 0x00,0x20,0x20,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x28 '(' + 0x00,0x04,0x08,0x10,0x10,0x10,0x10,0x08,0x04,0x00,0x00, + + 7, // 0x29 ')' + 0x00,0x40,0x20,0x10,0x10,0x10,0x10,0x20,0x40,0x00,0x00, + + 7, // 0x2a '*' + 0x00,0x00,0x00,0x20,0xa8,0x70,0xa8,0x20,0x00,0x00,0x00, + + 7, // 0x2b '+' + 0x00,0x00,0x00,0x10,0x10,0x7c,0x10,0x10,0x00,0x00,0x00, + + 7, // 0x2c ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x60, + + 7, // 0x2d '-' + 0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x2e '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00, + + 7, // 0x2f '/' + 0x00,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x00,0x00, + + 7, // 0x30 '0' + 0x00,0x38,0x44,0x4c,0x54,0x64,0x44,0x44,0x38,0x00,0x00, + + 7, // 0x31 '1' + 0x00,0x10,0x30,0x10,0x10,0x10,0x10,0x10,0x7c,0x00,0x00, + + 7, // 0x32 '2' + 0x00,0x38,0x44,0x04,0x08,0x10,0x20,0x44,0x7c,0x00,0x00, + + 7, // 0x33 '3' + 0x00,0x7c,0x48,0x10,0x38,0x04,0x04,0x44,0x38,0x00,0x00, + + 7, // 0x34 '4' + 0x00,0x08,0x10,0x20,0x48,0x48,0x7c,0x08,0x1c,0x00,0x00, + + 7, // 0x35 '5' + 0x00,0x7c,0x40,0x40,0x78,0x04,0x04,0x44,0x38,0x00,0x00, + + 7, // 0x36 '6' + 0x00,0x18,0x20,0x40,0x78,0x44,0x44,0x44,0x38,0x00,0x00, + + 7, // 0x37 '7' + 0x00,0x7c,0x44,0x04,0x08,0x10,0x10,0x10,0x10,0x00,0x00, + + 7, // 0x38 '8' + 0x00,0x38,0x44,0x44,0x38,0x44,0x44,0x44,0x38,0x00,0x00, + + 7, // 0x39 '9' + 0x00,0x38,0x44,0x44,0x44,0x3c,0x04,0x08,0x30,0x00,0x00, + + 7, // 0x3a ':' + 0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x30,0x00,0x00,0x00, + + 7, // 0x3b ';' + 0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x30,0x30,0x60,0x00, + + 7, // 0x3c '<' + 0x00,0x00,0x04,0x08,0x10,0x20,0x10,0x08,0x04,0x00,0x00, + + 7, // 0x3d '=' + 0x00,0x00,0x00,0x00,0xfc,0x00,0xfc,0x00,0x00,0x00,0x00, + + 7, // 0x3e '>' + 0x00,0x00,0x40,0x20,0x10,0x08,0x10,0x20,0x40,0x00,0x00, + + 7, // 0x3f '?' + 0x00,0x70,0x88,0x88,0x10,0x20,0x20,0x00,0x20,0x00,0x00, + + 7, // 0x40 '@' + 0x00,0x30,0x48,0x04,0x34,0x54,0x54,0x54,0x28,0x00,0x00, + + 7, // 0x41 'A' + 0x00,0x10,0x28,0x44,0x44,0x7c,0x44,0x44,0x44,0x00,0x00, + + 7, // 0x42 'B' + 0x00,0x78,0x44,0x44,0x78,0x44,0x44,0x44,0x78,0x00,0x00, + + 7, // 0x43 'C' + 0x00,0x38,0x44,0x40,0x40,0x40,0x40,0x44,0x38,0x00,0x00, + + 7, // 0x44 'D' + 0x00,0x70,0x48,0x44,0x44,0x44,0x44,0x48,0x70,0x00,0x00, + + 7, // 0x45 'E' + 0x00,0x7c,0x40,0x40,0x70,0x40,0x40,0x40,0x7c,0x00,0x00, + + 7, // 0x46 'F' + 0x00,0x7c,0x40,0x40,0x70,0x40,0x40,0x40,0x40,0x00,0x00, + + 7, // 0x47 'G' + 0x00,0x38,0x44,0x40,0x40,0x5c,0x44,0x44,0x38,0x00,0x00, + + 7, // 0x48 'H' + 0x00,0x44,0x44,0x44,0x7c,0x44,0x44,0x44,0x44,0x00,0x00, + + 7, // 0x49 'I' + 0x00,0x38,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00, + + 7, // 0x4a 'J' + 0x00,0x1c,0x08,0x08,0x08,0x08,0x08,0x48,0x30,0x00,0x00, + + 7, // 0x4b 'K' + 0x00,0x44,0x48,0x50,0x60,0x50,0x48,0x44,0x44,0x00,0x00, + + 7, // 0x4c 'L' + 0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7c,0x00,0x00, + + 7, // 0x4d 'M' + 0x00,0x44,0x6c,0x54,0x54,0x44,0x44,0x44,0x44,0x00,0x00, + + 7, // 0x4e 'N' + 0x00,0x44,0x44,0x64,0x54,0x4c,0x44,0x44,0x44,0x00,0x00, + + 7, // 0x4f 'O' + 0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00, + + 7, // 0x50 'P' + 0x00,0x78,0x44,0x44,0x44,0x78,0x40,0x40,0x40,0x00,0x00, + + 7, // 0x51 'Q' + 0x00,0x38,0x44,0x44,0x44,0x44,0x54,0x48,0x34,0x00,0x00, + + 7, // 0x52 'R' + 0x00,0x78,0x44,0x44,0x44,0x78,0x50,0x48,0x44,0x00,0x00, + + 7, // 0x53 'S' + 0x00,0x38,0x44,0x40,0x38,0x04,0x44,0x44,0x38,0x00,0x00, + + 7, // 0x54 'T' + 0x00,0x7c,0x54,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00, + + 7, // 0x55 'U' + 0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00, + + 7, // 0x56 'V' + 0x00,0x44,0x44,0x44,0x44,0x28,0x28,0x10,0x10,0x00,0x00, + + 7, // 0x57 'W' + 0x00,0x44,0x44,0x44,0x44,0x54,0x54,0x6c,0x44,0x00,0x00, + + 7, // 0x58 'X' + 0x00,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x44,0x00,0x00, + + 7, // 0x59 'Y' + 0x00,0x44,0x44,0x44,0x28,0x10,0x10,0x10,0x38,0x00,0x00, + + 7, // 0x5a 'Z' + 0x00,0x7c,0x04,0x08,0x10,0x20,0x40,0x44,0x7c,0x00,0x00, + + 7, // 0x5b '[' + 0x00,0x38,0x20,0x20,0x20,0x20,0x20,0x20,0x38,0x00,0x00, + + 7, // 0x5c '\' + 0x00,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x00,0x00, + + 7, // 0x5d ']' + 0x00,0x38,0x08,0x08,0x08,0x08,0x08,0x08,0x38,0x00,0x00, + + 7, // 0x5e '^' + 0x00,0x10,0x28,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x5f '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00, + + 7, // 0x60 '`' + 0x00,0x20,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x61 'a' + 0x00,0x00,0x00,0x38,0x04,0x3c,0x44,0x44,0x3c,0x00,0x00, + + 7, // 0x62 'b' + 0x00,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x78,0x00,0x00, + + 7, // 0x63 'c' + 0x00,0x00,0x00,0x38,0x44,0x40,0x40,0x44,0x38,0x00,0x00, + + 7, // 0x64 'd' + 0x00,0x04,0x04,0x3c,0x44,0x44,0x44,0x44,0x3c,0x00,0x00, + + 7, // 0x65 'e' + 0x00,0x00,0x00,0x38,0x44,0x7c,0x40,0x44,0x38,0x00,0x00, + + 7, // 0x66 'f' + 0x00,0x18,0x24,0x20,0x70,0x20,0x20,0x20,0x70,0x00,0x00, + + 7, // 0x67 'g' + 0x00,0x00,0x00,0x3c,0x44,0x44,0x44,0x3c,0x04,0x44,0x38, + + 7, // 0x68 'h' + 0x00,0x40,0x40,0x40,0x58,0x64,0x44,0x44,0x44,0x00,0x00, + + 7, // 0x69 'i' + 0x00,0x10,0x00,0x30,0x10,0x10,0x10,0x10,0x38,0x00,0x00, + + 7, // 0x6a 'j' + 0x00,0x08,0x00,0x18,0x08,0x08,0x08,0x08,0x48,0x30,0x00, + + 7, // 0x6b 'k' + 0x00,0x40,0x40,0x44,0x48,0x50,0x68,0x44,0x44,0x00,0x00, + + 7, // 0x6c 'l' + 0x00,0x30,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00, + + 7, // 0x6d 'm' + 0x00,0x00,0x00,0xa8,0x54,0x54,0x54,0x54,0x54,0x00,0x00, + + 7, // 0x6e 'n' + 0x00,0x00,0x00,0xb8,0x44,0x44,0x44,0x44,0x44,0x00,0x00, + + 7, // 0x6f 'o' + 0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x38,0x00,0x00, + + 7, // 0x70 'p' + 0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x44,0x78,0x40,0x40, + + 7, // 0x71 'q' + 0x00,0x00,0x00,0x3c,0x44,0x44,0x44,0x44,0x3c,0x04,0x04, + + 7, // 0x72 'r' + 0x00,0x00,0x00,0x58,0x64,0x44,0x40,0x40,0x40,0x00,0x00, + + 7, // 0x73 's' + 0x00,0x00,0x00,0x3c,0x40,0x38,0x04,0x04,0x78,0x00,0x00, + + 7, // 0x74 't' + 0x00,0x20,0x20,0x70,0x20,0x20,0x20,0x24,0x18,0x00,0x00, + + 7, // 0x75 'u' + 0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x3a,0x00,0x00, + + 7, // 0x76 'v' + 0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x28,0x10,0x00,0x00, + + 7, // 0x77 'w' + 0x00,0x00,0x00,0x44,0x44,0x54,0x54,0x6c,0x44,0x00,0x00, + + 7, // 0x78 'x' + 0x00,0x00,0x00,0x44,0x28,0x10,0x28,0x44,0x44,0x00,0x00, + + 7, // 0x79 'y' + 0x00,0x00,0x00,0x44,0x44,0x44,0x3c,0x04,0x08,0x30,0x00, + + 7, // 0x7a 'z' + 0x00,0x00,0x00,0x7c,0x08,0x10,0x20,0x44,0x7c,0x00,0x00, + + 7, // 0x7b '{' + 0x00,0x0c,0x10,0x10,0x10,0x60,0x10,0x10,0x0c,0x00,0x00, + + 7, // 0x7c '|' + 0x00,0x20,0x20,0x20,0x00,0x20,0x20,0x20,0x20,0x00,0x00, + + 7, // 0x7d '}' + 0x00,0x60,0x10,0x10,0x10,0x0c,0x10,0x10,0x60,0x00,0x00, + + 7, // 0x7e '~' + 0x00,0x00,0x64,0x98,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x7f '' + 0x00,0x00,0x00,0x10,0x28,0x44,0x44,0x7c,0x00,0x00,0x00, + 0 + }; + + const int8u gse7x11_bold[] = + { + 11, 0, 32, 128-32, + + 0x00,0x00,0x0c,0x00,0x18,0x00,0x24,0x00,0x30,0x00,0x3c,0x00,0x48,0x00,0x54,0x00,0x60,0x00, + 0x6c,0x00,0x78,0x00,0x84,0x00,0x90,0x00,0x9c,0x00,0xa8,0x00,0xb4,0x00,0xc0,0x00,0xcc,0x00, + 0xd8,0x00,0xe4,0x00,0xf0,0x00,0xfc,0x00,0x08,0x01,0x14,0x01,0x20,0x01,0x2c,0x01,0x38,0x01, + 0x44,0x01,0x50,0x01,0x5c,0x01,0x68,0x01,0x74,0x01,0x80,0x01,0x8c,0x01,0x98,0x01,0xa4,0x01, + 0xb0,0x01,0xbc,0x01,0xc8,0x01,0xd4,0x01,0xe0,0x01,0xec,0x01,0xf8,0x01,0x04,0x02,0x10,0x02, + 0x1c,0x02,0x28,0x02,0x34,0x02,0x40,0x02,0x4c,0x02,0x58,0x02,0x64,0x02,0x70,0x02,0x7c,0x02, + 0x88,0x02,0x94,0x02,0xa0,0x02,0xac,0x02,0xb8,0x02,0xc4,0x02,0xd0,0x02,0xdc,0x02,0xe8,0x02, + 0xf4,0x02,0x00,0x03,0x0c,0x03,0x18,0x03,0x24,0x03,0x30,0x03,0x3c,0x03,0x48,0x03,0x54,0x03, + 0x60,0x03,0x6c,0x03,0x78,0x03,0x84,0x03,0x90,0x03,0x9c,0x03,0xa8,0x03,0xb4,0x03,0xc0,0x03, + 0xcc,0x03,0xd8,0x03,0xe4,0x03,0xf0,0x03,0xfc,0x03,0x08,0x04,0x14,0x04,0x20,0x04,0x2c,0x04, + 0x38,0x04,0x44,0x04,0x50,0x04,0x5c,0x04,0x68,0x04,0x74,0x04, + + 7, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x21 '!' + 0x00,0x30,0x30,0x30,0x30,0x30,0x00,0x30,0x30,0x00,0x00, + + 7, // 0x22 '"' + 0x00,0x6c,0x6c,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x23 '#' + 0x00,0x48,0x48,0xfc,0x48,0x48,0xfc,0x48,0x48,0x00,0x00, + + 7, // 0x24 '$' + 0x30,0x30,0x78,0xcc,0xc0,0x78,0x0c,0xcc,0x78,0x30,0x30, + + 7, // 0x25 '%' + 0x00,0x00,0xc4,0x0c,0x18,0x30,0x60,0xc0,0x8c,0x00,0x00, + + 7, // 0x26 '&' + 0x00,0x30,0x58,0x58,0x30,0x74,0xdc,0xd8,0x6c,0x00,0x00, + + 7, // 0x27 ''' + 0x00,0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x28 '(' + 0x00,0x0c,0x18,0x30,0x30,0x30,0x30,0x18,0x0c,0x00,0x00, + + 7, // 0x29 ')' + 0x00,0xc0,0x60,0x30,0x30,0x30,0x30,0x60,0xc0,0x00,0x00, + + 7, // 0x2a '*' + 0x00,0x00,0x00,0x20,0xa8,0x70,0xa8,0x20,0x00,0x00,0x00, + + 7, // 0x2b '+' + 0x00,0x00,0x00,0x30,0x30,0xfc,0x30,0x30,0x00,0x00,0x00, + + 7, // 0x2c ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x60,0x00, + + 7, // 0x2d '-' + 0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x2e '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00, + + 7, // 0x2f '/' + 0x00,0x0c,0x0c,0x18,0x18,0x30,0x30,0x60,0x60,0x00,0x00, + + 7, // 0x30 '0' + 0x00,0x78,0xcc,0xcc,0xdc,0xec,0xcc,0xcc,0x78,0x00,0x00, + + 7, // 0x31 '1' + 0x00,0x30,0x70,0xf0,0x30,0x30,0x30,0x30,0xfc,0x00,0x00, + + 7, // 0x32 '2' + 0x00,0x78,0xcc,0xcc,0x18,0x30,0x60,0xcc,0xfc,0x00,0x00, + + 7, // 0x33 '3' + 0x00,0xfc,0x98,0x30,0x78,0x0c,0x0c,0xcc,0x78,0x00,0x00, + + 7, // 0x34 '4' + 0x00,0x18,0x30,0x68,0xd8,0xd8,0xfc,0x18,0x3c,0x00,0x00, + + 7, // 0x35 '5' + 0x00,0xfc,0xc0,0xc0,0xf8,0x0c,0x0c,0xcc,0x78,0x00,0x00, + + 7, // 0x36 '6' + 0x00,0x38,0x60,0xc0,0xf8,0xcc,0xcc,0xcc,0x78,0x00,0x00, + + 7, // 0x37 '7' + 0x00,0xfc,0x8c,0x0c,0x18,0x30,0x30,0x30,0x30,0x00,0x00, + + 7, // 0x38 '8' + 0x00,0x78,0xcc,0xcc,0x78,0xcc,0xcc,0xcc,0x78,0x00,0x00, + + 7, // 0x39 '9' + 0x00,0x78,0xcc,0xcc,0xcc,0x7c,0x0c,0x18,0x70,0x00,0x00, + + 7, // 0x3a ':' + 0x00,0x00,0x30,0x30,0x00,0x00,0x30,0x30,0x00,0x00,0x00, + + 7, // 0x3b ';' + 0x00,0x00,0x30,0x30,0x00,0x00,0x30,0x30,0x30,0x60,0x00, + + 7, // 0x3c '<' + 0x00,0x00,0x0c,0x18,0x30,0x60,0x30,0x18,0x0c,0x00,0x00, + + 7, // 0x3d '=' + 0x00,0x00,0x00,0x00,0xfc,0x00,0xfc,0x00,0x00,0x00,0x00, + + 7, // 0x3e '>' + 0x00,0x00,0x60,0x30,0x18,0x0c,0x18,0x30,0x60,0x00,0x00, + + 7, // 0x3f '?' + 0x00,0x78,0xcc,0xcc,0x18,0x30,0x30,0x00,0x30,0x00,0x00, + + 7, // 0x40 '@' + 0x00,0x70,0x88,0x04,0x74,0xb4,0xb4,0xb4,0x68,0x00,0x00, + + 7, // 0x41 'A' + 0x00,0x30,0x78,0xcc,0xcc,0xfc,0xcc,0xcc,0xcc,0x00,0x00, + + 7, // 0x42 'B' + 0x00,0xf8,0xcc,0xcc,0xf8,0xcc,0xcc,0xcc,0xf8,0x00,0x00, + + 7, // 0x43 'C' + 0x00,0x78,0xcc,0xc0,0xc0,0xc0,0xc0,0xcc,0x78,0x00,0x00, + + 7, // 0x44 'D' + 0x00,0xf0,0xd8,0xcc,0xcc,0xcc,0xcc,0xd8,0xf0,0x00,0x00, + + 7, // 0x45 'E' + 0x00,0xfc,0xc4,0xd0,0xf0,0xd0,0xc0,0xc4,0xfc,0x00,0x00, + + 7, // 0x46 'F' + 0x00,0xfc,0xc4,0xd0,0xf0,0xd0,0xc0,0xc0,0xc0,0x00,0x00, + + 7, // 0x47 'G' + 0x00,0x78,0xcc,0xc0,0xc0,0xdc,0xcc,0xcc,0x78,0x00,0x00, + + 7, // 0x48 'H' + 0x00,0xcc,0xcc,0xcc,0xfc,0xcc,0xcc,0xcc,0xcc,0x00,0x00, + + 7, // 0x49 'I' + 0x00,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x78,0x00,0x00, + + 7, // 0x4a 'J' + 0x00,0x3c,0x18,0x18,0x18,0x18,0xd8,0xd8,0x70,0x00,0x00, + + 7, // 0x4b 'K' + 0x00,0xcc,0xcc,0xd8,0xf0,0xd8,0xcc,0xcc,0xcc,0x00,0x00, + + 7, // 0x4c 'L' + 0x00,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc4,0xfc,0x00,0x00, + + 7, // 0x4d 'M' + 0x00,0x84,0xcc,0xfc,0xb4,0xcc,0xcc,0xcc,0xcc,0x00,0x00, + + 7, // 0x4e 'N' + 0x00,0xcc,0xcc,0xec,0xfc,0xdc,0xcc,0xcc,0xcc,0x00,0x00, + + 7, // 0x4f 'O' + 0x00,0x78,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x78,0x00,0x00, + + 7, // 0x50 'P' + 0x00,0xf8,0xcc,0xcc,0xcc,0xf8,0xc0,0xc0,0xc0,0x00,0x00, + + 7, // 0x51 'Q' + 0x00,0x78,0xcc,0xcc,0xcc,0xcc,0xdc,0x78,0x18,0x0c,0x00, + + 7, // 0x52 'R' + 0x00,0xf8,0xcc,0xcc,0xcc,0xf8,0xd8,0xcc,0xcc,0x00,0x00, + + 7, // 0x53 'S' + 0x00,0x78,0xcc,0xe0,0x70,0x38,0x1c,0xcc,0x78,0x00,0x00, + + 7, // 0x54 'T' + 0x00,0xfc,0xb4,0x30,0x30,0x30,0x30,0x30,0x30,0x00,0x00, + + 7, // 0x55 'U' + 0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x78,0x00,0x00, + + 7, // 0x56 'V' + 0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x78,0x30,0x00,0x00, + + 7, // 0x57 'W' + 0x00,0xcc,0xcc,0xcc,0xcc,0xb4,0xfc,0xcc,0x84,0x00,0x00, + + 7, // 0x58 'X' + 0x00,0xcc,0xcc,0x78,0x30,0x78,0xcc,0xcc,0xcc,0x00,0x00, + + 7, // 0x59 'Y' + 0x00,0xcc,0xcc,0xcc,0x78,0x30,0x30,0x30,0x78,0x00,0x00, + + 7, // 0x5a 'Z' + 0x00,0xfc,0x8c,0x18,0x30,0x60,0xc0,0xc4,0xfc,0x00,0x00, + + 7, // 0x5b '[' + 0x00,0x78,0x60,0x60,0x60,0x60,0x60,0x60,0x78,0x00,0x00, + + 7, // 0x5c '\' + 0x00,0x60,0x60,0x30,0x30,0x18,0x18,0x0c,0x0c,0x00,0x00, + + 7, // 0x5d ']' + 0x00,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x78,0x00,0x00, + + 7, // 0x5e '^' + 0x00,0x10,0x38,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x5f '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00, + + 7, // 0x60 '`' + 0x00,0x30,0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x61 'a' + 0x00,0x00,0x00,0x70,0x18,0x78,0xd8,0xd8,0x6c,0x00,0x00, + + 7, // 0x62 'b' + 0x00,0x60,0x60,0x60,0x78,0x6c,0x6c,0x6c,0x78,0x00,0x00, + + 7, // 0x63 'c' + 0x00,0x00,0x00,0x78,0xcc,0xc0,0xc0,0xcc,0x78,0x00,0x00, + + 7, // 0x64 'd' + 0x00,0x18,0x18,0x18,0x78,0xd8,0xd8,0xd8,0x6c,0x00,0x00, + + 7, // 0x65 'e' + 0x00,0x00,0x00,0x78,0xcc,0xfc,0xc0,0xcc,0x78,0x00,0x00, + + 7, // 0x66 'f' + 0x00,0x18,0x34,0x30,0x78,0x30,0x30,0x30,0x78,0x00,0x00, + + 7, // 0x67 'g' + 0x00,0x00,0x00,0x6c,0xd8,0xd8,0xd8,0x78,0x18,0xd8,0x70, + + 7, // 0x68 'h' + 0x00,0xc0,0xc0,0xd8,0xec,0xcc,0xcc,0xcc,0xcc,0x00,0x00, + + 7, // 0x69 'i' + 0x00,0x30,0x00,0x70,0x30,0x30,0x30,0x30,0x78,0x00,0x00, + + 7, // 0x6a 'j' + 0x00,0x0c,0x00,0x1c,0x0c,0x0c,0x0c,0x0c,0x6c,0x6c,0x38, + + 7, // 0x6b 'k' + 0x00,0xc0,0xc0,0xcc,0xcc,0xd8,0xf0,0xd8,0xcc,0x00,0x00, + + 7, // 0x6c 'l' + 0x00,0x70,0x30,0x30,0x30,0x30,0x30,0x30,0x78,0x00,0x00, + + 7, // 0x6d 'm' + 0x00,0x00,0x00,0xe8,0xfc,0xd4,0xd4,0xc4,0xc4,0x00,0x00, + + 7, // 0x6e 'n' + 0x00,0x00,0x00,0xd8,0x6c,0x6c,0x6c,0x6c,0x6c,0x00,0x00, + + 7, // 0x6f 'o' + 0x00,0x00,0x00,0x78,0xcc,0xcc,0xcc,0xcc,0x78,0x00,0x00, + + 7, // 0x70 'p' + 0x00,0x00,0x00,0xf8,0xcc,0xcc,0xcc,0xf8,0xc0,0xc0,0xc0, + + 7, // 0x71 'q' + 0x00,0x00,0x00,0x7c,0xcc,0xcc,0xcc,0x7c,0x0c,0x0c,0x0c, + + 7, // 0x72 'r' + 0x00,0x00,0x00,0xd8,0xec,0xcc,0xc0,0xc0,0xc0,0x00,0x00, + + 7, // 0x73 's' + 0x00,0x00,0x00,0x78,0xcc,0x60,0x18,0xcc,0x78,0x00,0x00, + + 7, // 0x74 't' + 0x00,0x20,0x60,0x60,0xf0,0x60,0x60,0x68,0x30,0x00,0x00, + + 7, // 0x75 'u' + 0x00,0x00,0x00,0xd8,0xd8,0xd8,0xd8,0xd8,0x6c,0x00,0x00, + + 7, // 0x76 'v' + 0x00,0x00,0x00,0xcc,0xcc,0xcc,0xcc,0x78,0x30,0x00,0x00, + + 7, // 0x77 'w' + 0x00,0x00,0x00,0xcc,0xcc,0xb4,0xfc,0xcc,0x84,0x00,0x00, + + 7, // 0x78 'x' + 0x00,0x00,0x00,0xcc,0x78,0x30,0x78,0xcc,0xcc,0x00,0x00, + + 7, // 0x79 'y' + 0x00,0x00,0x00,0xcc,0xcc,0xcc,0xcc,0x7c,0x0c,0x18,0xf0, + + 7, // 0x7a 'z' + 0x00,0x00,0x00,0xfc,0x98,0x30,0x60,0xc4,0xfc,0x00,0x00, + + 7, // 0x7b '{' + 0x1c,0x30,0x30,0x30,0xe0,0x30,0x30,0x30,0x1c,0x00,0x00, + + 7, // 0x7c '|' + 0x30,0x30,0x30,0x30,0x00,0x30,0x30,0x30,0x30,0x00,0x00, + + 7, // 0x7d '}' + 0xe0,0x30,0x30,0x30,0x1c,0x30,0x30,0x30,0xe0,0x00,0x00, + + 7, // 0x7e '~' + 0x00,0x34,0x58,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x7f '' + 0x00,0x00,0x00,0x30,0x78,0xcc,0xcc,0xfc,0x00,0x00,0x00, + 0 + }; + + const int8u gse7x15[] = + { + 15, 0, 32, 128-32, + + 0x00,0x00,0x10,0x00,0x20,0x00,0x30,0x00,0x40,0x00,0x50,0x00,0x60,0x00,0x70,0x00,0x80,0x00, + 0x90,0x00,0xa0,0x00,0xb0,0x00,0xc0,0x00,0xd0,0x00,0xe0,0x00,0xf0,0x00,0x00,0x01,0x10,0x01, + 0x20,0x01,0x30,0x01,0x40,0x01,0x50,0x01,0x60,0x01,0x70,0x01,0x80,0x01,0x90,0x01,0xa0,0x01, + 0xb0,0x01,0xc0,0x01,0xd0,0x01,0xe0,0x01,0xf0,0x01,0x00,0x02,0x10,0x02,0x20,0x02,0x30,0x02, + 0x40,0x02,0x50,0x02,0x60,0x02,0x70,0x02,0x80,0x02,0x90,0x02,0xa0,0x02,0xb0,0x02,0xc0,0x02, + 0xd0,0x02,0xe0,0x02,0xf0,0x02,0x00,0x03,0x10,0x03,0x20,0x03,0x30,0x03,0x40,0x03,0x50,0x03, + 0x60,0x03,0x70,0x03,0x80,0x03,0x90,0x03,0xa0,0x03,0xb0,0x03,0xc0,0x03,0xd0,0x03,0xe0,0x03, + 0xf0,0x03,0x00,0x04,0x10,0x04,0x20,0x04,0x30,0x04,0x40,0x04,0x50,0x04,0x60,0x04,0x70,0x04, + 0x80,0x04,0x90,0x04,0xa0,0x04,0xb0,0x04,0xc0,0x04,0xd0,0x04,0xe0,0x04,0xf0,0x04,0x00,0x05, + 0x10,0x05,0x20,0x05,0x30,0x05,0x40,0x05,0x50,0x05,0x60,0x05,0x70,0x05,0x80,0x05,0x90,0x05, + 0xa0,0x05,0xb0,0x05,0xc0,0x05,0xd0,0x05,0xe0,0x05,0xf0,0x05, + + 7, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x21 '!' + 0x00,0x00,0x10,0x38,0x38,0x38,0x38,0x10,0x10,0x00,0x10,0x10,0x00,0x00,0x00, + + 7, // 0x22 '"' + 0x00,0x00,0x24,0x24,0x24,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x23 '#' + 0x00,0x00,0x48,0x48,0x48,0xfc,0x48,0x48,0xfc,0x48,0x48,0x48,0x00,0x00,0x00, + + 7, // 0x24 '$' + 0x00,0x00,0x10,0x38,0x54,0x50,0x38,0x14,0x54,0x54,0x38,0x10,0x00,0x00,0x00, + + 7, // 0x25 '%' + 0x00,0x00,0x44,0x44,0x08,0x08,0x10,0x10,0x20,0x20,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x26 '&' + 0x00,0x00,0x00,0x30,0x48,0x48,0x30,0x60,0x94,0x98,0x90,0x6c,0x00,0x00,0x00, + + 7, // 0x27 ''' + 0x00,0x00,0x20,0x20,0x20,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x28 '(' + 0x00,0x04,0x08,0x10,0x20,0x20,0x20,0x20,0x20,0x10,0x08,0x04,0x00,0x00,0x00, + + 7, // 0x29 ')' + 0x00,0x40,0x20,0x10,0x08,0x08,0x08,0x08,0x08,0x10,0x20,0x40,0x00,0x00,0x00, + + 7, // 0x2a '*' + 0x00,0x00,0x00,0x00,0x00,0x20,0xa8,0x70,0xa8,0x20,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x2b '+' + 0x00,0x00,0x00,0x00,0x10,0x10,0x10,0x7c,0x10,0x10,0x10,0x00,0x00,0x00,0x00, + + 7, // 0x2c ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x60,0x00, + + 7, // 0x2d '-' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x2e '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00, + + 7, // 0x2f '/' + 0x00,0x00,0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x00,0x00,0x00, + + 7, // 0x30 '0' + 0x00,0x00,0x38,0x44,0x44,0x4c,0x54,0x64,0x44,0x44,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x31 '1' + 0x00,0x00,0x10,0x10,0x30,0x10,0x10,0x10,0x10,0x10,0x10,0x7c,0x00,0x00,0x00, + + 7, // 0x32 '2' + 0x00,0x00,0x38,0x44,0x44,0x04,0x08,0x10,0x20,0x40,0x44,0x7c,0x00,0x00,0x00, + + 7, // 0x33 '3' + 0x00,0x00,0x7c,0x44,0x08,0x10,0x38,0x04,0x04,0x04,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x34 '4' + 0x00,0x00,0x08,0x10,0x20,0x40,0x48,0x48,0x7c,0x08,0x08,0x1c,0x00,0x00,0x00, + + 7, // 0x35 '5' + 0x00,0x00,0x7c,0x40,0x40,0x40,0x78,0x04,0x04,0x04,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x36 '6' + 0x00,0x00,0x18,0x20,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x37 '7' + 0x00,0x00,0x7c,0x44,0x04,0x04,0x08,0x08,0x10,0x10,0x10,0x10,0x00,0x00,0x00, + + 7, // 0x38 '8' + 0x00,0x00,0x38,0x44,0x44,0x44,0x38,0x44,0x44,0x44,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x39 '9' + 0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x3c,0x04,0x04,0x08,0x30,0x00,0x00,0x00, + + 7, // 0x3a ':' + 0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00, + + 7, // 0x3b ';' + 0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x30,0x30,0x60,0x00,0x00, + + 7, // 0x3c '<' + 0x00,0x00,0x00,0x04,0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x04,0x00,0x00,0x00, + + 7, // 0x3d '=' + 0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x3e '>' + 0x00,0x00,0x00,0x40,0x20,0x10,0x08,0x04,0x08,0x10,0x20,0x40,0x00,0x00,0x00, + + 7, // 0x3f '?' + 0x00,0x00,0x78,0x84,0x84,0x84,0x08,0x10,0x20,0x20,0x00,0x20,0x00,0x00,0x00, + + 7, // 0x40 '@' + 0x00,0x00,0x00,0x30,0x48,0x04,0x34,0x54,0x54,0x54,0x54,0x28,0x00,0x00,0x00, + + 7, // 0x41 'A' + 0x00,0x00,0x10,0x28,0x44,0x44,0x44,0x7c,0x44,0x44,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x42 'B' + 0x00,0x00,0x78,0x44,0x44,0x44,0x78,0x44,0x44,0x44,0x44,0x78,0x00,0x00,0x00, + + 7, // 0x43 'C' + 0x00,0x00,0x38,0x44,0x44,0x40,0x40,0x40,0x40,0x44,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x44 'D' + 0x00,0x00,0x70,0x48,0x44,0x44,0x44,0x44,0x44,0x44,0x48,0x70,0x00,0x00,0x00, + + 7, // 0x45 'E' + 0x00,0x00,0x7c,0x40,0x40,0x40,0x70,0x40,0x40,0x40,0x40,0x7c,0x00,0x00,0x00, + + 7, // 0x46 'F' + 0x00,0x00,0x7c,0x40,0x40,0x40,0x70,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00, + + 7, // 0x47 'G' + 0x00,0x00,0x38,0x44,0x40,0x40,0x40,0x5c,0x44,0x44,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x48 'H' + 0x00,0x00,0x44,0x44,0x44,0x44,0x7c,0x44,0x44,0x44,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x49 'I' + 0x00,0x00,0x38,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00,0x00, + + 7, // 0x4a 'J' + 0x00,0x00,0x1c,0x08,0x08,0x08,0x08,0x08,0x08,0x48,0x48,0x30,0x00,0x00,0x00, + + 7, // 0x4b 'K' + 0x00,0x00,0x44,0x44,0x48,0x50,0x60,0x50,0x48,0x44,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x4c 'L' + 0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7c,0x00,0x00,0x00, + + 7, // 0x4d 'M' + 0x00,0x00,0x44,0x6c,0x54,0x54,0x44,0x44,0x44,0x44,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x4e 'N' + 0x00,0x00,0x44,0x44,0x44,0x64,0x54,0x4c,0x44,0x44,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x4f 'O' + 0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x50 'P' + 0x00,0x00,0x78,0x44,0x44,0x44,0x44,0x78,0x40,0x40,0x40,0x40,0x00,0x00,0x00, + + 7, // 0x51 'Q' + 0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x44,0x54,0x48,0x34,0x00,0x00,0x00, + + 7, // 0x52 'R' + 0x00,0x00,0x78,0x44,0x44,0x44,0x44,0x78,0x50,0x48,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x53 'S' + 0x00,0x00,0x38,0x44,0x44,0x40,0x38,0x04,0x04,0x44,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x54 'T' + 0x00,0x00,0x7c,0x54,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00,0x00, + + 7, // 0x55 'U' + 0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x56 'V' + 0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x28,0x28,0x10,0x10,0x00,0x00,0x00, + + 7, // 0x57 'W' + 0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x54,0x54,0x6c,0x44,0x00,0x00,0x00, + + 7, // 0x58 'X' + 0x00,0x00,0x44,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x59 'Y' + 0x00,0x00,0x44,0x44,0x44,0x44,0x28,0x10,0x10,0x10,0x10,0x38,0x00,0x00,0x00, + + 7, // 0x5a 'Z' + 0x00,0x00,0x7c,0x04,0x04,0x08,0x10,0x20,0x40,0x40,0x40,0x7c,0x00,0x00,0x00, + + 7, // 0x5b '[' + 0x00,0x38,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x38,0x00,0x00, + + 7, // 0x5c '\' + 0x00,0x00,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x04,0x04,0x00,0x00,0x00, + + 7, // 0x5d ']' + 0x00,0x38,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x38,0x00,0x00, + + 7, // 0x5e '^' + 0x00,0x10,0x28,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x5f '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00, + + 7, // 0x60 '`' + 0x00,0x20,0x20,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x61 'a' + 0x00,0x00,0x00,0x00,0x38,0x44,0x04,0x3c,0x44,0x44,0x44,0x3a,0x00,0x00,0x00, + + 7, // 0x62 'b' + 0x00,0x00,0x40,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x44,0x78,0x00,0x00,0x00, + + 7, // 0x63 'c' + 0x00,0x00,0x00,0x00,0x38,0x44,0x40,0x40,0x40,0x40,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x64 'd' + 0x00,0x00,0x04,0x04,0x04,0x3c,0x44,0x44,0x44,0x44,0x44,0x3a,0x00,0x00,0x00, + + 7, // 0x65 'e' + 0x00,0x00,0x00,0x00,0x38,0x44,0x44,0x7c,0x40,0x40,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x66 'f' + 0x00,0x00,0x18,0x24,0x20,0x70,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00,0x00, + + 7, // 0x67 'g' + 0x00,0x00,0x00,0x00,0x3a,0x44,0x44,0x44,0x44,0x44,0x3c,0x04,0x44,0x38,0x00, + + 7, // 0x68 'h' + 0x00,0x00,0x40,0x40,0x40,0x58,0x64,0x44,0x44,0x44,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x69 'i' + 0x00,0x00,0x10,0x10,0x00,0x30,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00,0x00, + + 7, // 0x6a 'j' + 0x00,0x00,0x08,0x08,0x00,0x18,0x08,0x08,0x08,0x08,0x08,0x48,0x48,0x30,0x00, + + 7, // 0x6b 'k' + 0x00,0x00,0x40,0x40,0x44,0x44,0x48,0x50,0x60,0x50,0x48,0x44,0x00,0x00,0x00, + + 7, // 0x6c 'l' + 0x00,0x00,0x30,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00,0x00, + + 7, // 0x6d 'm' + 0x00,0x00,0x00,0x00,0xa8,0x54,0x54,0x54,0x54,0x54,0x54,0x54,0x00,0x00,0x00, + + 7, // 0x6e 'n' + 0x00,0x00,0x00,0x00,0xb8,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x6f 'o' + 0x00,0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x70 'p' + 0x00,0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x44,0x44,0x78,0x40,0x40,0x40,0x00, + + 7, // 0x71 'q' + 0x00,0x00,0x00,0x00,0x3c,0x44,0x44,0x44,0x44,0x44,0x3c,0x04,0x04,0x04,0x00, + + 7, // 0x72 'r' + 0x00,0x00,0x00,0x00,0x58,0x64,0x44,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00, + + 7, // 0x73 's' + 0x00,0x00,0x00,0x00,0x38,0x44,0x40,0x38,0x04,0x44,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x74 't' + 0x00,0x00,0x20,0x20,0x20,0x70,0x20,0x20,0x20,0x20,0x24,0x18,0x00,0x00,0x00, + + 7, // 0x75 'u' + 0x00,0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x3a,0x00,0x00,0x00, + + 7, // 0x76 'v' + 0x00,0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x28,0x28,0x10,0x10,0x00,0x00,0x00, + + 7, // 0x77 'w' + 0x00,0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x54,0x54,0x6c,0x44,0x00,0x00,0x00, + + 7, // 0x78 'x' + 0x00,0x00,0x00,0x00,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x79 'y' + 0x00,0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x3c,0x04,0x08,0x70,0x00, + + 7, // 0x7a 'z' + 0x00,0x00,0x00,0x00,0x7c,0x04,0x08,0x10,0x20,0x40,0x40,0x7c,0x00,0x00,0x00, + + 7, // 0x7b '{' + 0x00,0x0c,0x10,0x10,0x10,0x10,0x10,0x60,0x10,0x10,0x10,0x10,0x0c,0x00,0x00, + + 7, // 0x7c '|' + 0x00,0x20,0x20,0x20,0x20,0x20,0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x00,0x00, + + 7, // 0x7d '}' + 0x00,0x60,0x10,0x10,0x10,0x10,0x10,0x0c,0x10,0x10,0x10,0x10,0x60,0x00,0x00, + + 7, // 0x7e '~' + 0x00,0x00,0x64,0x98,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x7f '' + 0x00,0x00,0x00,0x00,0x00,0x10,0x28,0x44,0x44,0x7c,0x00,0x00,0x00,0x00,0x00, + 0 + }; + + const int8u gse7x15_bold[] = + { + 15, 0, 32, 128-32, + + 0x00,0x00,0x10,0x00,0x20,0x00,0x30,0x00,0x40,0x00,0x50,0x00,0x60,0x00,0x70,0x00,0x80,0x00, + 0x90,0x00,0xa0,0x00,0xb0,0x00,0xc0,0x00,0xd0,0x00,0xe0,0x00,0xf0,0x00,0x00,0x01,0x10,0x01, + 0x20,0x01,0x30,0x01,0x40,0x01,0x50,0x01,0x60,0x01,0x70,0x01,0x80,0x01,0x90,0x01,0xa0,0x01, + 0xb0,0x01,0xc0,0x01,0xd0,0x01,0xe0,0x01,0xf0,0x01,0x00,0x02,0x10,0x02,0x20,0x02,0x30,0x02, + 0x40,0x02,0x50,0x02,0x60,0x02,0x70,0x02,0x80,0x02,0x90,0x02,0xa0,0x02,0xb0,0x02,0xc0,0x02, + 0xd0,0x02,0xe0,0x02,0xf0,0x02,0x00,0x03,0x10,0x03,0x20,0x03,0x30,0x03,0x40,0x03,0x50,0x03, + 0x60,0x03,0x70,0x03,0x80,0x03,0x90,0x03,0xa0,0x03,0xb0,0x03,0xc0,0x03,0xd0,0x03,0xe0,0x03, + 0xf0,0x03,0x00,0x04,0x10,0x04,0x20,0x04,0x30,0x04,0x40,0x04,0x50,0x04,0x60,0x04,0x70,0x04, + 0x80,0x04,0x90,0x04,0xa0,0x04,0xb0,0x04,0xc0,0x04,0xd0,0x04,0xe0,0x04,0xf0,0x04,0x00,0x05, + 0x10,0x05,0x20,0x05,0x30,0x05,0x40,0x05,0x50,0x05,0x60,0x05,0x70,0x05,0x80,0x05,0x90,0x05, + 0xa0,0x05,0xb0,0x05,0xc0,0x05,0xd0,0x05,0xe0,0x05,0xf0,0x05, + + 7, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x21 '!' + 0x00,0x00,0x00,0x30,0x78,0x78,0x78,0x30,0x30,0x00,0x30,0x30,0x00,0x00,0x00, + + 7, // 0x22 '"' + 0x00,0x00,0x6c,0x6c,0x6c,0x28,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x23 '#' + 0x00,0x00,0x48,0x48,0x48,0xfc,0x48,0x48,0xfc,0x48,0x48,0x48,0x00,0x00,0x00, + + 7, // 0x24 '$' + 0x00,0x30,0x30,0x78,0xcc,0xe0,0x70,0x38,0x1c,0xcc,0x78,0x30,0x30,0x00,0x00, + + 7, // 0x25 '%' + 0x00,0x00,0x00,0x64,0x6c,0x08,0x18,0x10,0x30,0x20,0x6c,0x4c,0x00,0x00,0x00, + + 7, // 0x26 '&' + 0x00,0x00,0x00,0x30,0x58,0x58,0x30,0x74,0xdc,0xd8,0xd8,0x6c,0x00,0x00,0x00, + + 7, // 0x27 ''' + 0x00,0x00,0x30,0x30,0x30,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x28 '(' + 0x00,0x0c,0x18,0x30,0x60,0x60,0x60,0x60,0x60,0x30,0x18,0x0c,0x00,0x00,0x00, + + 7, // 0x29 ')' + 0x00,0xc0,0x60,0x30,0x18,0x18,0x18,0x18,0x18,0x30,0x60,0xc0,0x00,0x00,0x00, + + 7, // 0x2a '*' + 0x00,0x00,0x00,0x00,0x00,0x20,0xa8,0x70,0xa8,0x20,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x2b '+' + 0x00,0x00,0x00,0x00,0x00,0x30,0x30,0xfc,0x30,0x30,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x2c ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x60,0x00, + + 7, // 0x2d '-' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x2e '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00, + + 7, // 0x2f '/' + 0x00,0x00,0x0c,0x0c,0x18,0x18,0x30,0x30,0x60,0x60,0xc0,0xc0,0x00,0x00,0x00, + + 7, // 0x30 '0' + 0x00,0x00,0x78,0xcc,0xcc,0xcc,0xdc,0xec,0xcc,0xcc,0xcc,0x78,0x00,0x00,0x00, + + 7, // 0x31 '1' + 0x00,0x00,0x30,0x30,0x70,0xf0,0x30,0x30,0x30,0x30,0x30,0xfc,0x00,0x00,0x00, + + 7, // 0x32 '2' + 0x00,0x00,0x78,0xcc,0xcc,0x0c,0x18,0x30,0x60,0xc0,0xcc,0xfc,0x00,0x00,0x00, + + 7, // 0x33 '3' + 0x00,0x00,0xfc,0x8c,0x18,0x30,0x78,0x0c,0x0c,0x0c,0xcc,0x78,0x00,0x00,0x00, + + 7, // 0x34 '4' + 0x00,0x00,0x18,0x30,0x60,0xc8,0xd8,0xd8,0xfc,0x18,0x18,0x3c,0x00,0x00,0x00, + + 7, // 0x35 '5' + 0x00,0x00,0xfc,0xc0,0xc0,0xc0,0xf8,0x0c,0x0c,0x0c,0xcc,0x78,0x00,0x00,0x00, + + 7, // 0x36 '6' + 0x00,0x00,0x38,0x60,0xc0,0xc0,0xf8,0xcc,0xcc,0xcc,0xcc,0x78,0x00,0x00,0x00, + + 7, // 0x37 '7' + 0x00,0x00,0xfc,0x8c,0x0c,0x0c,0x18,0x18,0x30,0x30,0x30,0x30,0x00,0x00,0x00, + + 7, // 0x38 '8' + 0x00,0x00,0x78,0xcc,0xcc,0xcc,0x78,0xcc,0xcc,0xcc,0xcc,0x78,0x00,0x00,0x00, + + 7, // 0x39 '9' + 0x00,0x00,0x78,0xcc,0xcc,0xcc,0xcc,0x7c,0x0c,0x0c,0x18,0x70,0x00,0x00,0x00, + + 7, // 0x3a ':' + 0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00, + + 7, // 0x3b ';' + 0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x60,0x00, + + 7, // 0x3c '<' + 0x00,0x00,0x00,0x0c,0x18,0x30,0x60,0xc0,0x60,0x30,0x18,0x0c,0x00,0x00,0x00, + + 7, // 0x3d '=' + 0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0xfc,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x3e '>' + 0x00,0x00,0x00,0xc0,0x60,0x30,0x18,0x0c,0x18,0x30,0x60,0xc0,0x00,0x00,0x00, + + 7, // 0x3f '?' + 0x00,0x00,0x78,0xcc,0xcc,0x18,0x30,0x30,0x30,0x00,0x30,0x30,0x00,0x00,0x00, + + 7, // 0x40 '@' + 0x00,0x00,0x00,0x70,0x88,0x04,0x74,0xb4,0xb4,0xb4,0xb4,0x68,0x00,0x00,0x00, + + 7, // 0x41 'A' + 0x00,0x00,0x30,0x78,0xcc,0xcc,0xcc,0xfc,0xcc,0xcc,0xcc,0xcc,0x00,0x00,0x00, + + 7, // 0x42 'B' + 0x00,0x00,0xf8,0xcc,0xcc,0xcc,0xf8,0xcc,0xcc,0xcc,0xcc,0xf8,0x00,0x00,0x00, + + 7, // 0x43 'C' + 0x00,0x00,0x78,0xcc,0xc4,0xc0,0xc0,0xc0,0xc0,0xc4,0xcc,0x78,0x00,0x00,0x00, + + 7, // 0x44 'D' + 0x00,0x00,0xf0,0xd8,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xd8,0xf0,0x00,0x00,0x00, + + 7, // 0x45 'E' + 0x00,0x00,0xfc,0xc4,0xc0,0xd0,0xf0,0xd0,0xc0,0xc0,0xc4,0xfc,0x00,0x00,0x00, + + 7, // 0x46 'F' + 0x00,0x00,0xfc,0xc4,0xc0,0xd0,0xf0,0xd0,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00, + + 7, // 0x47 'G' + 0x00,0x00,0x78,0xcc,0xc0,0xc0,0xc0,0xdc,0xcc,0xcc,0xcc,0x78,0x00,0x00,0x00, + + 7, // 0x48 'H' + 0x00,0x00,0xcc,0xcc,0xcc,0xcc,0xfc,0xcc,0xcc,0xcc,0xcc,0xcc,0x00,0x00,0x00, + + 7, // 0x49 'I' + 0x00,0x00,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x78,0x00,0x00,0x00, + + 7, // 0x4a 'J' + 0x00,0x00,0x3c,0x18,0x18,0x18,0x18,0x18,0x18,0xd8,0xd8,0x70,0x00,0x00,0x00, + + 7, // 0x4b 'K' + 0x00,0x00,0xcc,0xcc,0xd8,0xd8,0xf0,0xd8,0xd8,0xcc,0xcc,0xcc,0x00,0x00,0x00, + + 7, // 0x4c 'L' + 0x00,0x00,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc0,0xc4,0xfc,0x00,0x00,0x00, + + 7, // 0x4d 'M' + 0x00,0x00,0x84,0xcc,0xfc,0xb4,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x00,0x00,0x00, + + 7, // 0x4e 'N' + 0x00,0x00,0xcc,0xcc,0xcc,0xec,0xfc,0xdc,0xcc,0xcc,0xcc,0xcc,0x00,0x00,0x00, + + 7, // 0x4f 'O' + 0x00,0x00,0x78,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x78,0x00,0x00,0x00, + + 7, // 0x50 'P' + 0x00,0x00,0xf8,0xcc,0xcc,0xcc,0xcc,0xf8,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00, + + 7, // 0x51 'Q' + 0x00,0x00,0x78,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xdc,0x78,0x18,0x0c,0x00,0x00, + + 7, // 0x52 'R' + 0x00,0x00,0xf8,0xcc,0xcc,0xcc,0xcc,0xf8,0xd8,0xcc,0xcc,0xcc,0x00,0x00,0x00, + + 7, // 0x53 'S' + 0x00,0x00,0x78,0xcc,0xcc,0xe0,0x70,0x38,0x1c,0xcc,0xcc,0x78,0x00,0x00,0x00, + + 7, // 0x54 'T' + 0x00,0x00,0xfc,0xb4,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,0x00,0x00, + + 7, // 0x55 'U' + 0x00,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x78,0x00,0x00,0x00, + + 7, // 0x56 'V' + 0x00,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x78,0x30,0x00,0x00,0x00, + + 7, // 0x57 'W' + 0x00,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0xb4,0xfc,0xcc,0x84,0x00,0x00,0x00, + + 7, // 0x58 'X' + 0x00,0x00,0xcc,0xcc,0xcc,0x78,0x30,0x78,0xcc,0xcc,0xcc,0xcc,0x00,0x00,0x00, + + 7, // 0x59 'Y' + 0x00,0x00,0xcc,0xcc,0xcc,0xcc,0x78,0x30,0x30,0x30,0x30,0x78,0x00,0x00,0x00, + + 7, // 0x5a 'Z' + 0x00,0x00,0xfc,0x8c,0x0c,0x18,0x30,0x60,0xc0,0xc0,0xc4,0xfc,0x00,0x00,0x00, + + 7, // 0x5b '[' + 0x00,0x78,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x78,0x00,0x00, + + 7, // 0x5c '\' + 0x00,0x00,0xc0,0xc0,0x60,0x60,0x30,0x30,0x18,0x18,0x0c,0x0c,0x00,0x00,0x00, + + 7, // 0x5d ']' + 0x00,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x78,0x00,0x00, + + 7, // 0x5e '^' + 0x00,0x10,0x38,0x6c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x5f '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x00,0x00,0x00, + + 7, // 0x60 '`' + 0x00,0x30,0x30,0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x61 'a' + 0x00,0x00,0x00,0x00,0x70,0xd8,0x18,0x78,0xd8,0xd8,0xd8,0x6c,0x00,0x00,0x00, + + 7, // 0x62 'b' + 0x00,0x00,0x60,0x60,0x60,0x78,0x6c,0x6c,0x6c,0x6c,0x6c,0x78,0x00,0x00,0x00, + + 7, // 0x63 'c' + 0x00,0x00,0x00,0x00,0x78,0xcc,0xc0,0xc0,0xc0,0xc0,0xcc,0x78,0x00,0x00,0x00, + + 7, // 0x64 'd' + 0x00,0x00,0x18,0x18,0x18,0x78,0xd8,0xd8,0xd8,0xd8,0xd8,0x6c,0x00,0x00,0x00, + + 7, // 0x65 'e' + 0x00,0x00,0x00,0x00,0x78,0xcc,0xcc,0xfc,0xc0,0xc0,0xcc,0x78,0x00,0x00,0x00, + + 7, // 0x66 'f' + 0x00,0x00,0x30,0x68,0x60,0x60,0xf0,0x60,0x60,0x60,0x60,0xf0,0x00,0x00,0x00, + + 7, // 0x67 'g' + 0x00,0x00,0x00,0x00,0x6c,0xd8,0xd8,0xd8,0xd8,0xd8,0x78,0x18,0xd8,0x70,0x00, + + 7, // 0x68 'h' + 0x00,0x00,0xc0,0xc0,0xc0,0xd8,0xec,0xcc,0xcc,0xcc,0xcc,0xcc,0x00,0x00,0x00, + + 7, // 0x69 'i' + 0x00,0x00,0x30,0x30,0x00,0x70,0x30,0x30,0x30,0x30,0x30,0x78,0x00,0x00,0x00, + + 7, // 0x6a 'j' + 0x00,0x00,0x18,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0xd8,0xd8,0x70,0x00, + + 7, // 0x6b 'k' + 0x00,0x00,0xc0,0xc0,0xcc,0xcc,0xcc,0xd8,0xf0,0xd8,0xcc,0xcc,0x00,0x00,0x00, + + 7, // 0x6c 'l' + 0x00,0x00,0x70,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x78,0x00,0x00,0x00, + + 7, // 0x6d 'm' + 0x00,0x00,0x00,0x00,0xe8,0xfc,0xd4,0xd4,0xd4,0xc4,0xc4,0xc4,0x00,0x00,0x00, + + 7, // 0x6e 'n' + 0x00,0x00,0x00,0x00,0xd8,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x6c,0x00,0x00,0x00, + + 7, // 0x6f 'o' + 0x00,0x00,0x00,0x00,0x78,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x78,0x00,0x00,0x00, + + 7, // 0x70 'p' + 0x00,0x00,0x00,0x00,0xf8,0xcc,0xcc,0xcc,0xcc,0xcc,0xf8,0xc0,0xc0,0xc0,0x00, + + 7, // 0x71 'q' + 0x00,0x00,0x00,0x00,0x7c,0xcc,0xcc,0xcc,0xcc,0xcc,0x7c,0x0c,0x0c,0x0c,0x00, + + 7, // 0x72 'r' + 0x00,0x00,0x00,0x00,0xd8,0xec,0xcc,0xc0,0xc0,0xc0,0xc0,0xc0,0x00,0x00,0x00, + + 7, // 0x73 's' + 0x00,0x00,0x00,0x00,0x78,0xcc,0xe0,0x70,0x38,0x1c,0xcc,0x78,0x00,0x00,0x00, + + 7, // 0x74 't' + 0x00,0x00,0x20,0x60,0x60,0xf0,0x60,0x60,0x60,0x60,0x6c,0x38,0x00,0x00,0x00, + + 7, // 0x75 'u' + 0x00,0x00,0x00,0x00,0xd8,0xd8,0xd8,0xd8,0xd8,0xd8,0xd8,0x6c,0x00,0x00,0x00, + + 7, // 0x76 'v' + 0x00,0x00,0x00,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x78,0x30,0x00,0x00,0x00, + + 7, // 0x77 'w' + 0x00,0x00,0x00,0x00,0xcc,0xcc,0xcc,0xcc,0xb4,0xfc,0xcc,0x84,0x00,0x00,0x00, + + 7, // 0x78 'x' + 0x00,0x00,0x00,0x00,0xcc,0xcc,0x78,0x30,0x78,0xcc,0xcc,0xcc,0x00,0x00,0x00, + + 7, // 0x79 'y' + 0x00,0x00,0x00,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x7c,0x0c,0x18,0xf0,0x00, + + 7, // 0x7a 'z' + 0x00,0x00,0x00,0x00,0xfc,0x8c,0x18,0x30,0x60,0xc0,0xc4,0xfc,0x00,0x00,0x00, + + 7, // 0x7b '{' + 0x00,0x1c,0x30,0x30,0x30,0x30,0x30,0xe0,0x30,0x30,0x30,0x30,0x1c,0x00,0x00, + + 7, // 0x7c '|' + 0x00,0x30,0x30,0x30,0x30,0x30,0x00,0x00,0x30,0x30,0x30,0x30,0x30,0x00,0x00, + + 7, // 0x7d '}' + 0x00,0xe0,0x30,0x30,0x30,0x30,0x30,0x1c,0x30,0x30,0x30,0x30,0xe0,0x00,0x00, + + 7, // 0x7e '~' + 0x00,0x00,0x34,0x58,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x7f '' + 0x00,0x00,0x00,0x00,0x00,0x30,0x78,0xcc,0xcc,0xfc,0x00,0x00,0x00,0x00,0x00, + 0 + }; + + const int8u gse8x16[] = + { + 16, 0, 32, 128-32, + + 0x00,0x00,0x11,0x00,0x22,0x00,0x33,0x00,0x44,0x00,0x55,0x00,0x66,0x00,0x77,0x00,0x88,0x00, + 0x99,0x00,0xaa,0x00,0xbb,0x00,0xcc,0x00,0xdd,0x00,0xee,0x00,0xff,0x00,0x10,0x01,0x21,0x01, + 0x32,0x01,0x43,0x01,0x54,0x01,0x65,0x01,0x76,0x01,0x87,0x01,0x98,0x01,0xa9,0x01,0xba,0x01, + 0xcb,0x01,0xdc,0x01,0xed,0x01,0xfe,0x01,0x0f,0x02,0x20,0x02,0x31,0x02,0x42,0x02,0x53,0x02, + 0x64,0x02,0x75,0x02,0x86,0x02,0x97,0x02,0xa8,0x02,0xb9,0x02,0xca,0x02,0xdb,0x02,0xec,0x02, + 0xfd,0x02,0x0e,0x03,0x1f,0x03,0x30,0x03,0x41,0x03,0x52,0x03,0x63,0x03,0x74,0x03,0x85,0x03, + 0x96,0x03,0xa7,0x03,0xb8,0x03,0xc9,0x03,0xda,0x03,0xeb,0x03,0xfc,0x03,0x0d,0x04,0x1e,0x04, + 0x2f,0x04,0x40,0x04,0x51,0x04,0x62,0x04,0x73,0x04,0x84,0x04,0x95,0x04,0xa6,0x04,0xb7,0x04, + 0xc8,0x04,0xd9,0x04,0xea,0x04,0xfb,0x04,0x0c,0x05,0x1d,0x05,0x2e,0x05,0x3f,0x05,0x50,0x05, + 0x61,0x05,0x72,0x05,0x83,0x05,0x94,0x05,0xa5,0x05,0xb6,0x05,0xc7,0x05,0xd8,0x05,0xe9,0x05, + 0xfa,0x05,0x0b,0x06,0x1c,0x06,0x2d,0x06,0x3e,0x06,0x4f,0x06, + + 8, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x21 '!' + 0x00,0x00,0x10,0x38,0x38,0x38,0x38,0x10,0x10,0x00,0x10,0x10,0x00,0x00,0x00,0x00, + + 8, // 0x22 '"' + 0x00,0x24,0x24,0x24,0x24,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x23 '#' + 0x00,0x00,0x24,0x24,0x24,0x7e,0x24,0x24,0x7e,0x24,0x24,0x24,0x00,0x00,0x00,0x00, + + 8, // 0x24 '$' + 0x00,0x14,0x14,0x3e,0x55,0x54,0x54,0x3e,0x15,0x15,0x55,0x3e,0x14,0x14,0x00,0x00, + + 8, // 0x25 '%' + 0x00,0x00,0x32,0x56,0x6c,0x04,0x08,0x08,0x10,0x13,0x25,0x26,0x00,0x00,0x00,0x00, + + 8, // 0x26 '&' + 0x00,0x00,0x18,0x24,0x24,0x24,0x18,0x28,0x45,0x46,0x44,0x3b,0x00,0x00,0x00,0x00, + + 8, // 0x27 ''' + 0x00,0x00,0x08,0x08,0x08,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x28 '(' + 0x00,0x04,0x08,0x10,0x10,0x20,0x20,0x20,0x20,0x10,0x10,0x08,0x04,0x00,0x00,0x00, + + 8, // 0x29 ')' + 0x00,0x10,0x08,0x04,0x04,0x02,0x02,0x02,0x02,0x04,0x04,0x08,0x10,0x00,0x00,0x00, + + 8, // 0x2a '*' + 0x00,0x00,0x00,0x00,0x66,0x24,0x18,0xff,0x18,0x24,0x66,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x2b '+' + 0x00,0x00,0x00,0x00,0x08,0x08,0x08,0x7f,0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x2c ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x20,0x00, + + 8, // 0x2d '-' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x2e '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00, + + 8, // 0x2f '/' + 0x00,0x02,0x02,0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x00,0x00,0x00, + + 8, // 0x30 '0' + 0x00,0x00,0x3c,0x42,0x42,0x46,0x4a,0x52,0x62,0x42,0x42,0x3c,0x00,0x00,0x00,0x00, + + 8, // 0x31 '1' + 0x00,0x00,0x08,0x08,0x18,0x38,0x08,0x08,0x08,0x08,0x08,0x3e,0x00,0x00,0x00,0x00, + + 8, // 0x32 '2' + 0x00,0x00,0x3c,0x42,0x42,0x02,0x04,0x08,0x10,0x20,0x42,0x7e,0x00,0x00,0x00,0x00, + + 8, // 0x33 '3' + 0x00,0x00,0x7e,0x42,0x04,0x08,0x1c,0x02,0x02,0x02,0x42,0x3c,0x00,0x00,0x00,0x00, + + 8, // 0x34 '4' + 0x00,0x00,0x04,0x08,0x10,0x24,0x44,0x44,0x7e,0x04,0x04,0x0e,0x00,0x00,0x00,0x00, + + 8, // 0x35 '5' + 0x00,0x00,0x7e,0x42,0x40,0x40,0x7c,0x02,0x02,0x02,0x42,0x3c,0x00,0x00,0x00,0x00, + + 8, // 0x36 '6' + 0x00,0x00,0x1c,0x20,0x40,0x40,0x7c,0x42,0x42,0x42,0x42,0x3c,0x00,0x00,0x00,0x00, + + 8, // 0x37 '7' + 0x00,0x00,0x7e,0x42,0x42,0x02,0x04,0x08,0x10,0x10,0x10,0x10,0x00,0x00,0x00,0x00, + + 8, // 0x38 '8' + 0x00,0x00,0x3c,0x42,0x42,0x42,0x3c,0x42,0x42,0x42,0x42,0x3c,0x00,0x00,0x00,0x00, + + 8, // 0x39 '9' + 0x00,0x00,0x3c,0x42,0x42,0x42,0x42,0x3e,0x02,0x02,0x04,0x38,0x00,0x00,0x00,0x00, + + 8, // 0x3a ':' + 0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x3b ';' + 0x00,0x00,0x00,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x60,0x40,0x00, + + 8, // 0x3c '<' + 0x00,0x00,0x00,0x02,0x04,0x08,0x10,0x20,0x10,0x08,0x04,0x02,0x00,0x00,0x00,0x00, + + 8, // 0x3d '=' + 0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x00,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x3e '>' + 0x00,0x00,0x00,0x20,0x10,0x08,0x04,0x02,0x04,0x08,0x10,0x20,0x00,0x00,0x00,0x00, + + 8, // 0x3f '?' + 0x00,0x00,0x3c,0x42,0x42,0x42,0x04,0x08,0x08,0x00,0x08,0x08,0x00,0x00,0x00,0x00, + + 8, // 0x40 '@' + 0x00,0x00,0x3c,0x42,0x01,0x39,0x49,0x49,0x49,0x49,0x49,0x36,0x00,0x00,0x00,0x00, + + 8, // 0x41 'A' + 0x00,0x00,0x18,0x24,0x42,0x42,0x42,0x7e,0x42,0x42,0x42,0x42,0x00,0x00,0x00,0x00, + + 8, // 0x42 'B' + 0x00,0x00,0x7c,0x22,0x22,0x22,0x3c,0x22,0x22,0x22,0x22,0x7c,0x00,0x00,0x00,0x00, + + 8, // 0x43 'C' + 0x00,0x00,0x3c,0x42,0x42,0x40,0x40,0x40,0x40,0x42,0x42,0x3c,0x00,0x00,0x00,0x00, + + 8, // 0x44 'D' + 0x00,0x00,0x7c,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x22,0x7c,0x00,0x00,0x00,0x00, + + 8, // 0x45 'E' + 0x00,0x00,0x7e,0x22,0x20,0x28,0x38,0x28,0x20,0x20,0x22,0x7e,0x00,0x00,0x00,0x00, + + 8, // 0x46 'F' + 0x00,0x00,0x7e,0x22,0x20,0x28,0x38,0x28,0x20,0x20,0x20,0x70,0x00,0x00,0x00,0x00, + + 8, // 0x47 'G' + 0x00,0x00,0x3c,0x42,0x42,0x40,0x40,0x4e,0x42,0x42,0x42,0x3c,0x00,0x00,0x00,0x00, + + 8, // 0x48 'H' + 0x00,0x00,0x42,0x42,0x42,0x42,0x7e,0x42,0x42,0x42,0x42,0x42,0x00,0x00,0x00,0x00, + + 8, // 0x49 'I' + 0x00,0x00,0x1c,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x1c,0x00,0x00,0x00,0x00, + + 8, // 0x4a 'J' + 0x00,0x00,0x0e,0x04,0x04,0x04,0x04,0x04,0x04,0x44,0x44,0x38,0x00,0x00,0x00,0x00, + + 8, // 0x4b 'K' + 0x00,0x00,0x62,0x22,0x24,0x28,0x30,0x28,0x24,0x22,0x22,0x62,0x00,0x00,0x00,0x00, + + 8, // 0x4c 'L' + 0x00,0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x22,0x7e,0x00,0x00,0x00,0x00, + + 8, // 0x4d 'M' + 0x00,0x00,0x41,0x63,0x55,0x49,0x41,0x41,0x41,0x41,0x41,0x41,0x00,0x00,0x00,0x00, + + 8, // 0x4e 'N' + 0x00,0x00,0x42,0x42,0x62,0x52,0x4a,0x46,0x42,0x42,0x42,0x42,0x00,0x00,0x00,0x00, + + 8, // 0x4f 'O' + 0x00,0x00,0x3c,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x3c,0x00,0x00,0x00,0x00, + + 8, // 0x50 'P' + 0x00,0x00,0x7c,0x22,0x22,0x22,0x22,0x3c,0x20,0x20,0x20,0x70,0x00,0x00,0x00,0x00, + + 8, // 0x51 'Q' + 0x00,0x00,0x3c,0x42,0x42,0x42,0x42,0x42,0x42,0x4a,0x44,0x3a,0x02,0x00,0x00,0x00, + + 8, // 0x52 'R' + 0x00,0x00,0x7c,0x22,0x22,0x22,0x22,0x3c,0x28,0x24,0x22,0x62,0x00,0x00,0x00,0x00, + + 8, // 0x53 'S' + 0x00,0x00,0x3c,0x42,0x42,0x40,0x30,0x0c,0x02,0x42,0x42,0x3c,0x00,0x00,0x00,0x00, + + 8, // 0x54 'T' + 0x00,0x00,0x7f,0x49,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x1c,0x00,0x00,0x00,0x00, + + 8, // 0x55 'U' + 0x00,0x00,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x3c,0x00,0x00,0x00,0x00, + + 8, // 0x56 'V' + 0x00,0x00,0x41,0x41,0x41,0x41,0x22,0x22,0x14,0x14,0x08,0x08,0x00,0x00,0x00,0x00, + + 8, // 0x57 'W' + 0x00,0x00,0x41,0x41,0x41,0x41,0x41,0x49,0x49,0x55,0x63,0x41,0x00,0x00,0x00,0x00, + + 8, // 0x58 'X' + 0x00,0x00,0x42,0x42,0x42,0x24,0x18,0x18,0x24,0x42,0x42,0x42,0x00,0x00,0x00,0x00, + + 8, // 0x59 'Y' + 0x00,0x00,0x22,0x22,0x22,0x22,0x14,0x08,0x08,0x08,0x08,0x1c,0x00,0x00,0x00,0x00, + + 8, // 0x5a 'Z' + 0x00,0x00,0x7e,0x42,0x02,0x04,0x08,0x10,0x20,0x40,0x42,0x7e,0x00,0x00,0x00,0x00, + + 8, // 0x5b '[' + 0x00,0x1e,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x1e,0x00,0x00,0x00, + + 8, // 0x5c '\' + 0x00,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x04,0x04,0x02,0x02,0x00,0x00,0x00, + + 8, // 0x5d ']' + 0x00,0x3c,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x3c,0x00,0x00,0x00, + + 8, // 0x5e '^' + 0x00,0x00,0x08,0x14,0x22,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x5f '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0x00, + + 8, // 0x60 '`' + 0x00,0x00,0x08,0x08,0x08,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x61 'a' + 0x00,0x00,0x00,0x00,0x00,0x38,0x44,0x04,0x3c,0x44,0x44,0x3e,0x00,0x00,0x00,0x00, + + 8, // 0x62 'b' + 0x00,0x00,0x60,0x20,0x20,0x38,0x24,0x22,0x22,0x22,0x22,0x3c,0x00,0x00,0x00,0x00, + + 8, // 0x63 'c' + 0x00,0x00,0x00,0x00,0x00,0x3c,0x42,0x40,0x40,0x40,0x42,0x3c,0x00,0x00,0x00,0x00, + + 8, // 0x64 'd' + 0x00,0x00,0x0c,0x04,0x04,0x1c,0x24,0x44,0x44,0x44,0x44,0x3e,0x00,0x00,0x00,0x00, + + 8, // 0x65 'e' + 0x00,0x00,0x00,0x00,0x00,0x3c,0x42,0x42,0x7e,0x40,0x42,0x3c,0x00,0x00,0x00,0x00, + + 8, // 0x66 'f' + 0x00,0x00,0x0c,0x12,0x10,0x10,0x38,0x10,0x10,0x10,0x10,0x38,0x00,0x00,0x00,0x00, + + 8, // 0x67 'g' + 0x00,0x00,0x00,0x00,0x00,0x3e,0x44,0x44,0x44,0x44,0x44,0x3c,0x04,0x44,0x38,0x00, + + 8, // 0x68 'h' + 0x00,0x00,0x60,0x20,0x20,0x2c,0x32,0x22,0x22,0x22,0x22,0x62,0x00,0x00,0x00,0x00, + + 8, // 0x69 'i' + 0x00,0x00,0x08,0x08,0x00,0x18,0x08,0x08,0x08,0x08,0x08,0x1c,0x00,0x00,0x00,0x00, + + 8, // 0x6a 'j' + 0x00,0x00,0x04,0x04,0x00,0x0c,0x04,0x04,0x04,0x04,0x04,0x44,0x44,0x38,0x00,0x00, + + 8, // 0x6b 'k' + 0x00,0x00,0x60,0x20,0x20,0x22,0x24,0x28,0x38,0x24,0x22,0x62,0x00,0x00,0x00,0x00, + + 8, // 0x6c 'l' + 0x00,0x00,0x18,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x1c,0x00,0x00,0x00,0x00, + + 8, // 0x6d 'm' + 0x00,0x00,0x00,0x00,0x00,0x76,0x49,0x49,0x49,0x49,0x41,0x41,0x00,0x00,0x00,0x00, + + 8, // 0x6e 'n' + 0x00,0x00,0x00,0x00,0x00,0x5c,0x22,0x22,0x22,0x22,0x22,0x22,0x00,0x00,0x00,0x00, + + 8, // 0x6f 'o' + 0x00,0x00,0x00,0x00,0x00,0x3c,0x42,0x42,0x42,0x42,0x42,0x3c,0x00,0x00,0x00,0x00, + + 8, // 0x70 'p' + 0x00,0x00,0x00,0x00,0x00,0x7c,0x22,0x22,0x22,0x22,0x22,0x3c,0x20,0x20,0x70,0x00, + + 8, // 0x71 'q' + 0x00,0x00,0x00,0x00,0x00,0x3e,0x44,0x44,0x44,0x44,0x44,0x3c,0x04,0x04,0x0e,0x00, + + 8, // 0x72 'r' + 0x00,0x00,0x00,0x00,0x00,0x7c,0x22,0x22,0x20,0x20,0x20,0x70,0x00,0x00,0x00,0x00, + + 8, // 0x73 's' + 0x00,0x00,0x00,0x00,0x00,0x3c,0x42,0x40,0x3c,0x02,0x42,0x3c,0x00,0x00,0x00,0x00, + + 8, // 0x74 't' + 0x00,0x00,0x10,0x10,0x10,0x7c,0x10,0x10,0x10,0x10,0x12,0x0c,0x00,0x00,0x00,0x00, + + 8, // 0x75 'u' + 0x00,0x00,0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x3e,0x00,0x00,0x00,0x00, + + 8, // 0x76 'v' + 0x00,0x00,0x00,0x00,0x00,0x41,0x41,0x41,0x41,0x22,0x14,0x08,0x00,0x00,0x00,0x00, + + 8, // 0x77 'w' + 0x00,0x00,0x00,0x00,0x00,0x41,0x41,0x41,0x49,0x49,0x55,0x22,0x00,0x00,0x00,0x00, + + 8, // 0x78 'x' + 0x00,0x00,0x00,0x00,0x00,0x42,0x42,0x24,0x18,0x24,0x42,0x42,0x00,0x00,0x00,0x00, + + 8, // 0x79 'y' + 0x00,0x00,0x00,0x00,0x00,0x42,0x42,0x42,0x42,0x42,0x42,0x3e,0x02,0x04,0x78,0x00, + + 8, // 0x7a 'z' + 0x00,0x00,0x00,0x00,0x00,0x7e,0x44,0x08,0x10,0x20,0x42,0x7e,0x00,0x00,0x00,0x00, + + 8, // 0x7b '{' + 0x00,0x06,0x08,0x08,0x08,0x08,0x08,0x30,0x08,0x08,0x08,0x08,0x08,0x06,0x00,0x00, + + 8, // 0x7c '|' + 0x00,0x00,0x08,0x08,0x08,0x08,0x08,0x00,0x08,0x08,0x08,0x08,0x08,0x00,0x00,0x00, + + 8, // 0x7d '}' + 0x00,0x30,0x08,0x08,0x08,0x08,0x08,0x06,0x08,0x08,0x08,0x08,0x08,0x30,0x00,0x00, + + 8, // 0x7e '~' + 0x00,0x00,0x39,0x4e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x7f '' + 0x00,0x00,0x00,0x00,0x00,0x08,0x14,0x22,0x41,0x41,0x7f,0x00,0x00,0x00,0x00,0x00, + 0 + }; + + const int8u gse8x16_bold[] = + { + 16, 0, 32, 128-32, + + 0x00,0x00,0x11,0x00,0x22,0x00,0x33,0x00,0x44,0x00,0x55,0x00,0x66,0x00,0x77,0x00,0x88,0x00, + 0x99,0x00,0xaa,0x00,0xbb,0x00,0xcc,0x00,0xdd,0x00,0xee,0x00,0xff,0x00,0x10,0x01,0x21,0x01, + 0x32,0x01,0x43,0x01,0x54,0x01,0x65,0x01,0x76,0x01,0x87,0x01,0x98,0x01,0xa9,0x01,0xba,0x01, + 0xcb,0x01,0xdc,0x01,0xed,0x01,0xfe,0x01,0x0f,0x02,0x20,0x02,0x31,0x02,0x42,0x02,0x53,0x02, + 0x64,0x02,0x75,0x02,0x86,0x02,0x97,0x02,0xa8,0x02,0xb9,0x02,0xca,0x02,0xdb,0x02,0xec,0x02, + 0xfd,0x02,0x0e,0x03,0x1f,0x03,0x30,0x03,0x41,0x03,0x52,0x03,0x63,0x03,0x74,0x03,0x85,0x03, + 0x96,0x03,0xa7,0x03,0xb8,0x03,0xc9,0x03,0xda,0x03,0xeb,0x03,0xfc,0x03,0x0d,0x04,0x1e,0x04, + 0x2f,0x04,0x40,0x04,0x51,0x04,0x62,0x04,0x73,0x04,0x84,0x04,0x95,0x04,0xa6,0x04,0xb7,0x04, + 0xc8,0x04,0xd9,0x04,0xea,0x04,0xfb,0x04,0x0c,0x05,0x1d,0x05,0x2e,0x05,0x3f,0x05,0x50,0x05, + 0x61,0x05,0x72,0x05,0x83,0x05,0x94,0x05,0xa5,0x05,0xb6,0x05,0xc7,0x05,0xd8,0x05,0xe9,0x05, + 0xfa,0x05,0x0b,0x06,0x1c,0x06,0x2d,0x06,0x3e,0x06,0x4f,0x06, + + 8, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x21 '!' + 0x00,0x00,0x18,0x3c,0x3c,0x3c,0x3c,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00,0x00, + + 8, // 0x22 '"' + 0x00,0x66,0x66,0x66,0x66,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x23 '#' + 0x00,0x00,0x66,0x66,0x66,0xff,0x66,0x66,0xff,0x66,0x66,0x66,0x00,0x00,0x00,0x00, + + 8, // 0x24 '$' + 0x00,0x08,0x08,0x3e,0x6b,0x6b,0x68,0x3e,0x0b,0x6b,0x6b,0x3e,0x08,0x08,0x00,0x00, + + 8, // 0x25 '%' + 0x00,0x00,0x66,0xbe,0xcc,0x0c,0x18,0x18,0x30,0x33,0x65,0x66,0x00,0x00,0x00,0x00, + + 8, // 0x26 '&' + 0x00,0x00,0x1c,0x36,0x36,0x36,0x1c,0x3b,0x6e,0x66,0x66,0x3b,0x00,0x00,0x00,0x00, + + 8, // 0x27 ''' + 0x00,0x00,0x18,0x18,0x18,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x28 '(' + 0x00,0x06,0x0c,0x18,0x18,0x30,0x30,0x30,0x30,0x18,0x18,0x0c,0x06,0x00,0x00,0x00, + + 8, // 0x29 ')' + 0x00,0x30,0x18,0x0c,0x0c,0x06,0x06,0x06,0x06,0x0c,0x0c,0x18,0x30,0x00,0x00,0x00, + + 8, // 0x2a '*' + 0x00,0x00,0x00,0x00,0x66,0x24,0x18,0xff,0x18,0x24,0x66,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x2b '+' + 0x00,0x00,0x00,0x00,0x18,0x18,0x18,0xff,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x2c ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x18,0x30,0x20,0x00, + + 8, // 0x2d '-' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x2e '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00, + + 8, // 0x2f '/' + 0x00,0x03,0x03,0x06,0x06,0x0c,0x0c,0x18,0x18,0x30,0x30,0x60,0x60,0x00,0x00,0x00, + + 8, // 0x30 '0' + 0x00,0x00,0x3e,0x63,0x63,0x67,0x6b,0x73,0x63,0x63,0x63,0x3e,0x00,0x00,0x00,0x00, + + 8, // 0x31 '1' + 0x00,0x00,0x0c,0x0c,0x1c,0x3c,0x0c,0x0c,0x0c,0x0c,0x0c,0x3f,0x00,0x00,0x00,0x00, + + 8, // 0x32 '2' + 0x00,0x00,0x3e,0x63,0x63,0x03,0x06,0x0c,0x18,0x30,0x61,0x7f,0x00,0x00,0x00,0x00, + + 8, // 0x33 '3' + 0x00,0x00,0x7f,0x43,0x06,0x0c,0x1e,0x03,0x03,0x03,0x63,0x3e,0x00,0x00,0x00,0x00, + + 8, // 0x34 '4' + 0x00,0x00,0x06,0x0c,0x18,0x32,0x66,0x66,0x7f,0x06,0x06,0x0f,0x00,0x00,0x00,0x00, + + 8, // 0x35 '5' + 0x00,0x00,0x7f,0x61,0x60,0x60,0x7e,0x03,0x03,0x03,0x63,0x3e,0x00,0x00,0x00,0x00, + + 8, // 0x36 '6' + 0x00,0x00,0x1e,0x30,0x60,0x60,0x7e,0x63,0x63,0x63,0x63,0x3e,0x00,0x00,0x00,0x00, + + 8, // 0x37 '7' + 0x00,0x00,0x7f,0x63,0x63,0x03,0x06,0x0c,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00, + + 8, // 0x38 '8' + 0x00,0x00,0x3e,0x63,0x63,0x63,0x3e,0x63,0x63,0x63,0x63,0x3e,0x00,0x00,0x00,0x00, + + 8, // 0x39 '9' + 0x00,0x00,0x3e,0x63,0x63,0x63,0x63,0x3f,0x03,0x03,0x06,0x3c,0x00,0x00,0x00,0x00, + + 8, // 0x3a ':' + 0x00,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x3b ';' + 0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x60,0x40,0x00, + + 8, // 0x3c '<' + 0x00,0x00,0x00,0x06,0x0c,0x18,0x30,0x60,0x30,0x18,0x0c,0x06,0x00,0x00,0x00,0x00, + + 8, // 0x3d '=' + 0x00,0x00,0x00,0x00,0x00,0x00,0x7f,0x00,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x3e '>' + 0x00,0x00,0x00,0x30,0x18,0x0c,0x06,0x03,0x06,0x0c,0x18,0x30,0x00,0x00,0x00,0x00, + + 8, // 0x3f '?' + 0x00,0x00,0x3e,0x63,0x63,0x63,0x06,0x0c,0x0c,0x00,0x0c,0x0c,0x00,0x00,0x00,0x00, + + 8, // 0x40 '@' + 0x00,0x00,0x7c,0x86,0x03,0x73,0xdb,0xdb,0xdb,0xdb,0xdb,0x6e,0x00,0x00,0x00,0x00, + + 8, // 0x41 'A' + 0x00,0x00,0x08,0x1c,0x36,0x63,0x63,0x63,0x7f,0x63,0x63,0x63,0x00,0x00,0x00,0x00, + + 8, // 0x42 'B' + 0x00,0x00,0x7e,0x33,0x33,0x33,0x3e,0x33,0x33,0x33,0x33,0x7e,0x00,0x00,0x00,0x00, + + 8, // 0x43 'C' + 0x00,0x00,0x1e,0x33,0x61,0x60,0x60,0x60,0x60,0x61,0x33,0x1e,0x00,0x00,0x00,0x00, + + 8, // 0x44 'D' + 0x00,0x00,0x7c,0x36,0x33,0x33,0x33,0x33,0x33,0x33,0x36,0x7c,0x00,0x00,0x00,0x00, + + 8, // 0x45 'E' + 0x00,0x00,0x7f,0x33,0x31,0x34,0x3c,0x34,0x30,0x31,0x33,0x7f,0x00,0x00,0x00,0x00, + + 8, // 0x46 'F' + 0x00,0x00,0x7f,0x33,0x31,0x34,0x3c,0x34,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00, + + 8, // 0x47 'G' + 0x00,0x00,0x1f,0x33,0x61,0x60,0x60,0x6f,0x63,0x63,0x33,0x1e,0x00,0x00,0x00,0x00, + + 8, // 0x48 'H' + 0x00,0x00,0x63,0x63,0x63,0x63,0x7f,0x63,0x63,0x63,0x63,0x63,0x00,0x00,0x00,0x00, + + 8, // 0x49 'I' + 0x00,0x00,0x1e,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x1e,0x00,0x00,0x00,0x00, + + 8, // 0x4a 'J' + 0x00,0x00,0x0f,0x06,0x06,0x06,0x06,0x06,0x06,0x66,0x66,0x3c,0x00,0x00,0x00,0x00, + + 8, // 0x4b 'K' + 0x00,0x00,0x73,0x33,0x36,0x36,0x3c,0x36,0x36,0x33,0x33,0x73,0x00,0x00,0x00,0x00, + + 8, // 0x4c 'L' + 0x00,0x00,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x31,0x33,0x7f,0x00,0x00,0x00,0x00, + + 8, // 0x4d 'M' + 0x00,0x00,0x63,0x63,0x77,0x77,0x7f,0x6b,0x6b,0x63,0x63,0x63,0x00,0x00,0x00,0x00, + + 8, // 0x4e 'N' + 0x00,0x00,0x63,0x63,0x73,0x7b,0x6f,0x67,0x63,0x63,0x63,0x63,0x00,0x00,0x00,0x00, + + 8, // 0x4f 'O' + 0x00,0x00,0x1c,0x36,0x63,0x63,0x63,0x63,0x63,0x63,0x36,0x1c,0x00,0x00,0x00,0x00, + + 8, // 0x50 'P' + 0x00,0x00,0x7e,0x33,0x33,0x33,0x33,0x3e,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00, + + 8, // 0x51 'Q' + 0x00,0x00,0x1c,0x36,0x63,0x63,0x63,0x63,0x63,0x6f,0x36,0x1e,0x03,0x00,0x00,0x00, + + 8, // 0x52 'R' + 0x00,0x00,0x7e,0x33,0x33,0x33,0x33,0x3e,0x36,0x33,0x33,0x73,0x00,0x00,0x00,0x00, + + 8, // 0x53 'S' + 0x00,0x00,0x3e,0x63,0x63,0x30,0x18,0x0c,0x06,0x63,0x63,0x3e,0x00,0x00,0x00,0x00, + + 8, // 0x54 'T' + 0x00,0x00,0x3f,0x3f,0x2d,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x1e,0x00,0x00,0x00,0x00, + + 8, // 0x55 'U' + 0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x3e,0x00,0x00,0x00,0x00, + + 8, // 0x56 'V' + 0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x63,0x63,0x36,0x1c,0x08,0x00,0x00,0x00,0x00, + + 8, // 0x57 'W' + 0x00,0x00,0x63,0x63,0x63,0x6b,0x6b,0x7f,0x77,0x77,0x63,0x63,0x00,0x00,0x00,0x00, + + 8, // 0x58 'X' + 0x00,0x00,0x63,0x63,0x63,0x36,0x1c,0x1c,0x36,0x63,0x63,0x63,0x00,0x00,0x00,0x00, + + 8, // 0x59 'Y' + 0x00,0x00,0x33,0x33,0x33,0x33,0x1e,0x0c,0x0c,0x0c,0x0c,0x1e,0x00,0x00,0x00,0x00, + + 8, // 0x5a 'Z' + 0x00,0x00,0x7f,0x63,0x43,0x06,0x0c,0x18,0x30,0x61,0x63,0x7f,0x00,0x00,0x00,0x00, + + 8, // 0x5b '[' + 0x00,0x1f,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x1f,0x00,0x00,0x00, + + 8, // 0x5c '\' + 0x00,0x60,0x60,0x30,0x30,0x18,0x18,0x0c,0x0c,0x06,0x06,0x03,0x03,0x00,0x00,0x00, + + 8, // 0x5d ']' + 0x00,0x7c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x7c,0x00,0x00,0x00, + + 8, // 0x5e '^' + 0x00,0x00,0x08,0x1c,0x36,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x5f '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x00,0x00,0x00,0x00, + + 8, // 0x60 '`' + 0x00,0x00,0x18,0x18,0x18,0x0c,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x61 'a' + 0x00,0x00,0x00,0x00,0x00,0x3c,0x66,0x06,0x3e,0x66,0x66,0x3b,0x00,0x00,0x00,0x00, + + 8, // 0x62 'b' + 0x00,0x00,0x70,0x30,0x30,0x3c,0x36,0x33,0x33,0x33,0x33,0x3e,0x00,0x00,0x00,0x00, + + 8, // 0x63 'c' + 0x00,0x00,0x00,0x00,0x00,0x3e,0x63,0x63,0x60,0x60,0x63,0x3e,0x00,0x00,0x00,0x00, + + 8, // 0x64 'd' + 0x00,0x00,0x0e,0x06,0x06,0x1e,0x36,0x66,0x66,0x66,0x66,0x3b,0x00,0x00,0x00,0x00, + + 8, // 0x65 'e' + 0x00,0x00,0x00,0x00,0x00,0x3e,0x63,0x63,0x7f,0x60,0x63,0x3e,0x00,0x00,0x00,0x00, + + 8, // 0x66 'f' + 0x00,0x00,0x0e,0x1b,0x1b,0x18,0x3c,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00, + + 8, // 0x67 'g' + 0x00,0x00,0x00,0x00,0x00,0x3b,0x66,0x66,0x66,0x66,0x66,0x3e,0x06,0x66,0x3c,0x00, + + 8, // 0x68 'h' + 0x00,0x00,0x70,0x30,0x30,0x36,0x3b,0x33,0x33,0x33,0x33,0x73,0x00,0x00,0x00,0x00, + + 8, // 0x69 'i' + 0x00,0x00,0x0c,0x0c,0x00,0x1c,0x0c,0x0c,0x0c,0x0c,0x0c,0x1e,0x00,0x00,0x00,0x00, + + 8, // 0x6a 'j' + 0x00,0x00,0x06,0x06,0x00,0x0e,0x06,0x06,0x06,0x06,0x06,0x66,0x66,0x3c,0x00,0x00, + + 8, // 0x6b 'k' + 0x00,0x00,0x70,0x30,0x30,0x33,0x33,0x36,0x3c,0x36,0x33,0x73,0x00,0x00,0x00,0x00, + + 8, // 0x6c 'l' + 0x00,0x00,0x1c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x0c,0x1e,0x00,0x00,0x00,0x00, + + 8, // 0x6d 'm' + 0x00,0x00,0x00,0x00,0x00,0x76,0x7f,0x6b,0x6b,0x6b,0x63,0x63,0x00,0x00,0x00,0x00, + + 8, // 0x6e 'n' + 0x00,0x00,0x00,0x00,0x00,0x6e,0x33,0x33,0x33,0x33,0x33,0x33,0x00,0x00,0x00,0x00, + + 8, // 0x6f 'o' + 0x00,0x00,0x00,0x00,0x00,0x3e,0x63,0x63,0x63,0x63,0x63,0x3e,0x00,0x00,0x00,0x00, + + 8, // 0x70 'p' + 0x00,0x00,0x00,0x00,0x00,0x6e,0x33,0x33,0x33,0x33,0x33,0x3e,0x30,0x30,0x78,0x00, + + 8, // 0x71 'q' + 0x00,0x00,0x00,0x00,0x00,0x3b,0x66,0x66,0x66,0x66,0x66,0x3e,0x06,0x06,0x0f,0x00, + + 8, // 0x72 'r' + 0x00,0x00,0x00,0x00,0x00,0x6e,0x3b,0x33,0x30,0x30,0x30,0x78,0x00,0x00,0x00,0x00, + + 8, // 0x73 's' + 0x00,0x00,0x00,0x00,0x00,0x3e,0x63,0x60,0x3e,0x03,0x63,0x3e,0x00,0x00,0x00,0x00, + + 8, // 0x74 't' + 0x00,0x00,0x08,0x18,0x18,0x7e,0x18,0x18,0x18,0x18,0x1b,0x0e,0x00,0x00,0x00,0x00, + + 8, // 0x75 'u' + 0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x66,0x3b,0x00,0x00,0x00,0x00, + + 8, // 0x76 'v' + 0x00,0x00,0x00,0x00,0x00,0x63,0x63,0x63,0x63,0x36,0x1c,0x08,0x00,0x00,0x00,0x00, + + 8, // 0x77 'w' + 0x00,0x00,0x00,0x00,0x00,0x63,0x63,0x6b,0x6b,0x7f,0x36,0x36,0x00,0x00,0x00,0x00, + + 8, // 0x78 'x' + 0x00,0x00,0x00,0x00,0x00,0x63,0x63,0x36,0x1c,0x36,0x63,0x63,0x00,0x00,0x00,0x00, + + 8, // 0x79 'y' + 0x00,0x00,0x00,0x00,0x00,0x63,0x63,0x63,0x63,0x63,0x63,0x3f,0x03,0x06,0x7c,0x00, + + 8, // 0x7a 'z' + 0x00,0x00,0x00,0x00,0x00,0x7f,0x63,0x06,0x0c,0x18,0x31,0x7f,0x00,0x00,0x00,0x00, + + 8, // 0x7b '{' + 0x00,0x03,0x04,0x0c,0x0c,0x0c,0x08,0x30,0x08,0x0c,0x0c,0x0c,0x04,0x03,0x00,0x00, + + 8, // 0x7c '|' + 0x00,0x00,0x0c,0x0c,0x0c,0x0c,0x0c,0x00,0x0c,0x0c,0x0c,0x0c,0x0c,0x00,0x00,0x00, + + 8, // 0x7d '}' + 0x00,0x60,0x10,0x18,0x18,0x18,0x08,0x06,0x08,0x18,0x18,0x18,0x10,0x60,0x00,0x00, + + 8, // 0x7e '~' + 0x00,0x00,0x3b,0x6e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x7f '' + 0x00,0x00,0x00,0x00,0x00,0x08,0x1c,0x36,0x63,0x63,0x7f,0x00,0x00,0x00,0x00,0x00, + 0 + }; + + const int8u mcs11_prop[] = + { + 11, 2, 32, 128-32, + 0x00,0x00,0x0C,0x00,0x18,0x00,0x24,0x00,0x30,0x00,0x3C,0x00,0x48,0x00,0x54,0x00,0x60,0x00, + 0x6C,0x00,0x78,0x00,0x84,0x00,0x90,0x00,0x9C,0x00,0xA8,0x00,0xB4,0x00,0xC0,0x00,0xCC,0x00, + 0xD8,0x00,0xE4,0x00,0xF0,0x00,0xFC,0x00,0x08,0x01,0x14,0x01,0x20,0x01,0x2C,0x01,0x38,0x01, + 0x44,0x01,0x50,0x01,0x5C,0x01,0x68,0x01,0x74,0x01,0x80,0x01,0x8C,0x01,0x98,0x01,0xA4,0x01, + 0xB0,0x01,0xBC,0x01,0xC8,0x01,0xD4,0x01,0xE0,0x01,0xEC,0x01,0xF8,0x01,0x04,0x02,0x10,0x02, + 0x1C,0x02,0x28,0x02,0x34,0x02,0x40,0x02,0x4C,0x02,0x58,0x02,0x64,0x02,0x70,0x02,0x7C,0x02, + 0x88,0x02,0x94,0x02,0xA0,0x02,0xAC,0x02,0xB8,0x02,0xC4,0x02,0xD0,0x02,0xDC,0x02,0xE8,0x02, + 0xF4,0x02,0x00,0x03,0x0C,0x03,0x18,0x03,0x24,0x03,0x30,0x03,0x3C,0x03,0x48,0x03,0x54,0x03, + 0x60,0x03,0x6C,0x03,0x78,0x03,0x84,0x03,0x90,0x03,0x9C,0x03,0xA8,0x03,0xB4,0x03,0xC0,0x03, + 0xCC,0x03,0xD8,0x03,0xE4,0x03,0xF0,0x03,0xFC,0x03,0x08,0x04,0x14,0x04,0x20,0x04,0x2C,0x04, + 0x38,0x04,0x44,0x04,0x50,0x04,0x5C,0x04,0x68,0x04,0x74,0x04, + + 5, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x21 '!' + 0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00, + + 4, // 0x22 '"' + 0x50,0x50,0xA0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x23 '#' + 0x00,0x28,0x28,0x7C,0x28,0x28,0x28,0x7C,0x28,0x28,0x00, + + 6, // 0x24 '$' + 0x10,0x10,0x38,0x54,0x50,0x38,0x14,0x54,0x38,0x10,0x10, + + 6, // 0x25 '%' + 0x00,0x00,0x68,0xA8,0xD0,0x10,0x20,0x2C,0x54,0x58,0x00, + + 6, // 0x26 '&' + 0x00,0x20,0x50,0x50,0x50,0x20,0x54,0x54,0x48,0x34,0x00, + + 3, // 0x27 ''' + 0x40,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x28 '(' + 0x10,0x20,0x20,0x40,0x40,0x40,0x40,0x40,0x20,0x20,0x10, + + 5, // 0x29 ')' + 0x40,0x20,0x20,0x10,0x10,0x10,0x10,0x10,0x20,0x20,0x40, + + 6, // 0x2A '*' + 0x00,0x00,0x28,0x7C,0x38,0x7C,0x28,0x00,0x00,0x00,0x00, + + 6, // 0x2B '+' + 0x00,0x00,0x00,0x10,0x10,0x7C,0x10,0x10,0x00,0x00,0x00, + + 4, // 0x2C ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0xC0, + + 6, // 0x2D '-' + 0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x2E '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00, + + 7, // 0x2F '/' + 0x00,0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40, + + 6, // 0x30 '0' + 0x00,0x38,0x44,0x44,0x54,0x54,0x54,0x44,0x44,0x38,0x00, + + 4, // 0x31 '1' + 0x00,0x20,0x60,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00, + + 6, // 0x32 '2' + 0x00,0x38,0x44,0x44,0x04,0x08,0x10,0x20,0x40,0x7C,0x00, + + 6, // 0x33 '3' + 0x00,0x38,0x44,0x04,0x04,0x38,0x04,0x04,0x44,0x38,0x00, + + 6, // 0x34 '4' + 0x00,0x08,0x18,0x18,0x28,0x28,0x48,0x7C,0x08,0x08,0x00, + + 6, // 0x35 '5' + 0x00,0x7C,0x40,0x40,0x78,0x44,0x04,0x04,0x44,0x38,0x00, + + 6, // 0x36 '6' + 0x00,0x38,0x44,0x40,0x40,0x78,0x44,0x44,0x44,0x38,0x00, + + 6, // 0x37 '7' + 0x00,0x7C,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x20,0x00, + + 6, // 0x38 '8' + 0x00,0x38,0x44,0x44,0x44,0x38,0x44,0x44,0x44,0x38,0x00, + + 6, // 0x39 '9' + 0x00,0x38,0x44,0x44,0x44,0x3C,0x04,0x04,0x44,0x38,0x00, + + 4, // 0x3A ':' + 0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x60,0x60,0x00, + + 4, // 0x3B ';' + 0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x60,0x60,0xC0, + + 6, // 0x3C '<' + 0x00,0x04,0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x04,0x00, + + 6, // 0x3D '=' + 0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x7C,0x00,0x00,0x00, + + 6, // 0x3E '>' + 0x00,0x40,0x20,0x10,0x08,0x04,0x08,0x10,0x20,0x40,0x00, + + 6, // 0x3F '?' + 0x00,0x38,0x44,0x04,0x04,0x08,0x10,0x10,0x00,0x10,0x00, + + 6, // 0x40 '@' + 0x00,0x38,0x44,0x44,0x5C,0x54,0x54,0x4C,0x40,0x38,0x00, + + 6, // 0x41 'A' + 0x00,0x38,0x44,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x00, + + 6, // 0x42 'B' + 0x00,0x78,0x44,0x44,0x44,0x78,0x44,0x44,0x44,0x78,0x00, + + 6, // 0x43 'C' + 0x00,0x38,0x44,0x40,0x40,0x40,0x40,0x40,0x44,0x38,0x00, + + 6, // 0x44 'D' + 0x00,0x70,0x48,0x44,0x44,0x44,0x44,0x44,0x48,0x70,0x00, + + 6, // 0x45 'E' + 0x00,0x7C,0x40,0x40,0x40,0x78,0x40,0x40,0x40,0x7C,0x00, + + 6, // 0x46 'F' + 0x00,0x7C,0x40,0x40,0x40,0x78,0x40,0x40,0x40,0x40,0x00, + + 6, // 0x47 'G' + 0x00,0x38,0x44,0x40,0x40,0x5C,0x44,0x44,0x4C,0x34,0x00, + + 6, // 0x48 'H' + 0x00,0x44,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x44,0x00, + + 4, // 0x49 'I' + 0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00, + + 6, // 0x4A 'J' + 0x00,0x1C,0x08,0x08,0x08,0x08,0x08,0x08,0x48,0x30,0x00, + + 6, // 0x4B 'K' + 0x00,0x44,0x48,0x50,0x60,0x60,0x50,0x48,0x44,0x44,0x00, + + 6, // 0x4C 'L' + 0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7C,0x00, + + 8, // 0x4D 'M' + 0x00,0x41,0x63,0x55,0x49,0x49,0x41,0x41,0x41,0x41,0x00, + + 7, // 0x4E 'N' + 0x00,0x42,0x42,0x62,0x52,0x4A,0x46,0x42,0x42,0x42,0x00, + + 6, // 0x4F 'O' + 0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00, + + 6, // 0x50 'P' + 0x00,0x78,0x44,0x44,0x44,0x78,0x40,0x40,0x40,0x40,0x00, + + 6, // 0x51 'Q' + 0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x54,0x48,0x34,0x00, + + 6, // 0x52 'R' + 0x00,0x78,0x44,0x44,0x44,0x78,0x44,0x44,0x44,0x44,0x00, + + 6, // 0x53 'S' + 0x00,0x38,0x44,0x40,0x40,0x38,0x04,0x04,0x44,0x38,0x00, + + 6, // 0x54 'T' + 0x00,0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00, + + 6, // 0x55 'U' + 0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00, + + 6, // 0x56 'V' + 0x00,0x44,0x44,0x44,0x44,0x28,0x28,0x28,0x10,0x10,0x00, + + 8, // 0x57 'W' + 0x00,0x41,0x41,0x41,0x41,0x49,0x49,0x49,0x55,0x22,0x00, + + 6, // 0x58 'X' + 0x00,0x44,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x44,0x00, + + 6, // 0x59 'Y' + 0x00,0x44,0x44,0x44,0x28,0x10,0x10,0x10,0x10,0x10,0x00, + + 6, // 0x5A 'Z' + 0x00,0x7C,0x04,0x04,0x08,0x10,0x20,0x40,0x40,0x7C,0x00, + + 5, // 0x5B '[' + 0x30,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x30, + + 7, // 0x5C '\' + 0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x04,0x04,0x00, + + 4, // 0x5D ']' + 0x60,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x60, + + 6, // 0x5E '^' + 0x00,0x10,0x28,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x5F '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00, + + 4, // 0x60 '`' + 0x00,0x40,0x40,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x61 'a' + 0x00,0x00,0x00,0x38,0x04,0x3C,0x44,0x44,0x44,0x3C,0x00, + + 6, // 0x62 'b' + 0x00,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x44,0x78,0x00, + + 6, // 0x63 'c' + 0x00,0x00,0x00,0x38,0x44,0x40,0x40,0x40,0x44,0x38,0x00, + + 6, // 0x64 'd' + 0x00,0x04,0x04,0x3C,0x44,0x44,0x44,0x44,0x44,0x3C,0x00, + + 6, // 0x65 'e' + 0x00,0x00,0x00,0x38,0x44,0x44,0x7C,0x40,0x44,0x38,0x00, + + 4, // 0x66 'f' + 0x00,0x10,0x20,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x00, + + 6, // 0x67 'g' + 0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x3C,0x04,0x44,0x38, + + 6, // 0x68 'h' + 0x00,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x44,0x44,0x00, + + 2, // 0x69 'i' + 0x00,0x40,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00, + + 3, // 0x6A 'j' + 0x00,0x20,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0xA0,0x40, + + 5, // 0x6B 'k' + 0x00,0x40,0x40,0x48,0x50,0x60,0x60,0x50,0x48,0x48,0x00, + + 2, // 0x6C 'l' + 0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00, + + 8, // 0x6D 'm' + 0x00,0x00,0x00,0x76,0x49,0x49,0x49,0x49,0x41,0x41,0x00, + + 6, // 0x6E 'n' + 0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x44,0x44,0x44,0x00, + + 6, // 0x6F 'o' + 0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x38,0x00, + + 6, // 0x70 'p' + 0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x44,0x78,0x40,0x40, + + 6, // 0x71 'q' + 0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x44,0x3C,0x04,0x04, + + 6, // 0x72 'r' + 0x00,0x00,0x00,0x58,0x24,0x20,0x20,0x20,0x20,0x20,0x00, + + 6, // 0x73 's' + 0x00,0x00,0x00,0x38,0x44,0x40,0x38,0x04,0x44,0x38,0x00, + + 5, // 0x74 't' + 0x00,0x20,0x20,0x70,0x20,0x20,0x20,0x20,0x28,0x10,0x00, + + 6, // 0x75 'u' + 0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x4C,0x34,0x00, + + 6, // 0x76 'v' + 0x00,0x00,0x00,0x44,0x44,0x44,0x28,0x28,0x10,0x10,0x00, + + 8, // 0x77 'w' + 0x00,0x00,0x00,0x41,0x41,0x41,0x41,0x49,0x49,0x36,0x00, + + 6, // 0x78 'x' + 0x00,0x00,0x00,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x00, + + 6, // 0x79 'y' + 0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x3C,0x04,0x08,0x70, + + 6, // 0x7A 'z' + 0x00,0x00,0x00,0x7C,0x04,0x08,0x10,0x20,0x40,0x7C,0x00, + + 5, // 0x7B '{' + 0x18,0x20,0x20,0x20,0x20,0xC0,0x20,0x20,0x20,0x20,0x18, + + 3, // 0x7C '|' + 0x00,0x40,0x40,0x40,0x40,0x00,0x40,0x40,0x40,0x40,0x00, + + 5, // 0x7D '}' + 0xC0,0x20,0x20,0x20,0x20,0x18,0x20,0x20,0x20,0x20,0xC0, + + 6, // 0x7E '~' + 0x00,0x24,0x54,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x7F '' + 0x00,0x10,0x38,0x6C,0x44,0x44,0x7C,0x00,0x00,0x00,0x00, + + 0 + }; + + const int8u mcs11_prop_condensed[] = + { + 11, 2, 32, 128-32, + 0x00,0x00,0x0C,0x00,0x18,0x00,0x24,0x00,0x30,0x00,0x3C,0x00,0x48,0x00,0x54,0x00,0x60,0x00, + 0x6C,0x00,0x78,0x00,0x84,0x00,0x90,0x00,0x9C,0x00,0xA8,0x00,0xB4,0x00,0xC0,0x00,0xCC,0x00, + 0xD8,0x00,0xE4,0x00,0xF0,0x00,0xFC,0x00,0x08,0x01,0x14,0x01,0x20,0x01,0x2C,0x01,0x38,0x01, + 0x44,0x01,0x50,0x01,0x5C,0x01,0x68,0x01,0x74,0x01,0x80,0x01,0x8C,0x01,0x98,0x01,0xA4,0x01, + 0xB0,0x01,0xBC,0x01,0xC8,0x01,0xD4,0x01,0xE0,0x01,0xEC,0x01,0xF8,0x01,0x04,0x02,0x10,0x02, + 0x1C,0x02,0x28,0x02,0x34,0x02,0x40,0x02,0x4C,0x02,0x58,0x02,0x64,0x02,0x70,0x02,0x7C,0x02, + 0x88,0x02,0x94,0x02,0xA0,0x02,0xAC,0x02,0xB8,0x02,0xC4,0x02,0xD0,0x02,0xDC,0x02,0xE8,0x02, + 0xF4,0x02,0x00,0x03,0x0C,0x03,0x18,0x03,0x24,0x03,0x30,0x03,0x3C,0x03,0x48,0x03,0x54,0x03, + 0x60,0x03,0x6C,0x03,0x78,0x03,0x84,0x03,0x90,0x03,0x9C,0x03,0xA8,0x03,0xB4,0x03,0xC0,0x03, + 0xCC,0x03,0xD8,0x03,0xE4,0x03,0xF0,0x03,0xFC,0x03,0x08,0x04,0x14,0x04,0x20,0x04,0x2C,0x04, + 0x38,0x04,0x44,0x04,0x50,0x04,0x5C,0x04,0x68,0x04,0x74,0x04, + + 3, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 3, // 0x21 '!' + 0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x40,0x00, + + 4, // 0x22 '"' + 0x50,0x50,0xA0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x23 '#' + 0x00,0x50,0x50,0xF8,0x50,0x50,0x50,0xF8,0x50,0x50,0x00, + + 5, // 0x24 '$' + 0x00,0x40,0x60,0x90,0x80,0x60,0x10,0x90,0x60,0x20,0x00, + + 5, // 0x25 '%' + 0x00,0x00,0x90,0x90,0x20,0x20,0x40,0x40,0x90,0x90,0x00, + + 5, // 0x26 '&' + 0x00,0x40,0xA0,0xA0,0xA0,0x40,0xA8,0x90,0x90,0x68,0x00, + + 5, // 0x27 ''' + 0x00,0x00,0x20,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x28 '(' + 0x10,0x20,0x20,0x40,0x40,0x40,0x40,0x40,0x20,0x20,0x10, + + 4, // 0x29 ')' + 0x80,0x40,0x40,0x20,0x20,0x20,0x20,0x20,0x40,0x40,0x80, + + 5, // 0x2A '*' + 0x00,0x00,0x90,0x60,0xF0,0x60,0x90,0x00,0x00,0x00,0x00, + + 5, // 0x2B '+' + 0x00,0x00,0x00,0x20,0x20,0xF8,0x20,0x20,0x00,0x00,0x00, + + 4, // 0x2C ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0xC0, + + 5, // 0x2D '-' + 0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x2E '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0x00, + + 6, // 0x2F '/' + 0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x80,0x80,0x00, + + 5, // 0x30 '0' + 0x00,0x70,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0xE0,0x00, + + 3, // 0x31 '1' + 0x00,0x40,0xC0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00, + + 5, // 0x32 '2' + 0x00,0x60,0x90,0x90,0x10,0x10,0x20,0x40,0x80,0xF0,0x00, + + 5, // 0x33 '3' + 0x00,0x60,0x90,0x10,0x10,0x60,0x10,0x10,0x90,0x60,0x00, + + 5, // 0x34 '4' + 0x00,0x10,0x30,0x30,0x50,0x50,0x90,0xF0,0x10,0x10,0x00, + + 5, // 0x35 '5' + 0x00,0xF0,0x80,0x80,0xE0,0x90,0x10,0x10,0x90,0x60,0x00, + + 5, // 0x36 '6' + 0x00,0x60,0x90,0x80,0x80,0xE0,0x90,0x90,0x90,0x60,0x00, + + 5, // 0x37 '7' + 0x00,0xF0,0x10,0x10,0x10,0x20,0x20,0x40,0x40,0x40,0x00, + + 5, // 0x38 '8' + 0x00,0x60,0x90,0x90,0x90,0x60,0x90,0x90,0x90,0x60,0x00, + + 5, // 0x39 '9' + 0x00,0x60,0x90,0x90,0x90,0x70,0x10,0x10,0x90,0x60,0x00, + + 4, // 0x3A ':' + 0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x60,0x60,0x00, + + 4, // 0x3B ';' + 0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x60,0x60,0xC0, + + 6, // 0x3C '<' + 0x00,0x08,0x10,0x20,0x40,0x80,0x40,0x20,0x10,0x08,0x00, + + 5, // 0x3D '=' + 0x00,0x00,0x00,0x00,0xF0,0x00,0x00,0xF0,0x00,0x00,0x00, + + 6, // 0x3E '>' + 0x00,0x80,0x40,0x20,0x10,0x08,0x10,0x20,0x40,0x80,0x00, + + 5, // 0x3F '?' + 0x00,0x60,0x90,0x10,0x10,0x20,0x40,0x00,0x40,0x00,0x00, + + 5, // 0x40 '@' + 0x00,0x60,0x90,0x90,0xB0,0xB0,0xB0,0x80,0x80,0x70,0x00, + + 5, // 0x41 'A' + 0x00,0x60,0x90,0x90,0x90,0xF0,0x90,0x90,0x90,0x90,0x00, + + 5, // 0x42 'B' + 0x00,0xE0,0x90,0x90,0x90,0xE0,0x90,0x90,0x90,0xE0,0x00, + + 5, // 0x43 'C' + 0x00,0x60,0x90,0x80,0x80,0x80,0x80,0x80,0x90,0x60,0x00, + + 5, // 0x44 'D' + 0x00,0xE0,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0xE0,0x00, + + 5, // 0x45 'E' + 0x00,0xF0,0x80,0x80,0x80,0xF0,0x80,0x80,0x80,0xF0,0x00, + + 5, // 0x46 'F' + 0x00,0xF0,0x80,0x80,0x80,0xF0,0x80,0x80,0x80,0x80,0x00, + + 5, // 0x47 'G' + 0x00,0x70,0x80,0x80,0x80,0xB0,0x90,0x90,0x90,0x60,0x00, + + 5, // 0x48 'H' + 0x00,0x90,0x90,0x90,0x90,0xF0,0x90,0x90,0x90,0x90,0x00, + + 4, // 0x49 'I' + 0x00,0xE0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0xE0,0x00, + + 5, // 0x4A 'J' + 0x00,0x70,0x20,0x20,0x20,0x20,0x20,0xA0,0xA0,0x40,0x00, + + 5, // 0x4B 'K' + 0x00,0x90,0x90,0xA0,0xA0,0xC0,0xA0,0xA0,0x90,0x90,0x00, + + 5, // 0x4C 'L' + 0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xF0,0x00, + + 6, // 0x4D 'M' + 0x00,0x88,0xD8,0xA8,0xA8,0xA8,0x88,0x88,0x88,0x88,0x00, + + 5, // 0x4E 'N' + 0x00,0x90,0x90,0xD0,0xD0,0xB0,0xB0,0x90,0x90,0x90,0x00, + + 5, // 0x4F 'O' + 0x00,0x60,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x60,0x00, + + 5, // 0x50 'P' + 0x00,0xE0,0x90,0x90,0x90,0x90,0xE0,0x80,0x80,0x80,0x00, + + 5, // 0x51 'Q' + 0x00,0x60,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x60,0x30, + + 5, // 0x52 'R' + 0x00,0xE0,0x90,0x90,0x90,0x90,0xE0,0xA0,0x90,0x90,0x00, + + 5, // 0x53 'S' + 0x00,0x60,0x90,0x80,0x80,0x60,0x10,0x10,0x90,0x60,0x00, + + 6, // 0x54 'T' + 0x00,0xF8,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00, + + 5, // 0x55 'U' + 0x00,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x60,0x00, + + 6, // 0x56 'V' + 0x00,0x88,0x88,0x88,0x88,0x50,0x50,0x50,0x20,0x20,0x00, + + 6, // 0x57 'W' + 0x00,0x88,0x88,0x88,0xA8,0xA8,0xA8,0xA8,0xA8,0x50,0x00, + + 5, // 0x58 'X' + 0x00,0x90,0x90,0x90,0x60,0x60,0x90,0x90,0x90,0x90,0x00, + + 6, // 0x59 'Y' + 0x00,0x88,0x88,0x88,0x50,0x20,0x20,0x20,0x20,0x20,0x00, + + 5, // 0x5A 'Z' + 0x00,0xF0,0x10,0x20,0x20,0x40,0x40,0x80,0x80,0xF0,0x00, + + 4, // 0x5B '[' + 0x60,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x60,0x00, + + 6, // 0x5C '\' + 0x80,0x80,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x00, + + 4, // 0x5D ']' + 0x60,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x60,0x00, + + 5, // 0x5E '^' + 0x00,0x20,0x50,0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x5F '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x00, + + 5, // 0x60 '`' + 0x00,0x40,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x61 'a' + 0x00,0x00,0x00,0x60,0x90,0x10,0x70,0x90,0x90,0x70,0x00, + + 5, // 0x62 'b' + 0x00,0x80,0x80,0x80,0xE0,0x90,0x90,0x90,0x90,0xE0,0x00, + + 5, // 0x63 'c' + 0x00,0x00,0x00,0x60,0x90,0x80,0x80,0x80,0x90,0x60,0x00, + + 5, // 0x64 'd' + 0x00,0x10,0x10,0x10,0x70,0x90,0x90,0x90,0x90,0x70,0x00, + + 5, // 0x65 'e' + 0x00,0x00,0x00,0x60,0x90,0x90,0xF0,0x80,0x90,0x60,0x00, + + 4, // 0x66 'f' + 0x00,0x20,0x40,0x40,0xE0,0x40,0x40,0x40,0x40,0x40,0x00, + + 5, // 0x67 'g' + 0x00,0x00,0x00,0x70,0x90,0x90,0x90,0x70,0x10,0x90,0x60, + + 5, // 0x68 'h' + 0x00,0x80,0x80,0x80,0xE0,0x90,0x90,0x90,0x90,0x90,0x00, + + 2, // 0x69 'i' + 0x00,0x80,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00, + + 4, // 0x6A 'j' + 0x00,0x20,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0xA0,0x40, + + 5, // 0x6B 'k' + 0x00,0x80,0x80,0x90,0x90,0xA0,0xC0,0xA0,0x90,0x90,0x00, + + 2, // 0x6C 'l' + 0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00, + + 6, // 0x6D 'm' + 0x00,0x00,0x00,0xD0,0xA8,0xA8,0xA8,0x88,0x88,0x88,0x00, + + 5, // 0x6E 'n' + 0x00,0x00,0x00,0xA0,0xD0,0x90,0x90,0x90,0x90,0x90,0x00, + + 5, // 0x6F 'o' + 0x00,0x00,0x00,0x60,0x90,0x90,0x90,0x90,0x90,0x60,0x00, + + 5, // 0x70 'p' + 0x00,0x00,0x00,0xE0,0x90,0x90,0x90,0x90,0xE0,0x80,0x80, + + 5, // 0x71 'q' + 0x00,0x00,0x00,0x70,0x90,0x90,0x90,0x90,0x70,0x10,0x10, + + 6, // 0x72 'r' + 0x00,0x00,0x00,0xB8,0x48,0x40,0x40,0x40,0x40,0x40,0x00, + + 5, // 0x73 's' + 0x00,0x00,0x00,0x60,0x90,0x40,0x20,0x10,0x90,0x60,0x00, + + 4, // 0x74 't' + 0x00,0x40,0x40,0xE0,0x40,0x40,0x40,0x40,0x40,0x20,0x00, + + 5, // 0x75 'u' + 0x00,0x00,0x00,0x90,0x90,0x90,0x90,0x90,0x90,0x70,0x00, + + 6, // 0x76 'v' + 0x00,0x00,0x00,0x88,0x88,0x88,0x50,0x50,0x20,0x20,0x00, + + 6, // 0x77 'w' + 0x00,0x00,0x00,0x88,0x88,0x88,0xA8,0xA8,0xA8,0x50,0x00, + + 5, // 0x78 'x' + 0x00,0x00,0x00,0x90,0x90,0x60,0x60,0x90,0x90,0x90,0x00, + + 5, // 0x79 'y' + 0x00,0x00,0x00,0x90,0x90,0x90,0x90,0x70,0x10,0x20,0xC0, + + 5, // 0x7A 'z' + 0x00,0x00,0x00,0xF0,0x10,0x20,0x40,0x80,0x80,0xF0,0x00, + + 5, // 0x7B '{' + 0x30,0x40,0x40,0x40,0x40,0x80,0x40,0x40,0x40,0x40,0x30, + + 3, // 0x7C '|' + 0x00,0x40,0x40,0x40,0x40,0x00,0x40,0x40,0x40,0x40,0x00, + + 5, // 0x7D '}' + 0xC0,0x20,0x20,0x20,0x20,0x10,0x20,0x20,0x20,0x20,0xC0, + + 5, // 0x7E '~' + 0x00,0x40,0xA8,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x7F '' + 0x00,0x20,0x70,0xD8,0x88,0x88,0xF8,0x00,0x00,0x00,0x00, + + 0 + }; + + const int8u mcs12_prop[] = + { + 12, 3, 32, 128-32, + 0x00,0x00,0x0D,0x00,0x1A,0x00,0x27,0x00,0x34,0x00,0x41,0x00,0x4E,0x00,0x5B,0x00,0x68,0x00, + 0x75,0x00,0x82,0x00,0x8F,0x00,0x9C,0x00,0xA9,0x00,0xB6,0x00,0xC3,0x00,0xD0,0x00,0xDD,0x00, + 0xEA,0x00,0xF7,0x00,0x04,0x01,0x11,0x01,0x1E,0x01,0x2B,0x01,0x38,0x01,0x45,0x01,0x52,0x01, + 0x5F,0x01,0x6C,0x01,0x79,0x01,0x86,0x01,0x93,0x01,0xA0,0x01,0xAD,0x01,0xBA,0x01,0xC7,0x01, + 0xD4,0x01,0xE1,0x01,0xEE,0x01,0xFB,0x01,0x08,0x02,0x15,0x02,0x22,0x02,0x2F,0x02,0x3C,0x02, + 0x49,0x02,0x62,0x02,0x6F,0x02,0x7C,0x02,0x89,0x02,0x96,0x02,0xA3,0x02,0xB0,0x02,0xBD,0x02, + 0xCA,0x02,0xD7,0x02,0xF0,0x02,0xFD,0x02,0x0A,0x03,0x17,0x03,0x24,0x03,0x31,0x03,0x3E,0x03, + 0x4B,0x03,0x58,0x03,0x65,0x03,0x72,0x03,0x7F,0x03,0x8C,0x03,0x99,0x03,0xA6,0x03,0xB3,0x03, + 0xC0,0x03,0xCD,0x03,0xDA,0x03,0xE7,0x03,0xF4,0x03,0x01,0x04,0x1A,0x04,0x27,0x04,0x34,0x04, + 0x41,0x04,0x4E,0x04,0x5B,0x04,0x68,0x04,0x75,0x04,0x82,0x04,0x8F,0x04,0xA8,0x04,0xB5,0x04, + 0xC2,0x04,0xCF,0x04,0xDC,0x04,0xE9,0x04,0xF6,0x04,0x03,0x05, + + 5, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x21 '!' + 0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00,0x00, + + 4, // 0x22 '"' + 0x50,0x50,0xA0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x23 '#' + 0x28,0x28,0x28,0x7C,0x28,0x28,0x28,0x7C,0x28,0x28,0x28,0x00, + + 6, // 0x24 '$' + 0x10,0x10,0x38,0x54,0x50,0x38,0x14,0x54,0x38,0x10,0x10,0x00, + + 7, // 0x25 '%' + 0x32,0x54,0x64,0x08,0x08,0x10,0x10,0x26,0x2A,0x4C,0x00,0x00, + + 7, // 0x26 '&' + 0x00,0x30,0x48,0x48,0x48,0x30,0x4A,0x4A,0x44,0x3A,0x00,0x00, + + 3, // 0x27 ''' + 0x40,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x28 '(' + 0x10,0x20,0x20,0x40,0x40,0x40,0x40,0x40,0x20,0x20,0x10,0x00, + + 5, // 0x29 ')' + 0x40,0x20,0x20,0x10,0x10,0x10,0x10,0x10,0x20,0x20,0x40,0x00, + + 6, // 0x2A '*' + 0x00,0x00,0x10,0x54,0x38,0x7C,0x38,0x54,0x10,0x00,0x00,0x00, + + 6, // 0x2B '+' + 0x00,0x00,0x00,0x00,0x10,0x10,0x7C,0x10,0x10,0x00,0x00,0x00, + + 4, // 0x2C ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x40,0x80, + + 6, // 0x2D '-' + 0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x2E '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00, + + 7, // 0x2F '/' + 0x00,0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x00, + + 7, // 0x30 '0' + 0x00,0x38,0x44,0x44,0x54,0x54,0x54,0x44,0x44,0x38,0x00,0x00, + + 4, // 0x31 '1' + 0x00,0x20,0x60,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00, + + 7, // 0x32 '2' + 0x00,0x38,0x44,0x04,0x04,0x08,0x10,0x20,0x40,0x7C,0x00,0x00, + + 7, // 0x33 '3' + 0x00,0x38,0x44,0x04,0x04,0x38,0x04,0x04,0x44,0x38,0x00,0x00, + + 6, // 0x34 '4' + 0x00,0x08,0x18,0x28,0x28,0x48,0x48,0x7C,0x08,0x08,0x00,0x00, + + 7, // 0x35 '5' + 0x00,0x7C,0x40,0x40,0x78,0x44,0x04,0x04,0x44,0x38,0x00,0x00, + + 7, // 0x36 '6' + 0x00,0x38,0x44,0x40,0x78,0x44,0x44,0x44,0x44,0x38,0x00,0x00, + + 6, // 0x37 '7' + 0x00,0x7C,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x20,0x00,0x00, + + 7, // 0x38 '8' + 0x00,0x38,0x44,0x44,0x44,0x38,0x44,0x44,0x44,0x38,0x00,0x00, + + 7, // 0x39 '9' + 0x00,0x38,0x44,0x44,0x44,0x3C,0x04,0x04,0x44,0x38,0x00,0x00, + + 4, // 0x3A ':' + 0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x60,0x60,0x00,0x00, + + 4, // 0x3B ';' + 0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x60,0x60,0x40,0x80, + + 6, // 0x3C '<' + 0x00,0x00,0x04,0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x04,0x00, + + 6, // 0x3D '=' + 0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x7C,0x00,0x00,0x00,0x00, + + 6, // 0x3E '>' + 0x00,0x00,0x40,0x20,0x10,0x08,0x04,0x08,0x10,0x20,0x40,0x00, + + 6, // 0x3F '?' + 0x00,0x38,0x44,0x04,0x04,0x08,0x10,0x10,0x00,0x10,0x00,0x00, + + 7, // 0x40 '@' + 0x00,0x38,0x44,0x44,0x5C,0x54,0x54,0x4C,0x40,0x38,0x00,0x00, + + 7, // 0x41 'A' + 0x00,0x38,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x44,0x00,0x00, + + 7, // 0x42 'B' + 0x00,0x78,0x44,0x44,0x44,0x78,0x44,0x44,0x44,0x78,0x00,0x00, + + 6, // 0x43 'C' + 0x00,0x38,0x44,0x40,0x40,0x40,0x40,0x40,0x44,0x38,0x00,0x00, + + 7, // 0x44 'D' + 0x00,0x70,0x48,0x44,0x44,0x44,0x44,0x44,0x48,0x70,0x00,0x00, + + 6, // 0x45 'E' + 0x00,0x7C,0x40,0x40,0x40,0x78,0x40,0x40,0x40,0x7C,0x00,0x00, + + 6, // 0x46 'F' + 0x00,0x7C,0x40,0x40,0x40,0x78,0x40,0x40,0x40,0x40,0x00,0x00, + + 7, // 0x47 'G' + 0x00,0x38,0x44,0x40,0x40,0x5C,0x44,0x44,0x4C,0x34,0x00,0x00, + + 7, // 0x48 'H' + 0x00,0x44,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x44,0x00,0x00, + + 5, // 0x49 'I' + 0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, + + 6, // 0x4A 'J' + 0x00,0x1C,0x08,0x08,0x08,0x08,0x08,0x48,0x48,0x30,0x00,0x00, + + 6, // 0x4B 'K' + 0x00,0x44,0x48,0x50,0x60,0x60,0x50,0x48,0x44,0x44,0x00,0x00, + + 6, // 0x4C 'L' + 0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7C,0x00,0x00, + + 9, // 0x4D 'M' + 0x00,0x00,0x41,0x00,0x63,0x00,0x55,0x00,0x49,0x00,0x49,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x4E 'N' + 0x00,0x44,0x64,0x64,0x54,0x54,0x4C,0x4C,0x44,0x44,0x00,0x00, + + 7, // 0x4F 'O' + 0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00, + + 7, // 0x50 'P' + 0x00,0x78,0x44,0x44,0x44,0x44,0x78,0x40,0x40,0x40,0x00,0x00, + + 7, // 0x51 'Q' + 0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x54,0x48,0x34,0x00,0x00, + + 7, // 0x52 'R' + 0x00,0x78,0x44,0x44,0x44,0x44,0x78,0x48,0x44,0x44,0x00,0x00, + + 7, // 0x53 'S' + 0x00,0x38,0x44,0x40,0x40,0x38,0x04,0x04,0x44,0x38,0x00,0x00, + + 6, // 0x54 'T' + 0x00,0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00, + + 7, // 0x55 'U' + 0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00, + + 6, // 0x56 'V' + 0x00,0x44,0x44,0x44,0x44,0x28,0x28,0x28,0x10,0x10,0x00,0x00, + + 9, // 0x57 'W' + 0x00,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x49,0x00,0x49,0x00,0x55,0x00,0x22,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x58 'X' + 0x00,0x44,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x44,0x00,0x00, + + 7, // 0x59 'Y' + 0x00,0x44,0x44,0x44,0x44,0x28,0x10,0x10,0x10,0x10,0x00,0x00, + + 6, // 0x5A 'Z' + 0x00,0x7C,0x04,0x04,0x08,0x10,0x20,0x40,0x40,0x7C,0x00,0x00, + + 4, // 0x5B '[' + 0x70,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x70,0x00, + + 7, // 0x5C '\' + 0x00,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x04,0x04,0x00, + + 4, // 0x5D ']' + 0xE0,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xE0,0x00, + + 6, // 0x5E '^' + 0x00,0x10,0x28,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x5F '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00, + + 4, // 0x60 '`' + 0x00,0x40,0x40,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x61 'a' + 0x00,0x00,0x00,0x38,0x04,0x3C,0x44,0x44,0x44,0x3C,0x00,0x00, + + 7, // 0x62 'b' + 0x00,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x44,0x78,0x00,0x00, + + 6, // 0x63 'c' + 0x00,0x00,0x00,0x38,0x44,0x40,0x40,0x40,0x44,0x38,0x00,0x00, + + 7, // 0x64 'd' + 0x00,0x04,0x04,0x3C,0x44,0x44,0x44,0x44,0x44,0x3C,0x00,0x00, + + 7, // 0x65 'e' + 0x00,0x00,0x00,0x38,0x44,0x44,0x7C,0x40,0x44,0x38,0x00,0x00, + + 4, // 0x66 'f' + 0x00,0x30,0x40,0xE0,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00, + + 7, // 0x67 'g' + 0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x44,0x44,0x3C,0x04,0x78, + + 7, // 0x68 'h' + 0x00,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x44,0x44,0x00,0x00, + + 3, // 0x69 'i' + 0x00,0x40,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00, + + 5, // 0x6A 'j' + 0x00,0x10,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x90,0x60, + + 6, // 0x6B 'k' + 0x00,0x40,0x40,0x44,0x48,0x50,0x60,0x50,0x48,0x44,0x00,0x00, + + 3, // 0x6C 'l' + 0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00, + + 9, // 0x6D 'm' + 0x00,0x00,0x00,0x00,0x00,0x00,0x76,0x00,0x49,0x00,0x49,0x00,0x49,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x6E 'n' + 0x00,0x00,0x00,0x58,0x64,0x44,0x44,0x44,0x44,0x44,0x00,0x00, + + 7, // 0x6F 'o' + 0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00, + + 7, // 0x70 'p' + 0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x44,0x44,0x78,0x40,0x40, + + 7, // 0x71 'q' + 0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x44,0x44,0x3C,0x04,0x04, + + 6, // 0x72 'r' + 0x00,0x00,0x00,0x58,0x24,0x20,0x20,0x20,0x20,0x70,0x00,0x00, + + 7, // 0x73 's' + 0x00,0x00,0x00,0x38,0x44,0x40,0x38,0x04,0x44,0x38,0x00,0x00, + + 5, // 0x74 't' + 0x00,0x20,0x20,0x70,0x20,0x20,0x20,0x20,0x20,0x18,0x00,0x00, + + 7, // 0x75 'u' + 0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x4C,0x34,0x00,0x00, + + 6, // 0x76 'v' + 0x00,0x00,0x00,0x44,0x44,0x44,0x28,0x28,0x10,0x10,0x00,0x00, + + 9, // 0x77 'w' + 0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x49,0x00,0x49,0x00,0x49,0x00,0x36,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x78 'x' + 0x00,0x00,0x00,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x00,0x00, + + 7, // 0x79 'y' + 0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x3C,0x08,0x70, + + 6, // 0x7A 'z' + 0x00,0x00,0x00,0x7C,0x04,0x08,0x10,0x20,0x40,0x7C,0x00,0x00, + + 5, // 0x7B '{' + 0x18,0x20,0x20,0x20,0x20,0xC0,0x20,0x20,0x20,0x20,0x18,0x00, + + 3, // 0x7C '|' + 0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00, + + 5, // 0x7D '}' + 0xC0,0x20,0x20,0x20,0x20,0x18,0x20,0x20,0x20,0x20,0xC0,0x00, + + 7, // 0x7E '~' + 0x00,0x60,0x92,0x92,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x7F '' + 0x00,0x10,0x38,0x6C,0x44,0x44,0x7C,0x00,0x00,0x00,0x00,0x00, + + 0 + }; + + const int8u mcs13_prop[] = + { + 13, 4, 32, 128-32, + 0x00,0x00,0x0E,0x00,0x1C,0x00,0x2A,0x00,0x38,0x00,0x46,0x00,0x54,0x00,0x62,0x00,0x70,0x00, + 0x7E,0x00,0x8C,0x00,0x9A,0x00,0xA8,0x00,0xB6,0x00,0xC4,0x00,0xD2,0x00,0xE0,0x00,0xEE,0x00, + 0xFC,0x00,0x0A,0x01,0x18,0x01,0x26,0x01,0x34,0x01,0x42,0x01,0x50,0x01,0x5E,0x01,0x6C,0x01, + 0x7A,0x01,0x88,0x01,0x96,0x01,0xA4,0x01,0xB2,0x01,0xC0,0x01,0xCE,0x01,0xDC,0x01,0xEA,0x01, + 0xF8,0x01,0x06,0x02,0x14,0x02,0x22,0x02,0x30,0x02,0x3E,0x02,0x4C,0x02,0x5A,0x02,0x68,0x02, + 0x76,0x02,0x91,0x02,0x9F,0x02,0xAD,0x02,0xBB,0x02,0xC9,0x02,0xD7,0x02,0xE5,0x02,0xF3,0x02, + 0x01,0x03,0x0F,0x03,0x2A,0x03,0x38,0x03,0x46,0x03,0x54,0x03,0x62,0x03,0x70,0x03,0x7E,0x03, + 0x8C,0x03,0x9A,0x03,0xA8,0x03,0xB6,0x03,0xC4,0x03,0xD2,0x03,0xE0,0x03,0xEE,0x03,0xFC,0x03, + 0x0A,0x04,0x18,0x04,0x26,0x04,0x34,0x04,0x42,0x04,0x50,0x04,0x6B,0x04,0x79,0x04,0x87,0x04, + 0x95,0x04,0xA3,0x04,0xB1,0x04,0xBF,0x04,0xCD,0x04,0xDB,0x04,0xE9,0x04,0x04,0x05,0x12,0x05, + 0x20,0x05,0x2E,0x05,0x3C,0x05,0x4A,0x05,0x58,0x05,0x66,0x05, + + 5, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x21 '!' + 0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00,0x00, + + 4, // 0x22 '"' + 0x00,0x50,0x50,0xA0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x23 '#' + 0x00,0x28,0x28,0x28,0x7C,0x28,0x28,0x28,0x7C,0x28,0x28,0x28,0x00, + + 6, // 0x24 '$' + 0x00,0x10,0x10,0x38,0x54,0x50,0x38,0x14,0x54,0x38,0x10,0x10,0x00, + + 7, // 0x25 '%' + 0x00,0x32,0x54,0x64,0x08,0x08,0x10,0x10,0x26,0x2A,0x4C,0x00,0x00, + + 7, // 0x26 '&' + 0x00,0x30,0x48,0x48,0x48,0x30,0x4A,0x4A,0x44,0x3A,0x00,0x00,0x00, + + 3, // 0x27 ''' + 0x00,0x40,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x28 '(' + 0x10,0x20,0x20,0x40,0x40,0x40,0x40,0x40,0x20,0x20,0x10,0x00,0x00, + + 5, // 0x29 ')' + 0x40,0x20,0x20,0x10,0x10,0x10,0x10,0x10,0x20,0x20,0x40,0x00,0x00, + + 6, // 0x2A '*' + 0x00,0x00,0x10,0x54,0x38,0x7C,0x38,0x54,0x10,0x00,0x00,0x00,0x00, + + 6, // 0x2B '+' + 0x00,0x00,0x00,0x00,0x10,0x10,0x7C,0x10,0x10,0x00,0x00,0x00,0x00, + + 4, // 0x2C ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x20,0x40,0x80, + + 6, // 0x2D '-' + 0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x2E '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00, + + 7, // 0x2F '/' + 0x00,0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x00,0x00, + + 7, // 0x30 '0' + 0x00,0x38,0x44,0x44,0x54,0x54,0x54,0x44,0x44,0x38,0x00,0x00,0x00, + + 4, // 0x31 '1' + 0x00,0x20,0x60,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00,0x00, + + 7, // 0x32 '2' + 0x00,0x38,0x44,0x04,0x04,0x08,0x10,0x20,0x40,0x7C,0x00,0x00,0x00, + + 7, // 0x33 '3' + 0x00,0x38,0x44,0x04,0x04,0x38,0x04,0x04,0x44,0x38,0x00,0x00,0x00, + + 6, // 0x34 '4' + 0x00,0x08,0x18,0x28,0x28,0x48,0x48,0x7C,0x08,0x08,0x00,0x00,0x00, + + 7, // 0x35 '5' + 0x00,0x7C,0x40,0x40,0x78,0x44,0x04,0x04,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x36 '6' + 0x00,0x38,0x44,0x40,0x78,0x44,0x44,0x44,0x44,0x38,0x00,0x00,0x00, + + 6, // 0x37 '7' + 0x00,0x7C,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x20,0x00,0x00,0x00, + + 7, // 0x38 '8' + 0x00,0x38,0x44,0x44,0x44,0x38,0x44,0x44,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x39 '9' + 0x00,0x38,0x44,0x44,0x44,0x3C,0x04,0x04,0x44,0x38,0x00,0x00,0x00, + + 4, // 0x3A ':' + 0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00, + + 4, // 0x3B ';' + 0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x60,0x60,0x20,0x40,0x80, + + 6, // 0x3C '<' + 0x00,0x00,0x04,0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x04,0x00,0x00, + + 6, // 0x3D '=' + 0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x3E '>' + 0x00,0x00,0x40,0x20,0x10,0x08,0x04,0x08,0x10,0x20,0x40,0x00,0x00, + + 6, // 0x3F '?' + 0x00,0x38,0x44,0x04,0x04,0x08,0x10,0x10,0x00,0x10,0x00,0x00,0x00, + + 7, // 0x40 '@' + 0x00,0x38,0x44,0x44,0x5C,0x54,0x54,0x4C,0x40,0x38,0x00,0x00,0x00, + + 7, // 0x41 'A' + 0x00,0x38,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x42 'B' + 0x00,0x78,0x44,0x44,0x44,0x78,0x44,0x44,0x44,0x78,0x00,0x00,0x00, + + 6, // 0x43 'C' + 0x00,0x38,0x44,0x40,0x40,0x40,0x40,0x40,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x44 'D' + 0x00,0x70,0x48,0x44,0x44,0x44,0x44,0x44,0x48,0x70,0x00,0x00,0x00, + + 6, // 0x45 'E' + 0x00,0x7C,0x40,0x40,0x40,0x78,0x40,0x40,0x40,0x7C,0x00,0x00,0x00, + + 6, // 0x46 'F' + 0x00,0x7C,0x40,0x40,0x40,0x78,0x40,0x40,0x40,0x40,0x00,0x00,0x00, + + 7, // 0x47 'G' + 0x00,0x38,0x44,0x40,0x40,0x5C,0x44,0x44,0x4C,0x34,0x00,0x00,0x00, + + 7, // 0x48 'H' + 0x00,0x44,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x44,0x00,0x00,0x00, + + 5, // 0x49 'I' + 0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00,0x00, + + 6, // 0x4A 'J' + 0x00,0x1C,0x08,0x08,0x08,0x08,0x08,0x48,0x48,0x30,0x00,0x00,0x00, + + 6, // 0x4B 'K' + 0x00,0x44,0x48,0x50,0x60,0x60,0x50,0x48,0x44,0x44,0x00,0x00,0x00, + + 6, // 0x4C 'L' + 0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7C,0x00,0x00,0x00, + + 9, // 0x4D 'M' + 0x00,0x00,0x41,0x00,0x63,0x00,0x55,0x00,0x49,0x00,0x49,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x4E 'N' + 0x00,0x44,0x64,0x64,0x54,0x54,0x4C,0x4C,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x4F 'O' + 0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x50 'P' + 0x00,0x78,0x44,0x44,0x44,0x44,0x78,0x40,0x40,0x40,0x00,0x00,0x00, + + 7, // 0x51 'Q' + 0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x54,0x48,0x34,0x00,0x00,0x00, + + 7, // 0x52 'R' + 0x00,0x78,0x44,0x44,0x44,0x44,0x78,0x48,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x53 'S' + 0x00,0x38,0x44,0x40,0x40,0x38,0x04,0x04,0x44,0x38,0x00,0x00,0x00, + + 6, // 0x54 'T' + 0x00,0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00,0x00, + + 7, // 0x55 'U' + 0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00,0x00, + + 6, // 0x56 'V' + 0x00,0x44,0x44,0x44,0x44,0x28,0x28,0x28,0x10,0x10,0x00,0x00,0x00, + + 9, // 0x57 'W' + 0x00,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x49,0x00,0x49,0x00,0x55,0x00,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x58 'X' + 0x00,0x44,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x59 'Y' + 0x00,0x44,0x44,0x44,0x44,0x28,0x10,0x10,0x10,0x10,0x00,0x00,0x00, + + 6, // 0x5A 'Z' + 0x00,0x7C,0x04,0x04,0x08,0x10,0x20,0x40,0x40,0x7C,0x00,0x00,0x00, + + 4, // 0x5B '[' + 0x70,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x70,0x00,0x00, + + 7, // 0x5C '\' + 0x00,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x04,0x04,0x00,0x00, + + 4, // 0x5D ']' + 0xE0,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xE0,0x00,0x00, + + 6, // 0x5E '^' + 0x00,0x10,0x28,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x5F '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00, + + 4, // 0x60 '`' + 0x00,0x40,0x40,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x61 'a' + 0x00,0x00,0x00,0x38,0x04,0x3C,0x44,0x44,0x44,0x3C,0x00,0x00,0x00, + + 7, // 0x62 'b' + 0x00,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x44,0x78,0x00,0x00,0x00, + + 6, // 0x63 'c' + 0x00,0x00,0x00,0x38,0x44,0x40,0x40,0x40,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x64 'd' + 0x00,0x04,0x04,0x3C,0x44,0x44,0x44,0x44,0x44,0x3C,0x00,0x00,0x00, + + 7, // 0x65 'e' + 0x00,0x00,0x00,0x38,0x44,0x44,0x7C,0x40,0x44,0x38,0x00,0x00,0x00, + + 4, // 0x66 'f' + 0x00,0x30,0x40,0xE0,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00, + + 7, // 0x67 'g' + 0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x44,0x44,0x3C,0x04,0x44,0x38, + + 7, // 0x68 'h' + 0x00,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x44,0x44,0x00,0x00,0x00, + + 3, // 0x69 'i' + 0x00,0x40,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00, + + 5, // 0x6A 'j' + 0x00,0x10,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x90,0x60,0x00, + + 6, // 0x6B 'k' + 0x00,0x40,0x40,0x44,0x48,0x50,0x60,0x50,0x48,0x44,0x00,0x00,0x00, + + 3, // 0x6C 'l' + 0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00, + + 9, // 0x6D 'm' + 0x00,0x00,0x00,0x00,0x00,0x00,0x76,0x00,0x49,0x00,0x49,0x00,0x49,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x6E 'n' + 0x00,0x00,0x00,0x58,0x64,0x44,0x44,0x44,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x6F 'o' + 0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x70 'p' + 0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x44,0x44,0x78,0x40,0x40,0x40, + + 7, // 0x71 'q' + 0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x44,0x44,0x3C,0x04,0x04,0x04, + + 6, // 0x72 'r' + 0x00,0x00,0x00,0x58,0x24,0x20,0x20,0x20,0x20,0x70,0x00,0x00,0x00, + + 7, // 0x73 's' + 0x00,0x00,0x00,0x38,0x44,0x40,0x38,0x04,0x44,0x38,0x00,0x00,0x00, + + 5, // 0x74 't' + 0x00,0x20,0x20,0x70,0x20,0x20,0x20,0x20,0x20,0x18,0x00,0x00,0x00, + + 7, // 0x75 'u' + 0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x4C,0x34,0x00,0x00,0x00, + + 6, // 0x76 'v' + 0x00,0x00,0x00,0x44,0x44,0x44,0x28,0x28,0x10,0x10,0x00,0x00,0x00, + + 9, // 0x77 'w' + 0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x49,0x00,0x49,0x00,0x49,0x00,0x36,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x78 'x' + 0x00,0x00,0x00,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x79 'y' + 0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x3C,0x04,0x08,0x70, + + 6, // 0x7A 'z' + 0x00,0x00,0x00,0x7C,0x04,0x08,0x10,0x20,0x40,0x7C,0x00,0x00,0x00, + + 5, // 0x7B '{' + 0x18,0x20,0x20,0x20,0x20,0xC0,0x20,0x20,0x20,0x20,0x18,0x00,0x00, + + 3, // 0x7C '|' + 0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00, + + 5, // 0x7D '}' + 0xC0,0x20,0x20,0x20,0x20,0x18,0x20,0x20,0x20,0x20,0xC0,0x00,0x00, + + 7, // 0x7E '~' + 0x00,0x60,0x92,0x92,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x7F '' + 0x00,0x10,0x38,0x6C,0x44,0x44,0x7C,0x00,0x00,0x00,0x00,0x00,0x00, + + 0 + }; + + const int8u mcs5x10_mono[] = + { + 10, 2, 32, 128-32, + 0x00,0x00,0x0B,0x00,0x16,0x00,0x21,0x00,0x2C,0x00,0x37,0x00,0x42,0x00,0x4D,0x00,0x58,0x00, + 0x63,0x00,0x6E,0x00,0x79,0x00,0x84,0x00,0x8F,0x00,0x9A,0x00,0xA5,0x00,0xB0,0x00,0xBB,0x00, + 0xC6,0x00,0xD1,0x00,0xDC,0x00,0xE7,0x00,0xF2,0x00,0xFD,0x00,0x08,0x01,0x13,0x01,0x1E,0x01, + 0x29,0x01,0x34,0x01,0x3F,0x01,0x4A,0x01,0x55,0x01,0x60,0x01,0x6B,0x01,0x76,0x01,0x81,0x01, + 0x8C,0x01,0x97,0x01,0xA2,0x01,0xAD,0x01,0xB8,0x01,0xC3,0x01,0xCE,0x01,0xD9,0x01,0xE4,0x01, + 0xEF,0x01,0xFA,0x01,0x05,0x02,0x10,0x02,0x1B,0x02,0x26,0x02,0x31,0x02,0x3C,0x02,0x47,0x02, + 0x52,0x02,0x5D,0x02,0x68,0x02,0x73,0x02,0x7E,0x02,0x89,0x02,0x94,0x02,0x9F,0x02,0xAA,0x02, + 0xB5,0x02,0xC0,0x02,0xCB,0x02,0xD6,0x02,0xE1,0x02,0xEC,0x02,0xF7,0x02,0x02,0x03,0x0D,0x03, + 0x18,0x03,0x23,0x03,0x2E,0x03,0x39,0x03,0x44,0x03,0x4F,0x03,0x5A,0x03,0x65,0x03,0x70,0x03, + 0x7B,0x03,0x86,0x03,0x91,0x03,0x9C,0x03,0xA7,0x03,0xB2,0x03,0xBD,0x03,0xC8,0x03,0xD3,0x03, + 0xDE,0x03,0xE9,0x03,0xF4,0x03,0xFF,0x03,0x0A,0x04,0x15,0x04, + + 5, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x21 '!' + 0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00, + + 5, // 0x22 '"' + 0x00,0x50,0x50,0xA0,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x23 '#' + 0x00,0x50,0x50,0xF8,0x50,0x50,0x50,0xF8,0x50,0x50, + + 5, // 0x24 '$' + 0x00,0x40,0x60,0x90,0x80,0x60,0x10,0x90,0x60,0x20, + + 5, // 0x25 '%' + 0x00,0x00,0x90,0x90,0x20,0x20,0x40,0x40,0x90,0x90, + + 5, // 0x26 '&' + 0x00,0x40,0xA0,0xA0,0xA0,0x40,0xA8,0x90,0x90,0x68, + + 5, // 0x27 ''' + 0x00,0x20,0x20,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x28 '(' + 0x10,0x20,0x20,0x40,0x40,0x40,0x40,0x20,0x20,0x10, + + 5, // 0x29 ')' + 0x40,0x20,0x20,0x10,0x10,0x10,0x10,0x20,0x20,0x40, + + 5, // 0x2A '*' + 0x00,0x00,0x90,0x60,0xF0,0x60,0x90,0x00,0x00,0x00, + + 5, // 0x2B '+' + 0x00,0x00,0x00,0x20,0x20,0xF8,0x20,0x20,0x00,0x00, + + 5, // 0x2C ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0xC0, + + 5, // 0x2D '-' + 0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00, + + 5, // 0x2E '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00, + + 5, // 0x2F '/' + 0x00,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x80,0x00, + + 5, // 0x30 '0' + 0x00,0x70,0x90,0x90,0x90,0x90,0x90,0x90,0xE0,0x00, + + 5, // 0x31 '1' + 0x00,0x20,0x60,0x20,0x20,0x20,0x20,0x20,0x70,0x00, + + 5, // 0x32 '2' + 0x00,0x60,0x90,0x90,0x10,0x20,0x40,0x80,0xF0,0x00, + + 5, // 0x33 '3' + 0x00,0x60,0x90,0x10,0x60,0x10,0x10,0x90,0x60,0x00, + + 5, // 0x34 '4' + 0x00,0x10,0x30,0x50,0x50,0x90,0xF0,0x10,0x10,0x00, + + 5, // 0x35 '5' + 0x00,0xF0,0x80,0x80,0xE0,0x10,0x10,0x90,0x60,0x00, + + 5, // 0x36 '6' + 0x00,0x60,0x80,0x80,0xE0,0x90,0x90,0x90,0x60,0x00, + + 5, // 0x37 '7' + 0x00,0xF0,0x10,0x10,0x20,0x20,0x40,0x40,0x40,0x00, + + 5, // 0x38 '8' + 0x00,0x60,0x90,0x90,0x60,0x90,0x90,0x90,0x60,0x00, + + 5, // 0x39 '9' + 0x00,0x60,0x90,0x90,0x90,0x70,0x10,0x10,0x60,0x00, + + 5, // 0x3A ':' + 0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x60,0x60,0x00, + + 5, // 0x3B ';' + 0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x60,0x60,0xC0, + + 5, // 0x3C '<' + 0x00,0x08,0x10,0x20,0x40,0x80,0x40,0x20,0x10,0x08, + + 5, // 0x3D '=' + 0x00,0x00,0x00,0x00,0xF0,0x00,0xF0,0x00,0x00,0x00, + + 5, // 0x3E '>' + 0x00,0x80,0x40,0x20,0x10,0x08,0x10,0x20,0x40,0x80, + + 5, // 0x3F '?' + 0x00,0x60,0x90,0x10,0x10,0x20,0x40,0x00,0x40,0x00, + + 5, // 0x40 '@' + 0x00,0x60,0x90,0x90,0xB0,0xB0,0x80,0x80,0x70,0x00, + + 5, // 0x41 'A' + 0x00,0x60,0x90,0x90,0x90,0xF0,0x90,0x90,0x90,0x00, + + 5, // 0x42 'B' + 0x00,0xE0,0x90,0x90,0xE0,0x90,0x90,0x90,0xE0,0x00, + + 5, // 0x43 'C' + 0x00,0x60,0x90,0x80,0x80,0x80,0x80,0x90,0x60,0x00, + + 5, // 0x44 'D' + 0x00,0xE0,0x90,0x90,0x90,0x90,0x90,0x90,0xE0,0x00, + + 5, // 0x45 'E' + 0x00,0xF0,0x80,0x80,0xF0,0x80,0x80,0x80,0xF0,0x00, + + 5, // 0x46 'F' + 0x00,0xF0,0x80,0x80,0xF0,0x80,0x80,0x80,0x80,0x00, + + 5, // 0x47 'G' + 0x00,0x60,0x90,0x80,0x80,0xB0,0x90,0x90,0x60,0x00, + + 5, // 0x48 'H' + 0x00,0x90,0x90,0x90,0x90,0xF0,0x90,0x90,0x90,0x00, + + 5, // 0x49 'I' + 0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00, + + 5, // 0x4A 'J' + 0x00,0x70,0x20,0x20,0x20,0x20,0x20,0xA0,0x40,0x00, + + 5, // 0x4B 'K' + 0x00,0x90,0xA0,0xA0,0xC0,0xC0,0xA0,0xA0,0x90,0x00, + + 5, // 0x4C 'L' + 0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xF0,0x00, + + 5, // 0x4D 'M' + 0x00,0x90,0x90,0xF0,0xF0,0x90,0x90,0x90,0x90,0x00, + + 5, // 0x4E 'N' + 0x00,0x90,0x90,0xD0,0xD0,0xB0,0xB0,0x90,0x90,0x00, + + 5, // 0x4F 'O' + 0x00,0x60,0x90,0x90,0x90,0x90,0x90,0x90,0x60,0x00, + + 5, // 0x50 'P' + 0x00,0xE0,0x90,0x90,0x90,0xE0,0x80,0x80,0x80,0x00, + + 5, // 0x51 'Q' + 0x00,0x60,0x90,0x90,0x90,0x90,0x90,0x90,0x60,0x30, + + 5, // 0x52 'R' + 0x00,0xE0,0x90,0x90,0x90,0xE0,0xA0,0x90,0x90,0x00, + + 5, // 0x53 'S' + 0x00,0x60,0x90,0x80,0x60,0x10,0x90,0x90,0x60,0x00, + + 5, // 0x54 'T' + 0x00,0xF8,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00, + + 5, // 0x55 'U' + 0x00,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x60,0x00, + + 5, // 0x56 'V' + 0x00,0x90,0x90,0x90,0x50,0x50,0x50,0x20,0x20,0x00, + + 5, // 0x57 'W' + 0x00,0x90,0x90,0x90,0x90,0x90,0xF0,0xF0,0x90,0x00, + + 5, // 0x58 'X' + 0x00,0x90,0x90,0x90,0x60,0x60,0x90,0x90,0x90,0x00, + + 5, // 0x59 'Y' + 0x00,0x88,0x88,0x88,0x50,0x20,0x20,0x20,0x20,0x00, + + 5, // 0x5A 'Z' + 0x00,0xF0,0x10,0x20,0x20,0x40,0x40,0x80,0xF0,0x00, + + 5, // 0x5B '[' + 0x60,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x60, + + 5, // 0x5C '\' + 0x80,0x80,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08, + + 5, // 0x5D ']' + 0x60,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x60, + + 5, // 0x5E '^' + 0x00,0x20,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x5F '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x00, + + 5, // 0x60 '`' + 0x00,0x40,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x61 'a' + 0x00,0x00,0x00,0x60,0x10,0x70,0x90,0x90,0x70,0x00, + + 5, // 0x62 'b' + 0x00,0x80,0x80,0xE0,0x90,0x90,0x90,0x90,0xE0,0x00, + + 5, // 0x63 'c' + 0x00,0x00,0x00,0x60,0x90,0x80,0x80,0x90,0x60,0x00, + + 5, // 0x64 'd' + 0x00,0x10,0x10,0x70,0x90,0x90,0x90,0x90,0x70,0x00, + + 5, // 0x65 'e' + 0x00,0x00,0x00,0x60,0x90,0x90,0xF0,0x80,0x70,0x00, + + 5, // 0x66 'f' + 0x00,0x30,0x40,0xE0,0x40,0x40,0x40,0x40,0x40,0x00, + + 5, // 0x67 'g' + 0x00,0x00,0x00,0x70,0x90,0x90,0x90,0x70,0x10,0xE0, + + 5, // 0x68 'h' + 0x00,0x80,0x80,0xE0,0x90,0x90,0x90,0x90,0x90,0x00, + + 5, // 0x69 'i' + 0x00,0x20,0x00,0x60,0x20,0x20,0x20,0x20,0x70,0x00, + + 5, // 0x6A 'j' + 0x00,0x20,0x00,0x60,0x20,0x20,0x20,0x20,0x20,0xC0, + + 5, // 0x6B 'k' + 0x00,0x80,0x80,0x90,0xA0,0xC0,0xA0,0x90,0x90,0x00, + + 5, // 0x6C 'l' + 0x00,0x60,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00, + + 5, // 0x6D 'm' + 0x00,0x00,0x00,0x90,0xF0,0x90,0x90,0x90,0x90,0x00, + + 5, // 0x6E 'n' + 0x00,0x00,0x00,0xE0,0x90,0x90,0x90,0x90,0x90,0x00, + + 5, // 0x6F 'o' + 0x00,0x00,0x00,0x60,0x90,0x90,0x90,0x90,0x60,0x00, + + 5, // 0x70 'p' + 0x00,0x00,0x00,0xE0,0x90,0x90,0x90,0xE0,0x80,0x80, + + 5, // 0x71 'q' + 0x00,0x00,0x00,0x70,0x90,0x90,0x90,0x70,0x10,0x10, + + 5, // 0x72 'r' + 0x00,0x00,0x00,0xB0,0x50,0x40,0x40,0x40,0xE0,0x00, + + 5, // 0x73 's' + 0x00,0x00,0x00,0x60,0x90,0x40,0x20,0x90,0x60,0x00, + + 5, // 0x74 't' + 0x00,0x40,0x40,0xE0,0x40,0x40,0x40,0x50,0x20,0x00, + + 5, // 0x75 'u' + 0x00,0x00,0x00,0x90,0x90,0x90,0x90,0x90,0x70,0x00, + + 5, // 0x76 'v' + 0x00,0x00,0x00,0x90,0x90,0x50,0x50,0x20,0x20,0x00, + + 5, // 0x77 'w' + 0x00,0x00,0x00,0x90,0x90,0x90,0x90,0xF0,0x90,0x00, + + 5, // 0x78 'x' + 0x00,0x00,0x00,0x90,0x90,0x60,0x60,0x90,0x90,0x00, + + 5, // 0x79 'y' + 0x00,0x00,0x00,0x90,0x90,0x90,0x90,0x70,0x10,0xE0, + + 5, // 0x7A 'z' + 0x00,0x00,0x00,0xF0,0x10,0x20,0x40,0x80,0xF0,0x00, + + 5, // 0x7B '{' + 0x30,0x40,0x40,0x40,0x80,0x40,0x40,0x40,0x40,0x30, + + 5, // 0x7C '|' + 0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + + 5, // 0x7D '}' + 0xC0,0x20,0x20,0x20,0x10,0x20,0x20,0x20,0x20,0xC0, + + 5, // 0x7E '~' + 0x00,0x40,0xA8,0x10,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x7F '' + 0x00,0x20,0x70,0xD8,0x88,0x88,0xF8,0x00,0x00,0x00, + + 0 + }; + + const int8u mcs5x11_mono[] = + { + 11, 3, 32, 128-32, + 0x00,0x00,0x0C,0x00,0x18,0x00,0x24,0x00,0x30,0x00,0x3C,0x00,0x48,0x00,0x54,0x00,0x60,0x00, + 0x6C,0x00,0x78,0x00,0x84,0x00,0x90,0x00,0x9C,0x00,0xA8,0x00,0xB4,0x00,0xC0,0x00,0xCC,0x00, + 0xD8,0x00,0xE4,0x00,0xF0,0x00,0xFC,0x00,0x08,0x01,0x14,0x01,0x20,0x01,0x2C,0x01,0x38,0x01, + 0x44,0x01,0x50,0x01,0x5C,0x01,0x68,0x01,0x74,0x01,0x80,0x01,0x8C,0x01,0x98,0x01,0xA4,0x01, + 0xB0,0x01,0xBC,0x01,0xC8,0x01,0xD4,0x01,0xE0,0x01,0xEC,0x01,0xF8,0x01,0x04,0x02,0x10,0x02, + 0x1C,0x02,0x28,0x02,0x34,0x02,0x40,0x02,0x4C,0x02,0x58,0x02,0x64,0x02,0x70,0x02,0x7C,0x02, + 0x88,0x02,0x94,0x02,0xA0,0x02,0xAC,0x02,0xB8,0x02,0xC4,0x02,0xD0,0x02,0xDC,0x02,0xE8,0x02, + 0xF4,0x02,0x00,0x03,0x0C,0x03,0x18,0x03,0x24,0x03,0x30,0x03,0x3C,0x03,0x48,0x03,0x54,0x03, + 0x60,0x03,0x6C,0x03,0x78,0x03,0x84,0x03,0x90,0x03,0x9C,0x03,0xA8,0x03,0xB4,0x03,0xC0,0x03, + 0xCC,0x03,0xD8,0x03,0xE4,0x03,0xF0,0x03,0xFC,0x03,0x08,0x04,0x14,0x04,0x20,0x04,0x2C,0x04, + 0x38,0x04,0x44,0x04,0x50,0x04,0x5C,0x04,0x68,0x04,0x74,0x04, + + 5, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x21 '!' + 0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00,0x00, + + 5, // 0x22 '"' + 0x00,0x50,0x50,0xA0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x23 '#' + 0x00,0x50,0x50,0xF8,0x50,0x50,0x50,0xF8,0x50,0x50,0x00, + + 5, // 0x24 '$' + 0x00,0x40,0x60,0x90,0x80,0x60,0x10,0x90,0x60,0x20,0x00, + + 5, // 0x25 '%' + 0x00,0x00,0x90,0x90,0x20,0x20,0x40,0x40,0x90,0x90,0x00, + + 5, // 0x26 '&' + 0x00,0x40,0xA0,0xA0,0x40,0xA8,0x90,0x90,0x68,0x00,0x00, + + 5, // 0x27 ''' + 0x00,0x20,0x20,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x28 '(' + 0x00,0x10,0x20,0x20,0x40,0x40,0x40,0x40,0x20,0x20,0x10, + + 5, // 0x29 ')' + 0x00,0x40,0x20,0x20,0x10,0x10,0x10,0x10,0x20,0x20,0x40, + + 5, // 0x2A '*' + 0x00,0x00,0x90,0x60,0xF0,0x60,0x90,0x00,0x00,0x00,0x00, + + 5, // 0x2B '+' + 0x00,0x00,0x00,0x20,0x20,0xF8,0x20,0x20,0x00,0x00,0x00, + + 5, // 0x2C ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x40,0x80, + + 5, // 0x2D '-' + 0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x2E '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00, + + 5, // 0x2F '/' + 0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x80,0x80,0x00, + + 5, // 0x30 '0' + 0x00,0x70,0x90,0x90,0x90,0x90,0x90,0x90,0xE0,0x00,0x00, + + 5, // 0x31 '1' + 0x00,0x20,0x60,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, + + 5, // 0x32 '2' + 0x00,0x60,0x90,0x90,0x10,0x20,0x40,0x80,0xF0,0x00,0x00, + + 5, // 0x33 '3' + 0x00,0x60,0x90,0x10,0x60,0x10,0x10,0x90,0x60,0x00,0x00, + + 5, // 0x34 '4' + 0x00,0x10,0x30,0x50,0x50,0x90,0xF8,0x10,0x10,0x00,0x00, + + 5, // 0x35 '5' + 0x00,0xF0,0x80,0xE0,0x90,0x10,0x10,0x90,0x60,0x00,0x00, + + 5, // 0x36 '6' + 0x00,0x60,0x90,0x80,0xE0,0x90,0x90,0x90,0x60,0x00,0x00, + + 5, // 0x37 '7' + 0x00,0xF0,0x10,0x10,0x20,0x20,0x40,0x40,0x40,0x00,0x00, + + 5, // 0x38 '8' + 0x00,0x60,0x90,0x90,0x60,0x90,0x90,0x90,0x60,0x00,0x00, + + 5, // 0x39 '9' + 0x00,0x60,0x90,0x90,0x90,0x70,0x10,0x90,0x60,0x00,0x00, + + 5, // 0x3A ':' + 0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x60,0x60,0x00,0x00, + + 5, // 0x3B ';' + 0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x60,0x60,0x40,0x80, + + 5, // 0x3C '<' + 0x00,0x08,0x10,0x20,0x40,0x80,0x40,0x20,0x10,0x08,0x00, + + 5, // 0x3D '=' + 0x00,0x00,0x00,0x00,0xF0,0x00,0x00,0xF0,0x00,0x00,0x00, + + 5, // 0x3E '>' + 0x00,0x80,0x40,0x20,0x10,0x08,0x10,0x20,0x40,0x80,0x00, + + 5, // 0x3F '?' + 0x00,0x60,0x90,0x10,0x10,0x20,0x40,0x00,0x40,0x00,0x00, + + 5, // 0x40 '@' + 0x00,0x60,0x90,0x90,0xB0,0xB0,0x80,0x80,0x70,0x00,0x00, + + 5, // 0x41 'A' + 0x00,0x60,0x90,0x90,0x90,0xF0,0x90,0x90,0x90,0x00,0x00, + + 5, // 0x42 'B' + 0x00,0xE0,0x90,0x90,0xE0,0x90,0x90,0x90,0xE0,0x00,0x00, + + 5, // 0x43 'C' + 0x00,0x60,0x90,0x80,0x80,0x80,0x80,0x90,0x60,0x00,0x00, + + 5, // 0x44 'D' + 0x00,0xE0,0x90,0x90,0x90,0x90,0x90,0x90,0xE0,0x00,0x00, + + 5, // 0x45 'E' + 0x00,0xF0,0x80,0x80,0xE0,0x80,0x80,0x80,0xF0,0x00,0x00, + + 5, // 0x46 'F' + 0x00,0xF0,0x80,0x80,0xE0,0x80,0x80,0x80,0x80,0x00,0x00, + + 5, // 0x47 'G' + 0x00,0x60,0x90,0x80,0x80,0xB0,0x90,0x90,0x60,0x00,0x00, + + 5, // 0x48 'H' + 0x00,0x90,0x90,0x90,0xF0,0x90,0x90,0x90,0x90,0x00,0x00, + + 5, // 0x49 'I' + 0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, + + 5, // 0x4A 'J' + 0x00,0x70,0x20,0x20,0x20,0x20,0xA0,0xA0,0x40,0x00,0x00, + + 5, // 0x4B 'K' + 0x00,0x90,0xA0,0xA0,0xC0,0xA0,0xA0,0x90,0x90,0x00,0x00, + + 5, // 0x4C 'L' + 0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0xF0,0x00,0x00, + + 5, // 0x4D 'M' + 0x00,0x90,0xF0,0xF0,0x90,0x90,0x90,0x90,0x90,0x00,0x00, + + 5, // 0x4E 'N' + 0x00,0x90,0x90,0xD0,0xD0,0xB0,0xB0,0x90,0x90,0x00,0x00, + + 5, // 0x4F 'O' + 0x00,0x60,0x90,0x90,0x90,0x90,0x90,0x90,0x60,0x00,0x00, + + 5, // 0x50 'P' + 0x00,0xE0,0x90,0x90,0x90,0xE0,0x80,0x80,0x80,0x00,0x00, + + 5, // 0x51 'Q' + 0x00,0x60,0x90,0x90,0x90,0x90,0x90,0x90,0x60,0x30,0x00, + + 5, // 0x52 'R' + 0x00,0xE0,0x90,0x90,0x90,0xE0,0xA0,0x90,0x90,0x00,0x00, + + 5, // 0x53 'S' + 0x00,0x60,0x90,0x80,0x60,0x10,0x90,0x90,0x60,0x00,0x00, + + 5, // 0x54 'T' + 0x00,0xF8,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00, + + 5, // 0x55 'U' + 0x00,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x60,0x00,0x00, + + 5, // 0x56 'V' + 0x00,0x90,0x90,0x90,0x50,0x50,0x50,0x20,0x20,0x00,0x00, + + 5, // 0x57 'W' + 0x00,0x90,0x90,0x90,0x90,0x90,0xF0,0xF0,0x90,0x00,0x00, + + 5, // 0x58 'X' + 0x00,0x90,0x90,0x90,0x60,0x60,0x90,0x90,0x90,0x00,0x00, + + 5, // 0x59 'Y' + 0x00,0x88,0x88,0x88,0x50,0x20,0x20,0x20,0x20,0x00,0x00, + + 5, // 0x5A 'Z' + 0x00,0xF0,0x10,0x20,0x20,0x40,0x40,0x80,0xF0,0x00,0x00, + + 5, // 0x5B '[' + 0x00,0x60,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x60, + + 5, // 0x5C '\' + 0x80,0x80,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x00, + + 5, // 0x5D ']' + 0x00,0x60,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x60, + + 5, // 0x5E '^' + 0x00,0x20,0x50,0x88,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x5F '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0x00, + + 5, // 0x60 '`' + 0x00,0x40,0x40,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x61 'a' + 0x00,0x00,0x00,0x60,0x10,0x70,0x90,0x90,0x70,0x00,0x00, + + 5, // 0x62 'b' + 0x00,0x80,0x80,0xE0,0x90,0x90,0x90,0x90,0xE0,0x00,0x00, + + 5, // 0x63 'c' + 0x00,0x00,0x00,0x60,0x90,0x80,0x80,0x90,0x60,0x00,0x00, + + 5, // 0x64 'd' + 0x00,0x10,0x10,0x70,0x90,0x90,0x90,0x90,0x70,0x00,0x00, + + 5, // 0x65 'e' + 0x00,0x00,0x00,0x60,0x90,0x90,0xF0,0x80,0x70,0x00,0x00, + + 5, // 0x66 'f' + 0x00,0x30,0x40,0xE0,0x40,0x40,0x40,0x40,0x40,0x00,0x00, + + 5, // 0x67 'g' + 0x00,0x00,0x00,0x70,0x90,0x90,0x90,0x90,0x70,0x10,0xE0, + + 5, // 0x68 'h' + 0x00,0x80,0x80,0xE0,0x90,0x90,0x90,0x90,0x90,0x00,0x00, + + 5, // 0x69 'i' + 0x00,0x20,0x00,0x60,0x20,0x20,0x20,0x20,0x70,0x00,0x00, + + 5, // 0x6A 'j' + 0x00,0x20,0x00,0x60,0x20,0x20,0x20,0x20,0x20,0xA0,0x40, + + 5, // 0x6B 'k' + 0x00,0x80,0x80,0x90,0xA0,0xC0,0xA0,0x90,0x90,0x00,0x00, + + 5, // 0x6C 'l' + 0x00,0x60,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, + + 5, // 0x6D 'm' + 0x00,0x00,0x00,0x90,0xF0,0x90,0x90,0x90,0x90,0x00,0x00, + + 5, // 0x6E 'n' + 0x00,0x00,0x00,0xE0,0x90,0x90,0x90,0x90,0x90,0x00,0x00, + + 5, // 0x6F 'o' + 0x00,0x00,0x00,0x60,0x90,0x90,0x90,0x90,0x60,0x00,0x00, + + 5, // 0x70 'p' + 0x00,0x00,0x00,0xE0,0x90,0x90,0x90,0x90,0xE0,0x80,0x80, + + 5, // 0x71 'q' + 0x00,0x00,0x00,0x70,0x90,0x90,0x90,0x90,0x70,0x10,0x10, + + 5, // 0x72 'r' + 0x00,0x00,0x00,0xA0,0x50,0x40,0x40,0x40,0xE0,0x00,0x00, + + 5, // 0x73 's' + 0x00,0x00,0x00,0x60,0x90,0x40,0x20,0x90,0x60,0x00,0x00, + + 5, // 0x74 't' + 0x00,0x40,0x40,0xE0,0x40,0x40,0x40,0x40,0x30,0x00,0x00, + + 5, // 0x75 'u' + 0x00,0x00,0x00,0x90,0x90,0x90,0x90,0x90,0x70,0x00,0x00, + + 5, // 0x76 'v' + 0x00,0x00,0x00,0x90,0x90,0x50,0x50,0x20,0x20,0x00,0x00, + + 5, // 0x77 'w' + 0x00,0x00,0x00,0x90,0x90,0x90,0x90,0xF0,0x90,0x00,0x00, + + 5, // 0x78 'x' + 0x00,0x00,0x00,0x90,0x90,0x60,0x60,0x90,0x90,0x00,0x00, + + 5, // 0x79 'y' + 0x00,0x00,0x00,0x90,0x90,0x90,0x90,0x90,0x70,0x10,0xE0, + + 5, // 0x7A 'z' + 0x00,0x00,0x00,0xF0,0x10,0x20,0x40,0x80,0xF0,0x00,0x00, + + 5, // 0x7B '{' + 0x30,0x40,0x40,0x40,0x40,0x80,0x40,0x40,0x40,0x40,0x30, + + 5, // 0x7C '|' + 0x00,0x20,0x20,0x20,0x20,0x00,0x20,0x20,0x20,0x20,0x00, + + 5, // 0x7D '}' + 0xC0,0x20,0x20,0x20,0x20,0x10,0x20,0x20,0x20,0x20,0xC0, + + 5, // 0x7E '~' + 0x00,0x40,0xA8,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x7F '' + 0x00,0x20,0x70,0xD8,0x88,0x88,0xF8,0x00,0x00,0x00,0x00, + + 0 + }; + + const int8u mcs6x10_mono[] = + { + 10, 3, 32, 128-32, + 0x00,0x00,0x0B,0x00,0x16,0x00,0x21,0x00,0x2C,0x00,0x37,0x00,0x42,0x00,0x4D,0x00,0x58,0x00, + 0x63,0x00,0x6E,0x00,0x79,0x00,0x84,0x00,0x8F,0x00,0x9A,0x00,0xA5,0x00,0xB0,0x00,0xBB,0x00, + 0xC6,0x00,0xD1,0x00,0xDC,0x00,0xE7,0x00,0xF2,0x00,0xFD,0x00,0x08,0x01,0x13,0x01,0x1E,0x01, + 0x29,0x01,0x34,0x01,0x3F,0x01,0x4A,0x01,0x55,0x01,0x60,0x01,0x6B,0x01,0x76,0x01,0x81,0x01, + 0x8C,0x01,0x97,0x01,0xA2,0x01,0xAD,0x01,0xB8,0x01,0xC3,0x01,0xCE,0x01,0xD9,0x01,0xE4,0x01, + 0xEF,0x01,0xFA,0x01,0x05,0x02,0x10,0x02,0x1B,0x02,0x26,0x02,0x31,0x02,0x3C,0x02,0x47,0x02, + 0x52,0x02,0x5D,0x02,0x68,0x02,0x73,0x02,0x7E,0x02,0x89,0x02,0x94,0x02,0x9F,0x02,0xAA,0x02, + 0xB5,0x02,0xC0,0x02,0xCB,0x02,0xD6,0x02,0xE1,0x02,0xEC,0x02,0xF7,0x02,0x02,0x03,0x0D,0x03, + 0x18,0x03,0x23,0x03,0x2E,0x03,0x39,0x03,0x44,0x03,0x4F,0x03,0x5A,0x03,0x65,0x03,0x70,0x03, + 0x7B,0x03,0x86,0x03,0x91,0x03,0x9C,0x03,0xA7,0x03,0xB2,0x03,0xBD,0x03,0xC8,0x03,0xD3,0x03, + 0xDE,0x03,0xE9,0x03,0xF4,0x03,0xFF,0x03,0x0A,0x04,0x15,0x04, + + 6, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x21 '!' + 0x00,0x10,0x10,0x10,0x10,0x10,0x00,0x10,0x00,0x00, + + 6, // 0x22 '"' + 0x00,0x28,0x28,0x50,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x23 '#' + 0x00,0x28,0x28,0x7C,0x28,0x28,0x7C,0x28,0x28,0x00, + + 6, // 0x24 '$' + 0x10,0x38,0x54,0x50,0x38,0x14,0x54,0x38,0x10,0x00, + + 6, // 0x25 '%' + 0x00,0x08,0xC8,0xD0,0x10,0x20,0x2C,0x4C,0x40,0x00, + + 6, // 0x26 '&' + 0x00,0x20,0x50,0x50,0x24,0x54,0x48,0x34,0x00,0x00, + + 6, // 0x27 ''' + 0x00,0x10,0x10,0x20,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x28 '(' + 0x08,0x10,0x10,0x20,0x20,0x20,0x10,0x10,0x08,0x00, + + 6, // 0x29 ')' + 0x20,0x10,0x10,0x08,0x08,0x08,0x10,0x10,0x20,0x00, + + 6, // 0x2A '*' + 0x00,0x00,0x28,0x7C,0x38,0x7C,0x28,0x00,0x00,0x00, + + 6, // 0x2B '+' + 0x00,0x00,0x10,0x10,0x7C,0x10,0x10,0x00,0x00,0x00, + + 6, // 0x2C ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x20,0x40, + + 6, // 0x2D '-' + 0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x2E '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00, + + 6, // 0x2F '/' + 0x00,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x00, + + 6, // 0x30 '0' + 0x00,0x38,0x44,0x4C,0x54,0x64,0x44,0x38,0x00,0x00, + + 6, // 0x31 '1' + 0x00,0x10,0x30,0x10,0x10,0x10,0x10,0x38,0x00,0x00, + + 6, // 0x32 '2' + 0x00,0x38,0x44,0x04,0x18,0x20,0x40,0x7C,0x00,0x00, + + 6, // 0x33 '3' + 0x00,0x38,0x44,0x04,0x38,0x04,0x44,0x38,0x00,0x00, + + 6, // 0x34 '4' + 0x00,0x08,0x18,0x28,0x48,0x7C,0x08,0x08,0x00,0x00, + + 6, // 0x35 '5' + 0x00,0x7C,0x40,0x40,0x78,0x04,0x44,0x38,0x00,0x00, + + 6, // 0x36 '6' + 0x00,0x38,0x40,0x40,0x78,0x44,0x44,0x38,0x00,0x00, + + 6, // 0x37 '7' + 0x00,0x7C,0x04,0x08,0x10,0x20,0x20,0x20,0x00,0x00, + + 6, // 0x38 '8' + 0x00,0x38,0x44,0x44,0x38,0x44,0x44,0x38,0x00,0x00, + + 6, // 0x39 '9' + 0x00,0x38,0x44,0x44,0x3C,0x04,0x04,0x38,0x00,0x00, + + 6, // 0x3A ':' + 0x00,0x00,0x30,0x30,0x00,0x00,0x30,0x30,0x00,0x00, + + 6, // 0x3B ';' + 0x00,0x00,0x30,0x30,0x00,0x00,0x30,0x30,0x20,0x40, + + 6, // 0x3C '<' + 0x04,0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x04,0x00, + + 6, // 0x3D '=' + 0x00,0x00,0x00,0x7C,0x00,0x00,0x7C,0x00,0x00,0x00, + + 6, // 0x3E '>' + 0x40,0x20,0x10,0x08,0x04,0x08,0x10,0x20,0x40,0x00, + + 6, // 0x3F '?' + 0x00,0x38,0x44,0x04,0x18,0x10,0x00,0x10,0x00,0x00, + + 6, // 0x40 '@' + 0x00,0x38,0x44,0x5C,0x54,0x5C,0x40,0x38,0x00,0x00, + + 6, // 0x41 'A' + 0x00,0x38,0x44,0x44,0x44,0x7C,0x44,0x44,0x00,0x00, + + 6, // 0x42 'B' + 0x00,0x78,0x44,0x44,0x78,0x44,0x44,0x78,0x00,0x00, + + 6, // 0x43 'C' + 0x00,0x38,0x44,0x40,0x40,0x40,0x44,0x38,0x00,0x00, + + 6, // 0x44 'D' + 0x00,0x78,0x44,0x44,0x44,0x44,0x44,0x78,0x00,0x00, + + 6, // 0x45 'E' + 0x00,0x7C,0x40,0x40,0x78,0x40,0x40,0x7C,0x00,0x00, + + 6, // 0x46 'F' + 0x00,0x7C,0x40,0x40,0x78,0x40,0x40,0x40,0x00,0x00, + + 6, // 0x47 'G' + 0x00,0x38,0x44,0x40,0x4C,0x44,0x44,0x3C,0x00,0x00, + + 6, // 0x48 'H' + 0x00,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x00,0x00, + + 6, // 0x49 'I' + 0x00,0x38,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00, + + 6, // 0x4A 'J' + 0x00,0x1C,0x08,0x08,0x08,0x48,0x48,0x30,0x00,0x00, + + 6, // 0x4B 'K' + 0x00,0x44,0x48,0x50,0x60,0x50,0x48,0x44,0x00,0x00, + + 6, // 0x4C 'L' + 0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x7C,0x00,0x00, + + 6, // 0x4D 'M' + 0x00,0x44,0x6C,0x54,0x54,0x44,0x44,0x44,0x00,0x00, + + 6, // 0x4E 'N' + 0x00,0x44,0x44,0x64,0x54,0x4C,0x44,0x44,0x00,0x00, + + 6, // 0x4F 'O' + 0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00, + + 6, // 0x50 'P' + 0x00,0x78,0x44,0x44,0x78,0x40,0x40,0x40,0x00,0x00, + + 6, // 0x51 'Q' + 0x00,0x38,0x44,0x44,0x44,0x54,0x48,0x34,0x00,0x00, + + 6, // 0x52 'R' + 0x00,0x78,0x44,0x44,0x78,0x48,0x44,0x44,0x00,0x00, + + 6, // 0x53 'S' + 0x00,0x38,0x44,0x40,0x38,0x04,0x44,0x38,0x00,0x00, + + 6, // 0x54 'T' + 0x00,0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00, + + 6, // 0x55 'U' + 0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00, + + 6, // 0x56 'V' + 0x00,0x44,0x44,0x44,0x44,0x28,0x28,0x10,0x00,0x00, + + 6, // 0x57 'W' + 0x00,0x44,0x44,0x54,0x54,0x54,0x54,0x28,0x00,0x00, + + 6, // 0x58 'X' + 0x00,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x00,0x00, + + 6, // 0x59 'Y' + 0x00,0x44,0x44,0x44,0x28,0x10,0x10,0x10,0x00,0x00, + + 6, // 0x5A 'Z' + 0x00,0x78,0x08,0x10,0x20,0x40,0x40,0x78,0x00,0x00, + + 6, // 0x5B '[' + 0x38,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x38,0x00, + + 6, // 0x5C '\' + 0x00,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x00, + + 6, // 0x5D ']' + 0x38,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x38,0x00, + + 6, // 0x5E '^' + 0x10,0x28,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x5F '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00, + + 6, // 0x60 '`' + 0x00,0x10,0x10,0x20,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x61 'a' + 0x00,0x00,0x00,0x38,0x04,0x3C,0x44,0x3C,0x00,0x00, + + 6, // 0x62 'b' + 0x00,0x40,0x40,0x78,0x44,0x44,0x44,0x78,0x00,0x00, + + 6, // 0x63 'c' + 0x00,0x00,0x00,0x38,0x44,0x40,0x40,0x3C,0x00,0x00, + + 6, // 0x64 'd' + 0x00,0x04,0x04,0x3C,0x44,0x44,0x44,0x3C,0x00,0x00, + + 6, // 0x65 'e' + 0x00,0x00,0x00,0x38,0x44,0x78,0x40,0x3C,0x00,0x00, + + 6, // 0x66 'f' + 0x00,0x0C,0x10,0x10,0x38,0x10,0x10,0x10,0x00,0x00, + + 6, // 0x67 'g' + 0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x3C,0x04,0x38, + + 6, // 0x68 'h' + 0x00,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x00,0x00, + + 6, // 0x69 'i' + 0x00,0x10,0x00,0x30,0x10,0x10,0x10,0x38,0x00,0x00, + + 6, // 0x6A 'j' + 0x00,0x08,0x00,0x18,0x08,0x08,0x08,0x08,0x48,0x30, + + 6, // 0x6B 'k' + 0x00,0x40,0x40,0x48,0x50,0x60,0x50,0x48,0x00,0x00, + + 6, // 0x6C 'l' + 0x00,0x30,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00, + + 6, // 0x6D 'm' + 0x00,0x00,0x00,0x68,0x54,0x54,0x44,0x44,0x00,0x00, + + 6, // 0x6E 'n' + 0x00,0x00,0x00,0x58,0x64,0x44,0x44,0x44,0x00,0x00, + + 6, // 0x6F 'o' + 0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x38,0x00,0x00, + + 6, // 0x70 'p' + 0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x78,0x40,0x40, + + 6, // 0x71 'q' + 0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x3C,0x04,0x04, + + 6, // 0x72 'r' + 0x00,0x00,0x00,0x58,0x24,0x20,0x20,0x70,0x00,0x00, + + 6, // 0x73 's' + 0x00,0x00,0x00,0x38,0x40,0x38,0x04,0x78,0x00,0x00, + + 6, // 0x74 't' + 0x00,0x10,0x10,0x38,0x10,0x10,0x14,0x08,0x00,0x00, + + 6, // 0x75 'u' + 0x00,0x00,0x00,0x44,0x44,0x44,0x4C,0x34,0x00,0x00, + + 6, // 0x76 'v' + 0x00,0x00,0x00,0x44,0x44,0x44,0x28,0x10,0x00,0x00, + + 6, // 0x77 'w' + 0x00,0x00,0x00,0x44,0x44,0x54,0x7C,0x28,0x00,0x00, + + 6, // 0x78 'x' + 0x00,0x00,0x00,0x48,0x48,0x30,0x48,0x48,0x00,0x00, + + 6, // 0x79 'y' + 0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x3C,0x04,0x38, + + 6, // 0x7A 'z' + 0x00,0x00,0x00,0x78,0x08,0x30,0x40,0x78,0x00,0x00, + + 6, // 0x7B '{' + 0x18,0x20,0x20,0x20,0xC0,0x20,0x20,0x20,0x18,0x00, + + 6, // 0x7C '|' + 0x10,0x10,0x10,0x10,0x00,0x10,0x10,0x10,0x10,0x00, + + 6, // 0x7D '}' + 0x60,0x10,0x10,0x10,0x0C,0x10,0x10,0x10,0x60,0x00, + + 6, // 0x7E '~' + 0x00,0x48,0xA8,0x90,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x7F '' + 0x00,0x10,0x38,0x6C,0x44,0x44,0x7C,0x00,0x00,0x00, + + 0 + }; + + const int8u mcs6x11_mono[] = + { + 11, 3, 32, 128-32, + 0x00,0x00,0x0C,0x00,0x18,0x00,0x24,0x00,0x30,0x00,0x3C,0x00,0x48,0x00,0x54,0x00,0x60,0x00, + 0x6C,0x00,0x78,0x00,0x84,0x00,0x90,0x00,0x9C,0x00,0xA8,0x00,0xB4,0x00,0xC0,0x00,0xCC,0x00, + 0xD8,0x00,0xE4,0x00,0xF0,0x00,0xFC,0x00,0x08,0x01,0x14,0x01,0x20,0x01,0x2C,0x01,0x38,0x01, + 0x44,0x01,0x50,0x01,0x5C,0x01,0x68,0x01,0x74,0x01,0x80,0x01,0x8C,0x01,0x98,0x01,0xA4,0x01, + 0xB0,0x01,0xBC,0x01,0xC8,0x01,0xD4,0x01,0xE0,0x01,0xEC,0x01,0xF8,0x01,0x04,0x02,0x10,0x02, + 0x1C,0x02,0x28,0x02,0x34,0x02,0x40,0x02,0x4C,0x02,0x58,0x02,0x64,0x02,0x70,0x02,0x7C,0x02, + 0x88,0x02,0x94,0x02,0xA0,0x02,0xAC,0x02,0xB8,0x02,0xC4,0x02,0xD0,0x02,0xDC,0x02,0xE8,0x02, + 0xF4,0x02,0x00,0x03,0x0C,0x03,0x18,0x03,0x24,0x03,0x30,0x03,0x3C,0x03,0x48,0x03,0x54,0x03, + 0x60,0x03,0x6C,0x03,0x78,0x03,0x84,0x03,0x90,0x03,0x9C,0x03,0xA8,0x03,0xB4,0x03,0xC0,0x03, + 0xCC,0x03,0xD8,0x03,0xE4,0x03,0xF0,0x03,0xFC,0x03,0x08,0x04,0x14,0x04,0x20,0x04,0x2C,0x04, + 0x38,0x04,0x44,0x04,0x50,0x04,0x5C,0x04,0x68,0x04,0x74,0x04, + + 6, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x21 '!' + 0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00,0x00, + + 6, // 0x22 '"' + 0x00,0x28,0x28,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x23 '#' + 0x00,0x28,0x28,0x7C,0x28,0x28,0x7C,0x28,0x28,0x00,0x00, + + 6, // 0x24 '$' + 0x00,0x10,0x38,0x54,0x50,0x38,0x14,0x54,0x38,0x10,0x00, + + 6, // 0x25 '%' + 0x00,0x68,0xA8,0xD0,0x10,0x20,0x2C,0x54,0x58,0x00,0x00, + + 6, // 0x26 '&' + 0x00,0x20,0x50,0x50,0x20,0x54,0x54,0x48,0x34,0x00,0x00, + + 6, // 0x27 ''' + 0x00,0x10,0x10,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x28 '(' + 0x08,0x10,0x10,0x20,0x20,0x20,0x20,0x10,0x10,0x08,0x00, + + 6, // 0x29 ')' + 0x20,0x10,0x10,0x08,0x08,0x08,0x08,0x10,0x10,0x20,0x00, + + 6, // 0x2A '*' + 0x00,0x00,0x28,0x7C,0x38,0x7C,0x28,0x00,0x00,0x00,0x00, + + 6, // 0x2B '+' + 0x00,0x00,0x00,0x10,0x10,0x7C,0x10,0x10,0x00,0x00,0x00, + + 6, // 0x2C ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x20,0x40, + + 6, // 0x2D '-' + 0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x2E '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00, + + 6, // 0x2F '/' + 0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x00, + + 6, // 0x30 '0' + 0x00,0x38,0x44,0x44,0x54,0x54,0x44,0x44,0x38,0x00,0x00, + + 6, // 0x31 '1' + 0x00,0x10,0x30,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00, + + 6, // 0x32 '2' + 0x00,0x38,0x44,0x44,0x08,0x10,0x20,0x40,0x7C,0x00,0x00, + + 6, // 0x33 '3' + 0x00,0x38,0x44,0x04,0x38,0x04,0x04,0x44,0x38,0x00,0x00, + + 6, // 0x34 '4' + 0x00,0x08,0x18,0x28,0x28,0x48,0x7C,0x08,0x08,0x00,0x00, + + 6, // 0x35 '5' + 0x00,0x7C,0x40,0x78,0x44,0x04,0x04,0x44,0x38,0x00,0x00, + + 6, // 0x36 '6' + 0x00,0x38,0x44,0x40,0x78,0x44,0x44,0x44,0x38,0x00,0x00, + + 6, // 0x37 '7' + 0x00,0x7C,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x00,0x00, + + 6, // 0x38 '8' + 0x00,0x38,0x44,0x44,0x38,0x44,0x44,0x44,0x38,0x00,0x00, + + 6, // 0x39 '9' + 0x00,0x38,0x44,0x44,0x3C,0x04,0x04,0x44,0x38,0x00,0x00, + + 6, // 0x3A ':' + 0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x30,0x30,0x00,0x00, + + 6, // 0x3B ';' + 0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x30,0x30,0x20,0x40, + + 6, // 0x3C '<' + 0x00,0x04,0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x04,0x00, + + 6, // 0x3D '=' + 0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x7C,0x00,0x00,0x00, + + 6, // 0x3E '>' + 0x00,0x40,0x20,0x10,0x08,0x04,0x08,0x10,0x20,0x40,0x00, + + 6, // 0x3F '?' + 0x00,0x38,0x44,0x04,0x08,0x10,0x10,0x00,0x10,0x00,0x00, + + 6, // 0x40 '@' + 0x00,0x38,0x44,0x5C,0x54,0x54,0x4C,0x40,0x38,0x00,0x00, + + 6, // 0x41 'A' + 0x00,0x38,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x00,0x00, + + 6, // 0x42 'B' + 0x00,0x78,0x44,0x44,0x78,0x44,0x44,0x44,0x78,0x00,0x00, + + 6, // 0x43 'C' + 0x00,0x38,0x44,0x40,0x40,0x40,0x40,0x44,0x38,0x00,0x00, + + 6, // 0x44 'D' + 0x00,0x70,0x48,0x44,0x44,0x44,0x44,0x48,0x70,0x00,0x00, + + 6, // 0x45 'E' + 0x00,0x7C,0x40,0x40,0x78,0x40,0x40,0x40,0x7C,0x00,0x00, + + 6, // 0x46 'F' + 0x00,0x7C,0x40,0x40,0x78,0x40,0x40,0x40,0x40,0x00,0x00, + + 6, // 0x47 'G' + 0x00,0x38,0x44,0x40,0x40,0x5C,0x44,0x4C,0x34,0x00,0x00, + + 6, // 0x48 'H' + 0x00,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x44,0x00,0x00, + + 6, // 0x49 'I' + 0x00,0x38,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00, + + 6, // 0x4A 'J' + 0x00,0x1C,0x08,0x08,0x08,0x08,0x48,0x48,0x30,0x00,0x00, + + 6, // 0x4B 'K' + 0x00,0x44,0x48,0x50,0x60,0x50,0x48,0x44,0x44,0x00,0x00, + + 6, // 0x4C 'L' + 0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7C,0x00,0x00, + + 6, // 0x4D 'M' + 0x00,0x44,0x6C,0x54,0x54,0x54,0x44,0x44,0x44,0x00,0x00, + + 6, // 0x4E 'N' + 0x00,0x44,0x64,0x64,0x54,0x54,0x4C,0x4C,0x44,0x00,0x00, + + 6, // 0x4F 'O' + 0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00, + + 6, // 0x50 'P' + 0x00,0x78,0x44,0x44,0x44,0x78,0x40,0x40,0x40,0x00,0x00, + + 6, // 0x51 'Q' + 0x00,0x38,0x44,0x44,0x44,0x44,0x54,0x48,0x34,0x00,0x00, + + 6, // 0x52 'R' + 0x00,0x78,0x44,0x44,0x44,0x78,0x48,0x44,0x44,0x00,0x00, + + 6, // 0x53 'S' + 0x00,0x38,0x44,0x40,0x38,0x04,0x04,0x44,0x38,0x00,0x00, + + 6, // 0x54 'T' + 0x00,0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00, + + 6, // 0x55 'U' + 0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00, + + 6, // 0x56 'V' + 0x00,0x44,0x44,0x44,0x28,0x28,0x28,0x10,0x10,0x00,0x00, + + 6, // 0x57 'W' + 0x00,0x44,0x44,0x54,0x54,0x54,0x54,0x54,0x28,0x00,0x00, + + 6, // 0x58 'X' + 0x00,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x44,0x00,0x00, + + 6, // 0x59 'Y' + 0x00,0x44,0x44,0x44,0x28,0x10,0x10,0x10,0x10,0x00,0x00, + + 6, // 0x5A 'Z' + 0x00,0x7C,0x04,0x08,0x10,0x20,0x40,0x40,0x7C,0x00,0x00, + + 6, // 0x5B '[' + 0x38,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x38,0x00, + + 6, // 0x5C '\' + 0x80,0x80,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x00, + + 6, // 0x5D ']' + 0x38,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x38,0x00, + + 6, // 0x5E '^' + 0x00,0x10,0x28,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x5F '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00, + + 6, // 0x60 '`' + 0x00,0x20,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x61 'a' + 0x00,0x00,0x00,0x38,0x04,0x3C,0x44,0x44,0x3C,0x00,0x00, + + 6, // 0x62 'b' + 0x00,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x78,0x00,0x00, + + 6, // 0x63 'c' + 0x00,0x00,0x00,0x38,0x44,0x40,0x40,0x44,0x38,0x00,0x00, + + 6, // 0x64 'd' + 0x00,0x04,0x04,0x3C,0x44,0x44,0x44,0x44,0x3C,0x00,0x00, + + 6, // 0x65 'e' + 0x00,0x00,0x00,0x38,0x44,0x7C,0x40,0x44,0x38,0x00,0x00, + + 6, // 0x66 'f' + 0x00,0x0C,0x10,0x38,0x10,0x10,0x10,0x10,0x10,0x00,0x00, + + 6, // 0x67 'g' + 0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x44,0x3C,0x04,0x78, + + 6, // 0x68 'h' + 0x00,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x44,0x00,0x00, + + 6, // 0x69 'i' + 0x00,0x10,0x00,0x30,0x10,0x10,0x10,0x10,0x38,0x00,0x00, + + 6, // 0x6A 'j' + 0x00,0x10,0x00,0x30,0x10,0x10,0x10,0x10,0x10,0x50,0x20, + + 6, // 0x6B 'k' + 0x00,0x40,0x40,0x4C,0x50,0x60,0x50,0x48,0x44,0x00,0x00, + + 6, // 0x6C 'l' + 0x00,0x30,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00, + + 6, // 0x6D 'm' + 0x00,0x00,0x00,0x68,0x54,0x54,0x54,0x44,0x44,0x00,0x00, + + 6, // 0x6E 'n' + 0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x44,0x44,0x00,0x00, + + 6, // 0x6F 'o' + 0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x38,0x00,0x00, + + 6, // 0x70 'p' + 0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x44,0x78,0x40,0x40, + + 6, // 0x71 'q' + 0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x44,0x3C,0x04,0x04, + + 6, // 0x72 'r' + 0x00,0x00,0x00,0x58,0x24,0x20,0x20,0x20,0x70,0x00,0x00, + + 6, // 0x73 's' + 0x00,0x00,0x00,0x38,0x44,0x30,0x08,0x44,0x38,0x00,0x00, + + 6, // 0x74 't' + 0x00,0x20,0x20,0x70,0x20,0x20,0x20,0x20,0x18,0x00,0x00, + + 6, // 0x75 'u' + 0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x4C,0x34,0x00,0x00, + + 6, // 0x76 'v' + 0x00,0x00,0x00,0x44,0x44,0x28,0x28,0x10,0x10,0x00,0x00, + + 6, // 0x77 'w' + 0x00,0x00,0x00,0x44,0x44,0x44,0x54,0x7C,0x28,0x00,0x00, + + 6, // 0x78 'x' + 0x00,0x00,0x00,0x44,0x28,0x10,0x28,0x44,0x44,0x00,0x00, + + 6, // 0x79 'y' + 0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x3C,0x08,0x70, + + 6, // 0x7A 'z' + 0x00,0x00,0x00,0x7C,0x08,0x10,0x20,0x40,0x7C,0x00,0x00, + + 6, // 0x7B '{' + 0x18,0x20,0x20,0x20,0xC0,0xC0,0x20,0x20,0x20,0x18,0x00, + + 6, // 0x7C '|' + 0x00,0x10,0x10,0x10,0x10,0x00,0x10,0x10,0x10,0x10,0x00, + + 6, // 0x7D '}' + 0x60,0x10,0x10,0x10,0x0C,0x0C,0x10,0x10,0x10,0x60,0x00, + + 6, // 0x7E '~' + 0x00,0x24,0x54,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x7F '' + 0x00,0x10,0x38,0x6C,0x44,0x44,0x7C,0x00,0x00,0x00,0x00, + + 0 + }; + + const int8u mcs7x12_mono_high[] = + { + 12, 3, 32, 128-32, + 0x00,0x00,0x0D,0x00,0x1A,0x00,0x27,0x00,0x34,0x00,0x41,0x00,0x4E,0x00,0x5B,0x00,0x68,0x00, + 0x75,0x00,0x82,0x00,0x8F,0x00,0x9C,0x00,0xA9,0x00,0xB6,0x00,0xC3,0x00,0xD0,0x00,0xDD,0x00, + 0xEA,0x00,0xF7,0x00,0x04,0x01,0x11,0x01,0x1E,0x01,0x2B,0x01,0x38,0x01,0x45,0x01,0x52,0x01, + 0x5F,0x01,0x6C,0x01,0x79,0x01,0x86,0x01,0x93,0x01,0xA0,0x01,0xAD,0x01,0xBA,0x01,0xC7,0x01, + 0xD4,0x01,0xE1,0x01,0xEE,0x01,0xFB,0x01,0x08,0x02,0x15,0x02,0x22,0x02,0x2F,0x02,0x3C,0x02, + 0x49,0x02,0x56,0x02,0x63,0x02,0x70,0x02,0x7D,0x02,0x8A,0x02,0x97,0x02,0xA4,0x02,0xB1,0x02, + 0xBE,0x02,0xCB,0x02,0xD8,0x02,0xE5,0x02,0xF2,0x02,0xFF,0x02,0x0C,0x03,0x19,0x03,0x26,0x03, + 0x33,0x03,0x40,0x03,0x4D,0x03,0x5A,0x03,0x67,0x03,0x74,0x03,0x81,0x03,0x8E,0x03,0x9B,0x03, + 0xA8,0x03,0xB5,0x03,0xC2,0x03,0xCF,0x03,0xDC,0x03,0xE9,0x03,0xF6,0x03,0x03,0x04,0x10,0x04, + 0x1D,0x04,0x2A,0x04,0x37,0x04,0x44,0x04,0x51,0x04,0x5E,0x04,0x6B,0x04,0x78,0x04,0x85,0x04, + 0x92,0x04,0x9F,0x04,0xAC,0x04,0xB9,0x04,0xC6,0x04,0xD3,0x04, + + 7, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x21 '!' + 0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x10,0x00,0x00, + + 7, // 0x22 '"' + 0x28,0x28,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x23 '#' + 0x24,0x24,0x24,0x7E,0x24,0x24,0x24,0x7E,0x24,0x24,0x24,0x00, + + 7, // 0x24 '$' + 0x10,0x10,0x38,0x54,0x50,0x38,0x14,0x54,0x38,0x10,0x10,0x00, + + 7, // 0x25 '%' + 0x32,0x54,0x64,0x08,0x08,0x10,0x10,0x26,0x2A,0x4C,0x00,0x00, + + 7, // 0x26 '&' + 0x00,0x20,0x50,0x50,0x50,0x20,0x54,0x54,0x48,0x34,0x00,0x00, + + 7, // 0x27 ''' + 0x10,0x10,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x28 '(' + 0x08,0x10,0x10,0x20,0x20,0x20,0x20,0x20,0x10,0x10,0x08,0x00, + + 7, // 0x29 ')' + 0x20,0x10,0x10,0x08,0x08,0x08,0x08,0x08,0x10,0x10,0x20,0x00, + + 7, // 0x2A '*' + 0x00,0x00,0x10,0x54,0x38,0x7C,0x38,0x54,0x10,0x00,0x00,0x00, + + 7, // 0x2B '+' + 0x00,0x00,0x00,0x00,0x10,0x10,0x7C,0x10,0x10,0x00,0x00,0x00, + + 7, // 0x2C ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x20,0x40, + + 7, // 0x2D '-' + 0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x2E '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00, + + 7, // 0x2F '/' + 0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x00,0x00, + + 7, // 0x30 '0' + 0x00,0x38,0x44,0x44,0x54,0x54,0x54,0x44,0x44,0x38,0x00,0x00, + + 7, // 0x31 '1' + 0x00,0x10,0x30,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00, + + 7, // 0x32 '2' + 0x00,0x38,0x44,0x04,0x04,0x08,0x10,0x20,0x40,0x7C,0x00,0x00, + + 7, // 0x33 '3' + 0x00,0x38,0x44,0x04,0x04,0x38,0x04,0x04,0x44,0x38,0x00,0x00, + + 7, // 0x34 '4' + 0x00,0x08,0x18,0x28,0x28,0x48,0x48,0x7C,0x08,0x08,0x00,0x00, + + 7, // 0x35 '5' + 0x00,0x7C,0x40,0x40,0x78,0x44,0x04,0x04,0x44,0x38,0x00,0x00, + + 7, // 0x36 '6' + 0x00,0x38,0x44,0x40,0x78,0x44,0x44,0x44,0x44,0x38,0x00,0x00, + + 7, // 0x37 '7' + 0x00,0x7C,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x20,0x00,0x00, + + 7, // 0x38 '8' + 0x00,0x38,0x44,0x44,0x44,0x38,0x44,0x44,0x44,0x38,0x00,0x00, + + 7, // 0x39 '9' + 0x00,0x38,0x44,0x44,0x44,0x3C,0x04,0x04,0x44,0x38,0x00,0x00, + + 7, // 0x3A ':' + 0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x30,0x30,0x00,0x00, + + 7, // 0x3B ';' + 0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x30,0x30,0x20,0x40, + + 7, // 0x3C '<' + 0x00,0x04,0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x04,0x00,0x00, + + 7, // 0x3D '=' + 0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x7C,0x00,0x00,0x00,0x00, + + 7, // 0x3E '>' + 0x00,0x40,0x20,0x10,0x08,0x04,0x08,0x10,0x20,0x40,0x00,0x00, + + 7, // 0x3F '?' + 0x00,0x38,0x44,0x04,0x04,0x08,0x10,0x10,0x00,0x10,0x00,0x00, + + 7, // 0x40 '@' + 0x00,0x38,0x44,0x44,0x5C,0x54,0x54,0x4C,0x40,0x38,0x00,0x00, + + 7, // 0x41 'A' + 0x00,0x38,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x44,0x00,0x00, + + 7, // 0x42 'B' + 0x00,0x78,0x44,0x44,0x44,0x78,0x44,0x44,0x44,0x78,0x00,0x00, + + 7, // 0x43 'C' + 0x00,0x38,0x44,0x40,0x40,0x40,0x40,0x40,0x44,0x38,0x00,0x00, + + 7, // 0x44 'D' + 0x00,0x70,0x48,0x44,0x44,0x44,0x44,0x44,0x48,0x70,0x00,0x00, + + 7, // 0x45 'E' + 0x00,0x7C,0x40,0x40,0x40,0x78,0x40,0x40,0x40,0x7C,0x00,0x00, + + 7, // 0x46 'F' + 0x00,0x7C,0x40,0x40,0x40,0x78,0x40,0x40,0x40,0x40,0x00,0x00, + + 7, // 0x47 'G' + 0x00,0x38,0x44,0x40,0x40,0x5C,0x44,0x44,0x4C,0x34,0x00,0x00, + + 7, // 0x48 'H' + 0x00,0x44,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x44,0x00,0x00, + + 7, // 0x49 'I' + 0x00,0x38,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00, + + 7, // 0x4A 'J' + 0x00,0x1C,0x08,0x08,0x08,0x08,0x08,0x48,0x48,0x30,0x00,0x00, + + 7, // 0x4B 'K' + 0x00,0x44,0x48,0x50,0x60,0x60,0x50,0x48,0x44,0x44,0x00,0x00, + + 7, // 0x4C 'L' + 0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7C,0x00,0x00, + + 7, // 0x4D 'M' + 0x00,0x44,0x6C,0x6C,0x54,0x54,0x44,0x44,0x44,0x44,0x00,0x00, + + 7, // 0x4E 'N' + 0x00,0x44,0x64,0x64,0x54,0x54,0x4C,0x4C,0x44,0x44,0x00,0x00, + + 7, // 0x4F 'O' + 0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00, + + 7, // 0x50 'P' + 0x00,0x78,0x44,0x44,0x44,0x44,0x78,0x40,0x40,0x40,0x00,0x00, + + 7, // 0x51 'Q' + 0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x54,0x48,0x34,0x00,0x00, + + 7, // 0x52 'R' + 0x00,0x78,0x44,0x44,0x44,0x44,0x78,0x48,0x44,0x44,0x00,0x00, + + 7, // 0x53 'S' + 0x00,0x38,0x44,0x40,0x40,0x38,0x04,0x04,0x44,0x38,0x00,0x00, + + 7, // 0x54 'T' + 0x00,0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00, + + 7, // 0x55 'U' + 0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00, + + 7, // 0x56 'V' + 0x00,0x44,0x44,0x44,0x44,0x28,0x28,0x28,0x10,0x10,0x00,0x00, + + 7, // 0x57 'W' + 0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x54,0x54,0x28,0x00,0x00, + + 7, // 0x58 'X' + 0x00,0x44,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x44,0x00,0x00, + + 7, // 0x59 'Y' + 0x00,0x44,0x44,0x44,0x44,0x28,0x10,0x10,0x10,0x10,0x00,0x00, + + 7, // 0x5A 'Z' + 0x00,0x7C,0x04,0x04,0x08,0x10,0x20,0x40,0x40,0x7C,0x00,0x00, + + 7, // 0x5B '[' + 0x38,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x38,0x00, + + 7, // 0x5C '\' + 0x00,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x04,0x04,0x00, + + 7, // 0x5D ']' + 0x38,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x38,0x00, + + 7, // 0x5E '^' + 0x00,0x10,0x28,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x5F '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00, + + 7, // 0x60 '`' + 0x00,0x20,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x61 'a' + 0x00,0x00,0x00,0x38,0x04,0x3C,0x44,0x44,0x44,0x3C,0x00,0x00, + + 7, // 0x62 'b' + 0x00,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x44,0x78,0x00,0x00, + + 7, // 0x63 'c' + 0x00,0x00,0x00,0x38,0x44,0x40,0x40,0x40,0x44,0x38,0x00,0x00, + + 7, // 0x64 'd' + 0x00,0x04,0x04,0x3C,0x44,0x44,0x44,0x44,0x44,0x3C,0x00,0x00, + + 7, // 0x65 'e' + 0x00,0x00,0x00,0x38,0x44,0x44,0x7C,0x40,0x44,0x38,0x00,0x00, + + 7, // 0x66 'f' + 0x00,0x0C,0x10,0x38,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00, + + 7, // 0x67 'g' + 0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x44,0x44,0x3C,0x04,0x78, + + 7, // 0x68 'h' + 0x00,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x44,0x44,0x00,0x00, + + 7, // 0x69 'i' + 0x00,0x10,0x00,0x30,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00, + + 7, // 0x6A 'j' + 0x00,0x08,0x00,0x18,0x08,0x08,0x08,0x08,0x08,0x08,0x48,0x30, + + 7, // 0x6B 'k' + 0x00,0x40,0x40,0x44,0x48,0x50,0x60,0x50,0x48,0x44,0x00,0x00, + + 7, // 0x6C 'l' + 0x00,0x30,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00, + + 7, // 0x6D 'm' + 0x00,0x00,0x00,0x68,0x54,0x54,0x44,0x44,0x44,0x44,0x00,0x00, + + 7, // 0x6E 'n' + 0x00,0x00,0x00,0x58,0x64,0x44,0x44,0x44,0x44,0x44,0x00,0x00, + + 7, // 0x6F 'o' + 0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00, + + 7, // 0x70 'p' + 0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x44,0x44,0x78,0x40,0x40, + + 7, // 0x71 'q' + 0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x44,0x44,0x3C,0x04,0x04, + + 7, // 0x72 'r' + 0x00,0x00,0x00,0x58,0x24,0x20,0x20,0x20,0x20,0x70,0x00,0x00, + + 7, // 0x73 's' + 0x00,0x00,0x00,0x38,0x44,0x40,0x38,0x04,0x44,0x38,0x00,0x00, + + 7, // 0x74 't' + 0x00,0x20,0x20,0x70,0x20,0x20,0x20,0x20,0x24,0x18,0x00,0x00, + + 7, // 0x75 'u' + 0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x4C,0x34,0x00,0x00, + + 7, // 0x76 'v' + 0x00,0x00,0x00,0x44,0x44,0x44,0x28,0x28,0x10,0x10,0x00,0x00, + + 7, // 0x77 'w' + 0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x54,0x54,0x28,0x00,0x00, + + 7, // 0x78 'x' + 0x00,0x00,0x00,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x00,0x00, + + 7, // 0x79 'y' + 0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x3C,0x08,0x70, + + 7, // 0x7A 'z' + 0x00,0x00,0x00,0x7C,0x04,0x08,0x10,0x20,0x40,0x7C,0x00,0x00, + + 7, // 0x7B '{' + 0x18,0x20,0x20,0x20,0x20,0xC0,0x20,0x20,0x20,0x20,0x18,0x00, + + 7, // 0x7C '|' + 0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00, + + 7, // 0x7D '}' + 0x60,0x10,0x10,0x10,0x10,0x0C,0x10,0x10,0x10,0x10,0x60,0x00, + + 7, // 0x7E '~' + 0x00,0x60,0x92,0x92,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x7F '' + 0x00,0x10,0x38,0x6C,0x44,0x44,0x7C,0x00,0x00,0x00,0x00,0x00, + + 0 + }; + + const int8u mcs7x12_mono_low[] = + { + 12, 4, 32, 128-32, + 0x00,0x00,0x0D,0x00,0x1A,0x00,0x27,0x00,0x34,0x00,0x41,0x00,0x4E,0x00,0x5B,0x00,0x68,0x00, + 0x75,0x00,0x82,0x00,0x8F,0x00,0x9C,0x00,0xA9,0x00,0xB6,0x00,0xC3,0x00,0xD0,0x00,0xDD,0x00, + 0xEA,0x00,0xF7,0x00,0x04,0x01,0x11,0x01,0x1E,0x01,0x2B,0x01,0x38,0x01,0x45,0x01,0x52,0x01, + 0x5F,0x01,0x6C,0x01,0x79,0x01,0x86,0x01,0x93,0x01,0xA0,0x01,0xAD,0x01,0xBA,0x01,0xC7,0x01, + 0xD4,0x01,0xE1,0x01,0xEE,0x01,0xFB,0x01,0x08,0x02,0x15,0x02,0x22,0x02,0x2F,0x02,0x3C,0x02, + 0x49,0x02,0x56,0x02,0x63,0x02,0x70,0x02,0x7D,0x02,0x8A,0x02,0x97,0x02,0xA4,0x02,0xB1,0x02, + 0xBE,0x02,0xCB,0x02,0xD8,0x02,0xE5,0x02,0xF2,0x02,0xFF,0x02,0x0C,0x03,0x19,0x03,0x26,0x03, + 0x33,0x03,0x40,0x03,0x4D,0x03,0x5A,0x03,0x67,0x03,0x74,0x03,0x81,0x03,0x8E,0x03,0x9B,0x03, + 0xA8,0x03,0xB5,0x03,0xC2,0x03,0xCF,0x03,0xDC,0x03,0xE9,0x03,0xF6,0x03,0x03,0x04,0x10,0x04, + 0x1D,0x04,0x2A,0x04,0x37,0x04,0x44,0x04,0x51,0x04,0x5E,0x04,0x6B,0x04,0x78,0x04,0x85,0x04, + 0x92,0x04,0x9F,0x04,0xAC,0x04,0xB9,0x04,0xC6,0x04,0xD3,0x04, + + 7, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x21 '!' + 0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x10,0x00,0x00, + + 7, // 0x22 '"' + 0x28,0x28,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x23 '#' + 0x00,0x28,0x28,0x7C,0x28,0x28,0x28,0x7C,0x28,0x28,0x00,0x00, + + 7, // 0x24 '$' + 0x00,0x10,0x38,0x54,0x50,0x38,0x14,0x54,0x38,0x10,0x00,0x00, + + 7, // 0x25 '%' + 0x34,0x54,0x68,0x08,0x10,0x10,0x20,0x2C,0x54,0x58,0x00,0x00, + + 7, // 0x26 '&' + 0x00,0x20,0x50,0x50,0x20,0x54,0x54,0x48,0x34,0x00,0x00,0x00, + + 7, // 0x27 ''' + 0x00,0x10,0x10,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x28 '(' + 0x08,0x10,0x10,0x20,0x20,0x20,0x20,0x20,0x10,0x10,0x08,0x00, + + 7, // 0x29 ')' + 0x20,0x10,0x10,0x08,0x08,0x08,0x08,0x08,0x10,0x10,0x20,0x00, + + 7, // 0x2A '*' + 0x00,0x00,0x10,0x54,0x38,0x7C,0x38,0x54,0x10,0x00,0x00,0x00, + + 7, // 0x2B '+' + 0x00,0x00,0x00,0x10,0x10,0x7C,0x10,0x10,0x00,0x00,0x00,0x00, + + 7, // 0x2C ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x20,0x40,0x00, + + 7, // 0x2D '-' + 0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x2E '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00, + + 7, // 0x2F '/' + 0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x00,0x00, + + 7, // 0x30 '0' + 0x00,0x38,0x44,0x44,0x54,0x54,0x44,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x31 '1' + 0x00,0x10,0x30,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00,0x00, + + 7, // 0x32 '2' + 0x00,0x38,0x44,0x44,0x08,0x10,0x20,0x40,0x7C,0x00,0x00,0x00, + + 7, // 0x33 '3' + 0x00,0x38,0x44,0x04,0x38,0x04,0x04,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x34 '4' + 0x00,0x08,0x18,0x28,0x28,0x48,0x7C,0x08,0x08,0x00,0x00,0x00, + + 7, // 0x35 '5' + 0x00,0x7C,0x40,0x78,0x44,0x04,0x04,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x36 '6' + 0x00,0x38,0x44,0x40,0x78,0x44,0x44,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x37 '7' + 0x00,0x7C,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x00,0x00,0x00, + + 7, // 0x38 '8' + 0x00,0x38,0x44,0x44,0x38,0x44,0x44,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x39 '9' + 0x00,0x38,0x44,0x44,0x44,0x3C,0x04,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x3A ':' + 0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x30,0x30,0x00,0x00,0x00, + + 7, // 0x3B ';' + 0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x30,0x30,0x20,0x40,0x00, + + 7, // 0x3C '<' + 0x00,0x04,0x08,0x10,0x20,0x40,0x20,0x10,0x08,0x04,0x00,0x00, + + 7, // 0x3D '=' + 0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x7C,0x00,0x00,0x00,0x00, + + 7, // 0x3E '>' + 0x00,0x40,0x20,0x10,0x08,0x04,0x08,0x10,0x20,0x40,0x00,0x00, + + 7, // 0x3F '?' + 0x00,0x38,0x44,0x04,0x04,0x08,0x10,0x10,0x00,0x10,0x00,0x00, + + 7, // 0x40 '@' + 0x00,0x38,0x44,0x44,0x5C,0x54,0x4C,0x40,0x38,0x00,0x00,0x00, + + 7, // 0x41 'A' + 0x00,0x38,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x42 'B' + 0x00,0x78,0x44,0x44,0x78,0x44,0x44,0x44,0x78,0x00,0x00,0x00, + + 7, // 0x43 'C' + 0x00,0x38,0x44,0x40,0x40,0x40,0x40,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x44 'D' + 0x00,0x70,0x48,0x44,0x44,0x44,0x44,0x48,0x70,0x00,0x00,0x00, + + 7, // 0x45 'E' + 0x00,0x7C,0x40,0x40,0x78,0x40,0x40,0x40,0x7C,0x00,0x00,0x00, + + 7, // 0x46 'F' + 0x00,0x7C,0x40,0x40,0x78,0x40,0x40,0x40,0x40,0x00,0x00,0x00, + + 7, // 0x47 'G' + 0x00,0x38,0x44,0x40,0x40,0x4C,0x44,0x4C,0x34,0x00,0x00,0x00, + + 7, // 0x48 'H' + 0x00,0x44,0x44,0x44,0x7C,0x44,0x44,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x49 'I' + 0x00,0x38,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00,0x00, + + 7, // 0x4A 'J' + 0x00,0x1C,0x08,0x08,0x08,0x08,0x48,0x48,0x30,0x00,0x00,0x00, + + 7, // 0x4B 'K' + 0x00,0x44,0x48,0x50,0x60,0x60,0x50,0x48,0x44,0x00,0x00,0x00, + + 7, // 0x4C 'L' + 0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7C,0x00,0x00,0x00, + + 7, // 0x4D 'M' + 0x00,0x44,0x6C,0x54,0x54,0x44,0x44,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x4E 'N' + 0x00,0x44,0x64,0x64,0x54,0x54,0x4C,0x4C,0x44,0x00,0x00,0x00, + + 7, // 0x4F 'O' + 0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x50 'P' + 0x00,0x78,0x44,0x44,0x44,0x78,0x40,0x40,0x40,0x00,0x00,0x00, + + 7, // 0x51 'Q' + 0x00,0x38,0x44,0x44,0x44,0x44,0x54,0x48,0x34,0x00,0x00,0x00, + + 7, // 0x52 'R' + 0x00,0x78,0x44,0x44,0x44,0x78,0x48,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x53 'S' + 0x00,0x38,0x44,0x40,0x38,0x04,0x44,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x54 'T' + 0x00,0x7C,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00,0x00, + + 7, // 0x55 'U' + 0x00,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x56 'V' + 0x00,0x44,0x44,0x44,0x28,0x28,0x28,0x10,0x10,0x00,0x00,0x00, + + 7, // 0x57 'W' + 0x00,0x44,0x44,0x44,0x44,0x44,0x54,0x54,0x28,0x00,0x00,0x00, + + 7, // 0x58 'X' + 0x00,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x59 'Y' + 0x00,0x44,0x44,0x44,0x28,0x10,0x10,0x10,0x10,0x00,0x00,0x00, + + 7, // 0x5A 'Z' + 0x00,0x7C,0x04,0x08,0x10,0x20,0x40,0x40,0x7C,0x00,0x00,0x00, + + 7, // 0x5B '[' + 0x38,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x38,0x00, + + 7, // 0x5C '\' + 0x00,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x04,0x04,0x00, + + 7, // 0x5D ']' + 0x38,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x38,0x00, + + 7, // 0x5E '^' + 0x00,0x10,0x28,0x44,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x5F '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00, + + 7, // 0x60 '`' + 0x00,0x20,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x61 'a' + 0x00,0x00,0x00,0x38,0x04,0x3C,0x44,0x44,0x3C,0x00,0x00,0x00, + + 7, // 0x62 'b' + 0x00,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x78,0x00,0x00,0x00, + + 7, // 0x63 'c' + 0x00,0x00,0x00,0x38,0x44,0x40,0x40,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x64 'd' + 0x00,0x04,0x04,0x3C,0x44,0x44,0x44,0x44,0x3C,0x00,0x00,0x00, + + 7, // 0x65 'e' + 0x00,0x00,0x00,0x38,0x44,0x7C,0x40,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x66 'f' + 0x00,0x0C,0x10,0x38,0x10,0x10,0x10,0x10,0x10,0x00,0x00,0x00, + + 7, // 0x67 'g' + 0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x44,0x3C,0x04,0x44,0x38, + + 7, // 0x68 'h' + 0x00,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x69 'i' + 0x00,0x10,0x00,0x30,0x10,0x10,0x10,0x10,0x38,0x00,0x00,0x00, + + 7, // 0x6A 'j' + 0x00,0x08,0x00,0x18,0x08,0x08,0x08,0x08,0x08,0x48,0x48,0x30, + + 7, // 0x6B 'k' + 0x00,0x40,0x40,0x4C,0x50,0x60,0x50,0x48,0x44,0x00,0x00,0x00, + + 7, // 0x6C 'l' + 0x00,0x30,0x10,0x10,0x10,0x10,0x10,0x10,0x38,0x00,0x00,0x00, + + 7, // 0x6D 'm' + 0x00,0x00,0x00,0x68,0x54,0x54,0x44,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x6E 'n' + 0x00,0x00,0x00,0x58,0x64,0x44,0x44,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x6F 'o' + 0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x70 'p' + 0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x44,0x78,0x40,0x40,0x40, + + 7, // 0x71 'q' + 0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x44,0x3C,0x04,0x04,0x04, + + 7, // 0x72 'r' + 0x00,0x00,0x00,0x58,0x24,0x20,0x20,0x20,0x70,0x00,0x00,0x00, + + 7, // 0x73 's' + 0x00,0x00,0x00,0x38,0x44,0x30,0x08,0x44,0x38,0x00,0x00,0x00, + + 7, // 0x74 't' + 0x00,0x20,0x20,0x70,0x20,0x20,0x20,0x24,0x18,0x00,0x00,0x00, + + 7, // 0x75 'u' + 0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x4C,0x34,0x00,0x00,0x00, + + 7, // 0x76 'v' + 0x00,0x00,0x00,0x44,0x44,0x28,0x28,0x10,0x10,0x00,0x00,0x00, + + 7, // 0x77 'w' + 0x00,0x00,0x00,0x44,0x44,0x44,0x54,0x54,0x28,0x00,0x00,0x00, + + 7, // 0x78 'x' + 0x00,0x00,0x00,0x44,0x28,0x10,0x28,0x44,0x44,0x00,0x00,0x00, + + 7, // 0x79 'y' + 0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x3C,0x04,0x08,0x70, + + 7, // 0x7A 'z' + 0x00,0x00,0x00,0x7C,0x08,0x10,0x20,0x40,0x7C,0x00,0x00,0x00, + + 7, // 0x7B '{' + 0x18,0x20,0x20,0x20,0x20,0xC0,0x20,0x20,0x20,0x20,0x18,0x00, + + 7, // 0x7C '|' + 0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00, + + 7, // 0x7D '}' + 0x60,0x10,0x10,0x10,0x10,0x0C,0x10,0x10,0x10,0x10,0x60,0x00, + + 7, // 0x7E '~' + 0x00,0x24,0x54,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x7F '' + 0x00,0x10,0x38,0x6C,0x44,0x44,0x7C,0x00,0x00,0x00,0x00,0x00, + + 0 + }; + + const int8u verdana12[] = + { + 12, 3, 32, 128-32, + 0x00,0x00,0x0D,0x00,0x1A,0x00,0x27,0x00,0x34,0x00,0x41,0x00,0x5A,0x00,0x67,0x00,0x74,0x00, + 0x81,0x00,0x8E,0x00,0x9B,0x00,0xA8,0x00,0xB5,0x00,0xC2,0x00,0xCF,0x00,0xDC,0x00,0xE9,0x00, + 0xF6,0x00,0x03,0x01,0x10,0x01,0x1D,0x01,0x2A,0x01,0x37,0x01,0x44,0x01,0x51,0x01,0x5E,0x01, + 0x6B,0x01,0x78,0x01,0x85,0x01,0x92,0x01,0x9F,0x01,0xAC,0x01,0xC5,0x01,0xD2,0x01,0xDF,0x01, + 0xEC,0x01,0xF9,0x01,0x06,0x02,0x13,0x02,0x20,0x02,0x2D,0x02,0x3A,0x02,0x47,0x02,0x54,0x02, + 0x61,0x02,0x7A,0x02,0x87,0x02,0xA0,0x02,0xAD,0x02,0xC6,0x02,0xD3,0x02,0xE0,0x02,0xED,0x02, + 0xFA,0x02,0x07,0x03,0x20,0x03,0x2D,0x03,0x3A,0x03,0x47,0x03,0x54,0x03,0x61,0x03,0x6E,0x03, + 0x7B,0x03,0x88,0x03,0x95,0x03,0xA2,0x03,0xAF,0x03,0xBC,0x03,0xC9,0x03,0xD6,0x03,0xE3,0x03, + 0xF0,0x03,0xFD,0x03,0x0A,0x04,0x17,0x04,0x24,0x04,0x31,0x04,0x4A,0x04,0x57,0x04,0x64,0x04, + 0x71,0x04,0x7E,0x04,0x8B,0x04,0x98,0x04,0xA5,0x04,0xB2,0x04,0xBF,0x04,0xCC,0x04,0xD9,0x04, + 0xE6,0x04,0xF3,0x04,0x00,0x05,0x0D,0x05,0x1A,0x05,0x27,0x05, + + 3, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x21 '!' + 0x00,0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00,0x00, + + 5, // 0x22 '"' + 0x00,0x00,0x50,0x50,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x23 '#' + 0x00,0x00,0x00,0x00,0x28,0x7C,0x28,0x7C,0x28,0x00,0x00,0x00, + + 7, // 0x24 '$' + 0x00,0x00,0x10,0x10,0x3C,0x50,0x30,0x18,0x14,0x78,0x10,0x10, + + 11, // 0x25 '%' + 0x00,0x00,0x00,0x00,0x00,0x00,0x31,0x00,0x4A,0x00,0x4A,0x00,0x35,0x80,0x0A,0x40,0x0A,0x40,0x11,0x80,0x00,0x00,0x00,0x00, + + 7, // 0x26 '&' + 0x00,0x00,0x00,0x30,0x48,0x48,0x32,0x4A,0x44,0x3A,0x00,0x00, + + 3, // 0x27 ''' + 0x00,0x00,0x40,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x28 '(' + 0x00,0x00,0x10,0x20,0x40,0x40,0x40,0x40,0x40,0x40,0x20,0x10, + + 4, // 0x29 ')' + 0x00,0x00,0x80,0x40,0x20,0x20,0x20,0x20,0x20,0x20,0x40,0x80, + + 7, // 0x2A '*' + 0x00,0x10,0x54,0x38,0x54,0x10,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x2B '+' + 0x00,0x00,0x00,0x00,0x10,0x10,0x7C,0x10,0x10,0x00,0x00,0x00, + + 3, // 0x2C ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x80,0x00, + + 5, // 0x2D '-' + 0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00, + + 3, // 0x2E '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x00,0x00, + + 4, // 0x2F '/' + 0x00,0x00,0x10,0x10,0x20,0x20,0x40,0x40,0x40,0x80,0x80,0x00, + + 7, // 0x30 '0' + 0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00, + + 7, // 0x31 '1' + 0x00,0x00,0x00,0x10,0x30,0x10,0x10,0x10,0x10,0x38,0x00,0x00, + + 7, // 0x32 '2' + 0x00,0x00,0x00,0x38,0x44,0x04,0x08,0x10,0x20,0x7C,0x00,0x00, + + 7, // 0x33 '3' + 0x00,0x00,0x00,0x38,0x44,0x04,0x18,0x04,0x44,0x38,0x00,0x00, + + 7, // 0x34 '4' + 0x00,0x00,0x00,0x08,0x18,0x28,0x48,0x7C,0x08,0x08,0x00,0x00, + + 7, // 0x35 '5' + 0x00,0x00,0x00,0x7C,0x40,0x78,0x04,0x04,0x44,0x38,0x00,0x00, + + 7, // 0x36 '6' + 0x00,0x00,0x00,0x18,0x20,0x40,0x78,0x44,0x44,0x38,0x00,0x00, + + 7, // 0x37 '7' + 0x00,0x00,0x00,0x7C,0x04,0x08,0x08,0x10,0x10,0x10,0x00,0x00, + + 7, // 0x38 '8' + 0x00,0x00,0x00,0x38,0x44,0x44,0x38,0x44,0x44,0x38,0x00,0x00, + + 7, // 0x39 '9' + 0x00,0x00,0x00,0x38,0x44,0x44,0x3C,0x04,0x08,0x30,0x00,0x00, + + 4, // 0x3A ':' + 0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x00,0x40,0x40,0x00,0x00, + + 4, // 0x3B ';' + 0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x00,0x40,0x40,0x80,0x00, + + 7, // 0x3C '<' + 0x00,0x00,0x00,0x00,0x04,0x18,0x60,0x18,0x04,0x00,0x00,0x00, + + 7, // 0x3D '=' + 0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x7C,0x00,0x00,0x00,0x00, + + 7, // 0x3E '>' + 0x00,0x00,0x00,0x00,0x40,0x30,0x0C,0x30,0x40,0x00,0x00,0x00, + + 6, // 0x3F '?' + 0x00,0x00,0x00,0x70,0x08,0x08,0x10,0x20,0x00,0x20,0x00,0x00, + + 10, // 0x40 '@' + 0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x20,0x80,0x4E,0x80,0x52,0x80,0x52,0x80,0x4D,0x00,0x20,0x00,0x1F,0x00,0x00,0x00, + + 8, // 0x41 'A' + 0x00,0x00,0x00,0x18,0x18,0x24,0x24,0x7E,0x42,0x42,0x00,0x00, + + 7, // 0x42 'B' + 0x00,0x00,0x00,0x70,0x48,0x48,0x78,0x44,0x44,0x78,0x00,0x00, + + 8, // 0x43 'C' + 0x00,0x00,0x00,0x1C,0x22,0x40,0x40,0x40,0x22,0x1C,0x00,0x00, + + 8, // 0x44 'D' + 0x00,0x00,0x00,0x78,0x44,0x42,0x42,0x42,0x44,0x78,0x00,0x00, + + 7, // 0x45 'E' + 0x00,0x00,0x00,0x7C,0x40,0x40,0x78,0x40,0x40,0x7C,0x00,0x00, + + 6, // 0x46 'F' + 0x00,0x00,0x00,0x7C,0x40,0x40,0x78,0x40,0x40,0x40,0x00,0x00, + + 8, // 0x47 'G' + 0x00,0x00,0x00,0x1C,0x22,0x40,0x4E,0x42,0x22,0x1C,0x00,0x00, + + 8, // 0x48 'H' + 0x00,0x00,0x00,0x42,0x42,0x42,0x7E,0x42,0x42,0x42,0x00,0x00, + + 5, // 0x49 'I' + 0x00,0x00,0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, + + 5, // 0x4A 'J' + 0x00,0x00,0x00,0x30,0x10,0x10,0x10,0x10,0x10,0xE0,0x00,0x00, + + 7, // 0x4B 'K' + 0x00,0x00,0x00,0x44,0x48,0x50,0x60,0x50,0x48,0x44,0x00,0x00, + + 6, // 0x4C 'L' + 0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x7C,0x00,0x00, + + 9, // 0x4D 'M' + 0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x00,0x63,0x00,0x55,0x00,0x55,0x00,0x49,0x00,0x49,0x00,0x41,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x4E 'N' + 0x00,0x00,0x00,0x42,0x62,0x52,0x4A,0x46,0x42,0x42,0x00,0x00, + + 9, // 0x4F 'O' + 0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x22,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x22,0x00,0x1C,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x50 'P' + 0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x78,0x40,0x40,0x00,0x00, + + 9, // 0x51 'Q' + 0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x22,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x22,0x00,0x1C,0x00,0x04,0x00,0x03,0x00, + + 7, // 0x52 'R' + 0x00,0x00,0x00,0x78,0x44,0x44,0x78,0x50,0x48,0x44,0x00,0x00, + + 7, // 0x53 'S' + 0x00,0x00,0x00,0x38,0x44,0x40,0x38,0x04,0x44,0x38,0x00,0x00, + + 7, // 0x54 'T' + 0x00,0x00,0x00,0xFE,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00, + + 8, // 0x55 'U' + 0x00,0x00,0x00,0x42,0x42,0x42,0x42,0x42,0x42,0x3C,0x00,0x00, + + 8, // 0x56 'V' + 0x00,0x00,0x00,0x42,0x42,0x42,0x24,0x24,0x18,0x18,0x00,0x00, + + 9, // 0x57 'W' + 0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x49,0x00,0x49,0x00,0x55,0x00,0x55,0x00,0x22,0x00,0x22,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x58 'X' + 0x00,0x00,0x00,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x00,0x00, + + 7, // 0x59 'Y' + 0x00,0x00,0x00,0x44,0x44,0x28,0x28,0x10,0x10,0x10,0x00,0x00, + + 7, // 0x5A 'Z' + 0x00,0x00,0x00,0x7C,0x04,0x08,0x10,0x20,0x40,0x7C,0x00,0x00, + + 4, // 0x5B '[' + 0x00,0x00,0x60,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x60, + + 4, // 0x5C '\' + 0x00,0x00,0x80,0x80,0x40,0x40,0x40,0x20,0x20,0x10,0x10,0x00, + + 4, // 0x5D ']' + 0x00,0x00,0x60,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x60, + + 7, // 0x5E '^' + 0x00,0x00,0x00,0x10,0x28,0x44,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x5F '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC, + + 6, // 0x60 '`' + 0x00,0x00,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x61 'a' + 0x00,0x00,0x00,0x00,0x00,0x30,0x08,0x38,0x48,0x38,0x00,0x00, + + 6, // 0x62 'b' + 0x00,0x00,0x40,0x40,0x40,0x70,0x48,0x48,0x48,0x70,0x00,0x00, + + 6, // 0x63 'c' + 0x00,0x00,0x00,0x00,0x00,0x38,0x40,0x40,0x40,0x38,0x00,0x00, + + 6, // 0x64 'd' + 0x00,0x00,0x08,0x08,0x08,0x38,0x48,0x48,0x48,0x38,0x00,0x00, + + 6, // 0x65 'e' + 0x00,0x00,0x00,0x00,0x00,0x30,0x48,0x78,0x40,0x38,0x00,0x00, + + 4, // 0x66 'f' + 0x00,0x00,0x30,0x40,0x40,0xE0,0x40,0x40,0x40,0x40,0x00,0x00, + + 6, // 0x67 'g' + 0x00,0x00,0x00,0x00,0x00,0x38,0x48,0x48,0x48,0x38,0x08,0x30, + + 6, // 0x68 'h' + 0x00,0x00,0x40,0x40,0x40,0x70,0x48,0x48,0x48,0x48,0x00,0x00, + + 3, // 0x69 'i' + 0x00,0x00,0x00,0x40,0x00,0x40,0x40,0x40,0x40,0x40,0x00,0x00, + + 3, // 0x6A 'j' + 0x00,0x00,0x00,0x40,0x00,0xC0,0x40,0x40,0x40,0x40,0x40,0x80, + + 6, // 0x6B 'k' + 0x00,0x00,0x40,0x40,0x40,0x48,0x50,0x60,0x50,0x48,0x00,0x00, + + 3, // 0x6C 'l' + 0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00, + + 9, // 0x6D 'm' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x76,0x00,0x49,0x00,0x49,0x00,0x49,0x00,0x49,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x6E 'n' + 0x00,0x00,0x00,0x00,0x00,0x70,0x48,0x48,0x48,0x48,0x00,0x00, + + 6, // 0x6F 'o' + 0x00,0x00,0x00,0x00,0x00,0x30,0x48,0x48,0x48,0x30,0x00,0x00, + + 6, // 0x70 'p' + 0x00,0x00,0x00,0x00,0x00,0x70,0x48,0x48,0x48,0x70,0x40,0x40, + + 6, // 0x71 'q' + 0x00,0x00,0x00,0x00,0x00,0x38,0x48,0x48,0x48,0x38,0x08,0x08, + + 4, // 0x72 'r' + 0x00,0x00,0x00,0x00,0x00,0x50,0x60,0x40,0x40,0x40,0x00,0x00, + + 6, // 0x73 's' + 0x00,0x00,0x00,0x00,0x00,0x38,0x40,0x30,0x08,0x70,0x00,0x00, + + 4, // 0x74 't' + 0x00,0x00,0x00,0x00,0x40,0xF0,0x40,0x40,0x40,0x30,0x00,0x00, + + 6, // 0x75 'u' + 0x00,0x00,0x00,0x00,0x00,0x48,0x48,0x48,0x48,0x38,0x00,0x00, + + 6, // 0x76 'v' + 0x00,0x00,0x00,0x00,0x00,0x48,0x48,0x48,0x30,0x30,0x00,0x00, + + 7, // 0x77 'w' + 0x00,0x00,0x00,0x00,0x00,0x44,0x54,0x54,0x28,0x28,0x00,0x00, + + 6, // 0x78 'x' + 0x00,0x00,0x00,0x00,0x00,0x48,0x48,0x30,0x48,0x48,0x00,0x00, + + 6, // 0x79 'y' + 0x00,0x00,0x00,0x00,0x00,0x48,0x48,0x48,0x30,0x10,0x20,0x20, + + 5, // 0x7A 'z' + 0x00,0x00,0x00,0x00,0x00,0x70,0x10,0x20,0x40,0x70,0x00,0x00, + + 6, // 0x7B '{' + 0x00,0x00,0x18,0x20,0x20,0x20,0x20,0xC0,0x20,0x20,0x20,0x18, + + 5, // 0x7C '|' + 0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + + 6, // 0x7D '}' + 0x00,0x00,0x60,0x10,0x10,0x10,0x10,0x0C,0x10,0x10,0x10,0x60, + + 7, // 0x7E '~' + 0x00,0x00,0x00,0x00,0x00,0x00,0x34,0x58,0x00,0x00,0x00,0x00, + + 9, // 0x7F '' + 0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x7F,0x00,0x00,0x00,0x00,0x00, + + 0 + }; + + const int8u verdana12_bold[] = + { + 12, 3, 32, 128-32, + 0x00,0x00,0x0D,0x00,0x1A,0x00,0x27,0x00,0x34,0x00,0x41,0x00,0x5A,0x00,0x67,0x00,0x74,0x00, + 0x81,0x00,0x8E,0x00,0x9B,0x00,0xA8,0x00,0xB5,0x00,0xC2,0x00,0xCF,0x00,0xDC,0x00,0xE9,0x00, + 0xF6,0x00,0x03,0x01,0x10,0x01,0x1D,0x01,0x2A,0x01,0x37,0x01,0x44,0x01,0x51,0x01,0x5E,0x01, + 0x6B,0x01,0x78,0x01,0x85,0x01,0x92,0x01,0x9F,0x01,0xAC,0x01,0xC5,0x01,0xD2,0x01,0xDF,0x01, + 0xEC,0x01,0xF9,0x01,0x06,0x02,0x13,0x02,0x20,0x02,0x2D,0x02,0x3A,0x02,0x47,0x02,0x54,0x02, + 0x61,0x02,0x6E,0x02,0x7B,0x02,0x88,0x02,0x95,0x02,0xA2,0x02,0xAF,0x02,0xBC,0x02,0xC9,0x02, + 0xD6,0x02,0xE3,0x02,0xFC,0x02,0x09,0x03,0x16,0x03,0x23,0x03,0x30,0x03,0x3D,0x03,0x4A,0x03, + 0x57,0x03,0x64,0x03,0x71,0x03,0x7E,0x03,0x8B,0x03,0x98,0x03,0xA5,0x03,0xB2,0x03,0xBF,0x03, + 0xCC,0x03,0xD9,0x03,0xE6,0x03,0xF3,0x03,0x00,0x04,0x0D,0x04,0x26,0x04,0x33,0x04,0x40,0x04, + 0x4D,0x04,0x5A,0x04,0x67,0x04,0x74,0x04,0x81,0x04,0x8E,0x04,0x9B,0x04,0xB4,0x04,0xC1,0x04, + 0xCE,0x04,0xDB,0x04,0xE8,0x04,0xF5,0x04,0x02,0x05,0x0F,0x05, + + 3, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x21 '!' + 0x00,0x00,0x00,0x60,0x60,0x60,0x60,0x60,0x00,0x60,0x00,0x00, + + 5, // 0x22 '"' + 0x00,0x00,0xD8,0xD8,0xD8,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x23 '#' + 0x00,0x00,0x00,0x14,0x14,0x7E,0x28,0xFC,0x50,0x50,0x00,0x00, + + 6, // 0x24 '$' + 0x00,0x00,0x20,0x20,0x70,0xE8,0xE0,0x38,0xB8,0x70,0x20,0x20, + + 11, // 0x25 '%' + 0x00,0x00,0x00,0x00,0x00,0x00,0x62,0x00,0x94,0x00,0x94,0x00,0x69,0x80,0x0A,0x40,0x0A,0x40,0x11,0x80,0x00,0x00,0x00,0x00, + + 8, // 0x26 '&' + 0x00,0x00,0x00,0x70,0xD8,0xD8,0x76,0xDC,0xCC,0x76,0x00,0x00, + + 3, // 0x27 ''' + 0x00,0x00,0xC0,0xC0,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x28 '(' + 0x00,0x00,0x30,0x60,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x60,0x30, + + 5, // 0x29 ')' + 0x00,0x00,0xC0,0x60,0x30,0x30,0x30,0x30,0x30,0x30,0x60,0xC0, + + 6, // 0x2A '*' + 0x00,0x00,0x20,0xA8,0x70,0xA8,0x20,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x2B '+' + 0x00,0x00,0x00,0x00,0x10,0x10,0x7C,0x10,0x10,0x00,0x00,0x00, + + 3, // 0x2C ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0x80,0x00, + + 4, // 0x2D '-' + 0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0x00,0x00,0x00,0x00,0x00, + + 3, // 0x2E '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0x00,0x00, + + 6, // 0x2F '/' + 0x00,0x00,0x08,0x08,0x10,0x10,0x20,0x40,0x40,0x80,0x80,0x00, + + 6, // 0x30 '0' + 0x00,0x00,0x00,0x70,0xD8,0xD8,0xD8,0xD8,0xD8,0x70,0x00,0x00, + + 6, // 0x31 '1' + 0x00,0x00,0x00,0x30,0x70,0x30,0x30,0x30,0x30,0x78,0x00,0x00, + + 6, // 0x32 '2' + 0x00,0x00,0x00,0x70,0x98,0x18,0x30,0x60,0xC0,0xF8,0x00,0x00, + + 6, // 0x33 '3' + 0x00,0x00,0x00,0x70,0x98,0x18,0x70,0x18,0x98,0x70,0x00,0x00, + + 6, // 0x34 '4' + 0x00,0x00,0x00,0x18,0x38,0x58,0x98,0xFC,0x18,0x18,0x00,0x00, + + 6, // 0x35 '5' + 0x00,0x00,0x00,0xF8,0xC0,0xF0,0x18,0x18,0x98,0x70,0x00,0x00, + + 6, // 0x36 '6' + 0x00,0x00,0x00,0x70,0xC0,0xF0,0xD8,0xD8,0xD8,0x70,0x00,0x00, + + 6, // 0x37 '7' + 0x00,0x00,0x00,0xF8,0x18,0x30,0x30,0x60,0x60,0xC0,0x00,0x00, + + 6, // 0x38 '8' + 0x00,0x00,0x00,0x70,0xD8,0xD8,0x70,0xD8,0xD8,0x70,0x00,0x00, + + 6, // 0x39 '9' + 0x00,0x00,0x00,0x70,0xD8,0xD8,0xD8,0x78,0x18,0x70,0x00,0x00, + + 4, // 0x3A ':' + 0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x60,0x60,0x00,0x00, + + 4, // 0x3B ';' + 0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x60,0x60,0x40,0x00, + + 8, // 0x3C '<' + 0x00,0x00,0x00,0x00,0x04,0x18,0x60,0x60,0x18,0x04,0x00,0x00, + + 8, // 0x3D '=' + 0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x7C,0x00,0x00,0x00,0x00, + + 8, // 0x3E '>' + 0x00,0x00,0x00,0x00,0x40,0x30,0x0C,0x0C,0x30,0x40,0x00,0x00, + + 6, // 0x3F '?' + 0x00,0x00,0x00,0xF0,0x18,0x18,0x30,0x60,0x00,0x60,0x00,0x00, + + 9, // 0x40 '@' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x00,0x42,0x00,0x9D,0x00,0xA5,0x00,0xA5,0x00,0x9E,0x00,0x40,0x00,0x3C,0x00,0x00,0x00, + + 8, // 0x41 'A' + 0x00,0x00,0x00,0x38,0x38,0x6C,0x6C,0x7C,0xC6,0xC6,0x00,0x00, + + 7, // 0x42 'B' + 0x00,0x00,0x00,0xF8,0xCC,0xCC,0xF8,0xCC,0xCC,0xF8,0x00,0x00, + + 6, // 0x43 'C' + 0x00,0x00,0x00,0x70,0xC8,0xC0,0xC0,0xC0,0xC8,0x70,0x00,0x00, + + 7, // 0x44 'D' + 0x00,0x00,0x00,0xF8,0xCC,0xCC,0xCC,0xCC,0xCC,0xF8,0x00,0x00, + + 6, // 0x45 'E' + 0x00,0x00,0x00,0xF8,0xC0,0xC0,0xF8,0xC0,0xC0,0xF8,0x00,0x00, + + 6, // 0x46 'F' + 0x00,0x00,0x00,0xF8,0xC0,0xC0,0xF8,0xC0,0xC0,0xC0,0x00,0x00, + + 7, // 0x47 'G' + 0x00,0x00,0x00,0x78,0xC4,0xC0,0xC0,0xDC,0xCC,0x7C,0x00,0x00, + + 7, // 0x48 'H' + 0x00,0x00,0x00,0xCC,0xCC,0xCC,0xFC,0xCC,0xCC,0xCC,0x00,0x00, + + 5, // 0x49 'I' + 0x00,0x00,0x00,0xF0,0x60,0x60,0x60,0x60,0x60,0xF0,0x00,0x00, + + 5, // 0x4A 'J' + 0x00,0x00,0x00,0x70,0x30,0x30,0x30,0x30,0x30,0xE0,0x00,0x00, + + 7, // 0x4B 'K' + 0x00,0x00,0x00,0xCC,0xD8,0xF0,0xE0,0xF0,0xD8,0xCC,0x00,0x00, + + 6, // 0x4C 'L' + 0x00,0x00,0x00,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xF8,0x00,0x00, + + 8, // 0x4D 'M' + 0x00,0x00,0x00,0x82,0xC6,0xEE,0xB6,0xB6,0x86,0x86,0x00,0x00, + + 7, // 0x4E 'N' + 0x00,0x00,0x00,0x84,0xC4,0xE4,0xB4,0x9C,0x8C,0x84,0x00,0x00, + + 8, // 0x4F 'O' + 0x00,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x00,0x00, + + 7, // 0x50 'P' + 0x00,0x00,0x00,0xF8,0xCC,0xCC,0xCC,0xF8,0xC0,0xC0,0x00,0x00, + + 8, // 0x51 'Q' + 0x00,0x00,0x00,0x7C,0xC6,0xC6,0xC6,0xC6,0xC6,0x7C,0x18,0x0E, + + 7, // 0x52 'R' + 0x00,0x00,0x00,0xF8,0xCC,0xCC,0xF8,0xD8,0xCC,0xC6,0x00,0x00, + + 6, // 0x53 'S' + 0x00,0x00,0x00,0x70,0xC8,0xC0,0x70,0x18,0x98,0x70,0x00,0x00, + + 6, // 0x54 'T' + 0x00,0x00,0x00,0xFC,0x30,0x30,0x30,0x30,0x30,0x30,0x00,0x00, + + 7, // 0x55 'U' + 0x00,0x00,0x00,0xCC,0xCC,0xCC,0xCC,0xCC,0xCC,0x78,0x00,0x00, + + 7, // 0x56 'V' + 0x00,0x00,0x00,0xCC,0xCC,0x78,0x78,0x78,0x30,0x30,0x00,0x00, + + 11, // 0x57 'W' + 0x00,0x00,0x00,0x00,0x00,0x00,0xCC,0xC0,0xCC,0xC0,0x6D,0x80,0x6D,0x80,0x73,0x80,0x33,0x00,0x33,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x58 'X' + 0x00,0x00,0x00,0xCC,0xCC,0x78,0x30,0x78,0xCC,0xCC,0x00,0x00, + + 7, // 0x59 'Y' + 0x00,0x00,0x00,0xCC,0xCC,0x78,0x30,0x30,0x30,0x30,0x00,0x00, + + 6, // 0x5A 'Z' + 0x00,0x00,0x00,0xF8,0x18,0x30,0x60,0xC0,0xC0,0xF8,0x00,0x00, + + 5, // 0x5B '[' + 0x00,0x00,0x70,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x70, + + 6, // 0x5C '\' + 0x00,0x00,0x80,0x80,0x40,0x40,0x20,0x10,0x10,0x08,0x08,0x00, + + 5, // 0x5D ']' + 0x00,0x00,0x70,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x70, + + 8, // 0x5E '^' + 0x00,0x00,0x00,0x18,0x3C,0x66,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x5F '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFC, + + 6, // 0x60 '`' + 0x00,0x00,0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x61 'a' + 0x00,0x00,0x00,0x00,0x00,0x70,0x18,0x78,0xD8,0x78,0x00,0x00, + + 6, // 0x62 'b' + 0x00,0x00,0xC0,0xC0,0xC0,0xF0,0xD8,0xD8,0xD8,0xF0,0x00,0x00, + + 5, // 0x63 'c' + 0x00,0x00,0x00,0x00,0x00,0x70,0xC0,0xC0,0xC0,0x70,0x00,0x00, + + 6, // 0x64 'd' + 0x00,0x00,0x18,0x18,0x18,0x78,0xD8,0xD8,0xD8,0x78,0x00,0x00, + + 6, // 0x65 'e' + 0x00,0x00,0x00,0x00,0x00,0x70,0xD8,0xF8,0xC0,0x78,0x00,0x00, + + 5, // 0x66 'f' + 0x00,0x00,0x38,0x60,0x60,0xF8,0x60,0x60,0x60,0x60,0x00,0x00, + + 6, // 0x67 'g' + 0x00,0x00,0x00,0x00,0x00,0x78,0xD8,0xD8,0xD8,0x78,0x18,0x70, + + 6, // 0x68 'h' + 0x00,0x00,0xC0,0xC0,0xC0,0xF0,0xD8,0xD8,0xD8,0xD8,0x00,0x00, + + 3, // 0x69 'i' + 0x00,0x00,0x00,0xC0,0x00,0xC0,0xC0,0xC0,0xC0,0xC0,0x00,0x00, + + 4, // 0x6A 'j' + 0x00,0x00,0x00,0x60,0x00,0xE0,0x60,0x60,0x60,0x60,0x60,0xC0, + + 6, // 0x6B 'k' + 0x00,0x00,0xC0,0xC0,0xC0,0xD8,0xD8,0xF0,0xD8,0xD8,0x00,0x00, + + 3, // 0x6C 'l' + 0x00,0x00,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x00,0x00, + + 9, // 0x6D 'm' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xF6,0x00,0xDB,0x00,0xDB,0x00,0xDB,0x00,0xDB,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x6E 'n' + 0x00,0x00,0x00,0x00,0x00,0xF0,0xD8,0xD8,0xD8,0xD8,0x00,0x00, + + 6, // 0x6F 'o' + 0x00,0x00,0x00,0x00,0x00,0x70,0xD8,0xD8,0xD8,0x70,0x00,0x00, + + 6, // 0x70 'p' + 0x00,0x00,0x00,0x00,0x00,0xF0,0xD8,0xD8,0xD8,0xF0,0xC0,0xC0, + + 6, // 0x71 'q' + 0x00,0x00,0x00,0x00,0x00,0x78,0xD8,0xD8,0xD8,0x78,0x18,0x18, + + 4, // 0x72 'r' + 0x00,0x00,0x00,0x00,0x00,0xD0,0xE0,0xC0,0xC0,0xC0,0x00,0x00, + + 5, // 0x73 's' + 0x00,0x00,0x00,0x00,0x00,0x70,0xC0,0xF0,0x30,0xE0,0x00,0x00, + + 5, // 0x74 't' + 0x00,0x00,0x00,0x60,0x60,0xF8,0x60,0x60,0x60,0x38,0x00,0x00, + + 6, // 0x75 'u' + 0x00,0x00,0x00,0x00,0x00,0xD8,0xD8,0xD8,0xD8,0x78,0x00,0x00, + + 6, // 0x76 'v' + 0x00,0x00,0x00,0x00,0x00,0xD8,0xD8,0xD8,0x70,0x70,0x00,0x00, + + 9, // 0x77 'w' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xDB,0x00,0xDB,0x00,0xDB,0x00,0x66,0x00,0x66,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x78 'x' + 0x00,0x00,0x00,0x00,0x00,0xD8,0xD8,0x70,0xD8,0xD8,0x00,0x00, + + 6, // 0x79 'y' + 0x00,0x00,0x00,0x00,0x00,0xD8,0xD8,0xD8,0x70,0x70,0x30,0x60, + + 5, // 0x7A 'z' + 0x00,0x00,0x00,0x00,0x00,0xF0,0x30,0x60,0xC0,0xF0,0x00,0x00, + + 6, // 0x7B '{' + 0x00,0x00,0x18,0x30,0x30,0x30,0xE0,0x30,0x30,0x30,0x30,0x18, + + 5, // 0x7C '|' + 0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + + 6, // 0x7D '}' + 0x00,0x00,0xC0,0x60,0x60,0x60,0x38,0x60,0x60,0x60,0x60,0xC0, + + 8, // 0x7E '~' + 0x00,0x00,0x00,0x00,0x00,0x00,0x62,0x92,0x8C,0x00,0x00,0x00, + + 9, // 0x7F '' + 0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x7F,0x00,0x00,0x00,0x00,0x00, + + 0 + }; + + const int8u verdana13[] = + { + 13, 3, 32, 128-32, + 0x00,0x00,0x0E,0x00,0x1C,0x00,0x2A,0x00,0x45,0x00,0x53,0x00,0x6E,0x00,0x7C,0x00,0x8A,0x00, + 0x98,0x00,0xA6,0x00,0xB4,0x00,0xCF,0x00,0xDD,0x00,0xEB,0x00,0xF9,0x00,0x07,0x01,0x15,0x01, + 0x23,0x01,0x31,0x01,0x3F,0x01,0x4D,0x01,0x5B,0x01,0x69,0x01,0x77,0x01,0x85,0x01,0x93,0x01, + 0xA1,0x01,0xAF,0x01,0xCA,0x01,0xE5,0x01,0x00,0x02,0x0E,0x02,0x29,0x02,0x37,0x02,0x45,0x02, + 0x60,0x02,0x7B,0x02,0x89,0x02,0x97,0x02,0xB2,0x02,0xC0,0x02,0xCE,0x02,0xDC,0x02,0xEA,0x02, + 0xF8,0x02,0x13,0x03,0x21,0x03,0x3C,0x03,0x4A,0x03,0x65,0x03,0x73,0x03,0x81,0x03,0x8F,0x03, + 0x9D,0x03,0xAB,0x03,0xC6,0x03,0xD4,0x03,0xE2,0x03,0xF0,0x03,0xFE,0x03,0x0C,0x04,0x1A,0x04, + 0x35,0x04,0x43,0x04,0x51,0x04,0x5F,0x04,0x6D,0x04,0x7B,0x04,0x89,0x04,0x97,0x04,0xA5,0x04, + 0xB3,0x04,0xC1,0x04,0xCF,0x04,0xDD,0x04,0xEB,0x04,0xF9,0x04,0x14,0x05,0x22,0x05,0x30,0x05, + 0x3E,0x05,0x4C,0x05,0x5A,0x05,0x68,0x05,0x76,0x05,0x84,0x05,0x92,0x05,0xAD,0x05,0xBB,0x05, + 0xC9,0x05,0xD7,0x05,0xE5,0x05,0xF3,0x05,0x01,0x06,0x1C,0x06, + + 4, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x21 '!' + 0x00,0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00,0x00, + + 5, // 0x22 '"' + 0x00,0x00,0x50,0x50,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x23 '#' + 0x00,0x00,0x00,0x00,0x00,0x00,0x0A,0x00,0x0A,0x00,0x3F,0x00,0x14,0x00,0x14,0x00,0x7E,0x00,0x28,0x00,0x28,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x24 '$' + 0x00,0x00,0x10,0x10,0x3C,0x50,0x50,0x38,0x14,0x14,0x78,0x10,0x10, + + 12, // 0x25 '%' + 0x00,0x00,0x00,0x00,0x00,0x00,0x31,0x00,0x49,0x00,0x4A,0x00,0x32,0x00,0x04,0xC0,0x05,0x20,0x09,0x20,0x08,0xC0,0x00,0x00,0x00,0x00, + + 8, // 0x26 '&' + 0x00,0x00,0x00,0x30,0x48,0x48,0x32,0x4A,0x44,0x46,0x39,0x00,0x00, + + 3, // 0x27 ''' + 0x00,0x00,0x40,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x28 '(' + 0x00,0x00,0x10,0x20,0x20,0x40,0x40,0x40,0x40,0x40,0x20,0x20,0x10, + + 5, // 0x29 ')' + 0x00,0x00,0x40,0x20,0x20,0x10,0x10,0x10,0x10,0x10,0x20,0x20,0x40, + + 7, // 0x2A '*' + 0x00,0x00,0x10,0x54,0x38,0x54,0x10,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x2B '+' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x7F,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x2C ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x20,0x40, + + 5, // 0x2D '-' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x2E '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x00,0x00, + + 5, // 0x2F '/' + 0x00,0x00,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x80,0x80,0x00, + + 7, // 0x30 '0' + 0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x44,0x44,0x38,0x00,0x00, + + 7, // 0x31 '1' + 0x00,0x00,0x00,0x10,0x70,0x10,0x10,0x10,0x10,0x10,0x7C,0x00,0x00, + + 7, // 0x32 '2' + 0x00,0x00,0x00,0x38,0x44,0x04,0x08,0x10,0x20,0x40,0x7C,0x00,0x00, + + 7, // 0x33 '3' + 0x00,0x00,0x00,0x38,0x44,0x04,0x18,0x04,0x04,0x44,0x38,0x00,0x00, + + 7, // 0x34 '4' + 0x00,0x00,0x00,0x08,0x18,0x28,0x48,0x88,0xFC,0x08,0x08,0x00,0x00, + + 7, // 0x35 '5' + 0x00,0x00,0x00,0x7C,0x40,0x40,0x78,0x04,0x04,0x44,0x38,0x00,0x00, + + 7, // 0x36 '6' + 0x00,0x00,0x00,0x18,0x20,0x40,0x78,0x44,0x44,0x44,0x38,0x00,0x00, + + 7, // 0x37 '7' + 0x00,0x00,0x00,0x7C,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x00,0x00, + + 7, // 0x38 '8' + 0x00,0x00,0x00,0x38,0x44,0x44,0x38,0x44,0x44,0x44,0x38,0x00,0x00, + + 7, // 0x39 '9' + 0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x3C,0x04,0x08,0x30,0x00,0x00, + + 5, // 0x3A ':' + 0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x00,0x00,0x20,0x20,0x00,0x00, + + 5, // 0x3B ';' + 0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x00,0x00,0x20,0x20,0x20,0x40, + + 9, // 0x3C '<' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x18,0x00,0x60,0x00,0x18,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x3D '=' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x3E '>' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x0C,0x00,0x03,0x00,0x0C,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x3F '?' + 0x00,0x00,0x00,0x70,0x08,0x08,0x10,0x20,0x20,0x00,0x20,0x00,0x00, + + 10, // 0x40 '@' + 0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x20,0x80,0x4E,0x80,0x52,0x80,0x52,0x80,0x52,0x80,0x4D,0x00,0x20,0x00,0x1E,0x00,0x00,0x00, + + 8, // 0x41 'A' + 0x00,0x00,0x00,0x18,0x18,0x24,0x24,0x24,0x7E,0x42,0x42,0x00,0x00, + + 8, // 0x42 'B' + 0x00,0x00,0x00,0x78,0x44,0x44,0x7C,0x42,0x42,0x42,0x7C,0x00,0x00, + + 9, // 0x43 'C' + 0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x21,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x21,0x00,0x1E,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x44 'D' + 0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x42,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x42,0x00,0x7C,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x45 'E' + 0x00,0x00,0x00,0x7C,0x40,0x40,0x7C,0x40,0x40,0x40,0x7C,0x00,0x00, + + 6, // 0x46 'F' + 0x00,0x00,0x00,0x7C,0x40,0x40,0x78,0x40,0x40,0x40,0x40,0x00,0x00, + + 9, // 0x47 'G' + 0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x21,0x00,0x40,0x00,0x40,0x00,0x47,0x00,0x41,0x00,0x21,0x00,0x1E,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x48 'H' + 0x00,0x00,0x00,0x42,0x42,0x42,0x7E,0x42,0x42,0x42,0x42,0x00,0x00, + + 5, // 0x49 'I' + 0x00,0x00,0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, + + 5, // 0x4A 'J' + 0x00,0x00,0x00,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0xE0,0x00,0x00, + + 8, // 0x4B 'K' + 0x00,0x00,0x00,0x42,0x44,0x48,0x50,0x70,0x48,0x44,0x42,0x00,0x00, + + 6, // 0x4C 'L' + 0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7C,0x00,0x00, + + 9, // 0x4D 'M' + 0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x00,0x63,0x00,0x55,0x00,0x55,0x00,0x49,0x00,0x49,0x00,0x41,0x00,0x41,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x4E 'N' + 0x00,0x00,0x00,0x62,0x62,0x52,0x52,0x4A,0x4A,0x46,0x46,0x00,0x00, + + 9, // 0x4F 'O' + 0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x22,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x22,0x00,0x1C,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x50 'P' + 0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x78,0x40,0x40,0x40,0x00,0x00, + + 9, // 0x51 'Q' + 0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x22,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x22,0x00,0x1C,0x00,0x04,0x00,0x03,0x00, + + 8, // 0x52 'R' + 0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x78,0x48,0x44,0x42,0x00,0x00, + + 8, // 0x53 'S' + 0x00,0x00,0x00,0x3C,0x42,0x40,0x30,0x0C,0x02,0x42,0x3C,0x00,0x00, + + 7, // 0x54 'T' + 0x00,0x00,0x00,0xFE,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00, + + 8, // 0x55 'U' + 0x00,0x00,0x00,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x3C,0x00,0x00, + + 8, // 0x56 'V' + 0x00,0x00,0x00,0x42,0x42,0x42,0x24,0x24,0x24,0x18,0x18,0x00,0x00, + + 11, // 0x57 'W' + 0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x40,0x44,0x40,0x2A,0x80,0x2A,0x80,0x2A,0x80,0x2A,0x80,0x11,0x00,0x11,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x58 'X' + 0x00,0x00,0x00,0x42,0x42,0x24,0x18,0x18,0x24,0x42,0x42,0x00,0x00, + + 7, // 0x59 'Y' + 0x00,0x00,0x00,0x82,0x44,0x28,0x10,0x10,0x10,0x10,0x10,0x00,0x00, + + 8, // 0x5A 'Z' + 0x00,0x00,0x00,0x7E,0x02,0x04,0x08,0x10,0x20,0x40,0x7E,0x00,0x00, + + 5, // 0x5B '[' + 0x00,0x00,0x70,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x70, + + 5, // 0x5C '\' + 0x00,0x00,0x80,0x80,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x00, + + 5, // 0x5D ']' + 0x00,0x00,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x70, + + 9, // 0x5E '^' + 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x14,0x00,0x22,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x5F '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFE, + + 7, // 0x60 '`' + 0x00,0x00,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x61 'a' + 0x00,0x00,0x00,0x00,0x00,0x38,0x04,0x3C,0x44,0x44,0x3C,0x00,0x00, + + 7, // 0x62 'b' + 0x00,0x00,0x40,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x78,0x00,0x00, + + 6, // 0x63 'c' + 0x00,0x00,0x00,0x00,0x00,0x38,0x44,0x40,0x40,0x44,0x38,0x00,0x00, + + 7, // 0x64 'd' + 0x00,0x00,0x04,0x04,0x04,0x3C,0x44,0x44,0x44,0x44,0x3C,0x00,0x00, + + 7, // 0x65 'e' + 0x00,0x00,0x00,0x00,0x00,0x38,0x44,0x7C,0x40,0x44,0x38,0x00,0x00, + + 4, // 0x66 'f' + 0x00,0x00,0x30,0x40,0x40,0xF0,0x40,0x40,0x40,0x40,0x40,0x00,0x00, + + 7, // 0x67 'g' + 0x00,0x00,0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x44,0x3C,0x04,0x38, + + 7, // 0x68 'h' + 0x00,0x00,0x40,0x40,0x40,0x78,0x44,0x44,0x44,0x44,0x44,0x00,0x00, + + 3, // 0x69 'i' + 0x00,0x00,0x40,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00, + + 4, // 0x6A 'j' + 0x00,0x00,0x20,0x00,0x00,0x60,0x20,0x20,0x20,0x20,0x20,0x20,0xC0, + + 7, // 0x6B 'k' + 0x00,0x00,0x40,0x40,0x40,0x44,0x48,0x50,0x70,0x48,0x44,0x00,0x00, + + 3, // 0x6C 'l' + 0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00, + + 11, // 0x6D 'm' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7B,0x80,0x44,0x40,0x44,0x40,0x44,0x40,0x44,0x40,0x44,0x40,0x00,0x00,0x00,0x00, + + 7, // 0x6E 'n' + 0x00,0x00,0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x44,0x44,0x00,0x00, + + 7, // 0x6F 'o' + 0x00,0x00,0x00,0x00,0x00,0x38,0x44,0x44,0x44,0x44,0x38,0x00,0x00, + + 7, // 0x70 'p' + 0x00,0x00,0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x44,0x78,0x40,0x40, + + 7, // 0x71 'q' + 0x00,0x00,0x00,0x00,0x00,0x3C,0x44,0x44,0x44,0x44,0x3C,0x04,0x04, + + 5, // 0x72 'r' + 0x00,0x00,0x00,0x00,0x00,0x58,0x60,0x40,0x40,0x40,0x40,0x00,0x00, + + 6, // 0x73 's' + 0x00,0x00,0x00,0x00,0x00,0x38,0x40,0x60,0x18,0x08,0x70,0x00,0x00, + + 4, // 0x74 't' + 0x00,0x00,0x00,0x40,0x40,0xF0,0x40,0x40,0x40,0x40,0x30,0x00,0x00, + + 7, // 0x75 'u' + 0x00,0x00,0x00,0x00,0x00,0x44,0x44,0x44,0x44,0x44,0x3C,0x00,0x00, + + 7, // 0x76 'v' + 0x00,0x00,0x00,0x00,0x00,0x44,0x44,0x28,0x28,0x10,0x10,0x00,0x00, + + 9, // 0x77 'w' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x49,0x00,0x49,0x00,0x55,0x00,0x55,0x00,0x22,0x00,0x22,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x78 'x' + 0x00,0x00,0x00,0x00,0x00,0x44,0x28,0x10,0x10,0x28,0x44,0x00,0x00, + + 7, // 0x79 'y' + 0x00,0x00,0x00,0x00,0x00,0x44,0x28,0x28,0x28,0x10,0x10,0x10,0x20, + + 6, // 0x7A 'z' + 0x00,0x00,0x00,0x00,0x00,0x78,0x08,0x10,0x20,0x40,0x78,0x00,0x00, + + 7, // 0x7B '{' + 0x00,0x00,0x0C,0x10,0x10,0x10,0x10,0x60,0x10,0x10,0x10,0x10,0x0C, + + 5, // 0x7C '|' + 0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + + 7, // 0x7D '}' + 0x00,0x00,0x60,0x10,0x10,0x10,0x10,0x0C,0x10,0x10,0x10,0x10,0x60, + + 9, // 0x7E '~' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x31,0x00,0x49,0x00,0x46,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x7F '' + 0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x7F,0x80,0x00,0x00,0x00,0x00, + + 0 + }; + + const int8u verdana13_bold[] = + { + 13, 3, 32, 128-32, + 0x00,0x00,0x0E,0x00,0x1C,0x00,0x2A,0x00,0x45,0x00,0x53,0x00,0x6E,0x00,0x89,0x00,0x97,0x00, + 0xA5,0x00,0xB3,0x00,0xC1,0x00,0xDC,0x00,0xEA,0x00,0xF8,0x00,0x06,0x01,0x14,0x01,0x22,0x01, + 0x30,0x01,0x3E,0x01,0x4C,0x01,0x5A,0x01,0x68,0x01,0x76,0x01,0x84,0x01,0x92,0x01,0xA0,0x01, + 0xAE,0x01,0xBC,0x01,0xD7,0x01,0xF2,0x01,0x0D,0x02,0x1B,0x02,0x36,0x02,0x51,0x02,0x5F,0x02, + 0x6D,0x02,0x88,0x02,0x96,0x02,0xA4,0x02,0xBF,0x02,0xDA,0x02,0xE8,0x02,0xF6,0x02,0x04,0x03, + 0x12,0x03,0x2D,0x03,0x48,0x03,0x63,0x03,0x71,0x03,0x8C,0x03,0x9A,0x03,0xA8,0x03,0xB6,0x03, + 0xD1,0x03,0xDF,0x03,0xFA,0x03,0x08,0x04,0x16,0x04,0x24,0x04,0x32,0x04,0x40,0x04,0x4E,0x04, + 0x69,0x04,0x77,0x04,0x85,0x04,0x93,0x04,0xA1,0x04,0xAF,0x04,0xBD,0x04,0xCB,0x04,0xD9,0x04, + 0xE7,0x04,0xF5,0x04,0x03,0x05,0x11,0x05,0x1F,0x05,0x2D,0x05,0x48,0x05,0x56,0x05,0x64,0x05, + 0x72,0x05,0x80,0x05,0x8E,0x05,0x9C,0x05,0xAA,0x05,0xB8,0x05,0xC6,0x05,0xE1,0x05,0xEF,0x05, + 0xFD,0x05,0x0B,0x06,0x19,0x06,0x27,0x06,0x35,0x06,0x50,0x06, + + 4, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x21 '!' + 0x00,0x00,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x60,0x00,0x00, + + 7, // 0x22 '"' + 0x00,0x00,0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x23 '#' + 0x00,0x00,0x00,0x00,0x00,0x00,0x0A,0x00,0x0A,0x00,0x3F,0x00,0x14,0x00,0x14,0x00,0x7E,0x00,0x28,0x00,0x28,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x24 '$' + 0x00,0x00,0x08,0x08,0x3C,0x6A,0x68,0x3C,0x16,0x56,0x3C,0x10,0x10, + + 14, // 0x25 '%' + 0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x80,0x6C,0x80,0x6D,0x00,0x6D,0x70,0x3A,0xD8,0x02,0xD8,0x04,0xD8,0x04,0x70,0x00,0x00,0x00,0x00, + + 10, // 0x26 '&' + 0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x6C,0x00,0x6C,0x00,0x39,0x80,0x6D,0x00,0x66,0x00,0x63,0x00,0x3D,0x80,0x00,0x00,0x00,0x00, + + 4, // 0x27 ''' + 0x00,0x00,0x60,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x28 '(' + 0x00,0x00,0x18,0x30,0x30,0x60,0x60,0x60,0x60,0x60,0x30,0x30,0x18, + + 6, // 0x29 ')' + 0x00,0x00,0x60,0x30,0x30,0x18,0x18,0x18,0x18,0x18,0x30,0x30,0x60, + + 8, // 0x2A '*' + 0x00,0x00,0x10,0x54,0x38,0x54,0x10,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x2B '+' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x7F,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x2C ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x60,0x40, + + 6, // 0x2D '-' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x2E '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00, + + 8, // 0x2F '/' + 0x00,0x00,0x06,0x06,0x0C,0x0C,0x18,0x18,0x18,0x30,0x30,0x60,0x60, + + 8, // 0x30 '0' + 0x00,0x00,0x00,0x3C,0x66,0x66,0x66,0x66,0x66,0x66,0x3C,0x00,0x00, + + 8, // 0x31 '1' + 0x00,0x00,0x00,0x18,0x38,0x18,0x18,0x18,0x18,0x18,0x3C,0x00,0x00, + + 8, // 0x32 '2' + 0x00,0x00,0x00,0x3C,0x66,0x06,0x0C,0x18,0x30,0x60,0x7E,0x00,0x00, + + 8, // 0x33 '3' + 0x00,0x00,0x00,0x3C,0x66,0x06,0x1C,0x06,0x06,0x66,0x3C,0x00,0x00, + + 8, // 0x34 '4' + 0x00,0x00,0x00,0x04,0x0C,0x1C,0x2C,0x4C,0x7E,0x0C,0x0C,0x00,0x00, + + 8, // 0x35 '5' + 0x00,0x00,0x00,0x3E,0x30,0x30,0x3C,0x06,0x06,0x66,0x3C,0x00,0x00, + + 8, // 0x36 '6' + 0x00,0x00,0x00,0x1C,0x30,0x60,0x7C,0x66,0x66,0x66,0x3C,0x00,0x00, + + 8, // 0x37 '7' + 0x00,0x00,0x00,0x7E,0x06,0x0C,0x0C,0x18,0x18,0x30,0x30,0x00,0x00, + + 8, // 0x38 '8' + 0x00,0x00,0x00,0x3C,0x66,0x66,0x3C,0x66,0x66,0x66,0x3C,0x00,0x00, + + 8, // 0x39 '9' + 0x00,0x00,0x00,0x3C,0x66,0x66,0x66,0x3E,0x06,0x0C,0x38,0x00,0x00, + + 4, // 0x3A ':' + 0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x60,0x60,0x00,0x00, + + 4, // 0x3B ';' + 0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x60,0x60,0x60,0x40, + + 9, // 0x3C '<' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x0C,0x00,0x30,0x00,0x40,0x00,0x30,0x00,0x0C,0x00,0x03,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x3D '=' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x3E '>' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x18,0x00,0x06,0x00,0x01,0x00,0x06,0x00,0x18,0x00,0x60,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x3F '?' + 0x00,0x00,0x00,0x38,0x4C,0x0C,0x18,0x30,0x30,0x00,0x30,0x00,0x00, + + 11, // 0x40 '@' + 0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x80,0x20,0x40,0x4F,0x40,0x5B,0x40,0x5B,0x40,0x5B,0x40,0x4F,0x80,0x20,0x00,0x1F,0x00,0x00,0x00, + + 9, // 0x41 'A' + 0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x1C,0x00,0x36,0x00,0x36,0x00,0x36,0x00,0x7F,0x00,0x63,0x00,0x63,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x42 'B' + 0x00,0x00,0x00,0x7C,0x66,0x66,0x7C,0x66,0x66,0x66,0x7C,0x00,0x00, + + 8, // 0x43 'C' + 0x00,0x00,0x00,0x3C,0x62,0x60,0x60,0x60,0x60,0x62,0x3C,0x00,0x00, + + 9, // 0x44 'D' + 0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x66,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x66,0x00,0x7C,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x45 'E' + 0x00,0x00,0x00,0x7E,0x60,0x60,0x7E,0x60,0x60,0x60,0x7E,0x00,0x00, + + 8, // 0x46 'F' + 0x00,0x00,0x00,0x7E,0x60,0x60,0x7E,0x60,0x60,0x60,0x60,0x00,0x00, + + 9, // 0x47 'G' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x61,0x00,0x60,0x00,0x60,0x00,0x67,0x00,0x63,0x00,0x63,0x00,0x3F,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x48 'H' + 0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x7F,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x49 'I' + 0x00,0x00,0x00,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x78,0x00,0x00, + + 6, // 0x4A 'J' + 0x00,0x00,0x00,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0xF0,0x00,0x00, + + 8, // 0x4B 'K' + 0x00,0x00,0x00,0x66,0x6C,0x78,0x70,0x70,0x78,0x6C,0x66,0x00,0x00, + + 7, // 0x4C 'L' + 0x00,0x00,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x7E,0x00,0x00, + + 10, // 0x4D 'M' + 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x80,0x71,0x80,0x7B,0x80,0x5D,0x80,0x49,0x80,0x41,0x80,0x41,0x80,0x41,0x80,0x00,0x00,0x00,0x00, + + 9, // 0x4E 'N' + 0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x61,0x00,0x71,0x00,0x59,0x00,0x4D,0x00,0x47,0x00,0x43,0x00,0x41,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x4F 'O' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x50 'P' + 0x00,0x00,0x00,0x7C,0x66,0x66,0x66,0x7C,0x60,0x60,0x60,0x00,0x00, + + 9, // 0x51 'Q' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x3E,0x00,0x0C,0x00,0x07,0x00, + + 8, // 0x52 'R' + 0x00,0x00,0x00,0x7C,0x66,0x66,0x66,0x7C,0x6C,0x66,0x63,0x00,0x00, + + 8, // 0x53 'S' + 0x00,0x00,0x00,0x3C,0x62,0x60,0x7C,0x3E,0x06,0x46,0x3C,0x00,0x00, + + 8, // 0x54 'T' + 0x00,0x00,0x00,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00, + + 9, // 0x55 'U' + 0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x56 'V' + 0x00,0x00,0x00,0x66,0x66,0x66,0x3C,0x3C,0x3C,0x18,0x18,0x00,0x00, + + 12, // 0x57 'W' + 0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x60,0x66,0x60,0x66,0x60,0x36,0xC0,0x3F,0xC0,0x39,0xC0,0x19,0x80,0x19,0x80,0x00,0x00,0x00,0x00, + + 8, // 0x58 'X' + 0x00,0x00,0x00,0x66,0x66,0x3C,0x18,0x18,0x3C,0x66,0x66,0x00,0x00, + + 8, // 0x59 'Y' + 0x00,0x00,0x00,0x66,0x66,0x3C,0x3C,0x18,0x18,0x18,0x18,0x00,0x00, + + 8, // 0x5A 'Z' + 0x00,0x00,0x00,0x7E,0x06,0x0E,0x1C,0x38,0x70,0x60,0x7E,0x00,0x00, + + 6, // 0x5B '[' + 0x00,0x00,0x78,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x78, + + 8, // 0x5C '\' + 0x00,0x00,0x60,0x60,0x30,0x30,0x18,0x18,0x18,0x0C,0x0C,0x06,0x06, + + 6, // 0x5D ']' + 0x00,0x00,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x78, + + 10, // 0x5E '^' + 0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x5F '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF, + + 8, // 0x60 '`' + 0x00,0x00,0x30,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x61 'a' + 0x00,0x00,0x00,0x00,0x00,0x3C,0x06,0x3E,0x66,0x66,0x3E,0x00,0x00, + + 8, // 0x62 'b' + 0x00,0x00,0x60,0x60,0x60,0x7C,0x66,0x66,0x66,0x66,0x7C,0x00,0x00, + + 7, // 0x63 'c' + 0x00,0x00,0x00,0x00,0x00,0x3C,0x60,0x60,0x60,0x60,0x3C,0x00,0x00, + + 8, // 0x64 'd' + 0x00,0x00,0x06,0x06,0x06,0x3E,0x66,0x66,0x66,0x66,0x3E,0x00,0x00, + + 8, // 0x65 'e' + 0x00,0x00,0x00,0x00,0x00,0x3C,0x66,0x7E,0x60,0x62,0x3C,0x00,0x00, + + 5, // 0x66 'f' + 0x00,0x00,0x38,0x60,0x60,0xF8,0x60,0x60,0x60,0x60,0x60,0x00,0x00, + + 8, // 0x67 'g' + 0x00,0x00,0x00,0x00,0x00,0x3E,0x66,0x66,0x66,0x66,0x3E,0x06,0x3C, + + 8, // 0x68 'h' + 0x00,0x00,0x60,0x60,0x60,0x7C,0x66,0x66,0x66,0x66,0x66,0x00,0x00, + + 4, // 0x69 'i' + 0x00,0x00,0x00,0x60,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00, + + 5, // 0x6A 'j' + 0x00,0x00,0x00,0x30,0x00,0x70,0x30,0x30,0x30,0x30,0x30,0x30,0xE0, + + 8, // 0x6B 'k' + 0x00,0x00,0x60,0x60,0x60,0x66,0x6C,0x78,0x78,0x6C,0x66,0x00,0x00, + + 4, // 0x6C 'l' + 0x00,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00, + + 12, // 0x6D 'm' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7D,0xC0,0x66,0x60,0x66,0x60,0x66,0x60,0x66,0x60,0x66,0x60,0x00,0x00,0x00,0x00, + + 8, // 0x6E 'n' + 0x00,0x00,0x00,0x00,0x00,0x7C,0x66,0x66,0x66,0x66,0x66,0x00,0x00, + + 8, // 0x6F 'o' + 0x00,0x00,0x00,0x00,0x00,0x3C,0x66,0x66,0x66,0x66,0x3C,0x00,0x00, + + 8, // 0x70 'p' + 0x00,0x00,0x00,0x00,0x00,0x7C,0x66,0x66,0x66,0x66,0x7C,0x60,0x60, + + 8, // 0x71 'q' + 0x00,0x00,0x00,0x00,0x00,0x3E,0x66,0x66,0x66,0x66,0x3E,0x06,0x06, + + 6, // 0x72 'r' + 0x00,0x00,0x00,0x00,0x00,0x6C,0x7C,0x60,0x60,0x60,0x60,0x00,0x00, + + 7, // 0x73 's' + 0x00,0x00,0x00,0x00,0x00,0x3C,0x60,0x78,0x3C,0x0C,0x78,0x00,0x00, + + 5, // 0x74 't' + 0x00,0x00,0x00,0x60,0x60,0xF8,0x60,0x60,0x60,0x60,0x38,0x00,0x00, + + 8, // 0x75 'u' + 0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x3E,0x00,0x00, + + 8, // 0x76 'v' + 0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x3C,0x3C,0x18,0x00,0x00, + + 10, // 0x77 'w' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6D,0x80,0x6D,0x80,0x6D,0x80,0x6D,0x80,0x33,0x00,0x33,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x78 'x' + 0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x3C,0x3C,0x66,0x66,0x00,0x00, + + 8, // 0x79 'y' + 0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x3C,0x3C,0x18,0x18,0x30,0x30, + + 7, // 0x7A 'z' + 0x00,0x00,0x00,0x00,0x00,0x7C,0x0C,0x18,0x30,0x60,0x7C,0x00,0x00, + + 8, // 0x7B '{' + 0x00,0x00,0x0E,0x18,0x18,0x18,0x18,0x70,0x18,0x18,0x18,0x18,0x0E, + + 6, // 0x7C '|' + 0x00,0x00,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30, + + 8, // 0x7D '}' + 0x00,0x00,0x70,0x18,0x18,0x18,0x18,0x0E,0x18,0x18,0x18,0x18,0x70, + + 9, // 0x7E '~' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x31,0x00,0x49,0x00,0x49,0x00,0x46,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x7F '' + 0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x7F,0x80,0x00,0x00,0x00,0x00, + + 0 + }; + + const int8u verdana14[] = + { + 14, 3, 32, 128-32, + 0x00,0x00,0x0F,0x00,0x1E,0x00,0x2D,0x00,0x4A,0x00,0x59,0x00,0x76,0x00,0x93,0x00,0xA2,0x00, + 0xB1,0x00,0xC0,0x00,0xCF,0x00,0xEC,0x00,0xFB,0x00,0x0A,0x01,0x19,0x01,0x28,0x01,0x37,0x01, + 0x46,0x01,0x55,0x01,0x64,0x01,0x73,0x01,0x82,0x01,0x91,0x01,0xA0,0x01,0xAF,0x01,0xBE,0x01, + 0xCD,0x01,0xDC,0x01,0xF9,0x01,0x16,0x02,0x33,0x02,0x42,0x02,0x5F,0x02,0x6E,0x02,0x7D,0x02, + 0x9A,0x02,0xB7,0x02,0xC6,0x02,0xD5,0x02,0xF2,0x02,0x0F,0x03,0x1E,0x03,0x2D,0x03,0x3C,0x03, + 0x4B,0x03,0x68,0x03,0x85,0x03,0xA2,0x03,0xB1,0x03,0xCE,0x03,0xDD,0x03,0xEC,0x03,0xFB,0x03, + 0x18,0x04,0x27,0x04,0x44,0x04,0x53,0x04,0x62,0x04,0x71,0x04,0x80,0x04,0x8F,0x04,0x9E,0x04, + 0xBB,0x04,0xCA,0x04,0xD9,0x04,0xE8,0x04,0xF7,0x04,0x06,0x05,0x15,0x05,0x24,0x05,0x33,0x05, + 0x42,0x05,0x51,0x05,0x60,0x05,0x6F,0x05,0x7E,0x05,0x8D,0x05,0xAA,0x05,0xB9,0x05,0xC8,0x05, + 0xD7,0x05,0xE6,0x05,0xF5,0x05,0x04,0x06,0x13,0x06,0x22,0x06,0x31,0x06,0x4E,0x06,0x5D,0x06, + 0x6C,0x06,0x7B,0x06,0x8A,0x06,0x99,0x06,0xA8,0x06,0xC5,0x06, + + 4, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x21 '!' + 0x00,0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x00,0x00, + + 6, // 0x22 '"' + 0x00,0x00,0x48,0x48,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x23 '#' + 0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x00,0x09,0x00,0x12,0x00,0x3F,0x80,0x12,0x00,0x12,0x00,0x7F,0x00,0x24,0x00,0x24,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x24 '$' + 0x00,0x00,0x10,0x10,0x3E,0x50,0x50,0x30,0x1C,0x12,0x12,0x7C,0x10,0x10, + + 13, // 0x25 '%' + 0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x80,0x49,0x00,0x49,0x00,0x4A,0x00,0x32,0x60,0x02,0x90,0x04,0x90,0x04,0x90,0x08,0x60,0x00,0x00,0x00,0x00, + + 10, // 0x26 '&' + 0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x44,0x00,0x44,0x00,0x44,0x00,0x39,0x00,0x45,0x00,0x42,0x00,0x43,0x00,0x3C,0x80,0x00,0x00,0x00,0x00, + + 3, // 0x27 ''' + 0x00,0x00,0x40,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x28 '(' + 0x00,0x00,0x10,0x20,0x20,0x40,0x40,0x40,0x40,0x40,0x40,0x20,0x20,0x10, + + 5, // 0x29 ')' + 0x00,0x00,0x40,0x20,0x20,0x10,0x10,0x10,0x10,0x10,0x10,0x20,0x20,0x40, + + 8, // 0x2A '*' + 0x00,0x00,0x10,0x54,0x38,0x54,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x2B '+' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x7F,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x2C ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x20,0x40, + + 5, // 0x2D '-' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x2E '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x00,0x00, + + 5, // 0x2F '/' + 0x00,0x00,0x08,0x08,0x10,0x10,0x10,0x20,0x20,0x20,0x40,0x40,0x40,0x80, + + 8, // 0x30 '0' + 0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x3C,0x00,0x00, + + 8, // 0x31 '1' + 0x00,0x00,0x00,0x08,0x38,0x08,0x08,0x08,0x08,0x08,0x08,0x3E,0x00,0x00, + + 8, // 0x32 '2' + 0x00,0x00,0x00,0x3C,0x42,0x42,0x02,0x04,0x18,0x20,0x40,0x7E,0x00,0x00, + + 8, // 0x33 '3' + 0x00,0x00,0x00,0x3C,0x42,0x02,0x02,0x1C,0x02,0x02,0x42,0x3C,0x00,0x00, + + 8, // 0x34 '4' + 0x00,0x00,0x00,0x04,0x0C,0x14,0x24,0x44,0x7F,0x04,0x04,0x04,0x00,0x00, + + 8, // 0x35 '5' + 0x00,0x00,0x00,0x7E,0x40,0x40,0x7C,0x02,0x02,0x02,0x42,0x3C,0x00,0x00, + + 8, // 0x36 '6' + 0x00,0x00,0x00,0x1C,0x20,0x40,0x7C,0x42,0x42,0x42,0x42,0x3C,0x00,0x00, + + 8, // 0x37 '7' + 0x00,0x00,0x00,0x7E,0x02,0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x00,0x00, + + 8, // 0x38 '8' + 0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x3C,0x42,0x42,0x42,0x3C,0x00,0x00, + + 8, // 0x39 '9' + 0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x42,0x3E,0x02,0x04,0x38,0x00,0x00, + + 5, // 0x3A ':' + 0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x00,0x00,0x00,0x20,0x20,0x00,0x00, + + 5, // 0x3B ';' + 0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x00,0x00,0x00,0x20,0x20,0x20,0x40, + + 9, // 0x3C '<' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x0C,0x00,0x30,0x00,0x40,0x00,0x30,0x00,0x0C,0x00,0x03,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x3D '=' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x3E '>' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x18,0x00,0x06,0x00,0x01,0x00,0x06,0x00,0x18,0x00,0x60,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x3F '?' + 0x00,0x00,0x00,0x38,0x44,0x04,0x04,0x08,0x10,0x10,0x00,0x10,0x00,0x00, + + 12, // 0x40 '@' + 0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x30,0xC0,0x27,0x40,0x49,0x20,0x49,0x20,0x49,0x20,0x49,0x20,0x27,0xC0,0x30,0x00,0x0F,0x00,0x00,0x00, + + 8, // 0x41 'A' + 0x00,0x00,0x00,0x18,0x18,0x24,0x24,0x42,0x42,0x7E,0x81,0x81,0x00,0x00, + + 8, // 0x42 'B' + 0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x7C,0x42,0x42,0x42,0x7C,0x00,0x00, + + 9, // 0x43 'C' + 0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x21,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x21,0x00,0x1E,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x44 'D' + 0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x42,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x42,0x00,0x7C,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x45 'E' + 0x00,0x00,0x00,0x7E,0x40,0x40,0x40,0x7E,0x40,0x40,0x40,0x7E,0x00,0x00, + + 7, // 0x46 'F' + 0x00,0x00,0x00,0x7E,0x40,0x40,0x40,0x7C,0x40,0x40,0x40,0x40,0x00,0x00, + + 9, // 0x47 'G' + 0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x21,0x00,0x40,0x00,0x40,0x00,0x47,0x00,0x41,0x00,0x41,0x00,0x21,0x00,0x1E,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x48 'H' + 0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x7F,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x49 'I' + 0x00,0x00,0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00, + + 5, // 0x4A 'J' + 0x00,0x00,0x00,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0xE0,0x00,0x00, + + 8, // 0x4B 'K' + 0x00,0x00,0x00,0x42,0x44,0x48,0x50,0x60,0x50,0x48,0x44,0x42,0x00,0x00, + + 7, // 0x4C 'L' + 0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7E,0x00,0x00, + + 10, // 0x4D 'M' + 0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x52,0x80,0x52,0x80,0x52,0x80,0x4C,0x80,0x4C,0x80,0x40,0x80,0x40,0x80,0x00,0x00,0x00,0x00, + + 9, // 0x4E 'N' + 0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x00,0x61,0x00,0x51,0x00,0x51,0x00,0x49,0x00,0x45,0x00,0x45,0x00,0x43,0x00,0x43,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x4F 'O' + 0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x21,0x00,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x21,0x00,0x1E,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x50 'P' + 0x00,0x00,0x00,0x7C,0x42,0x42,0x42,0x42,0x7C,0x40,0x40,0x40,0x00,0x00, + + 10, // 0x51 'Q' + 0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x21,0x00,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x21,0x00,0x1E,0x00,0x02,0x00,0x01,0x80, + + 8, // 0x52 'R' + 0x00,0x00,0x00,0x7C,0x42,0x42,0x42,0x7C,0x48,0x44,0x42,0x41,0x00,0x00, + + 8, // 0x53 'S' + 0x00,0x00,0x00,0x3C,0x42,0x40,0x40,0x3C,0x02,0x02,0x42,0x3C,0x00,0x00, + + 7, // 0x54 'T' + 0x00,0x00,0x00,0xFE,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00,0x00, + + 9, // 0x55 'U' + 0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x22,0x00,0x1C,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x56 'V' + 0x00,0x00,0x00,0x81,0x81,0x42,0x42,0x42,0x24,0x24,0x18,0x18,0x00,0x00, + + 13, // 0x57 'W' + 0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x10,0x42,0x10,0x45,0x10,0x45,0x10,0x25,0x20,0x28,0xA0,0x28,0xA0,0x10,0x40,0x10,0x40,0x00,0x00,0x00,0x00, + + 8, // 0x58 'X' + 0x00,0x00,0x00,0x42,0x42,0x24,0x18,0x18,0x18,0x24,0x42,0x42,0x00,0x00, + + 7, // 0x59 'Y' + 0x00,0x00,0x00,0x82,0x44,0x44,0x28,0x10,0x10,0x10,0x10,0x10,0x00,0x00, + + 8, // 0x5A 'Z' + 0x00,0x00,0x00,0x7E,0x02,0x04,0x08,0x10,0x10,0x20,0x40,0x7E,0x00,0x00, + + 5, // 0x5B '[' + 0x00,0x00,0x70,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x70, + + 5, // 0x5C '\' + 0x00,0x00,0x80,0x80,0x40,0x40,0x40,0x20,0x20,0x10,0x10,0x10,0x08,0x08, + + 5, // 0x5D ']' + 0x00,0x00,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x70, + + 10, // 0x5E '^' + 0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x12,0x00,0x21,0x00,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x5F '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF, + + 8, // 0x60 '`' + 0x00,0x00,0x20,0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x61 'a' + 0x00,0x00,0x00,0x00,0x00,0x3C,0x02,0x02,0x3E,0x42,0x42,0x3E,0x00,0x00, + + 8, // 0x62 'b' + 0x00,0x00,0x40,0x40,0x40,0x5C,0x62,0x42,0x42,0x42,0x42,0x7C,0x00,0x00, + + 6, // 0x63 'c' + 0x00,0x00,0x00,0x00,0x00,0x38,0x44,0x40,0x40,0x40,0x44,0x38,0x00,0x00, + + 8, // 0x64 'd' + 0x00,0x00,0x02,0x02,0x02,0x3E,0x42,0x42,0x42,0x42,0x46,0x3A,0x00,0x00, + + 8, // 0x65 'e' + 0x00,0x00,0x00,0x00,0x00,0x3C,0x42,0x42,0x7E,0x40,0x42,0x3C,0x00,0x00, + + 4, // 0x66 'f' + 0x00,0x00,0x30,0x40,0x40,0xF0,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00, + + 8, // 0x67 'g' + 0x00,0x00,0x00,0x00,0x00,0x3E,0x42,0x42,0x42,0x42,0x46,0x3A,0x02,0x3C, + + 8, // 0x68 'h' + 0x00,0x00,0x40,0x40,0x40,0x5C,0x62,0x42,0x42,0x42,0x42,0x42,0x00,0x00, + + 3, // 0x69 'i' + 0x00,0x00,0x40,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00, + + 4, // 0x6A 'j' + 0x00,0x00,0x20,0x00,0x00,0x60,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xC0, + + 7, // 0x6B 'k' + 0x00,0x00,0x40,0x40,0x40,0x44,0x48,0x50,0x60,0x50,0x48,0x44,0x00,0x00, + + 3, // 0x6C 'l' + 0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00, + + 11, // 0x6D 'm' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7B,0x80,0x44,0x40,0x44,0x40,0x44,0x40,0x44,0x40,0x44,0x40,0x44,0x40,0x00,0x00,0x00,0x00, + + 8, // 0x6E 'n' + 0x00,0x00,0x00,0x00,0x00,0x5C,0x62,0x42,0x42,0x42,0x42,0x42,0x00,0x00, + + 8, // 0x6F 'o' + 0x00,0x00,0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x42,0x42,0x3C,0x00,0x00, + + 8, // 0x70 'p' + 0x00,0x00,0x00,0x00,0x00,0x5C,0x62,0x42,0x42,0x42,0x42,0x7C,0x40,0x40, + + 8, // 0x71 'q' + 0x00,0x00,0x00,0x00,0x00,0x3E,0x42,0x42,0x42,0x42,0x46,0x3A,0x02,0x02, + + 5, // 0x72 'r' + 0x00,0x00,0x00,0x00,0x00,0x58,0x60,0x40,0x40,0x40,0x40,0x40,0x00,0x00, + + 7, // 0x73 's' + 0x00,0x00,0x00,0x00,0x00,0x3C,0x40,0x40,0x38,0x04,0x04,0x78,0x00,0x00, + + 5, // 0x74 't' + 0x00,0x00,0x00,0x40,0x40,0xF8,0x40,0x40,0x40,0x40,0x40,0x38,0x00,0x00, + + 8, // 0x75 'u' + 0x00,0x00,0x00,0x00,0x00,0x42,0x42,0x42,0x42,0x42,0x46,0x3A,0x00,0x00, + + 7, // 0x76 'v' + 0x00,0x00,0x00,0x00,0x00,0x44,0x44,0x28,0x28,0x28,0x10,0x10,0x00,0x00, + + 11, // 0x77 'w' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x40,0x44,0x40,0x2A,0x80,0x2A,0x80,0x2A,0x80,0x11,0x00,0x11,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x78 'x' + 0x00,0x00,0x00,0x00,0x00,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x00,0x00, + + 7, // 0x79 'y' + 0x00,0x00,0x00,0x00,0x00,0x44,0x44,0x28,0x28,0x28,0x10,0x10,0x10,0x20, + + 7, // 0x7A 'z' + 0x00,0x00,0x00,0x00,0x00,0x7C,0x04,0x08,0x10,0x20,0x40,0x7C,0x00,0x00, + + 8, // 0x7B '{' + 0x00,0x00,0x0C,0x10,0x10,0x10,0x10,0x60,0x10,0x10,0x10,0x10,0x10,0x0C, + + 5, // 0x7C '|' + 0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, + + 8, // 0x7D '}' + 0x00,0x00,0x30,0x08,0x08,0x08,0x08,0x06,0x08,0x08,0x08,0x08,0x08,0x30, + + 10, // 0x7E '~' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x80,0x4C,0x80,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 12, // 0x7F '' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xE0,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3F,0xE0,0x00,0x00,0x00,0x00, + + 0 + }; + + const int8u verdana14_bold[] = + { + 14, 3, 32, 128-32, + 0x00,0x00,0x0F,0x00,0x1E,0x00,0x2D,0x00,0x4A,0x00,0x67,0x00,0x84,0x00,0xA1,0x00,0xB0,0x00, + 0xBF,0x00,0xCE,0x00,0xEB,0x00,0x08,0x01,0x17,0x01,0x26,0x01,0x35,0x01,0x44,0x01,0x61,0x01, + 0x7E,0x01,0x9B,0x01,0xB8,0x01,0xD5,0x01,0xF2,0x01,0x0F,0x02,0x2C,0x02,0x49,0x02,0x66,0x02, + 0x75,0x02,0x84,0x02,0xA1,0x02,0xBE,0x02,0xDB,0x02,0xEA,0x02,0x07,0x03,0x24,0x03,0x41,0x03, + 0x5E,0x03,0x7B,0x03,0x8A,0x03,0x99,0x03,0xB6,0x03,0xD3,0x03,0xE2,0x03,0xF1,0x03,0x0E,0x04, + 0x1D,0x04,0x3A,0x04,0x57,0x04,0x74,0x04,0x91,0x04,0xAE,0x04,0xCB,0x04,0xE8,0x04,0xF7,0x04, + 0x14,0x05,0x31,0x05,0x4E,0x05,0x6B,0x05,0x88,0x05,0x97,0x05,0xA6,0x05,0xB5,0x05,0xC4,0x05, + 0xE1,0x05,0xFE,0x05,0x1B,0x06,0x2A,0x06,0x39,0x06,0x48,0x06,0x57,0x06,0x66,0x06,0x75,0x06, + 0x84,0x06,0x93,0x06,0xA2,0x06,0xB1,0x06,0xC0,0x06,0xCF,0x06,0xEC,0x06,0xFB,0x06,0x0A,0x07, + 0x19,0x07,0x28,0x07,0x37,0x07,0x46,0x07,0x55,0x07,0x64,0x07,0x73,0x07,0x90,0x07,0x9F,0x07, + 0xAE,0x07,0xBD,0x07,0xDA,0x07,0xE9,0x07,0x06,0x08,0x23,0x08, + + 4, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x21 '!' + 0x00,0x00,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x60,0x60,0x00,0x00, + + 7, // 0x22 '"' + 0x00,0x00,0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x23 '#' + 0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x00,0x09,0x00,0x3F,0x80,0x3F,0x80,0x12,0x00,0x7F,0x00,0x7F,0x00,0x24,0x00,0x24,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x24 '$' + 0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x3E,0x00,0x69,0x00,0x68,0x00,0x7E,0x00,0x3F,0x00,0x0B,0x00,0x4B,0x00,0x3E,0x00,0x08,0x00,0x08,0x00, + + 15, // 0x25 '%' + 0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x40,0x6C,0x40,0x6C,0x80,0x6C,0xB8,0x6D,0x6C,0x3A,0x6C,0x02,0x6C,0x04,0x6C,0x04,0x38,0x00,0x00,0x00,0x00, + + 10, // 0x26 '&' + 0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x6C,0x00,0x6C,0x00,0x6C,0x00,0x39,0x80,0x6D,0x00,0x66,0x00,0x63,0x00,0x3D,0x80,0x00,0x00,0x00,0x00, + + 4, // 0x27 ''' + 0x00,0x00,0x60,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x28 '(' + 0x00,0x00,0x18,0x30,0x30,0x60,0x60,0x60,0x60,0x60,0x60,0x30,0x30,0x18, + + 7, // 0x29 ')' + 0x00,0x00,0x30,0x18,0x18,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x18,0x18,0x30, + + 9, // 0x2A '*' + 0x00,0x00,0x00,0x00,0x08,0x00,0x2A,0x00,0x1C,0x00,0x1C,0x00,0x2A,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x2B '+' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x7F,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x2C ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x60,0x40, + + 6, // 0x2D '-' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x2E '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00, + + 8, // 0x2F '/' + 0x00,0x00,0x06,0x06,0x0C,0x0C,0x0C,0x18,0x18,0x30,0x30,0x30,0x60,0x60, + + 9, // 0x30 '0' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x31 '1' + 0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x3C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x3F,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x32 '2' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x03,0x00,0x03,0x00,0x06,0x00,0x0C,0x00,0x18,0x00,0x30,0x00,0x7F,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x33 '3' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x03,0x00,0x03,0x00,0x1E,0x00,0x03,0x00,0x03,0x00,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x34 '4' + 0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x0E,0x00,0x16,0x00,0x16,0x00,0x26,0x00,0x46,0x00,0x7F,0x00,0x06,0x00,0x06,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x35 '5' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x30,0x00,0x30,0x00,0x3E,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x36 '6' + 0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x30,0x00,0x60,0x00,0x7E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x37 '7' + 0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x03,0x00,0x06,0x00,0x06,0x00,0x0C,0x00,0x0C,0x00,0x18,0x00,0x18,0x00,0x30,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x38 '8' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x3E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x39 '9' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x3F,0x00,0x03,0x00,0x06,0x00,0x3C,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x3A ':' + 0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x60,0x60,0x00,0x00, + + 5, // 0x3B ';' + 0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x00,0x60,0x60,0x60,0x40, + + 10, // 0x3C '<' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x06,0x00,0x18,0x00,0x60,0x00,0x60,0x00,0x18,0x00,0x06,0x00,0x01,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x3D '=' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x3E '>' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x30,0x00,0x0C,0x00,0x03,0x00,0x03,0x00,0x0C,0x00,0x30,0x00,0x40,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x3F '?' + 0x00,0x00,0x00,0x38,0x4C,0x0C,0x18,0x30,0x30,0x00,0x30,0x30,0x00,0x00, + + 12, // 0x40 '@' + 0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x30,0xC0,0x2F,0x40,0x5B,0x20,0x5B,0x20,0x5B,0x20,0x5B,0x20,0x2F,0xC0,0x30,0x00,0x0F,0x00,0x00,0x00, + + 9, // 0x41 'A' + 0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x1C,0x00,0x36,0x00,0x36,0x00,0x36,0x00,0x36,0x00,0x7F,0x00,0x63,0x00,0x63,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x42 'B' + 0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x66,0x00,0x66,0x00,0x66,0x00,0x7E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x7E,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x43 'C' + 0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x31,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x31,0x00,0x1E,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x44 'D' + 0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x63,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x63,0x00,0x7E,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x45 'E' + 0x00,0x00,0x00,0x7E,0x60,0x60,0x60,0x7E,0x60,0x60,0x60,0x7E,0x00,0x00, + + 8, // 0x46 'F' + 0x00,0x00,0x00,0x7E,0x60,0x60,0x60,0x7E,0x60,0x60,0x60,0x60,0x00,0x00, + + 10, // 0x47 'G' + 0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x30,0x80,0x60,0x00,0x60,0x00,0x60,0x00,0x67,0x80,0x61,0x80,0x31,0x80,0x1F,0x80,0x00,0x00,0x00,0x00, + + 10, // 0x48 'H' + 0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x7F,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x00,0x00,0x00,0x00, + + 6, // 0x49 'I' + 0x00,0x00,0x00,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x78,0x00,0x00, + + 7, // 0x4A 'J' + 0x00,0x00,0x00,0x7C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0xF8,0x00,0x00, + + 9, // 0x4B 'K' + 0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x00,0x66,0x00,0x6C,0x00,0x78,0x00,0x70,0x00,0x78,0x00,0x6C,0x00,0x66,0x00,0x63,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x4C 'L' + 0x00,0x00,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x7F,0x00,0x00, + + 11, // 0x4D 'M' + 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xC0,0x71,0xC0,0x71,0xC0,0x5A,0xC0,0x5A,0xC0,0x4C,0xC0,0x4C,0xC0,0x40,0xC0,0x40,0xC0,0x00,0x00,0x00,0x00, + + 10, // 0x4E 'N' + 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x80,0x70,0x80,0x58,0x80,0x58,0x80,0x4C,0x80,0x46,0x80,0x46,0x80,0x43,0x80,0x41,0x80,0x00,0x00,0x00,0x00, + + 11, // 0x4F 'O' + 0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x31,0x80,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x31,0x80,0x1F,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x50 'P' + 0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x7E,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x51 'Q' + 0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x31,0x80,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x31,0x80,0x1F,0x00,0x06,0x00,0x03,0xC0, + + 9, // 0x52 'R' + 0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x7E,0x00,0x6C,0x00,0x66,0x00,0x63,0x00,0x61,0x80,0x00,0x00,0x00,0x00, + + 9, // 0x53 'S' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x61,0x00,0x60,0x00,0x70,0x00,0x3E,0x00,0x07,0x00,0x03,0x00,0x43,0x00,0x3E,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x54 'T' + 0x00,0x00,0x00,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00, + + 10, // 0x55 'U' + 0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x3F,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x56 'V' + 0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x36,0x00,0x36,0x00,0x36,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x00,0x00,0x00,0x00, + + 14, // 0x57 'W' + 0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x18,0x63,0x18,0x63,0x18,0x33,0x30,0x37,0xB0,0x34,0xB0,0x1C,0xE0,0x18,0x60,0x18,0x60,0x00,0x00,0x00,0x00, + + 9, // 0x58 'X' + 0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x00,0x63,0x00,0x36,0x00,0x1C,0x00,0x1C,0x00,0x1C,0x00,0x36,0x00,0x63,0x00,0x63,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x59 'Y' + 0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x5A 'Z' + 0x00,0x00,0x00,0x7E,0x0C,0x0C,0x18,0x18,0x30,0x30,0x60,0x7E,0x00,0x00, + + 6, // 0x5B '[' + 0x00,0x00,0x78,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x78, + + 8, // 0x5C '\' + 0x00,0x00,0x60,0x60,0x30,0x30,0x30,0x18,0x18,0x0C,0x0C,0x0C,0x06,0x06, + + 6, // 0x5D ']' + 0x00,0x00,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x78, + + 10, // 0x5E '^' + 0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x5F '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x80, + + 9, // 0x60 '`' + 0x00,0x00,0x00,0x00,0x30,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x61 'a' + 0x00,0x00,0x00,0x00,0x00,0x3C,0x06,0x3E,0x66,0x66,0x66,0x3E,0x00,0x00, + + 8, // 0x62 'b' + 0x00,0x00,0x60,0x60,0x60,0x7C,0x66,0x66,0x66,0x66,0x66,0x7C,0x00,0x00, + + 7, // 0x63 'c' + 0x00,0x00,0x00,0x00,0x00,0x3C,0x62,0x60,0x60,0x60,0x62,0x3C,0x00,0x00, + + 8, // 0x64 'd' + 0x00,0x00,0x06,0x06,0x06,0x3E,0x66,0x66,0x66,0x66,0x66,0x3E,0x00,0x00, + + 8, // 0x65 'e' + 0x00,0x00,0x00,0x00,0x00,0x3C,0x66,0x66,0x7E,0x60,0x62,0x3C,0x00,0x00, + + 5, // 0x66 'f' + 0x00,0x00,0x38,0x60,0x60,0xF8,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00, + + 8, // 0x67 'g' + 0x00,0x00,0x00,0x00,0x00,0x3E,0x66,0x66,0x66,0x66,0x66,0x3E,0x06,0x3C, + + 8, // 0x68 'h' + 0x00,0x00,0x60,0x60,0x60,0x7C,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00, + + 4, // 0x69 'i' + 0x00,0x00,0x60,0x60,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00, + + 5, // 0x6A 'j' + 0x00,0x00,0x30,0x30,0x00,0x70,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0xE0, + + 8, // 0x6B 'k' + 0x00,0x00,0x60,0x60,0x60,0x66,0x6C,0x78,0x78,0x6C,0x66,0x63,0x00,0x00, + + 4, // 0x6C 'l' + 0x00,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00, + + 12, // 0x6D 'm' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6C,0xC0,0x77,0x60,0x66,0x60,0x66,0x60,0x66,0x60,0x66,0x60,0x66,0x60,0x00,0x00,0x00,0x00, + + 8, // 0x6E 'n' + 0x00,0x00,0x00,0x00,0x00,0x7C,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00, + + 8, // 0x6F 'o' + 0x00,0x00,0x00,0x00,0x00,0x3C,0x66,0x66,0x66,0x66,0x66,0x3C,0x00,0x00, + + 8, // 0x70 'p' + 0x00,0x00,0x00,0x00,0x00,0x7C,0x66,0x66,0x66,0x66,0x66,0x7C,0x60,0x60, + + 8, // 0x71 'q' + 0x00,0x00,0x00,0x00,0x00,0x3E,0x66,0x66,0x66,0x66,0x66,0x3E,0x06,0x06, + + 6, // 0x72 'r' + 0x00,0x00,0x00,0x00,0x00,0x6C,0x7C,0x60,0x60,0x60,0x60,0x60,0x00,0x00, + + 7, // 0x73 's' + 0x00,0x00,0x00,0x00,0x00,0x3C,0x60,0x60,0x38,0x0C,0x0C,0x78,0x00,0x00, + + 5, // 0x74 't' + 0x00,0x00,0x00,0x60,0x60,0xF8,0x60,0x60,0x60,0x60,0x60,0x38,0x00,0x00, + + 8, // 0x75 'u' + 0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x66,0x66,0x3E,0x00,0x00, + + 8, // 0x76 'v' + 0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x3C,0x3C,0x3C,0x18,0x00,0x00, + + 12, // 0x77 'w' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x60,0x66,0x60,0x66,0x60,0x69,0x60,0x39,0xC0,0x30,0xC0,0x30,0xC0,0x00,0x00,0x00,0x00, + + 8, // 0x78 'x' + 0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x3C,0x18,0x3C,0x66,0x66,0x00,0x00, + + 8, // 0x79 'y' + 0x00,0x00,0x00,0x00,0x00,0x66,0x66,0x66,0x3C,0x3C,0x3C,0x18,0x18,0x30, + + 7, // 0x7A 'z' + 0x00,0x00,0x00,0x00,0x00,0x7C,0x0C,0x18,0x38,0x30,0x60,0x7C,0x00,0x00, + + 9, // 0x7B '{' + 0x00,0x00,0x00,0x00,0x0E,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x70,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x0E,0x00, + + 6, // 0x7C '|' + 0x00,0x00,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30, + + 9, // 0x7D '}' + 0x00,0x00,0x00,0x00,0x38,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x07,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x38,0x00, + + 10, // 0x7E '~' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x80,0x48,0x80,0x44,0x80,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 12, // 0x7F '' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xE0,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3F,0xE0,0x00,0x00,0x00,0x00, + + 0 + }; + + const int8u verdana16[] = + { + 16, 4, 32, 128-32, + 0x00,0x00,0x11,0x00,0x22,0x00,0x33,0x00,0x54,0x00,0x65,0x00,0x86,0x00,0xA7,0x00,0xB8,0x00, + 0xC9,0x00,0xDA,0x00,0xFB,0x00,0x1C,0x01,0x2D,0x01,0x3E,0x01,0x4F,0x01,0x60,0x01,0x71,0x01, + 0x82,0x01,0x93,0x01,0xA4,0x01,0xB5,0x01,0xC6,0x01,0xD7,0x01,0xE8,0x01,0xF9,0x01,0x0A,0x02, + 0x1B,0x02,0x2C,0x02,0x4D,0x02,0x6E,0x02,0x8F,0x02,0xA0,0x02,0xC1,0x02,0xE2,0x02,0xF3,0x02, + 0x14,0x03,0x35,0x03,0x46,0x03,0x57,0x03,0x78,0x03,0x99,0x03,0xAA,0x03,0xBB,0x03,0xCC,0x03, + 0xDD,0x03,0xFE,0x03,0x1F,0x04,0x40,0x04,0x51,0x04,0x72,0x04,0x93,0x04,0xB4,0x04,0xD5,0x04, + 0xF6,0x04,0x17,0x05,0x38,0x05,0x59,0x05,0x7A,0x05,0x9B,0x05,0xAC,0x05,0xBD,0x05,0xCE,0x05, + 0xEF,0x05,0x00,0x06,0x11,0x06,0x22,0x06,0x33,0x06,0x44,0x06,0x55,0x06,0x66,0x06,0x77,0x06, + 0x88,0x06,0x99,0x06,0xAA,0x06,0xBB,0x06,0xCC,0x06,0xDD,0x06,0xFE,0x06,0x0F,0x07,0x20,0x07, + 0x31,0x07,0x42,0x07,0x53,0x07,0x64,0x07,0x75,0x07,0x86,0x07,0x97,0x07,0xB8,0x07,0xC9,0x07, + 0xDA,0x07,0xEB,0x07,0xFC,0x07,0x0D,0x08,0x1E,0x08,0x3F,0x08, + + 5, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x21 '!' + 0x00,0x00,0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x20,0x00,0x00,0x00, + + 5, // 0x22 '"' + 0x00,0x00,0x00,0x50,0x50,0x50,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x23 '#' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x00,0x09,0x00,0x3F,0x80,0x12,0x00,0x12,0x00,0x7F,0x00,0x24,0x00,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x24 '$' + 0x00,0x00,0x00,0x10,0x10,0x3E,0x50,0x50,0x30,0x1C,0x12,0x12,0x7C,0x10,0x10,0x00, + + 13, // 0x25 '%' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x40,0x44,0x80,0x45,0x00,0x45,0x00,0x3A,0xE0,0x05,0x10,0x05,0x10,0x09,0x10,0x10,0xE0,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x26 '&' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x44,0x00,0x44,0x00,0x44,0x00,0x38,0x80,0x45,0x00,0x42,0x00,0x46,0x00,0x39,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 3, // 0x27 ''' + 0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x28 '(' + 0x00,0x00,0x00,0x08,0x10,0x20,0x20,0x40,0x40,0x40,0x40,0x40,0x20,0x20,0x10,0x08, + + 6, // 0x29 ')' + 0x00,0x00,0x00,0x40,0x20,0x10,0x10,0x08,0x08,0x08,0x08,0x08,0x10,0x10,0x20,0x40, + + 9, // 0x2A '*' + 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x2A,0x00,0x1C,0x00,0x2A,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x2B '+' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x7F,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x2C ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x20,0x40,0x00, + + 7, // 0x2D '-' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x2E '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x00,0x00,0x00, + + 6, // 0x2F '/' + 0x00,0x00,0x00,0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x80,0x80,0x00, + + 8, // 0x30 '0' + 0x00,0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x42,0x42,0x42,0x42,0x3C,0x00,0x00,0x00, + + 8, // 0x31 '1' + 0x00,0x00,0x00,0x00,0x08,0x38,0x08,0x08,0x08,0x08,0x08,0x08,0x3E,0x00,0x00,0x00, + + 8, // 0x32 '2' + 0x00,0x00,0x00,0x00,0x3C,0x42,0x42,0x02,0x04,0x18,0x20,0x40,0x7E,0x00,0x00,0x00, + + 8, // 0x33 '3' + 0x00,0x00,0x00,0x00,0x3C,0x42,0x02,0x02,0x1C,0x02,0x02,0x42,0x3C,0x00,0x00,0x00, + + 8, // 0x34 '4' + 0x00,0x00,0x00,0x00,0x04,0x0C,0x14,0x24,0x44,0x7F,0x04,0x04,0x04,0x00,0x00,0x00, + + 8, // 0x35 '5' + 0x00,0x00,0x00,0x00,0x3E,0x20,0x20,0x20,0x3C,0x02,0x02,0x42,0x3C,0x00,0x00,0x00, + + 8, // 0x36 '6' + 0x00,0x00,0x00,0x00,0x1C,0x20,0x40,0x7C,0x42,0x42,0x42,0x42,0x3C,0x00,0x00,0x00, + + 8, // 0x37 '7' + 0x00,0x00,0x00,0x00,0x7E,0x02,0x04,0x04,0x08,0x08,0x10,0x10,0x10,0x00,0x00,0x00, + + 8, // 0x38 '8' + 0x00,0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x3C,0x42,0x42,0x42,0x3C,0x00,0x00,0x00, + + 8, // 0x39 '9' + 0x00,0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x42,0x3E,0x02,0x04,0x38,0x00,0x00,0x00, + + 6, // 0x3A ':' + 0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x00,0x00,0x00,0x20,0x20,0x00,0x00,0x00, + + 6, // 0x3B ';' + 0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x00,0x00,0x00,0x20,0x20,0x20,0x40,0x00, + + 9, // 0x3C '<' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x0C,0x00,0x30,0x00,0x40,0x00,0x30,0x00,0x0C,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x3D '=' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x3E '>' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x18,0x00,0x06,0x00,0x01,0x00,0x06,0x00,0x18,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x3F '?' + 0x00,0x00,0x00,0x00,0x38,0x44,0x04,0x08,0x10,0x10,0x00,0x10,0x10,0x00,0x00,0x00, + + 13, // 0x40 '@' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x80,0x10,0x40,0x27,0xA0,0x48,0x90,0x48,0x90,0x48,0x90,0x48,0x90,0x48,0x90,0x27,0xE0,0x10,0x00,0x0F,0x80,0x00,0x00, + + 9, // 0x41 'A' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x14,0x00,0x14,0x00,0x22,0x00,0x22,0x00,0x3E,0x00,0x41,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x42 'B' + 0x00,0x00,0x00,0x00,0x78,0x44,0x44,0x44,0x7C,0x42,0x42,0x42,0x7C,0x00,0x00,0x00, + + 9, // 0x43 'C' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x21,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x21,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x44 'D' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x42,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x42,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x45 'E' + 0x00,0x00,0x00,0x00,0x7E,0x40,0x40,0x40,0x7E,0x40,0x40,0x40,0x7E,0x00,0x00,0x00, + + 8, // 0x46 'F' + 0x00,0x00,0x00,0x00,0x7E,0x40,0x40,0x40,0x7C,0x40,0x40,0x40,0x40,0x00,0x00,0x00, + + 9, // 0x47 'G' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x21,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x47,0x00,0x41,0x00,0x21,0x00,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x48 'H' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x7F,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x49 'I' + 0x00,0x00,0x00,0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00,0x00, + + 6, // 0x4A 'J' + 0x00,0x00,0x00,0x00,0x38,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0xF0,0x00,0x00,0x00, + + 8, // 0x4B 'K' + 0x00,0x00,0x00,0x00,0x42,0x44,0x48,0x50,0x60,0x50,0x48,0x44,0x42,0x00,0x00,0x00, + + 7, // 0x4C 'L' + 0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7E,0x00,0x00,0x00, + + 11, // 0x4D 'M' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xC0,0x60,0xC0,0x51,0x40,0x51,0x40,0x4A,0x40,0x4A,0x40,0x44,0x40,0x44,0x40,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x4E 'N' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x00,0x61,0x00,0x51,0x00,0x51,0x00,0x49,0x00,0x45,0x00,0x45,0x00,0x43,0x00,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x4F 'O' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x21,0x00,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x21,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x50 'P' + 0x00,0x00,0x00,0x00,0x7C,0x42,0x42,0x42,0x42,0x7C,0x40,0x40,0x40,0x00,0x00,0x00, + + 10, // 0x51 'Q' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x21,0x00,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x21,0x00,0x1E,0x00,0x02,0x00,0x01,0x80,0x00,0x00, + + 9, // 0x52 'R' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x44,0x00,0x78,0x00,0x44,0x00,0x42,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x53 'S' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x41,0x00,0x40,0x00,0x40,0x00,0x3E,0x00,0x01,0x00,0x01,0x00,0x41,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x54 'T' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x55 'U' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x22,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x56 'V' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x22,0x00,0x22,0x00,0x14,0x00,0x14,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 13, // 0x57 'W' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x10,0x42,0x10,0x45,0x10,0x45,0x10,0x25,0x20,0x28,0xA0,0x28,0xA0,0x10,0x40,0x10,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x58 'X' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x41,0x00,0x22,0x00,0x14,0x00,0x08,0x00,0x14,0x00,0x22,0x00,0x41,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x59 'Y' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x22,0x00,0x22,0x00,0x14,0x00,0x14,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x5A 'Z' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x01,0x00,0x02,0x00,0x04,0x00,0x08,0x00,0x10,0x00,0x20,0x00,0x40,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x5B '[' + 0x00,0x00,0x00,0x38,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x38,0x00, + + 6, // 0x5C '\' + 0x00,0x00,0x00,0x80,0x80,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x04,0x04,0x00, + + 6, // 0x5D ']' + 0x00,0x00,0x00,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x70,0x00, + + 11, // 0x5E '^' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x0A,0x00,0x11,0x00,0x20,0x80,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x5F '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x00, + + 8, // 0x60 '`' + 0x00,0x00,0x00,0x10,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x61 'a' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x02,0x02,0x3E,0x42,0x42,0x3E,0x00,0x00,0x00, + + 8, // 0x62 'b' + 0x00,0x00,0x00,0x40,0x40,0x40,0x5C,0x62,0x42,0x42,0x42,0x42,0x7C,0x00,0x00,0x00, + + 8, // 0x63 'c' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x42,0x40,0x40,0x40,0x42,0x3C,0x00,0x00,0x00, + + 8, // 0x64 'd' + 0x00,0x00,0x00,0x02,0x02,0x02,0x3E,0x42,0x42,0x42,0x42,0x46,0x3A,0x00,0x00,0x00, + + 8, // 0x65 'e' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x42,0x42,0x7E,0x40,0x42,0x3C,0x00,0x00,0x00, + + 6, // 0x66 'f' + 0x00,0x00,0x00,0x1C,0x20,0x20,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00,0x00, + + 8, // 0x67 'g' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x42,0x42,0x42,0x42,0x46,0x3A,0x02,0x02,0x3C, + + 8, // 0x68 'h' + 0x00,0x00,0x00,0x40,0x40,0x40,0x5C,0x62,0x42,0x42,0x42,0x42,0x42,0x00,0x00,0x00, + + 3, // 0x69 'i' + 0x00,0x00,0x00,0x40,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00, + + 4, // 0x6A 'j' + 0x00,0x00,0x00,0x20,0x00,0x00,0x60,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0xC0, + + 7, // 0x6B 'k' + 0x00,0x00,0x00,0x40,0x40,0x40,0x44,0x48,0x50,0x60,0x50,0x48,0x44,0x00,0x00,0x00, + + 3, // 0x6C 'l' + 0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00, + + 11, // 0x6D 'm' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x59,0x80,0x66,0x40,0x44,0x40,0x44,0x40,0x44,0x40,0x44,0x40,0x44,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x6E 'n' + 0x00,0x00,0x00,0x00,0x00,0x00,0x5C,0x62,0x42,0x42,0x42,0x42,0x42,0x00,0x00,0x00, + + 8, // 0x6F 'o' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x42,0x42,0x42,0x42,0x42,0x3C,0x00,0x00,0x00, + + 8, // 0x70 'p' + 0x00,0x00,0x00,0x00,0x00,0x00,0x5C,0x62,0x42,0x42,0x42,0x42,0x7C,0x40,0x40,0x40, + + 8, // 0x71 'q' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x42,0x42,0x42,0x42,0x46,0x3A,0x02,0x02,0x02, + + 5, // 0x72 'r' + 0x00,0x00,0x00,0x00,0x00,0x00,0x58,0x60,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00, + + 7, // 0x73 's' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x40,0x40,0x38,0x04,0x04,0x78,0x00,0x00,0x00, + + 6, // 0x74 't' + 0x00,0x00,0x00,0x00,0x20,0x20,0x78,0x20,0x20,0x20,0x20,0x20,0x18,0x00,0x00,0x00, + + 8, // 0x75 'u' + 0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x42,0x42,0x42,0x42,0x46,0x3A,0x00,0x00,0x00, + + 8, // 0x76 'v' + 0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x42,0x24,0x24,0x24,0x18,0x18,0x00,0x00,0x00, + + 11, // 0x77 'w' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x40,0x44,0x40,0x2A,0x80,0x2A,0x80,0x2A,0x80,0x11,0x00,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x78 'x' + 0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x44,0x28,0x10,0x28,0x44,0x44,0x00,0x00,0x00, + + 8, // 0x79 'y' + 0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x42,0x24,0x24,0x24,0x18,0x18,0x10,0x10,0x20, + + 7, // 0x7A 'z' + 0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x04,0x08,0x10,0x20,0x40,0x7C,0x00,0x00,0x00, + + 8, // 0x7B '{' + 0x00,0x00,0x00,0x0C,0x10,0x10,0x10,0x10,0x60,0x10,0x10,0x10,0x10,0x10,0x0C,0x00, + + 7, // 0x7C '|' + 0x00,0x00,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x00, + + 8, // 0x7D '}' + 0x00,0x00,0x00,0x30,0x08,0x08,0x08,0x08,0x06,0x08,0x08,0x08,0x08,0x08,0x30,0x00, + + 11, // 0x7E '~' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x80,0x4C,0x80,0x43,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 13, // 0x7F '' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xF0,0x20,0x10,0x20,0x10,0x20,0x10,0x20,0x10,0x20,0x10,0x20,0x10,0x20,0x10,0x20,0x10,0x3F,0xF0,0x00,0x00,0x00,0x00,0x00,0x00, + + 0 + }; + + const int8u verdana16_bold[] = + { + 16, 4, 32, 128-32, + 0x00,0x00,0x11,0x00,0x22,0x00,0x33,0x00,0x54,0x00,0x75,0x00,0xA6,0x00,0xC7,0x00,0xD8,0x00, + 0xE9,0x00,0xFA,0x00,0x1B,0x01,0x3C,0x01,0x4D,0x01,0x5E,0x01,0x6F,0x01,0x90,0x01,0xB1,0x01, + 0xD2,0x01,0xF3,0x01,0x14,0x02,0x35,0x02,0x56,0x02,0x77,0x02,0x98,0x02,0xB9,0x02,0xDA,0x02, + 0xEB,0x02,0xFC,0x02,0x1D,0x03,0x3E,0x03,0x5F,0x03,0x70,0x03,0x91,0x03,0xB2,0x03,0xD3,0x03, + 0xF4,0x03,0x15,0x04,0x36,0x04,0x57,0x04,0x78,0x04,0x99,0x04,0xAA,0x04,0xBB,0x04,0xDC,0x04, + 0xED,0x04,0x0E,0x05,0x2F,0x05,0x50,0x05,0x71,0x05,0x92,0x05,0xB3,0x05,0xD4,0x05,0xE5,0x05, + 0x06,0x06,0x27,0x06,0x48,0x06,0x69,0x06,0x8A,0x06,0xAB,0x06,0xBC,0x06,0xDD,0x06,0xEE,0x06, + 0x0F,0x07,0x30,0x07,0x51,0x07,0x72,0x07,0x93,0x07,0xA4,0x07,0xC5,0x07,0xE6,0x07,0xF7,0x07, + 0x18,0x08,0x39,0x08,0x4A,0x08,0x5B,0x08,0x6C,0x08,0x7D,0x08,0x9E,0x08,0xBF,0x08,0xE0,0x08, + 0x01,0x09,0x22,0x09,0x33,0x09,0x44,0x09,0x55,0x09,0x76,0x09,0x97,0x09,0xB8,0x09,0xD9,0x09, + 0xFA,0x09,0x0B,0x0A,0x2C,0x0A,0x3D,0x0A,0x5E,0x0A,0x7F,0x0A, + + 4, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x21 '!' + 0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x30,0x30,0x30,0x00,0x30,0x30,0x00,0x00,0x00, + + 7, // 0x22 '"' + 0x00,0x00,0x00,0x6C,0x6C,0x6C,0x6C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x23 '#' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x09,0x00,0x09,0x00,0x3F,0x80,0x3F,0x80,0x12,0x00,0x7F,0x00,0x7F,0x00,0x24,0x00,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x24 '$' + 0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x3E,0x00,0x69,0x00,0x68,0x00,0x78,0x00,0x3E,0x00,0x0F,0x00,0x0B,0x00,0x4B,0x00,0x3E,0x00,0x08,0x00,0x08,0x00,0x00,0x00, + + 17, // 0x25 '%' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x20,0x00,0x66,0x20,0x00,0x66,0x40,0x00,0x66,0x5E,0x00,0x66,0xB3,0x00,0x3D,0x33,0x00,0x01,0x33,0x00,0x02,0x33,0x00,0x02,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x26 '&' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x00,0x66,0x00,0x66,0x00,0x66,0xC0,0x3C,0xC0,0x66,0x80,0x63,0x00,0x63,0x80,0x3C,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x27 ''' + 0x00,0x00,0x00,0x60,0x60,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x28 '(' + 0x00,0x00,0x00,0x0C,0x18,0x30,0x30,0x60,0x60,0x60,0x60,0x60,0x30,0x30,0x18,0x0C, + + 7, // 0x29 ')' + 0x00,0x00,0x00,0x60,0x30,0x18,0x18,0x0C,0x0C,0x0C,0x0C,0x0C,0x18,0x18,0x30,0x60, + + 9, // 0x2A '*' + 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x49,0x00,0x2A,0x00,0x1C,0x00,0x2A,0x00,0x49,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x2B '+' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x3F,0x80,0x04,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x2C ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x60,0x60,0xC0,0xC0, + + 7, // 0x2D '-' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x2E '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00, + + 9, // 0x2F '/' + 0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x03,0x00,0x06,0x00,0x06,0x00,0x0C,0x00,0x0C,0x00,0x18,0x00,0x18,0x00,0x30,0x00,0x30,0x00,0x60,0x00,0x60,0x00,0x00,0x00, + + 9, // 0x30 '0' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x31 '1' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x3C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x32 '2' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x63,0x00,0x03,0x00,0x06,0x00,0x0C,0x00,0x18,0x00,0x30,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x33 '3' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x63,0x00,0x03,0x00,0x0E,0x00,0x03,0x00,0x63,0x00,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x34 '4' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x0E,0x00,0x16,0x00,0x26,0x00,0x46,0x00,0x7F,0x80,0x06,0x00,0x06,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x35 '5' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x30,0x00,0x30,0x00,0x3E,0x00,0x03,0x00,0x03,0x00,0x63,0x00,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x36 '6' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x30,0x00,0x60,0x00,0x7E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x37 '7' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x03,0x00,0x03,0x00,0x06,0x00,0x06,0x00,0x0C,0x00,0x0C,0x00,0x18,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x38 '8' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x3E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x39 '9' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x3F,0x00,0x03,0x00,0x06,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x3A ':' + 0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00, + + 5, // 0x3B ';' + 0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x00,0x00,0x00,0x38,0x30,0x30,0x60,0x60, + + 11, // 0x3C '<' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x03,0x00,0x0C,0x00,0x30,0x00,0x40,0x00,0x30,0x00,0x0C,0x00,0x03,0x00,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x3D '=' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x80,0x00,0x00,0x00,0x00,0x3F,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x3E '>' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x18,0x00,0x06,0x00,0x01,0x80,0x00,0x40,0x01,0x80,0x06,0x00,0x18,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x3F '?' + 0x00,0x00,0x00,0x00,0x3C,0x66,0x06,0x0C,0x18,0x18,0x00,0x18,0x18,0x00,0x00,0x00, + + 13, // 0x40 '@' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x80,0x30,0x60,0x27,0xA0,0x4D,0x90,0x4D,0x90,0x4D,0x90,0x4D,0x90,0x27,0xE0,0x30,0x00,0x0F,0x80,0x00,0x00,0x00,0x00, + + 10, // 0x41 'A' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x0C,0x00,0x1E,0x00,0x1E,0x00,0x33,0x00,0x33,0x00,0x7F,0x80,0x61,0x80,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x42 'B' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x7F,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x43 'C' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x31,0x80,0x61,0x80,0x60,0x00,0x60,0x00,0x60,0x00,0x61,0x80,0x31,0x80,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x44 'D' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x63,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x63,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x45 'E' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x7F,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x46 'F' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x7F,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x47 'G' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x31,0x80,0x61,0x80,0x60,0x00,0x60,0x00,0x63,0x80,0x61,0x80,0x31,0x80,0x1F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x48 'H' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x7F,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x49 'I' + 0x00,0x00,0x00,0x00,0x78,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x78,0x00,0x00,0x00, + + 7, // 0x4A 'J' + 0x00,0x00,0x00,0x00,0x7C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0xF8,0x00,0x00,0x00, + + 9, // 0x4B 'K' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x00,0x66,0x00,0x6C,0x00,0x78,0x00,0x78,0x00,0x6C,0x00,0x66,0x00,0x63,0x00,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x4C 'L' + 0x00,0x00,0x00,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x7F,0x00,0x00,0x00, + + 12, // 0x4D 'M' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0xE0,0x70,0xE0,0x59,0x60,0x59,0x60,0x4E,0x60,0x4E,0x60,0x44,0x60,0x44,0x60,0x40,0x60,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x4E 'N' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x80,0x70,0x80,0x58,0x80,0x58,0x80,0x4C,0x80,0x46,0x80,0x46,0x80,0x43,0x80,0x43,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x4F 'O' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x31,0x80,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x31,0x80,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x50 'P' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x7E,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x51 'Q' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x31,0x80,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x31,0x80,0x1F,0x00,0x03,0x00,0x01,0xC0,0x00,0x00, + + 9, // 0x52 'R' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x7E,0x00,0x6C,0x00,0x66,0x00,0x63,0x00,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x53 'S' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x63,0x00,0x70,0x00,0x3E,0x00,0x07,0x00,0x63,0x00,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x54 'T' + 0x00,0x00,0x00,0x00,0xFF,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00,0x00,0x00, + + 10, // 0x55 'U' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x56 'V' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x00,0x33,0x00,0x1E,0x00,0x1E,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 14, // 0x57 'W' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x18,0x63,0x18,0x63,0x18,0x33,0x30,0x37,0xB0,0x34,0xB0,0x1C,0xE0,0x18,0x60,0x18,0x60,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x58 'X' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x33,0x00,0x33,0x00,0x1E,0x00,0x0C,0x00,0x1E,0x00,0x33,0x00,0x33,0x00,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x59 'Y' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x5A 'Z' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x06,0x00,0x0C,0x00,0x0C,0x00,0x18,0x00,0x18,0x00,0x30,0x00,0x30,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x5B '[' + 0x00,0x00,0x00,0x78,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x78,0x00, + + 9, // 0x5C '\' + 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x30,0x00,0x30,0x00,0x18,0x00,0x18,0x00,0x0C,0x00,0x0C,0x00,0x06,0x00,0x06,0x00,0x03,0x00,0x03,0x00,0x00,0x00, + + 6, // 0x5D ']' + 0x00,0x00,0x00,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x78,0x00, + + 10, // 0x5E '^' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x5F '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x80,0x00,0x00, + + 9, // 0x60 '`' + 0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x61 'a' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x03,0x00,0x3F,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x62 'b' + 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x6E,0x00,0x73,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x63 'c' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x63,0x60,0x60,0x60,0x63,0x3E,0x00,0x00,0x00, + + 9, // 0x64 'd' + 0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x03,0x00,0x03,0x00,0x3F,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x67,0x00,0x3B,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x65 'e' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x63,0x00,0x7F,0x00,0x60,0x00,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x66 'f' + 0x00,0x00,0x00,0x38,0x60,0x60,0xF8,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00,0x00, + + 9, // 0x67 'g' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x67,0x00,0x3B,0x00,0x03,0x00,0x03,0x00,0x3E,0x00, + + 9, // 0x68 'h' + 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x6E,0x00,0x73,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x69 'i' + 0x00,0x00,0x00,0x60,0x60,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00,0x00, + + 5, // 0x6A 'j' + 0x00,0x00,0x00,0x30,0x30,0x00,0x70,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0xE0, + + 8, // 0x6B 'k' + 0x00,0x00,0x00,0x60,0x60,0x60,0x66,0x6C,0x78,0x78,0x6C,0x66,0x63,0x00,0x00,0x00, + + 4, // 0x6C 'l' + 0x00,0x00,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00,0x00, + + 14, // 0x6D 'm' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6E,0x70,0x73,0x98,0x63,0x18,0x63,0x18,0x63,0x18,0x63,0x18,0x63,0x18,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x6E 'n' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6E,0x00,0x73,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x6F 'o' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x70 'p' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6E,0x00,0x73,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x7E,0x00,0x60,0x00,0x60,0x00,0x60,0x00, + + 9, // 0x71 'q' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x67,0x00,0x3B,0x00,0x03,0x00,0x03,0x00,0x03,0x00, + + 6, // 0x72 'r' + 0x00,0x00,0x00,0x00,0x00,0x00,0x6C,0x7C,0x60,0x60,0x60,0x60,0x60,0x00,0x00,0x00, + + 8, // 0x73 's' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x60,0x70,0x3C,0x0E,0x06,0x7C,0x00,0x00,0x00, + + 6, // 0x74 't' + 0x00,0x00,0x00,0x00,0x60,0x60,0xF8,0x60,0x60,0x60,0x60,0x60,0x38,0x00,0x00,0x00, + + 9, // 0x75 'u' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x67,0x00,0x3B,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x76 'v' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x36,0x00,0x36,0x00,0x1C,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 12, // 0x77 'w' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66,0x60,0x66,0x60,0x66,0x60,0x69,0x60,0x39,0xC0,0x30,0xC0,0x30,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x78 'x' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x00,0x63,0x00,0x36,0x00,0x1C,0x00,0x36,0x00,0x63,0x00,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x79 'y' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x36,0x00,0x36,0x00,0x1C,0x00,0x1C,0x00,0x0C,0x00,0x18,0x00,0x18,0x00, + + 8, // 0x7A 'z' + 0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x06,0x0C,0x18,0x30,0x60,0x7E,0x00,0x00,0x00, + + 9, // 0x7B '{' + 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x18,0x00,0x70,0x00,0x18,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x07,0x00,0x00,0x00, + + 8, // 0x7C '|' + 0x00,0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x00, + + 9, // 0x7D '}' + 0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x0C,0x00,0x07,0x00,0x0C,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x70,0x00,0x00,0x00, + + 11, // 0x7E '~' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x40,0x44,0x40,0x44,0x40,0x43,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 13, // 0x7F '' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xF0,0x20,0x10,0x20,0x10,0x20,0x10,0x20,0x10,0x20,0x10,0x20,0x10,0x20,0x10,0x20,0x10,0x3F,0xF0,0x00,0x00,0x00,0x00,0x00,0x00, + + 0 + }; + + const int8u verdana17[] = + { + 17, 4, 32, 128-32, + 0x00,0x00,0x12,0x00,0x24,0x00,0x36,0x00,0x59,0x00,0x7C,0x00,0x9F,0x00,0xC2,0x00,0xD4,0x00, + 0xE6,0x00,0xF8,0x00,0x1B,0x01,0x3E,0x01,0x50,0x01,0x62,0x01,0x74,0x01,0x86,0x01,0xA9,0x01, + 0xCC,0x01,0xEF,0x01,0x12,0x02,0x35,0x02,0x58,0x02,0x7B,0x02,0x9E,0x02,0xC1,0x02,0xE4,0x02, + 0xF6,0x02,0x08,0x03,0x2B,0x03,0x4E,0x03,0x71,0x03,0x83,0x03,0xA6,0x03,0xC9,0x03,0xEC,0x03, + 0x0F,0x04,0x32,0x04,0x55,0x04,0x67,0x04,0x8A,0x04,0xAD,0x04,0xBF,0x04,0xD1,0x04,0xF4,0x04, + 0x06,0x05,0x29,0x05,0x4C,0x05,0x6F,0x05,0x81,0x05,0xA4,0x05,0xC7,0x05,0xEA,0x05,0x0D,0x06, + 0x30,0x06,0x53,0x06,0x76,0x06,0x99,0x06,0xBC,0x06,0xDF,0x06,0xF1,0x06,0x03,0x07,0x15,0x07, + 0x38,0x07,0x5B,0x07,0x7E,0x07,0x90,0x07,0xB3,0x07,0xC5,0x07,0xE8,0x07,0xFA,0x07,0x0C,0x08, + 0x2F,0x08,0x52,0x08,0x64,0x08,0x76,0x08,0x88,0x08,0x9A,0x08,0xBD,0x08,0xE0,0x08,0x03,0x09, + 0x26,0x09,0x49,0x09,0x5B,0x09,0x6D,0x09,0x7F,0x09,0xA2,0x09,0xB4,0x09,0xD7,0x09,0xFA,0x09, + 0x0C,0x0A,0x1E,0x0A,0x41,0x0A,0x53,0x0A,0x76,0x0A,0x99,0x0A, + + 5, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x21 '!' + 0x00,0x00,0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x20,0x00,0x00,0x00, + + 6, // 0x22 '"' + 0x00,0x00,0x00,0x48,0x48,0x48,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x23 '#' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x80,0x04,0x80,0x09,0x00,0x3F,0xC0,0x09,0x00,0x12,0x00,0x7F,0x80,0x12,0x00,0x24,0x00,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x24 '$' + 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x3E,0x00,0x49,0x00,0x48,0x00,0x48,0x00,0x3E,0x00,0x09,0x00,0x09,0x00,0x49,0x00,0x3E,0x00,0x08,0x00,0x08,0x00,0x00,0x00, + + 15, // 0x25 '%' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x20,0x44,0x40,0x44,0x80,0x44,0x80,0x45,0x38,0x39,0x44,0x02,0x44,0x04,0x44,0x04,0x44,0x08,0x38,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x26 '&' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x00,0x42,0x00,0x42,0x00,0x44,0x00,0x38,0x80,0x44,0x80,0x42,0x80,0x41,0x00,0x22,0x80,0x1C,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x27 ''' + 0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x28 '(' + 0x00,0x00,0x00,0x08,0x10,0x20,0x20,0x40,0x40,0x40,0x40,0x40,0x40,0x20,0x20,0x10,0x08, + + 6, // 0x29 ')' + 0x00,0x00,0x00,0x40,0x20,0x10,0x10,0x08,0x08,0x08,0x08,0x08,0x08,0x10,0x10,0x20,0x40, + + 9, // 0x2A '*' + 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x49,0x00,0x2A,0x00,0x1C,0x00,0x2A,0x00,0x49,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x2B '+' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x7F,0xC0,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x2C ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x20,0x40,0x00, + + 7, // 0x2D '-' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x2E '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x00,0x00,0x00, + + 6, // 0x2F '/' + 0x00,0x00,0x00,0x04,0x08,0x08,0x08,0x10,0x10,0x20,0x20,0x20,0x40,0x40,0x80,0x80,0x00, + + 9, // 0x30 '0' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x22,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x22,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x31 '1' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x38,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x32 '2' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x41,0x00,0x01,0x00,0x01,0x00,0x02,0x00,0x0C,0x00,0x10,0x00,0x20,0x00,0x40,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x33 '3' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x41,0x00,0x01,0x00,0x02,0x00,0x1C,0x00,0x02,0x00,0x01,0x00,0x01,0x00,0x42,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x34 '4' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x06,0x00,0x0A,0x00,0x12,0x00,0x22,0x00,0x42,0x00,0x7F,0x80,0x02,0x00,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x35 '5' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x7C,0x00,0x02,0x00,0x01,0x00,0x01,0x00,0x42,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x36 '6' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x30,0x00,0x20,0x00,0x40,0x00,0x7C,0x00,0x42,0x00,0x41,0x00,0x41,0x00,0x22,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x37 '7' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x01,0x00,0x02,0x00,0x02,0x00,0x04,0x00,0x04,0x00,0x08,0x00,0x10,0x00,0x10,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x38 '8' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x3E,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x39 '9' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x22,0x00,0x41,0x00,0x41,0x00,0x21,0x00,0x1F,0x00,0x01,0x00,0x02,0x00,0x06,0x00,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x3A ':' + 0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x00,0x00,0x00,0x00,0x20,0x20,0x00,0x00,0x00, + + 6, // 0x3B ';' + 0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x00,0x00,0x00,0x00,0x20,0x20,0x20,0x40,0x00, + + 11, // 0x3C '<' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x06,0x00,0x18,0x00,0x60,0x00,0x60,0x00,0x18,0x00,0x06,0x00,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x3D '=' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xC0,0x00,0x00,0x00,0x00,0x3F,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x3E '>' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x0C,0x00,0x03,0x00,0x00,0xC0,0x00,0xC0,0x03,0x00,0x0C,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x3F '?' + 0x00,0x00,0x00,0x00,0x3C,0x42,0x02,0x02,0x0C,0x10,0x10,0x00,0x10,0x10,0x00,0x00,0x00, + + 14, // 0x40 '@' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xC0,0x18,0x20,0x20,0x10,0x27,0xC8,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x27,0xF0,0x20,0x00,0x18,0x00,0x07,0xC0,0x00,0x00, + + 10, // 0x41 'A' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x12,0x00,0x12,0x00,0x21,0x00,0x21,0x00,0x21,0x00,0x7F,0x80,0x40,0x80,0x80,0x40,0x80,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x42 'B' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x7E,0x00,0x41,0x00,0x40,0x80,0x40,0x80,0x41,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x43 'C' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x30,0x80,0x20,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x20,0x00,0x30,0x80,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x44 'D' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x41,0x80,0x40,0x80,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x41,0x80,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x45 'E' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x7F,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x46 'F' + 0x00,0x00,0x00,0x00,0x7F,0x40,0x40,0x40,0x7E,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00, + + 11, // 0x47 'G' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x30,0xC0,0x20,0x40,0x40,0x00,0x40,0x00,0x43,0xC0,0x40,0x40,0x20,0x40,0x30,0x40,0x0F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x48 'H' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x7F,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x49 'I' + 0x00,0x00,0x00,0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00,0x00, + + 6, // 0x4A 'J' + 0x00,0x00,0x00,0x00,0x38,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0xF0,0x00,0x00,0x00, + + 10, // 0x4B 'K' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x42,0x00,0x44,0x00,0x48,0x00,0x50,0x00,0x68,0x00,0x44,0x00,0x42,0x00,0x41,0x00,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x4C 'L' + 0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7F,0x00,0x00,0x00, + + 11, // 0x4D 'M' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xC0,0x60,0xC0,0x51,0x40,0x51,0x40,0x4A,0x40,0x4A,0x40,0x44,0x40,0x44,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x4E 'N' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x80,0x60,0x80,0x50,0x80,0x48,0x80,0x48,0x80,0x44,0x80,0x44,0x80,0x42,0x80,0x41,0x80,0x41,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x4F 'O' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x31,0x80,0x20,0x80,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x20,0x80,0x31,0x80,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x50 'P' + 0x00,0x00,0x00,0x00,0x7C,0x42,0x41,0x41,0x42,0x7C,0x40,0x40,0x40,0x40,0x00,0x00,0x00, + + 11, // 0x51 'Q' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x31,0x80,0x20,0x80,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x20,0x80,0x31,0x80,0x0E,0x00,0x02,0x00,0x02,0x00,0x01,0xC0, + + 10, // 0x52 'R' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x42,0x00,0x42,0x00,0x42,0x00,0x44,0x00,0x78,0x00,0x44,0x00,0x42,0x00,0x41,0x00,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x53 'S' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x20,0x80,0x40,0x00,0x40,0x00,0x38,0x00,0x07,0x00,0x00,0x80,0x40,0x80,0x21,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x54 'T' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x80,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x55 'U' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x21,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x56 'V' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x80,0x40,0x40,0x80,0x40,0x80,0x21,0x00,0x21,0x00,0x21,0x00,0x12,0x00,0x12,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 15, // 0x57 'W' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x04,0x41,0x04,0x22,0x88,0x22,0x88,0x22,0x88,0x14,0x50,0x14,0x50,0x14,0x50,0x08,0x20,0x08,0x20,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x58 'X' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x80,0x21,0x00,0x12,0x00,0x12,0x00,0x0C,0x00,0x0C,0x00,0x12,0x00,0x12,0x00,0x21,0x00,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x59 'Y' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x41,0x00,0x22,0x00,0x22,0x00,0x14,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x5A 'Z' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x00,0x80,0x01,0x00,0x02,0x00,0x04,0x00,0x08,0x00,0x10,0x00,0x20,0x00,0x40,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x5B '[' + 0x00,0x00,0x00,0x3C,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3C, + + 6, // 0x5C '\' + 0x00,0x00,0x00,0x80,0x40,0x40,0x40,0x20,0x20,0x10,0x10,0x10,0x08,0x08,0x08,0x04,0x00, + + 6, // 0x5D ']' + 0x00,0x00,0x00,0x78,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x78, + + 11, // 0x5E '^' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x0A,0x00,0x11,0x00,0x20,0x80,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x5F '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x80,0x00,0x00, + + 9, // 0x60 '`' + 0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x61 'a' + 0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x22,0x02,0x3E,0x42,0x42,0x46,0x3A,0x00,0x00,0x00, + + 9, // 0x62 'b' + 0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x5C,0x00,0x62,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x42,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x63 'c' + 0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x22,0x40,0x40,0x40,0x40,0x22,0x1C,0x00,0x00,0x00, + + 9, // 0x64 'd' + 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x1F,0x00,0x21,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x23,0x00,0x1D,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x65 'e' + 0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x24,0x42,0x7E,0x40,0x40,0x22,0x1C,0x00,0x00,0x00, + + 6, // 0x66 'f' + 0x00,0x00,0x00,0x1C,0x20,0x20,0x7C,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00,0x00, + + 9, // 0x67 'g' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x21,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x23,0x00,0x1D,0x00,0x01,0x00,0x22,0x00,0x1C,0x00, + + 9, // 0x68 'h' + 0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x5E,0x00,0x61,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 3, // 0x69 'i' + 0x00,0x00,0x00,0x00,0x40,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00, + + 5, // 0x6A 'j' + 0x00,0x00,0x00,0x00,0x10,0x00,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0xE0, + + 8, // 0x6B 'k' + 0x00,0x00,0x00,0x40,0x40,0x40,0x42,0x44,0x48,0x50,0x70,0x48,0x44,0x42,0x00,0x00,0x00, + + 3, // 0x6C 'l' + 0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00, + + 13, // 0x6D 'm' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5C,0xE0,0x63,0x10,0x42,0x10,0x42,0x10,0x42,0x10,0x42,0x10,0x42,0x10,0x42,0x10,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x6E 'n' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5E,0x00,0x61,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x6F 'o' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x22,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x22,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x70 'p' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5C,0x00,0x62,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x42,0x00,0x7C,0x00,0x40,0x00,0x40,0x00,0x40,0x00, + + 9, // 0x71 'q' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x21,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x23,0x00,0x1D,0x00,0x01,0x00,0x01,0x00,0x01,0x00, + + 6, // 0x72 'r' + 0x00,0x00,0x00,0x00,0x00,0x00,0x5C,0x60,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00, + + 8, // 0x73 's' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x42,0x40,0x30,0x0C,0x02,0x42,0x3C,0x00,0x00,0x00, + + 6, // 0x74 't' + 0x00,0x00,0x00,0x00,0x20,0x20,0x7C,0x20,0x20,0x20,0x20,0x20,0x20,0x1C,0x00,0x00,0x00, + + 9, // 0x75 'u' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x43,0x00,0x3D,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x76 'v' + 0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x42,0x24,0x24,0x24,0x18,0x18,0x18,0x00,0x00,0x00, + + 11, // 0x77 'w' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x40,0x44,0x40,0x2A,0x80,0x2A,0x80,0x2A,0x80,0x2A,0x80,0x11,0x00,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x78 'x' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x22,0x00,0x14,0x00,0x08,0x00,0x08,0x00,0x14,0x00,0x22,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x79 'y' + 0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x42,0x24,0x24,0x24,0x18,0x18,0x18,0x10,0x10,0x20, + + 8, // 0x7A 'z' + 0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x02,0x04,0x08,0x10,0x20,0x40,0x7E,0x00,0x00,0x00, + + 9, // 0x7B '{' + 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x10,0x00,0x60,0x00,0x10,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x07,0x00, + + 6, // 0x7C '|' + 0x00,0x00,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + + 9, // 0x7D '}' + 0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x04,0x00,0x03,0x00,0x04,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x70,0x00, + + 11, // 0x7E '~' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x40,0x44,0x40,0x44,0x40,0x43,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 14, // 0x7F '' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xF8,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x3F,0xF8,0x00,0x00,0x00,0x00,0x00,0x00, + + 0 + }; + + const int8u verdana17_bold[] = + { + 17, 4, 32, 128-32, + 0x00,0x00,0x12,0x00,0x24,0x00,0x36,0x00,0x59,0x00,0x7C,0x00,0xB0,0x00,0xD3,0x00,0xE5,0x00, + 0xF7,0x00,0x09,0x01,0x2C,0x01,0x4F,0x01,0x61,0x01,0x73,0x01,0x85,0x01,0xA8,0x01,0xCB,0x01, + 0xEE,0x01,0x11,0x02,0x34,0x02,0x57,0x02,0x7A,0x02,0x9D,0x02,0xC0,0x02,0xE3,0x02,0x06,0x03, + 0x18,0x03,0x2A,0x03,0x4D,0x03,0x70,0x03,0x93,0x03,0xB6,0x03,0xD9,0x03,0xFC,0x03,0x1F,0x04, + 0x42,0x04,0x65,0x04,0x88,0x04,0xAB,0x04,0xCE,0x04,0xF1,0x04,0x03,0x05,0x15,0x05,0x38,0x05, + 0x5B,0x05,0x7E,0x05,0xA1,0x05,0xC4,0x05,0xE7,0x05,0x0A,0x06,0x2D,0x06,0x50,0x06,0x73,0x06, + 0x96,0x06,0xB9,0x06,0xDC,0x06,0xFF,0x06,0x22,0x07,0x45,0x07,0x57,0x07,0x7A,0x07,0x8C,0x07, + 0xAF,0x07,0xD2,0x07,0xF5,0x07,0x18,0x08,0x3B,0x08,0x4D,0x08,0x70,0x08,0x93,0x08,0xA5,0x08, + 0xC8,0x08,0xEB,0x08,0xFD,0x08,0x0F,0x09,0x32,0x09,0x44,0x09,0x67,0x09,0x8A,0x09,0xAD,0x09, + 0xD0,0x09,0xF3,0x09,0x05,0x0A,0x17,0x0A,0x29,0x0A,0x4C,0x0A,0x6F,0x0A,0x92,0x0A,0xB5,0x0A, + 0xD8,0x0A,0xEA,0x0A,0x0D,0x0B,0x1F,0x0B,0x42,0x0B,0x65,0x0B, + + 5, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x21 '!' + 0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,0x30,0x30,0x00,0x00,0x00, + + 8, // 0x22 '"' + 0x00,0x00,0x00,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 12, // 0x23 '#' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x40,0x04,0x40,0x3F,0xE0,0x3F,0xE0,0x08,0x80,0x11,0x00,0x7F,0xC0,0x7F,0xC0,0x22,0x00,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x24 '$' + 0x00,0x00,0x00,0x00,0x04,0x00,0x04,0x00,0x1F,0x00,0x34,0x80,0x64,0x00,0x74,0x00,0x3C,0x00,0x0F,0x00,0x0B,0x80,0x09,0x80,0x4B,0x00,0x3E,0x00,0x08,0x00,0x08,0x00,0x00,0x00, + + 18, // 0x25 '%' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x08,0x00,0x66,0x10,0x00,0x66,0x20,0x00,0x66,0x2F,0x00,0x66,0x59,0x80,0x66,0x99,0x80,0x3D,0x19,0x80,0x01,0x19,0x80,0x02,0x19,0x80,0x04,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 12, // 0x26 '&' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x33,0x00,0x36,0x00,0x1C,0x60,0x36,0x60,0x63,0x60,0x61,0xC0,0x31,0xC0,0x1F,0x60,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x27 ''' + 0x00,0x00,0x00,0x60,0x60,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x28 '(' + 0x00,0x00,0x00,0x0C,0x18,0x30,0x30,0x60,0x60,0x60,0x60,0x60,0x60,0x30,0x30,0x18,0x0C, + + 8, // 0x29 ')' + 0x00,0x00,0x00,0x30,0x18,0x0C,0x0C,0x06,0x06,0x06,0x06,0x06,0x06,0x0C,0x0C,0x18,0x30, + + 10, // 0x2A '*' + 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x49,0x00,0x2A,0x00,0x1C,0x00,0x2A,0x00,0x49,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 12, // 0x2B '+' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x7F,0xC0,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x2C ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x60,0x60,0xC0,0xC0,0x00, + + 7, // 0x2D '-' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x2E '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x00,0x00,0x00, + + 10, // 0x2F '/' + 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x01,0x80,0x03,0x00,0x03,0x00,0x06,0x00,0x06,0x00,0x0C,0x00,0x18,0x00,0x18,0x00,0x30,0x00,0x30,0x00,0x60,0x00,0x60,0x00,0x00,0x00, + + 10, // 0x30 '0' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x31 '1' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x3C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x32 '2' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x61,0x80,0x61,0x80,0x01,0x80,0x03,0x00,0x06,0x00,0x0C,0x00,0x18,0x00,0x30,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x33 '3' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x61,0x80,0x61,0x80,0x01,0x80,0x0F,0x00,0x03,0x00,0x01,0x80,0x61,0x80,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x34 '4' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x07,0x00,0x0B,0x00,0x13,0x00,0x23,0x00,0x43,0x00,0x7F,0xC0,0x03,0x00,0x03,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x35 '5' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x80,0x30,0x00,0x30,0x00,0x3E,0x00,0x03,0x00,0x01,0x80,0x01,0x80,0x61,0x80,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x36 '6' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x38,0x00,0x30,0x00,0x6E,0x00,0x73,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x37 '7' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x01,0x80,0x03,0x00,0x03,0x00,0x06,0x00,0x06,0x00,0x0C,0x00,0x0C,0x00,0x18,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x38 '8' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x3F,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x39 '9' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x80,0x1D,0x80,0x03,0x00,0x07,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x3A ':' + 0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x00,0x00,0x30,0x30,0x30,0x00,0x00,0x00, + + 6, // 0x3B ';' + 0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x00,0x00,0x38,0x30,0x30,0x60,0x60,0x00, + + 12, // 0x3C '<' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x03,0x00,0x0C,0x00,0x30,0x00,0x40,0x00,0x30,0x00,0x0C,0x00,0x03,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, + + 12, // 0x3D '=' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 12, // 0x3E '>' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x18,0x00,0x06,0x00,0x01,0x80,0x00,0x40,0x01,0x80,0x06,0x00,0x18,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x3F '?' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x03,0x00,0x06,0x00,0x0C,0x00,0x18,0x00,0x18,0x00,0x00,0x00,0x18,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 14, // 0x40 '@' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0xC0,0x18,0x20,0x20,0x10,0x27,0xC8,0x4C,0xC8,0x4C,0xC8,0x4C,0xC8,0x4C,0xC8,0x27,0xF0,0x20,0x00,0x18,0x00,0x07,0xC0,0x00,0x00, + + 11, // 0x41 'A' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x1B,0x00,0x1B,0x00,0x31,0x80,0x3F,0x80,0x31,0x80,0x60,0xC0,0x60,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x42 'B' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x7F,0x00,0x61,0x80,0x60,0xC0,0x60,0xC0,0x61,0x80,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x43 'C' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x80,0x30,0xC0,0x30,0xC0,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x30,0xC0,0x30,0xC0,0x0F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x44 'D' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x61,0x80,0x61,0x80,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x61,0x80,0x61,0x80,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x45 'E' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x60,0x00,0x60,0x00,0x60,0x00,0x7F,0x80,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x46 'F' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x7F,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x47 'G' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x80,0x30,0xC0,0x30,0xC0,0x60,0x00,0x60,0x00,0x63,0xC0,0x60,0xC0,0x30,0xC0,0x30,0xC0,0x0F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x48 'H' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x7F,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x49 'I' + 0x00,0x00,0x00,0x00,0x7E,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x00,0x00,0x00, + + 8, // 0x4A 'J' + 0x00,0x00,0x00,0x00,0x3E,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0C,0xF8,0x00,0x00,0x00, + + 11, // 0x4B 'K' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xC0,0x61,0x80,0x63,0x00,0x66,0x00,0x6C,0x00,0x7C,0x00,0x76,0x00,0x63,0x00,0x61,0x80,0x60,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x4C 'L' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 13, // 0x4D 'M' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x70,0x70,0x70,0x70,0xF0,0x58,0xB0,0x59,0xB0,0x4D,0x30,0x4F,0x30,0x46,0x30,0x46,0x30,0x40,0x30,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x4E 'N' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x40,0x70,0x40,0x58,0x40,0x4C,0x40,0x4C,0x40,0x46,0x40,0x43,0x40,0x43,0x40,0x41,0xC0,0x40,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, + + 12, // 0x4F 'O' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x30,0xC0,0x30,0xC0,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x30,0xC0,0x30,0xC0,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x50 'P' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x63,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x63,0x00,0x7E,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 12, // 0x51 'Q' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x30,0xC0,0x30,0xC0,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x30,0xC0,0x30,0xC0,0x0F,0x80,0x03,0x00,0x03,0x00,0x01,0xE0, + + 11, // 0x52 'R' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x61,0x80,0x60,0xC0,0x60,0xC0,0x61,0x80,0x7F,0x00,0x63,0x00,0x61,0x80,0x60,0xC0,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x53 'S' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x31,0x80,0x61,0x80,0x60,0x00,0x3E,0x00,0x1F,0x00,0x01,0x80,0x61,0x80,0x63,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x54 'T' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x55 'U' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x31,0x80,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x56 'V' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x31,0x80,0x31,0x80,0x31,0x80,0x1B,0x00,0x1B,0x00,0x0E,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 16, // 0x57 'W' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x86,0x61,0x86,0x63,0xC6,0x32,0x4C,0x36,0x6C,0x36,0x6C,0x34,0x2C,0x1C,0x38,0x18,0x18,0x18,0x18,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x58 'X' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xC0,0x31,0x80,0x31,0x80,0x1B,0x00,0x0E,0x00,0x0E,0x00,0x1B,0x00,0x31,0x80,0x31,0x80,0x60,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x59 'Y' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0x61,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x5A 'Z' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x01,0x80,0x03,0x00,0x06,0x00,0x0C,0x00,0x0C,0x00,0x18,0x00,0x30,0x00,0x60,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x5B '[' + 0x00,0x00,0x00,0x3E,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3E, + + 10, // 0x5C '\' + 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x30,0x00,0x30,0x00,0x18,0x00,0x18,0x00,0x0C,0x00,0x06,0x00,0x06,0x00,0x03,0x00,0x03,0x00,0x01,0x80,0x01,0x80,0x00,0x00, + + 8, // 0x5D ']' + 0x00,0x00,0x00,0x7C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x7C, + + 12, // 0x5E '^' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x0E,0x00,0x1B,0x00,0x31,0x80,0x60,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x5F '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xC0,0x00,0x00, + + 10, // 0x60 '`' + 0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x61 'a' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x03,0x00,0x03,0x00,0x3F,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x62 'b' + 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x6E,0x00,0x73,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x63,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x63 'c' + 0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x33,0x60,0x60,0x60,0x60,0x33,0x1E,0x00,0x00,0x00, + + 10, // 0x64 'd' + 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x01,0x80,0x01,0x80,0x1F,0x80,0x31,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x80,0x1D,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x65 'e' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x63,0x00,0x7F,0x00,0x60,0x00,0x60,0x00,0x33,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x66 'f' + 0x00,0x00,0x00,0x1C,0x30,0x30,0x7C,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,0x00,0x00, + + 10, // 0x67 'g' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x80,0x31,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x80,0x1D,0x80,0x01,0x80,0x03,0x00,0x3E,0x00, + + 10, // 0x68 'h' + 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x6F,0x00,0x71,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x69 'i' + 0x00,0x00,0x00,0x60,0x60,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00,0x00, + + 6, // 0x6A 'j' + 0x00,0x00,0x00,0x18,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xF0, + + 9, // 0x6B 'k' + 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x63,0x00,0x66,0x00,0x6C,0x00,0x78,0x00,0x7C,0x00,0x66,0x00,0x63,0x00,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x6C 'l' + 0x00,0x00,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00,0x00, + + 14, // 0x6D 'm' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6E,0x70,0x73,0x98,0x63,0x18,0x63,0x18,0x63,0x18,0x63,0x18,0x63,0x18,0x63,0x18,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x6E 'n' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6F,0x00,0x71,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x6F 'o' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x70 'p' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6E,0x00,0x73,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x63,0x00,0x7E,0x00,0x60,0x00,0x60,0x00,0x60,0x00, + + 10, // 0x71 'q' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x80,0x31,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x80,0x1D,0x80,0x01,0x80,0x01,0x80,0x01,0x80, + + 7, // 0x72 'r' + 0x00,0x00,0x00,0x00,0x00,0x00,0x6E,0x7E,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00,0x00, + + 8, // 0x73 's' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x62,0x60,0x7C,0x3E,0x06,0x46,0x3C,0x00,0x00,0x00, + + 6, // 0x74 't' + 0x00,0x00,0x00,0x00,0x60,0x60,0xFC,0x60,0x60,0x60,0x60,0x60,0x60,0x3C,0x00,0x00,0x00, + + 10, // 0x75 'u' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x63,0x80,0x3D,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x76 'v' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x36,0x00,0x36,0x00,0x36,0x00,0x1C,0x00,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 14, // 0x77 'w' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x18,0x63,0x18,0x33,0x30,0x37,0xB0,0x34,0xB0,0x1C,0xE0,0x1C,0xE0,0x0C,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x78 'x' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x00,0x63,0x00,0x36,0x00,0x1C,0x00,0x1C,0x00,0x36,0x00,0x63,0x00,0x63,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x79 'y' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x00,0x63,0x00,0x63,0x00,0x36,0x00,0x36,0x00,0x36,0x00,0x1C,0x00,0x1C,0x00,0x0C,0x00,0x18,0x00,0x18,0x00, + + 8, // 0x7A 'z' + 0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x06,0x0C,0x18,0x18,0x30,0x60,0x7E,0x00,0x00,0x00, + + 10, // 0x7B '{' + 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x80,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x18,0x00,0x70,0x00,0x18,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x07,0x80, + + 8, // 0x7C '|' + 0x00,0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + + 10, // 0x7D '}' + 0x00,0x00,0x00,0x00,0x00,0x00,0x78,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x06,0x00,0x03,0x80,0x06,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x78,0x00, + + 12, // 0x7E '~' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x20,0x24,0x20,0x46,0x20,0x42,0x40,0x41,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 14, // 0x7F '' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xF8,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x3F,0xF8,0x00,0x00,0x00,0x00,0x00,0x00, + + 0 + }; + + const int8u verdana18[] = + { + 18, 4, 32, 128-32, + 0x00,0x00,0x13,0x00,0x26,0x00,0x39,0x00,0x5E,0x00,0x83,0x00,0xA8,0x00,0xCD,0x00,0xE0,0x00, + 0xF3,0x00,0x06,0x01,0x2B,0x01,0x50,0x01,0x63,0x01,0x76,0x01,0x89,0x01,0x9C,0x01,0xC1,0x01, + 0xE6,0x01,0x0B,0x02,0x30,0x02,0x55,0x02,0x7A,0x02,0x9F,0x02,0xC4,0x02,0xE9,0x02,0x0E,0x03, + 0x21,0x03,0x34,0x03,0x59,0x03,0x7E,0x03,0xA3,0x03,0xB6,0x03,0xDB,0x03,0x00,0x04,0x25,0x04, + 0x4A,0x04,0x6F,0x04,0x94,0x04,0xB9,0x04,0xDE,0x04,0x03,0x05,0x16,0x05,0x29,0x05,0x4E,0x05, + 0x61,0x05,0x86,0x05,0xAB,0x05,0xD0,0x05,0xF5,0x05,0x1A,0x06,0x3F,0x06,0x64,0x06,0x89,0x06, + 0xAE,0x06,0xD3,0x06,0xF8,0x06,0x1D,0x07,0x42,0x07,0x67,0x07,0x7A,0x07,0x8D,0x07,0xA0,0x07, + 0xC5,0x07,0xEA,0x07,0x0F,0x08,0x34,0x08,0x59,0x08,0x6C,0x08,0x91,0x08,0xB6,0x08,0xC9,0x08, + 0xEE,0x08,0x13,0x09,0x26,0x09,0x39,0x09,0x5E,0x09,0x71,0x09,0x96,0x09,0xBB,0x09,0xE0,0x09, + 0x05,0x0A,0x2A,0x0A,0x3D,0x0A,0x50,0x0A,0x63,0x0A,0x88,0x0A,0xAD,0x0A,0xD2,0x0A,0xF7,0x0A, + 0x1C,0x0B,0x41,0x0B,0x66,0x0B,0x79,0x0B,0x9E,0x0B,0xC3,0x0B, + + 5, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x21 '!' + 0x00,0x00,0x00,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x20,0x20,0x00,0x00,0x00, + + 7, // 0x22 '"' + 0x00,0x00,0x00,0x48,0x48,0x48,0x48,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 12, // 0x23 '#' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x80,0x04,0x80,0x09,0x00,0x3F,0xC0,0x09,0x00,0x11,0x00,0x12,0x00,0x7F,0x80,0x12,0x00,0x24,0x00,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x24 '$' + 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x08,0x00,0x3E,0x00,0x49,0x00,0x48,0x00,0x48,0x00,0x38,0x00,0x0E,0x00,0x09,0x00,0x09,0x00,0x49,0x00,0x3E,0x00,0x08,0x00,0x08,0x00,0x08,0x00, + + 16, // 0x25 '%' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x20,0x44,0x40,0x44,0x40,0x44,0x80,0x44,0x80,0x38,0x9C,0x01,0x22,0x01,0x22,0x02,0x22,0x02,0x22,0x04,0x1C,0x00,0x00,0x00,0x00,0x00,0x00, + + 12, // 0x26 '&' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x21,0x00,0x21,0x00,0x21,0x00,0x1E,0x40,0x24,0x40,0x42,0x40,0x41,0x40,0x40,0x80,0x21,0x40,0x1E,0x20,0x00,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x27 ''' + 0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x28 '(' + 0x00,0x00,0x00,0x08,0x10,0x20,0x20,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x20,0x20,0x10,0x08, + + 7, // 0x29 ')' + 0x00,0x00,0x00,0x20,0x10,0x08,0x08,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x08,0x08,0x10,0x20, + + 10, // 0x2A '*' + 0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x49,0x00,0x2A,0x00,0x1C,0x00,0x2A,0x00,0x49,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 12, // 0x2B '+' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x3F,0xE0,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x2C ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x20,0x40,0x40, + + 7, // 0x2D '-' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x2E '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x00,0x00,0x00, + + 7, // 0x2F '/' + 0x00,0x00,0x00,0x02,0x04,0x04,0x04,0x08,0x08,0x10,0x10,0x20,0x20,0x40,0x40,0x40,0x80,0x00, + + 10, // 0x30 '0' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x21,0x00,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x21,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x31 '1' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x04,0x00,0x1C,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x32 '2' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x41,0x00,0x00,0x80,0x00,0x80,0x00,0x80,0x01,0x00,0x02,0x00,0x0C,0x00,0x30,0x00,0x40,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x33 '3' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x40,0x80,0x00,0x80,0x01,0x00,0x0E,0x00,0x01,0x00,0x00,0x80,0x00,0x80,0x00,0x80,0x41,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x34 '4' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x03,0x00,0x05,0x00,0x09,0x00,0x11,0x00,0x21,0x00,0x41,0x00,0x7F,0xC0,0x01,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x35 '5' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x80,0x20,0x00,0x20,0x00,0x20,0x00,0x3E,0x00,0x01,0x00,0x00,0x80,0x00,0x80,0x00,0x80,0x41,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x36 '6' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x10,0x00,0x20,0x00,0x40,0x00,0x5E,0x00,0x61,0x00,0x40,0x80,0x40,0x80,0x40,0x80,0x21,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x37 '7' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x01,0x00,0x02,0x00,0x02,0x00,0x04,0x00,0x04,0x00,0x08,0x00,0x08,0x00,0x10,0x00,0x10,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x38 '8' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x21,0x00,0x40,0x80,0x40,0x80,0x21,0x00,0x1E,0x00,0x21,0x00,0x40,0x80,0x40,0x80,0x21,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x39 '9' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x21,0x00,0x40,0x80,0x40,0x80,0x40,0x80,0x20,0x80,0x1F,0x80,0x00,0x80,0x01,0x00,0x02,0x00,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x3A ':' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x00,0x00,0x00,0x00,0x10,0x10,0x00,0x00,0x00, + + 7, // 0x3B ';' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x10,0x00,0x00,0x00,0x00,0x10,0x10,0x10,0x20,0x20, + + 12, // 0x3C '<' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0x03,0x00,0x0C,0x00,0x30,0x00,0x30,0x00,0x0C,0x00,0x03,0x00,0x00,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 12, // 0x3D '=' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xE0,0x00,0x00,0x00,0x00,0x3F,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 12, // 0x3E '>' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x00,0x0C,0x00,0x03,0x00,0x00,0xC0,0x00,0xC0,0x03,0x00,0x0C,0x00,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x3F '?' + 0x00,0x00,0x00,0x00,0x3C,0x42,0x02,0x02,0x04,0x08,0x10,0x10,0x00,0x10,0x10,0x00,0x00,0x00, + + 15, // 0x40 '@' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x80,0x18,0x60,0x20,0x10,0x23,0xD0,0x44,0x48,0x48,0x48,0x48,0x48,0x48,0x48,0x44,0x48,0x23,0xF0,0x20,0x00,0x18,0x00,0x07,0xC0,0x00,0x00, + + 10, // 0x41 'A' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x21,0x00,0x21,0x00,0x40,0x80,0x7F,0x80,0x40,0x80,0x80,0x40,0x80,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x42 'B' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x7E,0x00,0x41,0x00,0x40,0x80,0x40,0x80,0x40,0x80,0x41,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x43 'C' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x30,0xC0,0x20,0x40,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x20,0x40,0x30,0xC0,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x44 'D' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x41,0x80,0x40,0x80,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x80,0x41,0x80,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x45 'E' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x7F,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x46 'F' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x40,0x00,0x40,0x00,0x40,0x00,0x7F,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 12, // 0x47 'G' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x80,0x30,0x60,0x20,0x20,0x40,0x00,0x40,0x00,0x41,0xE0,0x40,0x20,0x40,0x20,0x20,0x20,0x30,0x20,0x0F,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x48 'H' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7F,0xC0,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x49 'I' + 0x00,0x00,0x00,0x00,0x70,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x70,0x00,0x00,0x00, + + 7, // 0x4A 'J' + 0x00,0x00,0x00,0x00,0x3C,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x04,0x08,0xF0,0x00,0x00,0x00, + + 10, // 0x4B 'K' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x80,0x41,0x00,0x42,0x00,0x44,0x00,0x48,0x00,0x50,0x00,0x68,0x00,0x44,0x00,0x42,0x00,0x41,0x00,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x4C 'L' + 0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x7F,0x00,0x00,0x00, + + 13, // 0x4D 'M' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x30,0x50,0x50,0x50,0x50,0x48,0x90,0x48,0x90,0x45,0x10,0x45,0x10,0x42,0x10,0x42,0x10,0x40,0x10,0x40,0x10,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x4E 'N' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x60,0x40,0x50,0x40,0x48,0x40,0x48,0x40,0x44,0x40,0x42,0x40,0x42,0x40,0x41,0x40,0x40,0xC0,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + + 12, // 0x4F 'O' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x30,0xC0,0x20,0x40,0x40,0x20,0x40,0x20,0x40,0x20,0x40,0x20,0x40,0x20,0x20,0x40,0x30,0xC0,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x50 'P' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7E,0x00,0x41,0x00,0x40,0x80,0x40,0x80,0x40,0x80,0x41,0x00,0x7E,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 12, // 0x51 'Q' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x00,0x30,0xC0,0x20,0x40,0x40,0x20,0x40,0x20,0x40,0x20,0x40,0x20,0x40,0x20,0x20,0x40,0x30,0xC0,0x0F,0x00,0x01,0x00,0x01,0x00,0x00,0xE0, + + 10, // 0x52 'R' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x42,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x42,0x00,0x7C,0x00,0x42,0x00,0x41,0x00,0x40,0x80,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x53 'S' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x20,0x80,0x40,0x00,0x40,0x00,0x20,0x00,0x1E,0x00,0x01,0x00,0x00,0x80,0x40,0x80,0x21,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x54 'T' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0x80,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x55 'U' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x20,0x80,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x56 'V' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x40,0x80,0x40,0x40,0x80,0x40,0x80,0x40,0x80,0x21,0x00,0x21,0x00,0x12,0x00,0x12,0x00,0x12,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 15, // 0x57 'W' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x04,0x41,0x04,0x22,0x88,0x22,0x88,0x22,0x88,0x12,0x90,0x14,0x50,0x14,0x50,0x14,0x50,0x08,0x20,0x08,0x20,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x58 'X' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x80,0x21,0x00,0x21,0x00,0x12,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x12,0x00,0x21,0x00,0x21,0x00,0x40,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x59 'Y' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x80,0x41,0x00,0x22,0x00,0x22,0x00,0x14,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x5A 'Z' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x00,0x80,0x01,0x00,0x02,0x00,0x04,0x00,0x08,0x00,0x08,0x00,0x10,0x00,0x20,0x00,0x40,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x5B '[' + 0x00,0x00,0x00,0x3C,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x3C, + + 7, // 0x5C '\' + 0x00,0x00,0x00,0x80,0x40,0x40,0x40,0x20,0x20,0x10,0x10,0x08,0x08,0x04,0x04,0x04,0x02,0x00, + + 7, // 0x5D ']' + 0x00,0x00,0x00,0x78,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x78, + + 12, // 0x5E '^' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x09,0x00,0x10,0x80,0x20,0x40,0x40,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x5F '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xC0,0x00,0x00, + + 10, // 0x60 '`' + 0x00,0x00,0x00,0x00,0x00,0x00,0x10,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x61 'a' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x21,0x00,0x01,0x00,0x3F,0x00,0x41,0x00,0x41,0x00,0x43,0x00,0x3D,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x62 'b' + 0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x5C,0x00,0x62,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x42,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x63 'c' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x21,0x40,0x40,0x40,0x40,0x21,0x1E,0x00,0x00,0x00, + + 9, // 0x64 'd' + 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x1F,0x00,0x21,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x23,0x00,0x1D,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x65 'e' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x00,0x22,0x00,0x41,0x00,0x7F,0x00,0x40,0x00,0x40,0x00,0x21,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x66 'f' + 0x00,0x00,0x00,0x1C,0x20,0x20,0x20,0x7C,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00,0x00, + + 9, // 0x67 'g' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x21,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x23,0x00,0x1D,0x00,0x01,0x00,0x22,0x00,0x1C,0x00, + + 9, // 0x68 'h' + 0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x5E,0x00,0x61,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 3, // 0x69 'i' + 0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00, + + 5, // 0x6A 'j' + 0x00,0x00,0x00,0x00,0x10,0x00,0x00,0x70,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0xE0, + + 9, // 0x6B 'k' + 0x00,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x40,0x00,0x42,0x00,0x44,0x00,0x48,0x00,0x50,0x00,0x68,0x00,0x44,0x00,0x42,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 3, // 0x6C 'l' + 0x00,0x00,0x00,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00, + + 15, // 0x6D 'm' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2E,0x70,0x31,0x88,0x21,0x08,0x21,0x08,0x21,0x08,0x21,0x08,0x21,0x08,0x21,0x08,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x6E 'n' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5E,0x00,0x61,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x6F 'o' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x21,0x00,0x40,0x80,0x40,0x80,0x40,0x80,0x40,0x80,0x21,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x70 'p' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5C,0x00,0x62,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x42,0x00,0x7C,0x00,0x40,0x00,0x40,0x00,0x40,0x00, + + 9, // 0x71 'q' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x21,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x23,0x00,0x1D,0x00,0x01,0x00,0x01,0x00,0x01,0x00, + + 6, // 0x72 'r' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x5C,0x60,0x40,0x40,0x40,0x40,0x40,0x40,0x00,0x00,0x00, + + 8, // 0x73 's' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x42,0x40,0x30,0x0C,0x02,0x42,0x3C,0x00,0x00,0x00, + + 6, // 0x74 't' + 0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x7C,0x20,0x20,0x20,0x20,0x20,0x20,0x1C,0x00,0x00,0x00, + + 9, // 0x75 'u' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x41,0x00,0x43,0x00,0x3D,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x76 'v' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x41,0x00,0x22,0x00,0x22,0x00,0x22,0x00,0x14,0x00,0x14,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 13, // 0x77 'w' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x42,0x10,0x42,0x10,0x25,0x20,0x25,0x20,0x28,0xA0,0x28,0xA0,0x10,0x40,0x10,0x40,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x78 'x' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x22,0x00,0x14,0x00,0x08,0x00,0x08,0x00,0x14,0x00,0x22,0x00,0x41,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x79 'y' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x41,0x00,0x41,0x00,0x22,0x00,0x22,0x00,0x22,0x00,0x14,0x00,0x14,0x00,0x08,0x00,0x08,0x00,0x10,0x00,0x10,0x00, + + 9, // 0x7A 'z' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x02,0x00,0x04,0x00,0x08,0x00,0x10,0x00,0x20,0x00,0x40,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x7B '{' + 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x10,0x00,0x60,0x00,0x10,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x08,0x00,0x07,0x00, + + 7, // 0x7C '|' + 0x00,0x00,0x00,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10,0x10, + + 10, // 0x7D '}' + 0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x02,0x00,0x01,0x80,0x02,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x04,0x00,0x38,0x00, + + 12, // 0x7E '~' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x20,0x24,0x20,0x42,0x40,0x41,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 15, // 0x7F '' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xF8,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x3F,0xF8,0x00,0x00,0x00,0x00,0x00,0x00, + + 0 + }; + + const int8u verdana18_bold[] = + { + 18, 4, 32, 128-32, + 0x00,0x00,0x13,0x00,0x26,0x00,0x4B,0x00,0x70,0x00,0x95,0x00,0xCC,0x00,0xF1,0x00,0x04,0x01, + 0x17,0x01,0x2A,0x01,0x4F,0x01,0x74,0x01,0x87,0x01,0x9A,0x01,0xAD,0x01,0xD2,0x01,0xF7,0x01, + 0x1C,0x02,0x41,0x02,0x66,0x02,0x8B,0x02,0xB0,0x02,0xD5,0x02,0xFA,0x02,0x1F,0x03,0x44,0x03, + 0x57,0x03,0x6A,0x03,0x8F,0x03,0xB4,0x03,0xD9,0x03,0xFE,0x03,0x23,0x04,0x48,0x04,0x6D,0x04, + 0x92,0x04,0xB7,0x04,0xDC,0x04,0x01,0x05,0x26,0x05,0x4B,0x05,0x5E,0x05,0x71,0x05,0x96,0x05, + 0xBB,0x05,0xE0,0x05,0x05,0x06,0x2A,0x06,0x4F,0x06,0x74,0x06,0x99,0x06,0xBE,0x06,0xE3,0x06, + 0x08,0x07,0x2D,0x07,0x52,0x07,0x77,0x07,0x9C,0x07,0xC1,0x07,0xD4,0x07,0xF9,0x07,0x0C,0x08, + 0x31,0x08,0x56,0x08,0x7B,0x08,0xA0,0x08,0xC5,0x08,0xD8,0x08,0xFD,0x08,0x22,0x09,0x35,0x09, + 0x5A,0x09,0x7F,0x09,0x92,0x09,0xA5,0x09,0xCA,0x09,0xDD,0x09,0x02,0x0A,0x27,0x0A,0x4C,0x0A, + 0x71,0x0A,0x96,0x0A,0xA9,0x0A,0xCE,0x0A,0xE1,0x0A,0x06,0x0B,0x2B,0x0B,0x50,0x0B,0x75,0x0B, + 0x9A,0x0B,0xBF,0x0B,0xE4,0x0B,0xF7,0x0B,0x1C,0x0C,0x41,0x0C, + + 5, // 0x20 ' ' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x21 '!' + 0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,0x30,0x30,0x00,0x00,0x00, + + 9, // 0x22 '"' + 0x00,0x00,0x00,0x00,0x00,0x00,0x36,0x00,0x36,0x00,0x36,0x00,0x36,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 13, // 0x23 '#' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x20,0x04,0x20,0x08,0x40,0x3F,0xF0,0x3F,0xF0,0x08,0x40,0x10,0x80,0x7F,0xE0,0x7F,0xE0,0x21,0x00,0x21,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x24 '$' + 0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x04,0x00,0x1F,0x80,0x34,0xC0,0x64,0xC0,0x64,0x00,0x3C,0x00,0x07,0x80,0x04,0xC0,0x64,0xC0,0x65,0x80,0x3F,0x00,0x04,0x00,0x04,0x00,0x00,0x00, + + 19, // 0x25 '%' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x08,0x00,0x63,0x10,0x00,0x63,0x10,0x00,0x63,0x20,0x00,0x63,0x2F,0x80,0x63,0x58,0xC0,0x3E,0x98,0xC0,0x00,0x98,0xC0,0x01,0x18,0xC0,0x01,0x18,0xC0,0x02,0x0F,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 13, // 0x26 '&' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x33,0x00,0x33,0x00,0x1E,0x60,0x36,0x60,0x63,0x60,0x61,0xC0,0x60,0xC0,0x30,0xE0,0x1F,0x30,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x27 ''' + 0x00,0x00,0x00,0x60,0x60,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x28 '(' + 0x00,0x00,0x00,0x06,0x0C,0x18,0x30,0x30,0x60,0x60,0x60,0x60,0x60,0x30,0x30,0x18,0x0C,0x06, + + 8, // 0x29 ')' + 0x00,0x00,0x00,0x60,0x30,0x18,0x0C,0x0C,0x06,0x06,0x06,0x06,0x06,0x0C,0x0C,0x18,0x30,0x60, + + 11, // 0x2A '*' + 0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x24,0x80,0x15,0x00,0x0E,0x00,0x15,0x00,0x24,0x80,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 13, // 0x2B '+' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x3F,0xE0,0x02,0x00,0x02,0x00,0x02,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x2C ',' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x60,0x60,0x60,0xC0,0xC0, + + 7, // 0x2D '-' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 5, // 0x2E '.' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x00,0x00,0x00, + + 10, // 0x2F '/' + 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x01,0x80,0x03,0x00,0x03,0x00,0x06,0x00,0x06,0x00,0x0C,0x00,0x0C,0x00,0x18,0x00,0x18,0x00,0x30,0x00,0x30,0x00,0x60,0x00,0x60,0x00,0x00,0x00, + + 11, // 0x30 '0' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x31,0x80,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x31,0x80,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x31 '1' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x1E,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x1F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x32 '2' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x61,0x80,0x60,0xC0,0x00,0xC0,0x01,0x80,0x03,0x00,0x06,0x00,0x0C,0x00,0x18,0x00,0x30,0x00,0x7F,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x33 '3' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x61,0x80,0x60,0xC0,0x00,0xC0,0x01,0x80,0x0F,0x00,0x01,0x80,0x00,0xC0,0x60,0xC0,0x61,0x80,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x34 '4' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x03,0x80,0x05,0x80,0x09,0x80,0x11,0x80,0x21,0x80,0x41,0x80,0x7F,0xE0,0x01,0x80,0x01,0x80,0x01,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x35 '5' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xC0,0x30,0x00,0x30,0x00,0x30,0x00,0x3F,0x00,0x01,0x80,0x00,0xC0,0x00,0xC0,0x60,0xC0,0x61,0x80,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x36 '6' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x80,0x18,0x00,0x30,0x00,0x60,0x00,0x6F,0x00,0x71,0x80,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x31,0x80,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x37 '7' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0xC0,0x00,0xC0,0x01,0x80,0x01,0x80,0x03,0x00,0x03,0x00,0x06,0x00,0x06,0x00,0x0C,0x00,0x0C,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x38 '8' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x31,0x80,0x60,0xC0,0x60,0xC0,0x31,0x80,0x1F,0x00,0x31,0x80,0x60,0xC0,0x60,0xC0,0x31,0x80,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x39 '9' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x31,0x80,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x31,0xC0,0x1E,0xC0,0x00,0xC0,0x01,0x80,0x03,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x3A ':' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x00,0x00,0x30,0x30,0x30,0x00,0x00,0x00, + + 6, // 0x3B ';' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x30,0x00,0x00,0x38,0x30,0x30,0x30,0x60,0x60, + + 13, // 0x3C '<' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0xC0,0x03,0x00,0x0C,0x00,0x30,0x00,0x30,0x00,0x0C,0x00,0x03,0x00,0x00,0xC0,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00, + + 13, // 0x3D '=' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 13, // 0x3E '>' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x00,0x18,0x00,0x06,0x00,0x01,0x80,0x00,0x60,0x00,0x60,0x01,0x80,0x06,0x00,0x18,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 9, // 0x3F '?' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x63,0x00,0x03,0x00,0x03,0x00,0x06,0x00,0x0C,0x00,0x18,0x00,0x18,0x00,0x00,0x00,0x18,0x00,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 14, // 0x40 '@' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x80,0x18,0x60,0x20,0x10,0x27,0xD0,0x4C,0xC8,0x4C,0xC8,0x4C,0xC8,0x4C,0xC8,0x4C,0xC8,0x27,0xF0,0x20,0x00,0x18,0x00,0x07,0xC0,0x00,0x00, + + 12, // 0x41 'A' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x06,0x00,0x0F,0x00,0x0F,0x00,0x19,0x80,0x19,0x80,0x30,0xC0,0x3F,0xC0,0x30,0xC0,0x60,0x60,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x42 'B' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x63,0x00,0x7F,0x00,0x61,0x80,0x60,0xC0,0x60,0xC0,0x61,0x80,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x43 'C' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x80,0x38,0xC0,0x30,0xC0,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x30,0xC0,0x38,0xC0,0x0F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 12, // 0x44 'D' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x61,0xC0,0x60,0xC0,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0xC0,0x61,0xC0,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x45 'E' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x7F,0x80,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x46 'F' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x7F,0x80,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 12, // 0x47 'G' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0xC0,0x38,0x60,0x30,0x60,0x60,0x00,0x60,0x00,0x63,0xE0,0x60,0x60,0x60,0x60,0x30,0x60,0x38,0x60,0x0F,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, + + 12, // 0x48 'H' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x7F,0xE0,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x49 'I' + 0x00,0x00,0x00,0x00,0x7E,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x7E,0x00,0x00,0x00, + + 8, // 0x4A 'J' + 0x00,0x00,0x00,0x00,0x3E,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x06,0x0C,0xF8,0x00,0x00,0x00, + + 12, // 0x4B 'K' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x60,0xC0,0x61,0x80,0x63,0x00,0x66,0x00,0x6C,0x00,0x7E,0x00,0x73,0x00,0x61,0x80,0x60,0xC0,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x4C 'L' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 14, // 0x4D 'M' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x38,0x70,0x38,0x70,0x78,0x58,0x58,0x58,0xD8,0x4C,0x98,0x4D,0x98,0x47,0x18,0x47,0x18,0x42,0x18,0x40,0x18,0x00,0x00,0x00,0x00,0x00,0x00, + + 12, // 0x4E 'N' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x70,0x20,0x70,0x20,0x58,0x20,0x4C,0x20,0x4C,0x20,0x46,0x20,0x43,0x20,0x43,0x20,0x41,0xA0,0x40,0xE0,0x40,0xE0,0x00,0x00,0x00,0x00,0x00,0x00, + + 13, // 0x4F 'O' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x80,0x38,0xE0,0x30,0x60,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0x30,0x60,0x38,0xE0,0x0F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x50 'P' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x61,0x80,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x61,0x80,0x7F,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 13, // 0x51 'Q' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0F,0x80,0x38,0xE0,0x30,0x60,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0x60,0x30,0x30,0x60,0x38,0xE0,0x0F,0x80,0x03,0x00,0x03,0x80,0x01,0xF0, + + 12, // 0x52 'R' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x61,0x80,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x61,0x80,0x7F,0x00,0x61,0x80,0x60,0xC0,0x60,0x60,0x60,0x30,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x53 'S' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x80,0x30,0xC0,0x60,0xC0,0x60,0x00,0x7C,0x00,0x3F,0x80,0x03,0xC0,0x00,0xC0,0x60,0xC0,0x61,0x80,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x54 'T' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 12, // 0x55 'U' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x30,0xC0,0x1F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x56 'V' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xC0,0x60,0xC0,0x60,0xC0,0x31,0x80,0x31,0x80,0x31,0x80,0x1B,0x00,0x1B,0x00,0x1B,0x00,0x0E,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 16, // 0x57 'W' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x86,0x61,0x86,0x63,0xC6,0x33,0xCC,0x32,0x4C,0x32,0x4C,0x1E,0x78,0x1C,0x38,0x1C,0x38,0x0C,0x30,0x0C,0x30,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x58 'X' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x60,0xC0,0x31,0x80,0x31,0x80,0x1B,0x00,0x0E,0x00,0x0E,0x00,0x0E,0x00,0x1B,0x00,0x31,0x80,0x31,0x80,0x60,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x59 'Y' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xC0,0x61,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x1E,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x5A 'Z' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x80,0x01,0x80,0x03,0x00,0x06,0x00,0x06,0x00,0x0C,0x00,0x18,0x00,0x18,0x00,0x30,0x00,0x60,0x00,0x7F,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x5B '[' + 0x00,0x00,0x00,0x3E,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x3E, + + 10, // 0x5C '\' + 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x30,0x00,0x30,0x00,0x18,0x00,0x18,0x00,0x0C,0x00,0x0C,0x00,0x06,0x00,0x06,0x00,0x03,0x00,0x03,0x00,0x01,0x80,0x01,0x80,0x00,0x00, + + 8, // 0x5D ']' + 0x00,0x00,0x00,0x7C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x0C,0x7C, + + 13, // 0x5E '^' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x0F,0x00,0x19,0x80,0x30,0xC0,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x5F '_' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xE0,0x00,0x00, + + 11, // 0x60 '`' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x61 'a' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x00,0x01,0x80,0x01,0x80,0x3F,0x80,0x61,0x80,0x61,0x80,0x63,0x80,0x3D,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x62 'b' + 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x6E,0x00,0x73,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x63,0x00,0x7E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 8, // 0x63 'c' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x33,0x60,0x60,0x60,0x60,0x33,0x1E,0x00,0x00,0x00, + + 10, // 0x64 'd' + 0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x01,0x80,0x01,0x80,0x01,0x80,0x1F,0x80,0x31,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x80,0x1D,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x65 'e' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x7F,0x80,0x60,0x00,0x60,0x00,0x31,0x80,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 6, // 0x66 'f' + 0x00,0x00,0x00,0x1C,0x30,0x30,0x30,0x7C,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,0x00,0x00, + + 10, // 0x67 'g' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x80,0x31,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x80,0x1D,0x80,0x01,0x80,0x03,0x00,0x3E,0x00, + + 10, // 0x68 'h' + 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x6F,0x00,0x71,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x69 'i' + 0x00,0x00,0x00,0x60,0x60,0x00,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00,0x00, + + 6, // 0x6A 'j' + 0x00,0x00,0x00,0x18,0x18,0x00,0x00,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0xF0, + + 10, // 0x6B 'k' + 0x00,0x00,0x00,0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x60,0x00,0x61,0x80,0x63,0x00,0x66,0x00,0x6C,0x00,0x7E,0x00,0x73,0x00,0x61,0x80,0x60,0xC0,0x00,0x00,0x00,0x00,0x00,0x00, + + 4, // 0x6C 'l' + 0x00,0x00,0x00,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00,0x00, + + 16, // 0x6D 'm' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6F,0x3C,0x71,0xC6,0x61,0x86,0x61,0x86,0x61,0x86,0x61,0x86,0x61,0x86,0x61,0x86,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x6E 'n' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6F,0x00,0x71,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x6F 'o' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1E,0x00,0x33,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x00,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x70 'p' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6E,0x00,0x73,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x63,0x00,0x7E,0x00,0x60,0x00,0x60,0x00,0x60,0x00, + + 10, // 0x71 'q' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x80,0x31,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x33,0x80,0x1D,0x80,0x01,0x80,0x01,0x80,0x01,0x80, + + 7, // 0x72 'r' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x6E,0x7E,0x60,0x60,0x60,0x60,0x60,0x60,0x00,0x00,0x00, + + 9, // 0x73 's' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0x61,0x00,0x60,0x00,0x7E,0x00,0x3F,0x00,0x03,0x00,0x43,0x00,0x3E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 7, // 0x74 't' + 0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x7E,0x30,0x30,0x30,0x30,0x30,0x30,0x1E,0x00,0x00,0x00, + + 10, // 0x75 'u' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x61,0x80,0x63,0x80,0x3D,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x76 'v' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x33,0x00,0x33,0x00,0x33,0x00,0x1E,0x00,0x1E,0x00,0x0C,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 14, // 0x77 'w' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x63,0x18,0x63,0x18,0x63,0x18,0x37,0xB0,0x34,0xB0,0x3C,0xF0,0x18,0x60,0x18,0x60,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x78 'x' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x33,0x00,0x33,0x00,0x1E,0x00,0x1E,0x00,0x33,0x00,0x33,0x00,0x61,0x80,0x00,0x00,0x00,0x00,0x00,0x00, + + 10, // 0x79 'y' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x61,0x80,0x61,0x80,0x33,0x00,0x33,0x00,0x33,0x00,0x1E,0x00,0x1E,0x00,0x0C,0x00,0x0C,0x00,0x18,0x00,0x18,0x00, + + 9, // 0x7A 'z' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7F,0x00,0x03,0x00,0x06,0x00,0x0C,0x00,0x18,0x00,0x30,0x00,0x60,0x00,0x7F,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 11, // 0x7B '{' + 0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x80,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x18,0x00,0x70,0x00,0x18,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x0C,0x00,0x07,0x80, + + 8, // 0x7C '|' + 0x00,0x00,0x00,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18, + + 11, // 0x7D '}' + 0x00,0x00,0x00,0x00,0x00,0x00,0x3C,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x03,0x00,0x01,0xC0,0x03,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x3C,0x00, + + 13, // 0x7E '~' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x18,0x10,0x24,0x10,0x42,0x10,0x41,0x20,0x40,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + + 15, // 0x7F '' + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0xF8,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x20,0x08,0x3F,0xF8,0x00,0x00,0x00,0x00,0x00,0x00, + + 0 + }; + +} + diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_gsv_text.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_gsv_text.cpp new file mode 100644 index 00000000000..ffb24eb9b63 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_gsv_text.cpp @@ -0,0 +1,675 @@ +//---------------------------------------------------------------------------- +// 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 +// +//---------------------------------------------------------------------------- +#include <string.h> +#include <stdio.h> +#include "agg_gsv_text.h" +#include "agg_bounding_rect.h" + + + +namespace agg +{ + int8u gsv_default_font[] = + { + 0x40,0x00,0x6c,0x0f,0x15,0x00,0x0e,0x00,0xf9,0xff, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x0d,0x0a,0x0d,0x0a,0x46,0x6f,0x6e,0x74,0x20,0x28, + 0x63,0x29,0x20,0x4d,0x69,0x63,0x72,0x6f,0x50,0x72, + 0x6f,0x66,0x20,0x32,0x37,0x20,0x53,0x65,0x70,0x74, + 0x65,0x6d,0x62,0x2e,0x31,0x39,0x38,0x39,0x00,0x0d, + 0x0a,0x0d,0x0a,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, + 0x02,0x00,0x12,0x00,0x34,0x00,0x46,0x00,0x94,0x00, + 0xd0,0x00,0x2e,0x01,0x3e,0x01,0x64,0x01,0x8a,0x01, + 0x98,0x01,0xa2,0x01,0xb4,0x01,0xba,0x01,0xc6,0x01, + 0xcc,0x01,0xf0,0x01,0xfa,0x01,0x18,0x02,0x38,0x02, + 0x44,0x02,0x68,0x02,0x98,0x02,0xa2,0x02,0xde,0x02, + 0x0e,0x03,0x24,0x03,0x40,0x03,0x48,0x03,0x52,0x03, + 0x5a,0x03,0x82,0x03,0xec,0x03,0xfa,0x03,0x26,0x04, + 0x4c,0x04,0x6a,0x04,0x7c,0x04,0x8a,0x04,0xb6,0x04, + 0xc4,0x04,0xca,0x04,0xe0,0x04,0xee,0x04,0xf8,0x04, + 0x0a,0x05,0x18,0x05,0x44,0x05,0x5e,0x05,0x8e,0x05, + 0xac,0x05,0xd6,0x05,0xe0,0x05,0xf6,0x05,0x00,0x06, + 0x12,0x06,0x1c,0x06,0x28,0x06,0x36,0x06,0x48,0x06, + 0x4e,0x06,0x60,0x06,0x6e,0x06,0x74,0x06,0x84,0x06, + 0xa6,0x06,0xc8,0x06,0xe6,0x06,0x08,0x07,0x2c,0x07, + 0x3c,0x07,0x68,0x07,0x7c,0x07,0x8c,0x07,0xa2,0x07, + 0xb0,0x07,0xb6,0x07,0xd8,0x07,0xec,0x07,0x10,0x08, + 0x32,0x08,0x54,0x08,0x64,0x08,0x88,0x08,0x98,0x08, + 0xac,0x08,0xb6,0x08,0xc8,0x08,0xd2,0x08,0xe4,0x08, + 0xf2,0x08,0x3e,0x09,0x48,0x09,0x94,0x09,0xc2,0x09, + 0xc4,0x09,0xd0,0x09,0xe2,0x09,0x04,0x0a,0x0e,0x0a, + 0x26,0x0a,0x34,0x0a,0x4a,0x0a,0x66,0x0a,0x70,0x0a, + 0x7e,0x0a,0x8e,0x0a,0x9a,0x0a,0xa6,0x0a,0xb4,0x0a, + 0xd8,0x0a,0xe2,0x0a,0xf6,0x0a,0x18,0x0b,0x22,0x0b, + 0x32,0x0b,0x56,0x0b,0x60,0x0b,0x6e,0x0b,0x7c,0x0b, + 0x8a,0x0b,0x9c,0x0b,0x9e,0x0b,0xb2,0x0b,0xc2,0x0b, + 0xd8,0x0b,0xf4,0x0b,0x08,0x0c,0x30,0x0c,0x56,0x0c, + 0x72,0x0c,0x90,0x0c,0xb2,0x0c,0xce,0x0c,0xe2,0x0c, + 0xfe,0x0c,0x10,0x0d,0x26,0x0d,0x36,0x0d,0x42,0x0d, + 0x4e,0x0d,0x5c,0x0d,0x78,0x0d,0x8c,0x0d,0x8e,0x0d, + 0x90,0x0d,0x92,0x0d,0x94,0x0d,0x96,0x0d,0x98,0x0d, + 0x9a,0x0d,0x9c,0x0d,0x9e,0x0d,0xa0,0x0d,0xa2,0x0d, + 0xa4,0x0d,0xa6,0x0d,0xa8,0x0d,0xaa,0x0d,0xac,0x0d, + 0xae,0x0d,0xb0,0x0d,0xb2,0x0d,0xb4,0x0d,0xb6,0x0d, + 0xb8,0x0d,0xba,0x0d,0xbc,0x0d,0xbe,0x0d,0xc0,0x0d, + 0xc2,0x0d,0xc4,0x0d,0xc6,0x0d,0xc8,0x0d,0xca,0x0d, + 0xcc,0x0d,0xce,0x0d,0xd0,0x0d,0xd2,0x0d,0xd4,0x0d, + 0xd6,0x0d,0xd8,0x0d,0xda,0x0d,0xdc,0x0d,0xde,0x0d, + 0xe0,0x0d,0xe2,0x0d,0xe4,0x0d,0xe6,0x0d,0xe8,0x0d, + 0xea,0x0d,0xec,0x0d,0x0c,0x0e,0x26,0x0e,0x48,0x0e, + 0x64,0x0e,0x88,0x0e,0x92,0x0e,0xa6,0x0e,0xb4,0x0e, + 0xd0,0x0e,0xee,0x0e,0x02,0x0f,0x16,0x0f,0x26,0x0f, + 0x3c,0x0f,0x58,0x0f,0x6c,0x0f,0x6c,0x0f,0x6c,0x0f, + 0x6c,0x0f,0x6c,0x0f,0x6c,0x0f,0x6c,0x0f,0x6c,0x0f, + 0x6c,0x0f,0x6c,0x0f,0x6c,0x0f,0x6c,0x0f,0x6c,0x0f, + 0x6c,0x0f,0x6c,0x0f,0x6c,0x0f,0x6c,0x0f,0x10,0x80, + 0x05,0x95,0x00,0x72,0x00,0xfb,0xff,0x7f,0x01,0x7f, + 0x01,0x01,0xff,0x01,0x05,0xfe,0x05,0x95,0xff,0x7f, + 0x00,0x7a,0x01,0x86,0xff,0x7a,0x01,0x87,0x01,0x7f, + 0xfe,0x7a,0x0a,0x87,0xff,0x7f,0x00,0x7a,0x01,0x86, + 0xff,0x7a,0x01,0x87,0x01,0x7f,0xfe,0x7a,0x05,0xf2, + 0x0b,0x95,0xf9,0x64,0x0d,0x9c,0xf9,0x64,0xfa,0x91, + 0x0e,0x00,0xf1,0xfa,0x0e,0x00,0x04,0xfc,0x08,0x99, + 0x00,0x63,0x04,0x9d,0x00,0x63,0x04,0x96,0xff,0x7f, + 0x01,0x7f,0x01,0x01,0x00,0x01,0xfe,0x02,0xfd,0x01, + 0xfc,0x00,0xfd,0x7f,0xfe,0x7e,0x00,0x7e,0x01,0x7e, + 0x01,0x7f,0x02,0x7f,0x06,0x7e,0x02,0x7f,0x02,0x7e, + 0xf2,0x89,0x02,0x7e,0x02,0x7f,0x06,0x7e,0x02,0x7f, + 0x01,0x7f,0x01,0x7e,0x00,0x7c,0xfe,0x7e,0xfd,0x7f, + 0xfc,0x00,0xfd,0x01,0xfe,0x02,0x00,0x01,0x01,0x01, + 0x01,0x7f,0xff,0x7f,0x10,0xfd,0x15,0x95,0xee,0x6b, + 0x05,0x95,0x02,0x7e,0x00,0x7e,0xff,0x7e,0xfe,0x7f, + 0xfe,0x00,0xfe,0x02,0x00,0x02,0x01,0x02,0x02,0x01, + 0x02,0x00,0x02,0x7f,0x03,0x7f,0x03,0x00,0x03,0x01, + 0x02,0x01,0xfc,0xf2,0xfe,0x7f,0xff,0x7e,0x00,0x7e, + 0x02,0x7e,0x02,0x00,0x02,0x01,0x01,0x02,0x00,0x02, + 0xfe,0x02,0xfe,0x00,0x07,0xf9,0x15,0x8d,0xff,0x7f, + 0x01,0x7f,0x01,0x01,0x00,0x01,0xff,0x01,0xff,0x00, + 0xff,0x7f,0xff,0x7e,0xfe,0x7b,0xfe,0x7d,0xfe,0x7e, + 0xfe,0x7f,0xfd,0x00,0xfd,0x01,0xff,0x02,0x00,0x03, + 0x01,0x02,0x06,0x04,0x02,0x02,0x01,0x02,0x00,0x02, + 0xff,0x02,0xfe,0x01,0xfe,0x7f,0xff,0x7e,0x00,0x7e, + 0x01,0x7d,0x02,0x7d,0x05,0x79,0x02,0x7e,0x03,0x7f, + 0x01,0x00,0x01,0x01,0x00,0x01,0xf1,0xfe,0xfe,0x01, + 0xff,0x02,0x00,0x03,0x01,0x02,0x02,0x02,0x00,0x86, + 0x01,0x7e,0x08,0x75,0x02,0x7e,0x02,0x7f,0x05,0x80, + 0x05,0x93,0xff,0x01,0x01,0x01,0x01,0x7f,0x00,0x7e, + 0xff,0x7e,0xff,0x7f,0x06,0xf1,0x0b,0x99,0xfe,0x7e, + 0xfe,0x7d,0xfe,0x7c,0xff,0x7b,0x00,0x7c,0x01,0x7b, + 0x02,0x7c,0x02,0x7d,0x02,0x7e,0xfe,0x9e,0xfe,0x7c, + 0xff,0x7d,0xff,0x7b,0x00,0x7c,0x01,0x7b,0x01,0x7d, + 0x02,0x7c,0x05,0x85,0x03,0x99,0x02,0x7e,0x02,0x7d, + 0x02,0x7c,0x01,0x7b,0x00,0x7c,0xff,0x7b,0xfe,0x7c, + 0xfe,0x7d,0xfe,0x7e,0x02,0x9e,0x02,0x7c,0x01,0x7d, + 0x01,0x7b,0x00,0x7c,0xff,0x7b,0xff,0x7d,0xfe,0x7c, + 0x09,0x85,0x08,0x95,0x00,0x74,0xfb,0x89,0x0a,0x7a, + 0x00,0x86,0xf6,0x7a,0x0d,0xf4,0x0d,0x92,0x00,0x6e, + 0xf7,0x89,0x12,0x00,0x04,0xf7,0x06,0x81,0xff,0x7f, + 0xff,0x01,0x01,0x01,0x01,0x7f,0x00,0x7e,0xff,0x7e, + 0xff,0x7f,0x06,0x84,0x04,0x89,0x12,0x00,0x04,0xf7, + 0x05,0x82,0xff,0x7f,0x01,0x7f,0x01,0x01,0xff,0x01, + 0x05,0xfe,0x00,0xfd,0x0e,0x18,0x00,0xeb,0x09,0x95, + 0xfd,0x7f,0xfe,0x7d,0xff,0x7b,0x00,0x7d,0x01,0x7b, + 0x02,0x7d,0x03,0x7f,0x02,0x00,0x03,0x01,0x02,0x03, + 0x01,0x05,0x00,0x03,0xff,0x05,0xfe,0x03,0xfd,0x01, + 0xfe,0x00,0x0b,0xeb,0x06,0x91,0x02,0x01,0x03,0x03, + 0x00,0x6b,0x09,0x80,0x04,0x90,0x00,0x01,0x01,0x02, + 0x01,0x01,0x02,0x01,0x04,0x00,0x02,0x7f,0x01,0x7f, + 0x01,0x7e,0x00,0x7e,0xff,0x7e,0xfe,0x7d,0xf6,0x76, + 0x0e,0x00,0x03,0x80,0x05,0x95,0x0b,0x00,0xfa,0x78, + 0x03,0x00,0x02,0x7f,0x01,0x7f,0x01,0x7d,0x00,0x7e, + 0xff,0x7d,0xfe,0x7e,0xfd,0x7f,0xfd,0x00,0xfd,0x01, + 0xff,0x01,0xff,0x02,0x11,0xfc,0x0d,0x95,0xf6,0x72, + 0x0f,0x00,0xfb,0x8e,0x00,0x6b,0x07,0x80,0x0f,0x95, + 0xf6,0x00,0xff,0x77,0x01,0x01,0x03,0x01,0x03,0x00, + 0x03,0x7f,0x02,0x7e,0x01,0x7d,0x00,0x7e,0xff,0x7d, + 0xfe,0x7e,0xfd,0x7f,0xfd,0x00,0xfd,0x01,0xff,0x01, + 0xff,0x02,0x11,0xfc,0x10,0x92,0xff,0x02,0xfd,0x01, + 0xfe,0x00,0xfd,0x7f,0xfe,0x7d,0xff,0x7b,0x00,0x7b, + 0x01,0x7c,0x02,0x7e,0x03,0x7f,0x01,0x00,0x03,0x01, + 0x02,0x02,0x01,0x03,0x00,0x01,0xff,0x03,0xfe,0x02, + 0xfd,0x01,0xff,0x00,0xfd,0x7f,0xfe,0x7e,0xff,0x7d, + 0x10,0xf9,0x11,0x95,0xf6,0x6b,0xfc,0x95,0x0e,0x00, + 0x03,0xeb,0x08,0x95,0xfd,0x7f,0xff,0x7e,0x00,0x7e, + 0x01,0x7e,0x02,0x7f,0x04,0x7f,0x03,0x7f,0x02,0x7e, + 0x01,0x7e,0x00,0x7d,0xff,0x7e,0xff,0x7f,0xfd,0x7f, + 0xfc,0x00,0xfd,0x01,0xff,0x01,0xff,0x02,0x00,0x03, + 0x01,0x02,0x02,0x02,0x03,0x01,0x04,0x01,0x02,0x01, + 0x01,0x02,0x00,0x02,0xff,0x02,0xfd,0x01,0xfc,0x00, + 0x0c,0xeb,0x10,0x8e,0xff,0x7d,0xfe,0x7e,0xfd,0x7f, + 0xff,0x00,0xfd,0x01,0xfe,0x02,0xff,0x03,0x00,0x01, + 0x01,0x03,0x02,0x02,0x03,0x01,0x01,0x00,0x03,0x7f, + 0x02,0x7e,0x01,0x7c,0x00,0x7b,0xff,0x7b,0xfe,0x7d, + 0xfd,0x7f,0xfe,0x00,0xfd,0x01,0xff,0x02,0x10,0xfd, + 0x05,0x8e,0xff,0x7f,0x01,0x7f,0x01,0x01,0xff,0x01, + 0x00,0xf4,0xff,0x7f,0x01,0x7f,0x01,0x01,0xff,0x01, + 0x05,0xfe,0x05,0x8e,0xff,0x7f,0x01,0x7f,0x01,0x01, + 0xff,0x01,0x01,0xf3,0xff,0x7f,0xff,0x01,0x01,0x01, + 0x01,0x7f,0x00,0x7e,0xff,0x7e,0xff,0x7f,0x06,0x84, + 0x14,0x92,0xf0,0x77,0x10,0x77,0x04,0x80,0x04,0x8c, + 0x12,0x00,0xee,0xfa,0x12,0x00,0x04,0xfa,0x04,0x92, + 0x10,0x77,0xf0,0x77,0x14,0x80,0x03,0x90,0x00,0x01, + 0x01,0x02,0x01,0x01,0x02,0x01,0x04,0x00,0x02,0x7f, + 0x01,0x7f,0x01,0x7e,0x00,0x7e,0xff,0x7e,0xff,0x7f, + 0xfc,0x7e,0x00,0x7d,0x00,0xfb,0xff,0x7f,0x01,0x7f, + 0x01,0x01,0xff,0x01,0x09,0xfe,0x12,0x8d,0xff,0x02, + 0xfe,0x01,0xfd,0x00,0xfe,0x7f,0xff,0x7f,0xff,0x7d, + 0x00,0x7d,0x01,0x7e,0x02,0x7f,0x03,0x00,0x02,0x01, + 0x01,0x02,0xfb,0x88,0xfe,0x7e,0xff,0x7d,0x00,0x7d, + 0x01,0x7e,0x01,0x7f,0x07,0x8b,0xff,0x78,0x00,0x7e, + 0x02,0x7f,0x02,0x00,0x02,0x02,0x01,0x03,0x00,0x02, + 0xff,0x03,0xff,0x02,0xfe,0x02,0xfe,0x01,0xfd,0x01, + 0xfd,0x00,0xfd,0x7f,0xfe,0x7f,0xfe,0x7e,0xff,0x7e, + 0xff,0x7d,0x00,0x7d,0x01,0x7d,0x01,0x7e,0x02,0x7e, + 0x02,0x7f,0x03,0x7f,0x03,0x00,0x03,0x01,0x02,0x01, + 0x01,0x01,0xfe,0x8d,0xff,0x78,0x00,0x7e,0x01,0x7f, + 0x08,0xfb,0x09,0x95,0xf8,0x6b,0x08,0x95,0x08,0x6b, + 0xf3,0x87,0x0a,0x00,0x04,0xf9,0x04,0x95,0x00,0x6b, + 0x00,0x95,0x09,0x00,0x03,0x7f,0x01,0x7f,0x01,0x7e, + 0x00,0x7e,0xff,0x7e,0xff,0x7f,0xfd,0x7f,0xf7,0x80, + 0x09,0x00,0x03,0x7f,0x01,0x7f,0x01,0x7e,0x00,0x7d, + 0xff,0x7e,0xff,0x7f,0xfd,0x7f,0xf7,0x00,0x11,0x80, + 0x12,0x90,0xff,0x02,0xfe,0x02,0xfe,0x01,0xfc,0x00, + 0xfe,0x7f,0xfe,0x7e,0xff,0x7e,0xff,0x7d,0x00,0x7b, + 0x01,0x7d,0x01,0x7e,0x02,0x7e,0x02,0x7f,0x04,0x00, + 0x02,0x01,0x02,0x02,0x01,0x02,0x03,0xfb,0x04,0x95, + 0x00,0x6b,0x00,0x95,0x07,0x00,0x03,0x7f,0x02,0x7e, + 0x01,0x7e,0x01,0x7d,0x00,0x7b,0xff,0x7d,0xff,0x7e, + 0xfe,0x7e,0xfd,0x7f,0xf9,0x00,0x11,0x80,0x04,0x95, + 0x00,0x6b,0x00,0x95,0x0d,0x00,0xf3,0xf6,0x08,0x00, + 0xf8,0xf5,0x0d,0x00,0x02,0x80,0x04,0x95,0x00,0x6b, + 0x00,0x95,0x0d,0x00,0xf3,0xf6,0x08,0x00,0x06,0xf5, + 0x12,0x90,0xff,0x02,0xfe,0x02,0xfe,0x01,0xfc,0x00, + 0xfe,0x7f,0xfe,0x7e,0xff,0x7e,0xff,0x7d,0x00,0x7b, + 0x01,0x7d,0x01,0x7e,0x02,0x7e,0x02,0x7f,0x04,0x00, + 0x02,0x01,0x02,0x02,0x01,0x02,0x00,0x03,0xfb,0x80, + 0x05,0x00,0x03,0xf8,0x04,0x95,0x00,0x6b,0x0e,0x95, + 0x00,0x6b,0xf2,0x8b,0x0e,0x00,0x04,0xf5,0x04,0x95, + 0x00,0x6b,0x04,0x80,0x0c,0x95,0x00,0x70,0xff,0x7d, + 0xff,0x7f,0xfe,0x7f,0xfe,0x00,0xfe,0x01,0xff,0x01, + 0xff,0x03,0x00,0x02,0x0e,0xf9,0x04,0x95,0x00,0x6b, + 0x0e,0x95,0xf2,0x72,0x05,0x85,0x09,0x74,0x03,0x80, + 0x04,0x95,0x00,0x6b,0x00,0x80,0x0c,0x00,0x01,0x80, + 0x04,0x95,0x00,0x6b,0x00,0x95,0x08,0x6b,0x08,0x95, + 0xf8,0x6b,0x08,0x95,0x00,0x6b,0x04,0x80,0x04,0x95, + 0x00,0x6b,0x00,0x95,0x0e,0x6b,0x00,0x95,0x00,0x6b, + 0x04,0x80,0x09,0x95,0xfe,0x7f,0xfe,0x7e,0xff,0x7e, + 0xff,0x7d,0x00,0x7b,0x01,0x7d,0x01,0x7e,0x02,0x7e, + 0x02,0x7f,0x04,0x00,0x02,0x01,0x02,0x02,0x01,0x02, + 0x01,0x03,0x00,0x05,0xff,0x03,0xff,0x02,0xfe,0x02, + 0xfe,0x01,0xfc,0x00,0x0d,0xeb,0x04,0x95,0x00,0x6b, + 0x00,0x95,0x09,0x00,0x03,0x7f,0x01,0x7f,0x01,0x7e, + 0x00,0x7d,0xff,0x7e,0xff,0x7f,0xfd,0x7f,0xf7,0x00, + 0x11,0xf6,0x09,0x95,0xfe,0x7f,0xfe,0x7e,0xff,0x7e, + 0xff,0x7d,0x00,0x7b,0x01,0x7d,0x01,0x7e,0x02,0x7e, + 0x02,0x7f,0x04,0x00,0x02,0x01,0x02,0x02,0x01,0x02, + 0x01,0x03,0x00,0x05,0xff,0x03,0xff,0x02,0xfe,0x02, + 0xfe,0x01,0xfc,0x00,0x03,0xef,0x06,0x7a,0x04,0x82, + 0x04,0x95,0x00,0x6b,0x00,0x95,0x09,0x00,0x03,0x7f, + 0x01,0x7f,0x01,0x7e,0x00,0x7e,0xff,0x7e,0xff,0x7f, + 0xfd,0x7f,0xf7,0x00,0x07,0x80,0x07,0x75,0x03,0x80, + 0x11,0x92,0xfe,0x02,0xfd,0x01,0xfc,0x00,0xfd,0x7f, + 0xfe,0x7e,0x00,0x7e,0x01,0x7e,0x01,0x7f,0x02,0x7f, + 0x06,0x7e,0x02,0x7f,0x01,0x7f,0x01,0x7e,0x00,0x7d, + 0xfe,0x7e,0xfd,0x7f,0xfc,0x00,0xfd,0x01,0xfe,0x02, + 0x11,0xfd,0x08,0x95,0x00,0x6b,0xf9,0x95,0x0e,0x00, + 0x01,0xeb,0x04,0x95,0x00,0x71,0x01,0x7d,0x02,0x7e, + 0x03,0x7f,0x02,0x00,0x03,0x01,0x02,0x02,0x01,0x03, + 0x00,0x0f,0x04,0xeb,0x01,0x95,0x08,0x6b,0x08,0x95, + 0xf8,0x6b,0x09,0x80,0x02,0x95,0x05,0x6b,0x05,0x95, + 0xfb,0x6b,0x05,0x95,0x05,0x6b,0x05,0x95,0xfb,0x6b, + 0x07,0x80,0x03,0x95,0x0e,0x6b,0x00,0x95,0xf2,0x6b, + 0x11,0x80,0x01,0x95,0x08,0x76,0x00,0x75,0x08,0x95, + 0xf8,0x76,0x09,0xf5,0x11,0x95,0xf2,0x6b,0x00,0x95, + 0x0e,0x00,0xf2,0xeb,0x0e,0x00,0x03,0x80,0x03,0x93, + 0x00,0x6c,0x01,0x94,0x00,0x6c,0xff,0x94,0x05,0x00, + 0xfb,0xec,0x05,0x00,0x02,0x81,0x00,0x95,0x0e,0x68, + 0x00,0x83,0x06,0x93,0x00,0x6c,0x01,0x94,0x00,0x6c, + 0xfb,0x94,0x05,0x00,0xfb,0xec,0x05,0x00,0x03,0x81, + 0x03,0x87,0x08,0x05,0x08,0x7b,0xf0,0x80,0x08,0x04, + 0x08,0x7c,0x03,0xf9,0x01,0x80,0x10,0x00,0x01,0x80, + 0x06,0x95,0xff,0x7f,0xff,0x7e,0x00,0x7e,0x01,0x7f, + 0x01,0x01,0xff,0x01,0x05,0xef,0x0f,0x8e,0x00,0x72, + 0x00,0x8b,0xfe,0x02,0xfe,0x01,0xfd,0x00,0xfe,0x7f, + 0xfe,0x7e,0xff,0x7d,0x00,0x7e,0x01,0x7d,0x02,0x7e, + 0x02,0x7f,0x03,0x00,0x02,0x01,0x02,0x02,0x04,0xfd, + 0x04,0x95,0x00,0x6b,0x00,0x8b,0x02,0x02,0x02,0x01, + 0x03,0x00,0x02,0x7f,0x02,0x7e,0x01,0x7d,0x00,0x7e, + 0xff,0x7d,0xfe,0x7e,0xfe,0x7f,0xfd,0x00,0xfe,0x01, + 0xfe,0x02,0x0f,0xfd,0x0f,0x8b,0xfe,0x02,0xfe,0x01, + 0xfd,0x00,0xfe,0x7f,0xfe,0x7e,0xff,0x7d,0x00,0x7e, + 0x01,0x7d,0x02,0x7e,0x02,0x7f,0x03,0x00,0x02,0x01, + 0x02,0x02,0x03,0xfd,0x0f,0x95,0x00,0x6b,0x00,0x8b, + 0xfe,0x02,0xfe,0x01,0xfd,0x00,0xfe,0x7f,0xfe,0x7e, + 0xff,0x7d,0x00,0x7e,0x01,0x7d,0x02,0x7e,0x02,0x7f, + 0x03,0x00,0x02,0x01,0x02,0x02,0x04,0xfd,0x03,0x88, + 0x0c,0x00,0x00,0x02,0xff,0x02,0xff,0x01,0xfe,0x01, + 0xfd,0x00,0xfe,0x7f,0xfe,0x7e,0xff,0x7d,0x00,0x7e, + 0x01,0x7d,0x02,0x7e,0x02,0x7f,0x03,0x00,0x02,0x01, + 0x02,0x02,0x03,0xfd,0x0a,0x95,0xfe,0x00,0xfe,0x7f, + 0xff,0x7d,0x00,0x6f,0xfd,0x8e,0x07,0x00,0x03,0xf2, + 0x0f,0x8e,0x00,0x70,0xff,0x7d,0xff,0x7f,0xfe,0x7f, + 0xfd,0x00,0xfe,0x01,0x09,0x91,0xfe,0x02,0xfe,0x01, + 0xfd,0x00,0xfe,0x7f,0xfe,0x7e,0xff,0x7d,0x00,0x7e, + 0x01,0x7d,0x02,0x7e,0x02,0x7f,0x03,0x00,0x02,0x01, + 0x02,0x02,0x04,0xfd,0x04,0x95,0x00,0x6b,0x00,0x8a, + 0x03,0x03,0x02,0x01,0x03,0x00,0x02,0x7f,0x01,0x7d, + 0x00,0x76,0x04,0x80,0x03,0x95,0x01,0x7f,0x01,0x01, + 0xff,0x01,0xff,0x7f,0x01,0xf9,0x00,0x72,0x04,0x80, + 0x05,0x95,0x01,0x7f,0x01,0x01,0xff,0x01,0xff,0x7f, + 0x01,0xf9,0x00,0x6f,0xff,0x7d,0xfe,0x7f,0xfe,0x00, + 0x09,0x87,0x04,0x95,0x00,0x6b,0x0a,0x8e,0xf6,0x76, + 0x04,0x84,0x07,0x78,0x02,0x80,0x04,0x95,0x00,0x6b, + 0x04,0x80,0x04,0x8e,0x00,0x72,0x00,0x8a,0x03,0x03, + 0x02,0x01,0x03,0x00,0x02,0x7f,0x01,0x7d,0x00,0x76, + 0x00,0x8a,0x03,0x03,0x02,0x01,0x03,0x00,0x02,0x7f, + 0x01,0x7d,0x00,0x76,0x04,0x80,0x04,0x8e,0x00,0x72, + 0x00,0x8a,0x03,0x03,0x02,0x01,0x03,0x00,0x02,0x7f, + 0x01,0x7d,0x00,0x76,0x04,0x80,0x08,0x8e,0xfe,0x7f, + 0xfe,0x7e,0xff,0x7d,0x00,0x7e,0x01,0x7d,0x02,0x7e, + 0x02,0x7f,0x03,0x00,0x02,0x01,0x02,0x02,0x01,0x03, + 0x00,0x02,0xff,0x03,0xfe,0x02,0xfe,0x01,0xfd,0x00, + 0x0b,0xf2,0x04,0x8e,0x00,0x6b,0x00,0x92,0x02,0x02, + 0x02,0x01,0x03,0x00,0x02,0x7f,0x02,0x7e,0x01,0x7d, + 0x00,0x7e,0xff,0x7d,0xfe,0x7e,0xfe,0x7f,0xfd,0x00, + 0xfe,0x01,0xfe,0x02,0x0f,0xfd,0x0f,0x8e,0x00,0x6b, + 0x00,0x92,0xfe,0x02,0xfe,0x01,0xfd,0x00,0xfe,0x7f, + 0xfe,0x7e,0xff,0x7d,0x00,0x7e,0x01,0x7d,0x02,0x7e, + 0x02,0x7f,0x03,0x00,0x02,0x01,0x02,0x02,0x04,0xfd, + 0x04,0x8e,0x00,0x72,0x00,0x88,0x01,0x03,0x02,0x02, + 0x02,0x01,0x03,0x00,0x01,0xf2,0x0e,0x8b,0xff,0x02, + 0xfd,0x01,0xfd,0x00,0xfd,0x7f,0xff,0x7e,0x01,0x7e, + 0x02,0x7f,0x05,0x7f,0x02,0x7f,0x01,0x7e,0x00,0x7f, + 0xff,0x7e,0xfd,0x7f,0xfd,0x00,0xfd,0x01,0xff,0x02, + 0x0e,0xfd,0x05,0x95,0x00,0x6f,0x01,0x7d,0x02,0x7f, + 0x02,0x00,0xf8,0x8e,0x07,0x00,0x03,0xf2,0x04,0x8e, + 0x00,0x76,0x01,0x7d,0x02,0x7f,0x03,0x00,0x02,0x01, + 0x03,0x03,0x00,0x8a,0x00,0x72,0x04,0x80,0x02,0x8e, + 0x06,0x72,0x06,0x8e,0xfa,0x72,0x08,0x80,0x03,0x8e, + 0x04,0x72,0x04,0x8e,0xfc,0x72,0x04,0x8e,0x04,0x72, + 0x04,0x8e,0xfc,0x72,0x07,0x80,0x03,0x8e,0x0b,0x72, + 0x00,0x8e,0xf5,0x72,0x0e,0x80,0x02,0x8e,0x06,0x72, + 0x06,0x8e,0xfa,0x72,0xfe,0x7c,0xfe,0x7e,0xfe,0x7f, + 0xff,0x00,0x0f,0x87,0x0e,0x8e,0xf5,0x72,0x00,0x8e, + 0x0b,0x00,0xf5,0xf2,0x0b,0x00,0x03,0x80,0x09,0x99, + 0xfe,0x7f,0xff,0x7f,0xff,0x7e,0x00,0x7e,0x01,0x7e, + 0x01,0x7f,0x01,0x7e,0x00,0x7e,0xfe,0x7e,0x01,0x8e, + 0xff,0x7e,0x00,0x7e,0x01,0x7e,0x01,0x7f,0x01,0x7e, + 0x00,0x7e,0xff,0x7e,0xfc,0x7e,0x04,0x7e,0x01,0x7e, + 0x00,0x7e,0xff,0x7e,0xff,0x7f,0xff,0x7e,0x00,0x7e, + 0x01,0x7e,0xff,0x8e,0x02,0x7e,0x00,0x7e,0xff,0x7e, + 0xff,0x7f,0xff,0x7e,0x00,0x7e,0x01,0x7e,0x01,0x7f, + 0x02,0x7f,0x05,0x87,0x04,0x95,0x00,0x77,0x00,0xfd, + 0x00,0x77,0x04,0x80,0x05,0x99,0x02,0x7f,0x01,0x7f, + 0x01,0x7e,0x00,0x7e,0xff,0x7e,0xff,0x7f,0xff,0x7e, + 0x00,0x7e,0x02,0x7e,0xff,0x8e,0x01,0x7e,0x00,0x7e, + 0xff,0x7e,0xff,0x7f,0xff,0x7e,0x00,0x7e,0x01,0x7e, + 0x04,0x7e,0xfc,0x7e,0xff,0x7e,0x00,0x7e,0x01,0x7e, + 0x01,0x7f,0x01,0x7e,0x00,0x7e,0xff,0x7e,0x01,0x8e, + 0xfe,0x7e,0x00,0x7e,0x01,0x7e,0x01,0x7f,0x01,0x7e, + 0x00,0x7e,0xff,0x7e,0xff,0x7f,0xfe,0x7f,0x09,0x87, + 0x03,0x86,0x00,0x02,0x01,0x03,0x02,0x01,0x02,0x00, + 0x02,0x7f,0x04,0x7d,0x02,0x7f,0x02,0x00,0x02,0x01, + 0x01,0x02,0xee,0xfe,0x01,0x02,0x02,0x01,0x02,0x00, + 0x02,0x7f,0x04,0x7d,0x02,0x7f,0x02,0x00,0x02,0x01, + 0x01,0x03,0x00,0x02,0x03,0xf4,0x10,0x80,0x03,0x80, + 0x07,0x15,0x08,0x6b,0xfe,0x85,0xf5,0x00,0x10,0xfb, + 0x0d,0x95,0xf6,0x00,0x00,0x6b,0x0a,0x00,0x02,0x02, + 0x00,0x08,0xfe,0x02,0xf6,0x00,0x0e,0xf4,0x03,0x80, + 0x00,0x15,0x0a,0x00,0x02,0x7e,0x00,0x7e,0x00,0x7d, + 0x00,0x7e,0xfe,0x7f,0xf6,0x00,0x0a,0x80,0x02,0x7e, + 0x01,0x7e,0x00,0x7d,0xff,0x7d,0xfe,0x7f,0xf6,0x00, + 0x10,0x80,0x03,0x80,0x00,0x15,0x0c,0x00,0xff,0x7e, + 0x03,0xed,0x03,0xfd,0x00,0x03,0x02,0x00,0x00,0x12, + 0x02,0x03,0x0a,0x00,0x00,0x6b,0x02,0x00,0x00,0x7d, + 0xfe,0x83,0xf4,0x00,0x11,0x80,0x0f,0x80,0xf4,0x00, + 0x00,0x15,0x0c,0x00,0xff,0xf6,0xf5,0x00,0x0f,0xf5, + 0x04,0x95,0x07,0x76,0x00,0x0a,0x07,0x80,0xf9,0x76, + 0x00,0x75,0xf8,0x80,0x07,0x0c,0x09,0xf4,0xf9,0x0c, + 0x09,0xf4,0x03,0x92,0x02,0x03,0x07,0x00,0x03,0x7d, + 0x00,0x7b,0xfc,0x7e,0x04,0x7d,0x00,0x7a,0xfd,0x7e, + 0xf9,0x00,0xfe,0x02,0x06,0x89,0x02,0x00,0x06,0xf5, + 0x03,0x95,0x00,0x6b,0x0c,0x15,0x00,0x6b,0x02,0x80, + 0x03,0x95,0x00,0x6b,0x0c,0x15,0x00,0x6b,0xf8,0x96, + 0x03,0x00,0x07,0xea,0x03,0x80,0x00,0x15,0x0c,0x80, + 0xf7,0x76,0xfd,0x00,0x03,0x80,0x0a,0x75,0x03,0x80, + 0x03,0x80,0x07,0x13,0x02,0x02,0x03,0x00,0x00,0x6b, + 0x02,0x80,0x03,0x80,0x00,0x15,0x09,0x6b,0x09,0x15, + 0x00,0x6b,0x03,0x80,0x03,0x80,0x00,0x15,0x00,0xf6, + 0x0d,0x00,0x00,0x8a,0x00,0x6b,0x03,0x80,0x07,0x80, + 0xfd,0x00,0xff,0x03,0x00,0x04,0x00,0x07,0x00,0x04, + 0x01,0x02,0x03,0x01,0x06,0x00,0x03,0x7f,0x01,0x7e, + 0x01,0x7c,0x00,0x79,0xff,0x7c,0xff,0x7d,0xfd,0x00, + 0xfa,0x00,0x0e,0x80,0x03,0x80,0x00,0x15,0x0c,0x00, + 0x00,0x6b,0x02,0x80,0x03,0x80,0x00,0x15,0x0a,0x00, + 0x02,0x7f,0x01,0x7d,0x00,0x7b,0xff,0x7e,0xfe,0x7f, + 0xf6,0x00,0x10,0xf7,0x11,0x8f,0xff,0x03,0xff,0x02, + 0xfe,0x01,0xfa,0x00,0xfd,0x7f,0xff,0x7e,0x00,0x7c, + 0x00,0x79,0x00,0x7b,0x01,0x7e,0x03,0x00,0x06,0x00, + 0x02,0x00,0x01,0x03,0x01,0x02,0x03,0xfb,0x03,0x95, + 0x0c,0x00,0xfa,0x80,0x00,0x6b,0x09,0x80,0x03,0x95, + 0x00,0x77,0x06,0x7a,0x06,0x06,0x00,0x09,0xfa,0xf1, + 0xfa,0x7a,0x0e,0x80,0x03,0x87,0x00,0x0b,0x02,0x02, + 0x03,0x00,0x02,0x7e,0x01,0x02,0x04,0x00,0x02,0x7e, + 0x00,0x75,0xfe,0x7e,0xfc,0x00,0xff,0x01,0xfe,0x7f, + 0xfd,0x00,0xfe,0x02,0x07,0x8e,0x00,0x6b,0x09,0x80, + 0x03,0x80,0x0e,0x15,0xf2,0x80,0x0e,0x6b,0x03,0x80, + 0x03,0x95,0x00,0x6b,0x0e,0x00,0x00,0x7d,0xfe,0x98, + 0x00,0x6b,0x05,0x80,0x03,0x95,0x00,0x75,0x02,0x7d, + 0x0a,0x00,0x00,0x8e,0x00,0x6b,0x02,0x80,0x03,0x95, + 0x00,0x6b,0x10,0x00,0x00,0x15,0xf8,0x80,0x00,0x6b, + 0x0a,0x80,0x03,0x95,0x00,0x6b,0x10,0x00,0x00,0x15, + 0xf8,0x80,0x00,0x6b,0x0a,0x00,0x00,0x7d,0x02,0x83, + 0x10,0x80,0x03,0x95,0x00,0x6b,0x09,0x00,0x03,0x02, + 0x00,0x08,0xfd,0x02,0xf7,0x00,0x0e,0x89,0x00,0x6b, + 0x03,0x80,0x03,0x95,0x00,0x6b,0x09,0x00,0x03,0x02, + 0x00,0x08,0xfd,0x02,0xf7,0x00,0x0e,0xf4,0x03,0x92, + 0x02,0x03,0x07,0x00,0x03,0x7d,0x00,0x70,0xfd,0x7e, + 0xf9,0x00,0xfe,0x02,0x03,0x89,0x09,0x00,0x02,0xf5, + 0x03,0x80,0x00,0x15,0x00,0xf5,0x07,0x00,0x00,0x08, + 0x02,0x03,0x06,0x00,0x02,0x7d,0x00,0x70,0xfe,0x7e, + 0xfa,0x00,0xfe,0x02,0x00,0x08,0x0c,0xf6,0x0f,0x80, + 0x00,0x15,0xf6,0x00,0xfe,0x7d,0x00,0x79,0x02,0x7e, + 0x0a,0x00,0xf4,0xf7,0x07,0x09,0x07,0xf7,0x03,0x8c, + 0x01,0x02,0x01,0x01,0x05,0x00,0x02,0x7f,0x01,0x7e, + 0x00,0x74,0x00,0x86,0xff,0x01,0xfe,0x01,0xfb,0x00, + 0xff,0x7f,0xff,0x7f,0x00,0x7c,0x01,0x7e,0x01,0x00, + 0x05,0x00,0x02,0x00,0x01,0x02,0x03,0xfe,0x04,0x8e, + 0x02,0x01,0x04,0x00,0x02,0x7f,0x01,0x7e,0x00,0x77, + 0xff,0x7e,0xfe,0x7f,0xfc,0x00,0xfe,0x01,0xff,0x02, + 0x00,0x09,0x01,0x02,0x02,0x02,0x03,0x01,0x02,0x01, + 0x01,0x01,0x01,0x02,0x02,0xeb,0x03,0x80,0x00,0x15, + 0x03,0x00,0x02,0x7e,0x00,0x7b,0xfe,0x7e,0xfd,0x00, + 0x03,0x80,0x04,0x00,0x03,0x7e,0x00,0x78,0xfd,0x7e, + 0xf9,0x00,0x0c,0x80,0x03,0x8c,0x02,0x02,0x02,0x01, + 0x03,0x00,0x02,0x7f,0x01,0x7d,0xfe,0x7e,0xf9,0x7d, + 0xff,0x7e,0x00,0x7d,0x03,0x7f,0x02,0x00,0x03,0x01, + 0x02,0x01,0x02,0xfe,0x0d,0x8c,0xff,0x02,0xfe,0x01, + 0xfc,0x00,0xfe,0x7f,0xff,0x7e,0x00,0x77,0x01,0x7e, + 0x02,0x7f,0x04,0x00,0x02,0x01,0x01,0x02,0x00,0x0f, + 0xff,0x02,0xfe,0x01,0xf9,0x00,0x0c,0xeb,0x03,0x88, + 0x0a,0x00,0x00,0x02,0x00,0x03,0xfe,0x02,0xfa,0x00, + 0xff,0x7e,0xff,0x7d,0x00,0x7b,0x01,0x7c,0x01,0x7f, + 0x06,0x00,0x02,0x02,0x03,0xfe,0x03,0x8f,0x06,0x77, + 0x06,0x09,0xfa,0x80,0x00,0x71,0xff,0x87,0xfb,0x79, + 0x07,0x87,0x05,0x79,0x02,0x80,0x03,0x8d,0x02,0x02, + 0x06,0x00,0x02,0x7e,0x00,0x7d,0xfc,0x7d,0x04,0x7e, + 0x00,0x7d,0xfe,0x7e,0xfa,0x00,0xfe,0x02,0x04,0x85, + 0x02,0x00,0x06,0xf9,0x03,0x8f,0x00,0x73,0x01,0x7e, + 0x07,0x00,0x02,0x02,0x00,0x0d,0x00,0xf3,0x01,0x7e, + 0x03,0x80,0x03,0x8f,0x00,0x73,0x01,0x7e,0x07,0x00, + 0x02,0x02,0x00,0x0d,0x00,0xf3,0x01,0x7e,0xf8,0x90, + 0x03,0x00,0x08,0xf0,0x03,0x80,0x00,0x15,0x00,0xf3, + 0x02,0x00,0x06,0x07,0xfa,0xf9,0x07,0x78,0x03,0x80, + 0x03,0x80,0x04,0x0c,0x02,0x03,0x04,0x00,0x00,0x71, + 0x02,0x80,0x03,0x80,0x00,0x0f,0x06,0x77,0x06,0x09, + 0x00,0x71,0x02,0x80,0x03,0x80,0x00,0x0f,0x0a,0xf1, + 0x00,0x0f,0xf6,0xf8,0x0a,0x00,0x02,0xf9,0x05,0x80, + 0xff,0x01,0xff,0x04,0x00,0x05,0x01,0x03,0x01,0x02, + 0x06,0x00,0x02,0x7e,0x00,0x7d,0x00,0x7b,0x00,0x7c, + 0xfe,0x7f,0xfa,0x00,0x0b,0x80,0x03,0x80,0x00,0x0f, + 0x00,0xfb,0x01,0x03,0x01,0x02,0x05,0x00,0x02,0x7e, + 0x01,0x7d,0x00,0x76,0x03,0x80,0x10,0x80,0x10,0x80, + 0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80, + 0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80, + 0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80, + 0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80, + 0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80, + 0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80, + 0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80, + 0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80, + 0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80,0x10,0x80, + 0x10,0x80,0x0a,0x8f,0x02,0x7f,0x01,0x7e,0x00,0x76, + 0xff,0x7f,0xfe,0x7f,0xfb,0x00,0xff,0x01,0xff,0x01, + 0x00,0x0a,0x01,0x02,0x01,0x01,0x05,0x00,0xf9,0x80, + 0x00,0x6b,0x0c,0x86,0x0d,0x8a,0xff,0x03,0xfe,0x02, + 0xfb,0x00,0xff,0x7e,0xff,0x7d,0x00,0x7b,0x01,0x7c, + 0x01,0x7f,0x05,0x00,0x02,0x01,0x01,0x03,0x03,0xfc, + 0x03,0x80,0x00,0x0f,0x00,0xfb,0x01,0x03,0x01,0x02, + 0x04,0x00,0x01,0x7e,0x01,0x7d,0x00,0x76,0x00,0x8a, + 0x01,0x03,0x02,0x02,0x03,0x00,0x02,0x7e,0x01,0x7d, + 0x00,0x76,0x03,0x80,0x03,0x8f,0x00,0x74,0x01,0x7e, + 0x02,0x7f,0x04,0x00,0x02,0x01,0x01,0x01,0x00,0x8d, + 0x00,0x6e,0xff,0x7e,0xfe,0x7f,0xfb,0x00,0xfe,0x01, + 0x0c,0x85,0x03,0x8d,0x01,0x02,0x03,0x00,0x02,0x7e, + 0x01,0x02,0x03,0x00,0x02,0x7e,0x00,0x74,0xfe,0x7f, + 0xfd,0x00,0xff,0x01,0xfe,0x7f,0xfd,0x00,0xff,0x01, + 0x00,0x0c,0x06,0x82,0x00,0x6b,0x08,0x86,0x03,0x80, + 0x0a,0x0f,0xf6,0x80,0x0a,0x71,0x03,0x80,0x03,0x8f, + 0x00,0x73,0x01,0x7e,0x07,0x00,0x02,0x02,0x00,0x0d, + 0x00,0xf3,0x01,0x7e,0x00,0x7e,0x03,0x82,0x03,0x8f, + 0x00,0x79,0x02,0x7e,0x08,0x00,0x00,0x89,0x00,0x71, + 0x02,0x80,0x03,0x8f,0x00,0x73,0x01,0x7e,0x03,0x00, + 0x02,0x02,0x00,0x0d,0x00,0xf3,0x01,0x7e,0x03,0x00, + 0x02,0x02,0x00,0x0d,0x00,0xf3,0x01,0x7e,0x03,0x80, + 0x03,0x8f,0x00,0x73,0x01,0x7e,0x03,0x00,0x02,0x02, + 0x00,0x0d,0x00,0xf3,0x01,0x7e,0x03,0x00,0x02,0x02, + 0x00,0x0d,0x00,0xf3,0x01,0x7e,0x00,0x7e,0x03,0x82, + 0x03,0x8d,0x00,0x02,0x02,0x00,0x00,0x71,0x08,0x00, + 0x02,0x02,0x00,0x06,0xfe,0x02,0xf8,0x00,0x0c,0xf6, + 0x03,0x8f,0x00,0x71,0x07,0x00,0x02,0x02,0x00,0x06, + 0xfe,0x02,0xf9,0x00,0x0c,0x85,0x00,0x71,0x02,0x80, + 0x03,0x8f,0x00,0x71,0x07,0x00,0x03,0x02,0x00,0x06, + 0xfd,0x02,0xf9,0x00,0x0c,0xf6,0x03,0x8d,0x02,0x02, + 0x06,0x00,0x02,0x7e,0x00,0x75,0xfe,0x7e,0xfa,0x00, + 0xfe,0x02,0x04,0x85,0x06,0x00,0x02,0xf9,0x03,0x80, + 0x00,0x0f,0x00,0xf8,0x04,0x00,0x00,0x06,0x02,0x02, + 0x04,0x00,0x02,0x7e,0x00,0x75,0xfe,0x7e,0xfc,0x00, + 0xfe,0x02,0x00,0x05,0x0a,0xf9,0x0d,0x80,0x00,0x0f, + 0xf7,0x00,0xff,0x7e,0x00,0x7b,0x01,0x7e,0x09,0x00, + 0xf6,0xfa,0x04,0x06,0x08,0xfa + }; + + //------------------------------------------------------------------------- + gsv_text::gsv_text() : + m_x(0.0), + m_y(0.0), + m_start_x(0.0), + m_width(10.0), + m_height(0.0), + m_space(0.0), + m_line_space(0.0), + m_text(m_chr), + m_text_buf(), + m_cur_chr(m_chr), + m_font(gsv_default_font), + m_loaded_font(), + m_status(initial), + m_big_endian(false), + m_flip(false) + { + m_chr[0] = m_chr[1] = 0; + + int t = 1; + if(*(char*)&t == 0) m_big_endian = true; + } + + //------------------------------------------------------------------------- + void gsv_text::font(const void* font) + { + m_font = font; + if(m_font == 0) m_font = &m_loaded_font[0]; + } + + //------------------------------------------------------------------------- + void gsv_text::size(double height, double width) + { + m_height = height; + m_width = width; + } + + //------------------------------------------------------------------------- + void gsv_text::space(double space) + { + m_space = space; + } + + //------------------------------------------------------------------------- + void gsv_text::line_space(double line_space) + { + m_line_space = line_space; + } + + //------------------------------------------------------------------------- + void gsv_text::start_point(double x, double y) + { + m_x = m_start_x = x; + m_y = y; + //if(m_flip) m_y += m_height; + } + + //------------------------------------------------------------------------- + void gsv_text::load_font(const char* file) + { + m_loaded_font.resize(0); + FILE* fd = fopen(file, "rb"); + if(fd) + { + unsigned len; + + fseek(fd, 0l, SEEK_END); + len = ftell(fd); + fseek(fd, 0l, SEEK_SET); + if(len > 0) + { + m_loaded_font.resize(len); + fread(&m_loaded_font[0], 1, len, fd); + m_font = &m_loaded_font[0]; + } + fclose(fd); + } + } + + //------------------------------------------------------------------------- + void gsv_text::text(const char* text) + { + if(text == 0) + { + m_chr[0] = 0; + m_text = m_chr; + return; + } + unsigned new_size = strlen(text) + 1; + if(new_size > m_text_buf.size()) + { + m_text_buf.resize(new_size); + } + memcpy(&m_text_buf[0], text, new_size); + m_text = &m_text_buf[0]; + } + + //------------------------------------------------------------------------- + void gsv_text::rewind(unsigned) + { + m_status = initial; + if(m_font == 0) return; + + m_indices = (int8u*)m_font; + double base_height = value(m_indices + 4); + m_indices += value(m_indices); + m_glyphs = (int8*)(m_indices + 257*2); + m_h = m_height / base_height; + m_w = (m_width == 0.0) ? m_h : m_width / base_height; + if(m_flip) m_h = -m_h; + m_cur_chr = m_text; + } + + //------------------------------------------------------------------------- + unsigned gsv_text::vertex(double* x, double* y) + { + unsigned idx; + int8 yc, yf; + int dx, dy; + bool quit = false; + + while(!quit) + { + switch(m_status) + { + case initial: + if(m_font == 0) + { + quit = true; + break; + } + m_status = next_char; + + case next_char: + if(*m_cur_chr == 0) + { + quit = true; + break; + } + idx = (*m_cur_chr++) & 0xFF; + if(idx == '\n') + { + m_x = m_start_x; + m_y -= m_flip ? -m_height - m_line_space : m_height + m_line_space; + break; + } + idx <<= 1; + m_bglyph = m_glyphs + value(m_indices + idx); + m_eglyph = m_glyphs + value(m_indices + idx + 2); + m_status = start_glyph; + + case start_glyph: + *x = m_x; + *y = m_y; + m_status = glyph; + return path_cmd_move_to; + + case glyph: + if(m_bglyph >= m_eglyph) + { + m_status = next_char; + m_x += m_space; + break; + } + dx = int(*m_bglyph++); + yf = (yc = *m_bglyph++) & 0x80; + yc <<= 1; + yc >>= 1; + dy = int(yc); + m_x += double(dx) * m_w; + m_y += double(dy) * m_h; + *x = m_x; + *y = m_y; + return yf ? path_cmd_move_to : path_cmd_line_to; + } + + } + return path_cmd_stop; + } + + //------------------------------------------------------------------------- + double gsv_text::text_width() + { + double x1, y1, x2, y2; + bounding_rect_single(*this, 0, &x1, &y1, &x2, &y2); + return x2 - x1; + } + + +} diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_image_filters.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_image_filters.cpp new file mode 100644 index 00000000000..549d9adbf5a --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_image_filters.cpp @@ -0,0 +1,103 @@ +//---------------------------------------------------------------------------- +// 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 +//---------------------------------------------------------------------------- +// +// Filtering class image_filter_lut implemantation +// +//---------------------------------------------------------------------------- + + +#include "agg_image_filters.h" + + +namespace agg +{ + //-------------------------------------------------------------------- + void image_filter_lut::realloc_lut(double radius) + { + m_radius = radius; + m_diameter = uceil(radius) * 2; + m_start = -int(m_diameter / 2 - 1); + unsigned size = m_diameter << image_subpixel_shift; + if(size > m_weight_array.size()) + { + m_weight_array.resize(size); + } + } + + + + //-------------------------------------------------------------------- + // This function normalizes integer values and corrects the rounding + // errors. It doesn't do anything with the source floating point values + // (m_weight_array_dbl), it corrects only integers according to the rule + // of 1.0 which means that any sum of pixel weights must be equal to 1.0. + // So, the filter function must produce a graph of the proper shape. + //-------------------------------------------------------------------- + void image_filter_lut::normalize() + { + unsigned i; + int flip = 1; + + for(i = 0; i < image_subpixel_scale; i++) + { + for(;;) + { + int sum = 0; + unsigned j; + for(j = 0; j < m_diameter; j++) + { + sum += m_weight_array[j * image_subpixel_scale + i]; + } + + if(sum == image_filter_scale) break; + + double k = double(image_filter_scale) / double(sum); + sum = 0; + for(j = 0; j < m_diameter; j++) + { + sum += m_weight_array[j * image_subpixel_scale + i] = + iround(m_weight_array[j * image_subpixel_scale + i] * k); + } + + sum -= image_filter_scale; + int inc = (sum > 0) ? -1 : 1; + + for(j = 0; j < m_diameter && sum; j++) + { + flip ^= 1; + unsigned idx = flip ? m_diameter/2 + j/2 : m_diameter/2 - j/2; + int v = m_weight_array[idx * image_subpixel_scale + i]; + if(v < image_filter_scale) + { + m_weight_array[idx * image_subpixel_scale + i] += inc; + sum += inc; + } + } + } + } + + unsigned pivot = m_diameter << (image_subpixel_shift - 1); + + for(i = 0; i < pivot; i++) + { + m_weight_array[pivot + i] = m_weight_array[pivot - i]; + } + unsigned end = (diameter() << image_subpixel_shift) - 1; + m_weight_array[0] = m_weight_array[end]; + } + + +} + diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_line_aa_basics.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_line_aa_basics.cpp new file mode 100644 index 00000000000..018d65366f2 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_line_aa_basics.cpp @@ -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 +//---------------------------------------------------------------------------- + +#include <math.h> +#include "agg_line_aa_basics.h" + +namespace agg +{ + //------------------------------------------------------------------------- + // The number of the octant is determined as a 3-bit value as follows: + // bit 0 = vertical flag + // bit 1 = sx < 0 + // bit 2 = sy < 0 + // + // [N] shows the number of the orthogonal quadrant + // <M> shows the number of the diagonal quadrant + // <1> + // [1] | [0] + // . (3)011 | 001(1) . + // . | . + // . | . + // . | . + // (2)010 .|. 000(0) + // <2> ----------.+.----------- <0> + // (6)110 . | . 100(4) + // . | . + // . | . + // . | . + // (7)111 | 101(5) + // [2] | [3] + // <3> + // 0,1,2,3,4,5,6,7 + const int8u line_parameters::s_orthogonal_quadrant[8] = { 0,0,1,1,3,3,2,2 }; + const int8u line_parameters::s_diagonal_quadrant[8] = { 0,1,2,1,0,3,2,3 }; + + + + //------------------------------------------------------------------------- + void bisectrix(const line_parameters& l1, + const line_parameters& l2, + int* x, int* y) + { + double k = double(l2.len) / double(l1.len); + double tx = l2.x2 - (l2.x1 - l1.x1) * k; + double ty = l2.y2 - (l2.y1 - l1.y1) * k; + + //All bisectrices must be on the right of the line + //If the next point is on the left (l1 => l2.2) + //then the bisectix should be rotated by 180 degrees. + if(double(l2.x2 - l2.x1) * double(l2.y1 - l1.y1) < + double(l2.y2 - l2.y1) * double(l2.x1 - l1.x1) + 100.0) + { + tx -= (tx - l2.x1) * 2.0; + ty -= (ty - l2.y1) * 2.0; + } + + // Check if the bisectrix is too short + double dx = tx - l2.x1; + double dy = ty - l2.y1; + if((int)sqrt(dx * dx + dy * dy) < line_subpixel_scale) + { + *x = (l2.x1 + l2.x1 + (l2.y1 - l1.y1) + (l2.y2 - l2.y1)) >> 1; + *y = (l2.y1 + l2.y1 - (l2.x1 - l1.x1) - (l2.x2 - l2.x1)) >> 1; + return; + } + *x = iround(tx); + *y = iround(ty); + } + +} diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_line_profile_aa.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_line_profile_aa.cpp new file mode 100644 index 00000000000..6066662cb9d --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_line_profile_aa.cpp @@ -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 +//---------------------------------------------------------------------------- + +#include "agg_renderer_outline_aa.h" + +namespace agg +{ + + //--------------------------------------------------------------------- + void line_profile_aa::width(double w) + { + if(w < 0.0) w = 0.0; + + if(w < m_smoother_width) w += w; + else w += m_smoother_width; + + w *= 0.5; + + w -= m_smoother_width; + double s = m_smoother_width; + if(w < 0.0) + { + s += w; + w = 0.0; + } + set(w, s); + } + + + //--------------------------------------------------------------------- + line_profile_aa::value_type* line_profile_aa::profile(double w) + { + m_subpixel_width = uround(w * subpixel_scale); + unsigned size = m_subpixel_width + subpixel_scale * 6; + if(size > m_profile.size()) + { + m_profile.resize(size); + } + return &m_profile[0]; + } + + + //--------------------------------------------------------------------- + void line_profile_aa::set(double center_width, double smoother_width) + { + double base_val = 1.0; + if(center_width == 0.0) center_width = 1.0 / subpixel_scale; + if(smoother_width == 0.0) smoother_width = 1.0 / subpixel_scale; + + double width = center_width + smoother_width; + if(width < m_min_width) + { + double k = width / m_min_width; + base_val *= k; + center_width /= k; + smoother_width /= k; + } + + value_type* ch = profile(center_width + smoother_width); + + unsigned subpixel_center_width = unsigned(center_width * subpixel_scale); + unsigned subpixel_smoother_width = unsigned(smoother_width * subpixel_scale); + + value_type* ch_center = ch + subpixel_scale*2; + value_type* ch_smoother = ch_center + subpixel_center_width; + + unsigned i; + + unsigned val = m_gamma[unsigned(base_val * aa_mask)]; + ch = ch_center; + for(i = 0; i < subpixel_center_width; i++) + { + *ch++ = (value_type)val; + } + + for(i = 0; i < subpixel_smoother_width; i++) + { + *ch_smoother++ = + m_gamma[unsigned((base_val - + base_val * + (double(i) / subpixel_smoother_width)) * aa_mask)]; + } + + unsigned n_smoother = profile_size() - + subpixel_smoother_width - + subpixel_center_width - + subpixel_scale*2; + + val = m_gamma[0]; + for(i = 0; i < n_smoother; i++) + { + *ch_smoother++ = (value_type)val; + } + + ch = ch_center; + for(i = 0; i < subpixel_scale*2; i++) + { + *--ch = *ch_center++; + } + } + + +} + diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_rounded_rect.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_rounded_rect.cpp new file mode 100644 index 00000000000..bebc0636288 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_rounded_rect.cpp @@ -0,0 +1,164 @@ +//---------------------------------------------------------------------------- +// 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 +// +//---------------------------------------------------------------------------- + +#include <math.h> +#include "agg_rounded_rect.h" + + +namespace agg +{ + //------------------------------------------------------------------------ + rounded_rect::rounded_rect(double x1, double y1, double x2, double y2, double r) : + m_x1(x1), m_y1(y1), m_x2(x2), m_y2(y2), + m_rx1(r), m_ry1(r), m_rx2(r), m_ry2(r), + m_rx3(r), m_ry3(r), m_rx4(r), m_ry4(r) + { + if(x1 > x2) { m_x1 = x2; m_x2 = x1; } + if(y1 > y2) { m_y1 = y2; m_y2 = y1; } + } + + //-------------------------------------------------------------------- + void rounded_rect::rect(double x1, double y1, double x2, double y2) + { + m_x1 = x1; + m_y1 = y1; + m_x2 = x2; + m_y2 = y2; + if(x1 > x2) { m_x1 = x2; m_x2 = x1; } + if(y1 > y2) { m_y1 = y2; m_y2 = y1; } + } + + //-------------------------------------------------------------------- + void rounded_rect::radius(double r) + { + m_rx1 = m_ry1 = m_rx2 = m_ry2 = m_rx3 = m_ry3 = m_rx4 = m_ry4 = r; + } + + //-------------------------------------------------------------------- + void rounded_rect::radius(double rx, double ry) + { + m_rx1 = m_rx2 = m_rx3 = m_rx4 = rx; + m_ry1 = m_ry2 = m_ry3 = m_ry4 = ry; + } + + //-------------------------------------------------------------------- + void rounded_rect::radius(double rx_bottom, double ry_bottom, + double rx_top, double ry_top) + { + m_rx1 = m_rx2 = rx_bottom; + m_rx3 = m_rx4 = rx_top; + m_ry1 = m_ry2 = ry_bottom; + m_ry3 = m_ry4 = ry_top; + } + + //-------------------------------------------------------------------- + void rounded_rect::radius(double rx1, double ry1, double rx2, double ry2, + double rx3, double ry3, double rx4, double ry4) + { + m_rx1 = rx1; m_ry1 = ry1; m_rx2 = rx2; m_ry2 = ry2; + m_rx3 = rx3; m_ry3 = ry3; m_rx4 = rx4; m_ry4 = ry4; + } + + //-------------------------------------------------------------------- + void rounded_rect::normalize_radius() + { + double dx = fabs(m_y2 - m_y1); + double dy = fabs(m_x2 - m_x1); + + double k = 1.0; + double t; + t = dx / (m_rx1 + m_rx2); if(t < k) k = t; + t = dx / (m_rx3 + m_rx4); if(t < k) k = t; + t = dy / (m_ry1 + m_ry2); if(t < k) k = t; + t = dy / (m_ry3 + m_ry4); if(t < k) k = t; + + if(k < 1.0) + { + m_rx1 *= k; m_ry1 *= k; m_rx2 *= k; m_ry2 *= k; + m_rx3 *= k; m_ry3 *= k; m_rx4 *= k; m_ry4 *= k; + } + } + + //-------------------------------------------------------------------- + void rounded_rect::rewind(unsigned) + { + m_status = 0; + } + + //-------------------------------------------------------------------- + unsigned rounded_rect::vertex(double* x, double* y) + { + unsigned cmd = path_cmd_stop; + switch(m_status) + { + case 0: + m_arc.init(m_x1 + m_rx1, m_y1 + m_ry1, m_rx1, m_ry1, + pi, pi+pi*0.5); + m_arc.rewind(0); + m_status++; + + case 1: + cmd = m_arc.vertex(x, y); + if(is_stop(cmd)) m_status++; + else return cmd; + + case 2: + m_arc.init(m_x2 - m_rx2, m_y1 + m_ry2, m_rx2, m_ry2, + pi+pi*0.5, 0.0); + m_arc.rewind(0); + m_status++; + + case 3: + cmd = m_arc.vertex(x, y); + if(is_stop(cmd)) m_status++; + else return path_cmd_line_to; + + case 4: + m_arc.init(m_x2 - m_rx3, m_y2 - m_ry3, m_rx3, m_ry3, + 0.0, pi*0.5); + m_arc.rewind(0); + m_status++; + + case 5: + cmd = m_arc.vertex(x, y); + if(is_stop(cmd)) m_status++; + else return path_cmd_line_to; + + case 6: + m_arc.init(m_x1 + m_rx4, m_y2 - m_ry4, m_rx4, m_ry4, + pi*0.5, pi); + m_arc.rewind(0); + m_status++; + + case 7: + cmd = m_arc.vertex(x, y); + if(is_stop(cmd)) m_status++; + else return path_cmd_line_to; + + case 8: + cmd = path_cmd_end_poly | path_flags_close | path_flags_ccw; + m_status++; + break; + } + return cmd; + } + + +} + diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_sqrt_tables.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_sqrt_tables.cpp new file mode 100644 index 00000000000..19a1bd8cb79 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_sqrt_tables.cpp @@ -0,0 +1,115 @@ +//---------------------------------------------------------------------------- +// 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 +//---------------------------------------------------------------------------- +// +// static tables for fast integer sqrt +// +//---------------------------------------------------------------------------- + +#include "agg_basics.h" + +namespace agg +{ + int16u g_sqrt_table[1024] = //----------g_sqrt_table + { + 0, + 2048,2896,3547,4096,4579,5017,5418,5793,6144,6476,6792,7094,7384,7663,7932,8192,8444, + 8689,8927,9159,9385,9606,9822,10033,10240,10443,10642,10837,11029,11217,11403,11585, + 11765,11942,12116,12288,12457,12625,12790,12953,13114,13273,13430,13585,13738,13890, + 14040,14189,14336,14482,14626,14768,14910,15050,15188,15326,15462,15597,15731,15864, + 15995,16126,16255,16384,16512,16638,16764,16888,17012,17135,17257,17378,17498,17618, + 17736,17854,17971,18087,18203,18318,18432,18545,18658,18770,18882,18992,19102,19212, + 19321,19429,19537,19644,19750,19856,19961,20066,20170,20274,20377,20480,20582,20684, + 20785,20886,20986,21085,21185,21283,21382,21480,21577,21674,21771,21867,21962,22058, + 22153,22247,22341,22435,22528,22621,22713,22806,22897,22989,23080,23170,23261,23351, + 23440,23530,23619,23707,23796,23884,23971,24059,24146,24232,24319,24405,24491,24576, + 24661,24746,24831,24915,24999,25083,25166,25249,25332,25415,25497,25580,25661,25743, + 25824,25905,25986,26067,26147,26227,26307,26387,26466,26545,26624,26703,26781,26859, + 26937,27015,27092,27170,27247,27324,27400,27477,27553,27629,27705,27780,27856,27931, + 28006,28081,28155,28230,28304,28378,28452,28525,28599,28672,28745,28818,28891,28963, + 29035,29108,29180,29251,29323,29394,29466,29537,29608,29678,29749,29819,29890,29960, + 30030,30099,30169,30238,30308,30377,30446,30515,30583,30652,30720,30788,30856,30924, + 30992,31059,31127,31194,31261,31328,31395,31462,31529,31595,31661,31727,31794,31859, + 31925,31991,32056,32122,32187,32252,32317,32382,32446,32511,32575,32640,32704,32768, + 32832,32896,32959,33023,33086,33150,33213,33276,33339,33402,33465,33527,33590,33652, + 33714,33776,33839,33900,33962,34024,34086,34147,34208,34270,34331,34392,34453,34514, + 34574,34635,34695,34756,34816,34876,34936,34996,35056,35116,35176,35235,35295,35354, + 35413,35472,35531,35590,35649,35708,35767,35825,35884,35942,36001,36059,36117,36175, + 36233,36291,36348,36406,36464,36521,36578,36636,36693,36750,36807,36864,36921,36978, + 37034,37091,37147,37204,37260,37316,37372,37429,37485,37540,37596,37652,37708,37763, + 37819,37874,37929,37985,38040,38095,38150,38205,38260,38315,38369,38424,38478,38533, + 38587,38642,38696,38750,38804,38858,38912,38966,39020,39073,39127,39181,39234,39287, + 39341,39394,39447,39500,39553,39606,39659,39712,39765,39818,39870,39923,39975,40028, + 40080,40132,40185,40237,40289,40341,40393,40445,40497,40548,40600,40652,40703,40755, + 40806,40857,40909,40960,41011,41062,41113,41164,41215,41266,41317,41368,41418,41469, + 41519,41570,41620,41671,41721,41771,41821,41871,41922,41972,42021,42071,42121,42171, + 42221,42270,42320,42369,42419,42468,42518,42567,42616,42665,42714,42763,42813,42861, + 42910,42959,43008,43057,43105,43154,43203,43251,43300,43348,43396,43445,43493,43541, + 43589,43637,43685,43733,43781,43829,43877,43925,43972,44020,44068,44115,44163,44210, + 44258,44305,44352,44400,44447,44494,44541,44588,44635,44682,44729,44776,44823,44869, + 44916,44963,45009,45056,45103,45149,45195,45242,45288,45334,45381,45427,45473,45519, + 45565,45611,45657,45703,45749,45795,45840,45886,45932,45977,46023,46069,46114,46160, + 46205,46250,46296,46341,46386,46431,46477,46522,46567,46612,46657,46702,46746,46791, + 46836,46881,46926,46970,47015,47059,47104,47149,47193,47237,47282,47326,47370,47415, + 47459,47503,47547,47591,47635,47679,47723,47767,47811,47855,47899,47942,47986,48030, + 48074,48117,48161,48204,48248,48291,48335,48378,48421,48465,48508,48551,48594,48637, + 48680,48723,48766,48809,48852,48895,48938,48981,49024,49067,49109,49152,49195,49237, + 49280,49322,49365,49407,49450,49492,49535,49577,49619,49661,49704,49746,49788,49830, + 49872,49914,49956,49998,50040,50082,50124,50166,50207,50249,50291,50332,50374,50416, + 50457,50499,50540,50582,50623,50665,50706,50747,50789,50830,50871,50912,50954,50995, + 51036,51077,51118,51159,51200,51241,51282,51323,51364,51404,51445,51486,51527,51567, + 51608,51649,51689,51730,51770,51811,51851,51892,51932,51972,52013,52053,52093,52134, + 52174,52214,52254,52294,52334,52374,52414,52454,52494,52534,52574,52614,52654,52694, + 52734,52773,52813,52853,52892,52932,52972,53011,53051,53090,53130,53169,53209,53248, + 53287,53327,53366,53405,53445,53484,53523,53562,53601,53640,53679,53719,53758,53797, + 53836,53874,53913,53952,53991,54030,54069,54108,54146,54185,54224,54262,54301,54340, + 54378,54417,54455,54494,54532,54571,54609,54647,54686,54724,54762,54801,54839,54877, + 54915,54954,54992,55030,55068,55106,55144,55182,55220,55258,55296,55334,55372,55410, + 55447,55485,55523,55561,55599,55636,55674,55712,55749,55787,55824,55862,55900,55937, + 55975,56012,56049,56087,56124,56162,56199,56236,56273,56311,56348,56385,56422,56459, + 56497,56534,56571,56608,56645,56682,56719,56756,56793,56830,56867,56903,56940,56977, + 57014,57051,57087,57124,57161,57198,57234,57271,57307,57344,57381,57417,57454,57490, + 57527,57563,57599,57636,57672,57709,57745,57781,57817,57854,57890,57926,57962,57999, + 58035,58071,58107,58143,58179,58215,58251,58287,58323,58359,58395,58431,58467,58503, + 58538,58574,58610,58646,58682,58717,58753,58789,58824,58860,58896,58931,58967,59002, + 59038,59073,59109,59144,59180,59215,59251,59286,59321,59357,59392,59427,59463,59498, + 59533,59568,59603,59639,59674,59709,59744,59779,59814,59849,59884,59919,59954,59989, + 60024,60059,60094,60129,60164,60199,60233,60268,60303,60338,60373,60407,60442,60477, + 60511,60546,60581,60615,60650,60684,60719,60753,60788,60822,60857,60891,60926,60960, + 60995,61029,61063,61098,61132,61166,61201,61235,61269,61303,61338,61372,61406,61440, + 61474,61508,61542,61576,61610,61644,61678,61712,61746,61780,61814,61848,61882,61916, + 61950,61984,62018,62051,62085,62119,62153,62186,62220,62254,62287,62321,62355,62388, + 62422,62456,62489,62523,62556,62590,62623,62657,62690,62724,62757,62790,62824,62857, + 62891,62924,62957,62991,63024,63057,63090,63124,63157,63190,63223,63256,63289,63323, + 63356,63389,63422,63455,63488,63521,63554,63587,63620,63653,63686,63719,63752,63785, + 63817,63850,63883,63916,63949,63982,64014,64047,64080,64113,64145,64178,64211,64243, + 64276,64309,64341,64374,64406,64439,64471,64504,64536,64569,64601,64634,64666,64699, + 64731,64763,64796,64828,64861,64893,64925,64957,64990,65022,65054,65086,65119,65151, + 65183,65215,65247,65279,65312,65344,65376,65408,65440,65472,65504 + }; + + + int8 g_elder_bit_table[256] = //---------g_elder_bit_table + { + 0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4, + 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7, + 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7 + }; + +} diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_trans_affine.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_trans_affine.cpp new file mode 100644 index 00000000000..99febc953a1 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_trans_affine.cpp @@ -0,0 +1,194 @@ +//---------------------------------------------------------------------------- +// 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 +//---------------------------------------------------------------------------- +// +// Affine transformations +// +//---------------------------------------------------------------------------- +#include "agg_trans_affine.h" + + + +namespace agg +{ + + //------------------------------------------------------------------------ + const trans_affine& trans_affine::parl_to_parl(const double* src, + const double* dst) + { + sx = src[2] - src[0]; + shy = src[3] - src[1]; + shx = src[4] - src[0]; + sy = src[5] - src[1]; + tx = src[0]; + ty = src[1]; + invert(); + multiply(trans_affine(dst[2] - dst[0], dst[3] - dst[1], + dst[4] - dst[0], dst[5] - dst[1], + dst[0], dst[1])); + return *this; + } + + //------------------------------------------------------------------------ + const trans_affine& trans_affine::rect_to_parl(double x1, double y1, + double x2, double y2, + const double* parl) + { + double src[6]; + src[0] = x1; src[1] = y1; + src[2] = x2; src[3] = y1; + src[4] = x2; src[5] = y2; + parl_to_parl(src, parl); + return *this; + } + + //------------------------------------------------------------------------ + const trans_affine& trans_affine::parl_to_rect(const double* parl, + double x1, double y1, + double x2, double y2) + { + double dst[6]; + dst[0] = x1; dst[1] = y1; + dst[2] = x2; dst[3] = y1; + dst[4] = x2; dst[5] = y2; + parl_to_parl(parl, dst); + return *this; + } + + //------------------------------------------------------------------------ + const trans_affine& trans_affine::multiply(const trans_affine& m) + { + double t0 = sx * m.sx + shy * m.shx; + double t2 = shx * m.sx + sy * m.shx; + double t4 = tx * m.sx + ty * m.shx + m.tx; + shy = sx * m.shy + shy * m.sy; + sy = shx * m.shy + sy * m.sy; + ty = tx * m.shy + ty * m.sy + m.ty; + sx = t0; + shx = t2; + tx = t4; + return *this; + } + + + //------------------------------------------------------------------------ + const trans_affine& trans_affine::invert() + { + double d = determinant_reciprocal(); + + double t0 = sy * d; + sy = sx * d; + shy = -shy * d; + shx = -shx * d; + + double t4 = -tx * t0 - ty * shx; + ty = -tx * shy - ty * sy; + + sx = t0; + tx = t4; + return *this; + } + + + //------------------------------------------------------------------------ + const trans_affine& trans_affine::flip_x() + { + sx = -sx; + shy = -shy; + tx = -tx; + return *this; + } + + //------------------------------------------------------------------------ + const trans_affine& trans_affine::flip_y() + { + shx = -shx; + sy = -sy; + ty = -ty; + return *this; + } + + //------------------------------------------------------------------------ + const trans_affine& trans_affine::reset() + { + sx = sy = 1.0; + shy = shx = tx = ty = 0.0; + return *this; + } + + //------------------------------------------------------------------------ + bool trans_affine::is_identity(double epsilon) const + { + return is_equal_eps(sx, 1.0, epsilon) && + is_equal_eps(shy, 0.0, epsilon) && + is_equal_eps(shx, 0.0, epsilon) && + is_equal_eps(sy, 1.0, epsilon) && + is_equal_eps(tx, 0.0, epsilon) && + is_equal_eps(ty, 0.0, epsilon); + } + + //------------------------------------------------------------------------ + bool trans_affine::is_valid(double epsilon) const + { + return fabs(sx) > epsilon && fabs(sy) > epsilon; + } + + //------------------------------------------------------------------------ + bool trans_affine::is_equal(const trans_affine& m, double epsilon) const + { + return is_equal_eps(sx, m.sx, epsilon) && + is_equal_eps(shy, m.shy, epsilon) && + is_equal_eps(shx, m.shx, epsilon) && + is_equal_eps(sy, m.sy, epsilon) && + is_equal_eps(tx, m.tx, epsilon) && + is_equal_eps(ty, m.ty, epsilon); + } + + //------------------------------------------------------------------------ + double trans_affine::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_affine::translation(double* dx, double* dy) const + { + *dx = tx; + *dy = ty; + } + + //------------------------------------------------------------------------ + void trans_affine::scaling(double* x, double* y) const + { + double x1 = 0.0; + double y1 = 0.0; + double x2 = 1.0; + double y2 = 1.0; + trans_affine t(*this); + t *= trans_affine_rotation(-rotation()); + t.transform(&x1, &y1); + t.transform(&x2, &y2); + *x = x2 - x1; + *y = y2 - y1; + } + + +} + diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_trans_double_path.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_trans_double_path.cpp new file mode 100644 index 00000000000..cd40c7f5869 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_trans_double_path.cpp @@ -0,0 +1,273 @@ +//---------------------------------------------------------------------------- +// 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 +//---------------------------------------------------------------------------- + +#include "agg_math.h" +#include "agg_trans_double_path.h" + +namespace agg +{ + + //------------------------------------------------------------------------ + trans_double_path::trans_double_path() : + m_kindex1(0.0), + m_kindex2(0.0), + m_base_length(0.0), + m_base_height(1.0), + m_status1(initial), + m_status2(initial), + m_preserve_x_scale(true) + { + } + + + //------------------------------------------------------------------------ + void trans_double_path::reset() + { + m_src_vertices1.remove_all(); + m_src_vertices2.remove_all(); + m_kindex1 = 0.0; + m_kindex1 = 0.0; + m_status1 = initial; + m_status2 = initial; + } + + + //------------------------------------------------------------------------ + void trans_double_path::move_to1(double x, double y) + { + if(m_status1 == initial) + { + m_src_vertices1.modify_last(vertex_dist(x, y)); + m_status1 = making_path; + } + else + { + line_to1(x, y); + } + } + + + //------------------------------------------------------------------------ + void trans_double_path::line_to1(double x, double y) + { + if(m_status1 == making_path) + { + m_src_vertices1.add(vertex_dist(x, y)); + } + } + + + //------------------------------------------------------------------------ + void trans_double_path::move_to2(double x, double y) + { + if(m_status2 == initial) + { + m_src_vertices2.modify_last(vertex_dist(x, y)); + m_status2 = making_path; + } + else + { + line_to2(x, y); + } + } + + + //------------------------------------------------------------------------ + void trans_double_path::line_to2(double x, double y) + { + if(m_status2 == making_path) + { + m_src_vertices2.add(vertex_dist(x, y)); + } + } + + + //------------------------------------------------------------------------ + double trans_double_path::finalize_path(vertex_storage& vertices) + { + unsigned i; + double dist; + double d; + + vertices.close(false); + if(vertices.size() > 2) + { + if(vertices[vertices.size() - 2].dist * 10.0 < + vertices[vertices.size() - 3].dist) + { + d = vertices[vertices.size() - 3].dist + + vertices[vertices.size() - 2].dist; + + vertices[vertices.size() - 2] = + vertices[vertices.size() - 1]; + + vertices.remove_last(); + vertices[vertices.size() - 2].dist = d; + } + } + + dist = 0; + for(i = 0; i < vertices.size(); i++) + { + vertex_dist& v = vertices[i]; + d = v.dist; + v.dist = dist; + dist += d; + } + + return (vertices.size() - 1) / dist; + } + + + //------------------------------------------------------------------------ + void trans_double_path::finalize_paths() + { + if(m_status1 == making_path && m_src_vertices1.size() > 1 && + m_status2 == making_path && m_src_vertices2.size() > 1) + { + m_kindex1 = finalize_path(m_src_vertices1); + m_kindex2 = finalize_path(m_src_vertices2); + m_status1 = ready; + m_status2 = ready; + } + } + + + //------------------------------------------------------------------------ + double trans_double_path::total_length1() const + { + if(m_base_length >= 1e-10) return m_base_length; + return (m_status1 == ready) ? + m_src_vertices1[m_src_vertices1.size() - 1].dist : + 0.0; + } + + + //------------------------------------------------------------------------ + double trans_double_path::total_length2() const + { + if(m_base_length >= 1e-10) return m_base_length; + return (m_status2 == ready) ? + m_src_vertices2[m_src_vertices2.size() - 1].dist : + 0.0; + } + + + //------------------------------------------------------------------------ + void trans_double_path::transform1(const vertex_storage& vertices, + double kindex, double kx, + double *x, double* y) const + { + double x1 = 0.0; + double y1 = 0.0; + double dx = 1.0; + double dy = 1.0; + double d = 0.0; + double dd = 1.0; + *x *= kx; + if(*x < 0.0) + { + // Extrapolation on the left + //-------------------------- + x1 = vertices[0].x; + y1 = vertices[0].y; + dx = vertices[1].x - x1; + dy = vertices[1].y - y1; + dd = vertices[1].dist - vertices[0].dist; + d = *x; + } + else + if(*x > vertices[vertices.size() - 1].dist) + { + // Extrapolation on the right + //-------------------------- + unsigned i = vertices.size() - 2; + unsigned j = vertices.size() - 1; + x1 = vertices[j].x; + y1 = vertices[j].y; + dx = x1 - vertices[i].x; + dy = y1 - vertices[i].y; + dd = vertices[j].dist - vertices[i].dist; + d = *x - vertices[j].dist; + } + else + { + // Interpolation + //-------------------------- + unsigned i = 0; + unsigned j = vertices.size() - 1; + if(m_preserve_x_scale) + { + unsigned k; + for(i = 0; (j - i) > 1; ) + { + if(*x < vertices[k = (i + j) >> 1].dist) + { + j = k; + } + else + { + i = k; + } + } + d = vertices[i].dist; + dd = vertices[j].dist - d; + d = *x - d; + } + else + { + i = unsigned(*x * kindex); + j = i + 1; + dd = vertices[j].dist - vertices[i].dist; + d = ((*x * kindex) - i) * dd; + } + x1 = vertices[i].x; + y1 = vertices[i].y; + dx = vertices[j].x - x1; + dy = vertices[j].y - y1; + } + *x = x1 + dx * d / dd; + *y = y1 + dy * d / dd; + } + + + //------------------------------------------------------------------------ + void trans_double_path::transform(double *x, double *y) const + { + if(m_status1 == ready && m_status2 == ready) + { + if(m_base_length > 1e-10) + { + *x *= m_src_vertices1[m_src_vertices1.size() - 1].dist / + m_base_length; + } + + double x1 = *x; + double y1 = *y; + double x2 = *x; + double y2 = *y; + double dd = m_src_vertices2[m_src_vertices2.size() - 1].dist / + m_src_vertices1[m_src_vertices1.size() - 1].dist; + + transform1(m_src_vertices1, m_kindex1, 1.0, &x1, &y1); + transform1(m_src_vertices2, m_kindex2, dd, &x2, &y2); + + *x = x1 + *y * (x2 - x1) / m_base_height; + *y = y1 + *y * (y2 - y1) / m_base_height; + } + } + +} + diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_trans_single_path.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_trans_single_path.cpp new file mode 100644 index 00000000000..2120fc9b9b6 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_trans_single_path.cpp @@ -0,0 +1,202 @@ +//---------------------------------------------------------------------------- +// 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 +//---------------------------------------------------------------------------- + +#include "agg_math.h" +#include "agg_vertex_sequence.h" +#include "agg_trans_single_path.h" + +namespace agg +{ + + //------------------------------------------------------------------------ + trans_single_path::trans_single_path() : + m_base_length(0.0), + m_kindex(0.0), + m_status(initial), + m_preserve_x_scale(true) + { + } + + //------------------------------------------------------------------------ + void trans_single_path::reset() + { + m_src_vertices.remove_all(); + m_kindex = 0.0; + m_status = initial; + } + + //------------------------------------------------------------------------ + void trans_single_path::move_to(double x, double y) + { + if(m_status == initial) + { + m_src_vertices.modify_last(vertex_dist(x, y)); + m_status = making_path; + } + else + { + line_to(x, y); + } + } + + //------------------------------------------------------------------------ + void trans_single_path::line_to(double x, double y) + { + if(m_status == making_path) + { + m_src_vertices.add(vertex_dist(x, y)); + } + } + + + //------------------------------------------------------------------------ + void trans_single_path::finalize_path() + { + if(m_status == making_path && m_src_vertices.size() > 1) + { + unsigned i; + double dist; + double d; + + m_src_vertices.close(false); + if(m_src_vertices.size() > 2) + { + if(m_src_vertices[m_src_vertices.size() - 2].dist * 10.0 < + m_src_vertices[m_src_vertices.size() - 3].dist) + { + d = m_src_vertices[m_src_vertices.size() - 3].dist + + m_src_vertices[m_src_vertices.size() - 2].dist; + + m_src_vertices[m_src_vertices.size() - 2] = + m_src_vertices[m_src_vertices.size() - 1]; + + m_src_vertices.remove_last(); + m_src_vertices[m_src_vertices.size() - 2].dist = d; + } + } + + dist = 0.0; + for(i = 0; i < m_src_vertices.size(); i++) + { + vertex_dist& v = m_src_vertices[i]; + double d = v.dist; + v.dist = dist; + dist += d; + } + m_kindex = (m_src_vertices.size() - 1) / dist; + m_status = ready; + } + } + + + + //------------------------------------------------------------------------ + double trans_single_path::total_length() const + { + if(m_base_length >= 1e-10) return m_base_length; + return (m_status == ready) ? + m_src_vertices[m_src_vertices.size() - 1].dist : + 0.0; + } + + + //------------------------------------------------------------------------ + void trans_single_path::transform(double *x, double *y) const + { + if(m_status == ready) + { + if(m_base_length > 1e-10) + { + *x *= m_src_vertices[m_src_vertices.size() - 1].dist / + m_base_length; + } + + double x1 = 0.0; + double y1 = 0.0; + double dx = 1.0; + double dy = 1.0; + double d = 0.0; + double dd = 1.0; + if(*x < 0.0) + { + // Extrapolation on the left + //-------------------------- + x1 = m_src_vertices[0].x; + y1 = m_src_vertices[0].y; + dx = m_src_vertices[1].x - x1; + dy = m_src_vertices[1].y - y1; + dd = m_src_vertices[1].dist - m_src_vertices[0].dist; + d = *x; + } + else + if(*x > m_src_vertices[m_src_vertices.size() - 1].dist) + { + // Extrapolation on the right + //-------------------------- + unsigned i = m_src_vertices.size() - 2; + unsigned j = m_src_vertices.size() - 1; + x1 = m_src_vertices[j].x; + y1 = m_src_vertices[j].y; + dx = x1 - m_src_vertices[i].x; + dy = y1 - m_src_vertices[i].y; + dd = m_src_vertices[j].dist - m_src_vertices[i].dist; + d = *x - m_src_vertices[j].dist; + } + else + { + // Interpolation + //-------------------------- + unsigned i = 0; + unsigned j = m_src_vertices.size() - 1; + if(m_preserve_x_scale) + { + unsigned k; + for(i = 0; (j - i) > 1; ) + { + if(*x < m_src_vertices[k = (i + j) >> 1].dist) + { + j = k; + } + else + { + i = k; + } + } + d = m_src_vertices[i].dist; + dd = m_src_vertices[j].dist - d; + d = *x - d; + } + else + { + i = unsigned(*x * m_kindex); + j = i + 1; + dd = m_src_vertices[j].dist - m_src_vertices[i].dist; + d = ((*x * m_kindex) - i) * dd; + } + x1 = m_src_vertices[i].x; + y1 = m_src_vertices[i].y; + dx = m_src_vertices[j].x - x1; + dy = m_src_vertices[j].y - y1; + } + double x2 = x1 + dx * d / dd; + double y2 = y1 + dy * d / dd; + *x = x2 - *y * dy / dd; + *y = y2 + *y * dx / dd; + } + } + + +} + diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_trans_warp_magnifier.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_trans_warp_magnifier.cpp new file mode 100644 index 00000000000..e65afabba78 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_trans_warp_magnifier.cpp @@ -0,0 +1,70 @@ +//---------------------------------------------------------------------------- +// 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 +//---------------------------------------------------------------------------- + +#include <math.h> +#include "agg_trans_warp_magnifier.h" + +namespace agg +{ + + //------------------------------------------------------------------------ + void trans_warp_magnifier::transform(double* x, double* y) const + { + double dx = *x - m_xc; + double dy = *y - m_yc; + double r = sqrt(dx * dx + dy * dy); + if(r < m_radius) + { + *x = m_xc + dx * m_magn; + *y = m_yc + dy * m_magn; + return; + } + + double m = (r + m_radius * (m_magn - 1.0)) / r; + *x = m_xc + dx * m; + *y = m_yc + dy * m; + } + + //------------------------------------------------------------------------ + void trans_warp_magnifier::inverse_transform(double* x, double* y) const + { + // New version by Andrew Skalkin + //----------------- + double dx = *x - m_xc; + double dy = *y - m_yc; + double r = sqrt(dx * dx + dy * dy); + + if(r < m_radius * m_magn) + { + *x = m_xc + dx / m_magn; + *y = m_yc + dy / m_magn; + } + else + { + double rnew = r - m_radius * (m_magn - 1.0); + *x = m_xc + rnew * dx / r; + *y = m_yc + rnew * dy / r; + } + + // Old version + //----------------- + //trans_warp_magnifier t(*this); + //t.magnification(1.0 / m_magn); + //t.radius(m_radius * m_magn); + //t.transform(x, y); + } + + +} diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vcgen_bspline.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vcgen_bspline.cpp new file mode 100644 index 00000000000..4a0be6693ee --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vcgen_bspline.cpp @@ -0,0 +1,194 @@ +//---------------------------------------------------------------------------- +// 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 +//---------------------------------------------------------------------------- + +#include "agg_vcgen_bspline.h" + +namespace agg +{ + + //------------------------------------------------------------------------ + vcgen_bspline::vcgen_bspline() : + m_src_vertices(), + m_spline_x(), + m_spline_y(), + m_interpolation_step(1.0/50.0), + m_closed(0), + m_status(initial), + m_src_vertex(0) + { + } + + + //------------------------------------------------------------------------ + void vcgen_bspline::remove_all() + { + m_src_vertices.remove_all(); + m_closed = 0; + m_status = initial; + m_src_vertex = 0; + } + + + //------------------------------------------------------------------------ + void vcgen_bspline::add_vertex(double x, double y, unsigned cmd) + { + m_status = initial; + if(is_move_to(cmd)) + { + m_src_vertices.modify_last(point_d(x, y)); + } + else + { + if(is_vertex(cmd)) + { + m_src_vertices.add(point_d(x, y)); + } + else + { + m_closed = get_close_flag(cmd); + } + } + } + + + //------------------------------------------------------------------------ + void vcgen_bspline::rewind(unsigned) + { + m_cur_abscissa = 0.0; + m_max_abscissa = 0.0; + m_src_vertex = 0; + if(m_status == initial && m_src_vertices.size() > 2) + { + if(m_closed) + { + m_spline_x.init(m_src_vertices.size() + 8); + m_spline_y.init(m_src_vertices.size() + 8); + m_spline_x.add_point(0.0, m_src_vertices.prev(m_src_vertices.size() - 3).x); + m_spline_y.add_point(0.0, m_src_vertices.prev(m_src_vertices.size() - 3).y); + m_spline_x.add_point(1.0, m_src_vertices[m_src_vertices.size() - 3].x); + m_spline_y.add_point(1.0, m_src_vertices[m_src_vertices.size() - 3].y); + m_spline_x.add_point(2.0, m_src_vertices[m_src_vertices.size() - 2].x); + m_spline_y.add_point(2.0, m_src_vertices[m_src_vertices.size() - 2].y); + m_spline_x.add_point(3.0, m_src_vertices[m_src_vertices.size() - 1].x); + m_spline_y.add_point(3.0, m_src_vertices[m_src_vertices.size() - 1].y); + } + else + { + m_spline_x.init(m_src_vertices.size()); + m_spline_y.init(m_src_vertices.size()); + } + unsigned i; + for(i = 0; i < m_src_vertices.size(); i++) + { + double x = m_closed ? i + 4 : i; + m_spline_x.add_point(x, m_src_vertices[i].x); + m_spline_y.add_point(x, m_src_vertices[i].y); + } + m_cur_abscissa = 0.0; + m_max_abscissa = m_src_vertices.size() - 1; + if(m_closed) + { + m_cur_abscissa = 4.0; + m_max_abscissa += 5.0; + m_spline_x.add_point(m_src_vertices.size() + 4, m_src_vertices[0].x); + m_spline_y.add_point(m_src_vertices.size() + 4, m_src_vertices[0].y); + m_spline_x.add_point(m_src_vertices.size() + 5, m_src_vertices[1].x); + m_spline_y.add_point(m_src_vertices.size() + 5, m_src_vertices[1].y); + m_spline_x.add_point(m_src_vertices.size() + 6, m_src_vertices[2].x); + m_spline_y.add_point(m_src_vertices.size() + 6, m_src_vertices[2].y); + m_spline_x.add_point(m_src_vertices.size() + 7, m_src_vertices.next(2).x); + m_spline_y.add_point(m_src_vertices.size() + 7, m_src_vertices.next(2).y); + } + m_spline_x.prepare(); + m_spline_y.prepare(); + } + m_status = ready; + } + + + + + + + //------------------------------------------------------------------------ + unsigned vcgen_bspline::vertex(double* x, double* y) + { + unsigned cmd = path_cmd_line_to; + while(!is_stop(cmd)) + { + switch(m_status) + { + case initial: + rewind(0); + + case ready: + if(m_src_vertices.size() < 2) + { + cmd = path_cmd_stop; + break; + } + + if(m_src_vertices.size() == 2) + { + *x = m_src_vertices[m_src_vertex].x; + *y = m_src_vertices[m_src_vertex].y; + m_src_vertex++; + if(m_src_vertex == 1) return path_cmd_move_to; + if(m_src_vertex == 2) return path_cmd_line_to; + cmd = path_cmd_stop; + break; + } + + cmd = path_cmd_move_to; + m_status = polygon; + m_src_vertex = 0; + + case polygon: + if(m_cur_abscissa >= m_max_abscissa) + { + if(m_closed) + { + m_status = end_poly; + break; + } + else + { + *x = m_src_vertices[m_src_vertices.size() - 1].x; + *y = m_src_vertices[m_src_vertices.size() - 1].y; + m_status = end_poly; + return path_cmd_line_to; + } + } + + *x = m_spline_x.get_stateful(m_cur_abscissa); + *y = m_spline_y.get_stateful(m_cur_abscissa); + m_src_vertex++; + m_cur_abscissa += m_interpolation_step; + return (m_src_vertex == 1) ? path_cmd_move_to : path_cmd_line_to; + + case end_poly: + m_status = stop; + return path_cmd_end_poly | m_closed; + + case stop: + return path_cmd_stop; + } + } + return cmd; + } + + +} + diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vcgen_contour.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vcgen_contour.cpp new file mode 100644 index 00000000000..a6a99405ad2 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vcgen_contour.cpp @@ -0,0 +1,165 @@ +//---------------------------------------------------------------------------- +// 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 +//---------------------------------------------------------------------------- +// +// Contour generator +// +//---------------------------------------------------------------------------- + +#include <math.h> +#include "agg_vcgen_contour.h" + +namespace agg +{ + + //------------------------------------------------------------------------ + vcgen_contour::vcgen_contour() : + m_stroker(), + m_width(1), + m_src_vertices(), + m_out_vertices(), + m_status(initial), + m_src_vertex(0), + m_closed(0), + m_orientation(0), + m_auto_detect(false) + { + } + + //------------------------------------------------------------------------ + void vcgen_contour::remove_all() + { + m_src_vertices.remove_all(); + m_closed = 0; + m_orientation = 0; + m_status = initial; + } + + //------------------------------------------------------------------------ + void vcgen_contour::add_vertex(double x, double y, unsigned cmd) + { + m_status = initial; + if(is_move_to(cmd)) + { + m_src_vertices.modify_last(vertex_dist(x, y)); + } + else + { + if(is_vertex(cmd)) + { + m_src_vertices.add(vertex_dist(x, y)); + } + else + { + if(is_end_poly(cmd)) + { + m_closed = get_close_flag(cmd); + if(m_orientation == path_flags_none) + { + m_orientation = get_orientation(cmd); + } + } + } + } + } + + //------------------------------------------------------------------------ + void vcgen_contour::rewind(unsigned) + { + if(m_status == initial) + { + m_src_vertices.close(true); + if(m_auto_detect) + { + if(!is_oriented(m_orientation)) + { + m_orientation = (calc_polygon_area(m_src_vertices) > 0.0) ? + path_flags_ccw : + path_flags_cw; + } + } + if(is_oriented(m_orientation)) + { + m_stroker.width(is_ccw(m_orientation) ? m_width : -m_width); + } + } + m_status = ready; + m_src_vertex = 0; + } + + //------------------------------------------------------------------------ + unsigned vcgen_contour::vertex(double* x, double* y) + { + unsigned cmd = path_cmd_line_to; + while(!is_stop(cmd)) + { + switch(m_status) + { + case initial: + rewind(0); + + case ready: + if(m_src_vertices.size() < 2 + unsigned(m_closed != 0)) + { + cmd = path_cmd_stop; + break; + } + m_status = outline; + cmd = path_cmd_move_to; + m_src_vertex = 0; + m_out_vertex = 0; + + case outline: + if(m_src_vertex >= m_src_vertices.size()) + { + m_status = end_poly; + break; + } + m_stroker.calc_join(m_out_vertices, + m_src_vertices.prev(m_src_vertex), + m_src_vertices.curr(m_src_vertex), + m_src_vertices.next(m_src_vertex), + m_src_vertices.prev(m_src_vertex).dist, + m_src_vertices.curr(m_src_vertex).dist); + ++m_src_vertex; + m_status = out_vertices; + m_out_vertex = 0; + + case out_vertices: + if(m_out_vertex >= m_out_vertices.size()) + { + m_status = outline; + } + else + { + const point_d& c = m_out_vertices[m_out_vertex++]; + *x = c.x; + *y = c.y; + return cmd; + } + break; + + case end_poly: + if(!m_closed) return path_cmd_stop; + m_status = stop; + return path_cmd_end_poly | path_flags_close | path_flags_ccw; + + case stop: + return path_cmd_stop; + } + } + return cmd; + } + +} diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vcgen_dash.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vcgen_dash.cpp new file mode 100644 index 00000000000..129505786c9 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vcgen_dash.cpp @@ -0,0 +1,235 @@ +//---------------------------------------------------------------------------- +// 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 +//---------------------------------------------------------------------------- +// +// Line dash generator +// +//---------------------------------------------------------------------------- + +#include <math.h> +#include "agg_vcgen_dash.h" +#include "agg_shorten_path.h" + +namespace agg +{ + + //------------------------------------------------------------------------ + vcgen_dash::vcgen_dash() : + m_total_dash_len(0.0), + m_num_dashes(0), + m_dash_start(0.0), + m_shorten(0.0), + m_curr_dash_start(0.0), + m_curr_dash(0), + m_src_vertices(), + m_closed(0), + m_status(initial), + m_src_vertex(0) + { + } + + + + //------------------------------------------------------------------------ + void vcgen_dash::remove_all_dashes() + { + m_total_dash_len = 0.0; + m_num_dashes = 0; + m_curr_dash_start = 0.0; + m_curr_dash = 0; + } + + + //------------------------------------------------------------------------ + void vcgen_dash::add_dash(double dash_len, double gap_len) + { + if(m_num_dashes < max_dashes) + { + m_total_dash_len += dash_len + gap_len; + m_dashes[m_num_dashes++] = dash_len; + m_dashes[m_num_dashes++] = gap_len; + } + } + + + //------------------------------------------------------------------------ + void vcgen_dash::dash_start(double ds) + { + m_dash_start = ds; + calc_dash_start(fabs(ds)); + } + + + //------------------------------------------------------------------------ + void vcgen_dash::calc_dash_start(double ds) + { + m_curr_dash = 0; + m_curr_dash_start = 0.0; + while(ds > 0.0) + { + if(ds > m_dashes[m_curr_dash]) + { + ds -= m_dashes[m_curr_dash]; + ++m_curr_dash; + m_curr_dash_start = 0.0; + if(m_curr_dash >= m_num_dashes) m_curr_dash = 0; + } + else + { + m_curr_dash_start = ds; + ds = 0.0; + } + } + } + + + //------------------------------------------------------------------------ + void vcgen_dash::remove_all() + { + m_status = initial; + m_src_vertices.remove_all(); + m_closed = 0; + } + + + //------------------------------------------------------------------------ + void vcgen_dash::add_vertex(double x, double y, unsigned cmd) + { + m_status = initial; + if(is_move_to(cmd)) + { + m_src_vertices.modify_last(vertex_dist(x, y)); + } + else + { + if(is_vertex(cmd)) + { + m_src_vertices.add(vertex_dist(x, y)); + } + else + { + m_closed = get_close_flag(cmd); + } + } + } + + + //------------------------------------------------------------------------ + void vcgen_dash::rewind(unsigned) + { + if(m_status == initial) + { + m_src_vertices.close(m_closed != 0); + shorten_path(m_src_vertices, m_shorten, m_closed); + } + m_status = ready; + m_src_vertex = 0; + } + + + //------------------------------------------------------------------------ + unsigned vcgen_dash::vertex(double* x, double* y) + { + unsigned cmd = path_cmd_move_to; + while(!is_stop(cmd)) + { + switch(m_status) + { + case initial: + rewind(0); + + case ready: + if(m_num_dashes < 2 || m_src_vertices.size() < 2) + { + cmd = path_cmd_stop; + break; + } + m_status = polyline; + m_src_vertex = 1; + m_v1 = &m_src_vertices[0]; + m_v2 = &m_src_vertices[1]; + m_curr_rest = m_v1->dist; + *x = m_v1->x; + *y = m_v1->y; + if(m_dash_start >= 0.0) calc_dash_start(m_dash_start); + return path_cmd_move_to; + + case polyline: + { + double dash_rest = m_dashes[m_curr_dash] - m_curr_dash_start; + + unsigned cmd = (m_curr_dash & 1) ? + path_cmd_move_to : + path_cmd_line_to; + + if(m_curr_rest > dash_rest) + { + m_curr_rest -= dash_rest; + ++m_curr_dash; + if(m_curr_dash >= m_num_dashes) m_curr_dash = 0; + m_curr_dash_start = 0.0; + *x = m_v2->x - (m_v2->x - m_v1->x) * m_curr_rest / m_v1->dist; + *y = m_v2->y - (m_v2->y - m_v1->y) * m_curr_rest / m_v1->dist; + } + else + { + m_curr_dash_start += m_curr_rest; + *x = m_v2->x; + *y = m_v2->y; + ++m_src_vertex; + m_v1 = m_v2; + m_curr_rest = m_v1->dist; + if(m_closed) + { + if(m_src_vertex > m_src_vertices.size()) + { + m_status = stop; + } + else + { + m_v2 = &m_src_vertices + [ + (m_src_vertex >= m_src_vertices.size()) ? 0 : + m_src_vertex + ]; + } + } + else + { + if(m_src_vertex >= m_src_vertices.size()) + { + m_status = stop; + } + else + { + m_v2 = &m_src_vertices[m_src_vertex]; + } + } + } + return cmd; + } + break; + + case stop: + cmd = path_cmd_stop; + break; + } + + } + return path_cmd_stop; + } + + +} + diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vcgen_markers_term.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vcgen_markers_term.cpp new file mode 100644 index 00000000000..3374ab5e82a --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vcgen_markers_term.cpp @@ -0,0 +1,103 @@ +//---------------------------------------------------------------------------- +// 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 +//---------------------------------------------------------------------------- +// +// Terminal markers generator (arrowhead/arrowtail) +// +//---------------------------------------------------------------------------- + +#include "agg_vcgen_markers_term.h" + +namespace agg +{ + + //------------------------------------------------------------------------ + void vcgen_markers_term::remove_all() + { + m_markers.remove_all(); + } + + + //------------------------------------------------------------------------ + void vcgen_markers_term::add_vertex(double x, double y, unsigned cmd) + { + if(is_move_to(cmd)) + { + if(m_markers.size() & 1) + { + // Initial state, the first coordinate was added. + // If two of more calls of start_vertex() occures + // we just modify the last one. + m_markers.modify_last(coord_type(x, y)); + } + else + { + m_markers.add(coord_type(x, y)); + } + } + else + { + if(is_vertex(cmd)) + { + if(m_markers.size() & 1) + { + // Initial state, the first coordinate was added. + // Add three more points, 0,1,1,0 + m_markers.add(coord_type(x, y)); + m_markers.add(m_markers[m_markers.size() - 1]); + m_markers.add(m_markers[m_markers.size() - 3]); + } + else + { + if(m_markers.size()) + { + // Replace two last points: 0,1,1,0 -> 0,1,2,1 + m_markers[m_markers.size() - 1] = m_markers[m_markers.size() - 2]; + m_markers[m_markers.size() - 2] = coord_type(x, y); + } + } + } + } + } + + + //------------------------------------------------------------------------ + void vcgen_markers_term::rewind(unsigned path_id) + { + m_curr_id = path_id * 2; + m_curr_idx = m_curr_id; + } + + + //------------------------------------------------------------------------ + unsigned vcgen_markers_term::vertex(double* x, double* y) + { + if(m_curr_id > 2 || m_curr_idx >= m_markers.size()) + { + return path_cmd_stop; + } + const coord_type& c = m_markers[m_curr_idx]; + *x = c.x; + *y = c.y; + if(m_curr_idx & 1) + { + m_curr_idx += 3; + return path_cmd_line_to; + } + ++m_curr_idx; + return path_cmd_move_to; + } + + +} diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vcgen_smooth_poly1.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vcgen_smooth_poly1.cpp new file mode 100644 index 00000000000..ff7d488d399 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vcgen_smooth_poly1.cpp @@ -0,0 +1,225 @@ +//---------------------------------------------------------------------------- +// 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 +// +//---------------------------------------------------------------------------- + +#include "agg_vcgen_smooth_poly1.h" + +namespace agg +{ + + //------------------------------------------------------------------------ + vcgen_smooth_poly1::vcgen_smooth_poly1() : + m_src_vertices(), + m_smooth_value(0.5), + m_closed(0), + m_status(initial), + m_src_vertex(0) + { + } + + + //------------------------------------------------------------------------ + void vcgen_smooth_poly1::remove_all() + { + m_src_vertices.remove_all(); + m_closed = 0; + m_status = initial; + } + + + //------------------------------------------------------------------------ + void vcgen_smooth_poly1::add_vertex(double x, double y, unsigned cmd) + { + m_status = initial; + if(is_move_to(cmd)) + { + m_src_vertices.modify_last(vertex_dist(x, y)); + } + else + { + if(is_vertex(cmd)) + { + m_src_vertices.add(vertex_dist(x, y)); + } + else + { + m_closed = get_close_flag(cmd); + } + } + } + + + //------------------------------------------------------------------------ + void vcgen_smooth_poly1::rewind(unsigned) + { + if(m_status == initial) + { + m_src_vertices.close(m_closed != 0); + } + m_status = ready; + m_src_vertex = 0; + } + + + //------------------------------------------------------------------------ + void vcgen_smooth_poly1::calculate(const vertex_dist& v0, + const vertex_dist& v1, + const vertex_dist& v2, + const vertex_dist& v3) + { + + double k1 = v0.dist / (v0.dist + v1.dist); + double k2 = v1.dist / (v1.dist + v2.dist); + + double xm1 = v0.x + (v2.x - v0.x) * k1; + double ym1 = v0.y + (v2.y - v0.y) * k1; + double xm2 = v1.x + (v3.x - v1.x) * k2; + double ym2 = v1.y + (v3.y - v1.y) * k2; + + m_ctrl1_x = v1.x + m_smooth_value * (v2.x - xm1); + m_ctrl1_y = v1.y + m_smooth_value * (v2.y - ym1); + m_ctrl2_x = v2.x + m_smooth_value * (v1.x - xm2); + m_ctrl2_y = v2.y + m_smooth_value * (v1.y - ym2); + } + + + //------------------------------------------------------------------------ + unsigned vcgen_smooth_poly1::vertex(double* x, double* y) + { + unsigned cmd = path_cmd_line_to; + while(!is_stop(cmd)) + { + switch(m_status) + { + case initial: + rewind(0); + + case ready: + if(m_src_vertices.size() < 2) + { + cmd = path_cmd_stop; + break; + } + + if(m_src_vertices.size() == 2) + { + *x = m_src_vertices[m_src_vertex].x; + *y = m_src_vertices[m_src_vertex].y; + m_src_vertex++; + if(m_src_vertex == 1) return path_cmd_move_to; + if(m_src_vertex == 2) return path_cmd_line_to; + cmd = path_cmd_stop; + break; + } + + cmd = path_cmd_move_to; + m_status = polygon; + m_src_vertex = 0; + + case polygon: + if(m_closed) + { + if(m_src_vertex >= m_src_vertices.size()) + { + *x = m_src_vertices[0].x; + *y = m_src_vertices[0].y; + m_status = end_poly; + return path_cmd_curve4; + } + } + else + { + if(m_src_vertex >= m_src_vertices.size() - 1) + { + *x = m_src_vertices[m_src_vertices.size() - 1].x; + *y = m_src_vertices[m_src_vertices.size() - 1].y; + m_status = end_poly; + return path_cmd_curve3; + } + } + + calculate(m_src_vertices.prev(m_src_vertex), + m_src_vertices.curr(m_src_vertex), + m_src_vertices.next(m_src_vertex), + m_src_vertices.next(m_src_vertex + 1)); + + *x = m_src_vertices[m_src_vertex].x; + *y = m_src_vertices[m_src_vertex].y; + m_src_vertex++; + + if(m_closed) + { + m_status = ctrl1; + return ((m_src_vertex == 1) ? + path_cmd_move_to : + path_cmd_curve4); + } + else + { + if(m_src_vertex == 1) + { + m_status = ctrl_b; + return path_cmd_move_to; + } + if(m_src_vertex >= m_src_vertices.size() - 1) + { + m_status = ctrl_e; + return path_cmd_curve3; + } + m_status = ctrl1; + return path_cmd_curve4; + } + break; + + case ctrl_b: + *x = m_ctrl2_x; + *y = m_ctrl2_y; + m_status = polygon; + return path_cmd_curve3; + + case ctrl_e: + *x = m_ctrl1_x; + *y = m_ctrl1_y; + m_status = polygon; + return path_cmd_curve3; + + case ctrl1: + *x = m_ctrl1_x; + *y = m_ctrl1_y; + m_status = ctrl2; + return path_cmd_curve4; + + case ctrl2: + *x = m_ctrl2_x; + *y = m_ctrl2_y; + m_status = polygon; + return path_cmd_curve4; + + case end_poly: + m_status = stop; + return path_cmd_end_poly | m_closed; + + case stop: + return path_cmd_stop; + } + } + return cmd; + } + +} + diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vcgen_stroke.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vcgen_stroke.cpp new file mode 100644 index 00000000000..2dae3e122b8 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vcgen_stroke.cpp @@ -0,0 +1,213 @@ +//---------------------------------------------------------------------------- +// 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 +//---------------------------------------------------------------------------- +// +// Stroke generator +// +//---------------------------------------------------------------------------- +#include <math.h> +#include "agg_vcgen_stroke.h" +#include "agg_shorten_path.h" + +namespace agg +{ + + //------------------------------------------------------------------------ + vcgen_stroke::vcgen_stroke() : + m_stroker(), + m_src_vertices(), + m_out_vertices(), + m_shorten(0.0), + m_closed(0), + m_status(initial), + m_src_vertex(0), + m_out_vertex(0) + { + } + + //------------------------------------------------------------------------ + void vcgen_stroke::remove_all() + { + m_src_vertices.remove_all(); + m_closed = 0; + m_status = initial; + } + + + //------------------------------------------------------------------------ + void vcgen_stroke::add_vertex(double x, double y, unsigned cmd) + { + m_status = initial; + if(is_move_to(cmd)) + { + m_src_vertices.modify_last(vertex_dist(x, y)); + } + else + { + if(is_vertex(cmd)) + { + m_src_vertices.add(vertex_dist(x, y)); + } + else + { + m_closed = get_close_flag(cmd); + } + } + } + + //------------------------------------------------------------------------ + void vcgen_stroke::rewind(unsigned) + { + if(m_status == initial) + { + m_src_vertices.close(m_closed != 0); + shorten_path(m_src_vertices, m_shorten, m_closed); + if(m_src_vertices.size() < 3) m_closed = 0; + } + m_status = ready; + m_src_vertex = 0; + m_out_vertex = 0; + } + + + //------------------------------------------------------------------------ + unsigned vcgen_stroke::vertex(double* x, double* y) + { + unsigned cmd = path_cmd_line_to; + while(!is_stop(cmd)) + { + switch(m_status) + { + case initial: + rewind(0); + + case ready: + if(m_src_vertices.size() < 2 + unsigned(m_closed != 0)) + { + cmd = path_cmd_stop; + break; + } + m_status = m_closed ? outline1 : cap1; + cmd = path_cmd_move_to; + m_src_vertex = 0; + m_out_vertex = 0; + break; + + case cap1: + m_stroker.calc_cap(m_out_vertices, + m_src_vertices[0], + m_src_vertices[1], + m_src_vertices[0].dist); + m_src_vertex = 1; + m_prev_status = outline1; + m_status = out_vertices; + m_out_vertex = 0; + break; + + case cap2: + m_stroker.calc_cap(m_out_vertices, + m_src_vertices[m_src_vertices.size() - 1], + m_src_vertices[m_src_vertices.size() - 2], + m_src_vertices[m_src_vertices.size() - 2].dist); + m_prev_status = outline2; + m_status = out_vertices; + m_out_vertex = 0; + break; + + case outline1: + if(m_closed) + { + if(m_src_vertex >= m_src_vertices.size()) + { + m_prev_status = close_first; + m_status = end_poly1; + break; + } + } + else + { + if(m_src_vertex >= m_src_vertices.size() - 1) + { + m_status = cap2; + break; + } + } + m_stroker.calc_join(m_out_vertices, + m_src_vertices.prev(m_src_vertex), + m_src_vertices.curr(m_src_vertex), + m_src_vertices.next(m_src_vertex), + m_src_vertices.prev(m_src_vertex).dist, + m_src_vertices.curr(m_src_vertex).dist); + ++m_src_vertex; + m_prev_status = m_status; + m_status = out_vertices; + m_out_vertex = 0; + break; + + case close_first: + m_status = outline2; + cmd = path_cmd_move_to; + + case outline2: + if(m_src_vertex <= unsigned(m_closed == 0)) + { + m_status = end_poly2; + m_prev_status = stop; + break; + } + + --m_src_vertex; + m_stroker.calc_join(m_out_vertices, + m_src_vertices.next(m_src_vertex), + m_src_vertices.curr(m_src_vertex), + m_src_vertices.prev(m_src_vertex), + m_src_vertices.curr(m_src_vertex).dist, + m_src_vertices.prev(m_src_vertex).dist); + + m_prev_status = m_status; + m_status = out_vertices; + m_out_vertex = 0; + break; + + case out_vertices: + if(m_out_vertex >= m_out_vertices.size()) + { + m_status = m_prev_status; + } + else + { + const point_d& c = m_out_vertices[m_out_vertex++]; + *x = c.x; + *y = c.y; + return cmd; + } + break; + + case end_poly1: + m_status = m_prev_status; + return path_cmd_end_poly | path_flags_close | path_flags_ccw; + + case end_poly2: + m_status = m_prev_status; + return path_cmd_end_poly | path_flags_close | path_flags_cw; + + case stop: + cmd = path_cmd_stop; + break; + } + } + return cmd; + } + +} diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vpgen_clip_polygon.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vpgen_clip_polygon.cpp new file mode 100644 index 00000000000..45245260172 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vpgen_clip_polygon.cpp @@ -0,0 +1,133 @@ +//---------------------------------------------------------------------------- +// 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 +//---------------------------------------------------------------------------- + +#include "agg_vpgen_clip_polygon.h" +#include "agg_clip_liang_barsky.h" + +namespace agg +{ + + //------------------------------------------------------------------------ + // Determine the clipping code of the vertex according to the + // Cyrus-Beck line clipping algorithm + // + // | | + // 0110 | 0010 | 0011 + // | | + // -------+--------+-------- clip_box.y2 + // | | + // 0100 | 0000 | 0001 + // | | + // -------+--------+-------- clip_box.y1 + // | | + // 1100 | 1000 | 1001 + // | | + // clip_box.x1 clip_box.x2 + // + // + unsigned vpgen_clip_polygon::clipping_flags(double x, double y) + { + if(x < m_clip_box.x1) + { + if(y > m_clip_box.y2) return 6; + if(y < m_clip_box.y1) return 12; + return 4; + } + + if(x > m_clip_box.x2) + { + if(y > m_clip_box.y2) return 3; + if(y < m_clip_box.y1) return 9; + return 1; + } + + if(y > m_clip_box.y2) return 2; + if(y < m_clip_box.y1) return 8; + + return 0; + } + + //---------------------------------------------------------------------------- + void vpgen_clip_polygon::reset() + { + m_vertex = 0; + m_num_vertices = 0; + } + + //---------------------------------------------------------------------------- + void vpgen_clip_polygon::move_to(double x, double y) + { + m_vertex = 0; + m_num_vertices = 0; + m_clip_flags = clipping_flags(x, y); + if(m_clip_flags == 0) + { + m_x[0] = x; + m_y[0] = y; + m_num_vertices = 1; + } + m_x1 = x; + m_y1 = y; + m_cmd = path_cmd_move_to; + } + + + //---------------------------------------------------------------------------- + void vpgen_clip_polygon::line_to(double x, double y) + { + m_vertex = 0; + m_num_vertices = 0; + unsigned flags = clipping_flags(x, y); + + if(m_clip_flags == flags) + { + if(flags == 0) + { + m_x[0] = x; + m_y[0] = y; + m_num_vertices = 1; + } + } + else + { + m_num_vertices = clip_liang_barsky(m_x1, m_y1, + x, y, + m_clip_box, + m_x, m_y); + } + + m_clip_flags = flags; + m_x1 = x; + m_y1 = y; + } + + + //---------------------------------------------------------------------------- + unsigned vpgen_clip_polygon::vertex(double* x, double* y) + { + if(m_vertex < m_num_vertices) + { + *x = m_x[m_vertex]; + *y = m_y[m_vertex]; + ++m_vertex; + unsigned cmd = m_cmd; + m_cmd = path_cmd_line_to; + return cmd; + } + return path_cmd_stop; + } + + +} diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vpgen_clip_polyline.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vpgen_clip_polyline.cpp new file mode 100644 index 00000000000..6840803a988 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vpgen_clip_polyline.cpp @@ -0,0 +1,77 @@ +//---------------------------------------------------------------------------- +// 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 +//---------------------------------------------------------------------------- + +#include "agg_vpgen_clip_polyline.h" +#include "agg_clip_liang_barsky.h" + +namespace agg +{ + //---------------------------------------------------------------------------- + void vpgen_clip_polyline::reset() + { + m_vertex = 0; + m_num_vertices = 0; + m_move_to = false; + } + + //---------------------------------------------------------------------------- + void vpgen_clip_polyline::move_to(double x, double y) + { + m_vertex = 0; + m_num_vertices = 0; + m_x1 = x; + m_y1 = y; + m_move_to = true; + } + + //---------------------------------------------------------------------------- + void vpgen_clip_polyline::line_to(double x, double y) + { + double x2 = x; + double y2 = y; + unsigned flags = clip_line_segment(&m_x1, &m_y1, &x2, &y2, m_clip_box); + + m_vertex = 0; + m_num_vertices = 0; + if((flags & 4) == 0) + { + if((flags & 1) != 0 || m_move_to) + { + m_x[0] = m_x1; + m_y[0] = m_y1; + m_cmd[0] = path_cmd_move_to; + m_num_vertices = 1; + } + m_x[m_num_vertices] = x2; + m_y[m_num_vertices] = y2; + m_cmd[m_num_vertices++] = path_cmd_line_to; + m_move_to = (flags & 2) != 0; + } + m_x1 = x; + m_y1 = y; + } + + //---------------------------------------------------------------------------- + unsigned vpgen_clip_polyline::vertex(double* x, double* y) + { + if(m_vertex < m_num_vertices) + { + *x = m_x[m_vertex]; + *y = m_y[m_vertex]; + return m_cmd[m_vertex++]; + } + return path_cmd_stop; + } +} diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vpgen_segmentator.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vpgen_segmentator.cpp new file mode 100644 index 00000000000..49a45b6b13d --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/src/agg_vpgen_segmentator.cpp @@ -0,0 +1,67 @@ +//---------------------------------------------------------------------------- +// 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 +//---------------------------------------------------------------------------- + +#include <math.h> +#include "agg_vpgen_segmentator.h" + +namespace agg +{ + + void vpgen_segmentator::move_to(double x, double y) + { + m_x1 = x; + m_y1 = y; + m_dx = 0.0; + m_dy = 0.0; + m_dl = 2.0; + m_ddl = 2.0; + m_cmd = path_cmd_move_to; + } + + void vpgen_segmentator::line_to(double x, double y) + { + m_x1 += m_dx; + m_y1 += m_dy; + m_dx = x - m_x1; + m_dy = y - m_y1; + double len = sqrt(m_dx * m_dx + m_dy * m_dy) * m_approximation_scale; + if(len < 1e-30) len = 1e-30; + m_ddl = 1.0 / len; + m_dl = (m_cmd == path_cmd_move_to) ? 0.0 : m_ddl; + if(m_cmd == path_cmd_stop) m_cmd = path_cmd_line_to; + } + + unsigned vpgen_segmentator::vertex(double* x, double* y) + { + if(m_cmd == path_cmd_stop) return path_cmd_stop; + + unsigned cmd = m_cmd; + m_cmd = path_cmd_line_to; + if(m_dl >= 1.0 - m_ddl) + { + m_dl = 1.0; + m_cmd = path_cmd_stop; + *x = m_x1 + m_dx; + *y = m_y1 + m_dy; + return cmd; + } + *x = m_x1 + m_dx * m_dl; + *y = m_y1 + m_dy * m_dl; + m_dl += m_ddl; + return cmd; + } + +} + diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/src/authors b/contrib/python/matplotlib/py3/extern/agg24-svn/src/authors new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/src/authors diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/src/copying b/contrib/python/matplotlib/py3/extern/agg24-svn/src/copying new file mode 100644 index 00000000000..a08de15faa5 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/src/copying @@ -0,0 +1,11 @@ +The Anti-Grain Geometry Project +A high quality rendering engine for C++ +http://antigrain.com + +Anti-Grain Geometry - Version 2.4 +Copyright (C) 2002-2005 Maxim Shemanarev (McSeem) + +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. diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_bezier_ctrl.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_bezier_ctrl.cpp new file mode 100644 index 00000000000..13a4c15af9c --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_bezier_ctrl.cpp @@ -0,0 +1,370 @@ +//---------------------------------------------------------------------------- +// 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 +// +//---------------------------------------------------------------------------- + +#include <string.h> +#include <stdio.h> +#include "ctrl/agg_bezier_ctrl.h" + +namespace agg +{ + + //------------------------------------------------------------------------ + bezier_ctrl_impl::bezier_ctrl_impl() : + ctrl(0,0,1,1,false), + m_stroke(m_curve), + m_poly(4, 5.0), + m_idx(0) + { + m_poly.in_polygon_check(false); + m_poly.xn(0) = 100.0; + m_poly.yn(0) = 0.0; + m_poly.xn(1) = 100.0; + m_poly.yn(1) = 50.0; + m_poly.xn(2) = 50.0; + m_poly.yn(2) = 100.0; + m_poly.xn(3) = 0.0; + m_poly.yn(3) = 100.0; + } + + + //------------------------------------------------------------------------ + void bezier_ctrl_impl::curve(double x1, double y1, + double x2, double y2, + double x3, double y3, + double x4, double y4) + { + m_poly.xn(0) = x1; + m_poly.yn(0) = y1; + m_poly.xn(1) = x2; + m_poly.yn(1) = y2; + m_poly.xn(2) = x3; + m_poly.yn(2) = y3; + m_poly.xn(3) = x4; + m_poly.yn(3) = y4; + curve(); + } + + //------------------------------------------------------------------------ + curve4& bezier_ctrl_impl::curve() + { + m_curve.init(m_poly.xn(0), m_poly.yn(0), + m_poly.xn(1), m_poly.yn(1), + m_poly.xn(2), m_poly.yn(2), + m_poly.xn(3), m_poly.yn(3)); + return m_curve; + } + + //------------------------------------------------------------------------ + void bezier_ctrl_impl::rewind(unsigned idx) + { + m_idx = idx; + + m_curve.approximation_scale(scale()); + switch(idx) + { + default: + case 0: // Control line 1 + m_curve.init(m_poly.xn(0), m_poly.yn(0), + (m_poly.xn(0) + m_poly.xn(1)) * 0.5, + (m_poly.yn(0) + m_poly.yn(1)) * 0.5, + (m_poly.xn(0) + m_poly.xn(1)) * 0.5, + (m_poly.yn(0) + m_poly.yn(1)) * 0.5, + m_poly.xn(1), m_poly.yn(1)); + m_stroke.rewind(0); + break; + + case 1: // Control line 2 + m_curve.init(m_poly.xn(2), m_poly.yn(2), + (m_poly.xn(2) + m_poly.xn(3)) * 0.5, + (m_poly.yn(2) + m_poly.yn(3)) * 0.5, + (m_poly.xn(2) + m_poly.xn(3)) * 0.5, + (m_poly.yn(2) + m_poly.yn(3)) * 0.5, + m_poly.xn(3), m_poly.yn(3)); + m_stroke.rewind(0); + break; + + case 2: // Curve itself + m_curve.init(m_poly.xn(0), m_poly.yn(0), + m_poly.xn(1), m_poly.yn(1), + m_poly.xn(2), m_poly.yn(2), + m_poly.xn(3), m_poly.yn(3)); + m_stroke.rewind(0); + break; + + case 3: // Point 1 + m_ellipse.init(m_poly.xn(0), m_poly.yn(0), point_radius(), point_radius(), 20); + m_ellipse.rewind(0); + break; + + case 4: // Point 2 + m_ellipse.init(m_poly.xn(1), m_poly.yn(1), point_radius(), point_radius(), 20); + m_ellipse.rewind(0); + break; + + case 5: // Point 3 + m_ellipse.init(m_poly.xn(2), m_poly.yn(2), point_radius(), point_radius(), 20); + m_ellipse.rewind(0); + break; + + case 6: // Point 4 + m_ellipse.init(m_poly.xn(3), m_poly.yn(3), point_radius(), point_radius(), 20); + m_ellipse.rewind(0); + break; + } + } + + + //------------------------------------------------------------------------ + unsigned bezier_ctrl_impl::vertex(double* x, double* y) + { + unsigned cmd = path_cmd_stop; + switch(m_idx) + { + case 0: + case 1: + case 2: + cmd = m_stroke.vertex(x, y); + break; + + case 3: + case 4: + case 5: + case 6: + case 7: + cmd = m_ellipse.vertex(x, y); + break; + } + + if(!is_stop(cmd)) + { + transform_xy(x, y); + } + return cmd; + } + + + + //------------------------------------------------------------------------ + bool bezier_ctrl_impl::in_rect(double x, double y) const + { + return false; + } + + + //------------------------------------------------------------------------ + bool bezier_ctrl_impl::on_mouse_button_down(double x, double y) + { + inverse_transform_xy(&x, &y); + return m_poly.on_mouse_button_down(x, y); + } + + + //------------------------------------------------------------------------ + bool bezier_ctrl_impl::on_mouse_move(double x, double y, bool button_flag) + { + inverse_transform_xy(&x, &y); + return m_poly.on_mouse_move(x, y, button_flag); + } + + + //------------------------------------------------------------------------ + bool bezier_ctrl_impl::on_mouse_button_up(double x, double y) + { + return m_poly.on_mouse_button_up(x, y); + } + + + //------------------------------------------------------------------------ + bool bezier_ctrl_impl::on_arrow_keys(bool left, bool right, bool down, bool up) + { + return m_poly.on_arrow_keys(left, right, down, up); + } + + + + + + + //------------------------------------------------------------------------ + curve3_ctrl_impl::curve3_ctrl_impl() : + ctrl(0,0,1,1,false), + m_stroke(m_curve), + m_poly(3, 5.0), + m_idx(0) + { + m_poly.in_polygon_check(false); + m_poly.xn(0) = 100.0; + m_poly.yn(0) = 0.0; + m_poly.xn(1) = 100.0; + m_poly.yn(1) = 50.0; + m_poly.xn(2) = 50.0; + m_poly.yn(2) = 100.0; + } + + + //------------------------------------------------------------------------ + void curve3_ctrl_impl::curve(double x1, double y1, + double x2, double y2, + double x3, double y3) + { + m_poly.xn(0) = x1; + m_poly.yn(0) = y1; + m_poly.xn(1) = x2; + m_poly.yn(1) = y2; + m_poly.xn(2) = x3; + m_poly.yn(2) = y3; + curve(); + } + + //------------------------------------------------------------------------ + curve3& curve3_ctrl_impl::curve() + { + m_curve.init(m_poly.xn(0), m_poly.yn(0), + m_poly.xn(1), m_poly.yn(1), + m_poly.xn(2), m_poly.yn(2)); + return m_curve; + } + + //------------------------------------------------------------------------ + void curve3_ctrl_impl::rewind(unsigned idx) + { + m_idx = idx; + + switch(idx) + { + default: + case 0: // Control line + m_curve.init(m_poly.xn(0), m_poly.yn(0), + (m_poly.xn(0) + m_poly.xn(1)) * 0.5, + (m_poly.yn(0) + m_poly.yn(1)) * 0.5, + m_poly.xn(1), m_poly.yn(1)); + m_stroke.rewind(0); + break; + + case 1: // Control line 2 + m_curve.init(m_poly.xn(1), m_poly.yn(1), + (m_poly.xn(1) + m_poly.xn(2)) * 0.5, + (m_poly.yn(1) + m_poly.yn(2)) * 0.5, + m_poly.xn(2), m_poly.yn(2)); + m_stroke.rewind(0); + break; + + case 2: // Curve itself + m_curve.init(m_poly.xn(0), m_poly.yn(0), + m_poly.xn(1), m_poly.yn(1), + m_poly.xn(2), m_poly.yn(2)); + m_stroke.rewind(0); + break; + + case 3: // Point 1 + m_ellipse.init(m_poly.xn(0), m_poly.yn(0), point_radius(), point_radius(), 20); + m_ellipse.rewind(0); + break; + + case 4: // Point 2 + m_ellipse.init(m_poly.xn(1), m_poly.yn(1), point_radius(), point_radius(), 20); + m_ellipse.rewind(0); + break; + + case 5: // Point 3 + m_ellipse.init(m_poly.xn(2), m_poly.yn(2), point_radius(), point_radius(), 20); + m_ellipse.rewind(0); + break; + } + } + + + //------------------------------------------------------------------------ + unsigned curve3_ctrl_impl::vertex(double* x, double* y) + { + unsigned cmd = path_cmd_stop; + switch(m_idx) + { + case 0: + case 1: + case 2: + cmd = m_stroke.vertex(x, y); + break; + + case 3: + case 4: + case 5: + case 6: + cmd = m_ellipse.vertex(x, y); + break; + } + + if(!is_stop(cmd)) + { + transform_xy(x, y); + } + return cmd; + } + + + + //------------------------------------------------------------------------ + bool curve3_ctrl_impl::in_rect(double x, double y) const + { + return false; + } + + + //------------------------------------------------------------------------ + bool curve3_ctrl_impl::on_mouse_button_down(double x, double y) + { + inverse_transform_xy(&x, &y); + return m_poly.on_mouse_button_down(x, y); + } + + + //------------------------------------------------------------------------ + bool curve3_ctrl_impl::on_mouse_move(double x, double y, bool button_flag) + { + inverse_transform_xy(&x, &y); + return m_poly.on_mouse_move(x, y, button_flag); + } + + + //------------------------------------------------------------------------ + bool curve3_ctrl_impl::on_mouse_button_up(double x, double y) + { + return m_poly.on_mouse_button_up(x, y); + } + + + //------------------------------------------------------------------------ + bool curve3_ctrl_impl::on_arrow_keys(bool left, bool right, bool down, bool up) + { + return m_poly.on_arrow_keys(left, right, down, up); + } + + + + + + + + + + + + +} + diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_cbox_ctrl.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_cbox_ctrl.cpp new file mode 100644 index 00000000000..3cf14f6a854 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_cbox_ctrl.cpp @@ -0,0 +1,214 @@ +//---------------------------------------------------------------------------- +// 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 +// +//---------------------------------------------------------------------------- + +#include <string.h> +#include "ctrl/agg_cbox_ctrl.h" + + +namespace agg +{ + + //------------------------------------------------------------------------ + cbox_ctrl_impl::cbox_ctrl_impl(double x, double y, + const char* l, + bool flip_y) : + ctrl(x, y, x + 9.0 * 1.5, y + 9.0 * 1.5, flip_y), + m_text_thickness(1.5), + m_text_height(9.0), + m_text_width(0.0), + m_status(false), + m_text_poly(m_text) + { + label(l); + } + + + //------------------------------------------------------------------------ + void cbox_ctrl_impl::text_size(double h, double w) + { + m_text_width = w; + m_text_height = h; + } + + //------------------------------------------------------------------------ + void cbox_ctrl_impl::label(const char* l) + { + unsigned len = strlen(l); + if(len > 127) len = 127; + memcpy(m_label, l, len); + m_label[len] = 0; + } + + + //------------------------------------------------------------------------ + bool cbox_ctrl_impl::on_mouse_button_down(double x, double y) + { + inverse_transform_xy(&x, &y); + if(x >= m_x1 && y >= m_y1 && x <= m_x2 && y <= m_y2) + { + m_status = !m_status; + return true; + } + return false; + } + + + //------------------------------------------------------------------------ + bool cbox_ctrl_impl::on_mouse_move(double, double, bool) + { + return false; + } + + //------------------------------------------------------------------------ + bool cbox_ctrl_impl::in_rect(double x, double y) const + { + inverse_transform_xy(&x, &y); + return x >= m_x1 && y >= m_y1 && x <= m_x2 && y <= m_y2; + } + + //------------------------------------------------------------------------ + bool cbox_ctrl_impl::on_mouse_button_up(double, double) + { + return false; + } + + //------------------------------------------------------------------------ + bool cbox_ctrl_impl::on_arrow_keys(bool, bool, bool, bool) + { + return false; + } + + + //------------------------------------------------------------------------ + void cbox_ctrl_impl::rewind(unsigned idx) + { + m_idx = idx; + + double d2; + double t; + + switch(idx) + { + default: + case 0: // Border + m_vertex = 0; + m_vx[0] = m_x1; + m_vy[0] = m_y1; + m_vx[1] = m_x2; + m_vy[1] = m_y1; + m_vx[2] = m_x2; + m_vy[2] = m_y2; + m_vx[3] = m_x1; + m_vy[3] = m_y2; + m_vx[4] = m_x1 + m_text_thickness; + m_vy[4] = m_y1 + m_text_thickness; + m_vx[5] = m_x1 + m_text_thickness; + m_vy[5] = m_y2 - m_text_thickness; + m_vx[6] = m_x2 - m_text_thickness; + m_vy[6] = m_y2 - m_text_thickness; + m_vx[7] = m_x2 - m_text_thickness; + m_vy[7] = m_y1 + m_text_thickness; + break; + + case 1: // Text + m_text.text(m_label); + m_text.start_point(m_x1 + m_text_height * 2.0, m_y1 + m_text_height / 5.0); + m_text.size(m_text_height, m_text_width); + m_text_poly.width(m_text_thickness); + m_text_poly.line_join(round_join); + m_text_poly.line_cap(round_cap); + m_text_poly.rewind(0); + break; + + case 2: // Active item + m_vertex = 0; + d2 = (m_y2 - m_y1) / 2.0; + t = m_text_thickness * 1.5; + m_vx[0] = m_x1 + m_text_thickness; + m_vy[0] = m_y1 + m_text_thickness; + m_vx[1] = m_x1 + d2; + m_vy[1] = m_y1 + d2 - t; + m_vx[2] = m_x2 - m_text_thickness; + m_vy[2] = m_y1 + m_text_thickness; + m_vx[3] = m_x1 + d2 + t; + m_vy[3] = m_y1 + d2; + m_vx[4] = m_x2 - m_text_thickness; + m_vy[4] = m_y2 - m_text_thickness; + m_vx[5] = m_x1 + d2; + m_vy[5] = m_y1 + d2 + t; + m_vx[6] = m_x1 + m_text_thickness; + m_vy[6] = m_y2 - m_text_thickness; + m_vx[7] = m_x1 + d2 - t; + m_vy[7] = m_y1 + d2; + break; + + } + } + + + + + //------------------------------------------------------------------------ + unsigned cbox_ctrl_impl::vertex(double* x, double* y) + { + unsigned cmd = path_cmd_line_to; + switch(m_idx) + { + case 0: + if(m_vertex == 0 || m_vertex == 4) cmd = path_cmd_move_to; + if(m_vertex >= 8) cmd = path_cmd_stop; + *x = m_vx[m_vertex]; + *y = m_vy[m_vertex]; + m_vertex++; + break; + + case 1: + cmd = m_text_poly.vertex(x, y); + break; + + case 2: + if(m_status) + { + if(m_vertex == 0) cmd = path_cmd_move_to; + if(m_vertex >= 8) cmd = path_cmd_stop; + *x = m_vx[m_vertex]; + *y = m_vy[m_vertex]; + m_vertex++; + } + else + { + cmd = path_cmd_stop; + } + break; + + default: + cmd = path_cmd_stop; + break; + } + + if(!is_stop(cmd)) + { + transform_xy(x, y); + } + return cmd; + } +} + + + diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_gamma_ctrl.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_gamma_ctrl.cpp new file mode 100644 index 00000000000..7fd6448cd5b --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_gamma_ctrl.cpp @@ -0,0 +1,433 @@ +//---------------------------------------------------------------------------- +// 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_impl +// +//---------------------------------------------------------------------------- + +#include <stdio.h> +#include "agg_math.h" +#include "ctrl/agg_gamma_ctrl.h" + +namespace agg +{ + + //------------------------------------------------------------------------ + gamma_ctrl_impl::gamma_ctrl_impl(double x1, double y1, double x2, double y2, bool flip_y) : + ctrl(x1, y1, x2, y2, flip_y), + m_border_width(2.0), + m_border_extra(0.0), + m_curve_width(2.0), + m_grid_width(0.2), + m_text_thickness(1.5), + m_point_size(5.0), + m_text_height(9.0), + m_text_width(0.0), + m_xc1(x1), + m_yc1(y1), + m_xc2(x2), + m_yc2(y2 - m_text_height * 2.0), + m_xt1(x1), + m_yt1(y2 - m_text_height * 2.0), + m_xt2(x2), + m_yt2(y2), + m_curve_poly(m_gamma_spline), + m_text_poly(m_text), + m_idx(0), + m_vertex(0), + m_p1_active(true), + m_mouse_point(0), + m_pdx(0.0), + m_pdy(0.0) + { + calc_spline_box(); + } + + + //------------------------------------------------------------------------ + void gamma_ctrl_impl::calc_spline_box() + { + m_xs1 = m_xc1 + m_border_width; + m_ys1 = m_yc1 + m_border_width; + m_xs2 = m_xc2 - m_border_width; + m_ys2 = m_yc2 - m_border_width * 0.5; + } + + + //------------------------------------------------------------------------ + void gamma_ctrl_impl::calc_points() + { + double kx1, ky1, kx2, ky2; + m_gamma_spline.values(&kx1, &ky1, &kx2, &ky2); + m_xp1 = m_xs1 + (m_xs2 - m_xs1) * kx1 * 0.25; + m_yp1 = m_ys1 + (m_ys2 - m_ys1) * ky1 * 0.25; + m_xp2 = m_xs2 - (m_xs2 - m_xs1) * kx2 * 0.25; + m_yp2 = m_ys2 - (m_ys2 - m_ys1) * ky2 * 0.25; + } + + + //------------------------------------------------------------------------ + void gamma_ctrl_impl::calc_values() + { + double kx1, ky1, kx2, ky2; + + kx1 = (m_xp1 - m_xs1) * 4.0 / (m_xs2 - m_xs1); + ky1 = (m_yp1 - m_ys1) * 4.0 / (m_ys2 - m_ys1); + kx2 = (m_xs2 - m_xp2) * 4.0 / (m_xs2 - m_xs1); + ky2 = (m_ys2 - m_yp2) * 4.0 / (m_ys2 - m_ys1); + m_gamma_spline.values(kx1, ky1, kx2, ky2); + } + + + //------------------------------------------------------------------------ + void gamma_ctrl_impl::text_size(double h, double w) + { + m_text_width = w; + m_text_height = h; + m_yc2 = m_y2 - m_text_height * 2.0; + m_yt1 = m_y2 - m_text_height * 2.0; + calc_spline_box(); + } + + + //------------------------------------------------------------------------ + void gamma_ctrl_impl::border_width(double t, double extra) + { + m_border_width = t; + m_border_extra = extra; + calc_spline_box(); + } + + //------------------------------------------------------------------------ + void gamma_ctrl_impl::values(double kx1, double ky1, double kx2, double ky2) + { + m_gamma_spline.values(kx1, ky1, kx2, ky2); + } + + + //------------------------------------------------------------------------ + void gamma_ctrl_impl::values(double* kx1, double* ky1, double* kx2, double* ky2) const + { + m_gamma_spline.values(kx1, ky1, kx2, ky2); + } + + //------------------------------------------------------------------------ + void gamma_ctrl_impl::rewind(unsigned idx) + { + double kx1, ky1, kx2, ky2; + char tbuf[32]; + + m_idx = idx; + + switch(idx) + { + default: + + case 0: // Background + m_vertex = 0; + m_vx[0] = m_x1 - m_border_extra; + m_vy[0] = m_y1 - m_border_extra; + m_vx[1] = m_x2 + m_border_extra; + m_vy[1] = m_y1 - m_border_extra; + m_vx[2] = m_x2 + m_border_extra; + m_vy[2] = m_y2 + m_border_extra; + m_vx[3] = m_x1 - m_border_extra; + m_vy[3] = m_y2 + m_border_extra; + break; + + case 1: // Border + m_vertex = 0; + m_vx[0] = m_x1; + m_vy[0] = m_y1; + m_vx[1] = m_x2; + m_vy[1] = m_y1; + m_vx[2] = m_x2; + m_vy[2] = m_y2; + m_vx[3] = m_x1; + m_vy[3] = m_y2; + m_vx[4] = m_x1 + m_border_width; + m_vy[4] = m_y1 + m_border_width; + m_vx[5] = m_x1 + m_border_width; + m_vy[5] = m_y2 - m_border_width; + m_vx[6] = m_x2 - m_border_width; + m_vy[6] = m_y2 - m_border_width; + m_vx[7] = m_x2 - m_border_width; + m_vy[7] = m_y1 + m_border_width; + m_vx[8] = m_xc1 + m_border_width; + m_vy[8] = m_yc2 - m_border_width * 0.5; + m_vx[9] = m_xc2 - m_border_width; + m_vy[9] = m_yc2 - m_border_width * 0.5; + m_vx[10] = m_xc2 - m_border_width; + m_vy[10] = m_yc2 + m_border_width * 0.5; + m_vx[11] = m_xc1 + m_border_width; + m_vy[11] = m_yc2 + m_border_width * 0.5; + break; + + case 2: // Curve + m_gamma_spline.box(m_xs1, m_ys1, m_xs2, m_ys2); + m_curve_poly.width(m_curve_width); + m_curve_poly.rewind(0); + break; + + case 3: // Grid + m_vertex = 0; + m_vx[0] = m_xs1; + m_vy[0] = (m_ys1 + m_ys2) * 0.5 - m_grid_width * 0.5; + m_vx[1] = m_xs2; + m_vy[1] = (m_ys1 + m_ys2) * 0.5 - m_grid_width * 0.5; + m_vx[2] = m_xs2; + m_vy[2] = (m_ys1 + m_ys2) * 0.5 + m_grid_width * 0.5; + m_vx[3] = m_xs1; + m_vy[3] = (m_ys1 + m_ys2) * 0.5 + m_grid_width * 0.5; + m_vx[4] = (m_xs1 + m_xs2) * 0.5 - m_grid_width * 0.5; + m_vy[4] = m_ys1; + m_vx[5] = (m_xs1 + m_xs2) * 0.5 - m_grid_width * 0.5; + m_vy[5] = m_ys2; + m_vx[6] = (m_xs1 + m_xs2) * 0.5 + m_grid_width * 0.5; + m_vy[6] = m_ys2; + m_vx[7] = (m_xs1 + m_xs2) * 0.5 + m_grid_width * 0.5; + m_vy[7] = m_ys1; + calc_points(); + m_vx[8] = m_xs1; + m_vy[8] = m_yp1 - m_grid_width * 0.5; + m_vx[9] = m_xp1 - m_grid_width * 0.5; + m_vy[9] = m_yp1 - m_grid_width * 0.5; + m_vx[10] = m_xp1 - m_grid_width * 0.5; + m_vy[10] = m_ys1; + m_vx[11] = m_xp1 + m_grid_width * 0.5; + m_vy[11] = m_ys1; + m_vx[12] = m_xp1 + m_grid_width * 0.5; + m_vy[12] = m_yp1 + m_grid_width * 0.5; + m_vx[13] = m_xs1; + m_vy[13] = m_yp1 + m_grid_width * 0.5; + m_vx[14] = m_xs2; + m_vy[14] = m_yp2 + m_grid_width * 0.5; + m_vx[15] = m_xp2 + m_grid_width * 0.5; + m_vy[15] = m_yp2 + m_grid_width * 0.5; + m_vx[16] = m_xp2 + m_grid_width * 0.5; + m_vy[16] = m_ys2; + m_vx[17] = m_xp2 - m_grid_width * 0.5; + m_vy[17] = m_ys2; + m_vx[18] = m_xp2 - m_grid_width * 0.5; + m_vy[18] = m_yp2 - m_grid_width * 0.5; + m_vx[19] = m_xs2; + m_vy[19] = m_yp2 - m_grid_width * 0.5; + break; + + case 4: // Point1 + calc_points(); + if(m_p1_active) m_ellipse.init(m_xp2, m_yp2, m_point_size, m_point_size, 32); + else m_ellipse.init(m_xp1, m_yp1, m_point_size, m_point_size, 32); + break; + + case 5: // Point2 + calc_points(); + if(m_p1_active) m_ellipse.init(m_xp1, m_yp1, m_point_size, m_point_size, 32); + else m_ellipse.init(m_xp2, m_yp2, m_point_size, m_point_size, 32); + break; + + case 6: // Text + m_gamma_spline.values(&kx1, &ky1, &kx2, &ky2); + sprintf(tbuf, "%5.3f %5.3f %5.3f %5.3f", kx1, ky1, kx2, ky2); + m_text.text(tbuf); + m_text.size(m_text_height, m_text_width); + m_text.start_point(m_xt1 + m_border_width * 2.0, (m_yt1 + m_yt2) * 0.5 - m_text_height * 0.5); + m_text_poly.width(m_text_thickness); + m_text_poly.line_join(round_join); + m_text_poly.line_cap(round_cap); + m_text_poly.rewind(0); + break; + } + } + + + //------------------------------------------------------------------------ + unsigned gamma_ctrl_impl::vertex(double* x, double* y) + { + unsigned cmd = path_cmd_line_to; + switch(m_idx) + { + case 0: + if(m_vertex == 0) cmd = path_cmd_move_to; + if(m_vertex >= 4) cmd = path_cmd_stop; + *x = m_vx[m_vertex]; + *y = m_vy[m_vertex]; + m_vertex++; + break; + + case 1: + if(m_vertex == 0 || m_vertex == 4 || m_vertex == 8) cmd = path_cmd_move_to; + if(m_vertex >= 12) cmd = path_cmd_stop; + *x = m_vx[m_vertex]; + *y = m_vy[m_vertex]; + m_vertex++; + break; + + case 2: + cmd = m_curve_poly.vertex(x, y); + break; + + case 3: + if(m_vertex == 0 || + m_vertex == 4 || + m_vertex == 8 || + m_vertex == 14) cmd = path_cmd_move_to; + + if(m_vertex >= 20) cmd = path_cmd_stop; + *x = m_vx[m_vertex]; + *y = m_vy[m_vertex]; + m_vertex++; + break; + + case 4: // Point1 + case 5: // Point2 + cmd = m_ellipse.vertex(x, y); + break; + + case 6: + cmd = m_text_poly.vertex(x, y); + break; + + default: + cmd = path_cmd_stop; + break; + } + + if(!is_stop(cmd)) + { + transform_xy(x, y); + } + + return cmd; + } + + + + //------------------------------------------------------------------------ + bool gamma_ctrl_impl::on_arrow_keys(bool left, bool right, bool down, bool up) + { + double kx1, ky1, kx2, ky2; + bool ret = false; + m_gamma_spline.values(&kx1, &ky1, &kx2, &ky2); + if(m_p1_active) + { + if(left) { kx1 -= 0.005; ret = true; } + if(right) { kx1 += 0.005; ret = true; } + if(down) { ky1 -= 0.005; ret = true; } + if(up) { ky1 += 0.005; ret = true; } + } + else + { + if(left) { kx2 += 0.005; ret = true; } + if(right) { kx2 -= 0.005; ret = true; } + if(down) { ky2 += 0.005; ret = true; } + if(up) { ky2 -= 0.005; ret = true; } + } + if(ret) + { + m_gamma_spline.values(kx1, ky1, kx2, ky2); + } + return ret; + } + + + + //------------------------------------------------------------------------ + void gamma_ctrl_impl::change_active_point() + { + m_p1_active = m_p1_active ? false : true; + } + + + + + //------------------------------------------------------------------------ + bool gamma_ctrl_impl::in_rect(double x, double y) const + { + inverse_transform_xy(&x, &y); + return x >= m_x1 && x <= m_x2 && y >= m_y1 && y <= m_y2; + } + + + //------------------------------------------------------------------------ + bool gamma_ctrl_impl::on_mouse_button_down(double x, double y) + { + inverse_transform_xy(&x, &y); + calc_points(); + + if(calc_distance(x, y, m_xp1, m_yp1) <= m_point_size + 1) + { + m_mouse_point = 1; + m_pdx = m_xp1 - x; + m_pdy = m_yp1 - y; + m_p1_active = true; + return true; + } + + if(calc_distance(x, y, m_xp2, m_yp2) <= m_point_size + 1) + { + m_mouse_point = 2; + m_pdx = m_xp2 - x; + m_pdy = m_yp2 - y; + m_p1_active = false; + return true; + } + + return false; + } + + + //------------------------------------------------------------------------ + bool gamma_ctrl_impl::on_mouse_button_up(double, double) + { + if(m_mouse_point) + { + m_mouse_point = 0; + return true; + } + return false; + } + + + //------------------------------------------------------------------------ + bool gamma_ctrl_impl::on_mouse_move(double x, double y, bool button_flag) + { + inverse_transform_xy(&x, &y); + if(!button_flag) + { + return on_mouse_button_up(x, y); + } + + if(m_mouse_point == 1) + { + m_xp1 = x + m_pdx; + m_yp1 = y + m_pdy; + calc_values(); + return true; + } + if(m_mouse_point == 2) + { + m_xp2 = x + m_pdx; + m_yp2 = y + m_pdy; + calc_values(); + return true; + } + return false; + } + + + +} + diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_gamma_spline.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_gamma_spline.cpp new file mode 100644 index 00000000000..f720fddd8e7 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_gamma_spline.cpp @@ -0,0 +1,130 @@ +//---------------------------------------------------------------------------- +// 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 +// +//---------------------------------------------------------------------------- + +#include "ctrl/agg_gamma_spline.h" + +namespace agg +{ + + //------------------------------------------------------------------------ + gamma_spline::gamma_spline() : + m_x1(0), m_y1(0), m_x2(10), m_y2(10), m_cur_x(0.0) + { + values(1.0, 1.0, 1.0, 1.0); + } + + + //------------------------------------------------------------------------ + double gamma_spline::y(double x) const + { + if(x < 0.0) x = 0.0; + if(x > 1.0) x = 1.0; + double val = m_spline.get(x); + if(val < 0.0) val = 0.0; + if(val > 1.0) val = 1.0; + return val; + } + + + + //------------------------------------------------------------------------ + void gamma_spline::values(double kx1, double ky1, double kx2, double ky2) + { + if(kx1 < 0.001) kx1 = 0.001; + if(kx1 > 1.999) kx1 = 1.999; + if(ky1 < 0.001) ky1 = 0.001; + if(ky1 > 1.999) ky1 = 1.999; + if(kx2 < 0.001) kx2 = 0.001; + if(kx2 > 1.999) kx2 = 1.999; + if(ky2 < 0.001) ky2 = 0.001; + if(ky2 > 1.999) ky2 = 1.999; + + m_x[0] = 0.0; + m_y[0] = 0.0; + m_x[1] = kx1 * 0.25; + m_y[1] = ky1 * 0.25; + m_x[2] = 1.0 - kx2 * 0.25; + m_y[2] = 1.0 - ky2 * 0.25; + m_x[3] = 1.0; + m_y[3] = 1.0; + + m_spline.init(4, m_x, m_y); + + int i; + for(i = 0; i < 256; i++) + { + m_gamma[i] = (unsigned char)(y(double(i) / 255.0) * 255.0); + } + } + + + //------------------------------------------------------------------------ + void gamma_spline::values(double* kx1, double* ky1, double* kx2, double* ky2) const + { + *kx1 = m_x[1] * 4.0; + *ky1 = m_y[1] * 4.0; + *kx2 = (1.0 - m_x[2]) * 4.0; + *ky2 = (1.0 - m_y[2]) * 4.0; + } + + + //------------------------------------------------------------------------ + void gamma_spline::box(double x1, double y1, double x2, double y2) + { + m_x1 = x1; + m_y1 = y1; + m_x2 = x2; + m_y2 = y2; + } + + + //------------------------------------------------------------------------ + void gamma_spline::rewind(unsigned) + { + m_cur_x = 0.0; + } + + + //------------------------------------------------------------------------ + unsigned gamma_spline::vertex(double* vx, double* vy) + { + if(m_cur_x == 0.0) + { + *vx = m_x1; + *vy = m_y1; + m_cur_x += 1.0 / (m_x2 - m_x1); + return path_cmd_move_to; + } + + if(m_cur_x > 1.0) + { + return path_cmd_stop; + } + + *vx = m_x1 + m_cur_x * (m_x2 - m_x1); + *vy = m_y1 + y(m_cur_x) * (m_y2 - m_y1); + + m_cur_x += 1.0 / (m_x2 - m_x1); + return path_cmd_line_to; + } + + + +} + diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_polygon_ctrl.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_polygon_ctrl.cpp new file mode 100644 index 00000000000..40daee45e83 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_polygon_ctrl.cpp @@ -0,0 +1,332 @@ +//---------------------------------------------------------------------------- +// 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 +// +//---------------------------------------------------------------------------- + +#include "ctrl/agg_polygon_ctrl.h" + +namespace agg +{ + + polygon_ctrl_impl::polygon_ctrl_impl(unsigned np, double point_radius) : + ctrl(0, 0, 1, 1, false), + m_polygon(np * 2), + m_num_points(np), + m_node(-1), + m_edge(-1), + m_vs(&m_polygon[0], m_num_points, false), + m_stroke(m_vs), + m_point_radius(point_radius), + m_status(0), + m_dx(0.0), + m_dy(0.0), + m_in_polygon_check(true) + { + m_stroke.width(1.0); + } + + + void polygon_ctrl_impl::rewind(unsigned) + { + m_status = 0; + m_stroke.rewind(0); + } + + unsigned polygon_ctrl_impl::vertex(double* x, double* y) + { + unsigned cmd = path_cmd_stop; + double r = m_point_radius; + if(m_status == 0) + { + cmd = m_stroke.vertex(x, y); + if(!is_stop(cmd)) + { + transform_xy(x, y); + return cmd; + } + if(m_node >= 0 && m_node == int(m_status)) r *= 1.2; + m_ellipse.init(xn(m_status), yn(m_status), r, r, 32); + ++m_status; + } + cmd = m_ellipse.vertex(x, y); + if(!is_stop(cmd)) + { + transform_xy(x, y); + return cmd; + } + if(m_status >= m_num_points) return path_cmd_stop; + if(m_node >= 0 && m_node == int(m_status)) r *= 1.2; + m_ellipse.init(xn(m_status), yn(m_status), r, r, 32); + ++m_status; + cmd = m_ellipse.vertex(x, y); + if(!is_stop(cmd)) + { + transform_xy(x, y); + } + return cmd; + } + + + bool polygon_ctrl_impl::check_edge(unsigned i, double x, double y) const + { + bool ret = false; + + unsigned n1 = i; + unsigned n2 = (i + m_num_points - 1) % m_num_points; + double x1 = xn(n1); + double y1 = yn(n1); + double x2 = xn(n2); + double y2 = yn(n2); + + double dx = x2 - x1; + double dy = y2 - y1; + + if(sqrt(dx*dx + dy*dy) > 0.0000001) + { + double x3 = x; + double y3 = y; + double x4 = x3 - dy; + double y4 = y3 + dx; + + double den = (y4-y3) * (x2-x1) - (x4-x3) * (y2-y1); + double u1 = ((x4-x3) * (y1-y3) - (y4-y3) * (x1-x3)) / den; + + double xi = x1 + u1 * (x2 - x1); + double yi = y1 + u1 * (y2 - y1); + + dx = xi - x; + dy = yi - y; + + if (u1 > 0.0 && u1 < 1.0 && sqrt(dx*dx + dy*dy) <= m_point_radius) + { + ret = true; + } + } + return ret; + } + + + + bool polygon_ctrl_impl::in_rect(double x, double y) const + { + return false; + } + + + bool polygon_ctrl_impl::on_mouse_button_down(double x, double y) + { + unsigned i; + bool ret = false; + m_node = -1; + m_edge = -1; + inverse_transform_xy(&x, &y); + for (i = 0; i < m_num_points; i++) + { + if(sqrt( (x-xn(i)) * (x-xn(i)) + (y-yn(i)) * (y-yn(i)) ) < m_point_radius) + { + m_dx = x - xn(i); + m_dy = y - yn(i); + m_node = int(i); + ret = true; + break; + } + } + + if(!ret) + { + for (i = 0; i < m_num_points; i++) + { + if(check_edge(i, x, y)) + { + m_dx = x; + m_dy = y; + m_edge = int(i); + ret = true; + break; + } + } + } + + if(!ret) + { + if(point_in_polygon(x, y)) + { + m_dx = x; + m_dy = y; + m_node = int(m_num_points); + ret = true; + } + } + return ret; + } + + + bool polygon_ctrl_impl::on_mouse_move(double x, double y, bool button_flag) + { + bool ret = false; + double dx; + double dy; + inverse_transform_xy(&x, &y); + if(m_node == int(m_num_points)) + { + dx = x - m_dx; + dy = y - m_dy; + unsigned i; + for(i = 0; i < m_num_points; i++) + { + xn(i) += dx; + yn(i) += dy; + } + m_dx = x; + m_dy = y; + ret = true; + } + else + { + if(m_edge >= 0) + { + unsigned n1 = m_edge; + unsigned n2 = (n1 + m_num_points - 1) % m_num_points; + dx = x - m_dx; + dy = y - m_dy; + xn(n1) += dx; + yn(n1) += dy; + xn(n2) += dx; + yn(n2) += dy; + m_dx = x; + m_dy = y; + ret = true; + } + else + { + if(m_node >= 0) + { + xn(m_node) = x - m_dx; + yn(m_node) = y - m_dy; + ret = true; + } + } + } + return ret; + } + + bool polygon_ctrl_impl::on_mouse_button_up(double x, double y) + { + bool ret = (m_node >= 0) || (m_edge >= 0); + m_node = -1; + m_edge = -1; + return ret; + } + + + bool polygon_ctrl_impl::on_arrow_keys(bool left, bool right, bool down, bool up) + { + return false; + } + + + //======= Crossings Multiply algorithm of InsideTest ======================== + // + // By Eric Haines, 3D/Eye Inc, erich@eye.com + // + // This version is usually somewhat faster than the original published in + // Graphics Gems IV; by turning the division for testing the X axis crossing + // into a tricky multiplication test this part of the test became faster, + // which had the additional effect of making the test for "both to left or + // both to right" a bit slower for triangles than simply computing the + // intersection each time. The main increase is in triangle testing speed, + // which was about 15% faster; all other polygon complexities were pretty much + // the same as before. On machines where division is very expensive (not the + // case on the HP 9000 series on which I tested) this test should be much + // faster overall than the old code. Your mileage may (in fact, will) vary, + // depending on the machine and the test data, but in general I believe this + // code is both shorter and faster. This test was inspired by unpublished + // Graphics Gems submitted by Joseph Samosky and Mark Haigh-Hutchinson. + // Related work by Samosky is in: + // + // Samosky, Joseph, "SectionView: A system for interactively specifying and + // visualizing sections through three-dimensional medical image data", + // M.S. Thesis, Department of Electrical Engineering and Computer Science, + // Massachusetts Institute of Technology, 1993. + // + // Shoot a test ray along +X axis. The strategy is to compare vertex Y values + // to the testing point's Y and quickly discard edges which are entirely to one + // side of the test ray. Note that CONVEX and WINDING code can be added as + // for the CrossingsTest() code; it is left out here for clarity. + // + // Input 2D polygon _pgon_ with _numverts_ number of vertices and test point + // _point_, returns 1 if inside, 0 if outside. + bool polygon_ctrl_impl::point_in_polygon(double tx, double ty) const + { + if(m_num_points < 3) return false; + if(!m_in_polygon_check) return false; + + unsigned j; + int yflag0, yflag1, inside_flag; + double vtx0, vty0, vtx1, vty1; + + vtx0 = xn(m_num_points - 1); + vty0 = yn(m_num_points - 1); + + // get test bit for above/below X axis + yflag0 = (vty0 >= ty); + + vtx1 = xn(0); + vty1 = yn(0); + + inside_flag = 0; + for (j = 1; j <= m_num_points; ++j) + { + yflag1 = (vty1 >= ty); + // Check if endpoints straddle (are on opposite sides) of X axis + // (i.e. the Y's differ); if so, +X ray could intersect this edge. + // The old test also checked whether the endpoints are both to the + // right or to the left of the test point. However, given the faster + // intersection point computation used below, this test was found to + // be a break-even proposition for most polygons and a loser for + // triangles (where 50% or more of the edges which survive this test + // will cross quadrants and so have to have the X intersection computed + // anyway). I credit Joseph Samosky with inspiring me to try dropping + // the "both left or both right" part of my code. + if (yflag0 != yflag1) + { + // Check intersection of pgon segment with +X ray. + // Note if >= point's X; if so, the ray hits it. + // The division operation is avoided for the ">=" test by checking + // the sign of the first vertex wrto the test point; idea inspired + // by Joseph Samosky's and Mark Haigh-Hutchinson's different + // polygon inclusion tests. + if ( ((vty1-ty) * (vtx0-vtx1) >= + (vtx1-tx) * (vty0-vty1)) == yflag1 ) + { + inside_flag ^= 1; + } + } + + // Move to the next pair of vertices, retaining info as possible. + yflag0 = yflag1; + vtx0 = vtx1; + vty0 = vty1; + + unsigned k = (j >= m_num_points) ? j - m_num_points : j; + vtx1 = xn(k); + vty1 = yn(k); + } + return inside_flag != 0; + } +} + diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_rbox_ctrl.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_rbox_ctrl.cpp new file mode 100644 index 00000000000..4e36b3b26b9 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_rbox_ctrl.cpp @@ -0,0 +1,325 @@ +//---------------------------------------------------------------------------- +// 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 +// +//---------------------------------------------------------------------------- + +#include <string.h> +#include "ctrl/agg_rbox_ctrl.h" + +namespace agg +{ + + //------------------------------------------------------------------------ + rbox_ctrl_impl::rbox_ctrl_impl(double x1, double y1, + double x2, double y2, bool flip_y) : + ctrl(x1, y1, x2, y2, flip_y), + m_border_width(1.0), + m_border_extra(0.0), + m_text_thickness(1.5), + m_text_height(9.0), + m_text_width(0.0), + m_num_items(0), + m_cur_item(-1), + m_ellipse_poly(m_ellipse), + m_text_poly(m_text), + m_idx(0), + m_vertex(0) + { + calc_rbox(); + } + + + //------------------------------------------------------------------------ + void rbox_ctrl_impl::calc_rbox() + { + m_xs1 = m_x1 + m_border_width; + m_ys1 = m_y1 + m_border_width; + m_xs2 = m_x2 - m_border_width; + m_ys2 = m_y2 - m_border_width; + } + + + //------------------------------------------------------------------------ + void rbox_ctrl_impl::add_item(const char* text) + { + if(m_num_items < 32) + { + m_items[m_num_items].resize(strlen(text) + 1); + strcpy(&m_items[m_num_items][0], text); + m_num_items++; + } + } + + + //------------------------------------------------------------------------ + void rbox_ctrl_impl::border_width(double t, double extra) + { + m_border_width = t; + m_border_extra = extra; + calc_rbox(); + } + + + //------------------------------------------------------------------------ + void rbox_ctrl_impl::text_size(double h, double w) + { + m_text_width = w; + m_text_height = h; + } + + + + //------------------------------------------------------------------------ + void rbox_ctrl_impl::rewind(unsigned idx) + { + m_idx = idx; + m_dy = m_text_height * 2.0; + m_draw_item = 0; + + switch(idx) + { + default: + + case 0: // Background + m_vertex = 0; + m_vx[0] = m_x1 - m_border_extra; + m_vy[0] = m_y1 - m_border_extra; + m_vx[1] = m_x2 + m_border_extra; + m_vy[1] = m_y1 - m_border_extra; + m_vx[2] = m_x2 + m_border_extra; + m_vy[2] = m_y2 + m_border_extra; + m_vx[3] = m_x1 - m_border_extra; + m_vy[3] = m_y2 + m_border_extra; + break; + + case 1: // Border + m_vertex = 0; + m_vx[0] = m_x1; + m_vy[0] = m_y1; + m_vx[1] = m_x2; + m_vy[1] = m_y1; + m_vx[2] = m_x2; + m_vy[2] = m_y2; + m_vx[3] = m_x1; + m_vy[3] = m_y2; + m_vx[4] = m_x1 + m_border_width; + m_vy[4] = m_y1 + m_border_width; + m_vx[5] = m_x1 + m_border_width; + m_vy[5] = m_y2 - m_border_width; + m_vx[6] = m_x2 - m_border_width; + m_vy[6] = m_y2 - m_border_width; + m_vx[7] = m_x2 - m_border_width; + m_vy[7] = m_y1 + m_border_width; + break; + + case 2: // Text + m_text.text(&m_items[0][0]); + m_text.start_point(m_xs1 + m_dy * 1.5, m_ys1 + m_dy / 2.0); + m_text.size(m_text_height, m_text_width); + m_text_poly.width(m_text_thickness); + m_text_poly.line_join(round_join); + m_text_poly.line_cap(round_cap); + m_text_poly.rewind(0); + break; + + case 3: // Inactive items + m_ellipse.init(m_xs1 + m_dy / 1.3, + m_ys1 + m_dy / 1.3, + m_text_height / 1.5, + m_text_height / 1.5, 32); + m_ellipse_poly.width(m_text_thickness); + m_ellipse_poly.rewind(0); + break; + + + case 4: // Active Item + if(m_cur_item >= 0) + { + m_ellipse.init(m_xs1 + m_dy / 1.3, + m_ys1 + m_dy * m_cur_item + m_dy / 1.3, + m_text_height / 2.0, + m_text_height / 2.0, 32); + m_ellipse.rewind(0); + } + break; + + } + } + + + //------------------------------------------------------------------------ + unsigned rbox_ctrl_impl::vertex(double* x, double* y) + { + unsigned cmd = path_cmd_line_to; + switch(m_idx) + { + case 0: + if(m_vertex == 0) cmd = path_cmd_move_to; + if(m_vertex >= 4) cmd = path_cmd_stop; + *x = m_vx[m_vertex]; + *y = m_vy[m_vertex]; + m_vertex++; + break; + + case 1: + if(m_vertex == 0 || m_vertex == 4) cmd = path_cmd_move_to; + if(m_vertex >= 8) cmd = path_cmd_stop; + *x = m_vx[m_vertex]; + *y = m_vy[m_vertex]; + m_vertex++; + break; + + case 2: + cmd = m_text_poly.vertex(x, y); + if(is_stop(cmd)) + { + m_draw_item++; + if(m_draw_item >= m_num_items) + { + break; + } + else + { + m_text.text(&m_items[m_draw_item][0]); + m_text.start_point(m_xs1 + m_dy * 1.5, + m_ys1 + m_dy * (m_draw_item + 1) - m_dy / 2.0); + + m_text_poly.rewind(0); + cmd = m_text_poly.vertex(x, y); + } + } + break; + + case 3: + cmd = m_ellipse_poly.vertex(x, y); + if(is_stop(cmd)) + { + m_draw_item++; + if(m_draw_item >= m_num_items) + { + break; + } + else + { + m_ellipse.init(m_xs1 + m_dy / 1.3, + m_ys1 + m_dy * m_draw_item + m_dy / 1.3, + m_text_height / 1.5, + m_text_height / 1.5, 32); + m_ellipse_poly.rewind(0); + cmd = m_ellipse_poly.vertex(x, y); + } + } + break; + + + case 4: + if(m_cur_item >= 0) + { + cmd = m_ellipse.vertex(x, y); + } + else + { + cmd = path_cmd_stop; + } + break; + + default: + cmd = path_cmd_stop; + break; + } + + if(!is_stop(cmd)) + { + transform_xy(x, y); + } + + return cmd; + } + + + //------------------------------------------------------------------------ + bool rbox_ctrl_impl::in_rect(double x, double y) const + { + inverse_transform_xy(&x, &y); + return x >= m_x1 && x <= m_x2 && y >= m_y1 && y <= m_y2; + } + + + + //------------------------------------------------------------------------ + bool rbox_ctrl_impl::on_mouse_button_down(double x, double y) + { + inverse_transform_xy(&x, &y); + unsigned i; + for(i = 0; i < m_num_items; i++) + { + double xp = m_xs1 + m_dy / 1.3; + double yp = m_ys1 + m_dy * i + m_dy / 1.3; + if(calc_distance(x, y, xp, yp) <= m_text_height / 1.5) + { + m_cur_item = int(i); + return true; + } + } + return false; + } + + + //------------------------------------------------------------------------ + bool rbox_ctrl_impl::on_mouse_move(double, double, bool) + { + return false; + } + + //------------------------------------------------------------------------ + bool rbox_ctrl_impl::on_mouse_button_up(double, double) + { + return false; + } + + //------------------------------------------------------------------------ + bool rbox_ctrl_impl::on_arrow_keys(bool left, bool right, bool down, bool up) + { + if(m_cur_item >= 0) + { + if(up || right) + { + m_cur_item++; + if(m_cur_item >= int(m_num_items)) + { + m_cur_item = 0; + } + return true; + } + + if(down || left) + { + m_cur_item--; + if(m_cur_item < 0) + { + m_cur_item = m_num_items - 1; + } + return true; + } + } + return false; + } + + +} + + diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_scale_ctrl.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_scale_ctrl.cpp new file mode 100644 index 00000000000..7f167792bd9 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_scale_ctrl.cpp @@ -0,0 +1,454 @@ +//---------------------------------------------------------------------------- +// 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 +// +//---------------------------------------------------------------------------- + +#include "ctrl/agg_scale_ctrl.h" + +namespace agg +{ + + //------------------------------------------------------------------------ + scale_ctrl_impl::scale_ctrl_impl(double x1, double y1, + double x2, double y2, bool flip_y) : + ctrl(x1, y1, x2, y2, flip_y), + m_border_thickness(1.0), + m_border_extra((fabs(x2 - x1) > fabs(y2 - y1)) ? (y2 - y1) / 2 : (x2 - x1) / 2), + m_pdx(0.0), + m_pdy(0.0), + m_move_what(move_nothing), + m_value1(0.3), + m_value2(0.7), + m_min_d(0.01) + { + calc_box(); + } + + + //------------------------------------------------------------------------ + void scale_ctrl_impl::calc_box() + { + m_xs1 = m_x1 + m_border_thickness; + m_ys1 = m_y1 + m_border_thickness; + m_xs2 = m_x2 - m_border_thickness; + m_ys2 = m_y2 - m_border_thickness; + } + + + //------------------------------------------------------------------------ + void scale_ctrl_impl::border_thickness(double t, double extra) + { + m_border_thickness = t; + m_border_extra = extra; + calc_box(); + } + + + //------------------------------------------------------------------------ + void scale_ctrl_impl::resize(double x1, double y1, double x2, double y2) + { + m_x1 = x1; + m_y1 = y1; + m_x2 = x2; + m_y2 = y2; + calc_box(); + m_border_extra = (fabs(x2 - x1) > fabs(y2 - y1)) ? + (y2 - y1) / 2 : + (x2 - x1) / 2; + } + + + //------------------------------------------------------------------------ + void scale_ctrl_impl::value1(double value) + { + if(value < 0.0) value = 0.0; + if(value > 1.0) value = 1.0; + if(m_value2 - value < m_min_d) value = m_value2 - m_min_d; + m_value1 = value; + } + + + //------------------------------------------------------------------------ + void scale_ctrl_impl::value2(double value) + { + if(value < 0.0) value = 0.0; + if(value > 1.0) value = 1.0; + if(m_value1 + value < m_min_d) value = m_value1 + m_min_d; + m_value2 = value; + } + + + //------------------------------------------------------------------------ + void scale_ctrl_impl::move(double d) + { + m_value1 += d; + m_value2 += d; + if(m_value1 < 0.0) + { + m_value2 -= m_value1; + m_value1 = 0.0; + } + if(m_value2 > 1.0) + { + m_value1 -= m_value2 - 1.0; + m_value2 = 1.0; + } + } + + + //------------------------------------------------------------------------ + void scale_ctrl_impl::rewind(unsigned idx) + { + m_idx = idx; + + switch(idx) + { + default: + + case 0: // Background + m_vertex = 0; + m_vx[0] = m_x1 - m_border_extra; + m_vy[0] = m_y1 - m_border_extra; + m_vx[1] = m_x2 + m_border_extra; + m_vy[1] = m_y1 - m_border_extra; + m_vx[2] = m_x2 + m_border_extra; + m_vy[2] = m_y2 + m_border_extra; + m_vx[3] = m_x1 - m_border_extra; + m_vy[3] = m_y2 + m_border_extra; + break; + + case 1: // Border + m_vertex = 0; + m_vx[0] = m_x1; + m_vy[0] = m_y1; + m_vx[1] = m_x2; + m_vy[1] = m_y1; + m_vx[2] = m_x2; + m_vy[2] = m_y2; + m_vx[3] = m_x1; + m_vy[3] = m_y2; + m_vx[4] = m_x1 + m_border_thickness; + m_vy[4] = m_y1 + m_border_thickness; + m_vx[5] = m_x1 + m_border_thickness; + m_vy[5] = m_y2 - m_border_thickness; + m_vx[6] = m_x2 - m_border_thickness; + m_vy[6] = m_y2 - m_border_thickness; + m_vx[7] = m_x2 - m_border_thickness; + m_vy[7] = m_y1 + m_border_thickness; + break; + + case 2: // pointer1 + if(fabs(m_x2 - m_x1) > fabs(m_y2 - m_y1)) + { + m_ellipse.init(m_xs1 + (m_xs2 - m_xs1) * m_value1, + (m_ys1 + m_ys2) / 2.0, + m_y2 - m_y1, + m_y2 - m_y1, + 32); + } + else + { + m_ellipse.init((m_xs1 + m_xs2) / 2.0, + m_ys1 + (m_ys2 - m_ys1) * m_value1, + m_x2 - m_x1, + m_x2 - m_x1, + 32); + } + m_ellipse.rewind(0); + break; + + case 3: // pointer2 + if(fabs(m_x2 - m_x1) > fabs(m_y2 - m_y1)) + { + m_ellipse.init(m_xs1 + (m_xs2 - m_xs1) * m_value2, + (m_ys1 + m_ys2) / 2.0, + m_y2 - m_y1, + m_y2 - m_y1, + 32); + } + else + { + m_ellipse.init((m_xs1 + m_xs2) / 2.0, + m_ys1 + (m_ys2 - m_ys1) * m_value2, + m_x2 - m_x1, + m_x2 - m_x1, + 32); + } + m_ellipse.rewind(0); + break; + + case 4: // slider + m_vertex = 0; + if(fabs(m_x2 - m_x1) > fabs(m_y2 - m_y1)) + { + m_vx[0] = m_xs1 + (m_xs2 - m_xs1) * m_value1; + m_vy[0] = m_y1 - m_border_extra / 2.0; + m_vx[1] = m_xs1 + (m_xs2 - m_xs1) * m_value2; + m_vy[1] = m_vy[0]; + m_vx[2] = m_vx[1]; + m_vy[2] = m_y2 + m_border_extra / 2.0; + m_vx[3] = m_vx[0]; + m_vy[3] = m_vy[2]; + } + else + { + m_vx[0] = m_x1 - m_border_extra / 2.0; + m_vy[0] = m_ys1 + (m_ys2 - m_ys1) * m_value1; + m_vx[1] = m_vx[0]; + m_vy[1] = m_ys1 + (m_ys2 - m_ys1) * m_value2; + m_vx[2] = m_x2 + m_border_extra / 2.0; + m_vy[2] = m_vy[1]; + m_vx[3] = m_vx[2]; + m_vy[3] = m_vy[0]; + } + break; + } + } + + + //------------------------------------------------------------------------ + unsigned scale_ctrl_impl::vertex(double* x, double* y) + { + unsigned cmd = path_cmd_line_to; + switch(m_idx) + { + case 0: + case 4: + if(m_vertex == 0) cmd = path_cmd_move_to; + if(m_vertex >= 4) cmd = path_cmd_stop; + *x = m_vx[m_vertex]; + *y = m_vy[m_vertex]; + m_vertex++; + break; + + case 1: + if(m_vertex == 0 || m_vertex == 4) cmd = path_cmd_move_to; + if(m_vertex >= 8) cmd = path_cmd_stop; + *x = m_vx[m_vertex]; + *y = m_vy[m_vertex]; + m_vertex++; + break; + + case 2: + case 3: + cmd = m_ellipse.vertex(x, y); + break; + + default: + cmd = path_cmd_stop; + break; + } + + if(!is_stop(cmd)) + { + transform_xy(x, y); + } + + return cmd; + } + + + + //------------------------------------------------------------------------ + bool scale_ctrl_impl::in_rect(double x, double y) const + { + inverse_transform_xy(&x, &y); + return x >= m_x1 && x <= m_x2 && y >= m_y1 && y <= m_y2; + } + + + //------------------------------------------------------------------------ + bool scale_ctrl_impl::on_mouse_button_down(double x, double y) + { + inverse_transform_xy(&x, &y); + + double xp1; + double xp2; + double ys1; + double ys2; + double xp; + double yp; + + if(fabs(m_x2 - m_x1) > fabs(m_y2 - m_y1)) + { + xp1 = m_xs1 + (m_xs2 - m_xs1) * m_value1; + xp2 = m_xs1 + (m_xs2 - m_xs1) * m_value2; + ys1 = m_y1 - m_border_extra / 2.0; + ys2 = m_y2 + m_border_extra / 2.0; + yp = (m_ys1 + m_ys2) / 2.0; + + if(x > xp1 && y > ys1 && x < xp2 && y < ys2) + { + m_pdx = xp1 - x; + m_move_what = move_slider; + return true; + } + + //if(x < xp1 && calc_distance(x, y, xp1, yp) <= m_y2 - m_y1) + if(calc_distance(x, y, xp1, yp) <= m_y2 - m_y1) + { + m_pdx = xp1 - x; + m_move_what = move_value1; + return true; + } + + //if(x > xp2 && calc_distance(x, y, xp2, yp) <= m_y2 - m_y1) + if(calc_distance(x, y, xp2, yp) <= m_y2 - m_y1) + { + m_pdx = xp2 - x; + m_move_what = move_value2; + return true; + } + } + else + { + xp1 = m_x1 - m_border_extra / 2.0; + xp2 = m_x2 + m_border_extra / 2.0; + ys1 = m_ys1 + (m_ys2 - m_ys1) * m_value1; + ys2 = m_ys1 + (m_ys2 - m_ys1) * m_value2; + xp = (m_xs1 + m_xs2) / 2.0; + + if(x > xp1 && y > ys1 && x < xp2 && y < ys2) + { + m_pdy = ys1 - y; + m_move_what = move_slider; + return true; + } + + //if(y < ys1 && calc_distance(x, y, xp, ys1) <= m_x2 - m_x1) + if(calc_distance(x, y, xp, ys1) <= m_x2 - m_x1) + { + m_pdy = ys1 - y; + m_move_what = move_value1; + return true; + } + + //if(y > ys2 && calc_distance(x, y, xp, ys2) <= m_x2 - m_x1) + if(calc_distance(x, y, xp, ys2) <= m_x2 - m_x1) + { + m_pdy = ys2 - y; + m_move_what = move_value2; + return true; + } + } + + return false; + } + + + //------------------------------------------------------------------------ + bool scale_ctrl_impl::on_mouse_move(double x, double y, bool button_flag) + { + inverse_transform_xy(&x, &y); + if(!button_flag) + { + return on_mouse_button_up(x, y); + } + + double xp = x + m_pdx; + double yp = y + m_pdy; + double dv; + + switch(m_move_what) + { + case move_value1: + if(fabs(m_x2 - m_x1) > fabs(m_y2 - m_y1)) + { + m_value1 = (xp - m_xs1) / (m_xs2 - m_xs1); + } + else + { + m_value1 = (yp - m_ys1) / (m_ys2 - m_ys1); + } + if(m_value1 < 0.0) m_value1 = 0.0; + if(m_value1 > m_value2 - m_min_d) m_value1 = m_value2 - m_min_d; + return true; + + case move_value2: + if(fabs(m_x2 - m_x1) > fabs(m_y2 - m_y1)) + { + m_value2 = (xp - m_xs1) / (m_xs2 - m_xs1); + } + else + { + m_value2 = (yp - m_ys1) / (m_ys2 - m_ys1); + } + if(m_value2 > 1.0) m_value2 = 1.0; + if(m_value2 < m_value1 + m_min_d) m_value2 = m_value1 + m_min_d; + return true; + + case move_slider: + dv = m_value2 - m_value1; + if(fabs(m_x2 - m_x1) > fabs(m_y2 - m_y1)) + { + m_value1 = (xp - m_xs1) / (m_xs2 - m_xs1); + } + else + { + m_value1 = (yp - m_ys1) / (m_ys2 - m_ys1); + } + m_value2 = m_value1 + dv; + if(m_value1 < 0.0) + { + dv = m_value2 - m_value1; + m_value1 = 0.0; + m_value2 = m_value1 + dv; + } + if(m_value2 > 1.0) + { + dv = m_value2 - m_value1; + m_value2 = 1.0; + m_value1 = m_value2 - dv; + } + return true; + } + + return false; + } + + + //------------------------------------------------------------------------ + bool scale_ctrl_impl::on_mouse_button_up(double, double) + { + m_move_what = move_nothing; + return false; + } + + + //------------------------------------------------------------------------ + bool scale_ctrl_impl::on_arrow_keys(bool left, bool right, bool down, bool up) + { +/* + if(right || up) + { + m_value += 0.005; + if(m_value > 1.0) m_value = 1.0; + return true; + } + + if(left || down) + { + m_value -= 0.005; + if(m_value < 0.0) m_value = 0.0; + return true; + } +*/ + return false; + } + +} + diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_slider_ctrl.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_slider_ctrl.cpp new file mode 100644 index 00000000000..ad0048631cf --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_slider_ctrl.cpp @@ -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 +//---------------------------------------------------------------------------- +// +// classes slider_ctrl_impl, slider_ctrl +// +//---------------------------------------------------------------------------- + +#include <string.h> +#include <stdio.h> +#include "ctrl/agg_slider_ctrl.h" + +namespace agg +{ + + //------------------------------------------------------------------------ + slider_ctrl_impl::slider_ctrl_impl(double x1, double y1, + double x2, double y2, bool flip_y) : + ctrl(x1, y1, x2, y2, flip_y), + m_border_width(1.0), + m_border_extra((y2 - y1) / 2), + m_text_thickness(1.0), + m_pdx(0.0), + m_mouse_move(false), + m_value(0.5), + m_preview_value(0.5), + m_min(0.0), + m_max(1.0), + m_num_steps(0), + m_descending(false), + m_text_poly(m_text) + { + m_label[0] = 0; + calc_box(); + } + + + //------------------------------------------------------------------------ + void slider_ctrl_impl::calc_box() + { + m_xs1 = m_x1 + m_border_width; + m_ys1 = m_y1 + m_border_width; + m_xs2 = m_x2 - m_border_width; + m_ys2 = m_y2 - m_border_width; + } + + + //------------------------------------------------------------------------ + bool slider_ctrl_impl::normalize_value(bool preview_value_flag) + { + bool ret = true; + if(m_num_steps) + { + int step = int(m_preview_value * m_num_steps + 0.5); + ret = m_value != step / double(m_num_steps); + m_value = step / double(m_num_steps); + } + else + { + m_value = m_preview_value; + } + + if(preview_value_flag) + { + m_preview_value = m_value; + } + return ret; + } + + + //------------------------------------------------------------------------ + void slider_ctrl_impl::border_width(double t, double extra) + { + m_border_width = t; + m_border_extra = extra; + calc_box(); + } + + + //------------------------------------------------------------------------ + void slider_ctrl_impl::value(double value) + { + m_preview_value = (value - m_min) / (m_max - m_min); + if(m_preview_value > 1.0) m_preview_value = 1.0; + if(m_preview_value < 0.0) m_preview_value = 0.0; + normalize_value(true); + } + + //------------------------------------------------------------------------ + void slider_ctrl_impl::label(const char* fmt) + { + m_label[0] = 0; + if(fmt) + { + unsigned len = strlen(fmt); + if(len > 63) len = 63; + memcpy(m_label, fmt, len); + m_label[len] = 0; + } + } + + //------------------------------------------------------------------------ + void slider_ctrl_impl::rewind(unsigned idx) + { + m_idx = idx; + + switch(idx) + { + default: + + case 0: // Background + m_vertex = 0; + m_vx[0] = m_x1 - m_border_extra; + m_vy[0] = m_y1 - m_border_extra; + m_vx[1] = m_x2 + m_border_extra; + m_vy[1] = m_y1 - m_border_extra; + m_vx[2] = m_x2 + m_border_extra; + m_vy[2] = m_y2 + m_border_extra; + m_vx[3] = m_x1 - m_border_extra; + m_vy[3] = m_y2 + m_border_extra; + break; + + case 1: // Triangle + m_vertex = 0; + if(m_descending) + { + m_vx[0] = m_x1; + m_vy[0] = m_y1; + m_vx[1] = m_x2; + m_vy[1] = m_y1; + m_vx[2] = m_x1; + m_vy[2] = m_y2; + m_vx[3] = m_x1; + m_vy[3] = m_y1; + } + else + { + m_vx[0] = m_x1; + m_vy[0] = m_y1; + m_vx[1] = m_x2; + m_vy[1] = m_y1; + m_vx[2] = m_x2; + m_vy[2] = m_y2; + m_vx[3] = m_x1; + m_vy[3] = m_y1; + } + break; + + case 2: + m_text.text(m_label); + if(m_label[0]) + { + char buf[256]; + sprintf(buf, m_label, value()); + m_text.text(buf); + } + m_text.start_point(m_x1, m_y1); + m_text.size((m_y2 - m_y1) * 1.2, m_y2 - m_y1); + m_text_poly.width(m_text_thickness); + m_text_poly.line_join(round_join); + m_text_poly.line_cap(round_cap); + m_text_poly.rewind(0); + break; + + case 3: // pointer preview + m_ellipse.init(m_xs1 + (m_xs2 - m_xs1) * m_preview_value, + (m_ys1 + m_ys2) / 2.0, + m_y2 - m_y1, + m_y2 - m_y1, + 32); + break; + + + case 4: // pointer + normalize_value(false); + m_ellipse.init(m_xs1 + (m_xs2 - m_xs1) * m_value, + (m_ys1 + m_ys2) / 2.0, + m_y2 - m_y1, + m_y2 - m_y1, + 32); + m_ellipse.rewind(0); + break; + + case 5: + m_storage.remove_all(); + if(m_num_steps) + { + unsigned i; + double d = (m_xs2 - m_xs1) / m_num_steps; + if(d > 0.004) d = 0.004; + for(i = 0; i < m_num_steps + 1; i++) + { + double x = m_xs1 + (m_xs2 - m_xs1) * i / m_num_steps; + m_storage.move_to(x, m_y1); + m_storage.line_to(x - d * (m_x2 - m_x1), m_y1 - m_border_extra); + m_storage.line_to(x + d * (m_x2 - m_x1), m_y1 - m_border_extra); + } + } + } + } + + + //------------------------------------------------------------------------ + unsigned slider_ctrl_impl::vertex(double* x, double* y) + { + unsigned cmd = path_cmd_line_to; + switch(m_idx) + { + case 0: + if(m_vertex == 0) cmd = path_cmd_move_to; + if(m_vertex >= 4) cmd = path_cmd_stop; + *x = m_vx[m_vertex]; + *y = m_vy[m_vertex]; + m_vertex++; + break; + + case 1: + if(m_vertex == 0) cmd = path_cmd_move_to; + if(m_vertex >= 4) cmd = path_cmd_stop; + *x = m_vx[m_vertex]; + *y = m_vy[m_vertex]; + m_vertex++; + break; + + case 2: + cmd = m_text_poly.vertex(x, y); + break; + + case 3: + case 4: + cmd = m_ellipse.vertex(x, y); + break; + + case 5: + cmd = m_storage.vertex(x, y); + break; + + default: + cmd = path_cmd_stop; + break; + } + + if(!is_stop(cmd)) + { + transform_xy(x, y); + } + + return cmd; + } + + + + //------------------------------------------------------------------------ + bool slider_ctrl_impl::in_rect(double x, double y) const + { + inverse_transform_xy(&x, &y); + return x >= m_x1 && x <= m_x2 && y >= m_y1 && y <= m_y2; + } + + + //------------------------------------------------------------------------ + bool slider_ctrl_impl::on_mouse_button_down(double x, double y) + { + inverse_transform_xy(&x, &y); + + double xp = m_xs1 + (m_xs2 - m_xs1) * m_value; + double yp = (m_ys1 + m_ys2) / 2.0; + + if(calc_distance(x, y, xp, yp) <= m_y2 - m_y1) + { + m_pdx = xp - x; + m_mouse_move = true; + return true; + } + return false; + } + + + //------------------------------------------------------------------------ + bool slider_ctrl_impl::on_mouse_move(double x, double y, bool button_flag) + { + inverse_transform_xy(&x, &y); + if(!button_flag) + { + on_mouse_button_up(x, y); + return false; + } + + if(m_mouse_move) + { + double xp = x + m_pdx; + m_preview_value = (xp - m_xs1) / (m_xs2 - m_xs1); + if(m_preview_value < 0.0) m_preview_value = 0.0; + if(m_preview_value > 1.0) m_preview_value = 1.0; + return true; + } + return false; + } + + + //------------------------------------------------------------------------ + bool slider_ctrl_impl::on_mouse_button_up(double, double) + { + m_mouse_move = false; + normalize_value(true); + return true; + } + + + //------------------------------------------------------------------------ + bool slider_ctrl_impl::on_arrow_keys(bool left, bool right, bool down, bool up) + { + double d = 0.005; + if(m_num_steps) + { + d = 1.0 / m_num_steps; + } + + if(right || up) + { + m_preview_value += d; + if(m_preview_value > 1.0) m_preview_value = 1.0; + normalize_value(true); + return true; + } + + if(left || down) + { + m_preview_value -= d; + if(m_preview_value < 0.0) m_preview_value = 0.0; + normalize_value(true); + return true; + } + return false; + } + +} + diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_spline_ctrl.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_spline_ctrl.cpp new file mode 100644 index 00000000000..74808d4f87f --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/src/ctrl/agg_spline_ctrl.cpp @@ -0,0 +1,407 @@ +//---------------------------------------------------------------------------- +// 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 +// +//---------------------------------------------------------------------------- + +#include "ctrl/agg_spline_ctrl.h" + + +namespace agg +{ + + //------------------------------------------------------------------------ + spline_ctrl_impl::spline_ctrl_impl(double x1, double y1, double x2, double y2, + unsigned num_pnt, bool flip_y) : + ctrl(x1, y1, x2, y2, flip_y), + m_num_pnt(num_pnt), + m_border_width(1.0), + m_border_extra(0.0), + m_curve_width(1.0), + m_point_size(3.0), + m_curve_poly(m_curve_pnt), + m_idx(0), + m_vertex(0), + m_active_pnt(-1), + m_move_pnt(-1), + m_pdx(0.0), + m_pdy(0.0) + { + if(m_num_pnt < 4) m_num_pnt = 4; + if(m_num_pnt > 32) m_num_pnt = 32; + + unsigned i; + for(i = 0; i < m_num_pnt; i++) + { + m_xp[i] = double(i) / double(m_num_pnt - 1); + m_yp[i] = 0.5; + } + calc_spline_box(); + update_spline(); + } + + + //------------------------------------------------------------------------ + void spline_ctrl_impl::border_width(double t, double extra) + { + m_border_width = t; + m_border_extra = extra; + calc_spline_box(); + } + + + //------------------------------------------------------------------------ + void spline_ctrl_impl::calc_spline_box() + { + m_xs1 = m_x1 + m_border_width; + m_ys1 = m_y1 + m_border_width; + m_xs2 = m_x2 - m_border_width; + m_ys2 = m_y2 - m_border_width; + } + + + //------------------------------------------------------------------------ + void spline_ctrl_impl::update_spline() + { + int i; + m_spline.init(m_num_pnt, m_xp, m_yp); + for(i = 0; i < 256; i++) + { + m_spline_values[i] = m_spline.get(double(i) / 255.0); + if(m_spline_values[i] < 0.0) m_spline_values[i] = 0.0; + if(m_spline_values[i] > 1.0) m_spline_values[i] = 1.0; + m_spline_values8[i] = (int8u)(m_spline_values[i] * 255.0); + } + } + + + //------------------------------------------------------------------------ + void spline_ctrl_impl::calc_curve() + { + int i; + m_curve_pnt.remove_all(); + m_curve_pnt.move_to(m_xs1, m_ys1 + (m_ys2 - m_ys1) * m_spline_values[0]); + for(i = 1; i < 256; i++) + { + m_curve_pnt.line_to(m_xs1 + (m_xs2 - m_xs1) * double(i) / 255.0, + m_ys1 + (m_ys2 - m_ys1) * m_spline_values[i]); + } + } + + + //------------------------------------------------------------------------ + double spline_ctrl_impl::calc_xp(unsigned idx) + { + return m_xs1 + (m_xs2 - m_xs1) * m_xp[idx]; + } + + + //------------------------------------------------------------------------ + double spline_ctrl_impl::calc_yp(unsigned idx) + { + return m_ys1 + (m_ys2 - m_ys1) * m_yp[idx]; + } + + + //------------------------------------------------------------------------ + void spline_ctrl_impl::set_xp(unsigned idx, double val) + { + if(val < 0.0) val = 0.0; + if(val > 1.0) val = 1.0; + + if(idx == 0) + { + val = 0.0; + } + else if(idx == m_num_pnt - 1) + { + val = 1.0; + } + else + { + if(val < m_xp[idx - 1] + 0.001) val = m_xp[idx - 1] + 0.001; + if(val > m_xp[idx + 1] - 0.001) val = m_xp[idx + 1] - 0.001; + } + m_xp[idx] = val; + } + + //------------------------------------------------------------------------ + void spline_ctrl_impl::set_yp(unsigned idx, double val) + { + if(val < 0.0) val = 0.0; + if(val > 1.0) val = 1.0; + m_yp[idx] = val; + } + + + //------------------------------------------------------------------------ + void spline_ctrl_impl::point(unsigned idx, double x, double y) + { + if(idx < m_num_pnt) + { + set_xp(idx, x); + set_yp(idx, y); + } + } + + + //------------------------------------------------------------------------ + void spline_ctrl_impl::value(unsigned idx, double y) + { + if(idx < m_num_pnt) + { + set_yp(idx, y); + } + } + + //------------------------------------------------------------------------ + double spline_ctrl_impl::value(double x) const + { + x = m_spline.get(x); + if(x < 0.0) x = 0.0; + if(x > 1.0) x = 1.0; + return x; + } + + + //------------------------------------------------------------------------ + void spline_ctrl_impl::rewind(unsigned idx) + { + unsigned i; + + m_idx = idx; + + switch(idx) + { + default: + + case 0: // Background + m_vertex = 0; + m_vx[0] = m_x1 - m_border_extra; + m_vy[0] = m_y1 - m_border_extra; + m_vx[1] = m_x2 + m_border_extra; + m_vy[1] = m_y1 - m_border_extra; + m_vx[2] = m_x2 + m_border_extra; + m_vy[2] = m_y2 + m_border_extra; + m_vx[3] = m_x1 - m_border_extra; + m_vy[3] = m_y2 + m_border_extra; + break; + + case 1: // Border + m_vertex = 0; + m_vx[0] = m_x1; + m_vy[0] = m_y1; + m_vx[1] = m_x2; + m_vy[1] = m_y1; + m_vx[2] = m_x2; + m_vy[2] = m_y2; + m_vx[3] = m_x1; + m_vy[3] = m_y2; + m_vx[4] = m_x1 + m_border_width; + m_vy[4] = m_y1 + m_border_width; + m_vx[5] = m_x1 + m_border_width; + m_vy[5] = m_y2 - m_border_width; + m_vx[6] = m_x2 - m_border_width; + m_vy[6] = m_y2 - m_border_width; + m_vx[7] = m_x2 - m_border_width; + m_vy[7] = m_y1 + m_border_width; + break; + + case 2: // Curve + calc_curve(); + m_curve_poly.width(m_curve_width); + m_curve_poly.rewind(0); + break; + + + case 3: // Inactive points + m_curve_pnt.remove_all(); + for(i = 0; i < m_num_pnt; i++) + { + if(int(i) != m_active_pnt) + { + m_ellipse.init(calc_xp(i), calc_yp(i), + m_point_size, m_point_size, 32); + m_curve_pnt.concat_path(m_ellipse); + } + } + m_curve_poly.rewind(0); + break; + + + case 4: // Active point + m_curve_pnt.remove_all(); + if(m_active_pnt >= 0) + { + m_ellipse.init(calc_xp(m_active_pnt), calc_yp(m_active_pnt), + m_point_size, m_point_size, 32); + + m_curve_pnt.concat_path(m_ellipse); + } + m_curve_poly.rewind(0); + break; + + } + } + + + //------------------------------------------------------------------------ + unsigned spline_ctrl_impl::vertex(double* x, double* y) + { + unsigned cmd = path_cmd_line_to; + switch(m_idx) + { + case 0: + if(m_vertex == 0) cmd = path_cmd_move_to; + if(m_vertex >= 4) cmd = path_cmd_stop; + *x = m_vx[m_vertex]; + *y = m_vy[m_vertex]; + m_vertex++; + break; + + case 1: + if(m_vertex == 0 || m_vertex == 4) cmd = path_cmd_move_to; + if(m_vertex >= 8) cmd = path_cmd_stop; + *x = m_vx[m_vertex]; + *y = m_vy[m_vertex]; + m_vertex++; + break; + + case 2: + cmd = m_curve_poly.vertex(x, y); + break; + + case 3: + case 4: + cmd = m_curve_pnt.vertex(x, y); + break; + + default: + cmd = path_cmd_stop; + break; + } + + if(!is_stop(cmd)) + { + transform_xy(x, y); + } + + return cmd; + } + + + + //------------------------------------------------------------------------ + void spline_ctrl_impl::active_point(int i) + { + m_active_pnt = i; + } + + + //------------------------------------------------------------------------ + bool spline_ctrl_impl::in_rect(double x, double y) const + { + inverse_transform_xy(&x, &y); + return x >= m_x1 && x <= m_x2 && y >= m_y1 && y <= m_y2; + } + + + //------------------------------------------------------------------------ + bool spline_ctrl_impl::on_mouse_button_down(double x, double y) + { + inverse_transform_xy(&x, &y); + unsigned i; + for(i = 0; i < m_num_pnt; i++) + { + double xp = calc_xp(i); + double yp = calc_yp(i); + if(calc_distance(x, y, xp, yp) <= m_point_size + 1) + { + m_pdx = xp - x; + m_pdy = yp - y; + m_active_pnt = m_move_pnt = int(i); + return true; + } + } + return false; + } + + + //------------------------------------------------------------------------ + bool spline_ctrl_impl::on_mouse_button_up(double, double) + { + if(m_move_pnt >= 0) + { + m_move_pnt = -1; + return true; + } + return false; + } + + + //------------------------------------------------------------------------ + bool spline_ctrl_impl::on_mouse_move(double x, double y, bool button_flag) + { + inverse_transform_xy(&x, &y); + if(!button_flag) + { + return on_mouse_button_up(x, y); + } + + if(m_move_pnt >= 0) + { + double xp = x + m_pdx; + double yp = y + m_pdy; + + set_xp(m_move_pnt, (xp - m_xs1) / (m_xs2 - m_xs1)); + set_yp(m_move_pnt, (yp - m_ys1) / (m_ys2 - m_ys1)); + + update_spline(); + return true; + } + return false; + } + + + //------------------------------------------------------------------------ + bool spline_ctrl_impl::on_arrow_keys(bool left, bool right, bool down, bool up) + { + double kx = 0.0; + double ky = 0.0; + bool ret = false; + if(m_active_pnt >= 0) + { + kx = m_xp[m_active_pnt]; + ky = m_yp[m_active_pnt]; + if(left) { kx -= 0.001; ret = true; } + if(right) { kx += 0.001; ret = true; } + if(down) { ky -= 0.001; ret = true; } + if(up) { ky += 0.001; ret = true; } + } + if(ret) + { + set_xp(m_active_pnt, kx); + set_yp(m_active_pnt, ky); + update_spline(); + } + return ret; + } + + + + +} + diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/AmigaOS/agg_platform_support.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/AmigaOS/agg_platform_support.cpp new file mode 100644 index 00000000000..b14d09cd1c1 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/AmigaOS/agg_platform_support.cpp @@ -0,0 +1,977 @@ +//---------------------------------------------------------------------------- +// 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 +// +//---------------------------------------------------------------------------- + +#include "platform/agg_platform_support.h" +#include "util/agg_color_conv_rgb8.h" + +#include <sys/time.h> +#include <cstring> + +#include <classes/requester.h> +#include <classes/window.h> +#include <datatypes/pictureclass.h> +#include <proto/exec.h> +#include <proto/datatypes.h> +#include <proto/dos.h> +#include <proto/graphics.h> +#include <proto/intuition.h> +#include <proto/keymap.h> +#include <proto/Picasso96API.h> +#include <proto/utility.h> + +Library* DataTypesBase = 0; +Library* GraphicsBase = 0; +Library* IntuitionBase = 0; +Library* KeymapBase = 0; +Library* P96Base = 0; + +DataTypesIFace* IDataTypes = 0; +GraphicsIFace* IGraphics = 0; +IntuitionIFace* IIntuition = 0; +KeymapIFace* IKeymap = 0; +P96IFace* IP96 = 0; + +Class* RequesterClass = 0; +Class* WindowClass = 0; + + +namespace agg +{ + void handle_idcmp(Hook* hook, APTR win, IntuiMessage* msg); + + //------------------------------------------------------------------------ + class platform_specific + { + public: + platform_specific(platform_support& support, pix_format_e format, + bool flip_y); + ~platform_specific(); + bool handle_input(); + bool load_img(const char* file, unsigned idx, rendering_buffer* rbuf); + bool create_img(unsigned idx, rendering_buffer* rbuf, unsigned width, + unsigned height); + bool make_bitmap(); + public: + platform_support& m_support; + RGBFTYPE m_ftype; + pix_format_e m_format; + unsigned m_bpp; + BitMap* m_bitmap; + bool m_flip_y; + uint16 m_width; + uint16 m_height; + APTR m_window_obj; + Window* m_window; + Hook* m_idcmp_hook; + unsigned m_input_flags; + bool m_dragging; + double m_start_time; + uint16 m_last_key; + BitMap* m_img_bitmaps[platform_support::max_images]; + }; + + //------------------------------------------------------------------------ + platform_specific::platform_specific(platform_support& support, + pix_format_e format, bool flip_y) : + m_support(support), + m_ftype(RGBFB_NONE), + m_format(format), + m_bpp(0), + m_bitmap(0), + m_flip_y(flip_y), + m_width(0), + m_height(0), + m_window_obj(0), + m_window(0), + m_idcmp_hook(0), + m_input_flags(0), + m_dragging(false), + m_start_time(0.0), + m_last_key(0) + { + switch ( format ) + { + case pix_format_gray8: + // Not supported. + break; + case pix_format_rgb555: + m_ftype = RGBFB_R5G5B5; + m_bpp = 15; + break; + case pix_format_rgb565: + m_ftype = RGBFB_R5G6B5; + m_bpp = 16; + break; + case pix_format_rgb24: + m_ftype = RGBFB_R8G8B8; + m_bpp = 24; + break; + case pix_format_bgr24: + m_ftype = RGBFB_B8G8R8; + m_bpp = 24; + break; + case pix_format_bgra32: + m_ftype = RGBFB_B8G8R8A8; + m_bpp = 32; + break; + case pix_format_abgr32: + m_ftype = RGBFB_A8B8G8R8; + m_bpp = 32; + break; + case pix_format_argb32: + m_ftype = RGBFB_A8R8G8B8; + m_bpp = 32; + break; + case pix_format_rgba32: + m_ftype = RGBFB_R8G8B8A8; + m_bpp = 32; + break; + } + + for ( unsigned i = 0; i < platform_support::max_images; ++i ) + { + m_img_bitmaps[i] = 0; + } + } + + //------------------------------------------------------------------------ + platform_specific::~platform_specific() + { + IIntuition->DisposeObject(m_window_obj); + + IP96->p96FreeBitMap(m_bitmap); + + for ( unsigned i = 0; i < platform_support::max_images; ++i ) + { + IP96->p96FreeBitMap(m_img_bitmaps[i]); + } + + if ( m_idcmp_hook != 0 ) + { + IExec->FreeSysObject(ASOT_HOOK, m_idcmp_hook); + } + } + + //------------------------------------------------------------------------ + bool platform_specific::handle_input() + { + int16 code = 0; + uint32 result = 0; + Object* obj = reinterpret_cast<Object*>(m_window_obj); + + while ( (result = IIntuition->IDoMethod(obj, WM_HANDLEINPUT, + &code)) != WMHI_LASTMSG ) + { + switch ( result & WMHI_CLASSMASK ) + { + case WMHI_CLOSEWINDOW: + return true; + break; + case WMHI_INTUITICK: + if ( !m_support.wait_mode() ) + { + m_support.on_idle(); + } + break; + case WMHI_NEWSIZE: + if ( make_bitmap() ) + { + m_support.trans_affine_resizing(m_width, m_height); + m_support.on_resize(m_width, m_height); + m_support.force_redraw(); + } + break; + } + } + + return false; + } + + //------------------------------------------------------------------------ + bool platform_specific::load_img(const char* file, unsigned idx, + rendering_buffer* rbuf) + { + if ( m_img_bitmaps[idx] != 0 ) + { + IP96->p96FreeBitMap(m_img_bitmaps[idx]); + m_img_bitmaps[idx] = 0; + } + + bool result = false; + + Object* picture = IDataTypes->NewDTObject(const_cast<STRPTR>(file), + DTA_GroupID, GID_PICTURE, + PDTA_DestMode, PMODE_V43, + PDTA_Remap, FALSE, + TAG_END); + if ( picture != 0 ) + { + gpLayout layout; + layout.MethodID = DTM_PROCLAYOUT; + layout.gpl_GInfo = 0; + layout.gpl_Initial = 1; + ULONG loaded = IDataTypes->DoDTMethodA(picture, 0, 0, + reinterpret_cast<Msg>(&layout)); + if ( loaded != 0 ) + { + BitMap* src_bitmap = 0; + IDataTypes->GetDTAttrs(picture, + PDTA_ClassBitMap, &src_bitmap, + TAG_END); + + bool supported = false; + + RGBFTYPE ftype = static_cast<RGBFTYPE>(IP96->p96GetBitMapAttr( + src_bitmap, P96BMA_RGBFORMAT)); + + switch ( ftype ) + { + case RGBFB_R8G8B8: + supported = true; + break; + default: + m_support.message("File uses unsupported graphics mode."); + break; + } + + if ( supported ) { + uint16 width = IP96->p96GetBitMapAttr(src_bitmap, + P96BMA_WIDTH); + uint16 height = IP96->p96GetBitMapAttr(src_bitmap, + P96BMA_HEIGHT); + + m_img_bitmaps[idx] = IP96->p96AllocBitMap(width, height, + m_bpp, BMF_USERPRIVATE, 0, m_ftype); + if ( m_img_bitmaps[idx] != 0 ) + { + int8u* buf = reinterpret_cast<int8u*>( + IP96->p96GetBitMapAttr(m_img_bitmaps[idx], + P96BMA_MEMORY)); + int bpr = IP96->p96GetBitMapAttr(m_img_bitmaps[idx], + P96BMA_BYTESPERROW); + int stride = (m_flip_y) ? -bpr : bpr; + rbuf->attach(buf, width, height, stride); + + // P96 sets the alpha to zero so it can't be used to + // color convert true color modes. + if ( m_bpp == 32 ) + { + RenderInfo ri; + int32 lock = IP96->p96LockBitMap(src_bitmap, + reinterpret_cast<uint8*>(&ri), + sizeof(RenderInfo)); + + rendering_buffer rbuf_src; + rbuf_src.attach( + reinterpret_cast<int8u*>(ri.Memory), + width, height, (m_flip_y) ? + -ri.BytesPerRow : ri.BytesPerRow); + + switch ( m_format ) + { + case pix_format_bgra32: + color_conv(rbuf, &rbuf_src, + color_conv_rgb24_to_bgra32()); + break; + case pix_format_abgr32: + color_conv(rbuf, &rbuf_src, + color_conv_rgb24_to_abgr32()); + break; + case pix_format_argb32: + color_conv(rbuf, &rbuf_src, + color_conv_rgb24_to_argb32()); + break; + case pix_format_rgba32: + color_conv(rbuf, &rbuf_src, + color_conv_rgb24_to_rgba32()); + break; + } + + IP96->p96UnlockBitMap(src_bitmap, lock); + } + else + { + IGraphics->BltBitMap(src_bitmap, 0, 0, + m_img_bitmaps[idx], 0, 0, width, height, + ABC|ABNC, 0xFF, 0); + } + + result = true; + } + } + } + } + + IGraphics->WaitBlit(); + IDataTypes->DisposeDTObject(picture); + + return result; + } + + //------------------------------------------------------------------------ + bool platform_specific::create_img(unsigned idx, rendering_buffer* rbuf, + unsigned width, unsigned height) + { + if ( m_img_bitmaps[idx] != 0 ) + { + IP96->p96FreeBitMap(m_img_bitmaps[idx]); + m_img_bitmaps[idx] = 0; + } + + m_img_bitmaps[idx] = IP96->p96AllocBitMap(width, height, + m_bpp, BMF_USERPRIVATE, m_bitmap, m_ftype); + if ( m_img_bitmaps[idx] != 0 ) + { + int8u* buf = reinterpret_cast<int8u*>( + IP96->p96GetBitMapAttr(m_img_bitmaps[idx], + P96BMA_MEMORY)); + int bpr = IP96->p96GetBitMapAttr(m_img_bitmaps[idx], + P96BMA_BYTESPERROW); + int stride = (m_flip_y) ? -bpr : bpr; + + rbuf->attach(buf, width, height, stride); + + return true; + } + + return false; + } + + //------------------------------------------------------------------------ + bool platform_specific::make_bitmap() + { + uint32 width = 0; + uint32 height = 0; + IIntuition->GetWindowAttrs(m_window, + WA_InnerWidth, &width, + WA_InnerHeight, &height, + TAG_END); + + BitMap* bm = IP96->p96AllocBitMap(width, height, m_bpp, + BMF_USERPRIVATE|BMF_CLEAR, 0, m_ftype); + if ( bm == 0 ) + { + return false; + } + + int8u* buf = reinterpret_cast<int8u*>( + IP96->p96GetBitMapAttr(bm, P96BMA_MEMORY)); + int bpr = IP96->p96GetBitMapAttr(bm, P96BMA_BYTESPERROW); + int stride = (m_flip_y) ? -bpr : bpr; + + m_support.rbuf_window().attach(buf, width, height, stride); + + if ( m_bitmap != 0 ) + { + IP96->p96FreeBitMap(m_bitmap); + m_bitmap = 0; + } + + m_bitmap = bm; + m_width = width; + m_height = height; + + return true; + } + + //------------------------------------------------------------------------ + platform_support::platform_support(pix_format_e format, bool flip_y) : + m_specific(new platform_specific(*this, format, flip_y)), + m_format(format), + m_bpp(m_specific->m_bpp), + m_window_flags(0), + m_wait_mode(true), + m_flip_y(flip_y), + m_initial_width(10), + m_initial_height(10) + { + std::strncpy(m_caption, "Anti-Grain Geometry", 256); + } + + //------------------------------------------------------------------------ + platform_support::~platform_support() + { + delete m_specific; + } + + //------------------------------------------------------------------------ + void platform_support::caption(const char* cap) + { + std::strncpy(m_caption, cap, 256); + if ( m_specific->m_window != 0 ) + { + const char* ignore = reinterpret_cast<const char*>(-1); + IIntuition->SetWindowAttr(m_specific->m_window, + WA_Title, m_caption, sizeof(char*)); + } + } + + //------------------------------------------------------------------------ + void platform_support::start_timer() + { + timeval tv; + gettimeofday(&tv, 0); + m_specific->m_start_time = tv.tv_secs + tv.tv_micro/1e6; + } + + //------------------------------------------------------------------------ + double platform_support::elapsed_time() const + { + timeval tv; + gettimeofday(&tv, 0); + double end_time = tv.tv_secs + tv.tv_micro/1e6; + + double elasped_seconds = end_time - m_specific->m_start_time; + double elasped_millis = elasped_seconds*1e3; + + return elasped_millis; + } + + //------------------------------------------------------------------------ + void* platform_support::raw_display_handler() + { + return 0; // Not available. + } + + //------------------------------------------------------------------------ + void platform_support::message(const char* msg) + { + APTR req = IIntuition->NewObject(RequesterClass, 0, + REQ_TitleText, "Anti-Grain Geometry", + REQ_Image, REQIMAGE_INFO, + REQ_BodyText, msg, + REQ_GadgetText, "_Ok", + TAG_END); + if ( req == 0 ) + { + IDOS->Printf("Message: %s\n", msg); + return; + } + + orRequest reqmsg; + reqmsg.MethodID = RM_OPENREQ; + reqmsg.or_Attrs = 0; + reqmsg.or_Window = m_specific->m_window; + reqmsg.or_Screen = 0; + + IIntuition->IDoMethodA(reinterpret_cast<Object*>(req), + reinterpret_cast<Msg>(&reqmsg)); + IIntuition->DisposeObject(req); + } + + //------------------------------------------------------------------------ + bool platform_support::init(unsigned width, unsigned height, + unsigned flags) + { + if( m_specific->m_ftype == RGBFB_NONE ) + { + message("Unsupported mode requested."); + return false; + } + + m_window_flags = flags; + + m_specific->m_idcmp_hook = reinterpret_cast<Hook*>( + IExec->AllocSysObjectTags(ASOT_HOOK, + ASOHOOK_Entry, handle_idcmp, + ASOHOOK_Data, this, + TAG_END)); + if ( m_specific->m_idcmp_hook == 0 ) + { + return false; + } + + m_specific->m_window_obj = IIntuition->NewObject(WindowClass, 0, + WA_Title, m_caption, + WA_AutoAdjustDClip, TRUE, + WA_InnerWidth, width, + WA_InnerHeight, height, + WA_Activate, TRUE, + WA_SmartRefresh, TRUE, + WA_NoCareRefresh, TRUE, + WA_CloseGadget, TRUE, + WA_DepthGadget, TRUE, + WA_SizeGadget, (flags & agg::window_resize) ? TRUE : FALSE, + WA_DragBar, TRUE, + WA_AutoAdjust, TRUE, + WA_ReportMouse, TRUE, + WA_RMBTrap, TRUE, + WA_MouseQueue, 1, + WA_IDCMP, + IDCMP_NEWSIZE | + IDCMP_MOUSEBUTTONS | + IDCMP_MOUSEMOVE | + IDCMP_RAWKEY | + IDCMP_INTUITICKS, + WINDOW_IDCMPHook, m_specific->m_idcmp_hook, + WINDOW_IDCMPHookBits, + IDCMP_MOUSEBUTTONS | + IDCMP_MOUSEMOVE | + IDCMP_RAWKEY, + TAG_END); + if ( m_specific->m_window_obj == 0 ) + { + return false; + } + + Object* obj = reinterpret_cast<Object*>(m_specific->m_window_obj); + m_specific->m_window = + reinterpret_cast<Window*>(IIntuition->IDoMethod(obj, WM_OPEN)); + if ( m_specific->m_window == 0 ) + { + return false; + } + + RGBFTYPE ftype = static_cast<RGBFTYPE>(IP96->p96GetBitMapAttr( + m_specific->m_window->RPort->BitMap, P96BMA_RGBFORMAT)); + + switch ( ftype ) + { + case RGBFB_A8R8G8B8: + case RGBFB_B8G8R8A8: + case RGBFB_R5G6B5PC: + break; + default: + message("Unsupported screen mode.\n"); + return false; + } + + if ( !m_specific->make_bitmap() ) + { + return false; + } + + m_initial_width = width; + m_initial_height = height; + + on_init(); + on_resize(width, height); + force_redraw(); + + return true; + } + + //------------------------------------------------------------------------ + int platform_support::run() + { + uint32 window_mask = 0; + IIntuition->GetAttr(WINDOW_SigMask, m_specific->m_window_obj, + &window_mask); + uint32 wait_mask = window_mask | SIGBREAKF_CTRL_C; + + bool done = false; + + while ( !done ) + { + uint32 sig_mask = IExec->Wait(wait_mask); + if ( sig_mask & SIGBREAKF_CTRL_C ) + { + done = true; + } + else + { + done = m_specific->handle_input(); + } + } + + return 0; + } + + //------------------------------------------------------------------------ + const char* platform_support::img_ext() const + { + return ".bmp"; + } + + //------------------------------------------------------------------------ + const char* platform_support::full_file_name(const char* file_name) + { + return file_name; + } + + //------------------------------------------------------------------------ + bool platform_support::load_img(unsigned idx, const char* file) + { + if ( idx < max_images ) + { + static char fn[1024]; + std::strncpy(fn, file, 1024); + int len = std::strlen(fn); + if ( len < 4 || std::strcmp(fn + len - 4, ".bmp") != 0 ) + { + std::strncat(fn, ".bmp", 1024); + } + + return m_specific->load_img(fn, idx, &m_rbuf_img[idx]); + } + + return false; + } + + //------------------------------------------------------------------------ + bool platform_support::save_img(unsigned idx, const char* file) + { + message("Not supported"); + return false; + } + + //------------------------------------------------------------------------ + bool platform_support::create_img(unsigned idx, unsigned width, + unsigned height) + { + if ( idx < max_images ) + { + if ( width == 0 ) + { + width = m_specific->m_width; + } + + if ( height == 0 ) + { + height = m_specific->m_height; + } + + return m_specific->create_img(idx, &m_rbuf_img[idx], width, + height); + } + + return false; + } + + //------------------------------------------------------------------------ + void platform_support::force_redraw() + { + on_draw(); + update_window(); + } + + //------------------------------------------------------------------------ + void platform_support::update_window() + { + // Note this function does automatic color conversion. + IGraphics->BltBitMapRastPort(m_specific->m_bitmap, 0, 0, + m_specific->m_window->RPort, m_specific->m_window->BorderLeft, + m_specific->m_window->BorderTop, m_specific->m_width, + m_specific->m_height, ABC|ABNC); + } + + //------------------------------------------------------------------------ + void platform_support::on_init() {} + void platform_support::on_resize(int sx, int sy) {} + void platform_support::on_idle() {} + void platform_support::on_mouse_move(int x, int y, unsigned flags) {} + void platform_support::on_mouse_button_down(int x, int y, unsigned flags) {} + void platform_support::on_mouse_button_up(int x, int y, unsigned flags) {} + void platform_support::on_key(int x, int y, unsigned key, unsigned flags) {} + void platform_support::on_ctrl_change() {} + void platform_support::on_draw() {} + void platform_support::on_post_draw(void* raw_handler) {} + + //------------------------------------------------------------------------ + void handle_idcmp(Hook* hook, APTR obj, IntuiMessage* msg) + { + platform_support* app = + reinterpret_cast<platform_support*>(hook->h_Data); + Window* window = app->m_specific->m_window; + + int16 x = msg->MouseX - window->BorderLeft; + + int16 y = 0; + if ( app->flip_y() ) + { + y = window->Height - window->BorderBottom - msg->MouseY; + } + else + { + y = msg->MouseY - window->BorderTop; + } + + switch ( msg->Class ) + { + case IDCMP_MOUSEBUTTONS: + if ( msg->Code & IECODE_UP_PREFIX ) + { + if ( msg->Code == SELECTUP ) + { + app->m_specific->m_input_flags = mouse_left; + app->m_specific->m_dragging = false; + } + else if ( msg->Code == MENUUP ) + { + app->m_specific->m_input_flags = mouse_right; + app->m_specific->m_dragging = false; + } + else + { + return; + } + + + if ( app->m_ctrls.on_mouse_button_up(x, y) ) + { + app->on_ctrl_change(); + app->force_redraw(); + } + + app->on_mouse_button_up(x, y, app->m_specific->m_input_flags); + } + else + { + if ( msg->Code == SELECTDOWN ) + { + app->m_specific->m_input_flags = mouse_left; + app->m_specific->m_dragging = true; + } + else if ( msg->Code == MENUDOWN ) + { + app->m_specific->m_input_flags = mouse_right; + app->m_specific->m_dragging = true; + } + else + { + return; + } + + app->m_ctrls.set_cur(x, y); + if ( app->m_ctrls.on_mouse_button_down(x, y) ) + { + app->on_ctrl_change(); + app->force_redraw(); + } + else + { + if ( app->m_ctrls.in_rect(x, y) ) + { + if ( app->m_ctrls.set_cur(x, y) ) + { + app->on_ctrl_change(); + app->force_redraw(); + } + } + else + { + app->on_mouse_button_down(x, y, + app->m_specific->m_input_flags); + } + } + } + break; + case IDCMP_MOUSEMOVE: + if ( app->m_specific->m_dragging ) { + if ( app->m_ctrls.on_mouse_move(x, y, + app->m_specific->m_input_flags & mouse_left) != 0 ) + { + app->on_ctrl_change(); + app->force_redraw(); + } + else + { + if ( !app->m_ctrls.in_rect(x, y) ) + { + app->on_mouse_move(x, y, + app->m_specific->m_input_flags); + } + } + } + break; + case IDCMP_RAWKEY: + { + static InputEvent ie = { 0 }; + ie.ie_Class = IECLASS_RAWKEY; + ie.ie_Code = msg->Code; + ie.ie_Qualifier = msg->Qualifier; + + static const unsigned BUF_SIZE = 16; + static char key_buf[BUF_SIZE]; + int16 num_chars = IKeymap->MapRawKey(&ie, key_buf, BUF_SIZE, 0); + + uint32 code = 0x00000000; + switch ( num_chars ) + { + case 1: + code = key_buf[0]; + break; + case 2: + code = key_buf[0]<<8 | key_buf[1]; + break; + case 3: + code = key_buf[0]<<16 | key_buf[1]<<8 | key_buf[2]; + break; + } + + uint16 key_code = 0; + + if ( num_chars == 1 ) + { + if ( code >= IECODE_ASCII_FIRST && code <= IECODE_ASCII_LAST ) + { + key_code = code; + } + } + + if ( key_code == 0 ) + { + switch ( code ) + { + case 0x00000008: key_code = key_backspace; break; + case 0x00000009: key_code = key_tab; break; + case 0x0000000D: key_code = key_return; break; + case 0x0000001B: key_code = key_escape; break; + case 0x0000007F: key_code = key_delete; break; + case 0x00009B41: + case 0x00009B54: key_code = key_up; break; + case 0x00009B42: + case 0x00009B53: key_code = key_down; break; + case 0x00009B43: + case 0x009B2040: key_code = key_right; break; + case 0x00009B44: + case 0x009B2041: key_code = key_left; break; + case 0x009B307E: key_code = key_f1; break; + case 0x009B317E: key_code = key_f2; break; + case 0x009B327E: key_code = key_f3; break; + case 0x009B337E: key_code = key_f4; break; + case 0x009B347E: key_code = key_f5; break; + case 0x009B357E: key_code = key_f6; break; + case 0x009B367E: key_code = key_f7; break; + case 0x009B377E: key_code = key_f8; break; + case 0x009B387E: key_code = key_f9; break; + case 0x009B397E: key_code = key_f10; break; + case 0x009B3F7E: key_code = key_scrollock; break; + } + } + + if ( ie.ie_Code & IECODE_UP_PREFIX ) + { + if ( app->m_specific->m_last_key != 0 ) + { + bool left = (key_code == key_left) ? true : false; + bool right = (key_code == key_right) ? true : false; + bool down = (key_code == key_down) ? true : false; + bool up = (key_code == key_up) ? true : false; + + if ( app->m_ctrls.on_arrow_keys(left, right, down, up) ) + { + app->on_ctrl_change(); + app->force_redraw(); + } + else + { + app->on_key(x, y, app->m_specific->m_last_key, 0); + } + + app->m_specific->m_last_key = 0; + } + } + else + { + app->m_specific->m_last_key = key_code; + } + break; + } + default: + break; + } + } +} + +//---------------------------------------------------------------------------- +int agg_main(int argc, char* argv[]); +bool open_libs(); +void close_libs(); + +//---------------------------------------------------------------------------- +bool open_libs() +{ + DataTypesBase = IExec->OpenLibrary("datatypes.library", 51); + GraphicsBase = IExec->OpenLibrary("graphics.library", 51); + IntuitionBase = IExec->OpenLibrary("intuition.library", 51); + KeymapBase = IExec->OpenLibrary("keymap.library", 51); + P96Base = IExec->OpenLibrary("Picasso96API.library", 2); + + IDataTypes = reinterpret_cast<DataTypesIFace*>( + IExec->GetInterface(DataTypesBase, "main", 1, 0)); + IGraphics = reinterpret_cast<GraphicsIFace*>( + IExec->GetInterface(GraphicsBase, "main", 1, 0)); + IIntuition = reinterpret_cast<IntuitionIFace*>( + IExec->GetInterface(IntuitionBase, "main", 1, 0)); + IKeymap = reinterpret_cast<KeymapIFace*>( + IExec->GetInterface(KeymapBase, "main", 1, 0)); + IP96 = reinterpret_cast<P96IFace*>( + IExec->GetInterface(P96Base, "main", 1, 0)); + + if ( IDataTypes == 0 || + IGraphics == 0 || + IIntuition == 0 || + IKeymap == 0 || + IP96 == 0 ) + { + close_libs(); + return false; + } + else + { + return true; + } +} + +//---------------------------------------------------------------------------- +void close_libs() +{ + IExec->DropInterface(reinterpret_cast<Interface*>(IP96)); + IExec->DropInterface(reinterpret_cast<Interface*>(IKeymap)); + IExec->DropInterface(reinterpret_cast<Interface*>(IIntuition)); + IExec->DropInterface(reinterpret_cast<Interface*>(IGraphics)); + IExec->DropInterface(reinterpret_cast<Interface*>(IDataTypes)); + + IExec->CloseLibrary(P96Base); + IExec->CloseLibrary(KeymapBase); + IExec->CloseLibrary(IntuitionBase); + IExec->CloseLibrary(GraphicsBase); + IExec->CloseLibrary(DataTypesBase); +} + +//---------------------------------------------------------------------------- +int main(int argc, char* argv[]) +{ + if ( !open_libs() ) { + IDOS->Printf("Can't open libraries.\n"); + return -1; + } + + ClassLibrary* requester = + IIntuition->OpenClass("requester.class", 51, &RequesterClass); + ClassLibrary* window = + IIntuition->OpenClass("window.class", 51, &WindowClass); + if ( requester == 0 || window == 0 ) + { + IDOS->Printf("Can't open classes.\n"); + IIntuition->CloseClass(requester); + IIntuition->CloseClass(window); + close_libs(); + return -1; + } + + int rc = agg_main(argc, argv); + + IIntuition->CloseClass(window); + IIntuition->CloseClass(requester); + close_libs(); + + return rc; +} diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/BeOS/agg_platform_support.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/BeOS/agg_platform_support.cpp new file mode 100644 index 00000000000..078e141ccb0 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/BeOS/agg_platform_support.cpp @@ -0,0 +1,990 @@ +//---------------------------------------------------------------------------- +// 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: superstippi@gmx.de +//---------------------------------------------------------------------------- +// +// class platform_support +// +//---------------------------------------------------------------------------- + +#include <new> +#include <stdio.h> + +#include <Alert.h> +#include <Application.h> +#include <Bitmap.h> +#include <Message.h> +#include <MessageRunner.h> +#include <Messenger.h> +#include <Path.h> +#include <Roster.h> +#include <TranslationUtils.h> +#include <View.h> +#include <Window.h> + +#include <string.h> +#include "platform/agg_platform_support.h" +#include "util/agg_color_conv_rgb8.h" + +using std::nothrow; + + +static void +attach_buffer_to_BBitmap(agg::rendering_buffer& buffer, BBitmap* bitmap, bool flipY) +{ + uint8* bits = (uint8*)bitmap->Bits(); + uint32 width = bitmap->Bounds().IntegerWidth() + 1; + uint32 height = bitmap->Bounds().IntegerHeight() + 1; + int32 bpr = bitmap->BytesPerRow(); + if (flipY) { +// XXX: why don't I have to do this?!? +// bits += bpr * (height - 1); + bpr = -bpr; + } + buffer.attach(bits, width, height, bpr); +} + + +static color_space +pix_format_to_color_space(agg::pix_format_e format) +{ + color_space bitmapFormat = B_NO_COLOR_SPACE; + switch (format) { + case agg::pix_format_rgb555: + + bitmapFormat = B_RGB15; + break; + + case agg::pix_format_rgb565: + + bitmapFormat = B_RGB16; + break; + + case agg::pix_format_rgb24: + case agg::pix_format_bgr24: + + bitmapFormat = B_RGB24; + break; + + case agg::pix_format_rgba32: + case agg::pix_format_argb32: + case agg::pix_format_abgr32: + case agg::pix_format_bgra32: + + bitmapFormat = B_RGBA32; + break; + } + return bitmapFormat; +} + + +// #pragma mark - + + +class AGGView : public BView { + public: + AGGView(BRect frame, agg::platform_support* agg, + agg::pix_format_e format, bool flipY); + virtual ~AGGView(); + + virtual void AttachedToWindow(); + virtual void DetachedFromWindow(); + + virtual void MessageReceived(BMessage* message); + virtual void Draw(BRect updateRect); + virtual void FrameResized(float width, float height); + + virtual void KeyDown(const char* bytes, int32 numBytes); + + virtual void MouseDown(BPoint where); + virtual void MouseMoved(BPoint where, uint32 transit, + const BMessage* dragMesage); + virtual void MouseUp(BPoint where); + + BBitmap* Bitmap() const; + + uint8 LastKeyDown() const; + uint32 MouseButtons(); + + void Update(); + void ForceRedraw(); + + unsigned GetKeyFlags(); + + private: + BBitmap* fBitmap; + agg::pix_format_e fFormat; + bool fFlipY; + + agg::platform_support* fAGG; + + uint32 fMouseButtons; + int32 fMouseX; + int32 fMouseY; + + uint8 fLastKeyDown; + + bool fRedraw; + + BMessageRunner* fPulse; + bigtime_t fLastPulse; + bool fEnableTicks; +}; + +AGGView::AGGView(BRect frame, + agg::platform_support* agg, + agg::pix_format_e format, + bool flipY) + : BView(frame, "AGG View", B_FOLLOW_ALL, + B_FRAME_EVENTS | B_WILL_DRAW), + fFormat(format), + fFlipY(flipY), + + fAGG(agg), + + fMouseButtons(0), + fMouseX(-1), + fMouseY(-1), + + fLastKeyDown(0), + + fRedraw(true), + + fPulse(NULL), + fLastPulse(0), + fEnableTicks(true) +{ + SetViewColor(B_TRANSPARENT_32_BIT); + + frame.OffsetTo(0.0, 0.0); + fBitmap = new BBitmap(frame, 0, pix_format_to_color_space(fFormat)); + if (fBitmap->IsValid()) { + attach_buffer_to_BBitmap(fAGG->rbuf_window(), fBitmap, fFlipY); + } else { + delete fBitmap; + fBitmap = NULL; + } +} + + +AGGView::~AGGView() +{ + delete fBitmap; + delete fPulse; +} + + +void +AGGView::AttachedToWindow() +{ + BMessage message('tick'); + BMessenger target(this, Looper()); + delete fPulse; +// BScreen screen; +// TODO: calc screen retrace + fPulse = new BMessageRunner(target, &message, 40000); + + // make sure we call this once + fAGG->on_resize(Bounds().IntegerWidth() + 1, + Bounds().IntegerHeight() + 1); + MakeFocus(); +} + + +void +AGGView::DetachedFromWindow() +{ + delete fPulse; + fPulse = NULL; +} + + +void +AGGView::MessageReceived(BMessage* message) +{ + bigtime_t now = system_time(); + switch (message->what) { + case 'tick': + // drop messages that have piled up + if (/*now - fLastPulse > 30000*/fEnableTicks) { + fLastPulse = now; + if (!fAGG->wait_mode()) + fAGG->on_idle(); + Window()->PostMessage('entk', this); + fEnableTicks = false; + } else { +// printf("dropping tick message (%lld)\n", now - fLastPulse); + } + break; + case 'entk': + fEnableTicks = true; + if (now - fLastPulse > 30000) { + fLastPulse = now; + if (!fAGG->wait_mode()) + fAGG->on_idle(); + } + break; + default: + BView::MessageReceived(message); + break; + } +} + + +void +AGGView::Draw(BRect updateRect) +{ + if (fBitmap) { + if (fRedraw) { + fAGG->on_draw(); + fRedraw = false; + } + if (fFormat == agg::pix_format_bgra32) { + DrawBitmap(fBitmap, updateRect, updateRect); + } else { + BBitmap* bitmap = new BBitmap(fBitmap->Bounds(), 0, B_RGBA32); + + agg::rendering_buffer rbufSrc; + attach_buffer_to_BBitmap(rbufSrc, fBitmap, false); + + agg::rendering_buffer rbufDst; + attach_buffer_to_BBitmap(rbufDst, bitmap, false); + + switch(fFormat) { + case agg::pix_format_rgb555: + agg::color_conv(&rbufDst, &rbufSrc, + agg::color_conv_rgb555_to_bgra32()); + break; + case agg::pix_format_rgb565: + agg::color_conv(&rbufDst, &rbufSrc, + agg::color_conv_rgb565_to_bgra32()); + break; + case agg::pix_format_rgb24: + agg::color_conv(&rbufDst, &rbufSrc, + agg::color_conv_rgb24_to_bgra32()); + break; + case agg::pix_format_bgr24: + agg::color_conv(&rbufDst, &rbufSrc, + agg::color_conv_bgr24_to_bgra32()); + break; + case agg::pix_format_rgba32: + agg::color_conv(&rbufDst, &rbufSrc, + agg::color_conv_rgba32_to_bgra32()); + break; + case agg::pix_format_argb32: + agg::color_conv(&rbufDst, &rbufSrc, + agg::color_conv_argb32_to_bgra32()); + break; + case agg::pix_format_abgr32: + agg::color_conv(&rbufDst, &rbufSrc, + agg::color_conv_abgr32_to_bgra32()); + break; + case agg::pix_format_bgra32: + agg::color_conv(&rbufDst, &rbufSrc, + agg::color_conv_bgra32_to_bgra32()); + break; + } + DrawBitmap(bitmap, updateRect, updateRect); + delete bitmap; + } + } else { + FillRect(updateRect); + } +} + + +void +AGGView::FrameResized(float width, float height) +{ + BRect r(0.0, 0.0, width, height); + BBitmap* bitmap = new BBitmap(r, 0, pix_format_to_color_space(fFormat)); + if (bitmap->IsValid()) { + delete fBitmap; + fBitmap = bitmap; + attach_buffer_to_BBitmap(fAGG->rbuf_window(), fBitmap, fFlipY); + + fAGG->trans_affine_resizing((int)width + 1, + (int)height + 1); + + // pass the event on to AGG + fAGG->on_resize((int)width + 1, (int)height + 1); + + fRedraw = true; + Invalidate(); + } else + delete bitmap; +} + + +void +AGGView::KeyDown(const char* bytes, int32 numBytes) +{ + if (bytes && numBytes > 0) { + fLastKeyDown = bytes[0]; + + bool left = false; + bool up = false; + bool right = false; + bool down = false; + + switch (fLastKeyDown) { + + case B_LEFT_ARROW: + left = true; + break; + + case B_UP_ARROW: + up = true; + break; + + case B_RIGHT_ARROW: + right = true; + break; + + case B_DOWN_ARROW: + down = true; + break; + } + +/* case key_f2: +fAGG->copy_window_to_img(agg::platform_support::max_images - 1); +fAGG->save_img(agg::platform_support::max_images - 1, "screenshot"); +break; +}*/ + + + if (fAGG->m_ctrls.on_arrow_keys(left, right, down, up)) { + fAGG->on_ctrl_change(); + fAGG->force_redraw(); + } else { + fAGG->on_key(fMouseX, fMouseY, fLastKeyDown, GetKeyFlags()); + } +// fAGG->on_key(fMouseX, fMouseY, fLastKeyDown, GetKeyFlags()); + + } +} + + +void +AGGView::MouseDown(BPoint where) +{ + BMessage* currentMessage = Window()->CurrentMessage(); + if (currentMessage) { + if (currentMessage->FindInt32("buttons", (int32*)&fMouseButtons) < B_OK) + fMouseButtons = B_PRIMARY_MOUSE_BUTTON; + } else + fMouseButtons = B_PRIMARY_MOUSE_BUTTON; + + fMouseX = (int)where.x; + fMouseY = fFlipY ? (int)(Bounds().Height() - where.y) : (int)where.y; + + // pass the event on to AGG + if (fMouseButtons == B_PRIMARY_MOUSE_BUTTON) { + // left mouse button -> see if to handle in controls + fAGG->m_ctrls.set_cur(fMouseX, fMouseY); + if (fAGG->m_ctrls.on_mouse_button_down(fMouseX, fMouseY)) { + fAGG->on_ctrl_change(); + fAGG->force_redraw(); + } else { + if (fAGG->m_ctrls.in_rect(fMouseX, fMouseY)) { + if (fAGG->m_ctrls.set_cur(fMouseX, fMouseY)) { + fAGG->on_ctrl_change(); + fAGG->force_redraw(); + } + } else { + fAGG->on_mouse_button_down(fMouseX, fMouseY, GetKeyFlags()); + } + } + } else if (fMouseButtons & B_SECONDARY_MOUSE_BUTTON) { + // right mouse button -> simple + fAGG->on_mouse_button_down(fMouseX, fMouseY, GetKeyFlags()); + } + SetMouseEventMask(B_POINTER_EVENTS, B_LOCK_WINDOW_FOCUS); +} + + +void +AGGView::MouseMoved(BPoint where, uint32 transit, const BMessage* dragMesage) +{ + // workarround missed mouse up events + // (if we react too slowly, app_server might have dropped events) + BMessage* currentMessage = Window()->CurrentMessage(); + int32 buttons = 0; + if (currentMessage->FindInt32("buttons", &buttons) < B_OK) { + buttons = 0; + } + if (!buttons) + MouseUp(where); + + fMouseX = (int)where.x; + fMouseY = fFlipY ? (int)(Bounds().Height() - where.y) : (int)where.y; + + // pass the event on to AGG + if (fAGG->m_ctrls.on_mouse_move(fMouseX, fMouseY, + (GetKeyFlags() & agg::mouse_left) != 0)) { + fAGG->on_ctrl_change(); + fAGG->force_redraw(); + } else { + if (!fAGG->m_ctrls.in_rect(fMouseX, fMouseY)) { + fAGG->on_mouse_move(fMouseX, fMouseY, GetKeyFlags()); + } + } +} + + +void +AGGView::MouseUp(BPoint where) +{ + fMouseX = (int)where.x; + fMouseY = fFlipY ? (int)(Bounds().Height() - where.y) : (int)where.y; + + // pass the event on to AGG + if (fMouseButtons == B_PRIMARY_MOUSE_BUTTON) { + fMouseButtons = 0; + + if (fAGG->m_ctrls.on_mouse_button_up(fMouseX, fMouseY)) { + fAGG->on_ctrl_change(); + fAGG->force_redraw(); + } + fAGG->on_mouse_button_up(fMouseX, fMouseY, GetKeyFlags()); + } else if (fMouseButtons == B_SECONDARY_MOUSE_BUTTON) { + fMouseButtons = 0; + + fAGG->on_mouse_button_up(fMouseX, fMouseY, GetKeyFlags()); + } +} + + +BBitmap* +AGGView::Bitmap() const +{ + return fBitmap; +} + + +uint8 +AGGView::LastKeyDown() const +{ + return fLastKeyDown; +} + + +uint32 +AGGView::MouseButtons() +{ + uint32 buttons = 0; + if (LockLooper()) { + buttons = fMouseButtons; + UnlockLooper(); + } + return buttons; +} + + +void +AGGView::Update() +{ + // trigger display update + if (LockLooper()) { + Invalidate(); + UnlockLooper(); + } +} + + +void +AGGView::ForceRedraw() +{ + // force a redraw (fRedraw = true;) + // and trigger display update + if (LockLooper()) { + fRedraw = true; + Invalidate(); + UnlockLooper(); + } +} + + +unsigned +AGGView::GetKeyFlags() +{ + uint32 buttons = fMouseButtons; + uint32 mods = modifiers(); + unsigned flags = 0; + if (buttons & B_PRIMARY_MOUSE_BUTTON) flags |= agg::mouse_left; + if (buttons & B_SECONDARY_MOUSE_BUTTON) flags |= agg::mouse_right; + if (mods & B_SHIFT_KEY) flags |= agg::kbd_shift; + if (mods & B_COMMAND_KEY) flags |= agg::kbd_ctrl; + return flags; +} + +// #pragma mark - + + +class AGGWindow : public BWindow { + public: + AGGWindow() + : BWindow(BRect(-50.0, -50.0, -10.0, -10.0), + "AGG Application", B_TITLED_WINDOW, B_ASYNCHRONOUS_CONTROLS) + { + } + + virtual bool QuitRequested() + { + be_app->PostMessage(B_QUIT_REQUESTED); + return true; + } + + bool Init(BRect frame, agg::platform_support* agg, agg::pix_format_e format, + bool flipY, uint32 flags) + { + MoveTo(frame.LeftTop()); + ResizeTo(frame.Width(), frame.Height()); + + SetFlags(flags); + + frame.OffsetTo(0.0, 0.0); + fView = new AGGView(frame, agg, format, flipY); + AddChild(fView); + + return fView->Bitmap() != NULL; + } + + + AGGView* View() const + { + return fView; + } + private: + AGGView* fView; +}; + +// #pragma mark - + + +class AGGApplication : public BApplication { + public: + AGGApplication() + : BApplication("application/x-vnd.AGG-AGG") + { + fWindow = new AGGWindow(); + } + + virtual void ReadyToRun() + { + if (fWindow) { + fWindow->Show(); + } + } + + virtual bool Init(agg::platform_support* agg, int width, int height, + agg::pix_format_e format, bool flipY, uint32 flags) + { + BRect r(50.0, 50.0, + 50.0 + width - 1.0, + 50.0 + height - 1.0); + uint32 windowFlags = B_ASYNCHRONOUS_CONTROLS; + if (!(flags & agg::window_resize)) + windowFlags |= B_NOT_RESIZABLE; + + return fWindow->Init(r, agg, format, flipY, windowFlags);; + } + + + AGGWindow* Window() const + { + return fWindow; + } + + private: + AGGWindow* fWindow; +}; + + +// #pragma mark - + + +namespace agg +{ + +class platform_specific { + public: + platform_specific(agg::platform_support* agg, + agg::pix_format_e format, bool flip_y) + : fAGG(agg), + fApp(NULL), + fFormat(format), + fFlipY(flip_y), + fTimerStart(system_time()) + { + memset(fImages, 0, sizeof(fImages)); + fApp = new AGGApplication(); + fAppPath[0] = 0; + // figure out where we're running from + app_info info; + status_t ret = fApp->GetAppInfo(&info); + if (ret >= B_OK) { + BPath path(&info.ref); + ret = path.InitCheck(); + if (ret >= B_OK) { + ret = path.GetParent(&path); + if (ret >= B_OK) { + sprintf(fAppPath, "%s", path.Path()); + } else { + fprintf(stderr, "getting app parent folder failed: %s\n", strerror(ret)); + } + } else { + fprintf(stderr, "making app path failed: %s\n", strerror(ret)); + } + } else { + fprintf(stderr, "GetAppInfo() failed: %s\n", strerror(ret)); + } + } + ~platform_specific() + { + for (int32 i = 0; i < agg::platform_support::max_images; i++) + delete fImages[i]; + delete fApp; + } + + bool Init(int width, int height, unsigned flags) + { + return fApp->Init(fAGG, width, height, fFormat, fFlipY, flags); + } + + int Run() + { + status_t ret = B_NO_INIT; + if (fApp) { + fApp->Run(); + ret = B_OK; + } + return ret; + } + + void SetTitle(const char* title) + { + if (fApp && fApp->Window() && fApp->Window()->Lock()) { + fApp->Window()->SetTitle(title); + fApp->Window()->Unlock(); + } + } + void StartTimer() + { + fTimerStart = system_time(); + } + double ElapsedTime() const + { + return (system_time() - fTimerStart) / 1000.0; + } + + void ForceRedraw() + { + fApp->Window()->View()->ForceRedraw(); + } + void UpdateWindow() + { + fApp->Window()->View()->Update(); + } + + + agg::platform_support* fAGG; + AGGApplication* fApp; + agg::pix_format_e fFormat; + bool fFlipY; + bigtime_t fTimerStart; + BBitmap* fImages[agg::platform_support::max_images]; + + char fAppPath[B_PATH_NAME_LENGTH]; + char fFilePath[B_PATH_NAME_LENGTH]; +}; + + + //------------------------------------------------------------------------ + platform_support::platform_support(pix_format_e format, bool flip_y) : + m_specific(new platform_specific(this, format, flip_y)), + m_format(format), + m_bpp(32/*m_specific->m_bpp*/), + m_window_flags(0), + m_wait_mode(true), + m_flip_y(flip_y), + m_initial_width(10), + m_initial_height(10) + { + strcpy(m_caption, "Anti-Grain Geometry Application"); + } + + + //------------------------------------------------------------------------ + platform_support::~platform_support() + { + delete m_specific; + } + + //------------------------------------------------------------------------ + void platform_support::caption(const char* cap) + { + strcpy(m_caption, cap); + m_specific->SetTitle(cap); + } + + //------------------------------------------------------------------------ + void platform_support::start_timer() + { + m_specific->StartTimer(); + } + + //------------------------------------------------------------------------ + double platform_support::elapsed_time() const + { + return m_specific->ElapsedTime(); + } + + //------------------------------------------------------------------------ + void* platform_support::raw_display_handler() + { + // TODO: if we ever support BDirectWindow here, that would + // be the frame buffer pointer with offset to the window top left + return NULL; + } + + //------------------------------------------------------------------------ + void platform_support::message(const char* msg) + { + BAlert* alert = new BAlert("AGG Message", msg, "Ok"); + alert->Go(/*NULL*/); + } + + + //------------------------------------------------------------------------ + bool platform_support::init(unsigned width, unsigned height, unsigned flags) + { + m_initial_width = width; + m_initial_height = height; + m_window_flags = flags; + + if (m_specific->Init(width, height, flags)) { + on_init(); + return true; + } + + return false; + } + + + //------------------------------------------------------------------------ + int platform_support::run() + { + return m_specific->Run(); + } + + + //------------------------------------------------------------------------ + const char* platform_support::img_ext() const { return ".ppm"; } + + + const char* platform_support::full_file_name(const char* file_name) + { + sprintf(m_specific->fFilePath, "%s/%s", m_specific->fAppPath, file_name); + return m_specific->fFilePath; + } + + + //------------------------------------------------------------------------ + bool platform_support::load_img(unsigned idx, const char* file) + { + if (idx < max_images) + { + char path[B_PATH_NAME_LENGTH]; + sprintf(path, "%s/%s%s", m_specific->fAppPath, file, img_ext()); + BBitmap* transBitmap = BTranslationUtils::GetBitmap(path); + if (transBitmap && transBitmap->IsValid()) { + if(transBitmap->ColorSpace() != B_RGB32 && transBitmap->ColorSpace() != B_RGBA32) { + // ups we got a smart ass Translator making our live harder + delete transBitmap; + return false; + } + + color_space format = B_RGB24; + + switch (m_format) { + case pix_format_gray8: + format = B_GRAY8; + break; + case pix_format_rgb555: + format = B_RGB15; + break; + case pix_format_rgb565: + format = B_RGB16; + break; + case pix_format_rgb24: + format = B_RGB24_BIG; + break; + case pix_format_bgr24: + format = B_RGB24; + break; + case pix_format_abgr32: + case pix_format_argb32: + case pix_format_bgra32: + format = B_RGB32; + break; + case pix_format_rgba32: + format = B_RGB32_BIG; + break; + } + BBitmap* bitmap = new (nothrow) BBitmap(transBitmap->Bounds(), 0, format); + if (!bitmap || !bitmap->IsValid()) { + fprintf(stderr, "failed to allocate temporary bitmap!\n"); + delete transBitmap; + delete bitmap; + return false; + } + + delete m_specific->fImages[idx]; + + rendering_buffer rbuf_tmp; + attach_buffer_to_BBitmap(rbuf_tmp, transBitmap, m_flip_y); + + m_specific->fImages[idx] = bitmap; + + attach_buffer_to_BBitmap(m_rbuf_img[idx], bitmap, m_flip_y); + + rendering_buffer* dst = &m_rbuf_img[idx]; + + switch(m_format) + { + case pix_format_gray8: + return false; +// color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_gray8()); break; + break; + + case pix_format_rgb555: + color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_rgb555()); break; + break; + + case pix_format_rgb565: + color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_rgb565()); break; + break; + + case pix_format_rgb24: + color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_rgb24()); break; + break; + + case pix_format_bgr24: + color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_bgr24()); break; + break; + + case pix_format_abgr32: + color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_abgr32()); break; + break; + + case pix_format_argb32: + color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_argb32()); break; + break; + + case pix_format_bgra32: + color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_bgra32()); break; + break; + + case pix_format_rgba32: + color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_rgba32()); break; + break; + } + delete transBitmap; + + return true; + + } else { + fprintf(stderr, "failed to load bitmap: '%s'\n", full_file_name(file)); + } + } + return false; + } + + + + //------------------------------------------------------------------------ + bool platform_support::save_img(unsigned idx, const char* file) + { + // TODO: implement using BTranslatorRoster and friends + return false; + } + + + + //------------------------------------------------------------------------ + bool platform_support::create_img(unsigned idx, unsigned width, unsigned height) + { + if(idx < max_images) + { + if(width == 0) width = m_specific->fApp->Window()->View()->Bitmap()->Bounds().IntegerWidth() + 1; + if(height == 0) height = m_specific->fApp->Window()->View()->Bitmap()->Bounds().IntegerHeight() + 1; + BBitmap* bitmap = new BBitmap(BRect(0.0, 0.0, width - 1, height - 1), 0, B_RGBA32);; + if (bitmap && bitmap->IsValid()) { + delete m_specific->fImages[idx]; + m_specific->fImages[idx] = bitmap; + attach_buffer_to_BBitmap(m_rbuf_img[idx], bitmap, m_flip_y); + return true; + } else { + delete bitmap; + } + } + return false; + } + + + //------------------------------------------------------------------------ + void platform_support::force_redraw() + { + m_specific->ForceRedraw(); + } + + + + //------------------------------------------------------------------------ + void platform_support::update_window() + { + m_specific->UpdateWindow(); + } + + + //------------------------------------------------------------------------ + void platform_support::on_init() {} + void platform_support::on_resize(int sx, int sy) {} + void platform_support::on_idle() {} + void platform_support::on_mouse_move(int x, int y, unsigned flags) {} + void platform_support::on_mouse_button_down(int x, int y, unsigned flags) {} + void platform_support::on_mouse_button_up(int x, int y, unsigned flags) {} + void platform_support::on_key(int x, int y, unsigned key, unsigned flags) {} + void platform_support::on_ctrl_change() {} + void platform_support::on_draw() {} + void platform_support::on_post_draw(void* raw_handler) {} +} + + + + + + +//---------------------------------------------------------------------------- +int agg_main(int argc, char* argv[]); + + + +int +main(int argc, char* argv[]) +{ + return agg_main(argc, argv); +} + + + + diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/X11/agg_platform_support.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/X11/agg_platform_support.cpp new file mode 100644 index 00000000000..46b874d7385 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/X11/agg_platform_support.cpp @@ -0,0 +1,1601 @@ +//---------------------------------------------------------------------------- +// 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. X11 version. +// +//---------------------------------------------------------------------------- + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <ctype.h> +#include <time.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <X11/Xatom.h> +#include <X11/keysym.h> +#include "agg_basics.h" +#include "agg_pixfmt_gray.h" +#include "agg_pixfmt_rgb.h" +#include "agg_pixfmt_rgba.h" +#include "util/agg_color_conv_rgb8.h" +#include "platform/agg_platform_support.h" + + +namespace agg +{ + //------------------------------------------------------------------------ + class platform_specific + { + public: + platform_specific(pix_format_e format, bool flip_y); + ~platform_specific(); + + void caption(const char* capt); + void put_image(const rendering_buffer* src); + + pix_format_e m_format; + pix_format_e m_sys_format; + int m_byte_order; + bool m_flip_y; + unsigned m_bpp; + unsigned m_sys_bpp; + Display* m_display; + int m_screen; + int m_depth; + Visual* m_visual; + Window m_window; + GC m_gc; + XImage* m_ximg_window; + XSetWindowAttributes m_window_attributes; + Atom m_close_atom; + unsigned char* m_buf_window; + unsigned char* m_buf_img[platform_support::max_images]; + unsigned m_keymap[256]; + + bool m_update_flag; + bool m_resize_flag; + bool m_initialized; + //bool m_wait_mode; + clock_t m_sw_start; + }; + + + + //------------------------------------------------------------------------ + platform_specific::platform_specific(pix_format_e format, bool flip_y) : + m_format(format), + m_sys_format(pix_format_undefined), + m_byte_order(LSBFirst), + m_flip_y(flip_y), + m_bpp(0), + m_sys_bpp(0), + m_display(0), + m_screen(0), + m_depth(0), + m_visual(0), + m_window(0), + m_gc(0), + m_ximg_window(0), + m_close_atom(0), + + m_buf_window(0), + + m_update_flag(true), + m_resize_flag(true), + m_initialized(false) + //m_wait_mode(true) + { + memset(m_buf_img, 0, sizeof(m_buf_img)); + + unsigned i; + for(i = 0; i < 256; i++) + { + m_keymap[i] = i; + } + + m_keymap[XK_Pause&0xFF] = key_pause; + m_keymap[XK_Clear&0xFF] = key_clear; + + m_keymap[XK_KP_0&0xFF] = key_kp0; + m_keymap[XK_KP_1&0xFF] = key_kp1; + m_keymap[XK_KP_2&0xFF] = key_kp2; + m_keymap[XK_KP_3&0xFF] = key_kp3; + m_keymap[XK_KP_4&0xFF] = key_kp4; + m_keymap[XK_KP_5&0xFF] = key_kp5; + m_keymap[XK_KP_6&0xFF] = key_kp6; + m_keymap[XK_KP_7&0xFF] = key_kp7; + m_keymap[XK_KP_8&0xFF] = key_kp8; + m_keymap[XK_KP_9&0xFF] = key_kp9; + + m_keymap[XK_KP_Insert&0xFF] = key_kp0; + m_keymap[XK_KP_End&0xFF] = key_kp1; + m_keymap[XK_KP_Down&0xFF] = key_kp2; + m_keymap[XK_KP_Page_Down&0xFF] = key_kp3; + m_keymap[XK_KP_Left&0xFF] = key_kp4; + m_keymap[XK_KP_Begin&0xFF] = key_kp5; + m_keymap[XK_KP_Right&0xFF] = key_kp6; + m_keymap[XK_KP_Home&0xFF] = key_kp7; + m_keymap[XK_KP_Up&0xFF] = key_kp8; + m_keymap[XK_KP_Page_Up&0xFF] = key_kp9; + m_keymap[XK_KP_Delete&0xFF] = key_kp_period; + m_keymap[XK_KP_Decimal&0xFF] = key_kp_period; + m_keymap[XK_KP_Divide&0xFF] = key_kp_divide; + m_keymap[XK_KP_Multiply&0xFF] = key_kp_multiply; + m_keymap[XK_KP_Subtract&0xFF] = key_kp_minus; + m_keymap[XK_KP_Add&0xFF] = key_kp_plus; + m_keymap[XK_KP_Enter&0xFF] = key_kp_enter; + m_keymap[XK_KP_Equal&0xFF] = key_kp_equals; + + m_keymap[XK_Up&0xFF] = key_up; + m_keymap[XK_Down&0xFF] = key_down; + m_keymap[XK_Right&0xFF] = key_right; + m_keymap[XK_Left&0xFF] = key_left; + m_keymap[XK_Insert&0xFF] = key_insert; + m_keymap[XK_Home&0xFF] = key_delete; + m_keymap[XK_End&0xFF] = key_end; + m_keymap[XK_Page_Up&0xFF] = key_page_up; + m_keymap[XK_Page_Down&0xFF] = key_page_down; + + m_keymap[XK_F1&0xFF] = key_f1; + m_keymap[XK_F2&0xFF] = key_f2; + m_keymap[XK_F3&0xFF] = key_f3; + m_keymap[XK_F4&0xFF] = key_f4; + m_keymap[XK_F5&0xFF] = key_f5; + m_keymap[XK_F6&0xFF] = key_f6; + m_keymap[XK_F7&0xFF] = key_f7; + m_keymap[XK_F8&0xFF] = key_f8; + m_keymap[XK_F9&0xFF] = key_f9; + m_keymap[XK_F10&0xFF] = key_f10; + m_keymap[XK_F11&0xFF] = key_f11; + m_keymap[XK_F12&0xFF] = key_f12; + m_keymap[XK_F13&0xFF] = key_f13; + m_keymap[XK_F14&0xFF] = key_f14; + m_keymap[XK_F15&0xFF] = key_f15; + + m_keymap[XK_Num_Lock&0xFF] = key_numlock; + m_keymap[XK_Caps_Lock&0xFF] = key_capslock; + m_keymap[XK_Scroll_Lock&0xFF] = key_scrollock; + + switch(m_format) + { + default: break; + case pix_format_gray8: + case pix_format_sgray8: + m_bpp = 8; + break; + + case pix_format_gray16: + m_bpp = 16; + break; + + case pix_format_gray32: + m_bpp = 32; + break; + + case pix_format_rgb565: + case pix_format_rgb555: + m_bpp = 16; + break; + + case pix_format_rgb24: + case pix_format_bgr24: + case pix_format_srgb24: + case pix_format_sbgr24: + m_bpp = 24; + break; + + case pix_format_bgra32: + case pix_format_abgr32: + case pix_format_argb32: + case pix_format_rgba32: + case pix_format_sbgra32: + case pix_format_sabgr32: + case pix_format_sargb32: + case pix_format_srgba32: + m_bpp = 32; + break; + + case pix_format_rgb48: + case pix_format_bgr48: + m_bpp = 48; + break; + + case pix_format_bgra64: + case pix_format_abgr64: + case pix_format_argb64: + case pix_format_rgba64: + m_bpp = 64; + break; + + case pix_format_rgb96: + case pix_format_bgr96: + m_bpp = 96; + break; + + case pix_format_bgra128: + case pix_format_abgr128: + case pix_format_argb128: + case pix_format_rgba128: + m_bpp = 128; + break; + } + m_sw_start = clock(); + } + + //------------------------------------------------------------------------ + platform_specific::~platform_specific() + { + } + + //------------------------------------------------------------------------ + void platform_specific::caption(const char* capt) + { + XTextProperty tp; + tp.value = (unsigned char *)capt; + tp.encoding = XA_WM_NAME; + tp.format = 8; + tp.nitems = strlen(capt); + XSetWMName(m_display, m_window, &tp); + XStoreName(m_display, m_window, capt); + XSetIconName(m_display, m_window, capt); + XSetWMIconName(m_display, m_window, &tp); + } + + + //------------------------------------------------------------------------ + void platform_specific::put_image(const rendering_buffer* src) + { + if(m_ximg_window == 0) return; + m_ximg_window->data = (char*)m_buf_window; + + if(m_format == m_sys_format) + { + XPutImage(m_display, + m_window, + m_gc, + m_ximg_window, + 0, 0, 0, 0, + src->width(), + src->height()); + } + else + { + int row_len = src->width() * m_sys_bpp / 8; + unsigned char* buf_tmp = + new unsigned char[row_len * src->height()]; + + rendering_buffer rbuf_tmp; + rbuf_tmp.attach(buf_tmp, + src->width(), + src->height(), + m_flip_y ? -row_len : row_len); + + switch(m_sys_format) + { + default: break; + case pix_format_rgb555: + switch(m_format) + { + default: break; + case pix_format_rgb555: color_conv(&rbuf_tmp, src, color_conv_rgb555_to_rgb555()); break; + case pix_format_rgb565: color_conv(&rbuf_tmp, src, color_conv_rgb565_to_rgb555()); break; + case pix_format_rgb24: color_conv(&rbuf_tmp, src, color_conv_rgb24_to_rgb555()); break; + case pix_format_bgr24: color_conv(&rbuf_tmp, src, color_conv_bgr24_to_rgb555()); break; + case pix_format_rgba32: color_conv(&rbuf_tmp, src, color_conv_rgba32_to_rgb555()); break; + case pix_format_argb32: color_conv(&rbuf_tmp, src, color_conv_argb32_to_rgb555()); break; + case pix_format_bgra32: color_conv(&rbuf_tmp, src, color_conv_bgra32_to_rgb555()); break; + case pix_format_abgr32: color_conv(&rbuf_tmp, src, color_conv_abgr32_to_rgb555()); break; + } + break; + + case pix_format_rgb565: + switch(m_format) + { + default: break; + case pix_format_rgb555: color_conv(&rbuf_tmp, src, color_conv_rgb555_to_rgb565()); break; + case pix_format_rgb565: color_conv(&rbuf_tmp, src, color_conv_rgb565_to_rgb565()); break; + case pix_format_rgb24: color_conv(&rbuf_tmp, src, color_conv_rgb24_to_rgb565()); break; + case pix_format_bgr24: color_conv(&rbuf_tmp, src, color_conv_bgr24_to_rgb565()); break; + case pix_format_rgba32: color_conv(&rbuf_tmp, src, color_conv_rgba32_to_rgb565()); break; + case pix_format_argb32: color_conv(&rbuf_tmp, src, color_conv_argb32_to_rgb565()); break; + case pix_format_bgra32: color_conv(&rbuf_tmp, src, color_conv_bgra32_to_rgb565()); break; + case pix_format_abgr32: color_conv(&rbuf_tmp, src, color_conv_abgr32_to_rgb565()); break; + } + break; + + case pix_format_rgba32: + switch(m_format) + { + default: break; + case pix_format_sgray8: convert<pixfmt_srgba32, pixfmt_sgray8>(&rbuf_tmp, src); break; + case pix_format_gray8: convert<pixfmt_srgba32, pixfmt_gray8>(&rbuf_tmp, src); break; + case pix_format_gray16: convert<pixfmt_srgba32, pixfmt_gray16>(&rbuf_tmp, src); break; + case pix_format_gray32: convert<pixfmt_srgba32, pixfmt_gray32>(&rbuf_tmp, src); break; + case pix_format_rgb555: color_conv(&rbuf_tmp, src, color_conv_rgb555_to_rgba32()); break; + case pix_format_rgb565: color_conv(&rbuf_tmp, src, color_conv_rgb565_to_rgba32()); break; + case pix_format_srgb24: convert<pixfmt_srgba32, pixfmt_srgb24>(&rbuf_tmp, src); break; + case pix_format_sbgr24: convert<pixfmt_srgba32, pixfmt_sbgr24>(&rbuf_tmp, src); break; + case pix_format_rgb24: convert<pixfmt_srgba32, pixfmt_rgb24>(&rbuf_tmp, src); break; + case pix_format_bgr24: convert<pixfmt_srgba32, pixfmt_bgr24>(&rbuf_tmp, src); break; + case pix_format_srgba32: convert<pixfmt_srgba32, pixfmt_srgba32>(&rbuf_tmp, src); break; + case pix_format_sargb32: convert<pixfmt_srgba32, pixfmt_sargb32>(&rbuf_tmp, src); break; + case pix_format_sabgr32: convert<pixfmt_srgba32, pixfmt_sabgr32>(&rbuf_tmp, src); break; + case pix_format_sbgra32: convert<pixfmt_srgba32, pixfmt_sbgra32>(&rbuf_tmp, src); break; + case pix_format_rgba32: convert<pixfmt_srgba32, pixfmt_rgba32>(&rbuf_tmp, src); break; + case pix_format_argb32: convert<pixfmt_srgba32, pixfmt_argb32>(&rbuf_tmp, src); break; + case pix_format_abgr32: convert<pixfmt_srgba32, pixfmt_abgr32>(&rbuf_tmp, src); break; + case pix_format_bgra32: convert<pixfmt_srgba32, pixfmt_bgra32>(&rbuf_tmp, src); break; + case pix_format_rgb48: convert<pixfmt_srgba32, pixfmt_rgb48>(&rbuf_tmp, src); break; + case pix_format_bgr48: convert<pixfmt_srgba32, pixfmt_bgr48>(&rbuf_tmp, src); break; + case pix_format_rgba64: convert<pixfmt_srgba32, pixfmt_rgba64>(&rbuf_tmp, src); break; + case pix_format_argb64: convert<pixfmt_srgba32, pixfmt_argb64>(&rbuf_tmp, src); break; + case pix_format_abgr64: convert<pixfmt_srgba32, pixfmt_abgr64>(&rbuf_tmp, src); break; + case pix_format_bgra64: convert<pixfmt_srgba32, pixfmt_bgra64>(&rbuf_tmp, src); break; + case pix_format_rgb96: convert<pixfmt_srgba32, pixfmt_rgb96>(&rbuf_tmp, src); break; + case pix_format_bgr96: convert<pixfmt_srgba32, pixfmt_bgr96>(&rbuf_tmp, src); break; + case pix_format_rgba128: convert<pixfmt_srgba32, pixfmt_rgba128>(&rbuf_tmp, src); break; + case pix_format_argb128: convert<pixfmt_srgba32, pixfmt_argb128>(&rbuf_tmp, src); break; + case pix_format_abgr128: convert<pixfmt_srgba32, pixfmt_abgr128>(&rbuf_tmp, src); break; + case pix_format_bgra128: convert<pixfmt_srgba32, pixfmt_bgra128>(&rbuf_tmp, src); break; + } + break; + + case pix_format_abgr32: + switch(m_format) + { + default: break; + case pix_format_sgray8: convert<pixfmt_sabgr32, pixfmt_sgray8>(&rbuf_tmp, src); break; + case pix_format_gray8: convert<pixfmt_sabgr32, pixfmt_gray8>(&rbuf_tmp, src); break; + case pix_format_gray16: convert<pixfmt_sabgr32, pixfmt_gray16>(&rbuf_tmp, src); break; + case pix_format_gray32: convert<pixfmt_sabgr32, pixfmt_gray32>(&rbuf_tmp, src); break; + case pix_format_rgb555: color_conv(&rbuf_tmp, src, color_conv_rgb555_to_abgr32()); break; + case pix_format_rgb565: color_conv(&rbuf_tmp, src, color_conv_rgb565_to_abgr32()); break; + case pix_format_srgb24: convert<pixfmt_sabgr32, pixfmt_srgb24>(&rbuf_tmp, src); break; + case pix_format_sbgr24: convert<pixfmt_sabgr32, pixfmt_sbgr24>(&rbuf_tmp, src); break; + case pix_format_rgb24: convert<pixfmt_sabgr32, pixfmt_rgb24>(&rbuf_tmp, src); break; + case pix_format_bgr24: convert<pixfmt_sabgr32, pixfmt_bgr24>(&rbuf_tmp, src); break; + case pix_format_srgba32: convert<pixfmt_sabgr32, pixfmt_srgba32>(&rbuf_tmp, src); break; + case pix_format_sargb32: convert<pixfmt_sabgr32, pixfmt_sargb32>(&rbuf_tmp, src); break; + case pix_format_sabgr32: convert<pixfmt_sabgr32, pixfmt_sabgr32>(&rbuf_tmp, src); break; + case pix_format_sbgra32: convert<pixfmt_sabgr32, pixfmt_sbgra32>(&rbuf_tmp, src); break; + case pix_format_rgba32: convert<pixfmt_sabgr32, pixfmt_rgba32>(&rbuf_tmp, src); break; + case pix_format_argb32: convert<pixfmt_sabgr32, pixfmt_argb32>(&rbuf_tmp, src); break; + case pix_format_abgr32: convert<pixfmt_sabgr32, pixfmt_abgr32>(&rbuf_tmp, src); break; + case pix_format_bgra32: convert<pixfmt_sabgr32, pixfmt_bgra32>(&rbuf_tmp, src); break; + case pix_format_rgb48: convert<pixfmt_sabgr32, pixfmt_rgb48>(&rbuf_tmp, src); break; + case pix_format_bgr48: convert<pixfmt_sabgr32, pixfmt_bgr48>(&rbuf_tmp, src); break; + case pix_format_rgba64: convert<pixfmt_sabgr32, pixfmt_rgba64>(&rbuf_tmp, src); break; + case pix_format_argb64: convert<pixfmt_sabgr32, pixfmt_argb64>(&rbuf_tmp, src); break; + case pix_format_abgr64: convert<pixfmt_sabgr32, pixfmt_abgr64>(&rbuf_tmp, src); break; + case pix_format_bgra64: convert<pixfmt_sabgr32, pixfmt_bgra64>(&rbuf_tmp, src); break; + case pix_format_rgb96: convert<pixfmt_sabgr32, pixfmt_rgb96>(&rbuf_tmp, src); break; + case pix_format_bgr96: convert<pixfmt_sabgr32, pixfmt_bgr96>(&rbuf_tmp, src); break; + case pix_format_rgba128: convert<pixfmt_sabgr32, pixfmt_rgba128>(&rbuf_tmp, src); break; + case pix_format_argb128: convert<pixfmt_sabgr32, pixfmt_argb128>(&rbuf_tmp, src); break; + case pix_format_abgr128: convert<pixfmt_sabgr32, pixfmt_abgr128>(&rbuf_tmp, src); break; + case pix_format_bgra128: convert<pixfmt_sabgr32, pixfmt_bgra128>(&rbuf_tmp, src); break; + } + break; + + case pix_format_argb32: + switch(m_format) + { + default: break; + case pix_format_sgray8: convert<pixfmt_sargb32, pixfmt_sgray8>(&rbuf_tmp, src); break; + case pix_format_gray8: convert<pixfmt_sargb32, pixfmt_gray8>(&rbuf_tmp, src); break; + case pix_format_gray16: convert<pixfmt_sargb32, pixfmt_gray16>(&rbuf_tmp, src); break; + case pix_format_gray32: convert<pixfmt_sargb32, pixfmt_gray32>(&rbuf_tmp, src); break; + case pix_format_rgb555: color_conv(&rbuf_tmp, src, color_conv_rgb555_to_argb32()); break; + case pix_format_rgb565: color_conv(&rbuf_tmp, src, color_conv_rgb565_to_argb32()); break; + case pix_format_srgb24: convert<pixfmt_sargb32, pixfmt_srgb24>(&rbuf_tmp, src); break; + case pix_format_sbgr24: convert<pixfmt_sargb32, pixfmt_sbgr24>(&rbuf_tmp, src); break; + case pix_format_rgb24: convert<pixfmt_sargb32, pixfmt_rgb24>(&rbuf_tmp, src); break; + case pix_format_bgr24: convert<pixfmt_sargb32, pixfmt_bgr24>(&rbuf_tmp, src); break; + case pix_format_srgba32: convert<pixfmt_sargb32, pixfmt_srgba32>(&rbuf_tmp, src); break; + case pix_format_sargb32: convert<pixfmt_sargb32, pixfmt_sargb32>(&rbuf_tmp, src); break; + case pix_format_sabgr32: convert<pixfmt_sargb32, pixfmt_sabgr32>(&rbuf_tmp, src); break; + case pix_format_sbgra32: convert<pixfmt_sargb32, pixfmt_sbgra32>(&rbuf_tmp, src); break; + case pix_format_rgba32: convert<pixfmt_sargb32, pixfmt_rgba32>(&rbuf_tmp, src); break; + case pix_format_argb32: convert<pixfmt_sargb32, pixfmt_argb32>(&rbuf_tmp, src); break; + case pix_format_abgr32: convert<pixfmt_sargb32, pixfmt_abgr32>(&rbuf_tmp, src); break; + case pix_format_bgra32: convert<pixfmt_sargb32, pixfmt_bgra32>(&rbuf_tmp, src); break; + case pix_format_rgb48: convert<pixfmt_sargb32, pixfmt_rgb48>(&rbuf_tmp, src); break; + case pix_format_bgr48: convert<pixfmt_sargb32, pixfmt_bgr48>(&rbuf_tmp, src); break; + case pix_format_rgba64: convert<pixfmt_sargb32, pixfmt_rgba64>(&rbuf_tmp, src); break; + case pix_format_argb64: convert<pixfmt_sargb32, pixfmt_argb64>(&rbuf_tmp, src); break; + case pix_format_abgr64: convert<pixfmt_sargb32, pixfmt_abgr64>(&rbuf_tmp, src); break; + case pix_format_bgra64: convert<pixfmt_sargb32, pixfmt_bgra64>(&rbuf_tmp, src); break; + case pix_format_rgb96: convert<pixfmt_sargb32, pixfmt_rgb96>(&rbuf_tmp, src); break; + case pix_format_bgr96: convert<pixfmt_sargb32, pixfmt_bgr96>(&rbuf_tmp, src); break; + case pix_format_rgba128: convert<pixfmt_sargb32, pixfmt_rgba128>(&rbuf_tmp, src); break; + case pix_format_argb128: convert<pixfmt_sargb32, pixfmt_argb128>(&rbuf_tmp, src); break; + case pix_format_abgr128: convert<pixfmt_sargb32, pixfmt_abgr128>(&rbuf_tmp, src); break; + case pix_format_bgra128: convert<pixfmt_sargb32, pixfmt_bgra128>(&rbuf_tmp, src); break; + } + break; + + case pix_format_bgra32: + switch(m_format) + { + default: break; + case pix_format_sgray8: convert<pixfmt_sbgra32, pixfmt_sgray8>(&rbuf_tmp, src); break; + case pix_format_gray8: convert<pixfmt_sbgra32, pixfmt_gray8>(&rbuf_tmp, src); break; + case pix_format_gray16: convert<pixfmt_sbgra32, pixfmt_gray16>(&rbuf_tmp, src); break; + case pix_format_gray32: convert<pixfmt_sbgra32, pixfmt_gray32>(&rbuf_tmp, src); break; + case pix_format_rgb555: color_conv(&rbuf_tmp, src, color_conv_rgb555_to_bgra32()); break; + case pix_format_rgb565: color_conv(&rbuf_tmp, src, color_conv_rgb565_to_bgra32()); break; + case pix_format_srgb24: convert<pixfmt_sbgra32, pixfmt_srgb24>(&rbuf_tmp, src); break; + case pix_format_sbgr24: convert<pixfmt_sbgra32, pixfmt_sbgr24>(&rbuf_tmp, src); break; + case pix_format_rgb24: convert<pixfmt_sbgra32, pixfmt_rgb24>(&rbuf_tmp, src); break; + case pix_format_bgr24: convert<pixfmt_sbgra32, pixfmt_bgr24>(&rbuf_tmp, src); break; + case pix_format_srgba32: convert<pixfmt_sbgra32, pixfmt_srgba32>(&rbuf_tmp, src); break; + case pix_format_sargb32: convert<pixfmt_sbgra32, pixfmt_sargb32>(&rbuf_tmp, src); break; + case pix_format_sabgr32: convert<pixfmt_sbgra32, pixfmt_sabgr32>(&rbuf_tmp, src); break; + case pix_format_sbgra32: convert<pixfmt_sbgra32, pixfmt_sbgra32>(&rbuf_tmp, src); break; + case pix_format_rgba32: convert<pixfmt_sbgra32, pixfmt_rgba32>(&rbuf_tmp, src); break; + case pix_format_argb32: convert<pixfmt_sbgra32, pixfmt_argb32>(&rbuf_tmp, src); break; + case pix_format_abgr32: convert<pixfmt_sbgra32, pixfmt_abgr32>(&rbuf_tmp, src); break; + case pix_format_bgra32: convert<pixfmt_sbgra32, pixfmt_bgra32>(&rbuf_tmp, src); break; + case pix_format_rgb48: convert<pixfmt_sbgra32, pixfmt_rgb48>(&rbuf_tmp, src); break; + case pix_format_bgr48: convert<pixfmt_sbgra32, pixfmt_bgr48>(&rbuf_tmp, src); break; + case pix_format_rgba64: convert<pixfmt_sbgra32, pixfmt_rgba64>(&rbuf_tmp, src); break; + case pix_format_argb64: convert<pixfmt_sbgra32, pixfmt_argb64>(&rbuf_tmp, src); break; + case pix_format_abgr64: convert<pixfmt_sbgra32, pixfmt_abgr64>(&rbuf_tmp, src); break; + case pix_format_bgra64: convert<pixfmt_sbgra32, pixfmt_bgra64>(&rbuf_tmp, src); break; + case pix_format_rgb96: convert<pixfmt_sbgra32, pixfmt_rgb96>(&rbuf_tmp, src); break; + case pix_format_bgr96: convert<pixfmt_sbgra32, pixfmt_bgr96>(&rbuf_tmp, src); break; + case pix_format_rgba128: convert<pixfmt_sbgra32, pixfmt_rgba128>(&rbuf_tmp, src); break; + case pix_format_argb128: convert<pixfmt_sbgra32, pixfmt_argb128>(&rbuf_tmp, src); break; + case pix_format_abgr128: convert<pixfmt_sbgra32, pixfmt_abgr128>(&rbuf_tmp, src); break; + case pix_format_bgra128: convert<pixfmt_sbgra32, pixfmt_bgra128>(&rbuf_tmp, src); break; + } + break; + } + + m_ximg_window->data = (char*)buf_tmp; + XPutImage(m_display, + m_window, + m_gc, + m_ximg_window, + 0, 0, 0, 0, + src->width(), + src->height()); + + delete [] buf_tmp; + } + } + + + //------------------------------------------------------------------------ + platform_support::platform_support(pix_format_e format, bool flip_y) : + m_specific(new platform_specific(format, flip_y)), + m_format(format), + m_bpp(m_specific->m_bpp), + m_window_flags(0), + m_wait_mode(true), + m_flip_y(flip_y), + m_initial_width(10), + m_initial_height(10) + { + strcpy(m_caption, "AGG Application"); + } + + //------------------------------------------------------------------------ + platform_support::~platform_support() + { + delete m_specific; + } + + + + //------------------------------------------------------------------------ + void platform_support::caption(const char* cap) + { + strcpy(m_caption, cap); + if(m_specific->m_initialized) + { + m_specific->caption(cap); + } + } + + + //------------------------------------------------------------------------ + enum xevent_mask_e + { + xevent_mask = + PointerMotionMask| + ButtonPressMask| + ButtonReleaseMask| + ExposureMask| + KeyPressMask| + StructureNotifyMask + }; + + + //------------------------------------------------------------------------ + bool platform_support::init(unsigned width, unsigned height, unsigned flags) + { + m_window_flags = flags; + + m_specific->m_display = XOpenDisplay(NULL); + if(m_specific->m_display == 0) + { + fprintf(stderr, "Unable to open DISPLAY!\n"); + return false; + } + + m_specific->m_screen = XDefaultScreen(m_specific->m_display); + m_specific->m_depth = XDefaultDepth(m_specific->m_display, + m_specific->m_screen); + m_specific->m_visual = XDefaultVisual(m_specific->m_display, + m_specific->m_screen); + unsigned long r_mask = m_specific->m_visual->red_mask; + unsigned long g_mask = m_specific->m_visual->green_mask; + unsigned long b_mask = m_specific->m_visual->blue_mask; + +//printf("depth=%d, red=%08x, green=%08x, blue=%08x\n", +// m_specific->m_depth, +// m_specific->m_visual->red_mask, +// m_specific->m_visual->green_mask, +// m_specific->m_visual->blue_mask); + + +// // NOT COMPLETED YET! +// // Try to find an appropriate Visual if the default doesn't fit. +// if(m_specific->m_depth < 15 || +// r_mask == 0 || g_mask == 0 || b_mask == 0) +// { +// +// // This is an attempt to find an appropriate Visual if +// // the default one doesn't match the minumum requirements +// static int depth[] = { 32, 24, 16, 15 }; +// int i; +// for(int i = 0; i < 4; i++) +// { +// XVisualInfo vi; +// if(XMatchVisualInfo(m_specific->m_display, +// m_specific->m_screen, +// depth[i], +// TrueColor, +// &vi)) +// { +// // printf("TrueColor depth=%d, red=%08x, green=%08x, blue=%08x, bits=%d\n", +// // vi.depth, +// // vi.visual->red_mask, +// // vi.visual->green_mask, +// // vi.visual->blue_mask, +// // vi.bits_per_rgb); +// m_specific->m_depth = vi.depth; +// m_specific->m_visual = vi.visual; +// r_mask = m_specific->m_visual->red_mask; +// g_mask = m_specific->m_visual->green_mask; +// b_mask = m_specific->m_visual->blue_mask; +// break; +// } +// if(XMatchVisualInfo(m_specific->m_display, +// m_specific->m_screen, +// depth[i], +// DirectColor, +// &vi)) +// { +// // printf("DirectColor depth=%d, red=%08x, green=%08x, blue=%08x, bits=%d\n", +// // vi.depth, +// // vi.visual->red_mask, +// // vi.visual->green_mask, +// // vi.visual->blue_mask, +// // vi.bits_per_rgb); +// m_specific->m_depth = vi.depth; +// m_specific->m_visual = vi.visual; +// r_mask = m_specific->m_visual->red_mask; +// g_mask = m_specific->m_visual->green_mask; +// b_mask = m_specific->m_visual->blue_mask; +// break; +// } +// } +// } + + if(m_specific->m_depth < 15 || + r_mask == 0 || g_mask == 0 || b_mask == 0) + { + fprintf(stderr, + "There's no Visual compatible with minimal AGG requirements:\n" + "At least 15-bit color depth and True- or DirectColor class.\n\n"); + XCloseDisplay(m_specific->m_display); + return false; + } + + int t = 1; + int hw_byte_order = LSBFirst; + if(*(char*)&t == 0) hw_byte_order = MSBFirst; + + // Perceive SYS-format by mask + switch(m_specific->m_depth) + { + case 15: + m_specific->m_sys_bpp = 16; + if(r_mask == 0x7C00 && g_mask == 0x3E0 && b_mask == 0x1F) + { + m_specific->m_sys_format = pix_format_rgb555; + m_specific->m_byte_order = hw_byte_order; + } + break; + + case 16: + m_specific->m_sys_bpp = 16; + if(r_mask == 0xF800 && g_mask == 0x7E0 && b_mask == 0x1F) + { + m_specific->m_sys_format = pix_format_rgb565; + m_specific->m_byte_order = hw_byte_order; + } + break; + + case 24: + case 32: + m_specific->m_sys_bpp = 32; + if(g_mask == 0xFF00) + { + if(r_mask == 0xFF && b_mask == 0xFF0000) + { + switch(m_specific->m_format) + { + case pix_format_rgba32: + m_specific->m_sys_format = pix_format_rgba32; + m_specific->m_byte_order = LSBFirst; + break; + + case pix_format_abgr32: + m_specific->m_sys_format = pix_format_abgr32; + m_specific->m_byte_order = MSBFirst; + break; + + default: + m_specific->m_byte_order = hw_byte_order; + m_specific->m_sys_format = + (hw_byte_order == LSBFirst) ? + pix_format_rgba32 : + pix_format_abgr32; + break; + } + } + + if(r_mask == 0xFF0000 && b_mask == 0xFF) + { + switch(m_specific->m_format) + { + case pix_format_argb32: + m_specific->m_sys_format = pix_format_argb32; + m_specific->m_byte_order = MSBFirst; + break; + + case pix_format_bgra32: + m_specific->m_sys_format = pix_format_bgra32; + m_specific->m_byte_order = LSBFirst; + break; + + default: + m_specific->m_byte_order = hw_byte_order; + m_specific->m_sys_format = + (hw_byte_order == MSBFirst) ? + pix_format_argb32 : + pix_format_bgra32; + break; + } + } + } + break; + } + + if(m_specific->m_sys_format == pix_format_undefined) + { + fprintf(stderr, + "RGB masks are not compatible with AGG pixel formats:\n" + "R=%08x, R=%08x, B=%08x\n", r_mask, g_mask, b_mask); + XCloseDisplay(m_specific->m_display); + return false; + } + + + + memset(&m_specific->m_window_attributes, + 0, + sizeof(m_specific->m_window_attributes)); + + m_specific->m_window_attributes.border_pixel = + XBlackPixel(m_specific->m_display, m_specific->m_screen); + + m_specific->m_window_attributes.background_pixel = + XWhitePixel(m_specific->m_display, m_specific->m_screen); + + m_specific->m_window_attributes.override_redirect = 0; + + unsigned long window_mask = CWBackPixel | CWBorderPixel; + + m_specific->m_window = + XCreateWindow(m_specific->m_display, + XDefaultRootWindow(m_specific->m_display), + 0, 0, + width, + height, + 0, + m_specific->m_depth, + InputOutput, + CopyFromParent, + window_mask, + &m_specific->m_window_attributes); + + + m_specific->m_gc = XCreateGC(m_specific->m_display, + m_specific->m_window, + 0, 0); + m_specific->m_buf_window = + new unsigned char[width * height * (m_bpp / 8)]; + + memset(m_specific->m_buf_window, 255, width * height * (m_bpp / 8)); + + m_rbuf_window.attach(m_specific->m_buf_window, + width, + height, + m_flip_y ? -width * (m_bpp / 8) : width * (m_bpp / 8)); + + m_specific->m_ximg_window = + XCreateImage(m_specific->m_display, + m_specific->m_visual, //CopyFromParent, + m_specific->m_depth, + ZPixmap, + 0, + (char*)m_specific->m_buf_window, + width, + height, + m_specific->m_sys_bpp, + width * (m_specific->m_sys_bpp / 8)); + m_specific->m_ximg_window->byte_order = m_specific->m_byte_order; + + m_specific->caption(m_caption); + m_initial_width = width; + m_initial_height = height; + + if(!m_specific->m_initialized) + { + on_init(); + m_specific->m_initialized = true; + } + + trans_affine_resizing(width, height); + on_resize(width, height); + m_specific->m_update_flag = true; + + XSizeHints *hints = XAllocSizeHints(); + if(hints) + { + if(flags & window_resize) + { + hints->min_width = 32; + hints->min_height = 32; + hints->max_width = 4096; + hints->max_height = 4096; + } + else + { + hints->min_width = width; + hints->min_height = height; + hints->max_width = width; + hints->max_height = height; + } + hints->flags = PMaxSize | PMinSize; + + XSetWMNormalHints(m_specific->m_display, + m_specific->m_window, + hints); + + XFree(hints); + } + + + XMapWindow(m_specific->m_display, + m_specific->m_window); + + XSelectInput(m_specific->m_display, + m_specific->m_window, + xevent_mask); + + + m_specific->m_close_atom = XInternAtom(m_specific->m_display, + "WM_DELETE_WINDOW", + false); + + XSetWMProtocols(m_specific->m_display, + m_specific->m_window, + &m_specific->m_close_atom, + 1); + + return true; + } + + + + //------------------------------------------------------------------------ + void platform_support::update_window() + { + m_specific->put_image(&m_rbuf_window); + + // When m_wait_mode is true we can discard all the events + // came while the image is being drawn. In this case + // the X server does not accumulate mouse motion events. + // When m_wait_mode is false, i.e. we have some idle drawing + // we cannot afford to miss any events + XSync(m_specific->m_display, m_wait_mode); + } + + + //------------------------------------------------------------------------ + int platform_support::run() + { + XFlush(m_specific->m_display); + + bool quit = false; + unsigned flags; + int cur_x; + int cur_y; + + while(!quit) + { + if(m_specific->m_update_flag) + { + on_draw(); + update_window(); + m_specific->m_update_flag = false; + } + + if(!m_wait_mode) + { + if(XPending(m_specific->m_display) == 0) + { + on_idle(); + continue; + } + } + + XEvent x_event; + XNextEvent(m_specific->m_display, &x_event); + + // In the Idle mode discard all intermediate MotionNotify events + if(!m_wait_mode && x_event.type == MotionNotify) + { + XEvent te = x_event; + for(;;) + { + if(XPending(m_specific->m_display) == 0) break; + XNextEvent(m_specific->m_display, &te); + if(te.type != MotionNotify) break; + } + x_event = te; + } + + switch(x_event.type) + { + case ConfigureNotify: + { + if(x_event.xconfigure.width != int(m_rbuf_window.width()) || + x_event.xconfigure.height != int(m_rbuf_window.height())) + { + int width = x_event.xconfigure.width; + int height = x_event.xconfigure.height; + + delete [] m_specific->m_buf_window; + m_specific->m_ximg_window->data = 0; + XDestroyImage(m_specific->m_ximg_window); + + m_specific->m_buf_window = + new unsigned char[width * height * (m_bpp / 8)]; + + m_rbuf_window.attach(m_specific->m_buf_window, + width, + height, + m_flip_y ? + -width * (m_bpp / 8) : + width * (m_bpp / 8)); + + m_specific->m_ximg_window = + XCreateImage(m_specific->m_display, + m_specific->m_visual, //CopyFromParent, + m_specific->m_depth, + ZPixmap, + 0, + (char*)m_specific->m_buf_window, + width, + height, + m_specific->m_sys_bpp, + width * (m_specific->m_sys_bpp / 8)); + m_specific->m_ximg_window->byte_order = m_specific->m_byte_order; + + trans_affine_resizing(width, height); + on_resize(width, height); + on_draw(); + update_window(); + } + } + break; + + case Expose: + m_specific->put_image(&m_rbuf_window); + XFlush(m_specific->m_display); + XSync(m_specific->m_display, false); + break; + + case KeyPress: + { + KeySym key = XLookupKeysym(&x_event.xkey, 0); + flags = 0; + if(x_event.xkey.state & Button1Mask) flags |= mouse_left; + if(x_event.xkey.state & Button3Mask) flags |= mouse_right; + if(x_event.xkey.state & ShiftMask) flags |= kbd_shift; + if(x_event.xkey.state & ControlMask) flags |= kbd_ctrl; + + bool left = false; + bool up = false; + bool right = false; + bool down = false; + + switch(m_specific->m_keymap[key & 0xFF]) + { + case key_left: + left = true; + break; + + case key_up: + up = true; + break; + + case key_right: + right = true; + break; + + case key_down: + down = true; + break; + + case key_f2: + copy_window_to_img(max_images - 1); + save_img(max_images - 1, "screenshot"); + break; + } + + if(m_ctrls.on_arrow_keys(left, right, down, up)) + { + on_ctrl_change(); + force_redraw(); + } + else + { + on_key(x_event.xkey.x, + m_flip_y ? + m_rbuf_window.height() - x_event.xkey.y : + x_event.xkey.y, + m_specific->m_keymap[key & 0xFF], + flags); + } + } + break; + + + case ButtonPress: + { + flags = 0; + if(x_event.xbutton.state & ShiftMask) flags |= kbd_shift; + if(x_event.xbutton.state & ControlMask) flags |= kbd_ctrl; + if(x_event.xbutton.button == Button1) flags |= mouse_left; + if(x_event.xbutton.button == Button3) flags |= mouse_right; + + cur_x = x_event.xbutton.x; + cur_y = m_flip_y ? m_rbuf_window.height() - x_event.xbutton.y : + x_event.xbutton.y; + + if(flags & mouse_left) + { + if(m_ctrls.on_mouse_button_down(cur_x, cur_y)) + { + m_ctrls.set_cur(cur_x, cur_y); + on_ctrl_change(); + force_redraw(); + } + else + { + if(m_ctrls.in_rect(cur_x, cur_y)) + { + if(m_ctrls.set_cur(cur_x, cur_y)) + { + on_ctrl_change(); + force_redraw(); + } + } + else + { + on_mouse_button_down(cur_x, cur_y, flags); + } + } + } + if(flags & mouse_right) + { + on_mouse_button_down(cur_x, cur_y, flags); + } + //m_specific->m_wait_mode = m_wait_mode; + //m_wait_mode = true; + } + break; + + + case MotionNotify: + { + flags = 0; + if(x_event.xmotion.state & Button1Mask) flags |= mouse_left; + if(x_event.xmotion.state & Button3Mask) flags |= mouse_right; + if(x_event.xmotion.state & ShiftMask) flags |= kbd_shift; + if(x_event.xmotion.state & ControlMask) flags |= kbd_ctrl; + + cur_x = x_event.xbutton.x; + cur_y = m_flip_y ? m_rbuf_window.height() - x_event.xbutton.y : + x_event.xbutton.y; + + if(m_ctrls.on_mouse_move(cur_x, cur_y, (flags & mouse_left) != 0)) + { + on_ctrl_change(); + force_redraw(); + } + else + { + if(!m_ctrls.in_rect(cur_x, cur_y)) + { + on_mouse_move(cur_x, cur_y, flags); + } + } + } + break; + + case ButtonRelease: + { + flags = 0; + if(x_event.xbutton.state & ShiftMask) flags |= kbd_shift; + if(x_event.xbutton.state & ControlMask) flags |= kbd_ctrl; + if(x_event.xbutton.button == Button1) flags |= mouse_left; + if(x_event.xbutton.button == Button3) flags |= mouse_right; + + cur_x = x_event.xbutton.x; + cur_y = m_flip_y ? m_rbuf_window.height() - x_event.xbutton.y : + x_event.xbutton.y; + + if(flags & mouse_left) + { + if(m_ctrls.on_mouse_button_up(cur_x, cur_y)) + { + on_ctrl_change(); + force_redraw(); + } + } + if(flags & (mouse_left | mouse_right)) + { + on_mouse_button_up(cur_x, cur_y, flags); + } + } + //m_wait_mode = m_specific->m_wait_mode; + break; + + case ClientMessage: + if((x_event.xclient.format == 32) && + (x_event.xclient.data.l[0] == int(m_specific->m_close_atom))) + { + quit = true; + } + break; + } + } + + + unsigned i = platform_support::max_images; + while(i--) + { + if(m_specific->m_buf_img[i]) + { + delete [] m_specific->m_buf_img[i]; + } + } + + delete [] m_specific->m_buf_window; + m_specific->m_ximg_window->data = 0; + XDestroyImage(m_specific->m_ximg_window); + XFreeGC(m_specific->m_display, m_specific->m_gc); + XDestroyWindow(m_specific->m_display, m_specific->m_window); + XCloseDisplay(m_specific->m_display); + + return 0; + } + + + + //------------------------------------------------------------------------ + const char* platform_support::img_ext() const { return ".ppm"; } + + //------------------------------------------------------------------------ + const char* platform_support::full_file_name(const char* file_name) + { + return file_name; + } + + //------------------------------------------------------------------------ + bool platform_support::load_img(unsigned idx, const char* file) + { + if(idx < max_images) + { + char buf[1024]; + strcpy(buf, file); + int len = strlen(buf); + if(len < 4 || strcasecmp(buf + len - 4, ".ppm") != 0) + { + strcat(buf, ".ppm"); + } + + FILE* fd = fopen(buf, "rb"); + if(fd == 0) return false; + + if((len = fread(buf, 1, 1022, fd)) == 0) + { + fclose(fd); + return false; + } + buf[len] = 0; + + if(buf[0] != 'P' && buf[1] != '6') + { + fclose(fd); + return false; + } + + char* ptr = buf + 2; + + while(*ptr && !isdigit(*ptr)) ptr++; + if(*ptr == 0) + { + fclose(fd); + return false; + } + + unsigned width = atoi(ptr); + if(width == 0 || width > 4096) + { + fclose(fd); + return false; + } + while(*ptr && isdigit(*ptr)) ptr++; + while(*ptr && !isdigit(*ptr)) ptr++; + if(*ptr == 0) + { + fclose(fd); + return false; + } + unsigned height = atoi(ptr); + if(height == 0 || height > 4096) + { + fclose(fd); + return false; + } + while(*ptr && isdigit(*ptr)) ptr++; + while(*ptr && !isdigit(*ptr)) ptr++; + if(atoi(ptr) != 255) + { + fclose(fd); + return false; + } + while(*ptr && isdigit(*ptr)) ptr++; + if(*ptr == 0) + { + fclose(fd); + return false; + } + ptr++; + fseek(fd, long(ptr - buf), SEEK_SET); + + create_img(idx, width, height); + bool ret = true; + + if(m_format == pix_format_rgb24) + { + fread(m_specific->m_buf_img[idx], 1, width * height * 3, fd); + } + else + { + unsigned char* buf_img = new unsigned char [width * height * 3]; + rendering_buffer rbuf_img; + rbuf_img.attach(buf_img, + width, + height, + m_flip_y ? + -width * 3 : + width * 3); + + fread(buf_img, 1, width * height * 3, fd); + + switch(m_format) + { + case pix_format_sgray8: + convert<pixfmt_sgray8, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_gray8: + convert<pixfmt_gray8, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_gray16: + convert<pixfmt_gray16, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_gray32: + convert<pixfmt_gray32, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_rgb555: + color_conv(m_rbuf_img+idx, &rbuf_img, color_conv_rgb24_to_rgb555()); + break; + + case pix_format_rgb565: + color_conv(m_rbuf_img+idx, &rbuf_img, color_conv_rgb24_to_rgb565()); + break; + + case pix_format_sbgr24: + convert<pixfmt_sbgr24, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_rgb24: + convert<pixfmt_rgb24, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_bgr24: + convert<pixfmt_bgr24, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_srgba32: + convert<pixfmt_srgba32, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_sargb32: + convert<pixfmt_sargb32, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_sbgra32: + convert<pixfmt_sbgra32, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_sabgr32: + convert<pixfmt_sabgr32, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_rgba32: + convert<pixfmt_rgba32, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_argb32: + convert<pixfmt_argb32, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_bgra32: + convert<pixfmt_bgra32, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_abgr32: + convert<pixfmt_abgr32, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_rgb48: + convert<pixfmt_rgb48, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_bgr48: + convert<pixfmt_bgr48, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_rgba64: + convert<pixfmt_rgba64, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_argb64: + convert<pixfmt_argb64, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_bgra64: + convert<pixfmt_bgra64, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_abgr64: + convert<pixfmt_abgr64, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_rgb96: + convert<pixfmt_rgb96, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_bgr96: + convert<pixfmt_bgr96, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_rgba128: + convert<pixfmt_rgba128, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_argb128: + convert<pixfmt_argb128, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_bgra128: + convert<pixfmt_bgra128, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + case pix_format_abgr128: + convert<pixfmt_abgr128, pixfmt_srgb24>(m_rbuf_img+idx, &rbuf_img); + break; + + default: + ret = false; + } + delete [] buf_img; + } + + fclose(fd); + return ret; + } + return false; + } + + + + + //------------------------------------------------------------------------ + bool platform_support::save_img(unsigned idx, const char* file) + { + if(idx < max_images && rbuf_img(idx).buf()) + { + char buf[1024]; + strcpy(buf, file); + int len = strlen(buf); + if(len < 4 || strcasecmp(buf + len - 4, ".ppm") != 0) + { + strcat(buf, ".ppm"); + } + + FILE* fd = fopen(buf, "wb"); + if(fd == 0) return false; + + unsigned w = rbuf_img(idx).width(); + unsigned h = rbuf_img(idx).height(); + + fprintf(fd, "P6\n%d %d\n255\n", w, h); + + unsigned y; + unsigned char* tmp_buf = new unsigned char [w * 3]; + for(y = 0; y < rbuf_img(idx).height(); y++) + { + const unsigned char* src = rbuf_img(idx).row_ptr(m_flip_y ? h - 1 - y : y); + switch(m_format) + { + case pix_format_sgray8: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_sgray8>()); + break; + + case pix_format_gray8: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_gray8>()); + break; + + case pix_format_gray16: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_gray16>()); + break; + + case pix_format_gray32: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_gray32>()); + break; + + default: break; + case pix_format_rgb555: + color_conv_row(tmp_buf, src, w, color_conv_rgb555_to_rgb24()); + break; + + case pix_format_rgb565: + color_conv_row(tmp_buf, src, w, color_conv_rgb565_to_rgb24()); + break; + + case pix_format_sbgr24: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_sbgr24>()); + break; + + case pix_format_srgb24: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_srgb24>()); + break; + + case pix_format_bgr24: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_bgr24>()); + break; + + case pix_format_rgb24: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_rgb24>()); + break; + + case pix_format_srgba32: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_srgba32>()); + break; + + case pix_format_sargb32: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_sargb32>()); + break; + + case pix_format_sbgra32: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_sbgra32>()); + break; + + case pix_format_sabgr32: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_sabgr32>()); + break; + + case pix_format_rgba32: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_rgba32>()); + break; + + case pix_format_argb32: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_argb32>()); + break; + + case pix_format_bgra32: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_bgra32>()); + break; + + case pix_format_abgr32: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_abgr32>()); + break; + + case pix_format_bgr48: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_bgr48>()); + break; + + case pix_format_rgb48: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_rgb48>()); + break; + + case pix_format_rgba64: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_rgba64>()); + break; + + case pix_format_argb64: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_argb64>()); + break; + + case pix_format_bgra64: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_bgra64>()); + break; + + case pix_format_abgr64: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_abgr64>()); + break; + + case pix_format_bgr96: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_bgr96>()); + break; + + case pix_format_rgb96: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_rgb96>()); + break; + + case pix_format_rgba128: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_rgba128>()); + break; + + case pix_format_argb128: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_argb128>()); + break; + + case pix_format_bgra128: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_bgra128>()); + break; + + case pix_format_abgr128: + color_conv_row(tmp_buf, src, w, conv_row<pixfmt_srgb24, pixfmt_abgr128>()); + break; + } + fwrite(tmp_buf, 1, w * 3, fd); + } + delete [] tmp_buf; + fclose(fd); + return true; + } + return false; + } + + + + //------------------------------------------------------------------------ + bool platform_support::create_img(unsigned idx, unsigned width, unsigned height) + { + if(idx < max_images) + { + if(width == 0) width = rbuf_window().width(); + if(height == 0) height = rbuf_window().height(); + delete [] m_specific->m_buf_img[idx]; + m_specific->m_buf_img[idx] = + new unsigned char[width * height * (m_bpp / 8)]; + + m_rbuf_img[idx].attach(m_specific->m_buf_img[idx], + width, + height, + m_flip_y ? + -width * (m_bpp / 8) : + width * (m_bpp / 8)); + return true; + } + return false; + } + + + //------------------------------------------------------------------------ + void platform_support::force_redraw() + { + m_specific->m_update_flag = true; + } + + + //------------------------------------------------------------------------ + void platform_support::message(const char* msg) + { + fprintf(stderr, "%s\n", msg); + } + + //------------------------------------------------------------------------ + void platform_support::start_timer() + { + m_specific->m_sw_start = clock(); + } + + //------------------------------------------------------------------------ + double platform_support::elapsed_time() const + { + clock_t stop = clock(); + return double(stop - m_specific->m_sw_start) * 1000.0 / CLOCKS_PER_SEC; + } + + + //------------------------------------------------------------------------ + void platform_support::on_init() {} + void platform_support::on_resize(int sx, int sy) {} + void platform_support::on_idle() {} + void platform_support::on_mouse_move(int x, int y, unsigned flags) {} + void platform_support::on_mouse_button_down(int x, int y, unsigned flags) {} + void platform_support::on_mouse_button_up(int x, int y, unsigned flags) {} + void platform_support::on_key(int x, int y, unsigned key, unsigned flags) {} + void platform_support::on_ctrl_change() {} + void platform_support::on_draw() {} + void platform_support::on_post_draw(void* raw_handler) {} + + + +} + + +int agg_main(int argc, char* argv[]); + + +int main(int argc, char* argv[]) +{ + return agg_main(argc, argv); +} + + + + + + diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/mac/agg_mac_pmap.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/mac/agg_mac_pmap.cpp new file mode 100644 index 00000000000..dc85fd69ffd --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/mac/agg_mac_pmap.cpp @@ -0,0 +1,298 @@ +//---------------------------------------------------------------------------- +// +//---------------------------------------------------------------------------- +// Contact: mcseemagg@yahoo.com +// baer@karto.baug.ethz.ch +//---------------------------------------------------------------------------- +// +// class pixel_map +// +//---------------------------------------------------------------------------- + +#include <string.h> +#include <Carbon.h> +#include <QuickTimeComponents.h> +#include <ImageCompression.h> +#include "platform/mac/agg_mac_pmap.h" +#include "agg_basics.h" + +namespace agg +{ + + //------------------------------------------------------------------------ + pixel_map::~pixel_map() + { + destroy(); + } + + + //------------------------------------------------------------------------ + pixel_map::pixel_map() : + m_pmap(0), + m_buf(0), + m_bpp(0), + m_img_size(0) + + { + } + + + //------------------------------------------------------------------------ + void pixel_map::destroy() + { + delete[] m_buf; + m_buf = NULL; + if (m_pmap != nil) + { + DisposeGWorld(m_pmap); + m_pmap = nil; + } + } + + + //------------------------------------------------------------------------ + void pixel_map::create(unsigned width, + unsigned height, + org_e org, + unsigned clear_val) + { + destroy(); + if(width == 0) width = 1; + if(height == 0) height = 1; + m_bpp = org; + + Rect r; + int row_bytes = calc_row_len (width, m_bpp); + MacSetRect(&r, 0, 0, width, height); + m_buf = new unsigned char[m_img_size = row_bytes * height]; + // The Quicktime version for creating GWorlds is more flexible than the classical function. + QTNewGWorldFromPtr (&m_pmap, m_bpp, &r, nil, nil, 0, m_buf, row_bytes); + + // create_gray_scale_palette(m_pmap); I didn't care about gray scale palettes so far. + if(clear_val <= 255) + { + memset(m_buf, clear_val, m_img_size); + } + } + + + + //------------------------------------------------------------------------ + void pixel_map::clear(unsigned clear_val) + { + if(m_buf) memset(m_buf, clear_val, m_img_size); + } + + + //static + //This function is just copied from the Win32 plattform support. + //Is also seems to be appropriate for MacOS as well, but it is not + //thouroughly tested so far. + //------------------------------------------------------------------------ + + unsigned pixel_map::calc_row_len(unsigned width, unsigned bits_per_pixel) + { + unsigned n = width; + unsigned k; + + switch(bits_per_pixel) + { + case 1: k = n; + n = n >> 3; + if(k & 7) n++; + break; + + case 4: k = n; + n = n >> 1; + if(k & 3) n++; + break; + + case 8: + break; + + case 16: n = n << 1; + break; + + case 24: n = (n << 1) + n; + break; + + case 32: n = n << 2; + break; + + default: n = 0; + break; + } + return ((n + 3) >> 2) << 2; + } + + + + + //------------------------------------------------------------------------ + void pixel_map::draw(WindowRef window, const Rect *device_rect, const Rect *pmap_rect) const + { + if(m_pmap == nil || m_buf == NULL) return; + + PixMapHandle pm = GetGWorldPixMap (m_pmap); + CGrafPtr port = GetWindowPort (window); + Rect dest_rect; + + // Again, I used the Quicktime version. + // Good old 'CopyBits' does better interpolation when scaling + // but does not support all pixel depths. + MacSetRect (&dest_rect, 0, 0, this->width(), this->height()); + ImageDescriptionHandle image_description; + MakeImageDescriptionForPixMap (pm, &image_description); + if (image_description != nil) + { + DecompressImage (GetPixBaseAddr (pm), image_description, GetPortPixMap (port), nil, &dest_rect, ditherCopy, nil); + DisposeHandle ((Handle) image_description); + } + } + + + //------------------------------------------------------------------------ + void pixel_map::draw(WindowRef window, int x, int y, double scale) const + { + if(m_pmap == nil || m_buf == NULL) return; + unsigned width = (unsigned)(this->width() * scale); + unsigned height = (unsigned)(this->height() * scale); + Rect rect; + SetRect (&rect, x, y, x + width, y + height); + draw(window, &rect); + } + + + + //------------------------------------------------------------------------ + void pixel_map::blend(WindowRef window, const Rect *device_rect, const Rect *bmp_rect) const + { + draw (window, device_rect, bmp_rect); // currently just mapped to drawing method + } + + + //------------------------------------------------------------------------ + void pixel_map::blend(WindowRef window, int x, int y, double scale) const + { + draw(window, x, y, scale); // currently just mapped to drawing method + } + + + // I let Quicktime handle image import since it supports most popular + // image formats such as: + // *.psd, *.bmp, *.tif, *.png, *.jpg, *.gif, *.pct, *.pcx + //------------------------------------------------------------------------ + bool pixel_map::load_from_qt(const char *filename) + { + FSSpec fss; + OSErr err; + + // get file specification to application directory + err = HGetVol(nil, &fss.vRefNum, &fss.parID); + if (err == noErr) + { + CopyCStringToPascal(filename, fss.name); + GraphicsImportComponent gi; + err = GetGraphicsImporterForFile (&fss, &gi); + if (err == noErr) + { + ImageDescriptionHandle desc; + GraphicsImportGetImageDescription(gi, &desc); +// For simplicity, all images are currently converted to 32 bit. + // create an empty pixelmap + short depth = 32; + create ((**desc).width, (**desc).height, (org_e)depth, 0xff); + DisposeHandle ((Handle)desc); + // let Quicktime draw to pixelmap + GraphicsImportSetGWorld(gi, m_pmap, nil); + GraphicsImportDraw(gi); +// Well, this is a hack. The graphics importer sets the alpha channel of the pixelmap to 0x00 +// for imported images without alpha channel but this would cause agg to draw an invisible image. + // set alpha channel to 0xff + unsigned char * buf = m_buf; + for (unsigned int size = 0; size < m_img_size; size += 4) + { + *buf = 0xff; + buf += 4; + } + } + } + return err == noErr; + } + + + + //------------------------------------------------------------------------ + bool pixel_map::save_as_qt(const char *filename) const + { + FSSpec fss; + OSErr err; + + // get file specification to application directory + err = HGetVol(nil, &fss.vRefNum, &fss.parID); + if (err == noErr) + { + GraphicsExportComponent ge; + CopyCStringToPascal(filename, fss.name); + // I decided to use PNG as output image file type. + // There are a number of other available formats. + // Should I check the file suffix to choose the image file format? + err = OpenADefaultComponent(GraphicsExporterComponentType, kQTFileTypePNG, &ge); + if (err == noErr) + { + err = GraphicsExportSetInputGWorld(ge, m_pmap); + if (err == noErr) + { + err = GraphicsExportSetOutputFile (ge, &fss); + if (err == noErr) + { + GraphicsExportDoExport(ge, nil); + } + } + CloseComponent(ge); + } + } + + return err == noErr; + } + + //------------------------------------------------------------------------ + unsigned char* pixel_map::buf() + { + return m_buf; + } + + //------------------------------------------------------------------------ + unsigned pixel_map::width() const + { + if(m_pmap == nil) return 0; + PixMapHandle pm = GetGWorldPixMap (m_pmap); + Rect bounds; + GetPixBounds (pm, &bounds); + return bounds.right - bounds.left; + } + + //------------------------------------------------------------------------ + unsigned pixel_map::height() const + { + if(m_pmap == nil) return 0; + PixMapHandle pm = GetGWorldPixMap (m_pmap); + Rect bounds; + GetPixBounds (pm, &bounds); + return bounds.bottom - bounds.top; + } + + //------------------------------------------------------------------------ + int pixel_map::row_bytes() const + { + if(m_pmap == nil) return 0; + PixMapHandle pm = GetGWorldPixMap (m_pmap); + return calc_row_len(width(), GetPixDepth(pm)); + } + + + +} + + + diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/mac/agg_platform_support.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/mac/agg_platform_support.cpp new file mode 100644 index 00000000000..f518dbe1f27 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/mac/agg_platform_support.cpp @@ -0,0 +1,1053 @@ +//---------------------------------------------------------------------------- +// Anti-Grain Geometry - Version 2.4 +// Copyright (C) 2002-2005 Maxim Shemanarev (McSeem) +// Copyright (C) 2003 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 platform_support +// +//---------------------------------------------------------------------------- +// +// Note: +// I tried to retain the original structure for the Win32 platform as far +// as possible. Currently, not all features are implemented but the examples +// should work properly. +// HB +//---------------------------------------------------------------------------- + +#include <Carbon.h> +#if defined(__MWERKS__) +#include "console.h" +#endif +#include <string.h> +#include <unistd.h> +#include "platform/agg_platform_support.h" +#include "platform/mac/agg_mac_pmap.h" +#include "util/agg_color_conv_rgb8.h" + + +namespace agg +{ + +pascal OSStatus DoWindowClose (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData); +pascal OSStatus DoWindowDrawContent (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData); +pascal OSStatus DoAppQuit (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData); +pascal OSStatus DoMouseDown (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData); +pascal OSStatus DoMouseUp (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData); +pascal OSStatus DoMouseDragged (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData); +pascal OSStatus DoKeyDown (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData); +pascal OSStatus DoKeyUp (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData); +pascal void DoPeriodicTask (EventLoopTimerRef theTimer, void* userData); + + + //------------------------------------------------------------------------ + class platform_specific + { + public: + platform_specific(pix_format_e format, bool flip_y); + + void create_pmap(unsigned width, unsigned height, + rendering_buffer* wnd); + + void display_pmap(WindowRef window, const rendering_buffer* src); + bool load_pmap(const char* fn, unsigned idx, + rendering_buffer* dst); + + bool save_pmap(const char* fn, unsigned idx, + const rendering_buffer* src); + + unsigned translate(unsigned keycode); + + pix_format_e m_format; + pix_format_e m_sys_format; + bool m_flip_y; + unsigned m_bpp; + unsigned m_sys_bpp; + WindowRef m_window; + pixel_map m_pmap_window; + pixel_map m_pmap_img[platform_support::max_images]; + unsigned m_keymap[256]; + unsigned m_last_translated_key; + int m_cur_x; + int m_cur_y; + unsigned m_input_flags; + bool m_redraw_flag; + UnsignedWide m_sw_freq; + UnsignedWide m_sw_start; + }; + + + //------------------------------------------------------------------------ + platform_specific::platform_specific(pix_format_e format, bool flip_y) : + m_format(format), + m_sys_format(pix_format_undefined), + m_flip_y(flip_y), + m_bpp(0), + m_sys_bpp(0), + m_window(nil), + m_last_translated_key(0), + m_cur_x(0), + m_cur_y(0), + m_input_flags(0), + m_redraw_flag(true) + { + memset(m_keymap, 0, sizeof(m_keymap)); + + //Keyboard input is not yet fully supported nor tested + //m_keymap[VK_PAUSE] = key_pause; + m_keymap[kClearCharCode] = key_clear; + + //m_keymap[VK_NUMPAD0] = key_kp0; + //m_keymap[VK_NUMPAD1] = key_kp1; + //m_keymap[VK_NUMPAD2] = key_kp2; + //m_keymap[VK_NUMPAD3] = key_kp3; + //m_keymap[VK_NUMPAD4] = key_kp4; + //m_keymap[VK_NUMPAD5] = key_kp5; + //m_keymap[VK_NUMPAD6] = key_kp6; + //m_keymap[VK_NUMPAD7] = key_kp7; + //m_keymap[VK_NUMPAD8] = key_kp8; + //m_keymap[VK_NUMPAD9] = key_kp9; + //m_keymap[VK_DECIMAL] = key_kp_period; + //m_keymap[VK_DIVIDE] = key_kp_divide; + //m_keymap[VK_MULTIPLY] = key_kp_multiply; + //m_keymap[VK_SUBTRACT] = key_kp_minus; + //m_keymap[VK_ADD] = key_kp_plus; + + m_keymap[kUpArrowCharCode] = key_up; + m_keymap[kDownArrowCharCode] = key_down; + m_keymap[kRightArrowCharCode] = key_right; + m_keymap[kLeftArrowCharCode] = key_left; + //m_keymap[VK_INSERT] = key_insert; + m_keymap[kDeleteCharCode] = key_delete; + m_keymap[kHomeCharCode] = key_home; + m_keymap[kEndCharCode] = key_end; + m_keymap[kPageUpCharCode] = key_page_up; + m_keymap[kPageDownCharCode] = key_page_down; + + //m_keymap[VK_F1] = key_f1; + //m_keymap[VK_F2] = key_f2; + //m_keymap[VK_F3] = key_f3; + //m_keymap[VK_F4] = key_f4; + //m_keymap[VK_F5] = key_f5; + //m_keymap[VK_F6] = key_f6; + //m_keymap[VK_F7] = key_f7; + //m_keymap[VK_F8] = key_f8; + //m_keymap[VK_F9] = key_f9; + //m_keymap[VK_F10] = key_f10; + //m_keymap[VK_F11] = key_f11; + //m_keymap[VK_F12] = key_f12; + //m_keymap[VK_F13] = key_f13; + //m_keymap[VK_F14] = key_f14; + //m_keymap[VK_F15] = key_f15; + + //m_keymap[VK_NUMLOCK] = key_numlock; + //m_keymap[VK_CAPITAL] = key_capslock; + //m_keymap[VK_SCROLL] = key_scrollock; + + switch(m_format) + { + case pix_format_gray8: + m_sys_format = pix_format_gray8; + m_bpp = 8; + m_sys_bpp = 8; + break; + + case pix_format_rgb565: + case pix_format_rgb555: + m_sys_format = pix_format_rgb555; + m_bpp = 16; + m_sys_bpp = 16; + break; + + case pix_format_rgb24: + case pix_format_bgr24: + m_sys_format = pix_format_rgb24; + m_bpp = 24; + m_sys_bpp = 24; + break; + + case pix_format_bgra32: + case pix_format_abgr32: + case pix_format_argb32: + case pix_format_rgba32: + m_sys_format = pix_format_argb32; + m_bpp = 32; + m_sys_bpp = 32; + break; + } + ::Microseconds(&m_sw_freq); + ::Microseconds(&m_sw_start); + } + + + //------------------------------------------------------------------------ + void platform_specific::create_pmap(unsigned width, + unsigned height, + rendering_buffer* wnd) + { + m_pmap_window.create(width, height, org_e(m_bpp)); + wnd->attach(m_pmap_window.buf(), + m_pmap_window.width(), + m_pmap_window.height(), + m_flip_y ? + -m_pmap_window.row_bytes() : + m_pmap_window.row_bytes()); + } + + + //------------------------------------------------------------------------ + void platform_specific::display_pmap(WindowRef window, const rendering_buffer* src) + { + if(m_sys_format == m_format) + { + m_pmap_window.draw(window); + } + else + { + pixel_map pmap_tmp; + pmap_tmp.create(m_pmap_window.width(), + m_pmap_window.height(), + org_e(m_sys_bpp)); + + rendering_buffer rbuf_tmp; + rbuf_tmp.attach(pmap_tmp.buf(), + pmap_tmp.width(), + pmap_tmp.height(), + m_flip_y ? + -pmap_tmp.row_bytes() : + pmap_tmp.row_bytes()); + + switch(m_format) + { + case pix_format_gray8: + return; + + case pix_format_rgb565: + color_conv(&rbuf_tmp, src, color_conv_rgb565_to_rgb555()); + break; + + case pix_format_bgr24: + color_conv(&rbuf_tmp, src, color_conv_bgr24_to_rgb24()); + break; + + case pix_format_abgr32: + color_conv(&rbuf_tmp, src, color_conv_abgr32_to_argb32()); + break; + + case pix_format_bgra32: + color_conv(&rbuf_tmp, src, color_conv_bgra32_to_argb32()); + break; + + case pix_format_rgba32: + color_conv(&rbuf_tmp, src, color_conv_rgba32_to_argb32()); + break; + } + pmap_tmp.draw(window); + } + } + + + //------------------------------------------------------------------------ + bool platform_specific::save_pmap(const char* fn, unsigned idx, + const rendering_buffer* src) + { + if(m_sys_format == m_format) + { + return m_pmap_img[idx].save_as_qt(fn); + } + else + { + pixel_map pmap_tmp; + pmap_tmp.create(m_pmap_img[idx].width(), + m_pmap_img[idx].height(), + org_e(m_sys_bpp)); + + rendering_buffer rbuf_tmp; + rbuf_tmp.attach(pmap_tmp.buf(), + pmap_tmp.width(), + pmap_tmp.height(), + m_flip_y ? + -pmap_tmp.row_bytes() : + pmap_tmp.row_bytes()); + switch(m_format) + { + case pix_format_gray8: + return false; + + case pix_format_rgb565: + color_conv(&rbuf_tmp, src, color_conv_rgb565_to_rgb555()); + break; + + case pix_format_rgb24: + color_conv(&rbuf_tmp, src, color_conv_rgb24_to_bgr24()); + break; + + case pix_format_abgr32: + color_conv(&rbuf_tmp, src, color_conv_abgr32_to_bgra32()); + break; + + case pix_format_argb32: + color_conv(&rbuf_tmp, src, color_conv_argb32_to_bgra32()); + break; + + case pix_format_rgba32: + color_conv(&rbuf_tmp, src, color_conv_rgba32_to_bgra32()); + break; + } + return pmap_tmp.save_as_qt(fn); + } + return true; + } + + + + //------------------------------------------------------------------------ + bool platform_specific::load_pmap(const char* fn, unsigned idx, + rendering_buffer* dst) + { + pixel_map pmap_tmp; + if(!pmap_tmp.load_from_qt(fn)) return false; + + rendering_buffer rbuf_tmp; + rbuf_tmp.attach(pmap_tmp.buf(), + pmap_tmp.width(), + pmap_tmp.height(), + m_flip_y ? + -pmap_tmp.row_bytes() : + pmap_tmp.row_bytes()); + + m_pmap_img[idx].create(pmap_tmp.width(), + pmap_tmp.height(), + org_e(m_bpp), + 0); + + dst->attach(m_pmap_img[idx].buf(), + m_pmap_img[idx].width(), + m_pmap_img[idx].height(), + m_flip_y ? + -m_pmap_img[idx].row_bytes() : + m_pmap_img[idx].row_bytes()); + + switch(m_format) + { + case pix_format_gray8: + return false; + break; + + case pix_format_rgb555: + switch(pmap_tmp.bpp()) + { + case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_rgb555()); break; + case 24: color_conv(dst, &rbuf_tmp, color_conv_rgb24_to_rgb555()); break; + case 32: color_conv(dst, &rbuf_tmp, color_conv_argb32_to_rgb555()); break; + } + break; + + case pix_format_rgb565: + switch(pmap_tmp.bpp()) + { + case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_rgb565()); break; + case 24: color_conv(dst, &rbuf_tmp, color_conv_rgb24_to_rgb565()); break; + case 32: color_conv(dst, &rbuf_tmp, color_conv_argb32_to_rgb565()); break; + } + break; + + case pix_format_rgb24: + switch(pmap_tmp.bpp()) + { + case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_rgb24()); break; + case 24: color_conv(dst, &rbuf_tmp, color_conv_rgb24_to_rgb24()); break; + case 32: color_conv(dst, &rbuf_tmp, color_conv_argb32_to_rgb24()); break; + } + break; + + case pix_format_bgr24: + switch(pmap_tmp.bpp()) + { + case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_bgr24()); break; + case 24: color_conv(dst, &rbuf_tmp, color_conv_rgb24_to_bgr24()); break; + case 32: color_conv(dst, &rbuf_tmp, color_conv_argb32_to_bgr24()); break; + } + break; + + case pix_format_abgr32: + switch(pmap_tmp.bpp()) + { + case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_abgr32()); break; + case 24: color_conv(dst, &rbuf_tmp, color_conv_rgb24_to_abgr32()); break; + case 32: color_conv(dst, &rbuf_tmp, color_conv_argb32_to_abgr32()); break; + } + break; + + case pix_format_argb32: + switch(pmap_tmp.bpp()) + { + case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_argb32()); break; + case 24: color_conv(dst, &rbuf_tmp, color_conv_rgb24_to_argb32()); break; + case 32: color_conv(dst, &rbuf_tmp, color_conv_argb32_to_argb32()); break; + } + break; + + case pix_format_bgra32: + switch(pmap_tmp.bpp()) + { + case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_bgra32()); break; + case 24: color_conv(dst, &rbuf_tmp, color_conv_rgb24_to_bgra32()); break; + case 32: color_conv(dst, &rbuf_tmp, color_conv_argb32_to_bgra32()); break; + } + break; + + case pix_format_rgba32: + switch(pmap_tmp.bpp()) + { + case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_rgba32()); break; + case 24: color_conv(dst, &rbuf_tmp, color_conv_rgb24_to_rgba32()); break; + case 32: color_conv(dst, &rbuf_tmp, color_conv_argb32_to_rgba32()); break; + } + break; + } + + return true; + } + + + + + + + + + //------------------------------------------------------------------------ + unsigned platform_specific::translate(unsigned keycode) + { + return m_last_translated_key = (keycode > 255) ? 0 : m_keymap[keycode]; + } + + + + //------------------------------------------------------------------------ + platform_support::platform_support(pix_format_e format, bool flip_y) : + m_specific(new platform_specific(format, flip_y)), + m_format(format), + m_bpp(m_specific->m_bpp), + m_window_flags(0), + m_wait_mode(true), + m_flip_y(flip_y), + m_initial_width(10), + m_initial_height(10) + { + strcpy(m_caption, "Anti-Grain Geometry Application"); + } + + + //------------------------------------------------------------------------ + platform_support::~platform_support() + { + delete m_specific; + } + + + + //------------------------------------------------------------------------ + void platform_support::caption(const char* cap) + { + strcpy(m_caption, cap); + if(m_specific->m_window) + { + SetWindowTitleWithCFString (m_specific->m_window, CFStringCreateWithCStringNoCopy (nil, cap, kCFStringEncodingASCII, nil)); + } + } + + + + //------------------------------------------------------------------------ + static unsigned get_key_flags(UInt32 wflags) + { + unsigned flags = 0; + + if(wflags & shiftKey) flags |= kbd_shift; + if(wflags & controlKey) flags |= kbd_ctrl; + + return flags; + } + + + //------------------------------------------------------------------------ + void platform_support::message(const char* msg) + { + SInt16 item; + Str255 p_msg; + + ::CopyCStringToPascal (msg, p_msg); + ::StandardAlert (kAlertPlainAlert, (const unsigned char*) "\013AGG Message", p_msg, NULL, &item); + //::StandardAlert (kAlertPlainAlert, (const unsigned char*) "\pAGG Message", p_msg, NULL, &item); + } + + + //------------------------------------------------------------------------ + void platform_support::start_timer() + { + ::Microseconds (&(m_specific->m_sw_start)); + } + + + //------------------------------------------------------------------------ + double platform_support::elapsed_time() const + { + UnsignedWide stop; + ::Microseconds(&stop); + return double(stop.lo - + m_specific->m_sw_start.lo) * 1e6 / + double(m_specific->m_sw_freq.lo); + } + + + //------------------------------------------------------------------------ + bool platform_support::init(unsigned width, unsigned height, unsigned flags) + { + if(m_specific->m_sys_format == pix_format_undefined) + { + return false; + } + + m_window_flags = flags; + + // application + EventTypeSpec eventType; + EventHandlerUPP handlerUPP; + + eventType.eventClass = kEventClassApplication; + eventType.eventKind = kEventAppQuit; + + handlerUPP = NewEventHandlerUPP(DoAppQuit); + + InstallApplicationEventHandler (handlerUPP, 1, &eventType, nil, nil); + + eventType.eventClass = kEventClassMouse; + eventType.eventKind = kEventMouseDown; + handlerUPP = NewEventHandlerUPP(DoMouseDown); + InstallApplicationEventHandler (handlerUPP, 1, &eventType, this, nil); + + eventType.eventKind = kEventMouseUp; + handlerUPP = NewEventHandlerUPP(DoMouseUp); + InstallApplicationEventHandler (handlerUPP, 1, &eventType, this, nil); + + eventType.eventKind = kEventMouseDragged; + handlerUPP = NewEventHandlerUPP(DoMouseDragged); + InstallApplicationEventHandler (handlerUPP, 1, &eventType, this, nil); + + eventType.eventClass = kEventClassKeyboard; + eventType.eventKind = kEventRawKeyDown; + handlerUPP = NewEventHandlerUPP(DoKeyDown); + InstallApplicationEventHandler (handlerUPP, 1, &eventType, this, nil); + + eventType.eventKind = kEventRawKeyUp; + handlerUPP = NewEventHandlerUPP(DoKeyUp); + InstallApplicationEventHandler (handlerUPP, 1, &eventType, this, nil); + + eventType.eventKind = kEventRawKeyRepeat; + handlerUPP = NewEventHandlerUPP(DoKeyDown); // 'key repeat' is translated to 'key down' + InstallApplicationEventHandler (handlerUPP, 1, &eventType, this, nil); + + WindowAttributes windowAttrs; + Rect bounds; + + // window + windowAttrs = kWindowCloseBoxAttribute | kWindowCollapseBoxAttribute | kWindowStandardHandlerAttribute; + SetRect (&bounds, 0, 0, width, height); + OffsetRect (&bounds, 100, 100); + CreateNewWindow (kDocumentWindowClass, windowAttrs, &bounds, &m_specific->m_window); + + if(m_specific->m_window == nil) + { + return false; + } + + // I assume the text is ASCII. + // Change to kCFStringEncodingMacRoman, kCFStringEncodingISOLatin1, kCFStringEncodingUTF8 or what else you need. + SetWindowTitleWithCFString (m_specific->m_window, CFStringCreateWithCStringNoCopy (nil, m_caption, kCFStringEncodingASCII, nil)); + + eventType.eventClass = kEventClassWindow; + eventType.eventKind = kEventWindowClose; + + handlerUPP = NewEventHandlerUPP(DoWindowClose); + InstallWindowEventHandler (m_specific->m_window, handlerUPP, 1, &eventType, this, NULL); + + eventType.eventKind = kEventWindowDrawContent; + handlerUPP = NewEventHandlerUPP(DoWindowDrawContent); + InstallWindowEventHandler (m_specific->m_window, handlerUPP, 1, &eventType, this, NULL); + + // Periodic task + // Instead of an idle function I use the Carbon event timer. + // You may decide to change the wait value which is currently 50 milliseconds. + EventLoopRef mainLoop; + EventLoopTimerUPP timerUPP; + EventLoopTimerRef theTimer; + + mainLoop = GetMainEventLoop(); + timerUPP = NewEventLoopTimerUPP (DoPeriodicTask); + InstallEventLoopTimer (mainLoop, 0, 50 * kEventDurationMillisecond, timerUPP, this, &theTimer); + + m_specific->create_pmap(width, height, &m_rbuf_window); + m_initial_width = width; + m_initial_height = height; + on_init(); + on_resize(width, height); + m_specific->m_redraw_flag = true; + + ShowWindow (m_specific->m_window); + SetPortWindowPort (m_specific->m_window); + + return true; + } + + + //------------------------------------------------------------------------ + int platform_support::run() + { + + RunApplicationEventLoop (); + return true; + } + + + //------------------------------------------------------------------------ + const char* platform_support::img_ext() const { return ".bmp"; } + + //------------------------------------------------------------------------ + const char* platform_support::full_file_name(const char* file_name) + { + return file_name; + } + + //------------------------------------------------------------------------ + bool platform_support::load_img(unsigned idx, const char* file) + { + if(idx < max_images) + { + char fn[1024]; + strcpy(fn, file); + int len = strlen(fn); +#if defined(__MWERKS__) + if(len < 4 || stricmp(fn + len - 4, ".BMP") != 0) +#else + if(len < 4 || strncasecmp(fn + len - 4, ".BMP", 4) != 0) +#endif + { + strcat(fn, ".bmp"); + } + return m_specific->load_pmap(fn, idx, &m_rbuf_img[idx]); + } + return true; + } + + + + //------------------------------------------------------------------------ + bool platform_support::save_img(unsigned idx, const char* file) + { + if(idx < max_images) + { + char fn[1024]; + strcpy(fn, file); + int len = strlen(fn); +#if defined(__MWERKS__) + if(len < 4 || stricmp(fn + len - 4, ".BMP") != 0) +#else + if(len < 4 || strncasecmp(fn + len - 4, ".BMP", 4) != 0) +#endif + { + strcat(fn, ".bmp"); + } + return m_specific->save_pmap(fn, idx, &m_rbuf_img[idx]); + } + return true; + } + + + + //------------------------------------------------------------------------ + bool platform_support::create_img(unsigned idx, unsigned width, unsigned height) + { + if(idx < max_images) + { + if(width == 0) width = m_specific->m_pmap_window.width(); + if(height == 0) height = m_specific->m_pmap_window.height(); + m_specific->m_pmap_img[idx].create(width, height, org_e(m_specific->m_bpp)); + m_rbuf_img[idx].attach(m_specific->m_pmap_img[idx].buf(), + m_specific->m_pmap_img[idx].width(), + m_specific->m_pmap_img[idx].height(), + m_flip_y ? + -m_specific->m_pmap_img[idx].row_bytes() : + m_specific->m_pmap_img[idx].row_bytes()); + return true; + } + return false; + } + + + //------------------------------------------------------------------------ + void platform_support::force_redraw() + { + Rect bounds; + + m_specific->m_redraw_flag = true; + // on_ctrl_change (); + on_draw(); + + SetRect(&bounds, 0, 0, m_rbuf_window.width(), m_rbuf_window.height()); + InvalWindowRect(m_specific->m_window, &bounds); + } + + + + //------------------------------------------------------------------------ + void platform_support::update_window() + { + m_specific->display_pmap(m_specific->m_window, &m_rbuf_window); + } + + + //------------------------------------------------------------------------ + void platform_support::on_init() {} + void platform_support::on_resize(int sx, int sy) {} + void platform_support::on_idle() {} + void platform_support::on_mouse_move(int x, int y, unsigned flags) {} + void platform_support::on_mouse_button_down(int x, int y, unsigned flags) {} + void platform_support::on_mouse_button_up(int x, int y, unsigned flags) {} + void platform_support::on_key(int x, int y, unsigned key, unsigned flags) {} + void platform_support::on_ctrl_change() {} + void platform_support::on_draw() {} + void platform_support::on_post_draw(void* raw_handler) {} + + +//------------------------------------------------------------------------ +pascal OSStatus DoWindowClose (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData) +{ + userData; + + QuitApplicationEventLoop (); + + return CallNextEventHandler (nextHandler, theEvent); +} + + +//------------------------------------------------------------------------ +pascal OSStatus DoAppQuit (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData) +{ + userData; + + return CallNextEventHandler (nextHandler, theEvent); +} + + +//------------------------------------------------------------------------ +pascal OSStatus DoMouseDown (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData) +{ + Point wheresMyMouse; + UInt32 modifier; + + GetEventParameter (theEvent, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &wheresMyMouse); + GlobalToLocal (&wheresMyMouse); + GetEventParameter (theEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifier); + + platform_support * app = reinterpret_cast<platform_support*>(userData); + + app->m_specific->m_cur_x = wheresMyMouse.h; + if(app->flip_y()) + { + app->m_specific->m_cur_y = app->rbuf_window().height() - wheresMyMouse.v; + } + else + { + app->m_specific->m_cur_y = wheresMyMouse.v; + } + app->m_specific->m_input_flags = mouse_left | get_key_flags(modifier); + + app->m_ctrls.set_cur(app->m_specific->m_cur_x, + app->m_specific->m_cur_y); + if(app->m_ctrls.on_mouse_button_down(app->m_specific->m_cur_x, + app->m_specific->m_cur_y)) + { + app->on_ctrl_change(); + app->force_redraw(); + } + else + { + if(app->m_ctrls.in_rect(app->m_specific->m_cur_x, + app->m_specific->m_cur_y)) + { + if(app->m_ctrls.set_cur(app->m_specific->m_cur_x, + app->m_specific->m_cur_y)) + { + app->on_ctrl_change(); + app->force_redraw(); + } + } + else + { + app->on_mouse_button_down(app->m_specific->m_cur_x, + app->m_specific->m_cur_y, + app->m_specific->m_input_flags); + } + } + + return CallNextEventHandler (nextHandler, theEvent); +} + + +//------------------------------------------------------------------------ +pascal OSStatus DoMouseUp (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData) +{ + Point wheresMyMouse; + UInt32 modifier; + + GetEventParameter (theEvent, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &wheresMyMouse); + GlobalToLocal (&wheresMyMouse); + GetEventParameter (theEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifier); + + platform_support * app = reinterpret_cast<platform_support*>(userData); + + app->m_specific->m_cur_x = wheresMyMouse.h; + if(app->flip_y()) + { + app->m_specific->m_cur_y = app->rbuf_window().height() - wheresMyMouse.v; + } + else + { + app->m_specific->m_cur_y = wheresMyMouse.v; + } + app->m_specific->m_input_flags = mouse_left | get_key_flags(modifier); + + if(app->m_ctrls.on_mouse_button_up(app->m_specific->m_cur_x, + app->m_specific->m_cur_y)) + { + app->on_ctrl_change(); + app->force_redraw(); + } + app->on_mouse_button_up(app->m_specific->m_cur_x, + app->m_specific->m_cur_y, + app->m_specific->m_input_flags); + + return CallNextEventHandler (nextHandler, theEvent); +} + + +//------------------------------------------------------------------------ +pascal OSStatus DoMouseDragged (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData) +{ + Point wheresMyMouse; + UInt32 modifier; + + GetEventParameter (theEvent, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &wheresMyMouse); + GlobalToLocal (&wheresMyMouse); + GetEventParameter (theEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifier); + + platform_support * app = reinterpret_cast<platform_support*>(userData); + + app->m_specific->m_cur_x = wheresMyMouse.h; + if(app->flip_y()) + { + app->m_specific->m_cur_y = app->rbuf_window().height() - wheresMyMouse.v; + } + else + { + app->m_specific->m_cur_y = wheresMyMouse.v; + } + app->m_specific->m_input_flags = mouse_left | get_key_flags(modifier); + + + if(app->m_ctrls.on_mouse_move( + app->m_specific->m_cur_x, + app->m_specific->m_cur_y, + (app->m_specific->m_input_flags & mouse_left) != 0)) + { + app->on_ctrl_change(); + app->force_redraw(); + } + else + { + app->on_mouse_move(app->m_specific->m_cur_x, + app->m_specific->m_cur_y, + app->m_specific->m_input_flags); + } + + return CallNextEventHandler (nextHandler, theEvent); +} + + +//------------------------------------------------------------------------ +pascal OSStatus DoKeyDown (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData) +{ + char key_code; + UInt32 modifier; + + GetEventParameter (theEvent, kEventParamKeyMacCharCodes, typeChar, NULL, sizeof(char), NULL, &key_code); + GetEventParameter (theEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifier); + + platform_support * app = reinterpret_cast<platform_support*>(userData); + + app->m_specific->m_last_translated_key = 0; + switch(modifier) + { + case controlKey: + app->m_specific->m_input_flags |= kbd_ctrl; + break; + + case shiftKey: + app->m_specific->m_input_flags |= kbd_shift; + break; + + default: + app->m_specific->translate(key_code); + break; + } + + if(app->m_specific->m_last_translated_key) + { + bool left = false; + bool up = false; + bool right = false; + bool down = false; + + switch(app->m_specific->m_last_translated_key) + { + case key_left: + left = true; + break; + + case key_up: + up = true; + break; + + case key_right: + right = true; + break; + + case key_down: + down = true; + break; + + //On a Mac, screenshots are handled by the system. + case key_f2: + app->copy_window_to_img(agg::platform_support::max_images - 1); + app->save_img(agg::platform_support::max_images - 1, "screenshot"); + break; + } + + + if(app->m_ctrls.on_arrow_keys(left, right, down, up)) + { + app->on_ctrl_change(); + app->force_redraw(); + } + else + { + app->on_key(app->m_specific->m_cur_x, + app->m_specific->m_cur_y, + app->m_specific->m_last_translated_key, + app->m_specific->m_input_flags); + } + } + + return CallNextEventHandler (nextHandler, theEvent); +} + + +//------------------------------------------------------------------------ +pascal OSStatus DoKeyUp (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData) +{ + char key_code; + UInt32 modifier; + + GetEventParameter (theEvent, kEventParamKeyMacCharCodes, typeChar, NULL, sizeof(char), NULL, &key_code); + GetEventParameter (theEvent, kEventParamKeyModifiers, typeUInt32, NULL, sizeof(UInt32), NULL, &modifier); + + platform_support * app = reinterpret_cast<platform_support*>(userData); + + app->m_specific->m_last_translated_key = 0; + switch(modifier) + { + case controlKey: + app->m_specific->m_input_flags &= ~kbd_ctrl; + break; + + case shiftKey: + app->m_specific->m_input_flags &= ~kbd_shift; + break; + } + + return CallNextEventHandler (nextHandler, theEvent); +} + + +//------------------------------------------------------------------------ +pascal OSStatus DoWindowDrawContent (EventHandlerCallRef nextHandler, EventRef theEvent, void* userData) +{ + platform_support * app = reinterpret_cast<platform_support*>(userData); + + if(app) + { + if(app->m_specific->m_redraw_flag) + { + app->on_draw(); + app->m_specific->m_redraw_flag = false; + } + app->m_specific->display_pmap(app->m_specific->m_window, &app->rbuf_window()); + } + + return CallNextEventHandler (nextHandler, theEvent); +} + + +//------------------------------------------------------------------------ +pascal void DoPeriodicTask (EventLoopTimerRef theTimer, void* userData) +{ + platform_support * app = reinterpret_cast<platform_support*>(userData); + + if(!app->wait_mode()) + app->on_idle(); +} + + +} + + + + +//---------------------------------------------------------------------------- +int agg_main(int argc, char* argv[]); + + +// Hm. Classic MacOS does not know command line input. +// CodeWarrior provides a way to mimic command line input. +// The function 'ccommand' can be used to get the command +// line arguments. +//---------------------------------------------------------------------------- +int main(int argc, char* argv[]) +{ +#if defined(__MWERKS__) + // argc = ccommand (&argv); +#endif + + // Check if we are launched by double-clicking under OSX + // Get rid of extra argument, this will confuse the standard argument parsing + // calls used in the examples to get the name of the image file to be used + if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) { + argc = 1; + } + +launch: + return agg_main(argc, argv); +}
\ No newline at end of file diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/sdl/agg_platform_support.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/sdl/agg_platform_support.cpp new file mode 100644 index 00000000000..28c6436baa1 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/sdl/agg_platform_support.cpp @@ -0,0 +1,708 @@ +//---------------------------------------------------------------------------- +// 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. SDL version. +// +//---------------------------------------------------------------------------- + +#include <string.h> +#include "platform/agg_platform_support.h" +#include "SDL.h" +#include "SDL_byteorder.h" + + +namespace agg +{ + + //------------------------------------------------------------------------ + class platform_specific + { + public: + platform_specific(pix_format_e format, bool flip_y); + ~platform_specific(); + + pix_format_e m_format; + pix_format_e m_sys_format; + bool m_flip_y; + unsigned m_bpp; + unsigned m_sys_bpp; + unsigned m_rmask; + unsigned m_gmask; + unsigned m_bmask; + unsigned m_amask; + bool m_update_flag; + bool m_resize_flag; + bool m_initialized; + SDL_Surface* m_surf_screen; + SDL_Surface* m_surf_window; + SDL_Surface* m_surf_img[platform_support::max_images]; + int m_cur_x; + int m_cur_y; + int m_sw_start; + }; + + + + //------------------------------------------------------------------------ + platform_specific::platform_specific(pix_format_e format, bool flip_y) : + m_format(format), + m_sys_format(pix_format_undefined), + m_flip_y(flip_y), + m_bpp(0), + m_sys_bpp(0), + m_update_flag(true), + m_resize_flag(true), + m_initialized(false), + m_surf_screen(0), + m_surf_window(0), + m_cur_x(0), + m_cur_y(0) + { + memset(m_surf_img, 0, sizeof(m_surf_img)); + + switch(m_format) + { + case pix_format_gray8: + m_bpp = 8; + break; + + case pix_format_rgb565: + m_rmask = 0xF800; + m_gmask = 0x7E0; + m_bmask = 0x1F; + m_amask = 0; + m_bpp = 16; + break; + + case pix_format_rgb555: + m_rmask = 0x7C00; + m_gmask = 0x3E0; + m_bmask = 0x1F; + m_amask = 0; + m_bpp = 16; + break; + +#if SDL_BYTEORDER == SDL_LIL_ENDIAN + case pix_format_rgb24: + m_rmask = 0xFF; + m_gmask = 0xFF00; + m_bmask = 0xFF0000; + m_amask = 0; + m_bpp = 24; + break; + + case pix_format_bgr24: + m_rmask = 0xFF0000; + m_gmask = 0xFF00; + m_bmask = 0xFF; + m_amask = 0; + m_bpp = 24; + break; + + case pix_format_bgra32: + m_rmask = 0xFF0000; + m_gmask = 0xFF00; + m_bmask = 0xFF; + m_amask = 0xFF000000; + m_bpp = 32; + break; + + case pix_format_abgr32: + m_rmask = 0xFF000000; + m_gmask = 0xFF0000; + m_bmask = 0xFF00; + m_amask = 0xFF; + m_bpp = 32; + break; + + case pix_format_argb32: + m_rmask = 0xFF00; + m_gmask = 0xFF0000; + m_bmask = 0xFF000000; + m_amask = 0xFF; + m_bpp = 32; + break; + + case pix_format_rgba32: + m_rmask = 0xFF; + m_gmask = 0xFF00; + m_bmask = 0xFF0000; + m_amask = 0xFF000000; + m_bpp = 32; + break; +#else //SDL_BIG_ENDIAN (PPC) + case pix_format_rgb24: + m_rmask = 0xFF0000; + m_gmask = 0xFF00; + m_bmask = 0xFF; + m_amask = 0; + m_bpp = 24; + break; + + case pix_format_bgr24: + m_rmask = 0xFF; + m_gmask = 0xFF00; + m_bmask = 0xFF0000; + m_amask = 0; + m_bpp = 24; + break; + + case pix_format_bgra32: + m_rmask = 0xFF00; + m_gmask = 0xFF0000; + m_bmask = 0xFF000000; + m_amask = 0xFF; + m_bpp = 32; + break; + + case pix_format_abgr32: + m_rmask = 0xFF; + m_gmask = 0xFF00; + m_bmask = 0xFF0000; + m_amask = 0xFF000000; + m_bpp = 32; + break; + + case pix_format_argb32: + m_rmask = 0xFF0000; + m_gmask = 0xFF00; + m_bmask = 0xFF; + m_amask = 0xFF000000; + m_bpp = 32; + break; + + case pix_format_rgba32: + m_rmask = 0xFF000000; + m_gmask = 0xFF0000; + m_bmask = 0xFF00; + m_amask = 0xFF; + m_bpp = 32; + break; +#endif + } + } + + //------------------------------------------------------------------------ + platform_specific::~platform_specific() + { + int i; + for(i = platform_support::max_images - 1; i >= 0; --i) + { + if(m_surf_img[i]) SDL_FreeSurface(m_surf_img[i]); + } + if(m_surf_window) SDL_FreeSurface(m_surf_window); + if(m_surf_screen) SDL_FreeSurface(m_surf_screen); + } + + + + //------------------------------------------------------------------------ + platform_support::platform_support(pix_format_e format, bool flip_y) : + m_specific(new platform_specific(format, flip_y)), + m_format(format), + m_bpp(m_specific->m_bpp), + m_window_flags(0), + m_wait_mode(true), + m_flip_y(flip_y) + { + SDL_Init(SDL_INIT_VIDEO); + strcpy(m_caption, "Anti-Grain Geometry Application"); + } + + + //------------------------------------------------------------------------ + platform_support::~platform_support() + { + delete m_specific; + } + + + + //------------------------------------------------------------------------ + void platform_support::caption(const char* cap) + { + strcpy(m_caption, cap); + if(m_specific->m_initialized) + { + SDL_WM_SetCaption(cap, 0); + } + } + + + + + + //------------------------------------------------------------------------ + bool platform_support::init(unsigned width, unsigned height, unsigned flags) + { + m_window_flags = flags; + unsigned wflags = SDL_SWSURFACE; + + if(m_window_flags & window_hw_buffer) + { + wflags = SDL_HWSURFACE; + } + + if(m_window_flags & window_resize) + { + wflags |= SDL_RESIZABLE; + } + + if(m_specific->m_surf_screen) SDL_FreeSurface(m_specific->m_surf_screen); + + m_specific->m_surf_screen = SDL_SetVideoMode(width, height, m_bpp, wflags); + if(m_specific->m_surf_screen == 0) + { + fprintf(stderr, + "Unable to set %dx%d %d bpp video: %s\n", + width, + height, + m_bpp, + ::SDL_GetError()); + return false; + } + + SDL_WM_SetCaption(m_caption, 0); + + if(m_specific->m_surf_window) SDL_FreeSurface(m_specific->m_surf_window); + + m_specific->m_surf_window = + SDL_CreateRGBSurface(SDL_HWSURFACE, + m_specific->m_surf_screen->w, + m_specific->m_surf_screen->h, + m_specific->m_surf_screen->format->BitsPerPixel, + m_specific->m_rmask, + m_specific->m_gmask, + m_specific->m_bmask, + m_specific->m_amask); + + if(m_specific->m_surf_window == 0) + { + fprintf(stderr, + "Unable to create image buffer %dx%d %d bpp: %s\n", + width, + height, + m_bpp, + SDL_GetError()); + return false; + } + + m_rbuf_window.attach((unsigned char*)m_specific->m_surf_window->pixels, + m_specific->m_surf_window->w, + m_specific->m_surf_window->h, + m_flip_y ? -m_specific->m_surf_window->pitch : + m_specific->m_surf_window->pitch); + + if(!m_specific->m_initialized) + { + m_initial_width = width; + m_initial_height = height; + on_init(); + m_specific->m_initialized = true; + } + on_resize(m_rbuf_window.width(), m_rbuf_window.height()); + m_specific->m_update_flag = true; + return true; + } + + + + //------------------------------------------------------------------------ + void platform_support::update_window() + { + SDL_BlitSurface(m_specific->m_surf_window, 0, m_specific->m_surf_screen, 0); + SDL_UpdateRect(m_specific->m_surf_screen, 0, 0, 0, 0); + } + + + //------------------------------------------------------------------------ + int platform_support::run() + { + SDL_Event event; + bool ev_flag = false; + + for(;;) + { + if(m_specific->m_update_flag) + { + on_draw(); + update_window(); + m_specific->m_update_flag = false; + } + + ev_flag = false; + if(m_wait_mode) + { + SDL_WaitEvent(&event); + ev_flag = true; + } + else + { + if(SDL_PollEvent(&event)) + { + ev_flag = true; + } + else + { + on_idle(); + } + } + + if(ev_flag) + { + if(event.type == SDL_QUIT) + { + break; + } + + int y; + unsigned flags = 0; + + switch (event.type) + { + case SDL_VIDEORESIZE: + if(!init(event.resize.w, event.resize.h, m_window_flags)) return false; + on_resize(m_rbuf_window.width(), m_rbuf_window.height()); + trans_affine_resizing(event.resize.w, event.resize.h); + m_specific->m_update_flag = true; + break; + + case SDL_KEYDOWN: + { + flags = 0; + if(event.key.keysym.mod & KMOD_SHIFT) flags |= kbd_shift; + if(event.key.keysym.mod & KMOD_CTRL) flags |= kbd_ctrl; + + bool left = false; + bool up = false; + bool right = false; + bool down = false; + + switch(event.key.keysym.sym) + { + case key_left: + left = true; + break; + + case key_up: + up = true; + break; + + case key_right: + right = true; + break; + + case key_down: + down = true; + break; + } + + if(m_ctrls.on_arrow_keys(left, right, down, up)) + { + on_ctrl_change(); + force_redraw(); + } + else + { + on_key(m_specific->m_cur_x, + m_specific->m_cur_y, + event.key.keysym.sym, + flags); + } + } + break; + + case SDL_MOUSEMOTION: + y = m_flip_y ? + m_rbuf_window.height() - event.motion.y : + event.motion.y; + + m_specific->m_cur_x = event.motion.x; + m_specific->m_cur_y = y; + flags = 0; + if(event.motion.state & SDL_BUTTON_LMASK) flags |= mouse_left; + if(event.motion.state & SDL_BUTTON_RMASK) flags |= mouse_right; + + if(m_ctrls.on_mouse_move(m_specific->m_cur_x, + m_specific->m_cur_y, + (flags & mouse_left) != 0)) + { + on_ctrl_change(); + force_redraw(); + } + else + { + on_mouse_move(m_specific->m_cur_x, + m_specific->m_cur_y, + flags); + } + SDL_Event eventtrash; + while (SDL_PeepEvents(&eventtrash, 1, SDL_GETEVENT, SDL_EVENTMASK(SDL_MOUSEMOTION))!=0){;} + break; + + case SDL_MOUSEBUTTONDOWN: + y = m_flip_y + ? m_rbuf_window.height() - event.button.y + : event.button.y; + + m_specific->m_cur_x = event.button.x; + m_specific->m_cur_y = y; + flags = 0; + switch(event.button.button) + { + case SDL_BUTTON_LEFT: + { + flags = mouse_left; + +if(m_ctrls.on_mouse_button_down(m_specific->m_cur_x, + m_specific->m_cur_y)) + { + m_ctrls.set_cur(m_specific->m_cur_x, + m_specific->m_cur_y); + on_ctrl_change(); + force_redraw(); + } + else + { + if(m_ctrls.in_rect(m_specific->m_cur_x, + m_specific->m_cur_y)) + { + if(m_ctrls.set_cur(m_specific->m_cur_x, + m_specific->m_cur_y)) + { + on_ctrl_change(); + force_redraw(); + } + } + else + { + on_mouse_button_down(m_specific->m_cur_x, + m_specific->m_cur_y, + flags); + } + } + } + break; + case SDL_BUTTON_RIGHT: + flags = mouse_right; + on_mouse_button_down(m_specific->m_cur_x, + m_specific->m_cur_y, + flags); + break; + } //switch(event.button.button) + break; + + case SDL_MOUSEBUTTONUP: + y = m_flip_y + ? m_rbuf_window.height() - event.button.y + : event.button.y; + + m_specific->m_cur_x = event.button.x; + m_specific->m_cur_y = y; + flags = 0; + if(m_ctrls.on_mouse_button_up(m_specific->m_cur_x, + m_specific->m_cur_y)) + { + on_ctrl_change(); + force_redraw(); + } + on_mouse_button_up(m_specific->m_cur_x, + m_specific->m_cur_y, + flags); + break; + } + } + } + return 0; + } + + + + //------------------------------------------------------------------------ + const char* platform_support::img_ext() const { return ".bmp"; } + + //------------------------------------------------------------------------ + const char* platform_support::full_file_name(const char* file_name) + { + return file_name; + } + + //------------------------------------------------------------------------ + bool platform_support::load_img(unsigned idx, const char* file) + { + if(idx < max_images) + { + if(m_specific->m_surf_img[idx]) SDL_FreeSurface(m_specific->m_surf_img[idx]); + + char fn[1024]; + strcpy(fn, file); + int len = strlen(fn); + if(len < 4 || strcmp(fn + len - 4, ".bmp") != 0) + { + strcat(fn, ".bmp"); + } + + SDL_Surface* tmp_surf = SDL_LoadBMP(fn); + if (tmp_surf == 0) + { + fprintf(stderr, "Couldn't load %s: %s\n", fn, SDL_GetError()); + return false; + } + + SDL_PixelFormat format; + format.palette = 0; + format.BitsPerPixel = m_bpp; + format.BytesPerPixel = m_bpp >> 8; + format.Rmask = m_specific->m_rmask; + format.Gmask = m_specific->m_gmask; + format.Bmask = m_specific->m_bmask; + format.Amask = m_specific->m_amask; + format.Rshift = 0; + format.Gshift = 0; + format.Bshift = 0; + format.Ashift = 0; + format.Rloss = 0; + format.Gloss = 0; + format.Bloss = 0; + format.Aloss = 0; + format.colorkey = 0; + format.alpha = 0; + + m_specific->m_surf_img[idx] = + SDL_ConvertSurface(tmp_surf, + &format, + SDL_SWSURFACE); + + SDL_FreeSurface(tmp_surf); + + if(m_specific->m_surf_img[idx] == 0) return false; + + m_rbuf_img[idx].attach((unsigned char*)m_specific->m_surf_img[idx]->pixels, + m_specific->m_surf_img[idx]->w, + m_specific->m_surf_img[idx]->h, + m_flip_y ? -m_specific->m_surf_img[idx]->pitch : + m_specific->m_surf_img[idx]->pitch); + return true; + + } + return false; + } + + + + + //------------------------------------------------------------------------ + bool platform_support::save_img(unsigned idx, const char* file) + { + if(idx < max_images && m_specific->m_surf_img[idx]) + { + char fn[1024]; + strcpy(fn, file); + int len = strlen(fn); + if(len < 4 || strcmp(fn + len - 4, ".bmp") != 0) + { + strcat(fn, ".bmp"); + } + return SDL_SaveBMP(m_specific->m_surf_img[idx], fn) == 0; + } + return false; + } + + + + //------------------------------------------------------------------------ + bool platform_support::create_img(unsigned idx, unsigned width, unsigned height) + { + if(idx < max_images) + { + + if(m_specific->m_surf_img[idx]) SDL_FreeSurface(m_specific->m_surf_img[idx]); + + m_specific->m_surf_img[idx] = + SDL_CreateRGBSurface(SDL_SWSURFACE, + width, + height, + m_specific->m_surf_screen->format->BitsPerPixel, + m_specific->m_rmask, + m_specific->m_gmask, + m_specific->m_bmask, + m_specific->m_amask); + if(m_specific->m_surf_img[idx] == 0) + { + fprintf(stderr, "Couldn't create image: %s\n", SDL_GetError()); + return false; + } + + m_rbuf_img[idx].attach((unsigned char*)m_specific->m_surf_img[idx]->pixels, + m_specific->m_surf_img[idx]->w, + m_specific->m_surf_img[idx]->h, + m_flip_y ? -m_specific->m_surf_img[idx]->pitch : + m_specific->m_surf_img[idx]->pitch); + + return true; + } + + return false; + } + + //------------------------------------------------------------------------ + void platform_support::start_timer() + { + m_specific->m_sw_start = SDL_GetTicks(); + } + + //------------------------------------------------------------------------ + double platform_support::elapsed_time() const + { + int stop = SDL_GetTicks(); + return double(stop - m_specific->m_sw_start); + } + + //------------------------------------------------------------------------ + void platform_support::message(const char* msg) + { + fprintf(stderr, "%s\n", msg); + } + + //------------------------------------------------------------------------ + void platform_support::force_redraw() + { + m_specific->m_update_flag = true; + } + + + //------------------------------------------------------------------------ + void platform_support::on_init() {} + void platform_support::on_resize(int sx, int sy) {} + void platform_support::on_idle() {} + void platform_support::on_mouse_move(int x, int y, unsigned flags) {} + void platform_support::on_mouse_button_down(int x, int y, unsigned flags) {} + void platform_support::on_mouse_button_up(int x, int y, unsigned flags) {} + void platform_support::on_key(int x, int y, unsigned key, unsigned flags) {} + void platform_support::on_ctrl_change() {} + void platform_support::on_draw() {} + void platform_support::on_post_draw(void* raw_handler) {} + + +} + + +int agg_main(int argc, char* argv[]); + +int main(int argc, char* argv[]) +{ + return agg_main(argc, argv); +} + diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/win32/agg_platform_support.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/win32/agg_platform_support.cpp new file mode 100644 index 00000000000..ea9123802f2 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/win32/agg_platform_support.cpp @@ -0,0 +1,1655 @@ +//---------------------------------------------------------------------------- +// 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 +// +//---------------------------------------------------------------------------- + +#include <windows.h> +#include <string.h> +#include "platform/agg_platform_support.h" +#include "platform/win32/agg_win32_bmp.h" +#include "util/agg_color_conv.h" +#include "util/agg_color_conv_rgb8.h" +#include "util/agg_color_conv_rgb16.h" +#include "agg_pixfmt_gray.h" +#include "agg_pixfmt_rgb.h" +#include "agg_pixfmt_rgba.h" + + +namespace agg +{ + + //------------------------------------------------------------------------ + HINSTANCE g_windows_instance = 0; + int g_windows_cmd_show = 0; + + + //------------------------------------------------------------------------ + class platform_specific + { + public: + platform_specific(pix_format_e format, bool flip_y); + + void create_pmap(unsigned width, unsigned height, + rendering_buffer* wnd); + + void display_pmap(HDC dc, const rendering_buffer* src); + bool load_pmap(const char* fn, unsigned idx, + rendering_buffer* dst); + + bool save_pmap(const char* fn, unsigned idx, + const rendering_buffer* src); + + unsigned translate(unsigned keycode); + + pix_format_e m_format; + pix_format_e m_sys_format; + bool m_flip_y; + unsigned m_bpp; + unsigned m_sys_bpp; + HWND m_hwnd; + pixel_map m_pmap_window; + pixel_map m_pmap_img[platform_support::max_images]; + unsigned m_keymap[256]; + unsigned m_last_translated_key; + int m_cur_x; + int m_cur_y; + unsigned m_input_flags; + bool m_redraw_flag; + HDC m_current_dc; + LARGE_INTEGER m_sw_freq; + LARGE_INTEGER m_sw_start; + }; + + + //------------------------------------------------------------------------ + platform_specific::platform_specific(pix_format_e format, bool flip_y) : + m_format(format), + m_sys_format(pix_format_undefined), + m_flip_y(flip_y), + m_bpp(0), + m_sys_bpp(0), + m_hwnd(0), + m_last_translated_key(0), + m_cur_x(0), + m_cur_y(0), + m_input_flags(0), + m_redraw_flag(true), + m_current_dc(0) + { + memset(m_keymap, 0, sizeof(m_keymap)); + + m_keymap[VK_PAUSE] = key_pause; + m_keymap[VK_CLEAR] = key_clear; + + m_keymap[VK_NUMPAD0] = key_kp0; + m_keymap[VK_NUMPAD1] = key_kp1; + m_keymap[VK_NUMPAD2] = key_kp2; + m_keymap[VK_NUMPAD3] = key_kp3; + m_keymap[VK_NUMPAD4] = key_kp4; + m_keymap[VK_NUMPAD5] = key_kp5; + m_keymap[VK_NUMPAD6] = key_kp6; + m_keymap[VK_NUMPAD7] = key_kp7; + m_keymap[VK_NUMPAD8] = key_kp8; + m_keymap[VK_NUMPAD9] = key_kp9; + m_keymap[VK_DECIMAL] = key_kp_period; + m_keymap[VK_DIVIDE] = key_kp_divide; + m_keymap[VK_MULTIPLY] = key_kp_multiply; + m_keymap[VK_SUBTRACT] = key_kp_minus; + m_keymap[VK_ADD] = key_kp_plus; + + m_keymap[VK_UP] = key_up; + m_keymap[VK_DOWN] = key_down; + m_keymap[VK_RIGHT] = key_right; + m_keymap[VK_LEFT] = key_left; + m_keymap[VK_INSERT] = key_insert; + m_keymap[VK_DELETE] = key_delete; + m_keymap[VK_HOME] = key_home; + m_keymap[VK_END] = key_end; + m_keymap[VK_PRIOR] = key_page_up; + m_keymap[VK_NEXT] = key_page_down; + + m_keymap[VK_F1] = key_f1; + m_keymap[VK_F2] = key_f2; + m_keymap[VK_F3] = key_f3; + m_keymap[VK_F4] = key_f4; + m_keymap[VK_F5] = key_f5; + m_keymap[VK_F6] = key_f6; + m_keymap[VK_F7] = key_f7; + m_keymap[VK_F8] = key_f8; + m_keymap[VK_F9] = key_f9; + m_keymap[VK_F10] = key_f10; + m_keymap[VK_F11] = key_f11; + m_keymap[VK_F12] = key_f12; + m_keymap[VK_F13] = key_f13; + m_keymap[VK_F14] = key_f14; + m_keymap[VK_F15] = key_f15; + + m_keymap[VK_NUMLOCK] = key_numlock; + m_keymap[VK_CAPITAL] = key_capslock; + m_keymap[VK_SCROLL] = key_scrollock; + + + switch(m_format) + { + case pix_format_bw: + m_sys_format = pix_format_bw; + m_bpp = 1; + m_sys_bpp = 1; + break; + + case pix_format_gray8: + case pix_format_sgray8: + m_sys_format = pix_format_sgray8; + m_bpp = 8; + m_sys_bpp = 8; + break; + + case pix_format_gray16: + m_sys_format = pix_format_sgray8; + m_bpp = 16; + m_sys_bpp = 8; + break; + + case pix_format_gray32: + m_sys_format = pix_format_sgray8; + m_bpp = 32; + m_sys_bpp = 8; + break; + + case pix_format_rgb565: + case pix_format_rgb555: + m_sys_format = pix_format_rgb555; + m_bpp = 16; + m_sys_bpp = 16; + break; + + case pix_format_rgbAAA: + case pix_format_bgrAAA: + case pix_format_rgbBBA: + case pix_format_bgrABB: + m_sys_format = pix_format_bgr24; + m_bpp = 32; + m_sys_bpp = 24; + break; + + case pix_format_rgb24: + case pix_format_bgr24: + case pix_format_srgb24: + case pix_format_sbgr24: + m_sys_format = pix_format_sbgr24; + m_bpp = 24; + m_sys_bpp = 24; + break; + + case pix_format_rgb48: + case pix_format_bgr48: + m_sys_format = pix_format_sbgr24; + m_bpp = 48; + m_sys_bpp = 24; + break; + + case pix_format_rgb96: + case pix_format_bgr96: + m_sys_format = pix_format_sbgr24; + m_bpp = 96; + m_sys_bpp = 24; + break; + + case pix_format_bgra32: + case pix_format_abgr32: + case pix_format_argb32: + case pix_format_rgba32: + case pix_format_sbgra32: + case pix_format_sabgr32: + case pix_format_sargb32: + case pix_format_srgba32: + m_sys_format = pix_format_sbgr24; + m_bpp = 32; + m_sys_bpp = 24; + break; + + case pix_format_bgra64: + case pix_format_abgr64: + case pix_format_argb64: + case pix_format_rgba64: + m_sys_format = pix_format_sbgr24; + m_bpp = 64; + m_sys_bpp = 24; + break; + + case pix_format_bgra128: + case pix_format_abgr128: + case pix_format_argb128: + case pix_format_rgba128: + m_sys_format = pix_format_sbgr24; + m_bpp = 128; + m_sys_bpp = 24; + break; + + } + ::QueryPerformanceFrequency(&m_sw_freq); + ::QueryPerformanceCounter(&m_sw_start); + } + + + //------------------------------------------------------------------------ + void platform_specific::create_pmap(unsigned width, + unsigned height, + rendering_buffer* wnd) + { + m_pmap_window.create(width, height, org_e(m_bpp)); + wnd->attach(m_pmap_window.buf(), + m_pmap_window.width(), + m_pmap_window.height(), + m_flip_y ? + m_pmap_window.stride() : + -m_pmap_window.stride()); + } + + + //------------------------------------------------------------------------ + static void convert_pmap(rendering_buffer* dst, + const rendering_buffer* src, + pix_format_e format) + { + switch(format) + { + case pix_format_gray8: + convert<pixfmt_sgray8, pixfmt_gray8>(dst, src); + break; + + case pix_format_gray16: + convert<pixfmt_sgray8, pixfmt_gray16>(dst, src); + break; + + case pix_format_gray32: + convert<pixfmt_sgray8, pixfmt_gray32>(dst, src); + break; + + case pix_format_rgb565: + color_conv(dst, src, color_conv_rgb565_to_rgb555()); + break; + + case pix_format_rgbAAA: + color_conv(dst, src, color_conv_rgbAAA_to_bgr24()); + break; + + case pix_format_bgrAAA: + color_conv(dst, src, color_conv_bgrAAA_to_bgr24()); + break; + + case pix_format_rgbBBA: + color_conv(dst, src, color_conv_rgbBBA_to_bgr24()); + break; + + case pix_format_bgrABB: + color_conv(dst, src, color_conv_bgrABB_to_bgr24()); + break; + + case pix_format_srgb24: + color_conv(dst, src, color_conv_rgb24_to_bgr24()); + break; + + case pix_format_rgb24: + convert<pixfmt_sbgr24, pixfmt_rgb24>(dst, src); + break; + + case pix_format_bgr24: + convert<pixfmt_sbgr24, pixfmt_bgr24>(dst, src); + break; + + case pix_format_rgb48: + convert<pixfmt_sbgr24, pixfmt_rgb48>(dst, src); + break; + + case pix_format_bgr48: + convert<pixfmt_sbgr24, pixfmt_bgr48>(dst, src); + break; + + case pix_format_bgra32: + convert<pixfmt_sbgr24, pixfmt_bgrx32>(dst, src); + break; + + case pix_format_abgr32: + convert<pixfmt_sbgr24, pixfmt_xbgr32>(dst, src); + break; + + case pix_format_argb32: + convert<pixfmt_sbgr24, pixfmt_xrgb32>(dst, src); + break; + + case pix_format_rgba32: + convert<pixfmt_sbgr24, pixfmt_rgbx32>(dst, src); + break; + + case pix_format_sbgra32: + convert<pixfmt_sbgr24, pixfmt_sbgrx32>(dst, src); + break; + + case pix_format_sabgr32: + convert<pixfmt_sbgr24, pixfmt_sxbgr32>(dst, src); + break; + + case pix_format_sargb32: + convert<pixfmt_sbgr24, pixfmt_sxrgb32>(dst, src); + break; + + case pix_format_srgba32: + convert<pixfmt_sbgr24, pixfmt_srgbx32>(dst, src); + break; + + case pix_format_bgra64: + convert<pixfmt_sbgr24, pixfmt_bgrx64>(dst, src); + break; + + case pix_format_abgr64: + convert<pixfmt_sbgr24, pixfmt_xbgr64>(dst, src); + break; + + case pix_format_argb64: + convert<pixfmt_sbgr24, pixfmt_xrgb64>(dst, src); + break; + + case pix_format_rgba64: + convert<pixfmt_sbgr24, pixfmt_rgbx64>(dst, src); + break; + + case pix_format_rgb96: + convert<pixfmt_sbgr24, pixfmt_rgb96>(dst, src); + break; + + case pix_format_bgr96: + convert<pixfmt_sbgr24, pixfmt_bgr96>(dst, src); + break; + + case pix_format_bgra128: + convert<pixfmt_sbgr24, pixfmt_bgrx128>(dst, src); + break; + + case pix_format_abgr128: + convert<pixfmt_sbgr24, pixfmt_xbgr128>(dst, src); + break; + + case pix_format_argb128: + convert<pixfmt_sbgr24, pixfmt_xrgb128>(dst, src); + break; + + case pix_format_rgba128: + convert<pixfmt_sbgr24, pixfmt_rgbx128>(dst, src); + break; + } + } + + + //------------------------------------------------------------------------ + void platform_specific::display_pmap(HDC dc, const rendering_buffer* src) + { + if(m_sys_format == m_format) + { + m_pmap_window.draw(dc); + } + else + { + pixel_map pmap_tmp; + pmap_tmp.create(m_pmap_window.width(), + m_pmap_window.height(), + org_e(m_sys_bpp)); + + rendering_buffer rbuf_tmp; + rbuf_tmp.attach(pmap_tmp.buf(), + pmap_tmp.width(), + pmap_tmp.height(), + m_flip_y ? + pmap_tmp.stride() : + -pmap_tmp.stride()); + + convert_pmap(&rbuf_tmp, src, m_format); + pmap_tmp.draw(dc); + } + } + + + + //------------------------------------------------------------------------ + bool platform_specific::save_pmap(const char* fn, unsigned idx, + const rendering_buffer* src) + { + if(m_sys_format == m_format) + { + return m_pmap_img[idx].save_as_bmp(fn); + } + + pixel_map pmap_tmp; + pmap_tmp.create(m_pmap_img[idx].width(), + m_pmap_img[idx].height(), + org_e(m_sys_bpp)); + + rendering_buffer rbuf_tmp; + rbuf_tmp.attach(pmap_tmp.buf(), + pmap_tmp.width(), + pmap_tmp.height(), + m_flip_y ? + pmap_tmp.stride() : + -pmap_tmp.stride()); + + convert_pmap(&rbuf_tmp, src, m_format); + return pmap_tmp.save_as_bmp(fn); + } + + + + //------------------------------------------------------------------------ + bool platform_specific::load_pmap(const char* fn, unsigned idx, + rendering_buffer* dst) + { + pixel_map pmap_tmp; + if(!pmap_tmp.load_from_bmp(fn)) return false; + + rendering_buffer rbuf_tmp; + rbuf_tmp.attach(pmap_tmp.buf(), + pmap_tmp.width(), + pmap_tmp.height(), + m_flip_y ? + pmap_tmp.stride() : + -pmap_tmp.stride()); + + m_pmap_img[idx].create(pmap_tmp.width(), + pmap_tmp.height(), + org_e(m_bpp), + 0); + + dst->attach(m_pmap_img[idx].buf(), + m_pmap_img[idx].width(), + m_pmap_img[idx].height(), + m_flip_y ? + m_pmap_img[idx].stride() : + -m_pmap_img[idx].stride()); + + switch(m_format) + { + case pix_format_sgray8: + switch(pmap_tmp.bpp()) + { + //case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_gray8()); break; + case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_gray8()); break; + //case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_gray8()); break; + } + break; + + case pix_format_gray8: + switch(pmap_tmp.bpp()) + { + case 24: convert<pixfmt_gray8, pixfmt_sbgr24>(dst, &rbuf_tmp); break; + } + break; + + case pix_format_gray16: + switch(pmap_tmp.bpp()) + { + //case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_gray16()); break; + case 24: convert<pixfmt_gray16, pixfmt_sbgr24>(dst, &rbuf_tmp); break; + //case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_gray16()); break; + } + break; + + case pix_format_gray32: + switch(pmap_tmp.bpp()) + { + //case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_gray32()); break; + case 24: convert<pixfmt_gray32, pixfmt_sbgr24>(dst, &rbuf_tmp); break; + //case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_gray32()); break; + } + break; + + case pix_format_rgb555: + switch(pmap_tmp.bpp()) + { + case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_rgb555()); break; + case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_rgb555()); break; + case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_rgb555()); break; + } + break; + + case pix_format_rgb565: + switch(pmap_tmp.bpp()) + { + case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_rgb565()); break; + case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_rgb565()); break; + case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_rgb565()); break; + } + break; + + case pix_format_srgb24: + switch(pmap_tmp.bpp()) + { + case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_rgb24()); break; + case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_rgb24()); break; + case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_rgb24()); break; + } + break; + + case pix_format_sbgr24: + switch(pmap_tmp.bpp()) + { + case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_bgr24()); break; + case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_bgr24()); break; + case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_bgr24()); break; + } + break; + + case pix_format_rgb24: + switch(pmap_tmp.bpp()) + { + case 24: convert<pixfmt_rgb24, pixfmt_sbgr24>(dst, &rbuf_tmp); break; + } + break; + + case pix_format_bgr24: + switch(pmap_tmp.bpp()) + { + case 24: convert<pixfmt_bgr24, pixfmt_sbgr24>(dst, &rbuf_tmp); break; + } + break; + + case pix_format_rgb48: + switch(pmap_tmp.bpp()) + { + //case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_rgb48()); break; + case 24: convert<pixfmt_rgb48, pixfmt_sbgr24>(dst, &rbuf_tmp); break; + //case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_rgb48()); break; + } + break; + + case pix_format_bgr48: + switch(pmap_tmp.bpp()) + { + //case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_bgr48()); break; + case 24: convert<pixfmt_bgr48, pixfmt_sbgr24>(dst, &rbuf_tmp); break; + //case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_bgr48()); break; + } + break; + + case pix_format_sabgr32: + switch(pmap_tmp.bpp()) + { + case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_abgr32()); break; + case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_abgr32()); break; + case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_abgr32()); break; + } + break; + + case pix_format_sargb32: + switch(pmap_tmp.bpp()) + { + case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_argb32()); break; + case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_argb32()); break; + case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_argb32()); break; + } + break; + + case pix_format_sbgra32: + switch(pmap_tmp.bpp()) + { + case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_bgra32()); break; + case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_bgra32()); break; + case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_bgra32()); break; + } + break; + + case pix_format_srgba32: + switch(pmap_tmp.bpp()) + { + case 16: color_conv(dst, &rbuf_tmp, color_conv_rgb555_to_rgba32()); break; + case 24: color_conv(dst, &rbuf_tmp, color_conv_bgr24_to_rgba32()); break; + case 32: color_conv(dst, &rbuf_tmp, color_conv_bgra32_to_rgba32()); break; + } + break; + + case pix_format_abgr32: + switch(pmap_tmp.bpp()) + { + case 24: convert<pixfmt_abgr32, pixfmt_sbgr24>(dst, &rbuf_tmp); break; + } + break; + + case pix_format_argb32: + switch(pmap_tmp.bpp()) + { + case 24: convert<pixfmt_argb32, pixfmt_sbgr24>(dst, &rbuf_tmp); break; + } + break; + + case pix_format_bgra32: + switch(pmap_tmp.bpp()) + { + case 24: convert<pixfmt_bgra32, pixfmt_sbgr24>(dst, &rbuf_tmp); break; + } + break; + + case pix_format_rgba32: + switch(pmap_tmp.bpp()) + { + case 24: convert<pixfmt_rgba32, pixfmt_sbgr24>(dst, &rbuf_tmp); break; + } + break; + + case pix_format_abgr64: + switch(pmap_tmp.bpp()) + { + case 24: convert<pixfmt_abgr64, pixfmt_sbgr24>(dst, &rbuf_tmp); break; + } + break; + + case pix_format_argb64: + switch(pmap_tmp.bpp()) + { + case 24: convert<pixfmt_argb64, pixfmt_sbgr24>(dst, &rbuf_tmp); break; + } + break; + + case pix_format_bgra64: + switch(pmap_tmp.bpp()) + { + case 24: convert<pixfmt_bgra64, pixfmt_sbgr24>(dst, &rbuf_tmp); break; + } + break; + + case pix_format_rgba64: + switch(pmap_tmp.bpp()) + { + case 24: convert<pixfmt_rgba64, pixfmt_sbgr24>(dst, &rbuf_tmp); break; + } + break; + + case pix_format_rgb96: + switch(pmap_tmp.bpp()) + { + case 24: convert<pixfmt_rgb96, pixfmt_sbgr24>(dst, &rbuf_tmp); break; + } + break; + + case pix_format_bgr96: + switch(pmap_tmp.bpp()) + { + case 24: convert<pixfmt_bgr96, pixfmt_sbgr24>(dst, &rbuf_tmp); break; + } + break; + + case pix_format_abgr128: + switch(pmap_tmp.bpp()) + { + case 24: convert<pixfmt_abgr128, pixfmt_sbgr24>(dst, &rbuf_tmp); break; + } + break; + + case pix_format_argb128: + switch(pmap_tmp.bpp()) + { + case 24: convert<pixfmt_argb128, pixfmt_sbgr24>(dst, &rbuf_tmp); break; + } + break; + + case pix_format_bgra128: + switch(pmap_tmp.bpp()) + { + case 24: convert<pixfmt_bgra128, pixfmt_sbgr24>(dst, &rbuf_tmp); break; + } + break; + + case pix_format_rgba128: + switch(pmap_tmp.bpp()) + { + case 24: convert<pixfmt_rgba128, pixfmt_sbgr24>(dst, &rbuf_tmp); break; + } + break; + } + + return true; + } + + + + + + + + + //------------------------------------------------------------------------ + unsigned platform_specific::translate(unsigned keycode) + { + return m_last_translated_key = (keycode > 255) ? 0 : m_keymap[keycode]; + } + + + + //------------------------------------------------------------------------ + platform_support::platform_support(pix_format_e format, bool flip_y) : + m_specific(new platform_specific(format, flip_y)), + m_format(format), + m_bpp(m_specific->m_bpp), + m_window_flags(0), + m_wait_mode(true), + m_flip_y(flip_y), + m_initial_width(10), + m_initial_height(10) + { + strcpy(m_caption, "Anti-Grain Geometry Application"); + } + + + //------------------------------------------------------------------------ + platform_support::~platform_support() + { + delete m_specific; + } + + + + //------------------------------------------------------------------------ + void platform_support::caption(const char* cap) + { + strcpy(m_caption, cap); + if(m_specific->m_hwnd) + { + SetWindowText(m_specific->m_hwnd, m_caption); + } + } + + //------------------------------------------------------------------------ + void platform_support::start_timer() + { + ::QueryPerformanceCounter(&(m_specific->m_sw_start)); + } + + //------------------------------------------------------------------------ + double platform_support::elapsed_time() const + { + LARGE_INTEGER stop; + ::QueryPerformanceCounter(&stop); + return double(stop.QuadPart - + m_specific->m_sw_start.QuadPart) * 1000.0 / + double(m_specific->m_sw_freq.QuadPart); + } + + + + //------------------------------------------------------------------------ + static unsigned get_key_flags(int wflags) + { + unsigned flags = 0; + if(wflags & MK_LBUTTON) flags |= mouse_left; + if(wflags & MK_RBUTTON) flags |= mouse_right; + if(wflags & MK_SHIFT) flags |= kbd_shift; + if(wflags & MK_CONTROL) flags |= kbd_ctrl; + return flags; + } + + + void* platform_support::raw_display_handler() + { + return m_specific->m_current_dc; + } + + + //------------------------------------------------------------------------ + LRESULT CALLBACK window_proc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) + { + PAINTSTRUCT ps; + HDC paintDC; + + + void* user_data = reinterpret_cast<void*>(::GetWindowLongPtr(hWnd, GWLP_USERDATA)); + platform_support* app = 0; + + if(user_data) + { + app = reinterpret_cast<platform_support*>(user_data); + } + + if(app == 0) + { + if(msg == WM_DESTROY) + { + ::PostQuitMessage(0); + return 0; + } + return ::DefWindowProc(hWnd, msg, wParam, lParam); + } + + HDC dc = ::GetDC(app->m_specific->m_hwnd); + app->m_specific->m_current_dc = dc; + LRESULT ret = 0; + + switch(msg) + { + //-------------------------------------------------------------------- + case WM_CREATE: + break; + + //-------------------------------------------------------------------- + case WM_SIZE: + app->m_specific->create_pmap(LOWORD(lParam), + HIWORD(lParam), + &app->rbuf_window()); + + app->trans_affine_resizing(LOWORD(lParam), HIWORD(lParam)); + app->on_resize(LOWORD(lParam), HIWORD(lParam)); + app->force_redraw(); + break; + + //-------------------------------------------------------------------- + case WM_ERASEBKGND: + break; + + //-------------------------------------------------------------------- + case WM_LBUTTONDOWN: + ::SetCapture(app->m_specific->m_hwnd); + app->m_specific->m_cur_x = int16(LOWORD(lParam)); + if(app->flip_y()) + { + app->m_specific->m_cur_y = app->rbuf_window().height() - int16(HIWORD(lParam)); + } + else + { + app->m_specific->m_cur_y = int16(HIWORD(lParam)); + } + app->m_specific->m_input_flags = mouse_left | get_key_flags(wParam); + + app->m_ctrls.set_cur(app->m_specific->m_cur_x, + app->m_specific->m_cur_y); + if(app->m_ctrls.on_mouse_button_down(app->m_specific->m_cur_x, + app->m_specific->m_cur_y)) + { + app->on_ctrl_change(); + app->force_redraw(); + } + else + { + if(app->m_ctrls.in_rect(app->m_specific->m_cur_x, + app->m_specific->m_cur_y)) + { + if(app->m_ctrls.set_cur(app->m_specific->m_cur_x, + app->m_specific->m_cur_y)) + { + app->on_ctrl_change(); + app->force_redraw(); + } + } + else + { + app->on_mouse_button_down(app->m_specific->m_cur_x, + app->m_specific->m_cur_y, + app->m_specific->m_input_flags); + } + } +/* + if(!app->wait_mode()) + { + app->on_idle(); + } +*/ + break; + + //-------------------------------------------------------------------- + case WM_LBUTTONUP: + ::ReleaseCapture(); + app->m_specific->m_cur_x = int16(LOWORD(lParam)); + if(app->flip_y()) + { + app->m_specific->m_cur_y = app->rbuf_window().height() - int16(HIWORD(lParam)); + } + else + { + app->m_specific->m_cur_y = int16(HIWORD(lParam)); + } + app->m_specific->m_input_flags = mouse_left | get_key_flags(wParam); + + if(app->m_ctrls.on_mouse_button_up(app->m_specific->m_cur_x, + app->m_specific->m_cur_y)) + { + app->on_ctrl_change(); + app->force_redraw(); + } + app->on_mouse_button_up(app->m_specific->m_cur_x, + app->m_specific->m_cur_y, + app->m_specific->m_input_flags); +/* + if(!app->wait_mode()) + { + app->on_idle(); + } +*/ + break; + + + //-------------------------------------------------------------------- + case WM_RBUTTONDOWN: + ::SetCapture(app->m_specific->m_hwnd); + app->m_specific->m_cur_x = int16(LOWORD(lParam)); + if(app->flip_y()) + { + app->m_specific->m_cur_y = app->rbuf_window().height() - int16(HIWORD(lParam)); + } + else + { + app->m_specific->m_cur_y = int16(HIWORD(lParam)); + } + app->m_specific->m_input_flags = mouse_right | get_key_flags(wParam); + app->on_mouse_button_down(app->m_specific->m_cur_x, + app->m_specific->m_cur_y, + app->m_specific->m_input_flags); +/* + if(!app->wait_mode()) + { + app->on_idle(); + } +*/ + break; + + //-------------------------------------------------------------------- + case WM_RBUTTONUP: + ::ReleaseCapture(); + app->m_specific->m_cur_x = int16(LOWORD(lParam)); + if(app->flip_y()) + { + app->m_specific->m_cur_y = app->rbuf_window().height() - int16(HIWORD(lParam)); + } + else + { + app->m_specific->m_cur_y = int16(HIWORD(lParam)); + } + app->m_specific->m_input_flags = mouse_right | get_key_flags(wParam); + app->on_mouse_button_up(app->m_specific->m_cur_x, + app->m_specific->m_cur_y, + app->m_specific->m_input_flags); +/* + if(!app->wait_mode()) + { + app->on_idle(); + } +*/ + break; + + //-------------------------------------------------------------------- + case WM_MOUSEMOVE: + app->m_specific->m_cur_x = int16(LOWORD(lParam)); + if(app->flip_y()) + { + app->m_specific->m_cur_y = app->rbuf_window().height() - int16(HIWORD(lParam)); + } + else + { + app->m_specific->m_cur_y = int16(HIWORD(lParam)); + } + app->m_specific->m_input_flags = get_key_flags(wParam); + + + if(app->m_ctrls.on_mouse_move( + app->m_specific->m_cur_x, + app->m_specific->m_cur_y, + (app->m_specific->m_input_flags & mouse_left) != 0)) + { + app->on_ctrl_change(); + app->force_redraw(); + } + else + { + if(!app->m_ctrls.in_rect(app->m_specific->m_cur_x, + app->m_specific->m_cur_y)) + { + app->on_mouse_move(app->m_specific->m_cur_x, + app->m_specific->m_cur_y, + app->m_specific->m_input_flags); + } + } +/* + if(!app->wait_mode()) + { + app->on_idle(); + } +*/ + break; + + //-------------------------------------------------------------------- + case WM_SYSKEYDOWN: + case WM_KEYDOWN: + app->m_specific->m_last_translated_key = 0; + switch(wParam) + { + case VK_CONTROL: + app->m_specific->m_input_flags |= kbd_ctrl; + break; + + case VK_SHIFT: + app->m_specific->m_input_flags |= kbd_shift; + break; + + default: + app->m_specific->translate(wParam); + break; + } + + if(app->m_specific->m_last_translated_key) + { + bool left = false; + bool up = false; + bool right = false; + bool down = false; + + switch(app->m_specific->m_last_translated_key) + { + case key_left: + left = true; + break; + + case key_up: + up = true; + break; + + case key_right: + right = true; + break; + + case key_down: + down = true; + break; + + case key_f2: + app->copy_window_to_img(agg::platform_support::max_images - 1); + app->save_img(agg::platform_support::max_images - 1, "screenshot"); + break; + } + + if(app->window_flags() & window_process_all_keys) + { + app->on_key(app->m_specific->m_cur_x, + app->m_specific->m_cur_y, + app->m_specific->m_last_translated_key, + app->m_specific->m_input_flags); + } + else + { + if(app->m_ctrls.on_arrow_keys(left, right, down, up)) + { + app->on_ctrl_change(); + app->force_redraw(); + } + else + { + app->on_key(app->m_specific->m_cur_x, + app->m_specific->m_cur_y, + app->m_specific->m_last_translated_key, + app->m_specific->m_input_flags); + } + } + } +/* + if(!app->wait_mode()) + { + app->on_idle(); + } +*/ + break; + + //-------------------------------------------------------------------- + case WM_SYSKEYUP: + case WM_KEYUP: + app->m_specific->m_last_translated_key = 0; + switch(wParam) + { + case VK_CONTROL: + app->m_specific->m_input_flags &= ~kbd_ctrl; + break; + + case VK_SHIFT: + app->m_specific->m_input_flags &= ~kbd_shift; + break; + } + break; + + //-------------------------------------------------------------------- + case WM_CHAR: + case WM_SYSCHAR: + if(app->m_specific->m_last_translated_key == 0) + { + app->on_key(app->m_specific->m_cur_x, + app->m_specific->m_cur_y, + wParam, + app->m_specific->m_input_flags); + } + break; + + //-------------------------------------------------------------------- + case WM_PAINT: + paintDC = ::BeginPaint(hWnd, &ps); + app->m_specific->m_current_dc = paintDC; + if(app->m_specific->m_redraw_flag) + { + app->on_draw(); + app->m_specific->m_redraw_flag = false; + } + app->m_specific->display_pmap(paintDC, &app->rbuf_window()); + app->on_post_draw(paintDC); + app->m_specific->m_current_dc = 0; + ::EndPaint(hWnd, &ps); + break; + + //-------------------------------------------------------------------- + case WM_COMMAND: + break; + + //-------------------------------------------------------------------- + case WM_DESTROY: + ::PostQuitMessage(0); + break; + + //-------------------------------------------------------------------- + default: + ret = ::DefWindowProc(hWnd, msg, wParam, lParam); + break; + } + app->m_specific->m_current_dc = 0; + ::ReleaseDC(app->m_specific->m_hwnd, dc); + return ret; + } + + + //------------------------------------------------------------------------ + void platform_support::message(const char* msg) + { + ::MessageBox(m_specific->m_hwnd, msg, "AGG Message", MB_OK); + } + + + //------------------------------------------------------------------------ + bool platform_support::init(unsigned width, unsigned height, unsigned flags) + { + if(m_specific->m_sys_format == pix_format_undefined) + { + return false; + } + + m_window_flags = flags; + + int wflags = CS_OWNDC | CS_VREDRAW | CS_HREDRAW; + + WNDCLASS wc; + wc.lpszClassName = "AGGAppClass"; + wc.lpfnWndProc = window_proc; + wc.style = wflags; + wc.hInstance = g_windows_instance; + wc.hIcon = LoadIcon(0, IDI_APPLICATION); + wc.hCursor = LoadCursor(0, IDC_ARROW); + wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); + wc.lpszMenuName = "AGGAppMenu"; + wc.cbClsExtra = 0; + wc.cbWndExtra = 0; + ::RegisterClass(&wc); + + wflags = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX; + + if(m_window_flags & window_resize) + { + wflags |= WS_THICKFRAME | WS_MAXIMIZEBOX; + } + + m_specific->m_hwnd = ::CreateWindow("AGGAppClass", + m_caption, + wflags, + 100, + 100, + width, + height, + 0, + 0, + g_windows_instance, + 0); + + if(m_specific->m_hwnd == 0) + { + return false; + } + + + RECT rct; + ::GetClientRect(m_specific->m_hwnd, &rct); + + ::MoveWindow(m_specific->m_hwnd, // handle to window + 100, // horizontal position + 100, // vertical position + width + (width - (rct.right - rct.left)), + height + (height - (rct.bottom - rct.top)), + FALSE); + + ::SetWindowLongPtr(m_specific->m_hwnd, GWLP_USERDATA, (LONG)this); + m_specific->create_pmap(width, height, &m_rbuf_window); + m_initial_width = width; + m_initial_height = height; + on_init(); + m_specific->m_redraw_flag = true; + ::ShowWindow(m_specific->m_hwnd, g_windows_cmd_show); + return true; + } + + + + //------------------------------------------------------------------------ + int platform_support::run() + { + MSG msg; + + for(;;) + { + if(m_wait_mode) + { + if(!::GetMessage(&msg, 0, 0, 0)) + { + break; + } + ::TranslateMessage(&msg); + ::DispatchMessage(&msg); + } + else + { + if(::PeekMessage(&msg, 0, 0, 0, PM_REMOVE)) + { + ::TranslateMessage(&msg); + if(msg.message == WM_QUIT) + { + break; + } + ::DispatchMessage(&msg); + } + else + { + on_idle(); + } + } + } + return (int)msg.wParam; + } + + + //------------------------------------------------------------------------ + const char* platform_support::img_ext() const { return ".bmp"; } + + + //------------------------------------------------------------------------ + const char* platform_support::full_file_name(const char* file_name) + { + return file_name; + } + + //------------------------------------------------------------------------ + bool platform_support::load_img(unsigned idx, const char* file) + { + if(idx < max_images) + { + char fn[1024]; + strcpy(fn, file); + int len = strlen(fn); + if(len < 4 || _stricmp(fn + len - 4, ".BMP") != 0) + { + strcat(fn, ".bmp"); + } + return m_specific->load_pmap(fn, idx, &m_rbuf_img[idx]); + } + return true; + } + + + + //------------------------------------------------------------------------ + bool platform_support::save_img(unsigned idx, const char* file) + { + if(idx < max_images) + { + char fn[1024]; + strcpy(fn, file); + int len = strlen(fn); + if(len < 4 || _stricmp(fn + len - 4, ".BMP") != 0) + { + strcat(fn, ".bmp"); + } + return m_specific->save_pmap(fn, idx, &m_rbuf_img[idx]); + } + return true; + } + + + + //------------------------------------------------------------------------ + bool platform_support::create_img(unsigned idx, unsigned width, unsigned height) + { + if(idx < max_images) + { + if(width == 0) width = m_specific->m_pmap_window.width(); + if(height == 0) height = m_specific->m_pmap_window.height(); + m_specific->m_pmap_img[idx].create(width, height, org_e(m_specific->m_bpp)); + m_rbuf_img[idx].attach(m_specific->m_pmap_img[idx].buf(), + m_specific->m_pmap_img[idx].width(), + m_specific->m_pmap_img[idx].height(), + m_flip_y ? + m_specific->m_pmap_img[idx].stride() : + -m_specific->m_pmap_img[idx].stride()); + return true; + } + return false; + } + + + //------------------------------------------------------------------------ + void platform_support::force_redraw() + { + m_specific->m_redraw_flag = true; + ::InvalidateRect(m_specific->m_hwnd, 0, FALSE); + } + + + + //------------------------------------------------------------------------ + void platform_support::update_window() + { + HDC dc = ::GetDC(m_specific->m_hwnd); + m_specific->display_pmap(dc, &m_rbuf_window); + ::ReleaseDC(m_specific->m_hwnd, dc); + } + + + //------------------------------------------------------------------------ + void platform_support::on_init() {} + void platform_support::on_resize(int sx, int sy) {} + void platform_support::on_idle() {} + void platform_support::on_mouse_move(int x, int y, unsigned flags) {} + void platform_support::on_mouse_button_down(int x, int y, unsigned flags) {} + void platform_support::on_mouse_button_up(int x, int y, unsigned flags) {} + void platform_support::on_key(int x, int y, unsigned key, unsigned flags) {} + void platform_support::on_ctrl_change() {} + void platform_support::on_draw() {} + void platform_support::on_post_draw(void* raw_handler) {} +} + + + + +namespace agg +{ + // That's ridiculous. I have to parse the command line by myself + // because Windows doesn't provide a method of getting the command + // line arguments in a form of argc, argv. Of course, there's + // CommandLineToArgv() but first, it returns Unicode that I don't + // need to deal with, but most of all, it's not compatible with Win98. + //----------------------------------------------------------------------- + class tokenizer + { + public: + enum sep_flag + { + single, + multiple, + whole_str + }; + + struct token + { + const char* ptr; + unsigned len; + }; + + public: + tokenizer(const char* sep, + const char* trim=0, + const char* quote="\"", + char mask_chr='\\', + sep_flag sf=multiple); + + void set_str(const char* str); + token next_token(); + + private: + int check_chr(const char *str, char chr); + + private: + const char* m_src_string; + int m_start; + const char* m_sep; + const char* m_trim; + const char* m_quote; + char m_mask_chr; + unsigned m_sep_len; + sep_flag m_sep_flag; + }; + + + + //----------------------------------------------------------------------- + inline void tokenizer::set_str(const char* str) + { + m_src_string = str; + m_start = 0; + } + + + //----------------------------------------------------------------------- + inline int tokenizer::check_chr(const char *str, char chr) + { + return int(strchr(str, chr)); + } + + + //----------------------------------------------------------------------- + tokenizer::tokenizer(const char* sep, + const char* trim, + const char* quote, + char mask_chr, + sep_flag sf) : + m_src_string(0), + m_start(0), + m_sep(sep), + m_trim(trim), + m_quote(quote), + m_mask_chr(mask_chr), + m_sep_len(sep ? strlen(sep) : 0), + m_sep_flag(sep ? sf : single) + { + } + + + //----------------------------------------------------------------------- + tokenizer::token tokenizer::next_token() + { + unsigned count = 0; + char quote_chr = 0; + token tok; + + tok.ptr = 0; + tok.len = 0; + if(m_src_string == 0 || m_start == -1) return tok; + + const char *pstr = m_src_string + m_start; + + if(*pstr == 0) + { + m_start = -1; + return tok; + } + + int sep_len = 1; + if(m_sep_flag == whole_str) sep_len = m_sep_len; + + if(m_sep_flag == multiple) + { + //Pass all the separator symbols at the begin of the string + while(*pstr && check_chr(m_sep, *pstr)) + { + ++pstr; + ++m_start; + } + } + + if(*pstr == 0) + { + m_start = -1; + return tok; + } + + for(count = 0;; ++count) + { + char c = *pstr; + int found = 0; + + //We are outside of qotation: find one of separator symbols + if(quote_chr == 0) + { + if(sep_len == 1) + { + found = check_chr(m_sep, c); + } + else + { + found = strncmp(m_sep, pstr, m_sep_len) == 0; + } + } + + ++pstr; + + if(c == 0 || found) + { + if(m_trim) + { + while(count && + check_chr(m_trim, m_src_string[m_start])) + { + ++m_start; + --count; + } + + while(count && + check_chr(m_trim, m_src_string[m_start + count - 1])) + { + --count; + } + } + + tok.ptr = m_src_string + m_start; + tok.len = count; + + //Next time it will be the next separator character + //But we must check, whether it is NOT the end of the string. + m_start += count; + if(c) + { + m_start += sep_len; + if(m_sep_flag == multiple) + { + //Pass all the separator symbols + //after the end of the string + while(check_chr(m_sep, m_src_string[m_start])) + { + ++m_start; + } + } + } + break; + } + + //Switch quote. If it is not a quote yet, try to check any of + //quote symbols. Otherwise quote must be finished with quote_symb + if(quote_chr == 0) + { + if(check_chr(m_quote, c)) + { + quote_chr = c; + continue; + } + } + else + { + //We are inside quote: pass all the mask symbols + if(m_mask_chr && c == m_mask_chr) + { + if(*pstr) + { + ++count; + ++pstr; + } + continue; + } + if(c == quote_chr) + { + quote_chr = 0; + continue; + } + } + } + return tok; + } + + +} + + + +//---------------------------------------------------------------------------- +int agg_main(int argc, char* argv[]); + + + +//---------------------------------------------------------------------------- +int PASCAL WinMain(HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPSTR lpszCmdLine, + int nCmdShow) +{ + agg::g_windows_instance = hInstance; + agg::g_windows_cmd_show = nCmdShow; + + char* argv_str = new char [strlen(lpszCmdLine) + 3]; + char* argv_ptr = argv_str; + + char* argv[64]; + memset(argv, 0, sizeof(argv)); + + agg::tokenizer cmd_line(" ", "\"' ", "\"'", '\\', agg::tokenizer::multiple); + cmd_line.set_str(lpszCmdLine); + + int argc = 0; + argv[argc++] = argv_ptr; + *argv_ptr++ = 0; + + while(argc < 64) + { + agg::tokenizer::token tok = cmd_line.next_token(); + if(tok.ptr == 0) break; + if(tok.len) + { + memcpy(argv_ptr, tok.ptr, tok.len); + argv[argc++] = argv_ptr; + argv_ptr += tok.len; + *argv_ptr++ = 0; + } + } + + int ret = agg_main(argc, argv); + delete [] argv_str; + + return ret; +} + + + + diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/win32/agg_win32_bmp.cpp b/contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/win32/agg_win32_bmp.cpp new file mode 100644 index 00000000000..8c3bdc83fd7 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/src/platform/win32/agg_win32_bmp.cpp @@ -0,0 +1,631 @@ +//---------------------------------------------------------------------------- +// +//---------------------------------------------------------------------------- +// Contact: mcseemagg@yahoo.com +//---------------------------------------------------------------------------- +// +// class pixel_map +// +//---------------------------------------------------------------------------- + +#include "platform/win32/agg_win32_bmp.h" +#include "agg_basics.h" + +namespace agg +{ + + //------------------------------------------------------------------------ + pixel_map::~pixel_map() + { + destroy(); + } + + + //------------------------------------------------------------------------ + pixel_map::pixel_map() : + m_bmp(0), + m_buf(0), + m_bpp(0), + m_is_internal(false), + m_img_size(0), + m_full_size(0) + + { + } + + + //------------------------------------------------------------------------ + void pixel_map::destroy() + { + if(m_bmp && m_is_internal) delete [] (unsigned char*)m_bmp; + m_bmp = 0; + m_is_internal = false; + m_buf = 0; + } + + + //------------------------------------------------------------------------ + void pixel_map::create(unsigned width, + unsigned height, + org_e org, + unsigned clear_val) + { + destroy(); + if(width == 0) width = 1; + if(height == 0) height = 1; + m_bpp = org; + create_from_bmp(create_bitmap_info(width, height, m_bpp)); + create_gray_scale_palette(m_bmp); + m_is_internal = true; + if(clear_val <= 255) + { + memset(m_buf, clear_val, m_img_size); + } + } + + + //------------------------------------------------------------------------ + HBITMAP pixel_map::create_dib_section(HDC h_dc, + unsigned width, + unsigned height, + org_e org, + unsigned clear_val) + { + destroy(); + if(width == 0) width = 1; + if(height == 0) height = 1; + m_bpp = org; + HBITMAP h_bitmap = create_dib_section_from_args(h_dc, width, height, m_bpp); + create_gray_scale_palette(m_bmp); + m_is_internal = true; + if(clear_val <= 255) + { + memset(m_buf, clear_val, m_img_size); + } + return h_bitmap; + } + + + + //------------------------------------------------------------------------ + void pixel_map::clear(unsigned clear_val) + { + if(m_buf) memset(m_buf, clear_val, m_img_size); + } + + + //------------------------------------------------------------------------ + void pixel_map::attach_to_bmp(BITMAPINFO *bmp) + { + if(bmp) + { + destroy(); + create_from_bmp(bmp); + m_is_internal = false; + } + } + + + + //static + //------------------------------------------------------------------------ + unsigned pixel_map::calc_full_size(BITMAPINFO *bmp) + { + if(bmp == 0) return 0; + + return sizeof(BITMAPINFOHEADER) + + sizeof(RGBQUAD) * calc_palette_size(bmp) + + bmp->bmiHeader.biSizeImage; + } + + //static + //------------------------------------------------------------------------ + unsigned pixel_map::calc_header_size(BITMAPINFO *bmp) + { + if(bmp == 0) return 0; + return sizeof(BITMAPINFOHEADER) + sizeof(RGBQUAD) * calc_palette_size(bmp); + } + + + //static + //------------------------------------------------------------------------ + unsigned pixel_map::calc_palette_size(unsigned clr_used, unsigned bits_per_pixel) + { + int palette_size = 0; + + if(bits_per_pixel <= 8) + { + palette_size = clr_used; + if(palette_size == 0) + { + palette_size = 1 << bits_per_pixel; + } + } + return palette_size; + } + + //static + //------------------------------------------------------------------------ + unsigned pixel_map::calc_palette_size(BITMAPINFO *bmp) + { + if(bmp == 0) return 0; + return calc_palette_size(bmp->bmiHeader.biClrUsed, bmp->bmiHeader.biBitCount); + } + + + //static + //------------------------------------------------------------------------ + unsigned char * pixel_map::calc_img_ptr(BITMAPINFO *bmp) + { + if(bmp == 0) return 0; + return ((unsigned char*)bmp) + calc_header_size(bmp); + } + + //static + //------------------------------------------------------------------------ + BITMAPINFO* pixel_map::create_bitmap_info(unsigned width, + unsigned height, + unsigned bits_per_pixel) + { + unsigned line_len = calc_row_len(width, bits_per_pixel); + unsigned img_size = line_len * height; + unsigned rgb_size = calc_palette_size(0, bits_per_pixel) * sizeof(RGBQUAD); + unsigned full_size = sizeof(BITMAPINFOHEADER) + rgb_size + img_size; + + BITMAPINFO *bmp = (BITMAPINFO *) new unsigned char[full_size]; + + bmp->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bmp->bmiHeader.biWidth = width; + bmp->bmiHeader.biHeight = height; + bmp->bmiHeader.biPlanes = 1; + bmp->bmiHeader.biBitCount = (unsigned short)bits_per_pixel; + bmp->bmiHeader.biCompression = 0; + bmp->bmiHeader.biSizeImage = img_size; + bmp->bmiHeader.biXPelsPerMeter = 0; + bmp->bmiHeader.biYPelsPerMeter = 0; + bmp->bmiHeader.biClrUsed = 0; + bmp->bmiHeader.biClrImportant = 0; + + return bmp; + } + + + //static + //------------------------------------------------------------------------ + void pixel_map::create_gray_scale_palette(BITMAPINFO *bmp) + { + if(bmp == 0) return; + + unsigned rgb_size = calc_palette_size(bmp); + RGBQUAD *rgb = (RGBQUAD*)(((unsigned char*)bmp) + sizeof(BITMAPINFOHEADER)); + unsigned brightness; + unsigned i; + + for(i = 0; i < rgb_size; i++) + { + brightness = (255 * i) / (rgb_size - 1); + rgb->rgbBlue = + rgb->rgbGreen = + rgb->rgbRed = (unsigned char)brightness; + rgb->rgbReserved = 0; + rgb++; + } + } + + + + //static + //------------------------------------------------------------------------ + unsigned pixel_map::calc_row_len(unsigned width, unsigned bits_per_pixel) + { + unsigned n = width; + unsigned k; + + switch(bits_per_pixel) + { + case 1: k = n; + n = n >> 3; + if(k & 7) n++; + break; + + case 4: k = n; + n = n >> 1; + if(k & 3) n++; + break; + + case 8: + break; + + case 16: n *= 2; + break; + + case 24: n *= 3; + break; + + case 32: n *= 4; + break; + + case 48: n *= 6; + break; + + case 64: n *= 8; + break; + + case 96: n *= 12; + break; + + case 128: n *= 16; + break; + + default: n = 0; + break; + } + return ((n + 3) >> 2) << 2; + } + + + + + + //------------------------------------------------------------------------ + void pixel_map::draw(HDC h_dc, const RECT *device_rect, const RECT *bmp_rect) const + { + if(m_bmp == 0 || m_buf == 0) return; + + unsigned bmp_x = 0; + unsigned bmp_y = 0; + unsigned bmp_width = m_bmp->bmiHeader.biWidth; + unsigned bmp_height = m_bmp->bmiHeader.biHeight; + unsigned dvc_x = 0; + unsigned dvc_y = 0; + unsigned dvc_width = m_bmp->bmiHeader.biWidth; + unsigned dvc_height = m_bmp->bmiHeader.biHeight; + + if(bmp_rect) + { + bmp_x = bmp_rect->left; + bmp_y = bmp_rect->top; + bmp_width = bmp_rect->right - bmp_rect->left; + bmp_height = bmp_rect->bottom - bmp_rect->top; + } + + dvc_x = bmp_x; + dvc_y = bmp_y; + dvc_width = bmp_width; + dvc_height = bmp_height; + + if(device_rect) + { + dvc_x = device_rect->left; + dvc_y = device_rect->top; + dvc_width = device_rect->right - device_rect->left; + dvc_height = device_rect->bottom - device_rect->top; + } + + if(dvc_width != bmp_width || dvc_height != bmp_height) + { + ::SetStretchBltMode(h_dc, COLORONCOLOR); + ::StretchDIBits( + h_dc, // handle of device context + dvc_x, // x-coordinate of upper-left corner of source rect. + dvc_y, // y-coordinate of upper-left corner of source rect. + dvc_width, // width of source rectangle + dvc_height, // height of source rectangle + bmp_x, + bmp_y, // x, y -coordinates of upper-left corner of dest. rect. + bmp_width, // width of destination rectangle + bmp_height, // height of destination rectangle + m_buf, // address of bitmap bits + m_bmp, // address of bitmap data + DIB_RGB_COLORS, // usage + SRCCOPY // raster operation code + ); + } + else + { + ::SetDIBitsToDevice( + h_dc, // handle to device context + dvc_x, // x-coordinate of upper-left corner of + dvc_y, // y-coordinate of upper-left corner of + dvc_width, // source rectangle width + dvc_height, // source rectangle height + bmp_x, // x-coordinate of lower-left corner of + bmp_y, // y-coordinate of lower-left corner of + 0, // first scan line in array + bmp_height, // number of scan lines + m_buf, // address of array with DIB bits + m_bmp, // address of structure with bitmap info. + DIB_RGB_COLORS // RGB or palette indexes + ); + } + } + + + //------------------------------------------------------------------------ + void pixel_map::draw(HDC h_dc, int x, int y, double scale) const + { + if(m_bmp == 0 || m_buf == 0) return; + + unsigned width = unsigned(m_bmp->bmiHeader.biWidth * scale); + unsigned height = unsigned(m_bmp->bmiHeader.biHeight * scale); + RECT rect; + rect.left = x; + rect.top = y; + rect.right = x + width; + rect.bottom = y + height; + draw(h_dc, &rect); + } + + + + + //------------------------------------------------------------------------ + void pixel_map::blend(HDC h_dc, const RECT *device_rect, const RECT *bmp_rect) const + { +#if !defined(AGG_BMP_ALPHA_BLEND) + draw(h_dc, device_rect, bmp_rect); + return; +#else + if(m_bpp != 32) + { + draw(h_dc, device_rect, bmp_rect); + return; + } + + if(m_bmp == 0 || m_buf == 0) return; + + unsigned bmp_x = 0; + unsigned bmp_y = 0; + unsigned bmp_width = m_bmp->bmiHeader.biWidth; + unsigned bmp_height = m_bmp->bmiHeader.biHeight; + unsigned dvc_x = 0; + unsigned dvc_y = 0; + unsigned dvc_width = m_bmp->bmiHeader.biWidth; + unsigned dvc_height = m_bmp->bmiHeader.biHeight; + + if(bmp_rect) + { + bmp_x = bmp_rect->left; + bmp_y = bmp_rect->top; + bmp_width = bmp_rect->right - bmp_rect->left; + bmp_height = bmp_rect->bottom - bmp_rect->top; + } + + dvc_x = bmp_x; + dvc_y = bmp_y; + dvc_width = bmp_width; + dvc_height = bmp_height; + + if(device_rect) + { + dvc_x = device_rect->left; + dvc_y = device_rect->top; + dvc_width = device_rect->right - device_rect->left; + dvc_height = device_rect->bottom - device_rect->top; + } + + HDC mem_dc = ::CreateCompatibleDC(h_dc); + void* buf = 0; + HBITMAP bmp = ::CreateDIBSection( + mem_dc, + m_bmp, + DIB_RGB_COLORS, + &buf, + 0, + 0 + ); + memcpy(buf, m_buf, m_bmp->bmiHeader.biSizeImage); + + HBITMAP temp = (HBITMAP)::SelectObject(mem_dc, bmp); + + BLENDFUNCTION blend; + blend.BlendOp = AC_SRC_OVER; + blend.BlendFlags = 0; + +#if defined(AC_SRC_ALPHA) + blend.AlphaFormat = AC_SRC_ALPHA; +//#elif defined(AC_SRC_NO_PREMULT_ALPHA) +// blend.AlphaFormat = AC_SRC_NO_PREMULT_ALPHA; +#else +#error "No appropriate constant for alpha format. Check version of wingdi.h, There must be AC_SRC_ALPHA or AC_SRC_NO_PREMULT_ALPHA" +#endif + + blend.SourceConstantAlpha = 255; + ::AlphaBlend( + h_dc, + dvc_x, + dvc_y, + dvc_width, + dvc_height, + mem_dc, + bmp_x, + bmp_y, + bmp_width, + bmp_height, + blend + ); + + ::SelectObject(mem_dc, temp); + ::DeleteObject(bmp); + ::DeleteObject(mem_dc); +#endif //defined(AGG_BMP_ALPHA_BLEND) + } + + + //------------------------------------------------------------------------ + void pixel_map::blend(HDC h_dc, int x, int y, double scale) const + { + if(m_bmp == 0 || m_buf == 0) return; + unsigned width = unsigned(m_bmp->bmiHeader.biWidth * scale); + unsigned height = unsigned(m_bmp->bmiHeader.biHeight * scale); + RECT rect; + rect.left = x; + rect.top = y; + rect.right = x + width; + rect.bottom = y + height; + blend(h_dc, &rect); + } + + + //------------------------------------------------------------------------ + bool pixel_map::load_from_bmp(FILE *fd) + { + BITMAPFILEHEADER bmf; + BITMAPINFO *bmi = 0; + unsigned bmp_size; + + fread(&bmf, sizeof(bmf), 1, fd); + if(bmf.bfType != 0x4D42) goto bmperr; + + bmp_size = bmf.bfSize - sizeof(BITMAPFILEHEADER); + + bmi = (BITMAPINFO*) new unsigned char [bmp_size]; + if(fread(bmi, 1, bmp_size, fd) != bmp_size) goto bmperr; + destroy(); + m_bpp = bmi->bmiHeader.biBitCount; + create_from_bmp(bmi); + m_is_internal = 1; + return true; + + bmperr: + if(bmi) delete [] (unsigned char*) bmi; + return false; + } + + + + //------------------------------------------------------------------------ + bool pixel_map::load_from_bmp(const char *filename) + { + FILE *fd = fopen(filename, "rb"); + bool ret = false; + if(fd) + { + ret = load_from_bmp(fd); + fclose(fd); + } + return ret; + } + + + + //------------------------------------------------------------------------ + bool pixel_map::save_as_bmp(FILE *fd) const + { + if(m_bmp == 0) return 0; + + BITMAPFILEHEADER bmf; + + bmf.bfType = 0x4D42; + bmf.bfOffBits = calc_header_size(m_bmp) + sizeof(bmf); + bmf.bfSize = bmf.bfOffBits + m_img_size; + bmf.bfReserved1 = 0; + bmf.bfReserved2 = 0; + + fwrite(&bmf, sizeof(bmf), 1, fd); + fwrite(m_bmp, m_full_size, 1, fd); + return true; + } + + + + //------------------------------------------------------------------------ + bool pixel_map::save_as_bmp(const char *filename) const + { + FILE *fd = fopen(filename, "wb"); + bool ret = false; + if(fd) + { + ret = save_as_bmp(fd); + fclose(fd); + } + return ret; + } + + + //------------------------------------------------------------------------ + unsigned char* pixel_map::buf() + { + return m_buf; + } + + //------------------------------------------------------------------------ + unsigned pixel_map::width() const + { + return m_bmp->bmiHeader.biWidth; + } + + //------------------------------------------------------------------------ + unsigned pixel_map::height() const + { + return m_bmp->bmiHeader.biHeight; + } + + //------------------------------------------------------------------------ + int pixel_map::stride() const + { + return calc_row_len(m_bmp->bmiHeader.biWidth, + m_bmp->bmiHeader.biBitCount); + } + + + //private + //------------------------------------------------------------------------ + void pixel_map::create_from_bmp(BITMAPINFO *bmp) + { + if(bmp) + { + m_img_size = calc_row_len(bmp->bmiHeader.biWidth, + bmp->bmiHeader.biBitCount) * + bmp->bmiHeader.biHeight; + + m_full_size = calc_full_size(bmp); + m_bmp = bmp; + m_buf = calc_img_ptr(bmp); + } + } + + + //private + //------------------------------------------------------------------------ + HBITMAP pixel_map::create_dib_section_from_args(HDC h_dc, + unsigned width, + unsigned height, + unsigned bits_per_pixel) + { + unsigned line_len = calc_row_len(width, bits_per_pixel); + unsigned img_size = line_len * height; + unsigned rgb_size = calc_palette_size(0, bits_per_pixel) * sizeof(RGBQUAD); + unsigned full_size = sizeof(BITMAPINFOHEADER) + rgb_size; + + BITMAPINFO *bmp = (BITMAPINFO *) new unsigned char[full_size]; + + bmp->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); + bmp->bmiHeader.biWidth = width; + bmp->bmiHeader.biHeight = height; + bmp->bmiHeader.biPlanes = 1; + bmp->bmiHeader.biBitCount = (unsigned short)bits_per_pixel; + bmp->bmiHeader.biCompression = 0; + bmp->bmiHeader.biSizeImage = img_size; + bmp->bmiHeader.biXPelsPerMeter = 0; + bmp->bmiHeader.biYPelsPerMeter = 0; + bmp->bmiHeader.biClrUsed = 0; + bmp->bmiHeader.biClrImportant = 0; + + void* img_ptr = 0; + HBITMAP h_bitmap = ::CreateDIBSection(h_dc, bmp, DIB_RGB_COLORS, &img_ptr, NULL, 0); + + if(img_ptr) + { + m_img_size = calc_row_len(width, bits_per_pixel) * height; + m_full_size = 0; + m_bmp = bmp; + m_buf = (unsigned char *) img_ptr; + } + + return h_bitmap; + } +} + + + diff --git a/contrib/python/matplotlib/py3/extern/agg24-svn/ya.make b/contrib/python/matplotlib/py3/extern/agg24-svn/ya.make new file mode 100644 index 00000000000..6dd0f2d6f0f --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/agg24-svn/ya.make @@ -0,0 +1,24 @@ +LIBRARY() + +VERSION(Service-proxy-version) + +LICENSE(PSF-2.0) + +ADDINCL( + contrib/python/matplotlib/py3/extern/agg24-svn/include +) + +NO_COMPILER_WARNINGS() + +SRCS( + src/agg_bezier_arc.cpp + src/agg_curves.cpp + src/agg_image_filters.cpp + src/agg_trans_affine.cpp + src/agg_vcgen_contour.cpp + src/agg_vcgen_dash.cpp + src/agg_vcgen_stroke.cpp + src/agg_vpgen_segmentator.cpp +) + +END() diff --git a/contrib/python/matplotlib/py3/extern/ttconv/pprdrv.h b/contrib/python/matplotlib/py3/extern/ttconv/pprdrv.h new file mode 100644 index 00000000000..8c0b6c19556 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/ttconv/pprdrv.h @@ -0,0 +1,102 @@ +/* -*- mode: c++; c-basic-offset: 4 -*- */ + +/* + * Modified for use within matplotlib + * 5 July 2007 + * Michael Droettboom + */ + +/* +** ~ppr/src/include/pprdrv.h +** Copyright 1995, Trinity College Computing Center. +** Written by David Chappell. +** +** Permission to use, copy, modify, and distribute this software and its +** documentation for any purpose and without fee is hereby granted, provided +** that the above copyright notice appear in all copies and that both that +** copyright notice and this permission notice appear in supporting +** documentation. This software is provided "as is" without express or +** implied warranty. +** +** This file last revised 5 December 1995. +*/ + +#include <vector> +#include <cassert> + +/* + * Encapsulates all of the output to write to an arbitrary output + * function. This both removes the hardcoding of output to go to stdout + * and makes output thread-safe. Michael Droettboom [06-07-07] + */ +class TTStreamWriter +{ + private: + // Private copy and assignment + TTStreamWriter& operator=(const TTStreamWriter& other); + TTStreamWriter(const TTStreamWriter& other); + + public: + TTStreamWriter() { } + virtual ~TTStreamWriter() { } + + virtual void write(const char*) = 0; + + virtual void printf(const char* format, ...); + virtual void put_char(int val); + virtual void puts(const char* a); + virtual void putline(const char* a); +}; + +void replace_newlines_with_spaces(char* a); + +/* + * A simple class for all ttconv exceptions. + */ +class TTException +{ + const char* message; + TTException& operator=(const TTStreamWriter& other); + TTException(const TTStreamWriter& other); + +public: + TTException(const char* message_) : message(message_) { } + const char* getMessage() + { + return message; + } +}; + +/* +** No debug code will be included if this +** is not defined: +*/ +/* #define DEBUG 1 */ + +/* +** Uncomment the defines for the debugging +** code you want to have included. +*/ +#ifdef DEBUG +#define DEBUG_TRUETYPE /* truetype fonts, conversion to Postscript */ +#endif + +#if DEBUG_TRUETYPE +#define debug(...) printf(__VA_ARGS__) +#else +#define debug(...) +#endif + +/* Do not change anything below this line. */ + +enum font_type_enum +{ + PS_TYPE_3 = 3, + PS_TYPE_42 = 42, + PS_TYPE_42_3_HYBRID = 43, +}; + +/* routines in pprdrv_tt.c */ +void insert_ttfont(const char *filename, TTStreamWriter& stream, font_type_enum target_type, std::vector<int>& glyph_ids); + +/* end of file */ diff --git a/contrib/python/matplotlib/py3/extern/ttconv/pprdrv_tt.cpp b/contrib/python/matplotlib/py3/extern/ttconv/pprdrv_tt.cpp new file mode 100644 index 00000000000..a0c724c8aa1 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/ttconv/pprdrv_tt.cpp @@ -0,0 +1,1401 @@ +/* -*- mode: c++; c-basic-offset: 4 -*- */ + +/* + * Modified for use within matplotlib + * 5 July 2007 + * Michael Droettboom + */ + +/* +** ~ppr/src/pprdrv/pprdrv_tt.c +** Copyright 1995, Trinity College Computing Center. +** Written by David Chappell. +** +** Permission to use, copy, modify, and distribute this software and its +** documentation for any purpose and without fee is hereby granted, provided +** that the above copyright notice appear in all copies and that both that +** copyright notice and this permission notice appear in supporting +** documentation. This software is provided "as is" without express or +** implied warranty. +** +** TrueType font support. These functions allow PPR to generate +** PostScript fonts from Microsoft compatible TrueType font files. +** +** Last revised 19 December 1995. +*/ + +#include <cstdio> +#include <cstdlib> +#include <cstring> +#include "pprdrv.h" +#include "truetype.h" +#include <sstream> +#ifdef _POSIX_C_SOURCE +# undef _POSIX_C_SOURCE +#endif +#ifndef _AIX +#ifdef _XOPEN_SOURCE +# undef _XOPEN_SOURCE +#endif +#endif +#include <Python.h> + +/*========================================================================== +** Convert the indicated Truetype font file to a type 42 or type 3 +** PostScript font and insert it in the output stream. +** +** All the routines from here to the end of file file are involved +** in this process. +==========================================================================*/ + +/*--------------------------------------- +** Endian conversion routines. +** These routines take a BYTE pointer +** and return a value formed by reading +** bytes starting at that point. +** +** These routines read the big-endian +** values which are used in TrueType +** font files. +---------------------------------------*/ + +/* +** Get an Unsigned 32 bit number. +*/ +ULONG getULONG(BYTE *p) +{ + int x; + ULONG val=0; + + for (x=0; x<4; x++) + { + val *= 0x100; + val += p[x]; + } + + return val; +} /* end of ftohULONG() */ + +/* +** Get an unsigned 16 bit number. +*/ +USHORT getUSHORT(BYTE *p) +{ + int x; + USHORT val=0; + + for (x=0; x<2; x++) + { + val *= 0x100; + val += p[x]; + } + + return val; +} /* end of getUSHORT() */ + +/* +** Get a 32 bit fixed point (16.16) number. +** A special structure is used to return the value. +*/ +Fixed getFixed(BYTE *s) +{ + Fixed val={0,0}; + + val.whole = ((s[0] * 256) + s[1]); + val.fraction = ((s[2] * 256) + s[3]); + + return val; +} /* end of getFixed() */ + +/*----------------------------------------------------------------------- +** Load a TrueType font table into memory and return a pointer to it. +** The font's "file" and "offset_table" fields must be set before this +** routine is called. +** +** This first argument is a TrueType font structure, the second +** argument is the name of the table to retrieve. A table name +** is always 4 characters, though the last characters may be +** padding spaces. +-----------------------------------------------------------------------*/ +BYTE *GetTable(struct TTFONT *font, const char *name) +{ + BYTE *ptr; + ULONG x; + debug("GetTable(file,font,\"%s\")",name); + + /* We must search the table directory. */ + ptr = font->offset_table + 12; + x=0; + while (true) + { + if ( strncmp((const char*)ptr,name,4) == 0 ) + { + ULONG offset,length; + BYTE *table; + + offset = getULONG( ptr + 8 ); + length = getULONG( ptr + 12 ); + table = (BYTE*)calloc( sizeof(BYTE), length + 2 ); + + try + { + debug("Loading table \"%s\" from offset %d, %d bytes",name,offset,length); + + if ( fseek( font->file, (long)offset, SEEK_SET ) ) + { + throw TTException("TrueType font may be corrupt (reason 3)"); + } + + if ( fread(table,sizeof(BYTE),length,font->file) != (sizeof(BYTE) * length)) + { + throw TTException("TrueType font may be corrupt (reason 4)"); + } + } + catch (TTException& ) + { + free(table); + throw; + } + /* Always NUL-terminate; add two in case of UTF16 strings. */ + table[length] = '\0'; + table[length + 1] = '\0'; + return table; + } + + x++; + ptr += 16; + if (x == font->numTables) + { + throw TTException("TrueType font is missing table"); + } + } + +} /* end of GetTable() */ + +static void utf16be_to_ascii(char *dst, char *src, size_t length) { + ++src; + for (; *src != 0 && length; dst++, src += 2, --length) { + *dst = *src; + } +} + +/*-------------------------------------------------------------------- +** Load the 'name' table, get information from it, +** and store that information in the font structure. +** +** The 'name' table contains information such as the name of +** the font, and it's PostScript name. +--------------------------------------------------------------------*/ +void Read_name(struct TTFONT *font) +{ + BYTE *table_ptr,*ptr2; + int numrecords; /* Number of strings in this table */ + BYTE *strings; /* pointer to start of string storage */ + int x; + int platform; /* Current platform id */ + int nameid; /* name id, */ + int offset,length; /* offset and length of string. */ + debug("Read_name()"); + + table_ptr = NULL; + + /* Set default values to avoid future references to undefined + * pointers. Allocate each of PostName, FullName, FamilyName, + * Version, and Style separately so they can be freed safely. */ + for (char **ptr = &(font->PostName); ptr != NULL; ) + { + *ptr = (char*) calloc(sizeof(char), strlen("unknown")+1); + strcpy(*ptr, "unknown"); + if (ptr == &(font->PostName)) ptr = &(font->FullName); + else if (ptr == &(font->FullName)) ptr = &(font->FamilyName); + else if (ptr == &(font->FamilyName)) ptr = &(font->Version); + else if (ptr == &(font->Version)) ptr = &(font->Style); + else ptr = NULL; + } + font->Copyright = font->Trademark = (char*)NULL; + + table_ptr = GetTable(font, "name"); /* pointer to table */ + try + { + numrecords = getUSHORT( table_ptr + 2 ); /* number of names */ + strings = table_ptr + getUSHORT( table_ptr + 4 ); /* start of string storage */ + + ptr2 = table_ptr + 6; + for (x=0; x < numrecords; x++,ptr2+=12) + { + platform = getUSHORT(ptr2); + nameid = getUSHORT(ptr2+6); + length = getUSHORT(ptr2+8); + offset = getUSHORT(ptr2+10); + debug("platform %d, encoding %d, language 0x%x, name %d, offset %d, length %d", + platform,encoding,language,nameid,offset,length); + + /* Copyright notice */ + if ( platform == 1 && nameid == 0 ) + { + font->Copyright = (char*)calloc(sizeof(char),length+1); + strncpy(font->Copyright,(const char*)strings+offset,length); + font->Copyright[length]='\0'; + replace_newlines_with_spaces(font->Copyright); + debug("font->Copyright=\"%s\"",font->Copyright); + continue; + } + + + /* Font Family name */ + if ( platform == 1 && nameid == 1 ) + { + free(font->FamilyName); + font->FamilyName = (char*)calloc(sizeof(char),length+1); + strncpy(font->FamilyName,(const char*)strings+offset,length); + font->FamilyName[length]='\0'; + replace_newlines_with_spaces(font->FamilyName); + debug("font->FamilyName=\"%s\"",font->FamilyName); + continue; + } + + + /* Font Family name */ + if ( platform == 1 && nameid == 2 ) + { + free(font->Style); + font->Style = (char*)calloc(sizeof(char),length+1); + strncpy(font->Style,(const char*)strings+offset,length); + font->Style[length]='\0'; + replace_newlines_with_spaces(font->Style); + debug("font->Style=\"%s\"",font->Style); + continue; + } + + + /* Full Font name */ + if ( platform == 1 && nameid == 4 ) + { + free(font->FullName); + font->FullName = (char*)calloc(sizeof(char),length+1); + strncpy(font->FullName,(const char*)strings+offset,length); + font->FullName[length]='\0'; + replace_newlines_with_spaces(font->FullName); + debug("font->FullName=\"%s\"",font->FullName); + continue; + } + + + /* Version string */ + if ( platform == 1 && nameid == 5 ) + { + free(font->Version); + font->Version = (char*)calloc(sizeof(char),length+1); + strncpy(font->Version,(const char*)strings+offset,length); + font->Version[length]='\0'; + replace_newlines_with_spaces(font->Version); + debug("font->Version=\"%s\"",font->Version); + continue; + } + + + /* PostScript name */ + if ( platform == 1 && nameid == 6 ) + { + free(font->PostName); + font->PostName = (char*)calloc(sizeof(char),length+1); + strncpy(font->PostName,(const char*)strings+offset,length); + font->PostName[length]='\0'; + replace_newlines_with_spaces(font->PostName); + debug("font->PostName=\"%s\"",font->PostName); + continue; + } + + /* Microsoft-format PostScript name */ + if ( platform == 3 && nameid == 6 ) + { + free(font->PostName); + font->PostName = (char*)calloc(sizeof(char),length+1); + utf16be_to_ascii(font->PostName, (char *)strings+offset, length); + font->PostName[length/2]='\0'; + replace_newlines_with_spaces(font->PostName); + debug("font->PostName=\"%s\"",font->PostName); + continue; + } + + + /* Trademark string */ + if ( platform == 1 && nameid == 7 ) + { + font->Trademark = (char*)calloc(sizeof(char),length+1); + strncpy(font->Trademark,(const char*)strings+offset,length); + font->Trademark[length]='\0'; + replace_newlines_with_spaces(font->Trademark); + debug("font->Trademark=\"%s\"",font->Trademark); + continue; + } + } + } + catch (TTException& ) + { + free(table_ptr); + throw; + } + + free(table_ptr); +} /* end of Read_name() */ + +/*--------------------------------------------------------------------- +** Write the header for a PostScript font. +---------------------------------------------------------------------*/ +void ttfont_header(TTStreamWriter& stream, struct TTFONT *font) +{ + int VMMin; + int VMMax; + + /* + ** To show that it is a TrueType font in PostScript format, + ** we will begin the file with a specific string. + ** This string also indicates the version of the TrueType + ** specification on which the font is based and the + ** font manufacturer's revision number for the font. + */ + if ( font->target_type == PS_TYPE_42 || + font->target_type == PS_TYPE_42_3_HYBRID) + { + stream.printf("%%!PS-TrueTypeFont-%d.%d-%d.%d\n", + font->TTVersion.whole, font->TTVersion.fraction, + font->MfrRevision.whole, font->MfrRevision.fraction); + } + + /* If it is not a Type 42 font, we will use a different format. */ + else + { + stream.putline("%!PS-Adobe-3.0 Resource-Font"); + } /* See RBIIp 641 */ + + /* We will make the title the name of the font. */ + stream.printf("%%%%Title: %s\n",font->FullName); + + /* If there is a Copyright notice, put it here too. */ + if ( font->Copyright != (char*)NULL ) + { + stream.printf("%%%%Copyright: %s\n",font->Copyright); + } + + /* We created this file. */ + if ( font->target_type == PS_TYPE_42 ) + { + stream.putline("%%Creator: Converted from TrueType to type 42 by PPR"); + } + else if (font->target_type == PS_TYPE_42_3_HYBRID) + { + stream.putline("%%Creator: Converted from TypeType to type 42/type 3 hybrid by PPR"); + } + else + { + stream.putline("%%Creator: Converted from TrueType to type 3 by PPR"); + } + + /* If VM usage information is available, print it. */ + if ( font->target_type == PS_TYPE_42 || font->target_type == PS_TYPE_42_3_HYBRID) + { + VMMin = (int)getULONG( font->post_table + 16 ); + VMMax = (int)getULONG( font->post_table + 20 ); + if ( VMMin > 0 && VMMax > 0 ) + stream.printf("%%%%VMUsage: %d %d\n",VMMin,VMMax); + } + + /* Start the dictionary which will eventually */ + /* become the font. */ + if (font->target_type == PS_TYPE_42) + { + stream.putline("15 dict begin"); + } + else + { + stream.putline("25 dict begin"); + + /* Type 3 fonts will need some subroutines here. */ + stream.putline("/_d{bind def}bind def"); + stream.putline("/_m{moveto}_d"); + stream.putline("/_l{lineto}_d"); + stream.putline("/_cl{closepath eofill}_d"); + stream.putline("/_c{curveto}_d"); + stream.putline("/_sc{7 -1 roll{setcachedevice}{pop pop pop pop pop pop}ifelse}_d"); + stream.putline("/_e{exec}_d"); + } + + stream.printf("/FontName /%s def\n",font->PostName); + stream.putline("/PaintType 0 def"); + + if (font->target_type == PS_TYPE_42 || font->target_type == PS_TYPE_42_3_HYBRID) + { + stream.putline("/FontMatrix[1 0 0 1 0 0]def"); + } + else + { + stream.putline("/FontMatrix[.001 0 0 .001 0 0]def"); + } + + stream.printf("/FontBBox[%d %d %d %d]def\n",font->llx-1,font->lly-1,font->urx,font->ury); + if (font->target_type == PS_TYPE_42 || font->target_type == PS_TYPE_42_3_HYBRID) + { + stream.printf("/FontType 42 def\n", font->target_type ); + } + else + { + stream.printf("/FontType 3 def\n", font->target_type ); + } +} /* end of ttfont_header() */ + +/*------------------------------------------------------------- +** Define the encoding array for this font. +** Since we don't really want to deal with converting all of +** the possible font encodings in the wild to a standard PS +** one, we just explicitly create one for each font. +-------------------------------------------------------------*/ +void ttfont_encoding(TTStreamWriter& stream, struct TTFONT *font, std::vector<int>& glyph_ids, font_type_enum target_type) +{ + if (target_type == PS_TYPE_3 || target_type == PS_TYPE_42_3_HYBRID) + { + stream.printf("/Encoding [ "); + + for (std::vector<int>::const_iterator i = glyph_ids.begin(); + i != glyph_ids.end(); ++i) + { + const char* name = ttfont_CharStrings_getname(font, *i); + stream.printf("/%s ", name); + } + + stream.printf("] def\n"); + } + else + { + stream.putline("/Encoding StandardEncoding def"); + } +} /* end of ttfont_encoding() */ + +/*----------------------------------------------------------- +** Create the optional "FontInfo" sub-dictionary. +-----------------------------------------------------------*/ +void ttfont_FontInfo(TTStreamWriter& stream, struct TTFONT *font) +{ + Fixed ItalicAngle; + + /* We create a sub dictionary named "FontInfo" where we */ + /* store information which though it is not used by the */ + /* interpreter, is useful to some programs which will */ + /* be printing with the font. */ + stream.putline("/FontInfo 10 dict dup begin"); + + /* These names come from the TrueType font's "name" table. */ + stream.printf("/FamilyName (%s) def\n",font->FamilyName); + stream.printf("/FullName (%s) def\n",font->FullName); + + if ( font->Copyright != (char*)NULL || font->Trademark != (char*)NULL ) + { + stream.printf("/Notice (%s", + font->Copyright != (char*)NULL ? font->Copyright : ""); + stream.printf("%s%s) def\n", + font->Trademark != (char*)NULL ? " " : "", + font->Trademark != (char*)NULL ? font->Trademark : ""); + } + + /* This information is not quite correct. */ + stream.printf("/Weight (%s) def\n",font->Style); + + /* Some fonts have this as "version". */ + stream.printf("/Version (%s) def\n",font->Version); + + /* Some information from the "post" table. */ + ItalicAngle = getFixed( font->post_table + 4 ); + stream.printf("/ItalicAngle %d.%d def\n",ItalicAngle.whole,ItalicAngle.fraction); + stream.printf("/isFixedPitch %s def\n", getULONG( font->post_table + 12 ) ? "true" : "false" ); + stream.printf("/UnderlinePosition %d def\n", (int)getFWord( font->post_table + 8 ) ); + stream.printf("/UnderlineThickness %d def\n", (int)getFWord( font->post_table + 10 ) ); + stream.putline("end readonly def"); +} /* end of ttfont_FontInfo() */ + +/*------------------------------------------------------------------- +** sfnts routines +** These routines generate the PostScript "sfnts" array which +** contains one or more strings which contain a reduced version +** of the TrueType font. +** +** A number of functions are required to accomplish this rather +** complicated task. +-------------------------------------------------------------------*/ +int string_len; +int line_len; +bool in_string; + +/* +** This is called once at the start. +*/ +void sfnts_start(TTStreamWriter& stream) +{ + stream.puts("/sfnts[<"); + in_string=true; + string_len=0; + line_len=8; +} /* end of sfnts_start() */ + +/* +** Write a BYTE as a hexadecimal value as part of the sfnts array. +*/ +void sfnts_pputBYTE(TTStreamWriter& stream, BYTE n) +{ + static const char hexdigits[]="0123456789ABCDEF"; + + if (!in_string) + { + stream.put_char('<'); + string_len=0; + line_len++; + in_string=true; + } + + stream.put_char( hexdigits[ n / 16 ] ); + stream.put_char( hexdigits[ n % 16 ] ); + string_len++; + line_len+=2; + + if (line_len > 70) + { + stream.put_char('\n'); + line_len=0; + } + +} /* end of sfnts_pputBYTE() */ + +/* +** Write a USHORT as a hexadecimal value as part of the sfnts array. +*/ +void sfnts_pputUSHORT(TTStreamWriter& stream, USHORT n) +{ + sfnts_pputBYTE(stream, n / 256); + sfnts_pputBYTE(stream, n % 256); +} /* end of sfnts_pputUSHORT() */ + +/* +** Write a ULONG as part of the sfnts array. +*/ +void sfnts_pputULONG(TTStreamWriter& stream, ULONG n) +{ + int x1,x2,x3; + + x1 = n % 256; + n /= 256; + x2 = n % 256; + n /= 256; + x3 = n % 256; + n /= 256; + + sfnts_pputBYTE(stream, n); + sfnts_pputBYTE(stream, x3); + sfnts_pputBYTE(stream, x2); + sfnts_pputBYTE(stream, x1); +} /* end of sfnts_pputULONG() */ + +/* +** This is called whenever it is +** necessary to end a string in the sfnts array. +** +** (The array must be broken into strings which are +** no longer than 64K characters.) +*/ +void sfnts_end_string(TTStreamWriter& stream) +{ + if (in_string) + { + string_len=0; /* fool sfnts_pputBYTE() */ + +#ifdef DEBUG_TRUETYPE_INLINE + puts("\n% dummy byte:\n"); +#endif + + sfnts_pputBYTE(stream, 0); /* extra byte for pre-2013 compatibility */ + stream.put_char('>'); + line_len++; + } + in_string=false; +} /* end of sfnts_end_string() */ + +/* +** This is called at the start of each new table. +** The argement is the length in bytes of the table +** which will follow. If the new table will not fit +** in the current string, a new one is started. +*/ +void sfnts_new_table(TTStreamWriter& stream, ULONG length) +{ + if ( (string_len + length) > 65528 ) + sfnts_end_string(stream); +} /* end of sfnts_new_table() */ + +/* +** We may have to break up the 'glyf' table. That is the reason +** why we provide this special routine to copy it into the sfnts +** array. +*/ +void sfnts_glyf_table(TTStreamWriter& stream, struct TTFONT *font, ULONG oldoffset, ULONG correct_total_length) +{ + ULONG off; + ULONG length; + int c; + ULONG total=0; /* running total of bytes written to table */ + int x; + bool loca_is_local=false; + debug("sfnts_glyf_table(font,%d)", (int)correct_total_length); + + if (font->loca_table == NULL) + { + font->loca_table = GetTable(font,"loca"); + loca_is_local = true; + } + + /* Seek to proper position in the file. */ + fseek( font->file, oldoffset, SEEK_SET ); + + /* Copy the glyphs one by one */ + for (x=0; x < font->numGlyphs; x++) + { + /* Read the glyph offset from the index-to-location table. */ + if (font->indexToLocFormat == 0) + { + off = getUSHORT( font->loca_table + (x * 2) ); + off *= 2; + length = getUSHORT( font->loca_table + ((x+1) * 2) ); + length *= 2; + length -= off; + } + else + { + off = getULONG( font->loca_table + (x * 4) ); + length = getULONG( font->loca_table + ((x+1) * 4) ); + length -= off; + } + debug("glyph length=%d",(int)length); + + /* Start new string if necessary. */ + sfnts_new_table( stream, (int)length ); + + /* + ** Make sure the glyph is padded out to a + ** two byte boundary. + */ + if ( length % 2 ) { + throw TTException("TrueType font contains a 'glyf' table without 2 byte padding"); + } + + /* Copy the bytes of the glyph. */ + while ( length-- ) + { + if ( (c = fgetc(font->file)) == EOF ) { + throw TTException("TrueType font may be corrupt (reason 6)"); + } + + sfnts_pputBYTE(stream, c); + total++; /* add to running total */ + } + + } + + if (loca_is_local) + { + free(font->loca_table); + font->loca_table = NULL; + } + + /* Pad out to full length from table directory */ + while ( total < correct_total_length ) + { + sfnts_pputBYTE(stream, 0); + total++; + } + +} /* end of sfnts_glyf_table() */ + +/* +** Here is the routine which ties it all together. +** +** Create the array called "sfnts" which +** holds the actual TrueType data. +*/ +void ttfont_sfnts(TTStreamWriter& stream, struct TTFONT *font) +{ + static const char *table_names[] = /* The names of all tables */ + { + /* which it is worth while */ + "cvt ", /* to include in a Type 42 */ + "fpgm", /* PostScript font. */ + "glyf", + "head", + "hhea", + "hmtx", + "loca", + "maxp", + "prep" + } ; + + struct /* The location of each of */ + { + ULONG oldoffset; /* the above tables. */ + ULONG newoffset; + ULONG length; + ULONG checksum; + } tables[9]; + + BYTE *ptr; /* A pointer into the origional table directory. */ + ULONG x,y; /* General use loop countes. */ + int c; /* Input character. */ + int diff; + ULONG nextoffset; + int count; /* How many `important' tables did we find? */ + + ptr = font->offset_table + 12; + nextoffset=0; + count=0; + + /* + ** Find the tables we want and store there vital + ** statistics in tables[]. + */ + ULONG num_tables_read = 0; /* Number of tables read from the directory */ + for (x = 0; x < 9; x++) { + do { + if (num_tables_read < font->numTables) { + /* There are still tables to read from ptr */ + diff = strncmp((char*)ptr, table_names[x], 4); + + if (diff > 0) { /* If we are past it. */ + tables[x].length = 0; + diff = 0; + } else if (diff < 0) { /* If we haven't hit it yet. */ + ptr += 16; + num_tables_read++; + } else if (diff == 0) { /* Here it is! */ + tables[x].newoffset = nextoffset; + tables[x].checksum = getULONG( ptr + 4 ); + tables[x].oldoffset = getULONG( ptr + 8 ); + tables[x].length = getULONG( ptr + 12 ); + nextoffset += ( ((tables[x].length + 3) / 4) * 4 ); + count++; + ptr += 16; + num_tables_read++; + } + } else { + /* We've read the whole table directory already */ + /* Some tables couldn't be found */ + tables[x].length = 0; + break; /* Proceed to next tables[x] */ + } + } while (diff != 0); + + } /* end of for loop which passes over the table directory */ + + /* Begin the sfnts array. */ + sfnts_start(stream); + + /* Generate the offset table header */ + /* Start by copying the TrueType version number. */ + ptr = font->offset_table; + for (x=0; x < 4; x++) + { + sfnts_pputBYTE( stream, *(ptr++) ); + } + + /* Now, generate those silly numTables numbers. */ + sfnts_pputUSHORT(stream, count); /* number of tables */ + + int search_range = 1; + int entry_sel = 0; + + while (search_range <= count) { + search_range <<= 1; + entry_sel++; + } + entry_sel = entry_sel > 0 ? entry_sel - 1 : 0; + search_range = (search_range >> 1) * 16; + int range_shift = count * 16 - search_range; + + sfnts_pputUSHORT(stream, search_range); /* searchRange */ + sfnts_pputUSHORT(stream, entry_sel); /* entrySelector */ + sfnts_pputUSHORT(stream, range_shift); /* rangeShift */ + + debug("only %d tables selected",count); + + /* Now, emmit the table directory. */ + for (x=0; x < 9; x++) + { + if ( tables[x].length == 0 ) /* Skip missing tables */ + { + continue; + } + + /* Name */ + sfnts_pputBYTE( stream, table_names[x][0] ); + sfnts_pputBYTE( stream, table_names[x][1] ); + sfnts_pputBYTE( stream, table_names[x][2] ); + sfnts_pputBYTE( stream, table_names[x][3] ); + + /* Checksum */ + sfnts_pputULONG( stream, tables[x].checksum ); + + /* Offset */ + sfnts_pputULONG( stream, tables[x].newoffset + 12 + (count * 16) ); + + /* Length */ + sfnts_pputULONG( stream, tables[x].length ); + } + + /* Now, send the tables */ + for (x=0; x < 9; x++) + { + if ( tables[x].length == 0 ) /* skip tables that aren't there */ + { + continue; + } + debug("emmiting table '%s'",table_names[x]); + + /* 'glyf' table gets special treatment */ + if ( strcmp(table_names[x],"glyf")==0 ) + { + sfnts_glyf_table(stream,font,tables[x].oldoffset,tables[x].length); + } + else /* Other tables may not exceed */ + { + /* 65535 bytes in length. */ + if ( tables[x].length > 65535 ) + { + throw TTException("TrueType font has a table which is too long"); + } + + /* Start new string if necessary. */ + sfnts_new_table(stream, tables[x].length); + + /* Seek to proper position in the file. */ + fseek( font->file, tables[x].oldoffset, SEEK_SET ); + + /* Copy the bytes of the table. */ + for ( y=0; y < tables[x].length; y++ ) + { + if ( (c = fgetc(font->file)) == EOF ) + { + throw TTException("TrueType font may be corrupt (reason 7)"); + } + + sfnts_pputBYTE(stream, c); + } + } + + /* Padd it out to a four byte boundary. */ + y=tables[x].length; + while ( (y % 4) != 0 ) + { + sfnts_pputBYTE(stream, 0); + y++; +#ifdef DEBUG_TRUETYPE_INLINE + puts("\n% pad byte:\n"); +#endif + } + + } /* End of loop for all tables */ + + /* Close the array. */ + sfnts_end_string(stream); + stream.putline("]def"); +} /* end of ttfont_sfnts() */ + +/*-------------------------------------------------------------- +** Create the CharStrings dictionary which will translate +** PostScript character names to TrueType font character +** indexes. +** +** If we are creating a type 3 instead of a type 42 font, +** this array will instead convert PostScript character names +** to executable proceedures. +--------------------------------------------------------------*/ +const char *Apple_CharStrings[]= +{ + ".notdef",".null","nonmarkingreturn","space","exclam","quotedbl","numbersign", + "dollar","percent","ampersand","quotesingle","parenleft","parenright", + "asterisk","plus", "comma","hyphen","period","slash","zero","one","two", + "three","four","five","six","seven","eight","nine","colon","semicolon", + "less","equal","greater","question","at","A","B","C","D","E","F","G","H","I", + "J","K", "L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z", + "bracketleft","backslash","bracketright","asciicircum","underscore","grave", + "a","b","c","d","e","f","g","h","i","j","k", "l","m","n","o","p","q","r","s", + "t","u","v","w","x","y","z","braceleft","bar","braceright","asciitilde", + "Adieresis","Aring","Ccedilla","Eacute","Ntilde","Odieresis","Udieresis", + "aacute","agrave","acircumflex","adieresis","atilde","aring","ccedilla", + "eacute","egrave","ecircumflex","edieresis","iacute","igrave","icircumflex", + "idieresis","ntilde","oacute","ograve","ocircumflex","odieresis","otilde", + "uacute","ugrave","ucircumflex","udieresis","dagger","degree","cent", + "sterling","section","bullet","paragraph","germandbls","registered", + "copyright","trademark","acute","dieresis","notequal","AE","Oslash", + "infinity","plusminus","lessequal","greaterequal","yen","mu","partialdiff", + "summation","product","pi","integral","ordfeminine","ordmasculine","Omega", + "ae","oslash","questiondown","exclamdown","logicalnot","radical","florin", + "approxequal","Delta","guillemotleft","guillemotright","ellipsis", + "nobreakspace","Agrave","Atilde","Otilde","OE","oe","endash","emdash", + "quotedblleft","quotedblright","quoteleft","quoteright","divide","lozenge", + "ydieresis","Ydieresis","fraction","currency","guilsinglleft","guilsinglright", + "fi","fl","daggerdbl","periodcentered","quotesinglbase","quotedblbase", + "perthousand","Acircumflex","Ecircumflex","Aacute","Edieresis","Egrave", + "Iacute","Icircumflex","Idieresis","Igrave","Oacute","Ocircumflex","apple", + "Ograve","Uacute","Ucircumflex","Ugrave","dotlessi","circumflex","tilde", + "macron","breve","dotaccent","ring","cedilla","hungarumlaut","ogonek","caron", + "Lslash","lslash","Scaron","scaron","Zcaron","zcaron","brokenbar","Eth","eth", + "Yacute","yacute","Thorn","thorn","minus","multiply","onesuperior", + "twosuperior","threesuperior","onehalf","onequarter","threequarters","franc", + "Gbreve","gbreve","Idot","Scedilla","scedilla","Cacute","cacute","Ccaron", + "ccaron","dmacron","markingspace","capslock","shift","propeller","enter", + "markingtabrtol","markingtabltor","control","markingdeleteltor", + "markingdeletertol","option","escape","parbreakltor","parbreakrtol", + "newpage","checkmark","linebreakltor","linebreakrtol","markingnobreakspace", + "diamond","appleoutline" +}; + +/* +** This routine is called by the one below. +** It is also called from pprdrv_tt2.c +*/ +const char *ttfont_CharStrings_getname(struct TTFONT *font, int charindex) +{ + int GlyphIndex; + static char temp[80]; + char *ptr; + ULONG len; + + Fixed post_format; + + /* The 'post' table format number. */ + post_format = getFixed( font->post_table ); + + if ( post_format.whole != 2 || post_format.fraction != 0 ) + { + /* We don't have a glyph name table, so generate a name. + This generated name must match exactly the name that is + generated by FT2Font in get_glyph_name */ + PyOS_snprintf(temp, 80, "uni%08x", charindex); + return temp; + } + + GlyphIndex = (int)getUSHORT( font->post_table + 34 + (charindex * 2) ); + + if ( GlyphIndex <= 257 ) /* If a standard Apple name, */ + { + return Apple_CharStrings[GlyphIndex]; + } + else /* Otherwise, use one */ + { + /* of the pascal strings. */ + GlyphIndex -= 258; + + /* Set pointer to start of Pascal strings. */ + ptr = (char*)(font->post_table + 34 + (font->numGlyphs * 2)); + + len = (ULONG)*(ptr++); /* Step thru the strings */ + while (GlyphIndex--) /* until we get to the one */ + { + /* that we want. */ + ptr += len; + len = (ULONG)*(ptr++); + } + + if ( len >= sizeof(temp) ) + { + throw TTException("TrueType font file contains a very long PostScript name"); + } + + strncpy(temp,ptr,len); /* Copy the pascal string into */ + temp[len]='\0'; /* a buffer and make it ASCIIz. */ + + return temp; + } +} /* end of ttfont_CharStrings_getname() */ + +/* +** This is the central routine of this section. +*/ +void ttfont_CharStrings(TTStreamWriter& stream, struct TTFONT *font, std::vector<int>& glyph_ids) +{ + Fixed post_format; + + /* The 'post' table format number. */ + post_format = getFixed( font->post_table ); + + /* Emmit the start of the PostScript code to define the dictionary. */ + stream.printf("/CharStrings %d dict dup begin\n", glyph_ids.size()+1); + /* Section 5.8.2 table 5.7 of the PS Language Ref says a CharStrings dictionary must contain an entry for .notdef */ + stream.printf("/.notdef 0 def\n"); + + /* Emmit one key-value pair for each glyph. */ + for (std::vector<int>::const_iterator i = glyph_ids.begin(); + i != glyph_ids.end(); ++i) + { + if ((font->target_type == PS_TYPE_42 || + font->target_type == PS_TYPE_42_3_HYBRID) + && *i < 256) /* type 42 */ + { + stream.printf("/%s %d def\n",ttfont_CharStrings_getname(font, *i), *i); + } + else /* type 3 */ + { + stream.printf("/%s{",ttfont_CharStrings_getname(font, *i)); + + tt_type3_charproc(stream, font, *i); + + stream.putline("}_d"); /* "} bind def" */ + } + } + + stream.putline("end readonly def"); +} /* end of ttfont_CharStrings() */ + +/*---------------------------------------------------------------- +** Emmit the code to finish up the dictionary and turn +** it into a font. +----------------------------------------------------------------*/ +void ttfont_trailer(TTStreamWriter& stream, struct TTFONT *font) +{ + /* If we are generating a type 3 font, we need to provide */ + /* a BuildGlyph and BuildChar proceedures. */ + if (font->target_type == PS_TYPE_3 || + font->target_type == PS_TYPE_42_3_HYBRID) + { + stream.put_char('\n'); + + stream.putline("/BuildGlyph"); + stream.putline(" {exch begin"); /* start font dictionary */ + stream.putline(" CharStrings exch"); + stream.putline(" 2 copy known not{pop /.notdef}if"); + stream.putline(" true 3 1 roll get exec"); + stream.putline(" end}_d"); + + stream.put_char('\n'); + + /* This proceedure is for compatibility with */ + /* level 1 interpreters. */ + stream.putline("/BuildChar {"); + stream.putline(" 1 index /Encoding get exch get"); + stream.putline(" 1 index /BuildGlyph get exec"); + stream.putline("}_d"); + + stream.put_char('\n'); + } + + /* If we are generating a type 42 font, we need to check to see */ + /* if this PostScript interpreter understands type 42 fonts. If */ + /* it doesn't, we will hope that the Apple TrueType rasterizer */ + /* has been loaded and we will adjust the font accordingly. */ + /* I found out how to do this by examining a TrueType font */ + /* generated by a Macintosh. That is where the TrueType interpreter */ + /* setup instructions and part of BuildGlyph came from. */ + if (font->target_type == PS_TYPE_42 || + font->target_type == PS_TYPE_42_3_HYBRID) + { + stream.put_char('\n'); + + /* If we have no "resourcestatus" command, or FontType 42 */ + /* is unknown, leave "true" on the stack. */ + stream.putline("systemdict/resourcestatus known"); + stream.putline(" {42 /FontType resourcestatus"); + stream.putline(" {pop pop false}{true}ifelse}"); + stream.putline(" {true}ifelse"); + + /* If true, execute code to produce an error message if */ + /* we can't find Apple's TrueDict in VM. */ + stream.putline("{/TrueDict where{pop}{(%%[ Error: no TrueType rasterizer ]%%)= flush}ifelse"); + + /* Since we are expected to use Apple's TrueDict TrueType */ + /* reasterizer, change the font type to 3. */ + stream.putline("/FontType 3 def"); + + /* Define a string to hold the state of the Apple */ + /* TrueType interpreter. */ + stream.putline(" /TrueState 271 string def"); + + /* It looks like we get information about the resolution */ + /* of the printer and store it in the TrueState string. */ + stream.putline(" TrueDict begin sfnts save"); + stream.putline(" 72 0 matrix defaultmatrix dtransform dup"); + stream.putline(" mul exch dup mul add sqrt cvi 0 72 matrix"); + stream.putline(" defaultmatrix dtransform dup mul exch dup"); + stream.putline(" mul add sqrt cvi 3 -1 roll restore"); + stream.putline(" TrueState initer end"); + + /* This BuildGlyph procedure will look the name up in the */ + /* CharStrings array, and then check to see if what it gets */ + /* is a procedure. If it is, it executes it, otherwise, it */ + /* lets the TrueType rasterizer loose on it. */ + + /* When this proceedure is executed the stack contains */ + /* the font dictionary and the character name. We */ + /* exchange arguments and move the dictionary to the */ + /* dictionary stack. */ + stream.putline(" /BuildGlyph{exch begin"); + /* stack: charname */ + + /* Put two copies of CharStrings on the stack and consume */ + /* one testing to see if the charname is defined in it, */ + /* leave the answer on the stack. */ + stream.putline(" CharStrings dup 2 index known"); + /* stack: charname CharStrings bool */ + + /* Exchange the CharStrings dictionary and the charname, */ + /* but if the answer was false, replace the character name */ + /* with ".notdef". */ + stream.putline(" {exch}{exch pop /.notdef}ifelse"); + /* stack: CharStrings charname */ + + /* Get the value from the CharStrings dictionary and see */ + /* if it is executable. */ + stream.putline(" get dup xcheck"); + /* stack: CharStrings_entry */ + + /* If is a proceedure. Execute according to RBIIp 277-278. */ + stream.putline(" {currentdict systemdict begin begin exec end end}"); + + /* Is a TrueType character index, let the rasterizer at it. */ + stream.putline(" {TrueDict begin /bander load cvlit exch TrueState render end}"); + + stream.putline(" ifelse"); + + /* Pop the font's dictionary off the stack. */ + stream.putline(" end}bind def"); + + /* This is the level 1 compatibility BuildChar procedure. */ + /* See RBIIp 281. */ + stream.putline(" /BuildChar{"); + stream.putline(" 1 index /Encoding get exch get"); + stream.putline(" 1 index /BuildGlyph get exec"); + stream.putline(" }bind def"); + + /* Here we close the condition which is true */ + /* if the printer has no built-in TrueType */ + /* rasterizer. */ + stream.putline("}if"); + stream.put_char('\n'); + } /* end of if Type 42 not understood. */ + + stream.putline("FontName currentdict end definefont pop"); + /* stream.putline("%%EOF"); */ +} /* end of ttfont_trailer() */ + +/*------------------------------------------------------------------ +** This is the externally callable routine which inserts the font. +------------------------------------------------------------------*/ + +void read_font(const char *filename, font_type_enum target_type, std::vector<int>& glyph_ids, TTFONT& font) +{ + BYTE *ptr; + + /* Decide what type of PostScript font we will be generating. */ + font.target_type = target_type; + + if (font.target_type == PS_TYPE_42) + { + bool has_low = false; + bool has_high = false; + + for (std::vector<int>::const_iterator i = glyph_ids.begin(); + i != glyph_ids.end(); ++i) + { + if (*i > 255) + { + has_high = true; + if (has_low) break; + } + else + { + has_low = true; + if (has_high) break; + } + } + + if (has_high && has_low) + { + font.target_type = PS_TYPE_42_3_HYBRID; + } + else if (has_high && !has_low) + { + font.target_type = PS_TYPE_3; + } + } + + /* Save the file name for error messages. */ + font.filename=filename; + + /* Open the font file */ + if ( (font.file = fopen(filename,"rb")) == (FILE*)NULL ) + { + throw TTException("Failed to open TrueType font"); + } + + /* Allocate space for the unvarying part of the offset table. */ + assert(font.offset_table == NULL); + font.offset_table = (BYTE*)calloc( 12, sizeof(BYTE) ); + + /* Read the first part of the offset table. */ + if ( fread( font.offset_table, sizeof(BYTE), 12, font.file ) != 12 ) + { + throw TTException("TrueType font may be corrupt (reason 1)"); + } + + /* Determine how many directory entries there are. */ + font.numTables = getUSHORT( font.offset_table + 4 ); + debug("numTables=%d",(int)font.numTables); + + /* Expand the memory block to hold the whole thing. */ + font.offset_table = (BYTE*)realloc( font.offset_table, sizeof(BYTE) * (12 + font.numTables * 16) ); + + /* Read the rest of the table directory. */ + if ( fread( font.offset_table + 12, sizeof(BYTE), (font.numTables*16), font.file ) != (font.numTables*16) ) + { + throw TTException("TrueType font may be corrupt (reason 2)"); + } + + /* Extract information from the "Offset" table. */ + font.TTVersion = getFixed( font.offset_table ); + + /* Load the "head" table and extract information from it. */ + ptr = GetTable(&font, "head"); + try + { + font.MfrRevision = getFixed( ptr + 4 ); /* font revision number */ + font.unitsPerEm = getUSHORT( ptr + 18 ); + font.HUPM = font.unitsPerEm / 2; + debug("unitsPerEm=%d",(int)font.unitsPerEm); + font.llx = topost2( getFWord( ptr + 36 ) ); /* bounding box info */ + font.lly = topost2( getFWord( ptr + 38 ) ); + font.urx = topost2( getFWord( ptr + 40 ) ); + font.ury = topost2( getFWord( ptr + 42 ) ); + font.indexToLocFormat = getSHORT( ptr + 50 ); /* size of 'loca' data */ + if (font.indexToLocFormat != 0 && font.indexToLocFormat != 1) + { + throw TTException("TrueType font is unusable because indexToLocFormat != 0"); + } + if ( getSHORT(ptr+52) != 0 ) + { + throw TTException("TrueType font is unusable because glyphDataFormat != 0"); + } + } + catch (TTException& ) + { + free(ptr); + throw; + } + free(ptr); + + /* Load information from the "name" table. */ + Read_name(&font); + + /* We need to have the PostScript table around. */ + assert(font.post_table == NULL); + font.post_table = GetTable(&font, "post"); + font.numGlyphs = getUSHORT( font.post_table + 32 ); + + /* If we are generating a Type 3 font, we will need to */ + /* have the 'loca' and 'glyf' tables arround while */ + /* we are generating the CharStrings. */ + if (font.target_type == PS_TYPE_3 || font.target_type == PS_TYPE_42_3_HYBRID) + { + BYTE *ptr; /* We need only one value */ + ptr = GetTable(&font, "hhea"); + font.numberOfHMetrics = getUSHORT(ptr + 34); + free(ptr); + + assert(font.loca_table == NULL); + font.loca_table = GetTable(&font,"loca"); + assert(font.glyf_table == NULL); + font.glyf_table = GetTable(&font,"glyf"); + assert(font.hmtx_table == NULL); + font.hmtx_table = GetTable(&font,"hmtx"); + } + + if (glyph_ids.size() == 0) + { + glyph_ids.clear(); + glyph_ids.reserve(font.numGlyphs); + for (int x = 0; x < font.numGlyphs; ++x) + { + glyph_ids.push_back(x); + } + } + else if (font.target_type == PS_TYPE_3 || + font.target_type == PS_TYPE_42_3_HYBRID) + { + ttfont_add_glyph_dependencies(&font, glyph_ids); + } + +} /* end of insert_ttfont() */ + +void insert_ttfont(const char *filename, TTStreamWriter& stream, + font_type_enum target_type, std::vector<int>& glyph_ids) +{ + struct TTFONT font; + + read_font(filename, target_type, glyph_ids, font); + + /* Write the header for the PostScript font. */ + ttfont_header(stream, &font); + + /* Define the encoding. */ + ttfont_encoding(stream, &font, glyph_ids, target_type); + + /* Insert FontInfo dictionary. */ + ttfont_FontInfo(stream, &font); + + /* If we are generating a type 42 font, */ + /* emmit the sfnts array. */ + if (font.target_type == PS_TYPE_42 || + font.target_type == PS_TYPE_42_3_HYBRID) + { + ttfont_sfnts(stream, &font); + } + + /* Emmit the CharStrings array. */ + ttfont_CharStrings(stream, &font, glyph_ids); + + /* Send the font trailer. */ + ttfont_trailer(stream, &font); + +} /* end of insert_ttfont() */ + +TTFONT::TTFONT() : + file(NULL), + PostName(NULL), + FullName(NULL), + FamilyName(NULL), + Style(NULL), + Copyright(NULL), + Version(NULL), + Trademark(NULL), + offset_table(NULL), + post_table(NULL), + loca_table(NULL), + glyf_table(NULL), + hmtx_table(NULL) +{ + +} + +TTFONT::~TTFONT() +{ + if (file) + { + fclose(file); + } + free(PostName); + free(FullName); + free(FamilyName); + free(Style); + free(Copyright); + free(Version); + free(Trademark); + free(offset_table); + free(post_table); + free(loca_table); + free(glyf_table); + free(hmtx_table); +} + +/* end of file */ diff --git a/contrib/python/matplotlib/py3/extern/ttconv/pprdrv_tt2.cpp b/contrib/python/matplotlib/py3/extern/ttconv/pprdrv_tt2.cpp new file mode 100644 index 00000000000..ec2298c8c42 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/ttconv/pprdrv_tt2.cpp @@ -0,0 +1,693 @@ +/* -*- mode: c++; c-basic-offset: 4 -*- */ + +/* + * Modified for use within matplotlib + * 5 July 2007 + * Michael Droettboom + */ + +/* +** ~ppr/src/pprdrv/pprdrv_tt2.c +** Copyright 1995, Trinity College Computing Center. +** Written by David Chappell. +** +** Permission to use, copy, modify, and distribute this software and its +** documentation for any purpose and without fee is hereby granted, provided +** that the above copyright notice appear in all copies and that both that +** copyright notice and this permission notice appear in supporting +** documentation. This software is provided "as is" without express or +** implied warranty. +** +** TrueType font support. These functions allow PPR to generate +** PostScript fonts from Microsoft compatible TrueType font files. +** +** The functions in this file do most of the work to convert a +** TrueType font to a type 3 PostScript font. +** +** Most of the material in this file is derived from a program called +** "ttf2ps" which L. S. Ng posted to the usenet news group +** "comp.sources.postscript". The author did not provide a copyright +** notice or indicate any restrictions on use. +** +** Last revised 11 July 1995. +*/ + +#include <cstdlib> +#include <cmath> +#include <cstring> +#include <memory> +#include "pprdrv.h" +#include "truetype.h" +#include <algorithm> +#include <stack> +#include <list> + +class GlyphToType3 +{ +private: + GlyphToType3& operator=(const GlyphToType3& other); + GlyphToType3(const GlyphToType3& other); + + /* The PostScript bounding box. */ + int llx,lly,urx,ury; + int advance_width; + + /* Variables to hold the character data. */ + int *epts_ctr; /* array of contour endpoints */ + int num_pts, num_ctr; /* number of points, number of coutours */ + FWord *xcoor, *ycoor; /* arrays of x and y coordinates */ + BYTE *tt_flags; /* array of TrueType flags */ + + int stack_depth; /* A book-keeping variable for keeping track of the depth of the PS stack */ + + void load_char(TTFONT* font, BYTE *glyph); + void stack(TTStreamWriter& stream, int new_elem); + void stack_end(TTStreamWriter& stream); + void PSConvert(TTStreamWriter& stream); + void PSCurveto(TTStreamWriter& stream, + FWord x0, FWord y0, + FWord x1, FWord y1, + FWord x2, FWord y2); + void PSMoveto(TTStreamWriter& stream, int x, int y); + void PSLineto(TTStreamWriter& stream, int x, int y); + void do_composite(TTStreamWriter& stream, struct TTFONT *font, BYTE *glyph); + +public: + GlyphToType3(TTStreamWriter& stream, struct TTFONT *font, int charindex, bool embedded = false); + ~GlyphToType3(); +}; + +// Each point on a TrueType contour is either on the path or off it (a +// control point); here's a simple representation for building such +// contours. Added by Jouni Seppänen 2012-05-27. +enum Flag { ON_PATH, OFF_PATH }; +struct FlaggedPoint +{ + enum Flag flag; + FWord x; + FWord y; + FlaggedPoint(Flag flag_, FWord x_, FWord y_): flag(flag_), x(x_), y(y_) {}; +}; + +/* +** This routine is used to break the character +** procedure up into a number of smaller +** procedures. This is necessary so as not to +** overflow the stack on certain level 1 interpreters. +** +** Prepare to push another item onto the stack, +** starting a new proceedure if necessary. +** +** Not all the stack depth calculations in this routine +** are perfectly accurate, but they do the job. +*/ +void GlyphToType3::stack(TTStreamWriter& stream, int new_elem) +{ + if ( num_pts > 25 ) /* Only do something of we will have a log of points. */ + { + if (stack_depth == 0) + { + stream.put_char('{'); + stack_depth=1; + } + + stack_depth += new_elem; /* Account for what we propose to add */ + + if (stack_depth > 100) + { + stream.puts("}_e{"); + stack_depth = 3 + new_elem; /* A rough estimate */ + } + } +} /* end of stack() */ + +void GlyphToType3::stack_end(TTStreamWriter& stream) /* called at end */ +{ + if ( stack_depth ) + { + stream.puts("}_e"); + stack_depth=0; + } +} /* end of stack_end() */ + +/* +** We call this routine to emmit the PostScript code +** for the character we have loaded with load_char(). +*/ +void GlyphToType3::PSConvert(TTStreamWriter& stream) +{ + int j, k; + + /* Step thru the contours. + * j = index to xcoor, ycoor, tt_flags (point data) + * k = index to epts_ctr (which points belong to the same contour) */ + for(j = k = 0; k < num_ctr; k++) + { + // A TrueType contour consists of on-path and off-path points. + // Two consecutive on-path points are to be joined with a + // line; off-path points between on-path points indicate a + // quadratic spline, where the off-path point is the control + // point. Two consecutive off-path points have an implicit + // on-path point midway between them. + std::list<FlaggedPoint> points; + + // Represent flags and x/y coordinates as a C++ list + for (; j <= epts_ctr[k]; j++) + { + if (!(tt_flags[j] & 1)) { + points.push_back(FlaggedPoint(OFF_PATH, xcoor[j], ycoor[j])); + } else { + points.push_back(FlaggedPoint(ON_PATH, xcoor[j], ycoor[j])); + } + } + + if (points.size() == 0) { + // Don't try to access the last element of an empty list + continue; + } + + // For any two consecutive off-path points, insert the implied + // on-path point. + FlaggedPoint prev = points.back(); + for (std::list<FlaggedPoint>::iterator it = points.begin(); + it != points.end(); + it++) + { + if (prev.flag == OFF_PATH && it->flag == OFF_PATH) + { + points.insert(it, + FlaggedPoint(ON_PATH, + (prev.x + it->x) / 2, + (prev.y + it->y) / 2)); + } + prev = *it; + } + // Handle the wrap-around: insert a point either at the beginning + // or at the end that has the same coordinates as the opposite point. + // This also ensures that the initial point is ON_PATH. + if (points.front().flag == OFF_PATH) + { + assert(points.back().flag == ON_PATH); + points.insert(points.begin(), points.back()); + } + else + { + assert(points.front().flag == ON_PATH); + points.push_back(points.front()); + } + + // The first point + stack(stream, 3); + PSMoveto(stream, points.front().x, points.front().y); + + // Step through the remaining points + std::list<FlaggedPoint>::const_iterator it = points.begin(); + for (it++; it != points.end(); /* incremented inside */) + { + const FlaggedPoint& point = *it; + if (point.flag == ON_PATH) + { + stack(stream, 3); + PSLineto(stream, point.x, point.y); + it++; + } else { + std::list<FlaggedPoint>::const_iterator prev = it, next = it; + prev--; + next++; + assert(prev->flag == ON_PATH); + assert(next->flag == ON_PATH); + stack(stream, 7); + PSCurveto(stream, + prev->x, prev->y, + point.x, point.y, + next->x, next->y); + it++; + it++; + } + } + } + + /* Now, we can fill the whole thing. */ + stack(stream, 1); + stream.puts("_cl"); +} /* end of PSConvert() */ + +void GlyphToType3::PSMoveto(TTStreamWriter& stream, int x, int y) +{ + stream.printf("%d %d _m\n", x, y); +} + +void GlyphToType3::PSLineto(TTStreamWriter& stream, int x, int y) +{ + stream.printf("%d %d _l\n", x, y); +} + +/* +** Emit a PostScript "curveto" command, assuming the current point +** is (x0, y0), the control point of a quadratic spline is (x1, y1), +** and the endpoint is (x2, y2). Note that this requires a conversion, +** since PostScript splines are cubic. +*/ +void GlyphToType3::PSCurveto(TTStreamWriter& stream, + FWord x0, FWord y0, + FWord x1, FWord y1, + FWord x2, FWord y2) +{ + double sx[3], sy[3], cx[3], cy[3]; + + sx[0] = x0; + sy[0] = y0; + sx[1] = x1; + sy[1] = y1; + sx[2] = x2; + sy[2] = y2; + cx[0] = (2*sx[1]+sx[0])/3; + cy[0] = (2*sy[1]+sy[0])/3; + cx[1] = (sx[2]+2*sx[1])/3; + cy[1] = (sy[2]+2*sy[1])/3; + cx[2] = sx[2]; + cy[2] = sy[2]; + stream.printf("%d %d %d %d %d %d _c\n", + (int)cx[0], (int)cy[0], (int)cx[1], (int)cy[1], + (int)cx[2], (int)cy[2]); +} + +/* +** Deallocate the structures which stored +** the data for the last simple glyph. +*/ +GlyphToType3::~GlyphToType3() +{ + free(tt_flags); /* The flags array */ + free(xcoor); /* The X coordinates */ + free(ycoor); /* The Y coordinates */ + free(epts_ctr); /* The array of contour endpoints */ +} + +/* +** Load the simple glyph data pointed to by glyph. +** The pointer "glyph" should point 10 bytes into +** the glyph data. +*/ +void GlyphToType3::load_char(TTFONT* font, BYTE *glyph) +{ + int x; + BYTE c, ct; + + /* Read the contour endpoints list. */ + epts_ctr = (int *)calloc(num_ctr,sizeof(int)); + for (x = 0; x < num_ctr; x++) + { + epts_ctr[x] = getUSHORT(glyph); + glyph += 2; + } + + /* From the endpoint of the last contour, we can */ + /* determine the number of points. */ + num_pts = epts_ctr[num_ctr-1]+1; +#ifdef DEBUG_TRUETYPE + debug("num_pts=%d",num_pts); + stream.printf("%% num_pts=%d\n",num_pts); +#endif + + /* Skip the instructions. */ + x = getUSHORT(glyph); + glyph += 2; + glyph += x; + + /* Allocate space to hold the data. */ + tt_flags = (BYTE *)calloc(num_pts,sizeof(BYTE)); + xcoor = (FWord *)calloc(num_pts,sizeof(FWord)); + ycoor = (FWord *)calloc(num_pts,sizeof(FWord)); + + /* Read the flags array, uncompressing it as we go. */ + /* There is danger of overflow here. */ + for (x = 0; x < num_pts; ) + { + tt_flags[x++] = c = *(glyph++); + + if (c&8) /* If next byte is repeat count, */ + { + ct = *(glyph++); + + if ( (x + ct) > num_pts ) + { + throw TTException("Error in TT flags"); + } + + while (ct--) + { + tt_flags[x++] = c; + } + } + } + + /* Read the x coordinates */ + for (x = 0; x < num_pts; x++) + { + if (tt_flags[x] & 2) /* one byte value with */ + { + /* external sign */ + c = *(glyph++); + xcoor[x] = (tt_flags[x] & 0x10) ? c : (-1 * (int)c); + } + else if (tt_flags[x] & 0x10) /* repeat last */ + { + xcoor[x] = 0; + } + else /* two byte signed value */ + { + xcoor[x] = getFWord(glyph); + glyph+=2; + } + } + + /* Read the y coordinates */ + for (x = 0; x < num_pts; x++) + { + if (tt_flags[x] & 4) /* one byte value with */ + { + /* external sign */ + c = *(glyph++); + ycoor[x] = (tt_flags[x] & 0x20) ? c : (-1 * (int)c); + } + else if (tt_flags[x] & 0x20) /* repeat last value */ + { + ycoor[x] = 0; + } + else /* two byte signed value */ + { + ycoor[x] = getUSHORT(glyph); + glyph+=2; + } + } + + /* Convert delta values to absolute values. */ + for (x = 1; x < num_pts; x++) + { + xcoor[x] += xcoor[x-1]; + ycoor[x] += ycoor[x-1]; + } + + for (x=0; x < num_pts; x++) + { + xcoor[x] = topost(xcoor[x]); + ycoor[x] = topost(ycoor[x]); + } + +} /* end of load_char() */ + +/* +** Emmit PostScript code for a composite character. +*/ +void GlyphToType3::do_composite(TTStreamWriter& stream, struct TTFONT *font, BYTE *glyph) +{ + USHORT flags; + USHORT glyphIndex; + int arg1; + int arg2; + + /* Once around this loop for each component. */ + do + { + flags = getUSHORT(glyph); /* read the flags word */ + glyph += 2; + + glyphIndex = getUSHORT(glyph); /* read the glyphindex word */ + glyph += 2; + + if (flags & ARG_1_AND_2_ARE_WORDS) + { + /* The tt spec. seems to say these are signed. */ + arg1 = getSHORT(glyph); + glyph += 2; + arg2 = getSHORT(glyph); + glyph += 2; + } + else /* The tt spec. does not clearly indicate */ + { + /* whether these values are signed or not. */ + arg1 = *(signed char *)(glyph++); + arg2 = *(signed char *)(glyph++); + } + + if (flags & WE_HAVE_A_SCALE) + { + glyph += 2; + } + else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) + { + glyph += 4; + } + else if (flags & WE_HAVE_A_TWO_BY_TWO) + { + glyph += 8; + } + else + { + } + + /* Debugging */ +#ifdef DEBUG_TRUETYPE + stream.printf("%% flags=%d, arg1=%d, arg2=%d\n", + (int)flags,arg1,arg2); +#endif + + /* If we have an (X,Y) shift and it is non-zero, */ + /* translate the coordinate system. */ + if ( flags & ARGS_ARE_XY_VALUES ) + { + if ( arg1 != 0 || arg2 != 0 ) + stream.printf("gsave %d %d translate\n", topost(arg1), topost(arg2) ); + } + else + { + stream.printf("%% unimplemented shift, arg1=%d, arg2=%d\n",arg1,arg2); + } + + /* Invoke the CharStrings procedure to print the component. */ + stream.printf("false CharStrings /%s get exec\n", + ttfont_CharStrings_getname(font, glyphIndex)); + + /* If we translated the coordinate system, */ + /* put it back the way it was. */ + if ( flags & ARGS_ARE_XY_VALUES && (arg1 != 0 || arg2 != 0) ) + { + stream.puts("grestore "); + } + + } + while (flags & MORE_COMPONENTS); + +} /* end of do_composite() */ + +/* +** Return a pointer to a specific glyph's data. +*/ +BYTE *find_glyph_data(struct TTFONT *font, int charindex) +{ + ULONG off; + ULONG length; + + /* Read the glyph offset from the index to location table. */ + if (font->indexToLocFormat == 0) + { + off = getUSHORT( font->loca_table + (charindex * 2) ); + off *= 2; + length = getUSHORT( font->loca_table + ((charindex+1) * 2) ); + length *= 2; + length -= off; + } + else + { + off = getULONG( font->loca_table + (charindex * 4) ); + length = getULONG( font->loca_table + ((charindex+1) * 4) ); + length -= off; + } + + if (length > 0) + { + return font->glyf_table + off; + } + else + { + return (BYTE*)NULL; + } + +} /* end of find_glyph_data() */ + +GlyphToType3::GlyphToType3(TTStreamWriter& stream, struct TTFONT *font, int charindex, bool embedded /* = false */) +{ + BYTE *glyph; + + tt_flags = NULL; + xcoor = NULL; + ycoor = NULL; + epts_ctr = NULL; + stack_depth = 0; + + /* Get a pointer to the data. */ + glyph = find_glyph_data( font, charindex ); + + /* If the character is blank, it has no bounding box, */ + /* otherwise read the bounding box. */ + if ( glyph == (BYTE*)NULL ) + { + llx=lly=urx=ury=0; /* A blank char has an all zero BoundingBox */ + num_ctr=0; /* Set this for later if()s */ + } + else + { + /* Read the number of contours. */ + num_ctr = getSHORT(glyph); + + /* Read PostScript bounding box. */ + llx = getFWord(glyph + 2); + lly = getFWord(glyph + 4); + urx = getFWord(glyph + 6); + ury = getFWord(glyph + 8); + + /* Advance the pointer. */ + glyph += 10; + } + + /* If it is a simple character, load its data. */ + if (num_ctr > 0) + { + load_char(font, glyph); + } + else + { + num_pts=0; + } + + /* Consult the horizontal metrics table to determine */ + /* the character width. */ + if ( charindex < font->numberOfHMetrics ) + { + advance_width = getuFWord( font->hmtx_table + (charindex * 4) ); + } + else + { + advance_width = getuFWord( font->hmtx_table + ((font->numberOfHMetrics-1) * 4) ); + } + + /* Execute setcachedevice in order to inform the font machinery */ + /* of the character bounding box and advance width. */ + stack(stream, 7); + if (font->target_type == PS_TYPE_42_3_HYBRID) + { + stream.printf("pop gsave .001 .001 scale %d 0 %d %d %d %d setcachedevice\n", + topost(advance_width), + topost(llx), topost(lly), topost(urx), topost(ury) ); + } + else + { + stream.printf("%d 0 %d %d %d %d _sc\n", + topost(advance_width), + topost(llx), topost(lly), topost(urx), topost(ury) ); + } + + /* If it is a simple glyph, convert it, */ + /* otherwise, close the stack business. */ + if ( num_ctr > 0 ) /* simple */ + { + PSConvert(stream); + } + else if ( num_ctr < 0 ) /* composite */ + { + do_composite(stream, font, glyph); + } + + if (font->target_type == PS_TYPE_42_3_HYBRID) + { + stream.printf("\ngrestore\n"); + } + + stack_end(stream); +} + +/* +** This is the routine which is called from pprdrv_tt.c. +*/ +void tt_type3_charproc(TTStreamWriter& stream, struct TTFONT *font, int charindex) +{ + GlyphToType3 glyph(stream, font, charindex); +} /* end of tt_type3_charproc() */ + +/* +** Some of the given glyph ids may refer to composite glyphs. +** This function adds all of the dependencies of those composite +** glyphs to the glyph id vector. Michael Droettboom [06-07-07] +*/ +void ttfont_add_glyph_dependencies(struct TTFONT *font, std::vector<int>& glyph_ids) +{ + std::sort(glyph_ids.begin(), glyph_ids.end()); + + std::stack<int> glyph_stack; + for (std::vector<int>::iterator i = glyph_ids.begin(); + i != glyph_ids.end(); ++i) + { + glyph_stack.push(*i); + } + + while (glyph_stack.size()) + { + int gind = glyph_stack.top(); + glyph_stack.pop(); + + BYTE* glyph = find_glyph_data( font, gind ); + if (glyph != (BYTE*)NULL) + { + + int num_ctr = getSHORT(glyph); + if (num_ctr <= 0) // This is a composite glyph + { + + glyph += 10; + USHORT flags = 0; + + do + { + flags = getUSHORT(glyph); + glyph += 2; + gind = (int)getUSHORT(glyph); + glyph += 2; + + std::vector<int>::iterator insertion = + std::lower_bound(glyph_ids.begin(), glyph_ids.end(), gind); + if (insertion == glyph_ids.end() || *insertion != gind) + { + glyph_ids.insert(insertion, gind); + glyph_stack.push(gind); + } + + if (flags & ARG_1_AND_2_ARE_WORDS) + { + glyph += 4; + } + else + { + glyph += 2; + } + + if (flags & WE_HAVE_A_SCALE) + { + glyph += 2; + } + else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) + { + glyph += 4; + } + else if (flags & WE_HAVE_A_TWO_BY_TWO) + { + glyph += 8; + } + } + while (flags & MORE_COMPONENTS); + } + } + } +} + +/* end of file */ diff --git a/contrib/python/matplotlib/py3/extern/ttconv/truetype.h b/contrib/python/matplotlib/py3/extern/ttconv/truetype.h new file mode 100644 index 00000000000..86be14fe370 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/ttconv/truetype.h @@ -0,0 +1,129 @@ +/* -*- mode: c; c-basic-offset: 4 -*- */ + +/* + * Modified for use within matplotlib + * 5 July 2007 + * Michael Droettboom + */ + +#include <stdio.h> + +/* +** ~ppr/src/include/typetype.h +** +** Permission to use, copy, modify, and distribute this software and its +** documentation for any purpose and without fee is hereby granted, provided +** that the above copyright notice appear in all copies and that both that +** copyright notice and this permission notice appear in supporting +** documentation. This software is provided "as is" without express or +** implied warranty. +** +** This include file is shared by the source files +** "pprdrv/pprdrv_tt.c" and "pprdrv/pprdrv_tt2.c". +** +** Last modified 19 April 1995. +*/ + +/* Types used in TrueType font files. */ +#define BYTE unsigned char +#define USHORT unsigned short int +#define SHORT short signed int +#define ULONG unsigned int +#define FIXED long signed int +#define FWord short signed int +#define uFWord short unsigned int + +/* This structure stores a 16.16 bit fixed */ +/* point number. */ +typedef struct + { + short int whole; + unsigned short int fraction; + } Fixed; + +/* This structure tells what we have found out about */ +/* the current font. */ +struct TTFONT + { + // A quick-and-dirty way to create a minimum level of exception safety + // Added by Michael Droettboom + TTFONT(); + ~TTFONT(); + + const char *filename; /* Name of TT file */ + FILE *file; /* the open TT file */ + font_type_enum target_type; /* 42 or 3 for PS, or -3 for PDF */ + + ULONG numTables; /* number of tables present */ + char *PostName; /* Font's PostScript name */ + char *FullName; /* Font's full name */ + char *FamilyName; /* Font's family name */ + char *Style; /* Font's style string */ + char *Copyright; /* Font's copyright string */ + char *Version; /* Font's version string */ + char *Trademark; /* Font's trademark string */ + int llx,lly,urx,ury; /* bounding box */ + + Fixed TTVersion; /* Truetype version number from offset table */ + Fixed MfrRevision; /* Revision number of this font */ + + BYTE *offset_table; /* Offset table in memory */ + BYTE *post_table; /* 'post' table in memory */ + + BYTE *loca_table; /* 'loca' table in memory */ + BYTE *glyf_table; /* 'glyf' table in memory */ + BYTE *hmtx_table; /* 'hmtx' table in memory */ + + USHORT numberOfHMetrics; + int unitsPerEm; /* unitsPerEm converted to int */ + int HUPM; /* half of above */ + + int numGlyphs; /* from 'post' table */ + + int indexToLocFormat; /* short or long offsets */ +}; + +ULONG getULONG(BYTE *p); +USHORT getUSHORT(BYTE *p); +Fixed getFixed(BYTE *p); + +/* +** Get an funits word. +** since it is 16 bits long, we can +** use getUSHORT() to do the real work. +*/ +#define getFWord(x) (FWord)getUSHORT(x) +#define getuFWord(x) (uFWord)getUSHORT(x) + +/* +** We can get a SHORT by making USHORT signed. +*/ +#define getSHORT(x) (SHORT)getUSHORT(x) + +/* This is the one routine in pprdrv_tt.c that is */ +/* called from pprdrv_tt.c. */ +const char *ttfont_CharStrings_getname(struct TTFONT *font, int charindex); + +void tt_type3_charproc(TTStreamWriter& stream, struct TTFONT *font, int charindex); + +/* Added 06-07-07 Michael Droettboom */ +void ttfont_add_glyph_dependencies(struct TTFONT *font, std::vector<int>& glypy_ids); + +/* This routine converts a number in the font's character coordinate */ +/* system to a number in a 1000 unit character system. */ +#define topost(x) (int)( ((int)(x) * 1000 + font->HUPM) / font->unitsPerEm ) +#define topost2(x) (int)( ((int)(x) * 1000 + font.HUPM) / font.unitsPerEm ) + +/* Composite glyph values. */ +#define ARG_1_AND_2_ARE_WORDS 1 +#define ARGS_ARE_XY_VALUES 2 +#define ROUND_XY_TO_GRID 4 +#define WE_HAVE_A_SCALE 8 +/* RESERVED 16 */ +#define MORE_COMPONENTS 32 +#define WE_HAVE_AN_X_AND_Y_SCALE 64 +#define WE_HAVE_A_TWO_BY_TWO 128 +#define WE_HAVE_INSTRUCTIONS 256 +#define USE_MY_METRICS 512 + +/* end of file */ diff --git a/contrib/python/matplotlib/py3/extern/ttconv/ttutil.cpp b/contrib/python/matplotlib/py3/extern/ttconv/ttutil.cpp new file mode 100644 index 00000000000..6028e1d45d4 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/ttconv/ttutil.cpp @@ -0,0 +1,71 @@ +/* -*- mode: c++; c-basic-offset: 4 -*- */ + +/* + * Modified for use within matplotlib + * 5 July 2007 + * Michael Droettboom + */ + +/* Very simple interface to the ppr TT routines */ +/* (c) Frank Siegert 1996 */ + +#include <cstdio> +#include <cstdarg> +#include <cstdlib> +#include "pprdrv.h" + +#define PRINTF_BUFFER_SIZE 512 +void TTStreamWriter::printf(const char* format, ...) +{ + va_list arg_list; + va_start(arg_list, format); + char buffer[PRINTF_BUFFER_SIZE]; + +#if defined(WIN32) || defined(_MSC_VER) + int size = _vsnprintf(buffer, PRINTF_BUFFER_SIZE, format, arg_list); +#else + int size = vsnprintf(buffer, PRINTF_BUFFER_SIZE, format, arg_list); +#endif + if (size >= PRINTF_BUFFER_SIZE) { + char* buffer2 = (char*)malloc(size); +#if defined(WIN32) || defined(_MSC_VER) + _vsnprintf(buffer2, size, format, arg_list); +#else + vsnprintf(buffer2, size, format, arg_list); +#endif + this->write(buffer2); + free(buffer2); + } else { + this->write(buffer); + } + + va_end(arg_list); +} + +void TTStreamWriter::put_char(int val) +{ + char c[2]; + c[0] = (char)val; + c[1] = 0; + this->write(c); +} + +void TTStreamWriter::puts(const char *a) +{ + this->write(a); +} + +void TTStreamWriter::putline(const char *a) +{ + this->write(a); + this->write("\n"); +} + +void replace_newlines_with_spaces(char *a) { + char* i = a; + while (*i != 0) { + if (*i == '\r' || *i == '\n') + *i = ' '; + i++; + } +} diff --git a/contrib/python/matplotlib/py3/extern/ttconv/ya.make b/contrib/python/matplotlib/py3/extern/ttconv/ya.make new file mode 100644 index 00000000000..f877dfcbd27 --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/ttconv/ya.make @@ -0,0 +1,15 @@ +PY23_LIBRARY() + +VERSION(Service-proxy-version) + +LICENSE(PSF-2.0) + +NO_COMPILER_WARNINGS() + +SRCS( + pprdrv_tt.cpp + pprdrv_tt2.cpp + ttutil.cpp +) + +END() diff --git a/contrib/python/matplotlib/py3/extern/ya.make b/contrib/python/matplotlib/py3/extern/ya.make new file mode 100644 index 00000000000..ef8acb58eaa --- /dev/null +++ b/contrib/python/matplotlib/py3/extern/ya.make @@ -0,0 +1,4 @@ +RECURSE( + agg24-svn + ttconv +) |