diff options
author | maxim-yurchuk <maxim-yurchuk@yandex-team.com> | 2024-10-09 12:29:46 +0300 |
---|---|---|
committer | maxim-yurchuk <maxim-yurchuk@yandex-team.com> | 2024-10-09 13:14:22 +0300 |
commit | 9731d8a4bb7ee2cc8554eaf133bb85498a4c7d80 (patch) | |
tree | a8fb3181d5947c0d78cf402aa56e686130179049 /contrib/python/matplotlib/py2 | |
parent | a44b779cd359f06c3ebbef4ec98c6b38609d9d85 (diff) | |
download | ydb-9731d8a4bb7ee2cc8554eaf133bb85498a4c7d80.tar.gz |
publishFullContrib: true for ydb
<HIDDEN_URL>
commit_hash:c82a80ac4594723cebf2c7387dec9c60217f603e
Diffstat (limited to 'contrib/python/matplotlib/py2')
147 files changed, 63344 insertions, 0 deletions
diff --git a/contrib/python/matplotlib/py2/.dist-info/METADATA b/contrib/python/matplotlib/py2/.dist-info/METADATA new file mode 100644 index 0000000000..04815e8628 --- /dev/null +++ b/contrib/python/matplotlib/py2/.dist-info/METADATA @@ -0,0 +1,38 @@ +Metadata-Version: 2.1 +Name: matplotlib +Version: 2.2.5 +Summary: Python plotting package +Home-page: http://matplotlib.org +Author: John D. Hunter, Michael Droettboom +Author-email: matplotlib-users@python.org +License: PSF +Download-URL: http://matplotlib.org/users/installing.html +Platform: any +Classifier: Development Status :: 5 - Production/Stable +Classifier: Intended Audience :: Science/Research +Classifier: License :: OSI Approved :: Python Software Foundation License +Classifier: Programming Language :: Python +Classifier: Programming Language :: Python :: 2.7 +Classifier: Programming Language :: Python :: 3 +Classifier: Programming Language :: Python :: 3.4 +Classifier: Programming Language :: Python :: 3.5 +Classifier: Programming Language :: Python :: 3.6 +Classifier: Programming Language :: Python :: 3.7 +Classifier: Topic :: Scientific/Engineering :: Visualization +Requires-Dist: numpy (>=1.7.1) +Requires-Dist: cycler (>=0.10) +Requires-Dist: pyparsing (!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.1) +Requires-Dist: python-dateutil (>=2.1) +Requires-Dist: pytz +Requires-Dist: six (>=1.10) +Requires-Dist: kiwisolver (>=1.0.1) +Requires-Dist: backports.functools-lru-cache +Requires-Dist: subprocess32 + +matplotlib strives to produce publication quality 2D graphics +for interactive graphing, scientific publishing, user interface +development and web application servers targeting multiple user +interfaces and hardcopy output formats. There is a 'pylab' mode +which emulates matlab graphics. + + diff --git a/contrib/python/matplotlib/py2/.dist-info/top_level.txt b/contrib/python/matplotlib/py2/.dist-info/top_level.txt new file mode 100644 index 0000000000..0eb77e4d99 --- /dev/null +++ b/contrib/python/matplotlib/py2/.dist-info/top_level.txt @@ -0,0 +1,3 @@ +matplotlib +mpl_toolkits +pylab diff --git a/contrib/python/matplotlib/py2/LICENSE/pnpoly.license b/contrib/python/matplotlib/py2/LICENSE/pnpoly.license new file mode 100644 index 0000000000..0c838f9b01 --- /dev/null +++ b/contrib/python/matplotlib/py2/LICENSE/pnpoly.license @@ -0,0 +1,26 @@ +Copyright (c) 1970-2003, Wm. Randolph Franklin + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimers. + 2. Redistributions in binary form must reproduce the above + copyright notice in the documentation and/or other materials + provided with the distribution. + 3. The name of W. Randolph Franklin may not be used to endorse or + promote products derived from this Software without specific + prior written permission. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_arc.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_arc.h new file mode 100644 index 0000000000..17e1d43473 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_arrowhead.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_arrowhead.h new file mode 100644 index 0000000000..5e029ddee0 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_bitset_iterator.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_bitset_iterator.h new file mode 100644 index 0000000000..7382d5c335 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_blur.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_blur.h new file mode 100644 index 0000000000..cd5713f314 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_bounding_rect.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_bounding_rect.h new file mode 100644 index 0000000000..f13b863f0f --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_bspline.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_bspline.h new file mode 100644 index 0000000000..2c1ed9a38c --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_conv_bspline.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_bspline.h new file mode 100644 index 0000000000..13d22d9297 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_conv_clip_polygon.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_clip_polygon.h new file mode 100644 index 0000000000..87537638dc --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_conv_clip_polyline.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_clip_polyline.h new file mode 100644 index 0000000000..f3fc2888c2 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_conv_close_polygon.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_close_polygon.h new file mode 100644 index 0000000000..c46594fdfb --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_conv_concat.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_concat.h new file mode 100644 index 0000000000..745d349c6f --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_conv_gpc.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_gpc.h new file mode 100644 index 0000000000..2acada342d --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_conv_marker.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_marker.h new file mode 100644 index 0000000000..2cd3cb403f --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_conv_marker_adaptor.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_marker_adaptor.h new file mode 100644 index 0000000000..4486d6ace9 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_conv_shorten_path.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_shorten_path.h new file mode 100644 index 0000000000..5617e51d17 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_conv_smooth_poly1.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_smooth_poly1.h new file mode 100644 index 0000000000..4ac4e3d6e2 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_conv_unclose_polygon.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_conv_unclose_polygon.h new file mode 100644 index 0000000000..fe5c263810 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_ellipse.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_ellipse.h new file mode 100644 index 0000000000..e78ce27dd9 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_ellipse_bresenham.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_ellipse_bresenham.h new file mode 100644 index 0000000000..ee3b9c4638 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_embedded_raster_fonts.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_embedded_raster_fonts.h new file mode 100644 index 0000000000..9d522d671c --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_font_cache_manager.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_font_cache_manager.h new file mode 100644 index 0000000000..fe9a9280fa --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_font_cache_manager2.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_font_cache_manager2.h new file mode 100644 index 0000000000..75d311eff7 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_glyph_raster_bin.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_glyph_raster_bin.h new file mode 100644 index 0000000000..b0bf858efd --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_gradient_lut.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_gradient_lut.h new file mode 100644 index 0000000000..9aaa426815 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_gsv_text.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_gsv_text.h new file mode 100644 index 0000000000..16b3aeb33d --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_line_aa_basics.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_line_aa_basics.h new file mode 100644 index 0000000000..c5acb18e79 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_path_length.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_path_length.h new file mode 100644 index 0000000000..740ba31df2 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_path_storage_integer.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_path_storage_integer.h new file mode 100644 index 0000000000..7c48355993 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_pattern_filters_rgba.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_pattern_filters_rgba.h new file mode 100644 index 0000000000..c1d174cacb --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_pixfmt_rgb_packed.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_pixfmt_rgb_packed.h new file mode 100644 index 0000000000..d879517de6 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_pixfmt_transposer.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_pixfmt_transposer.h new file mode 100644 index 0000000000..64738b6c75 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_rasterizer_compound_aa.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_rasterizer_compound_aa.h new file mode 100644 index 0000000000..41d508010e --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_rasterizer_outline.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_rasterizer_outline.h new file mode 100644 index 0000000000..65203e34c5 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_rasterizer_outline_aa.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_rasterizer_outline_aa.h new file mode 100644 index 0000000000..a06bd1e843 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_renderer_markers.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_renderer_markers.h new file mode 100644 index 0000000000..820f753079 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_renderer_mclip.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_renderer_mclip.h new file mode 100644 index 0000000000..96a7d4e094 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_renderer_outline_aa.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_renderer_outline_aa.h new file mode 100644 index 0000000000..ee564f04d5 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_renderer_outline_image.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_renderer_outline_image.h new file mode 100644 index 0000000000..8abb9fa0bd --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_renderer_primitives.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_renderer_primitives.h new file mode 100644 index 0000000000..f008db7c94 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_renderer_raster_text.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_renderer_raster_text.h new file mode 100644 index 0000000000..87b43f9600 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_rendering_buffer_dynarow.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_rendering_buffer_dynarow.h new file mode 100644 index 0000000000..188746f3d3 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_rounded_rect.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_rounded_rect.h new file mode 100644 index 0000000000..fe8d26f71b --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_scanline_boolean_algebra.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_scanline_boolean_algebra.h new file mode 100644 index 0000000000..bc2e9c9d51 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_simul_eq.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_simul_eq.h new file mode 100644 index 0000000000..3d0dce4b44 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_span_gouraud_gray.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_gouraud_gray.h new file mode 100644 index 0000000000..d5fc39d102 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_span_gradient.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_gradient.h new file mode 100644 index 0000000000..58b506dcfe --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_span_gradient_alpha.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_gradient_alpha.h new file mode 100644 index 0000000000..2ec040e3b9 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_span_gradient_contour.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_gradient_contour.h new file mode 100644 index 0000000000..899bb799b6 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_span_gradient_image.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_gradient_image.h new file mode 100644 index 0000000000..c99eaca166 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_span_image_filter_rgb.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_image_filter_rgb.h new file mode 100644 index 0000000000..f78ae19c1b --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_span_interpolator_persp.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_interpolator_persp.h new file mode 100644 index 0000000000..cad437e04f --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_span_interpolator_trans.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_interpolator_trans.h new file mode 100644 index 0000000000..32bc678a8e --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_span_pattern_gray.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_pattern_gray.h new file mode 100644 index 0000000000..ae1a49f879 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_span_pattern_rgb.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_pattern_rgb.h new file mode 100644 index 0000000000..4850508af1 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_span_solid.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_solid.h new file mode 100644 index 0000000000..ee46df9991 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_span_subdiv_adaptor.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_span_subdiv_adaptor.h new file mode 100644 index 0000000000..b5b855ec97 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_trans_bilinear.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_trans_bilinear.h new file mode 100644 index 0000000000..f3ab596472 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_trans_double_path.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_trans_double_path.h new file mode 100644 index 0000000000..c645a7f869 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_trans_perspective.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_trans_perspective.h new file mode 100644 index 0000000000..7d4aa26c79 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_trans_single_path.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_trans_single_path.h new file mode 100644 index 0000000000..9f4bf53bdb --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_trans_viewport.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_trans_viewport.h new file mode 100644 index 0000000000..7088f99078 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_trans_warp_magnifier.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_trans_warp_magnifier.h new file mode 100644 index 0000000000..38a92dbec8 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_vcgen_bspline.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_vcgen_bspline.h new file mode 100644 index 0000000000..a2944548c0 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_vcgen_markers_term.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_vcgen_markers_term.h new file mode 100644 index 0000000000..ee1e74e3eb --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_vcgen_smooth_poly1.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_vcgen_smooth_poly1.h new file mode 100644 index 0000000000..80fc0fb796 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_vcgen_vertex_sequence.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_vcgen_vertex_sequence.h new file mode 100644 index 0000000000..5adc671597 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_vpgen_clip_polygon.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_vpgen_clip_polygon.h new file mode 100644 index 0000000000..ded754e211 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/agg_vpgen_clip_polyline.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/agg_vpgen_clip_polyline.h new file mode 100644 index 0000000000..b070a7759e --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/ctrl/agg_bezier_ctrl.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/ctrl/agg_bezier_ctrl.h new file mode 100644 index 0000000000..01851eb3e1 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/ctrl/agg_cbox_ctrl.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/ctrl/agg_cbox_ctrl.h new file mode 100644 index 0000000000..7ecbce27f4 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/ctrl/agg_ctrl.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/ctrl/agg_ctrl.h new file mode 100644 index 0000000000..7e811c63e1 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/ctrl/agg_gamma_ctrl.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/ctrl/agg_gamma_ctrl.h new file mode 100644 index 0000000000..0a645a7146 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/ctrl/agg_gamma_spline.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/ctrl/agg_gamma_spline.h new file mode 100644 index 0000000000..4f21710d9f --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/ctrl/agg_polygon_ctrl.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/ctrl/agg_polygon_ctrl.h new file mode 100644 index 0000000000..6f465d96b8 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/ctrl/agg_rbox_ctrl.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/ctrl/agg_rbox_ctrl.h new file mode 100644 index 0000000000..4d47bccdbb --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/ctrl/agg_scale_ctrl.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/ctrl/agg_scale_ctrl.h new file mode 100644 index 0000000000..b1e32c2037 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/ctrl/agg_slider_ctrl.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/ctrl/agg_slider_ctrl.h new file mode 100644 index 0000000000..b50a95c59d --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/ctrl/agg_spline_ctrl.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/ctrl/agg_spline_ctrl.h new file mode 100644 index 0000000000..8477f27d78 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/platform/agg_platform_support.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/platform/agg_platform_support.h new file mode 100644 index 0000000000..9a63411e50 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/platform/mac/agg_mac_pmap.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/platform/mac/agg_mac_pmap.h new file mode 100644 index 0000000000..d7860b6fee --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/platform/win32/agg_win32_bmp.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/platform/win32/agg_win32_bmp.h new file mode 100644 index 0000000000..5391e8bb9b --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/include/util/agg_color_conv_rgb16.h b/contrib/python/matplotlib/py2/extern/agg24-svn/include/util/agg_color_conv_rgb16.h new file mode 100644 index 0000000000..aaa41322c5 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/src/agg_arc.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_arc.cpp new file mode 100644 index 0000000000..df2c43a559 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/src/agg_arrowhead.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_arrowhead.cpp new file mode 100644 index 0000000000..1a6f8b4100 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/src/agg_bspline.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_bspline.cpp new file mode 100644 index 0000000000..e1fda9f51f --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/src/agg_color_rgba.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_color_rgba.cpp new file mode 100644 index 0000000000..9fe1534b03 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/src/agg_embedded_raster_fonts.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_embedded_raster_fonts.cpp new file mode 100644 index 0000000000..ee4dc65ee4 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/src/agg_gsv_text.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_gsv_text.cpp new file mode 100644 index 0000000000..ffb24eb9b6 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/src/agg_line_aa_basics.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_line_aa_basics.cpp new file mode 100644 index 0000000000..018d65366f --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/src/agg_line_profile_aa.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_line_profile_aa.cpp new file mode 100644 index 0000000000..6066662cb9 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/src/agg_rounded_rect.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_rounded_rect.cpp new file mode 100644 index 0000000000..bebc063628 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/src/agg_sqrt_tables.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_sqrt_tables.cpp new file mode 100644 index 0000000000..19a1bd8cb7 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/src/agg_trans_double_path.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_trans_double_path.cpp new file mode 100644 index 0000000000..cd40c7f586 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/src/agg_trans_single_path.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_trans_single_path.cpp new file mode 100644 index 0000000000..2120fc9b9b --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/src/agg_trans_warp_magnifier.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_trans_warp_magnifier.cpp new file mode 100644 index 0000000000..e65afabba7 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/src/agg_vcgen_bspline.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_vcgen_bspline.cpp new file mode 100644 index 0000000000..4a0be6693e --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/src/agg_vcgen_markers_term.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_vcgen_markers_term.cpp new file mode 100644 index 0000000000..3374ab5e82 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/src/agg_vcgen_smooth_poly1.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_vcgen_smooth_poly1.cpp new file mode 100644 index 0000000000..ff7d488d39 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/src/agg_vpgen_clip_polygon.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_vpgen_clip_polygon.cpp new file mode 100644 index 0000000000..4524526017 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/src/agg_vpgen_clip_polyline.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/agg_vpgen_clip_polyline.cpp new file mode 100644 index 0000000000..6840803a98 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/src/ctrl/agg_bezier_ctrl.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_bezier_ctrl.cpp new file mode 100644 index 0000000000..13a4c15af9 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/src/ctrl/agg_cbox_ctrl.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_cbox_ctrl.cpp new file mode 100644 index 0000000000..3cf14f6a85 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/src/ctrl/agg_gamma_ctrl.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_gamma_ctrl.cpp new file mode 100644 index 0000000000..7fd6448cd5 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/src/ctrl/agg_gamma_spline.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_gamma_spline.cpp new file mode 100644 index 0000000000..f720fddd8e --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/src/ctrl/agg_polygon_ctrl.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_polygon_ctrl.cpp new file mode 100644 index 0000000000..40daee45e8 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/src/ctrl/agg_rbox_ctrl.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_rbox_ctrl.cpp new file mode 100644 index 0000000000..4e36b3b26b --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/src/ctrl/agg_scale_ctrl.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_scale_ctrl.cpp new file mode 100644 index 0000000000..7f167792bd --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/src/ctrl/agg_slider_ctrl.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_slider_ctrl.cpp new file mode 100644 index 0000000000..ad0048631c --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/src/ctrl/agg_spline_ctrl.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/ctrl/agg_spline_ctrl.cpp new file mode 100644 index 0000000000..74808d4f87 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/src/platform/AmigaOS/agg_platform_support.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/AmigaOS/agg_platform_support.cpp new file mode 100644 index 0000000000..b14d09cd1c --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/src/platform/BeOS/agg_platform_support.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/BeOS/agg_platform_support.cpp new file mode 100644 index 0000000000..078e141ccb --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/src/platform/X11/agg_platform_support.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/X11/agg_platform_support.cpp new file mode 100644 index 0000000000..46b874d738 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/src/platform/mac/agg_mac_pmap.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/mac/agg_mac_pmap.cpp new file mode 100644 index 0000000000..dc85fd69ff --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/src/platform/mac/agg_platform_support.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/mac/agg_platform_support.cpp new file mode 100644 index 0000000000..f518dbe1f2 --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/src/platform/sdl/agg_platform_support.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/sdl/agg_platform_support.cpp new file mode 100644 index 0000000000..28c6436baa --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/src/platform/win32/agg_platform_support.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/win32/agg_platform_support.cpp new file mode 100644 index 0000000000..ea9123802f --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/extern/agg24-svn/src/platform/win32/agg_win32_bmp.cpp b/contrib/python/matplotlib/py2/extern/agg24-svn/src/platform/win32/agg_win32_bmp.cpp new file mode 100644 index 0000000000..8c3bdc83fd --- /dev/null +++ b/contrib/python/matplotlib/py2/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/py2/matplotlib/backends/web_backend/all_figures.html b/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/all_figures.html new file mode 100644 index 0000000000..41f48dc6d2 --- /dev/null +++ b/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/all_figures.html @@ -0,0 +1,43 @@ +<html> + <head> + <link rel="stylesheet" href="{{ prefix }}/_static/css/page.css" type="text/css"> + <link rel="stylesheet" href="{{ prefix }}/_static/css/boilerplate.css" type="text/css" /> + <link rel="stylesheet" href="{{ prefix }}/_static/css/fbm.css" type="text/css" /> + <link rel="stylesheet" href="{{ prefix }}/_static/jquery-ui-1.12.1/jquery-ui.min.css" > + <script src="{{ prefix }}/_static/jquery-ui-1.12.1/external/jquery/jquery.js"></script> + <script src="{{ prefix }}/_static/jquery-ui-1.12.1/jquery-ui.min.js"></script> + <script src="{{ prefix }}/_static/js/mpl_tornado.js"></script> + <script src="{{ prefix }}/js/mpl.js"></script> + + <script> + {% for (fig_id, fig_manager) in figures %} + $(document).ready( + function() { + var main_div = $('div#figures'); + var figure_div = $('<div id="figure-div"/>') + main_div.append(figure_div); + var websocket_type = mpl.get_websocket_type(); + var websocket = new websocket_type( + "{{ ws_uri }}" + "{{ fig_id }}" + "/ws"); + var fig = new mpl.figure( + "{{ fig_id }}", websocket, mpl_ondownload, figure_div); + + fig.focus_on_mouseover = true; + + $(fig.canvas).attr('tabindex', {{ fig_id }}); + } + ); + + {% end %} + </script> + + <title>MPL | WebAgg current figures</title> + + </head> + <body> + <div id="mpl-warnings" class="mpl-warnings"></div> + + <div id="figures" style="margin: 10px 10px;"></div> + + </body> +</html> diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/css/boilerplate.css b/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/css/boilerplate.css new file mode 100644 index 0000000000..2b1535f449 --- /dev/null +++ b/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/css/boilerplate.css @@ -0,0 +1,77 @@ +/** + * HTML5 ✰ Boilerplate + * + * style.css contains a reset, font normalization and some base styles. + * + * Credit is left where credit is due. + * Much inspiration was taken from these projects: + * - yui.yahooapis.com/2.8.1/build/base/base.css + * - camendesign.com/design/ + * - praegnanz.de/weblog/htmlcssjs-kickstart + */ + + +/** + * html5doctor.com Reset Stylesheet (Eric Meyer's Reset Reloaded + HTML5 baseline) + * v1.6.1 2010-09-17 | Authors: Eric Meyer & Richard Clark + * html5doctor.com/html-5-reset-stylesheet/ + */ + +html, body, div, span, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +abbr, address, cite, code, del, dfn, em, img, ins, kbd, q, samp, +small, strong, sub, sup, var, b, i, dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td, +article, aside, canvas, details, figcaption, figure, +footer, header, hgroup, menu, nav, section, summary, +time, mark, audio, video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; +} + +sup { vertical-align: super; } +sub { vertical-align: sub; } + +article, aside, details, figcaption, figure, +footer, header, hgroup, menu, nav, section { + display: block; +} + +blockquote, q { quotes: none; } + +blockquote:before, blockquote:after, +q:before, q:after { content: ""; content: none; } + +ins { background-color: #ff9; color: #000; text-decoration: none; } + +mark { background-color: #ff9; color: #000; font-style: italic; font-weight: bold; } + +del { text-decoration: line-through; } + +abbr[title], dfn[title] { border-bottom: 1px dotted; cursor: help; } + +table { border-collapse: collapse; border-spacing: 0; } + +hr { display: block; height: 1px; border: 0; border-top: 1px solid #ccc; margin: 1em 0; padding: 0; } + +input, select { vertical-align: middle; } + + +/** + * Font normalization inspired by YUI Library's fonts.css: developer.yahoo.com/yui/ + */ + +body { font:13px/1.231 sans-serif; *font-size:small; } /* Hack retained to preserve specificity */ +select, input, textarea, button { font:99% sans-serif; } + +/* Normalize monospace sizing: + en.wikipedia.org/wiki/MediaWiki_talk:Common.css/Archive_11#Teletype_style_fix_for_Chrome */ +pre, code, kbd, samp { font-family: monospace, sans-serif; } + +em,i { font-style: italic; } +b,strong { font-weight: bold; } diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/css/fbm.css b/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/css/fbm.css new file mode 100644 index 0000000000..0e21d19ae8 --- /dev/null +++ b/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/css/fbm.css @@ -0,0 +1,97 @@ + +/* Flexible box model classes */ +/* Taken from Alex Russell http://infrequently.org/2009/08/css-3-progress/ */ + +.hbox { + display: -webkit-box; + -webkit-box-orient: horizontal; + -webkit-box-align: stretch; + + display: -moz-box; + -moz-box-orient: horizontal; + -moz-box-align: stretch; + + display: box; + box-orient: horizontal; + box-align: stretch; +} + +.hbox > * { + -webkit-box-flex: 0; + -moz-box-flex: 0; + box-flex: 0; +} + +.vbox { + display: -webkit-box; + -webkit-box-orient: vertical; + -webkit-box-align: stretch; + + display: -moz-box; + -moz-box-orient: vertical; + -moz-box-align: stretch; + + display: box; + box-orient: vertical; + box-align: stretch; +} + +.vbox > * { + -webkit-box-flex: 0; + -moz-box-flex: 0; + box-flex: 0; +} + +.reverse { + -webkit-box-direction: reverse; + -moz-box-direction: reverse; + box-direction: reverse; +} + +.box-flex0 { + -webkit-box-flex: 0; + -moz-box-flex: 0; + box-flex: 0; +} + +.box-flex1, .box-flex { + -webkit-box-flex: 1; + -moz-box-flex: 1; + box-flex: 1; +} + +.box-flex2 { + -webkit-box-flex: 2; + -moz-box-flex: 2; + box-flex: 2; +} + +.box-group1 { + -webkit-box-flex-group: 1; + -moz-box-flex-group: 1; + box-flex-group: 1; +} + +.box-group2 { + -webkit-box-flex-group: 2; + -moz-box-flex-group: 2; + box-flex-group: 2; +} + +.start { + -webkit-box-pack: start; + -moz-box-pack: start; + box-pack: start; +} + +.end { + -webkit-box-pack: end; + -moz-box-pack: end; + box-pack: end; +} + +.center { + -webkit-box-pack: center; + -moz-box-pack: center; + box-pack: center; +} diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/css/page.css b/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/css/page.css new file mode 100644 index 0000000000..d284be1f59 --- /dev/null +++ b/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/css/page.css @@ -0,0 +1,82 @@ +/** + * Primary styles + * + * Author: IPython Development Team + */ + + +body { + background-color: white; + /* This makes sure that the body covers the entire window and needs to + be in a different element than the display: box in wrapper below */ + position: absolute; + left: 0px; + right: 0px; + top: 0px; + bottom: 0px; + overflow: visible; +} + + +div#header { + /* Initially hidden to prevent FLOUC */ + display: none; + position: relative; + height: 40px; + padding: 5px; + margin: 0px; + width: 100%; +} + +span#ipython_notebook { + position: absolute; + padding: 2px 2px 2px 5px; +} + +span#ipython_notebook img { + font-family: Verdana, "Helvetica Neue", Arial, Helvetica, Geneva, sans-serif; + height: 24px; + text-decoration:none; + display: inline; + color: black; +} + +#site { + width: 100%; + display: none; +} + +/* We set the fonts by hand here to override the values in the theme */ +.ui-widget { + font-family: "Lucinda Grande", "Lucinda Sans Unicode", Helvetica, Arial, Verdana, sans-serif; +} + +.ui-widget input, .ui-widget select, .ui-widget textarea, .ui-widget button { + font-family: "Lucinda Grande", "Lucinda Sans Unicode", Helvetica, Arial, Verdana, sans-serif; +} + +/* Smaller buttons */ +.ui-button .ui-button-text { + padding: 0.2em 0.8em; + font-size: 77%; +} + +input.ui-button { + padding: 0.3em 0.9em; +} + +span#login_widget { + float: right; +} + +.border-box-sizing { + box-sizing: border-box; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; +} + +#figure-div { + display: inline-block; + margin: 10px; +} + diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/ipython_inline_figure.html b/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/ipython_inline_figure.html new file mode 100644 index 0000000000..eed5af0f43 --- /dev/null +++ b/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/ipython_inline_figure.html @@ -0,0 +1,34 @@ +<!-- Within the kernel, we don't know the address of the matplotlib + websocket server, so we have to get in client-side and fetch our + resources that way. --> +<script> + // We can't proceed until these Javascript files are fetched, so + // we fetch them synchronously + $.ajaxSetup({async: false}); + $.getScript("http://" + window.location.hostname + ":{{ port }}{{prefix}}/_static/js/mpl_tornado.js"); + $.getScript("http://" + window.location.hostname + ":{{ port }}{{prefix}}/js/mpl.js"); + $.ajaxSetup({async: true}); + + function init_figure{{ fig_id }}(e) { + $('div.output').off('resize'); + + var output_div = $(e.target).find('div.output_subarea'); + var websocket_type = mpl.get_websocket_type(); + var websocket = new websocket_type( + "ws://" + window.location.hostname + ":{{ port }}{{ prefix}}/" + + {{ repr(str(fig_id)) }} + "/ws"); + + var fig = new mpl.figure( + {{repr(str(fig_id))}}, websocket, mpl_ondownload, output_div); + + // Fetch the first image + fig.context.drawImage(fig.imageObj, 0, 0); + + fig.focus_on_mouseover = true; + } + + // We can't initialize the figure contents until our content + // has been added to the DOM. This is a bit of hack to get an + // event for that. + $('div.output').resize(init_figure{{ fig_id }}); +</script> diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/jquery/js/jquery-1.11.3.js b/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/jquery/js/jquery-1.11.3.js new file mode 100644 index 0000000000..6feb11086f --- /dev/null +++ b/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/jquery/js/jquery-1.11.3.js @@ -0,0 +1,10351 @@ +/*! + * jQuery JavaScript Library v1.11.3 + * http://jquery.com/ + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * + * Copyright 2005, 2014 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2015-04-28T16:19Z + */ + +(function( global, factory ) { + + if ( typeof module === "object" && typeof module.exports === "object" ) { + // For CommonJS and CommonJS-like environments where a proper window is present, + // execute the factory and get jQuery + // For environments that do not inherently posses a window with a document + // (such as Node.js), expose a jQuery-making factory as module.exports + // This accentuates the need for the creation of a real window + // e.g. var jQuery = require("jquery")(window); + // See ticket #14549 for more info + module.exports = global.document ? + factory( global, true ) : + function( w ) { + if ( !w.document ) { + throw new Error( "jQuery requires a window with a document" ); + } + return factory( w ); + }; + } else { + factory( global ); + } + +// Pass this if window is not defined yet +}(typeof window !== "undefined" ? window : this, function( window, noGlobal ) { + +// Can't do this because several apps including ASP.NET trace +// the stack via arguments.caller.callee and Firefox dies if +// you try to trace through "use strict" call chains. (#13335) +// Support: Firefox 18+ +// + +var deletedIds = []; + +var slice = deletedIds.slice; + +var concat = deletedIds.concat; + +var push = deletedIds.push; + +var indexOf = deletedIds.indexOf; + +var class2type = {}; + +var toString = class2type.toString; + +var hasOwn = class2type.hasOwnProperty; + +var support = {}; + + + +var + version = "1.11.3", + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' + // Need init if jQuery is called (just allow error to be thrown if not included) + return new jQuery.fn.init( selector, context ); + }, + + // Support: Android<4.1, IE<9 + // Make sure we trim BOM and NBSP + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, + + // Matches dashed string for camelizing + rmsPrefix = /^-ms-/, + rdashAlpha = /-([\da-z])/gi, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return letter.toUpperCase(); + }; + +jQuery.fn = jQuery.prototype = { + // The current version of jQuery being used + jquery: version, + + constructor: jQuery, + + // Start with an empty selector + selector: "", + + // The default length of a jQuery object is 0 + length: 0, + + toArray: function() { + return slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num != null ? + + // Return just the one element from the set + ( num < 0 ? this[ num + this.length ] : this[ num ] ) : + + // Return all the elements in a clean array + slice.call( this ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + ret.context = this.context; + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + // (You can seed the arguments with an array of args, but this is + // only used internally.) + each: function( callback, args ) { + return jQuery.each( this, callback, args ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map(this, function( elem, i ) { + return callback.call( elem, i, elem ); + })); + }, + + slice: function() { + return this.pushStack( slice.apply( this, arguments ) ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + eq: function( i ) { + var len = this.length, + j = +i + ( i < 0 ? len : 0 ); + return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] ); + }, + + end: function() { + return this.prevObject || this.constructor(null); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: push, + sort: deletedIds.sort, + splice: deletedIds.splice +}; + +jQuery.extend = jQuery.fn.extend = function() { + var src, copyIsArray, copy, name, options, clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + + // skip the boolean and the target + target = arguments[ i ] || {}; + i++; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction(target) ) { + target = {}; + } + + // extend jQuery itself if only one argument is passed + if ( i === length ) { + target = this; + i--; + } + + for ( ; i < length; i++ ) { + // Only deal with non-null/undefined values + if ( (options = arguments[ i ]) != null ) { + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { + if ( copyIsArray ) { + copyIsArray = false; + clone = src && jQuery.isArray(src) ? src : []; + + } else { + clone = src && jQuery.isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend({ + // Unique for each copy of jQuery on the page + expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ), + + // Assume jQuery is ready without the ready module + isReady: true, + + error: function( msg ) { + throw new Error( msg ); + }, + + noop: function() {}, + + // See test/unit/core.js for details concerning isFunction. + // Since version 1.3, DOM methods and functions like alert + // aren't supported. They return false on IE (#2968). + isFunction: function( obj ) { + return jQuery.type(obj) === "function"; + }, + + isArray: Array.isArray || function( obj ) { + return jQuery.type(obj) === "array"; + }, + + isWindow: function( obj ) { + /* jshint eqeqeq: false */ + return obj != null && obj == obj.window; + }, + + isNumeric: function( obj ) { + // parseFloat NaNs numeric-cast false positives (null|true|false|"") + // ...but misinterprets leading-number strings, particularly hex literals ("0x...") + // subtraction forces infinities to NaN + // adding 1 corrects loss of precision from parseFloat (#15100) + return !jQuery.isArray( obj ) && (obj - parseFloat( obj ) + 1) >= 0; + }, + + isEmptyObject: function( obj ) { + var name; + for ( name in obj ) { + return false; + } + return true; + }, + + isPlainObject: function( obj ) { + var key; + + // Must be an Object. + // Because of IE, we also have to check the presence of the constructor property. + // Make sure that DOM nodes and window objects don't pass through, as well + if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + try { + // Not own constructor property must be Object + if ( obj.constructor && + !hasOwn.call(obj, "constructor") && + !hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { + return false; + } + } catch ( e ) { + // IE8,9 Will throw exceptions on certain host objects #9897 + return false; + } + + // Support: IE<9 + // Handle iteration over inherited properties before own properties. + if ( support.ownLast ) { + for ( key in obj ) { + return hasOwn.call( obj, key ); + } + } + + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + for ( key in obj ) {} + + return key === undefined || hasOwn.call( obj, key ); + }, + + type: function( obj ) { + if ( obj == null ) { + return obj + ""; + } + return typeof obj === "object" || typeof obj === "function" ? + class2type[ toString.call(obj) ] || "object" : + typeof obj; + }, + + // Evaluates a script in a global context + // Workarounds based on findings by Jim Driscoll + // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context + globalEval: function( data ) { + if ( data && jQuery.trim( data ) ) { + // We use execScript on Internet Explorer + // We use an anonymous function so that context is window + // rather than jQuery in Firefox + ( window.execScript || function( data ) { + window[ "eval" ].call( window, data ); + } )( data ); + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + }, + + // args is for internal usage only + each: function( obj, callback, args ) { + var value, + i = 0, + length = obj.length, + isArray = isArraylike( obj ); + + if ( args ) { + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback.apply( obj[ i ], args ); + + if ( value === false ) { + break; + } + } + } else { + for ( i in obj ) { + value = callback.apply( obj[ i ], args ); + + if ( value === false ) { + break; + } + } + } + + // A special, fast, case for the most common use of each + } else { + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback.call( obj[ i ], i, obj[ i ] ); + + if ( value === false ) { + break; + } + } + } else { + for ( i in obj ) { + value = callback.call( obj[ i ], i, obj[ i ] ); + + if ( value === false ) { + break; + } + } + } + } + + return obj; + }, + + // Support: Android<4.1, IE<9 + trim: function( text ) { + return text == null ? + "" : + ( text + "" ).replace( rtrim, "" ); + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var ret = results || []; + + if ( arr != null ) { + if ( isArraylike( Object(arr) ) ) { + jQuery.merge( ret, + typeof arr === "string" ? + [ arr ] : arr + ); + } else { + push.call( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + var len; + + if ( arr ) { + if ( indexOf ) { + return indexOf.call( arr, elem, i ); + } + + len = arr.length; + i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; + + for ( ; i < len; i++ ) { + // Skip accessing in sparse arrays + if ( i in arr && arr[ i ] === elem ) { + return i; + } + } + } + + return -1; + }, + + merge: function( first, second ) { + var len = +second.length, + j = 0, + i = first.length; + + while ( j < len ) { + first[ i++ ] = second[ j++ ]; + } + + // Support: IE<9 + // Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists) + if ( len !== len ) { + while ( second[j] !== undefined ) { + first[ i++ ] = second[ j++ ]; + } + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, invert ) { + var callbackInverse, + matches = [], + i = 0, + length = elems.length, + callbackExpect = !invert; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + callbackInverse = !callback( elems[ i ], i ); + if ( callbackInverse !== callbackExpect ) { + matches.push( elems[ i ] ); + } + } + + return matches; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var value, + i = 0, + length = elems.length, + isArray = isArraylike( elems ), + ret = []; + + // Go through the array, translating each of the items to their new values + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + + // Go through every key on the object, + } else { + for ( i in elems ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret.push( value ); + } + } + } + + // Flatten any nested arrays + return concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + var args, proxy, tmp; + + if ( typeof context === "string" ) { + tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + args = slice.call( arguments, 2 ); + proxy = function() { + return fn.apply( context || this, args.concat( slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || jQuery.guid++; + + return proxy; + }, + + now: function() { + return +( new Date() ); + }, + + // jQuery.support is not used in Core but other projects attach their + // properties to it so it needs to exist. + support: support +}); + +// Populate the class2type map +jQuery.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); + +function isArraylike( obj ) { + + // Support: iOS 8.2 (not reproducible in simulator) + // `in` check used to prevent JIT error (gh-2145) + // hasOwn isn't used here due to false negatives + // regarding Nodelist length in IE + var length = "length" in obj && obj.length, + type = jQuery.type( obj ); + + if ( type === "function" || jQuery.isWindow( obj ) ) { + return false; + } + + if ( obj.nodeType === 1 && length ) { + return true; + } + + return type === "array" || length === 0 || + typeof length === "number" && length > 0 && ( length - 1 ) in obj; +} +var Sizzle = +/*! + * Sizzle CSS Selector Engine v2.2.0-pre + * http://sizzlejs.com/ + * + * Copyright 2008, 2014 jQuery Foundation, Inc. and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: 2014-12-16 + */ +(function( window ) { + +var i, + support, + Expr, + getText, + isXML, + tokenize, + compile, + select, + outermostContext, + sortInput, + hasDuplicate, + + // Local document vars + setDocument, + document, + docElem, + documentIsHTML, + rbuggyQSA, + rbuggyMatches, + matches, + contains, + + // Instance-specific data + expando = "sizzle" + 1 * new Date(), + preferredDoc = window.document, + dirruns = 0, + done = 0, + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + sortOrder = function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + } + return 0; + }, + + // General-purpose constants + MAX_NEGATIVE = 1 << 31, + + // Instance methods + hasOwn = ({}).hasOwnProperty, + arr = [], + pop = arr.pop, + push_native = arr.push, + push = arr.push, + slice = arr.slice, + // Use a stripped-down indexOf as it's faster than native + // http://jsperf.com/thor-indexof-vs-for/5 + indexOf = function( list, elem ) { + var i = 0, + len = list.length; + for ( ; i < len; i++ ) { + if ( list[i] === elem ) { + return i; + } + } + return -1; + }, + + booleans = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", + + // Regular expressions + + // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + // http://www.w3.org/TR/css3-syntax/#characters + characterEncoding = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", + + // Loosely modeled on CSS identifier characters + // An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors + // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = characterEncoding.replace( "w", "w#" ), + + // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors + attributes = "\\[" + whitespace + "*(" + characterEncoding + ")(?:" + whitespace + + // Operator (capture 2) + "*([*^$|!~]?=)" + whitespace + + // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]" + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace + + "*\\]", + + pseudos = ":(" + characterEncoding + ")(?:\\((" + + // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments: + // 1. quoted (capture 3; capture 4 or capture 5) + "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" + + // 2. simple (capture 6) + "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" + + // 3. anything else (capture 2) + ".*" + + ")\\)|)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rwhitespace = new RegExp( whitespace + "+", "g" ), + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ), + + rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ), + + rpseudo = new RegExp( pseudos ), + ridentifier = new RegExp( "^" + identifier + "$" ), + + matchExpr = { + "ID": new RegExp( "^#(" + characterEncoding + ")" ), + "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), + "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace + + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + "bool": new RegExp( "^(?:" + booleans + ")$", "i" ), + // For use in libraries implementing .is() + // We use this for POS matching in `select` + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + + whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" ) + }, + + rinputs = /^(?:input|select|textarea|button)$/i, + rheader = /^h\d$/i, + + rnative = /^[^{]+\{\s*\[native \w/, + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, + + rsibling = /[+~]/, + rescape = /'|\\/g, + + // CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters + runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ), + funescape = function( _, escaped, escapedWhitespace ) { + var high = "0x" + escaped - 0x10000; + // NaN means non-codepoint + // Support: Firefox<24 + // Workaround erroneous numeric interpretation of +"0x" + return high !== high || escapedWhitespace ? + escaped : + high < 0 ? + // BMP codepoint + String.fromCharCode( high + 0x10000 ) : + // Supplemental Plane codepoint (surrogate pair) + String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 ); + }, + + // Used for iframes + // See setDocument() + // Removing the function wrapper causes a "Permission Denied" + // error in IE + unloadHandler = function() { + setDocument(); + }; + +// Optimize for push.apply( _, NodeList ) +try { + push.apply( + (arr = slice.call( preferredDoc.childNodes )), + preferredDoc.childNodes + ); + // Support: Android<4.0 + // Detect silently failing push.apply + arr[ preferredDoc.childNodes.length ].nodeType; +} catch ( e ) { + push = { apply: arr.length ? + + // Leverage slice if possible + function( target, els ) { + push_native.apply( target, slice.call(els) ); + } : + + // Support: IE<9 + // Otherwise append directly + function( target, els ) { + var j = target.length, + i = 0; + // Can't trust NodeList.length + while ( (target[j++] = els[i++]) ) {} + target.length = j - 1; + } + }; +} + +function Sizzle( selector, context, results, seed ) { + var match, elem, m, nodeType, + // QSA vars + i, groups, old, nid, newContext, newSelector; + + if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) { + setDocument( context ); + } + + context = context || document; + results = results || []; + nodeType = context.nodeType; + + if ( typeof selector !== "string" || !selector || + nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) { + + return results; + } + + if ( !seed && documentIsHTML ) { + + // Try to shortcut find operations when possible (e.g., not under DocumentFragment) + if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) { + // Speed-up: Sizzle("#ID") + if ( (m = match[1]) ) { + if ( nodeType === 9 ) { + elem = context.getElementById( m ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document (jQuery #6963) + if ( elem && elem.parentNode ) { + // Handle the case where IE, Opera, and Webkit return items + // by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + } else { + // Context is not a document + if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && + contains( context, elem ) && elem.id === m ) { + results.push( elem ); + return results; + } + } + + // Speed-up: Sizzle("TAG") + } else if ( match[2] ) { + push.apply( results, context.getElementsByTagName( selector ) ); + return results; + + // Speed-up: Sizzle(".CLASS") + } else if ( (m = match[3]) && support.getElementsByClassName ) { + push.apply( results, context.getElementsByClassName( m ) ); + return results; + } + } + + // QSA path + if ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) { + nid = old = expando; + newContext = context; + newSelector = nodeType !== 1 && selector; + + // qSA works strangely on Element-rooted queries + // We can work around this by specifying an extra ID on the root + // and working up from there (Thanks to Andrew Dupont for the technique) + // IE 8 doesn't work on object elements + if ( nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + groups = tokenize( selector ); + + if ( (old = context.getAttribute("id")) ) { + nid = old.replace( rescape, "\\$&" ); + } else { + context.setAttribute( "id", nid ); + } + nid = "[id='" + nid + "'] "; + + i = groups.length; + while ( i-- ) { + groups[i] = nid + toSelector( groups[i] ); + } + newContext = rsibling.test( selector ) && testContext( context.parentNode ) || context; + newSelector = groups.join(","); + } + + if ( newSelector ) { + try { + push.apply( results, + newContext.querySelectorAll( newSelector ) + ); + return results; + } catch(qsaError) { + } finally { + if ( !old ) { + context.removeAttribute("id"); + } + } + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed ); +} + +/** + * Create key-value caches of limited size + * @returns {Function(string, Object)} Returns the Object data after storing it on itself with + * property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength) + * deleting the oldest entry + */ +function createCache() { + var keys = []; + + function cache( key, value ) { + // Use (key + " ") to avoid collision with native prototype properties (see Issue #157) + if ( keys.push( key + " " ) > Expr.cacheLength ) { + // Only keep the most recent entries + delete cache[ keys.shift() ]; + } + return (cache[ key + " " ] = value); + } + return cache; +} + +/** + * Mark a function for special use by Sizzle + * @param {Function} fn The function to mark + */ +function markFunction( fn ) { + fn[ expando ] = true; + return fn; +} + +/** + * Support testing using an element + * @param {Function} fn Passed the created div and expects a boolean result + */ +function assert( fn ) { + var div = document.createElement("div"); + + try { + return !!fn( div ); + } catch (e) { + return false; + } finally { + // Remove from its parent by default + if ( div.parentNode ) { + div.parentNode.removeChild( div ); + } + // release memory in IE + div = null; + } +} + +/** + * Adds the same handler for all of the specified attrs + * @param {String} attrs Pipe-separated list of attributes + * @param {Function} handler The method that will be applied + */ +function addHandle( attrs, handler ) { + var arr = attrs.split("|"), + i = attrs.length; + + while ( i-- ) { + Expr.attrHandle[ arr[i] ] = handler; + } +} + +/** + * Checks document order of two siblings + * @param {Element} a + * @param {Element} b + * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b + */ +function siblingCheck( a, b ) { + var cur = b && a, + diff = cur && a.nodeType === 1 && b.nodeType === 1 && + ( ~b.sourceIndex || MAX_NEGATIVE ) - + ( ~a.sourceIndex || MAX_NEGATIVE ); + + // Use IE sourceIndex if available on both nodes + if ( diff ) { + return diff; + } + + // Check if b follows a + if ( cur ) { + while ( (cur = cur.nextSibling) ) { + if ( cur === b ) { + return -1; + } + } + } + + return a ? 1 : -1; +} + +/** + * Returns a function to use in pseudos for input types + * @param {String} type + */ +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for buttons + * @param {String} type + */ +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; +} + +/** + * Returns a function to use in pseudos for positionals + * @param {Function} fn + */ +function createPositionalPseudo( fn ) { + return markFunction(function( argument ) { + argument = +argument; + return markFunction(function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ (j = matchIndexes[i]) ] ) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); +} + +/** + * Checks a node for validity as a Sizzle context + * @param {Element|Object=} context + * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value + */ +function testContext( context ) { + return context && typeof context.getElementsByTagName !== "undefined" && context; +} + +// Expose support vars for convenience +support = Sizzle.support = {}; + +/** + * Detects XML nodes + * @param {Element|Object} elem An element or a document + * @returns {Boolean} True iff elem is a non-HTML XML node + */ +isXML = Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = elem && (elem.ownerDocument || elem).documentElement; + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +/** + * Sets document-related variables once based on the current document + * @param {Element|Object} [doc] An element or document object to use to set the document + * @returns {Object} Returns the current document + */ +setDocument = Sizzle.setDocument = function( node ) { + var hasCompare, parent, + doc = node ? node.ownerDocument || node : preferredDoc; + + // If no document and documentElement is available, return + if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) { + return document; + } + + // Set our document + document = doc; + docElem = doc.documentElement; + parent = doc.defaultView; + + // Support: IE>8 + // If iframe document is assigned to "document" variable and if iframe has been reloaded, + // IE will throw "permission denied" error when accessing "document" variable, see jQuery #13936 + // IE6-8 do not support the defaultView property so parent will be undefined + if ( parent && parent !== parent.top ) { + // IE11 does not have attachEvent, so all must suffer + if ( parent.addEventListener ) { + parent.addEventListener( "unload", unloadHandler, false ); + } else if ( parent.attachEvent ) { + parent.attachEvent( "onunload", unloadHandler ); + } + } + + /* Support tests + ---------------------------------------------------------------------- */ + documentIsHTML = !isXML( doc ); + + /* Attributes + ---------------------------------------------------------------------- */ + + // Support: IE<8 + // Verify that getAttribute really returns attributes and not properties + // (excepting IE8 booleans) + support.attributes = assert(function( div ) { + div.className = "i"; + return !div.getAttribute("className"); + }); + + /* getElement(s)By* + ---------------------------------------------------------------------- */ + + // Check if getElementsByTagName("*") returns only elements + support.getElementsByTagName = assert(function( div ) { + div.appendChild( doc.createComment("") ); + return !div.getElementsByTagName("*").length; + }); + + // Support: IE<9 + support.getElementsByClassName = rnative.test( doc.getElementsByClassName ); + + // Support: IE<10 + // Check if getElementById returns elements by name + // The broken getElementById methods don't pick up programatically-set names, + // so use a roundabout getElementsByName test + support.getById = assert(function( div ) { + docElem.appendChild( div ).id = expando; + return !doc.getElementsByName || !doc.getElementsByName( expando ).length; + }); + + // ID find and filter + if ( support.getById ) { + Expr.find["ID"] = function( id, context ) { + if ( typeof context.getElementById !== "undefined" && documentIsHTML ) { + var m = context.getElementById( id ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [ m ] : []; + } + }; + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + return elem.getAttribute("id") === attrId; + }; + }; + } else { + // Support: IE6/7 + // getElementById is not reliable as a find shortcut + delete Expr.find["ID"]; + + Expr.filter["ID"] = function( id ) { + var attrId = id.replace( runescape, funescape ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id"); + return node && node.value === attrId; + }; + }; + } + + // Tag + Expr.find["TAG"] = support.getElementsByTagName ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== "undefined" ) { + return context.getElementsByTagName( tag ); + + // DocumentFragment nodes don't have gEBTN + } else if ( support.qsa ) { + return context.querySelectorAll( tag ); + } + } : + + function( tag, context ) { + var elem, + tmp = [], + i = 0, + // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too + results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + while ( (elem = results[i++]) ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }; + + // Class + Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) { + if ( documentIsHTML ) { + return context.getElementsByClassName( className ); + } + }; + + /* QSA/matchesSelector + ---------------------------------------------------------------------- */ + + // QSA and matchesSelector support + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + rbuggyMatches = []; + + // qSa(:focus) reports false when true (Chrome 21) + // We allow this because of a bug in IE8/9 that throws an error + // whenever `document.activeElement` is accessed on an iframe + // So, we allow :focus to pass through QSA all the time to avoid the IE error + // See http://bugs.jquery.com/ticket/13378 + rbuggyQSA = []; + + if ( (support.qsa = rnative.test( doc.querySelectorAll )) ) { + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert(function( div ) { + // Select is set to empty string on purpose + // This is to test IE's treatment of not explicitly + // setting a boolean content attribute, + // since its presence should be enough + // http://bugs.jquery.com/ticket/12359 + docElem.appendChild( div ).innerHTML = "<a id='" + expando + "'></a>" + + "<select id='" + expando + "-\f]' msallowcapture=''>" + + "<option selected=''></option></select>"; + + // Support: IE8, Opera 11-12.16 + // Nothing should be selected when empty strings follow ^= or $= or *= + // The test attribute must be unknown in Opera but "safe" for WinRT + // http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section + if ( div.querySelectorAll("[msallowcapture^='']").length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" ); + } + + // Support: IE8 + // Boolean attributes and "value" are not treated correctly + if ( !div.querySelectorAll("[selected]").length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" ); + } + + // Support: Chrome<29, Android<4.2+, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.7+ + if ( !div.querySelectorAll( "[id~=" + expando + "-]" ).length ) { + rbuggyQSA.push("~="); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":checked").length ) { + rbuggyQSA.push(":checked"); + } + + // Support: Safari 8+, iOS 8+ + // https://bugs.webkit.org/show_bug.cgi?id=136851 + // In-page `selector#id sibing-combinator selector` fails + if ( !div.querySelectorAll( "a#" + expando + "+*" ).length ) { + rbuggyQSA.push(".#.+[+~]"); + } + }); + + assert(function( div ) { + // Support: Windows 8 Native Apps + // The type and name attributes are restricted during .innerHTML assignment + var input = doc.createElement("input"); + input.setAttribute( "type", "hidden" ); + div.appendChild( input ).setAttribute( "name", "D" ); + + // Support: IE8 + // Enforce case-sensitivity of name attribute + if ( div.querySelectorAll("[name=d]").length ) { + rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here and will not see later tests + if ( !div.querySelectorAll(":enabled").length ) { + rbuggyQSA.push( ":enabled", ":disabled" ); + } + + // Opera 10-11 does not throw on post-comma invalid pseudos + div.querySelectorAll("*,:x"); + rbuggyQSA.push(",.*:"); + }); + } + + if ( (support.matchesSelector = rnative.test( (matches = docElem.matches || + docElem.webkitMatchesSelector || + docElem.mozMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector) )) ) { + + assert(function( div ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + support.disconnectedMatch = matches.call( div, "div" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + matches.call( div, "[s!='']:x" ); + rbuggyMatches.push( "!=", pseudos ); + }); + } + + rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") ); + rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") ); + + /* Contains + ---------------------------------------------------------------------- */ + hasCompare = rnative.test( docElem.compareDocumentPosition ); + + // Element contains another + // Purposefully does not implement inclusive descendent + // As in, an element does not contain itself + contains = hasCompare || rnative.test( docElem.contains ) ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && ( + adown.contains ? + adown.contains( bup ) : + a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16 + )); + } : + function( a, b ) { + if ( b ) { + while ( (b = b.parentNode) ) { + if ( b === a ) { + return true; + } + } + } + return false; + }; + + /* Sorting + ---------------------------------------------------------------------- */ + + // Document order sorting + sortOrder = hasCompare ? + function( a, b ) { + + // Flag for duplicate removal + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + // Sort on method existence if only one input has compareDocumentPosition + var compare = !a.compareDocumentPosition - !b.compareDocumentPosition; + if ( compare ) { + return compare; + } + + // Calculate position if both inputs belong to the same document + compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ? + a.compareDocumentPosition( b ) : + + // Otherwise we know they are disconnected + 1; + + // Disconnected nodes + if ( compare & 1 || + (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) { + + // Choose the first element that is related to our preferred document + if ( a === doc || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) { + return -1; + } + if ( b === doc || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) { + return 1; + } + + // Maintain original order + return sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + } + + return compare & 4 ? -1 : 1; + } : + function( a, b ) { + // Exit early if the nodes are identical + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + var cur, + i = 0, + aup = a.parentNode, + bup = b.parentNode, + ap = [ a ], + bp = [ b ]; + + // Parentless nodes are either documents or disconnected + if ( !aup || !bup ) { + return a === doc ? -1 : + b === doc ? 1 : + aup ? -1 : + bup ? 1 : + sortInput ? + ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) : + 0; + + // If the nodes are siblings, we can do a quick check + } else if ( aup === bup ) { + return siblingCheck( a, b ); + } + + // Otherwise we need full lists of their ancestors for comparison + cur = a; + while ( (cur = cur.parentNode) ) { + ap.unshift( cur ); + } + cur = b; + while ( (cur = cur.parentNode) ) { + bp.unshift( cur ); + } + + // Walk down the tree looking for a discrepancy + while ( ap[i] === bp[i] ) { + i++; + } + + return i ? + // Do a sibling check if the nodes have a common ancestor + siblingCheck( ap[i], bp[i] ) : + + // Otherwise nodes in our document sort first + ap[i] === preferredDoc ? -1 : + bp[i] === preferredDoc ? 1 : + 0; + }; + + return doc; +}; + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + // Make sure that attribute selectors are quoted + expr = expr.replace( rattributeQuotes, "='$1']" ); + + if ( support.matchesSelector && documentIsHTML && + ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) && + ( !rbuggyQSA || !rbuggyQSA.test( expr ) ) ) { + + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || support.disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch (e) {} + } + + return Sizzle( expr, document, null, [ elem ] ).length > 0; +}; + +Sizzle.contains = function( context, elem ) { + // Set document vars if needed + if ( ( context.ownerDocument || context ) !== document ) { + setDocument( context ); + } + return contains( context, elem ); +}; + +Sizzle.attr = function( elem, name ) { + // Set document vars if needed + if ( ( elem.ownerDocument || elem ) !== document ) { + setDocument( elem ); + } + + var fn = Expr.attrHandle[ name.toLowerCase() ], + // Don't get fooled by Object.prototype properties (jQuery #13807) + val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ? + fn( elem, name, !documentIsHTML ) : + undefined; + + return val !== undefined ? + val : + support.attributes || !documentIsHTML ? + elem.getAttribute( name ) : + (val = elem.getAttributeNode(name)) && val.specified ? + val.value : + null; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +/** + * Document sorting and removing duplicates + * @param {ArrayLike} results + */ +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + j = 0, + i = 0; + + // Unless we *know* we can detect duplicates, assume their presence + hasDuplicate = !support.detectDuplicates; + sortInput = !support.sortStable && results.slice( 0 ); + results.sort( sortOrder ); + + if ( hasDuplicate ) { + while ( (elem = results[i++]) ) { + if ( elem === results[ i ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + // Clear input after sorting to release objects + // See https://github.com/jquery/sizzle/pull/225 + sortInput = null; + + return results; +}; + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( !nodeType ) { + // If no nodeType, this is expected to be an array + while ( (node = elem[i++]) ) { + // Do not traverse comment nodes + ret += getText( node ); + } + } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements + // innerText usage removed for consistency of new lines (jQuery #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + // Do not include comment or processing instruction nodes + + return ret; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + attrHandle: {}, + + find: {}, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[1] = match[1].replace( runescape, funescape ); + + // Move the given value to match[3] whether quoted or unquoted + match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape ); + + if ( match[2] === "~=" ) { + match[3] = " " + match[3] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 what (child|of-type) + 3 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 4 xn-component of xn+y argument ([+-]?\d*n|) + 5 sign of xn-component + 6 x of xn-component + 7 sign of y-component + 8 y of y-component + */ + match[1] = match[1].toLowerCase(); + + if ( match[1].slice( 0, 3 ) === "nth" ) { + // nth-* requires argument + if ( !match[3] ) { + Sizzle.error( match[0] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) ); + match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" ); + + // other types prohibit arguments + } else if ( match[3] ) { + Sizzle.error( match[0] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var excess, + unquoted = !match[6] && match[2]; + + if ( matchExpr["CHILD"].test( match[0] ) ) { + return null; + } + + // Accept quoted arguments as-is + if ( match[3] ) { + match[2] = match[4] || match[5] || ""; + + // Strip excess characters from unquoted arguments + } else if ( unquoted && rpseudo.test( unquoted ) && + // Get excess from tokenize (recursively) + (excess = tokenize( unquoted, true )) && + // advance to the next closing parenthesis + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + + // excess is a negative index + match[0] = match[0].slice( 0, excess ); + match[2] = unquoted.slice( 0, excess ); + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + + "TAG": function( nodeNameSelector ) { + var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase(); + return nodeNameSelector === "*" ? + function() { return true; } : + function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ className + " " ]; + + return pattern || + (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && + classCache( className, function( elem ) { + return pattern.test( typeof elem.className === "string" && elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" ); + }); + }, + + "ATTR": function( name, operator, check ) { + return function( elem ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.slice( -check.length ) === check : + operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" : + false; + }; + }, + + "CHILD": function( type, what, argument, first, last ) { + var simple = type.slice( 0, 3 ) !== "nth", + forward = type.slice( -4 ) !== "last", + ofType = what === "of-type"; + + return first === 1 && last === 0 ? + + // Shortcut for :nth-*(n) + function( elem ) { + return !!elem.parentNode; + } : + + function( elem, context, xml ) { + var cache, outerCache, node, diff, nodeIndex, start, + dir = simple !== forward ? "nextSibling" : "previousSibling", + parent = elem.parentNode, + name = ofType && elem.nodeName.toLowerCase(), + useCache = !xml && !ofType; + + if ( parent ) { + + // :(first|last|only)-(child|of-type) + if ( simple ) { + while ( dir ) { + node = elem; + while ( (node = node[ dir ]) ) { + if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) { + return false; + } + } + // Reverse direction for :only-* (if we haven't yet done so) + start = dir = type === "only" && !start && "nextSibling"; + } + return true; + } + + start = [ forward ? parent.firstChild : parent.lastChild ]; + + // non-xml :nth-child(...) stores cache data on `parent` + if ( forward && useCache ) { + // Seek `elem` from a previously-cached index + outerCache = parent[ expando ] || (parent[ expando ] = {}); + cache = outerCache[ type ] || []; + nodeIndex = cache[0] === dirruns && cache[1]; + diff = cache[0] === dirruns && cache[2]; + node = nodeIndex && parent.childNodes[ nodeIndex ]; + + while ( (node = ++nodeIndex && node && node[ dir ] || + + // Fallback to seeking `elem` from the start + (diff = nodeIndex = 0) || start.pop()) ) { + + // When found, cache indexes on `parent` and break + if ( node.nodeType === 1 && ++diff && node === elem ) { + outerCache[ type ] = [ dirruns, nodeIndex, diff ]; + break; + } + } + + // Use previously-cached element index if available + } else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) { + diff = cache[1]; + + // xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...) + } else { + // Use the same loop as above to seek `elem` from the start + while ( (node = ++nodeIndex && node && node[ dir ] || + (diff = nodeIndex = 0) || start.pop()) ) { + + if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) { + // Cache the index of each encountered element + if ( useCache ) { + (node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ]; + } + + if ( node === elem ) { + break; + } + } + } + } + + // Incorporate the offset, then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction(function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf( seed, matched[i] ); + seed[ idx ] = !( matches[ idx ] = matched[i] ); + } + }) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + // Potentially complex pseudos + "not": markFunction(function( selector ) { + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction(function( seed, matches, context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( (elem = unmatched[i]) ) { + seed[i] = !(matches[i] = elem); + } + } + }) : + function( elem, context, xml ) { + input[0] = elem; + matcher( input, null, xml, results ); + // Don't keep the element (issue #299) + input[0] = null; + return !results.pop(); + }; + }), + + "has": markFunction(function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + }), + + "contains": markFunction(function( text ) { + text = text.replace( runescape, funescape ); + return function( elem ) { + return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; + }; + }), + + // "Whether an element is represented by a :lang() selector + // is based solely on the element's language value + // being equal to the identifier C, + // or beginning with the identifier C immediately followed by "-". + // The matching of C against the element's language value is performed case-insensitively. + // The identifier C does not have to be a valid language name." + // http://www.w3.org/TR/selectors/#lang-pseudo + "lang": markFunction( function( lang ) { + // lang value must be a valid identifier + if ( !ridentifier.test(lang || "") ) { + Sizzle.error( "unsupported lang: " + lang ); + } + lang = lang.replace( runescape, funescape ).toLowerCase(); + return function( elem ) { + var elemLang; + do { + if ( (elemLang = documentIsHTML ? + elem.lang : + elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) { + + elemLang = elemLang.toLowerCase(); + return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0; + } + } while ( (elem = elem.parentNode) && elem.nodeType === 1 ); + return false; + }; + }), + + // Miscellaneous + "target": function( elem ) { + var hash = window.location && window.location.hash; + return hash && hash.slice( 1 ) === elem.id; + }, + + "root": function( elem ) { + return elem === docElem; + }, + + "focus": function( elem ) { + return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); + }, + + // Boolean properties + "enabled": function( elem ) { + return elem.disabled === false; + }, + + "disabled": function( elem ) { + return elem.disabled === true; + }, + + "checked": function( elem ) { + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); + }, + + "selected": function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + // Contents + "empty": function( elem ) { + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5), + // but not by others (comment: 8; processing instruction: 7; etc.) + // nodeType < 6 works because attributes (2) do not appear as children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + if ( elem.nodeType < 6 ) { + return false; + } + } + return true; + }, + + "parent": function( elem ) { + return !Expr.pseudos["empty"]( elem ); + }, + + // Element/input types + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "text": function( elem ) { + var attr; + return elem.nodeName.toLowerCase() === "input" && + elem.type === "text" && + + // Support: IE<8 + // New HTML5 attribute values (e.g., "search") appear with elem.type === "text" + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" ); + }, + + // Position-in-collection + "first": createPositionalPseudo(function() { + return [ 0 ]; + }), + + "last": createPositionalPseudo(function( matchIndexes, length ) { + return [ length - 1 ]; + }), + + "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + }), + + "even": createPositionalPseudo(function( matchIndexes, length ) { + var i = 0; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "odd": createPositionalPseudo(function( matchIndexes, length ) { + var i = 1; + for ( ; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { + var i = argument < 0 ? argument + length : argument; + for ( ; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }) + } +}; + +Expr.pseudos["nth"] = Expr.pseudos["eq"]; + +// Add button/input type pseudos +for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) { + Expr.pseudos[ i ] = createInputPseudo( i ); +} +for ( i in { submit: true, reset: true } ) { + Expr.pseudos[ i ] = createButtonPseudo( i ); +} + +// Easy API for creating new setFilters +function setFilters() {} +setFilters.prototype = Expr.filters = Expr.pseudos; +Expr.setFilters = new setFilters(); + +tokenize = Sizzle.tokenize = function( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( match ) { + // Don't consume trailing commas as valid + soFar = soFar.slice( match[0].length ) || soFar; + } + groups.push( (tokens = []) ); + } + + matched = false; + + // Combinators + if ( (match = rcombinators.exec( soFar )) ) { + matched = match.shift(); + tokens.push({ + value: matched, + // Cast descendant combinators to space + type: match[0].replace( rtrim, " " ) + }); + soFar = soFar.slice( matched.length ); + } + + // Filters + for ( type in Expr.filter ) { + if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || + (match = preFilters[ type ]( match ))) ) { + matched = match.shift(); + tokens.push({ + value: matched, + type: type, + matches: match + }); + soFar = soFar.slice( matched.length ); + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +}; + +function toSelector( tokens ) { + var i = 0, + len = tokens.length, + selector = ""; + for ( ; i < len; i++ ) { + selector += tokens[i].value; + } + return selector; +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + checkNonElements = base && dir === "parentNode", + doneName = done++; + + return combinator.first ? + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + return matcher( elem, context, xml ); + } + } + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + var oldCache, outerCache, + newCache = [ dirruns, doneName ]; + + // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching + if ( xml ) { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + if ( matcher( elem, context, xml ) ) { + return true; + } + } + } + } else { + while ( (elem = elem[ dir ]) ) { + if ( elem.nodeType === 1 || checkNonElements ) { + outerCache = elem[ expando ] || (elem[ expando ] = {}); + if ( (oldCache = outerCache[ dir ]) && + oldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) { + + // Assign to newCache so results back-propagate to previous elements + return (newCache[ 2 ] = oldCache[ 2 ]); + } else { + // Reuse newcache so results back-propagate to previous elements + outerCache[ dir ] = newCache; + + // A match means we're done; a fail means we have to keep checking + if ( (newCache[ 2 ] = matcher( elem, context, xml )) ) { + return true; + } + } + } + } + } + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[i]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[0]; +} + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[i], results ); + } + return results; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( (elem = unmatched[i]) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction(function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( (elem = temp[i]) ) { + matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) ) { + // Restore matcherIn since elem is not yet a final match + temp.push( (matcherIn[i] = elem) ); + } + } + postFinder( null, (matcherOut = []), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) && + (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) { + + seed[temp] = !(results[temp] = elem); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + }); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[0].type ], + implicitRelative = leadingRelative || Expr.relative[" "], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + (checkContext = context).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + // Avoid hanging onto element (issue #299) + checkContext = null; + return ret; + } ]; + + for ( ; i < len; i++ ) { + if ( (matcher = Expr.relative[ tokens[i].type ]) ) { + matchers = [ addCombinator(elementMatcher( matchers ), matcher) ]; + } else { + matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[j].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && toSelector( + // If the preceding token was a descendant combinator, insert an implicit any-element `*` + tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === " " ? "*" : "" }) + ).replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), + j < len && toSelector( tokens ) + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, outermost ) { + var elem, j, matcher, + matchedCount = 0, + i = "0", + unmatched = seed && [], + setMatched = [], + contextBackup = outermostContext, + // We must always have either seed elements or outermost context + elems = seed || byElement && Expr.find["TAG"]( "*", outermost ), + // Use integer dirruns iff this is the outermost matcher + dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1), + len = elems.length; + + if ( outermost ) { + outermostContext = context !== document && context; + } + + // Add elements passing elementMatchers directly to results + // Keep `i` a string if there are no elements so `matchedCount` will be "00" below + // Support: IE<9, Safari + // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by id + for ( ; i !== len && (elem = elems[i]) != null; i++ ) { + if ( byElement && elem ) { + j = 0; + while ( (matcher = elementMatchers[j++]) ) { + if ( matcher( elem, context, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + // They will have gone through all possible matchers + if ( (elem = !matcher && elem) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // Apply set filters to unmatched elements + matchedCount += i; + if ( bySet && i !== matchedCount ) { + j = 0; + while ( (matcher = setMatchers[j++]) ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !(unmatched[i] || setMatched[i]) ) { + setMatched[i] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ selector + " " ]; + + if ( !cached ) { + // Generate a function of recursive functions that can be used to check each element + if ( !match ) { + match = tokenize( selector ); + } + i = match.length; + while ( i-- ) { + cached = matcherFromTokens( match[i] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); + + // Save selector and tokenization + cached.selector = selector; + } + return cached; +}; + +/** + * A low-level selection function that works with Sizzle's compiled + * selector functions + * @param {String|Function} selector A selector or a pre-compiled + * selector function built with Sizzle.compile + * @param {Element} context + * @param {Array} [results] + * @param {Array} [seed] A set of elements to match against + */ +select = Sizzle.select = function( selector, context, results, seed ) { + var i, tokens, token, type, find, + compiled = typeof selector === "function" && selector, + match = !seed && tokenize( (selector = compiled.selector || selector) ); + + results = results || []; + + // Try to minimize operations if there is no seed and only one group + if ( match.length === 1 ) { + + // Take a shortcut and set the context if the root selector is an ID + tokens = match[0] = match[0].slice( 0 ); + if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && + support.getById && context.nodeType === 9 && documentIsHTML && + Expr.relative[ tokens[1].type ] ) { + + context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0]; + if ( !context ) { + return results; + + // Precompiled matchers will still verify ancestry, so step up a level + } else if ( compiled ) { + context = context.parentNode; + } + + selector = selector.slice( tokens.shift().value.length ); + } + + // Fetch a seed set for right-to-left matching + i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length; + while ( i-- ) { + token = tokens[i]; + + // Abort if we hit a combinator + if ( Expr.relative[ (type = token.type) ] ) { + break; + } + if ( (find = Expr.find[ type ]) ) { + // Search, expanding context for leading sibling combinators + if ( (seed = find( + token.matches[0].replace( runescape, funescape ), + rsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context + )) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && toSelector( tokens ); + if ( !selector ) { + push.apply( results, seed ); + return results; + } + + break; + } + } + } + } + + // Compile and execute a filtering function if one is not provided + // Provide `match` to avoid retokenization if we modified the selector above + ( compiled || compile( selector, match ) )( + seed, + context, + !documentIsHTML, + results, + rsibling.test( selector ) && testContext( context.parentNode ) || context + ); + return results; +}; + +// One-time assignments + +// Sort stability +support.sortStable = expando.split("").sort( sortOrder ).join("") === expando; + +// Support: Chrome 14-35+ +// Always assume duplicates if they aren't passed to the comparison function +support.detectDuplicates = !!hasDuplicate; + +// Initialize against the default document +setDocument(); + +// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27) +// Detached nodes confoundingly follow *each other* +support.sortDetached = assert(function( div1 ) { + // Should return 1, but returns 4 (following) + return div1.compareDocumentPosition( document.createElement("div") ) & 1; +}); + +// Support: IE<8 +// Prevent attribute/property "interpolation" +// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !assert(function( div ) { + div.innerHTML = "<a href='#'></a>"; + return div.firstChild.getAttribute("href") === "#" ; +}) ) { + addHandle( "type|href|height|width", function( elem, name, isXML ) { + if ( !isXML ) { + return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 ); + } + }); +} + +// Support: IE<9 +// Use defaultValue in place of getAttribute("value") +if ( !support.attributes || !assert(function( div ) { + div.innerHTML = "<input/>"; + div.firstChild.setAttribute( "value", "" ); + return div.firstChild.getAttribute( "value" ) === ""; +}) ) { + addHandle( "value", function( elem, name, isXML ) { + if ( !isXML && elem.nodeName.toLowerCase() === "input" ) { + return elem.defaultValue; + } + }); +} + +// Support: IE<9 +// Use getAttributeNode to fetch booleans when getAttribute lies +if ( !assert(function( div ) { + return div.getAttribute("disabled") == null; +}) ) { + addHandle( booleans, function( elem, name, isXML ) { + var val; + if ( !isXML ) { + return elem[ name ] === true ? name.toLowerCase() : + (val = elem.getAttributeNode( name )) && val.specified ? + val.value : + null; + } + }); +} + +return Sizzle; + +})( window ); + + + +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[":"] = jQuery.expr.pseudos; +jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + + +var rneedsContext = jQuery.expr.match.needsContext; + +var rsingleTag = (/^<(\w+)\s*\/?>(?:<\/\1>|)$/); + + + +var risSimple = /^.[^:#\[\.,]*$/; + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, not ) { + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep( elements, function( elem, i ) { + /* jshint -W018 */ + return !!qualifier.call( elem, i, elem ) !== not; + }); + + } + + if ( qualifier.nodeType ) { + return jQuery.grep( elements, function( elem ) { + return ( elem === qualifier ) !== not; + }); + + } + + if ( typeof qualifier === "string" ) { + if ( risSimple.test( qualifier ) ) { + return jQuery.filter( qualifier, elements, not ); + } + + qualifier = jQuery.filter( qualifier, elements ); + } + + return jQuery.grep( elements, function( elem ) { + return ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not; + }); +} + +jQuery.filter = function( expr, elems, not ) { + var elem = elems[ 0 ]; + + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 && elem.nodeType === 1 ? + jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] : + jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) { + return elem.nodeType === 1; + })); +}; + +jQuery.fn.extend({ + find: function( selector ) { + var i, + ret = [], + self = this, + len = self.length; + + if ( typeof selector !== "string" ) { + return this.pushStack( jQuery( selector ).filter(function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + }) ); + } + + for ( i = 0; i < len; i++ ) { + jQuery.find( selector, self[ i ], ret ); + } + + // Needed because $( selector, context ) becomes $( context ).find( selector ) + ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret ); + ret.selector = this.selector ? this.selector + " " + selector : selector; + return ret; + }, + filter: function( selector ) { + return this.pushStack( winnow(this, selector || [], false) ); + }, + not: function( selector ) { + return this.pushStack( winnow(this, selector || [], true) ); + }, + is: function( selector ) { + return !!winnow( + this, + + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + typeof selector === "string" && rneedsContext.test( selector ) ? + jQuery( selector ) : + selector || [], + false + ).length; + } +}); + + +// Initialize a jQuery object + + +// A central reference to the root jQuery(document) +var rootjQuery, + + // Use the correct document accordingly with window argument (sandbox) + document = window.document, + + // A simple way to check for HTML strings + // Prioritize #id over <tag> to avoid XSS via location.hash (#9521) + // Strict HTML recognition (#11290: must start with <) + rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, + + init = jQuery.fn.init = function( selector, context ) { + var match, elem; + + // HANDLE: $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) { + context = context instanceof jQuery ? context[0] : context; + + // scripts is true for back-compat + // Intentionally let the error be thrown if parseHTML is not present + jQuery.merge( this, jQuery.parseHTML( + match[1], + context && context.nodeType ? context.ownerDocument || context : document, + true + ) ); + + // HANDLE: $(html, props) + if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { + for ( match in context ) { + // Properties of context are called as methods if possible + if ( jQuery.isFunction( this[ match ] ) ) { + this[ match ]( context[ match ] ); + + // ...and otherwise set as attributes + } else { + this.attr( match, context[ match ] ); + } + } + } + + return this; + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[2] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id !== match[2] ) { + return rootjQuery.find( selector ); + } + + // Otherwise, we inject the element directly into the jQuery object + this.length = 1; + this[0] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || rootjQuery ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(DOMElement) + } else if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return typeof rootjQuery.ready !== "undefined" ? + rootjQuery.ready( selector ) : + // Execute immediately if ready is not present + selector( jQuery ); + } + + if ( selector.selector !== undefined ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return jQuery.makeArray( selector, this ); + }; + +// Give the init function the jQuery prototype for later instantiation +init.prototype = jQuery.fn; + +// Initialize central reference +rootjQuery = jQuery( document ); + + +var rparentsprev = /^(?:parents|prev(?:Until|All))/, + // methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.extend({ + dir: function( elem, dir, until ) { + var matched = [], + cur = elem[ dir ]; + + while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { + if ( cur.nodeType === 1 ) { + matched.push( cur ); + } + cur = cur[dir]; + } + return matched; + }, + + sibling: function( n, elem ) { + var r = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + r.push( n ); + } + } + + return r; + } +}); + +jQuery.fn.extend({ + has: function( target ) { + var i, + targets = jQuery( target, this ), + len = targets.length; + + return this.filter(function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( this, targets[i] ) ) { + return true; + } + } + }); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + matched = [], + pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( ; i < l; i++ ) { + for ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) { + // Always skip document fragments + if ( cur.nodeType < 11 && (pos ? + pos.index(cur) > -1 : + + // Don't pass non-elements to Sizzle + cur.nodeType === 1 && + jQuery.find.matchesSelector(cur, selectors)) ) { + + matched.push( cur ); + break; + } + } + } + + return this.pushStack( matched.length > 1 ? jQuery.unique( matched ) : matched ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1; + } + + // index in selector + if ( typeof elem === "string" ) { + return jQuery.inArray( this[0], jQuery( elem ) ); + } + + // Locate the position of the desired element + return jQuery.inArray( + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[0] : elem, this ); + }, + + add: function( selector, context ) { + return this.pushStack( + jQuery.unique( + jQuery.merge( this.get(), jQuery( selector, context ) ) + ) + ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter(selector) + ); + } +}); + +function sibling( cur, dir ) { + do { + cur = cur[ dir ]; + } while ( cur && cur.nodeType !== 1 ); + + return cur; +} + +jQuery.each({ + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return jQuery.dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return jQuery.dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return jQuery.dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return jQuery.dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return jQuery.dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return jQuery.dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return jQuery.sibling( elem.firstChild ); + }, + contents: function( elem ) { + return jQuery.nodeName( elem, "iframe" ) ? + elem.contentDocument || elem.contentWindow.document : + jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var ret = jQuery.map( this, fn, until ); + + if ( name.slice( -5 ) !== "Until" ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + ret = jQuery.filter( selector, ret ); + } + + if ( this.length > 1 ) { + // Remove duplicates + if ( !guaranteedUnique[ name ] ) { + ret = jQuery.unique( ret ); + } + + // Reverse order for parents* and prev-derivatives + if ( rparentsprev.test( name ) ) { + ret = ret.reverse(); + } + } + + return this.pushStack( ret ); + }; +}); +var rnotwhite = (/\S+/g); + + + +// String to Object options format cache +var optionsCache = {}; + +// Convert String-formatted options into Object-formatted ones and store in cache +function createOptions( options ) { + var object = optionsCache[ options ] = {}; + jQuery.each( options.match( rnotwhite ) || [], function( _, flag ) { + object[ flag ] = true; + }); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + ( optionsCache[ options ] || createOptions( options ) ) : + jQuery.extend( {}, options ); + + var // Flag to know if list is currently firing + firing, + // Last fire value (for non-forgettable lists) + memory, + // Flag to know if list was already fired + fired, + // End of the loop when firing + firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // First callback to fire (used internally by add and fireWith) + firingStart, + // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = !options.once && [], + // Fire callbacks + fire = function( data ) { + memory = options.memory && data; + fired = true; + firingIndex = firingStart || 0; + firingStart = 0; + firingLength = list.length; + firing = true; + for ( ; list && firingIndex < firingLength; firingIndex++ ) { + if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { + memory = false; // To prevent further calls using add + break; + } + } + firing = false; + if ( list ) { + if ( stack ) { + if ( stack.length ) { + fire( stack.shift() ); + } + } else if ( memory ) { + list = []; + } else { + self.disable(); + } + } + }, + // Actual Callbacks object + self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + // First, we save the current length + var start = list.length; + (function add( args ) { + jQuery.each( args, function( _, arg ) { + var type = jQuery.type( arg ); + if ( type === "function" ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && type !== "string" ) { + // Inspect recursively + add( arg ); + } + }); + })( arguments ); + // Do we need to add the callbacks to the + // current firing batch? + if ( firing ) { + firingLength = list.length; + // With memory, if we're not firing then + // we should call right away + } else if ( memory ) { + firingStart = start; + fire( memory ); + } + } + return this; + }, + // Remove a callback from the list + remove: function() { + if ( list ) { + jQuery.each( arguments, function( _, arg ) { + var index; + while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + // Handle firing indexes + if ( firing ) { + if ( index <= firingLength ) { + firingLength--; + } + if ( index <= firingIndex ) { + firingIndex--; + } + } + } + }); + } + return this; + }, + // Check if a given callback is in the list. + // If no argument is given, return whether or not list has callbacks attached. + has: function( fn ) { + return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length ); + }, + // Remove all callbacks from the list + empty: function() { + list = []; + firingLength = 0; + return this; + }, + // Have the list do nothing anymore + disable: function() { + list = stack = memory = undefined; + return this; + }, + // Is it disabled? + disabled: function() { + return !list; + }, + // Lock the list in its current state + lock: function() { + stack = undefined; + if ( !memory ) { + self.disable(); + } + return this; + }, + // Is it locked? + locked: function() { + return !stack; + }, + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + if ( list && ( !fired || stack ) ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + if ( firing ) { + stack.push( args ); + } else { + fire( args ); + } + } + return this; + }, + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; + + +jQuery.extend({ + + Deferred: function( func ) { + var tuples = [ + // action, add listener, listener list, final state + [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], + [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], + [ "notify", "progress", jQuery.Callbacks("memory") ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + then: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + return jQuery.Deferred(function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + var fn = jQuery.isFunction( fns[ i ] ) && fns[ i ]; + // deferred[ done | fail | progress ] for forwarding actions to newDefer + deferred[ tuple[1] ](function() { + var returned = fn && fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise() + .done( newDefer.resolve ) + .fail( newDefer.reject ) + .progress( newDefer.notify ); + } else { + newDefer[ tuple[ 0 ] + "With" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments ); + } + }); + }); + fns = null; + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Keep pipe for back-compat + promise.pipe = promise.then; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 3 ]; + + // promise[ done | fail | progress ] = list.add + promise[ tuple[1] ] = list.add; + + // Handle state + if ( stateString ) { + list.add(function() { + // state = [ resolved | rejected ] + state = stateString; + + // [ reject_list | resolve_list ].disable; progress_list.lock + }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); + } + + // deferred[ resolve | reject | notify ] + deferred[ tuple[0] ] = function() { + deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments ); + return this; + }; + deferred[ tuple[0] + "With" ] = list.fireWith; + }); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( subordinate /* , ..., subordinateN */ ) { + var i = 0, + resolveValues = slice.call( arguments ), + length = resolveValues.length, + + // the count of uncompleted subordinates + remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, + + // the master Deferred. If resolveValues consist of only a single Deferred, just use that. + deferred = remaining === 1 ? subordinate : jQuery.Deferred(), + + // Update function for both resolve and progress values + updateFunc = function( i, contexts, values ) { + return function( value ) { + contexts[ i ] = this; + values[ i ] = arguments.length > 1 ? slice.call( arguments ) : value; + if ( values === progressValues ) { + deferred.notifyWith( contexts, values ); + + } else if ( !(--remaining) ) { + deferred.resolveWith( contexts, values ); + } + }; + }, + + progressValues, progressContexts, resolveContexts; + + // add listeners to Deferred subordinates; treat others as resolved + if ( length > 1 ) { + progressValues = new Array( length ); + progressContexts = new Array( length ); + resolveContexts = new Array( length ); + for ( ; i < length; i++ ) { + if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { + resolveValues[ i ].promise() + .done( updateFunc( i, resolveContexts, resolveValues ) ) + .fail( deferred.reject ) + .progress( updateFunc( i, progressContexts, progressValues ) ); + } else { + --remaining; + } + } + } + + // if we're not waiting on anything, resolve the master + if ( !remaining ) { + deferred.resolveWith( resolveContexts, resolveValues ); + } + + return deferred.promise(); + } +}); + + +// The deferred used on DOM ready +var readyList; + +jQuery.fn.ready = function( fn ) { + // Add the callback + jQuery.ready.promise().done( fn ); + + return this; +}; + +jQuery.extend({ + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Hold (or release) the ready event + holdReady: function( hold ) { + if ( hold ) { + jQuery.readyWait++; + } else { + jQuery.ready( true ); + } + }, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( !document.body ) { + return setTimeout( jQuery.ready ); + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + + // Trigger any bound ready events + if ( jQuery.fn.triggerHandler ) { + jQuery( document ).triggerHandler( "ready" ); + jQuery( document ).off( "ready" ); + } + } +}); + +/** + * Clean-up method for dom ready events + */ +function detach() { + if ( document.addEventListener ) { + document.removeEventListener( "DOMContentLoaded", completed, false ); + window.removeEventListener( "load", completed, false ); + + } else { + document.detachEvent( "onreadystatechange", completed ); + window.detachEvent( "onload", completed ); + } +} + +/** + * The ready event handler and self cleanup method + */ +function completed() { + // readyState === "complete" is good enough for us to call the dom ready in oldIE + if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) { + detach(); + jQuery.ready(); + } +} + +jQuery.ready.promise = function( obj ) { + if ( !readyList ) { + + readyList = jQuery.Deferred(); + + // Catch cases where $(document).ready() is called after the browser event has already occurred. + // we once tried to use readyState "interactive" here, but it caused issues like the one + // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + setTimeout( jQuery.ready ); + + // Standards-based browsers support DOMContentLoaded + } else if ( document.addEventListener ) { + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", completed, false ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", completed, false ); + + // If IE event model is used + } else { + // Ensure firing before onload, maybe late but safe also for iframes + document.attachEvent( "onreadystatechange", completed ); + + // A fallback to window.onload, that will always work + window.attachEvent( "onload", completed ); + + // If IE and not a frame + // continually check to see if the document is ready + var top = false; + + try { + top = window.frameElement == null && document.documentElement; + } catch(e) {} + + if ( top && top.doScroll ) { + (function doScrollCheck() { + if ( !jQuery.isReady ) { + + try { + // Use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + top.doScroll("left"); + } catch(e) { + return setTimeout( doScrollCheck, 50 ); + } + + // detach all dom ready events + detach(); + + // and execute any waiting functions + jQuery.ready(); + } + })(); + } + } + } + return readyList.promise( obj ); +}; + + +var strundefined = typeof undefined; + + + +// Support: IE<9 +// Iteration over object's inherited properties before its own +var i; +for ( i in jQuery( support ) ) { + break; +} +support.ownLast = i !== "0"; + +// Note: most support tests are defined in their respective modules. +// false until the test is run +support.inlineBlockNeedsLayout = false; + +// Execute ASAP in case we need to set body.style.zoom +jQuery(function() { + // Minified: var a,b,c,d + var val, div, body, container; + + body = document.getElementsByTagName( "body" )[ 0 ]; + if ( !body || !body.style ) { + // Return for frameset docs that don't have a body + return; + } + + // Setup + div = document.createElement( "div" ); + container = document.createElement( "div" ); + container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px"; + body.appendChild( container ).appendChild( div ); + + if ( typeof div.style.zoom !== strundefined ) { + // Support: IE<8 + // Check if natively block-level elements act like inline-block + // elements when setting their display to 'inline' and giving + // them layout + div.style.cssText = "display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1"; + + support.inlineBlockNeedsLayout = val = div.offsetWidth === 3; + if ( val ) { + // Prevent IE 6 from affecting layout for positioned elements #11048 + // Prevent IE from shrinking the body in IE 7 mode #12869 + // Support: IE<8 + body.style.zoom = 1; + } + } + + body.removeChild( container ); +}); + + + + +(function() { + var div = document.createElement( "div" ); + + // Execute the test only if not already executed in another module. + if (support.deleteExpando == null) { + // Support: IE<9 + support.deleteExpando = true; + try { + delete div.test; + } catch( e ) { + support.deleteExpando = false; + } + } + + // Null elements to avoid leaks in IE. + div = null; +})(); + + +/** + * Determines whether an object can have data + */ +jQuery.acceptData = function( elem ) { + var noData = jQuery.noData[ (elem.nodeName + " ").toLowerCase() ], + nodeType = +elem.nodeType || 1; + + // Do not set data on non-element DOM nodes because it will not be cleared (#8335). + return nodeType !== 1 && nodeType !== 9 ? + false : + + // Nodes accept data unless otherwise specified; rejection can be conditional + !noData || noData !== true && elem.getAttribute("classid") === noData; +}; + + +var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, + rmultiDash = /([A-Z])/g; + +function dataAttr( elem, key, data ) { + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + + var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); + + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + // Only convert to a number if it doesn't change the string + +data + "" === data ? +data : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; + } catch( e ) {} + + // Make sure we set the data so it isn't changed later + jQuery.data( elem, key, data ); + + } else { + data = undefined; + } + } + + return data; +} + +// checks a cache object for emptiness +function isEmptyDataObject( obj ) { + var name; + for ( name in obj ) { + + // if the public data object is empty, the private is still empty + if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { + continue; + } + if ( name !== "toJSON" ) { + return false; + } + } + + return true; +} + +function internalData( elem, name, data, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var ret, thisCache, + internalKey = jQuery.expando, + + // We have to handle DOM nodes and JS objects differently because IE6-7 + // can't GC object references properly across the DOM-JS boundary + isNode = elem.nodeType, + + // Only DOM nodes need the global jQuery cache; JS object data is + // attached directly to the object so GC can occur automatically + cache = isNode ? jQuery.cache : elem, + + // Only defining an ID for JS objects if its cache already exists allows + // the code to shortcut on the same path as a DOM node with no cache + id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey; + + // Avoid doing any more work than we need to when trying to get data on an + // object that has no data at all + if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && data === undefined && typeof name === "string" ) { + return; + } + + if ( !id ) { + // Only DOM nodes need a new unique ID for each element since their data + // ends up in the global cache + if ( isNode ) { + id = elem[ internalKey ] = deletedIds.pop() || jQuery.guid++; + } else { + id = internalKey; + } + } + + if ( !cache[ id ] ) { + // Avoid exposing jQuery metadata on plain JS objects when the object + // is serialized using JSON.stringify + cache[ id ] = isNode ? {} : { toJSON: jQuery.noop }; + } + + // An object can be passed to jQuery.data instead of a key/value pair; this gets + // shallow copied over onto the existing cache + if ( typeof name === "object" || typeof name === "function" ) { + if ( pvt ) { + cache[ id ] = jQuery.extend( cache[ id ], name ); + } else { + cache[ id ].data = jQuery.extend( cache[ id ].data, name ); + } + } + + thisCache = cache[ id ]; + + // jQuery data() is stored in a separate object inside the object's internal data + // cache in order to avoid key collisions between internal data and user-defined + // data. + if ( !pvt ) { + if ( !thisCache.data ) { + thisCache.data = {}; + } + + thisCache = thisCache.data; + } + + if ( data !== undefined ) { + thisCache[ jQuery.camelCase( name ) ] = data; + } + + // Check for both converted-to-camel and non-converted data property names + // If a data property was specified + if ( typeof name === "string" ) { + + // First Try to find as-is property data + ret = thisCache[ name ]; + + // Test for null|undefined property data + if ( ret == null ) { + + // Try to find the camelCased property + ret = thisCache[ jQuery.camelCase( name ) ]; + } + } else { + ret = thisCache; + } + + return ret; +} + +function internalRemoveData( elem, name, pvt ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var thisCache, i, + isNode = elem.nodeType, + + // See jQuery.data for more information + cache = isNode ? jQuery.cache : elem, + id = isNode ? elem[ jQuery.expando ] : jQuery.expando; + + // If there is already no cache entry for this object, there is no + // purpose in continuing + if ( !cache[ id ] ) { + return; + } + + if ( name ) { + + thisCache = pvt ? cache[ id ] : cache[ id ].data; + + if ( thisCache ) { + + // Support array or space separated string names for data keys + if ( !jQuery.isArray( name ) ) { + + // try the string as a key before any manipulation + if ( name in thisCache ) { + name = [ name ]; + } else { + + // split the camel cased version by spaces unless a key with the spaces exists + name = jQuery.camelCase( name ); + if ( name in thisCache ) { + name = [ name ]; + } else { + name = name.split(" "); + } + } + } else { + // If "name" is an array of keys... + // When data is initially created, via ("key", "val") signature, + // keys will be converted to camelCase. + // Since there is no way to tell _how_ a key was added, remove + // both plain key and camelCase key. #12786 + // This will only penalize the array argument path. + name = name.concat( jQuery.map( name, jQuery.camelCase ) ); + } + + i = name.length; + while ( i-- ) { + delete thisCache[ name[i] ]; + } + + // If there is no data left in the cache, we want to continue + // and let the cache object itself get destroyed + if ( pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache) ) { + return; + } + } + } + + // See jQuery.data for more information + if ( !pvt ) { + delete cache[ id ].data; + + // Don't destroy the parent cache unless the internal data object + // had been the only thing left in it + if ( !isEmptyDataObject( cache[ id ] ) ) { + return; + } + } + + // Destroy the cache + if ( isNode ) { + jQuery.cleanData( [ elem ], true ); + + // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080) + /* jshint eqeqeq: false */ + } else if ( support.deleteExpando || cache != cache.window ) { + /* jshint eqeqeq: true */ + delete cache[ id ]; + + // When all else fails, null + } else { + cache[ id ] = null; + } +} + +jQuery.extend({ + cache: {}, + + // The following elements (space-suffixed to avoid Object.prototype collisions) + // throw uncatchable exceptions if you attempt to set expando properties + noData: { + "applet ": true, + "embed ": true, + // ...but Flash objects (which have this classid) *can* handle expandos + "object ": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" + }, + + hasData: function( elem ) { + elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; + return !!elem && !isEmptyDataObject( elem ); + }, + + data: function( elem, name, data ) { + return internalData( elem, name, data ); + }, + + removeData: function( elem, name ) { + return internalRemoveData( elem, name ); + }, + + // For internal use only. + _data: function( elem, name, data ) { + return internalData( elem, name, data, true ); + }, + + _removeData: function( elem, name ) { + return internalRemoveData( elem, name, true ); + } +}); + +jQuery.fn.extend({ + data: function( key, value ) { + var i, name, data, + elem = this[0], + attrs = elem && elem.attributes; + + // Special expections of .data basically thwart jQuery.access, + // so implement the relevant behavior ourselves + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = jQuery.data( elem ); + + if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { + i = attrs.length; + while ( i-- ) { + + // Support: IE11+ + // The attrs elements can be null (#14894) + if ( attrs[ i ] ) { + name = attrs[ i ].name; + if ( name.indexOf( "data-" ) === 0 ) { + name = jQuery.camelCase( name.slice(5) ); + dataAttr( elem, name, data[ name ] ); + } + } + } + jQuery._data( elem, "parsedAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each(function() { + jQuery.data( this, key ); + }); + } + + return arguments.length > 1 ? + + // Sets one value + this.each(function() { + jQuery.data( this, key, value ); + }) : + + // Gets one value + // Try to fetch any internally stored data first + elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : undefined; + }, + + removeData: function( key ) { + return this.each(function() { + jQuery.removeData( this, key ); + }); + } +}); + + +jQuery.extend({ + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = jQuery._data( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || jQuery.isArray(data) ) { + queue = jQuery._data( elem, type, jQuery.makeArray(data) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // not intended for public consumption - generates a queueHooks object, or returns the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return jQuery._data( elem, key ) || jQuery._data( elem, key, { + empty: jQuery.Callbacks("once memory").add(function() { + jQuery._removeData( elem, type + "queue" ); + jQuery._removeData( elem, key ); + }) + }); + } +}); + +jQuery.fn.extend({ + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[0], type ); + } + + return data === undefined ? + this : + this.each(function() { + var queue = jQuery.queue( this, type, data ); + + // ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[0] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + }); + }, + dequeue: function( type ) { + return this.each(function() { + jQuery.dequeue( this, type ); + }); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while ( i-- ) { + tmp = jQuery._data( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +}); +var pnum = (/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/).source; + +var cssExpand = [ "Top", "Right", "Bottom", "Left" ]; + +var isHidden = function( elem, el ) { + // isHidden might be called from jQuery#filter function; + // in that case, element will be second argument + elem = el || elem; + return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); + }; + + + +// Multifunctional method to get and set values of a collection +// The value/s can optionally be executed if it's a function +var access = jQuery.access = function( elems, fn, key, value, chainable, emptyGet, raw ) { + var i = 0, + length = elems.length, + bulk = key == null; + + // Sets many values + if ( jQuery.type( key ) === "object" ) { + chainable = true; + for ( i in key ) { + jQuery.access( elems, fn, i, key[i], true, emptyGet, raw ); + } + + // Sets one value + } else if ( value !== undefined ) { + chainable = true; + + if ( !jQuery.isFunction( value ) ) { + raw = true; + } + + if ( bulk ) { + // Bulk operations run against the entire set + if ( raw ) { + fn.call( elems, value ); + fn = null; + + // ...except when executing function values + } else { + bulk = fn; + fn = function( elem, key, value ) { + return bulk.call( jQuery( elem ), value ); + }; + } + } + + if ( fn ) { + for ( ; i < length; i++ ) { + fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) ); + } + } + } + + return chainable ? + elems : + + // Gets + bulk ? + fn.call( elems ) : + length ? fn( elems[0], key ) : emptyGet; +}; +var rcheckableType = (/^(?:checkbox|radio)$/i); + + + +(function() { + // Minified: var a,b,c + var input = document.createElement( "input" ), + div = document.createElement( "div" ), + fragment = document.createDocumentFragment(); + + // Setup + div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>"; + + // IE strips leading whitespace when .innerHTML is used + support.leadingWhitespace = div.firstChild.nodeType === 3; + + // Make sure that tbody elements aren't automatically inserted + // IE will insert them into empty tables + support.tbody = !div.getElementsByTagName( "tbody" ).length; + + // Make sure that link elements get serialized correctly by innerHTML + // This requires a wrapper element in IE + support.htmlSerialize = !!div.getElementsByTagName( "link" ).length; + + // Makes sure cloning an html5 element does not cause problems + // Where outerHTML is undefined, this still works + support.html5Clone = + document.createElement( "nav" ).cloneNode( true ).outerHTML !== "<:nav></:nav>"; + + // Check if a disconnected checkbox will retain its checked + // value of true after appended to the DOM (IE6/7) + input.type = "checkbox"; + input.checked = true; + fragment.appendChild( input ); + support.appendChecked = input.checked; + + // Make sure textarea (and checkbox) defaultValue is properly cloned + // Support: IE6-IE11+ + div.innerHTML = "<textarea>x</textarea>"; + support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue; + + // #11217 - WebKit loses check when the name is after the checked attribute + fragment.appendChild( div ); + div.innerHTML = "<input type='radio' checked='checked' name='t'/>"; + + // Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3 + // old WebKit doesn't clone checked state correctly in fragments + support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Support: IE<9 + // Opera does not clone events (and typeof div.attachEvent === undefined). + // IE9-10 clones events bound via attachEvent, but they don't trigger with .click() + support.noCloneEvent = true; + if ( div.attachEvent ) { + div.attachEvent( "onclick", function() { + support.noCloneEvent = false; + }); + + div.cloneNode( true ).click(); + } + + // Execute the test only if not already executed in another module. + if (support.deleteExpando == null) { + // Support: IE<9 + support.deleteExpando = true; + try { + delete div.test; + } catch( e ) { + support.deleteExpando = false; + } + } +})(); + + +(function() { + var i, eventName, + div = document.createElement( "div" ); + + // Support: IE<9 (lack submit/change bubble), Firefox 23+ (lack focusin event) + for ( i in { submit: true, change: true, focusin: true }) { + eventName = "on" + i; + + if ( !(support[ i + "Bubbles" ] = eventName in window) ) { + // Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP) + div.setAttribute( eventName, "t" ); + support[ i + "Bubbles" ] = div.attributes[ eventName ].expando === false; + } + } + + // Null elements to avoid leaks in IE. + div = null; +})(); + + +var rformElems = /^(?:input|select|textarea)$/i, + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|pointer|contextmenu)|click/, + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + rtypenamespace = /^([^.]*)(?:\.(.+)|)$/; + +function returnTrue() { + return true; +} + +function returnFalse() { + return false; +} + +function safeActiveElement() { + try { + return document.activeElement; + } catch ( err ) { } +} + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + global: {}, + + add: function( elem, types, handler, data, selector ) { + var tmp, events, t, handleObjIn, + special, eventHandle, handleObj, + handlers, type, namespaces, origType, + elemData = jQuery._data( elem ); + + // Don't attach events to noData or text/comment nodes (but allow plain objects) + if ( !elemData ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + if ( !(events = elemData.events) ) { + events = elemData.events = {}; + } + if ( !(eventHandle = elemData.handle) ) { + eventHandle = elemData.handle = function( e ) { + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== strundefined && (!e || jQuery.event.triggered !== e.type) ? + jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : + undefined; + }; + // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events + eventHandle.elem = elem; + } + + // Handle multiple events separated by a space + types = ( types || "" ).match( rnotwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[t] ) || []; + type = origType = tmp[1]; + namespaces = ( tmp[2] || "" ).split( "." ).sort(); + + // There *must* be a type, no attaching namespace-only handlers + if ( !type ) { + continue; + } + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend({ + type: type, + origType: origType, + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join(".") + }, handleObjIn ); + + // Init the event handler queue if we're the first + if ( !(handlers = events[ type ]) ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener/attachEvent if the special events handler returns false + if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + // Bind the global event handler to the element + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle, false ); + + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + // Nullify elem to prevent memory leaks in IE + elem = null; + }, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + var j, handleObj, tmp, + origCount, t, events, + special, handlers, type, + namespaces, origType, + elemData = jQuery.hasData( elem ) && jQuery._data( elem ); + + if ( !elemData || !(events = elemData.events) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = ( types || "" ).match( rnotwhite ) || [ "" ]; + t = types.length; + while ( t-- ) { + tmp = rtypenamespace.exec( types[t] ) || []; + type = origType = tmp[1]; + namespaces = ( tmp[2] || "" ).split( "." ).sort(); + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector ? special.delegateType : special.bindType ) || type; + handlers = events[ type ] || []; + tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ); + + // Remove matching events + origCount = j = handlers.length; + while ( j-- ) { + handleObj = handlers[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !tmp || tmp.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { + handlers.splice( j, 1 ); + + if ( handleObj.selector ) { + handlers.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( origCount && !handlers.length ) { + if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + delete elemData.handle; + + // removeData also checks for emptiness and clears the expando if empty + // so use it instead of delete + jQuery._removeData( elem, "events" ); + } + }, + + trigger: function( event, data, elem, onlyHandlers ) { + var handle, ontype, cur, + bubbleType, special, tmp, i, + eventPath = [ elem || document ], + type = hasOwn.call( event, "type" ) ? event.type : event, + namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : []; + + cur = tmp = elem = elem || document; + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf(".") >= 0 ) { + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split("."); + type = namespaces.shift(); + namespaces.sort(); + } + ontype = type.indexOf(":") < 0 && "on" + type; + + // Caller can pass in a jQuery.Event object, Object, or just an event type string + event = event[ jQuery.expando ] ? + event : + new jQuery.Event( type, typeof event === "object" && event ); + + // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true) + event.isTrigger = onlyHandlers ? 2 : 3; + event.namespace = namespaces.join("."); + event.namespace_re = event.namespace ? + new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) : + null; + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data == null ? + [ event ] : + jQuery.makeArray( data, [ event ] ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + if ( !rfocusMorph.test( bubbleType + type ) ) { + cur = cur.parentNode; + } + for ( ; cur; cur = cur.parentNode ) { + eventPath.push( cur ); + tmp = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( tmp === (elem.ownerDocument || document) ) { + eventPath.push( tmp.defaultView || tmp.parentWindow || window ); + } + } + + // Fire handlers on the event path + i = 0; + while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) { + + event.type = i > 1 ? + bubbleType : + special.bindType || type; + + // jQuery handler + handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + + // Native handler + handle = ontype && cur[ ontype ]; + if ( handle && handle.apply && jQuery.acceptData( cur ) ) { + event.result = handle.apply( cur, data ); + if ( event.result === false ) { + event.preventDefault(); + } + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) && + jQuery.acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name name as the event. + // Can't use an .isFunction() check here because IE6/7 fails that test. + // Don't do default actions on window, that's where global variables be (#6170) + if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + tmp = elem[ ontype ]; + + if ( tmp ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + try { + elem[ type ](); + } catch ( e ) { + // IE<9 dies on focus/blur to hidden element (#1486,#12518) + // only reproducible on winXP IE8 native, not IE9 in IE8 mode + } + jQuery.event.triggered = undefined; + + if ( tmp ) { + elem[ ontype ] = tmp; + } + } + } + } + + return event.result; + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event ); + + var i, ret, handleObj, matched, j, + handlerQueue = [], + args = slice.call( arguments ), + handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [], + special = jQuery.event.special[ event.type ] || {}; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[0] = event; + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers + handlerQueue = jQuery.event.handlers.call( this, event, handlers ); + + // Run delegates first; they may want to stop propagation beneath us + i = 0; + while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) { + event.currentTarget = matched.elem; + + j = 0; + while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) { + + // Triggered event must either 1) have no namespace, or + // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). + if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) { + + event.handleObj = handleObj; + event.data = handleObj.data; + + ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) + .apply( matched.elem, args ); + + if ( ret !== undefined ) { + if ( (event.result = ret) === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + handlers: function( event, handlers ) { + var sel, handleObj, matches, i, + handlerQueue = [], + delegateCount = handlers.delegateCount, + cur = event.target; + + // Find delegate handlers + // Black-hole SVG <use> instance trees (#13180) + // Avoid non-left-click bubbling in Firefox (#3861) + if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) { + + /* jshint eqeqeq: false */ + for ( ; cur != this; cur = cur.parentNode || this ) { + /* jshint eqeqeq: true */ + + // Don't check non-elements (#13208) + // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== "click") ) { + matches = []; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + + // Don't conflict with Object.prototype properties (#13203) + sel = handleObj.selector + " "; + + if ( matches[ sel ] === undefined ) { + matches[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) >= 0 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( matches[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push({ elem: cur, handlers: matches }); + } + } + } + } + + // Add the remaining (directly-bound) handlers + if ( delegateCount < handlers.length ) { + handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) }); + } + + return handlerQueue; + }, + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, copy, + type = event.type, + originalEvent = event, + fixHook = this.fixHooks[ type ]; + + if ( !fixHook ) { + this.fixHooks[ type ] = fixHook = + rmouseEvent.test( type ) ? this.mouseHooks : + rkeyEvent.test( type ) ? this.keyHooks : + {}; + } + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = new jQuery.Event( originalEvent ); + + i = copy.length; + while ( i-- ) { + prop = copy[ i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Support: IE<9 + // Fix target property (#1925) + if ( !event.target ) { + event.target = originalEvent.srcElement || document; + } + + // Support: Chrome 23+, Safari? + // Target should not be a text node (#504, #13143) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + // Support: IE<9 + // For mouse/key events, metaKey==false if it's undefined (#3368, #11328) + event.metaKey = !!event.metaKey; + + return fixHook.filter ? fixHook.filter( event, originalEvent ) : event; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), + + fixHooks: {}, + + keyHooks: { + props: "char charCode key keyCode".split(" "), + filter: function( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + filter: function( event, original ) { + var body, eventDoc, doc, + button = original.button, + fromElement = original.fromElement; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add relatedTarget, if necessary + if ( !event.relatedTarget && fromElement ) { + event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + special: { + load: { + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + focus: { + // Fire native event if possible so blur/focus sequence is correct + trigger: function() { + if ( this !== safeActiveElement() && this.focus ) { + try { + this.focus(); + return false; + } catch ( e ) { + // Support: IE<9 + // If we error on focus to hidden element (#1486, #12518), + // let .trigger() run the handlers + } + } + }, + delegateType: "focusin" + }, + blur: { + trigger: function() { + if ( this === safeActiveElement() && this.blur ) { + this.blur(); + return false; + } + }, + delegateType: "focusout" + }, + click: { + // For checkbox, fire native event so checked state will be right + trigger: function() { + if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) { + this.click(); + return false; + } + }, + + // For cross-browser consistency, don't fire native .click() on links + _default: function( event ) { + return jQuery.nodeName( event.target, "a" ); + } + }, + + beforeunload: { + postDispatch: function( event ) { + + // Support: Firefox 20+ + // Firefox doesn't alert if the returnValue field is not set. + if ( event.result !== undefined && event.originalEvent ) { + event.originalEvent.returnValue = event.result; + } + } + } + }, + + simulate: function( type, elem, event, bubble ) { + // Piggyback on a donor event to simulate a different one. + // Fake originalEvent to avoid donor's stopPropagation, but if the + // simulated event prevents default then we do the same on the donor. + var e = jQuery.extend( + new jQuery.Event(), + event, + { + type: type, + isSimulated: true, + originalEvent: {} + } + ); + if ( bubble ) { + jQuery.event.trigger( e, null, elem ); + } else { + jQuery.event.dispatch.call( elem, e ); + } + if ( e.isDefaultPrevented() ) { + event.preventDefault(); + } + } +}; + +jQuery.removeEvent = document.removeEventListener ? + function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } + } : + function( elem, type, handle ) { + var name = "on" + type; + + if ( elem.detachEvent ) { + + // #8545, #7054, preventing memory leaks for custom events in IE6-8 + // detachEvent needed property on element, by name of that event, to properly expose it to GC + if ( typeof elem[ name ] === strundefined ) { + elem[ name ] = null; + } + + elem.detachEvent( name, handle ); + } + }; + +jQuery.Event = function( src, props ) { + // Allow instantiation without the 'new' keyword + if ( !(this instanceof jQuery.Event) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = src.defaultPrevented || + src.defaultPrevented === undefined && + // Support: IE < 9, Android < 4.0 + src.returnValue === false ? + returnTrue : + returnFalse; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse, + + preventDefault: function() { + var e = this.originalEvent; + + this.isDefaultPrevented = returnTrue; + if ( !e ) { + return; + } + + // If preventDefault exists, run it on the original event + if ( e.preventDefault ) { + e.preventDefault(); + + // Support: IE + // Otherwise set the returnValue property of the original event to false + } else { + e.returnValue = false; + } + }, + stopPropagation: function() { + var e = this.originalEvent; + + this.isPropagationStopped = returnTrue; + if ( !e ) { + return; + } + // If stopPropagation exists, run it on the original event + if ( e.stopPropagation ) { + e.stopPropagation(); + } + + // Support: IE + // Set the cancelBubble property of the original event to true + e.cancelBubble = true; + }, + stopImmediatePropagation: function() { + var e = this.originalEvent; + + this.isImmediatePropagationStopped = returnTrue; + + if ( e && e.stopImmediatePropagation ) { + e.stopImmediatePropagation(); + } + + this.stopPropagation(); + } +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout", + pointerenter: "pointerover", + pointerleave: "pointerout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj; + + // For mousenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || (related !== target && !jQuery.contains( target, related )) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +}); + +// IE submit delegation +if ( !support.submitBubbles ) { + + jQuery.event.special.submit = { + setup: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Lazy-add a submit handler when a descendant form may potentially be submitted + jQuery.event.add( this, "click._submit keypress._submit", function( e ) { + // Node name check avoids a VML-related crash in IE (#9807) + var elem = e.target, + form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; + if ( form && !jQuery._data( form, "submitBubbles" ) ) { + jQuery.event.add( form, "submit._submit", function( event ) { + event._submit_bubble = true; + }); + jQuery._data( form, "submitBubbles", true ); + } + }); + // return undefined since we don't need an event listener + }, + + postDispatch: function( event ) { + // If form was submitted by the user, bubble the event up the tree + if ( event._submit_bubble ) { + delete event._submit_bubble; + if ( this.parentNode && !event.isTrigger ) { + jQuery.event.simulate( "submit", this.parentNode, event, true ); + } + } + }, + + teardown: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Remove delegated handlers; cleanData eventually reaps submit handlers attached above + jQuery.event.remove( this, "._submit" ); + } + }; +} + +// IE change delegation and checkbox/radio fix +if ( !support.changeBubbles ) { + + jQuery.event.special.change = { + + setup: function() { + + if ( rformElems.test( this.nodeName ) ) { + // IE doesn't fire change on a check/radio until blur; trigger it on click + // after a propertychange. Eat the blur-change in special.change.handle. + // This still fires onchange a second time for check/radio after blur. + if ( this.type === "checkbox" || this.type === "radio" ) { + jQuery.event.add( this, "propertychange._change", function( event ) { + if ( event.originalEvent.propertyName === "checked" ) { + this._just_changed = true; + } + }); + jQuery.event.add( this, "click._change", function( event ) { + if ( this._just_changed && !event.isTrigger ) { + this._just_changed = false; + } + // Allow triggered, simulated change events (#11500) + jQuery.event.simulate( "change", this, event, true ); + }); + } + return false; + } + // Delegated event; lazy-add a change handler on descendant inputs + jQuery.event.add( this, "beforeactivate._change", function( e ) { + var elem = e.target; + + if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "changeBubbles" ) ) { + jQuery.event.add( elem, "change._change", function( event ) { + if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { + jQuery.event.simulate( "change", this.parentNode, event, true ); + } + }); + jQuery._data( elem, "changeBubbles", true ); + } + }); + }, + + handle: function( event ) { + var elem = event.target; + + // Swallow native change events from checkbox/radio, we already triggered them above + if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { + return event.handleObj.handler.apply( this, arguments ); + } + }, + + teardown: function() { + jQuery.event.remove( this, "._change" ); + + return !rformElems.test( this.nodeName ); + } + }; +} + +// Create "bubbling" focus and blur events +if ( !support.focusinBubbles ) { + jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler on the document while someone wants focusin/focusout + var handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + var doc = this.ownerDocument || this, + attaches = jQuery._data( doc, fix ); + + if ( !attaches ) { + doc.addEventListener( orig, handler, true ); + } + jQuery._data( doc, fix, ( attaches || 0 ) + 1 ); + }, + teardown: function() { + var doc = this.ownerDocument || this, + attaches = jQuery._data( doc, fix ) - 1; + + if ( !attaches ) { + doc.removeEventListener( orig, handler, true ); + jQuery._removeData( doc, fix ); + } else { + jQuery._data( doc, fix, attaches ); + } + } + }; + }); +} + +jQuery.fn.extend({ + + on: function( types, selector, data, fn, /*INTERNAL*/ one ) { + var type, origFn; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + this.on( type, selector, data, types[ type ], one ); + } + return this; + } + + if ( data == null && fn == null ) { + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return this.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + }); + }, + one: function( types, selector, data, fn ) { + return this.on( types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each(function() { + jQuery.event.remove( this, types, fn, selector ); + }); + }, + + trigger: function( type, data ) { + return this.each(function() { + jQuery.event.trigger( type, data, this ); + }); + }, + triggerHandler: function( type, data ) { + var elem = this[0]; + if ( elem ) { + return jQuery.event.trigger( type, data, elem, true ); + } + } +}); + + +function createSafeFragment( document ) { + var list = nodeNames.split( "|" ), + safeFrag = document.createDocumentFragment(); + + if ( safeFrag.createElement ) { + while ( list.length ) { + safeFrag.createElement( + list.pop() + ); + } + } + return safeFrag; +} + +var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" + + "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", + rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g, + rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"), + rleadingWhitespace = /^\s+/, + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, + rtagName = /<([\w:]+)/, + rtbody = /<tbody/i, + rhtml = /<|&#?\w+;/, + rnoInnerhtml = /<(?:script|style|link)/i, + // checked="checked" or checked + rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, + rscriptType = /^$|\/(?:java|ecma)script/i, + rscriptTypeMasked = /^true\/(.*)/, + rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g, + + // We have to close these tags to support XHTML (#13200) + wrapMap = { + option: [ 1, "<select multiple='multiple'>", "</select>" ], + legend: [ 1, "<fieldset>", "</fieldset>" ], + area: [ 1, "<map>", "</map>" ], + param: [ 1, "<object>", "</object>" ], + thead: [ 1, "<table>", "</table>" ], + tr: [ 2, "<table><tbody>", "</tbody></table>" ], + col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ], + td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ], + + // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags, + // unless wrapped in a div with non-breaking characters in front of it. + _default: support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X<div>", "</div>" ] + }, + safeFragment = createSafeFragment( document ), + fragmentDiv = safeFragment.appendChild( document.createElement("div") ); + +wrapMap.optgroup = wrapMap.option; +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +function getAll( context, tag ) { + var elems, elem, + i = 0, + found = typeof context.getElementsByTagName !== strundefined ? context.getElementsByTagName( tag || "*" ) : + typeof context.querySelectorAll !== strundefined ? context.querySelectorAll( tag || "*" ) : + undefined; + + if ( !found ) { + for ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) { + if ( !tag || jQuery.nodeName( elem, tag ) ) { + found.push( elem ); + } else { + jQuery.merge( found, getAll( elem, tag ) ); + } + } + } + + return tag === undefined || tag && jQuery.nodeName( context, tag ) ? + jQuery.merge( [ context ], found ) : + found; +} + +// Used in buildFragment, fixes the defaultChecked property +function fixDefaultChecked( elem ) { + if ( rcheckableType.test( elem.type ) ) { + elem.defaultChecked = elem.checked; + } +} + +// Support: IE<8 +// Manipulating tables requires a tbody +function manipulationTarget( elem, content ) { + return jQuery.nodeName( elem, "table" ) && + jQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ? + + elem.getElementsByTagName("tbody")[0] || + elem.appendChild( elem.ownerDocument.createElement("tbody") ) : + elem; +} + +// Replace/restore the type attribute of script elements for safe DOM manipulation +function disableScript( elem ) { + elem.type = (jQuery.find.attr( elem, "type" ) !== null) + "/" + elem.type; + return elem; +} +function restoreScript( elem ) { + var match = rscriptTypeMasked.exec( elem.type ); + if ( match ) { + elem.type = match[1]; + } else { + elem.removeAttribute("type"); + } + return elem; +} + +// Mark scripts as having already been evaluated +function setGlobalEval( elems, refElements ) { + var elem, + i = 0; + for ( ; (elem = elems[i]) != null; i++ ) { + jQuery._data( elem, "globalEval", !refElements || jQuery._data( refElements[i], "globalEval" ) ); + } +} + +function cloneCopyEvent( src, dest ) { + + if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) { + return; + } + + var type, i, l, + oldData = jQuery._data( src ), + curData = jQuery._data( dest, oldData ), + events = oldData.events; + + if ( events ) { + delete curData.handle; + curData.events = {}; + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + + // make the cloned public data object a copy from the original + if ( curData.data ) { + curData.data = jQuery.extend( {}, curData.data ); + } +} + +function fixCloneNodeIssues( src, dest ) { + var nodeName, e, data; + + // We do not need to do anything for non-Elements + if ( dest.nodeType !== 1 ) { + return; + } + + nodeName = dest.nodeName.toLowerCase(); + + // IE6-8 copies events bound via attachEvent when using cloneNode. + if ( !support.noCloneEvent && dest[ jQuery.expando ] ) { + data = jQuery._data( dest ); + + for ( e in data.events ) { + jQuery.removeEvent( dest, e, data.handle ); + } + + // Event data gets referenced instead of copied if the expando gets copied too + dest.removeAttribute( jQuery.expando ); + } + + // IE blanks contents when cloning scripts, and tries to evaluate newly-set text + if ( nodeName === "script" && dest.text !== src.text ) { + disableScript( dest ).text = src.text; + restoreScript( dest ); + + // IE6-10 improperly clones children of object elements using classid. + // IE10 throws NoModificationAllowedError if parent is null, #12132. + } else if ( nodeName === "object" ) { + if ( dest.parentNode ) { + dest.outerHTML = src.outerHTML; + } + + // This path appears unavoidable for IE9. When cloning an object + // element in IE9, the outerHTML strategy above is not sufficient. + // If the src has innerHTML and the destination does not, + // copy the src.innerHTML into the dest.innerHTML. #10324 + if ( support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) { + dest.innerHTML = src.innerHTML; + } + + } else if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + // IE6-8 fails to persist the checked state of a cloned checkbox + // or radio button. Worse, IE6-7 fail to give the cloned element + // a checked appearance if the defaultChecked value isn't also set + + dest.defaultChecked = dest.checked = src.checked; + + // IE6-7 get confused and end up setting the value of a cloned + // checkbox/radio button to an empty string instead of "on" + if ( dest.value !== src.value ) { + dest.value = src.value; + } + + // IE6-8 fails to return the selected option to the default selected + // state when cloning options + } else if ( nodeName === "option" ) { + dest.defaultSelected = dest.selected = src.defaultSelected; + + // IE6-8 fails to set the defaultValue to the correct value when + // cloning other types of input fields + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + } +} + +jQuery.extend({ + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var destElements, node, clone, i, srcElements, + inPage = jQuery.contains( elem.ownerDocument, elem ); + + if ( support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) { + clone = elem.cloneNode( true ); + + // IE<=8 does not properly clone detached, unknown element nodes + } else { + fragmentDiv.innerHTML = elem.outerHTML; + fragmentDiv.removeChild( clone = fragmentDiv.firstChild ); + } + + if ( (!support.noCloneEvent || !support.noCloneChecked) && + (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) { + + // We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2 + destElements = getAll( clone ); + srcElements = getAll( elem ); + + // Fix all IE cloning issues + for ( i = 0; (node = srcElements[i]) != null; ++i ) { + // Ensure that the destination node is not null; Fixes #9587 + if ( destElements[i] ) { + fixCloneNodeIssues( node, destElements[i] ); + } + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + if ( deepDataAndEvents ) { + srcElements = srcElements || getAll( elem ); + destElements = destElements || getAll( clone ); + + for ( i = 0; (node = srcElements[i]) != null; i++ ) { + cloneCopyEvent( node, destElements[i] ); + } + } else { + cloneCopyEvent( elem, clone ); + } + } + + // Preserve script evaluation history + destElements = getAll( clone, "script" ); + if ( destElements.length > 0 ) { + setGlobalEval( destElements, !inPage && getAll( elem, "script" ) ); + } + + destElements = srcElements = node = null; + + // Return the cloned set + return clone; + }, + + buildFragment: function( elems, context, scripts, selection ) { + var j, elem, contains, + tmp, tag, tbody, wrap, + l = elems.length, + + // Ensure a safe fragment + safe = createSafeFragment( context ), + + nodes = [], + i = 0; + + for ( ; i < l; i++ ) { + elem = elems[ i ]; + + if ( elem || elem === 0 ) { + + // Add nodes directly + if ( jQuery.type( elem ) === "object" ) { + jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem ); + + // Convert non-html into a text node + } else if ( !rhtml.test( elem ) ) { + nodes.push( context.createTextNode( elem ) ); + + // Convert html into DOM nodes + } else { + tmp = tmp || safe.appendChild( context.createElement("div") ); + + // Deserialize a standard representation + tag = (rtagName.exec( elem ) || [ "", "" ])[ 1 ].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + + tmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, "<$1></$2>" ) + wrap[2]; + + // Descend through wrappers to the right content + j = wrap[0]; + while ( j-- ) { + tmp = tmp.lastChild; + } + + // Manually add leading whitespace removed by IE + if ( !support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { + nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) ); + } + + // Remove IE's autoinserted <tbody> from table fragments + if ( !support.tbody ) { + + // String was a <table>, *may* have spurious <tbody> + elem = tag === "table" && !rtbody.test( elem ) ? + tmp.firstChild : + + // String was a bare <thead> or <tfoot> + wrap[1] === "<table>" && !rtbody.test( elem ) ? + tmp : + 0; + + j = elem && elem.childNodes.length; + while ( j-- ) { + if ( jQuery.nodeName( (tbody = elem.childNodes[j]), "tbody" ) && !tbody.childNodes.length ) { + elem.removeChild( tbody ); + } + } + } + + jQuery.merge( nodes, tmp.childNodes ); + + // Fix #12392 for WebKit and IE > 9 + tmp.textContent = ""; + + // Fix #12392 for oldIE + while ( tmp.firstChild ) { + tmp.removeChild( tmp.firstChild ); + } + + // Remember the top-level container for proper cleanup + tmp = safe.lastChild; + } + } + } + + // Fix #11356: Clear elements from fragment + if ( tmp ) { + safe.removeChild( tmp ); + } + + // Reset defaultChecked for any radios and checkboxes + // about to be appended to the DOM in IE 6/7 (#8060) + if ( !support.appendChecked ) { + jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked ); + } + + i = 0; + while ( (elem = nodes[ i++ ]) ) { + + // #4087 - If origin and destination elements are the same, and this is + // that element, do not do anything + if ( selection && jQuery.inArray( elem, selection ) !== -1 ) { + continue; + } + + contains = jQuery.contains( elem.ownerDocument, elem ); + + // Append to fragment + tmp = getAll( safe.appendChild( elem ), "script" ); + + // Preserve script evaluation history + if ( contains ) { + setGlobalEval( tmp ); + } + + // Capture executables + if ( scripts ) { + j = 0; + while ( (elem = tmp[ j++ ]) ) { + if ( rscriptType.test( elem.type || "" ) ) { + scripts.push( elem ); + } + } + } + } + + tmp = null; + + return safe; + }, + + cleanData: function( elems, /* internal */ acceptData ) { + var elem, type, id, data, + i = 0, + internalKey = jQuery.expando, + cache = jQuery.cache, + deleteExpando = support.deleteExpando, + special = jQuery.event.special; + + for ( ; (elem = elems[i]) != null; i++ ) { + if ( acceptData || jQuery.acceptData( elem ) ) { + + id = elem[ internalKey ]; + data = id && cache[ id ]; + + if ( data ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Remove cache only if it was not already removed by jQuery.event.remove + if ( cache[ id ] ) { + + delete cache[ id ]; + + // IE does not allow us to delete expando properties from nodes, + // nor does it have a removeAttribute function on Document nodes; + // we must handle all of these cases + if ( deleteExpando ) { + delete elem[ internalKey ]; + + } else if ( typeof elem.removeAttribute !== strundefined ) { + elem.removeAttribute( internalKey ); + + } else { + elem[ internalKey ] = null; + } + + deletedIds.push( id ); + } + } + } + } + } +}); + +jQuery.fn.extend({ + text: function( value ) { + return access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) ); + }, null, value, arguments.length ); + }, + + append: function() { + return this.domManip( arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.appendChild( elem ); + } + }); + }, + + prepend: function() { + return this.domManip( arguments, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) { + var target = manipulationTarget( this, elem ); + target.insertBefore( elem, target.firstChild ); + } + }); + }, + + before: function() { + return this.domManip( arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this ); + } + }); + }, + + after: function() { + return this.domManip( arguments, function( elem ) { + if ( this.parentNode ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + } + }); + }, + + remove: function( selector, keepData /* Internal Use Only */ ) { + var elem, + elems = selector ? jQuery.filter( selector, this ) : this, + i = 0; + + for ( ; (elem = elems[i]) != null; i++ ) { + + if ( !keepData && elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem ) ); + } + + if ( elem.parentNode ) { + if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) { + setGlobalEval( getAll( elem, "script" ) ); + } + elem.parentNode.removeChild( elem ); + } + } + + return this; + }, + + empty: function() { + var elem, + i = 0; + + for ( ; (elem = this[i]) != null; i++ ) { + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + } + + // Remove any remaining nodes + while ( elem.firstChild ) { + elem.removeChild( elem.firstChild ); + } + + // If this is a select, ensure that it displays empty (#12336) + // Support: IE<9 + if ( elem.options && jQuery.nodeName( elem, "select" ) ) { + elem.options.length = 0; + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map(function() { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + }); + }, + + html: function( value ) { + return access( this, function( value ) { + var elem = this[ 0 ] || {}, + i = 0, + l = this.length; + + if ( value === undefined ) { + return elem.nodeType === 1 ? + elem.innerHTML.replace( rinlinejQuery, "" ) : + undefined; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + ( support.htmlSerialize || !rnoshimcache.test( value ) ) && + ( support.leadingWhitespace || !rleadingWhitespace.test( value ) ) && + !wrapMap[ (rtagName.exec( value ) || [ "", "" ])[ 1 ].toLowerCase() ] ) { + + value = value.replace( rxhtmlTag, "<$1></$2>" ); + + try { + for (; i < l; i++ ) { + // Remove element nodes and prevent memory leaks + elem = this[i] || {}; + if ( elem.nodeType === 1 ) { + jQuery.cleanData( getAll( elem, false ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch(e) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function() { + var arg = arguments[ 0 ]; + + // Make the changes, replacing each context element with the new content + this.domManip( arguments, function( elem ) { + arg = this.parentNode; + + jQuery.cleanData( getAll( this ) ); + + if ( arg ) { + arg.replaceChild( elem, this ); + } + }); + + // Force removal if there was no new content (e.g., from empty arguments) + return arg && (arg.length || arg.nodeType) ? this : this.remove(); + }, + + detach: function( selector ) { + return this.remove( selector, true ); + }, + + domManip: function( args, callback ) { + + // Flatten any nested arrays + args = concat.apply( [], args ); + + var first, node, hasScripts, + scripts, doc, fragment, + i = 0, + l = this.length, + set = this, + iNoClone = l - 1, + value = args[0], + isFunction = jQuery.isFunction( value ); + + // We can't cloneNode fragments that contain checked, in WebKit + if ( isFunction || + ( l > 1 && typeof value === "string" && + !support.checkClone && rchecked.test( value ) ) ) { + return this.each(function( index ) { + var self = set.eq( index ); + if ( isFunction ) { + args[0] = value.call( this, index, self.html() ); + } + self.domManip( args, callback ); + }); + } + + if ( l ) { + fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this ); + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + if ( first ) { + scripts = jQuery.map( getAll( fragment, "script" ), disableScript ); + hasScripts = scripts.length; + + // Use the original fragment for the last item instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + for ( ; i < l; i++ ) { + node = fragment; + + if ( i !== iNoClone ) { + node = jQuery.clone( node, true, true ); + + // Keep references to cloned scripts for later restoration + if ( hasScripts ) { + jQuery.merge( scripts, getAll( node, "script" ) ); + } + } + + callback.call( this[i], node, i ); + } + + if ( hasScripts ) { + doc = scripts[ scripts.length - 1 ].ownerDocument; + + // Reenable scripts + jQuery.map( scripts, restoreScript ); + + // Evaluate executable scripts on first document insertion + for ( i = 0; i < hasScripts; i++ ) { + node = scripts[ i ]; + if ( rscriptType.test( node.type || "" ) && + !jQuery._data( node, "globalEval" ) && jQuery.contains( doc, node ) ) { + + if ( node.src ) { + // Optional AJAX dependency, but won't run scripts if not present + if ( jQuery._evalUrl ) { + jQuery._evalUrl( node.src ); + } + } else { + jQuery.globalEval( ( node.text || node.textContent || node.innerHTML || "" ).replace( rcleanScript, "" ) ); + } + } + } + } + + // Fix #11809: Avoid leaking memory + fragment = first = null; + } + } + + return this; + } +}); + +jQuery.each({ + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + i = 0, + ret = [], + insert = jQuery( selector ), + last = insert.length - 1; + + for ( ; i <= last; i++ ) { + elems = i === last ? this : this.clone(true); + jQuery( insert[i] )[ original ]( elems ); + + // Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get() + push.apply( ret, elems.get() ); + } + + return this.pushStack( ret ); + }; +}); + + +var iframe, + elemdisplay = {}; + +/** + * Retrieve the actual display of a element + * @param {String} name nodeName of the element + * @param {Object} doc Document object + */ +// Called only from within defaultDisplay +function actualDisplay( name, doc ) { + var style, + elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ), + + // getDefaultComputedStyle might be reliably used only on attached element + display = window.getDefaultComputedStyle && ( style = window.getDefaultComputedStyle( elem[ 0 ] ) ) ? + + // Use of this method is a temporary fix (more like optmization) until something better comes along, + // since it was removed from specification and supported only in FF + style.display : jQuery.css( elem[ 0 ], "display" ); + + // We don't have any data stored on the element, + // so use "detach" method as fast way to get rid of the element + elem.detach(); + + return display; +} + +/** + * Try to determine the default display value of an element + * @param {String} nodeName + */ +function defaultDisplay( nodeName ) { + var doc = document, + display = elemdisplay[ nodeName ]; + + if ( !display ) { + display = actualDisplay( nodeName, doc ); + + // If the simple way fails, read from inside an iframe + if ( display === "none" || !display ) { + + // Use the already-created iframe if possible + iframe = (iframe || jQuery( "<iframe frameborder='0' width='0' height='0'/>" )).appendTo( doc.documentElement ); + + // Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse + doc = ( iframe[ 0 ].contentWindow || iframe[ 0 ].contentDocument ).document; + + // Support: IE + doc.write(); + doc.close(); + + display = actualDisplay( nodeName, doc ); + iframe.detach(); + } + + // Store the correct default display + elemdisplay[ nodeName ] = display; + } + + return display; +} + + +(function() { + var shrinkWrapBlocksVal; + + support.shrinkWrapBlocks = function() { + if ( shrinkWrapBlocksVal != null ) { + return shrinkWrapBlocksVal; + } + + // Will be changed later if needed. + shrinkWrapBlocksVal = false; + + // Minified: var b,c,d + var div, body, container; + + body = document.getElementsByTagName( "body" )[ 0 ]; + if ( !body || !body.style ) { + // Test fired too early or in an unsupported environment, exit. + return; + } + + // Setup + div = document.createElement( "div" ); + container = document.createElement( "div" ); + container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px"; + body.appendChild( container ).appendChild( div ); + + // Support: IE6 + // Check if elements with layout shrink-wrap their children + if ( typeof div.style.zoom !== strundefined ) { + // Reset CSS: box-sizing; display; margin; border + div.style.cssText = + // Support: Firefox<29, Android 2.3 + // Vendor-prefix box-sizing + "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" + + "box-sizing:content-box;display:block;margin:0;border:0;" + + "padding:1px;width:1px;zoom:1"; + div.appendChild( document.createElement( "div" ) ).style.width = "5px"; + shrinkWrapBlocksVal = div.offsetWidth !== 3; + } + + body.removeChild( container ); + + return shrinkWrapBlocksVal; + }; + +})(); +var rmargin = (/^margin/); + +var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" ); + + + +var getStyles, curCSS, + rposition = /^(top|right|bottom|left)$/; + +if ( window.getComputedStyle ) { + getStyles = function( elem ) { + // Support: IE<=11+, Firefox<=30+ (#15098, #14150) + // IE throws on elements created in popups + // FF meanwhile throws on frame elements through "defaultView.getComputedStyle" + if ( elem.ownerDocument.defaultView.opener ) { + return elem.ownerDocument.defaultView.getComputedStyle( elem, null ); + } + + return window.getComputedStyle( elem, null ); + }; + + curCSS = function( elem, name, computed ) { + var width, minWidth, maxWidth, ret, + style = elem.style; + + computed = computed || getStyles( elem ); + + // getPropertyValue is only needed for .css('filter') in IE9, see #12537 + ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined; + + if ( computed ) { + + if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) { + ret = jQuery.style( elem, name ); + } + + // A tribute to the "awesome hack by Dean Edwards" + // Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right + // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels + // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values + if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) { + + // Remember the original values + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + // Put in the new values to get a computed value out + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + // Revert the changed values + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + // Support: IE + // IE returns zIndex value as an integer. + return ret === undefined ? + ret : + ret + ""; + }; +} else if ( document.documentElement.currentStyle ) { + getStyles = function( elem ) { + return elem.currentStyle; + }; + + curCSS = function( elem, name, computed ) { + var left, rs, rsLeft, ret, + style = elem.style; + + computed = computed || getStyles( elem ); + ret = computed ? computed[ name ] : undefined; + + // Avoid setting ret to empty string here + // so we don't default to auto + if ( ret == null && style && style[ name ] ) { + ret = style[ name ]; + } + + // From the awesome hack by Dean Edwards + // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 + + // If we're not dealing with a regular pixel number + // but a number that has a weird ending, we need to convert it to pixels + // but not position css attributes, as those are proportional to the parent element instead + // and we can't measure the parent instead because it might trigger a "stacking dolls" problem + if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) { + + // Remember the original values + left = style.left; + rs = elem.runtimeStyle; + rsLeft = rs && rs.left; + + // Put in the new values to get a computed value out + if ( rsLeft ) { + rs.left = elem.currentStyle.left; + } + style.left = name === "fontSize" ? "1em" : ret; + ret = style.pixelLeft + "px"; + + // Revert the changed values + style.left = left; + if ( rsLeft ) { + rs.left = rsLeft; + } + } + + // Support: IE + // IE returns zIndex value as an integer. + return ret === undefined ? + ret : + ret + "" || "auto"; + }; +} + + + + +function addGetHookIf( conditionFn, hookFn ) { + // Define the hook, we'll check on the first run if it's really needed. + return { + get: function() { + var condition = conditionFn(); + + if ( condition == null ) { + // The test was not ready at this point; screw the hook this time + // but check again when needed next time. + return; + } + + if ( condition ) { + // Hook not needed (or it's not possible to use it due to missing dependency), + // remove it. + // Since there are no other hooks for marginRight, remove the whole object. + delete this.get; + return; + } + + // Hook needed; redefine it so that the support test is not executed again. + + return (this.get = hookFn).apply( this, arguments ); + } + }; +} + + +(function() { + // Minified: var b,c,d,e,f,g, h,i + var div, style, a, pixelPositionVal, boxSizingReliableVal, + reliableHiddenOffsetsVal, reliableMarginRightVal; + + // Setup + div = document.createElement( "div" ); + div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>"; + a = div.getElementsByTagName( "a" )[ 0 ]; + style = a && a.style; + + // Finish early in limited (non-browser) environments + if ( !style ) { + return; + } + + style.cssText = "float:left;opacity:.5"; + + // Support: IE<9 + // Make sure that element opacity exists (as opposed to filter) + support.opacity = style.opacity === "0.5"; + + // Verify style float existence + // (IE uses styleFloat instead of cssFloat) + support.cssFloat = !!style.cssFloat; + + div.style.backgroundClip = "content-box"; + div.cloneNode( true ).style.backgroundClip = ""; + support.clearCloneStyle = div.style.backgroundClip === "content-box"; + + // Support: Firefox<29, Android 2.3 + // Vendor-prefix box-sizing + support.boxSizing = style.boxSizing === "" || style.MozBoxSizing === "" || + style.WebkitBoxSizing === ""; + + jQuery.extend(support, { + reliableHiddenOffsets: function() { + if ( reliableHiddenOffsetsVal == null ) { + computeStyleTests(); + } + return reliableHiddenOffsetsVal; + }, + + boxSizingReliable: function() { + if ( boxSizingReliableVal == null ) { + computeStyleTests(); + } + return boxSizingReliableVal; + }, + + pixelPosition: function() { + if ( pixelPositionVal == null ) { + computeStyleTests(); + } + return pixelPositionVal; + }, + + // Support: Android 2.3 + reliableMarginRight: function() { + if ( reliableMarginRightVal == null ) { + computeStyleTests(); + } + return reliableMarginRightVal; + } + }); + + function computeStyleTests() { + // Minified: var b,c,d,j + var div, body, container, contents; + + body = document.getElementsByTagName( "body" )[ 0 ]; + if ( !body || !body.style ) { + // Test fired too early or in an unsupported environment, exit. + return; + } + + // Setup + div = document.createElement( "div" ); + container = document.createElement( "div" ); + container.style.cssText = "position:absolute;border:0;width:0;height:0;top:0;left:-9999px"; + body.appendChild( container ).appendChild( div ); + + div.style.cssText = + // Support: Firefox<29, Android 2.3 + // Vendor-prefix box-sizing + "-webkit-box-sizing:border-box;-moz-box-sizing:border-box;" + + "box-sizing:border-box;display:block;margin-top:1%;top:1%;" + + "border:1px;padding:1px;width:4px;position:absolute"; + + // Support: IE<9 + // Assume reasonable values in the absence of getComputedStyle + pixelPositionVal = boxSizingReliableVal = false; + reliableMarginRightVal = true; + + // Check for getComputedStyle so that this code is not run in IE<9. + if ( window.getComputedStyle ) { + pixelPositionVal = ( window.getComputedStyle( div, null ) || {} ).top !== "1%"; + boxSizingReliableVal = + ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px"; + + // Support: Android 2.3 + // Div with explicit width and no margin-right incorrectly + // gets computed margin-right based on width of container (#3333) + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + contents = div.appendChild( document.createElement( "div" ) ); + + // Reset CSS: box-sizing; display; margin; border; padding + contents.style.cssText = div.style.cssText = + // Support: Firefox<29, Android 2.3 + // Vendor-prefix box-sizing + "-webkit-box-sizing:content-box;-moz-box-sizing:content-box;" + + "box-sizing:content-box;display:block;margin:0;border:0;padding:0"; + contents.style.marginRight = contents.style.width = "0"; + div.style.width = "1px"; + + reliableMarginRightVal = + !parseFloat( ( window.getComputedStyle( contents, null ) || {} ).marginRight ); + + div.removeChild( contents ); + } + + // Support: IE8 + // Check if table cells still have offsetWidth/Height when they are set + // to display:none and there are still other visible table cells in a + // table row; if so, offsetWidth/Height are not reliable for use when + // determining if an element has been hidden directly using + // display:none (it is still safe to use offsets if a parent element is + // hidden; don safety goggles and see bug #4512 for more information). + div.innerHTML = "<table><tr><td></td><td>t</td></tr></table>"; + contents = div.getElementsByTagName( "td" ); + contents[ 0 ].style.cssText = "margin:0;border:0;padding:0;display:none"; + reliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0; + if ( reliableHiddenOffsetsVal ) { + contents[ 0 ].style.display = ""; + contents[ 1 ].style.display = "none"; + reliableHiddenOffsetsVal = contents[ 0 ].offsetHeight === 0; + } + + body.removeChild( container ); + } + +})(); + + +// A method for quickly swapping in/out CSS properties to get correct calculations. +jQuery.swap = function( elem, options, callback, args ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.apply( elem, args || [] ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; +}; + + +var + ralpha = /alpha\([^)]*\)/i, + ropacity = /opacity\s*=\s*([^)]*)/, + + // swappable if display is none or starts with table except "table", "table-cell", or "table-caption" + // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + rnumsplit = new RegExp( "^(" + pnum + ")(.*)$", "i" ), + rrelNum = new RegExp( "^([+-])=(" + pnum + ")", "i" ), + + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: "0", + fontWeight: "400" + }, + + cssPrefixes = [ "Webkit", "O", "Moz", "ms" ]; + + +// return a css property mapped to a potentially vendor prefixed property +function vendorPropName( style, name ) { + + // shortcut for names that are not vendor prefixed + if ( name in style ) { + return name; + } + + // check for vendor prefixed names + var capName = name.charAt(0).toUpperCase() + name.slice(1), + origName = name, + i = cssPrefixes.length; + + while ( i-- ) { + name = cssPrefixes[ i ] + capName; + if ( name in style ) { + return name; + } + } + + return origName; +} + +function showHide( elements, show ) { + var display, elem, hidden, + values = [], + index = 0, + length = elements.length; + + for ( ; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + + values[ index ] = jQuery._data( elem, "olddisplay" ); + display = elem.style.display; + if ( show ) { + // Reset the inline display of this element to learn if it is + // being hidden by cascaded rules or not + if ( !values[ index ] && display === "none" ) { + elem.style.display = ""; + } + + // Set elements which have been overridden with display: none + // in a stylesheet to whatever the default browser style is + // for such an element + if ( elem.style.display === "" && isHidden( elem ) ) { + values[ index ] = jQuery._data( elem, "olddisplay", defaultDisplay(elem.nodeName) ); + } + } else { + hidden = isHidden( elem ); + + if ( display && display !== "none" || !hidden ) { + jQuery._data( elem, "olddisplay", hidden ? display : jQuery.css( elem, "display" ) ); + } + } + } + + // Set the display of most of the elements in a second loop + // to avoid the constant reflow + for ( index = 0; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + if ( !show || elem.style.display === "none" || elem.style.display === "" ) { + elem.style.display = show ? values[ index ] || "" : "none"; + } + } + + return elements; +} + +function setPositiveNumber( elem, value, subtract ) { + var matches = rnumsplit.exec( value ); + return matches ? + // Guard against undefined "subtract", e.g., when used as in cssHooks + Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) : + value; +} + +function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) { + var i = extra === ( isBorderBox ? "border" : "content" ) ? + // If we already have the right measurement, avoid augmentation + 4 : + // Otherwise initialize for horizontal or vertical properties + name === "width" ? 1 : 0, + + val = 0; + + for ( ; i < 4; i += 2 ) { + // both box models exclude margin, so add it if we want it + if ( extra === "margin" ) { + val += jQuery.css( elem, extra + cssExpand[ i ], true, styles ); + } + + if ( isBorderBox ) { + // border-box includes padding, so remove it if we want content + if ( extra === "content" ) { + val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + } + + // at this point, extra isn't border nor margin, so remove border + if ( extra !== "margin" ) { + val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } else { + // at this point, extra isn't content, so add padding + val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles ); + + // at this point, extra isn't content nor padding, so add border + if ( extra !== "padding" ) { + val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles ); + } + } + } + + return val; +} + +function getWidthOrHeight( elem, name, extra ) { + + // Start with offset property, which is equivalent to the border-box value + var valueIsBorderBox = true, + val = name === "width" ? elem.offsetWidth : elem.offsetHeight, + styles = getStyles( elem ), + isBorderBox = support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box"; + + // some non-html elements return undefined for offsetWidth, so check for null/undefined + // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285 + // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668 + if ( val <= 0 || val == null ) { + // Fall back to computed then uncomputed css if necessary + val = curCSS( elem, name, styles ); + if ( val < 0 || val == null ) { + val = elem.style[ name ]; + } + + // Computed unit is not pixels. Stop here and return. + if ( rnumnonpx.test(val) ) { + return val; + } + + // we need the check for style in case a browser which returns unreliable values + // for getComputedStyle silently falls back to the reliable elem.style + valueIsBorderBox = isBorderBox && ( support.boxSizingReliable() || val === elem.style[ name ] ); + + // Normalize "", auto, and prepare for extra + val = parseFloat( val ) || 0; + } + + // use the active box-sizing model to add/subtract irrelevant styles + return ( val + + augmentWidthOrHeight( + elem, + name, + extra || ( isBorderBox ? "border" : "content" ), + valueIsBorderBox, + styles + ) + ) + "px"; +} + +jQuery.extend({ + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity" ); + return ret === "" ? "1" : ret; + } + } + } + }, + + // Don't automatically add "px" to these possibly-unitless properties + cssNumber: { + "columnCount": true, + "fillOpacity": true, + "flexGrow": true, + "flexShrink": true, + "fontWeight": true, + "lineHeight": true, + "opacity": true, + "order": true, + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: { + // normalize float css property + "float": support.cssFloat ? "cssFloat" : "styleFloat" + }, + + // Get and set the style property on a DOM Node + style: function( elem, name, value, extra ) { + // Don't set styles on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { + return; + } + + // Make sure that we're working with the right name + var ret, type, hooks, + origName = jQuery.camelCase( name ), + style = elem.style; + + name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) ); + + // gets hook for the prefixed version + // followed by the unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // Check if we're setting a value + if ( value !== undefined ) { + type = typeof value; + + // convert relative number strings (+= or -=) to relative numbers. #7345 + if ( type === "string" && (ret = rrelNum.exec( value )) ) { + value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) ); + // Fixes bug #9237 + type = "number"; + } + + // Make sure that null and NaN values aren't set. See: #7116 + if ( value == null || value !== value ) { + return; + } + + // If a number was passed in, add 'px' to the (except for certain CSS properties) + if ( type === "number" && !jQuery.cssNumber[ origName ] ) { + value += "px"; + } + + // Fixes #8908, it can be done more correctly by specifing setters in cssHooks, + // but it would mean to define eight (for every problematic property) identical functions + if ( !support.clearCloneStyle && value === "" && name.indexOf("background") === 0 ) { + style[ name ] = "inherit"; + } + + // If a hook was provided, use that value, otherwise just set the specified value + if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) { + + // Support: IE + // Swallow errors from 'invalid' CSS values (#5509) + try { + style[ name ] = value; + } catch(e) {} + } + + } else { + // If a hook was provided get the non-computed value from there + if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) { + return ret; + } + + // Otherwise just get the value from the style object + return style[ name ]; + } + }, + + css: function( elem, name, extra, styles ) { + var num, val, hooks, + origName = jQuery.camelCase( name ); + + // Make sure that we're working with the right name + name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) ); + + // gets hook for the prefixed version + // followed by the unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // If a hook was provided get the computed value from there + if ( hooks && "get" in hooks ) { + val = hooks.get( elem, true, extra ); + } + + // Otherwise, if a way to get the computed value exists, use that + if ( val === undefined ) { + val = curCSS( elem, name, styles ); + } + + //convert "normal" to computed value + if ( val === "normal" && name in cssNormalTransform ) { + val = cssNormalTransform[ name ]; + } + + // Return, converting to number if forced or a qualifier was provided and val looks numeric + if ( extra === "" || extra ) { + num = parseFloat( val ); + return extra === true || jQuery.isNumeric( num ) ? num || 0 : val; + } + return val; + } +}); + +jQuery.each([ "height", "width" ], function( i, name ) { + jQuery.cssHooks[ name ] = { + get: function( elem, computed, extra ) { + if ( computed ) { + // certain elements can have dimension info if we invisibly show them + // however, it must have a current display style that would benefit from this + return rdisplayswap.test( jQuery.css( elem, "display" ) ) && elem.offsetWidth === 0 ? + jQuery.swap( elem, cssShow, function() { + return getWidthOrHeight( elem, name, extra ); + }) : + getWidthOrHeight( elem, name, extra ); + } + }, + + set: function( elem, value, extra ) { + var styles = extra && getStyles( elem ); + return setPositiveNumber( elem, value, extra ? + augmentWidthOrHeight( + elem, + name, + extra, + support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box", + styles + ) : 0 + ); + } + }; +}); + +if ( !support.opacity ) { + jQuery.cssHooks.opacity = { + get: function( elem, computed ) { + // IE uses filters for opacity + return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ? + ( 0.01 * parseFloat( RegExp.$1 ) ) + "" : + computed ? "1" : ""; + }, + + set: function( elem, value ) { + var style = elem.style, + currentStyle = elem.currentStyle, + opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "", + filter = currentStyle && currentStyle.filter || style.filter || ""; + + // IE has trouble with opacity if it does not have layout + // Force it by setting the zoom level + style.zoom = 1; + + // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652 + // if value === "", then remove inline opacity #12685 + if ( ( value >= 1 || value === "" ) && + jQuery.trim( filter.replace( ralpha, "" ) ) === "" && + style.removeAttribute ) { + + // Setting style.filter to null, "" & " " still leave "filter:" in the cssText + // if "filter:" is present at all, clearType is disabled, we want to avoid this + // style.removeAttribute is IE Only, but so apparently is this code path... + style.removeAttribute( "filter" ); + + // if there is no filter style applied in a css rule or unset inline opacity, we are done + if ( value === "" || currentStyle && !currentStyle.filter ) { + return; + } + } + + // otherwise, set new filter values + style.filter = ralpha.test( filter ) ? + filter.replace( ralpha, opacity ) : + filter + " " + opacity; + } + }; +} + +jQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight, + function( elem, computed ) { + if ( computed ) { + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + // Work around by temporarily setting element display to inline-block + return jQuery.swap( elem, { "display": "inline-block" }, + curCSS, [ elem, "marginRight" ] ); + } + } +); + +// These hooks are used by animate to expand properties +jQuery.each({ + margin: "", + padding: "", + border: "Width" +}, function( prefix, suffix ) { + jQuery.cssHooks[ prefix + suffix ] = { + expand: function( value ) { + var i = 0, + expanded = {}, + + // assumes a single number if not a string + parts = typeof value === "string" ? value.split(" ") : [ value ]; + + for ( ; i < 4; i++ ) { + expanded[ prefix + cssExpand[ i ] + suffix ] = + parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; + } + + return expanded; + } + }; + + if ( !rmargin.test( prefix ) ) { + jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; + } +}); + +jQuery.fn.extend({ + css: function( name, value ) { + return access( this, function( elem, name, value ) { + var styles, len, + map = {}, + i = 0; + + if ( jQuery.isArray( name ) ) { + styles = getStyles( elem ); + len = name.length; + + for ( ; i < len; i++ ) { + map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles ); + } + + return map; + } + + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + }, + show: function() { + return showHide( this, true ); + }, + hide: function() { + return showHide( this ); + }, + toggle: function( state ) { + if ( typeof state === "boolean" ) { + return state ? this.show() : this.hide(); + } + + return this.each(function() { + if ( isHidden( this ) ) { + jQuery( this ).show(); + } else { + jQuery( this ).hide(); + } + }); + } +}); + + +function Tween( elem, options, prop, end, easing ) { + return new Tween.prototype.init( elem, options, prop, end, easing ); +} +jQuery.Tween = Tween; + +Tween.prototype = { + constructor: Tween, + init: function( elem, options, prop, end, easing, unit ) { + this.elem = elem; + this.prop = prop; + this.easing = easing || "swing"; + this.options = options; + this.start = this.now = this.cur(); + this.end = end; + this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); + }, + cur: function() { + var hooks = Tween.propHooks[ this.prop ]; + + return hooks && hooks.get ? + hooks.get( this ) : + Tween.propHooks._default.get( this ); + }, + run: function( percent ) { + var eased, + hooks = Tween.propHooks[ this.prop ]; + + if ( this.options.duration ) { + this.pos = eased = jQuery.easing[ this.easing ]( + percent, this.options.duration * percent, 0, 1, this.options.duration + ); + } else { + this.pos = eased = percent; + } + this.now = ( this.end - this.start ) * eased + this.start; + + if ( this.options.step ) { + this.options.step.call( this.elem, this.now, this ); + } + + if ( hooks && hooks.set ) { + hooks.set( this ); + } else { + Tween.propHooks._default.set( this ); + } + return this; + } +}; + +Tween.prototype.init.prototype = Tween.prototype; + +Tween.propHooks = { + _default: { + get: function( tween ) { + var result; + + if ( tween.elem[ tween.prop ] != null && + (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) { + return tween.elem[ tween.prop ]; + } + + // passing an empty string as a 3rd parameter to .css will automatically + // attempt a parseFloat and fallback to a string if the parse fails + // so, simple values such as "10px" are parsed to Float. + // complex values such as "rotate(1rad)" are returned as is. + result = jQuery.css( tween.elem, tween.prop, "" ); + // Empty strings, null, undefined and "auto" are converted to 0. + return !result || result === "auto" ? 0 : result; + }, + set: function( tween ) { + // use step hook for back compat - use cssHook if its there - use .style if its + // available and use plain properties where available + if ( jQuery.fx.step[ tween.prop ] ) { + jQuery.fx.step[ tween.prop ]( tween ); + } else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) { + jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); + } else { + tween.elem[ tween.prop ] = tween.now; + } + } + } +}; + +// Support: IE <=9 +// Panic based approach to setting things on disconnected nodes + +Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { + set: function( tween ) { + if ( tween.elem.nodeType && tween.elem.parentNode ) { + tween.elem[ tween.prop ] = tween.now; + } + } +}; + +jQuery.easing = { + linear: function( p ) { + return p; + }, + swing: function( p ) { + return 0.5 - Math.cos( p * Math.PI ) / 2; + } +}; + +jQuery.fx = Tween.prototype.init; + +// Back Compat <1.8 extension point +jQuery.fx.step = {}; + + + + +var + fxNow, timerId, + rfxtypes = /^(?:toggle|show|hide)$/, + rfxnum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" ), + rrun = /queueHooks$/, + animationPrefilters = [ defaultPrefilter ], + tweeners = { + "*": [ function( prop, value ) { + var tween = this.createTween( prop, value ), + target = tween.cur(), + parts = rfxnum.exec( value ), + unit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ), + + // Starting value computation is required for potential unit mismatches + start = ( jQuery.cssNumber[ prop ] || unit !== "px" && +target ) && + rfxnum.exec( jQuery.css( tween.elem, prop ) ), + scale = 1, + maxIterations = 20; + + if ( start && start[ 3 ] !== unit ) { + // Trust units reported by jQuery.css + unit = unit || start[ 3 ]; + + // Make sure we update the tween properties later on + parts = parts || []; + + // Iteratively approximate from a nonzero starting point + start = +target || 1; + + do { + // If previous iteration zeroed out, double until we get *something* + // Use a string for doubling factor so we don't accidentally see scale as unchanged below + scale = scale || ".5"; + + // Adjust and apply + start = start / scale; + jQuery.style( tween.elem, prop, start + unit ); + + // Update scale, tolerating zero or NaN from tween.cur() + // And breaking the loop if scale is unchanged or perfect, or if we've just had enough + } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations ); + } + + // Update tween properties + if ( parts ) { + start = tween.start = +start || +target || 0; + tween.unit = unit; + // If a +=/-= token was provided, we're doing a relative animation + tween.end = parts[ 1 ] ? + start + ( parts[ 1 ] + 1 ) * parts[ 2 ] : + +parts[ 2 ]; + } + + return tween; + } ] + }; + +// Animations created synchronously will run synchronously +function createFxNow() { + setTimeout(function() { + fxNow = undefined; + }); + return ( fxNow = jQuery.now() ); +} + +// Generate parameters to create a standard animation +function genFx( type, includeWidth ) { + var which, + attrs = { height: type }, + i = 0; + + // if we include width, step value is 1 to do all cssExpand values, + // if we don't include width, step value is 2 to skip over Left and Right + includeWidth = includeWidth ? 1 : 0; + for ( ; i < 4 ; i += 2 - includeWidth ) { + which = cssExpand[ i ]; + attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; + } + + if ( includeWidth ) { + attrs.opacity = attrs.width = type; + } + + return attrs; +} + +function createTween( value, prop, animation ) { + var tween, + collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ), + index = 0, + length = collection.length; + for ( ; index < length; index++ ) { + if ( (tween = collection[ index ].call( animation, prop, value )) ) { + + // we're done with this property + return tween; + } + } +} + +function defaultPrefilter( elem, props, opts ) { + /* jshint validthis: true */ + var prop, value, toggle, tween, hooks, oldfire, display, checkDisplay, + anim = this, + orig = {}, + style = elem.style, + hidden = elem.nodeType && isHidden( elem ), + dataShow = jQuery._data( elem, "fxshow" ); + + // handle queue: false promises + if ( !opts.queue ) { + hooks = jQuery._queueHooks( elem, "fx" ); + if ( hooks.unqueued == null ) { + hooks.unqueued = 0; + oldfire = hooks.empty.fire; + hooks.empty.fire = function() { + if ( !hooks.unqueued ) { + oldfire(); + } + }; + } + hooks.unqueued++; + + anim.always(function() { + // doing this makes sure that the complete handler will be called + // before this completes + anim.always(function() { + hooks.unqueued--; + if ( !jQuery.queue( elem, "fx" ).length ) { + hooks.empty.fire(); + } + }); + }); + } + + // height/width overflow pass + if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) { + // Make sure that nothing sneaks out + // Record all 3 overflow attributes because IE does not + // change the overflow attribute when overflowX and + // overflowY are set to the same value + opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; + + // Set display property to inline-block for height/width + // animations on inline elements that are having width/height animated + display = jQuery.css( elem, "display" ); + + // Test default display if display is currently "none" + checkDisplay = display === "none" ? + jQuery._data( elem, "olddisplay" ) || defaultDisplay( elem.nodeName ) : display; + + if ( checkDisplay === "inline" && jQuery.css( elem, "float" ) === "none" ) { + + // inline-level elements accept inline-block; + // block-level elements need to be inline with layout + if ( !support.inlineBlockNeedsLayout || defaultDisplay( elem.nodeName ) === "inline" ) { + style.display = "inline-block"; + } else { + style.zoom = 1; + } + } + } + + if ( opts.overflow ) { + style.overflow = "hidden"; + if ( !support.shrinkWrapBlocks() ) { + anim.always(function() { + style.overflow = opts.overflow[ 0 ]; + style.overflowX = opts.overflow[ 1 ]; + style.overflowY = opts.overflow[ 2 ]; + }); + } + } + + // show/hide pass + for ( prop in props ) { + value = props[ prop ]; + if ( rfxtypes.exec( value ) ) { + delete props[ prop ]; + toggle = toggle || value === "toggle"; + if ( value === ( hidden ? "hide" : "show" ) ) { + + // If there is dataShow left over from a stopped hide or show and we are going to proceed with show, we should pretend to be hidden + if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { + hidden = true; + } else { + continue; + } + } + orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); + + // Any non-fx value stops us from restoring the original display value + } else { + display = undefined; + } + } + + if ( !jQuery.isEmptyObject( orig ) ) { + if ( dataShow ) { + if ( "hidden" in dataShow ) { + hidden = dataShow.hidden; + } + } else { + dataShow = jQuery._data( elem, "fxshow", {} ); + } + + // store state if its toggle - enables .stop().toggle() to "reverse" + if ( toggle ) { + dataShow.hidden = !hidden; + } + if ( hidden ) { + jQuery( elem ).show(); + } else { + anim.done(function() { + jQuery( elem ).hide(); + }); + } + anim.done(function() { + var prop; + jQuery._removeData( elem, "fxshow" ); + for ( prop in orig ) { + jQuery.style( elem, prop, orig[ prop ] ); + } + }); + for ( prop in orig ) { + tween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); + + if ( !( prop in dataShow ) ) { + dataShow[ prop ] = tween.start; + if ( hidden ) { + tween.end = tween.start; + tween.start = prop === "width" || prop === "height" ? 1 : 0; + } + } + } + + // If this is a noop like .hide().hide(), restore an overwritten display value + } else if ( (display === "none" ? defaultDisplay( elem.nodeName ) : display) === "inline" ) { + style.display = display; + } +} + +function propFilter( props, specialEasing ) { + var index, name, easing, value, hooks; + + // camelCase, specialEasing and expand cssHook pass + for ( index in props ) { + name = jQuery.camelCase( index ); + easing = specialEasing[ name ]; + value = props[ index ]; + if ( jQuery.isArray( value ) ) { + easing = value[ 1 ]; + value = props[ index ] = value[ 0 ]; + } + + if ( index !== name ) { + props[ name ] = value; + delete props[ index ]; + } + + hooks = jQuery.cssHooks[ name ]; + if ( hooks && "expand" in hooks ) { + value = hooks.expand( value ); + delete props[ name ]; + + // not quite $.extend, this wont overwrite keys already present. + // also - reusing 'index' from above because we have the correct "name" + for ( index in value ) { + if ( !( index in props ) ) { + props[ index ] = value[ index ]; + specialEasing[ index ] = easing; + } + } + } else { + specialEasing[ name ] = easing; + } + } +} + +function Animation( elem, properties, options ) { + var result, + stopped, + index = 0, + length = animationPrefilters.length, + deferred = jQuery.Deferred().always( function() { + // don't match elem in the :animated selector + delete tick.elem; + }), + tick = function() { + if ( stopped ) { + return false; + } + var currentTime = fxNow || createFxNow(), + remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), + // archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497) + temp = remaining / animation.duration || 0, + percent = 1 - temp, + index = 0, + length = animation.tweens.length; + + for ( ; index < length ; index++ ) { + animation.tweens[ index ].run( percent ); + } + + deferred.notifyWith( elem, [ animation, percent, remaining ]); + + if ( percent < 1 && length ) { + return remaining; + } else { + deferred.resolveWith( elem, [ animation ] ); + return false; + } + }, + animation = deferred.promise({ + elem: elem, + props: jQuery.extend( {}, properties ), + opts: jQuery.extend( true, { specialEasing: {} }, options ), + originalProperties: properties, + originalOptions: options, + startTime: fxNow || createFxNow(), + duration: options.duration, + tweens: [], + createTween: function( prop, end ) { + var tween = jQuery.Tween( elem, animation.opts, prop, end, + animation.opts.specialEasing[ prop ] || animation.opts.easing ); + animation.tweens.push( tween ); + return tween; + }, + stop: function( gotoEnd ) { + var index = 0, + // if we are going to the end, we want to run all the tweens + // otherwise we skip this part + length = gotoEnd ? animation.tweens.length : 0; + if ( stopped ) { + return this; + } + stopped = true; + for ( ; index < length ; index++ ) { + animation.tweens[ index ].run( 1 ); + } + + // resolve when we played the last frame + // otherwise, reject + if ( gotoEnd ) { + deferred.resolveWith( elem, [ animation, gotoEnd ] ); + } else { + deferred.rejectWith( elem, [ animation, gotoEnd ] ); + } + return this; + } + }), + props = animation.props; + + propFilter( props, animation.opts.specialEasing ); + + for ( ; index < length ; index++ ) { + result = animationPrefilters[ index ].call( animation, elem, props, animation.opts ); + if ( result ) { + return result; + } + } + + jQuery.map( props, createTween, animation ); + + if ( jQuery.isFunction( animation.opts.start ) ) { + animation.opts.start.call( elem, animation ); + } + + jQuery.fx.timer( + jQuery.extend( tick, { + elem: elem, + anim: animation, + queue: animation.opts.queue + }) + ); + + // attach callbacks from options + return animation.progress( animation.opts.progress ) + .done( animation.opts.done, animation.opts.complete ) + .fail( animation.opts.fail ) + .always( animation.opts.always ); +} + +jQuery.Animation = jQuery.extend( Animation, { + tweener: function( props, callback ) { + if ( jQuery.isFunction( props ) ) { + callback = props; + props = [ "*" ]; + } else { + props = props.split(" "); + } + + var prop, + index = 0, + length = props.length; + + for ( ; index < length ; index++ ) { + prop = props[ index ]; + tweeners[ prop ] = tweeners[ prop ] || []; + tweeners[ prop ].unshift( callback ); + } + }, + + prefilter: function( callback, prepend ) { + if ( prepend ) { + animationPrefilters.unshift( callback ); + } else { + animationPrefilters.push( callback ); + } + } +}); + +jQuery.speed = function( speed, easing, fn ) { + var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { + complete: fn || !fn && easing || + jQuery.isFunction( speed ) && speed, + duration: speed, + easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing + }; + + opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration : + opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default; + + // normalize opt.queue - true/undefined/null -> "fx" + if ( opt.queue == null || opt.queue === true ) { + opt.queue = "fx"; + } + + // Queueing + opt.old = opt.complete; + + opt.complete = function() { + if ( jQuery.isFunction( opt.old ) ) { + opt.old.call( this ); + } + + if ( opt.queue ) { + jQuery.dequeue( this, opt.queue ); + } + }; + + return opt; +}; + +jQuery.fn.extend({ + fadeTo: function( speed, to, easing, callback ) { + + // show any hidden elements after setting opacity to 0 + return this.filter( isHidden ).css( "opacity", 0 ).show() + + // animate to the value specified + .end().animate({ opacity: to }, speed, easing, callback ); + }, + animate: function( prop, speed, easing, callback ) { + var empty = jQuery.isEmptyObject( prop ), + optall = jQuery.speed( speed, easing, callback ), + doAnimation = function() { + // Operate on a copy of prop so per-property easing won't be lost + var anim = Animation( this, jQuery.extend( {}, prop ), optall ); + + // Empty animations, or finishing resolves immediately + if ( empty || jQuery._data( this, "finish" ) ) { + anim.stop( true ); + } + }; + doAnimation.finish = doAnimation; + + return empty || optall.queue === false ? + this.each( doAnimation ) : + this.queue( optall.queue, doAnimation ); + }, + stop: function( type, clearQueue, gotoEnd ) { + var stopQueue = function( hooks ) { + var stop = hooks.stop; + delete hooks.stop; + stop( gotoEnd ); + }; + + if ( typeof type !== "string" ) { + gotoEnd = clearQueue; + clearQueue = type; + type = undefined; + } + if ( clearQueue && type !== false ) { + this.queue( type || "fx", [] ); + } + + return this.each(function() { + var dequeue = true, + index = type != null && type + "queueHooks", + timers = jQuery.timers, + data = jQuery._data( this ); + + if ( index ) { + if ( data[ index ] && data[ index ].stop ) { + stopQueue( data[ index ] ); + } + } else { + for ( index in data ) { + if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { + stopQueue( data[ index ] ); + } + } + } + + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) { + timers[ index ].anim.stop( gotoEnd ); + dequeue = false; + timers.splice( index, 1 ); + } + } + + // start the next in the queue if the last step wasn't forced + // timers currently will call their complete callbacks, which will dequeue + // but only if they were gotoEnd + if ( dequeue || !gotoEnd ) { + jQuery.dequeue( this, type ); + } + }); + }, + finish: function( type ) { + if ( type !== false ) { + type = type || "fx"; + } + return this.each(function() { + var index, + data = jQuery._data( this ), + queue = data[ type + "queue" ], + hooks = data[ type + "queueHooks" ], + timers = jQuery.timers, + length = queue ? queue.length : 0; + + // enable finishing flag on private data + data.finish = true; + + // empty the queue first + jQuery.queue( this, type, [] ); + + if ( hooks && hooks.stop ) { + hooks.stop.call( this, true ); + } + + // look for any active animations, and finish them + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && timers[ index ].queue === type ) { + timers[ index ].anim.stop( true ); + timers.splice( index, 1 ); + } + } + + // look for any animations in the old queue and finish them + for ( index = 0; index < length; index++ ) { + if ( queue[ index ] && queue[ index ].finish ) { + queue[ index ].finish.call( this ); + } + } + + // turn off finishing flag + delete data.finish; + }); + } +}); + +jQuery.each([ "toggle", "show", "hide" ], function( i, name ) { + var cssFn = jQuery.fn[ name ]; + jQuery.fn[ name ] = function( speed, easing, callback ) { + return speed == null || typeof speed === "boolean" ? + cssFn.apply( this, arguments ) : + this.animate( genFx( name, true ), speed, easing, callback ); + }; +}); + +// Generate shortcuts for custom animations +jQuery.each({ + slideDown: genFx("show"), + slideUp: genFx("hide"), + slideToggle: genFx("toggle"), + fadeIn: { opacity: "show" }, + fadeOut: { opacity: "hide" }, + fadeToggle: { opacity: "toggle" } +}, function( name, props ) { + jQuery.fn[ name ] = function( speed, easing, callback ) { + return this.animate( props, speed, easing, callback ); + }; +}); + +jQuery.timers = []; +jQuery.fx.tick = function() { + var timer, + timers = jQuery.timers, + i = 0; + + fxNow = jQuery.now(); + + for ( ; i < timers.length; i++ ) { + timer = timers[ i ]; + // Checks the timer has not already been removed + if ( !timer() && timers[ i ] === timer ) { + timers.splice( i--, 1 ); + } + } + + if ( !timers.length ) { + jQuery.fx.stop(); + } + fxNow = undefined; +}; + +jQuery.fx.timer = function( timer ) { + jQuery.timers.push( timer ); + if ( timer() ) { + jQuery.fx.start(); + } else { + jQuery.timers.pop(); + } +}; + +jQuery.fx.interval = 13; + +jQuery.fx.start = function() { + if ( !timerId ) { + timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval ); + } +}; + +jQuery.fx.stop = function() { + clearInterval( timerId ); + timerId = null; +}; + +jQuery.fx.speeds = { + slow: 600, + fast: 200, + // Default speed + _default: 400 +}; + + +// Based off of the plugin by Clint Helfers, with permission. +// http://blindsignals.com/index.php/2009/07/jquery-delay/ +jQuery.fn.delay = function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = setTimeout( next, time ); + hooks.stop = function() { + clearTimeout( timeout ); + }; + }); +}; + + +(function() { + // Minified: var a,b,c,d,e + var input, div, select, a, opt; + + // Setup + div = document.createElement( "div" ); + div.setAttribute( "className", "t" ); + div.innerHTML = " <link/><table></table><a href='/a'>a</a><input type='checkbox'/>"; + a = div.getElementsByTagName("a")[ 0 ]; + + // First batch of tests. + select = document.createElement("select"); + opt = select.appendChild( document.createElement("option") ); + input = div.getElementsByTagName("input")[ 0 ]; + + a.style.cssText = "top:1px"; + + // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) + support.getSetAttribute = div.className !== "t"; + + // Get the style information from getAttribute + // (IE uses .cssText instead) + support.style = /top/.test( a.getAttribute("style") ); + + // Make sure that URLs aren't manipulated + // (IE normalizes it by default) + support.hrefNormalized = a.getAttribute("href") === "/a"; + + // Check the default checkbox/radio value ("" on WebKit; "on" elsewhere) + support.checkOn = !!input.value; + + // Make sure that a selected-by-default option has a working selected property. + // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) + support.optSelected = opt.selected; + + // Tests for enctype support on a form (#6743) + support.enctype = !!document.createElement("form").enctype; + + // Make sure that the options inside disabled selects aren't marked as disabled + // (WebKit marks them as disabled) + select.disabled = true; + support.optDisabled = !opt.disabled; + + // Support: IE8 only + // Check if we can trust getAttribute("value") + input = document.createElement( "input" ); + input.setAttribute( "value", "" ); + support.input = input.getAttribute( "value" ) === ""; + + // Check if an input maintains its value after becoming a radio + input.value = "t"; + input.setAttribute( "type", "radio" ); + support.radioValue = input.value === "t"; +})(); + + +var rreturn = /\r/g; + +jQuery.fn.extend({ + val: function( value ) { + var hooks, ret, isFunction, + elem = this[0]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { + return ret; + } + + ret = elem.value; + + return typeof ret === "string" ? + // handle most common string cases + ret.replace(rreturn, "") : + // handle cases where value is null/undef or number + ret == null ? "" : ret; + } + + return; + } + + isFunction = jQuery.isFunction( value ); + + return this.each(function( i ) { + var val; + + if ( this.nodeType !== 1 ) { + return; + } + + if ( isFunction ) { + val = value.call( this, i, jQuery( this ).val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + } else if ( typeof val === "number" ) { + val += ""; + } else if ( jQuery.isArray( val ) ) { + val = jQuery.map( val, function( value ) { + return value == null ? "" : value + ""; + }); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + }); + } +}); + +jQuery.extend({ + valHooks: { + option: { + get: function( elem ) { + var val = jQuery.find.attr( elem, "value" ); + return val != null ? + val : + // Support: IE10-11+ + // option.text throws exceptions (#14686, #14858) + jQuery.trim( jQuery.text( elem ) ); + } + }, + select: { + get: function( elem ) { + var value, option, + options = elem.options, + index = elem.selectedIndex, + one = elem.type === "select-one" || index < 0, + values = one ? null : [], + max = one ? index + 1 : options.length, + i = index < 0 ? + max : + one ? index : 0; + + // Loop through all the selected options + for ( ; i < max; i++ ) { + option = options[ i ]; + + // oldIE doesn't update selected after form reset (#2551) + if ( ( option.selected || i === index ) && + // Don't return options that are disabled or in a disabled optgroup + ( support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) && + ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + return values; + }, + + set: function( elem, value ) { + var optionSet, option, + options = elem.options, + values = jQuery.makeArray( value ), + i = options.length; + + while ( i-- ) { + option = options[ i ]; + + if ( jQuery.inArray( jQuery.valHooks.option.get( option ), values ) >= 0 ) { + + // Support: IE6 + // When new option element is added to select box we need to + // force reflow of newly added node in order to workaround delay + // of initialization properties + try { + option.selected = optionSet = true; + + } catch ( _ ) { + + // Will be executed only in IE6 + option.scrollHeight; + } + + } else { + option.selected = false; + } + } + + // Force browsers to behave consistently when non-matching value is set + if ( !optionSet ) { + elem.selectedIndex = -1; + } + + return options; + } + } + } +}); + +// Radios and checkboxes getter/setter +jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + set: function( elem, value ) { + if ( jQuery.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); + } + } + }; + if ( !support.checkOn ) { + jQuery.valHooks[ this ].get = function( elem ) { + // Support: Webkit + // "" is returned instead of "on" if a value isn't specified + return elem.getAttribute("value") === null ? "on" : elem.value; + }; + } +}); + + + + +var nodeHook, boolHook, + attrHandle = jQuery.expr.attrHandle, + ruseDefault = /^(?:checked|selected)$/i, + getSetAttribute = support.getSetAttribute, + getSetInput = support.input; + +jQuery.fn.extend({ + attr: function( name, value ) { + return access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each(function() { + jQuery.removeAttr( this, name ); + }); + } +}); + +jQuery.extend({ + attr: function( elem, name, value ) { + var hooks, ret, + nType = elem.nodeType; + + // don't get/set attributes on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === strundefined ) { + return jQuery.prop( elem, name, value ); + } + + // All attributes are lowercase + // Grab necessary hook if one is defined + if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) { + name = name.toLowerCase(); + hooks = jQuery.attrHooks[ name ] || + ( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook ); + } + + if ( value !== undefined ) { + + if ( value === null ) { + jQuery.removeAttr( elem, name ); + + } else if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + elem.setAttribute( name, value + "" ); + return value; + } + + } else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + ret = jQuery.find.attr( elem, name ); + + // Non-existent attributes return null, we normalize to undefined + return ret == null ? + undefined : + ret; + } + }, + + removeAttr: function( elem, value ) { + var name, propName, + i = 0, + attrNames = value && value.match( rnotwhite ); + + if ( attrNames && elem.nodeType === 1 ) { + while ( (name = attrNames[i++]) ) { + propName = jQuery.propFix[ name ] || name; + + // Boolean attributes get special treatment (#10870) + if ( jQuery.expr.match.bool.test( name ) ) { + // Set corresponding property to false + if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) { + elem[ propName ] = false; + // Support: IE<9 + // Also clear defaultChecked/defaultSelected (if appropriate) + } else { + elem[ jQuery.camelCase( "default-" + name ) ] = + elem[ propName ] = false; + } + + // See #9699 for explanation of this approach (setting first, then removal) + } else { + jQuery.attr( elem, name, "" ); + } + + elem.removeAttribute( getSetAttribute ? name : propName ); + } + } + }, + + attrHooks: { + type: { + set: function( elem, value ) { + if ( !support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { + // Setting the type on a radio button after the value resets the value in IE6-9 + // Reset value to default in case type is set after value during creation + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + } + } +}); + +// Hook for boolean attributes +boolHook = { + set: function( elem, value, name ) { + if ( value === false ) { + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) { + // IE<8 needs the *property* name + elem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name ); + + // Use defaultChecked and defaultSelected for oldIE + } else { + elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true; + } + + return name; + } +}; + +// Retrieve booleans specially +jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) { + + var getter = attrHandle[ name ] || jQuery.find.attr; + + attrHandle[ name ] = getSetInput && getSetAttribute || !ruseDefault.test( name ) ? + function( elem, name, isXML ) { + var ret, handle; + if ( !isXML ) { + // Avoid an infinite loop by temporarily removing this function from the getter + handle = attrHandle[ name ]; + attrHandle[ name ] = ret; + ret = getter( elem, name, isXML ) != null ? + name.toLowerCase() : + null; + attrHandle[ name ] = handle; + } + return ret; + } : + function( elem, name, isXML ) { + if ( !isXML ) { + return elem[ jQuery.camelCase( "default-" + name ) ] ? + name.toLowerCase() : + null; + } + }; +}); + +// fix oldIE attroperties +if ( !getSetInput || !getSetAttribute ) { + jQuery.attrHooks.value = { + set: function( elem, value, name ) { + if ( jQuery.nodeName( elem, "input" ) ) { + // Does not return so that setAttribute is also used + elem.defaultValue = value; + } else { + // Use nodeHook if defined (#1954); otherwise setAttribute is fine + return nodeHook && nodeHook.set( elem, value, name ); + } + } + }; +} + +// IE6/7 do not support getting/setting some attributes with get/setAttribute +if ( !getSetAttribute ) { + + // Use this for any attribute in IE6/7 + // This fixes almost every IE6/7 issue + nodeHook = { + set: function( elem, value, name ) { + // Set the existing or create a new attribute node + var ret = elem.getAttributeNode( name ); + if ( !ret ) { + elem.setAttributeNode( + (ret = elem.ownerDocument.createAttribute( name )) + ); + } + + ret.value = value += ""; + + // Break association with cloned elements by also using setAttribute (#9646) + if ( name === "value" || value === elem.getAttribute( name ) ) { + return value; + } + } + }; + + // Some attributes are constructed with empty-string values when not defined + attrHandle.id = attrHandle.name = attrHandle.coords = + function( elem, name, isXML ) { + var ret; + if ( !isXML ) { + return (ret = elem.getAttributeNode( name )) && ret.value !== "" ? + ret.value : + null; + } + }; + + // Fixing value retrieval on a button requires this module + jQuery.valHooks.button = { + get: function( elem, name ) { + var ret = elem.getAttributeNode( name ); + if ( ret && ret.specified ) { + return ret.value; + } + }, + set: nodeHook.set + }; + + // Set contenteditable to false on removals(#10429) + // Setting to empty string throws an error as an invalid value + jQuery.attrHooks.contenteditable = { + set: function( elem, value, name ) { + nodeHook.set( elem, value === "" ? false : value, name ); + } + }; + + // Set width and height to auto instead of 0 on empty string( Bug #8150 ) + // This is for removals + jQuery.each([ "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = { + set: function( elem, value ) { + if ( value === "" ) { + elem.setAttribute( name, "auto" ); + return value; + } + } + }; + }); +} + +if ( !support.style ) { + jQuery.attrHooks.style = { + get: function( elem ) { + // Return undefined in the case of empty string + // Note: IE uppercases css property names, but if we were to .toLowerCase() + // .cssText, that would destroy case senstitivity in URL's, like in "background" + return elem.style.cssText || undefined; + }, + set: function( elem, value ) { + return ( elem.style.cssText = value + "" ); + } + }; +} + + + + +var rfocusable = /^(?:input|select|textarea|button|object)$/i, + rclickable = /^(?:a|area)$/i; + +jQuery.fn.extend({ + prop: function( name, value ) { + return access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + name = jQuery.propFix[ name ] || name; + return this.each(function() { + // try/catch handles cases where IE balks (such as removing a property on window) + try { + this[ name ] = undefined; + delete this[ name ]; + } catch( e ) {} + }); + } +}); + +jQuery.extend({ + propFix: { + "for": "htmlFor", + "class": "className" + }, + + prop: function( elem, name, value ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set properties on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + if ( notxml ) { + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + return hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ? + ret : + ( elem[ name ] = value ); + + } else { + return hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ? + ret : + elem[ name ]; + } + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set + // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + // Use proper attribute retrieval(#12072) + var tabindex = jQuery.find.attr( elem, "tabindex" ); + + return tabindex ? + parseInt( tabindex, 10 ) : + rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? + 0 : + -1; + } + } + } +}); + +// Some attributes require a special call on IE +// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx +if ( !support.hrefNormalized ) { + // href/src property should get the full normalized URL (#10299/#12915) + jQuery.each([ "href", "src" ], function( i, name ) { + jQuery.propHooks[ name ] = { + get: function( elem ) { + return elem.getAttribute( name, 4 ); + } + }; + }); +} + +// Support: Safari, IE9+ +// mis-reports the default selected property of an option +// Accessing the parent's selectedIndex property fixes it +if ( !support.optSelected ) { + jQuery.propHooks.selected = { + get: function( elem ) { + var parent = elem.parentNode; + + if ( parent ) { + parent.selectedIndex; + + // Make sure that it also works with optgroups, see #5701 + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + return null; + } + }; +} + +jQuery.each([ + "tabIndex", + "readOnly", + "maxLength", + "cellSpacing", + "cellPadding", + "rowSpan", + "colSpan", + "useMap", + "frameBorder", + "contentEditable" +], function() { + jQuery.propFix[ this.toLowerCase() ] = this; +}); + +// IE6/7 call enctype encoding +if ( !support.enctype ) { + jQuery.propFix.enctype = "encoding"; +} + + + + +var rclass = /[\t\r\n\f]/g; + +jQuery.fn.extend({ + addClass: function( value ) { + var classes, elem, cur, clazz, j, finalValue, + i = 0, + len = this.length, + proceed = typeof value === "string" && value; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).addClass( value.call( this, j, this.className ) ); + }); + } + + if ( proceed ) { + // The disjunction here is for better compressibility (see removeClass) + classes = ( value || "" ).match( rnotwhite ) || []; + + for ( ; i < len; i++ ) { + elem = this[ i ]; + cur = elem.nodeType === 1 && ( elem.className ? + ( " " + elem.className + " " ).replace( rclass, " " ) : + " " + ); + + if ( cur ) { + j = 0; + while ( (clazz = classes[j++]) ) { + if ( cur.indexOf( " " + clazz + " " ) < 0 ) { + cur += clazz + " "; + } + } + + // only assign if different to avoid unneeded rendering. + finalValue = jQuery.trim( cur ); + if ( elem.className !== finalValue ) { + elem.className = finalValue; + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var classes, elem, cur, clazz, j, finalValue, + i = 0, + len = this.length, + proceed = arguments.length === 0 || typeof value === "string" && value; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).removeClass( value.call( this, j, this.className ) ); + }); + } + if ( proceed ) { + classes = ( value || "" ).match( rnotwhite ) || []; + + for ( ; i < len; i++ ) { + elem = this[ i ]; + // This expression is here for better compressibility (see addClass) + cur = elem.nodeType === 1 && ( elem.className ? + ( " " + elem.className + " " ).replace( rclass, " " ) : + "" + ); + + if ( cur ) { + j = 0; + while ( (clazz = classes[j++]) ) { + // Remove *all* instances + while ( cur.indexOf( " " + clazz + " " ) >= 0 ) { + cur = cur.replace( " " + clazz + " ", " " ); + } + } + + // only assign if different to avoid unneeded rendering. + finalValue = value ? jQuery.trim( cur ) : ""; + if ( elem.className !== finalValue ) { + elem.className = finalValue; + } + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value; + + if ( typeof stateVal === "boolean" && type === "string" ) { + return stateVal ? this.addClass( value ) : this.removeClass( value ); + } + + if ( jQuery.isFunction( value ) ) { + return this.each(function( i ) { + jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); + }); + } + + return this.each(function() { + if ( type === "string" ) { + // toggle individual class names + var className, + i = 0, + self = jQuery( this ), + classNames = value.match( rnotwhite ) || []; + + while ( (className = classNames[ i++ ]) ) { + // check each className given, space separated list + if ( self.hasClass( className ) ) { + self.removeClass( className ); + } else { + self.addClass( className ); + } + } + + // Toggle whole class name + } else if ( type === strundefined || type === "boolean" ) { + if ( this.className ) { + // store className if set + jQuery._data( this, "__className__", this.className ); + } + + // If the element has a class name or if we're passed "false", + // then remove the whole classname (if there was one, the above saved it). + // Otherwise bring back whatever was previously saved (if anything), + // falling back to the empty string if nothing was stored. + this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; + } + }); + }, + + hasClass: function( selector ) { + var className = " " + selector + " ", + i = 0, + l = this.length; + for ( ; i < l; i++ ) { + if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) { + return true; + } + } + + return false; + } +}); + + + + +// Return jQuery for attributes-only inclusion + + +jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + + "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) { + + // Handle event binding + jQuery.fn[ name ] = function( data, fn ) { + return arguments.length > 0 ? + this.on( name, null, data, fn ) : + this.trigger( name ); + }; +}); + +jQuery.fn.extend({ + hover: function( fnOver, fnOut ) { + return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); + }, + + bind: function( types, data, fn ) { + return this.on( types, null, data, fn ); + }, + unbind: function( types, fn ) { + return this.off( types, null, fn ); + }, + + delegate: function( selector, types, data, fn ) { + return this.on( types, selector, data, fn ); + }, + undelegate: function( selector, types, fn ) { + // ( namespace ) or ( selector, types [, fn] ) + return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn ); + } +}); + + +var nonce = jQuery.now(); + +var rquery = (/\?/); + + + +var rvalidtokens = /(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g; + +jQuery.parseJSON = function( data ) { + // Attempt to parse using the native JSON parser first + if ( window.JSON && window.JSON.parse ) { + // Support: Android 2.3 + // Workaround failure to string-cast null input + return window.JSON.parse( data + "" ); + } + + var requireNonComma, + depth = null, + str = jQuery.trim( data + "" ); + + // Guard against invalid (and possibly dangerous) input by ensuring that nothing remains + // after removing valid tokens + return str && !jQuery.trim( str.replace( rvalidtokens, function( token, comma, open, close ) { + + // Force termination if we see a misplaced comma + if ( requireNonComma && comma ) { + depth = 0; + } + + // Perform no more replacements after returning to outermost depth + if ( depth === 0 ) { + return token; + } + + // Commas must not follow "[", "{", or "," + requireNonComma = open || comma; + + // Determine new depth + // array/object open ("[" or "{"): depth += true - false (increment) + // array/object close ("]" or "}"): depth += false - true (decrement) + // other cases ("," or primitive): depth += true - true (numeric cast) + depth += !close - !open; + + // Remove this token + return ""; + }) ) ? + ( Function( "return " + str ) )() : + jQuery.error( "Invalid JSON: " + data ); +}; + + +// Cross-browser xml parsing +jQuery.parseXML = function( data ) { + var xml, tmp; + if ( !data || typeof data !== "string" ) { + return null; + } + try { + if ( window.DOMParser ) { // Standard + tmp = new DOMParser(); + xml = tmp.parseFromString( data, "text/xml" ); + } else { // IE + xml = new ActiveXObject( "Microsoft.XMLDOM" ); + xml.async = "false"; + xml.loadXML( data ); + } + } catch( e ) { + xml = undefined; + } + if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) { + jQuery.error( "Invalid XML: " + data ); + } + return xml; +}; + + +var + // Document location + ajaxLocParts, + ajaxLocation, + + rhash = /#.*$/, + rts = /([?&])_=[^&]*/, + rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL + // #7653, #8125, #8152: local protocol detection + rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/, + rnoContent = /^(?:GET|HEAD)$/, + rprotocol = /^\/\//, + rurl = /^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/, + + /* Prefilters + * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) + * 2) These are called: + * - BEFORE asking for a transport + * - AFTER param serialization (s.data is a string if s.processData is true) + * 3) key is the dataType + * 4) the catchall symbol "*" can be used + * 5) execution will start with transport dataType and THEN continue down to "*" if needed + */ + prefilters = {}, + + /* Transports bindings + * 1) key is the dataType + * 2) the catchall symbol "*" can be used + * 3) selection will start with transport dataType and THEN go to "*" if needed + */ + transports = {}, + + // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression + allTypes = "*/".concat("*"); + +// #8138, IE may throw an exception when accessing +// a field from window.location if document.domain has been set +try { + ajaxLocation = location.href; +} catch( e ) { + // Use the href attribute of an A element + // since IE will modify it given document.location + ajaxLocation = document.createElement( "a" ); + ajaxLocation.href = ""; + ajaxLocation = ajaxLocation.href; +} + +// Segment location into parts +ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || []; + +// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport +function addToPrefiltersOrTransports( structure ) { + + // dataTypeExpression is optional and defaults to "*" + return function( dataTypeExpression, func ) { + + if ( typeof dataTypeExpression !== "string" ) { + func = dataTypeExpression; + dataTypeExpression = "*"; + } + + var dataType, + i = 0, + dataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || []; + + if ( jQuery.isFunction( func ) ) { + // For each dataType in the dataTypeExpression + while ( (dataType = dataTypes[i++]) ) { + // Prepend if requested + if ( dataType.charAt( 0 ) === "+" ) { + dataType = dataType.slice( 1 ) || "*"; + (structure[ dataType ] = structure[ dataType ] || []).unshift( func ); + + // Otherwise append + } else { + (structure[ dataType ] = structure[ dataType ] || []).push( func ); + } + } + } + }; +} + +// Base inspection function for prefilters and transports +function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) { + + var inspected = {}, + seekingTransport = ( structure === transports ); + + function inspect( dataType ) { + var selected; + inspected[ dataType ] = true; + jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) { + var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR ); + if ( typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) { + options.dataTypes.unshift( dataTypeOrTransport ); + inspect( dataTypeOrTransport ); + return false; + } else if ( seekingTransport ) { + return !( selected = dataTypeOrTransport ); + } + }); + return selected; + } + + return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" ); +} + +// A special extend for ajax options +// that takes "flat" options (not to be deep extended) +// Fixes #9887 +function ajaxExtend( target, src ) { + var deep, key, + flatOptions = jQuery.ajaxSettings.flatOptions || {}; + + for ( key in src ) { + if ( src[ key ] !== undefined ) { + ( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ]; + } + } + if ( deep ) { + jQuery.extend( true, target, deep ); + } + + return target; +} + +/* Handles responses to an ajax request: + * - finds the right dataType (mediates between content-type and expected dataType) + * - returns the corresponding response + */ +function ajaxHandleResponses( s, jqXHR, responses ) { + var firstDataType, ct, finalDataType, type, + contents = s.contents, + dataTypes = s.dataTypes; + + // Remove auto dataType and get content-type in the process + while ( dataTypes[ 0 ] === "*" ) { + dataTypes.shift(); + if ( ct === undefined ) { + ct = s.mimeType || jqXHR.getResponseHeader("Content-Type"); + } + } + + // Check if we're dealing with a known content-type + if ( ct ) { + for ( type in contents ) { + if ( contents[ type ] && contents[ type ].test( ct ) ) { + dataTypes.unshift( type ); + break; + } + } + } + + // Check to see if we have a response for the expected dataType + if ( dataTypes[ 0 ] in responses ) { + finalDataType = dataTypes[ 0 ]; + } else { + // Try convertible dataTypes + for ( type in responses ) { + if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) { + finalDataType = type; + break; + } + if ( !firstDataType ) { + firstDataType = type; + } + } + // Or just use first one + finalDataType = finalDataType || firstDataType; + } + + // If we found a dataType + // We add the dataType to the list if needed + // and return the corresponding response + if ( finalDataType ) { + if ( finalDataType !== dataTypes[ 0 ] ) { + dataTypes.unshift( finalDataType ); + } + return responses[ finalDataType ]; + } +} + +/* Chain conversions given the request and the original response + * Also sets the responseXXX fields on the jqXHR instance + */ +function ajaxConvert( s, response, jqXHR, isSuccess ) { + var conv2, current, conv, tmp, prev, + converters = {}, + // Work with a copy of dataTypes in case we need to modify it for conversion + dataTypes = s.dataTypes.slice(); + + // Create converters map with lowercased keys + if ( dataTypes[ 1 ] ) { + for ( conv in s.converters ) { + converters[ conv.toLowerCase() ] = s.converters[ conv ]; + } + } + + current = dataTypes.shift(); + + // Convert to each sequential dataType + while ( current ) { + + if ( s.responseFields[ current ] ) { + jqXHR[ s.responseFields[ current ] ] = response; + } + + // Apply the dataFilter if provided + if ( !prev && isSuccess && s.dataFilter ) { + response = s.dataFilter( response, s.dataType ); + } + + prev = current; + current = dataTypes.shift(); + + if ( current ) { + + // There's only work to do if current dataType is non-auto + if ( current === "*" ) { + + current = prev; + + // Convert response if prev dataType is non-auto and differs from current + } else if ( prev !== "*" && prev !== current ) { + + // Seek a direct converter + conv = converters[ prev + " " + current ] || converters[ "* " + current ]; + + // If none found, seek a pair + if ( !conv ) { + for ( conv2 in converters ) { + + // If conv2 outputs current + tmp = conv2.split( " " ); + if ( tmp[ 1 ] === current ) { + + // If prev can be converted to accepted input + conv = converters[ prev + " " + tmp[ 0 ] ] || + converters[ "* " + tmp[ 0 ] ]; + if ( conv ) { + // Condense equivalence converters + if ( conv === true ) { + conv = converters[ conv2 ]; + + // Otherwise, insert the intermediate dataType + } else if ( converters[ conv2 ] !== true ) { + current = tmp[ 0 ]; + dataTypes.unshift( tmp[ 1 ] ); + } + break; + } + } + } + } + + // Apply converter (if not an equivalence) + if ( conv !== true ) { + + // Unless errors are allowed to bubble, catch and return them + if ( conv && s[ "throws" ] ) { + response = conv( response ); + } else { + try { + response = conv( response ); + } catch ( e ) { + return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current }; + } + } + } + } + } + } + + return { state: "success", data: response }; +} + +jQuery.extend({ + + // Counter for holding the number of active queries + active: 0, + + // Last-Modified header cache for next request + lastModified: {}, + etag: {}, + + ajaxSettings: { + url: ajaxLocation, + type: "GET", + isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ), + global: true, + processData: true, + async: true, + contentType: "application/x-www-form-urlencoded; charset=UTF-8", + /* + timeout: 0, + data: null, + dataType: null, + username: null, + password: null, + cache: null, + throws: false, + traditional: false, + headers: {}, + */ + + accepts: { + "*": allTypes, + text: "text/plain", + html: "text/html", + xml: "application/xml, text/xml", + json: "application/json, text/javascript" + }, + + contents: { + xml: /xml/, + html: /html/, + json: /json/ + }, + + responseFields: { + xml: "responseXML", + text: "responseText", + json: "responseJSON" + }, + + // Data converters + // Keys separate source (or catchall "*") and destination types with a single space + converters: { + + // Convert anything to text + "* text": String, + + // Text to html (true = no transformation) + "text html": true, + + // Evaluate text as a json expression + "text json": jQuery.parseJSON, + + // Parse text as xml + "text xml": jQuery.parseXML + }, + + // For options that shouldn't be deep extended: + // you can add your own custom options here if + // and when you create one that shouldn't be + // deep extended (see ajaxExtend) + flatOptions: { + url: true, + context: true + } + }, + + // Creates a full fledged settings object into target + // with both ajaxSettings and settings fields. + // If target is omitted, writes into ajaxSettings. + ajaxSetup: function( target, settings ) { + return settings ? + + // Building a settings object + ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) : + + // Extending ajaxSettings + ajaxExtend( jQuery.ajaxSettings, target ); + }, + + ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), + ajaxTransport: addToPrefiltersOrTransports( transports ), + + // Main method + ajax: function( url, options ) { + + // If url is an object, simulate pre-1.5 signature + if ( typeof url === "object" ) { + options = url; + url = undefined; + } + + // Force options to be an object + options = options || {}; + + var // Cross-domain detection vars + parts, + // Loop variable + i, + // URL without anti-cache param + cacheURL, + // Response headers as string + responseHeadersString, + // timeout handle + timeoutTimer, + + // To know if global events are to be dispatched + fireGlobals, + + transport, + // Response headers + responseHeaders, + // Create the final options object + s = jQuery.ajaxSetup( {}, options ), + // Callbacks context + callbackContext = s.context || s, + // Context for global events is callbackContext if it is a DOM node or jQuery collection + globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ? + jQuery( callbackContext ) : + jQuery.event, + // Deferreds + deferred = jQuery.Deferred(), + completeDeferred = jQuery.Callbacks("once memory"), + // Status-dependent callbacks + statusCode = s.statusCode || {}, + // Headers (they are sent all at once) + requestHeaders = {}, + requestHeadersNames = {}, + // The jqXHR state + state = 0, + // Default abort message + strAbort = "canceled", + // Fake xhr + jqXHR = { + readyState: 0, + + // Builds headers hashtable if needed + getResponseHeader: function( key ) { + var match; + if ( state === 2 ) { + if ( !responseHeaders ) { + responseHeaders = {}; + while ( (match = rheaders.exec( responseHeadersString )) ) { + responseHeaders[ match[1].toLowerCase() ] = match[ 2 ]; + } + } + match = responseHeaders[ key.toLowerCase() ]; + } + return match == null ? null : match; + }, + + // Raw string + getAllResponseHeaders: function() { + return state === 2 ? responseHeadersString : null; + }, + + // Caches the header + setRequestHeader: function( name, value ) { + var lname = name.toLowerCase(); + if ( !state ) { + name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name; + requestHeaders[ name ] = value; + } + return this; + }, + + // Overrides response content-type header + overrideMimeType: function( type ) { + if ( !state ) { + s.mimeType = type; + } + return this; + }, + + // Status-dependent callbacks + statusCode: function( map ) { + var code; + if ( map ) { + if ( state < 2 ) { + for ( code in map ) { + // Lazy-add the new callback in a way that preserves old ones + statusCode[ code ] = [ statusCode[ code ], map[ code ] ]; + } + } else { + // Execute the appropriate callbacks + jqXHR.always( map[ jqXHR.status ] ); + } + } + return this; + }, + + // Cancel the request + abort: function( statusText ) { + var finalText = statusText || strAbort; + if ( transport ) { + transport.abort( finalText ); + } + done( 0, finalText ); + return this; + } + }; + + // Attach deferreds + deferred.promise( jqXHR ).complete = completeDeferred.add; + jqXHR.success = jqXHR.done; + jqXHR.error = jqXHR.fail; + + // Remove hash character (#7531: and string promotion) + // Add protocol if not provided (#5866: IE7 issue with protocol-less urls) + // Handle falsy url in the settings object (#10093: consistency with old signature) + // We also use the url parameter if available + s.url = ( ( url || s.url || ajaxLocation ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" ); + + // Alias method option to type as per ticket #12004 + s.type = options.method || options.type || s.method || s.type; + + // Extract dataTypes list + s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( rnotwhite ) || [ "" ]; + + // A cross-domain request is in order when we have a protocol:host:port mismatch + if ( s.crossDomain == null ) { + parts = rurl.exec( s.url.toLowerCase() ); + s.crossDomain = !!( parts && + ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] || + ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? "80" : "443" ) ) !== + ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? "80" : "443" ) ) ) + ); + } + + // Convert data if not already a string + if ( s.data && s.processData && typeof s.data !== "string" ) { + s.data = jQuery.param( s.data, s.traditional ); + } + + // Apply prefilters + inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); + + // If request was aborted inside a prefilter, stop there + if ( state === 2 ) { + return jqXHR; + } + + // We can fire global events as of now if asked to + // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118) + fireGlobals = jQuery.event && s.global; + + // Watch for a new set of requests + if ( fireGlobals && jQuery.active++ === 0 ) { + jQuery.event.trigger("ajaxStart"); + } + + // Uppercase the type + s.type = s.type.toUpperCase(); + + // Determine if request has content + s.hasContent = !rnoContent.test( s.type ); + + // Save the URL in case we're toying with the If-Modified-Since + // and/or If-None-Match header later on + cacheURL = s.url; + + // More options handling for requests with no content + if ( !s.hasContent ) { + + // If data is available, append data to url + if ( s.data ) { + cacheURL = ( s.url += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data ); + // #9682: remove data so that it's not used in an eventual retry + delete s.data; + } + + // Add anti-cache in url if needed + if ( s.cache === false ) { + s.url = rts.test( cacheURL ) ? + + // If there is already a '_' parameter, set its value + cacheURL.replace( rts, "$1_=" + nonce++ ) : + + // Otherwise add one to the end + cacheURL + ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + nonce++; + } + } + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + if ( jQuery.lastModified[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] ); + } + if ( jQuery.etag[ cacheURL ] ) { + jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] ); + } + } + + // Set the correct header, if data is being sent + if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { + jqXHR.setRequestHeader( "Content-Type", s.contentType ); + } + + // Set the Accepts header for the server, depending on the dataType + jqXHR.setRequestHeader( + "Accept", + s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ? + s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : + s.accepts[ "*" ] + ); + + // Check for headers option + for ( i in s.headers ) { + jqXHR.setRequestHeader( i, s.headers[ i ] ); + } + + // Allow custom headers/mimetypes and early abort + if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) { + // Abort if not done already and return + return jqXHR.abort(); + } + + // aborting is no longer a cancellation + strAbort = "abort"; + + // Install callbacks on deferreds + for ( i in { success: 1, error: 1, complete: 1 } ) { + jqXHR[ i ]( s[ i ] ); + } + + // Get transport + transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); + + // If no transport, we auto-abort + if ( !transport ) { + done( -1, "No Transport" ); + } else { + jqXHR.readyState = 1; + + // Send global event + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); + } + // Timeout + if ( s.async && s.timeout > 0 ) { + timeoutTimer = setTimeout(function() { + jqXHR.abort("timeout"); + }, s.timeout ); + } + + try { + state = 1; + transport.send( requestHeaders, done ); + } catch ( e ) { + // Propagate exception as error if not done + if ( state < 2 ) { + done( -1, e ); + // Simply rethrow otherwise + } else { + throw e; + } + } + } + + // Callback for when everything is done + function done( status, nativeStatusText, responses, headers ) { + var isSuccess, success, error, response, modified, + statusText = nativeStatusText; + + // Called once + if ( state === 2 ) { + return; + } + + // State is "done" now + state = 2; + + // Clear timeout if it exists + if ( timeoutTimer ) { + clearTimeout( timeoutTimer ); + } + + // Dereference transport for early garbage collection + // (no matter how long the jqXHR object will be used) + transport = undefined; + + // Cache response headers + responseHeadersString = headers || ""; + + // Set readyState + jqXHR.readyState = status > 0 ? 4 : 0; + + // Determine if successful + isSuccess = status >= 200 && status < 300 || status === 304; + + // Get response data + if ( responses ) { + response = ajaxHandleResponses( s, jqXHR, responses ); + } + + // Convert no matter what (that way responseXXX fields are always set) + response = ajaxConvert( s, response, jqXHR, isSuccess ); + + // If successful, handle type chaining + if ( isSuccess ) { + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + modified = jqXHR.getResponseHeader("Last-Modified"); + if ( modified ) { + jQuery.lastModified[ cacheURL ] = modified; + } + modified = jqXHR.getResponseHeader("etag"); + if ( modified ) { + jQuery.etag[ cacheURL ] = modified; + } + } + + // if no content + if ( status === 204 || s.type === "HEAD" ) { + statusText = "nocontent"; + + // if not modified + } else if ( status === 304 ) { + statusText = "notmodified"; + + // If we have data, let's convert it + } else { + statusText = response.state; + success = response.data; + error = response.error; + isSuccess = !error; + } + } else { + // We extract error from statusText + // then normalize statusText and status for non-aborts + error = statusText; + if ( status || !statusText ) { + statusText = "error"; + if ( status < 0 ) { + status = 0; + } + } + } + + // Set data for the fake xhr object + jqXHR.status = status; + jqXHR.statusText = ( nativeStatusText || statusText ) + ""; + + // Success/Error + if ( isSuccess ) { + deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); + } else { + deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); + } + + // Status-dependent callbacks + jqXHR.statusCode( statusCode ); + statusCode = undefined; + + if ( fireGlobals ) { + globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError", + [ jqXHR, s, isSuccess ? success : error ] ); + } + + // Complete + completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); + + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); + // Handle the global AJAX counter + if ( !( --jQuery.active ) ) { + jQuery.event.trigger("ajaxStop"); + } + } + } + + return jqXHR; + }, + + getJSON: function( url, data, callback ) { + return jQuery.get( url, data, callback, "json" ); + }, + + getScript: function( url, callback ) { + return jQuery.get( url, undefined, callback, "script" ); + } +}); + +jQuery.each( [ "get", "post" ], function( i, method ) { + jQuery[ method ] = function( url, data, callback, type ) { + // shift arguments if data argument was omitted + if ( jQuery.isFunction( data ) ) { + type = type || callback; + callback = data; + data = undefined; + } + + return jQuery.ajax({ + url: url, + type: method, + dataType: type, + data: data, + success: callback + }); + }; +}); + + +jQuery._evalUrl = function( url ) { + return jQuery.ajax({ + url: url, + type: "GET", + dataType: "script", + async: false, + global: false, + "throws": true + }); +}; + + +jQuery.fn.extend({ + wrapAll: function( html ) { + if ( jQuery.isFunction( html ) ) { + return this.each(function(i) { + jQuery(this).wrapAll( html.call(this, i) ); + }); + } + + if ( this[0] ) { + // The elements to wrap the target around + var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true); + + if ( this[0].parentNode ) { + wrap.insertBefore( this[0] ); + } + + wrap.map(function() { + var elem = this; + + while ( elem.firstChild && elem.firstChild.nodeType === 1 ) { + elem = elem.firstChild; + } + + return elem; + }).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( jQuery.isFunction( html ) ) { + return this.each(function(i) { + jQuery(this).wrapInner( html.call(this, i) ); + }); + } + + return this.each(function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + }); + }, + + wrap: function( html ) { + var isFunction = jQuery.isFunction( html ); + + return this.each(function(i) { + jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html ); + }); + }, + + unwrap: function() { + return this.parent().each(function() { + if ( !jQuery.nodeName( this, "body" ) ) { + jQuery( this ).replaceWith( this.childNodes ); + } + }).end(); + } +}); + + +jQuery.expr.filters.hidden = function( elem ) { + // Support: Opera <= 12.12 + // Opera reports offsetWidths and offsetHeights less than zero on some elements + return elem.offsetWidth <= 0 && elem.offsetHeight <= 0 || + (!support.reliableHiddenOffsets() && + ((elem.style && elem.style.display) || jQuery.css( elem, "display" )) === "none"); +}; + +jQuery.expr.filters.visible = function( elem ) { + return !jQuery.expr.filters.hidden( elem ); +}; + + + + +var r20 = /%20/g, + rbracket = /\[\]$/, + rCRLF = /\r?\n/g, + rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i, + rsubmittable = /^(?:input|select|textarea|keygen)/i; + +function buildParams( prefix, obj, traditional, add ) { + var name; + + if ( jQuery.isArray( obj ) ) { + // Serialize array item. + jQuery.each( obj, function( i, v ) { + if ( traditional || rbracket.test( prefix ) ) { + // Treat each array item as a scalar. + add( prefix, v ); + + } else { + // Item is non-scalar (array or object), encode its numeric index. + buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add ); + } + }); + + } else if ( !traditional && jQuery.type( obj ) === "object" ) { + // Serialize object item. + for ( name in obj ) { + buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); + } + + } else { + // Serialize scalar item. + add( prefix, obj ); + } +} + +// Serialize an array of form elements or a set of +// key/values into a query string +jQuery.param = function( a, traditional ) { + var prefix, + s = [], + add = function( key, value ) { + // If value is a function, invoke it and return its value + value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value ); + s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value ); + }; + + // Set traditional to true for jQuery <= 1.3.2 behavior. + if ( traditional === undefined ) { + traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional; + } + + // If an array was passed in, assume that it is an array of form elements. + if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { + // Serialize the form elements + jQuery.each( a, function() { + add( this.name, this.value ); + }); + + } else { + // If traditional, encode the "old" way (the way 1.3.2 or older + // did it), otherwise encode params recursively. + for ( prefix in a ) { + buildParams( prefix, a[ prefix ], traditional, add ); + } + } + + // Return the resulting serialization + return s.join( "&" ).replace( r20, "+" ); +}; + +jQuery.fn.extend({ + serialize: function() { + return jQuery.param( this.serializeArray() ); + }, + serializeArray: function() { + return this.map(function() { + // Can add propHook for "elements" to filter or add form elements + var elements = jQuery.prop( this, "elements" ); + return elements ? jQuery.makeArray( elements ) : this; + }) + .filter(function() { + var type = this.type; + // Use .is(":disabled") so that fieldset[disabled] works + return this.name && !jQuery( this ).is( ":disabled" ) && + rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) && + ( this.checked || !rcheckableType.test( type ) ); + }) + .map(function( i, elem ) { + var val = jQuery( this ).val(); + + return val == null ? + null : + jQuery.isArray( val ) ? + jQuery.map( val, function( val ) { + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + }) : + { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + }).get(); + } +}); + + +// Create the request object +// (This is still attached to ajaxSettings for backward compatibility) +jQuery.ajaxSettings.xhr = window.ActiveXObject !== undefined ? + // Support: IE6+ + function() { + + // XHR cannot access local files, always use ActiveX for that case + return !this.isLocal && + + // Support: IE7-8 + // oldIE XHR does not support non-RFC2616 methods (#13240) + // See http://msdn.microsoft.com/en-us/library/ie/ms536648(v=vs.85).aspx + // and http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html#sec9 + // Although this check for six methods instead of eight + // since IE also does not support "trace" and "connect" + /^(get|post|head|put|delete|options)$/i.test( this.type ) && + + createStandardXHR() || createActiveXHR(); + } : + // For all other browsers, use the standard XMLHttpRequest object + createStandardXHR; + +var xhrId = 0, + xhrCallbacks = {}, + xhrSupported = jQuery.ajaxSettings.xhr(); + +// Support: IE<10 +// Open requests must be manually aborted on unload (#5280) +// See https://support.microsoft.com/kb/2856746 for more info +if ( window.attachEvent ) { + window.attachEvent( "onunload", function() { + for ( var key in xhrCallbacks ) { + xhrCallbacks[ key ]( undefined, true ); + } + }); +} + +// Determine support properties +support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported ); +xhrSupported = support.ajax = !!xhrSupported; + +// Create transport if the browser can provide an xhr +if ( xhrSupported ) { + + jQuery.ajaxTransport(function( options ) { + // Cross domain only allowed if supported through XMLHttpRequest + if ( !options.crossDomain || support.cors ) { + + var callback; + + return { + send: function( headers, complete ) { + var i, + xhr = options.xhr(), + id = ++xhrId; + + // Open the socket + xhr.open( options.type, options.url, options.async, options.username, options.password ); + + // Apply custom fields if provided + if ( options.xhrFields ) { + for ( i in options.xhrFields ) { + xhr[ i ] = options.xhrFields[ i ]; + } + } + + // Override mime type if needed + if ( options.mimeType && xhr.overrideMimeType ) { + xhr.overrideMimeType( options.mimeType ); + } + + // X-Requested-With header + // For cross-domain requests, seeing as conditions for a preflight are + // akin to a jigsaw puzzle, we simply never set it to be sure. + // (it can always be set on a per-request basis or even using ajaxSetup) + // For same-domain requests, won't change header if already provided. + if ( !options.crossDomain && !headers["X-Requested-With"] ) { + headers["X-Requested-With"] = "XMLHttpRequest"; + } + + // Set headers + for ( i in headers ) { + // Support: IE<9 + // IE's ActiveXObject throws a 'Type Mismatch' exception when setting + // request header to a null-value. + // + // To keep consistent with other XHR implementations, cast the value + // to string and ignore `undefined`. + if ( headers[ i ] !== undefined ) { + xhr.setRequestHeader( i, headers[ i ] + "" ); + } + } + + // Do send the request + // This may raise an exception which is actually + // handled in jQuery.ajax (so no try/catch here) + xhr.send( ( options.hasContent && options.data ) || null ); + + // Listener + callback = function( _, isAbort ) { + var status, statusText, responses; + + // Was never called and is aborted or complete + if ( callback && ( isAbort || xhr.readyState === 4 ) ) { + // Clean up + delete xhrCallbacks[ id ]; + callback = undefined; + xhr.onreadystatechange = jQuery.noop; + + // Abort manually if needed + if ( isAbort ) { + if ( xhr.readyState !== 4 ) { + xhr.abort(); + } + } else { + responses = {}; + status = xhr.status; + + // Support: IE<10 + // Accessing binary-data responseText throws an exception + // (#11426) + if ( typeof xhr.responseText === "string" ) { + responses.text = xhr.responseText; + } + + // Firefox throws an exception when accessing + // statusText for faulty cross-domain requests + try { + statusText = xhr.statusText; + } catch( e ) { + // We normalize with Webkit giving an empty statusText + statusText = ""; + } + + // Filter status for non standard behaviors + + // If the request is local and we have data: assume a success + // (success with no data won't get notified, that's the best we + // can do given current implementations) + if ( !status && options.isLocal && !options.crossDomain ) { + status = responses.text ? 200 : 404; + // IE - #1450: sometimes returns 1223 when it should be 204 + } else if ( status === 1223 ) { + status = 204; + } + } + } + + // Call complete if needed + if ( responses ) { + complete( status, statusText, responses, xhr.getAllResponseHeaders() ); + } + }; + + if ( !options.async ) { + // if we're in sync mode we fire the callback + callback(); + } else if ( xhr.readyState === 4 ) { + // (IE6 & IE7) if it's in cache and has been + // retrieved directly we need to fire the callback + setTimeout( callback ); + } else { + // Add to the list of active xhr callbacks + xhr.onreadystatechange = xhrCallbacks[ id ] = callback; + } + }, + + abort: function() { + if ( callback ) { + callback( undefined, true ); + } + } + }; + } + }); +} + +// Functions to create xhrs +function createStandardXHR() { + try { + return new window.XMLHttpRequest(); + } catch( e ) {} +} + +function createActiveXHR() { + try { + return new window.ActiveXObject( "Microsoft.XMLHTTP" ); + } catch( e ) {} +} + + + + +// Install script dataType +jQuery.ajaxSetup({ + accepts: { + script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript" + }, + contents: { + script: /(?:java|ecma)script/ + }, + converters: { + "text script": function( text ) { + jQuery.globalEval( text ); + return text; + } + } +}); + +// Handle cache's special case and global +jQuery.ajaxPrefilter( "script", function( s ) { + if ( s.cache === undefined ) { + s.cache = false; + } + if ( s.crossDomain ) { + s.type = "GET"; + s.global = false; + } +}); + +// Bind script tag hack transport +jQuery.ajaxTransport( "script", function(s) { + + // This transport only deals with cross domain requests + if ( s.crossDomain ) { + + var script, + head = document.head || jQuery("head")[0] || document.documentElement; + + return { + + send: function( _, callback ) { + + script = document.createElement("script"); + + script.async = true; + + if ( s.scriptCharset ) { + script.charset = s.scriptCharset; + } + + script.src = s.url; + + // Attach handlers for all browsers + script.onload = script.onreadystatechange = function( _, isAbort ) { + + if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) { + + // Handle memory leak in IE + script.onload = script.onreadystatechange = null; + + // Remove the script + if ( script.parentNode ) { + script.parentNode.removeChild( script ); + } + + // Dereference the script + script = null; + + // Callback if not abort + if ( !isAbort ) { + callback( 200, "success" ); + } + } + }; + + // Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending + // Use native DOM manipulation to avoid our domManip AJAX trickery + head.insertBefore( script, head.firstChild ); + }, + + abort: function() { + if ( script ) { + script.onload( undefined, true ); + } + } + }; + } +}); + + + + +var oldCallbacks = [], + rjsonp = /(=)\?(?=&|$)|\?\?/; + +// Default jsonp settings +jQuery.ajaxSetup({ + jsonp: "callback", + jsonpCallback: function() { + var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) ); + this[ callback ] = true; + return callback; + } +}); + +// Detect, normalize options and install callbacks for jsonp requests +jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { + + var callbackName, overwritten, responseContainer, + jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ? + "url" : + typeof s.data === "string" && !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && rjsonp.test( s.data ) && "data" + ); + + // Handle iff the expected data type is "jsonp" or we have a parameter to set + if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) { + + // Get callback name, remembering preexisting value associated with it + callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ? + s.jsonpCallback() : + s.jsonpCallback; + + // Insert callback into url or form data + if ( jsonProp ) { + s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName ); + } else if ( s.jsonp !== false ) { + s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName; + } + + // Use data converter to retrieve json after script execution + s.converters["script json"] = function() { + if ( !responseContainer ) { + jQuery.error( callbackName + " was not called" ); + } + return responseContainer[ 0 ]; + }; + + // force json dataType + s.dataTypes[ 0 ] = "json"; + + // Install callback + overwritten = window[ callbackName ]; + window[ callbackName ] = function() { + responseContainer = arguments; + }; + + // Clean-up function (fires after converters) + jqXHR.always(function() { + // Restore preexisting value + window[ callbackName ] = overwritten; + + // Save back as free + if ( s[ callbackName ] ) { + // make sure that re-using the options doesn't screw things around + s.jsonpCallback = originalSettings.jsonpCallback; + + // save the callback name for future use + oldCallbacks.push( callbackName ); + } + + // Call if it was a function and we have a response + if ( responseContainer && jQuery.isFunction( overwritten ) ) { + overwritten( responseContainer[ 0 ] ); + } + + responseContainer = overwritten = undefined; + }); + + // Delegate to script + return "script"; + } +}); + + + + +// data: string of html +// context (optional): If specified, the fragment will be created in this context, defaults to document +// keepScripts (optional): If true, will include scripts passed in the html string +jQuery.parseHTML = function( data, context, keepScripts ) { + if ( !data || typeof data !== "string" ) { + return null; + } + if ( typeof context === "boolean" ) { + keepScripts = context; + context = false; + } + context = context || document; + + var parsed = rsingleTag.exec( data ), + scripts = !keepScripts && []; + + // Single tag + if ( parsed ) { + return [ context.createElement( parsed[1] ) ]; + } + + parsed = jQuery.buildFragment( [ data ], context, scripts ); + + if ( scripts && scripts.length ) { + jQuery( scripts ).remove(); + } + + return jQuery.merge( [], parsed.childNodes ); +}; + + +// Keep a copy of the old load method +var _load = jQuery.fn.load; + +/** + * Load a url into a page + */ +jQuery.fn.load = function( url, params, callback ) { + if ( typeof url !== "string" && _load ) { + return _load.apply( this, arguments ); + } + + var selector, response, type, + self = this, + off = url.indexOf(" "); + + if ( off >= 0 ) { + selector = jQuery.trim( url.slice( off, url.length ) ); + url = url.slice( 0, off ); + } + + // If it's a function + if ( jQuery.isFunction( params ) ) { + + // We assume that it's the callback + callback = params; + params = undefined; + + // Otherwise, build a param string + } else if ( params && typeof params === "object" ) { + type = "POST"; + } + + // If we have elements to modify, make the request + if ( self.length > 0 ) { + jQuery.ajax({ + url: url, + + // if "type" variable is undefined, then "GET" method will be used + type: type, + dataType: "html", + data: params + }).done(function( responseText ) { + + // Save response for use in complete callback + response = arguments; + + self.html( selector ? + + // If a selector was specified, locate the right elements in a dummy div + // Exclude scripts to avoid IE 'Permission Denied' errors + jQuery("<div>").append( jQuery.parseHTML( responseText ) ).find( selector ) : + + // Otherwise use the full result + responseText ); + + }).complete( callback && function( jqXHR, status ) { + self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] ); + }); + } + + return this; +}; + + + + +// Attach a bunch of functions for handling common AJAX events +jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ) { + jQuery.fn[ type ] = function( fn ) { + return this.on( type, fn ); + }; +}); + + + + +jQuery.expr.filters.animated = function( elem ) { + return jQuery.grep(jQuery.timers, function( fn ) { + return elem === fn.elem; + }).length; +}; + + + + + +var docElem = window.document.documentElement; + +/** + * Gets a window from an element + */ +function getWindow( elem ) { + return jQuery.isWindow( elem ) ? + elem : + elem.nodeType === 9 ? + elem.defaultView || elem.parentWindow : + false; +} + +jQuery.offset = { + setOffset: function( elem, options, i ) { + var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition, + position = jQuery.css( elem, "position" ), + curElem = jQuery( elem ), + props = {}; + + // set position first, in-case top/left are set even on static elem + if ( position === "static" ) { + elem.style.position = "relative"; + } + + curOffset = curElem.offset(); + curCSSTop = jQuery.css( elem, "top" ); + curCSSLeft = jQuery.css( elem, "left" ); + calculatePosition = ( position === "absolute" || position === "fixed" ) && + jQuery.inArray("auto", [ curCSSTop, curCSSLeft ] ) > -1; + + // need to be able to calculate position if either top or left is auto and position is either absolute or fixed + if ( calculatePosition ) { + curPosition = curElem.position(); + curTop = curPosition.top; + curLeft = curPosition.left; + } else { + curTop = parseFloat( curCSSTop ) || 0; + curLeft = parseFloat( curCSSLeft ) || 0; + } + + if ( jQuery.isFunction( options ) ) { + options = options.call( elem, i, curOffset ); + } + + if ( options.top != null ) { + props.top = ( options.top - curOffset.top ) + curTop; + } + if ( options.left != null ) { + props.left = ( options.left - curOffset.left ) + curLeft; + } + + if ( "using" in options ) { + options.using.call( elem, props ); + } else { + curElem.css( props ); + } + } +}; + +jQuery.fn.extend({ + offset: function( options ) { + if ( arguments.length ) { + return options === undefined ? + this : + this.each(function( i ) { + jQuery.offset.setOffset( this, options, i ); + }); + } + + var docElem, win, + box = { top: 0, left: 0 }, + elem = this[ 0 ], + doc = elem && elem.ownerDocument; + + if ( !doc ) { + return; + } + + docElem = doc.documentElement; + + // Make sure it's not a disconnected DOM node + if ( !jQuery.contains( docElem, elem ) ) { + return box; + } + + // If we don't have gBCR, just use 0,0 rather than error + // BlackBerry 5, iOS 3 (original iPhone) + if ( typeof elem.getBoundingClientRect !== strundefined ) { + box = elem.getBoundingClientRect(); + } + win = getWindow( doc ); + return { + top: box.top + ( win.pageYOffset || docElem.scrollTop ) - ( docElem.clientTop || 0 ), + left: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 ) + }; + }, + + position: function() { + if ( !this[ 0 ] ) { + return; + } + + var offsetParent, offset, + parentOffset = { top: 0, left: 0 }, + elem = this[ 0 ]; + + // fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is its only offset parent + if ( jQuery.css( elem, "position" ) === "fixed" ) { + // we assume that getBoundingClientRect is available when computed position is fixed + offset = elem.getBoundingClientRect(); + } else { + // Get *real* offsetParent + offsetParent = this.offsetParent(); + + // Get correct offsets + offset = this.offset(); + if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) { + parentOffset = offsetParent.offset(); + } + + // Add offsetParent borders + parentOffset.top += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true ); + parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true ); + } + + // Subtract parent offsets and element margins + // note: when an element has margin: auto the offsetLeft and marginLeft + // are the same in Safari causing offset.left to incorrectly be 0 + return { + top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ), + left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true) + }; + }, + + offsetParent: function() { + return this.map(function() { + var offsetParent = this.offsetParent || docElem; + + while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) && jQuery.css( offsetParent, "position" ) === "static" ) ) { + offsetParent = offsetParent.offsetParent; + } + return offsetParent || docElem; + }); + } +}); + +// Create scrollLeft and scrollTop methods +jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) { + var top = /Y/.test( prop ); + + jQuery.fn[ method ] = function( val ) { + return access( this, function( elem, method, val ) { + var win = getWindow( elem ); + + if ( val === undefined ) { + return win ? (prop in win) ? win[ prop ] : + win.document.documentElement[ method ] : + elem[ method ]; + } + + if ( win ) { + win.scrollTo( + !top ? val : jQuery( win ).scrollLeft(), + top ? val : jQuery( win ).scrollTop() + ); + + } else { + elem[ method ] = val; + } + }, method, val, arguments.length, null ); + }; +}); + +// Add the top/left cssHooks using jQuery.fn.position +// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 +// getComputedStyle returns percent when specified for top/left/bottom/right +// rather than make the css module depend on the offset module, we just check for it here +jQuery.each( [ "top", "left" ], function( i, prop ) { + jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition, + function( elem, computed ) { + if ( computed ) { + computed = curCSS( elem, prop ); + // if curCSS returns percentage, fallback to offset + return rnumnonpx.test( computed ) ? + jQuery( elem ).position()[ prop ] + "px" : + computed; + } + } + ); +}); + + +// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods +jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { + jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) { + // margin is only for outerHeight, outerWidth + jQuery.fn[ funcName ] = function( margin, value ) { + var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ), + extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" ); + + return access( this, function( elem, type, value ) { + var doc; + + if ( jQuery.isWindow( elem ) ) { + // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there + // isn't a whole lot we can do. See pull request at this URL for discussion: + // https://github.com/jquery/jquery/pull/764 + return elem.document.documentElement[ "client" + name ]; + } + + // Get document width or height + if ( elem.nodeType === 9 ) { + doc = elem.documentElement; + + // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest + // unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it. + return Math.max( + elem.body[ "scroll" + name ], doc[ "scroll" + name ], + elem.body[ "offset" + name ], doc[ "offset" + name ], + doc[ "client" + name ] + ); + } + + return value === undefined ? + // Get width or height on the element, requesting but not forcing parseFloat + jQuery.css( elem, type, extra ) : + + // Set width or height on the element + jQuery.style( elem, type, value, extra ); + }, type, chainable ? margin : undefined, chainable, null ); + }; + }); +}); + + +// The number of elements contained in the matched element set +jQuery.fn.size = function() { + return this.length; +}; + +jQuery.fn.andSelf = jQuery.fn.addBack; + + + + +// Register as a named AMD module, since jQuery can be concatenated with other +// files that may use define, but not via a proper concatenation script that +// understands anonymous AMD modules. A named AMD is safest and most robust +// way to register. Lowercase jquery is used because AMD module names are +// derived from file names, and jQuery is normally delivered in a lowercase +// file name. Do this after creating the global so that if an AMD module wants +// to call noConflict to hide this version of jQuery, it will work. + +// Note that for maximum portability, libraries that are not jQuery should +// declare themselves as anonymous modules, and avoid setting a global if an +// AMD loader is present. jQuery is a special case. For more information, see +// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon + +if ( typeof define === "function" && define.amd ) { + define( "jquery", [], function() { + return jQuery; + }); +} + + + + +var + // Map over jQuery in case of overwrite + _jQuery = window.jQuery, + + // Map over the $ in case of overwrite + _$ = window.$; + +jQuery.noConflict = function( deep ) { + if ( window.$ === jQuery ) { + window.$ = _$; + } + + if ( deep && window.jQuery === jQuery ) { + window.jQuery = _jQuery; + } + + return jQuery; +}; + +// Expose jQuery and $ identifiers, even in +// AMD (#7102#comment:10, https://github.com/jquery/jquery/pull/557) +// and CommonJS for browser emulators (#13566) +if ( typeof noGlobal === strundefined ) { + window.jQuery = window.$ = jQuery; +} + + + + +return jQuery; + +})); diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/jquery/js/jquery-1.11.3.min.js b/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/jquery/js/jquery-1.11.3.min.js new file mode 100644 index 0000000000..0f60b7bd0d --- /dev/null +++ b/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/jquery/js/jquery-1.11.3.min.js @@ -0,0 +1,5 @@ +/*! jQuery v1.11.3 | (c) 2005, 2015 jQuery Foundation, Inc. | jquery.org/license */ +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l="1.11.3",m=function(a,b){return new m.fn.init(a,b)},n=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,o=/^-ms-/,p=/-([\da-z])/gi,q=function(a,b){return b.toUpperCase()};m.fn=m.prototype={jquery:l,constructor:m,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=m.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return m.each(this,a,b)},map:function(a){return this.pushStack(m.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},m.extend=m.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||m.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(e=arguments[h]))for(d in e)a=g[d],c=e[d],g!==c&&(j&&c&&(m.isPlainObject(c)||(b=m.isArray(c)))?(b?(b=!1,f=a&&m.isArray(a)?a:[]):f=a&&m.isPlainObject(a)?a:{},g[d]=m.extend(j,f,c)):void 0!==c&&(g[d]=c));return g},m.extend({expando:"jQuery"+(l+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===m.type(a)},isArray:Array.isArray||function(a){return"array"===m.type(a)},isWindow:function(a){return null!=a&&a==a.window},isNumeric:function(a){return!m.isArray(a)&&a-parseFloat(a)+1>=0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},isPlainObject:function(a){var b;if(!a||"object"!==m.type(a)||a.nodeType||m.isWindow(a))return!1;try{if(a.constructor&&!j.call(a,"constructor")&&!j.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(c){return!1}if(k.ownLast)for(b in a)return j.call(a,b);for(b in a);return void 0===b||j.call(a,b)},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(b){b&&m.trim(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(o,"ms-").replace(p,q)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=r(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(n,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(r(Object(a))?m.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){var d;if(b){if(g)return g.call(b,a,c);for(d=b.length,c=c?0>c?Math.max(0,d+c):c:0;d>c;c++)if(c in b&&b[c]===a)return c}return-1},merge:function(a,b){var c=+b.length,d=0,e=a.length;while(c>d)a[e++]=b[d++];if(c!==c)while(void 0!==b[d])a[e++]=b[d++];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=r(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(f=a[b],b=a,a=f),m.isFunction(a)?(c=d.call(arguments,2),e=function(){return a.apply(b||this,c.concat(d.call(arguments)))},e.guid=a.guid=a.guid||m.guid++,e):void 0},now:function(){return+new Date},support:k}),m.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function r(a){var b="length"in a&&a.length,c=m.type(a);return"function"===c||m.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var s=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ha(),z=ha(),A=ha(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N=M.replace("w","w#"),O="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+N+"))|)"+L+"*\\]",P=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+O+")*)|.*)\\)|)",Q=new RegExp(L+"+","g"),R=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),S=new RegExp("^"+L+"*,"+L+"*"),T=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),U=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),V=new RegExp(P),W=new RegExp("^"+N+"$"),X={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+O),PSEUDO:new RegExp("^"+P),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,aa=/[+~]/,ba=/'|\\/g,ca=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),da=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},ea=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(fa){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function ga(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],k=b.nodeType,"string"!=typeof a||!a||1!==k&&9!==k&&11!==k)return d;if(!e&&p){if(11!==k&&(f=_.exec(a)))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return H.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName)return H.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=1!==k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(ba,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+ra(o[l]);w=aa.test(a)&&pa(b.parentNode)||b,x=o.join(",")}if(x)try{return H.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function ha(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ia(a){return a[u]=!0,a}function ja(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ka(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function la(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function na(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function oa(a){return ia(function(b){return b=+b,ia(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function pa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=ga.support={},f=ga.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=ga.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=g.documentElement,e=g.defaultView,e&&e!==e.top&&(e.addEventListener?e.addEventListener("unload",ea,!1):e.attachEvent&&e.attachEvent("onunload",ea)),p=!f(g),c.attributes=ja(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ja(function(a){return a.appendChild(g.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(g.getElementsByClassName),c.getById=ja(function(a){return o.appendChild(a).id=u,!g.getElementsByName||!g.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ca,da);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(g.querySelectorAll))&&(ja(function(a){o.appendChild(a).innerHTML="<a id='"+u+"'></a><select id='"+u+"-\f]' msallowcapture=''><option selected=''></option></select>",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ja(function(a){var b=g.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ja(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",P)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===g||a.ownerDocument===v&&t(v,a)?-1:b===g||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,h=[a],i=[b];if(!e||!f)return a===g?-1:b===g?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return la(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?la(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},g):n},ga.matches=function(a,b){return ga(a,null,null,b)},ga.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return ga(b,n,null,[a]).length>0},ga.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},ga.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},ga.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},ga.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=ga.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=ga.selectors={cacheLength:50,createPseudo:ia,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ca,da),a[3]=(a[3]||a[4]||a[5]||"").replace(ca,da),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||ga.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&ga.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ca,da).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=ga.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(Q," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||ga.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ia(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ia(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?ia(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ia(function(a){return function(b){return ga(a,b).length>0}}),contains:ia(function(a){return a=a.replace(ca,da),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ia(function(a){return W.test(a||"")||ga.error("unsupported lang: "+a),a=a.replace(ca,da).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:oa(function(){return[0]}),last:oa(function(a,b){return[b-1]}),eq:oa(function(a,b,c){return[0>c?c+b:c]}),even:oa(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:oa(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:oa(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:oa(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=ma(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=na(b);function qa(){}qa.prototype=d.filters=d.pseudos,d.setFilters=new qa,g=ga.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){(!c||(e=S.exec(h)))&&(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=T.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(R," ")}),h=h.slice(c.length));for(g in d.filter)!(e=X[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?ga.error(a):z(a,i).slice(0)};function ra(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function sa(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function ta(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ua(a,b,c){for(var d=0,e=b.length;e>d;d++)ga(a,b[d],c);return c}function va(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function wa(a,b,c,d,e,f){return d&&!d[u]&&(d=wa(d)),e&&!e[u]&&(e=wa(e,f)),ia(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ua(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:va(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=va(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=va(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function xa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=sa(function(a){return a===b},h,!0),l=sa(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[sa(ta(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return wa(i>1&&ta(m),i>1&&ra(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&xa(a.slice(i,e)),f>e&&xa(a=a.slice(e)),f>e&&ra(a))}m.push(c)}return ta(m)}function ya(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=F.call(i));s=va(s)}H.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&ga.uniqueSort(i)}return k&&(w=v,j=t),r};return c?ia(f):f}return h=ga.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=xa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,ya(e,d)),f.selector=a}return f},i=ga.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ca,da),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ca,da),aa.test(j[0].type)&&pa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&ra(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,aa.test(a)&&pa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ja(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ja(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||ka("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ja(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ka("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ja(function(a){return null==a.getAttribute("disabled")})||ka(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),ga}(a);m.find=s,m.expr=s.selectors,m.expr[":"]=m.expr.pseudos,m.unique=s.uniqueSort,m.text=s.getText,m.isXMLDoc=s.isXML,m.contains=s.contains;var t=m.expr.match.needsContext,u=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,v=/^.[^:#\[\.,]*$/;function w(a,b,c){if(m.isFunction(b))return m.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return m.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(v.test(b))return m.filter(b,a,c);b=m.filter(b,a)}return m.grep(a,function(a){return m.inArray(a,b)>=0!==c})}m.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?m.find.matchesSelector(d,a)?[d]:[]:m.find.matches(a,m.grep(b,function(a){return 1===a.nodeType}))},m.fn.extend({find:function(a){var b,c=[],d=this,e=d.length;if("string"!=typeof a)return this.pushStack(m(a).filter(function(){for(b=0;e>b;b++)if(m.contains(d[b],this))return!0}));for(b=0;e>b;b++)m.find(a,d[b],c);return c=this.pushStack(e>1?m.unique(c):c),c.selector=this.selector?this.selector+" "+a:a,c},filter:function(a){return this.pushStack(w(this,a||[],!1))},not:function(a){return this.pushStack(w(this,a||[],!0))},is:function(a){return!!w(this,"string"==typeof a&&t.test(a)?m(a):a||[],!1).length}});var x,y=a.document,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=m.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a.charAt(0)&&">"===a.charAt(a.length-1)&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||x).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof m?b[0]:b,m.merge(this,m.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:y,!0)),u.test(c[1])&&m.isPlainObject(b))for(c in b)m.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}if(d=y.getElementById(c[2]),d&&d.parentNode){if(d.id!==c[2])return x.find(a);this.length=1,this[0]=d}return this.context=y,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):m.isFunction(a)?"undefined"!=typeof x.ready?x.ready(a):a(m):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),m.makeArray(a,this))};A.prototype=m.fn,x=m(y);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};m.extend({dir:function(a,b,c){var d=[],e=a[b];while(e&&9!==e.nodeType&&(void 0===c||1!==e.nodeType||!m(e).is(c)))1===e.nodeType&&d.push(e),e=e[b];return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),m.fn.extend({has:function(a){var b,c=m(a,this),d=c.length;return this.filter(function(){for(b=0;d>b;b++)if(m.contains(this,c[b]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=t.test(a)||"string"!=typeof a?m(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&m.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?m.unique(f):f)},index:function(a){return a?"string"==typeof a?m.inArray(this[0],m(a)):m.inArray(a.jquery?a[0]:a,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(m.unique(m.merge(this.get(),m(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){do a=a[b];while(a&&1!==a.nodeType);return a}m.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return m.dir(a,"parentNode")},parentsUntil:function(a,b,c){return m.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return m.dir(a,"nextSibling")},prevAll:function(a){return m.dir(a,"previousSibling")},nextUntil:function(a,b,c){return m.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return m.dir(a,"previousSibling",c)},siblings:function(a){return m.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return m.sibling(a.firstChild)},contents:function(a){return m.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:m.merge([],a.childNodes)}},function(a,b){m.fn[a]=function(c,d){var e=m.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=m.filter(d,e)),this.length>1&&(C[a]||(e=m.unique(e)),B.test(a)&&(e=e.reverse())),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return m.each(a.match(E)||[],function(a,c){b[c]=!0}),b}m.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):m.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(c=a.memory&&l,d=!0,f=g||0,g=0,e=h.length,b=!0;h&&e>f;f++)if(h[f].apply(l[0],l[1])===!1&&a.stopOnFalse){c=!1;break}b=!1,h&&(i?i.length&&j(i.shift()):c?h=[]:k.disable())},k={add:function(){if(h){var d=h.length;!function f(b){m.each(b,function(b,c){var d=m.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&f(c)})}(arguments),b?e=h.length:c&&(g=d,j(c))}return this},remove:function(){return h&&m.each(arguments,function(a,c){var d;while((d=m.inArray(c,h,d))>-1)h.splice(d,1),b&&(e>=d&&e--,f>=d&&f--)}),this},has:function(a){return a?m.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],e=0,this},disable:function(){return h=i=c=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,c||k.disable(),this},locked:function(){return!i},fireWith:function(a,c){return!h||d&&!i||(c=c||[],c=[a,c.slice?c.slice():c],b?i.push(c):j(c)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!d}};return k},m.extend({Deferred:function(a){var b=[["resolve","done",m.Callbacks("once memory"),"resolved"],["reject","fail",m.Callbacks("once memory"),"rejected"],["notify","progress",m.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return m.Deferred(function(c){m.each(b,function(b,f){var g=m.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&m.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?m.extend(a,d):d}},e={};return d.pipe=d.then,m.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&m.isFunction(a.promise)?e:0,g=1===f?a:m.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&m.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;m.fn.ready=function(a){return m.ready.promise().done(a),this},m.extend({isReady:!1,readyWait:1,holdReady:function(a){a?m.readyWait++:m.ready(!0)},ready:function(a){if(a===!0?!--m.readyWait:!m.isReady){if(!y.body)return setTimeout(m.ready);m.isReady=!0,a!==!0&&--m.readyWait>0||(H.resolveWith(y,[m]),m.fn.triggerHandler&&(m(y).triggerHandler("ready"),m(y).off("ready")))}}});function I(){y.addEventListener?(y.removeEventListener("DOMContentLoaded",J,!1),a.removeEventListener("load",J,!1)):(y.detachEvent("onreadystatechange",J),a.detachEvent("onload",J))}function J(){(y.addEventListener||"load"===event.type||"complete"===y.readyState)&&(I(),m.ready())}m.ready.promise=function(b){if(!H)if(H=m.Deferred(),"complete"===y.readyState)setTimeout(m.ready);else if(y.addEventListener)y.addEventListener("DOMContentLoaded",J,!1),a.addEventListener("load",J,!1);else{y.attachEvent("onreadystatechange",J),a.attachEvent("onload",J);var c=!1;try{c=null==a.frameElement&&y.documentElement}catch(d){}c&&c.doScroll&&!function e(){if(!m.isReady){try{c.doScroll("left")}catch(a){return setTimeout(e,50)}I(),m.ready()}}()}return H.promise(b)};var K="undefined",L;for(L in m(k))break;k.ownLast="0"!==L,k.inlineBlockNeedsLayout=!1,m(function(){var a,b,c,d;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1",k.inlineBlockNeedsLayout=a=3===b.offsetWidth,a&&(c.style.zoom=1)),c.removeChild(d))}),function(){var a=y.createElement("div");if(null==k.deleteExpando){k.deleteExpando=!0;try{delete a.test}catch(b){k.deleteExpando=!1}}a=null}(),m.acceptData=function(a){var b=m.noData[(a.nodeName+" ").toLowerCase()],c=+a.nodeType||1;return 1!==c&&9!==c?!1:!b||b!==!0&&a.getAttribute("classid")===b};var M=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,N=/([A-Z])/g;function O(a,b,c){if(void 0===c&&1===a.nodeType){var d="data-"+b.replace(N,"-$1").toLowerCase();if(c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:M.test(c)?m.parseJSON(c):c}catch(e){}m.data(a,b,c)}else c=void 0}return c}function P(a){var b;for(b in a)if(("data"!==b||!m.isEmptyObject(a[b]))&&"toJSON"!==b)return!1; + +return!0}function Q(a,b,d,e){if(m.acceptData(a)){var f,g,h=m.expando,i=a.nodeType,j=i?m.cache:a,k=i?a[h]:a[h]&&h;if(k&&j[k]&&(e||j[k].data)||void 0!==d||"string"!=typeof b)return k||(k=i?a[h]=c.pop()||m.guid++:h),j[k]||(j[k]=i?{}:{toJSON:m.noop}),("object"==typeof b||"function"==typeof b)&&(e?j[k]=m.extend(j[k],b):j[k].data=m.extend(j[k].data,b)),g=j[k],e||(g.data||(g.data={}),g=g.data),void 0!==d&&(g[m.camelCase(b)]=d),"string"==typeof b?(f=g[b],null==f&&(f=g[m.camelCase(b)])):f=g,f}}function R(a,b,c){if(m.acceptData(a)){var d,e,f=a.nodeType,g=f?m.cache:a,h=f?a[m.expando]:m.expando;if(g[h]){if(b&&(d=c?g[h]:g[h].data)){m.isArray(b)?b=b.concat(m.map(b,m.camelCase)):b in d?b=[b]:(b=m.camelCase(b),b=b in d?[b]:b.split(" ")),e=b.length;while(e--)delete d[b[e]];if(c?!P(d):!m.isEmptyObject(d))return}(c||(delete g[h].data,P(g[h])))&&(f?m.cleanData([a],!0):k.deleteExpando||g!=g.window?delete g[h]:g[h]=null)}}}m.extend({cache:{},noData:{"applet ":!0,"embed ":!0,"object ":"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"},hasData:function(a){return a=a.nodeType?m.cache[a[m.expando]]:a[m.expando],!!a&&!P(a)},data:function(a,b,c){return Q(a,b,c)},removeData:function(a,b){return R(a,b)},_data:function(a,b,c){return Q(a,b,c,!0)},_removeData:function(a,b){return R(a,b,!0)}}),m.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=m.data(f),1===f.nodeType&&!m._data(f,"parsedAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=m.camelCase(d.slice(5)),O(f,d,e[d])));m._data(f,"parsedAttrs",!0)}return e}return"object"==typeof a?this.each(function(){m.data(this,a)}):arguments.length>1?this.each(function(){m.data(this,a,b)}):f?O(f,a,m.data(f,a)):void 0},removeData:function(a){return this.each(function(){m.removeData(this,a)})}}),m.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=m._data(a,b),c&&(!d||m.isArray(c)?d=m._data(a,b,m.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=m.queue(a,b),d=c.length,e=c.shift(),f=m._queueHooks(a,b),g=function(){m.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return m._data(a,c)||m._data(a,c,{empty:m.Callbacks("once memory").add(function(){m._removeData(a,b+"queue"),m._removeData(a,c)})})}}),m.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?m.queue(this[0],a):void 0===b?this:this.each(function(){var c=m.queue(this,a,b);m._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&m.dequeue(this,a)})},dequeue:function(a){return this.each(function(){m.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=m.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=m._data(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var S=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,T=["Top","Right","Bottom","Left"],U=function(a,b){return a=b||a,"none"===m.css(a,"display")||!m.contains(a.ownerDocument,a)},V=m.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===m.type(c)){e=!0;for(h in c)m.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,m.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(m(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},W=/^(?:checkbox|radio)$/i;!function(){var a=y.createElement("input"),b=y.createElement("div"),c=y.createDocumentFragment();if(b.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",k.leadingWhitespace=3===b.firstChild.nodeType,k.tbody=!b.getElementsByTagName("tbody").length,k.htmlSerialize=!!b.getElementsByTagName("link").length,k.html5Clone="<:nav></:nav>"!==y.createElement("nav").cloneNode(!0).outerHTML,a.type="checkbox",a.checked=!0,c.appendChild(a),k.appendChecked=a.checked,b.innerHTML="<textarea>x</textarea>",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue,c.appendChild(b),b.innerHTML="<input type='radio' checked='checked' name='t'/>",k.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,k.noCloneEvent=!0,b.attachEvent&&(b.attachEvent("onclick",function(){k.noCloneEvent=!1}),b.cloneNode(!0).click()),null==k.deleteExpando){k.deleteExpando=!0;try{delete b.test}catch(d){k.deleteExpando=!1}}}(),function(){var b,c,d=y.createElement("div");for(b in{submit:!0,change:!0,focusin:!0})c="on"+b,(k[b+"Bubbles"]=c in a)||(d.setAttribute(c,"t"),k[b+"Bubbles"]=d.attributes[c].expando===!1);d=null}();var X=/^(?:input|select|textarea)$/i,Y=/^key/,Z=/^(?:mouse|pointer|contextmenu)|click/,$=/^(?:focusinfocus|focusoutblur)$/,_=/^([^.]*)(?:\.(.+)|)$/;function aa(){return!0}function ba(){return!1}function ca(){try{return y.activeElement}catch(a){}}m.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m._data(a);if(r){c.handler&&(i=c,c=i.handler,e=i.selector),c.guid||(c.guid=m.guid++),(g=r.events)||(g=r.events={}),(k=r.handle)||(k=r.handle=function(a){return typeof m===K||a&&m.event.triggered===a.type?void 0:m.event.dispatch.apply(k.elem,arguments)},k.elem=a),b=(b||"").match(E)||[""],h=b.length;while(h--)f=_.exec(b[h])||[],o=q=f[1],p=(f[2]||"").split(".").sort(),o&&(j=m.event.special[o]||{},o=(e?j.delegateType:j.bindType)||o,j=m.event.special[o]||{},l=m.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&m.expr.match.needsContext.test(e),namespace:p.join(".")},i),(n=g[o])||(n=g[o]=[],n.delegateCount=0,j.setup&&j.setup.call(a,d,p,k)!==!1||(a.addEventListener?a.addEventListener(o,k,!1):a.attachEvent&&a.attachEvent("on"+o,k))),j.add&&(j.add.call(a,l),l.handler.guid||(l.handler.guid=c.guid)),e?n.splice(n.delegateCount++,0,l):n.push(l),m.event.global[o]=!0);a=null}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,n,o,p,q,r=m.hasData(a)&&m._data(a);if(r&&(k=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=_.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=m.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,n=k[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),i=f=n.length;while(f--)g=n[f],!e&&q!==g.origType||c&&c.guid!==g.guid||h&&!h.test(g.namespace)||d&&d!==g.selector&&("**"!==d||!g.selector)||(n.splice(f,1),g.selector&&n.delegateCount--,l.remove&&l.remove.call(a,g));i&&!n.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||m.removeEvent(a,o,r.handle),delete k[o])}else for(o in k)m.event.remove(a,o+b[j],c,d,!0);m.isEmptyObject(k)&&(delete r.handle,m._removeData(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,l,n,o=[d||y],p=j.call(b,"type")?b.type:b,q=j.call(b,"namespace")?b.namespace.split("."):[];if(h=l=d=d||y,3!==d.nodeType&&8!==d.nodeType&&!$.test(p+m.event.triggered)&&(p.indexOf(".")>=0&&(q=p.split("."),p=q.shift(),q.sort()),g=p.indexOf(":")<0&&"on"+p,b=b[m.expando]?b:new m.Event(p,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=q.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+q.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:m.makeArray(c,[b]),k=m.event.special[p]||{},e||!k.trigger||k.trigger.apply(d,c)!==!1)){if(!e&&!k.noBubble&&!m.isWindow(d)){for(i=k.delegateType||p,$.test(i+p)||(h=h.parentNode);h;h=h.parentNode)o.push(h),l=h;l===(d.ownerDocument||y)&&o.push(l.defaultView||l.parentWindow||a)}n=0;while((h=o[n++])&&!b.isPropagationStopped())b.type=n>1?i:k.bindType||p,f=(m._data(h,"events")||{})[b.type]&&m._data(h,"handle"),f&&f.apply(h,c),f=g&&h[g],f&&f.apply&&m.acceptData(h)&&(b.result=f.apply(h,c),b.result===!1&&b.preventDefault());if(b.type=p,!e&&!b.isDefaultPrevented()&&(!k._default||k._default.apply(o.pop(),c)===!1)&&m.acceptData(d)&&g&&d[p]&&!m.isWindow(d)){l=d[g],l&&(d[g]=null),m.event.triggered=p;try{d[p]()}catch(r){}m.event.triggered=void 0,l&&(d[g]=l)}return b.result}},dispatch:function(a){a=m.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(m._data(this,"events")||{})[a.type]||[],k=m.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=m.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,g=0;while((e=f.handlers[g++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(e.namespace))&&(a.handleObj=e,a.data=e.data,c=((m.event.special[e.origType]||{}).handle||e.handler).apply(f.elem,i),void 0!==c&&(a.result=c)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!=this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(e=[],f=0;h>f;f++)d=b[f],c=d.selector+" ",void 0===e[c]&&(e[c]=d.needsContext?m(c,this).index(i)>=0:m.find(c,this,null,[i]).length),e[c]&&e.push(d);e.length&&g.push({elem:i,handlers:e})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},fix:function(a){if(a[m.expando])return a;var b,c,d,e=a.type,f=a,g=this.fixHooks[e];g||(this.fixHooks[e]=g=Z.test(e)?this.mouseHooks:Y.test(e)?this.keyHooks:{}),d=g.props?this.props.concat(g.props):this.props,a=new m.Event(f),b=d.length;while(b--)c=d[b],a[c]=f[c];return a.target||(a.target=f.srcElement||y),3===a.target.nodeType&&(a.target=a.target.parentNode),a.metaKey=!!a.metaKey,g.filter?g.filter(a,f):a},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,d,e,f=b.button,g=b.fromElement;return null==a.pageX&&null!=b.clientX&&(d=a.target.ownerDocument||y,e=d.documentElement,c=d.body,a.pageX=b.clientX+(e&&e.scrollLeft||c&&c.scrollLeft||0)-(e&&e.clientLeft||c&&c.clientLeft||0),a.pageY=b.clientY+(e&&e.scrollTop||c&&c.scrollTop||0)-(e&&e.clientTop||c&&c.clientTop||0)),!a.relatedTarget&&g&&(a.relatedTarget=g===a.target?b.toElement:g),a.which||void 0===f||(a.which=1&f?1:2&f?3:4&f?2:0),a}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==ca()&&this.focus)try{return this.focus(),!1}catch(a){}},delegateType:"focusin"},blur:{trigger:function(){return this===ca()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return m.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):void 0},_default:function(a){return m.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}},simulate:function(a,b,c,d){var e=m.extend(new m.Event,c,{type:a,isSimulated:!0,originalEvent:{}});d?m.event.trigger(e,null,b):m.event.dispatch.call(b,e),e.isDefaultPrevented()&&c.preventDefault()}},m.removeEvent=y.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){var d="on"+b;a.detachEvent&&(typeof a[d]===K&&(a[d]=null),a.detachEvent(d,c))},m.Event=function(a,b){return this instanceof m.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?aa:ba):this.type=a,b&&m.extend(this,b),this.timeStamp=a&&a.timeStamp||m.now(),void(this[m.expando]=!0)):new m.Event(a,b)},m.Event.prototype={isDefaultPrevented:ba,isPropagationStopped:ba,isImmediatePropagationStopped:ba,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=aa,a&&(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=aa,a&&(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=aa,a&&a.stopImmediatePropagation&&a.stopImmediatePropagation(),this.stopPropagation()}},m.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){m.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return(!e||e!==d&&!m.contains(d,e))&&(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),k.submitBubbles||(m.event.special.submit={setup:function(){return m.nodeName(this,"form")?!1:void m.event.add(this,"click._submit keypress._submit",function(a){var b=a.target,c=m.nodeName(b,"input")||m.nodeName(b,"button")?b.form:void 0;c&&!m._data(c,"submitBubbles")&&(m.event.add(c,"submit._submit",function(a){a._submit_bubble=!0}),m._data(c,"submitBubbles",!0))})},postDispatch:function(a){a._submit_bubble&&(delete a._submit_bubble,this.parentNode&&!a.isTrigger&&m.event.simulate("submit",this.parentNode,a,!0))},teardown:function(){return m.nodeName(this,"form")?!1:void m.event.remove(this,"._submit")}}),k.changeBubbles||(m.event.special.change={setup:function(){return X.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(m.event.add(this,"propertychange._change",function(a){"checked"===a.originalEvent.propertyName&&(this._just_changed=!0)}),m.event.add(this,"click._change",function(a){this._just_changed&&!a.isTrigger&&(this._just_changed=!1),m.event.simulate("change",this,a,!0)})),!1):void m.event.add(this,"beforeactivate._change",function(a){var b=a.target;X.test(b.nodeName)&&!m._data(b,"changeBubbles")&&(m.event.add(b,"change._change",function(a){!this.parentNode||a.isSimulated||a.isTrigger||m.event.simulate("change",this.parentNode,a,!0)}),m._data(b,"changeBubbles",!0))})},handle:function(a){var b=a.target;return this!==b||a.isSimulated||a.isTrigger||"radio"!==b.type&&"checkbox"!==b.type?a.handleObj.handler.apply(this,arguments):void 0},teardown:function(){return m.event.remove(this,"._change"),!X.test(this.nodeName)}}),k.focusinBubbles||m.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){m.event.simulate(b,a.target,m.event.fix(a),!0)};m.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=m._data(d,b);e||d.addEventListener(a,c,!0),m._data(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=m._data(d,b)-1;e?m._data(d,b,e):(d.removeEventListener(a,c,!0),m._removeData(d,b))}}}),m.fn.extend({on:function(a,b,c,d,e){var f,g;if("object"==typeof a){"string"!=typeof b&&(c=c||b,b=void 0);for(f in a)this.on(f,b,c,a[f],e);return this}if(null==c&&null==d?(d=b,c=b=void 0):null==d&&("string"==typeof b?(d=c,c=void 0):(d=c,c=b,b=void 0)),d===!1)d=ba;else if(!d)return this;return 1===e&&(g=d,d=function(a){return m().off(a),g.apply(this,arguments)},d.guid=g.guid||(g.guid=m.guid++)),this.each(function(){m.event.add(this,a,d,c,b)})},one:function(a,b,c,d){return this.on(a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,m(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return(b===!1||"function"==typeof b)&&(c=b,b=void 0),c===!1&&(c=ba),this.each(function(){m.event.remove(this,a,c,b)})},trigger:function(a,b){return this.each(function(){m.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?m.event.trigger(a,b,c,!0):void 0}});function da(a){var b=ea.split("|"),c=a.createDocumentFragment();if(c.createElement)while(b.length)c.createElement(b.pop());return c}var ea="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",fa=/ jQuery\d+="(?:null|\d+)"/g,ga=new RegExp("<(?:"+ea+")[\\s/>]","i"),ha=/^\s+/,ia=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,ja=/<([\w:]+)/,ka=/<tbody/i,la=/<|&#?\w+;/,ma=/<(?:script|style|link)/i,na=/checked\s*(?:[^=]|=\s*.checked.)/i,oa=/^$|\/(?:java|ecma)script/i,pa=/^true\/(.*)/,qa=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,ra={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:k.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]},sa=da(y),ta=sa.appendChild(y.createElement("div"));ra.optgroup=ra.option,ra.tbody=ra.tfoot=ra.colgroup=ra.caption=ra.thead,ra.th=ra.td;function ua(a,b){var c,d,e=0,f=typeof a.getElementsByTagName!==K?a.getElementsByTagName(b||"*"):typeof a.querySelectorAll!==K?a.querySelectorAll(b||"*"):void 0;if(!f)for(f=[],c=a.childNodes||a;null!=(d=c[e]);e++)!b||m.nodeName(d,b)?f.push(d):m.merge(f,ua(d,b));return void 0===b||b&&m.nodeName(a,b)?m.merge([a],f):f}function va(a){W.test(a.type)&&(a.defaultChecked=a.checked)}function wa(a,b){return m.nodeName(a,"table")&&m.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function xa(a){return a.type=(null!==m.find.attr(a,"type"))+"/"+a.type,a}function ya(a){var b=pa.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function za(a,b){for(var c,d=0;null!=(c=a[d]);d++)m._data(c,"globalEval",!b||m._data(b[d],"globalEval"))}function Aa(a,b){if(1===b.nodeType&&m.hasData(a)){var c,d,e,f=m._data(a),g=m._data(b,f),h=f.events;if(h){delete g.handle,g.events={};for(c in h)for(d=0,e=h[c].length;e>d;d++)m.event.add(b,c,h[c][d])}g.data&&(g.data=m.extend({},g.data))}}function Ba(a,b){var c,d,e;if(1===b.nodeType){if(c=b.nodeName.toLowerCase(),!k.noCloneEvent&&b[m.expando]){e=m._data(b);for(d in e.events)m.removeEvent(b,d,e.handle);b.removeAttribute(m.expando)}"script"===c&&b.text!==a.text?(xa(b).text=a.text,ya(b)):"object"===c?(b.parentNode&&(b.outerHTML=a.outerHTML),k.html5Clone&&a.innerHTML&&!m.trim(b.innerHTML)&&(b.innerHTML=a.innerHTML)):"input"===c&&W.test(a.type)?(b.defaultChecked=b.checked=a.checked,b.value!==a.value&&(b.value=a.value)):"option"===c?b.defaultSelected=b.selected=a.defaultSelected:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}}m.extend({clone:function(a,b,c){var d,e,f,g,h,i=m.contains(a.ownerDocument,a);if(k.html5Clone||m.isXMLDoc(a)||!ga.test("<"+a.nodeName+">")?f=a.cloneNode(!0):(ta.innerHTML=a.outerHTML,ta.removeChild(f=ta.firstChild)),!(k.noCloneEvent&&k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||m.isXMLDoc(a)))for(d=ua(f),h=ua(a),g=0;null!=(e=h[g]);++g)d[g]&&Ba(e,d[g]);if(b)if(c)for(h=h||ua(a),d=d||ua(f),g=0;null!=(e=h[g]);g++)Aa(e,d[g]);else Aa(a,f);return d=ua(f,"script"),d.length>0&&za(d,!i&&ua(a,"script")),d=h=e=null,f},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,l,n=a.length,o=da(b),p=[],q=0;n>q;q++)if(f=a[q],f||0===f)if("object"===m.type(f))m.merge(p,f.nodeType?[f]:f);else if(la.test(f)){h=h||o.appendChild(b.createElement("div")),i=(ja.exec(f)||["",""])[1].toLowerCase(),l=ra[i]||ra._default,h.innerHTML=l[1]+f.replace(ia,"<$1></$2>")+l[2],e=l[0];while(e--)h=h.lastChild;if(!k.leadingWhitespace&&ha.test(f)&&p.push(b.createTextNode(ha.exec(f)[0])),!k.tbody){f="table"!==i||ka.test(f)?"<table>"!==l[1]||ka.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)m.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}m.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),k.appendChecked||m.grep(ua(p,"input"),va),q=0;while(f=p[q++])if((!d||-1===m.inArray(f,d))&&(g=m.contains(f.ownerDocument,f),h=ua(o.appendChild(f),"script"),g&&za(h),c)){e=0;while(f=h[e++])oa.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=m.expando,j=m.cache,l=k.deleteExpando,n=m.event.special;null!=(d=a[h]);h++)if((b||m.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)n[e]?m.event.remove(d,e):m.removeEvent(d,e,g.handle);j[f]&&(delete j[f],l?delete d[i]:typeof d.removeAttribute!==K?d.removeAttribute(i):d[i]=null,c.push(f))}}}),m.fn.extend({text:function(a){return V(this,function(a){return void 0===a?m.text(this):this.empty().append((this[0]&&this[0].ownerDocument||y).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wa(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wa(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?m.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||m.cleanData(ua(c)),c.parentNode&&(b&&m.contains(c.ownerDocument,c)&&za(ua(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&m.cleanData(ua(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&m.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return m.clone(this,a,b)})},html:function(a){return V(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(fa,""):void 0;if(!("string"!=typeof a||ma.test(a)||!k.htmlSerialize&&ga.test(a)||!k.leadingWhitespace&&ha.test(a)||ra[(ja.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(ia,"<$1></$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(m.cleanData(ua(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,m.cleanData(ua(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,n=this,o=l-1,p=a[0],q=m.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&na.test(p))return this.each(function(c){var d=n.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(i=m.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=m.map(ua(i,"script"),xa),f=g.length;l>j;j++)d=i,j!==o&&(d=m.clone(d,!0,!0),f&&m.merge(g,ua(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,m.map(g,ya),j=0;f>j;j++)d=g[j],oa.test(d.type||"")&&!m._data(d,"globalEval")&&m.contains(h,d)&&(d.src?m._evalUrl&&m._evalUrl(d.src):m.globalEval((d.text||d.textContent||d.innerHTML||"").replace(qa,"")));i=c=null}return this}}),m.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){m.fn[a]=function(a){for(var c,d=0,e=[],g=m(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),m(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Ca,Da={};function Ea(b,c){var d,e=m(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:m.css(e[0],"display");return e.detach(),f}function Fa(a){var b=y,c=Da[a];return c||(c=Ea(a,b),"none"!==c&&c||(Ca=(Ca||m("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=(Ca[0].contentWindow||Ca[0].contentDocument).document,b.write(),b.close(),c=Ea(a,b),Ca.detach()),Da[a]=c),c}!function(){var a;k.shrinkWrapBlocks=function(){if(null!=a)return a;a=!1;var b,c,d;return c=y.getElementsByTagName("body")[0],c&&c.style?(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1",b.appendChild(y.createElement("div")).style.width="5px",a=3!==b.offsetWidth),c.removeChild(d),a):void 0}}();var Ga=/^margin/,Ha=new RegExp("^("+S+")(?!px)[a-z%]+$","i"),Ia,Ja,Ka=/^(top|right|bottom|left)$/;a.getComputedStyle?(Ia=function(b){return b.ownerDocument.defaultView.opener?b.ownerDocument.defaultView.getComputedStyle(b,null):a.getComputedStyle(b,null)},Ja=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ia(a),g=c?c.getPropertyValue(b)||c[b]:void 0,c&&(""!==g||m.contains(a.ownerDocument,a)||(g=m.style(a,b)),Ha.test(g)&&Ga.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0===g?g:g+""}):y.documentElement.currentStyle&&(Ia=function(a){return a.currentStyle},Ja=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ia(a),g=c?c[b]:void 0,null==g&&h&&h[b]&&(g=h[b]),Ha.test(g)&&!Ka.test(b)&&(d=h.left,e=a.runtimeStyle,f=e&&e.left,f&&(e.left=a.currentStyle.left),h.left="fontSize"===b?"1em":g,g=h.pixelLeft+"px",h.left=d,f&&(e.left=f)),void 0===g?g:g+""||"auto"});function La(a,b){return{get:function(){var c=a();if(null!=c)return c?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d,e,f,g,h;if(b=y.createElement("div"),b.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",d=b.getElementsByTagName("a")[0],c=d&&d.style){c.cssText="float:left;opacity:.5",k.opacity="0.5"===c.opacity,k.cssFloat=!!c.cssFloat,b.style.backgroundClip="content-box",b.cloneNode(!0).style.backgroundClip="",k.clearCloneStyle="content-box"===b.style.backgroundClip,k.boxSizing=""===c.boxSizing||""===c.MozBoxSizing||""===c.WebkitBoxSizing,m.extend(k,{reliableHiddenOffsets:function(){return null==g&&i(),g},boxSizingReliable:function(){return null==f&&i(),f},pixelPosition:function(){return null==e&&i(),e},reliableMarginRight:function(){return null==h&&i(),h}});function i(){var b,c,d,i;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),b.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;margin-top:1%;top:1%;border:1px;padding:1px;width:4px;position:absolute",e=f=!1,h=!0,a.getComputedStyle&&(e="1%"!==(a.getComputedStyle(b,null)||{}).top,f="4px"===(a.getComputedStyle(b,null)||{width:"4px"}).width,i=b.appendChild(y.createElement("div")),i.style.cssText=b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",i.style.marginRight=i.style.width="0",b.style.width="1px",h=!parseFloat((a.getComputedStyle(i,null)||{}).marginRight),b.removeChild(i)),b.innerHTML="<table><tr><td></td><td>t</td></tr></table>",i=b.getElementsByTagName("td"),i[0].style.cssText="margin:0;border:0;padding:0;display:none",g=0===i[0].offsetHeight,g&&(i[0].style.display="",i[1].style.display="none",g=0===i[0].offsetHeight),c.removeChild(d))}}}(),m.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var Ma=/alpha\([^)]*\)/i,Na=/opacity\s*=\s*([^)]*)/,Oa=/^(none|table(?!-c[ea]).+)/,Pa=new RegExp("^("+S+")(.*)$","i"),Qa=new RegExp("^([+-])=("+S+")","i"),Ra={position:"absolute",visibility:"hidden",display:"block"},Sa={letterSpacing:"0",fontWeight:"400"},Ta=["Webkit","O","Moz","ms"];function Ua(a,b){if(b in a)return b;var c=b.charAt(0).toUpperCase()+b.slice(1),d=b,e=Ta.length;while(e--)if(b=Ta[e]+c,b in a)return b;return d}function Va(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=m._data(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&U(d)&&(f[g]=m._data(d,"olddisplay",Fa(d.nodeName)))):(e=U(d),(c&&"none"!==c||!e)&&m._data(d,"olddisplay",e?c:m.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}function Wa(a,b,c){var d=Pa.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Xa(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=m.css(a,c+T[f],!0,e)),d?("content"===c&&(g-=m.css(a,"padding"+T[f],!0,e)),"margin"!==c&&(g-=m.css(a,"border"+T[f]+"Width",!0,e))):(g+=m.css(a,"padding"+T[f],!0,e),"padding"!==c&&(g+=m.css(a,"border"+T[f]+"Width",!0,e)));return g}function Ya(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=Ia(a),g=k.boxSizing&&"border-box"===m.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=Ja(a,b,f),(0>e||null==e)&&(e=a.style[b]),Ha.test(e))return e;d=g&&(k.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Xa(a,b,c||(g?"border":"content"),d,f)+"px"}m.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Ja(a,"opacity");return""===c?"1":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":k.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=m.camelCase(b),i=a.style;if(b=m.cssProps[h]||(m.cssProps[h]=Ua(i,h)),g=m.cssHooks[b]||m.cssHooks[h],void 0===c)return g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b];if(f=typeof c,"string"===f&&(e=Qa.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(m.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||m.cssNumber[h]||(c+="px"),k.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),!(g&&"set"in g&&void 0===(c=g.set(a,c,d)))))try{i[b]=c}catch(j){}}},css:function(a,b,c,d){var e,f,g,h=m.camelCase(b);return b=m.cssProps[h]||(m.cssProps[h]=Ua(a.style,h)),g=m.cssHooks[b]||m.cssHooks[h],g&&"get"in g&&(f=g.get(a,!0,c)),void 0===f&&(f=Ja(a,b,d)),"normal"===f&&b in Sa&&(f=Sa[b]),""===c||c?(e=parseFloat(f),c===!0||m.isNumeric(e)?e||0:f):f}}),m.each(["height","width"],function(a,b){m.cssHooks[b]={get:function(a,c,d){return c?Oa.test(m.css(a,"display"))&&0===a.offsetWidth?m.swap(a,Ra,function(){return Ya(a,b,d)}):Ya(a,b,d):void 0},set:function(a,c,d){var e=d&&Ia(a);return Wa(a,c,d?Xa(a,b,d,k.boxSizing&&"border-box"===m.css(a,"boxSizing",!1,e),e):0)}}}),k.opacity||(m.cssHooks.opacity={get:function(a,b){return Na.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=m.isNumeric(b)?"alpha(opacity="+100*b+")":"",f=d&&d.filter||c.filter||"";c.zoom=1,(b>=1||""===b)&&""===m.trim(f.replace(Ma,""))&&c.removeAttribute&&(c.removeAttribute("filter"),""===b||d&&!d.filter)||(c.filter=Ma.test(f)?f.replace(Ma,e):f+" "+e)}}),m.cssHooks.marginRight=La(k.reliableMarginRight,function(a,b){return b?m.swap(a,{display:"inline-block"},Ja,[a,"marginRight"]):void 0}),m.each({margin:"",padding:"",border:"Width"},function(a,b){m.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+T[d]+b]=f[d]||f[d-2]||f[0];return e}},Ga.test(a)||(m.cssHooks[a+b].set=Wa)}),m.fn.extend({css:function(a,b){return V(this,function(a,b,c){var d,e,f={},g=0;if(m.isArray(b)){for(d=Ia(a),e=b.length;e>g;g++)f[b[g]]=m.css(a,b[g],!1,d);return f}return void 0!==c?m.style(a,b,c):m.css(a,b)},a,b,arguments.length>1)},show:function(){return Va(this,!0)},hide:function(){return Va(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){U(this)?m(this).show():m(this).hide()})}});function Za(a,b,c,d,e){ +return new Za.prototype.init(a,b,c,d,e)}m.Tween=Za,Za.prototype={constructor:Za,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(m.cssNumber[c]?"":"px")},cur:function(){var a=Za.propHooks[this.prop];return a&&a.get?a.get(this):Za.propHooks._default.get(this)},run:function(a){var b,c=Za.propHooks[this.prop];return this.options.duration?this.pos=b=m.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Za.propHooks._default.set(this),this}},Za.prototype.init.prototype=Za.prototype,Za.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=m.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){m.fx.step[a.prop]?m.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[m.cssProps[a.prop]]||m.cssHooks[a.prop])?m.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Za.propHooks.scrollTop=Za.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},m.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},m.fx=Za.prototype.init,m.fx.step={};var $a,_a,ab=/^(?:toggle|show|hide)$/,bb=new RegExp("^(?:([+-])=|)("+S+")([a-z%]*)$","i"),cb=/queueHooks$/,db=[ib],eb={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=bb.exec(b),f=e&&e[3]||(m.cssNumber[a]?"":"px"),g=(m.cssNumber[a]||"px"!==f&&+d)&&bb.exec(m.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,m.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function fb(){return setTimeout(function(){$a=void 0}),$a=m.now()}function gb(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=T[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function hb(a,b,c){for(var d,e=(eb[b]||[]).concat(eb["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ib(a,b,c){var d,e,f,g,h,i,j,l,n=this,o={},p=a.style,q=a.nodeType&&U(a),r=m._data(a,"fxshow");c.queue||(h=m._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,n.always(function(){n.always(function(){h.unqueued--,m.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=m.css(a,"display"),l="none"===j?m._data(a,"olddisplay")||Fa(a.nodeName):j,"inline"===l&&"none"===m.css(a,"float")&&(k.inlineBlockNeedsLayout&&"inline"!==Fa(a.nodeName)?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",k.shrinkWrapBlocks()||n.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],ab.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||m.style(a,d)}else j=void 0;if(m.isEmptyObject(o))"inline"===("none"===j?Fa(a.nodeName):j)&&(p.display=j);else{r?"hidden"in r&&(q=r.hidden):r=m._data(a,"fxshow",{}),f&&(r.hidden=!q),q?m(a).show():n.done(function(){m(a).hide()}),n.done(function(){var b;m._removeData(a,"fxshow");for(b in o)m.style(a,b,o[b])});for(d in o)g=hb(q?r[d]:0,d,n),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function jb(a,b){var c,d,e,f,g;for(c in a)if(d=m.camelCase(c),e=b[d],f=a[c],m.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=m.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function kb(a,b,c){var d,e,f=0,g=db.length,h=m.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=$a||fb(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:m.extend({},b),opts:m.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:$a||fb(),duration:c.duration,tweens:[],createTween:function(b,c){var d=m.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(jb(k,j.opts.specialEasing);g>f;f++)if(d=db[f].call(j,a,k,j.opts))return d;return m.map(k,hb,j),m.isFunction(j.opts.start)&&j.opts.start.call(a,j),m.fx.timer(m.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}m.Animation=m.extend(kb,{tweener:function(a,b){m.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],eb[c]=eb[c]||[],eb[c].unshift(b)},prefilter:function(a,b){b?db.unshift(a):db.push(a)}}),m.speed=function(a,b,c){var d=a&&"object"==typeof a?m.extend({},a):{complete:c||!c&&b||m.isFunction(a)&&a,duration:a,easing:c&&b||b&&!m.isFunction(b)&&b};return d.duration=m.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in m.fx.speeds?m.fx.speeds[d.duration]:m.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){m.isFunction(d.old)&&d.old.call(this),d.queue&&m.dequeue(this,d.queue)},d},m.fn.extend({fadeTo:function(a,b,c,d){return this.filter(U).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=m.isEmptyObject(a),f=m.speed(b,c,d),g=function(){var b=kb(this,m.extend({},a),f);(e||m._data(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=m.timers,g=m._data(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&cb.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&m.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=m._data(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=m.timers,g=d?d.length:0;for(c.finish=!0,m.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),m.each(["toggle","show","hide"],function(a,b){var c=m.fn[b];m.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(gb(b,!0),a,d,e)}}),m.each({slideDown:gb("show"),slideUp:gb("hide"),slideToggle:gb("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){m.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),m.timers=[],m.fx.tick=function(){var a,b=m.timers,c=0;for($a=m.now();c<b.length;c++)a=b[c],a()||b[c]!==a||b.splice(c--,1);b.length||m.fx.stop(),$a=void 0},m.fx.timer=function(a){m.timers.push(a),a()?m.fx.start():m.timers.pop()},m.fx.interval=13,m.fx.start=function(){_a||(_a=setInterval(m.fx.tick,m.fx.interval))},m.fx.stop=function(){clearInterval(_a),_a=null},m.fx.speeds={slow:600,fast:200,_default:400},m.fn.delay=function(a,b){return a=m.fx?m.fx.speeds[a]||a:a,b=b||"fx",this.queue(b,function(b,c){var d=setTimeout(b,a);c.stop=function(){clearTimeout(d)}})},function(){var a,b,c,d,e;b=y.createElement("div"),b.setAttribute("className","t"),b.innerHTML=" <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",d=b.getElementsByTagName("a")[0],c=y.createElement("select"),e=c.appendChild(y.createElement("option")),a=b.getElementsByTagName("input")[0],d.style.cssText="top:1px",k.getSetAttribute="t"!==b.className,k.style=/top/.test(d.getAttribute("style")),k.hrefNormalized="/a"===d.getAttribute("href"),k.checkOn=!!a.value,k.optSelected=e.selected,k.enctype=!!y.createElement("form").enctype,c.disabled=!0,k.optDisabled=!e.disabled,a=y.createElement("input"),a.setAttribute("value",""),k.input=""===a.getAttribute("value"),a.value="t",a.setAttribute("type","radio"),k.radioValue="t"===a.value}();var lb=/\r/g;m.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=m.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,m(this).val()):a,null==e?e="":"number"==typeof e?e+="":m.isArray(e)&&(e=m.map(e,function(a){return null==a?"":a+""})),b=m.valHooks[this.type]||m.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=m.valHooks[e.type]||m.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(lb,""):null==c?"":c)}}}),m.extend({valHooks:{option:{get:function(a){var b=m.find.attr(a,"value");return null!=b?b:m.trim(m.text(a))}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],!(!c.selected&&i!==e||(k.optDisabled?c.disabled:null!==c.getAttribute("disabled"))||c.parentNode.disabled&&m.nodeName(c.parentNode,"optgroup"))){if(b=m(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=m.makeArray(b),g=e.length;while(g--)if(d=e[g],m.inArray(m.valHooks.option.get(d),f)>=0)try{d.selected=c=!0}catch(h){d.scrollHeight}else d.selected=!1;return c||(a.selectedIndex=-1),e}}}}),m.each(["radio","checkbox"],function(){m.valHooks[this]={set:function(a,b){return m.isArray(b)?a.checked=m.inArray(m(a).val(),b)>=0:void 0}},k.checkOn||(m.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var mb,nb,ob=m.expr.attrHandle,pb=/^(?:checked|selected)$/i,qb=k.getSetAttribute,rb=k.input;m.fn.extend({attr:function(a,b){return V(this,m.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){m.removeAttr(this,a)})}}),m.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===K?m.prop(a,b,c):(1===f&&m.isXMLDoc(a)||(b=b.toLowerCase(),d=m.attrHooks[b]||(m.expr.match.bool.test(b)?nb:mb)),void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=m.find.attr(a,b),null==e?void 0:e):null!==c?d&&"set"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+""),c):void m.removeAttr(a,b))},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(E);if(f&&1===a.nodeType)while(c=f[e++])d=m.propFix[c]||c,m.expr.match.bool.test(c)?rb&&qb||!pb.test(c)?a[d]=!1:a[m.camelCase("default-"+c)]=a[d]=!1:m.attr(a,c,""),a.removeAttribute(qb?c:d)},attrHooks:{type:{set:function(a,b){if(!k.radioValue&&"radio"===b&&m.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),nb={set:function(a,b,c){return b===!1?m.removeAttr(a,c):rb&&qb||!pb.test(c)?a.setAttribute(!qb&&m.propFix[c]||c,c):a[m.camelCase("default-"+c)]=a[c]=!0,c}},m.each(m.expr.match.bool.source.match(/\w+/g),function(a,b){var c=ob[b]||m.find.attr;ob[b]=rb&&qb||!pb.test(b)?function(a,b,d){var e,f;return d||(f=ob[b],ob[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,ob[b]=f),e}:function(a,b,c){return c?void 0:a[m.camelCase("default-"+b)]?b.toLowerCase():null}}),rb&&qb||(m.attrHooks.value={set:function(a,b,c){return m.nodeName(a,"input")?void(a.defaultValue=b):mb&&mb.set(a,b,c)}}),qb||(mb={set:function(a,b,c){var d=a.getAttributeNode(c);return d||a.setAttributeNode(d=a.ownerDocument.createAttribute(c)),d.value=b+="","value"===c||b===a.getAttribute(c)?b:void 0}},ob.id=ob.name=ob.coords=function(a,b,c){var d;return c?void 0:(d=a.getAttributeNode(b))&&""!==d.value?d.value:null},m.valHooks.button={get:function(a,b){var c=a.getAttributeNode(b);return c&&c.specified?c.value:void 0},set:mb.set},m.attrHooks.contenteditable={set:function(a,b,c){mb.set(a,""===b?!1:b,c)}},m.each(["width","height"],function(a,b){m.attrHooks[b]={set:function(a,c){return""===c?(a.setAttribute(b,"auto"),c):void 0}}})),k.style||(m.attrHooks.style={get:function(a){return a.style.cssText||void 0},set:function(a,b){return a.style.cssText=b+""}});var sb=/^(?:input|select|textarea|button|object)$/i,tb=/^(?:a|area)$/i;m.fn.extend({prop:function(a,b){return V(this,m.prop,a,b,arguments.length>1)},removeProp:function(a){return a=m.propFix[a]||a,this.each(function(){try{this[a]=void 0,delete this[a]}catch(b){}})}}),m.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!m.isXMLDoc(a),f&&(b=m.propFix[b]||b,e=m.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=m.find.attr(a,"tabindex");return b?parseInt(b,10):sb.test(a.nodeName)||tb.test(a.nodeName)&&a.href?0:-1}}}}),k.hrefNormalized||m.each(["href","src"],function(a,b){m.propHooks[b]={get:function(a){return a.getAttribute(b,4)}}}),k.optSelected||(m.propHooks.selected={get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null}}),m.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){m.propFix[this.toLowerCase()]=this}),k.enctype||(m.propFix.enctype="encoding");var ub=/[\t\r\n\f]/g;m.fn.extend({addClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j="string"==typeof a&&a;if(m.isFunction(a))return this.each(function(b){m(this).addClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(E)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ub," "):" ")){f=0;while(e=b[f++])d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=m.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j=0===arguments.length||"string"==typeof a&&a;if(m.isFunction(a))return this.each(function(b){m(this).removeClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(E)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(ub," "):"")){f=0;while(e=b[f++])while(d.indexOf(" "+e+" ")>=0)d=d.replace(" "+e+" "," ");g=a?m.trim(d):"",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):this.each(m.isFunction(a)?function(c){m(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if("string"===c){var b,d=0,e=m(this),f=a.match(E)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===K||"boolean"===c)&&(this.className&&m._data(this,"__className__",this.className),this.className=this.className||a===!1?"":m._data(this,"__className__")||"")})},hasClass:function(a){for(var b=" "+a+" ",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(" "+this[c].className+" ").replace(ub," ").indexOf(b)>=0)return!0;return!1}}),m.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){m.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),m.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}});var vb=m.now(),wb=/\?/,xb=/(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;m.parseJSON=function(b){if(a.JSON&&a.JSON.parse)return a.JSON.parse(b+"");var c,d=null,e=m.trim(b+"");return e&&!m.trim(e.replace(xb,function(a,b,e,f){return c&&b&&(d=0),0===d?a:(c=e||b,d+=!f-!e,"")}))?Function("return "+e)():m.error("Invalid JSON: "+b)},m.parseXML=function(b){var c,d;if(!b||"string"!=typeof b)return null;try{a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b))}catch(e){c=void 0}return c&&c.documentElement&&!c.getElementsByTagName("parsererror").length||m.error("Invalid XML: "+b),c};var yb,zb,Ab=/#.*$/,Bb=/([?&])_=[^&]*/,Cb=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Db=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Eb=/^(?:GET|HEAD)$/,Fb=/^\/\//,Gb=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,Hb={},Ib={},Jb="*/".concat("*");try{zb=location.href}catch(Kb){zb=y.createElement("a"),zb.href="",zb=zb.href}yb=Gb.exec(zb.toLowerCase())||[];function Lb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(E)||[];if(m.isFunction(c))while(d=f[e++])"+"===d.charAt(0)?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Mb(a,b,c,d){var e={},f=a===Ib;function g(h){var i;return e[h]=!0,m.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Nb(a,b){var c,d,e=m.ajaxSettings.flatOptions||{};for(d in b)void 0!==b[d]&&((e[d]?a:c||(c={}))[d]=b[d]);return c&&m.extend(!0,a,c),a}function Ob(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===e&&(e=a.mimeType||b.getResponseHeader("Content-Type"));if(e)for(g in h)if(h[g]&&h[g].test(e)){i.unshift(g);break}if(i[0]in c)f=i[0];else{for(g in c){if(!i[0]||a.converters[g+" "+i[0]]){f=g;break}d||(d=g)}f=f||d}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Pb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}m.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:zb,type:"GET",isLocal:Db.test(yb[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Jb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":m.parseJSON,"text xml":m.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Nb(Nb(a,m.ajaxSettings),b):Nb(m.ajaxSettings,a)},ajaxPrefilter:Lb(Hb),ajaxTransport:Lb(Ib),ajax:function(a,b){"object"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=m.ajaxSetup({},b),l=k.context||k,n=k.context&&(l.nodeType||l.jquery)?m(l):m.event,o=m.Deferred(),p=m.Callbacks("once memory"),q=k.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!j){j={};while(b=Cb.exec(f))j[b[1].toLowerCase()]=b[2]}b=j[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?f:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(k.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return i&&i.abort(b),x(0,b),this}};if(o.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,k.url=((a||k.url||zb)+"").replace(Ab,"").replace(Fb,yb[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=m.trim(k.dataType||"*").toLowerCase().match(E)||[""],null==k.crossDomain&&(c=Gb.exec(k.url.toLowerCase()),k.crossDomain=!(!c||c[1]===yb[1]&&c[2]===yb[2]&&(c[3]||("http:"===c[1]?"80":"443"))===(yb[3]||("http:"===yb[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=m.param(k.data,k.traditional)),Mb(Hb,k,b,v),2===t)return v;h=m.event&&k.global,h&&0===m.active++&&m.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!Eb.test(k.type),e=k.url,k.hasContent||(k.data&&(e=k.url+=(wb.test(e)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=Bb.test(e)?e.replace(Bb,"$1_="+vb++):e+(wb.test(e)?"&":"?")+"_="+vb++)),k.ifModified&&(m.lastModified[e]&&v.setRequestHeader("If-Modified-Since",m.lastModified[e]),m.etag[e]&&v.setRequestHeader("If-None-Match",m.etag[e])),(k.data&&k.hasContent&&k.contentType!==!1||b.contentType)&&v.setRequestHeader("Content-Type",k.contentType),v.setRequestHeader("Accept",k.dataTypes[0]&&k.accepts[k.dataTypes[0]]?k.accepts[k.dataTypes[0]]+("*"!==k.dataTypes[0]?", "+Jb+"; q=0.01":""):k.accepts["*"]);for(d in k.headers)v.setRequestHeader(d,k.headers[d]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(d in{success:1,error:1,complete:1})v[d](k[d]);if(i=Mb(Ib,k,b,v)){v.readyState=1,h&&n.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,i.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,c,d){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),i=void 0,f=d||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,c&&(u=Ob(k,v,c)),u=Pb(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(m.lastModified[e]=w),w=v.getResponseHeader("etag"),w&&(m.etag[e]=w)),204===a||"HEAD"===k.type?x="nocontent":304===a?x="notmodified":(x=u.state,r=u.data,s=u.error,j=!s)):(s=x,(a||!x)&&(x="error",0>a&&(a=0))),v.status=a,v.statusText=(b||x)+"",j?o.resolveWith(l,[r,x,v]):o.rejectWith(l,[v,x,s]),v.statusCode(q),q=void 0,h&&n.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),h&&(n.trigger("ajaxComplete",[v,k]),--m.active||m.event.trigger("ajaxStop")))}return v},getJSON:function(a,b,c){return m.get(a,b,c,"json")},getScript:function(a,b){return m.get(a,void 0,b,"script")}}),m.each(["get","post"],function(a,b){m[b]=function(a,c,d,e){return m.isFunction(c)&&(e=e||d,d=c,c=void 0),m.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),m._evalUrl=function(a){return m.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},m.fn.extend({wrapAll:function(a){if(m.isFunction(a))return this.each(function(b){m(this).wrapAll(a.call(this,b))});if(this[0]){var b=m(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&1===a.firstChild.nodeType)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return this.each(m.isFunction(a)?function(b){m(this).wrapInner(a.call(this,b))}:function(){var b=m(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=m.isFunction(a);return this.each(function(c){m(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){m.nodeName(this,"body")||m(this).replaceWith(this.childNodes)}).end()}}),m.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0||!k.reliableHiddenOffsets()&&"none"===(a.style&&a.style.display||m.css(a,"display"))},m.expr.filters.visible=function(a){return!m.expr.filters.hidden(a)};var Qb=/%20/g,Rb=/\[\]$/,Sb=/\r?\n/g,Tb=/^(?:submit|button|image|reset|file)$/i,Ub=/^(?:input|select|textarea|keygen)/i;function Vb(a,b,c,d){var e;if(m.isArray(b))m.each(b,function(b,e){c||Rb.test(a)?d(a,e):Vb(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==m.type(b))d(a,b);else for(e in b)Vb(a+"["+e+"]",b[e],c,d)}m.param=function(a,b){var c,d=[],e=function(a,b){b=m.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=m.ajaxSettings&&m.ajaxSettings.traditional),m.isArray(a)||a.jquery&&!m.isPlainObject(a))m.each(a,function(){e(this.name,this.value)});else for(c in a)Vb(c,a[c],b,e);return d.join("&").replace(Qb,"+")},m.fn.extend({serialize:function(){return m.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=m.prop(this,"elements");return a?m.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!m(this).is(":disabled")&&Ub.test(this.nodeName)&&!Tb.test(a)&&(this.checked||!W.test(a))}).map(function(a,b){var c=m(this).val();return null==c?null:m.isArray(c)?m.map(c,function(a){return{name:b.name,value:a.replace(Sb,"\r\n")}}):{name:b.name,value:c.replace(Sb,"\r\n")}}).get()}}),m.ajaxSettings.xhr=void 0!==a.ActiveXObject?function(){return!this.isLocal&&/^(get|post|head|put|delete|options)$/i.test(this.type)&&Zb()||$b()}:Zb;var Wb=0,Xb={},Yb=m.ajaxSettings.xhr();a.attachEvent&&a.attachEvent("onunload",function(){for(var a in Xb)Xb[a](void 0,!0)}),k.cors=!!Yb&&"withCredentials"in Yb,Yb=k.ajax=!!Yb,Yb&&m.ajaxTransport(function(a){if(!a.crossDomain||k.cors){var b;return{send:function(c,d){var e,f=a.xhr(),g=++Wb;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c["X-Requested-With"]||(c["X-Requested-With"]="XMLHttpRequest");for(e in c)void 0!==c[e]&&f.setRequestHeader(e,c[e]+"");f.send(a.hasContent&&a.data||null),b=function(c,e){var h,i,j;if(b&&(e||4===f.readyState))if(delete Xb[g],b=void 0,f.onreadystatechange=m.noop,e)4!==f.readyState&&f.abort();else{j={},h=f.status,"string"==typeof f.responseText&&(j.text=f.responseText);try{i=f.statusText}catch(k){i=""}h||!a.isLocal||a.crossDomain?1223===h&&(h=204):h=j.text?200:404}j&&d(h,i,j,f.getAllResponseHeaders())},a.async?4===f.readyState?setTimeout(b):f.onreadystatechange=Xb[g]=b:b()},abort:function(){b&&b(void 0,!0)}}}});function Zb(){try{return new a.XMLHttpRequest}catch(b){}}function $b(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}m.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return m.globalEval(a),a}}}),m.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),m.ajaxTransport("script",function(a){if(a.crossDomain){var b,c=y.head||m("head")[0]||y.documentElement;return{send:function(d,e){b=y.createElement("script"),b.async=!0,a.scriptCharset&&(b.charset=a.scriptCharset),b.src=a.url,b.onload=b.onreadystatechange=function(a,c){(c||!b.readyState||/loaded|complete/.test(b.readyState))&&(b.onload=b.onreadystatechange=null,b.parentNode&&b.parentNode.removeChild(b),b=null,c||e(200,"success"))},c.insertBefore(b,c.firstChild)},abort:function(){b&&b.onload(void 0,!0)}}}});var _b=[],ac=/(=)\?(?=&|$)|\?\?/;m.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=_b.pop()||m.expando+"_"+vb++;return this[a]=!0,a}}),m.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(ac.test(b.url)?"url":"string"==typeof b.data&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&ac.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=m.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(ac,"$1"+e):b.jsonp!==!1&&(b.url+=(wb.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||m.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,_b.push(e)),g&&m.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),m.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||y;var d=u.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=m.buildFragment([a],b,e),e&&e.length&&m(e).remove(),m.merge([],d.childNodes))};var bc=m.fn.load;m.fn.load=function(a,b,c){if("string"!=typeof a&&bc)return bc.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>=0&&(d=m.trim(a.slice(h,a.length)),a=a.slice(0,h)),m.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(f="POST"),g.length>0&&m.ajax({url:a,type:f,dataType:"html",data:b}).done(function(a){e=arguments,g.html(d?m("<div>").append(m.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,e||[a.responseText,b,a])}),this},m.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){m.fn[b]=function(a){return this.on(b,a)}}),m.expr.filters.animated=function(a){return m.grep(m.timers,function(b){return a===b.elem}).length};var cc=a.document.documentElement;function dc(a){return m.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}m.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=m.css(a,"position"),l=m(a),n={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=m.css(a,"top"),i=m.css(a,"left"),j=("absolute"===k||"fixed"===k)&&m.inArray("auto",[f,i])>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),m.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(n.top=b.top-h.top+g),null!=b.left&&(n.left=b.left-h.left+e),"using"in b?b.using.call(a,n):l.css(n)}},m.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){m.offset.setOffset(this,a,b)});var b,c,d={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,m.contains(b,e)?(typeof e.getBoundingClientRect!==K&&(d=e.getBoundingClientRect()),c=dc(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return"fixed"===m.css(d,"position")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),m.nodeName(a[0],"html")||(c=a.offset()),c.top+=m.css(a[0],"borderTopWidth",!0),c.left+=m.css(a[0],"borderLeftWidth",!0)),{top:b.top-c.top-m.css(d,"marginTop",!0),left:b.left-c.left-m.css(d,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||cc;while(a&&!m.nodeName(a,"html")&&"static"===m.css(a,"position"))a=a.offsetParent;return a||cc})}}),m.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c=/Y/.test(b);m.fn[a]=function(d){return V(this,function(a,d,e){var f=dc(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?m(f).scrollLeft():e,c?e:m(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),m.each(["top","left"],function(a,b){m.cssHooks[b]=La(k.pixelPosition,function(a,c){return c?(c=Ja(a,b),Ha.test(c)?m(a).position()[b]+"px":c):void 0})}),m.each({Height:"height",Width:"width"},function(a,b){m.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){m.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return V(this,function(b,c,d){var e;return m.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?m.css(b,c,g):m.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),m.fn.size=function(){return this.length},m.fn.andSelf=m.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return m});var ec=a.jQuery,fc=a.$;return m.noConflict=function(b){return a.$===m&&(a.$=fc),b&&a.jQuery===m&&(a.jQuery=ec),m},typeof b===K&&(a.jQuery=a.$=m),m}); diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/js/mpl.js b/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/js/mpl.js new file mode 100644 index 0000000000..cde766b88f --- /dev/null +++ b/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/js/mpl.js @@ -0,0 +1,554 @@ +/* Put everything inside the global mpl namespace */ +window.mpl = {}; + + +mpl.get_websocket_type = function() { + if (typeof(WebSocket) !== 'undefined') { + return WebSocket; + } else if (typeof(MozWebSocket) !== 'undefined') { + return MozWebSocket; + } else { + alert('Your browser does not have WebSocket support.' + + 'Please try Chrome, Safari or Firefox ≥ 6. ' + + 'Firefox 4 and 5 are also supported but you ' + + 'have to enable WebSockets in about:config.'); + }; +} + +mpl.figure = function(figure_id, websocket, ondownload, parent_element) { + this.id = figure_id; + + this.ws = websocket; + + this.supports_binary = (this.ws.binaryType != undefined); + + if (!this.supports_binary) { + var warnings = document.getElementById("mpl-warnings"); + if (warnings) { + warnings.style.display = 'block'; + warnings.textContent = ( + "This browser does not support binary websocket messages. " + + "Performance may be slow."); + } + } + + this.imageObj = new Image(); + + this.context = undefined; + this.message = undefined; + this.canvas = undefined; + this.rubberband_canvas = undefined; + this.rubberband_context = undefined; + this.format_dropdown = undefined; + + this.image_mode = 'full'; + + this.root = $('<div/>'); + this._root_extra_style(this.root) + this.root.attr('style', 'display: inline-block'); + + $(parent_element).append(this.root); + + this._init_header(this); + this._init_canvas(this); + this._init_toolbar(this); + + var fig = this; + + this.waiting = false; + + this.ws.onopen = function () { + fig.send_message("supports_binary", {value: fig.supports_binary}); + fig.send_message("send_image_mode", {}); + if (mpl.ratio != 1) { + fig.send_message("set_dpi_ratio", {'dpi_ratio': mpl.ratio}); + } + fig.send_message("refresh", {}); + } + + this.imageObj.onload = function() { + if (fig.image_mode == 'full') { + // Full images could contain transparency (where diff images + // almost always do), so we need to clear the canvas so that + // there is no ghosting. + fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height); + } + fig.context.drawImage(fig.imageObj, 0, 0); + }; + + this.imageObj.onunload = function() { + fig.ws.close(); + } + + this.ws.onmessage = this._make_on_message_function(this); + + this.ondownload = ondownload; +} + +mpl.figure.prototype._init_header = function() { + var titlebar = $( + '<div class="ui-dialog-titlebar ui-widget-header ui-corner-all ' + + 'ui-helper-clearfix"/>'); + var titletext = $( + '<div class="ui-dialog-title" style="width: 100%; ' + + 'text-align: center; padding: 3px;"/>'); + titlebar.append(titletext) + this.root.append(titlebar); + this.header = titletext[0]; +} + + + +mpl.figure.prototype._canvas_extra_style = function(canvas_div) { + +} + + +mpl.figure.prototype._root_extra_style = function(canvas_div) { + +} + +mpl.figure.prototype._init_canvas = function() { + var fig = this; + + var canvas_div = $('<div/>'); + + canvas_div.attr('style', 'position: relative; clear: both; outline: 0'); + + function canvas_keyboard_event(event) { + return fig.key_event(event, event['data']); + } + + canvas_div.keydown('key_press', canvas_keyboard_event); + canvas_div.keyup('key_release', canvas_keyboard_event); + this.canvas_div = canvas_div + this._canvas_extra_style(canvas_div) + this.root.append(canvas_div); + + var canvas = $('<canvas/>'); + canvas.addClass('mpl-canvas'); + canvas.attr('style', "left: 0; top: 0; z-index: 0; outline: 0") + + this.canvas = canvas[0]; + this.context = canvas[0].getContext("2d"); + + var backingStore = this.context.backingStorePixelRatio || + this.context.webkitBackingStorePixelRatio || + this.context.mozBackingStorePixelRatio || + this.context.msBackingStorePixelRatio || + this.context.oBackingStorePixelRatio || + this.context.backingStorePixelRatio || 1; + + mpl.ratio = (window.devicePixelRatio || 1) / backingStore; + + var rubberband = $('<canvas/>'); + rubberband.attr('style', "position: absolute; left: 0; top: 0; z-index: 1;") + + var pass_mouse_events = true; + + canvas_div.resizable({ + start: function(event, ui) { + pass_mouse_events = false; + }, + resize: function(event, ui) { + fig.request_resize(ui.size.width, ui.size.height); + }, + stop: function(event, ui) { + pass_mouse_events = true; + fig.request_resize(ui.size.width, ui.size.height); + }, + }); + + function mouse_event_fn(event) { + if (pass_mouse_events) + return fig.mouse_event(event, event['data']); + } + + rubberband.mousedown('button_press', mouse_event_fn); + rubberband.mouseup('button_release', mouse_event_fn); + // Throttle sequential mouse events to 1 every 20ms. + rubberband.mousemove('motion_notify', mouse_event_fn); + + rubberband.mouseenter('figure_enter', mouse_event_fn); + rubberband.mouseleave('figure_leave', mouse_event_fn); + + canvas_div.on("wheel", function (event) { + event = event.originalEvent; + event['data'] = 'scroll' + if (event.deltaY < 0) { + event.step = 1; + } else { + event.step = -1; + } + mouse_event_fn(event); + }); + + canvas_div.append(canvas); + canvas_div.append(rubberband); + + this.rubberband = rubberband; + this.rubberband_canvas = rubberband[0]; + this.rubberband_context = rubberband[0].getContext("2d"); + this.rubberband_context.strokeStyle = "#000000"; + + this._resize_canvas = function(width, height) { + // Keep the size of the canvas, canvas container, and rubber band + // canvas in synch. + canvas_div.css('width', width) + canvas_div.css('height', height) + + canvas.attr('width', width * mpl.ratio); + canvas.attr('height', height * mpl.ratio); + canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;'); + + rubberband.attr('width', width); + rubberband.attr('height', height); + } + + // Set the figure to an initial 600x600px, this will subsequently be updated + // upon first draw. + this._resize_canvas(600, 600); + + // Disable right mouse context menu. + $(this.rubberband_canvas).bind("contextmenu",function(e){ + return false; + }); + + function set_focus () { + canvas.focus(); + canvas_div.focus(); + } + + window.setTimeout(set_focus, 100); +} + +mpl.figure.prototype._init_toolbar = function() { + var fig = this; + + var nav_element = $('<div/>') + nav_element.attr('style', 'width: 100%'); + this.root.append(nav_element); + + // Define a callback function for later on. + function toolbar_event(event) { + return fig.toolbar_button_onclick(event['data']); + } + function toolbar_mouse_event(event) { + return fig.toolbar_button_onmouseover(event['data']); + } + + for(var toolbar_ind in mpl.toolbar_items) { + var name = mpl.toolbar_items[toolbar_ind][0]; + var tooltip = mpl.toolbar_items[toolbar_ind][1]; + var image = mpl.toolbar_items[toolbar_ind][2]; + var method_name = mpl.toolbar_items[toolbar_ind][3]; + + if (!name) { + // put a spacer in here. + continue; + } + var button = $('<button/>'); + button.addClass('ui-button ui-widget ui-state-default ui-corner-all ' + + 'ui-button-icon-only'); + button.attr('role', 'button'); + button.attr('aria-disabled', 'false'); + button.click(method_name, toolbar_event); + button.mouseover(tooltip, toolbar_mouse_event); + + var icon_img = $('<span/>'); + icon_img.addClass('ui-button-icon-primary ui-icon'); + icon_img.addClass(image); + icon_img.addClass('ui-corner-all'); + + var tooltip_span = $('<span/>'); + tooltip_span.addClass('ui-button-text'); + tooltip_span.html(tooltip); + + button.append(icon_img); + button.append(tooltip_span); + + nav_element.append(button); + } + + var fmt_picker_span = $('<span/>'); + + var fmt_picker = $('<select/>'); + fmt_picker.addClass('mpl-toolbar-option ui-widget ui-widget-content'); + fmt_picker_span.append(fmt_picker); + nav_element.append(fmt_picker_span); + this.format_dropdown = fmt_picker[0]; + + for (var ind in mpl.extensions) { + var fmt = mpl.extensions[ind]; + var option = $( + '<option/>', {selected: fmt === mpl.default_extension}).html(fmt); + fmt_picker.append(option) + } + + // Add hover states to the ui-buttons + $( ".ui-button" ).hover( + function() { $(this).addClass("ui-state-hover");}, + function() { $(this).removeClass("ui-state-hover");} + ); + + var status_bar = $('<span class="mpl-message"/>'); + nav_element.append(status_bar); + this.message = status_bar[0]; +} + +mpl.figure.prototype.request_resize = function(x_pixels, y_pixels) { + // Request matplotlib to resize the figure. Matplotlib will then trigger a resize in the client, + // which will in turn request a refresh of the image. + this.send_message('resize', {'width': x_pixels, 'height': y_pixels}); +} + +mpl.figure.prototype.send_message = function(type, properties) { + properties['type'] = type; + properties['figure_id'] = this.id; + this.ws.send(JSON.stringify(properties)); +} + +mpl.figure.prototype.send_draw_message = function() { + if (!this.waiting) { + this.waiting = true; + this.ws.send(JSON.stringify({type: "draw", figure_id: this.id})); + } +} + + +mpl.figure.prototype.handle_save = function(fig, msg) { + var format_dropdown = fig.format_dropdown; + var format = format_dropdown.options[format_dropdown.selectedIndex].value; + fig.ondownload(fig, format); +} + + +mpl.figure.prototype.handle_resize = function(fig, msg) { + var size = msg['size']; + if (size[0] != fig.canvas.width || size[1] != fig.canvas.height) { + fig._resize_canvas(size[0], size[1]); + fig.send_message("refresh", {}); + }; +} + +mpl.figure.prototype.handle_rubberband = function(fig, msg) { + var x0 = msg['x0'] / mpl.ratio; + var y0 = (fig.canvas.height - msg['y0']) / mpl.ratio; + var x1 = msg['x1'] / mpl.ratio; + var y1 = (fig.canvas.height - msg['y1']) / mpl.ratio; + x0 = Math.floor(x0) + 0.5; + y0 = Math.floor(y0) + 0.5; + x1 = Math.floor(x1) + 0.5; + y1 = Math.floor(y1) + 0.5; + var min_x = Math.min(x0, x1); + var min_y = Math.min(y0, y1); + var width = Math.abs(x1 - x0); + var height = Math.abs(y1 - y0); + + fig.rubberband_context.clearRect( + 0, 0, fig.canvas.width, fig.canvas.height); + + fig.rubberband_context.strokeRect(min_x, min_y, width, height); +} + +mpl.figure.prototype.handle_figure_label = function(fig, msg) { + // Updates the figure title. + fig.header.textContent = msg['label']; +} + +mpl.figure.prototype.handle_cursor = function(fig, msg) { + var cursor = msg['cursor']; + switch(cursor) + { + case 0: + cursor = 'pointer'; + break; + case 1: + cursor = 'default'; + break; + case 2: + cursor = 'crosshair'; + break; + case 3: + cursor = 'move'; + break; + } + fig.rubberband_canvas.style.cursor = cursor; +} + +mpl.figure.prototype.handle_message = function(fig, msg) { + fig.message.textContent = msg['message']; +} + +mpl.figure.prototype.handle_draw = function(fig, msg) { + // Request the server to send over a new figure. + fig.send_draw_message(); +} + +mpl.figure.prototype.handle_image_mode = function(fig, msg) { + fig.image_mode = msg['mode']; +} + +mpl.figure.prototype.updated_canvas_event = function() { + // Called whenever the canvas gets updated. + this.send_message("ack", {}); +} + +// A function to construct a web socket function for onmessage handling. +// Called in the figure constructor. +mpl.figure.prototype._make_on_message_function = function(fig) { + return function socket_on_message(evt) { + if (evt.data instanceof Blob) { + /* FIXME: We get "Resource interpreted as Image but + * transferred with MIME type text/plain:" errors on + * Chrome. But how to set the MIME type? It doesn't seem + * to be part of the websocket stream */ + evt.data.type = "image/png"; + + /* Free the memory for the previous frames */ + if (fig.imageObj.src) { + (window.URL || window.webkitURL).revokeObjectURL( + fig.imageObj.src); + } + + fig.imageObj.src = (window.URL || window.webkitURL).createObjectURL( + evt.data); + fig.updated_canvas_event(); + fig.waiting = false; + return; + } + else if (typeof evt.data === 'string' && evt.data.slice(0, 21) == "data:image/png;base64") { + fig.imageObj.src = evt.data; + fig.updated_canvas_event(); + fig.waiting = false; + return; + } + + var msg = JSON.parse(evt.data); + var msg_type = msg['type']; + + // Call the "handle_{type}" callback, which takes + // the figure and JSON message as its only arguments. + try { + var callback = fig["handle_" + msg_type]; + } catch (e) { + console.log("No handler for the '" + msg_type + "' message type: ", msg); + return; + } + + if (callback) { + try { + // console.log("Handling '" + msg_type + "' message: ", msg); + callback(fig, msg); + } catch (e) { + console.log("Exception inside the 'handler_" + msg_type + "' callback:", e, e.stack, msg); + } + } + }; +} + +// from http://stackoverflow.com/questions/1114465/getting-mouse-location-in-canvas +mpl.findpos = function(e) { + //this section is from http://www.quirksmode.org/js/events_properties.html + var targ; + if (!e) + e = window.event; + if (e.target) + targ = e.target; + else if (e.srcElement) + targ = e.srcElement; + if (targ.nodeType == 3) // defeat Safari bug + targ = targ.parentNode; + + // jQuery normalizes the pageX and pageY + // pageX,Y are the mouse positions relative to the document + // offset() returns the position of the element relative to the document + var x = e.pageX - $(targ).offset().left; + var y = e.pageY - $(targ).offset().top; + + return {"x": x, "y": y}; +}; + +/* + * return a copy of an object with only non-object keys + * we need this to avoid circular references + * http://stackoverflow.com/a/24161582/3208463 + */ +function simpleKeys (original) { + return Object.keys(original).reduce(function (obj, key) { + if (typeof original[key] !== 'object') + obj[key] = original[key] + return obj; + }, {}); +} + +mpl.figure.prototype.mouse_event = function(event, name) { + var canvas_pos = mpl.findpos(event) + + if (name === 'button_press') + { + this.canvas.focus(); + this.canvas_div.focus(); + } + + var x = canvas_pos.x * mpl.ratio; + var y = canvas_pos.y * mpl.ratio; + + this.send_message(name, {x: x, y: y, button: event.button, + step: event.step, + guiEvent: simpleKeys(event)}); + + /* This prevents the web browser from automatically changing to + * the text insertion cursor when the button is pressed. We want + * to control all of the cursor setting manually through the + * 'cursor' event from matplotlib */ + event.preventDefault(); + return false; +} + +mpl.figure.prototype._key_event_extra = function(event, name) { + // Handle any extra behaviour associated with a key event +} + +mpl.figure.prototype.key_event = function(event, name) { + + // Prevent repeat events + if (name == 'key_press') + { + if (event.which === this._key) + return; + else + this._key = event.which; + } + if (name == 'key_release') + this._key = null; + + var value = ''; + if (event.ctrlKey && event.which != 17) + value += "ctrl+"; + if (event.altKey && event.which != 18) + value += "alt+"; + if (event.shiftKey && event.which != 16) + value += "shift+"; + + value += 'k'; + value += event.which.toString(); + + this._key_event_extra(event, name); + + this.send_message(name, {key: value, + guiEvent: simpleKeys(event)}); + return false; +} + +mpl.figure.prototype.toolbar_button_onclick = function(name) { + if (name == 'download') { + this.handle_save(this, null); + } else { + this.send_message("toolbar_button", {name: name}); + } +}; + +mpl.figure.prototype.toolbar_button_onmouseover = function(tooltip) { + this.message.textContent = tooltip; +}; diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/js/mpl_tornado.js b/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/js/mpl_tornado.js new file mode 100644 index 0000000000..8eb5eedb50 --- /dev/null +++ b/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/js/mpl_tornado.js @@ -0,0 +1,7 @@ +/* This .js file contains functions for matplotlib's built-in + tornado-based server, that are not relevant when embedding WebAgg + in another web application. */ + +function mpl_ondownload(figure, format) { + window.open(figure.id + '/download.' + format, '_blank'); +} diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/js/nbagg_mpl.js b/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/js/nbagg_mpl.js new file mode 100644 index 0000000000..c421872ad5 --- /dev/null +++ b/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/js/nbagg_mpl.js @@ -0,0 +1,208 @@ +var comm_websocket_adapter = function(comm) { + // Create a "websocket"-like object which calls the given IPython comm + // object with the appropriate methods. Currently this is a non binary + // socket, so there is still some room for performance tuning. + var ws = {}; + + ws.close = function() { + comm.close() + }; + ws.send = function(m) { + //console.log('sending', m); + comm.send(m); + }; + // Register the callback with on_msg. + comm.on_msg(function(msg) { + //console.log('receiving', msg['content']['data'], msg); + // Pass the mpl event to the overridden (by mpl) onmessage function. + ws.onmessage(msg['content']['data']) + }); + return ws; +} + +mpl.mpl_figure_comm = function(comm, msg) { + // This is the function which gets called when the mpl process + // starts-up an IPython Comm through the "matplotlib" channel. + + var id = msg.content.data.id; + // Get hold of the div created by the display call when the Comm + // socket was opened in Python. + var element = $("#" + id); + var ws_proxy = comm_websocket_adapter(comm) + + function ondownload(figure, format) { + window.open(figure.imageObj.src); + } + + var fig = new mpl.figure(id, ws_proxy, + ondownload, + element.get(0)); + + // Call onopen now - mpl needs it, as it is assuming we've passed it a real + // web socket which is closed, not our websocket->open comm proxy. + ws_proxy.onopen(); + + fig.parent_element = element.get(0); + fig.cell_info = mpl.find_output_cell("<div id='" + id + "'></div>"); + if (!fig.cell_info) { + console.error("Failed to find cell for figure", id, fig); + return; + } + + var output_index = fig.cell_info[2] + var cell = fig.cell_info[0]; + +}; + +mpl.figure.prototype.handle_close = function(fig, msg) { + var width = fig.canvas.width/mpl.ratio + fig.root.unbind('remove') + + // Update the output cell to use the data from the current canvas. + fig.push_to_output(); + var dataURL = fig.canvas.toDataURL(); + // Re-enable the keyboard manager in IPython - without this line, in FF, + // the notebook keyboard shortcuts fail. + IPython.keyboard_manager.enable() + $(fig.parent_element).html('<img src="' + dataURL + '" width="' + width + '">'); + fig.close_ws(fig, msg); +} + +mpl.figure.prototype.close_ws = function(fig, msg){ + fig.send_message('closing', msg); + // fig.ws.close() +} + +mpl.figure.prototype.push_to_output = function(remove_interactive) { + // Turn the data on the canvas into data in the output cell. + var width = this.canvas.width/mpl.ratio + var dataURL = this.canvas.toDataURL(); + this.cell_info[1]['text/html'] = '<img src="' + dataURL + '" width="' + width + '">'; +} + +mpl.figure.prototype.updated_canvas_event = function() { + // Tell IPython that the notebook contents must change. + IPython.notebook.set_dirty(true); + this.send_message("ack", {}); + var fig = this; + // Wait a second, then push the new image to the DOM so + // that it is saved nicely (might be nice to debounce this). + setTimeout(function () { fig.push_to_output() }, 1000); +} + +mpl.figure.prototype._init_toolbar = function() { + var fig = this; + + var nav_element = $('<div/>') + nav_element.attr('style', 'width: 100%'); + this.root.append(nav_element); + + // Define a callback function for later on. + function toolbar_event(event) { + return fig.toolbar_button_onclick(event['data']); + } + function toolbar_mouse_event(event) { + return fig.toolbar_button_onmouseover(event['data']); + } + + for(var toolbar_ind in mpl.toolbar_items){ + var name = mpl.toolbar_items[toolbar_ind][0]; + var tooltip = mpl.toolbar_items[toolbar_ind][1]; + var image = mpl.toolbar_items[toolbar_ind][2]; + var method_name = mpl.toolbar_items[toolbar_ind][3]; + + if (!name) { continue; }; + + var button = $('<button class="btn btn-default" href="#" title="' + name + '"><i class="fa ' + image + ' fa-lg"></i></button>'); + button.click(method_name, toolbar_event); + button.mouseover(tooltip, toolbar_mouse_event); + nav_element.append(button); + } + + // Add the status bar. + var status_bar = $('<span class="mpl-message" style="text-align:right; float: right;"/>'); + nav_element.append(status_bar); + this.message = status_bar[0]; + + // Add the close button to the window. + var buttongrp = $('<div class="btn-group inline pull-right"></div>'); + var button = $('<button class="btn btn-mini btn-primary" href="#" title="Stop Interaction"><i class="fa fa-power-off icon-remove icon-large"></i></button>'); + button.click(function (evt) { fig.handle_close(fig, {}); } ); + button.mouseover('Stop Interaction', toolbar_mouse_event); + buttongrp.append(button); + var titlebar = this.root.find($('.ui-dialog-titlebar')); + titlebar.prepend(buttongrp); +} + +mpl.figure.prototype._root_extra_style = function(el){ + var fig = this + el.on("remove", function(){ + fig.close_ws(fig, {}); + }); +} + +mpl.figure.prototype._canvas_extra_style = function(el){ + // this is important to make the div 'focusable + el.attr('tabindex', 0) + // reach out to IPython and tell the keyboard manager to turn it's self + // off when our div gets focus + + // location in version 3 + if (IPython.notebook.keyboard_manager) { + IPython.notebook.keyboard_manager.register_events(el); + } + else { + // location in version 2 + IPython.keyboard_manager.register_events(el); + } + +} + +mpl.figure.prototype._key_event_extra = function(event, name) { + var manager = IPython.notebook.keyboard_manager; + if (!manager) + manager = IPython.keyboard_manager; + + // Check for shift+enter + if (event.shiftKey && event.which == 13) { + this.canvas_div.blur(); + // select the cell after this one + var index = IPython.notebook.find_cell_index(this.cell_info[0]); + IPython.notebook.select(index + 1); + } +} + +mpl.figure.prototype.handle_save = function(fig, msg) { + fig.ondownload(fig, null); +} + + +mpl.find_output_cell = function(html_output) { + // Return the cell and output element which can be found *uniquely* in the notebook. + // Note - this is a bit hacky, but it is done because the "notebook_saving.Notebook" + // IPython event is triggered only after the cells have been serialised, which for + // our purposes (turning an active figure into a static one), is too late. + var cells = IPython.notebook.get_cells(); + var ncells = cells.length; + for (var i=0; i<ncells; i++) { + var cell = cells[i]; + if (cell.cell_type === 'code'){ + for (var j=0; j<cell.output_area.outputs.length; j++) { + var data = cell.output_area.outputs[j]; + if (data.data) { + // IPython >= 3 moved mimebundle to data attribute of output + data = data.data; + } + if (data['text/html'] == html_output) { + return [cell, data, j]; + } + } + } + } +} + +// Register the function which deals with the matplotlib target/channel. +// The kernel may be null if the page has been refreshed. +if (IPython.notebook.kernel != null) { + IPython.notebook.kernel.comm_manager.register_target('matplotlib', mpl.mpl_figure_comm); +} diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/nbagg_uat.ipynb b/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/nbagg_uat.ipynb new file mode 100644 index 0000000000..dfb264c375 --- /dev/null +++ b/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/nbagg_uat.ipynb @@ -0,0 +1,640 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "from __future__ import print_function\n", + "from imp import reload" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## UAT for NbAgg backend.\n", + "\n", + "The first line simply reloads matplotlib, uses the nbagg backend and then reloads the backend, just to ensure we have the latest modification to the backend code. Note: The underlying JavaScript will not be updated by this process, so a refresh of the browser after clearing the output and saving is necessary to clear everything fully." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import matplotlib\n", + "reload(matplotlib)\n", + "\n", + "matplotlib.use('nbagg')\n", + "\n", + "import matplotlib.backends.backend_nbagg\n", + "reload(matplotlib.backends.backend_nbagg)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### UAT 1 - Simple figure creation using pyplot\n", + "\n", + "Should produce a figure window which is interactive with the pan and zoom buttons. (Do not press the close button, but any others may be used)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import matplotlib.backends.backend_webagg_core\n", + "reload(matplotlib.backends.backend_webagg_core)\n", + "\n", + "import matplotlib.pyplot as plt\n", + "plt.interactive(False)\n", + "\n", + "fig1 = plt.figure()\n", + "plt.plot(range(10))\n", + "\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### UAT 2 - Creation of another figure, without the need to do plt.figure.\n", + "\n", + "As above, a new figure should be created." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "plt.plot([3, 2, 1])\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### UAT 3 - Connection info\n", + "\n", + "The printout should show that there are two figures which have active CommSockets, and no figures pending show." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "print(matplotlib.backends.backend_nbagg.connection_info())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### UAT 4 - Closing figures\n", + "\n", + "Closing a specific figure instance should turn the figure into a plain image - the UI should have been removed. In this case, scroll back to the first figure and assert this is the case." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "plt.close(fig1)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### UAT 5 - No show without plt.show in non-interactive mode\n", + "\n", + "Simply doing a plt.plot should not show a new figure, nor indeed update an existing one (easily verified in UAT 6).\n", + "The output should simply be a list of Line2D instances." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "plt.plot(range(10))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### UAT 6 - Connection information\n", + "\n", + "We just created a new figure, but didn't show it. Connection info should no longer have \"Figure 1\" (as we closed it in UAT 4) and should have figure 2 and 3, with Figure 3 without any connections. There should be 1 figure pending." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "print(matplotlib.backends.backend_nbagg.connection_info())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### UAT 7 - Show of previously created figure\n", + "\n", + "We should be able to show a figure we've previously created. The following should produce two figure windows." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "plt.show()\n", + "plt.figure()\n", + "plt.plot(range(5))\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### UAT 8 - Interactive mode\n", + "\n", + "In interactive mode, creating a line should result in a figure being shown." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "plt.interactive(True)\n", + "plt.figure()\n", + "plt.plot([3, 2, 1])" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Subsequent lines should be added to the existing figure, rather than creating a new one." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "plt.plot(range(3))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Calling connection_info in interactive mode should not show any pending figures." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "print(matplotlib.backends.backend_nbagg.connection_info())" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Disable interactive mode again." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "plt.interactive(False)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### UAT 9 - Multiple shows\n", + "\n", + "Unlike most of the other matplotlib backends, we may want to see a figure multiple times (with or without synchronisation between the views, though the former is not yet implemented). Assert that plt.gcf().canvas.manager.reshow() results in another figure window which is synchronised upon pan & zoom." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "plt.gcf().canvas.manager.reshow()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### UAT 10 - Saving notebook\n", + "\n", + "Saving the notebook (with CTRL+S or File->Save) should result in the saved notebook having static versions of the figues embedded within. The image should be the last update from user interaction and interactive plotting. (check by converting with ``ipython nbconvert <notebook>``)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### UAT 11 - Creation of a new figure on second show\n", + "\n", + "Create a figure, show it, then create a new axes and show it. The result should be a new figure.\n", + "\n", + "**BUG: Sometimes this doesn't work - not sure why (@pelson).**" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "fig = plt.figure()\n", + "plt.axes()\n", + "plt.show()\n", + "\n", + "plt.plot([1, 2, 3])\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### UAT 12 - OO interface\n", + "\n", + "Should produce a new figure and plot it." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "from matplotlib.backends.backend_nbagg import new_figure_manager,show\n", + "\n", + "manager = new_figure_manager(1000)\n", + "fig = manager.canvas.figure\n", + "ax = fig.add_subplot(1,1,1)\n", + "ax.plot([1,2,3])\n", + "fig.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## UAT 13 - Animation\n", + "\n", + "The following should generate an animated line:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import matplotlib.animation as animation\n", + "import numpy as np\n", + "\n", + "fig, ax = plt.subplots()\n", + "\n", + "x = np.arange(0, 2*np.pi, 0.01) # x-array\n", + "line, = ax.plot(x, np.sin(x))\n", + "\n", + "def animate(i):\n", + " line.set_ydata(np.sin(x+i/10.0)) # update the data\n", + " return line,\n", + "\n", + "#Init only required for blitting to give a clean slate.\n", + "def init():\n", + " line.set_ydata(np.ma.array(x, mask=True))\n", + " return line,\n", + "\n", + "ani = animation.FuncAnimation(fig, animate, np.arange(1, 200), init_func=init,\n", + " interval=32., blit=True)\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### UAT 14 - Keyboard shortcuts in IPython after close of figure\n", + "\n", + "After closing the previous figure (with the close button above the figure) the IPython keyboard shortcuts should still function.\n", + "\n", + "### UAT 15 - Figure face colours\n", + "\n", + "The nbagg honours all colours apart from that of the figure.patch. The two plots below should produce a figure with a red background. There should be no yellow figure." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import matplotlib\n", + "matplotlib.rcParams.update({'figure.facecolor': 'red',\n", + " 'savefig.facecolor': 'yellow'})\n", + "plt.figure()\n", + "plt.plot([3, 2, 1])\n", + "\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### UAT 16 - Events\n", + "\n", + "Pressing any keyboard key or mouse button (or scrolling) should cycle the line line while the figure has focus. The figure should have focus by default when it is created and re-gain it by clicking on the canvas. Clicking anywhere outside of the figure should release focus, but moving the mouse out of the figure should not release focus." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import itertools\n", + "fig, ax = plt.subplots()\n", + "x = np.linspace(0,10,10000)\n", + "y = np.sin(x)\n", + "ln, = ax.plot(x,y)\n", + "evt = []\n", + "colors = iter(itertools.cycle(['r', 'g', 'b', 'k', 'c']))\n", + "def on_event(event):\n", + " if event.name.startswith('key'):\n", + " fig.suptitle('%s: %s' % (event.name, event.key))\n", + " elif event.name == 'scroll_event':\n", + " fig.suptitle('%s: %s' % (event.name, event.step))\n", + " else:\n", + " fig.suptitle('%s: %s' % (event.name, event.button))\n", + " evt.append(event)\n", + " ln.set_color(next(colors))\n", + " fig.canvas.draw()\n", + " fig.canvas.draw_idle()\n", + "\n", + "fig.canvas.mpl_connect('button_press_event', on_event)\n", + "fig.canvas.mpl_connect('button_release_event', on_event)\n", + "fig.canvas.mpl_connect('scroll_event', on_event)\n", + "fig.canvas.mpl_connect('key_press_event', on_event)\n", + "fig.canvas.mpl_connect('key_release_event', on_event)\n", + "\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### UAT 17 - Timers\n", + "\n", + "Single-shot timers follow a completely different code path in the nbagg backend than regular timers (such as those used in the animation example above.) The next set of tests ensures that both \"regular\" and \"single-shot\" timers work properly.\n", + "\n", + "The following should show a simple clock that updates twice a second:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import time\n", + "\n", + "fig, ax = plt.subplots()\n", + "text = ax.text(0.5, 0.5, '', ha='center')\n", + "\n", + "def update(text):\n", + " text.set(text=time.ctime())\n", + " text.axes.figure.canvas.draw()\n", + " \n", + "timer = fig.canvas.new_timer(500, [(update, [text], {})])\n", + "timer.start()\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "However, the following should only update once and then stop:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "fig, ax = plt.subplots()\n", + "text = ax.text(0.5, 0.5, '', ha='center') \n", + "timer = fig.canvas.new_timer(500, [(update, [text], {})])\n", + "\n", + "timer.single_shot = True\n", + "timer.start()\n", + "\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "And the next two examples should never show any visible text at all:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "fig, ax = plt.subplots()\n", + "text = ax.text(0.5, 0.5, '', ha='center')\n", + "timer = fig.canvas.new_timer(500, [(update, [text], {})])\n", + "\n", + "timer.start()\n", + "timer.stop()\n", + "\n", + "plt.show()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "fig, ax = plt.subplots()\n", + "text = ax.text(0.5, 0.5, '', ha='center')\n", + "timer = fig.canvas.new_timer(500, [(update, [text], {})])\n", + "\n", + "timer.single_shot = True\n", + "timer.start()\n", + "timer.stop()\n", + "\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### UAT17 - stopping figure when removed from DOM\n", + "\n", + "When the div that contains from the figure is removed from the DOM the figure should shut down it's comm, and if the python-side figure has no more active comms, it should destroy the figure. Repeatedly running the cell below should always have the same figure number" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "fig, ax = plt.subplots()\n", + "ax.plot(range(5))\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Running the cell below will re-show the figure. After this, re-running the cell above should result in a new figure number." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "fig.canvas.manager.reshow()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.4.3" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/single_figure.html b/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/single_figure.html new file mode 100644 index 0000000000..4d5a366fbd --- /dev/null +++ b/contrib/python/matplotlib/py2/matplotlib/backends/web_backend/single_figure.html @@ -0,0 +1,30 @@ +<html> + <head> + <link rel="stylesheet" href="{{ prefix }}/_static/css/page.css" type="text/css"> + <link rel="stylesheet" href="{{ prefix }}/_static/css/boilerplate.css" type="text/css" /> + <link rel="stylesheet" href="{{ prefix }}/_static/css/fbm.css" type="text/css" /> + <link rel="stylesheet" href="{{ prefix }}/_static/jquery-ui-1.12.1/jquery-ui.min.css" > + <script src="{{ prefix }}/_static/jquery-ui-1.12.1/external/jquery/jquery.js"></script> + <script src="{{ prefix }}/_static/jquery-ui-1.12.1/jquery-ui.min.js"></script> + <script src="{{ prefix }}/_static/js/mpl_tornado.js"></script> + <script src="{{ prefix }}/js/mpl.js"></script> + <script> + $(document).ready( + function() { + var websocket_type = mpl.get_websocket_type(); + var websocket = new websocket_type( + "{{ ws_uri }}" + {{ repr(str(fig_id)) }} + "/ws"); + var fig = new mpl.figure( + {{repr(str(fig_id))}}, websocket, mpl_ondownload, $('div#figure')); + } + ); + </script> + + <title>matplotlib</title> + </head> + + <body> + <div id="mpl-warnings" class="mpl-warnings"></div> + <div id="figure" style="margin: 10px 10px;"></div> + </body> +</html> diff --git a/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/__init__.py b/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/__init__.py new file mode 100644 index 0000000000..7a8947f7fb --- /dev/null +++ b/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/__init__.py @@ -0,0 +1 @@ +# Make tests a package diff --git a/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/conftest.py b/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/conftest.py new file mode 100644 index 0000000000..2971a43141 --- /dev/null +++ b/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/conftest.py @@ -0,0 +1,6 @@ +from __future__ import (absolute_import, division, print_function, + unicode_literals) + +from matplotlib.testing.conftest import (mpl_test_settings, + mpl_image_comparison_parameters, + pytest_configure, pytest_unconfigure) diff --git a/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/test_tinypages.py b/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/test_tinypages.py new file mode 100644 index 0000000000..748a3f3819 --- /dev/null +++ b/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/test_tinypages.py @@ -0,0 +1,64 @@ +""" Tests for tinypages build using sphinx extensions """ + +import filecmp +from os.path import join as pjoin, dirname, isdir +from subprocess import call, Popen, PIPE +import sys + +import pytest + +from matplotlib import cbook + + +needs_sphinx = pytest.mark.skipif( + call([sys.executable, '-msphinx', '--help'], stdout=PIPE, stderr=PIPE), + reason="'{} -msphinx' does not return 0".format(sys.executable)) + + +@cbook.deprecated("2.1", alternative="filecmp.cmp") +def file_same(file1, file2): + with open(file1, 'rb') as fobj: + contents1 = fobj.read() + with open(file2, 'rb') as fobj: + contents2 = fobj.read() + return contents1 == contents2 + + +def test_tinypages(tmpdir): + html_dir = pjoin(str(tmpdir), 'html') + doctree_dir = pjoin(str(tmpdir), 'doctrees') + # Build the pages with warnings turned into errors + cmd = [sys.executable, '-msphinx', '-W', '-b', 'html', '-d', doctree_dir, + pjoin(dirname(__file__), 'tinypages'), html_dir] + proc = Popen(cmd, stdout=PIPE, stderr=PIPE) + out, err = proc.communicate() + assert proc.returncode == 0, \ + "'{} -msphinx' failed with stdout:\n{}\nstderr:\n{}\n".format( + sys.executable, out, err) + + assert isdir(html_dir) + + def plot_file(num): + return pjoin(html_dir, 'some_plots-{0}.png'.format(num)) + + range_10, range_6, range_4 = [plot_file(i) for i in range(1, 4)] + # Plot 5 is range(6) plot + assert filecmp.cmp(range_6, plot_file(5)) + # Plot 7 is range(4) plot + assert filecmp.cmp(range_4, plot_file(7)) + # Plot 11 is range(10) plot + assert filecmp.cmp(range_10, plot_file(11)) + # Plot 12 uses the old range(10) figure and the new range(6) figure + assert filecmp.cmp(range_10, plot_file('12_00')) + assert filecmp.cmp(range_6, plot_file('12_01')) + # Plot 13 shows close-figs in action + assert filecmp.cmp(range_4, plot_file(13)) + # Plot 14 has included source + with open(pjoin(html_dir, 'some_plots.html'), 'rb') as fobj: + html_contents = fobj.read() + assert b'# Only a comment' in html_contents + # check plot defined in external file. + assert filecmp.cmp(range_4, pjoin(html_dir, 'range4.png')) + assert filecmp.cmp(range_6, pjoin(html_dir, 'range6.png')) + # check if figure caption made it into html file + assert b'This is the caption for plot 15.' in html_contents diff --git a/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/.gitignore b/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/.gitignore new file mode 100644 index 0000000000..69fa449dd9 --- /dev/null +++ b/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/.gitignore @@ -0,0 +1 @@ +_build/ diff --git a/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/_static/.gitignore b/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/_static/.gitignore new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/_static/.gitignore diff --git a/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/conf.py b/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/conf.py new file mode 100644 index 0000000000..d2d26c18ec --- /dev/null +++ b/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/conf.py @@ -0,0 +1,264 @@ +# -*- coding: utf-8 -*- +# +# tinypages documentation build configuration file, created by +# sphinx-quickstart on Tue Mar 18 11:58:34 2014. +# +# This file is execfile()d with the current directory set to its +# containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys +from os.path import join as pjoin, abspath +import sphinx +from distutils.version import LooseVersion + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +#sys.path.insert(0, os.path.abspath('.')) +sys.path.insert(0, abspath(pjoin('..', '..'))) + +# -- General configuration ------------------------------------------------ + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = ['matplotlib.sphinxext.plot_directive'] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['_templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'tinypages' +copyright = u'2014, Matplotlib developers' + +# The version info for the project you're documenting, acts as replacement for +# |version| and |release|, also used in various other places throughout the +# built documents. +# +# The short X.Y version. +version = '0.1' +# The full version, including alpha/beta/rc tags. +release = '0.1' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +#language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = ['_build'] + +# The reST default role (used for this markup: `text`) to use for all +# documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + +# If true, keep warnings as "system message" paragraphs in the built documents. +#keep_warnings = False + + +# -- Options for HTML output ---------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +if LooseVersion(sphinx.__version__) >= LooseVersion('1.3'): + html_theme = 'classic' +else: + html_theme = 'default' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +#html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# "<project> v<release> documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['_static'] + +# Add any extra paths that contain custom files (such as robots.txt or +# .htaccess) here, relative to this directory. These files are copied +# directly to the root of the documentation. +#html_extra_path = [] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +#html_show_sourcelink = True + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a <link> tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = 'tinypagesdoc' + + +# -- Options for LaTeX output --------------------------------------------- + +latex_elements = { +# The paper size ('letterpaper' or 'a4paper'). +#'papersize': 'letterpaper', + +# The font size ('10pt', '11pt' or '12pt'). +#'pointsize': '10pt', + +# Additional stuff for the LaTeX preamble. +#'preamble': '', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, +# author, documentclass [howto, manual, or own class]). +latex_documents = [ + ('index', 'tinypages.tex', u'tinypages Documentation', + u'Matplotlib developers', 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output --------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ('index', 'tinypages', u'tinypages Documentation', + [u'Matplotlib developers'], 1) +] + +# If true, show URL addresses after external links. +#man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------- + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ('index', 'tinypages', u'tinypages Documentation', + u'Matplotlib developers', 'tinypages', 'One line description of project.', + 'Miscellaneous'), +] + +# Documents to append as an appendix to all manuals. +#texinfo_appendices = [] + +# If false, no module index is generated. +#texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +#texinfo_show_urls = 'footnote' + +# If true, do not generate a @detailmenu in the "Top" node's menu. +#texinfo_no_detailmenu = False diff --git a/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/range4.py b/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/range4.py new file mode 100644 index 0000000000..0772fc84ad --- /dev/null +++ b/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/range4.py @@ -0,0 +1,5 @@ +from matplotlib import pyplot as plt + +plt.figure() +plt.plot(range(4)) +plt.show() diff --git a/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/range6.py b/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/range6.py new file mode 100644 index 0000000000..7e78816bdf --- /dev/null +++ b/contrib/python/matplotlib/py2/matplotlib/sphinxext/tests/tinypages/range6.py @@ -0,0 +1,13 @@ +from matplotlib import pyplot as plt + + +def range4(): + '''This is never be called if plot_directive works as expected.''' + raise NotImplementedError + + +def range6(): + '''This is the function that should be executed.''' + plt.figure() + plt.plot(range(6)) + plt.show() diff --git a/contrib/python/matplotlib/py2/matplotlibrc.template b/contrib/python/matplotlib/py2/matplotlibrc.template new file mode 100644 index 0000000000..3c9d6f4cbc --- /dev/null +++ b/contrib/python/matplotlib/py2/matplotlibrc.template @@ -0,0 +1,618 @@ +#### MATPLOTLIBRC FORMAT + +## This is a sample matplotlib configuration file - you can find a copy +## of it on your system in +## site-packages/matplotlib/mpl-data/matplotlibrc. If you edit it +## there, please note that it will be overwritten in your next install. +## If you want to keep a permanent local copy that will not be +## overwritten, place it in the following location: +## unix/linux: +## $HOME/.config/matplotlib/matplotlibrc or +## $XDG_CONFIG_HOME/matplotlib/matplotlibrc (if $XDG_CONFIG_HOME is set) +## other platforms: +## $HOME/.matplotlib/matplotlibrc +## +## See http://matplotlib.org/users/customizing.html#the-matplotlibrc-file for +## more details on the paths which are checked for the configuration file. +## +## This file is best viewed in a editor which supports python mode +## syntax highlighting. Blank lines, or lines starting with a comment +## symbol, are ignored, as are trailing comments. Other lines must +## have the format +## key : val ## optional comment +## +## Colors: for the color values below, you can either use - a +## matplotlib color string, such as r, k, or b - an rgb tuple, such as +## (1.0, 0.5, 0.0) - a hex string, such as ff00ff - a scalar +## grayscale intensity such as 0.75 - a legal html color name, e.g., red, +## blue, darkslategray + +##### CONFIGURATION BEGINS HERE + +## The default backend; one of GTK GTKAgg GTKCairo GTK3Agg GTK3Cairo +## MacOSX Qt4Agg Qt5Agg TkAgg WX WXAgg Agg Cairo GDK PS PDF SVG +## Template. +## You can also deploy your own backend outside of matplotlib by +## referring to the module name (which must be in the PYTHONPATH) as +## 'module://my_backend'. +## +## If you omit this parameter, it will always default to "Agg", which is a +## non-interactive backend. +backend : $TEMPLATE_BACKEND + +## Note that this can be overridden by the environment variable +## QT_API used by Enthought Tool Suite (ETS); valid values are +## "pyqt" and "pyside". The "pyqt" setting has the side effect of +## forcing the use of Version 2 API for QString and QVariant. + +## The port to use for the web server in the WebAgg backend. +#webagg.port : 8988 + +## The address on which the WebAgg web server should be reachable +#webagg.address : 127.0.0.1 + +## If webagg.port is unavailable, a number of other random ports will +## be tried until one that is available is found. +#webagg.port_retries : 50 + +## When True, open the webbrowser to the plot that is shown +#webagg.open_in_browser : True + +## if you are running pyplot inside a GUI and your backend choice +## conflicts, we will automatically try to find a compatible one for +## you if backend_fallback is True +#backend_fallback: True + +#interactive : False +#toolbar : toolbar2 ## None | toolbar2 ("classic" is deprecated) +#timezone : UTC ## a pytz timezone string, e.g., US/Central or Europe/Paris + +## Where your matplotlib data lives if you installed to a non-default +## location. This is where the matplotlib fonts, bitmaps, etc reside +#datapath : /home/jdhunter/mpldata + + +#### LINES +## See http://matplotlib.org/api/artist_api.html#module-matplotlib.lines for more +## information on line properties. +#lines.linewidth : 1.5 ## line width in points +#lines.linestyle : - ## solid line +#lines.color : C0 ## has no affect on plot(); see axes.prop_cycle +#lines.marker : None ## the default marker +#lines.markeredgewidth : 1.0 ## the line width around the marker symbol +#lines.markersize : 6 ## markersize, in points +#lines.dash_joinstyle : round ## miter|round|bevel +#lines.dash_capstyle : butt ## butt|round|projecting +#lines.solid_joinstyle : round ## miter|round|bevel +#lines.solid_capstyle : projecting ## butt|round|projecting +#lines.antialiased : True ## render lines in antialiased (no jaggies) + +## The three standard dash patterns. These are scaled by the linewidth. +#lines.dashed_pattern : 3.7, 1.6 +#lines.dashdot_pattern : 6.4, 1.6, 1, 1.6 +#lines.dotted_pattern : 1, 1.65 +#lines.scale_dashes : True + +#markers.fillstyle: full ## full|left|right|bottom|top|none + +#### PATCHES +## Patches are graphical objects that fill 2D space, like polygons or +## circles. See +## http://matplotlib.org/api/artist_api.html#module-matplotlib.patches +## information on patch properties +#patch.linewidth : 1 ## edge width in points. +#patch.facecolor : C0 +#patch.edgecolor : k ## if forced, or patch is not filled +#patch.force_edgecolor : False ## True to always use edgecolor +#patch.antialiased : True ## render patches in antialiased (no jaggies) + +#### HATCHES +#hatch.color : k +#hatch.linewidth : 1.0 + +#### Boxplot +#boxplot.notch : False +#boxplot.vertical : True +#boxplot.whiskers : 1.5 +#boxplot.bootstrap : None +#boxplot.patchartist : False +#boxplot.showmeans : False +#boxplot.showcaps : True +#boxplot.showbox : True +#boxplot.showfliers : True +#boxplot.meanline : False + +#boxplot.flierprops.color : k +#boxplot.flierprops.marker : o +#boxplot.flierprops.markerfacecolor : none +#boxplot.flierprops.markeredgecolor : k +#boxplot.flierprops.markersize : 6 +#boxplot.flierprops.linestyle : none +#boxplot.flierprops.linewidth : 1.0 + +#boxplot.boxprops.color : k +#boxplot.boxprops.linewidth : 1.0 +#boxplot.boxprops.linestyle : - + +#boxplot.whiskerprops.color : k +#boxplot.whiskerprops.linewidth : 1.0 +#boxplot.whiskerprops.linestyle : - + +#boxplot.capprops.color : k +#boxplot.capprops.linewidth : 1.0 +#boxplot.capprops.linestyle : - + +#boxplot.medianprops.color : C1 +#boxplot.medianprops.linewidth : 1.0 +#boxplot.medianprops.linestyle : - + +#boxplot.meanprops.color : C2 +#boxplot.meanprops.marker : ^ +#boxplot.meanprops.markerfacecolor : C2 +#boxplot.meanprops.markeredgecolor : C2 +#boxplot.meanprops.markersize : 6 +#boxplot.meanprops.linestyle : -- +#boxplot.meanprops.linewidth : 1.0 + + +#### FONT + +## font properties used by text.Text. See +## http://matplotlib.org/api/font_manager_api.html for more +## information on font properties. The 6 font properties used for font +## matching are given below with their default values. +## +## The font.family property has five values: 'serif' (e.g., Times), +## 'sans-serif' (e.g., Helvetica), 'cursive' (e.g., Zapf-Chancery), +## 'fantasy' (e.g., Western), and 'monospace' (e.g., Courier). Each of +## these font families has a default list of font names in decreasing +## order of priority associated with them. When text.usetex is False, +## font.family may also be one or more concrete font names. +## +## The font.style property has three values: normal (or roman), italic +## or oblique. The oblique style will be used for italic, if it is not +## present. +## +## The font.variant property has two values: normal or small-caps. For +## TrueType fonts, which are scalable fonts, small-caps is equivalent +## to using a font size of 'smaller', or about 83%% of the current font +## size. +## +## The font.weight property has effectively 13 values: normal, bold, +## bolder, lighter, 100, 200, 300, ..., 900. Normal is the same as +## 400, and bold is 700. bolder and lighter are relative values with +## respect to the current weight. +## +## The font.stretch property has 11 values: ultra-condensed, +## extra-condensed, condensed, semi-condensed, normal, semi-expanded, +## expanded, extra-expanded, ultra-expanded, wider, and narrower. This +## property is not currently implemented. +## +## The font.size property is the default font size for text, given in pts. +## 10 pt is the standard value. + +#font.family : sans-serif +#font.style : normal +#font.variant : normal +#font.weight : normal +#font.stretch : normal +## note that font.size controls default text sizes. To configure +## special text sizes tick labels, axes, labels, title, etc, see the rc +## settings for axes and ticks. Special text sizes can be defined +## relative to font.size, using the following values: xx-small, x-small, +## small, medium, large, x-large, xx-large, larger, or smaller +#font.size : 10.0 +#font.serif : DejaVu Serif, Bitstream Vera Serif, Computer Modern Roman, New Century Schoolbook, Century Schoolbook L, Utopia, ITC Bookman, Bookman, Nimbus Roman No9 L, Times New Roman, Times, Palatino, Charter, serif +#font.sans-serif : DejaVu Sans, Bitstream Vera Sans, Computer Modern Sans Serif, Lucida Grande, Verdana, Geneva, Lucid, Arial, Helvetica, Avant Garde, sans-serif +#font.cursive : Apple Chancery, Textile, Zapf Chancery, Sand, Script MT, Felipa, cursive +#font.fantasy : Comic Sans MS, Chicago, Charcoal, ImpactWestern, Humor Sans, xkcd, fantasy +#font.monospace : DejaVu Sans Mono, Bitstream Vera Sans Mono, Computer Modern Typewriter, Andale Mono, Nimbus Mono L, Courier New, Courier, Fixed, Terminal, monospace + +#### TEXT +## text properties used by text.Text. See +## http://matplotlib.org/api/artist_api.html#module-matplotlib.text for more +## information on text properties +#text.color : k + +#### LaTeX customizations. See http://wiki.scipy.org/Cookbook/Matplotlib/UsingTex +#text.usetex : False ## use latex for all text handling. The following fonts + ## are supported through the usual rc parameter settings: + ## new century schoolbook, bookman, times, palatino, + ## zapf chancery, charter, serif, sans-serif, helvetica, + ## avant garde, courier, monospace, computer modern roman, + ## computer modern sans serif, computer modern typewriter + ## If another font is desired which can loaded using the + ## LaTeX \usepackage command, please inquire at the + ## matplotlib mailing list +#text.latex.unicode : False ## use "ucs" and "inputenc" LaTeX packages for handling + ## unicode strings. +#text.latex.preamble : ## IMPROPER USE OF THIS FEATURE WILL LEAD TO LATEX FAILURES + ## AND IS THEREFORE UNSUPPORTED. PLEASE DO NOT ASK FOR HELP + ## IF THIS FEATURE DOES NOT DO WHAT YOU EXPECT IT TO. + ## preamble is a comma separated list of LaTeX statements + ## that are included in the LaTeX document preamble. + ## An example: + ## text.latex.preamble : \usepackage{bm},\usepackage{euler} + ## The following packages are always loaded with usetex, so + ## beware of package collisions: color, geometry, graphicx, + ## type1cm, textcomp. Adobe Postscript (PSSNFS) font packages + ## may also be loaded, depending on your font settings +#text.latex.preview : False + +#text.hinting : auto ## May be one of the following: + ## none: Perform no hinting + ## auto: Use FreeType's autohinter + ## native: Use the hinting information in the + # font file, if available, and if your + # FreeType library supports it + ## either: Use the native hinting information, + # or the autohinter if none is available. + ## For backward compatibility, this value may also be + ## True === 'auto' or False === 'none'. +#text.hinting_factor : 8 ## Specifies the amount of softness for hinting in the + ## horizontal direction. A value of 1 will hint to full + ## pixels. A value of 2 will hint to half pixels etc. +#text.antialiased : True ## If True (default), the text will be antialiased. + ## This only affects the Agg backend. + +## The following settings allow you to select the fonts in math mode. +## They map from a TeX font name to a fontconfig font pattern. +## These settings are only used if mathtext.fontset is 'custom'. +## Note that this "custom" mode is unsupported and may go away in the +## future. +#mathtext.cal : cursive +#mathtext.rm : sans +#mathtext.tt : monospace +#mathtext.it : sans:italic +#mathtext.bf : sans:bold +#mathtext.sf : sans +#mathtext.fontset : dejavusans ## Should be 'dejavusans' (default), + ## 'dejavuserif', 'cm' (Computer Modern), 'stix', + ## 'stixsans' or 'custom' +#mathtext.fallback_to_cm : True ## When True, use symbols from the Computer Modern + ## fonts when a symbol can not be found in one of + ## the custom math fonts. +#mathtext.default : it ## The default font to use for math. + ## Can be any of the LaTeX font names, including + ## the special name "regular" for the same font + ## used in regular text. + +#### AXES +## default face and edge color, default tick sizes, +## default fontsizes for ticklabels, and so on. See +## http://matplotlib.org/api/axes_api.html#module-matplotlib.axes +#axes.facecolor : w ## axes background color +#axes.edgecolor : k ## axes edge color +#axes.linewidth : 0.8 ## edge linewidth +#axes.grid : False ## display grid or not +#axes.grid.axis : both ## which axis the grid should apply to +#axes.grid.which : major ## gridlines at major, minor or both ticks +#axes.titlesize : large ## fontsize of the axes title +#axes.titleweight : normal ## font weight of title +#axes.titlepad : 6.0 ## pad between axes and title in points +#axes.labelsize : medium ## fontsize of the x any y labels +#axes.labelpad : 4.0 ## space between label and axis +#axes.labelweight : normal ## weight of the x and y labels +#axes.labelcolor : k +#axes.axisbelow : line ## draw axis gridlines and ticks below + ## patches (True); above patches but below + ## lines ('line'); or above all (False) +#axes.formatter.limits : -7, 7 ## use scientific notation if log10 + ## of the axis range is smaller than the + ## first or larger than the second +#axes.formatter.use_locale : False ## When True, format tick labels + ## according to the user's locale. + ## For example, use ',' as a decimal + ## separator in the fr_FR locale. +#axes.formatter.use_mathtext : False ## When True, use mathtext for scientific + ## notation. +#axes.formatter.min_exponent: 0 ## minimum exponent to format in scientific notation +#axes.formatter.useoffset : True ## If True, the tick label formatter + ## will default to labeling ticks relative + ## to an offset when the data range is + ## small compared to the minimum absolute + ## value of the data. +#axes.formatter.offset_threshold : 4 ## When useoffset is True, the offset + ## will be used when it can remove + ## at least this number of significant + ## digits from tick labels. +#axes.spines.left : True ## display axis spines +#axes.spines.bottom : True +#axes.spines.top : True +#axes.spines.right : True +#axes.unicode_minus : True ## use unicode for the minus symbol + ## rather than hyphen. See + ## http://en.wikipedia.org/wiki/Plus_and_minus_signs#Character_codes +#axes.prop_cycle : cycler('color', ['1f77b4', 'ff7f0e', '2ca02c', 'd62728', '9467bd', '8c564b', 'e377c2', '7f7f7f', 'bcbd22', '17becf']) + ## color cycle for plot lines as list of string + ## colorspecs: single letter, long name, or web-style hex + ## Note the use of string escapes here ('1f77b4', instead of 1f77b4) + ## as opposed to the rest of this file. +#axes.autolimit_mode : data ## How to scale axes limits to the data. + ## Use "data" to use data limits, plus some margin + ## Use "round_number" move to the nearest "round" number +#axes.xmargin : .05 ## x margin. See `axes.Axes.margins` +#axes.ymargin : .05 ## y margin See `axes.Axes.margins` +#polaraxes.grid : True ## display grid on polar axes +#axes3d.grid : True ## display grid on 3d axes + +#### DATES +## These control the default format strings used in AutoDateFormatter. +## Any valid format datetime format string can be used (see the python +## `datetime` for details). For example using '%%x' will use the locale date representation +## '%%X' will use the locale time representation and '%%c' will use the full locale datetime +## representation. +## These values map to the scales: +## {'year': 365, 'month': 30, 'day': 1, 'hour': 1/24, 'minute': 1 / (24 * 60)} + +#date.autoformatter.year : %Y +#date.autoformatter.month : %Y-%m +#date.autoformatter.day : %Y-%m-%d +#date.autoformatter.hour : %m-%d %H +#date.autoformatter.minute : %d %H:%M +#date.autoformatter.second : %H:%M:%S +#date.autoformatter.microsecond : %M:%S.%f + +#### TICKS +## see http://matplotlib.org/api/axis_api.html#matplotlib.axis.Tick +#xtick.top : False ## draw ticks on the top side +#xtick.bottom : True ## draw ticks on the bottom side +#xtick.labeltop : False ## draw label on the top +#xtick.labelbottom : True ## draw label on the bottom +#xtick.major.size : 3.5 ## major tick size in points +#xtick.minor.size : 2 ## minor tick size in points +#xtick.major.width : 0.8 ## major tick width in points +#xtick.minor.width : 0.6 ## minor tick width in points +#xtick.major.pad : 3.5 ## distance to major tick label in points +#xtick.minor.pad : 3.4 ## distance to the minor tick label in points +#xtick.color : k ## color of the tick labels +#xtick.labelsize : medium ## fontsize of the tick labels +#xtick.direction : out ## direction: in, out, or inout +#xtick.minor.visible : False ## visibility of minor ticks on x-axis +#xtick.major.top : True ## draw x axis top major ticks +#xtick.major.bottom : True ## draw x axis bottom major ticks +#xtick.minor.top : True ## draw x axis top minor ticks +#xtick.minor.bottom : True ## draw x axis bottom minor ticks +#xtick.alignment : center ## alignment of xticks + +#ytick.left : True ## draw ticks on the left side +#ytick.right : False ## draw ticks on the right side +#ytick.labelleft : True ## draw tick labels on the left side +#ytick.labelright : False ## draw tick labels on the right side +#ytick.major.size : 3.5 ## major tick size in points +#ytick.minor.size : 2 ## minor tick size in points +#ytick.major.width : 0.8 ## major tick width in points +#ytick.minor.width : 0.6 ## minor tick width in points +#ytick.major.pad : 3.5 ## distance to major tick label in points +#ytick.minor.pad : 3.4 ## distance to the minor tick label in points +#ytick.color : k ## color of the tick labels +#ytick.labelsize : medium ## fontsize of the tick labels +#ytick.direction : out ## direction: in, out, or inout +#ytick.minor.visible : False ## visibility of minor ticks on y-axis +#ytick.major.left : True ## draw y axis left major ticks +#ytick.major.right : True ## draw y axis right major ticks +#ytick.minor.left : True ## draw y axis left minor ticks +#ytick.minor.right : True ## draw y axis right minor ticks +#ytick.alignment : center_baseline ## alignment of yticks + +#### GRIDS +#grid.color : b0b0b0 ## grid color +#grid.linestyle : - ## solid +#grid.linewidth : 0.8 ## in points +#grid.alpha : 1.0 ## transparency, between 0.0 and 1.0 + +#### Legend +#legend.loc : best +#legend.frameon : True ## if True, draw the legend on a background patch +#legend.framealpha : 0.8 ## legend patch transparency +#legend.facecolor : inherit ## inherit from axes.facecolor; or color spec +#legend.edgecolor : 0.8 ## background patch boundary color +#legend.fancybox : True ## if True, use a rounded box for the + ## legend background, else a rectangle +#legend.shadow : False ## if True, give background a shadow effect +#legend.numpoints : 1 ## the number of marker points in the legend line +#legend.scatterpoints : 1 ## number of scatter points +#legend.markerscale : 1.0 ## the relative size of legend markers vs. original +#legend.fontsize : medium +## Dimensions as fraction of fontsize: +#legend.borderpad : 0.4 ## border whitespace +#legend.labelspacing : 0.5 ## the vertical space between the legend entries +#legend.handlelength : 2.0 ## the length of the legend lines +#legend.handleheight : 0.7 ## the height of the legend handle +#legend.handletextpad : 0.8 ## the space between the legend line and legend text +#legend.borderaxespad : 0.5 ## the border between the axes and legend edge +#legend.columnspacing : 2.0 ## column separation + +#### FIGURE +## See http://matplotlib.org/api/figure_api.html#matplotlib.figure.Figure +#figure.titlesize : large ## size of the figure title (Figure.suptitle()) +#figure.titleweight : normal ## weight of the figure title +#figure.figsize : 6.4, 4.8 ## figure size in inches +#figure.dpi : 100 ## figure dots per inch +#figure.facecolor : w ## figure facecolor; 0.75 is scalar gray +#figure.edgecolor : w ## figure edgecolor +#figure.frameon : True ## enable figure frame +#figure.max_open_warning : 20 ## The maximum number of figures to open through + ## the pyplot interface before emitting a warning. + ## If less than one this feature is disabled. +## The figure subplot parameters. All dimensions are a fraction of the +#figure.subplot.left : 0.125 ## the left side of the subplots of the figure +#figure.subplot.right : 0.9 ## the right side of the subplots of the figure +#figure.subplot.bottom : 0.11 ## the bottom of the subplots of the figure +#figure.subplot.top : 0.88 ## the top of the subplots of the figure +#figure.subplot.wspace : 0.2 ## the amount of width reserved for space between subplots, + ## expressed as a fraction of the average axis width +#figure.subplot.hspace : 0.2 ## the amount of height reserved for space between subplots, + ## expressed as a fraction of the average axis height + +## Figure layout +#figure.autolayout : False ## When True, automatically adjust subplot + ## parameters to make the plot fit the figure + ## using `tight_layout` +#figure.constrained_layout.use: False ## When True, automatically make plot + ## elements fit on the figure. (Not compatible + ## with `autolayout`, above). +#figure.constrained_layout.h_pad : 0.04167 ## Padding around axes objects. Float representing +#figure.constrained_layout.w_pad : 0.04167 ## inches. Default is 3./72. inches (3 pts) +#figure.constrained_layout.hspace : 0.02 ## Space between subplot groups. Float representing +#figure.constrained_layout.wspace : 0.02 ## a fraction of the subplot widths being separated. + +#### IMAGES +#image.aspect : equal ## equal | auto | a number +#image.interpolation : nearest ## see help(imshow) for options +#image.cmap : viridis ## A colormap name, gray etc... +#image.lut : 256 ## the size of the colormap lookup table +#image.origin : upper ## lower | upper +#image.resample : True +#image.composite_image : True ## When True, all the images on a set of axes are + ## combined into a single composite image before + ## saving a figure as a vector graphics file, + ## such as a PDF. + +#### CONTOUR PLOTS +#contour.negative_linestyle : dashed ## string or on-off ink sequence +#contour.corner_mask : True ## True | False | legacy + +#### ERRORBAR PLOTS +#errorbar.capsize : 0 ## length of end cap on error bars in pixels + +#### HISTOGRAM PLOTS +#hist.bins : 10 ## The default number of histogram bins. + ## If Numpy 1.11 or later is + ## installed, may also be `auto` + +#### SCATTER PLOTS +#scatter.marker : o ## The default marker type for scatter plots. + +#### Agg rendering +#### Warning: experimental, 2008/10/10 +#agg.path.chunksize : 0 ## 0 to disable; values in the range + ## 10000 to 100000 can improve speed slightly + ## and prevent an Agg rendering failure + ## when plotting very large data sets, + ## especially if they are very gappy. + ## It may cause minor artifacts, though. + ## A value of 20000 is probably a good + ## starting point. +#### PATHS +#path.simplify : True ## When True, simplify paths by removing "invisible" + ## points to reduce file size and increase rendering + ## speed +#path.simplify_threshold : 0.111111111111 ## The threshold of similarity below which + ## vertices will be removed in the + ## simplification process +#path.snap : True ## When True, rectilinear axis-aligned paths will be snapped to + ## the nearest pixel when certain criteria are met. When False, + ## paths will never be snapped. +#path.sketch : None ## May be none, or a 3-tuple of the form (scale, length, + ## randomness). + ## *scale* is the amplitude of the wiggle + ## perpendicular to the line (in pixels). *length* + ## is the length of the wiggle along the line (in + ## pixels). *randomness* is the factor by which + ## the length is randomly scaled. +#path.effects : [] ## + +#### SAVING FIGURES +## the default savefig params can be different from the display params +## e.g., you may want a higher resolution, or to make the figure +## background white +#savefig.dpi : figure ## figure dots per inch or 'figure' +#savefig.facecolor : w ## figure facecolor when saving +#savefig.edgecolor : w ## figure edgecolor when saving +#savefig.format : png ## png, ps, pdf, svg +#savefig.bbox : standard ## 'tight' or 'standard'. + ## 'tight' is incompatible with pipe-based animation + ## backends but will workd with temporary file based ones: + ## e.g. setting animation.writer to ffmpeg will not work, + ## use ffmpeg_file instead +#savefig.pad_inches : 0.1 ## Padding to be used when bbox is set to 'tight' +#savefig.jpeg_quality: 95 ## when a jpeg is saved, the default quality parameter. +#savefig.directory : ~ ## default directory in savefig dialog box, + ## leave empty to always use current working directory +#savefig.transparent : False ## setting that controls whether figures are saved with a + ## transparent background by default +#savefig.frameon : True ## enable frame of figure when saving +#savefig.orientation : portrait ## Orientation of saved figure + +### tk backend params +#tk.window_focus : False ## Maintain shell focus for TkAgg + +### ps backend params +#ps.papersize : letter ## auto, letter, legal, ledger, A0-A10, B0-B10 +#ps.useafm : False ## use of afm fonts, results in small files +#ps.usedistiller : False ## can be: None, ghostscript or xpdf + ## Experimental: may produce smaller files. + ## xpdf intended for production of publication quality files, + ## but requires ghostscript, xpdf and ps2eps +#ps.distiller.res : 6000 ## dpi +#ps.fonttype : 3 ## Output Type 3 (Type3) or Type 42 (TrueType) + +### pdf backend params +#pdf.compression : 6 ## integer from 0 to 9 + ## 0 disables compression (good for debugging) +#pdf.fonttype : 3 ## Output Type 3 (Type3) or Type 42 (TrueType) +#pdf.use14corefonts : False +#pdf.inheritcolor : False + +### svg backend params +#svg.image_inline : True ## write raster image data directly into the svg file +#svg.fonttype : path ## How to handle SVG fonts: + ## none: Assume fonts are installed on the machine where the SVG will be viewed. + ## path: Embed characters as paths -- supported by most SVG renderers + ## svgfont: Embed characters as SVG fonts -- supported only by Chrome, + ## Opera and Safari +#svg.hashsalt : None ## if not None, use this string as hash salt + ## instead of uuid4 +### pgf parameter +#pgf.rcfonts : True +#pgf.preamble : +#pgf.texsystem : xelatex +#pgf.debug : False + +### docstring params +##docstring.hardcopy = False ## set this when you want to generate hardcopy docstring + +## Event keys to interact with figures/plots via keyboard. +## Customize these settings according to your needs. +## Leave the field(s) empty if you don't need a key-map. (i.e., fullscreen : '') +#keymap.fullscreen : f, ctrl+f ## toggling +#keymap.home : h, r, home ## home or reset mnemonic +#keymap.back : left, c, backspace ## forward / backward keys to enable +#keymap.forward : right, v ## left handed quick navigation +#keymap.pan : p ## pan mnemonic +#keymap.zoom : o ## zoom mnemonic +#keymap.save : s, ctrl+s ## saving current figure +#keymap.quit : ctrl+w, cmd+w, q ## close the current figure +#keymap.quit_all : W, cmd+W, Q ## close all figures +#keymap.grid : g ## switching on/off major grids in current axes +#keymap.grid_minor : G ## switching on/off minor grids in current axes +#keymap.yscale : l ## toggle scaling of y-axes ('log'/'linear') +#keymap.xscale : k, L ## toggle scaling of x-axes ('log'/'linear') +#keymap.all_axes : a ## enable all axes + +## Control location of examples data files +#examples.directory : ## directory to look in for custom installation + +###ANIMATION settings +#animation.html : none ## How to display the animation as HTML in + ## the IPython notebook. 'html5' uses + ## HTML5 video tag; 'jshtml' creates a + ## Javascript animation +#animation.writer : ffmpeg ## MovieWriter 'backend' to use +#animation.codec : h264 ## Codec to use for writing movie +#animation.bitrate: -1 ## Controls size/quality tradeoff for movie. + ## -1 implies let utility auto-determine +#animation.frame_format: png ## Controls frame format used by temp files +#animation.html_args: ## Additional arguments to pass to html writer +#animation.ffmpeg_path: ffmpeg ## Path to ffmpeg binary. Without full path + ## $PATH is searched +#animation.ffmpeg_args: ## Additional arguments to pass to ffmpeg +#animation.avconv_path: avconv ## Path to avconv binary. Without full path + ## $PATH is searched +#animation.avconv_args: ## Additional arguments to pass to avconv +#animation.convert_path: convert ## Path to ImageMagick's convert binary. + ## On Windows use the full path since convert + ## is also the name of a system tool. +#animation.convert_args: ## Additional arguments to pass to convert +#animation.embed_limit : 20.0 diff --git a/contrib/python/matplotlib/py2/src/_backend_gdk.c b/contrib/python/matplotlib/py2/src/_backend_gdk.c new file mode 100644 index 0000000000..8314219cca --- /dev/null +++ b/contrib/python/matplotlib/py2/src/_backend_gdk.c @@ -0,0 +1,72 @@ +/* -*- mode: C; c-basic-offset: 4 -*- + * C extensions for backend_gdk + */ + +#include "Python.h" +#include "numpy/arrayobject.h" + +#include <pygtk/pygtk.h> + +static PyTypeObject *_PyGdkPixbuf_Type; +#define PyGdkPixbuf_Type (*_PyGdkPixbuf_Type) + +static PyObject *pixbuf_get_pixels_array(PyObject *self, PyObject *args) +{ + /* 1) read in Python pixbuf, get the underlying gdk_pixbuf */ + PyGObject *py_pixbuf; + GdkPixbuf *gdk_pixbuf; + PyArrayObject *array; + npy_intp dims[3] = { 0, 0, 3 }; + npy_intp strides[3]; + + if (!PyArg_ParseTuple(args, "O!:pixbuf_get_pixels_array", &PyGdkPixbuf_Type, &py_pixbuf)) + return NULL; + + gdk_pixbuf = GDK_PIXBUF(py_pixbuf->obj); + + /* 2) same as pygtk/gtk/gdk.c _wrap_gdk_pixbuf_get_pixels_array() + * with 'self' changed to py_pixbuf + */ + + dims[0] = gdk_pixbuf_get_height(gdk_pixbuf); + dims[1] = gdk_pixbuf_get_width(gdk_pixbuf); + if (gdk_pixbuf_get_has_alpha(gdk_pixbuf)) + dims[2] = 4; + + strides[0] = gdk_pixbuf_get_rowstride(gdk_pixbuf); + strides[1] = dims[2]; + strides[2] = 1; + + array = (PyArrayObject*) + PyArray_New(&PyArray_Type, 3, dims, NPY_UBYTE, strides, + (void*)gdk_pixbuf_get_pixels(gdk_pixbuf), 1, + NPY_ARRAY_WRITEABLE, NULL); + + if (array == NULL) + return NULL; + + /* the array holds a ref to the pixbuf pixels through this wrapper*/ + Py_INCREF(py_pixbuf); + if (PyArray_SetBaseObject(array, (PyObject *)py_pixbuf) == -1) { + Py_DECREF(py_pixbuf); + Py_DECREF(array); + return NULL; + } + return PyArray_Return(array); +} + +static PyMethodDef _backend_gdk_functions[] = { + { "pixbuf_get_pixels_array", (PyCFunction)pixbuf_get_pixels_array, METH_VARARGS }, + { NULL, NULL, 0 } +}; + +PyMODINIT_FUNC init_backend_gdk(void) +{ + PyObject *mod; + mod = Py_InitModule("matplotlib.backends._backend_gdk", _backend_gdk_functions); + import_array(); + init_pygtk(); + + mod = PyImport_ImportModule("gtk.gdk"); + _PyGdkPixbuf_Type = (PyTypeObject *)PyObject_GetAttrString(mod, "Pixbuf"); +} diff --git a/contrib/python/matplotlib/py2/src/_gtkagg.cpp b/contrib/python/matplotlib/py2/src/_gtkagg.cpp new file mode 100644 index 0000000000..2d6a1cec13 --- /dev/null +++ b/contrib/python/matplotlib/py2/src/_gtkagg.cpp @@ -0,0 +1,155 @@ +/* -*- mode: c++; c-basic-offset: 4 -*- */ + +#include <pygobject.h> +#include <pygtk/pygtk.h> + +#include <vector> + +#include "agg_basics.h" +#include "agg_pixfmt_rgba.h" +#include "agg_renderer_base.h" +#include "agg_rendering_buffer.h" + +#include "numpy_cpp.h" +#include "py_converters.h" + +static PyObject *Py_agg_to_gtk_drawable(PyObject *self, PyObject *args, PyObject *kwds) +{ + typedef agg::pixfmt_rgba32_plain pixfmt; + typedef agg::renderer_base<pixfmt> renderer_base; + + PyGObject *py_drawable; + numpy::array_view<agg::int8u, 3> buffer; + agg::rect_d rect; + + // args are gc, renderer, bbox where bbox is a transforms BBox + // (possibly None). If bbox is None, blit the entire agg buffer + // to gtk. If bbox is not None, blit only the region defined by + // the bbox + + if (!PyArg_ParseTuple(args, + "OO&O&:agg_to_gtk_drawable", + &py_drawable, + &buffer.converter, + &buffer, + &convert_rect, + &rect)) { + return NULL; + } + + if (buffer.dim(2) != 4) { + PyErr_SetString(PyExc_ValueError, "Invalid image buffer. Must be NxMx4."); + return NULL; + } + + GdkDrawable *drawable = GDK_DRAWABLE(py_drawable->obj); + GdkGC *gc = gdk_gc_new(drawable); + + int srcstride = buffer.dim(1) * 4; + int srcwidth = buffer.dim(1); + int srcheight = buffer.dim(0); + + // these three will be overridden below + int destx = 0; + int desty = 0; + int destwidth = 1; + int destheight = 1; + int deststride = 1; + + std::vector<agg::int8u> destbuffer; + agg::int8u *destbufferptr; + + if (rect.x1 == 0.0 && rect.x2 == 0.0 && rect.y1 == 0.0 && rect.y2 == 0.0) { + // bbox is None; copy the entire image + destbufferptr = (agg::int8u *)buffer.data(); + destwidth = srcwidth; + destheight = srcheight; + deststride = srcstride; + } else { + destx = (int)rect.x1; + desty = srcheight - (int)rect.y2; + destwidth = (int)(rect.x2 - rect.x1); + destheight = (int)(rect.y2 - rect.y1); + deststride = destwidth * 4; + destbuffer.resize(destheight * deststride, 0); + destbufferptr = &destbuffer.front(); + + agg::rendering_buffer destrbuf; + destrbuf.attach(destbufferptr, destwidth, destheight, deststride); + pixfmt destpf(destrbuf); + renderer_base destrb(destpf); + + agg::rendering_buffer srcrbuf; + srcrbuf.attach((agg::int8u *)buffer.data(), buffer.dim(1), buffer.dim(0), buffer.dim(1) * 4); + + agg::rect_base<int> region(destx, desty, (int)rect.x2, srcheight - (int)rect.y1); + destrb.copy_from(srcrbuf, ®ion, -destx, -desty); + } + + gdk_draw_rgb_32_image(drawable, + gc, + destx, + desty, + destwidth, + destheight, + GDK_RGB_DITHER_NORMAL, + destbufferptr, + deststride); + + gdk_gc_destroy(gc); + + Py_RETURN_NONE; +} + +static PyMethodDef module_methods[] = { + {"agg_to_gtk_drawable", (PyCFunction)Py_agg_to_gtk_drawable, METH_VARARGS, NULL}, + NULL +}; + +extern "C" { + +#if PY3K + static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + "_gtkagg", + NULL, + 0, + module_methods, + NULL, + NULL, + NULL, + NULL + }; + +#define INITERROR return NULL + + PyMODINIT_FUNC PyInit__gtkagg(void) + +#else +#define INITERROR return + + PyMODINIT_FUNC init_gtkagg(void) +#endif + + { + PyObject *m; + +#if PY3K + m = PyModule_Create(&moduledef); +#else + m = Py_InitModule3("_gtkagg", module_methods, NULL); +#endif + + if (m == NULL) { + INITERROR; + } + + init_pygobject(); + init_pygtk(); + import_array(); + +#if PY3K + return m; +#endif + } +} diff --git a/contrib/python/matplotlib/py2/src/_macosx.m b/contrib/python/matplotlib/py2/src/_macosx.m new file mode 100644 index 0000000000..8f44f1eb0c --- /dev/null +++ b/contrib/python/matplotlib/py2/src/_macosx.m @@ -0,0 +1,3174 @@ +#include <Cocoa/Cocoa.h> +#include <ApplicationServices/ApplicationServices.h> +#include <sys/socket.h> +#include <Python.h> + +#define PYOSINPUTHOOK_REPETITIVE 1 /* Remove this once Python is fixed */ + +#if PY_MAJOR_VERSION >= 3 +#define PY3K 1 +#else +#define PY3K 0 +#endif + +/* Proper way to check for the OS X version we are compiling for, from + http://developer.apple.com/documentation/DeveloperTools/Conceptual/cross_development */ +#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 +#define COMPILING_FOR_10_6 +#endif +#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 1070 +#define COMPILING_FOR_10_7 +#endif +#if __MAC_OS_X_VERSION_MIN_REQUIRED >= 10100 +#define COMPILING_FOR_10_10 +#endif + + +/* CGFloat was defined in Mac OS X 10.5 */ +#ifndef CGFLOAT_DEFINED +#define CGFloat float +#endif + + +/* Various NSApplicationDefined event subtypes */ +#define STOP_EVENT_LOOP 2 +#define WINDOW_CLOSING 3 + + +/* Keep track of number of windows present + Needed to know when to stop the NSApp */ +static long FigureWindowCount = 0; + +/* -------------------------- Helper function ---------------------------- */ + +static void +_stdin_callback(CFReadStreamRef stream, CFStreamEventType eventType, void* info) +{ + CFRunLoopRef runloop = info; + CFRunLoopStop(runloop); +} + +static int sigint_fd = -1; + +static void _sigint_handler(int sig) +{ + const char c = 'i'; + write(sigint_fd, &c, 1); +} + +static void _sigint_callback(CFSocketRef s, + CFSocketCallBackType type, + CFDataRef address, + const void * data, + void *info) +{ + char c; + int* interrupted = info; + CFSocketNativeHandle handle = CFSocketGetNative(s); + CFRunLoopRef runloop = CFRunLoopGetCurrent(); + read(handle, &c, 1); + *interrupted = 1; + CFRunLoopStop(runloop); +} + +static CGEventRef _eventtap_callback(CGEventTapProxy proxy, CGEventType type, CGEventRef event, void *refcon) +{ + CFRunLoopRef runloop = refcon; + CFRunLoopStop(runloop); + return event; +} + +static int wait_for_stdin(void) +{ + int interrupted = 0; + const UInt8 buffer[] = "/dev/fd/0"; + const CFIndex n = (CFIndex)strlen((char*)buffer); + CFRunLoopRef runloop = CFRunLoopGetCurrent(); + CFURLRef url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, + buffer, + n, + false); + CFReadStreamRef stream = CFReadStreamCreateWithFile(kCFAllocatorDefault, + url); + CFRelease(url); + + CFReadStreamOpen(stream); +#ifdef PYOSINPUTHOOK_REPETITIVE + if (!CFReadStreamHasBytesAvailable(stream)) + /* This is possible because of how PyOS_InputHook is called from Python */ + { +#endif + int error; + int channel[2]; + CFSocketRef sigint_socket = NULL; + PyOS_sighandler_t py_sigint_handler = NULL; + CFStreamClientContext clientContext = {0, NULL, NULL, NULL, NULL}; + clientContext.info = runloop; + CFReadStreamSetClient(stream, + kCFStreamEventHasBytesAvailable, + _stdin_callback, + &clientContext); + CFReadStreamScheduleWithRunLoop(stream, runloop, kCFRunLoopDefaultMode); + error = socketpair(AF_UNIX, SOCK_STREAM, 0, channel); + if (error==0) + { + CFSocketContext context; + context.version = 0; + context.info = &interrupted; + context.retain = NULL; + context.release = NULL; + context.copyDescription = NULL; + fcntl(channel[0], F_SETFL, O_WRONLY | O_NONBLOCK); + sigint_socket = CFSocketCreateWithNative( + kCFAllocatorDefault, + channel[1], + kCFSocketReadCallBack, + _sigint_callback, + &context); + if (sigint_socket) + { + CFRunLoopSourceRef source; + source = CFSocketCreateRunLoopSource(kCFAllocatorDefault, + sigint_socket, + 0); + CFRelease(sigint_socket); + if (source) + { + CFRunLoopAddSource(runloop, source, kCFRunLoopDefaultMode); + CFRelease(source); + sigint_fd = channel[0]; + py_sigint_handler = PyOS_setsig(SIGINT, _sigint_handler); + } + } + } + + NSEvent* event; + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + while (true) { + while (true) { + event = [NSApp nextEventMatchingMask: NSAnyEventMask + untilDate: [NSDate distantPast] + inMode: NSDefaultRunLoopMode + dequeue: YES]; + if (!event) break; + [NSApp sendEvent: event]; + } + CFRunLoopRun(); + if (interrupted || CFReadStreamHasBytesAvailable(stream)) break; + } + [pool release]; + + if (py_sigint_handler) PyOS_setsig(SIGINT, py_sigint_handler); + CFReadStreamUnscheduleFromRunLoop(stream, + runloop, + kCFRunLoopCommonModes); + if (sigint_socket) CFSocketInvalidate(sigint_socket); + if (error==0) { + close(channel[0]); + close(channel[1]); + } +#ifdef PYOSINPUTHOOK_REPETITIVE + } +#endif + CFReadStreamClose(stream); + CFRelease(stream); + if (interrupted) { + errno = EINTR; + raise(SIGINT); + return -1; + } + return 1; +} + +/* ---------------------------- Cocoa classes ---------------------------- */ + +@interface WindowServerConnectionManager : NSObject +{ +} ++ (WindowServerConnectionManager*)sharedManager; +- (void)launch:(NSNotification*)notification; +@end + +@interface Window : NSWindow +{ PyObject* manager; +} +- (Window*)initWithContentRect:(NSRect)rect styleMask:(unsigned int)mask backing:(NSBackingStoreType)bufferingType defer:(BOOL)deferCreation withManager: (PyObject*)theManager; +- (NSRect)constrainFrameRect:(NSRect)rect toScreen:(NSScreen*)screen; +- (BOOL)closeButtonPressed; +- (void)dealloc; +@end + +@interface ToolWindow : NSWindow +{ +} +- (ToolWindow*)initWithContentRect:(NSRect)rect master:(NSWindow*)window; +- (void)masterCloses:(NSNotification*)notification; +- (void)close; +@end + +#ifdef COMPILING_FOR_10_6 +@interface View : NSView <NSWindowDelegate> +#else +@interface View : NSView +#endif +{ PyObject* canvas; + NSRect rubberband; + BOOL inside; + NSTrackingRectTag tracking; + @public double device_scale; +} +- (void)dealloc; +- (void)drawRect:(NSRect)rect; +- (void)windowDidResize:(NSNotification*)notification; +- (View*)initWithFrame:(NSRect)rect; +- (void)setCanvas: (PyObject*)newCanvas; +- (void)windowWillClose:(NSNotification*)notification; +- (BOOL)windowShouldClose:(NSNotification*)notification; +- (BOOL)isFlipped; +- (void)mouseEntered:(NSEvent*)event; +- (void)mouseExited:(NSEvent*)event; +- (void)mouseDown:(NSEvent*)event; +- (void)mouseUp:(NSEvent*)event; +- (void)mouseDragged:(NSEvent*)event; +- (void)mouseMoved:(NSEvent*)event; +- (void)rightMouseDown:(NSEvent*)event; +- (void)rightMouseUp:(NSEvent*)event; +- (void)rightMouseDragged:(NSEvent*)event; +- (void)otherMouseDown:(NSEvent*)event; +- (void)otherMouseUp:(NSEvent*)event; +- (void)otherMouseDragged:(NSEvent*)event; +- (void)setRubberband:(NSRect)rect; +- (void)removeRubberband; +- (const char*)convertKeyEvent:(NSEvent*)event; +- (void)keyDown:(NSEvent*)event; +- (void)keyUp:(NSEvent*)event; +- (void)scrollWheel:(NSEvent *)event; +- (BOOL)acceptsFirstResponder; +//- (void)flagsChanged:(NSEvent*)event; +@end + +@interface ScrollableButton : NSButton +{ + SEL scrollWheelUpAction; + SEL scrollWheelDownAction; +} +- (void)setScrollWheelUpAction:(SEL)action; +- (void)setScrollWheelDownAction:(SEL)action; +- (void)scrollWheel:(NSEvent *)event; +@end + +@interface MenuItem: NSMenuItem +{ int index; +} ++ (MenuItem*)menuItemWithTitle:(NSString*)title; ++ (MenuItem*)menuItemSelectAll; ++ (MenuItem*)menuItemInvertAll; ++ (MenuItem*)menuItemForAxis:(int)i; +- (void)toggle:(id)sender; +- (void)selectAll:(id)sender; +- (void)invertAll:(id)sender; +- (int)index; +@end + +/* ---------------------------- Python classes ---------------------------- */ + +static CGFloat _get_device_scale(CGContextRef cr) +{ + CGSize pixelSize = CGContextConvertSizeToDeviceSpace(cr, CGSizeMake(1, 1)); + return pixelSize.width; +} + +typedef struct { + PyObject_HEAD + View* view; +} FigureCanvas; + +static PyObject* +FigureCanvas_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + FigureCanvas *self = (FigureCanvas*)type->tp_alloc(type, 0); + if (!self) return NULL; + self->view = [View alloc]; + return (PyObject*)self; +} + +static int +FigureCanvas_init(FigureCanvas *self, PyObject *args, PyObject *kwds) +{ + int width; + int height; + if(!self->view) + { + PyErr_SetString(PyExc_RuntimeError, "NSView* is NULL"); + return -1; + } + + if(!PyArg_ParseTuple(args, "ii", &width, &height)) return -1; + + NSRect rect = NSMakeRect(0.0, 0.0, width, height); + self->view = [self->view initWithFrame: rect]; + [self->view setCanvas: (PyObject*)self]; + return 0; +} + +static void +FigureCanvas_dealloc(FigureCanvas* self) +{ + if (self->view) + { + [self->view setCanvas: NULL]; + [self->view release]; + } + Py_TYPE(self)->tp_free((PyObject*)self); +} + +static PyObject* +FigureCanvas_repr(FigureCanvas* self) +{ +#if PY3K + return PyUnicode_FromFormat("FigureCanvas object %p wrapping NSView %p", + (void*)self, (void*)(self->view)); +#else + return PyString_FromFormat("FigureCanvas object %p wrapping NSView %p", + (void*)self, (void*)(self->view)); +#endif +} + +static PyObject* +FigureCanvas_draw(FigureCanvas* self) +{ + View* view = self->view; + + if(view) /* The figure may have been closed already */ + { + /* Whereas drawRect creates its own autorelease pool, apparently + * [view display] also needs one. Create and release it here. */ + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + [view display]; + [pool release]; + } + + Py_RETURN_NONE; +} + +static PyObject* +FigureCanvas_invalidate(FigureCanvas* self) +{ + View* view = self->view; + if(!view) + { + PyErr_SetString(PyExc_RuntimeError, "NSView* is NULL"); + return NULL; + } + [view setNeedsDisplay: YES]; + Py_RETURN_NONE; +} + +static PyObject* +FigureCanvas_flush_events(FigureCanvas* self) +{ + View* view = self->view; + if(!view) + { + PyErr_SetString(PyExc_RuntimeError, "NSView* is NULL"); + return NULL; + } + [view displayIfNeeded]; + Py_RETURN_NONE; +} + +static PyObject* +FigureCanvas_set_rubberband(FigureCanvas* self, PyObject *args) +{ + View* view = self->view; + int x0, y0, x1, y1; + NSRect rubberband; + if(!view) + { + PyErr_SetString(PyExc_RuntimeError, "NSView* is NULL"); + return NULL; + } + if(!PyArg_ParseTuple(args, "iiii", &x0, &y0, &x1, &y1)) return NULL; + + x0 /= view->device_scale; + x1 /= view->device_scale; + y0 /= view->device_scale; + y1 /= view->device_scale; + + if (x1 > x0) + { + rubberband.origin.x = x0; + rubberband.size.width = x1 - x0; + } + else + { + rubberband.origin.x = x1; + rubberband.size.width = x0 - x1; + } + if (y1 > y0) + { + rubberband.origin.y = y0; + rubberband.size.height = y1 - y0; + } + else + { + rubberband.origin.y = y1; + rubberband.size.height = y0 - y1; + } + + [view setRubberband: rubberband]; + Py_RETURN_NONE; +} + +static PyObject* +FigureCanvas_remove_rubberband(FigureCanvas* self) +{ + View* view = self->view; + if(!view) + { + PyErr_SetString(PyExc_RuntimeError, "NSView* is NULL"); + return NULL; + } + [view removeRubberband]; + Py_RETURN_NONE; +} + +static NSImage* _read_ppm_image(PyObject* obj) +{ + int width; + int height; + const char* data; + int n; + int i; + NSBitmapImageRep* bitmap; + unsigned char* bitmapdata; + + if (!obj) return NULL; + if (!PyTuple_Check(obj)) return NULL; + if (!PyArg_ParseTuple(obj, "iit#", &width, &height, &data, &n)) return NULL; + if (width*height*3 != n) return NULL; /* RGB image uses 3 colors / pixel */ + + bitmap = [[NSBitmapImageRep alloc] + initWithBitmapDataPlanes: NULL + pixelsWide: width + pixelsHigh: height + bitsPerSample: 8 + samplesPerPixel: 3 + hasAlpha: NO + isPlanar: NO + colorSpaceName: NSDeviceRGBColorSpace + bitmapFormat: 0 + bytesPerRow: width*3 + bitsPerPixel: 24]; + if (!bitmap) return NULL; + bitmapdata = [bitmap bitmapData]; + for (i = 0; i < n; i++) bitmapdata[i] = data[i]; + + NSSize size = NSMakeSize(width, height); + NSImage* image = [[NSImage alloc] initWithSize: size]; + if (image) [image addRepresentation: bitmap]; + + [bitmap release]; + + return image; +} + +static PyObject* +FigureCanvas_start_event_loop(FigureCanvas* self, PyObject* args, PyObject* keywords) +{ + float timeout = 0.0; + + static char* kwlist[] = {"timeout", NULL}; + if(!PyArg_ParseTupleAndKeywords(args, keywords, "f", kwlist, &timeout)) + return NULL; + + int error; + int interrupted = 0; + int channel[2]; + CFSocketRef sigint_socket = NULL; + PyOS_sighandler_t py_sigint_handler = NULL; + + CFRunLoopRef runloop = CFRunLoopGetCurrent(); + + error = pipe(channel); + if (error==0) + { + CFSocketContext context = {0, NULL, NULL, NULL, NULL}; + fcntl(channel[1], F_SETFL, O_WRONLY | O_NONBLOCK); + + context.info = &interrupted; + sigint_socket = CFSocketCreateWithNative(kCFAllocatorDefault, + channel[0], + kCFSocketReadCallBack, + _sigint_callback, + &context); + if (sigint_socket) + { + CFRunLoopSourceRef source; + source = CFSocketCreateRunLoopSource(kCFAllocatorDefault, + sigint_socket, + 0); + CFRelease(sigint_socket); + if (source) + { + CFRunLoopAddSource(runloop, source, kCFRunLoopDefaultMode); + CFRelease(source); + sigint_fd = channel[1]; + py_sigint_handler = PyOS_setsig(SIGINT, _sigint_handler); + } + } + else + close(channel[0]); + } + + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + NSDate* date = + (timeout > 0.0) ? [NSDate dateWithTimeIntervalSinceNow: timeout] + : [NSDate distantFuture]; + while (true) + { NSEvent* event = [NSApp nextEventMatchingMask: NSAnyEventMask + untilDate: date + inMode: NSDefaultRunLoopMode + dequeue: YES]; + if (!event || [event type]==NSApplicationDefined) break; + [NSApp sendEvent: event]; + } + [pool release]; + + if (py_sigint_handler) PyOS_setsig(SIGINT, py_sigint_handler); + + if (sigint_socket) CFSocketInvalidate(sigint_socket); + if (error==0) close(channel[1]); + if (interrupted) raise(SIGINT); + + Py_RETURN_NONE; +} + +static PyObject* +FigureCanvas_stop_event_loop(FigureCanvas* self) +{ + NSEvent* event = [NSEvent otherEventWithType: NSApplicationDefined + location: NSZeroPoint + modifierFlags: 0 + timestamp: 0.0 + windowNumber: 0 + context: nil + subtype: STOP_EVENT_LOOP + data1: 0 + data2: 0]; + [NSApp postEvent: event atStart: true]; + Py_RETURN_NONE; +} + +static PyMethodDef FigureCanvas_methods[] = { + {"draw", + (PyCFunction)FigureCanvas_draw, + METH_NOARGS, + "Draws the canvas." + }, + {"invalidate", + (PyCFunction)FigureCanvas_invalidate, + METH_NOARGS, + "Invalidates the canvas." + }, + {"flush_events", + (PyCFunction)FigureCanvas_flush_events, + METH_NOARGS, + "Flush the GUI events for the figure." + }, + {"set_rubberband", + (PyCFunction)FigureCanvas_set_rubberband, + METH_VARARGS, + "Specifies a new rubberband rectangle and invalidates it." + }, + {"remove_rubberband", + (PyCFunction)FigureCanvas_remove_rubberband, + METH_NOARGS, + "Removes the current rubberband rectangle." + }, + {"start_event_loop", + (PyCFunction)FigureCanvas_start_event_loop, + METH_KEYWORDS | METH_VARARGS, + "Runs the event loop until the timeout or until stop_event_loop is called.\n", + }, + {"stop_event_loop", + (PyCFunction)FigureCanvas_stop_event_loop, + METH_NOARGS, + "Stops the event loop that was started by start_event_loop.\n", + }, + {NULL} /* Sentinel */ +}; + +static char FigureCanvas_doc[] = +"A FigureCanvas object wraps a Cocoa NSView object.\n"; + +static PyTypeObject FigureCanvasType = { + PyVarObject_HEAD_INIT(NULL, 0) + "_macosx.FigureCanvas", /*tp_name*/ + sizeof(FigureCanvas), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)FigureCanvas_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + (reprfunc)FigureCanvas_repr, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ + FigureCanvas_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + FigureCanvas_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)FigureCanvas_init, /* tp_init */ + 0, /* tp_alloc */ + FigureCanvas_new, /* tp_new */ +}; + +typedef struct { + PyObject_HEAD + Window* window; +} FigureManager; + +static PyObject* +FigureManager_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + Window* window = [Window alloc]; + if (!window) return NULL; + FigureManager *self = (FigureManager*)type->tp_alloc(type, 0); + if (!self) + { + [window release]; + return NULL; + } + self->window = window; + ++FigureWindowCount; + return (PyObject*)self; +} + +static int +FigureManager_init(FigureManager *self, PyObject *args, PyObject *kwds) +{ + NSRect rect; + Window* window; + View* view; + const char* title; + PyObject* size; + int width, height; + PyObject* obj; + FigureCanvas* canvas; + + if(!self->window) + { + PyErr_SetString(PyExc_RuntimeError, "NSWindow* is NULL"); + return -1; + } + + if(!PyArg_ParseTuple(args, "Os", &obj, &title)) return -1; + + canvas = (FigureCanvas*)obj; + view = canvas->view; + if (!view) /* Something really weird going on */ + { + PyErr_SetString(PyExc_RuntimeError, "NSView* is NULL"); + return -1; + } + + size = PyObject_CallMethod(obj, "get_width_height", ""); + if(!size) return -1; + if(!PyArg_ParseTuple(size, "ii", &width, &height)) + { Py_DECREF(size); + return -1; + } + Py_DECREF(size); + + rect.origin.x = 100; + rect.origin.y = 350; + rect.size.height = height; + rect.size.width = width; + + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + self->window = [self->window initWithContentRect: rect + styleMask: NSTitledWindowMask + | NSClosableWindowMask + | NSResizableWindowMask + | NSMiniaturizableWindowMask + backing: NSBackingStoreBuffered + defer: YES + withManager: (PyObject*)self]; + window = self->window; + [window setTitle: [NSString stringWithCString: title + encoding: NSASCIIStringEncoding]]; + + [window setAcceptsMouseMovedEvents: YES]; + [window setDelegate: view]; + [window makeFirstResponder: view]; + [[window contentView] addSubview: view]; + + [pool release]; + return 0; +} + +static PyObject* +FigureManager_repr(FigureManager* self) +{ +#if PY3K + return PyUnicode_FromFormat("FigureManager object %p wrapping NSWindow %p", + (void*) self, (void*)(self->window)); +#else + return PyString_FromFormat("FigureManager object %p wrapping NSWindow %p", + (void*) self, (void*)(self->window)); +#endif +} + +static void +FigureManager_dealloc(FigureManager* self) +{ + Window* window = self->window; + if(window) + { + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + [window close]; + [pool release]; + } + Py_TYPE(self)->tp_free((PyObject*)self); +} + +static PyObject* +FigureManager_show(FigureManager* self) +{ + Window* window = self->window; + if(window) + { + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + [window makeKeyAndOrderFront: nil]; + [window orderFrontRegardless]; + [pool release]; + } + Py_RETURN_NONE; +} + +static PyObject* +FigureManager_destroy(FigureManager* self) +{ + Window* window = self->window; + if(window) + { + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + [window close]; + [pool release]; + self->window = NULL; + } + Py_RETURN_NONE; +} + +static PyObject* +FigureManager_set_window_title(FigureManager* self, + PyObject *args, PyObject *kwds) +{ + char* title; + if(!PyArg_ParseTuple(args, "es", "UTF-8", &title)) + return NULL; + + Window* window = self->window; + if(window) + { + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + NSString* ns_title = [[[NSString alloc] + initWithCString: title + encoding: NSUTF8StringEncoding] autorelease]; + [window setTitle: ns_title]; + [pool release]; + } + PyMem_Free(title); + Py_RETURN_NONE; +} + +static PyObject* +FigureManager_get_window_title(FigureManager* self) +{ + Window* window = self->window; + PyObject* result = NULL; + if(window) + { + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + NSString* title = [window title]; + if (title) { + const char* cTitle = [title UTF8String]; + result = PyUnicode_FromString(cTitle); + } + [pool release]; + } + if (result) { + return result; + } else { + Py_RETURN_NONE; + } +} + +static PyMethodDef FigureManager_methods[] = { + {"show", + (PyCFunction)FigureManager_show, + METH_NOARGS, + "Shows the window associated with the figure manager." + }, + {"destroy", + (PyCFunction)FigureManager_destroy, + METH_NOARGS, + "Closes the window associated with the figure manager." + }, + {"set_window_title", + (PyCFunction)FigureManager_set_window_title, + METH_VARARGS, + "Sets the title of the window associated with the figure manager." + }, + {"get_window_title", + (PyCFunction)FigureManager_get_window_title, + METH_NOARGS, + "Returns the title of the window associated with the figure manager." + }, + {NULL} /* Sentinel */ +}; + +static char FigureManager_doc[] = +"A FigureManager object wraps a Cocoa NSWindow object.\n"; + +static PyTypeObject FigureManagerType = { + PyVarObject_HEAD_INIT(NULL, 0) + "_macosx.FigureManager", /*tp_name*/ + sizeof(FigureManager), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)FigureManager_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + (reprfunc)FigureManager_repr, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ + FigureManager_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + FigureManager_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)FigureManager_init, /* tp_init */ + 0, /* tp_alloc */ + FigureManager_new, /* tp_new */ +}; + +@interface NavigationToolbarHandler : NSObject +{ PyObject* toolbar; +} +- (NavigationToolbarHandler*)initWithToolbar:(PyObject*)toolbar; +-(void)left:(id)sender; +-(void)right:(id)sender; +-(void)up:(id)sender; +-(void)down:(id)sender; +-(void)zoominx:(id)sender; +-(void)zoominy:(id)sender; +-(void)zoomoutx:(id)sender; +-(void)zoomouty:(id)sender; +@end + +typedef struct { + PyObject_HEAD + NSPopUpButton* menu; + NavigationToolbarHandler* handler; +} NavigationToolbar; + +@implementation NavigationToolbarHandler +- (NavigationToolbarHandler*)initWithToolbar:(PyObject*)theToolbar +{ [self init]; + toolbar = theToolbar; + return self; +} + +-(void)left:(id)sender +{ PyObject* result; + PyGILState_STATE gstate; + gstate = PyGILState_Ensure(); + result = PyObject_CallMethod(toolbar, "panx", "i", -1); + if(result) + Py_DECREF(result); + else + PyErr_Print(); + PyGILState_Release(gstate); +} + +-(void)right:(id)sender +{ PyObject* result; + PyGILState_STATE gstate; + gstate = PyGILState_Ensure(); + result = PyObject_CallMethod(toolbar, "panx", "i", 1); + if(result) + Py_DECREF(result); + else + PyErr_Print(); + PyGILState_Release(gstate); +} + +-(void)up:(id)sender +{ PyObject* result; + PyGILState_STATE gstate; + gstate = PyGILState_Ensure(); + result = PyObject_CallMethod(toolbar, "pany", "i", 1); + if(result) + Py_DECREF(result); + else + PyErr_Print(); + PyGILState_Release(gstate); +} + +-(void)down:(id)sender +{ PyObject* result; + PyGILState_STATE gstate; + gstate = PyGILState_Ensure(); + result = PyObject_CallMethod(toolbar, "pany", "i", -1); + if(result) + Py_DECREF(result); + else + PyErr_Print(); + PyGILState_Release(gstate); +} + +-(void)zoominx:(id)sender +{ PyObject* result; + PyGILState_STATE gstate; + gstate = PyGILState_Ensure(); + result = PyObject_CallMethod(toolbar, "zoomx", "i", 1); + if(result) + Py_DECREF(result); + else + PyErr_Print(); + PyGILState_Release(gstate); +} + +-(void)zoomoutx:(id)sender +{ PyObject* result; + PyGILState_STATE gstate; + gstate = PyGILState_Ensure(); + result = PyObject_CallMethod(toolbar, "zoomx", "i", -1); + if(result) + Py_DECREF(result); + else + PyErr_Print(); + PyGILState_Release(gstate); +} + +-(void)zoominy:(id)sender +{ PyObject* result; + PyGILState_STATE gstate; + gstate = PyGILState_Ensure(); + result = PyObject_CallMethod(toolbar, "zoomy", "i", 1); + if(result) + Py_DECREF(result); + else + PyErr_Print(); + PyGILState_Release(gstate); +} + +-(void)zoomouty:(id)sender +{ PyObject* result; + PyGILState_STATE gstate; + gstate = PyGILState_Ensure(); + result = PyObject_CallMethod(toolbar, "zoomy", "i", -1); + if(result) + Py_DECREF(result); + else + PyErr_Print(); + PyGILState_Release(gstate); +} + +-(void)save_figure:(id)sender +{ PyObject* result; + PyGILState_STATE gstate; + gstate = PyGILState_Ensure(); + result = PyObject_CallMethod(toolbar, "save_figure", ""); + if(result) + Py_DECREF(result); + else + PyErr_Print(); + PyGILState_Release(gstate); +} +@end + +static PyObject* +NavigationToolbar_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + NavigationToolbarHandler* handler = [NavigationToolbarHandler alloc]; + if (!handler) return NULL; + NavigationToolbar *self = (NavigationToolbar*)type->tp_alloc(type, 0); + if (!self) + { [handler release]; + return NULL; + } + self->handler = handler; + return (PyObject*)self; +} + +static int +NavigationToolbar_init(NavigationToolbar *self, PyObject *args, PyObject *kwds) +{ + int i; + NSRect rect; + + const float smallgap = 2; + const float biggap = 10; + const int height = 32; + + PyObject* images; + PyObject* obj; + + FigureCanvas* canvas; + View* view; + + obj = PyObject_GetAttrString((PyObject*)self, "canvas"); + if (obj==NULL) + { + PyErr_SetString(PyExc_AttributeError, "Attempt to install toolbar for NULL canvas"); + return -1; + } + Py_DECREF(obj); /* Don't increase the reference count */ + if (!PyObject_IsInstance(obj, (PyObject*) &FigureCanvasType)) + { + PyErr_SetString(PyExc_TypeError, "Attempt to install toolbar for object that is not a FigureCanvas"); + return -1; + } + canvas = (FigureCanvas*)obj; + view = canvas->view; + if(!view) + { + PyErr_SetString(PyExc_RuntimeError, "NSView* is NULL"); + return -1; + } + + if(!PyArg_ParseTuple(args, "O", &images)) return -1; + if(!PyDict_Check(images)) return -1; + + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + NSRect bounds = [view bounds]; + NSWindow* window = [view window]; + + bounds.origin.y += height; + [view setFrame: bounds]; + + bounds.size.height += height; + [window setContentSize: bounds.size]; + + char* imagenames[9] = {"stock_left", + "stock_right", + "stock_zoom-in", + "stock_zoom-out", + "stock_up", + "stock_down", + "stock_zoom-in", + "stock_zoom-out", + "stock_save_as"}; + + NSString* tooltips[9] = { + @"Pan left with click or wheel mouse (bidirectional)", + @"Pan right with click or wheel mouse (bidirectional)", + @"Zoom In X (shrink the x axis limits) with click or wheel mouse (bidirectional)", + @"Zoom Out X (expand the x axis limits) with click or wheel mouse (bidirectional)", + @"Pan up with click or wheel mouse (bidirectional)", + @"Pan down with click or wheel mouse (bidirectional)", + @"Zoom in Y (shrink the y axis limits) with click or wheel mouse (bidirectional)", + @"Zoom Out Y (expand the y axis limits) with click or wheel mouse (bidirectional)", + @"Save the figure"}; + + SEL actions[9] = {@selector(left:), + @selector(right:), + @selector(zoominx:), + @selector(zoomoutx:), + @selector(up:), + @selector(down:), + @selector(zoominy:), + @selector(zoomouty:), + @selector(save_figure:)}; + + SEL scroll_actions[9][2] = {{@selector(left:), @selector(right:)}, + {@selector(left:), @selector(right:)}, + {@selector(zoominx:), @selector(zoomoutx:)}, + {@selector(zoominx:), @selector(zoomoutx:)}, + {@selector(up:), @selector(down:)}, + {@selector(up:), @selector(down:)}, + {@selector(zoominy:), @selector(zoomouty:)}, + {@selector(zoominy:), @selector(zoomouty:)}, + {nil,nil}, + }; + + + rect.size.width = 120; + rect.size.height = 24; + rect.origin.x = biggap; + rect.origin.y = 0.5*(height - rect.size.height); + self->menu = [[NSPopUpButton alloc] initWithFrame: rect + pullsDown: YES]; + [self->menu setAutoenablesItems: NO]; + [[window contentView] addSubview: self->menu]; + [self->menu release]; + rect.origin.x += rect.size.width + biggap; + rect.size.width = 24; + + self->handler = [self->handler initWithToolbar: (PyObject*)self]; + for (i = 0; i < 9; i++) + { + NSButton* button; + SEL scrollWheelUpAction = scroll_actions[i][0]; + SEL scrollWheelDownAction = scroll_actions[i][1]; + if (scrollWheelUpAction && scrollWheelDownAction) + { + ScrollableButton* scrollable_button = [ScrollableButton alloc]; + [scrollable_button initWithFrame: rect]; + [scrollable_button setScrollWheelUpAction: scrollWheelUpAction]; + [scrollable_button setScrollWheelDownAction: scrollWheelDownAction]; + button = (NSButton*)scrollable_button; + } + else + { + button = [NSButton alloc]; + [button initWithFrame: rect]; + } + PyObject* imagedata = PyDict_GetItemString(images, imagenames[i]); + NSImage* image = _read_ppm_image(imagedata); + [button setBezelStyle: NSShadowlessSquareBezelStyle]; + [button setButtonType: NSMomentaryLightButton]; + if(image) + { + [button setImage: image]; + [image release]; + } + [button setToolTip: tooltips[i]]; + [button setTarget: self->handler]; + [button setAction: actions[i]]; + [[window contentView] addSubview: button]; + [button release]; + rect.origin.x += rect.size.width + smallgap; + } + [[window contentView] display]; + [pool release]; + + return 0; +} + +static void +NavigationToolbar_dealloc(NavigationToolbar *self) +{ + [self->handler release]; + Py_TYPE(self)->tp_free((PyObject*)self); +} + +static PyObject* +NavigationToolbar_repr(NavigationToolbar* self) +{ +#if PY3K + return PyUnicode_FromFormat("NavigationToolbar object %p", (void*)self); +#else + return PyString_FromFormat("NavigationToolbar object %p", (void*)self); +#endif +} + +static char NavigationToolbar_doc[] = +"NavigationToolbar\n"; + +static PyObject* +NavigationToolbar_update (NavigationToolbar* self) +{ + int n; + NSPopUpButton* button = self->menu; + if (!button) + { + PyErr_SetString(PyExc_RuntimeError, "Menu button is NULL"); + return NULL; + } + + PyObject* canvas = PyObject_GetAttrString((PyObject*)self, "canvas"); + if (canvas==NULL) + { + PyErr_SetString(PyExc_AttributeError, "Failed to find canvas"); + return NULL; + } + Py_DECREF(canvas); /* Don't keep a reference here */ + PyObject* figure = PyObject_GetAttrString(canvas, "figure"); + if (figure==NULL) + { + PyErr_SetString(PyExc_AttributeError, "Failed to find figure"); + return NULL; + } + Py_DECREF(figure); /* Don't keep a reference here */ + PyObject* axes = PyObject_GetAttrString(figure, "axes"); + if (axes==NULL) + { + PyErr_SetString(PyExc_AttributeError, "Failed to find figure axes"); + return NULL; + } + Py_DECREF(axes); /* Don't keep a reference here */ + if (!PyList_Check(axes)) + { + PyErr_SetString(PyExc_TypeError, "Figure axes is not a list"); + return NULL; + } + n = PyList_GET_SIZE(axes); + + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + [button removeAllItems]; + + NSMenu* menu = [button menu]; + [menu addItem: [MenuItem menuItemWithTitle: @"Axes"]]; + + if (n==0) + { + [button setEnabled: NO]; + } + else + { + int i; + [menu addItem: [MenuItem menuItemSelectAll]]; + [menu addItem: [MenuItem menuItemInvertAll]]; + [menu addItem: [NSMenuItem separatorItem]]; + for (i = 0; i < n; i++) + { + [menu addItem: [MenuItem menuItemForAxis: i]]; + } + [button setEnabled: YES]; + } + [pool release]; + Py_RETURN_NONE; +} + +static PyObject* +NavigationToolbar_get_active (NavigationToolbar* self) +{ + NSPopUpButton* button = self->menu; + if (!button) + { + PyErr_SetString(PyExc_RuntimeError, "Menu button is NULL"); + return NULL; + } + NSMenu* menu = [button menu]; + NSArray* items = [menu itemArray]; + size_t n = [items count]; + int* states = calloc(n, sizeof(int)); + if (!states) + { + PyErr_SetString(PyExc_RuntimeError, "calloc failed"); + return NULL; + } + int i; + unsigned int m = 0; + NSEnumerator* enumerator = [items objectEnumerator]; + MenuItem* item; + while ((item = [enumerator nextObject])) + { + if ([item isSeparatorItem]) continue; + i = [item index]; + if (i < 0) continue; + if ([item state]==NSOnState) + { + states[i] = 1; + m++; + } + } + Py_ssize_t list_index = 0; + PyObject* list = PyList_New(m); + + size_t state_index; + for (state_index = 0; state_index < n; state_index++) + { + if(states[state_index]==1) + { + PyList_SET_ITEM(list, list_index++, PyLong_FromSize_t(state_index)); + } + } + free(states); + return list; +} + +static PyMethodDef NavigationToolbar_methods[] = { + {"update", + (PyCFunction)NavigationToolbar_update, + METH_NOARGS, + "Updates the toolbar menu." + }, + {"get_active", + (PyCFunction)NavigationToolbar_get_active, + METH_NOARGS, + "Returns a list of integers identifying which items in the menu are selected." + }, + {NULL} /* Sentinel */ +}; + +static PyTypeObject NavigationToolbarType = { + PyVarObject_HEAD_INIT(NULL, 0) + "_macosx.NavigationToolbar", /*tp_name*/ + sizeof(NavigationToolbar), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)NavigationToolbar_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + (reprfunc)NavigationToolbar_repr, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ + NavigationToolbar_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + NavigationToolbar_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)NavigationToolbar_init, /* tp_init */ + 0, /* tp_alloc */ + NavigationToolbar_new, /* tp_new */ +}; + +@interface NavigationToolbar2Handler : NSObject +{ PyObject* toolbar; + NSButton* panbutton; + NSButton* zoombutton; +} +- (NavigationToolbar2Handler*)initWithToolbar:(PyObject*)toolbar; +- (void)installCallbacks:(SEL[7])actions forButtons: (NSButton*[7])buttons; +- (void)home:(id)sender; +- (void)back:(id)sender; +- (void)forward:(id)sender; +- (void)pan:(id)sender; +- (void)zoom:(id)sender; +- (void)configure_subplots:(id)sender; +- (void)save_figure:(id)sender; +@end + +typedef struct { + PyObject_HEAD + NSPopUpButton* menu; + NSText* messagebox; + NavigationToolbar2Handler* handler; +} NavigationToolbar2; + +@implementation NavigationToolbar2Handler +- (NavigationToolbar2Handler*)initWithToolbar:(PyObject*)theToolbar +{ [self init]; + toolbar = theToolbar; + return self; +} + +- (void)installCallbacks:(SEL[7])actions forButtons: (NSButton*[7])buttons +{ + int i; + for (i = 0; i < 7; i++) + { + SEL action = actions[i]; + NSButton* button = buttons[i]; + [button setTarget: self]; + [button setAction: action]; + if (action==@selector(pan:)) panbutton = button; + if (action==@selector(zoom:)) zoombutton = button; + } +} + +-(void)home:(id)sender +{ PyObject* result; + PyGILState_STATE gstate; + gstate = PyGILState_Ensure(); + result = PyObject_CallMethod(toolbar, "home", ""); + if(result) + Py_DECREF(result); + else + PyErr_Print(); + PyGILState_Release(gstate); +} + +-(void)back:(id)sender +{ PyObject* result; + PyGILState_STATE gstate; + gstate = PyGILState_Ensure(); + result = PyObject_CallMethod(toolbar, "back", ""); + if(result) + Py_DECREF(result); + else + PyErr_Print(); + PyGILState_Release(gstate); +} + +-(void)forward:(id)sender +{ PyObject* result; + PyGILState_STATE gstate; + gstate = PyGILState_Ensure(); + result = PyObject_CallMethod(toolbar, "forward", ""); + if(result) + Py_DECREF(result); + else + PyErr_Print(); + PyGILState_Release(gstate); +} + +-(void)pan:(id)sender +{ PyObject* result; + PyGILState_STATE gstate; + if ([sender state]) + { + if (zoombutton) [zoombutton setState: NO]; + } + gstate = PyGILState_Ensure(); + result = PyObject_CallMethod(toolbar, "pan", ""); + if(result) + Py_DECREF(result); + else + PyErr_Print(); + PyGILState_Release(gstate); +} + +-(void)zoom:(id)sender +{ PyObject* result; + PyGILState_STATE gstate; + if ([sender state]) + { + if (panbutton) [panbutton setState: NO]; + } + gstate = PyGILState_Ensure(); + result = PyObject_CallMethod(toolbar, "zoom", ""); + if(result) + Py_DECREF(result); + else + PyErr_Print(); + PyGILState_Release(gstate); +} + +-(void)configure_subplots:(id)sender +{ PyObject* canvas; + View* view; + PyObject* size; + NSRect rect; + int width, height; + + rect.origin.x = 100; + rect.origin.y = 350; + PyGILState_STATE gstate = PyGILState_Ensure(); + PyObject* master = PyObject_GetAttrString(toolbar, "canvas"); + if (master==nil) + { + PyErr_Print(); + PyGILState_Release(gstate); + return; + } + canvas = PyObject_CallMethod(toolbar, "prepare_configure_subplots", ""); + if(!canvas) + { + PyErr_Print(); + Py_DECREF(master); + PyGILState_Release(gstate); + return; + } + + view = ((FigureCanvas*)canvas)->view; + if (!view) /* Something really weird going on */ + { + PyErr_SetString(PyExc_RuntimeError, "NSView* is NULL"); + PyErr_Print(); + Py_DECREF(canvas); + Py_DECREF(master); + PyGILState_Release(gstate); + return; + } + + size = PyObject_CallMethod(canvas, "get_width_height", ""); + Py_DECREF(canvas); + if(!size) + { + PyErr_Print(); + Py_DECREF(master); + PyGILState_Release(gstate); + return; + } + + int ok = PyArg_ParseTuple(size, "ii", &width, &height); + Py_DECREF(size); + if (!ok) + { + PyErr_Print(); + Py_DECREF(master); + PyGILState_Release(gstate); + return; + } + + NSWindow* mw = [((FigureCanvas*)master)->view window]; + Py_DECREF(master); + PyGILState_Release(gstate); + + rect.size.width = width; + rect.size.height = height; + + ToolWindow* window = [ [ToolWindow alloc] initWithContentRect: rect + master: mw]; + [window setContentView: view]; + [view release]; + [window makeKeyAndOrderFront: nil]; +} + +-(void)save_figure:(id)sender +{ PyObject* result; + PyGILState_STATE gstate; + gstate = PyGILState_Ensure(); + result = PyObject_CallMethod(toolbar, "save_figure", ""); + if(result) + Py_DECREF(result); + else + PyErr_Print(); + PyGILState_Release(gstate); +} +@end + +static PyObject* +NavigationToolbar2_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +{ + NavigationToolbar2Handler* handler = [NavigationToolbar2Handler alloc]; + if (!handler) return NULL; + NavigationToolbar2 *self = (NavigationToolbar2*)type->tp_alloc(type, 0); + if (!self) + { + [handler release]; + return NULL; + } + self->handler = handler; + return (PyObject*)self; +} + +static int +NavigationToolbar2_init(NavigationToolbar2 *self, PyObject *args, PyObject *kwds) +{ + PyObject* obj; + FigureCanvas* canvas; + View* view; + + int i; + NSRect rect; + NSSize size; + NSSize scale; + + const float gap = 2; + const int height = 36; + const int imagesize = 24; + + const char* basedir; + + obj = PyObject_GetAttrString((PyObject*)self, "canvas"); + if (obj==NULL) + { + PyErr_SetString(PyExc_AttributeError, "Attempt to install toolbar for NULL canvas"); + return -1; + } + Py_DECREF(obj); /* Don't increase the reference count */ + if (!PyObject_IsInstance(obj, (PyObject*) &FigureCanvasType)) + { + PyErr_SetString(PyExc_TypeError, "Attempt to install toolbar for object that is not a FigureCanvas"); + return -1; + } + canvas = (FigureCanvas*)obj; + view = canvas->view; + if(!view) + { + PyErr_SetString(PyExc_RuntimeError, "NSView* is NULL"); + return -1; + } + + if(!PyArg_ParseTuple(args, "s", &basedir)) return -1; + + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + NSRect bounds = [view bounds]; + NSWindow* window = [view window]; + + bounds.origin.y += height; + [view setFrame: bounds]; + + bounds.size.height += height; + [window setContentSize: bounds.size]; + + NSString* dir = [NSString stringWithCString: basedir + encoding: NSASCIIStringEncoding]; + + NSButton* buttons[7]; + + NSString* images[7] = {@"home.pdf", + @"back.pdf", + @"forward.pdf", + @"move.pdf", + @"zoom_to_rect.pdf", + @"subplots.pdf", + @"filesave.pdf"}; + + NSString* tooltips[7] = {@"Reset original view", + @"Back to previous view", + @"Forward to next view", + @"Pan axes with left mouse, zoom with right", + @"Zoom to rectangle", + @"Configure subplots", + @"Save the figure"}; + + SEL actions[7] = {@selector(home:), + @selector(back:), + @selector(forward:), + @selector(pan:), + @selector(zoom:), + @selector(configure_subplots:), + @selector(save_figure:)}; + + NSButtonType buttontypes[7] = {NSMomentaryLightButton, + NSMomentaryLightButton, + NSMomentaryLightButton, + NSPushOnPushOffButton, + NSPushOnPushOffButton, + NSMomentaryLightButton, + NSMomentaryLightButton}; + + rect.origin.x = 0; + rect.origin.y = 0; + rect.size.width = imagesize; + rect.size.height = imagesize; +#ifdef COMPILING_FOR_10_7 + rect = [window convertRectToBacking: rect]; +#endif + size = rect.size; + scale.width = imagesize / size.width; + scale.height = imagesize / size.height; + + rect.size.width = 32; + rect.size.height = 32; + rect.origin.x = gap; + rect.origin.y = 0.5*(height - rect.size.height); + + for (i = 0; i < 7; i++) + { + NSString* filename = [dir stringByAppendingPathComponent: images[i]]; + NSImage* image = [[NSImage alloc] initWithContentsOfFile: filename]; + buttons[i] = [[NSButton alloc] initWithFrame: rect]; + [image setSize: size]; + [buttons[i] setBezelStyle: NSShadowlessSquareBezelStyle]; + [buttons[i] setButtonType: buttontypes[i]]; + [buttons[i] setImage: image]; + [buttons[i] scaleUnitSquareToSize: scale]; + [buttons[i] setImagePosition: NSImageOnly]; + [buttons[i] setToolTip: tooltips[i]]; + [[window contentView] addSubview: buttons[i]]; + [buttons[i] release]; + [image release]; + rect.origin.x += rect.size.width + gap; + } + + self->handler = [self->handler initWithToolbar: (PyObject*)self]; + [self->handler installCallbacks: actions forButtons: buttons]; + + NSFont* font = [NSFont systemFontOfSize: 0.0]; + rect.size.width = 300; + rect.size.height = 0; + rect.origin.x += height; + NSText* messagebox = [[NSText alloc] initWithFrame: rect]; + [messagebox setFont: font]; + [messagebox setDrawsBackground: NO]; + [messagebox setSelectable: NO]; + /* if selectable, the messagebox can become first responder, + * which is not supposed to happen */ + rect = [messagebox frame]; + rect.origin.y = 0.5 * (height - rect.size.height); + [messagebox setFrameOrigin: rect.origin]; + [[window contentView] addSubview: messagebox]; + [messagebox release]; + [[window contentView] display]; + + [pool release]; + + self->messagebox = messagebox; + return 0; +} + +static void +NavigationToolbar2_dealloc(NavigationToolbar2 *self) +{ + [self->handler release]; + Py_TYPE(self)->tp_free((PyObject*)self); +} + +static PyObject* +NavigationToolbar2_repr(NavigationToolbar2* self) +{ +#if PY3K + return PyUnicode_FromFormat("NavigationToolbar2 object %p", (void*)self); +#else + return PyString_FromFormat("NavigationToolbar2 object %p", (void*)self); +#endif +} + +static char NavigationToolbar2_doc[] = +"NavigationToolbar2\n"; + +static PyObject* +NavigationToolbar2_set_message(NavigationToolbar2 *self, PyObject* args) +{ + const char* message; + +#if PY3K + if(!PyArg_ParseTuple(args, "y", &message)) return NULL; +#else + if(!PyArg_ParseTuple(args, "s", &message)) return NULL; +#endif + + NSText* messagebox = self->messagebox; + + if (messagebox) + { NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + NSString* text = [NSString stringWithUTF8String: message]; + [messagebox setString: text]; + [pool release]; + } + + Py_RETURN_NONE; +} + +static PyMethodDef NavigationToolbar2_methods[] = { + {"set_message", + (PyCFunction)NavigationToolbar2_set_message, + METH_VARARGS, + "Set the message to be displayed on the toolbar." + }, + {NULL} /* Sentinel */ +}; + +static PyTypeObject NavigationToolbar2Type = { + PyVarObject_HEAD_INIT(NULL, 0) + "_macosx.NavigationToolbar2", /*tp_name*/ + sizeof(NavigationToolbar2), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)NavigationToolbar2_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + (reprfunc)NavigationToolbar2_repr, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ + NavigationToolbar2_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + NavigationToolbar2_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + (initproc)NavigationToolbar2_init, /* tp_init */ + 0, /* tp_alloc */ + NavigationToolbar2_new, /* tp_new */ +}; + +static PyObject* +choose_save_file(PyObject* unused, PyObject* args) +{ + int result; + const char* title; + char* default_filename; + if(!PyArg_ParseTuple(args, "ses", &title, "UTF-8", &default_filename)) + return NULL; + + NSSavePanel* panel = [NSSavePanel savePanel]; + [panel setTitle: [NSString stringWithCString: title + encoding: NSASCIIStringEncoding]]; + NSString* ns_default_filename = + [[NSString alloc] + initWithCString: default_filename + encoding: NSUTF8StringEncoding]; + PyMem_Free(default_filename); +#ifdef COMPILING_FOR_10_6 + [panel setNameFieldStringValue: ns_default_filename]; + result = [panel runModal]; +#else + result = [panel runModalForDirectory: nil file: ns_default_filename]; +#endif + [ns_default_filename release]; +#ifdef COMPILING_FOR_10_10 + if (result == NSModalResponseOK) +#else + if (result == NSOKButton) +#endif + { +#ifdef COMPILING_FOR_10_6 + NSURL* url = [panel URL]; + NSString* filename = [url path]; + if (!filename) { + PyErr_SetString(PyExc_RuntimeError, "Failed to obtain filename"); + return 0; + } +#else + NSString* filename = [panel filename]; +#endif + unsigned int n = [filename length]; + unichar* buffer = malloc(n*sizeof(unichar)); + [filename getCharacters: buffer]; +#if PY3K + PyObject* string = PyUnicode_FromKindAndData(PyUnicode_2BYTE_KIND, buffer, n); +#else + PyObject* string = PyUnicode_FromUnicode(buffer, n); +#endif + free(buffer); + return string; + } + Py_RETURN_NONE; +} + +static PyObject* +set_cursor(PyObject* unused, PyObject* args) +{ + int i; + if(!PyArg_ParseTuple(args, "i", &i)) return NULL; + switch (i) + { case 0: [[NSCursor pointingHandCursor] set]; break; + case 1: [[NSCursor arrowCursor] set]; break; + case 2: [[NSCursor crosshairCursor] set]; break; + case 3: [[NSCursor openHandCursor] set]; break; + /* OSX handles busy state itself so no need to set a cursor here */ + case 4: break; + default: return NULL; + } + Py_RETURN_NONE; +} + +@implementation WindowServerConnectionManager +static WindowServerConnectionManager *sharedWindowServerConnectionManager = nil; + ++ (WindowServerConnectionManager *)sharedManager +{ + if (sharedWindowServerConnectionManager == nil) + { + sharedWindowServerConnectionManager = [[super allocWithZone:NULL] init]; + } + return sharedWindowServerConnectionManager; +} + ++ (id)allocWithZone:(NSZone *)zone +{ + return [[self sharedManager] retain]; +} + ++ (id)copyWithZone:(NSZone *)zone +{ + return self; +} + ++ (id)retain +{ + return self; +} + +- (NSUInteger)retainCount +{ + return NSUIntegerMax; //denotes an object that cannot be released +} + +- (oneway void)release +{ + // Don't release a singleton object +} + +- (id)autorelease +{ + return self; +} + +- (void)launch:(NSNotification*)notification +{ + CFRunLoopRef runloop; + CFMachPortRef port; + CFRunLoopSourceRef source; + NSDictionary* dictionary = [notification userInfo]; + if (! [[dictionary valueForKey:@"NSApplicationName"] + isEqualToString:@"Python"]) + return; + NSNumber* psnLow = [dictionary valueForKey: @"NSApplicationProcessSerialNumberLow"]; + NSNumber* psnHigh = [dictionary valueForKey: @"NSApplicationProcessSerialNumberHigh"]; + ProcessSerialNumber psn; + psn.highLongOfPSN = [psnHigh intValue]; + psn.lowLongOfPSN = [psnLow intValue]; + runloop = CFRunLoopGetCurrent(); + port = CGEventTapCreateForPSN(&psn, + kCGHeadInsertEventTap, + kCGEventTapOptionListenOnly, + kCGEventMaskForAllEvents, + &_eventtap_callback, + runloop); + source = CFMachPortCreateRunLoopSource(kCFAllocatorDefault, + port, + 0); + CFRunLoopAddSource(runloop, source, kCFRunLoopDefaultMode); + CFRelease(port); +} +@end + +@implementation Window +- (Window*)initWithContentRect:(NSRect)rect styleMask:(unsigned int)mask backing:(NSBackingStoreType)bufferingType defer:(BOOL)deferCreation withManager: (PyObject*)theManager +{ + self = [super initWithContentRect: rect + styleMask: mask + backing: bufferingType + defer: deferCreation]; + manager = theManager; + Py_INCREF(manager); + return self; +} + +- (NSRect)constrainFrameRect:(NSRect)rect toScreen:(NSScreen*)screen +{ + /* Allow window sizes larger than the screen */ + NSRect suggested = [super constrainFrameRect: rect toScreen: screen]; + const CGFloat difference = rect.size.height - suggested.size.height; + suggested.origin.y -= difference; + suggested.size.height += difference; + return suggested; +} + +- (BOOL)closeButtonPressed +{ + PyObject* result; + PyGILState_STATE gstate; + gstate = PyGILState_Ensure(); + result = PyObject_CallMethod(manager, "close", ""); + if(result) + Py_DECREF(result); + else + PyErr_Print(); + PyGILState_Release(gstate); + return YES; +} + +- (void)close +{ + [super close]; + --FigureWindowCount; + if (!FigureWindowCount) [NSApp stop: self]; + /* This is needed for show(), which should exit from [NSApp run] + * after all windows are closed. + */ +} + +- (void)dealloc +{ + PyGILState_STATE gstate; + gstate = PyGILState_Ensure(); + Py_DECREF(manager); + PyGILState_Release(gstate); + /* The reference count of the view that was added as a subview to the + * content view of this window was increased during the call to addSubview, + * and is decreased during the call to [super dealloc]. + */ + [super dealloc]; +} +@end + +@implementation ToolWindow +- (ToolWindow*)initWithContentRect:(NSRect)rect master:(NSWindow*)window +{ + [self initWithContentRect: rect + styleMask: NSTitledWindowMask + | NSClosableWindowMask + | NSResizableWindowMask + | NSMiniaturizableWindowMask + backing: NSBackingStoreBuffered + defer: YES]; + [self setTitle: @"Subplot Configuration Tool"]; + [[NSNotificationCenter defaultCenter] addObserver: self + selector: @selector(masterCloses:) + name: NSWindowWillCloseNotification + object: window]; + return self; +} + +- (void)masterCloses:(NSNotification*)notification +{ + [self close]; +} + +- (void)close +{ + [[NSNotificationCenter defaultCenter] removeObserver: self]; + [super close]; +} +@end + +@implementation View +- (BOOL)isFlipped +{ + return NO; +} + +- (View*)initWithFrame:(NSRect)rect +{ + self = [super initWithFrame: rect]; + rubberband = NSZeroRect; + inside = false; + tracking = 0; + device_scale = 1; + return self; +} + +- (void)dealloc +{ + FigureCanvas* fc = (FigureCanvas*)canvas; + if (fc) fc->view = NULL; + [self removeTrackingRect: tracking]; + [super dealloc]; +} + +- (void)setCanvas: (PyObject*)newCanvas +{ + canvas = newCanvas; +} + +static void _buffer_release(void* info, const void* data, size_t size) { + PyBuffer_Release((Py_buffer *)info); +} + +static int _copy_agg_buffer(CGContextRef cr, PyObject *renderer) +{ + Py_buffer buffer; + + if (PyObject_GetBuffer(renderer, &buffer, PyBUF_CONTIG_RO) == -1) { + PyErr_Print(); + return 1; + } + + if (buffer.ndim != 3 || buffer.shape[2] != 4) { + PyBuffer_Release(&buffer); + return 1; + } + + const Py_ssize_t nrows = buffer.shape[0]; + const Py_ssize_t ncols = buffer.shape[1]; + const size_t bytesPerComponent = 1; + const size_t bitsPerComponent = 8 * bytesPerComponent; + const size_t nComponents = 4; /* red, green, blue, alpha */ + const size_t bitsPerPixel = bitsPerComponent * nComponents; + const size_t bytesPerRow = nComponents * bytesPerComponent * ncols; + + CGColorSpaceRef colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB); + if (!colorspace) { + PyBuffer_Release(&buffer); + return 1; + } + + CGDataProviderRef provider = CGDataProviderCreateWithData(&buffer, + buffer.buf, + buffer.len, + _buffer_release); + if (!provider) { + PyBuffer_Release(&buffer); + CGColorSpaceRelease(colorspace); + return 1; + } + + CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault | kCGImageAlphaLast; + CGImageRef bitmap = CGImageCreate(ncols, + nrows, + bitsPerComponent, + bitsPerPixel, + bytesPerRow, + colorspace, + bitmapInfo, + provider, + NULL, + false, + kCGRenderingIntentDefault); + CGColorSpaceRelease(colorspace); + CGDataProviderRelease(provider); + + if (!bitmap) { + PyBuffer_Release(&buffer); + return 1; + } + + CGFloat deviceScale = _get_device_scale(cr); + CGContextSaveGState(cr); + CGContextDrawImage(cr, CGRectMake(0, 0, ncols/deviceScale, nrows/deviceScale), bitmap); + CGImageRelease(bitmap); + CGContextRestoreGState(cr); + + return 0; +} + +-(void)drawRect:(NSRect)rect +{ + PyObject* renderer = NULL; + PyObject* renderer_buffer = NULL; + + PyGILState_STATE gstate = PyGILState_Ensure(); + + CGContextRef cr = [[NSGraphicsContext currentContext] graphicsPort]; + + double new_device_scale = _get_device_scale(cr); + + if (device_scale != new_device_scale) { + device_scale = new_device_scale; + if (!PyObject_CallMethod(canvas, "_set_device_scale", "d", device_scale, NULL)) { + PyErr_Print(); + goto exit; + } + } + + renderer = PyObject_CallMethod(canvas, "_draw", "", NULL); + if (!renderer) + { + PyErr_Print(); + goto exit; + } + + renderer_buffer = PyObject_GetAttrString(renderer, "_renderer"); + if (!renderer_buffer) { + PyErr_Print(); + goto exit; + } + + if (_copy_agg_buffer(cr, renderer_buffer)) { + printf("copy_agg_buffer failed\n"); + goto exit; + } + + + if (!NSIsEmptyRect(rubberband)) { + NSFrameRect(rubberband); + } + + exit: + Py_XDECREF(renderer_buffer); + Py_XDECREF(renderer); + + PyGILState_Release(gstate); +} + +- (void)windowDidResize: (NSNotification*)notification +{ + int width, height; + Window* window = [notification object]; + NSSize size = [[window contentView] frame].size; + NSRect rect = [self frame]; + + size.height -= rect.origin.y; + width = size.width; + height = size.height; + + [self setFrameSize: size]; + + PyGILState_STATE gstate = PyGILState_Ensure(); + PyObject* result = PyObject_CallMethod( + canvas, "resize", "ii", width, height); + if(result) + Py_DECREF(result); + else + PyErr_Print(); + PyGILState_Release(gstate); + if (tracking) [self removeTrackingRect: tracking]; + tracking = [self addTrackingRect: [self bounds] + owner: self + userData: nil + assumeInside: NO]; + [self setNeedsDisplay: YES]; +} + +- (void)windowWillClose:(NSNotification*)notification +{ + PyGILState_STATE gstate; + PyObject* result; + + gstate = PyGILState_Ensure(); + result = PyObject_CallMethod(canvas, "close_event", ""); + if(result) + Py_DECREF(result); + else + PyErr_Print(); + PyGILState_Release(gstate); +} + +- (BOOL)windowShouldClose:(NSNotification*)notification +{ + NSWindow* window = [self window]; + NSEvent* event = [NSEvent otherEventWithType: NSApplicationDefined + location: NSZeroPoint + modifierFlags: 0 + timestamp: 0.0 + windowNumber: 0 + context: nil + subtype: WINDOW_CLOSING + data1: 0 + data2: 0]; + [NSApp postEvent: event atStart: true]; + if ([window respondsToSelector: @selector(closeButtonPressed)]) + { BOOL closed = [((Window*) window) closeButtonPressed]; + /* If closed, the window has already been closed via the manager. */ + if (closed) return NO; + } + return YES; +} + +- (void)mouseEntered:(NSEvent *)event +{ + PyGILState_STATE gstate; + PyObject* result; + NSWindow* window = [self window]; + if ([window isKeyWindow]==false) return; + + gstate = PyGILState_Ensure(); + result = PyObject_CallMethod(canvas, "enter_notify_event", ""); + if(result) + Py_DECREF(result); + else + PyErr_Print(); + PyGILState_Release(gstate); + + [window setAcceptsMouseMovedEvents: YES]; + inside = true; +} + +- (void)mouseExited:(NSEvent *)event +{ + PyGILState_STATE gstate; + PyObject* result; + NSWindow* window = [self window]; + if ([window isKeyWindow]==false) return; + + if (inside==false) return; + gstate = PyGILState_Ensure(); + result = PyObject_CallMethod(canvas, "leave_notify_event", ""); + if(result) + Py_DECREF(result); + else + PyErr_Print(); + PyGILState_Release(gstate); + + [[self window] setAcceptsMouseMovedEvents: NO]; + inside = false; +} + +- (void)mouseDown:(NSEvent *)event +{ + int x, y; + int num; + int dblclick = 0; + PyObject* result; + PyGILState_STATE gstate; + NSPoint location = [event locationInWindow]; + location = [self convertPoint: location fromView: nil]; + x = location.x * device_scale; + y = location.y * device_scale; + switch ([event type]) + { case NSLeftMouseDown: + { unsigned int modifier = [event modifierFlags]; + if (modifier & NSControlKeyMask) + /* emulate a right-button click */ + num = 3; + else if (modifier & NSAlternateKeyMask) + /* emulate a middle-button click */ + num = 2; + else + { + num = 1; + if ([NSCursor currentCursor]==[NSCursor openHandCursor]) + [[NSCursor closedHandCursor] set]; + } + break; + } + case NSOtherMouseDown: num = 2; break; + case NSRightMouseDown: num = 3; break; + default: return; /* Unknown mouse event */ + } + if ([event clickCount] == 2) { + dblclick = 1; + } + gstate = PyGILState_Ensure(); + result = PyObject_CallMethod(canvas, "button_press_event", "iiii", x, y, num, dblclick); + if(result) + Py_DECREF(result); + else + PyErr_Print(); + + PyGILState_Release(gstate); +} + +- (void)mouseUp:(NSEvent *)event +{ + int num; + int x, y; + PyObject* result; + PyGILState_STATE gstate; + NSPoint location = [event locationInWindow]; + location = [self convertPoint: location fromView: nil]; + x = location.x * device_scale; + y = location.y * device_scale; + switch ([event type]) + { case NSLeftMouseUp: + num = 1; + if ([NSCursor currentCursor]==[NSCursor closedHandCursor]) + [[NSCursor openHandCursor] set]; + break; + case NSOtherMouseUp: num = 2; break; + case NSRightMouseUp: num = 3; break; + default: return; /* Unknown mouse event */ + } + gstate = PyGILState_Ensure(); + result = PyObject_CallMethod(canvas, "button_release_event", "iii", x, y, num); + if(result) + Py_DECREF(result); + else + PyErr_Print(); + + PyGILState_Release(gstate); +} + +- (void)mouseMoved:(NSEvent *)event +{ + int x, y; + NSPoint location = [event locationInWindow]; + location = [self convertPoint: location fromView: nil]; + x = location.x * device_scale; + y = location.y * device_scale; + PyGILState_STATE gstate = PyGILState_Ensure(); + PyObject* result = PyObject_CallMethod(canvas, "motion_notify_event", "ii", x, y); + if(result) + Py_DECREF(result); + else + PyErr_Print(); + + PyGILState_Release(gstate); +} + +- (void)mouseDragged:(NSEvent *)event +{ + int x, y; + NSPoint location = [event locationInWindow]; + location = [self convertPoint: location fromView: nil]; + x = location.x * device_scale; + y = location.y * device_scale; + PyGILState_STATE gstate = PyGILState_Ensure(); + PyObject* result = PyObject_CallMethod(canvas, "motion_notify_event", "ii", x, y); + if(result) + Py_DECREF(result); + else + PyErr_Print(); + + PyGILState_Release(gstate); +} + +- (void)rightMouseDown:(NSEvent *)event +{ + int x, y; + int num = 3; + int dblclick = 0; + PyObject* result; + PyGILState_STATE gstate; + NSPoint location = [event locationInWindow]; + location = [self convertPoint: location fromView: nil]; + x = location.x * device_scale; + y = location.y * device_scale; + gstate = PyGILState_Ensure(); + if ([event clickCount] == 2) { + dblclick = 1; + } + result = PyObject_CallMethod(canvas, "button_press_event", "iiii", x, y, num, dblclick); + if(result) + Py_DECREF(result); + else + PyErr_Print(); + + PyGILState_Release(gstate); +} + +- (void)rightMouseUp:(NSEvent *)event +{ + int x, y; + int num = 3; + PyObject* result; + PyGILState_STATE gstate; + NSPoint location = [event locationInWindow]; + location = [self convertPoint: location fromView: nil]; + x = location.x * device_scale; + y = location.y * device_scale; + gstate = PyGILState_Ensure(); + result = PyObject_CallMethod(canvas, "button_release_event", "iii", x, y, num); + if(result) + Py_DECREF(result); + else + PyErr_Print(); + + PyGILState_Release(gstate); +} + +- (void)rightMouseDragged:(NSEvent *)event +{ + int x, y; + NSPoint location = [event locationInWindow]; + location = [self convertPoint: location fromView: nil]; + x = location.x * device_scale; + y = location.y * device_scale; + PyGILState_STATE gstate = PyGILState_Ensure(); + PyObject* result = PyObject_CallMethod(canvas, "motion_notify_event", "ii", x, y); + if(result) + Py_DECREF(result); + else + PyErr_Print(); + + PyGILState_Release(gstate); +} + +- (void)otherMouseDown:(NSEvent *)event +{ + int x, y; + int num = 2; + int dblclick = 0; + PyObject* result; + PyGILState_STATE gstate; + NSPoint location = [event locationInWindow]; + location = [self convertPoint: location fromView: nil]; + x = location.x * device_scale; + y = location.y * device_scale; + gstate = PyGILState_Ensure(); + if ([event clickCount] == 2) { + dblclick = 1; + } + result = PyObject_CallMethod(canvas, "button_press_event", "iiii", x, y, num, dblclick); + if(result) + Py_DECREF(result); + else + PyErr_Print(); + + PyGILState_Release(gstate); +} + +- (void)otherMouseUp:(NSEvent *)event +{ + int x, y; + int num = 2; + PyObject* result; + PyGILState_STATE gstate; + NSPoint location = [event locationInWindow]; + location = [self convertPoint: location fromView: nil]; + x = location.x * device_scale; + y = location.y * device_scale; + gstate = PyGILState_Ensure(); + result = PyObject_CallMethod(canvas, "button_release_event", "iii", x, y, num); + if(result) + Py_DECREF(result); + else + PyErr_Print(); + + PyGILState_Release(gstate); +} + +- (void)otherMouseDragged:(NSEvent *)event +{ + int x, y; + NSPoint location = [event locationInWindow]; + location = [self convertPoint: location fromView: nil]; + x = location.x * device_scale; + y = location.y * device_scale; + PyGILState_STATE gstate = PyGILState_Ensure(); + PyObject* result = PyObject_CallMethod(canvas, "motion_notify_event", "ii", x, y); + if(result) + Py_DECREF(result); + else + PyErr_Print(); + + PyGILState_Release(gstate); +} + +- (void)setRubberband:(NSRect)rect +{ + if (!NSIsEmptyRect(rubberband)) [self setNeedsDisplayInRect: rubberband]; + rubberband = rect; + [self setNeedsDisplayInRect: rubberband]; +} + +- (void)removeRubberband +{ + if (NSIsEmptyRect(rubberband)) return; + [self setNeedsDisplayInRect: rubberband]; + rubberband = NSZeroRect; +} + + + +- (const char*)convertKeyEvent:(NSEvent*)event +{ + NSDictionary* specialkeymappings = [NSDictionary dictionaryWithObjectsAndKeys: + @"left", [NSNumber numberWithUnsignedLong:NSLeftArrowFunctionKey], + @"right", [NSNumber numberWithUnsignedLong:NSRightArrowFunctionKey], + @"up", [NSNumber numberWithUnsignedLong:NSUpArrowFunctionKey], + @"down", [NSNumber numberWithUnsignedLong:NSDownArrowFunctionKey], + @"f1", [NSNumber numberWithUnsignedLong:NSF1FunctionKey], + @"f2", [NSNumber numberWithUnsignedLong:NSF2FunctionKey], + @"f3", [NSNumber numberWithUnsignedLong:NSF3FunctionKey], + @"f4", [NSNumber numberWithUnsignedLong:NSF4FunctionKey], + @"f5", [NSNumber numberWithUnsignedLong:NSF5FunctionKey], + @"f6", [NSNumber numberWithUnsignedLong:NSF6FunctionKey], + @"f7", [NSNumber numberWithUnsignedLong:NSF7FunctionKey], + @"f8", [NSNumber numberWithUnsignedLong:NSF8FunctionKey], + @"f9", [NSNumber numberWithUnsignedLong:NSF9FunctionKey], + @"f10", [NSNumber numberWithUnsignedLong:NSF10FunctionKey], + @"f11", [NSNumber numberWithUnsignedLong:NSF11FunctionKey], + @"f12", [NSNumber numberWithUnsignedLong:NSF12FunctionKey], + @"f13", [NSNumber numberWithUnsignedLong:NSF13FunctionKey], + @"f14", [NSNumber numberWithUnsignedLong:NSF14FunctionKey], + @"f15", [NSNumber numberWithUnsignedLong:NSF15FunctionKey], + @"f16", [NSNumber numberWithUnsignedLong:NSF16FunctionKey], + @"f17", [NSNumber numberWithUnsignedLong:NSF17FunctionKey], + @"f18", [NSNumber numberWithUnsignedLong:NSF18FunctionKey], + @"f19", [NSNumber numberWithUnsignedLong:NSF19FunctionKey], + @"scroll_lock", [NSNumber numberWithUnsignedLong:NSScrollLockFunctionKey], + @"break", [NSNumber numberWithUnsignedLong:NSBreakFunctionKey], + @"insert", [NSNumber numberWithUnsignedLong:NSInsertFunctionKey], + @"delete", [NSNumber numberWithUnsignedLong:NSDeleteFunctionKey], + @"home", [NSNumber numberWithUnsignedLong:NSHomeFunctionKey], + @"end", [NSNumber numberWithUnsignedLong:NSEndFunctionKey], + @"pagedown", [NSNumber numberWithUnsignedLong:NSPageDownFunctionKey], + @"pageup", [NSNumber numberWithUnsignedLong:NSPageUpFunctionKey], + @"backspace", [NSNumber numberWithUnsignedLong:NSDeleteCharacter], + @"enter", [NSNumber numberWithUnsignedLong:NSEnterCharacter], + @"tab", [NSNumber numberWithUnsignedLong:NSTabCharacter], + @"enter", [NSNumber numberWithUnsignedLong:NSCarriageReturnCharacter], + @"backtab", [NSNumber numberWithUnsignedLong:NSBackTabCharacter], + @"escape", [NSNumber numberWithUnsignedLong:27], + nil + ]; + + NSMutableString* returnkey = [NSMutableString string]; + if ([event modifierFlags] & NSControlKeyMask) + [returnkey appendString:@"ctrl+" ]; + if ([event modifierFlags] & NSAlternateKeyMask) + [returnkey appendString:@"alt+" ]; + if ([event modifierFlags] & NSCommandKeyMask) + [returnkey appendString:@"cmd+" ]; + + unichar uc = [[event charactersIgnoringModifiers] characterAtIndex:0]; + NSString* specialchar = [specialkeymappings objectForKey:[NSNumber numberWithUnsignedLong:uc]]; + if (specialchar){ + if ([event modifierFlags] & NSShiftKeyMask) + [returnkey appendString:@"shift+" ]; + [returnkey appendString:specialchar]; + } + else + [returnkey appendString:[event charactersIgnoringModifiers]]; + + return [returnkey UTF8String]; +} + +- (void)keyDown:(NSEvent*)event +{ + PyObject* result; + const char* s = [self convertKeyEvent: event]; + PyGILState_STATE gstate = PyGILState_Ensure(); + if (s==NULL) + { + result = PyObject_CallMethod(canvas, "key_press_event", "O", Py_None); + } + else + { + result = PyObject_CallMethod(canvas, "key_press_event", "s", s); + } + if(result) + Py_DECREF(result); + else + PyErr_Print(); + + PyGILState_Release(gstate); +} + +- (void)keyUp:(NSEvent*)event +{ + PyObject* result; + const char* s = [self convertKeyEvent: event]; + PyGILState_STATE gstate = PyGILState_Ensure(); + if (s==NULL) + { + result = PyObject_CallMethod(canvas, "key_release_event", "O", Py_None); + } + else + { + result = PyObject_CallMethod(canvas, "key_release_event", "s", s); + } + if(result) + Py_DECREF(result); + else + PyErr_Print(); + + PyGILState_Release(gstate); +} + +- (void)scrollWheel:(NSEvent*)event +{ + int step; + float d = [event deltaY]; + if (d > 0) step = 1; + else if (d < 0) step = -1; + else return; + NSPoint location = [event locationInWindow]; + NSPoint point = [self convertPoint: location fromView: nil]; + int x = (int)round(point.x * device_scale); + int y = (int)round(point.y * device_scale - 1); + + PyObject* result; + PyGILState_STATE gstate = PyGILState_Ensure(); + result = PyObject_CallMethod(canvas, "scroll_event", "iii", x, y, step); + if(result) + Py_DECREF(result); + else + PyErr_Print(); + + PyGILState_Release(gstate); +} + +- (BOOL)acceptsFirstResponder +{ + return YES; +} + +/* This is all wrong. Address of pointer is being passed instead of pointer, keynames don't + match up with what the front-end and does the front-end even handle modifier keys by themselves? + +- (void)flagsChanged:(NSEvent*)event +{ + const char *s = NULL; + if (([event modifierFlags] & NSControlKeyMask) == NSControlKeyMask) + s = "control"; + else if (([event modifierFlags] & NSShiftKeyMask) == NSShiftKeyMask) + s = "shift"; + else if (([event modifierFlags] & NSAlternateKeyMask) == NSAlternateKeyMask) + s = "alt"; + else return; + PyGILState_STATE gstate = PyGILState_Ensure(); + PyObject* result = PyObject_CallMethod(canvas, "key_press_event", "s", &s); + if(result) + Py_DECREF(result); + else + PyErr_Print(); + + PyGILState_Release(gstate); +} + */ +@end + +@implementation ScrollableButton +- (void)setScrollWheelUpAction:(SEL)action +{ + scrollWheelUpAction = action; +} + +- (void)setScrollWheelDownAction:(SEL)action +{ + scrollWheelDownAction = action; +} + +- (void)scrollWheel:(NSEvent*)event +{ + float d = [event deltaY]; + Window* target = [self target]; + if (d > 0) + [NSApp sendAction: scrollWheelUpAction to: target from: self]; + else if (d < 0) + [NSApp sendAction: scrollWheelDownAction to: target from: self]; +} +@end + +@implementation MenuItem ++ (MenuItem*)menuItemWithTitle: (NSString*)title +{ + MenuItem* item = [[MenuItem alloc] initWithTitle: title + action: nil + keyEquivalent: @""]; + item->index = -1; + return [item autorelease]; +} + ++ (MenuItem*)menuItemForAxis: (int)i +{ + NSString* title = [NSString stringWithFormat: @"Axis %d", i+1]; + MenuItem* item = [[MenuItem alloc] initWithTitle: title + action: @selector(toggle:) + keyEquivalent: @""]; + [item setTarget: item]; + [item setState: NSOnState]; + item->index = i; + return [item autorelease]; +} + ++ (MenuItem*)menuItemSelectAll +{ + MenuItem* item = [[MenuItem alloc] initWithTitle: @"Select All" + action: @selector(selectAll:) + keyEquivalent: @""]; + [item setTarget: item]; + item->index = -1; + return [item autorelease]; +} + ++ (MenuItem*)menuItemInvertAll +{ + MenuItem* item = [[MenuItem alloc] initWithTitle: @"Invert All" + action: @selector(invertAll:) + keyEquivalent: @""]; + [item setTarget: item]; + item->index = -1; + return [item autorelease]; +} + +- (void)toggle:(id)sender +{ + if ([self state]) [self setState: NSOffState]; + else [self setState: NSOnState]; +} + +- (void)selectAll:(id)sender +{ + NSMenu* menu = [sender menu]; + if(!menu) return; /* Weird */ + NSArray* items = [menu itemArray]; + NSEnumerator* enumerator = [items objectEnumerator]; + MenuItem* item; + while ((item = [enumerator nextObject])) + { + if (item->index >= 0) [item setState: NSOnState]; + } +} + +- (void)invertAll:(id)sender +{ + NSMenu* menu = [sender menu]; + if(!menu) return; /* Weird */ + NSArray* items = [menu itemArray]; + NSEnumerator* enumerator = [items objectEnumerator]; + MenuItem* item; + while ((item = [enumerator nextObject])) + { + if (item->index < 0) continue; + if ([item state]==NSOffState) [item setState: NSOnState]; + else [item setState: NSOffState]; + } +} + +- (int)index +{ + return self->index; +} +@end + +static PyObject* +show(PyObject* self) +{ + [NSApp activateIgnoringOtherApps: YES]; + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + NSArray *windowsArray = [NSApp windows]; + NSEnumerator *enumerator = [windowsArray objectEnumerator]; + NSWindow *window; + while ((window = [enumerator nextObject])) { + [window orderFront:nil]; + } + [pool release]; + Py_BEGIN_ALLOW_THREADS + [NSApp run]; + Py_END_ALLOW_THREADS + Py_RETURN_NONE; +} + +typedef struct { + PyObject_HEAD + CFRunLoopTimerRef timer; +} Timer; + +static PyObject* +Timer_new(PyTypeObject* type, PyObject *args, PyObject *kwds) +{ + Timer* self = (Timer*)type->tp_alloc(type, 0); + if (!self) return NULL; + self->timer = NULL; + return (PyObject*) self; +} + +static PyObject* +Timer_repr(Timer* self) +{ +#if PY3K + return PyUnicode_FromFormat("Timer object %p wrapping CFRunLoopTimerRef %p", + (void*) self, (void*)(self->timer)); +#else + return PyString_FromFormat("Timer object %p wrapping CFRunLoopTimerRef %p", + (void*) self, (void*)(self->timer)); +#endif +} + +static char Timer_doc[] = +"A Timer object wraps a CFRunLoopTimerRef and can add it to the event loop.\n"; + +static void timer_callback(CFRunLoopTimerRef timer, void* info) +{ + PyObject* method = info; + PyGILState_STATE gstate = PyGILState_Ensure(); + PyObject* result = PyObject_CallFunction(method, NULL); + if (result) { + Py_DECREF(result); + } else { + PyErr_Print(); + } + PyGILState_Release(gstate); +} + +static void context_cleanup(const void* info) +{ + Py_DECREF((PyObject*)info); +} + +static PyObject* +Timer__timer_start(Timer* self, PyObject* args) +{ + CFRunLoopRef runloop; + CFRunLoopTimerRef timer; + CFRunLoopTimerContext context; + double milliseconds; + CFTimeInterval interval; + PyObject* attribute; + PyObject* failure; + runloop = CFRunLoopGetCurrent(); + if (!runloop) { + PyErr_SetString(PyExc_RuntimeError, "Failed to obtain run loop"); + return NULL; + } + attribute = PyObject_GetAttrString((PyObject*)self, "_interval"); + if (attribute==NULL) + { + PyErr_SetString(PyExc_AttributeError, "Timer has no attribute '_interval'"); + return NULL; + } + milliseconds = PyFloat_AsDouble(attribute); + failure = PyErr_Occurred(); + Py_DECREF(attribute); + if (failure) return NULL; + attribute = PyObject_GetAttrString((PyObject*)self, "_single"); + if (attribute==NULL) + { + PyErr_SetString(PyExc_AttributeError, "Timer has no attribute '_single'"); + return NULL; + } + switch (PyObject_IsTrue(attribute)) { + case 1: + interval = 0; + break; + case 0: + interval = milliseconds / 1000.0; + break; + case -1: + default: + PyErr_SetString(PyExc_ValueError, "Cannot interpret _single attribute as True of False"); + return NULL; + } + Py_DECREF(attribute); + attribute = PyObject_GetAttrString((PyObject*)self, "_on_timer"); + if (attribute==NULL) + { + PyErr_SetString(PyExc_AttributeError, "Timer has no attribute '_on_timer'"); + return NULL; + } + if (!PyMethod_Check(attribute)) { + PyErr_SetString(PyExc_RuntimeError, "_on_timer should be a Python method"); + return NULL; + } + context.version = 0; + context.retain = NULL; + context.release = context_cleanup; + context.copyDescription = NULL; + context.info = attribute; + timer = CFRunLoopTimerCreate(kCFAllocatorDefault, + 0, + interval, + 0, + 0, + timer_callback, + &context); + if (!timer) { + Py_DECREF(attribute); + PyErr_SetString(PyExc_RuntimeError, "Failed to create timer"); + return NULL; + } + if (self->timer) { + CFRunLoopTimerInvalidate(self->timer); + CFRelease(self->timer); + } + CFRunLoopAddTimer(runloop, timer, kCFRunLoopCommonModes); + /* Don't release the timer here, since the run loop may be destroyed and + * the timer lost before we have a chance to decrease the reference count + * of the attribute */ + self->timer = timer; + Py_RETURN_NONE; +} + +static PyObject* +Timer__timer_stop(Timer* self) +{ + if (self->timer) { + CFRunLoopTimerInvalidate(self->timer); + CFRelease(self->timer); + self->timer = NULL; + } + Py_RETURN_NONE; +} + +static void +Timer_dealloc(Timer* self) +{ + Timer__timer_stop(self); + Py_TYPE(self)->tp_free((PyObject*)self); +} + +static PyMethodDef Timer_methods[] = { + {"_timer_start", + (PyCFunction)Timer__timer_start, + METH_VARARGS, + "Initialize and start the timer." + }, + {"_timer_stop", + (PyCFunction)Timer__timer_stop, + METH_NOARGS, + "Stop the timer." + }, + {NULL} /* Sentinel */ +}; + +static PyTypeObject TimerType = { + PyVarObject_HEAD_INIT(NULL, 0) + "_macosx.Timer", /*tp_name*/ + sizeof(Timer), /*tp_basicsize*/ + 0, /*tp_itemsize*/ + (destructor)Timer_dealloc, /*tp_dealloc*/ + 0, /*tp_print*/ + 0, /*tp_getattr*/ + 0, /*tp_setattr*/ + 0, /*tp_compare*/ + (reprfunc)Timer_repr, /*tp_repr*/ + 0, /*tp_as_number*/ + 0, /*tp_as_sequence*/ + 0, /*tp_as_mapping*/ + 0, /*tp_hash */ + 0, /*tp_call*/ + 0, /*tp_str*/ + 0, /*tp_getattro*/ + 0, /*tp_setattro*/ + 0, /*tp_as_buffer*/ + Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/ + Timer_doc, /* tp_doc */ + 0, /* tp_traverse */ + 0, /* tp_clear */ + 0, /* tp_richcompare */ + 0, /* tp_weaklistoffset */ + 0, /* tp_iter */ + 0, /* tp_iternext */ + Timer_methods, /* tp_methods */ + 0, /* tp_members */ + 0, /* tp_getset */ + 0, /* tp_base */ + 0, /* tp_dict */ + 0, /* tp_descr_get */ + 0, /* tp_descr_set */ + 0, /* tp_dictoffset */ + 0, /* tp_init */ + 0, /* tp_alloc */ + Timer_new, /* tp_new */ +}; + +static bool verify_framework(void) +{ +#ifdef COMPILING_FOR_10_6 + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + NSRunningApplication* app = [NSRunningApplication currentApplication]; + NSApplicationActivationPolicy activationPolicy = [app activationPolicy]; + [pool release]; + switch (activationPolicy) { + case NSApplicationActivationPolicyRegular: + case NSApplicationActivationPolicyAccessory: + return true; + case NSApplicationActivationPolicyProhibited: + break; + } +#else + ProcessSerialNumber psn; + if (CGMainDisplayID()!=0 + && GetCurrentProcess(&psn)==noErr + && SetFrontProcess(&psn)==noErr) return true; +#endif + PyErr_SetString(PyExc_RuntimeError, + "Python is not installed as a framework. The Mac OS X backend will " + "not be able to function correctly if Python is not installed as a " + "framework. See the Python documentation for more information on " + "installing Python as a framework on Mac OS X. Please either reinstall " + "Python as a framework, or try one of the other backends. If you are " + "using (Ana)Conda please install python.app and replace the use of 'python' " + "with 'pythonw'. See 'Working with Matplotlib on OSX' " + "in the Matplotlib FAQ for more information."); + return false; +} + +static struct PyMethodDef methods[] = { + {"show", + (PyCFunction)show, + METH_NOARGS, + "Show all the figures and enter the main loop.\nThis function does not return until all Matplotlib windows are closed,\nand is normally not needed in interactive sessions." + }, + {"choose_save_file", + (PyCFunction)choose_save_file, + METH_VARARGS, + "Closes the window." + }, + {"set_cursor", + (PyCFunction)set_cursor, + METH_VARARGS, + "Sets the active cursor." + }, + {NULL, NULL, 0, NULL}/* sentinel */ +}; + +#if PY3K + +static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + "_macosx", + "Mac OS X native backend", + -1, + methods, + NULL, + NULL, + NULL, + NULL +}; + +PyObject* PyInit__macosx(void) + +#else + +void init_macosx(void) +#endif +{ + PyObject *module; + + if (PyType_Ready(&FigureCanvasType) < 0 + || PyType_Ready(&FigureManagerType) < 0 + || PyType_Ready(&NavigationToolbarType) < 0 + || PyType_Ready(&NavigationToolbar2Type) < 0 + || PyType_Ready(&TimerType) < 0) +#if PY3K + return NULL; +#else + return; +#endif + + NSApp = [NSApplication sharedApplication]; + + if (!verify_framework()) +#if PY3K + return NULL; +#else + return; +#endif + +#if PY3K + module = PyModule_Create(&moduledef); + if (module==NULL) return NULL; +#else + module = Py_InitModule4("_macosx", + methods, + "Mac OS X native backend", + NULL, + PYTHON_API_VERSION); +#endif + + Py_INCREF(&FigureCanvasType); + Py_INCREF(&FigureManagerType); + Py_INCREF(&NavigationToolbarType); + Py_INCREF(&NavigationToolbar2Type); + Py_INCREF(&TimerType); + PyModule_AddObject(module, "FigureCanvas", (PyObject*) &FigureCanvasType); + PyModule_AddObject(module, "FigureManager", (PyObject*) &FigureManagerType); + PyModule_AddObject(module, "NavigationToolbar", (PyObject*) &NavigationToolbarType); + PyModule_AddObject(module, "NavigationToolbar2", (PyObject*) &NavigationToolbar2Type); + PyModule_AddObject(module, "Timer", (PyObject*) &TimerType); + + PyOS_InputHook = wait_for_stdin; + + NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; + WindowServerConnectionManager* connectionManager = [WindowServerConnectionManager sharedManager]; + NSWorkspace* workspace = [NSWorkspace sharedWorkspace]; + NSNotificationCenter* notificationCenter = [workspace notificationCenter]; + [notificationCenter addObserver: connectionManager + selector: @selector(launch:) + name: NSWorkspaceDidLaunchApplicationNotification + object: nil]; + [pool release]; +#if PY3K + return module; +#endif +} diff --git a/contrib/python/matplotlib/py2/src/_windowing.cpp b/contrib/python/matplotlib/py2/src/_windowing.cpp new file mode 100644 index 0000000000..7a20baa0a3 --- /dev/null +++ b/contrib/python/matplotlib/py2/src/_windowing.cpp @@ -0,0 +1,64 @@ +#include "Python.h" +#include <windows.h> + +static PyObject * +_GetForegroundWindow(PyObject *module, PyObject *args) +{ + HWND handle = GetForegroundWindow(); + if (!PyArg_ParseTuple(args, ":GetForegroundWindow")) + { + return NULL; + } + return PyLong_FromSize_t((size_t)handle); +} + +static PyObject * +_SetForegroundWindow(PyObject *module, PyObject *args) +{ + HWND handle; + if (!PyArg_ParseTuple(args, "n:SetForegroundWindow", &handle)) + { + return NULL; + } + if (!SetForegroundWindow(handle)) + { + return PyErr_Format(PyExc_RuntimeError, + "Error setting window"); + } + Py_INCREF(Py_None); + return Py_None; +} + +static PyMethodDef _windowing_methods[] = +{ + {"GetForegroundWindow", _GetForegroundWindow, METH_VARARGS}, + {"SetForegroundWindow", _SetForegroundWindow, METH_VARARGS}, + {NULL, NULL} +}; + +#if PY_MAJOR_VERSION >= 3 + +static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + "_windowing", + "", + -1, + _windowing_methods, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC PyInit__windowing(void) +{ + PyObject *module = PyModule_Create(&moduledef); + return module; +} + +#else +PyMODINIT_FUNC init_windowing() +{ + Py_InitModule("_windowing", _windowing_methods); +} +#endif diff --git a/contrib/python/matplotlib/py2/src/path_cleanup.cpp b/contrib/python/matplotlib/py2/src/path_cleanup.cpp new file mode 100644 index 0000000000..f9f2213b3d --- /dev/null +++ b/contrib/python/matplotlib/py2/src/path_cleanup.cpp @@ -0,0 +1,113 @@ +/* -*- mode: c++; c-basic-offset: 4 -*- */ + +#include <Python.h> +#define NO_IMPORT_ARRAY +#include "numpy/arrayobject.h" + +#include "py_converters.h" + +#include "py_adaptors.h" +#include "agg_conv_transform.h" +#include "path_converters.h" + +class PathCleanupIterator +{ + typedef agg::conv_transform<py::PathIterator> transformed_path_t; + typedef PathNanRemover<transformed_path_t> nan_removal_t; + typedef PathClipper<nan_removal_t> clipped_t; + typedef PathSnapper<clipped_t> snapped_t; + typedef PathSimplifier<snapped_t> simplify_t; + typedef Sketch<simplify_t> sketch_t; + + py::PathIterator m_path_iter; + agg::trans_affine m_transform; + transformed_path_t m_transformed; + nan_removal_t m_nan_removed; + clipped_t m_clipped; + snapped_t m_snapped; + simplify_t m_simplify; + sketch_t m_sketch; + + public: + PathCleanupIterator(PyObject *path, + agg::trans_affine trans, + bool remove_nans, + bool do_clip, + const agg::rect_base<double> &rect, + e_snap_mode snap_mode, + double stroke_width, + bool do_simplify, + double sketch_scale, + double sketch_length, + double sketch_randomness) + : m_transform(trans), + m_transformed(m_path_iter, m_transform), + m_nan_removed(m_transformed, remove_nans, m_path_iter.has_curves()), + m_clipped(m_nan_removed, do_clip && !m_path_iter.has_curves(), rect), + m_snapped(m_clipped, snap_mode, m_path_iter.total_vertices(), stroke_width), + m_simplify(m_snapped, + do_simplify && m_path_iter.should_simplify(), + m_path_iter.simplify_threshold()), + m_sketch(m_simplify, sketch_scale, sketch_length, sketch_randomness) + { + convert_path(path, &m_path_iter); + + Py_INCREF(path); + m_path_iter.rewind(0); + } + + unsigned vertex(double *x, double *y) + { + return m_simplify.vertex(x, y); + } +}; + +extern "C" { +void *get_path_iterator(PyObject *path, + PyObject *trans, + int remove_nans, + int do_clip, + double rect[4], + e_snap_mode snap_mode, + double stroke_width, + int do_simplify, + double sketch_scale, + double sketch_length, + double sketch_randomness) +{ + agg::trans_affine agg_trans; + if (!convert_trans_affine(trans, &agg_trans)) { + return NULL; + } + agg::rect_base<double> clip_rect(rect[0], rect[1], rect[2], rect[3]); + + PathCleanupIterator *pipeline = new PathCleanupIterator(path, + agg_trans, + remove_nans != 0, + do_clip != 0, + clip_rect, + snap_mode, + stroke_width, + do_simplify != 0, + sketch_scale, + sketch_length, + sketch_randomness); + + return (void *)pipeline; +} + +unsigned get_vertex(void *pipeline, double *x, double *y) +{ + PathCleanupIterator *pipeline_iter = (PathCleanupIterator *)pipeline; + + unsigned code = pipeline_iter->vertex(x, y); + return code; +} + +void free_path_iterator(void *pipeline) +{ + PathCleanupIterator *pipeline_iter = (PathCleanupIterator *)pipeline; + + delete pipeline_iter; +} +} diff --git a/contrib/python/matplotlib/py2/src/path_cleanup.h b/contrib/python/matplotlib/py2/src/path_cleanup.h new file mode 100644 index 0000000000..b481395aa5 --- /dev/null +++ b/contrib/python/matplotlib/py2/src/path_cleanup.h @@ -0,0 +1,27 @@ +/* -*- mode: c++; c-basic-offset: 4 -*- */ + +#ifndef PATH_CLEANUP_H +#define PATH_CLEANUP_H + +#include <Python.h> + +enum e_snap_mode { + SNAP_AUTO, + SNAP_FALSE, + SNAP_TRUE +}; + +void *get_path_iterator(PyObject *path, + PyObject *trans, + int remove_nans, + int do_clip, + double rect[4], + enum e_snap_mode snap_mode, + double stroke_width, + int do_simplify); + +unsigned get_vertex(void *pipeline, double *x, double *y); + +void free_path_iterator(void *pipeline); + +#endif /* PATH_CLEANUP_H */ |