aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python/matplotlib/py2/src
diff options
context:
space:
mode:
authormaxim-yurchuk <maxim-yurchuk@yandex-team.com>2025-02-11 13:26:52 +0300
committermaxim-yurchuk <maxim-yurchuk@yandex-team.com>2025-02-11 13:57:59 +0300
commitf895bba65827952ed934b2b46f9a45e30a191fd2 (patch)
tree03260c906d9ec41cdc03e2a496b15d407459cec0 /contrib/python/matplotlib/py2/src
parent5f7060466f7b9707818c2091e1a25c14f33c3474 (diff)
downloadydb-f895bba65827952ed934b2b46f9a45e30a191fd2.tar.gz
Remove deps on pandas
<https://github.com/ydb-platform/ydb/pull/14418> <https://github.com/ydb-platform/ydb/pull/14419> \-- аналогичные правки в gh Хочу залить в обход синка, чтобы посмотреть удалится ли pandas в нашей gh репе через piglet commit_hash:abca127aa37d4dbb94b07e1e18cdb8eb5b711860
Diffstat (limited to 'contrib/python/matplotlib/py2/src')
-rw-r--r--contrib/python/matplotlib/py2/src/_backend_agg.cpp234
-rw-r--r--contrib/python/matplotlib/py2/src/_backend_agg.h1294
-rw-r--r--contrib/python/matplotlib/py2/src/_backend_agg_basic_types.h127
-rw-r--r--contrib/python/matplotlib/py2/src/_backend_agg_wrapper.cpp777
-rw-r--r--contrib/python/matplotlib/py2/src/_backend_gdk.c72
-rw-r--r--contrib/python/matplotlib/py2/src/_contour.cpp1790
-rw-r--r--contrib/python/matplotlib/py2/src/_contour.h530
-rw-r--r--contrib/python/matplotlib/py2/src/_contour_wrapper.cpp203
-rw-r--r--contrib/python/matplotlib/py2/src/_gtkagg.cpp155
-rw-r--r--contrib/python/matplotlib/py2/src/_image.cpp175
-rw-r--r--contrib/python/matplotlib/py2/src/_image.h200
-rw-r--r--contrib/python/matplotlib/py2/src/_image_resample.h1013
-rw-r--r--contrib/python/matplotlib/py2/src/_image_wrapper.cpp510
-rw-r--r--contrib/python/matplotlib/py2/src/_macosx.m3174
-rw-r--r--contrib/python/matplotlib/py2/src/_path.h1316
-rw-r--r--contrib/python/matplotlib/py2/src/_path_wrapper.cpp900
-rw-r--r--contrib/python/matplotlib/py2/src/_png.cpp793
-rw-r--r--contrib/python/matplotlib/py2/src/_tkagg.cpp475
-rw-r--r--contrib/python/matplotlib/py2/src/_tkmini.h128
-rw-r--r--contrib/python/matplotlib/py2/src/_ttconv.cpp307
-rw-r--r--contrib/python/matplotlib/py2/src/_windowing.cpp64
-rw-r--r--contrib/python/matplotlib/py2/src/agg_workaround.h85
-rw-r--r--contrib/python/matplotlib/py2/src/array.h80
-rw-r--r--contrib/python/matplotlib/py2/src/file_compat.h240
-rw-r--r--contrib/python/matplotlib/py2/src/ft2font.cpp808
-rw-r--r--contrib/python/matplotlib/py2/src/ft2font.h139
-rw-r--r--contrib/python/matplotlib/py2/src/ft2font_wrapper.cpp1808
-rw-r--r--contrib/python/matplotlib/py2/src/mplutils.cpp21
-rw-r--r--contrib/python/matplotlib/py2/src/mplutils.h73
-rw-r--r--contrib/python/matplotlib/py2/src/numpy_cpp.h569
-rw-r--r--contrib/python/matplotlib/py2/src/path_cleanup.cpp113
-rw-r--r--contrib/python/matplotlib/py2/src/path_cleanup.h27
-rw-r--r--contrib/python/matplotlib/py2/src/path_converters.h1011
-rw-r--r--contrib/python/matplotlib/py2/src/py_adaptors.h251
-rw-r--r--contrib/python/matplotlib/py2/src/py_converters.cpp619
-rw-r--r--contrib/python/matplotlib/py2/src/py_converters.h49
-rw-r--r--contrib/python/matplotlib/py2/src/py_exceptions.h72
-rw-r--r--contrib/python/matplotlib/py2/src/qhull_wrap.c378
-rw-r--r--contrib/python/matplotlib/py2/src/ya.make68
39 files changed, 0 insertions, 20648 deletions
diff --git a/contrib/python/matplotlib/py2/src/_backend_agg.cpp b/contrib/python/matplotlib/py2/src/_backend_agg.cpp
deleted file mode 100644
index 3dc35f6782..0000000000
--- a/contrib/python/matplotlib/py2/src/_backend_agg.cpp
+++ /dev/null
@@ -1,234 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-#define NO_IMPORT_ARRAY
-
-#include "_backend_agg.h"
-#include "mplutils.h"
-
-void BufferRegion::to_string_argb(uint8_t *buf)
-{
- unsigned char *pix;
- unsigned char tmp;
- size_t i, j;
-
- memcpy(buf, data, height * stride);
-
- for (i = 0; i < (size_t)height; ++i) {
- pix = buf + i * stride;
- for (j = 0; j < (size_t)width; ++j) {
- // Convert rgba to argb
- tmp = pix[2];
- pix[2] = pix[0];
- pix[0] = tmp;
- pix += 4;
- }
- }
-}
-
-RendererAgg::RendererAgg(unsigned int width, unsigned int height, double dpi)
- : width(width),
- height(height),
- dpi(dpi),
- NUMBYTES(width * height * 4),
- pixBuffer(NULL),
- renderingBuffer(),
- alphaBuffer(NULL),
- alphaMaskRenderingBuffer(),
- alphaMask(alphaMaskRenderingBuffer),
- pixfmtAlphaMask(alphaMaskRenderingBuffer),
- rendererBaseAlphaMask(),
- rendererAlphaMask(),
- scanlineAlphaMask(),
- slineP8(),
- slineBin(),
- pixFmt(),
- rendererBase(),
- rendererAA(),
- rendererBin(),
- theRasterizer(8192),
- lastclippath(NULL),
- _fill_color(agg::rgba(1, 1, 1, 0))
-{
- unsigned stride(width * 4);
-
- pixBuffer = new agg::int8u[NUMBYTES];
- renderingBuffer.attach(pixBuffer, width, height, stride);
- pixFmt.attach(renderingBuffer);
- rendererBase.attach(pixFmt);
- rendererBase.clear(_fill_color);
- rendererAA.attach(rendererBase);
- rendererBin.attach(rendererBase);
- hatch_size = int(dpi);
- hatchBuffer = new agg::int8u[hatch_size * hatch_size * 4];
- hatchRenderingBuffer.attach(hatchBuffer, hatch_size, hatch_size, hatch_size * 4);
-}
-
-RendererAgg::~RendererAgg()
-{
- delete[] hatchBuffer;
- delete[] alphaBuffer;
- delete[] pixBuffer;
-}
-
-void RendererAgg::create_alpha_buffers()
-{
- if (!alphaBuffer) {
- alphaBuffer = new agg::int8u[width * height];
- alphaMaskRenderingBuffer.attach(alphaBuffer, width, height, width);
- rendererBaseAlphaMask.attach(pixfmtAlphaMask);
- rendererAlphaMask.attach(rendererBaseAlphaMask);
- }
-}
-
-BufferRegion *RendererAgg::copy_from_bbox(agg::rect_d in_rect)
-{
- agg::rect_i rect(
- (int)in_rect.x1, height - (int)in_rect.y2, (int)in_rect.x2, height - (int)in_rect.y1);
-
- BufferRegion *reg = NULL;
- reg = new BufferRegion(rect);
-
- agg::rendering_buffer rbuf;
- rbuf.attach(reg->get_data(), reg->get_width(), reg->get_height(), reg->get_stride());
-
- pixfmt pf(rbuf);
- renderer_base rb(pf);
- rb.copy_from(renderingBuffer, &rect, -rect.x1, -rect.y1);
-
- return reg;
-}
-
-void RendererAgg::restore_region(BufferRegion &region)
-{
- if (region.get_data() == NULL) {
- throw std::runtime_error("Cannot restore_region from NULL data");
- }
-
- agg::rendering_buffer rbuf;
- rbuf.attach(region.get_data(), region.get_width(), region.get_height(), region.get_stride());
-
- rendererBase.copy_from(rbuf, 0, region.get_rect().x1, region.get_rect().y1);
-}
-
-// Restore the part of the saved region with offsets
-void
-RendererAgg::restore_region(BufferRegion &region, int xx1, int yy1, int xx2, int yy2, int x, int y )
-{
- if (region.get_data() == NULL) {
- throw std::runtime_error("Cannot restore_region from NULL data");
- }
-
- agg::rect_i &rrect = region.get_rect();
-
- agg::rect_i rect(xx1 - rrect.x1, (yy1 - rrect.y1), xx2 - rrect.x1, (yy2 - rrect.y1));
-
- agg::rendering_buffer rbuf;
- rbuf.attach(region.get_data(), region.get_width(), region.get_height(), region.get_stride());
-
- rendererBase.copy_from(rbuf, &rect, x, y);
-}
-
-bool RendererAgg::render_clippath(py::PathIterator &clippath,
- const agg::trans_affine &clippath_trans)
-{
- typedef agg::conv_transform<py::PathIterator> transformed_path_t;
- typedef agg::conv_curve<transformed_path_t> curve_t;
-
- bool has_clippath = (clippath.total_vertices() != 0);
-
- if (has_clippath &&
- (clippath.get_id() != lastclippath || clippath_trans != lastclippath_transform)) {
- create_alpha_buffers();
- agg::trans_affine trans(clippath_trans);
- trans *= agg::trans_affine_scaling(1.0, -1.0);
- trans *= agg::trans_affine_translation(0.0, (double)height);
-
- rendererBaseAlphaMask.clear(agg::gray8(0, 0));
- transformed_path_t transformed_clippath(clippath, trans);
- curve_t curved_clippath(transformed_clippath);
- theRasterizer.add_path(curved_clippath);
- rendererAlphaMask.color(agg::gray8(255, 255));
- agg::render_scanlines(theRasterizer, scanlineAlphaMask, rendererAlphaMask);
- lastclippath = clippath.get_id();
- lastclippath_transform = clippath_trans;
- }
-
- return has_clippath;
-}
-
-void RendererAgg::tostring_rgb(uint8_t *buf)
-{
- // "Return the rendered buffer as an RGB string"
-
- int row_len = width * 3;
-
- agg::rendering_buffer renderingBufferTmp;
- renderingBufferTmp.attach(buf, width, height, row_len);
-
- agg::color_conv(&renderingBufferTmp, &renderingBuffer, agg::color_conv_rgba32_to_rgb24());
-}
-
-void RendererAgg::tostring_argb(uint8_t *buf)
-{
- //"Return the rendered buffer as an RGB string";
-
- int row_len = width * 4;
-
- agg::rendering_buffer renderingBufferTmp;
- renderingBufferTmp.attach(buf, width, height, row_len);
- agg::color_conv(&renderingBufferTmp, &renderingBuffer, agg::color_conv_rgba32_to_argb32());
-}
-
-void RendererAgg::tostring_bgra(uint8_t *buf)
-{
- //"Return the rendered buffer as an RGB string";
-
- int row_len = width * 4;
-
- agg::rendering_buffer renderingBufferTmp;
- renderingBufferTmp.attach(buf, width, height, row_len);
-
- agg::color_conv(&renderingBufferTmp, &renderingBuffer, agg::color_conv_rgba32_to_bgra32());
-}
-
-agg::rect_i RendererAgg::get_content_extents()
-{
- agg::rect_i r(width, height, 0, 0);
-
- // Looks at the alpha channel to find the minimum extents of the image
- unsigned char *pixel = pixBuffer + 3;
- for (int y = 0; y < (int)height; ++y) {
- for (int x = 0; x < (int)width; ++x) {
- if (*pixel) {
- if (x < r.x1)
- r.x1 = x;
- if (y < r.y1)
- r.y1 = y;
- if (x > r.x2)
- r.x2 = x;
- if (y > r.y2)
- r.y2 = y;
- }
- pixel += 4;
- }
- }
-
- if (r.x1 == width && r.x2 == 0) {
- // The buffer is completely empty.
- r.x1 = r.y1 = r.x2 = r.y2 = 0;
- } else {
- r.x1 = std::max(0, r.x1);
- r.y1 = std::max(0, r.y1);
- r.x2 = std::min(r.x2 + 1, (int)width);
- r.y2 = std::min(r.y2 + 1, (int)height);
- }
-
- return r;
-}
-
-void RendererAgg::clear()
-{
- //"clear the rendered buffer";
-
- rendererBase.clear(_fill_color);
-}
diff --git a/contrib/python/matplotlib/py2/src/_backend_agg.h b/contrib/python/matplotlib/py2/src/_backend_agg.h
deleted file mode 100644
index 53b73f179b..0000000000
--- a/contrib/python/matplotlib/py2/src/_backend_agg.h
+++ /dev/null
@@ -1,1294 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-/* _backend_agg.h
-*/
-
-#ifndef __BACKEND_AGG_H__
-#define __BACKEND_AGG_H__
-
-#include <cmath>
-#include <vector>
-#include <algorithm>
-
-#include "agg_alpha_mask_u8.h"
-#include "agg_conv_curve.h"
-#include "agg_conv_dash.h"
-#include "agg_conv_stroke.h"
-#include "agg_image_accessors.h"
-#include "agg_pixfmt_amask_adaptor.h"
-#include "agg_pixfmt_gray.h"
-#include "agg_pixfmt_rgba.h"
-#include "agg_rasterizer_scanline_aa.h"
-#include "agg_renderer_base.h"
-#include "agg_renderer_scanline.h"
-#include "agg_rendering_buffer.h"
-#include "agg_scanline_bin.h"
-#include "agg_scanline_p.h"
-#include "agg_scanline_storage_aa.h"
-#include "agg_scanline_storage_bin.h"
-#include "agg_scanline_u.h"
-#include "agg_span_allocator.h"
-#include "agg_span_converter.h"
-#include "agg_span_gouraud_rgba.h"
-#include "agg_span_image_filter_gray.h"
-#include "agg_span_image_filter_rgba.h"
-#include "agg_span_interpolator_linear.h"
-#include "agg_span_pattern_rgba.h"
-#include "util/agg_color_conv_rgb8.h"
-
-#include "_backend_agg_basic_types.h"
-#include "path_converters.h"
-#include "array.h"
-#include "agg_workaround.h"
-
-/**********************************************************************/
-
-// a helper class to pass agg::buffer objects around. agg::buffer is
-// a class in the swig wrapper
-class BufferRegion
-{
- public:
- BufferRegion(const agg::rect_i &r) : rect(r)
- {
- width = r.x2 - r.x1;
- height = r.y2 - r.y1;
- stride = width * 4;
- data = new agg::int8u[stride * height];
- }
-
- virtual ~BufferRegion()
- {
- delete[] data;
- };
-
- agg::int8u *get_data()
- {
- return data;
- }
-
- agg::rect_i &get_rect()
- {
- return rect;
- }
-
- int get_width()
- {
- return width;
- }
-
- int get_height()
- {
- return height;
- }
-
- int get_stride()
- {
- return stride;
- }
-
- void to_string_argb(uint8_t *buf);
-
- private:
- agg::int8u *data;
- agg::rect_i rect;
- int width;
- int height;
- int stride;
-
- private:
- // prevent copying
- BufferRegion(const BufferRegion &);
- BufferRegion &operator=(const BufferRegion &);
-};
-
-#define MARKER_CACHE_SIZE 512
-
-// the renderer
-class RendererAgg
-{
- public:
-
- typedef fixed_blender_rgba_plain<agg::rgba8, agg::order_rgba> fixed_blender_rgba32_plain;
- typedef agg::pixfmt_alpha_blend_rgba<fixed_blender_rgba32_plain, agg::rendering_buffer> pixfmt;
- typedef agg::renderer_base<pixfmt> renderer_base;
- typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_aa;
- typedef agg::renderer_scanline_bin_solid<renderer_base> renderer_bin;
- typedef agg::rasterizer_scanline_aa<agg::rasterizer_sl_clip_dbl> rasterizer;
-
- typedef agg::scanline_p8 scanline_p8;
- typedef agg::scanline_bin scanline_bin;
- typedef agg::amask_no_clip_gray8 alpha_mask_type;
- typedef agg::scanline_u8_am<alpha_mask_type> scanline_am;
-
- typedef agg::renderer_base<agg::pixfmt_gray8> renderer_base_alpha_mask_type;
- typedef agg::renderer_scanline_aa_solid<renderer_base_alpha_mask_type> renderer_alpha_mask_type;
-
- /* TODO: Remove facepair_t */
- typedef std::pair<bool, agg::rgba> facepair_t;
-
- RendererAgg(unsigned int width, unsigned int height, double dpi);
-
- virtual ~RendererAgg();
-
- unsigned int get_width()
- {
- return width;
- }
-
- unsigned int get_height()
- {
- return height;
- }
-
- template <class PathIterator>
- void draw_path(GCAgg &gc, PathIterator &path, agg::trans_affine &trans, agg::rgba &color);
-
- template <class PathIterator>
- void draw_markers(GCAgg &gc,
- PathIterator &marker_path,
- agg::trans_affine &marker_path_trans,
- PathIterator &path,
- agg::trans_affine &trans,
- agg::rgba face);
-
- template <class ImageArray>
- void draw_text_image(GCAgg &gc, ImageArray &image, int x, int y, double angle);
-
- template <class ImageArray>
- void draw_image(GCAgg &gc,
- double x,
- double y,
- ImageArray &image);
-
- template <class PathGenerator,
- class TransformArray,
- class OffsetArray,
- class ColorArray,
- class LineWidthArray,
- class AntialiasedArray>
- void draw_path_collection(GCAgg &gc,
- agg::trans_affine &master_transform,
- PathGenerator &path,
- TransformArray &transforms,
- OffsetArray &offsets,
- agg::trans_affine &offset_trans,
- ColorArray &facecolors,
- ColorArray &edgecolors,
- LineWidthArray &linewidths,
- DashesVector &linestyles,
- AntialiasedArray &antialiaseds,
- e_offset_position offset_position);
-
- template <class CoordinateArray, class OffsetArray, class ColorArray>
- void draw_quad_mesh(GCAgg &gc,
- agg::trans_affine &master_transform,
- unsigned int mesh_width,
- unsigned int mesh_height,
- CoordinateArray &coordinates,
- OffsetArray &offsets,
- agg::trans_affine &offset_trans,
- ColorArray &facecolors,
- bool antialiased,
- ColorArray &edgecolors);
-
- template <class PointArray, class ColorArray>
- void draw_gouraud_triangle(GCAgg &gc,
- PointArray &points,
- ColorArray &colors,
- agg::trans_affine &trans);
-
- template <class PointArray, class ColorArray>
- void draw_gouraud_triangles(GCAgg &gc,
- PointArray &points,
- ColorArray &colors,
- agg::trans_affine &trans);
-
- void tostring_rgb(uint8_t *buf);
- void tostring_argb(uint8_t *buf);
- void tostring_bgra(uint8_t *buf);
- agg::rect_i get_content_extents();
- void clear();
-
- BufferRegion *copy_from_bbox(agg::rect_d in_rect);
- void restore_region(BufferRegion &reg);
- void restore_region(BufferRegion &region, int xx1, int yy1, int xx2, int yy2, int x, int y);
-
- unsigned int width, height;
- double dpi;
- size_t NUMBYTES; // the number of bytes in buffer
-
- agg::int8u *pixBuffer;
- agg::rendering_buffer renderingBuffer;
-
- agg::int8u *alphaBuffer;
- agg::rendering_buffer alphaMaskRenderingBuffer;
- alpha_mask_type alphaMask;
- agg::pixfmt_gray8 pixfmtAlphaMask;
- renderer_base_alpha_mask_type rendererBaseAlphaMask;
- renderer_alpha_mask_type rendererAlphaMask;
- scanline_am scanlineAlphaMask;
-
- scanline_p8 slineP8;
- scanline_bin slineBin;
- pixfmt pixFmt;
- renderer_base rendererBase;
- renderer_aa rendererAA;
- renderer_bin rendererBin;
- rasterizer theRasterizer;
-
- void *lastclippath;
- agg::trans_affine lastclippath_transform;
-
- size_t hatch_size;
- agg::int8u *hatchBuffer;
- agg::rendering_buffer hatchRenderingBuffer;
-
- agg::rgba _fill_color;
-
- protected:
- inline double points_to_pixels(double points)
- {
- return points * dpi / 72.0;
- }
-
- template <class R>
- void set_clipbox(const agg::rect_d &cliprect, R &rasterizer);
-
- bool render_clippath(py::PathIterator &clippath, const agg::trans_affine &clippath_trans);
-
- template <class PathIteratorType>
- void _draw_path(PathIteratorType &path, bool has_clippath, const facepair_t &face, GCAgg &gc);
-
- template <class PathIterator,
- class PathGenerator,
- class TransformArray,
- class OffsetArray,
- class ColorArray,
- class LineWidthArray,
- class AntialiasedArray>
- void _draw_path_collection_generic(GCAgg &gc,
- agg::trans_affine master_transform,
- const agg::rect_d &cliprect,
- PathIterator &clippath,
- const agg::trans_affine &clippath_trans,
- PathGenerator &path_generator,
- TransformArray &transforms,
- OffsetArray &offsets,
- const agg::trans_affine &offset_trans,
- ColorArray &facecolors,
- ColorArray &edgecolors,
- LineWidthArray &linewidths,
- DashesVector &linestyles,
- AntialiasedArray &antialiaseds,
- e_offset_position offset_position,
- int check_snap,
- int has_curves);
-
- template <class PointArray, class ColorArray>
- void _draw_gouraud_triangle(PointArray &points,
- ColorArray &colors,
- agg::trans_affine trans,
- bool has_clippath);
-
- private:
- void create_alpha_buffers();
-
- // prevent copying
- RendererAgg(const RendererAgg &);
- RendererAgg &operator=(const RendererAgg &);
-};
-
-/***************************************************************************
- * Implementation
- */
-
-template <class path_t>
-inline void
-RendererAgg::_draw_path(path_t &path, bool has_clippath, const facepair_t &face, GCAgg &gc)
-{
- typedef agg::conv_stroke<path_t> stroke_t;
- typedef agg::conv_dash<path_t> dash_t;
- typedef agg::conv_stroke<dash_t> stroke_dash_t;
- typedef agg::pixfmt_amask_adaptor<pixfmt, alpha_mask_type> pixfmt_amask_type;
- typedef agg::renderer_base<pixfmt_amask_type> amask_ren_type;
- typedef agg::renderer_scanline_aa_solid<amask_ren_type> amask_aa_renderer_type;
- typedef agg::renderer_scanline_bin_solid<amask_ren_type> amask_bin_renderer_type;
-
- // Render face
- if (face.first) {
- theRasterizer.add_path(path);
-
- if (gc.isaa) {
- if (has_clippath) {
- pixfmt_amask_type pfa(pixFmt, alphaMask);
- amask_ren_type r(pfa);
- amask_aa_renderer_type ren(r);
- ren.color(face.second);
- agg::render_scanlines(theRasterizer, scanlineAlphaMask, ren);
- } else {
- rendererAA.color(face.second);
- agg::render_scanlines(theRasterizer, slineP8, rendererAA);
- }
- } else {
- if (has_clippath) {
- pixfmt_amask_type pfa(pixFmt, alphaMask);
- amask_ren_type r(pfa);
- amask_bin_renderer_type ren(r);
- ren.color(face.second);
- agg::render_scanlines(theRasterizer, scanlineAlphaMask, ren);
- } else {
- rendererBin.color(face.second);
- agg::render_scanlines(theRasterizer, slineP8, rendererBin);
- }
- }
- }
-
- // Render hatch
- if (gc.has_hatchpath()) {
- // Reset any clipping that may be in effect, since we'll be
- // drawing the hatch in a scratch buffer at origin (0, 0)
- theRasterizer.reset_clipping();
- rendererBase.reset_clipping(true);
-
- // Create and transform the path
- typedef agg::conv_transform<py::PathIterator> hatch_path_trans_t;
- typedef agg::conv_curve<hatch_path_trans_t> hatch_path_curve_t;
- typedef agg::conv_stroke<hatch_path_curve_t> hatch_path_stroke_t;
-
- py::PathIterator hatch_path(gc.hatchpath);
- agg::trans_affine hatch_trans;
- hatch_trans *= agg::trans_affine_scaling(1.0, -1.0);
- hatch_trans *= agg::trans_affine_translation(0.0, 1.0);
- hatch_trans *= agg::trans_affine_scaling(hatch_size, hatch_size);
- hatch_path_trans_t hatch_path_trans(hatch_path, hatch_trans);
- hatch_path_curve_t hatch_path_curve(hatch_path_trans);
- hatch_path_stroke_t hatch_path_stroke(hatch_path_curve);
- hatch_path_stroke.width(points_to_pixels(gc.hatch_linewidth));
- hatch_path_stroke.line_cap(agg::square_cap);
-
- // Render the path into the hatch buffer
- pixfmt hatch_img_pixf(hatchRenderingBuffer);
- renderer_base rb(hatch_img_pixf);
- renderer_aa rs(rb);
- rb.clear(_fill_color);
- rs.color(gc.hatch_color);
-
- theRasterizer.add_path(hatch_path_curve);
- agg::render_scanlines(theRasterizer, slineP8, rs);
- theRasterizer.add_path(hatch_path_stroke);
- agg::render_scanlines(theRasterizer, slineP8, rs);
-
- // Put clipping back on, if originally set on entry to this
- // function
- set_clipbox(gc.cliprect, theRasterizer);
- if (has_clippath) {
- render_clippath(gc.clippath.path, gc.clippath.trans);
- }
-
- // Transfer the hatch to the main image buffer
- typedef agg::image_accessor_wrap<pixfmt,
- agg::wrap_mode_repeat_auto_pow2,
- agg::wrap_mode_repeat_auto_pow2> img_source_type;
- typedef agg::span_pattern_rgba<img_source_type> span_gen_type;
- agg::span_allocator<agg::rgba8> sa;
- img_source_type img_src(hatch_img_pixf);
- span_gen_type sg(img_src, 0, 0);
- theRasterizer.add_path(path);
-
- if (has_clippath) {
- pixfmt_amask_type pfa(pixFmt, alphaMask);
- amask_ren_type ren(pfa);
- agg::render_scanlines_aa(theRasterizer, slineP8, ren, sa, sg);
- } else {
- agg::render_scanlines_aa(theRasterizer, slineP8, rendererBase, sa, sg);
- }
- }
-
- // Render stroke
- if (gc.linewidth != 0.0) {
- double linewidth = points_to_pixels(gc.linewidth);
- if (!gc.isaa) {
- linewidth = (linewidth < 0.5) ? 0.5 : mpl_round(linewidth);
- }
- if (gc.dashes.size() == 0) {
- stroke_t stroke(path);
- stroke.width(points_to_pixels(gc.linewidth));
- stroke.line_cap(gc.cap);
- stroke.line_join(gc.join);
- stroke.miter_limit(points_to_pixels(gc.linewidth));
- theRasterizer.add_path(stroke);
- } else {
- dash_t dash(path);
- gc.dashes.dash_to_stroke(dash, dpi, gc.isaa);
- stroke_dash_t stroke(dash);
- stroke.line_cap(gc.cap);
- stroke.line_join(gc.join);
- stroke.width(linewidth);
- stroke.miter_limit(points_to_pixels(gc.linewidth));
- theRasterizer.add_path(stroke);
- }
-
- if (gc.isaa) {
- if (has_clippath) {
- pixfmt_amask_type pfa(pixFmt, alphaMask);
- amask_ren_type r(pfa);
- amask_aa_renderer_type ren(r);
- ren.color(gc.color);
- agg::render_scanlines(theRasterizer, scanlineAlphaMask, ren);
- } else {
- rendererAA.color(gc.color);
- agg::render_scanlines(theRasterizer, slineP8, rendererAA);
- }
- } else {
- if (has_clippath) {
- pixfmt_amask_type pfa(pixFmt, alphaMask);
- amask_ren_type r(pfa);
- amask_bin_renderer_type ren(r);
- ren.color(gc.color);
- agg::render_scanlines(theRasterizer, scanlineAlphaMask, ren);
- } else {
- rendererBin.color(gc.color);
- agg::render_scanlines(theRasterizer, slineBin, rendererBin);
- }
- }
- }
-}
-
-template <class PathIterator>
-inline void
-RendererAgg::draw_path(GCAgg &gc, PathIterator &path, agg::trans_affine &trans, agg::rgba &color)
-{
- typedef agg::conv_transform<py::PathIterator> transformed_path_t;
- typedef PathNanRemover<transformed_path_t> nan_removed_t;
- typedef PathClipper<nan_removed_t> clipped_t;
- typedef PathSnapper<clipped_t> snapped_t;
- typedef PathSimplifier<snapped_t> simplify_t;
- typedef agg::conv_curve<simplify_t> curve_t;
- typedef Sketch<curve_t> sketch_t;
-
- facepair_t face(color.a != 0.0, color);
-
- theRasterizer.reset_clipping();
- rendererBase.reset_clipping(true);
- set_clipbox(gc.cliprect, theRasterizer);
- bool has_clippath = render_clippath(gc.clippath.path, gc.clippath.trans);
-
- trans *= agg::trans_affine_scaling(1.0, -1.0);
- trans *= agg::trans_affine_translation(0.0, (double)height);
- bool clip = !face.first && !gc.has_hatchpath() && !path.has_curves();
- bool simplify = path.should_simplify() && clip;
- double snapping_linewidth = points_to_pixels(gc.linewidth);
- if (gc.color.a == 0.0) {
- snapping_linewidth = 0.0;
- }
-
- transformed_path_t tpath(path, trans);
- nan_removed_t nan_removed(tpath, true, path.has_curves());
- clipped_t clipped(nan_removed, clip && !path.has_curves(), width, height);
- snapped_t snapped(clipped, gc.snap_mode, path.total_vertices(), snapping_linewidth);
- simplify_t simplified(snapped, simplify, path.simplify_threshold());
- curve_t curve(simplified);
- sketch_t sketch(curve, gc.sketch.scale, gc.sketch.length, gc.sketch.randomness);
-
- _draw_path(sketch, has_clippath, face, gc);
-}
-
-template <class PathIterator>
-inline void RendererAgg::draw_markers(GCAgg &gc,
- PathIterator &marker_path,
- agg::trans_affine &marker_trans,
- PathIterator &path,
- agg::trans_affine &trans,
- agg::rgba color)
-{
- typedef agg::conv_transform<py::PathIterator> transformed_path_t;
- typedef PathNanRemover<transformed_path_t> nan_removed_t;
- typedef PathSnapper<nan_removed_t> snap_t;
- typedef agg::conv_curve<snap_t> curve_t;
- typedef agg::conv_stroke<curve_t> stroke_t;
- typedef agg::pixfmt_amask_adaptor<pixfmt, alpha_mask_type> pixfmt_amask_type;
- typedef agg::renderer_base<pixfmt_amask_type> amask_ren_type;
- typedef agg::renderer_scanline_aa_solid<amask_ren_type> amask_aa_renderer_type;
-
- // Deal with the difference in y-axis direction
- marker_trans *= agg::trans_affine_scaling(1.0, -1.0);
-
- trans *= agg::trans_affine_scaling(1.0, -1.0);
- trans *= agg::trans_affine_translation(0.5, (double)height + 0.5);
-
- transformed_path_t marker_path_transformed(marker_path, marker_trans);
- nan_removed_t marker_path_nan_removed(marker_path_transformed, true, marker_path.has_curves());
- snap_t marker_path_snapped(marker_path_nan_removed,
- gc.snap_mode,
- marker_path.total_vertices(),
- points_to_pixels(gc.linewidth));
- curve_t marker_path_curve(marker_path_snapped);
-
- if (!marker_path_snapped.is_snapping()) {
- // If the path snapper isn't in effect, at least make sure the marker
- // at (0, 0) is in the center of a pixel. This, importantly, makes
- // the circle markers look centered around the point they refer to.
- marker_trans *= agg::trans_affine_translation(0.5, 0.5);
- }
-
- transformed_path_t path_transformed(path, trans);
- nan_removed_t path_nan_removed(path_transformed, false, false);
- snap_t path_snapped(path_nan_removed, SNAP_FALSE, path.total_vertices(), 0.0);
- curve_t path_curve(path_snapped);
- path_curve.rewind(0);
-
- facepair_t face(color.a != 0.0, color);
-
- // maxim's suggestions for cached scanlines
- agg::scanline_storage_aa8 scanlines;
- theRasterizer.reset();
- theRasterizer.reset_clipping();
- rendererBase.reset_clipping(true);
- agg::rect_i marker_size(0x7FFFFFFF, 0x7FFFFFFF, -0x7FFFFFFF, -0x7FFFFFFF);
-
- agg::int8u staticFillCache[MARKER_CACHE_SIZE];
- agg::int8u staticStrokeCache[MARKER_CACHE_SIZE];
- agg::int8u *fillCache = staticFillCache;
- agg::int8u *strokeCache = staticStrokeCache;
-
- try
- {
- unsigned fillSize = 0;
- if (face.first) {
- theRasterizer.add_path(marker_path_curve);
- agg::render_scanlines(theRasterizer, slineP8, scanlines);
- fillSize = scanlines.byte_size();
- if (fillSize >= MARKER_CACHE_SIZE) {
- fillCache = new agg::int8u[fillSize];
- }
- scanlines.serialize(fillCache);
- marker_size = agg::rect_i(scanlines.min_x(),
- scanlines.min_y(),
- scanlines.max_x(),
- scanlines.max_y());
- }
-
- stroke_t stroke(marker_path_curve);
- stroke.width(points_to_pixels(gc.linewidth));
- stroke.line_cap(gc.cap);
- stroke.line_join(gc.join);
- stroke.miter_limit(points_to_pixels(gc.linewidth));
- theRasterizer.reset();
- theRasterizer.add_path(stroke);
- agg::render_scanlines(theRasterizer, slineP8, scanlines);
- unsigned strokeSize = scanlines.byte_size();
- if (strokeSize >= MARKER_CACHE_SIZE) {
- strokeCache = new agg::int8u[strokeSize];
- }
- scanlines.serialize(strokeCache);
- marker_size = agg::rect_i(std::min(marker_size.x1, scanlines.min_x()),
- std::min(marker_size.y1, scanlines.min_y()),
- std::max(marker_size.x2, scanlines.max_x()),
- std::max(marker_size.y2, scanlines.max_y()));
-
- theRasterizer.reset_clipping();
- rendererBase.reset_clipping(true);
- set_clipbox(gc.cliprect, rendererBase);
- bool has_clippath = render_clippath(gc.clippath.path, gc.clippath.trans);
-
- double x, y;
-
- agg::serialized_scanlines_adaptor_aa8 sa;
- agg::serialized_scanlines_adaptor_aa8::embedded_scanline sl;
-
- agg::rect_d clipping_rect(-1.0 - marker_size.x2,
- -1.0 - marker_size.y2,
- 1.0 + width - marker_size.x1,
- 1.0 + height - marker_size.y1);
-
- if (has_clippath) {
- while (path_curve.vertex(&x, &y) != agg::path_cmd_stop) {
- if (!(std::isfinite(x) && std::isfinite(y))) {
- continue;
- }
-
- /* These values are correctly snapped above -- so we don't want
- to round here, we really only want to truncate */
- x = floor(x);
- y = floor(y);
-
- // Cull points outside the boundary of the image.
- // Values that are too large may overflow and create
- // segfaults.
- // http://sourceforge.net/tracker/?func=detail&aid=2865490&group_id=80706&atid=560720
- if (!clipping_rect.hit_test(x, y)) {
- continue;
- }
-
- pixfmt_amask_type pfa(pixFmt, alphaMask);
- amask_ren_type r(pfa);
- amask_aa_renderer_type ren(r);
-
- if (face.first) {
- ren.color(face.second);
- sa.init(fillCache, fillSize, x, y);
- agg::render_scanlines(sa, sl, ren);
- }
- ren.color(gc.color);
- sa.init(strokeCache, strokeSize, x, y);
- agg::render_scanlines(sa, sl, ren);
- }
- } else {
- while (path_curve.vertex(&x, &y) != agg::path_cmd_stop) {
- if (!(std::isfinite(x) && std::isfinite(y))) {
- continue;
- }
-
- /* These values are correctly snapped above -- so we don't want
- to round here, we really only want to truncate */
- x = floor(x);
- y = floor(y);
-
- // Cull points outside the boundary of the image.
- // Values that are too large may overflow and create
- // segfaults.
- // http://sourceforge.net/tracker/?func=detail&aid=2865490&group_id=80706&atid=560720
- if (!clipping_rect.hit_test(x, y)) {
- continue;
- }
-
- if (face.first) {
- rendererAA.color(face.second);
- sa.init(fillCache, fillSize, x, y);
- agg::render_scanlines(sa, sl, rendererAA);
- }
-
- rendererAA.color(gc.color);
- sa.init(strokeCache, strokeSize, x, y);
- agg::render_scanlines(sa, sl, rendererAA);
- }
- }
- }
- catch (...)
- {
- if (fillCache != staticFillCache)
- delete[] fillCache;
- if (strokeCache != staticStrokeCache)
- delete[] strokeCache;
- theRasterizer.reset_clipping();
- rendererBase.reset_clipping(true);
- throw;
- }
-
- if (fillCache != staticFillCache)
- delete[] fillCache;
- if (strokeCache != staticStrokeCache)
- delete[] strokeCache;
-
- theRasterizer.reset_clipping();
- rendererBase.reset_clipping(true);
-}
-
-/**
- * This is a custom span generator that converts spans in the
- * 8-bit inverted greyscale font buffer to rgba that agg can use.
- */
-template <class ChildGenerator>
-class font_to_rgba
-{
- public:
- typedef ChildGenerator child_type;
- typedef agg::rgba8 color_type;
- typedef typename child_type::color_type child_color_type;
- typedef agg::span_allocator<child_color_type> span_alloc_type;
-
- private:
- child_type *_gen;
- color_type _color;
- span_alloc_type _allocator;
-
- public:
- font_to_rgba(child_type *gen, color_type color) : _gen(gen), _color(color)
- {
- }
-
- inline void generate(color_type *output_span, int x, int y, unsigned len)
- {
- _allocator.allocate(len);
- child_color_type *input_span = _allocator.span();
- _gen->generate(input_span, x, y, len);
-
- do {
- *output_span = _color;
- output_span->a = ((unsigned int)_color.a * (unsigned int)input_span->v) >> 8;
- ++output_span;
- ++input_span;
- } while (--len);
- }
-
- void prepare()
- {
- _gen->prepare();
- }
-};
-
-template <class ImageArray>
-inline void RendererAgg::draw_text_image(GCAgg &gc, ImageArray &image, int x, int y, double angle)
-{
- typedef agg::span_allocator<agg::rgba8> color_span_alloc_type;
- typedef agg::span_interpolator_linear<> interpolator_type;
- typedef agg::image_accessor_clip<agg::pixfmt_gray8> image_accessor_type;
- typedef agg::span_image_filter_gray<image_accessor_type, interpolator_type> image_span_gen_type;
- typedef font_to_rgba<image_span_gen_type> span_gen_type;
- typedef agg::renderer_scanline_aa<renderer_base, color_span_alloc_type, span_gen_type>
- renderer_type;
-
- theRasterizer.reset_clipping();
- rendererBase.reset_clipping(true);
- if (angle != 0.0) {
- agg::rendering_buffer srcbuf(
- image.data(), (unsigned)image.dim(1),
- (unsigned)image.dim(0), (unsigned)image.dim(1));
- agg::pixfmt_gray8 pixf_img(srcbuf);
-
- set_clipbox(gc.cliprect, theRasterizer);
-
- agg::trans_affine mtx;
- mtx *= agg::trans_affine_translation(0, -image.dim(0));
- mtx *= agg::trans_affine_rotation(-angle * agg::pi / 180.0);
- mtx *= agg::trans_affine_translation(x, y);
-
- agg::path_storage rect;
- rect.move_to(0, 0);
- rect.line_to(image.dim(1), 0);
- rect.line_to(image.dim(1), image.dim(0));
- rect.line_to(0, image.dim(0));
- rect.line_to(0, 0);
- agg::conv_transform<agg::path_storage> rect2(rect, mtx);
-
- agg::trans_affine inv_mtx(mtx);
- inv_mtx.invert();
-
- agg::image_filter_lut filter;
- filter.calculate(agg::image_filter_spline36());
- interpolator_type interpolator(inv_mtx);
- color_span_alloc_type sa;
- image_accessor_type ia(pixf_img, agg::gray8(0));
- image_span_gen_type image_span_generator(ia, interpolator, filter);
- span_gen_type output_span_generator(&image_span_generator, gc.color);
- renderer_type ri(rendererBase, sa, output_span_generator);
-
- theRasterizer.add_path(rect2);
- agg::render_scanlines(theRasterizer, slineP8, ri);
- } else {
- agg::rect_i fig, text;
-
- fig.init(0, 0, width, height);
- text.init(x, y - image.dim(0), x + image.dim(1), y);
- text.clip(fig);
-
- if (gc.cliprect.x1 != 0.0 || gc.cliprect.y1 != 0.0 || gc.cliprect.x2 != 0.0 || gc.cliprect.y2 != 0.0) {
- agg::rect_i clip;
-
- clip.init(int(mpl_round(gc.cliprect.x1)),
- int(mpl_round(height - gc.cliprect.y2)),
- int(mpl_round(gc.cliprect.x2)),
- int(mpl_round(height - gc.cliprect.y1)));
- text.clip(clip);
- }
-
- if (text.x2 > text.x1) {
- for (int yi = text.y1; yi < text.y2; ++yi) {
- pixFmt.blend_solid_hspan(text.x1, yi, (text.x2 - text.x1), gc.color,
- &image(yi - (y - image.dim(0)), text.x1 - x));
- }
- }
- }
-}
-
-class span_conv_alpha
-{
- public:
- typedef agg::rgba8 color_type;
-
- double m_alpha;
-
- span_conv_alpha(double alpha) : m_alpha(alpha)
- {
- }
-
- void prepare()
- {
- }
- void generate(color_type *span, int x, int y, unsigned len) const
- {
- do {
- span->a = (agg::int8u)((double)span->a * m_alpha);
- ++span;
- } while (--len);
- }
-};
-
-template <class ImageArray>
-inline void RendererAgg::draw_image(GCAgg &gc,
- double x,
- double y,
- ImageArray &image)
-{
- double alpha = gc.alpha;
-
- theRasterizer.reset_clipping();
- rendererBase.reset_clipping(true);
- set_clipbox(gc.cliprect, theRasterizer);
- bool has_clippath = render_clippath(gc.clippath.path, gc.clippath.trans);
-
- agg::rendering_buffer buffer;
- buffer.attach(
- image.data(), (unsigned)image.dim(1), (unsigned)image.dim(0), -(int)image.dim(1) * 4);
- pixfmt pixf(buffer);
-
- if (has_clippath) {
- agg::trans_affine mtx;
- agg::path_storage rect;
-
- mtx *= agg::trans_affine_translation((int)x, (int)(height - (y + image.dim(0))));
-
- rect.move_to(0, 0);
- rect.line_to(image.dim(1), 0);
- rect.line_to(image.dim(1), image.dim(0));
- rect.line_to(0, image.dim(0));
- rect.line_to(0, 0);
-
- agg::conv_transform<agg::path_storage> rect2(rect, mtx);
-
- agg::trans_affine inv_mtx(mtx);
- inv_mtx.invert();
-
- typedef agg::span_allocator<agg::rgba8> color_span_alloc_type;
- typedef agg::image_accessor_clip<pixfmt> image_accessor_type;
- typedef agg::span_interpolator_linear<> interpolator_type;
- typedef agg::span_image_filter_rgba_nn<image_accessor_type, interpolator_type>
- image_span_gen_type;
- typedef agg::span_converter<image_span_gen_type, span_conv_alpha> span_conv;
-
- color_span_alloc_type sa;
- image_accessor_type ia(pixf, agg::rgba8(0, 0, 0, 0));
- interpolator_type interpolator(inv_mtx);
- image_span_gen_type image_span_generator(ia, interpolator);
- span_conv_alpha conv_alpha(alpha);
- span_conv spans(image_span_generator, conv_alpha);
-
- typedef agg::pixfmt_amask_adaptor<pixfmt, alpha_mask_type> pixfmt_amask_type;
- typedef agg::renderer_base<pixfmt_amask_type> amask_ren_type;
- typedef agg::renderer_scanline_aa<amask_ren_type, color_span_alloc_type, span_conv>
- renderer_type_alpha;
-
- pixfmt_amask_type pfa(pixFmt, alphaMask);
- amask_ren_type r(pfa);
- renderer_type_alpha ri(r, sa, spans);
-
- theRasterizer.add_path(rect2);
- agg::render_scanlines(theRasterizer, scanlineAlphaMask, ri);
- } else {
- set_clipbox(gc.cliprect, rendererBase);
- rendererBase.blend_from(
- pixf, 0, (int)x, (int)(height - (y + image.dim(0))), (agg::int8u)(alpha * 255));
- }
-
- rendererBase.reset_clipping(true);
-}
-
-template <class PathIterator,
- class PathGenerator,
- class TransformArray,
- class OffsetArray,
- class ColorArray,
- class LineWidthArray,
- class AntialiasedArray>
-inline void RendererAgg::_draw_path_collection_generic(GCAgg &gc,
- agg::trans_affine master_transform,
- const agg::rect_d &cliprect,
- PathIterator &clippath,
- const agg::trans_affine &clippath_trans,
- PathGenerator &path_generator,
- TransformArray &transforms,
- OffsetArray &offsets,
- const agg::trans_affine &offset_trans,
- ColorArray &facecolors,
- ColorArray &edgecolors,
- LineWidthArray &linewidths,
- DashesVector &linestyles,
- AntialiasedArray &antialiaseds,
- e_offset_position offset_position,
- int check_snap,
- int has_curves)
-{
- typedef agg::conv_transform<typename PathGenerator::path_iterator> transformed_path_t;
- typedef PathNanRemover<transformed_path_t> nan_removed_t;
- typedef PathClipper<nan_removed_t> clipped_t;
- typedef PathSnapper<clipped_t> snapped_t;
- typedef agg::conv_curve<snapped_t> snapped_curve_t;
- typedef agg::conv_curve<clipped_t> curve_t;
-
- size_t Npaths = path_generator.num_paths();
- size_t Noffsets = offsets.size();
- size_t N = std::max(Npaths, Noffsets);
-
- size_t Ntransforms = transforms.size();
- size_t Nfacecolors = facecolors.size();
- size_t Nedgecolors = edgecolors.size();
- size_t Nlinewidths = linewidths.size();
- size_t Nlinestyles = std::min(linestyles.size(), N);
- size_t Naa = antialiaseds.size();
-
- if ((Nfacecolors == 0 && Nedgecolors == 0) || Npaths == 0) {
- return;
- }
-
- // Handle any clipping globally
- theRasterizer.reset_clipping();
- rendererBase.reset_clipping(true);
- set_clipbox(cliprect, theRasterizer);
- bool has_clippath = render_clippath(clippath, clippath_trans);
-
- // Set some defaults, assuming no face or edge
- gc.linewidth = 0.0;
- facepair_t face;
- face.first = Nfacecolors != 0;
- agg::trans_affine trans;
-
- for (int i = 0; i < (int)N; ++i) {
- typename PathGenerator::path_iterator path = path_generator(i);
-
- if (Ntransforms) {
- int it = i % Ntransforms;
- trans = agg::trans_affine(transforms(it, 0, 0),
- transforms(it, 1, 0),
- transforms(it, 0, 1),
- transforms(it, 1, 1),
- transforms(it, 0, 2),
- transforms(it, 1, 2));
- trans *= master_transform;
- } else {
- trans = master_transform;
- }
-
- if (Noffsets) {
- double xo = offsets(i % Noffsets, 0);
- double yo = offsets(i % Noffsets, 1);
- offset_trans.transform(&xo, &yo);
- if (offset_position == OFFSET_POSITION_DATA) {
- trans = agg::trans_affine_translation(xo, yo) * trans;
- } else {
- trans *= agg::trans_affine_translation(xo, yo);
- }
- }
-
- // These transformations must be done post-offsets
- trans *= agg::trans_affine_scaling(1.0, -1.0);
- trans *= agg::trans_affine_translation(0.0, (double)height);
-
- if (Nfacecolors) {
- int ic = i % Nfacecolors;
- face.second = agg::rgba(facecolors(ic, 0), facecolors(ic, 1), facecolors(ic, 2), facecolors(ic, 3));
- }
-
- if (Nedgecolors) {
- int ic = i % Nedgecolors;
- gc.color = agg::rgba(edgecolors(ic, 0), edgecolors(ic, 1), edgecolors(ic, 2), edgecolors(ic, 3));
-
- if (Nlinewidths) {
- gc.linewidth = linewidths(i % Nlinewidths);
- } else {
- gc.linewidth = 1.0;
- }
- if (Nlinestyles) {
- gc.dashes = linestyles[i % Nlinestyles];
- }
- }
-
- bool do_clip = !face.first && !gc.has_hatchpath() && !has_curves;
-
- if (check_snap) {
- gc.isaa = antialiaseds(i % Naa);
-
- transformed_path_t tpath(path, trans);
- nan_removed_t nan_removed(tpath, true, has_curves);
- clipped_t clipped(nan_removed, do_clip && !has_curves, width, height);
- snapped_t snapped(
- clipped, gc.snap_mode, path.total_vertices(), points_to_pixels(gc.linewidth));
- if (has_curves) {
- snapped_curve_t curve(snapped);
- _draw_path(curve, has_clippath, face, gc);
- } else {
- _draw_path(snapped, has_clippath, face, gc);
- }
- } else {
- gc.isaa = antialiaseds(i % Naa);
-
- transformed_path_t tpath(path, trans);
- nan_removed_t nan_removed(tpath, true, has_curves);
- clipped_t clipped(nan_removed, do_clip, width, height);
- if (has_curves) {
- curve_t curve(clipped);
- _draw_path(curve, has_clippath, face, gc);
- } else {
- _draw_path(clipped, has_clippath, face, gc);
- }
- }
- }
-}
-
-template <class PathGenerator,
- class TransformArray,
- class OffsetArray,
- class ColorArray,
- class LineWidthArray,
- class AntialiasedArray>
-inline void RendererAgg::draw_path_collection(GCAgg &gc,
- agg::trans_affine &master_transform,
- PathGenerator &path,
- TransformArray &transforms,
- OffsetArray &offsets,
- agg::trans_affine &offset_trans,
- ColorArray &facecolors,
- ColorArray &edgecolors,
- LineWidthArray &linewidths,
- DashesVector &linestyles,
- AntialiasedArray &antialiaseds,
- e_offset_position offset_position)
-{
- _draw_path_collection_generic(gc,
- master_transform,
- gc.cliprect,
- gc.clippath.path,
- gc.clippath.trans,
- path,
- transforms,
- offsets,
- offset_trans,
- facecolors,
- edgecolors,
- linewidths,
- linestyles,
- antialiaseds,
- offset_position,
- 1,
- 1);
-}
-
-template <class CoordinateArray>
-class QuadMeshGenerator
-{
- unsigned m_meshWidth;
- unsigned m_meshHeight;
- CoordinateArray m_coordinates;
-
- class QuadMeshPathIterator
- {
- unsigned m_iterator;
- unsigned m_m, m_n;
- const CoordinateArray *m_coordinates;
-
- public:
- QuadMeshPathIterator(unsigned m, unsigned n, const CoordinateArray *coordinates)
- : m_iterator(0), m_m(m), m_n(n), m_coordinates(coordinates)
- {
- }
-
- private:
- inline unsigned vertex(unsigned idx, double *x, double *y)
- {
- size_t m = m_m + ((idx & 0x2) >> 1);
- size_t n = m_n + (((idx + 1) & 0x2) >> 1);
- *x = (*m_coordinates)(n, m, 0);
- *y = (*m_coordinates)(n, m, 1);
- return (idx) ? agg::path_cmd_line_to : agg::path_cmd_move_to;
- }
-
- public:
- inline unsigned vertex(double *x, double *y)
- {
- if (m_iterator >= total_vertices()) {
- return agg::path_cmd_stop;
- }
- return vertex(m_iterator++, x, y);
- }
-
- inline void rewind(unsigned path_id)
- {
- m_iterator = path_id;
- }
-
- inline unsigned total_vertices()
- {
- return 5;
- }
-
- inline bool should_simplify()
- {
- return false;
- }
- };
-
- public:
- typedef QuadMeshPathIterator path_iterator;
-
- inline QuadMeshGenerator(unsigned meshWidth, unsigned meshHeight, CoordinateArray &coordinates)
- : m_meshWidth(meshWidth), m_meshHeight(meshHeight), m_coordinates(coordinates)
- {
- }
-
- inline size_t num_paths() const
- {
- return m_meshWidth * m_meshHeight;
- }
-
- inline path_iterator operator()(size_t i) const
- {
- return QuadMeshPathIterator(i % m_meshWidth, i / m_meshWidth, &m_coordinates);
- }
-};
-
-template <class CoordinateArray, class OffsetArray, class ColorArray>
-inline void RendererAgg::draw_quad_mesh(GCAgg &gc,
- agg::trans_affine &master_transform,
- unsigned int mesh_width,
- unsigned int mesh_height,
- CoordinateArray &coordinates,
- OffsetArray &offsets,
- agg::trans_affine &offset_trans,
- ColorArray &facecolors,
- bool antialiased,
- ColorArray &edgecolors)
-{
- QuadMeshGenerator<CoordinateArray> path_generator(mesh_width, mesh_height, coordinates);
-
- array::empty<double> transforms;
- array::scalar<double, 1> linewidths(gc.linewidth);
- array::scalar<uint8_t, 1> antialiaseds(antialiased);
- DashesVector linestyles;
- ColorArray *edgecolors_ptr = &edgecolors;
-
- if (edgecolors.size() == 0) {
- if (antialiased) {
- edgecolors_ptr = &facecolors;
- }
- }
-
- _draw_path_collection_generic(gc,
- master_transform,
- gc.cliprect,
- gc.clippath.path,
- gc.clippath.trans,
- path_generator,
- transforms,
- offsets,
- offset_trans,
- facecolors,
- *edgecolors_ptr,
- linewidths,
- linestyles,
- antialiaseds,
- OFFSET_POSITION_FIGURE,
- 0,
- 0);
-}
-
-template <class PointArray, class ColorArray>
-inline void RendererAgg::_draw_gouraud_triangle(PointArray &points,
- ColorArray &colors,
- agg::trans_affine trans,
- bool has_clippath)
-{
- typedef agg::rgba8 color_t;
- typedef agg::span_gouraud_rgba<color_t> span_gen_t;
- typedef agg::span_allocator<color_t> span_alloc_t;
-
- trans *= agg::trans_affine_scaling(1.0, -1.0);
- trans *= agg::trans_affine_translation(0.0, (double)height);
-
- double tpoints[3][2];
-
- for (int i = 0; i < 3; ++i) {
- for (int j = 0; j < 2; ++j) {
- tpoints[i][j] = points(i, j);
- }
- trans.transform(&tpoints[i][0], &tpoints[i][1]);
- }
-
- span_alloc_t span_alloc;
- span_gen_t span_gen;
-
- span_gen.colors(agg::rgba(colors(0, 0), colors(0, 1), colors(0, 2), colors(0, 3)),
- agg::rgba(colors(1, 0), colors(1, 1), colors(1, 2), colors(1, 3)),
- agg::rgba(colors(2, 0), colors(2, 1), colors(2, 2), colors(2, 3)));
- span_gen.triangle(tpoints[0][0],
- tpoints[0][1],
- tpoints[1][0],
- tpoints[1][1],
- tpoints[2][0],
- tpoints[2][1],
- 0.5);
-
- theRasterizer.add_path(span_gen);
-
- if (has_clippath) {
- typedef agg::pixfmt_amask_adaptor<pixfmt, alpha_mask_type> pixfmt_amask_type;
- typedef agg::renderer_base<pixfmt_amask_type> amask_ren_type;
- typedef agg::renderer_scanline_aa<amask_ren_type, span_alloc_t, span_gen_t>
- amask_aa_renderer_type;
-
- pixfmt_amask_type pfa(pixFmt, alphaMask);
- amask_ren_type r(pfa);
- amask_aa_renderer_type ren(r, span_alloc, span_gen);
- agg::render_scanlines(theRasterizer, scanlineAlphaMask, ren);
- } else {
- agg::render_scanlines_aa(theRasterizer, slineP8, rendererBase, span_alloc, span_gen);
- }
-}
-
-template <class PointArray, class ColorArray>
-inline void RendererAgg::draw_gouraud_triangle(GCAgg &gc,
- PointArray &points,
- ColorArray &colors,
- agg::trans_affine &trans)
-{
- theRasterizer.reset_clipping();
- rendererBase.reset_clipping(true);
- set_clipbox(gc.cliprect, theRasterizer);
- bool has_clippath = render_clippath(gc.clippath.path, gc.clippath.trans);
-
- _draw_gouraud_triangle(points, colors, trans, has_clippath);
-}
-
-template <class PointArray, class ColorArray>
-inline void RendererAgg::draw_gouraud_triangles(GCAgg &gc,
- PointArray &points,
- ColorArray &colors,
- agg::trans_affine &trans)
-{
- theRasterizer.reset_clipping();
- rendererBase.reset_clipping(true);
- set_clipbox(gc.cliprect, theRasterizer);
- bool has_clippath = render_clippath(gc.clippath.path, gc.clippath.trans);
-
- for (int i = 0; i < points.dim(0); ++i) {
- typename PointArray::sub_t point = points.subarray(i);
- typename ColorArray::sub_t color = colors.subarray(i);
-
- _draw_gouraud_triangle(point, color, trans, has_clippath);
- }
-}
-
-template <class R>
-void RendererAgg::set_clipbox(const agg::rect_d &cliprect, R &rasterizer)
-{
- // set the clip rectangle from the gc
-
- if (cliprect.x1 != 0.0 || cliprect.y1 != 0.0 || cliprect.x2 != 0.0 || cliprect.y2 != 0.0) {
- rasterizer.clip_box(std::max(int(floor(cliprect.x1 + 0.5)), 0),
- std::max(int(floor(height - cliprect.y1 + 0.5)), 0),
- std::min(int(floor(cliprect.x2 + 0.5)), int(width)),
- std::min(int(floor(height - cliprect.y2 + 0.5)), int(height)));
- } else {
- rasterizer.clip_box(0, 0, width, height);
- }
-}
-
-#endif
diff --git a/contrib/python/matplotlib/py2/src/_backend_agg_basic_types.h b/contrib/python/matplotlib/py2/src/_backend_agg_basic_types.h
deleted file mode 100644
index 74a318e7d2..0000000000
--- a/contrib/python/matplotlib/py2/src/_backend_agg_basic_types.h
+++ /dev/null
@@ -1,127 +0,0 @@
-#ifndef __BACKEND_AGG_BASIC_TYPES_H__
-#define __BACKEND_AGG_BASIC_TYPES_H__
-
-/* Contains some simple types from the Agg backend that are also used
- by other modules */
-
-#include <vector>
-
-#include "agg_color_rgba.h"
-#include "agg_math_stroke.h"
-#include "path_converters.h"
-
-#include "py_adaptors.h"
-
-struct ClipPath
-{
- py::PathIterator path;
- agg::trans_affine trans;
-};
-
-struct SketchParams
-{
- double scale;
- double length;
- double randomness;
-};
-
-class Dashes
-{
- typedef std::vector<std::pair<double, double> > dash_t;
- double dash_offset;
- dash_t dashes;
-
- public:
- double get_dash_offset() const
- {
- return dash_offset;
- }
- void set_dash_offset(double x)
- {
- dash_offset = x;
- }
- void add_dash_pair(double length, double skip)
- {
- dashes.push_back(std::make_pair(length, skip));
- }
- size_t size() const
- {
- return dashes.size();
- }
-
- template <class T>
- void dash_to_stroke(T &stroke, double dpi, bool isaa)
- {
- for (dash_t::const_iterator i = dashes.begin(); i != dashes.end(); ++i) {
- double val0 = i->first;
- double val1 = i->second;
- val0 = val0 * dpi / 72.0;
- val1 = val1 * dpi / 72.0;
- if (!isaa) {
- val0 = (int)val0 + 0.5;
- val1 = (int)val1 + 0.5;
- }
- stroke.add_dash(val0, val1);
- }
- stroke.dash_start(get_dash_offset() * dpi / 72.0);
- }
-};
-
-typedef std::vector<Dashes> DashesVector;
-
-enum e_offset_position {
- OFFSET_POSITION_FIGURE,
- OFFSET_POSITION_DATA
-};
-
-class GCAgg
-{
- public:
- GCAgg()
- : linewidth(1.0),
- alpha(1.0),
- cap(agg::butt_cap),
- join(agg::round_join),
- snap_mode(SNAP_FALSE)
- {
- }
-
- ~GCAgg()
- {
- }
-
- double linewidth;
- double alpha;
- bool forced_alpha;
- agg::rgba color;
- bool isaa;
-
- agg::line_cap_e cap;
- agg::line_join_e join;
-
- agg::rect_d cliprect;
-
- ClipPath clippath;
-
- Dashes dashes;
-
- e_snap_mode snap_mode;
-
- py::PathIterator hatchpath;
- agg::rgba hatch_color;
- double hatch_linewidth;
-
- SketchParams sketch;
-
- bool has_hatchpath()
- {
- return hatchpath.total_vertices();
- }
-
- private:
- // prevent copying
- GCAgg(const GCAgg &);
- GCAgg &operator=(const GCAgg &);
-};
-
-#endif
diff --git a/contrib/python/matplotlib/py2/src/_backend_agg_wrapper.cpp b/contrib/python/matplotlib/py2/src/_backend_agg_wrapper.cpp
deleted file mode 100644
index ea6c7b1267..0000000000
--- a/contrib/python/matplotlib/py2/src/_backend_agg_wrapper.cpp
+++ /dev/null
@@ -1,777 +0,0 @@
-#include "mplutils.h"
-#include "py_converters.h"
-#include "_backend_agg.h"
-
-typedef struct
-{
- PyObject_HEAD
- RendererAgg *x;
- Py_ssize_t shape[3];
- Py_ssize_t strides[3];
- Py_ssize_t suboffsets[3];
-} PyRendererAgg;
-
-typedef struct
-{
- PyObject_HEAD
- BufferRegion *x;
- Py_ssize_t shape[3];
- Py_ssize_t strides[3];
- Py_ssize_t suboffsets[3];
-} PyBufferRegion;
-
-
-/**********************************************************************
- * BufferRegion
- * */
-
-static PyObject *PyBufferRegion_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
- PyBufferRegion *self;
- self = (PyBufferRegion *)type->tp_alloc(type, 0);
- self->x = NULL;
- return (PyObject *)self;
-}
-
-static void PyBufferRegion_dealloc(PyBufferRegion *self)
-{
- delete self->x;
- Py_TYPE(self)->tp_free((PyObject *)self);
-}
-
-static PyObject *PyBufferRegion_to_string(PyBufferRegion *self, PyObject *args, PyObject *kwds)
-{
- return PyBytes_FromStringAndSize((const char *)self->x->get_data(),
- self->x->get_height() * self->x->get_stride());
-}
-
-/* TODO: This doesn't seem to be used internally. Remove? */
-
-static PyObject *PyBufferRegion_set_x(PyBufferRegion *self, PyObject *args, PyObject *kwds)
-{
- int x;
- if (!PyArg_ParseTuple(args, "i:set_x", &x)) {
- return NULL;
- }
- self->x->get_rect().x1 = x;
-
- Py_RETURN_NONE;
-}
-
-static PyObject *PyBufferRegion_set_y(PyBufferRegion *self, PyObject *args, PyObject *kwds)
-{
- int y;
- if (!PyArg_ParseTuple(args, "i:set_y", &y)) {
- return NULL;
- }
- self->x->get_rect().y1 = y;
-
- Py_RETURN_NONE;
-}
-
-static PyObject *PyBufferRegion_get_extents(PyBufferRegion *self, PyObject *args, PyObject *kwds)
-{
- agg::rect_i rect = self->x->get_rect();
-
- return Py_BuildValue("IIII", rect.x1, rect.y1, rect.x2, rect.y2);
-}
-
-static PyObject *PyBufferRegion_to_string_argb(PyBufferRegion *self, PyObject *args, PyObject *kwds)
-{
- PyObject *bufobj;
- uint8_t *buf;
-
- bufobj = PyBytes_FromStringAndSize(NULL, self->x->get_height() * self->x->get_stride());
- buf = (uint8_t *)PyBytes_AS_STRING(bufobj);
-
- CALL_CPP_CLEANUP("to_string_argb", (self->x->to_string_argb(buf)), Py_DECREF(bufobj));
-
- return bufobj;
-}
-
-int PyBufferRegion_get_buffer(PyBufferRegion *self, Py_buffer *buf, int flags)
-{
- Py_INCREF(self);
- buf->obj = (PyObject *)self;
- buf->buf = self->x->get_data();
- buf->len = self->x->get_width() * self->x->get_height() * 4;
- buf->readonly = 0;
- buf->format = (char *)"B";
- buf->ndim = 3;
- self->shape[0] = self->x->get_height();
- self->shape[1] = self->x->get_width();
- self->shape[2] = 4;
- buf->shape = self->shape;
- self->strides[0] = self->x->get_width() * 4;
- self->strides[1] = 4;
- self->strides[2] = 1;
- buf->strides = self->strides;
- buf->suboffsets = NULL;
- buf->itemsize = 1;
- buf->internal = NULL;
-
- return 1;
-}
-
-static PyTypeObject PyBufferRegionType;
-
-static PyTypeObject *PyBufferRegion_init_type(PyObject *m, PyTypeObject *type)
-{
- static PyMethodDef methods[] = {
- { "to_string", (PyCFunction)PyBufferRegion_to_string, METH_NOARGS, NULL },
- { "to_string_argb", (PyCFunction)PyBufferRegion_to_string_argb, METH_NOARGS, NULL },
- { "set_x", (PyCFunction)PyBufferRegion_set_x, METH_VARARGS, NULL },
- { "set_y", (PyCFunction)PyBufferRegion_set_y, METH_VARARGS, NULL },
- { "get_extents", (PyCFunction)PyBufferRegion_get_extents, METH_NOARGS, NULL },
- { NULL }
- };
-
- static PyBufferProcs buffer_procs;
- memset(&buffer_procs, 0, sizeof(PyBufferProcs));
- buffer_procs.bf_getbuffer = (getbufferproc)PyBufferRegion_get_buffer;
-
- memset(type, 0, sizeof(PyTypeObject));
- type->tp_name = "matplotlib.backends._backend_agg.BufferRegion";
- type->tp_basicsize = sizeof(PyBufferRegion);
- type->tp_dealloc = (destructor)PyBufferRegion_dealloc;
- type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_NEWBUFFER;
- type->tp_methods = methods;
- type->tp_new = PyBufferRegion_new;
- type->tp_as_buffer = &buffer_procs;
-
- if (PyType_Ready(type) < 0) {
- return NULL;
- }
-
- /* Don't need to add to module, since you can't create buffer
- regions directly from Python */
-
- return type;
-}
-
-/**********************************************************************
- * RendererAgg
- * */
-
-static PyObject *PyRendererAgg_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
- PyRendererAgg *self;
- self = (PyRendererAgg *)type->tp_alloc(type, 0);
- self->x = NULL;
- return (PyObject *)self;
-}
-
-static int PyRendererAgg_init(PyRendererAgg *self, PyObject *args, PyObject *kwds)
-{
- unsigned int width;
- unsigned int height;
- double dpi;
- int debug = 0;
-
- if (!PyArg_ParseTuple(args, "IId|i:RendererAgg", &width, &height, &dpi, &debug)) {
- return -1;
- }
-
- if (dpi <= 0.0) {
- PyErr_SetString(PyExc_ValueError, "dpi must be positive");
- return -1;
- }
-
- if (width >= 1 << 16 || height >= 1 << 16) {
- PyErr_Format(
- PyExc_ValueError,
- "Image size of %dx%d pixels is too large. "
- "It must be less than 2^16 in each direction.",
- width, height);
- return -1;
- }
-
- CALL_CPP_INIT("RendererAgg", self->x = new RendererAgg(width, height, dpi))
-
- return 0;
-}
-
-static void PyRendererAgg_dealloc(PyRendererAgg *self)
-{
- delete self->x;
- Py_TYPE(self)->tp_free((PyObject *)self);
-}
-
-static PyObject *PyRendererAgg_draw_path(PyRendererAgg *self, PyObject *args, PyObject *kwds)
-{
- GCAgg gc;
- py::PathIterator path;
- agg::trans_affine trans;
- PyObject *faceobj = NULL;
- agg::rgba face;
-
- if (!PyArg_ParseTuple(args,
- "O&O&O&|O:draw_path",
- &convert_gcagg,
- &gc,
- &convert_path,
- &path,
- &convert_trans_affine,
- &trans,
- &faceobj)) {
- return NULL;
- }
-
- if (!convert_face(faceobj, gc, &face)) {
- return NULL;
- }
-
- CALL_CPP("draw_path", (self->x->draw_path(gc, path, trans, face)));
-
- Py_RETURN_NONE;
-}
-
-static PyObject *PyRendererAgg_draw_text_image(PyRendererAgg *self, PyObject *args, PyObject *kwds)
-{
- numpy::array_view<agg::int8u, 2> image;
- double x;
- double y;
- double angle;
- GCAgg gc;
-
- if (!PyArg_ParseTuple(args,
- "O&dddO&:draw_text_image",
- &image.converter_contiguous,
- &image,
- &x,
- &y,
- &angle,
- &convert_gcagg,
- &gc)) {
- return NULL;
- }
-
- CALL_CPP("draw_text_image", (self->x->draw_text_image(gc, image, x, y, angle)));
-
- Py_RETURN_NONE;
-}
-
-PyObject *PyRendererAgg_draw_markers(PyRendererAgg *self, PyObject *args, PyObject *kwds)
-{
- GCAgg gc;
- py::PathIterator marker_path;
- agg::trans_affine marker_path_trans;
- py::PathIterator path;
- agg::trans_affine trans;
- PyObject *faceobj = NULL;
- agg::rgba face;
-
- if (!PyArg_ParseTuple(args,
- "O&O&O&O&O&|O:draw_markers",
- &convert_gcagg,
- &gc,
- &convert_path,
- &marker_path,
- &convert_trans_affine,
- &marker_path_trans,
- &convert_path,
- &path,
- &convert_trans_affine,
- &trans,
- &faceobj)) {
- return NULL;
- }
-
- if (!convert_face(faceobj, gc, &face)) {
- return NULL;
- }
-
- CALL_CPP("draw_markers",
- (self->x->draw_markers(gc, marker_path, marker_path_trans, path, trans, face)));
-
- Py_RETURN_NONE;
-}
-
-static PyObject *PyRendererAgg_draw_image(PyRendererAgg *self, PyObject *args, PyObject *kwds)
-{
- GCAgg gc;
- double x;
- double y;
- numpy::array_view<agg::int8u, 3> image;
-
- if (!PyArg_ParseTuple(args,
- "O&ddO&:draw_image",
- &convert_gcagg,
- &gc,
- &x,
- &y,
- &image.converter_contiguous,
- &image)) {
- return NULL;
- }
-
- x = mpl_round(x);
- y = mpl_round(y);
-
- gc.alpha = 1.0;
- CALL_CPP("draw_image", (self->x->draw_image(gc, x, y, image)));
-
- Py_RETURN_NONE;
-}
-
-static PyObject *
-PyRendererAgg_draw_path_collection(PyRendererAgg *self, PyObject *args, PyObject *kwds)
-{
- GCAgg gc;
- agg::trans_affine master_transform;
- PyObject *pathobj;
- numpy::array_view<const double, 3> transforms;
- numpy::array_view<const double, 2> offsets;
- agg::trans_affine offset_trans;
- numpy::array_view<const double, 2> facecolors;
- numpy::array_view<const double, 2> edgecolors;
- numpy::array_view<const double, 1> linewidths;
- DashesVector dashes;
- numpy::array_view<const uint8_t, 1> antialiaseds;
- PyObject *ignored;
- e_offset_position offset_position;
-
- if (!PyArg_ParseTuple(args,
- "O&O&OO&O&O&O&O&O&O&O&OO&:draw_path_collection",
- &convert_gcagg,
- &gc,
- &convert_trans_affine,
- &master_transform,
- &pathobj,
- &convert_transforms,
- &transforms,
- &convert_points,
- &offsets,
- &convert_trans_affine,
- &offset_trans,
- &convert_colors,
- &facecolors,
- &convert_colors,
- &edgecolors,
- &linewidths.converter,
- &linewidths,
- &convert_dashes_vector,
- &dashes,
- &antialiaseds.converter,
- &antialiaseds,
- &ignored,
- &convert_offset_position,
- &offset_position)) {
- return NULL;
- }
-
- try
- {
- py::PathGenerator path(pathobj);
-
- CALL_CPP("draw_path_collection",
- (self->x->draw_path_collection(gc,
- master_transform,
- path,
- transforms,
- offsets,
- offset_trans,
- facecolors,
- edgecolors,
- linewidths,
- dashes,
- antialiaseds,
- offset_position)));
- }
- catch (const py::exception &)
- {
- return NULL;
- }
-
- Py_RETURN_NONE;
-}
-
-static PyObject *PyRendererAgg_draw_quad_mesh(PyRendererAgg *self, PyObject *args, PyObject *kwds)
-{
- GCAgg gc;
- agg::trans_affine master_transform;
- unsigned int mesh_width;
- unsigned int mesh_height;
- numpy::array_view<const double, 3> coordinates;
- numpy::array_view<const double, 2> offsets;
- agg::trans_affine offset_trans;
- numpy::array_view<const double, 2> facecolors;
- int antialiased;
- numpy::array_view<const double, 2> edgecolors;
-
- if (!PyArg_ParseTuple(args,
- "O&O&IIO&O&O&O&iO&:draw_quad_mesh",
- &convert_gcagg,
- &gc,
- &convert_trans_affine,
- &master_transform,
- &mesh_width,
- &mesh_height,
- &coordinates.converter,
- &coordinates,
- &convert_points,
- &offsets,
- &convert_trans_affine,
- &offset_trans,
- &convert_colors,
- &facecolors,
- &antialiased,
- &convert_colors,
- &edgecolors)) {
- return NULL;
- }
-
- CALL_CPP("draw_quad_mesh",
- (self->x->draw_quad_mesh(gc,
- master_transform,
- mesh_width,
- mesh_height,
- coordinates,
- offsets,
- offset_trans,
- facecolors,
- antialiased,
- edgecolors)));
-
- Py_RETURN_NONE;
-}
-
-static PyObject *
-PyRendererAgg_draw_gouraud_triangle(PyRendererAgg *self, PyObject *args, PyObject *kwds)
-{
- GCAgg gc;
- numpy::array_view<const double, 2> points;
- numpy::array_view<const double, 2> colors;
- agg::trans_affine trans;
-
- if (!PyArg_ParseTuple(args,
- "O&O&O&O&|O:draw_gouraud_triangle",
- &convert_gcagg,
- &gc,
- &points.converter,
- &points,
- &colors.converter,
- &colors,
- &convert_trans_affine,
- &trans)) {
- return NULL;
- }
-
- if (points.dim(0) != 3 || points.dim(1) != 2) {
- PyErr_Format(PyExc_ValueError,
- "points must be a 3x2 array, got %" NPY_INTP_FMT "x%" NPY_INTP_FMT,
- points.dim(0), points.dim(1));
- return NULL;
- }
-
- if (colors.dim(0) != 3 || colors.dim(1) != 4) {
- PyErr_Format(PyExc_ValueError,
- "colors must be a 3x4 array, got %" NPY_INTP_FMT "x%" NPY_INTP_FMT,
- colors.dim(0), colors.dim(1));
- return NULL;
- }
-
-
- CALL_CPP("draw_gouraud_triangle", (self->x->draw_gouraud_triangle(gc, points, colors, trans)));
-
- Py_RETURN_NONE;
-}
-
-static PyObject *
-PyRendererAgg_draw_gouraud_triangles(PyRendererAgg *self, PyObject *args, PyObject *kwds)
-{
- GCAgg gc;
- numpy::array_view<const double, 3> points;
- numpy::array_view<const double, 3> colors;
- agg::trans_affine trans;
-
- if (!PyArg_ParseTuple(args,
- "O&O&O&O&|O:draw_gouraud_triangles",
- &convert_gcagg,
- &gc,
- &points.converter,
- &points,
- &colors.converter,
- &colors,
- &convert_trans_affine,
- &trans)) {
- return NULL;
- }
-
- if (points.size() != 0 && (points.dim(1) != 3 || points.dim(2) != 2)) {
- PyErr_Format(PyExc_ValueError,
- "points must be a Nx3x2 array, got %" NPY_INTP_FMT "x%" NPY_INTP_FMT "x%" NPY_INTP_FMT,
- points.dim(0), points.dim(1), points.dim(2));
- return NULL;
- }
-
- if (colors.size() != 0 && (colors.dim(1) != 3 || colors.dim(2) != 4)) {
- PyErr_Format(PyExc_ValueError,
- "colors must be a Nx3x4 array, got %" NPY_INTP_FMT "x%" NPY_INTP_FMT "x%" NPY_INTP_FMT,
- colors.dim(0), colors.dim(1), colors.dim(2));
- return NULL;
- }
-
- if (points.size() != colors.size()) {
- PyErr_Format(PyExc_ValueError,
- "points and colors arrays must be the same length, got %" NPY_INTP_FMT " and %" NPY_INTP_FMT,
- points.dim(0), colors.dim(0));
- return NULL;
- }
-
- CALL_CPP("draw_gouraud_triangles", self->x->draw_gouraud_triangles(gc, points, colors, trans));
-
- Py_RETURN_NONE;
-}
-
-static PyObject *PyRendererAgg_tostring_rgb(PyRendererAgg *self, PyObject *args, PyObject *kwds)
-{
- PyObject *buffobj = NULL;
-
- buffobj = PyBytes_FromStringAndSize(NULL, self->x->get_width() * self->x->get_height() * 3);
- if (buffobj == NULL) {
- return NULL;
- }
-
- CALL_CPP_CLEANUP("tostring_rgb",
- (self->x->tostring_rgb((uint8_t *)PyBytes_AS_STRING(buffobj))),
- Py_DECREF(buffobj));
-
- return buffobj;
-}
-
-static PyObject *PyRendererAgg_tostring_argb(PyRendererAgg *self, PyObject *args, PyObject *kwds)
-{
- PyObject *buffobj = NULL;
-
- buffobj = PyBytes_FromStringAndSize(NULL, self->x->get_width() * self->x->get_height() * 4);
- if (buffobj == NULL) {
- return NULL;
- }
-
- CALL_CPP_CLEANUP("tostring_argb",
- (self->x->tostring_argb((uint8_t *)PyBytes_AS_STRING(buffobj))),
- Py_DECREF(buffobj));
-
- return buffobj;
-}
-
-static PyObject *PyRendererAgg_tostring_bgra(PyRendererAgg *self, PyObject *args, PyObject *kwds)
-{
- PyObject *buffobj = NULL;
-
- buffobj = PyBytes_FromStringAndSize(NULL, self->x->get_width() * self->x->get_height() * 4);
- if (buffobj == NULL) {
- return NULL;
- }
-
- CALL_CPP_CLEANUP("to_string_bgra",
- (self->x->tostring_bgra((uint8_t *)PyBytes_AS_STRING(buffobj))),
- Py_DECREF(buffobj));
-
- return buffobj;
-}
-
-static PyObject *
-PyRendererAgg_get_content_extents(PyRendererAgg *self, PyObject *args, PyObject *kwds)
-{
- agg::rect_i extents;
-
- CALL_CPP("get_content_extents", (extents = self->x->get_content_extents()));
-
- return Py_BuildValue(
- "iiii", extents.x1, extents.y1, extents.x2 - extents.x1, extents.y2 - extents.y1);
-}
-
-static PyObject *PyRendererAgg_buffer_rgba(PyRendererAgg *self, PyObject *args, PyObject *kwds)
-{
-#if PY3K
- return PyBytes_FromStringAndSize((const char *)self->x->pixBuffer,
- self->x->get_width() * self->x->get_height() * 4);
-#else
- return PyBuffer_FromReadWriteMemory(self->x->pixBuffer,
- self->x->get_width() * self->x->get_height() * 4);
-#endif
-}
-
-int PyRendererAgg_get_buffer(PyRendererAgg *self, Py_buffer *buf, int flags)
-{
- Py_INCREF(self);
- buf->obj = (PyObject *)self;
- buf->buf = self->x->pixBuffer;
- buf->len = self->x->get_width() * self->x->get_height() * 4;
- buf->readonly = 0;
- buf->format = (char *)"B";
- buf->ndim = 3;
- self->shape[0] = self->x->get_height();
- self->shape[1] = self->x->get_width();
- self->shape[2] = 4;
- buf->shape = self->shape;
- self->strides[0] = self->x->get_width() * 4;
- self->strides[1] = 4;
- self->strides[2] = 1;
- buf->strides = self->strides;
- buf->suboffsets = NULL;
- buf->itemsize = 1;
- buf->internal = NULL;
-
- return 1;
-}
-
-static PyObject *PyRendererAgg_clear(PyRendererAgg *self, PyObject *args, PyObject *kwds)
-{
- CALL_CPP("clear", self->x->clear());
-
- Py_RETURN_NONE;
-}
-
-static PyObject *PyRendererAgg_copy_from_bbox(PyRendererAgg *self, PyObject *args, PyObject *kwds)
-{
- agg::rect_d bbox;
- BufferRegion *reg;
- PyObject *regobj;
-
- if (!PyArg_ParseTuple(args, "O&:copy_from_bbox", &convert_rect, &bbox)) {
- return 0;
- }
-
- CALL_CPP("copy_from_bbox", (reg = self->x->copy_from_bbox(bbox)));
-
- regobj = PyBufferRegion_new(&PyBufferRegionType, NULL, NULL);
- ((PyBufferRegion *)regobj)->x = reg;
-
- return regobj;
-}
-
-static PyObject *PyRendererAgg_restore_region(PyRendererAgg *self, PyObject *args, PyObject *kwds)
-{
- PyBufferRegion *regobj;
- int xx1 = 0, yy1 = 0, xx2 = 0, yy2 = 0, x = 0, y = 0;
-
- if (!PyArg_ParseTuple(args,
- "O!|iiiiii:restore_region",
- &PyBufferRegionType,
- &regobj,
- &xx1,
- &yy1,
- &xx2,
- &yy2,
- &x,
- &y)) {
- return 0;
- }
-
- if (PySequence_Size(args) == 1) {
- CALL_CPP("restore_region", (self->x->restore_region(*(regobj->x))));
- } else {
- CALL_CPP("restore_region", self->x->restore_region(*(regobj->x), xx1, yy1, xx2, yy2, x, y));
- }
-
- Py_RETURN_NONE;
-}
-
-PyTypeObject PyRendererAggType;
-
-static PyTypeObject *PyRendererAgg_init_type(PyObject *m, PyTypeObject *type)
-{
- static PyMethodDef methods[] = {
- {"draw_path", (PyCFunction)PyRendererAgg_draw_path, METH_VARARGS, NULL},
- {"draw_markers", (PyCFunction)PyRendererAgg_draw_markers, METH_VARARGS, NULL},
- {"draw_text_image", (PyCFunction)PyRendererAgg_draw_text_image, METH_VARARGS, NULL},
- {"draw_image", (PyCFunction)PyRendererAgg_draw_image, METH_VARARGS, NULL},
- {"draw_path_collection", (PyCFunction)PyRendererAgg_draw_path_collection, METH_VARARGS, NULL},
- {"draw_quad_mesh", (PyCFunction)PyRendererAgg_draw_quad_mesh, METH_VARARGS, NULL},
- {"draw_gouraud_triangle", (PyCFunction)PyRendererAgg_draw_gouraud_triangle, METH_VARARGS, NULL},
- {"draw_gouraud_triangles", (PyCFunction)PyRendererAgg_draw_gouraud_triangles, METH_VARARGS, NULL},
-
- {"tostring_rgb", (PyCFunction)PyRendererAgg_tostring_rgb, METH_NOARGS, NULL},
- {"tostring_argb", (PyCFunction)PyRendererAgg_tostring_argb, METH_NOARGS, NULL},
- {"tostring_bgra", (PyCFunction)PyRendererAgg_tostring_bgra, METH_NOARGS, NULL},
- {"get_content_extents", (PyCFunction)PyRendererAgg_get_content_extents, METH_NOARGS, NULL},
- {"buffer_rgba", (PyCFunction)PyRendererAgg_buffer_rgba, METH_NOARGS, NULL},
- {"clear", (PyCFunction)PyRendererAgg_clear, METH_NOARGS, NULL},
-
- {"copy_from_bbox", (PyCFunction)PyRendererAgg_copy_from_bbox, METH_VARARGS, NULL},
- {"restore_region", (PyCFunction)PyRendererAgg_restore_region, METH_VARARGS, NULL},
- {NULL}
- };
-
- static PyBufferProcs buffer_procs;
- memset(&buffer_procs, 0, sizeof(PyBufferProcs));
- buffer_procs.bf_getbuffer = (getbufferproc)PyRendererAgg_get_buffer;
-
- memset(type, 0, sizeof(PyTypeObject));
- type->tp_name = "matplotlib.backends._backend_agg.RendererAgg";
- type->tp_basicsize = sizeof(PyRendererAgg);
- type->tp_dealloc = (destructor)PyRendererAgg_dealloc;
- type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_NEWBUFFER;
- type->tp_methods = methods;
- type->tp_init = (initproc)PyRendererAgg_init;
- type->tp_new = PyRendererAgg_new;
- type->tp_as_buffer = &buffer_procs;
-
- if (PyType_Ready(type) < 0) {
- return NULL;
- }
-
- if (PyModule_AddObject(m, "RendererAgg", (PyObject *)type)) {
- return NULL;
- }
-
- return type;
-}
-
-extern "C" {
-
-#if PY3K
-static struct PyModuleDef moduledef = {
- PyModuleDef_HEAD_INIT,
- "_backend_agg",
- NULL,
- 0,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL
-};
-
-#define INITERROR return NULL
-
-PyMODINIT_FUNC PyInit__backend_agg(void)
-
-#else
-#define INITERROR return
-
-PyMODINIT_FUNC init_backend_agg(void)
-#endif
-
-{
- PyObject *m;
-
-#if PY3K
- m = PyModule_Create(&moduledef);
-#else
- m = Py_InitModule3("_backend_agg", NULL, NULL);
-#endif
-
- if (m == NULL) {
- INITERROR;
- }
-
- import_array();
-
- if (!PyRendererAgg_init_type(m, &PyRendererAggType)) {
- INITERROR;
- }
-
- if (!PyBufferRegion_init_type(m, &PyBufferRegionType)) {
- INITERROR;
- }
-
-#if PY3K
- return m;
-#endif
-}
-
-} // extern "C"
diff --git a/contrib/python/matplotlib/py2/src/_backend_gdk.c b/contrib/python/matplotlib/py2/src/_backend_gdk.c
deleted file mode 100644
index 8314219cca..0000000000
--- a/contrib/python/matplotlib/py2/src/_backend_gdk.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/* -*- 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/_contour.cpp b/contrib/python/matplotlib/py2/src/_contour.cpp
deleted file mode 100644
index aecb442c7e..0000000000
--- a/contrib/python/matplotlib/py2/src/_contour.cpp
+++ /dev/null
@@ -1,1790 +0,0 @@
-// This file contains liberal use of asserts to assist code development and
-// debugging. Standard matplotlib builds disable asserts so they cause no
-// performance reduction. To enable the asserts, you need to undefine the
-// NDEBUG macro, which is achieved by adding the following
-// undef_macros=['NDEBUG']
-// to the appropriate make_extension call in setupext.py, and then rebuilding.
-#define NO_IMPORT_ARRAY
-
-#include "src/mplutils.h"
-#include "src/_contour.h"
-#include <algorithm>
-
-
-// 'kind' codes.
-#define MOVETO 1
-#define LINETO 2
-#define CLOSEPOLY 79
-
-// Point indices from current quad index.
-#define POINT_SW (quad)
-#define POINT_SE (quad+1)
-#define POINT_NW (quad+_nx)
-#define POINT_NE (quad+_nx+1)
-
-// CacheItem masks, only accessed directly to set. To read, use accessors
-// detailed below. 1 and 2 refer to level indices (lower and upper).
-#define MASK_Z_LEVEL 0x0003 // Combines the following two.
-#define MASK_Z_LEVEL_1 0x0001 // z > lower_level.
-#define MASK_Z_LEVEL_2 0x0002 // z > upper_level.
-#define MASK_VISITED_1 0x0004 // Algorithm has visited this quad.
-#define MASK_VISITED_2 0x0008
-#define MASK_SADDLE_1 0x0010 // quad is a saddle quad.
-#define MASK_SADDLE_2 0x0020
-#define MASK_SADDLE_LEFT_1 0x0040 // Contours turn left at saddle quad.
-#define MASK_SADDLE_LEFT_2 0x0080
-#define MASK_SADDLE_START_SW_1 0x0100 // Next visit starts on S or W edge.
-#define MASK_SADDLE_START_SW_2 0x0200
-#define MASK_BOUNDARY_S 0x0400 // S edge of quad is a boundary.
-#define MASK_BOUNDARY_W 0x0800 // W edge of quad is a boundary.
-// EXISTS_QUAD bit is always used, but the 4 EXISTS_CORNER are only used if
-// _corner_mask is true. Only one of EXISTS_QUAD or EXISTS_??_CORNER is ever
-// set per quad, hence not using unique bits for each; care is needed when
-// testing for these flags as they overlap.
-#define MASK_EXISTS_QUAD 0x1000 // All of quad exists (is not masked).
-#define MASK_EXISTS_SW_CORNER 0x2000 // SW corner exists, NE corner is masked.
-#define MASK_EXISTS_SE_CORNER 0x3000
-#define MASK_EXISTS_NW_CORNER 0x4000
-#define MASK_EXISTS_NE_CORNER 0x5000
-#define MASK_EXISTS 0x7000 // Combines all 5 EXISTS masks.
-
-// The following are only needed for filled contours.
-#define MASK_VISITED_S 0x10000 // Algorithm has visited S boundary.
-#define MASK_VISITED_W 0x20000 // Algorithm has visited W boundary.
-#define MASK_VISITED_CORNER 0x40000 // Algorithm has visited corner edge.
-
-
-// Accessors for various CacheItem masks. li is shorthand for level_index.
-#define Z_LEVEL(quad) (_cache[quad] & MASK_Z_LEVEL)
-#define Z_NE Z_LEVEL(POINT_NE)
-#define Z_NW Z_LEVEL(POINT_NW)
-#define Z_SE Z_LEVEL(POINT_SE)
-#define Z_SW Z_LEVEL(POINT_SW)
-#define VISITED(quad,li) (_cache[quad] & (li==1 ? MASK_VISITED_1 : MASK_VISITED_2))
-#define VISITED_S(quad) (_cache[quad] & MASK_VISITED_S)
-#define VISITED_W(quad) (_cache[quad] & MASK_VISITED_W)
-#define VISITED_CORNER(quad) (_cache[quad] & MASK_VISITED_CORNER)
-#define SADDLE(quad,li) (_cache[quad] & (li==1 ? MASK_SADDLE_1 : MASK_SADDLE_2))
-#define SADDLE_LEFT(quad,li) (_cache[quad] & (li==1 ? MASK_SADDLE_LEFT_1 : MASK_SADDLE_LEFT_2))
-#define SADDLE_START_SW(quad,li) (_cache[quad] & (li==1 ? MASK_SADDLE_START_SW_1 : MASK_SADDLE_START_SW_2))
-#define BOUNDARY_S(quad) (_cache[quad] & MASK_BOUNDARY_S)
-#define BOUNDARY_W(quad) (_cache[quad] & MASK_BOUNDARY_W)
-#define BOUNDARY_N(quad) BOUNDARY_S(quad+_nx)
-#define BOUNDARY_E(quad) BOUNDARY_W(quad+1)
-#define EXISTS_QUAD(quad) ((_cache[quad] & MASK_EXISTS) == MASK_EXISTS_QUAD)
-#define EXISTS_NONE(quad) ((_cache[quad] & MASK_EXISTS) == 0)
-// The following are only used if _corner_mask is true.
-#define EXISTS_SW_CORNER(quad) ((_cache[quad] & MASK_EXISTS) == MASK_EXISTS_SW_CORNER)
-#define EXISTS_SE_CORNER(quad) ((_cache[quad] & MASK_EXISTS) == MASK_EXISTS_SE_CORNER)
-#define EXISTS_NW_CORNER(quad) ((_cache[quad] & MASK_EXISTS) == MASK_EXISTS_NW_CORNER)
-#define EXISTS_NE_CORNER(quad) ((_cache[quad] & MASK_EXISTS) == MASK_EXISTS_NE_CORNER)
-#define EXISTS_ANY_CORNER(quad) (!EXISTS_NONE(quad) && !EXISTS_QUAD(quad))
-#define EXISTS_W_EDGE(quad) (EXISTS_QUAD(quad) || EXISTS_SW_CORNER(quad) || EXISTS_NW_CORNER(quad))
-#define EXISTS_E_EDGE(quad) (EXISTS_QUAD(quad) || EXISTS_SE_CORNER(quad) || EXISTS_NE_CORNER(quad))
-#define EXISTS_S_EDGE(quad) (EXISTS_QUAD(quad) || EXISTS_SW_CORNER(quad) || EXISTS_SE_CORNER(quad))
-#define EXISTS_N_EDGE(quad) (EXISTS_QUAD(quad) || EXISTS_NW_CORNER(quad) || EXISTS_NE_CORNER(quad))
-// Note that EXISTS_NE_CORNER(quad) is equivalent to BOUNDARY_SW(quad), etc.
-
-
-
-QuadEdge::QuadEdge()
- : quad(-1), edge(Edge_None)
-{}
-
-QuadEdge::QuadEdge(long quad_, Edge edge_)
- : quad(quad_), edge(edge_)
-{}
-
-bool QuadEdge::operator<(const QuadEdge& other) const
-{
- if (quad != other.quad)
- return quad < other.quad;
- else
- return edge < other.edge;
-}
-
-bool QuadEdge::operator==(const QuadEdge& other) const
-{
- return quad == other.quad && edge == other.edge;
-}
-
-bool QuadEdge::operator!=(const QuadEdge& other) const
-{
- return !operator==(other);
-}
-
-std::ostream& operator<<(std::ostream& os, const QuadEdge& quad_edge)
-{
- return os << quad_edge.quad << ' ' << quad_edge.edge;
-}
-
-
-// conflict with code from matplotlib/tri/_tri.cpp
-#if 0
-XY::XY()
-{}
-
-XY::XY(const double& x_, const double& y_)
- : x(x_), y(y_)
-{}
-
-bool XY::operator==(const XY& other) const
-{
- return x == other.x && y == other.y;
-}
-
-bool XY::operator!=(const XY& other) const
-{
- return x != other.x || y != other.y;
-}
-
-XY XY::operator*(const double& multiplier) const
-{
- return XY(x*multiplier, y*multiplier);
-}
-
-const XY& XY::operator+=(const XY& other)
-{
- x += other.x;
- y += other.y;
- return *this;
-}
-
-const XY& XY::operator-=(const XY& other)
-{
- x -= other.x;
- y -= other.y;
- return *this;
-}
-
-XY XY::operator+(const XY& other) const
-{
- return XY(x + other.x, y + other.y);
-}
-
-XY XY::operator-(const XY& other) const
-{
- return XY(x - other.x, y - other.y);
-}
-
-std::ostream& operator<<(std::ostream& os, const XY& xy)
-{
- return os << '(' << xy.x << ' ' << xy.y << ')';
-}
-#endif
-
-
-ContourLine::ContourLine(bool is_hole)
- : std::vector<XY>(),
- _is_hole(is_hole),
- _parent(0)
-{}
-
-void ContourLine::add_child(ContourLine* child)
-{
- assert(!_is_hole && "Cannot add_child to a hole");
- assert(child != 0 && "Null child ContourLine");
- _children.push_back(child);
-}
-
-void ContourLine::clear_parent()
-{
- assert(is_hole() && "Cannot clear parent of non-hole");
- assert(_parent != 0 && "Null parent ContourLine");
- _parent = 0;
-}
-
-const ContourLine::Children& ContourLine::get_children() const
-{
- assert(!_is_hole && "Cannot get_children of a hole");
- return _children;
-}
-
-const ContourLine* ContourLine::get_parent() const
-{
- assert(_is_hole && "Cannot get_parent of a non-hole");
- return _parent;
-}
-
-ContourLine* ContourLine::get_parent()
-{
- assert(_is_hole && "Cannot get_parent of a non-hole");
- return _parent;
-}
-
-bool ContourLine::is_hole() const
-{
- return _is_hole;
-}
-
-// conflict with code from matplotlib/tri/_tri.cpp
-#if 0
-void ContourLine::push_back(const XY& point)
-{
- if (empty() || point != back())
- std::vector<XY>::push_back(point);
-}
-#endif
-
-void ContourLine::set_parent(ContourLine* parent)
-{
- assert(_is_hole && "Cannot set parent of a non-hole");
- assert(parent != 0 && "Null parent ContourLine");
- _parent = parent;
-}
-
-// conflict with code from matplotlib/tri/_tri.cpp
-#if 0
-void ContourLine::write() const
-{
- std::cout << "ContourLine " << this << " of " << size() << " points:";
- for (const_iterator it = begin(); it != end(); ++it)
- std::cout << ' ' << *it;
- if (is_hole())
- std::cout << " hole, parent=" << get_parent();
- else {
- std::cout << " not hole";
- if (!_children.empty()) {
- std::cout << ", children=";
- for (Children::const_iterator it = _children.begin();
- it != _children.end(); ++it)
- std::cout << *it << ' ';
- }
- }
- std::cout << std::endl;
-}
-#endif
-
-
-Contour::Contour()
-{}
-
-Contour::~Contour()
-{
- delete_contour_lines();
-}
-
-void Contour::delete_contour_lines()
-{
- for (iterator line_it = begin(); line_it != end(); ++line_it) {
- delete *line_it;
- *line_it = 0;
- }
- std::vector<ContourLine*>::clear();
-}
-
-void Contour::write() const
-{
- std::cout << "Contour of " << size() << " lines." << std::endl;
- for (const_iterator it = begin(); it != end(); ++it)
- (*it)->write();
-}
-
-
-
-ParentCache::ParentCache(long nx, long x_chunk_points, long y_chunk_points)
- : _nx(nx),
- _x_chunk_points(x_chunk_points),
- _y_chunk_points(y_chunk_points),
- _lines(0), // Initialised when first needed.
- _istart(0),
- _jstart(0)
-{
- assert(_x_chunk_points > 0 && _y_chunk_points > 0 &&
- "Chunk sizes must be positive");
-}
-
-ContourLine* ParentCache::get_parent(long quad)
-{
- long index = quad_to_index(quad);
- ContourLine* parent = _lines[index];
- while (parent == 0) {
- index -= _x_chunk_points;
- assert(index >= 0 && "Failed to find parent in chunk ParentCache");
- parent = _lines[index];
- }
- assert(parent != 0 && "Failed to find parent in chunk ParentCache");
- return parent;
-}
-
-long ParentCache::quad_to_index(long quad) const
-{
- long i = quad % _nx;
- long j = quad / _nx;
- long index = (i-_istart) + (j-_jstart)*_x_chunk_points;
-
- assert(i >= _istart && i < _istart + _x_chunk_points &&
- "i-index outside chunk");
- assert(j >= _jstart && j < _jstart + _y_chunk_points &&
- "j-index outside chunk");
- assert(index >= 0 && index < static_cast<long>(_lines.size()) &&
- "ParentCache index outside chunk");
-
- return index;
-}
-
-void ParentCache::set_chunk_starts(long istart, long jstart)
-{
- assert(istart >= 0 && jstart >= 0 &&
- "Chunk start indices cannot be negative");
- _istart = istart;
- _jstart = jstart;
- if (_lines.empty())
- _lines.resize(_x_chunk_points*_y_chunk_points, 0);
- else
- std::fill(_lines.begin(), _lines.end(), (ContourLine*)0);
-}
-
-void ParentCache::set_parent(long quad, ContourLine& contour_line)
-{
- assert(!_lines.empty() &&
- "Accessing ParentCache before it has been initialised");
- long index = quad_to_index(quad);
- if (_lines[index] == 0)
- _lines[index] = (contour_line.is_hole() ? contour_line.get_parent()
- : &contour_line);
-}
-
-
-
-QuadContourGenerator::QuadContourGenerator(const CoordinateArray& x,
- const CoordinateArray& y,
- const CoordinateArray& z,
- const MaskArray& mask,
- bool corner_mask,
- long chunk_size)
- : _x(x),
- _y(y),
- _z(z),
- _nx(static_cast<long>(_x.dim(1))),
- _ny(static_cast<long>(_x.dim(0))),
- _n(_nx*_ny),
- _corner_mask(corner_mask),
- _chunk_size(chunk_size > 0 ? std::min(chunk_size, std::max(_nx, _ny)-1)
- : std::max(_nx, _ny)-1),
- _nxchunk(calc_chunk_count(_nx)),
- _nychunk(calc_chunk_count(_ny)),
- _chunk_count(_nxchunk*_nychunk),
- _cache(new CacheItem[_n]),
- _parent_cache(_nx,
- chunk_size > 0 ? chunk_size+1 : _nx,
- chunk_size > 0 ? chunk_size+1 : _ny)
-{
- assert(!_x.empty() && !_y.empty() && !_z.empty() && "Empty array");
- assert(_y.dim(0) == _x.dim(0) && _y.dim(1) == _x.dim(1) &&
- "Different-sized y and x arrays");
- assert(_z.dim(0) == _x.dim(0) && _z.dim(1) == _x.dim(1) &&
- "Different-sized z and x arrays");
- assert((mask.empty() ||
- (mask.dim(0) == _x.dim(0) && mask.dim(1) == _x.dim(1))) &&
- "Different-sized mask and x arrays");
-
- init_cache_grid(mask);
-}
-
-QuadContourGenerator::~QuadContourGenerator()
-{
- delete [] _cache;
-}
-
-void QuadContourGenerator::append_contour_line_to_vertices(
- ContourLine& contour_line,
- PyObject* vertices_list) const
-{
- assert(vertices_list != 0 && "Null python vertices_list");
-
- // Convert ContourLine to python equivalent, and clear it.
- npy_intp dims[2] = {static_cast<npy_intp>(contour_line.size()), 2};
- numpy::array_view<double, 2> line(dims);
- npy_intp i = 0;
- for (ContourLine::const_iterator point = contour_line.begin();
- point != contour_line.end(); ++point, ++i) {
- line(i, 0) = point->x;
- line(i, 1) = point->y;
- }
- if (PyList_Append(vertices_list, line.pyobj_steal())) {
- Py_XDECREF(vertices_list);
- throw std::runtime_error("Unable to add contour line to vertices_list");
- }
-
- contour_line.clear();
-}
-
-void QuadContourGenerator::append_contour_to_vertices_and_codes(
- Contour& contour,
- PyObject* vertices_list,
- PyObject* codes_list) const
-{
- assert(vertices_list != 0 && "Null python vertices_list");
- assert(codes_list != 0 && "Null python codes_list");
-
- // Convert Contour to python equivalent, and clear it.
- for (Contour::iterator line_it = contour.begin(); line_it != contour.end();
- ++line_it) {
- ContourLine& line = **line_it;
- if (line.is_hole()) {
- // If hole has already been converted to python its parent will be
- // set to 0 and it can be deleted.
- if (line.get_parent() != 0) {
- delete *line_it;
- *line_it = 0;
- }
- }
- else {
- // Non-holes are converted to python together with their child
- // holes so that they are rendered correctly.
- ContourLine::const_iterator point;
- ContourLine::Children::const_iterator children_it;
-
- const ContourLine::Children& children = line.get_children();
- npy_intp npoints = static_cast<npy_intp>(line.size() + 1);
- for (children_it = children.begin(); children_it != children.end();
- ++children_it)
- npoints += static_cast<npy_intp>((*children_it)->size() + 1);
-
- npy_intp vertices_dims[2] = {npoints, 2};
- numpy::array_view<double, 2> vertices(vertices_dims);
- double* vertices_ptr = vertices.data();
-
- npy_intp codes_dims[1] = {npoints};
- numpy::array_view<unsigned char, 1> codes(codes_dims);
- unsigned char* codes_ptr = codes.data();
-
- for (point = line.begin(); point != line.end(); ++point) {
- *vertices_ptr++ = point->x;
- *vertices_ptr++ = point->y;
- *codes_ptr++ = (point == line.begin() ? MOVETO : LINETO);
- }
- point = line.begin();
- *vertices_ptr++ = point->x;
- *vertices_ptr++ = point->y;
- *codes_ptr++ = CLOSEPOLY;
-
- for (children_it = children.begin(); children_it != children.end();
- ++children_it) {
- ContourLine& child = **children_it;
- for (point = child.begin(); point != child.end(); ++point) {
- *vertices_ptr++ = point->x;
- *vertices_ptr++ = point->y;
- *codes_ptr++ = (point == child.begin() ? MOVETO : LINETO);
- }
- point = child.begin();
- *vertices_ptr++ = point->x;
- *vertices_ptr++ = point->y;
- *codes_ptr++ = CLOSEPOLY;
-
- child.clear_parent(); // To indicate it can be deleted.
- }
-
- if (PyList_Append(vertices_list, vertices.pyobj_steal()) ||
- PyList_Append(codes_list, codes.pyobj_steal())) {
- Py_XDECREF(vertices_list);
- Py_XDECREF(codes_list);
- contour.delete_contour_lines();
- throw std::runtime_error("Unable to add contour line to vertices and codes lists");
- }
-
- delete *line_it;
- *line_it = 0;
- }
- }
-
- // Delete remaining contour lines.
- contour.delete_contour_lines();
-}
-
-long QuadContourGenerator::calc_chunk_count(long point_count) const
-{
- assert(point_count > 0 && "point count must be positive");
- assert(_chunk_size > 0 && "Chunk size must be positive");
-
- if (_chunk_size > 0) {
- long count = (point_count-1) / _chunk_size;
- if (count*_chunk_size < point_count-1)
- ++count;
-
- assert(count >= 1 && "Invalid chunk count");
- return count;
- }
- else
- return 1;
-}
-
-PyObject* QuadContourGenerator::create_contour(const double& level)
-{
- init_cache_levels(level, level);
-
- PyObject* vertices_list = PyList_New(0);
- if (vertices_list == 0)
- throw std::runtime_error("Failed to create Python list");
-
- // Lines that start and end on boundaries.
- long ichunk, jchunk, istart, iend, jstart, jend;
- for (long ijchunk = 0; ijchunk < _chunk_count; ++ijchunk) {
- get_chunk_limits(ijchunk, ichunk, jchunk, istart, iend, jstart, jend);
-
- for (long j = jstart; j < jend; ++j) {
- long quad_end = iend + j*_nx;
- for (long quad = istart + j*_nx; quad < quad_end; ++quad) {
- if (EXISTS_NONE(quad) || VISITED(quad,1)) continue;
-
- if (BOUNDARY_S(quad) && Z_SW >= 1 && Z_SE < 1 &&
- start_line(vertices_list, quad, Edge_S, level)) continue;
-
- if (BOUNDARY_W(quad) && Z_NW >= 1 && Z_SW < 1 &&
- start_line(vertices_list, quad, Edge_W, level)) continue;
-
- if (BOUNDARY_N(quad) && Z_NE >= 1 && Z_NW < 1 &&
- start_line(vertices_list, quad, Edge_N, level)) continue;
-
- if (BOUNDARY_E(quad) && Z_SE >= 1 && Z_NE < 1 &&
- start_line(vertices_list, quad, Edge_E, level)) continue;
-
- if (_corner_mask) {
- // Equates to NE boundary.
- if (EXISTS_SW_CORNER(quad) && Z_SE >= 1 && Z_NW < 1 &&
- start_line(vertices_list, quad, Edge_NE, level)) continue;
-
- // Equates to NW boundary.
- if (EXISTS_SE_CORNER(quad) && Z_NE >= 1 && Z_SW < 1 &&
- start_line(vertices_list, quad, Edge_NW, level)) continue;
-
- // Equates to SE boundary.
- if (EXISTS_NW_CORNER(quad) && Z_SW >= 1 && Z_NE < 1 &&
- start_line(vertices_list, quad, Edge_SE, level)) continue;
-
- // Equates to SW boundary.
- if (EXISTS_NE_CORNER(quad) && Z_NW >= 1 && Z_SE < 1 &&
- start_line(vertices_list, quad, Edge_SW, level)) continue;
- }
- }
- }
- }
-
- // Internal loops.
- ContourLine contour_line(false); // Reused for each contour line.
- for (long ijchunk = 0; ijchunk < _chunk_count; ++ijchunk) {
- get_chunk_limits(ijchunk, ichunk, jchunk, istart, iend, jstart, jend);
-
- for (long j = jstart; j < jend; ++j) {
- long quad_end = iend + j*_nx;
- for (long quad = istart + j*_nx; quad < quad_end; ++quad) {
- if (EXISTS_NONE(quad) || VISITED(quad,1))
- continue;
-
- Edge start_edge = get_start_edge(quad, 1);
- if (start_edge == Edge_None)
- continue;
-
- QuadEdge quad_edge(quad, start_edge);
- QuadEdge start_quad_edge(quad_edge);
-
- // To obtain output identical to that produced by legacy code,
- // sometimes need to ignore the first point and add it on the
- // end instead.
- bool ignore_first = (start_edge == Edge_N);
- follow_interior(contour_line, quad_edge, 1, level,
- !ignore_first, &start_quad_edge, 1, false);
- if (ignore_first && !contour_line.empty())
- contour_line.push_back(contour_line.front());
- append_contour_line_to_vertices(contour_line, vertices_list);
-
- // Repeat if saddle point but not visited.
- if (SADDLE(quad,1) && !VISITED(quad,1))
- --quad;
- }
- }
- }
-
- return vertices_list;
-}
-
-PyObject* QuadContourGenerator::create_filled_contour(const double& lower_level,
- const double& upper_level)
-{
- init_cache_levels(lower_level, upper_level);
-
- Contour contour;
-
- PyObject* vertices = PyList_New(0);
- if (vertices == 0)
- throw std::runtime_error("Failed to create Python list");
-
- PyObject* codes = PyList_New(0);
- if (codes == 0) {
- Py_XDECREF(vertices);
- throw std::runtime_error("Failed to create Python list");
- }
-
- long ichunk, jchunk, istart, iend, jstart, jend;
- for (long ijchunk = 0; ijchunk < _chunk_count; ++ijchunk) {
- get_chunk_limits(ijchunk, ichunk, jchunk, istart, iend, jstart, jend);
- _parent_cache.set_chunk_starts(istart, jstart);
-
- for (long j = jstart; j < jend; ++j) {
- long quad_end = iend + j*_nx;
- for (long quad = istart + j*_nx; quad < quad_end; ++quad) {
- if (!EXISTS_NONE(quad))
- single_quad_filled(contour, quad, lower_level, upper_level);
- }
- }
-
- // Clear VISITED_W and VISITED_S flags that are reused by later chunks.
- if (jchunk < _nychunk-1) {
- long quad_end = iend + jend*_nx;
- for (long quad = istart + jend*_nx; quad < quad_end; ++quad)
- _cache[quad] &= ~MASK_VISITED_S;
- }
-
- if (ichunk < _nxchunk-1) {
- long quad_end = iend + jend*_nx;
- for (long quad = iend + jstart*_nx; quad < quad_end; quad += _nx)
- _cache[quad] &= ~MASK_VISITED_W;
- }
-
- // Create python objects to return for this chunk.
- append_contour_to_vertices_and_codes(contour, vertices, codes);
- }
-
- PyObject* tuple = PyTuple_New(2);
- if (tuple == 0) {
- Py_XDECREF(vertices);
- Py_XDECREF(codes);
- throw std::runtime_error("Failed to create Python tuple");
- }
-
- // No error checking here as filling in a brand new pre-allocated tuple.
- PyTuple_SET_ITEM(tuple, 0, vertices);
- PyTuple_SET_ITEM(tuple, 1, codes);
-
- return tuple;
-}
-
-XY QuadContourGenerator::edge_interp(const QuadEdge& quad_edge,
- const double& level)
-{
- assert(quad_edge.quad >= 0 && quad_edge.quad < _n &&
- "Quad index out of bounds");
- assert(quad_edge.edge != Edge_None && "Invalid edge");
- return interp(get_edge_point_index(quad_edge, true),
- get_edge_point_index(quad_edge, false),
- level);
-}
-
-unsigned int QuadContourGenerator::follow_boundary(
- ContourLine& contour_line,
- QuadEdge& quad_edge,
- const double& lower_level,
- const double& upper_level,
- unsigned int level_index,
- const QuadEdge& start_quad_edge)
-{
- assert(quad_edge.quad >= 0 && quad_edge.quad < _n &&
- "Quad index out of bounds");
- assert(quad_edge.edge != Edge_None && "Invalid edge");
- assert(is_edge_a_boundary(quad_edge) && "Not a boundary edge");
- assert((level_index == 1 || level_index == 2) &&
- "level index must be 1 or 2");
- assert(start_quad_edge.quad >= 0 && start_quad_edge.quad < _n &&
- "Start quad index out of bounds");
- assert(start_quad_edge.edge != Edge_None && "Invalid start edge");
-
- // Only called for filled contours, so always updates _parent_cache.
- unsigned int end_level = 0;
- bool first_edge = true;
- bool stop = false;
- long& quad = quad_edge.quad;
-
- while (true) {
- // Levels of start and end points of quad_edge.
- unsigned int start_level =
- (first_edge ? Z_LEVEL(get_edge_point_index(quad_edge, true))
- : end_level);
- long end_point = get_edge_point_index(quad_edge, false);
- end_level = Z_LEVEL(end_point);
-
- if (level_index == 1) {
- if (start_level <= level_index && end_level == 2) {
- // Increasing z, switching levels from 1 to 2.
- level_index = 2;
- stop = true;
- }
- else if (start_level >= 1 && end_level == 0) {
- // Decreasing z, keeping same level.
- stop = true;
- }
- }
- else { // level_index == 2
- if (start_level <= level_index && end_level == 2) {
- // Increasing z, keeping same level.
- stop = true;
- }
- else if (start_level >= 1 && end_level == 0) {
- // Decreasing z, switching levels from 2 to 1.
- level_index = 1;
- stop = true;
- }
- }
-
- if (!first_edge && !stop && quad_edge == start_quad_edge)
- // Return if reached start point of contour line. Do this before
- // checking/setting VISITED flags as will already have been
- // visited.
- break;
-
- switch (quad_edge.edge) {
- case Edge_E:
- assert(!VISITED_W(quad+1) && "Already visited");
- _cache[quad+1] |= MASK_VISITED_W;
- break;
- case Edge_N:
- assert(!VISITED_S(quad+_nx) && "Already visited");
- _cache[quad+_nx] |= MASK_VISITED_S;
- break;
- case Edge_W:
- assert(!VISITED_W(quad) && "Already visited");
- _cache[quad] |= MASK_VISITED_W;
- break;
- case Edge_S:
- assert(!VISITED_S(quad) && "Already visited");
- _cache[quad] |= MASK_VISITED_S;
- break;
- case Edge_NE:
- case Edge_NW:
- case Edge_SW:
- case Edge_SE:
- assert(!VISITED_CORNER(quad) && "Already visited");
- _cache[quad] |= MASK_VISITED_CORNER;
- break;
- default:
- assert(0 && "Invalid Edge");
- break;
- }
-
- if (stop) {
- // Exiting boundary to enter interior.
- contour_line.push_back(edge_interp(quad_edge,
- level_index == 1 ? lower_level
- : upper_level));
- break;
- }
-
- move_to_next_boundary_edge(quad_edge);
-
- // Just moved to new quad edge, so label parent of start of quad edge.
- switch (quad_edge.edge) {
- case Edge_W:
- case Edge_SW:
- case Edge_S:
- case Edge_SE:
- if (!EXISTS_SE_CORNER(quad))
- _parent_cache.set_parent(quad, contour_line);
- break;
- case Edge_E:
- case Edge_NE:
- case Edge_N:
- case Edge_NW:
- if (!EXISTS_SW_CORNER(quad))
- _parent_cache.set_parent(quad + 1, contour_line);
- break;
- default:
- assert(0 && "Invalid edge");
- break;
- }
-
- // Add point to contour.
- contour_line.push_back(get_point_xy(end_point));
-
- if (first_edge)
- first_edge = false;
- }
-
- return level_index;
-}
-
-void QuadContourGenerator::follow_interior(ContourLine& contour_line,
- QuadEdge& quad_edge,
- unsigned int level_index,
- const double& level,
- bool want_initial_point,
- const QuadEdge* start_quad_edge,
- unsigned int start_level_index,
- bool set_parents)
-{
- assert(quad_edge.quad >= 0 && quad_edge.quad < _n &&
- "Quad index out of bounds.");
- assert(quad_edge.edge != Edge_None && "Invalid edge");
- assert((level_index == 1 || level_index == 2) &&
- "level index must be 1 or 2");
- assert((start_quad_edge == 0 ||
- (start_quad_edge->quad >= 0 && start_quad_edge->quad < _n)) &&
- "Start quad index out of bounds.");
- assert((start_quad_edge == 0 || start_quad_edge->edge != Edge_None) &&
- "Invalid start edge");
- assert((start_level_index == 1 || start_level_index == 2) &&
- "start level index must be 1 or 2");
-
- long& quad = quad_edge.quad;
- Edge& edge = quad_edge.edge;
-
- if (want_initial_point)
- contour_line.push_back(edge_interp(quad_edge, level));
-
- CacheItem visited_mask = (level_index == 1 ? MASK_VISITED_1 : MASK_VISITED_2);
- CacheItem saddle_mask = (level_index == 1 ? MASK_SADDLE_1 : MASK_SADDLE_2);
- Dir dir = Dir_Straight;
-
- while (true) {
- assert(!EXISTS_NONE(quad) && "Quad does not exist");
- assert(!(_cache[quad] & visited_mask) && "Quad already visited");
-
- // Determine direction to move to next quad. If the quad is already
- // labelled as a saddle quad then the direction is easily read from
- // the cache. Otherwise the direction is determined differently
- // depending on whether the quad is a corner quad or not.
-
- if (_cache[quad] & saddle_mask) {
- // Already identified as a saddle quad, so direction is easy.
- dir = (SADDLE_LEFT(quad,level_index) ? Dir_Left : Dir_Right);
- _cache[quad] |= visited_mask;
- }
- else if (EXISTS_ANY_CORNER(quad)) {
- // Need z-level of point opposite the entry edge, as that
- // determines whether contour turns left or right.
- long point_opposite = -1;
- switch (edge) {
- case Edge_E:
- point_opposite = (EXISTS_SE_CORNER(quad) ? POINT_SW
- : POINT_NW);
- break;
- case Edge_N:
- point_opposite = (EXISTS_NW_CORNER(quad) ? POINT_SW
- : POINT_SE);
- break;
- case Edge_W:
- point_opposite = (EXISTS_SW_CORNER(quad) ? POINT_SE
- : POINT_NE);
- break;
- case Edge_S:
- point_opposite = (EXISTS_SW_CORNER(quad) ? POINT_NW
- : POINT_NE);
- break;
- case Edge_NE: point_opposite = POINT_SW; break;
- case Edge_NW: point_opposite = POINT_SE; break;
- case Edge_SW: point_opposite = POINT_NE; break;
- case Edge_SE: point_opposite = POINT_NW; break;
- default: assert(0 && "Invalid edge"); break;
- }
- assert(point_opposite != -1 && "Failed to find opposite point");
-
- // Lower-level polygons (level_index == 1) always have higher
- // values to the left of the contour. Upper-level contours
- // (level_index == 2) are reversed, which is what the fancy XOR
- // does below.
- if ((Z_LEVEL(point_opposite) >= level_index) ^ (level_index == 2))
- dir = Dir_Right;
- else
- dir = Dir_Left;
- _cache[quad] |= visited_mask;
- }
- else {
- // Calculate configuration of this quad.
- long point_left = -1, point_right = -1;
- switch (edge) {
- case Edge_E: point_left = POINT_SW; point_right = POINT_NW; break;
- case Edge_N: point_left = POINT_SE; point_right = POINT_SW; break;
- case Edge_W: point_left = POINT_NE; point_right = POINT_SE; break;
- case Edge_S: point_left = POINT_NW; point_right = POINT_NE; break;
- default: assert(0 && "Invalid edge"); break;
- }
-
- unsigned int config = (Z_LEVEL(point_left) >= level_index) << 1 |
- (Z_LEVEL(point_right) >= level_index);
-
- // Upper level (level_index == 2) polygons are reversed compared to
- // lower level ones, i.e. higher values on the right rather than
- // the left.
- if (level_index == 2)
- config = 3 - config;
-
- // Calculate turn direction to move to next quad along contour line.
- if (config == 1) {
- // New saddle quad, set up cache bits for it.
- double zmid = 0.25*(get_point_z(POINT_SW) +
- get_point_z(POINT_SE) +
- get_point_z(POINT_NW) +
- get_point_z(POINT_NE));
- _cache[quad] |= (level_index == 1 ? MASK_SADDLE_1 : MASK_SADDLE_2);
- if ((zmid > level) ^ (level_index == 2)) {
- dir = Dir_Right;
- }
- else {
- dir = Dir_Left;
- _cache[quad] |= (level_index == 1 ? MASK_SADDLE_LEFT_1
- : MASK_SADDLE_LEFT_2);
- }
- if (edge == Edge_N || edge == Edge_E) {
- // Next visit to this quad must start on S or W.
- _cache[quad] |= (level_index == 1 ? MASK_SADDLE_START_SW_1
- : MASK_SADDLE_START_SW_2);
- }
- }
- else {
- // Normal (non-saddle) quad.
- dir = (config == 0 ? Dir_Left
- : (config == 3 ? Dir_Right : Dir_Straight));
- _cache[quad] |= visited_mask;
- }
- }
-
- // Use dir to determine exit edge.
- edge = get_exit_edge(quad_edge, dir);
-
- if (set_parents) {
- if (edge == Edge_E)
- _parent_cache.set_parent(quad+1, contour_line);
- else if (edge == Edge_W)
- _parent_cache.set_parent(quad, contour_line);
- }
-
- // Add new point to contour line.
- contour_line.push_back(edge_interp(quad_edge, level));
-
- // Stop if reached boundary.
- if (is_edge_a_boundary(quad_edge))
- break;
-
- move_to_next_quad(quad_edge);
- assert(quad_edge.quad >= 0 && quad_edge.quad < _n &&
- "Quad index out of bounds");
-
- // Return if reached start point of contour line.
- if (start_quad_edge != 0 &&
- quad_edge == *start_quad_edge &&
- level_index == start_level_index)
- break;
- }
-}
-
-void QuadContourGenerator::get_chunk_limits(long ijchunk,
- long& ichunk,
- long& jchunk,
- long& istart,
- long& iend,
- long& jstart,
- long& jend)
-{
- assert(ijchunk >= 0 && ijchunk < _chunk_count && "ijchunk out of bounds");
- ichunk = ijchunk % _nxchunk;
- jchunk = ijchunk / _nxchunk;
- istart = ichunk*_chunk_size;
- iend = (ichunk == _nxchunk-1 ? _nx : (ichunk+1)*_chunk_size);
- jstart = jchunk*_chunk_size;
- jend = (jchunk == _nychunk-1 ? _ny : (jchunk+1)*_chunk_size);
-}
-
-Edge QuadContourGenerator::get_corner_start_edge(long quad,
- unsigned int level_index) const
-{
- assert(quad >= 0 && quad < _n && "Quad index out of bounds");
- assert((level_index == 1 || level_index == 2) &&
- "level index must be 1 or 2");
- assert(EXISTS_ANY_CORNER(quad) && "Quad is not a corner");
-
- // Diagram for NE corner. Rotate for other corners.
- //
- // edge12
- // point1 +---------+ point2
- // \ |
- // \ | edge23
- // edge31 \ |
- // \ |
- // + point3
- //
- long point1, point2, point3;
- Edge edge12, edge23, edge31;
- switch (_cache[quad] & MASK_EXISTS) {
- case MASK_EXISTS_SW_CORNER:
- point1 = POINT_SE; point2 = POINT_SW; point3 = POINT_NW;
- edge12 = Edge_S; edge23 = Edge_W; edge31 = Edge_NE;
- break;
- case MASK_EXISTS_SE_CORNER:
- point1 = POINT_NE; point2 = POINT_SE; point3 = POINT_SW;
- edge12 = Edge_E; edge23 = Edge_S; edge31 = Edge_NW;
- break;
- case MASK_EXISTS_NW_CORNER:
- point1 = POINT_SW; point2 = POINT_NW; point3 = POINT_NE;
- edge12 = Edge_W; edge23 = Edge_N; edge31 = Edge_SE;
- break;
- case MASK_EXISTS_NE_CORNER:
- point1 = POINT_NW; point2 = POINT_NE; point3 = POINT_SE;
- edge12 = Edge_N; edge23 = Edge_E; edge31 = Edge_SW;
- break;
- default:
- assert(0 && "Invalid EXISTS for quad");
- return Edge_None;
- }
-
- unsigned int config = (Z_LEVEL(point1) >= level_index) << 2 |
- (Z_LEVEL(point2) >= level_index) << 1 |
- (Z_LEVEL(point3) >= level_index);
-
- // Upper level (level_index == 2) polygons are reversed compared to lower
- // level ones, i.e. higher values on the right rather than the left.
- if (level_index == 2)
- config = 7 - config;
-
- switch (config) {
- case 0: return Edge_None;
- case 1: return edge23;
- case 2: return edge12;
- case 3: return edge12;
- case 4: return edge31;
- case 5: return edge23;
- case 6: return edge31;
- case 7: return Edge_None;
- default: assert(0 && "Invalid config"); return Edge_None;
- }
-}
-
-long QuadContourGenerator::get_edge_point_index(const QuadEdge& quad_edge,
- bool start) const
-{
- assert(quad_edge.quad >= 0 && quad_edge.quad < _n &&
- "Quad index out of bounds");
- assert(quad_edge.edge != Edge_None && "Invalid edge");
-
- // Edges are ordered anticlockwise around their quad, as indicated by
- // directions of arrows in diagrams below.
- // Full quad NW corner (others similar)
- //
- // POINT_NW Edge_N POINT_NE POINT_NW Edge_N POINT_NE
- // +----<-----+ +----<-----+
- // | | | /
- // | | | quad /
- // Edge_W V quad ^ Edge_E Edge_W V ^
- // | | | / Edge_SE
- // | | | /
- // +---->-----+ +
- // POINT_SW Edge_S POINT_SE POINT_SW
- //
- const long& quad = quad_edge.quad;
- switch (quad_edge.edge) {
- case Edge_E: return (start ? POINT_SE : POINT_NE);
- case Edge_N: return (start ? POINT_NE : POINT_NW);
- case Edge_W: return (start ? POINT_NW : POINT_SW);
- case Edge_S: return (start ? POINT_SW : POINT_SE);
- case Edge_NE: return (start ? POINT_SE : POINT_NW);
- case Edge_NW: return (start ? POINT_NE : POINT_SW);
- case Edge_SW: return (start ? POINT_NW : POINT_SE);
- case Edge_SE: return (start ? POINT_SW : POINT_NE);
- default: assert(0 && "Invalid edge"); return 0;
- }
-}
-
-Edge QuadContourGenerator::get_exit_edge(const QuadEdge& quad_edge,
- Dir dir) const
-{
- assert(quad_edge.quad >= 0 && quad_edge.quad < _n &&
- "Quad index out of bounds");
- assert(quad_edge.edge != Edge_None && "Invalid edge");
-
- const long& quad = quad_edge.quad;
- const Edge& edge = quad_edge.edge;
- if (EXISTS_ANY_CORNER(quad)) {
- // Corner directions are always left or right. A corner is a triangle,
- // entered via one edge so the other two edges are the left and right
- // ones.
- switch (edge) {
- case Edge_E:
- return (EXISTS_SE_CORNER(quad)
- ? (dir == Dir_Left ? Edge_S : Edge_NW)
- : (dir == Dir_Right ? Edge_N : Edge_SW));
- case Edge_N:
- return (EXISTS_NW_CORNER(quad)
- ? (dir == Dir_Right ? Edge_W : Edge_SE)
- : (dir == Dir_Left ? Edge_E : Edge_SW));
- case Edge_W:
- return (EXISTS_SW_CORNER(quad)
- ? (dir == Dir_Right ? Edge_S : Edge_NE)
- : (dir == Dir_Left ? Edge_N : Edge_SE));
- case Edge_S:
- return (EXISTS_SW_CORNER(quad)
- ? (dir == Dir_Left ? Edge_W : Edge_NE)
- : (dir == Dir_Right ? Edge_E : Edge_NW));
- case Edge_NE: return (dir == Dir_Left ? Edge_S : Edge_W);
- case Edge_NW: return (dir == Dir_Left ? Edge_E : Edge_S);
- case Edge_SW: return (dir == Dir_Left ? Edge_N : Edge_E);
- case Edge_SE: return (dir == Dir_Left ? Edge_W : Edge_N);
- default: assert(0 && "Invalid edge"); return Edge_None;
- }
- }
- else {
- // A full quad has four edges, entered via one edge so that other three
- // edges correspond to left, straight and right directions.
- switch (edge) {
- case Edge_E:
- return (dir == Dir_Left ? Edge_S :
- (dir == Dir_Right ? Edge_N : Edge_W));
- case Edge_N:
- return (dir == Dir_Left ? Edge_E :
- (dir == Dir_Right ? Edge_W : Edge_S));
- case Edge_W:
- return (dir == Dir_Left ? Edge_N :
- (dir == Dir_Right ? Edge_S : Edge_E));
- case Edge_S:
- return (dir == Dir_Left ? Edge_W :
- (dir == Dir_Right ? Edge_E : Edge_N));
- default: assert(0 && "Invalid edge"); return Edge_None;
- }
- }
-}
-
-XY QuadContourGenerator::get_point_xy(long point) const
-{
- assert(point >= 0 && point < _n && "Point index out of bounds.");
- return XY(_x.data()[static_cast<npy_intp>(point)],
- _y.data()[static_cast<npy_intp>(point)]);
-}
-
-const double& QuadContourGenerator::get_point_z(long point) const
-{
- assert(point >= 0 && point < _n && "Point index out of bounds.");
- return _z.data()[static_cast<npy_intp>(point)];
-}
-
-Edge QuadContourGenerator::get_quad_start_edge(long quad,
- unsigned int level_index) const
-{
- assert(quad >= 0 && quad < _n && "Quad index out of bounds");
- assert((level_index == 1 || level_index == 2) &&
- "level index must be 1 or 2");
- assert(EXISTS_QUAD(quad) && "Quad does not exist");
-
- unsigned int config = (Z_NW >= level_index) << 3 |
- (Z_NE >= level_index) << 2 |
- (Z_SW >= level_index) << 1 |
- (Z_SE >= level_index);
-
- // Upper level (level_index == 2) polygons are reversed compared to lower
- // level ones, i.e. higher values on the right rather than the left.
- if (level_index == 2)
- config = 15 - config;
-
- switch (config) {
- case 0: return Edge_None;
- case 1: return Edge_E;
- case 2: return Edge_S;
- case 3: return Edge_E;
- case 4: return Edge_N;
- case 5: return Edge_N;
- case 6:
- // If already identified as a saddle quad then the start edge is
- // read from the cache. Otherwise return either valid start edge
- // and the subsequent call to follow_interior() will correctly set
- // up saddle bits in cache.
- if (!SADDLE(quad,level_index) || SADDLE_START_SW(quad,level_index))
- return Edge_S;
- else
- return Edge_N;
- case 7: return Edge_N;
- case 8: return Edge_W;
- case 9:
- // See comment for 6 above.
- if (!SADDLE(quad,level_index) || SADDLE_START_SW(quad,level_index))
- return Edge_W;
- else
- return Edge_E;
- case 10: return Edge_S;
- case 11: return Edge_E;
- case 12: return Edge_W;
- case 13: return Edge_W;
- case 14: return Edge_S;
- case 15: return Edge_None;
- default: assert(0 && "Invalid config"); return Edge_None;
- }
-}
-
-Edge QuadContourGenerator::get_start_edge(long quad,
- unsigned int level_index) const
-{
- if (EXISTS_ANY_CORNER(quad))
- return get_corner_start_edge(quad, level_index);
- else
- return get_quad_start_edge(quad, level_index);
-}
-
-void QuadContourGenerator::init_cache_grid(const MaskArray& mask)
-{
- long i, j, quad;
-
- if (mask.empty()) {
- // No mask, easy to calculate quad existence and boundaries together.
- quad = 0;
- for (j = 0; j < _ny; ++j) {
- for (i = 0; i < _nx; ++i, ++quad) {
- _cache[quad] = 0;
-
- if (i < _nx-1 && j < _ny-1)
- _cache[quad] |= MASK_EXISTS_QUAD;
-
- if ((i % _chunk_size == 0 || i == _nx-1) && j < _ny-1)
- _cache[quad] |= MASK_BOUNDARY_W;
-
- if ((j % _chunk_size == 0 || j == _ny-1) && i < _nx-1)
- _cache[quad] |= MASK_BOUNDARY_S;
- }
- }
- }
- else {
- // Casting avoids problem when sizeof(bool) != sizeof(npy_bool).
- const npy_bool* mask_ptr =
- reinterpret_cast<const npy_bool*>(mask.data());
-
- // Have mask so use two stages.
- // Stage 1, determine if quads/corners exist.
- quad = 0;
- for (j = 0; j < _ny; ++j) {
- for (i = 0; i < _nx; ++i, ++quad) {
- _cache[quad] = 0;
-
- if (i < _nx-1 && j < _ny-1) {
- unsigned int config = mask_ptr[POINT_NW] << 3 |
- mask_ptr[POINT_NE] << 2 |
- mask_ptr[POINT_SW] << 1 |
- mask_ptr[POINT_SE];
-
- if (_corner_mask) {
- switch (config) {
- case 0: _cache[quad] = MASK_EXISTS_QUAD; break;
- case 1: _cache[quad] = MASK_EXISTS_NW_CORNER; break;
- case 2: _cache[quad] = MASK_EXISTS_NE_CORNER; break;
- case 4: _cache[quad] = MASK_EXISTS_SW_CORNER; break;
- case 8: _cache[quad] = MASK_EXISTS_SE_CORNER; break;
- default:
- // Do nothing, quad is masked out.
- break;
- }
- }
- else if (config == 0)
- _cache[quad] = MASK_EXISTS_QUAD;
- }
- }
- }
-
- // Stage 2, calculate W and S boundaries. For each quad use boundary
- // data already calculated for quads to W and S, so must iterate
- // through quads in correct order (increasing i and j indices).
- // Cannot use boundary data for quads to E and N as have not yet
- // calculated it.
- quad = 0;
- for (j = 0; j < _ny; ++j) {
- for (i = 0; i < _nx; ++i, ++quad) {
- if (_corner_mask) {
- bool W_exists_none = (i == 0 || EXISTS_NONE(quad-1));
- bool S_exists_none = (j == 0 || EXISTS_NONE(quad-_nx));
- bool W_exists_E_edge = (i > 0 && EXISTS_E_EDGE(quad-1));
- bool S_exists_N_edge = (j > 0 && EXISTS_N_EDGE(quad-_nx));
-
- if ((EXISTS_W_EDGE(quad) && W_exists_none) ||
- (EXISTS_NONE(quad) && W_exists_E_edge) ||
- (i % _chunk_size == 0 && EXISTS_W_EDGE(quad) &&
- W_exists_E_edge))
- _cache[quad] |= MASK_BOUNDARY_W;
-
- if ((EXISTS_S_EDGE(quad) && S_exists_none) ||
- (EXISTS_NONE(quad) && S_exists_N_edge) ||
- (j % _chunk_size == 0 && EXISTS_S_EDGE(quad) &&
- S_exists_N_edge))
- _cache[quad] |= MASK_BOUNDARY_S;
- }
- else {
- bool W_exists_quad = (i > 0 && EXISTS_QUAD(quad-1));
- bool S_exists_quad = (j > 0 && EXISTS_QUAD(quad-_nx));
-
- if ((EXISTS_QUAD(quad) != W_exists_quad) ||
- (i % _chunk_size == 0 && EXISTS_QUAD(quad) &&
- W_exists_quad))
- _cache[quad] |= MASK_BOUNDARY_W;
-
- if ((EXISTS_QUAD(quad) != S_exists_quad) ||
- (j % _chunk_size == 0 && EXISTS_QUAD(quad) &&
- S_exists_quad))
- _cache[quad] |= MASK_BOUNDARY_S;
- }
- }
- }
- }
-}
-
-void QuadContourGenerator::init_cache_levels(const double& lower_level,
- const double& upper_level)
-{
- assert(upper_level >= lower_level &&
- "upper and lower levels are wrong way round");
-
- bool two_levels = (lower_level != upper_level);
- CacheItem keep_mask =
- (_corner_mask ? MASK_EXISTS | MASK_BOUNDARY_S | MASK_BOUNDARY_W
- : MASK_EXISTS_QUAD | MASK_BOUNDARY_S | MASK_BOUNDARY_W);
-
- if (two_levels) {
- const double* z_ptr = _z.data();
- for (long quad = 0; quad < _n; ++quad, ++z_ptr) {
- _cache[quad] &= keep_mask;
- if (*z_ptr > upper_level)
- _cache[quad] |= MASK_Z_LEVEL_2;
- else if (*z_ptr > lower_level)
- _cache[quad] |= MASK_Z_LEVEL_1;
- }
- }
- else {
- const double* z_ptr = _z.data();
- for (long quad = 0; quad < _n; ++quad, ++z_ptr) {
- _cache[quad] &= keep_mask;
- if (*z_ptr > lower_level)
- _cache[quad] |= MASK_Z_LEVEL_1;
- }
- }
-}
-
-XY QuadContourGenerator::interp(
- long point1, long point2, const double& level) const
-{
- assert(point1 >= 0 && point1 < _n && "Point index 1 out of bounds.");
- assert(point2 >= 0 && point2 < _n && "Point index 2 out of bounds.");
- assert(point1 != point2 && "Identical points");
- double fraction = (get_point_z(point2) - level) /
- (get_point_z(point2) - get_point_z(point1));
- return get_point_xy(point1)*fraction + get_point_xy(point2)*(1.0 - fraction);
-}
-
-bool QuadContourGenerator::is_edge_a_boundary(const QuadEdge& quad_edge) const
-{
- assert(quad_edge.quad >= 0 && quad_edge.quad < _n &&
- "Quad index out of bounds");
- assert(quad_edge.edge != Edge_None && "Invalid edge");
-
- switch (quad_edge.edge) {
- case Edge_E: return BOUNDARY_E(quad_edge.quad);
- case Edge_N: return BOUNDARY_N(quad_edge.quad);
- case Edge_W: return BOUNDARY_W(quad_edge.quad);
- case Edge_S: return BOUNDARY_S(quad_edge.quad);
- case Edge_NE: return EXISTS_SW_CORNER(quad_edge.quad);
- case Edge_NW: return EXISTS_SE_CORNER(quad_edge.quad);
- case Edge_SW: return EXISTS_NE_CORNER(quad_edge.quad);
- case Edge_SE: return EXISTS_NW_CORNER(quad_edge.quad);
- default: assert(0 && "Invalid edge"); return true;
- }
-}
-
-void QuadContourGenerator::move_to_next_boundary_edge(QuadEdge& quad_edge) const
-{
- assert(is_edge_a_boundary(quad_edge) && "QuadEdge is not a boundary");
-
- long& quad = quad_edge.quad;
- Edge& edge = quad_edge.edge;
-
- quad = get_edge_point_index(quad_edge, false);
-
- // quad is now such that POINT_SW is the end point of the quad_edge passed
- // to this function.
-
- // To find the next boundary edge, first attempt to turn left 135 degrees
- // and if that edge is a boundary then move to it. If not, attempt to turn
- // left 90 degrees, then left 45 degrees, then straight on, etc, until can
- // move.
- // First determine which edge to attempt first.
- int index = 0;
- switch (edge) {
- case Edge_E: index = 0; break;
- case Edge_SE: index = 1; break;
- case Edge_S: index = 2; break;
- case Edge_SW: index = 3; break;
- case Edge_W: index = 4; break;
- case Edge_NW: index = 5; break;
- case Edge_N: index = 6; break;
- case Edge_NE: index = 7; break;
- default: assert(0 && "Invalid edge"); break;
- }
-
- // If _corner_mask not set, only need to consider odd index in loop below.
- if (!_corner_mask)
- ++index;
-
- // Try each edge in turn until a boundary is found.
- int start_index = index;
- do
- {
- switch (index) {
- case 0:
- if (EXISTS_SE_CORNER(quad-_nx-1)) { // Equivalent to BOUNDARY_NW
- quad -= _nx+1;
- edge = Edge_NW;
- return;
- }
- break;
- case 1:
- if (BOUNDARY_N(quad-_nx-1)) {
- quad -= _nx+1;
- edge = Edge_N;
- return;
- }
- break;
- case 2:
- if (EXISTS_SW_CORNER(quad-1)) { // Equivalent to BOUNDARY_NE
- quad -= 1;
- edge = Edge_NE;
- return;
- }
- break;
- case 3:
- if (BOUNDARY_E(quad-1)) {
- quad -= 1;
- edge = Edge_E;
- return;
- }
- break;
- case 4:
- if (EXISTS_NW_CORNER(quad)) { // Equivalent to BOUNDARY_SE
- edge = Edge_SE;
- return;
- }
- break;
- case 5:
- if (BOUNDARY_S(quad)) {
- edge = Edge_S;
- return;
- }
- break;
- case 6:
- if (EXISTS_NE_CORNER(quad-_nx)) { // Equivalent to BOUNDARY_SW
- quad -= _nx;
- edge = Edge_SW;
- return;
- }
- break;
- case 7:
- if (BOUNDARY_W(quad-_nx)) {
- quad -= _nx;
- edge = Edge_W;
- return;
- }
- break;
- default: assert(0 && "Invalid index"); break;
- }
-
- if (_corner_mask)
- index = (index + 1) % 8;
- else
- index = (index + 2) % 8;
- } while (index != start_index);
-
- assert(0 && "Failed to find next boundary edge");
-}
-
-void QuadContourGenerator::move_to_next_quad(QuadEdge& quad_edge) const
-{
- assert(quad_edge.quad >= 0 && quad_edge.quad < _n &&
- "Quad index out of bounds");
- assert(quad_edge.edge != Edge_None && "Invalid edge");
-
- // Move from quad_edge.quad to the neighbouring quad in the direction
- // specified by quad_edge.edge.
- switch (quad_edge.edge) {
- case Edge_E: quad_edge.quad += 1; quad_edge.edge = Edge_W; break;
- case Edge_N: quad_edge.quad += _nx; quad_edge.edge = Edge_S; break;
- case Edge_W: quad_edge.quad -= 1; quad_edge.edge = Edge_E; break;
- case Edge_S: quad_edge.quad -= _nx; quad_edge.edge = Edge_N; break;
- default: assert(0 && "Invalid edge"); break;
- }
-}
-
-void QuadContourGenerator::single_quad_filled(Contour& contour,
- long quad,
- const double& lower_level,
- const double& upper_level)
-{
- assert(quad >= 0 && quad < _n && "Quad index out of bounds");
-
- // Order of checking is important here as can have different ContourLines
- // from both lower and upper levels in the same quad. First check the S
- // edge, then move up the quad to the N edge checking as required.
-
- // Possible starts from S boundary.
- if (BOUNDARY_S(quad) && EXISTS_S_EDGE(quad)) {
-
- // Lower-level start from S boundary into interior.
- if (!VISITED_S(quad) && Z_SW >= 1 && Z_SE == 0)
- contour.push_back(start_filled(quad, Edge_S, 1, NotHole, Interior,
- lower_level, upper_level));
-
- // Upper-level start from S boundary into interior.
- if (!VISITED_S(quad) && Z_SW < 2 && Z_SE == 2)
- contour.push_back(start_filled(quad, Edge_S, 2, NotHole, Interior,
- lower_level, upper_level));
-
- // Lower-level start following S boundary from W to E.
- if (!VISITED_S(quad) && Z_SW <= 1 && Z_SE == 1)
- contour.push_back(start_filled(quad, Edge_S, 1, NotHole, Boundary,
- lower_level, upper_level));
-
- // Upper-level start following S boundary from W to E.
- if (!VISITED_S(quad) && Z_SW == 2 && Z_SE == 1)
- contour.push_back(start_filled(quad, Edge_S, 2, NotHole, Boundary,
- lower_level, upper_level));
- }
-
- // Possible starts from W boundary.
- if (BOUNDARY_W(quad) && EXISTS_W_EDGE(quad)) {
-
- // Lower-level start from W boundary into interior.
- if (!VISITED_W(quad) && Z_NW >= 1 && Z_SW == 0)
- contour.push_back(start_filled(quad, Edge_W, 1, NotHole, Interior,
- lower_level, upper_level));
-
- // Upper-level start from W boundary into interior.
- if (!VISITED_W(quad) && Z_NW < 2 && Z_SW == 2)
- contour.push_back(start_filled(quad, Edge_W, 2, NotHole, Interior,
- lower_level, upper_level));
-
- // Lower-level start following W boundary from N to S.
- if (!VISITED_W(quad) && Z_NW <= 1 && Z_SW == 1)
- contour.push_back(start_filled(quad, Edge_W, 1, NotHole, Boundary,
- lower_level, upper_level));
-
- // Upper-level start following W boundary from N to S.
- if (!VISITED_W(quad) && Z_NW == 2 && Z_SW == 1)
- contour.push_back(start_filled(quad, Edge_W, 2, NotHole, Boundary,
- lower_level, upper_level));
- }
-
- // Possible starts from NE boundary.
- if (EXISTS_SW_CORNER(quad)) { // i.e. BOUNDARY_NE
-
- // Lower-level start following NE boundary from SE to NW, hole.
- if (!VISITED_CORNER(quad) && Z_NW == 1 && Z_SE == 1)
- contour.push_back(start_filled(quad, Edge_NE, 1, Hole, Boundary,
- lower_level, upper_level));
- }
- // Possible starts from SE boundary.
- else if (EXISTS_NW_CORNER(quad)) { // i.e. BOUNDARY_SE
-
- // Lower-level start from N to SE.
- if (!VISITED(quad,1) && Z_NW == 0 && Z_SW == 0 && Z_NE >= 1)
- contour.push_back(start_filled(quad, Edge_N, 1, NotHole, Interior,
- lower_level, upper_level));
-
- // Upper-level start from SE to N, hole.
- if (!VISITED(quad,2) && Z_NW < 2 && Z_SW < 2 && Z_NE == 2)
- contour.push_back(start_filled(quad, Edge_SE, 2, Hole, Interior,
- lower_level, upper_level));
-
- // Upper-level start from N to SE.
- if (!VISITED(quad,2) && Z_NW == 2 && Z_SW == 2 && Z_NE < 2)
- contour.push_back(start_filled(quad, Edge_N, 2, NotHole, Interior,
- lower_level, upper_level));
-
- // Lower-level start from SE to N, hole.
- if (!VISITED(quad,1) && Z_NW >= 1 && Z_SW >= 1 && Z_NE == 0)
- contour.push_back(start_filled(quad, Edge_SE, 1, Hole, Interior,
- lower_level, upper_level));
- }
- // Possible starts from NW boundary.
- else if (EXISTS_SE_CORNER(quad)) { // i.e. BOUNDARY_NW
-
- // Lower-level start from NW to E.
- if (!VISITED(quad,1) && Z_SW == 0 && Z_SE == 0 && Z_NE >= 1)
- contour.push_back(start_filled(quad, Edge_NW, 1, NotHole, Interior,
- lower_level, upper_level));
-
- // Upper-level start from E to NW, hole.
- if (!VISITED(quad,2) && Z_SW < 2 && Z_SE < 2 && Z_NE == 2)
- contour.push_back(start_filled(quad, Edge_E, 2, Hole, Interior,
- lower_level, upper_level));
-
- // Upper-level start from NW to E.
- if (!VISITED(quad,2) && Z_SW == 2 && Z_SE == 2 && Z_NE < 2)
- contour.push_back(start_filled(quad, Edge_NW, 2, NotHole, Interior,
- lower_level, upper_level));
-
- // Lower-level start from E to NW, hole.
- if (!VISITED(quad,1) && Z_SW >= 1 && Z_SE >= 1 && Z_NE == 0)
- contour.push_back(start_filled(quad, Edge_E, 1, Hole, Interior,
- lower_level, upper_level));
- }
- // Possible starts from SW boundary.
- else if (EXISTS_NE_CORNER(quad)) { // i.e. BOUNDARY_SW
-
- // Lower-level start from SW boundary into interior.
- if (!VISITED_CORNER(quad) && Z_NW >= 1 && Z_SE == 0)
- contour.push_back(start_filled(quad, Edge_SW, 1, NotHole, Interior,
- lower_level, upper_level));
-
- // Upper-level start from SW boundary into interior.
- if (!VISITED_CORNER(quad) && Z_NW < 2 && Z_SE == 2)
- contour.push_back(start_filled(quad, Edge_SW, 2, NotHole, Interior,
- lower_level, upper_level));
-
- // Lower-level start following SW boundary from NW to SE.
- if (!VISITED_CORNER(quad) && Z_NW <= 1 && Z_SE == 1)
- contour.push_back(start_filled(quad, Edge_SW, 1, NotHole, Boundary,
- lower_level, upper_level));
-
- // Upper-level start following SW boundary from NW to SE.
- if (!VISITED_CORNER(quad) && Z_NW == 2 && Z_SE == 1)
- contour.push_back(start_filled(quad, Edge_SW, 2, NotHole, Boundary,
- lower_level, upper_level));
- }
-
- // A full (unmasked) quad can only have a start on the NE corner, i.e. from
- // N to E (lower level) or E to N (upper level). Any other start will have
- // already been created in a call to this function for a prior quad so we
- // don't need to test for it again here.
- //
- // The situation is complicated by the possibility that the quad is a
- // saddle quad, in which case a contour line starting on the N could leave
- // by either the W or the E. We only need to consider those leaving E.
- //
- // A NE corner can also have a N to E or E to N start.
- if (EXISTS_QUAD(quad) || EXISTS_NE_CORNER(quad)) {
-
- // Lower-level start from N to E.
- if (!VISITED(quad,1) && Z_NW == 0 && Z_SE == 0 && Z_NE >= 1 &&
- (!SADDLE(quad,1) || SADDLE_LEFT(quad,1)))
- contour.push_back(start_filled(quad, Edge_N, 1, NotHole, Interior,
- lower_level, upper_level));
-
- // Upper-level start from E to N, hole.
- if (!VISITED(quad,2) && Z_NW < 2 && Z_SE < 2 && Z_NE == 2 &&
- (!SADDLE(quad,2) || !SADDLE_LEFT(quad,2)))
- contour.push_back(start_filled(quad, Edge_E, 2, Hole, Interior,
- lower_level, upper_level));
-
- // Upper-level start from N to E.
- if (!VISITED(quad,2) && Z_NW == 2 && Z_SE == 2 && Z_NE < 2 &&
- (!SADDLE(quad,2) || SADDLE_LEFT(quad,2)))
- contour.push_back(start_filled(quad, Edge_N, 2, NotHole, Interior,
- lower_level, upper_level));
-
- // Lower-level start from E to N, hole.
- if (!VISITED(quad,1) && Z_NW >= 1 && Z_SE >= 1 && Z_NE == 0 &&
- (!SADDLE(quad,1) || !SADDLE_LEFT(quad,1)))
- contour.push_back(start_filled(quad, Edge_E, 1, Hole, Interior,
- lower_level, upper_level));
-
- // All possible contours passing through the interior of this quad
- // should have already been created, so assert this.
- assert((VISITED(quad,1) || get_start_edge(quad, 1) == Edge_None) &&
- "Found start of contour that should have already been created");
- assert((VISITED(quad,2) || get_start_edge(quad, 2) == Edge_None) &&
- "Found start of contour that should have already been created");
- }
-
- // Lower-level start following N boundary from E to W, hole.
- // This is required for an internal masked region which is a hole in a
- // surrounding contour line.
- if (BOUNDARY_N(quad) && EXISTS_N_EDGE(quad) &&
- !VISITED_S(quad+_nx) && Z_NW == 1 && Z_NE == 1)
- contour.push_back(start_filled(quad, Edge_N, 1, Hole, Boundary,
- lower_level, upper_level));
-}
-
-ContourLine* QuadContourGenerator::start_filled(
- long quad,
- Edge edge,
- unsigned int start_level_index,
- HoleOrNot hole_or_not,
- BoundaryOrInterior boundary_or_interior,
- const double& lower_level,
- const double& upper_level)
-{
- assert(quad >= 0 && quad < _n && "Quad index out of bounds");
- assert(edge != Edge_None && "Invalid edge");
- assert((start_level_index == 1 || start_level_index == 2) &&
- "start level index must be 1 or 2");
-
- ContourLine* contour_line = new ContourLine(hole_or_not == Hole);
- if (hole_or_not == Hole) {
- // Find and set parent ContourLine.
- ContourLine* parent = _parent_cache.get_parent(quad + 1);
- assert(parent != 0 && "Failed to find parent ContourLine");
- contour_line->set_parent(parent);
- parent->add_child(contour_line);
- }
-
- QuadEdge quad_edge(quad, edge);
- const QuadEdge start_quad_edge(quad_edge);
- unsigned int level_index = start_level_index;
-
- // If starts on interior, can only finish on interior.
- // If starts on boundary, can only finish on boundary.
-
- while (true) {
- if (boundary_or_interior == Interior) {
- double level = (level_index == 1 ? lower_level : upper_level);
- follow_interior(*contour_line, quad_edge, level_index, level,
- false, &start_quad_edge, start_level_index, true);
- }
- else {
- level_index = follow_boundary(
- *contour_line, quad_edge, lower_level,
- upper_level, level_index, start_quad_edge);
- }
-
- if (quad_edge == start_quad_edge && (boundary_or_interior == Boundary ||
- level_index == start_level_index))
- break;
-
- if (boundary_or_interior == Boundary)
- boundary_or_interior = Interior;
- else
- boundary_or_interior = Boundary;
- }
-
- return contour_line;
-}
-
-bool QuadContourGenerator::start_line(
- PyObject* vertices_list, long quad, Edge edge, const double& level)
-{
- assert(vertices_list != 0 && "Null python vertices list");
- assert(is_edge_a_boundary(QuadEdge(quad, edge)) &&
- "QuadEdge is not a boundary");
-
- QuadEdge quad_edge(quad, edge);
- ContourLine contour_line(false);
- follow_interior(contour_line, quad_edge, 1, level, true, 0, 1, false);
- append_contour_line_to_vertices(contour_line, vertices_list);
- return VISITED(quad,1);
-}
-
-void QuadContourGenerator::write_cache(bool grid_only) const
-{
- std::cout << "-----------------------------------------------" << std::endl;
- for (long quad = 0; quad < _n; ++quad)
- write_cache_quad(quad, grid_only);
- std::cout << "-----------------------------------------------" << std::endl;
-}
-
-void QuadContourGenerator::write_cache_quad(long quad, bool grid_only) const
-{
- long j = quad / _nx;
- long i = quad - j*_nx;
- std::cout << quad << ": i=" << i << " j=" << j
- << " EXISTS=" << EXISTS_QUAD(quad);
- if (_corner_mask)
- std::cout << " CORNER=" << EXISTS_SW_CORNER(quad) << EXISTS_SE_CORNER(quad)
- << EXISTS_NW_CORNER(quad) << EXISTS_NE_CORNER(quad);
- std::cout << " BNDY=" << (BOUNDARY_S(quad)>0) << (BOUNDARY_W(quad)>0);
- if (!grid_only) {
- std::cout << " Z=" << Z_LEVEL(quad)
- << " SAD=" << (SADDLE(quad,1)>0) << (SADDLE(quad,2)>0)
- << " LEFT=" << (SADDLE_LEFT(quad,1)>0) << (SADDLE_LEFT(quad,2)>0)
- << " NW=" << (SADDLE_START_SW(quad,1)>0) << (SADDLE_START_SW(quad,2)>0)
- << " VIS=" << (VISITED(quad,1)>0) << (VISITED(quad,2)>0)
- << (VISITED_S(quad)>0) << (VISITED_W(quad)>0)
- << (VISITED_CORNER(quad)>0);
- }
- std::cout << std::endl;
-}
diff --git a/contrib/python/matplotlib/py2/src/_contour.h b/contrib/python/matplotlib/py2/src/_contour.h
deleted file mode 100644
index e01c3bc732..0000000000
--- a/contrib/python/matplotlib/py2/src/_contour.h
+++ /dev/null
@@ -1,530 +0,0 @@
-/*
- * QuadContourGenerator
- * --------------------
- * A QuadContourGenerator generates contours for scalar fields defined on
- * quadrilateral grids. A single QuadContourGenerator object can create both
- * line contours (at single levels) and filled contours (between pairs of
- * levels) for the same field.
- *
- * A field to be contoured has nx, ny points in the x- and y-directions
- * respectively. The quad grid is defined by x and y arrays of shape(ny, nx),
- * and the field itself is the z array also of shape(ny, nx). There is an
- * optional boolean mask; if it exists then it also has shape(ny, nx). The
- * mask applies to grid points rather than quads.
- *
- * How quads are masked based on the point mask is determined by the boolean
- * 'corner_mask' flag. If false then any quad that has one or more of its four
- * corner points masked is itself masked. If true the behaviour is the same
- * except that any quad which has exactly one of its four corner points masked
- * has only the triangular corner (half of the quad) adjacent to that point
- * masked; the opposite triangular corner has three unmasked points and is not
- * masked.
- *
- * By default the entire domain of nx*ny points is contoured together which can
- * result in some very long polygons. The alternative is to break up the
- * domain into subdomains or 'chunks' of smaller size, each of which is
- * independently contoured. The size of these chunks is controlled by the
- * 'nchunk' (or 'chunk_size') parameter. Chunking not only results in shorter
- * polygons but also requires slightly less RAM. It can result in rendering
- * artifacts though, depending on backend, antialiased flag and alpha value.
- *
- * Notation
- * --------
- * i and j are array indices in the x- and y-directions respectively. Although
- * a single element of an array z can be accessed using z[j][i] or z(j,i), it
- * is often convenient to use the single quad index z[quad], where
- * quad = i + j*nx
- * and hence
- * i = quad % nx
- * j = quad / nx
- *
- * Rather than referring to x- and y-directions, compass directions are used
- * instead such that W, E, S, N refer to the -x, +x, -y, +y directions
- * respectively. To move one quad to the E you would therefore add 1 to the
- * quad index, to move one quad to the N you would add nx to the quad index.
- *
- * Cache
- * -----
- * Lots of information that is reused during contouring is stored as single
- * bits in a mesh-sized cache, indexed by quad. Each quad's cache entry stores
- * information about the quad itself such as if it is masked, and about the
- * point at the SW corner of the quad, and about the W and S edges. Hence
- * information about each point and each edge is only stored once in the cache.
- *
- * Cache information is divided into two types: that which is constant over the
- * lifetime of the QuadContourGenerator, and that which changes for each
- * contouring operation. The former is all grid-specific information such
- * as quad and corner masks, and which edges are boundaries, either between
- * masked and non-masked regions or between adjacent chunks. The latter
- * includes whether points lie above or below the current contour levels, plus
- * some flags to indicate how the contouring is progressing.
- *
- * Line Contours
- * -------------
- * A line contour connects points with the same z-value. Each point of such a
- * contour occurs on an edge of the grid, at a point linearly interpolated to
- * the contour z-level from the z-values at the end points of the edge. The
- * direction of a line contour is such that higher values are to the left of
- * the contour, so any edge that the contour passes through will have a left-
- * hand end point with z > contour level and a right-hand end point with
- * z <= contour level.
- *
- * Line contours are of two types. Firstly there are open line strips that
- * start on a boundary, traverse the interior of the domain and end on a
- * boundary. Secondly there are closed line loops that occur completely within
- * the interior of the domain and do not touch a boundary.
- *
- * The QuadContourGenerator makes two sweeps through the grid to generate line
- * contours for a particular level. In the first sweep it looks only for start
- * points that occur on boundaries, and when it finds one it follows the
- * contour through the interior until it finishes on another boundary edge.
- * Each quad that is visited by the algorithm has a 'visited' flag set in the
- * cache to indicate that the quad does not need to be visited again. In the
- * second sweep all non-visited quads are checked to see if they contain part
- * of an interior closed loop, and again each time one is found it is followed
- * through the domain interior until it returns back to its start quad and is
- * therefore completed.
- *
- * The situation is complicated by saddle quads that have two opposite corners
- * with z >= contour level and the other two corners with z < contour level.
- * These therefore contain two segments of a line contour, and the visited
- * flags take account of this by only being set on the second visit. On the
- * first visit a number of saddle flags are set in the cache to indicate which
- * one of the two segments has been completed so far.
- *
- * Filled Contours
- * ---------------
- * Filled contours are produced between two contour levels and are always
- * closed polygons. They can occur completely within the interior of the
- * domain without touching a boundary, following either the lower or upper
- * contour levels. Those on the lower level are exactly like interior line
- * contours with higher values on the left. Those on the upper level are
- * reversed such that higher values are on the right.
- *
- * Filled contours can also involve a boundary in which case they consist of
- * one or more sections along a boundary and one or more sections through the
- * interior. Interior sections can be on either level, and again those on the
- * upper level have higher values on the right. Boundary sections can remain
- * on either contour level or switch between the two.
- *
- * Once the start of a filled contour is found, the algorithm is similar to
- * that for line contours in that it follows the contour to its end, which
- * because filled contours are always closed polygons will be by returning
- * back to the start. However, because two levels must be considered, each
- * level has its own set of saddle and visited flags and indeed some extra
- * visited flags for boundary edges.
- *
- * The major complication for filled contours is that some polygons can be
- * holes (with points ordered clockwise) within other polygons (with points
- * ordered anticlockwise). When it comes to rendering filled contours each
- * non-hole polygon must be rendered along with its zero or more contained
- * holes or the rendering will not be correct. The filled contour finding
- * algorithm could progress pretty much as the line contour algorithm does,
- * taking each polygon as it is found, but then at the end there would have to
- * be an extra step to identify the parent non-hole polygon for each hole.
- * This is not a particularly onerous task but it does not scale well and can
- * easily dominate the execution time of the contour finding for even modest
- * problems. It is much better to identity each hole's parent non-hole during
- * the sweep algorithm.
- *
- * This requirement dictates the order that filled contours are identified. As
- * the algorithm sweeps up through the grid, every time a polygon passes
- * through a quad a ParentCache object is updated with the new possible parent.
- * When a new hole polygon is started, the ParentCache is used to find the
- * first possible parent in the same quad or to the S of it. Great care is
- * needed each time a new quad is checked to see if a new polygon should be
- * started, as a single quad can have multiple polygon starts, e.g. a quad
- * could be a saddle quad for both lower and upper contour levels, meaning it
- * has four contour line segments passing through it which could all be from
- * different polygons. The S-most polygon must be started first, then the next
- * S-most and so on until the N-most polygon is started in that quad.
- */
-#ifndef _CONTOUR_H
-#define _CONTOUR_H
-
-#include "src/numpy_cpp.h"
-#include <stdint.h>
-#include <list>
-#include <iostream>
-#include <vector>
-
-
-// Edge of a quad including diagonal edges of masked quads if _corner_mask true.
-typedef enum
-{
- // Listing values here so easier to check for debug purposes.
- Edge_None = -1,
- Edge_E = 0,
- Edge_N = 1,
- Edge_W = 2,
- Edge_S = 3,
- // The following are only used if _corner_mask is true.
- Edge_NE = 4,
- Edge_NW = 5,
- Edge_SW = 6,
- Edge_SE = 7
-} Edge;
-
-// Combination of a quad and an edge of that quad.
-// An invalid quad edge has quad of -1.
-struct QuadEdge
-{
- QuadEdge();
- QuadEdge(long quad_, Edge edge_);
- bool operator<(const QuadEdge& other) const;
- bool operator==(const QuadEdge& other) const;
- bool operator!=(const QuadEdge& other) const;
- friend std::ostream& operator<<(std::ostream& os,
- const QuadEdge& quad_edge);
-
- long quad;
- Edge edge;
-};
-
-// 2D point with x,y coordinates.
-struct XY
-{
- XY();
- XY(const double& x_, const double& y_);
- bool operator==(const XY& other) const;
- bool operator!=(const XY& other) const;
- XY operator*(const double& multiplier) const;
- const XY& operator+=(const XY& other);
- const XY& operator-=(const XY& other);
- XY operator+(const XY& other) const;
- XY operator-(const XY& other) const;
- friend std::ostream& operator<<(std::ostream& os, const XY& xy);
-
- double x, y;
-};
-
-// A single line of a contour, which may be a closed line loop or an open line
-// strip. Identical adjacent points are avoided using push_back().
-// A ContourLine is either a hole (points ordered clockwise) or it is not
-// (points ordered anticlockwise). Each hole has a parent ContourLine that is
-// not a hole; each non-hole contains zero or more child holes. A non-hole and
-// its child holes must be rendered together to obtain the correct results.
-class ContourLine : public std::vector<XY>
-{
-public:
- typedef std::list<ContourLine*> Children;
-
- ContourLine(bool is_hole);
- void add_child(ContourLine* child);
- void clear_parent();
- const Children& get_children() const;
- const ContourLine* get_parent() const;
- ContourLine* get_parent();
- bool is_hole() const;
- void push_back(const XY& point);
- void set_parent(ContourLine* parent);
- void write() const;
-
-private:
- bool _is_hole;
- ContourLine* _parent; // Only set if is_hole, not owned.
- Children _children; // Only set if !is_hole, not owned.
-};
-
-
-// A Contour is a collection of zero or more ContourLines.
-class Contour : public std::vector<ContourLine*>
-{
-public:
- Contour();
- virtual ~Contour();
- void delete_contour_lines();
- void write() const;
-};
-
-
-// Single chunk of ContourLine parents, indexed by quad. As a chunk's filled
-// contours are created, the ParentCache is updated each time a ContourLine
-// passes through each quad. When a new ContourLine is created, if it is a
-// hole its parent ContourLine is read from the ParentCache by looking at the
-// start quad, then each quad to the S in turn until a non-zero ContourLine is
-// found.
-class ParentCache
-{
-public:
- ParentCache(long nx, long x_chunk_points, long y_chunk_points);
- ContourLine* get_parent(long quad);
- void set_chunk_starts(long istart, long jstart);
- void set_parent(long quad, ContourLine& contour_line);
-
-private:
- long quad_to_index(long quad) const;
-
- long _nx;
- long _x_chunk_points, _y_chunk_points; // Number of points not quads.
- std::vector<ContourLine*> _lines; // Not owned.
- long _istart, _jstart;
-};
-
-
-// See overview of algorithm at top of file.
-class QuadContourGenerator
-{
-public:
- typedef numpy::array_view<const double, 2> CoordinateArray;
- typedef numpy::array_view<const bool, 2> MaskArray;
-
- // Constructor with optional mask.
- // x, y, z: double arrays of shape (ny,nx).
- // mask: boolean array, ether empty (if no mask), or of shape (ny,nx).
- // corner_mask: flag for different masking behaviour.
- // chunk_size: 0 for no chunking, or +ve integer for size of chunks that
- // the domain is subdivided into.
- QuadContourGenerator(const CoordinateArray& x,
- const CoordinateArray& y,
- const CoordinateArray& z,
- const MaskArray& mask,
- bool corner_mask,
- long chunk_size);
-
- // Destructor.
- ~QuadContourGenerator();
-
- // Create and return polygons for a line (i.e. non-filled) contour at the
- // specified level.
- PyObject* create_contour(const double& level);
-
- // Create and return polygons for a filled contour between the two
- // specified levels.
- PyObject* create_filled_contour(const double& lower_level,
- const double& upper_level);
-
-private:
- // Typedef for following either a boundary of the domain or the interior;
- // clearer than using a boolean.
- typedef enum
- {
- Boundary,
- Interior
- } BoundaryOrInterior;
-
- // Typedef for direction of movement from one quad to the next.
- typedef enum
- {
- Dir_Right = -1,
- Dir_Straight = 0,
- Dir_Left = +1
- } Dir;
-
- // Typedef for a polygon being a hole or not; clearer than using a boolean.
- typedef enum
- {
- NotHole,
- Hole
- } HoleOrNot;
-
- // Append a C++ ContourLine to the end of a python list. Used for line
- // contours where each ContourLine is converted to a separate numpy array
- // of (x,y) points.
- // Clears the ContourLine too.
- void append_contour_line_to_vertices(ContourLine& contour_line,
- PyObject* vertices_list) const;
-
- // Append a C++ Contour to the end of two python lists. Used for filled
- // contours where each non-hole ContourLine and its child holes are
- // represented by a numpy array of (x,y) points and a second numpy array of
- // 'kinds' or 'codes' that indicates where the points array is split into
- // individual polygons.
- // Clears the Contour too, freeing each ContourLine as soon as possible
- // for minimum RAM usage.
- void append_contour_to_vertices_and_codes(Contour& contour,
- PyObject* vertices_list,
- PyObject* codes_list) const;
-
- // Return number of chunks that fit in the specified point_count.
- long calc_chunk_count(long point_count) const;
-
- // Return the point on the specified QuadEdge that intersects the specified
- // level.
- XY edge_interp(const QuadEdge& quad_edge, const double& level);
-
- // Follow a contour along a boundary, appending points to the ContourLine
- // as it progresses. Only called for filled contours. Stops when the
- // contour leaves the boundary to move into the interior of the domain, or
- // when the start_quad_edge is reached in which case the ContourLine is a
- // completed closed loop. Always adds the end point of each boundary edge
- // to the ContourLine, regardless of whether moving to another boundary
- // edge or leaving the boundary into the interior. Never adds the start
- // point of the first boundary edge to the ContourLine.
- // contour_line: ContourLine to append points to.
- // quad_edge: on entry the QuadEdge to start from, on exit the QuadEdge
- // that is stopped on.
- // lower_level: lower contour z-value.
- // upper_level: upper contour z-value.
- // level_index: level index started on (1 = lower, 2 = upper level).
- // start_quad_edge: QuadEdge that the ContourLine started from, which is
- // used to check if the ContourLine is finished.
- // Returns the end level_index.
- unsigned int follow_boundary(ContourLine& contour_line,
- QuadEdge& quad_edge,
- const double& lower_level,
- const double& upper_level,
- unsigned int level_index,
- const QuadEdge& start_quad_edge);
-
- // Follow a contour across the interior of the domain, appending points to
- // the ContourLine as it progresses. Called for both line and filled
- // contours. Stops when the contour reaches a boundary or, if the
- // start_quad_edge is specified, when quad_edge == start_quad_edge and
- // level_index == start_level_index. Always adds the end point of each
- // quad traversed to the ContourLine; only adds the start point of the
- // first quad if want_initial_point flag is true.
- // contour_line: ContourLine to append points to.
- // quad_edge: on entry the QuadEdge to start from, on exit the QuadEdge
- // that is stopped on.
- // level_index: level index started on (1 = lower, 2 = upper level).
- // level: contour z-value.
- // want_initial_point: whether want to append the initial point to the
- // ContourLine or not.
- // start_quad_edge: the QuadEdge that the ContourLine started from to
- // check if the ContourLine is finished, or 0 if no check should occur.
- // start_level_index: the level_index that the ContourLine started from.
- // set_parents: whether should set ParentCache as it progresses or not.
- // This is true for filled contours, false for line contours.
- void follow_interior(ContourLine& contour_line,
- QuadEdge& quad_edge,
- unsigned int level_index,
- const double& level,
- bool want_initial_point,
- const QuadEdge* start_quad_edge,
- unsigned int start_level_index,
- bool set_parents);
-
- // Return the index limits of a particular chunk.
- void get_chunk_limits(long ijchunk,
- long& ichunk,
- long& jchunk,
- long& istart,
- long& iend,
- long& jstart,
- long& jend);
-
- // Check if a contour starts within the specified corner quad on the
- // specified level_index, and if so return the start edge. Otherwise
- // return Edge_None.
- Edge get_corner_start_edge(long quad, unsigned int level_index) const;
-
- // Return index of point at start or end of specified QuadEdge, assuming
- // anticlockwise ordering around non-masked quads.
- long get_edge_point_index(const QuadEdge& quad_edge, bool start) const;
-
- // Return the edge to exit a quad from, given the specified entry quad_edge
- // and direction to move in.
- Edge get_exit_edge(const QuadEdge& quad_edge, Dir dir) const;
-
- // Return the (x,y) coordinates of the specified point index.
- XY get_point_xy(long point) const;
-
- // Return the z-value of the specified point index.
- const double& get_point_z(long point) const;
-
- // Check if a contour starts within the specified non-corner quad on the
- // specified level_index, and if so return the start edge. Otherwise
- // return Edge_None.
- Edge get_quad_start_edge(long quad, unsigned int level_index) const;
-
- // Check if a contour starts within the specified quad, whether it is a
- // corner or a full quad, and if so return the start edge. Otherwise
- // return Edge_None.
- Edge get_start_edge(long quad, unsigned int level_index) const;
-
- // Initialise the cache to contain grid information that is constant
- // across the lifetime of this object, i.e. does not vary between calls to
- // create_contour() and create_filled_contour().
- void init_cache_grid(const MaskArray& mask);
-
- // Initialise the cache with information that is specific to contouring the
- // specified two levels. The levels are the same for contour lines,
- // different for filled contours.
- void init_cache_levels(const double& lower_level,
- const double& upper_level);
-
- // Return the (x,y) point at which the level intersects the line connecting
- // the two specified point indices.
- XY interp(long point1, long point2, const double& level) const;
-
- // Return true if the specified QuadEdge is a boundary, i.e. is either an
- // edge between a masked and non-masked quad/corner or is a chunk boundary.
- bool is_edge_a_boundary(const QuadEdge& quad_edge) const;
-
- // Follow a boundary from one QuadEdge to the next in an anticlockwise
- // manner around the non-masked region.
- void move_to_next_boundary_edge(QuadEdge& quad_edge) const;
-
- // Move from the quad specified by quad_edge.quad to the neighbouring quad
- // by crossing the edge specified by quad_edge.edge.
- void move_to_next_quad(QuadEdge& quad_edge) const;
-
- // Check for filled contours starting within the specified quad and
- // complete any that are found, appending them to the specified Contour.
- void single_quad_filled(Contour& contour,
- long quad,
- const double& lower_level,
- const double& upper_level);
-
- // Start and complete a filled contour line.
- // quad: index of quad to start ContourLine in.
- // edge: edge of quad to start ContourLine from.
- // start_level_index: the level_index that the ContourLine starts from.
- // hole_or_not: whether the ContourLine is a hole or not.
- // boundary_or_interior: whether the ContourLine starts on a boundary or
- // the interior.
- // lower_level: lower contour z-value.
- // upper_level: upper contour z-value.
- // Returns newly created ContourLine.
- ContourLine* start_filled(long quad,
- Edge edge,
- unsigned int start_level_index,
- HoleOrNot hole_or_not,
- BoundaryOrInterior boundary_or_interior,
- const double& lower_level,
- const double& upper_level);
-
- // Start and complete a line contour that both starts and end on a
- // boundary, traversing the interior of the domain.
- // vertices_list: Python list that the ContourLine should be appended to.
- // quad: index of quad to start ContourLine in.
- // edge: boundary edge to start ContourLine from.
- // level: contour z-value.
- // Returns true if the start quad does not need to be visited again, i.e.
- // VISITED(quad,1).
- bool start_line(PyObject* vertices_list,
- long quad,
- Edge edge,
- const double& level);
-
- // Debug function that writes the cache status to stdout.
- void write_cache(bool grid_only = false) const;
-
- // Debug function that writes that cache status for a single quad to
- // stdout.
- void write_cache_quad(long quad, bool grid_only) const;
-
-
-
- // Note that mask is not stored as once it has been used to initialise the
- // cache it is no longer needed.
- CoordinateArray _x, _y, _z;
- long _nx, _ny; // Number of points in each direction.
- long _n; // Total number of points (and hence quads).
-
- bool _corner_mask;
- long _chunk_size; // Number of quads per chunk (not points).
- // Always > 0, unlike python nchunk which is 0
- // for no chunking.
-
- long _nxchunk, _nychunk; // Number of chunks in each direction.
- long _chunk_count; // Total number of chunks.
-
- typedef uint32_t CacheItem;
- CacheItem* _cache;
-
- ParentCache _parent_cache; // On W quad sides.
-};
-
-#endif // _CONTOUR_H
diff --git a/contrib/python/matplotlib/py2/src/_contour_wrapper.cpp b/contrib/python/matplotlib/py2/src/_contour_wrapper.cpp
deleted file mode 100644
index eedc8a1aec..0000000000
--- a/contrib/python/matplotlib/py2/src/_contour_wrapper.cpp
+++ /dev/null
@@ -1,203 +0,0 @@
-#include "src/_contour.h"
-#include "src/mplutils.h"
-#include "src/py_exceptions.h"
-
-/* QuadContourGenerator */
-
-typedef struct
-{
- PyObject_HEAD
- QuadContourGenerator* ptr;
-} PyQuadContourGenerator;
-
-static PyTypeObject PyQuadContourGeneratorType;
-
-static PyObject* PyQuadContourGenerator_new(PyTypeObject* type, PyObject* args, PyObject* kwds)
-{
- PyQuadContourGenerator* self;
- self = (PyQuadContourGenerator*)type->tp_alloc(type, 0);
- self->ptr = NULL;
- return (PyObject*)self;
-}
-
-const char* PyQuadContourGenerator_init__doc__ =
- "QuadContourGenerator(x, y, z, mask, corner_mask, chunk_size)\n"
- "\n"
- "Create a new C++ QuadContourGenerator object\n";
-
-static int PyQuadContourGenerator_init(PyQuadContourGenerator* self, PyObject* args, PyObject* kwds)
-{
- QuadContourGenerator::CoordinateArray x, y, z;
- QuadContourGenerator::MaskArray mask;
- int corner_mask;
- long chunk_size;
-
- if (!PyArg_ParseTuple(args, "O&O&O&O&il",
- &x.converter_contiguous, &x,
- &y.converter_contiguous, &y,
- &z.converter_contiguous, &z,
- &mask.converter_contiguous, &mask,
- &corner_mask,
- &chunk_size)) {
- return -1;
- }
-
- if (x.empty() || y.empty() || z.empty() ||
- y.dim(0) != x.dim(0) || z.dim(0) != x.dim(0) ||
- y.dim(1) != x.dim(1) || z.dim(1) != x.dim(1)) {
- PyErr_SetString(PyExc_ValueError,
- "x, y and z must all be 2D arrays with the same dimensions");
- return -1;
- }
-
- if (z.dim(0) < 2 || z.dim(1) < 2) {
- PyErr_SetString(PyExc_ValueError,
- "x, y and z must all be at least 2x2 arrays");
- return -1;
- }
-
- // Mask array is optional, if set must be same size as other arrays.
- if (!mask.empty() && (mask.dim(0) != x.dim(0) || mask.dim(1) != x.dim(1))) {
- PyErr_SetString(PyExc_ValueError,
- "If mask is set it must be a 2D array with the same dimensions as x.");
- return -1;
- }
-
- CALL_CPP_INIT("QuadContourGenerator",
- (self->ptr = new QuadContourGenerator(
- x, y, z, mask, corner_mask, chunk_size)));
- return 0;
-}
-
-static void PyQuadContourGenerator_dealloc(PyQuadContourGenerator* self)
-{
- delete self->ptr;
- Py_TYPE(self)->tp_free((PyObject *)self);
-}
-
-const char* PyQuadContourGenerator_create_contour__doc__ =
- "create_contour(level)\n"
- "\n"
- "Create and return a non-filled contour.";
-
-static PyObject* PyQuadContourGenerator_create_contour(PyQuadContourGenerator* self, PyObject* args, PyObject* kwds)
-{
- double level;
- if (!PyArg_ParseTuple(args, "d:create_contour", &level)) {
- return NULL;
- }
-
- PyObject* result;
- CALL_CPP("create_contour", (result = self->ptr->create_contour(level)));
- return result;
-}
-
-const char* PyQuadContourGenerator_create_filled_contour__doc__ =
- "create_filled_contour(lower_level, upper_level)\n"
- "\n"
- "Create and return a filled contour";
-
-static PyObject* PyQuadContourGenerator_create_filled_contour(PyQuadContourGenerator* self, PyObject* args, PyObject* kwds)
-{
- double lower_level, upper_level;
- if (!PyArg_ParseTuple(args, "dd:create_filled_contour",
- &lower_level, &upper_level)) {
- return NULL;
- }
-
- if (lower_level >= upper_level)
- {
- PyErr_SetString(PyExc_ValueError,
- "filled contour levels must be increasing");
- return NULL;
- }
-
- PyObject* result;
- CALL_CPP("create_filled_contour",
- (result = self->ptr->create_filled_contour(lower_level,
- upper_level)));
- return result;
-}
-
-static PyTypeObject* PyQuadContourGenerator_init_type(PyObject* m, PyTypeObject* type)
-{
- static PyMethodDef methods[] = {
- {"create_contour", (PyCFunction)PyQuadContourGenerator_create_contour, METH_VARARGS, PyQuadContourGenerator_create_contour__doc__},
- {"create_filled_contour", (PyCFunction)PyQuadContourGenerator_create_filled_contour, METH_VARARGS, PyQuadContourGenerator_create_filled_contour__doc__},
- {NULL}
- };
-
- memset(type, 0, sizeof(PyTypeObject));
- type->tp_name = "matplotlib.QuadContourGenerator";
- type->tp_doc = PyQuadContourGenerator_init__doc__;
- type->tp_basicsize = sizeof(PyQuadContourGenerator);
- type->tp_dealloc = (destructor)PyQuadContourGenerator_dealloc;
- type->tp_flags = Py_TPFLAGS_DEFAULT;
- type->tp_methods = methods;
- type->tp_new = PyQuadContourGenerator_new;
- type->tp_init = (initproc)PyQuadContourGenerator_init;
-
- if (PyType_Ready(type) < 0) {
- return NULL;
- }
-
- if (PyModule_AddObject(m, "QuadContourGenerator", (PyObject*)type)) {
- return NULL;
- }
-
- return type;
-}
-
-
-/* Module */
-
-extern "C" {
-
-#if PY3K
-static struct PyModuleDef moduledef = {
- PyModuleDef_HEAD_INIT,
- "_contour",
- NULL,
- 0,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL
-};
-
-#define INITERROR return NULL
-
-PyMODINIT_FUNC PyInit__contour(void)
-
-#else
-#define INITERROR return
-
-PyMODINIT_FUNC init_contour(void)
-#endif
-
-{
- PyObject *m;
-
-#if PY3K
- m = PyModule_Create(&moduledef);
-#else
- m = Py_InitModule3("_contour", NULL, NULL);
-#endif
-
- if (m == NULL) {
- INITERROR;
- }
-
- if (!PyQuadContourGenerator_init_type(m, &PyQuadContourGeneratorType)) {
- INITERROR;
- }
-
- import_array();
-
-#if PY3K
- return m;
-#endif
-}
-
-} // extern "C"
diff --git a/contrib/python/matplotlib/py2/src/_gtkagg.cpp b/contrib/python/matplotlib/py2/src/_gtkagg.cpp
deleted file mode 100644
index 2d6a1cec13..0000000000
--- a/contrib/python/matplotlib/py2/src/_gtkagg.cpp
+++ /dev/null
@@ -1,155 +0,0 @@
-/* -*- 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, &region, -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/_image.cpp b/contrib/python/matplotlib/py2/src/_image.cpp
deleted file mode 100644
index 8fc386fccb..0000000000
--- a/contrib/python/matplotlib/py2/src/_image.cpp
+++ /dev/null
@@ -1,175 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-#define NO_IMPORT_ARRAY
-
-#include <math.h>
-
-// utilities for irregular grids
-void _bin_indices_middle(
- unsigned int *irows, int nrows, const float *ys1, unsigned long ny, float dy, float y_min)
-{
- int i, j, j_last;
- unsigned int *rowstart = irows;
- const float *ys2 = ys1 + 1;
- const float *yl = ys1 + ny;
- float yo = y_min + dy / 2.0;
- float ym = 0.5f * (*ys1 + *ys2);
- // y/rows
- j = 0;
- j_last = j;
- for (i = 0; i < nrows; i++, yo += dy, rowstart++) {
- while (ys2 != yl && yo > ym) {
- ys1 = ys2;
- ys2 = ys1 + 1;
- ym = 0.5f * (*ys1 + *ys2);
- j++;
- }
- *rowstart = j - j_last;
- j_last = j;
- }
-}
-
-void _bin_indices_middle_linear(float *arows,
- unsigned int *irows,
- int nrows,
- const float *y,
- unsigned long ny,
- float dy,
- float y_min)
-{
- int i;
- int ii = 0;
- int iilast = (int)ny - 1;
- float sc = 1 / dy;
- int iy0 = (int)floor(sc * (y[ii] - y_min));
- int iy1 = (int)floor(sc * (y[ii + 1] - y_min));
- float invgap = 1.0f / (iy1 - iy0);
- for (i = 0; i < nrows && i <= iy0; i++) {
- irows[i] = 0;
- arows[i] = 1.0;
- }
- for (; i < nrows; i++) {
- while (i > iy1 && ii < iilast) {
- ii++;
- iy0 = iy1;
- iy1 = (int)floor(sc * (y[ii + 1] - y_min));
- invgap = 1.0f / (iy1 - iy0);
- }
- if (i >= iy0 && i <= iy1) {
- irows[i] = ii;
- arows[i] = (iy1 - i) * invgap;
- } else
- break;
- }
- for (; i < nrows; i++) {
- irows[i] = iilast - 1;
- arows[i] = 0.0;
- }
-}
-
-void _bin_indices(int *irows, int nrows, const double *y, unsigned long ny, double sc, double offs)
-{
- int i;
- if (sc * (y[ny - 1] - y[0]) > 0) {
- int ii = 0;
- int iilast = (int)ny - 1;
- int iy0 = (int)floor(sc * (y[ii] - offs));
- int iy1 = (int)floor(sc * (y[ii + 1] - offs));
- for (i = 0; i < nrows && i < iy0; i++) {
- irows[i] = -1;
- }
- for (; i < nrows; i++) {
- while (i > iy1 && ii < iilast) {
- ii++;
- iy0 = iy1;
- iy1 = (int)floor(sc * (y[ii + 1] - offs));
- }
- if (i >= iy0 && i <= iy1)
- irows[i] = ii;
- else
- break;
- }
- for (; i < nrows; i++) {
- irows[i] = -1;
- }
- } else {
- int iilast = (int)ny - 1;
- int ii = iilast;
- int iy0 = (int)floor(sc * (y[ii] - offs));
- int iy1 = (int)floor(sc * (y[ii - 1] - offs));
- for (i = 0; i < nrows && i < iy0; i++) {
- irows[i] = -1;
- }
- for (; i < nrows; i++) {
- while (i > iy1 && ii > 1) {
- ii--;
- iy0 = iy1;
- iy1 = (int)floor(sc * (y[ii - 1] - offs));
- }
- if (i >= iy0 && i <= iy1)
- irows[i] = ii - 1;
- else
- break;
- }
- for (; i < nrows; i++) {
- irows[i] = -1;
- }
- }
-}
-
-void _bin_indices_linear(
- float *arows, int *irows, int nrows, double *y, unsigned long ny, double sc, double offs)
-{
- int i;
- if (sc * (y[ny - 1] - y[0]) > 0) {
- int ii = 0;
- int iilast = (int)ny - 1;
- int iy0 = (int)floor(sc * (y[ii] - offs));
- int iy1 = (int)floor(sc * (y[ii + 1] - offs));
- float invgap = 1.0 / (iy1 - iy0);
- for (i = 0; i < nrows && i < iy0; i++) {
- irows[i] = -1;
- }
- for (; i < nrows; i++) {
- while (i > iy1 && ii < iilast) {
- ii++;
- iy0 = iy1;
- iy1 = (int)floor(sc * (y[ii + 1] - offs));
- invgap = 1.0 / (iy1 - iy0);
- }
- if (i >= iy0 && i <= iy1) {
- irows[i] = ii;
- arows[i] = (iy1 - i) * invgap;
- } else
- break;
- }
- for (; i < nrows; i++) {
- irows[i] = -1;
- }
- } else {
- int iilast = (int)ny - 1;
- int ii = iilast;
- int iy0 = (int)floor(sc * (y[ii] - offs));
- int iy1 = (int)floor(sc * (y[ii - 1] - offs));
- float invgap = 1.0 / (iy1 - iy0);
- for (i = 0; i < nrows && i < iy0; i++) {
- irows[i] = -1;
- }
- for (; i < nrows; i++) {
- while (i > iy1 && ii > 1) {
- ii--;
- iy0 = iy1;
- iy1 = (int)floor(sc * (y[ii - 1] - offs));
- invgap = 1.0 / (iy1 - iy0);
- }
- if (i >= iy0 && i <= iy1) {
- irows[i] = ii - 1;
- arows[i] = (i - iy0) * invgap;
- } else
- break;
- }
- for (; i < nrows; i++) {
- irows[i] = -1;
- }
- }
-}
diff --git a/contrib/python/matplotlib/py2/src/_image.h b/contrib/python/matplotlib/py2/src/_image.h
deleted file mode 100644
index 629714d2ec..0000000000
--- a/contrib/python/matplotlib/py2/src/_image.h
+++ /dev/null
@@ -1,200 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-/* image.h
- *
- */
-
-#ifndef _IMAGE_H
-#define _IMAGE_H
-
-#include <vector>
-
-
-// utilities for irregular grids
-void _bin_indices_middle(
- unsigned int *irows, int nrows, const float *ys1, unsigned long ny, float dy, float y_min);
-void _bin_indices_middle_linear(float *arows,
- unsigned int *irows,
- int nrows,
- const float *y,
- unsigned long ny,
- float dy,
- float y_min);
-void _bin_indices(int *irows, int nrows, const double *y, unsigned long ny, double sc, double offs);
-void _bin_indices_linear(
- float *arows, int *irows, int nrows, double *y, unsigned long ny, double sc, double offs);
-
-template <class CoordinateArray, class ColorArray, class OutputArray>
-void pcolor(CoordinateArray &x,
- CoordinateArray &y,
- ColorArray &d,
- unsigned int rows,
- unsigned int cols,
- float bounds[4],
- int interpolation,
- OutputArray &out)
-{
- if (rows >= 32768 || cols >= 32768) {
- throw std::runtime_error("rows and cols must both be less than 32768");
- }
-
- float x_min = bounds[0];
- float x_max = bounds[1];
- float y_min = bounds[2];
- float y_max = bounds[3];
- float width = x_max - x_min;
- float height = y_max - y_min;
- float dx = width / ((float)cols);
- float dy = height / ((float)rows);
-
- // Check we have something to output to
- if (rows == 0 || cols == 0) {
- throw std::runtime_error("Cannot scale to zero size");
- }
-
- if (d.dim(2) != 4) {
- throw std::runtime_error("data must be in RGBA format");
- }
-
- // Check dimensions match
- unsigned long nx = x.dim(0);
- unsigned long ny = y.dim(0);
- if (nx != (unsigned long)d.dim(1) || ny != (unsigned long)d.dim(0)) {
- throw std::runtime_error("data and axis dimensions do not match");
- }
-
- // Allocate memory for pointer arrays
- std::vector<unsigned int> rowstarts(rows);
- std::vector<unsigned int> colstarts(cols);
-
- // Calculate the pointer arrays to map input x to output x
- unsigned int i, j;
- unsigned int *colstart = &colstarts[0];
- unsigned int *rowstart = &rowstarts[0];
- const float *xs1 = x.data();
- const float *ys1 = y.data();
-
- // Copy data to output buffer
- const unsigned char *start;
- const unsigned char *inposition;
- size_t inrowsize = nx * 4;
- size_t rowsize = cols * 4;
- unsigned char *position = (unsigned char *)out.data();
- unsigned char *oldposition = NULL;
- start = d.data();
-
- if (interpolation == NEAREST) {
- _bin_indices_middle(colstart, cols, xs1, nx, dx, x_min);
- _bin_indices_middle(rowstart, rows, ys1, ny, dy, y_min);
- for (i = 0; i < rows; i++, rowstart++) {
- if (i > 0 && *rowstart == 0) {
- memcpy(position, oldposition, rowsize * sizeof(unsigned char));
- oldposition = position;
- position += rowsize;
- } else {
- oldposition = position;
- start += *rowstart * inrowsize;
- inposition = start;
- for (j = 0, colstart = &colstarts[0]; j < cols; j++, position += 4, colstart++) {
- inposition += *colstart * 4;
- memcpy(position, inposition, 4 * sizeof(unsigned char));
- }
- }
- }
- } else if (interpolation == BILINEAR) {
- std::vector<float> acols(cols);
- std::vector<float> arows(rows);
-
- _bin_indices_middle_linear(&acols[0], colstart, cols, xs1, nx, dx, x_min);
- _bin_indices_middle_linear(&arows[0], rowstart, rows, ys1, ny, dy, y_min);
- double a00, a01, a10, a11, alpha, beta;
-
- // Copy data to output buffer
- for (i = 0; i < rows; i++) {
- for (j = 0; j < cols; j++) {
- alpha = arows[i];
- beta = acols[j];
-
- a00 = alpha * beta;
- a01 = alpha * (1.0 - beta);
- a10 = (1.0 - alpha) * beta;
- a11 = 1.0 - a00 - a01 - a10;
-
- for (size_t k = 0; k < 4; ++k) {
- position[k] =
- d(rowstart[i], colstart[j], k) * a00 +
- d(rowstart[i], colstart[j] + 1, k) * a01 +
- d(rowstart[i] + 1, colstart[j], k) * a10 +
- d(rowstart[i] + 1, colstart[j] + 1, k) * a11;
- }
- position += 4;
- }
- }
- }
-}
-
-template <class CoordinateArray, class ColorArray, class Color, class OutputArray>
-void pcolor2(CoordinateArray &x,
- CoordinateArray &y,
- ColorArray &d,
- unsigned int rows,
- unsigned int cols,
- float bounds[4],
- Color &bg,
- OutputArray &out)
-{
- double x_left = bounds[0];
- double x_right = bounds[1];
- double y_bot = bounds[2];
- double y_top = bounds[3];
-
- // Check we have something to output to
- if (rows == 0 || cols == 0) {
- throw std::runtime_error("rows or cols is zero; there are no pixels");
- }
-
- if (d.dim(2) != 4) {
- throw std::runtime_error("data must be in RGBA format");
- }
-
- // Check dimensions match
- unsigned long nx = x.dim(0);
- unsigned long ny = y.dim(0);
- if (nx != (unsigned long)d.dim(1) + 1 || ny != (unsigned long)d.dim(0) + 1) {
- throw std::runtime_error("data and axis bin boundary dimensions are incompatible");
- }
-
- if (bg.dim(0) != 4) {
- throw std::runtime_error("bg must be in RGBA format");
- }
-
- std::vector<int> irows(rows);
- std::vector<int> jcols(cols);
-
- // Calculate the pointer arrays to map input x to output x
- size_t i, j;
- const double *x0 = x.data();
- const double *y0 = y.data();
- double sx = cols / (x_right - x_left);
- double sy = rows / (y_top - y_bot);
- _bin_indices(&jcols[0], cols, x0, nx, sx, x_left);
- _bin_indices(&irows[0], rows, y0, ny, sy, y_bot);
-
- // Copy data to output buffer
- unsigned char *position = (unsigned char *)out.data();
-
- for (i = 0; i < rows; i++) {
- for (j = 0; j < cols; j++) {
- if (irows[i] == -1 || jcols[j] == -1) {
- memcpy(position, (const unsigned char *)bg.data(), 4 * sizeof(unsigned char));
- } else {
- for (size_t k = 0; k < 4; ++k) {
- position[k] = d(irows[i], jcols[j], k);
- }
- }
- position += 4;
- }
- }
-}
-
-#endif
diff --git a/contrib/python/matplotlib/py2/src/_image_resample.h b/contrib/python/matplotlib/py2/src/_image_resample.h
deleted file mode 100644
index 86cbef0324..0000000000
--- a/contrib/python/matplotlib/py2/src/_image_resample.h
+++ /dev/null
@@ -1,1013 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-#ifndef RESAMPLE_H
-#define RESAMPLE_H
-
-#include "agg_image_accessors.h"
-#include "agg_path_storage.h"
-#include "agg_pixfmt_gray.h"
-#include "agg_pixfmt_rgb.h"
-#include "agg_pixfmt_rgba.h"
-#include "agg_renderer_base.h"
-#include "agg_renderer_scanline.h"
-#include "agg_rasterizer_scanline_aa.h"
-#include "agg_scanline_u.h"
-#include "agg_span_allocator.h"
-#include "agg_span_converter.h"
-#include "agg_span_image_filter_gray.h"
-#include "agg_span_image_filter_rgba.h"
-#include "agg_span_interpolator_adaptor.h"
-#include "agg_span_interpolator_linear.h"
-
-#include "agg_workaround.h"
-
-// Based on:
-
-//----------------------------------------------------------------------------
-// Anti-Grain Geometry - Version 2.4
-// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
-//
-// Permission to copy, use, modify, sell and distribute this software
-// is granted provided this copyright notice appears in all copies.
-// This software is provided "as is" without express or 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.
-//
-
-//===================================================================gray64
-namespace agg
-{
- struct gray64
- {
- typedef double value_type;
- typedef double calc_type;
- typedef double long_type;
- typedef gray64 self_type;
-
- value_type v;
- value_type a;
-
- //--------------------------------------------------------------------
- gray64() {}
-
- //--------------------------------------------------------------------
- explicit gray64(value_type v_, value_type a_ = 1) :
- v(v_), a(a_) {}
-
- //--------------------------------------------------------------------
- gray64(const self_type& c, value_type a_) :
- v(c.v), a(a_) {}
-
- //--------------------------------------------------------------------
- gray64(const gray64& c) :
- v(c.v),
- a(c.a) {}
-
- //--------------------------------------------------------------------
- static AGG_INLINE double to_double(value_type a)
- {
- return a;
- }
-
- //--------------------------------------------------------------------
- static AGG_INLINE value_type from_double(double a)
- {
- return value_type(a);
- }
-
- //--------------------------------------------------------------------
- static AGG_INLINE value_type empty_value()
- {
- return 0;
- }
-
- //--------------------------------------------------------------------
- static AGG_INLINE value_type full_value()
- {
- return 1;
- }
-
- //--------------------------------------------------------------------
- AGG_INLINE bool is_transparent() const
- {
- return a <= 0;
- }
-
- //--------------------------------------------------------------------
- AGG_INLINE bool is_opaque() const
- {
- return a >= 1;
- }
-
- //--------------------------------------------------------------------
- static AGG_INLINE value_type invert(value_type x)
- {
- return 1 - x;
- }
-
- //--------------------------------------------------------------------
- static AGG_INLINE value_type multiply(value_type a, value_type b)
- {
- return value_type(a * b);
- }
-
- //--------------------------------------------------------------------
- static AGG_INLINE value_type demultiply(value_type a, value_type b)
- {
- return (b == 0) ? 0 : value_type(a / b);
- }
-
- //--------------------------------------------------------------------
- template<typename T>
- static AGG_INLINE T downscale(T a)
- {
- return a;
- }
-
- //--------------------------------------------------------------------
- template<typename T>
- static AGG_INLINE T downshift(T a, unsigned n)
- {
- return n > 0 ? a / (1 << n) : a;
- }
-
- //--------------------------------------------------------------------
- static AGG_INLINE value_type mult_cover(value_type a, cover_type b)
- {
- return value_type(a * b / cover_mask);
- }
-
- //--------------------------------------------------------------------
- static AGG_INLINE cover_type scale_cover(cover_type a, value_type b)
- {
- return cover_type(uround(a * b));
- }
-
- //--------------------------------------------------------------------
- // Interpolate p to q by a, assuming q is premultiplied by a.
- static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a)
- {
- return (1 - a) * p + q; // more accurate than "p + q - p * a"
- }
-
- //--------------------------------------------------------------------
- // Interpolate p to q by a.
- static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a)
- {
- // The form "p + a * (q - p)" avoids a multiplication, but may produce an
- // inaccurate result. For example, "p + (q - p)" may not be exactly equal
- // to q. Therefore, stick to the basic expression, which at least produces
- // the correct result at either extreme.
- return (1 - a) * p + a * q;
- }
-
- //--------------------------------------------------------------------
- self_type& clear()
- {
- v = a = 0;
- return *this;
- }
-
- //--------------------------------------------------------------------
- self_type& transparent()
- {
- a = 0;
- return *this;
- }
-
- //--------------------------------------------------------------------
- self_type& opacity(double a_)
- {
- if (a_ < 0) a = 0;
- else if (a_ > 1) a = 1;
- else a = value_type(a_);
- return *this;
- }
-
- //--------------------------------------------------------------------
- double opacity() const
- {
- return a;
- }
-
-
- //--------------------------------------------------------------------
- self_type& premultiply()
- {
- if (a < 0) v = 0;
- else if(a < 1) v *= a;
- return *this;
- }
-
- //--------------------------------------------------------------------
- self_type& demultiply()
- {
- if (a < 0) v = 0;
- else if (a < 1) v /= a;
- return *this;
- }
-
- //--------------------------------------------------------------------
- self_type gradient(self_type c, double k) const
- {
- return self_type(
- value_type(v + (c.v - v) * k),
- value_type(a + (c.a - a) * k));
- }
-
- //--------------------------------------------------------------------
- static self_type no_color() { return self_type(0,0); }
- };
-
-
- //====================================================================rgba32
- struct rgba64
- {
- typedef double value_type;
- typedef double calc_type;
- typedef double long_type;
- typedef rgba64 self_type;
-
- value_type r;
- value_type g;
- value_type b;
- value_type a;
-
- //--------------------------------------------------------------------
- rgba64() {}
-
- //--------------------------------------------------------------------
- rgba64(value_type r_, value_type g_, value_type b_, value_type a_= 1) :
- r(r_), g(g_), b(b_), a(a_) {}
-
- //--------------------------------------------------------------------
- rgba64(const self_type& c, float a_) :
- r(c.r), g(c.g), b(c.b), a(a_) {}
-
- //--------------------------------------------------------------------
- rgba64(const rgba& c) :
- r(value_type(c.r)), g(value_type(c.g)), b(value_type(c.b)), a(value_type(c.a)) {}
-
- //--------------------------------------------------------------------
- operator rgba() const
- {
- return rgba(r, g, b, a);
- }
-
- //--------------------------------------------------------------------
- static AGG_INLINE double to_double(value_type a)
- {
- return a;
- }
-
- //--------------------------------------------------------------------
- static AGG_INLINE value_type from_double(double a)
- {
- return value_type(a);
- }
-
- //--------------------------------------------------------------------
- static AGG_INLINE value_type empty_value()
- {
- return 0;
- }
-
- //--------------------------------------------------------------------
- static AGG_INLINE value_type full_value()
- {
- return 1;
- }
-
- //--------------------------------------------------------------------
- AGG_INLINE bool is_transparent() const
- {
- return a <= 0;
- }
-
- //--------------------------------------------------------------------
- AGG_INLINE bool is_opaque() const
- {
- return a >= 1;
- }
-
- //--------------------------------------------------------------------
- static AGG_INLINE value_type invert(value_type x)
- {
- return 1 - x;
- }
-
- //--------------------------------------------------------------------
- static AGG_INLINE value_type multiply(value_type a, value_type b)
- {
- return value_type(a * b);
- }
-
- //--------------------------------------------------------------------
- static AGG_INLINE value_type demultiply(value_type a, value_type b)
- {
- return (b == 0) ? 0 : value_type(a / b);
- }
-
- //--------------------------------------------------------------------
- template<typename T>
- static AGG_INLINE T downscale(T a)
- {
- return a;
- }
-
- //--------------------------------------------------------------------
- template<typename T>
- static AGG_INLINE T downshift(T a, unsigned n)
- {
- return n > 0 ? a / (1 << n) : a;
- }
-
- //--------------------------------------------------------------------
- static AGG_INLINE value_type mult_cover(value_type a, cover_type b)
- {
- return value_type(a * b / cover_mask);
- }
-
- //--------------------------------------------------------------------
- static AGG_INLINE cover_type scale_cover(cover_type a, value_type b)
- {
- return cover_type(uround(a * b));
- }
-
- //--------------------------------------------------------------------
- // Interpolate p to q by a, assuming q is premultiplied by a.
- static AGG_INLINE value_type prelerp(value_type p, value_type q, value_type a)
- {
- return (1 - a) * p + q; // more accurate than "p + q - p * a"
- }
-
- //--------------------------------------------------------------------
- // Interpolate p to q by a.
- static AGG_INLINE value_type lerp(value_type p, value_type q, value_type a)
- {
- // The form "p + a * (q - p)" avoids a multiplication, but may produce an
- // inaccurate result. For example, "p + (q - p)" may not be exactly equal
- // to q. Therefore, stick to the basic expression, which at least produces
- // the correct result at either extreme.
- return (1 - a) * p + a * q;
- }
-
- //--------------------------------------------------------------------
- self_type& clear()
- {
- r = g = b = a = 0;
- return *this;
- }
-
- //--------------------------------------------------------------------
- self_type& transparent()
- {
- a = 0;
- return *this;
- }
-
- //--------------------------------------------------------------------
- AGG_INLINE self_type& opacity(double a_)
- {
- if (a_ < 0) a = 0;
- else if (a_ > 1) a = 1;
- else a = value_type(a_);
- return *this;
- }
-
- //--------------------------------------------------------------------
- double opacity() const
- {
- return a;
- }
-
- //--------------------------------------------------------------------
- AGG_INLINE self_type& premultiply()
- {
- if (a < 1)
- {
- if (a <= 0)
- {
- r = g = b = 0;
- }
- else
- {
- r *= a;
- g *= a;
- b *= a;
- }
- }
- return *this;
- }
-
- //--------------------------------------------------------------------
- AGG_INLINE self_type& demultiply()
- {
- if (a < 1)
- {
- if (a <= 0)
- {
- r = g = b = 0;
- }
- else
- {
- r /= a;
- g /= a;
- b /= a;
- }
- }
- return *this;
- }
-
- //--------------------------------------------------------------------
- AGG_INLINE self_type gradient(const self_type& c, double k) const
- {
- self_type ret;
- ret.r = value_type(r + (c.r - r) * k);
- ret.g = value_type(g + (c.g - g) * k);
- ret.b = value_type(b + (c.b - b) * k);
- ret.a = value_type(a + (c.a - a) * k);
- return ret;
- }
-
- //--------------------------------------------------------------------
- AGG_INLINE void add(const self_type& c, unsigned cover)
- {
- if (cover == cover_mask)
- {
- if (c.is_opaque())
- {
- *this = c;
- return;
- }
- else
- {
- r += c.r;
- g += c.g;
- b += c.b;
- a += c.a;
- }
- }
- else
- {
- r += mult_cover(c.r, cover);
- g += mult_cover(c.g, cover);
- b += mult_cover(c.b, cover);
- a += mult_cover(c.a, cover);
- }
- if (a > 1) a = 1;
- if (r > a) r = a;
- if (g > a) g = a;
- if (b > a) b = a;
- }
-
- //--------------------------------------------------------------------
- static self_type no_color() { return self_type(0,0,0,0); }
- };
-}
-
-
-typedef enum {
- NEAREST,
- BILINEAR,
- BICUBIC,
- SPLINE16,
- SPLINE36,
- HANNING,
- HAMMING,
- HERMITE,
- KAISER,
- QUADRIC,
- CATROM,
- GAUSSIAN,
- BESSEL,
- MITCHELL,
- SINC,
- LANCZOS,
- BLACKMAN,
- _n_interpolation
-} interpolation_e;
-
-
-template <typename T>
-class type_mapping;
-
-
-template <> class type_mapping<agg::rgba8>
-{
- public:
- typedef agg::rgba8 color_type;
- typedef fixed_blender_rgba_plain<color_type, agg::order_rgba> blender_type;
- typedef fixed_blender_rgba_pre<color_type, agg::order_rgba> pre_blender_type;
- typedef agg::pixfmt_alpha_blend_rgba<blender_type, agg::rendering_buffer> pixfmt_type;
- typedef agg::pixfmt_alpha_blend_rgba<pre_blender_type, agg::rendering_buffer> pixfmt_pre_type;
-
- template <typename A>
- struct span_gen_affine_type
- {
- typedef agg::span_image_resample_rgba_affine<A> type;
- };
-
- template <typename A, typename B>
- struct span_gen_filter_type
- {
- typedef agg::span_image_filter_rgba<A, B> type;
- };
-
- template <typename A, typename B>
- struct span_gen_nn_type
- {
- typedef agg::span_image_filter_rgba_nn<A, B> type;
- };
-};
-
-
-template <> class type_mapping<agg::rgba16>
-{
- public:
- typedef agg::rgba16 color_type;
- typedef fixed_blender_rgba_plain<color_type, agg::order_rgba> blender_type;
- typedef fixed_blender_rgba_pre<color_type, agg::order_rgba> pre_blender_type;
- typedef agg::pixfmt_alpha_blend_rgba<blender_type, agg::rendering_buffer> pixfmt_type;
- typedef agg::pixfmt_alpha_blend_rgba<pre_blender_type, agg::rendering_buffer> pixfmt_pre_type;
-
- template <typename A>
- struct span_gen_affine_type
- {
- typedef agg::span_image_resample_rgba_affine<A> type;
- };
-
- template <typename A, typename B>
- struct span_gen_filter_type
- {
- typedef agg::span_image_filter_rgba<A, B> type;
- };
-
- template <typename A, typename B>
- struct span_gen_nn_type
- {
- typedef agg::span_image_filter_rgba_nn<A, B> type;
- };
-};
-
-
-template <> class type_mapping<agg::rgba32>
-{
- public:
- typedef agg::rgba32 color_type;
- typedef agg::blender_rgba_plain<color_type, agg::order_rgba> blender_type;
- typedef agg::blender_rgba_pre<color_type, agg::order_rgba> pre_blender_type;
- typedef agg::pixfmt_alpha_blend_rgba<blender_type, agg::rendering_buffer> pixfmt_type;
- typedef agg::pixfmt_alpha_blend_rgba<pre_blender_type, agg::rendering_buffer> pixfmt_pre_type;
-
- template <typename A>
- struct span_gen_affine_type
- {
- typedef agg::span_image_resample_rgba_affine<A> type;
- };
-
- template <typename A, typename B>
- struct span_gen_filter_type
- {
- typedef agg::span_image_filter_rgba<A, B> type;
- };
-
- template <typename A, typename B>
- struct span_gen_nn_type
- {
- typedef agg::span_image_filter_rgba_nn<A, B> type;
- };
-};
-
-
-template <> class type_mapping<agg::rgba64>
-{
- public:
- typedef agg::rgba64 color_type;
- typedef agg::blender_rgba_plain<color_type, agg::order_rgba> blender_type;
- typedef agg::blender_rgba_pre<color_type, agg::order_rgba> pre_blender_type;
- typedef agg::pixfmt_alpha_blend_rgba<blender_type, agg::rendering_buffer> pixfmt_type;
- typedef agg::pixfmt_alpha_blend_rgba<pre_blender_type, agg::rendering_buffer> pixfmt_pre_type;
-
- template <typename A>
- struct span_gen_affine_type
- {
- typedef agg::span_image_resample_rgba_affine<A> type;
- };
-
- template <typename A, typename B>
- struct span_gen_filter_type
- {
- typedef agg::span_image_filter_rgba<A, B> type;
- };
-
- template <typename A, typename B>
- struct span_gen_nn_type
- {
- typedef agg::span_image_filter_rgba_nn<A, B> type;
- };
-};
-
-
-template <> class type_mapping<double>
-{
- public:
- typedef agg::gray64 color_type;
- typedef agg::blender_gray<color_type> blender_type;
- typedef agg::pixfmt_alpha_blend_gray<blender_type, agg::rendering_buffer> pixfmt_type;
- typedef pixfmt_type pixfmt_pre_type;
-
- template <typename A>
- struct span_gen_affine_type
- {
- typedef agg::span_image_resample_gray_affine<A> type;
- };
-
- template <typename A, typename B>
- struct span_gen_filter_type
- {
- typedef agg::span_image_filter_gray<A, B> type;
- };
-
- template <typename A, typename B>
- struct span_gen_nn_type
- {
- typedef agg::span_image_filter_gray_nn<A, B> type;
- };
-};
-
-
-template <> class type_mapping<float>
-{
- public:
- typedef agg::gray32 color_type;
- typedef agg::blender_gray<color_type> blender_type;
- typedef agg::pixfmt_alpha_blend_gray<blender_type, agg::rendering_buffer> pixfmt_type;
- typedef pixfmt_type pixfmt_pre_type;
-
- template <typename A>
- struct span_gen_affine_type
- {
- typedef agg::span_image_resample_gray_affine<A> type;
- };
-
- template <typename A, typename B>
- struct span_gen_filter_type
- {
- typedef agg::span_image_filter_gray<A, B> type;
- };
-
- template <typename A, typename B>
- struct span_gen_nn_type
- {
- typedef agg::span_image_filter_gray_nn<A, B> type;
- };
-};
-
-
-template <> class type_mapping<unsigned short>
-{
- public:
- typedef agg::gray16 color_type;
- typedef agg::blender_gray<color_type> blender_type;
- typedef agg::pixfmt_alpha_blend_gray<blender_type, agg::rendering_buffer> pixfmt_type;
- typedef pixfmt_type pixfmt_pre_type;
-
- template <typename A>
- struct span_gen_affine_type
- {
- typedef agg::span_image_resample_gray_affine<A> type;
- };
-
- template <typename A, typename B>
- struct span_gen_filter_type
- {
- typedef agg::span_image_filter_gray<A, B> type;
- };
-
- template <typename A, typename B>
- struct span_gen_nn_type
- {
- typedef agg::span_image_filter_gray_nn<A, B> type;
- };
-};
-
-
-template <> class type_mapping<unsigned char>
-{
- public:
- typedef agg::gray8 color_type;
- typedef agg::blender_gray<color_type> blender_type;
- typedef agg::pixfmt_alpha_blend_gray<blender_type, agg::rendering_buffer> pixfmt_type;
- typedef pixfmt_type pixfmt_pre_type;
-
- template <typename A>
- struct span_gen_affine_type
- {
- typedef agg::span_image_resample_gray_affine<A> type;
- };
-
- template <typename A, typename B>
- struct span_gen_filter_type
- {
- typedef agg::span_image_filter_gray<A, B> type;
- };
-
- template <typename A, typename B>
- struct span_gen_nn_type
- {
- typedef agg::span_image_filter_gray_nn<A, B> type;
- };
-};
-
-
-
-template<class color_type>
-class span_conv_alpha
-{
-public:
- span_conv_alpha(const double alpha) :
- m_alpha(alpha)
- {
- }
-
- void prepare() {}
-
- void generate(color_type* span, int x, int y, unsigned len) const
- {
- if (m_alpha != 1.0) {
- do {
- span->a *= m_alpha;
- ++span;
- } while (--len);
- }
- }
-private:
-
- const double m_alpha;
-};
-
-
-/* A class to use a lookup table for a transformation */
-class lookup_distortion
-{
-public:
- lookup_distortion(const double *mesh, int in_width, int in_height,
- int out_width, int out_height) :
- m_mesh(mesh),
- m_in_width(in_width),
- m_in_height(in_height),
- m_out_width(out_width),
- m_out_height(out_height)
- {}
-
- void calculate(int* x, int* y) {
- if (m_mesh) {
- double dx = double(*x) / agg::image_subpixel_scale;
- double dy = double(*y) / agg::image_subpixel_scale;
- if (dx >= 0 && dx < m_out_width &&
- dy >= 0 && dy < m_out_height) {
- const double *coord = m_mesh + (int(dy) * m_out_width + int(dx)) * 2;
- *x = int(coord[0] * agg::image_subpixel_scale);
- *y = int(coord[1] * agg::image_subpixel_scale);
- }
- }
- }
-
-protected:
- const double *m_mesh;
- int m_in_width;
- int m_in_height;
- int m_out_width;
- int m_out_height;
-};
-
-
-struct resample_params_t {
- interpolation_e interpolation;
- bool is_affine;
- agg::trans_affine affine;
- const double *transform_mesh;
- bool resample;
- double norm;
- double radius;
- double alpha;
-};
-
-
-static void get_filter(const resample_params_t &params,
- agg::image_filter_lut &filter)
-{
- switch (params.interpolation) {
- case NEAREST:
- case _n_interpolation:
- // Never should get here. Here to silence compiler warnings.
- break;
-
- case HANNING:
- filter.calculate(agg::image_filter_hanning(), params.norm);
- break;
-
- case HAMMING:
- filter.calculate(agg::image_filter_hamming(), params.norm);
- break;
-
- case HERMITE:
- filter.calculate(agg::image_filter_hermite(), params.norm);
- break;
-
- case BILINEAR:
- filter.calculate(agg::image_filter_bilinear(), params.norm);
- break;
-
- case BICUBIC:
- filter.calculate(agg::image_filter_bicubic(), params.norm);
- break;
-
- case SPLINE16:
- filter.calculate(agg::image_filter_spline16(), params.norm);
- break;
-
- case SPLINE36:
- filter.calculate(agg::image_filter_spline36(), params.norm);
- break;
-
- case KAISER:
- filter.calculate(agg::image_filter_kaiser(), params.norm);
- break;
-
- case QUADRIC:
- filter.calculate(agg::image_filter_quadric(), params.norm);
- break;
-
- case CATROM:
- filter.calculate(agg::image_filter_catrom(), params.norm);
- break;
-
- case GAUSSIAN:
- filter.calculate(agg::image_filter_gaussian(), params.norm);
- break;
-
- case BESSEL:
- filter.calculate(agg::image_filter_bessel(), params.norm);
- break;
-
- case MITCHELL:
- filter.calculate(agg::image_filter_mitchell(), params.norm);
- break;
-
- case SINC:
- filter.calculate(agg::image_filter_sinc(params.radius), params.norm);
- break;
-
- case LANCZOS:
- filter.calculate(agg::image_filter_lanczos(params.radius), params.norm);
- break;
-
- case BLACKMAN:
- filter.calculate(agg::image_filter_blackman(params.radius), params.norm);
- break;
- }
-}
-
-
-template<class T>
-void resample(
- const T *input, int in_width, int in_height,
- T *output, int out_width, int out_height,
- resample_params_t &params)
-{
- typedef type_mapping<T> type_mapping_t;
-
- typedef typename type_mapping_t::pixfmt_type input_pixfmt_t;
- typedef typename type_mapping_t::pixfmt_type output_pixfmt_t;
-
- typedef agg::renderer_base<output_pixfmt_t> renderer_t;
- typedef agg::rasterizer_scanline_aa<agg::rasterizer_sl_clip_dbl> rasterizer_t;
-
- typedef agg::wrap_mode_reflect reflect_t;
- typedef agg::image_accessor_wrap<input_pixfmt_t, reflect_t, reflect_t> image_accessor_t;
-
- typedef agg::span_allocator<typename type_mapping_t::color_type> span_alloc_t;
- typedef span_conv_alpha<typename type_mapping_t::color_type> span_conv_alpha_t;
-
- typedef agg::span_interpolator_linear<> affine_interpolator_t;
- typedef agg::span_interpolator_adaptor<agg::span_interpolator_linear<>, lookup_distortion>
- arbitrary_interpolator_t;
-
- if (params.interpolation != NEAREST &&
- params.is_affine &&
- fabs(params.affine.sx) == 1.0 &&
- fabs(params.affine.sy) == 1.0 &&
- params.affine.shx == 0.0 &&
- params.affine.shy == 0.0) {
- params.interpolation = NEAREST;
- }
-
- span_alloc_t span_alloc;
- rasterizer_t rasterizer;
- agg::scanline_u8 scanline;
-
- span_conv_alpha_t conv_alpha(params.alpha);
-
- agg::rendering_buffer input_buffer;
- input_buffer.attach((unsigned char *)input, in_width, in_height,
- in_width * sizeof(T));
- input_pixfmt_t input_pixfmt(input_buffer);
- image_accessor_t input_accessor(input_pixfmt);
-
- agg::rendering_buffer output_buffer;
- output_buffer.attach((unsigned char *)output, out_width, out_height,
- out_width * sizeof(T));
- output_pixfmt_t output_pixfmt(output_buffer);
- renderer_t renderer(output_pixfmt);
-
- agg::trans_affine inverted = params.affine;
- inverted.invert();
-
- rasterizer.clip_box(0, 0, out_width, out_height);
-
- agg::path_storage path;
- if (params.is_affine) {
- path.move_to(0, 0);
- path.line_to(in_width, 0);
- path.line_to(in_width, in_height);
- path.line_to(0, in_height);
- path.close_polygon();
- agg::conv_transform<agg::path_storage> rectangle(path, params.affine);
- rasterizer.add_path(rectangle);
- } else {
- path.move_to(0, 0);
- path.line_to(out_width, 0);
- path.line_to(out_width, out_height);
- path.line_to(0, out_height);
- path.close_polygon();
- rasterizer.add_path(path);
- }
-
- if (params.interpolation == NEAREST) {
- if (params.is_affine) {
- typedef typename type_mapping_t::template span_gen_nn_type<image_accessor_t, affine_interpolator_t>::type span_gen_t;
- typedef agg::span_converter<span_gen_t, span_conv_alpha_t> span_conv_t;
- typedef agg::renderer_scanline_aa<renderer_t, span_alloc_t, span_conv_t> nn_renderer_t;
-
- affine_interpolator_t interpolator(inverted);
- span_gen_t span_gen(input_accessor, interpolator);
- span_conv_t span_conv(span_gen, conv_alpha);
- nn_renderer_t nn_renderer(renderer, span_alloc, span_conv);
- agg::render_scanlines(rasterizer, scanline, nn_renderer);
- } else {
- typedef typename type_mapping_t::template span_gen_nn_type<image_accessor_t, arbitrary_interpolator_t>::type span_gen_t;
- typedef agg::span_converter<span_gen_t, span_conv_alpha_t> span_conv_t;
- typedef agg::renderer_scanline_aa<renderer_t, span_alloc_t, span_conv_t> nn_renderer_t;
-
- lookup_distortion dist(
- params.transform_mesh, in_width, in_height, out_width, out_height);
- arbitrary_interpolator_t interpolator(inverted, dist);
- span_gen_t span_gen(input_accessor, interpolator);
- span_conv_t span_conv(span_gen, conv_alpha);
- nn_renderer_t nn_renderer(renderer, span_alloc, span_conv);
- agg::render_scanlines(rasterizer, scanline, nn_renderer);
- }
- } else {
- agg::image_filter_lut filter;
- get_filter(params, filter);
-
- if (params.is_affine && params.resample) {
- typedef typename type_mapping_t::template span_gen_affine_type<image_accessor_t>::type span_gen_t;
- typedef agg::span_converter<span_gen_t, span_conv_alpha_t> span_conv_t;
- typedef agg::renderer_scanline_aa<renderer_t, span_alloc_t, span_conv_t> int_renderer_t;
-
- affine_interpolator_t interpolator(inverted);
- span_gen_t span_gen(input_accessor, interpolator, filter);
- span_conv_t span_conv(span_gen, conv_alpha);
- int_renderer_t int_renderer(renderer, span_alloc, span_conv);
- agg::render_scanlines(rasterizer, scanline, int_renderer);
- } else {
- typedef typename type_mapping_t::template span_gen_filter_type<image_accessor_t, arbitrary_interpolator_t>::type span_gen_t;
- typedef agg::span_converter<span_gen_t, span_conv_alpha_t> span_conv_t;
- typedef agg::renderer_scanline_aa<renderer_t, span_alloc_t, span_conv_t> int_renderer_t;
-
- lookup_distortion dist(
- params.transform_mesh, in_width, in_height, out_width, out_height);
- arbitrary_interpolator_t interpolator(inverted, dist);
- span_gen_t span_gen(input_accessor, interpolator, filter);
- span_conv_t span_conv(span_gen, conv_alpha);
- int_renderer_t int_renderer(renderer, span_alloc, span_conv);
- agg::render_scanlines(rasterizer, scanline, int_renderer);
- }
- }
-}
-
-#endif /* RESAMPLE_H */
diff --git a/contrib/python/matplotlib/py2/src/_image_wrapper.cpp b/contrib/python/matplotlib/py2/src/_image_wrapper.cpp
deleted file mode 100644
index ee0bfe84c7..0000000000
--- a/contrib/python/matplotlib/py2/src/_image_wrapper.cpp
+++ /dev/null
@@ -1,510 +0,0 @@
-#include "mplutils.h"
-#include "_image_resample.h"
-#include "_image.h"
-#include "py_converters.h"
-
-
-#ifndef NPY_1_7_API_VERSION
-#define NPY_ARRAY_C_CONTIGUOUS NPY_C_CONTIGUOUS
-#endif
-
-
-/**********************************************************************
- * Free functions
- * */
-
-const char* image_resample__doc__ =
-"resample(input_array, output_array, matrix, interpolation=NEAREST, alpha=1.0, norm=0, radius=1)\n\n"
-
-"Resample input_array, blending it in-place into output_array, using an\n"
-"affine transformation.\n\n"
-
-"Parameters\n"
-"----------\n"
-"input_array : 2-d or 3-d Numpy array of float, double or uint8\n"
-" If 2-d, the image is grayscale. If 3-d, the image must be of size\n"
-" 4 in the last dimension and represents RGBA data.\n\n"
-
-"output_array : 2-d or 3-d Numpy array of float, double or uint8\n"
-" The dtype and number of dimensions must match `input_array`.\n\n"
-
-"transform : matplotlib.transforms.Transform instance\n"
-" The transformation from the input array to the output\n"
-" array.\n\n"
-
-"interpolation : int, optional\n"
-" The interpolation method. Must be one of the following constants\n"
-" defined in this module:\n\n"
-
-" NEAREST (default), BILINEAR, BICUBIC, SPLINE16, SPLINE36,\n"
-" HANNING, HAMMING, HERMITE, KAISER, QUADRIC, CATROM, GAUSSIAN,\n"
-" BESSEL, MITCHELL, SINC, LANCZOS, BLACKMAN\n\n"
-
-"resample : bool, optional\n"
-" When `True`, use a full resampling method. When `False`, only\n"
-" resample when the output image is larger than the input image.\n\n"
-
-"alpha : float, optional\n"
-" The level of transparency to apply. 1.0 is completely opaque.\n"
-" 0.0 is completely transparent.\n\n"
-
-"norm : float, optional\n"
-" The norm for the interpolation function. Default is 0.\n\n"
-
-"radius: float, optional\n"
-" The radius of the kernel, if method is SINC, LANCZOS or BLACKMAN.\n"
-" Default is 1.\n";
-
-
-static PyArrayObject *
-_get_transform_mesh(PyObject *py_affine, npy_intp *dims)
-{
- /* TODO: Could we get away with float, rather than double, arrays here? */
-
- /* Given a non-affine transform object, create a mesh that maps
- every pixel in the output image to the input image. This is used
- as a lookup table during the actual resampling. */
-
- PyObject *py_inverse = NULL;
- npy_intp out_dims[3];
-
- out_dims[0] = dims[0] * dims[1];
- out_dims[1] = 2;
-
- py_inverse = PyObject_CallMethod(
- py_affine, (char *)"inverted", (char *)"", NULL);
- if (py_inverse == NULL) {
- return NULL;
- }
-
- numpy::array_view<double, 2> input_mesh(out_dims);
- double *p = (double *)input_mesh.data();
-
- for (npy_intp y = 0; y < dims[0]; ++y) {
- for (npy_intp x = 0; x < dims[1]; ++x) {
- *p++ = (double)x;
- *p++ = (double)y;
- }
- }
-
- PyObject *output_mesh =
- PyObject_CallMethod(
- py_inverse, (char *)"transform", (char *)"O",
- (char *)input_mesh.pyobj(), NULL);
-
- Py_DECREF(py_inverse);
-
- if (output_mesh == NULL) {
- return NULL;
- }
-
- PyArrayObject *output_mesh_array =
- (PyArrayObject *)PyArray_ContiguousFromAny(
- output_mesh, NPY_DOUBLE, 2, 2);
-
- Py_DECREF(output_mesh);
-
- if (output_mesh_array == NULL) {
- return NULL;
- }
-
- return output_mesh_array;
-}
-
-
-static PyObject *
-image_resample(PyObject *self, PyObject* args, PyObject *kwargs)
-{
- PyObject *py_input_array = NULL;
- PyObject *py_output_array = NULL;
- PyObject *py_transform = NULL;
- resample_params_t params;
- int resample_;
-
- PyArrayObject *input_array = NULL;
- PyArrayObject *output_array = NULL;
- PyArrayObject *transform_mesh_array = NULL;
-
- params.transform_mesh = NULL;
-
- const char *kwlist[] = {
- "input_array", "output_array", "transform", "interpolation",
- "resample", "alpha", "norm", "radius", NULL };
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kwargs, "OOO|iiddd:resample", (char **)kwlist,
- &py_input_array, &py_output_array, &py_transform,
- &params.interpolation, &resample_, &params.alpha, &params.norm,
- &params.radius)) {
- return NULL;
- }
-
- if (params.interpolation < 0 || params.interpolation >= _n_interpolation) {
- PyErr_Format(PyExc_ValueError, "invalid interpolation value %d",
- params.interpolation);
- goto error;
- }
-
- params.resample = (resample_ != 0);
-
- input_array = (PyArrayObject *)PyArray_FromAny(
- py_input_array, NULL, 2, 3, NPY_ARRAY_C_CONTIGUOUS, NULL);
- if (input_array == NULL) {
- goto error;
- }
-
- output_array = (PyArrayObject *)PyArray_FromAny(
- py_output_array, NULL, 2, 3, NPY_ARRAY_C_CONTIGUOUS, NULL);
- if (output_array == NULL) {
- goto error;
- }
-
- if (py_transform == NULL || py_transform == Py_None) {
- params.is_affine = true;
- } else {
- PyObject *py_is_affine;
- int py_is_affine2;
- py_is_affine = PyObject_GetAttrString(py_transform, "is_affine");
- if (py_is_affine == NULL) {
- goto error;
- }
-
- py_is_affine2 = PyObject_IsTrue(py_is_affine);
- Py_DECREF(py_is_affine);
-
- if (py_is_affine2 == -1) {
- goto error;
- } else if (py_is_affine2) {
- if (!convert_trans_affine(py_transform, &params.affine)) {
- goto error;
- }
- params.is_affine = true;
- } else {
- transform_mesh_array = _get_transform_mesh(
- py_transform, PyArray_DIMS(output_array));
- if (transform_mesh_array == NULL) {
- goto error;
- }
- params.transform_mesh = (double *)PyArray_DATA(transform_mesh_array);
- params.is_affine = false;
- }
- }
-
- if (PyArray_NDIM(input_array) != PyArray_NDIM(output_array)) {
- PyErr_Format(
- PyExc_ValueError,
- "Mismatched number of dimensions. Got %d and %d.",
- PyArray_NDIM(input_array), PyArray_NDIM(output_array));
- goto error;
- }
-
- if (PyArray_TYPE(input_array) != PyArray_TYPE(output_array)) {
- PyErr_SetString(PyExc_ValueError, "Mismatched types");
- goto error;
- }
-
- if (PyArray_NDIM(input_array) == 3) {
- if (PyArray_DIM(output_array, 2) != 4) {
- PyErr_SetString(
- PyExc_ValueError,
- "Output array must be RGBA");
- goto error;
- }
-
- if (PyArray_DIM(input_array, 2) == 4) {
- switch(PyArray_TYPE(input_array)) {
- case NPY_BYTE:
- case NPY_UINT8:
- Py_BEGIN_ALLOW_THREADS
- resample(
- (agg::rgba8 *)PyArray_DATA(input_array),
- PyArray_DIM(input_array, 1),
- PyArray_DIM(input_array, 0),
- (agg::rgba8 *)PyArray_DATA(output_array),
- PyArray_DIM(output_array, 1),
- PyArray_DIM(output_array, 0),
- params);
- Py_END_ALLOW_THREADS
- break;
- case NPY_UINT16:
- case NPY_INT16:
- Py_BEGIN_ALLOW_THREADS
- resample(
- (agg::rgba16 *)PyArray_DATA(input_array),
- PyArray_DIM(input_array, 1),
- PyArray_DIM(input_array, 0),
- (agg::rgba16 *)PyArray_DATA(output_array),
- PyArray_DIM(output_array, 1),
- PyArray_DIM(output_array, 0),
- params);
- Py_END_ALLOW_THREADS
- break;
- case NPY_FLOAT32:
- Py_BEGIN_ALLOW_THREADS
- resample(
- (agg::rgba32 *)PyArray_DATA(input_array),
- PyArray_DIM(input_array, 1),
- PyArray_DIM(input_array, 0),
- (agg::rgba32 *)PyArray_DATA(output_array),
- PyArray_DIM(output_array, 1),
- PyArray_DIM(output_array, 0),
- params);
- Py_END_ALLOW_THREADS
- break;
- case NPY_FLOAT64:
- Py_BEGIN_ALLOW_THREADS
- resample(
- (agg::rgba64 *)PyArray_DATA(input_array),
- PyArray_DIM(input_array, 1),
- PyArray_DIM(input_array, 0),
- (agg::rgba64 *)PyArray_DATA(output_array),
- PyArray_DIM(output_array, 1),
- PyArray_DIM(output_array, 0),
- params);
- Py_END_ALLOW_THREADS
- break;
- default:
- PyErr_SetString(
- PyExc_ValueError,
- "3-dimensional arrays must be of dtype unsigned byte, "
- "unsigned short, float32 or float64");
- goto error;
- }
- } else {
- PyErr_Format(
- PyExc_ValueError,
- "If 3-dimensional, array must be RGBA. Got %" NPY_INTP_FMT " planes.",
- PyArray_DIM(input_array, 2));
- goto error;
- }
- } else { // NDIM == 2
- switch (PyArray_TYPE(input_array)) {
- case NPY_DOUBLE:
- Py_BEGIN_ALLOW_THREADS
- resample(
- (double *)PyArray_DATA(input_array),
- PyArray_DIM(input_array, 1),
- PyArray_DIM(input_array, 0),
- (double *)PyArray_DATA(output_array),
- PyArray_DIM(output_array, 1),
- PyArray_DIM(output_array, 0),
- params);
- Py_END_ALLOW_THREADS
- break;
- case NPY_FLOAT:
- Py_BEGIN_ALLOW_THREADS
- resample(
- (float *)PyArray_DATA(input_array),
- PyArray_DIM(input_array, 1),
- PyArray_DIM(input_array, 0),
- (float *)PyArray_DATA(output_array),
- PyArray_DIM(output_array, 1),
- PyArray_DIM(output_array, 0),
- params);
- Py_END_ALLOW_THREADS
- break;
- case NPY_UINT8:
- case NPY_BYTE:
- Py_BEGIN_ALLOW_THREADS
- resample(
- (unsigned char *)PyArray_DATA(input_array),
- PyArray_DIM(input_array, 1),
- PyArray_DIM(input_array, 0),
- (unsigned char *)PyArray_DATA(output_array),
- PyArray_DIM(output_array, 1),
- PyArray_DIM(output_array, 0),
- params);
- Py_END_ALLOW_THREADS
- break;
- case NPY_UINT16:
- case NPY_INT16:
- Py_BEGIN_ALLOW_THREADS
- resample(
- (unsigned short *)PyArray_DATA(input_array),
- PyArray_DIM(input_array, 1),
- PyArray_DIM(input_array, 0),
- (unsigned short *)PyArray_DATA(output_array),
- PyArray_DIM(output_array, 1),
- PyArray_DIM(output_array, 0),
- params);
- Py_END_ALLOW_THREADS
- break;
- default:
- PyErr_SetString(PyExc_ValueError, "Unsupported dtype");
- goto error;
- }
- }
-
- Py_DECREF(input_array);
- Py_XDECREF(transform_mesh_array);
- return (PyObject *)output_array;
-
- error:
- Py_XDECREF(input_array);
- Py_XDECREF(output_array);
- Py_XDECREF(transform_mesh_array);
- return NULL;
-}
-
-
-const char *image_pcolor__doc__ =
- "pcolor(x, y, data, rows, cols, bounds)\n"
- "\n"
- "Generate a pseudo-color image from data on a non-uniform grid using\n"
- "nearest neighbour or linear interpolation.\n"
- "bounds = (x_min, x_max, y_min, y_max)\n"
- "interpolation = NEAREST or BILINEAR \n";
-
-static PyObject *image_pcolor(PyObject *self, PyObject *args, PyObject *kwds)
-{
- numpy::array_view<const float, 1> x;
- numpy::array_view<const float, 1> y;
- numpy::array_view<const agg::int8u, 3> d;
- npy_intp rows, cols;
- float bounds[4];
- int interpolation;
-
- if (!PyArg_ParseTuple(args,
- "O&O&O&nn(ffff)i:pcolor",
- &x.converter,
- &x,
- &y.converter,
- &y,
- &d.converter_contiguous,
- &d,
- &rows,
- &cols,
- &bounds[0],
- &bounds[1],
- &bounds[2],
- &bounds[3],
- &interpolation)) {
- return NULL;
- }
-
- npy_intp dim[3] = {rows, cols, 4};
- numpy::array_view<const agg::int8u, 3> output(dim);
-
- CALL_CPP("pcolor", (pcolor(x, y, d, rows, cols, bounds, interpolation, output)));
-
- return output.pyobj();
-}
-
-const char *image_pcolor2__doc__ =
- "pcolor2(x, y, data, rows, cols, bounds, bg)\n"
- "\n"
- "Generate a pseudo-color image from data on a non-uniform grid\n"
- "specified by its cell boundaries.\n"
- "bounds = (x_left, x_right, y_bot, y_top)\n"
- "bg = ndarray of 4 uint8 representing background rgba\n";
-
-static PyObject *image_pcolor2(PyObject *self, PyObject *args, PyObject *kwds)
-{
- numpy::array_view<const double, 1> x;
- numpy::array_view<const double, 1> y;
- numpy::array_view<const agg::int8u, 3> d;
- npy_intp rows, cols;
- float bounds[4];
- numpy::array_view<const agg::int8u, 1> bg;
-
- if (!PyArg_ParseTuple(args,
- "O&O&O&nn(ffff)O&:pcolor2",
- &x.converter_contiguous,
- &x,
- &y.converter_contiguous,
- &y,
- &d.converter_contiguous,
- &d,
- &rows,
- &cols,
- &bounds[0],
- &bounds[1],
- &bounds[2],
- &bounds[3],
- &bg.converter,
- &bg)) {
- return NULL;
- }
-
- npy_intp dim[3] = {rows, cols, 4};
- numpy::array_view<const agg::int8u, 3> output(dim);
-
- CALL_CPP("pcolor2", (pcolor2(x, y, d, rows, cols, bounds, bg, output)));
-
- return output.pyobj();
-}
-
-static PyMethodDef module_functions[] = {
- {"resample", (PyCFunction)image_resample, METH_VARARGS|METH_KEYWORDS, image_resample__doc__},
- {"pcolor", (PyCFunction)image_pcolor, METH_VARARGS, image_pcolor__doc__},
- {"pcolor2", (PyCFunction)image_pcolor2, METH_VARARGS, image_pcolor2__doc__},
- {NULL}
-};
-
-extern "C" {
-
-#if PY3K
-static struct PyModuleDef moduledef = {
- PyModuleDef_HEAD_INIT,
- "_image",
- NULL,
- 0,
- module_functions,
- NULL,
- NULL,
- NULL,
- NULL
-};
-
-#define INITERROR return NULL
-
-PyMODINIT_FUNC PyInit__image(void)
-
-#else
-#define INITERROR return
-
-PyMODINIT_FUNC init_image(void)
-#endif
-
-{
- PyObject *m;
-
-#if PY3K
- m = PyModule_Create(&moduledef);
-#else
- m = Py_InitModule3("_image", module_functions, NULL);
-#endif
-
- if (m == NULL) {
- INITERROR;
- }
-
- if (PyModule_AddIntConstant(m, "NEAREST", NEAREST) ||
- PyModule_AddIntConstant(m, "BILINEAR", BILINEAR) ||
- PyModule_AddIntConstant(m, "BICUBIC", BICUBIC) ||
- PyModule_AddIntConstant(m, "SPLINE16", SPLINE16) ||
- PyModule_AddIntConstant(m, "SPLINE36", SPLINE36) ||
- PyModule_AddIntConstant(m, "HANNING", HANNING) ||
- PyModule_AddIntConstant(m, "HAMMING", HAMMING) ||
- PyModule_AddIntConstant(m, "HERMITE", HERMITE) ||
- PyModule_AddIntConstant(m, "KAISER", KAISER) ||
- PyModule_AddIntConstant(m, "QUADRIC", QUADRIC) ||
- PyModule_AddIntConstant(m, "CATROM", CATROM) ||
- PyModule_AddIntConstant(m, "GAUSSIAN", GAUSSIAN) ||
- PyModule_AddIntConstant(m, "BESSEL", BESSEL) ||
- PyModule_AddIntConstant(m, "MITCHELL", MITCHELL) ||
- PyModule_AddIntConstant(m, "SINC", SINC) ||
- PyModule_AddIntConstant(m, "LANCZOS", LANCZOS) ||
- PyModule_AddIntConstant(m, "BLACKMAN", BLACKMAN) ||
- PyModule_AddIntConstant(m, "_n_interpolation", _n_interpolation)) {
- INITERROR;
- }
-
- import_array();
-
-#if PY3K
- return m;
-#endif
-}
-
-} // extern "C"
diff --git a/contrib/python/matplotlib/py2/src/_macosx.m b/contrib/python/matplotlib/py2/src/_macosx.m
deleted file mode 100644
index 8f44f1eb0c..0000000000
--- a/contrib/python/matplotlib/py2/src/_macosx.m
+++ /dev/null
@@ -1,3174 +0,0 @@
-#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/_path.h b/contrib/python/matplotlib/py2/src/_path.h
deleted file mode 100644
index 76f1894c4a..0000000000
--- a/contrib/python/matplotlib/py2/src/_path.h
+++ /dev/null
@@ -1,1316 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-#ifndef __PATH_H__
-#define __PATH_H__
-
-#include <limits>
-#include <math.h>
-#include <vector>
-#include <cmath>
-#include <algorithm>
-
-#include "agg_conv_contour.h"
-#include "agg_conv_curve.h"
-#include "agg_conv_stroke.h"
-#include "agg_conv_transform.h"
-#include "agg_path_storage.h"
-#include "agg_trans_affine.h"
-
-#include "path_converters.h"
-#include "_backend_agg_basic_types.h"
-#include "numpy_cpp.h"
-
-struct XY
-{
- double x;
- double y;
-
- XY(double x_, double y_) : x(x_), y(y_)
- {
- }
-
- bool operator==(const XY& o)
- {
- return (x == o.x && y == o.y);
- }
-
- bool operator!=(const XY& o)
- {
- return (x != o.x || y != o.y);
- }
-};
-
-typedef std::vector<XY> Polygon;
-
-void _finalize_polygon(std::vector<Polygon> &result, int closed_only)
-{
- if (result.size() == 0) {
- return;
- }
-
- Polygon &polygon = result.back();
-
- /* Clean up the last polygon in the result. */
- if (polygon.size() == 0) {
- result.pop_back();
- } else if (closed_only) {
- if (polygon.size() < 3) {
- result.pop_back();
- } else if (polygon.front() != polygon.back()) {
- polygon.push_back(polygon.front());
- }
- }
-}
-
-//
-// The following function was found in the Agg 2.3 examples (interactive_polygon.cpp).
-// It has been generalized to work on (possibly curved) polylines, rather than
-// just polygons. The original comments have been kept intact.
-// -- Michael Droettboom 2007-10-02
-//
-//======= 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.
-template <class PathIterator, class PointArray, class ResultArray>
-void point_in_path_impl(PointArray &points, PathIterator &path, ResultArray &inside_flag)
-{
- uint8_t yflag1;
- double vtx0, vty0, vtx1, vty1;
- double tx, ty;
- double sx, sy;
- double x, y;
- size_t i;
- bool all_done;
-
- size_t n = points.size();
-
- std::vector<uint8_t> yflag0(n);
- std::vector<uint8_t> subpath_flag(n);
-
- path.rewind(0);
-
- for (i = 0; i < n; ++i) {
- inside_flag[i] = 0;
- }
-
- unsigned code = 0;
- do {
- if (code != agg::path_cmd_move_to) {
- code = path.vertex(&x, &y);
- if (code == agg::path_cmd_stop ||
- (code & agg::path_cmd_end_poly) == agg::path_cmd_end_poly) {
- continue;
- }
- }
-
- sx = vtx0 = vtx1 = x;
- sy = vty0 = vty1 = y;
-
- for (i = 0; i < n; ++i) {
- ty = points(i, 1);
-
- if (std::isfinite(ty)) {
- // get test bit for above/below X axis
- yflag0[i] = (vty0 >= ty);
-
- subpath_flag[i] = 0;
- }
- }
-
- do {
- code = path.vertex(&x, &y);
-
- // The following cases denote the beginning on a new subpath
- if (code == agg::path_cmd_stop ||
- (code & agg::path_cmd_end_poly) == agg::path_cmd_end_poly) {
- x = sx;
- y = sy;
- } else if (code == agg::path_cmd_move_to) {
- break;
- }
-
- for (i = 0; i < n; ++i) {
- tx = points(i, 0);
- ty = points(i, 1);
-
- if (!(std::isfinite(tx) && std::isfinite(ty))) {
- continue;
- }
-
- 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[i] != 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) {
- subpath_flag[i] ^= 1;
- }
- }
-
- // Move to the next pair of vertices, retaining info as
- // possible.
- yflag0[i] = yflag1;
- }
-
- vtx0 = vtx1;
- vty0 = vty1;
-
- vtx1 = x;
- vty1 = y;
- } while (code != agg::path_cmd_stop &&
- (code & agg::path_cmd_end_poly) != agg::path_cmd_end_poly);
-
- all_done = true;
- for (i = 0; i < n; ++i) {
- tx = points(i, 0);
- ty = points(i, 1);
-
- if (!(std::isfinite(tx) && std::isfinite(ty))) {
- continue;
- }
-
- yflag1 = (vty1 >= ty);
- if (yflag0[i] != yflag1) {
- if (((vty1 - ty) * (vtx0 - vtx1) >= (vtx1 - tx) * (vty0 - vty1)) == yflag1) {
- subpath_flag[i] = subpath_flag[i] ^ true;
- }
- }
- inside_flag[i] |= subpath_flag[i];
- if (inside_flag[i] == 0) {
- all_done = false;
- }
- }
-
- if (all_done) {
- break;
- }
- } while (code != agg::path_cmd_stop);
-}
-
-template <class PathIterator, class PointArray, class ResultArray>
-inline void points_in_path(PointArray &points,
- const double r,
- PathIterator &path,
- agg::trans_affine &trans,
- ResultArray &result)
-{
- typedef agg::conv_transform<PathIterator> transformed_path_t;
- typedef PathNanRemover<transformed_path_t> no_nans_t;
- typedef agg::conv_curve<no_nans_t> curve_t;
- typedef agg::conv_contour<curve_t> contour_t;
-
- size_t i;
- for (i = 0; i < points.size(); ++i) {
- result[i] = false;
- }
-
- if (path.total_vertices() < 3) {
- return;
- }
-
- transformed_path_t trans_path(path, trans);
- no_nans_t no_nans_path(trans_path, true, path.has_curves());
- curve_t curved_path(no_nans_path);
- if (r != 0.0) {
- contour_t contoured_path(curved_path);
- contoured_path.width(r);
- point_in_path_impl(points, contoured_path, result);
- } else {
- point_in_path_impl(points, curved_path, result);
- }
-}
-
-template <class PathIterator>
-inline bool point_in_path(
- double x, double y, const double r, PathIterator &path, agg::trans_affine &trans)
-{
- npy_intp shape[] = {1, 2};
- numpy::array_view<double, 2> points(shape);
- points(0, 0) = x;
- points(0, 1) = y;
-
- int result[1];
- result[0] = 0;
-
- points_in_path(points, r, path, trans, result);
-
- return (bool)result[0];
-}
-
-template <class PathIterator, class PointArray, class ResultArray>
-void points_on_path(PointArray &points,
- const double r,
- PathIterator &path,
- agg::trans_affine &trans,
- ResultArray result)
-{
- typedef agg::conv_transform<PathIterator> transformed_path_t;
- typedef PathNanRemover<transformed_path_t> no_nans_t;
- typedef agg::conv_curve<no_nans_t> curve_t;
- typedef agg::conv_stroke<curve_t> stroke_t;
-
- size_t i;
- for (i = 0; i < points.size(); ++i) {
- result[i] = false;
- }
-
- transformed_path_t trans_path(path, trans);
- no_nans_t nan_removed_path(trans_path, true, path.has_curves());
- curve_t curved_path(nan_removed_path);
- stroke_t stroked_path(curved_path);
- stroked_path.width(r * 2.0);
- point_in_path_impl(points, stroked_path, result);
-}
-
-template <class PathIterator>
-inline bool point_on_path(
- double x, double y, const double r, PathIterator &path, agg::trans_affine &trans)
-{
- npy_intp shape[] = {1, 2};
- numpy::array_view<double, 2> points(shape);
- points(0, 0) = x;
- points(0, 1) = y;
-
- int result[1];
- result[0] = 0;
-
- points_on_path(points, r, path, trans, result);
-
- return (bool)result[0];
-}
-
-struct extent_limits
-{
- double x0;
- double y0;
- double x1;
- double y1;
- double xm;
- double ym;
-};
-
-void reset_limits(extent_limits &e)
-{
- e.x0 = std::numeric_limits<double>::infinity();
- e.y0 = std::numeric_limits<double>::infinity();
- e.x1 = -std::numeric_limits<double>::infinity();
- e.y1 = -std::numeric_limits<double>::infinity();
- /* xm and ym are the minimum positive values in the data, used
- by log scaling */
- e.xm = std::numeric_limits<double>::infinity();
- e.ym = std::numeric_limits<double>::infinity();
-}
-
-inline void update_limits(double x, double y, extent_limits &e)
-{
- if (x < e.x0)
- e.x0 = x;
- if (y < e.y0)
- e.y0 = y;
- if (x > e.x1)
- e.x1 = x;
- if (y > e.y1)
- e.y1 = y;
- /* xm and ym are the minimum positive values in the data, used
- by log scaling */
- if (x > 0.0 && x < e.xm)
- e.xm = x;
- if (y > 0.0 && y < e.ym)
- e.ym = y;
-}
-
-template <class PathIterator>
-void update_path_extents(PathIterator &path, agg::trans_affine &trans, extent_limits &extents)
-{
- typedef agg::conv_transform<PathIterator> transformed_path_t;
- typedef PathNanRemover<transformed_path_t> nan_removed_t;
- double x, y;
- unsigned code;
-
- transformed_path_t tpath(path, trans);
- nan_removed_t nan_removed(tpath, true, path.has_curves());
-
- nan_removed.rewind(0);
-
- while ((code = nan_removed.vertex(&x, &y)) != agg::path_cmd_stop) {
- if ((code & agg::path_cmd_end_poly) == agg::path_cmd_end_poly) {
- continue;
- }
- update_limits(x, y, extents);
- }
-}
-
-template <class PathGenerator, class TransformArray, class OffsetArray>
-void get_path_collection_extents(agg::trans_affine &master_transform,
- PathGenerator &paths,
- TransformArray &transforms,
- OffsetArray &offsets,
- agg::trans_affine &offset_trans,
- extent_limits &extent)
-{
- if (offsets.size() != 0 && offsets.dim(1) != 2) {
- throw std::runtime_error("Offsets array must be Nx2");
- }
-
- size_t Npaths = paths.size();
- size_t Noffsets = offsets.size();
- size_t N = std::max(Npaths, Noffsets);
- size_t Ntransforms = std::min(transforms.size(), N);
- size_t i;
-
- agg::trans_affine trans;
-
- reset_limits(extent);
-
- for (i = 0; i < N; ++i) {
- typename PathGenerator::path_iterator path(paths(i % Npaths));
- if (Ntransforms) {
- size_t ti = i % Ntransforms;
- trans = agg::trans_affine(transforms(ti, 0, 0),
- transforms(ti, 1, 0),
- transforms(ti, 0, 1),
- transforms(ti, 1, 1),
- transforms(ti, 0, 2),
- transforms(ti, 1, 2));
- } else {
- trans = master_transform;
- }
-
- if (Noffsets) {
- double xo = offsets(i % Noffsets, 0);
- double yo = offsets(i % Noffsets, 1);
- offset_trans.transform(&xo, &yo);
- trans *= agg::trans_affine_translation(xo, yo);
- }
-
- update_path_extents(path, trans, extent);
- }
-}
-
-template <class PathGenerator, class TransformArray, class OffsetArray>
-void point_in_path_collection(double x,
- double y,
- double radius,
- agg::trans_affine &master_transform,
- PathGenerator &paths,
- TransformArray &transforms,
- OffsetArray &offsets,
- agg::trans_affine &offset_trans,
- bool filled,
- e_offset_position offset_position,
- std::vector<int> &result)
-{
- size_t Npaths = paths.size();
-
- if (Npaths == 0) {
- return;
- }
-
- size_t Noffsets = offsets.size();
- size_t N = std::max(Npaths, Noffsets);
- size_t Ntransforms = std::min(transforms.size(), N);
- size_t i;
-
- agg::trans_affine trans;
-
- for (i = 0; i < N; ++i) {
- typename PathGenerator::path_iterator path = paths(i % Npaths);
-
- if (Ntransforms) {
- size_t ti = i % Ntransforms;
- trans = agg::trans_affine(transforms(ti, 0, 0),
- transforms(ti, 1, 0),
- transforms(ti, 0, 1),
- transforms(ti, 1, 1),
- transforms(ti, 0, 2),
- transforms(ti, 1, 2));
- trans *= master_transform;
- } else {
- trans = master_transform;
- }
-
- if (Noffsets) {
- double xo = offsets(i % Noffsets, 0);
- double yo = offsets(i % Noffsets, 1);
- offset_trans.transform(&xo, &yo);
- if (offset_position == OFFSET_POSITION_DATA) {
- trans = agg::trans_affine_translation(xo, yo) * trans;
- } else {
- trans *= agg::trans_affine_translation(xo, yo);
- }
- }
-
- if (filled) {
- if (point_in_path(x, y, radius, path, trans)) {
- result.push_back(i);
- }
- } else {
- if (point_on_path(x, y, radius, path, trans)) {
- result.push_back(i);
- }
- }
- }
-}
-
-template <class PathIterator1, class PathIterator2>
-bool path_in_path(PathIterator1 &a,
- agg::trans_affine &atrans,
- PathIterator2 &b,
- agg::trans_affine &btrans)
-{
- typedef agg::conv_transform<PathIterator2> transformed_path_t;
- typedef PathNanRemover<transformed_path_t> no_nans_t;
- typedef agg::conv_curve<no_nans_t> curve_t;
-
- if (a.total_vertices() < 3) {
- return false;
- }
-
- transformed_path_t b_path_trans(b, btrans);
- no_nans_t b_no_nans(b_path_trans, true, b.has_curves());
- curve_t b_curved(b_no_nans);
-
- double x, y;
- b_curved.rewind(0);
- while (b_curved.vertex(&x, &y) != agg::path_cmd_stop) {
- if (!point_in_path(x, y, 0.0, a, atrans)) {
- return false;
- }
- }
-
- return true;
-}
-
-/** The clip_path_to_rect code here is a clean-room implementation of
- the Sutherland-Hodgman clipping algorithm described here:
-
- http://en.wikipedia.org/wiki/Sutherland-Hodgman_clipping_algorithm
-*/
-
-namespace clip_to_rect_filters
-{
-/* There are four different passes needed to create/remove
- vertices (one for each side of the rectangle). The differences
- between those passes are encapsulated in these functor classes.
-*/
-struct bisectx
-{
- double m_x;
-
- bisectx(double x) : m_x(x)
- {
- }
-
- inline void bisect(double sx, double sy, double px, double py, double *bx, double *by) const
- {
- *bx = m_x;
- double dx = px - sx;
- double dy = py - sy;
- *by = sy + dy * ((m_x - sx) / dx);
- }
-};
-
-struct xlt : public bisectx
-{
- xlt(double x) : bisectx(x)
- {
- }
-
- inline bool is_inside(double x, double y) const
- {
- return x <= m_x;
- }
-};
-
-struct xgt : public bisectx
-{
- xgt(double x) : bisectx(x)
- {
- }
-
- inline bool is_inside(double x, double y) const
- {
- return x >= m_x;
- }
-};
-
-struct bisecty
-{
- double m_y;
-
- bisecty(double y) : m_y(y)
- {
- }
-
- inline void bisect(double sx, double sy, double px, double py, double *bx, double *by) const
- {
- *by = m_y;
- double dx = px - sx;
- double dy = py - sy;
- *bx = sx + dx * ((m_y - sy) / dy);
- }
-};
-
-struct ylt : public bisecty
-{
- ylt(double y) : bisecty(y)
- {
- }
-
- inline bool is_inside(double x, double y) const
- {
- return y <= m_y;
- }
-};
-
-struct ygt : public bisecty
-{
- ygt(double y) : bisecty(y)
- {
- }
-
- inline bool is_inside(double x, double y) const
- {
- return y >= m_y;
- }
-};
-}
-
-template <class Filter>
-inline void clip_to_rect_one_step(const Polygon &polygon, Polygon &result, const Filter &filter)
-{
- double sx, sy, px, py, bx, by;
- bool sinside, pinside;
- result.clear();
-
- if (polygon.size() == 0) {
- return;
- }
-
- sx = polygon.back().x;
- sy = polygon.back().y;
- for (Polygon::const_iterator i = polygon.begin(); i != polygon.end(); ++i) {
- px = i->x;
- py = i->y;
-
- sinside = filter.is_inside(sx, sy);
- pinside = filter.is_inside(px, py);
-
- if (sinside ^ pinside) {
- filter.bisect(sx, sy, px, py, &bx, &by);
- result.push_back(XY(bx, by));
- }
-
- if (pinside) {
- result.push_back(XY(px, py));
- }
-
- sx = px;
- sy = py;
- }
-}
-
-template <class PathIterator>
-void
-clip_path_to_rect(PathIterator &path, agg::rect_d &rect, bool inside, std::vector<Polygon> &results)
-{
- double xmin, ymin, xmax, ymax;
- if (rect.x1 < rect.x2) {
- xmin = rect.x1;
- xmax = rect.x2;
- } else {
- xmin = rect.x2;
- xmax = rect.x1;
- }
-
- if (rect.y1 < rect.y2) {
- ymin = rect.y1;
- ymax = rect.y2;
- } else {
- ymin = rect.y2;
- ymax = rect.y1;
- }
-
- if (!inside) {
- std::swap(xmin, xmax);
- std::swap(ymin, ymax);
- }
-
- typedef agg::conv_curve<PathIterator> curve_t;
- curve_t curve(path);
-
- Polygon polygon1, polygon2;
- double x = 0, y = 0;
- unsigned code = 0;
- curve.rewind(0);
-
- do {
- // Grab the next subpath and store it in polygon1
- polygon1.clear();
- do {
- if (code == agg::path_cmd_move_to) {
- polygon1.push_back(XY(x, y));
- }
-
- code = curve.vertex(&x, &y);
-
- if (code == agg::path_cmd_stop) {
- break;
- }
-
- if (code != agg::path_cmd_move_to) {
- polygon1.push_back(XY(x, y));
- }
- } while ((code & agg::path_cmd_end_poly) != agg::path_cmd_end_poly);
-
- // The result of each step is fed into the next (note the
- // swapping of polygon1 and polygon2 at each step).
- clip_to_rect_one_step(polygon1, polygon2, clip_to_rect_filters::xlt(xmax));
- clip_to_rect_one_step(polygon2, polygon1, clip_to_rect_filters::xgt(xmin));
- clip_to_rect_one_step(polygon1, polygon2, clip_to_rect_filters::ylt(ymax));
- clip_to_rect_one_step(polygon2, polygon1, clip_to_rect_filters::ygt(ymin));
-
- // Empty polygons aren't very useful, so skip them
- if (polygon1.size()) {
- _finalize_polygon(results, 1);
- results.push_back(polygon1);
- }
- } while (code != agg::path_cmd_stop);
-
- _finalize_polygon(results, 1);
-}
-
-template <class VerticesArray, class ResultArray>
-void affine_transform_2d(VerticesArray &vertices, agg::trans_affine &trans, ResultArray &result)
-{
- if (vertices.size() != 0 && vertices.dim(1) != 2) {
- throw std::runtime_error("Invalid vertices array.");
- }
-
- size_t n = vertices.size();
- double x;
- double y;
- double t0;
- double t1;
- double t;
-
- for (size_t i = 0; i < n; ++i) {
- x = vertices(i, 0);
- y = vertices(i, 1);
-
- t0 = trans.sx * x;
- t1 = trans.shx * y;
- t = t0 + t1 + trans.tx;
- result(i, 0) = t;
-
- t0 = trans.shy * x;
- t1 = trans.sy * y;
- t = t0 + t1 + trans.ty;
- result(i, 1) = t;
- }
-}
-
-template <class VerticesArray, class ResultArray>
-void affine_transform_1d(VerticesArray &vertices, agg::trans_affine &trans, ResultArray &result)
-{
- if (vertices.dim(0) != 2) {
- throw std::runtime_error("Invalid vertices array.");
- }
-
- double x;
- double y;
- double t0;
- double t1;
- double t;
-
- x = vertices(0);
- y = vertices(1);
-
- t0 = trans.sx * x;
- t1 = trans.shx * y;
- t = t0 + t1 + trans.tx;
- result(0) = t;
-
- t0 = trans.shy * x;
- t1 = trans.sy * y;
- t = t0 + t1 + trans.ty;
- result(1) = t;
-}
-
-template <class BBoxArray>
-int count_bboxes_overlapping_bbox(agg::rect_d &a, BBoxArray &bboxes)
-{
- agg::rect_d b;
- int count = 0;
-
- if (a.x2 < a.x1) {
- std::swap(a.x1, a.x2);
- }
- if (a.y2 < a.y1) {
- std::swap(a.y1, a.y2);
- }
-
- size_t num_bboxes = bboxes.size();
- for (size_t i = 0; i < num_bboxes; ++i) {
- b = agg::rect_d(bboxes(i, 0, 0), bboxes(i, 0, 1), bboxes(i, 1, 0), bboxes(i, 1, 1));
-
- if (b.x2 < b.x1) {
- std::swap(b.x1, b.x2);
- }
- if (b.y2 < b.y1) {
- std::swap(b.y1, b.y2);
- }
- if (!((b.x2 <= a.x1) || (b.y2 <= a.y1) || (b.x1 >= a.x2) || (b.y1 >= a.y2))) {
- ++count;
- }
- }
-
- return count;
-}
-
-inline bool segments_intersect(const double &x1,
- const double &y1,
- const double &x2,
- const double &y2,
- const double &x3,
- const double &y3,
- const double &x4,
- const double &y4)
-{
- double den = ((y4 - y3) * (x2 - x1)) - ((x4 - x3) * (y2 - y1));
- if (den == 0.0) {
- return false;
- }
-
- double n1 = ((x4 - x3) * (y1 - y3)) - ((y4 - y3) * (x1 - x3));
- double n2 = ((x2 - x1) * (y1 - y3)) - ((y2 - y1) * (x1 - x3));
-
- double u1 = n1 / den;
- double u2 = n2 / den;
-
- return (u1 >= 0.0 && u1 <= 1.0 && u2 >= 0.0 && u2 <= 1.0);
-}
-
-template <class PathIterator1, class PathIterator2>
-bool path_intersects_path(PathIterator1 &p1, PathIterator2 &p2)
-{
- typedef PathNanRemover<py::PathIterator> no_nans_t;
- typedef agg::conv_curve<no_nans_t> curve_t;
-
- if (p1.total_vertices() < 2 || p2.total_vertices() < 2) {
- return false;
- }
-
- no_nans_t n1(p1, true, p1.has_curves());
- no_nans_t n2(p2, true, p2.has_curves());
-
- curve_t c1(n1);
- curve_t c2(n2);
-
- double x11, y11, x12, y12;
- double x21, y21, x22, y22;
-
- c1.vertex(&x11, &y11);
- while (c1.vertex(&x12, &y12) != agg::path_cmd_stop) {
- c2.rewind(0);
- c2.vertex(&x21, &y21);
- while (c2.vertex(&x22, &y22) != agg::path_cmd_stop) {
- if (segments_intersect(x11, y11, x12, y12, x21, y21, x22, y22)) {
- return true;
- }
- x21 = x22;
- y21 = y22;
- }
- x11 = x12;
- y11 = y12;
- }
-
- return false;
-}
-
-// returns whether the segment from (x1,y1) to (x2,y2)
-// intersects the rectangle centered at (cx,cy) with size (w,h)
-// see doc/segment_intersects_rectangle.svg for a more detailed explanation
-inline bool segment_intersects_rectangle(double x1, double y1,
- double x2, double y2,
- double cx, double cy,
- double w, double h)
-{
- return fabs(x1 + x2 - 2.0 * cx) < fabs(x1 - x2) + w &&
- fabs(y1 + y2 - 2.0 * cy) < fabs(y1 - y2) + h &&
- 2.0 * fabs((x1 - cx) * (y1 - y2) - (y1 - cy) * (x1 - x2)) <
- w * fabs(y1 - y2) + h * fabs(x1 - x2);
-}
-
-template <class PathIterator>
-bool path_intersects_rectangle(PathIterator &path,
- double rect_x1, double rect_y1,
- double rect_x2, double rect_y2,
- bool filled)
-{
- typedef PathNanRemover<py::PathIterator> no_nans_t;
- typedef agg::conv_curve<no_nans_t> curve_t;
-
- if (path.total_vertices() == 0) {
- return false;
- }
-
- no_nans_t no_nans(path, true, path.has_curves());
- curve_t curve(no_nans);
-
- double cx = (rect_x1 + rect_x2) * 0.5, cy = (rect_y1 + rect_y2) * 0.5;
- double w = fabs(rect_x1 - rect_x2), h = fabs(rect_y1 - rect_y2);
-
- double x1, y1, x2, y2;
-
- curve.vertex(&x1, &y1);
- if (2.0 * fabs(x1 - cx) <= w && 2.0 * fabs(y1 - cy) <= h) {
- return true;
- }
-
- while (curve.vertex(&x2, &y2) != agg::path_cmd_stop) {
- if (segment_intersects_rectangle(x1, y1, x2, y2, cx, cy, w, h)) {
- return true;
- }
- x1 = x2;
- y1 = y2;
- }
-
- if (filled) {
- agg::trans_affine trans;
- if (point_in_path(cx, cy, 0.0, path, trans)) {
- return true;
- }
- }
-
- return false;
-}
-
-template <class PathIterator>
-void convert_path_to_polygons(PathIterator &path,
- agg::trans_affine &trans,
- double width,
- double height,
- int closed_only,
- std::vector<Polygon> &result)
-{
- 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 PathSimplifier<clipped_t> simplify_t;
- typedef agg::conv_curve<simplify_t> curve_t;
-
- bool do_clip = width != 0.0 && height != 0.0;
- bool simplify = path.should_simplify();
-
- transformed_path_t tpath(path, trans);
- nan_removal_t nan_removed(tpath, true, path.has_curves());
- clipped_t clipped(nan_removed, do_clip && !path.has_curves(), width, height);
- simplify_t simplified(clipped, simplify, path.simplify_threshold());
- curve_t curve(simplified);
-
- result.push_back(Polygon());
- Polygon *polygon = &result.back();
- double x, y;
- unsigned code;
-
- while ((code = curve.vertex(&x, &y)) != agg::path_cmd_stop) {
- if ((code & agg::path_cmd_end_poly) == agg::path_cmd_end_poly) {
- _finalize_polygon(result, 1);
- result.push_back(Polygon());
- polygon = &result.back();
- } else {
- if (code == agg::path_cmd_move_to) {
- _finalize_polygon(result, closed_only);
- result.push_back(Polygon());
- polygon = &result.back();
- }
- polygon->push_back(XY(x, y));
- }
- }
-
- _finalize_polygon(result, closed_only);
-}
-
-template <class VertexSource>
-void
-__cleanup_path(VertexSource &source, std::vector<double> &vertices, std::vector<npy_uint8> &codes)
-{
- unsigned code;
- double x, y;
- do {
- code = source.vertex(&x, &y);
- vertices.push_back(x);
- vertices.push_back(y);
- codes.push_back((npy_uint8)code);
- } while (code != agg::path_cmd_stop);
-}
-
-template <class PathIterator>
-void cleanup_path(PathIterator &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,
- bool return_curves,
- SketchParams sketch_params,
- std::vector<double> &vertices,
- std::vector<unsigned char> &codes)
-{
- 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 agg::conv_curve<simplify_t> curve_t;
- typedef Sketch<curve_t> sketch_t;
-
- transformed_path_t tpath(path, trans);
- nan_removal_t nan_removed(tpath, remove_nans, path.has_curves());
- clipped_t clipped(nan_removed, do_clip && !path.has_curves(), rect);
- snapped_t snapped(clipped, snap_mode, path.total_vertices(), stroke_width);
- simplify_t simplified(snapped, do_simplify, path.simplify_threshold());
-
- vertices.reserve(path.total_vertices() * 2);
- codes.reserve(path.total_vertices());
-
- if (return_curves && sketch_params.scale == 0.0) {
- __cleanup_path(simplified, vertices, codes);
- } else {
- curve_t curve(simplified);
- sketch_t sketch(curve, sketch_params.scale, sketch_params.length, sketch_params.randomness);
- __cleanup_path(sketch, vertices, codes);
- }
-}
-
-void quad2cubic(double x0, double y0,
- double x1, double y1,
- double x2, double y2,
- double *outx, double *outy)
-{
-
- outx[0] = x0 + 2./3. * (x1 - x0);
- outy[0] = y0 + 2./3. * (y1 - y0);
- outx[1] = outx[0] + 1./3. * (x2 - x0);
- outy[1] = outy[0] + 1./3. * (y2 - y0);
- outx[2] = x2;
- outy[2] = y2;
-}
-
-char *__append_to_string(char *p, char **buffer, size_t *buffersize,
- const char *content)
-{
- for (const char *i = content; *i; ++i) {
- if (p < *buffer) {
- /* This is just an internal error */
- return NULL;
- }
- if ((size_t)(p - *buffer) >= *buffersize) {
- ptrdiff_t diff = p - *buffer;
- *buffersize *= 2;
- *buffer = (char *)realloc(*buffer, *buffersize);
- if (*buffer == NULL) {
- return NULL;
- }
- p = *buffer + diff;
- }
-
- *p++ = *i;
- }
-
- return p;
-}
-
-
-char *__add_number(double val, const char *format, int precision,
- char **buffer, char *p, size_t *buffersize)
-{
- char *result;
-
-#if PY_VERSION_HEX >= 0x02070000
- char *str;
- str = PyOS_double_to_string(val, format[0], precision, 0, NULL);
-#else
- char str[64];
- PyOS_ascii_formatd(str, 64, format, val);
-#endif
-
- // Delete trailing zeros and decimal point
- char *q = str;
- for (; *q != 0; ++q) {
- // Find the end of the string
- }
-
- --q;
- for (; q >= str && *q == '0'; --q) {
- // Rewind through all the zeros
- }
-
- // If the end is a decimal qoint, delete that too
- if (q >= str && *q == '.') {
- --q;
- }
-
- // Truncate the string
- ++q;
- *q = 0;
-
-#if PY_VERSION_HEX >= 0x02070000
- if ((result = __append_to_string(p, buffer, buffersize, str)) == NULL) {
- PyMem_Free(str);
- return NULL;
- }
- PyMem_Free(str);
-#else
- if ((result = __append_to_string(p, buffer, buffersize, str)) == NULL) {
- return NULL;
- }
-#endif
-
- return result;
-}
-
-
-template <class PathIterator>
-int __convert_to_string(PathIterator &path,
- int precision,
- char **codes,
- bool postfix,
- char **buffer,
- size_t *buffersize)
-{
-#if PY_VERSION_HEX >= 0x02070000
- const char *format = "f";
-#else
- char format[64];
- snprintf(format, 64, "%s.%df", "%", precision);
-#endif
-
- char *p = *buffer;
- double x[3];
- double y[3];
- double last_x = 0.0;
- double last_y = 0.0;
-
- const int sizes[] = { 1, 1, 2, 3 };
- int size = 0;
- unsigned code;
-
- while ((code = path.vertex(&x[0], &y[0])) != agg::path_cmd_stop) {
- if (code == 0x4f) {
- if ((p = __append_to_string(p, buffer, buffersize, codes[4])) == NULL) return 1;
- } else if (code < 5) {
- size = sizes[code - 1];
-
- for (int i = 1; i < size; ++i) {
- unsigned subcode = path.vertex(&x[i], &y[i]);
- if (subcode != code) {
- return 2;
- }
- }
-
- /* For formats that don't support quad curves, convert to
- cubic curves */
- if (code == CURVE3 && codes[code - 1][0] == '\0') {
- quad2cubic(last_x, last_y, x[0], y[0], x[1], y[1], x, y);
- code++;
- size = 3;
- }
-
- if (!postfix) {
- if ((p = __append_to_string(p, buffer, buffersize, codes[code - 1])) == NULL) return 1;
- if ((p = __append_to_string(p, buffer, buffersize, " ")) == NULL) return 1;
- }
-
- for (int i = 0; i < size; ++i) {
- if ((p = __add_number(x[i], format, precision, buffer, p, buffersize)) == NULL) return 1;
- if ((p = __append_to_string(p, buffer, buffersize, " ")) == NULL) return 1;
- if ((p = __add_number(y[i], format, precision, buffer, p, buffersize)) == NULL) return 1;
- if ((p = __append_to_string(p, buffer, buffersize, " ")) == NULL) return 1;
- }
-
- if (postfix) {
- if ((p = __append_to_string(p, buffer, buffersize, codes[code - 1])) == NULL) return 1;
- }
-
- last_x = x[size - 1];
- last_y = y[size - 1];
- } else {
- // Unknown code value
- return 2;
- }
-
- if ((p = __append_to_string(p, buffer, buffersize, "\n")) == NULL) return 1;
- }
-
- *buffersize = p - *buffer;
-
- return 0;
-}
-
-template <class PathIterator>
-int convert_to_string(PathIterator &path,
- agg::trans_affine &trans,
- agg::rect_d &clip_rect,
- bool simplify,
- SketchParams sketch_params,
- int precision,
- char **codes,
- bool postfix,
- char **buffer,
- size_t *buffersize)
-{
- 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 PathSimplifier<clipped_t> simplify_t;
- typedef agg::conv_curve<simplify_t> curve_t;
- typedef Sketch<curve_t> sketch_t;
-
- bool do_clip = (clip_rect.x1 < clip_rect.x2 && clip_rect.y1 < clip_rect.y2);
-
- transformed_path_t tpath(path, trans);
- nan_removal_t nan_removed(tpath, true, path.has_curves());
- clipped_t clipped(nan_removed, do_clip && !path.has_curves(), clip_rect);
- simplify_t simplified(clipped, simplify, path.simplify_threshold());
-
- *buffersize = path.total_vertices() * (precision + 5) * 4;
- if (*buffersize == 0) {
- return 0;
- }
-
- if (sketch_params.scale != 0.0) {
- *buffersize *= 10.0;
- }
-
- *buffer = (char *)malloc(*buffersize);
- if (*buffer == NULL) {
- return 1;
- }
-
- if (sketch_params.scale == 0.0) {
- return __convert_to_string(simplified, precision, codes, postfix, buffer, buffersize);
- } else {
- curve_t curve(simplified);
- sketch_t sketch(curve, sketch_params.scale, sketch_params.length, sketch_params.randomness);
- return __convert_to_string(sketch, precision, codes, postfix, buffer, buffersize);
- }
-
-}
-
-template<class T>
-struct _is_sorted
-{
- bool operator()(PyArrayObject *array)
- {
- npy_intp size;
- npy_intp i;
- T last_value;
- T current_value;
-
- size = PyArray_DIM(array, 0);
-
- // std::isnan is only in C++11, which we don't yet require,
- // so we use the "self == self" trick
- for (i = 0; i < size; ++i) {
- last_value = *((T *)PyArray_GETPTR1(array, i));
- if (last_value == last_value) {
- break;
- }
- }
-
- if (i == size) {
- // The whole array is non-finite
- return false;
- }
-
- for (; i < size; ++i) {
- current_value = *((T *)PyArray_GETPTR1(array, i));
- if (current_value == current_value) {
- if (current_value < last_value) {
- return false;
- }
- last_value = current_value;
- }
- }
-
- return true;
- }
-};
-
-
-template<class T>
-struct _is_sorted_int
-{
- bool operator()(PyArrayObject *array)
- {
- npy_intp size;
- npy_intp i;
- T last_value;
- T current_value;
-
- size = PyArray_DIM(array, 0);
-
- last_value = *((T *)PyArray_GETPTR1(array, 0));
-
- for (i = 1; i < size; ++i) {
- current_value = *((T *)PyArray_GETPTR1(array, i));
- if (current_value < last_value) {
- return false;
- }
- last_value = current_value;
- }
-
- return true;
- }
-};
-
-
-#endif
diff --git a/contrib/python/matplotlib/py2/src/_path_wrapper.cpp b/contrib/python/matplotlib/py2/src/_path_wrapper.cpp
deleted file mode 100644
index 08a595e7c4..0000000000
--- a/contrib/python/matplotlib/py2/src/_path_wrapper.cpp
+++ /dev/null
@@ -1,900 +0,0 @@
-#include "numpy_cpp.h"
-
-#include "_path.h"
-
-#include "py_converters.h"
-#include "py_adaptors.h"
-
-PyObject *convert_polygon_vector(std::vector<Polygon> &polygons)
-{
- PyObject *pyresult = PyList_New(polygons.size());
-
- for (size_t i = 0; i < polygons.size(); ++i) {
- Polygon poly = polygons[i];
- npy_intp dims[2];
- dims[1] = 2;
-
- dims[0] = (npy_intp)poly.size();
-
- numpy::array_view<double, 2> subresult(dims);
- memcpy(subresult.data(), &poly[0], sizeof(double) * poly.size() * 2);
-
- if (PyList_SetItem(pyresult, i, subresult.pyobj())) {
- Py_DECREF(pyresult);
- return NULL;
- }
- }
-
- return pyresult;
-}
-
-const char *Py_point_in_path__doc__ = "point_in_path(x, y, radius, path, trans)";
-
-static PyObject *Py_point_in_path(PyObject *self, PyObject *args, PyObject *kwds)
-{
- double x, y, r;
- py::PathIterator path;
- agg::trans_affine trans;
- bool result;
-
- if (!PyArg_ParseTuple(args,
- "dddO&O&:point_in_path",
- &x,
- &y,
- &r,
- &convert_path,
- &path,
- &convert_trans_affine,
- &trans)) {
- return NULL;
- }
-
- CALL_CPP("point_in_path", (result = point_in_path(x, y, r, path, trans)));
-
- if (result) {
- Py_RETURN_TRUE;
- } else {
- Py_RETURN_FALSE;
- }
-}
-
-const char *Py_points_in_path__doc__ = "points_in_path(points, radius, path, trans)";
-
-static PyObject *Py_points_in_path(PyObject *self, PyObject *args, PyObject *kwds)
-{
- numpy::array_view<const double, 2> points;
- double r;
- py::PathIterator path;
- agg::trans_affine trans;
-
- if (!PyArg_ParseTuple(args,
- "O&dO&O&:points_in_path",
- &convert_points,
- &points,
- &r,
- &convert_path,
- &path,
- &convert_trans_affine,
- &trans)) {
- return NULL;
- }
-
- npy_intp dims[] = { (npy_intp)points.size() };
- numpy::array_view<uint8_t, 1> results(dims);
-
- CALL_CPP("points_in_path", (points_in_path(points, r, path, trans, results)));
-
- return results.pyobj();
-}
-
-const char *Py_point_on_path__doc__ = "point_on_path(x, y, radius, path, trans)";
-
-static PyObject *Py_point_on_path(PyObject *self, PyObject *args, PyObject *kwds)
-{
- double x, y, r;
- py::PathIterator path;
- agg::trans_affine trans;
- bool result;
-
- if (!PyArg_ParseTuple(args,
- "dddO&O&:point_on_path",
- &x,
- &y,
- &r,
- &convert_path,
- &path,
- &convert_trans_affine,
- &trans)) {
- return NULL;
- }
-
- CALL_CPP("point_on_path", (result = point_on_path(x, y, r, path, trans)));
-
- if (result) {
- Py_RETURN_TRUE;
- } else {
- Py_RETURN_FALSE;
- }
-}
-
-const char *Py_points_on_path__doc__ = "points_on_path(points, radius, path, trans)";
-
-static PyObject *Py_points_on_path(PyObject *self, PyObject *args, PyObject *kwds)
-{
- numpy::array_view<const double, 2> points;
- double r;
- py::PathIterator path;
- agg::trans_affine trans;
-
- if (!PyArg_ParseTuple(args,
- "O&dO&O&:points_on_path",
- &convert_points,
- &points,
- &r,
- &convert_path,
- &path,
- &convert_trans_affine,
- &trans)) {
- return NULL;
- }
-
- npy_intp dims[] = { (npy_intp)points.size() };
- numpy::array_view<uint8_t, 1> results(dims);
-
- CALL_CPP("points_on_path", (points_on_path(points, r, path, trans, results)));
-
- return results.pyobj();
-}
-
-const char *Py_get_path_extents__doc__ = "get_path_extents(path, trans)";
-
-static PyObject *Py_get_path_extents(PyObject *self, PyObject *args, PyObject *kwds)
-{
- py::PathIterator path;
- agg::trans_affine trans;
-
- if (!PyArg_ParseTuple(
- args, "O&O&:get_path_extents", &convert_path, &path, &convert_trans_affine, &trans)) {
- return NULL;
- }
-
- extent_limits e;
-
- CALL_CPP("get_path_extents", (reset_limits(e)));
- CALL_CPP("get_path_extents", (update_path_extents(path, trans, e)));
-
- npy_intp dims[] = { 2, 2 };
- numpy::array_view<double, 2> extents(dims);
- extents(0, 0) = e.x0;
- extents(0, 1) = e.y0;
- extents(1, 0) = e.x1;
- extents(1, 1) = e.y1;
-
- return extents.pyobj();
-}
-
-const char *Py_update_path_extents__doc__ =
- "update_path_extents(path, trans, rect, minpos, ignore)";
-
-static PyObject *Py_update_path_extents(PyObject *self, PyObject *args, PyObject *kwds)
-{
- py::PathIterator path;
- agg::trans_affine trans;
- agg::rect_d rect;
- numpy::array_view<double, 1> minpos;
- int ignore;
- int changed;
-
- if (!PyArg_ParseTuple(args,
- "O&O&O&O&i:update_path_extents",
- &convert_path,
- &path,
- &convert_trans_affine,
- &trans,
- &convert_rect,
- &rect,
- &minpos.converter,
- &minpos,
- &ignore)) {
- return NULL;
- }
-
- if (minpos.dim(0) != 2) {
- PyErr_Format(PyExc_ValueError,
- "minpos must be of length 2, got %" NPY_INTP_FMT,
- minpos.dim(0));
- return NULL;
- }
-
- extent_limits e;
-
- if (ignore) {
- CALL_CPP("update_path_extents", reset_limits(e));
- } else {
- if (rect.x1 > rect.x2) {
- e.x0 = std::numeric_limits<double>::infinity();
- e.x1 = -std::numeric_limits<double>::infinity();
- } else {
- e.x0 = rect.x1;
- e.x1 = rect.x2;
- }
- if (rect.y1 > rect.y2) {
- e.y0 = std::numeric_limits<double>::infinity();
- e.y1 = -std::numeric_limits<double>::infinity();
- } else {
- e.y0 = rect.y1;
- e.y1 = rect.y2;
- }
- e.xm = minpos(0);
- e.ym = minpos(1);
- }
-
- CALL_CPP("update_path_extents", (update_path_extents(path, trans, e)));
-
- changed = (e.x0 != rect.x1 || e.y0 != rect.y1 || e.x1 != rect.x2 || e.y1 != rect.y2 ||
- e.xm != minpos(0) || e.ym != minpos(1));
-
- npy_intp extentsdims[] = { 2, 2 };
- numpy::array_view<double, 2> outextents(extentsdims);
- outextents(0, 0) = e.x0;
- outextents(0, 1) = e.y0;
- outextents(1, 0) = e.x1;
- outextents(1, 1) = e.y1;
-
- npy_intp minposdims[] = { 2 };
- numpy::array_view<double, 1> outminpos(minposdims);
- outminpos(0) = e.xm;
- outminpos(1) = e.ym;
-
- return Py_BuildValue(
- "NNi", outextents.pyobj(), outminpos.pyobj(), changed);
-}
-
-const char *Py_get_path_collection_extents__doc__ = "get_path_collection_extents(";
-
-static PyObject *Py_get_path_collection_extents(PyObject *self, PyObject *args, PyObject *kwds)
-{
- agg::trans_affine master_transform;
- PyObject *pathsobj;
- numpy::array_view<const double, 3> transforms;
- numpy::array_view<const double, 2> offsets;
- agg::trans_affine offset_trans;
- extent_limits e;
-
- if (!PyArg_ParseTuple(args,
- "O&OO&O&O&:get_path_collection_extents",
- &convert_trans_affine,
- &master_transform,
- &pathsobj,
- &convert_transforms,
- &transforms,
- &convert_points,
- &offsets,
- &convert_trans_affine,
- &offset_trans)) {
- return NULL;
- }
-
- try
- {
- py::PathGenerator paths(pathsobj);
-
- CALL_CPP("get_path_collection_extents",
- (get_path_collection_extents(
- master_transform, paths, transforms, offsets, offset_trans, e)));
- }
- catch (const py::exception &)
- {
- return NULL;
- }
-
- npy_intp dims[] = { 2, 2 };
- numpy::array_view<double, 2> extents(dims);
- extents(0, 0) = e.x0;
- extents(0, 1) = e.y0;
- extents(1, 0) = e.x1;
- extents(1, 1) = e.y1;
-
- return extents.pyobj();
-}
-
-const char *Py_point_in_path_collection__doc__ =
- "point_in_path_collection(x, y, radius, master_transform, paths, transforms, offsets, "
- "offset_trans, filled, offset_position)";
-
-static PyObject *Py_point_in_path_collection(PyObject *self, PyObject *args, PyObject *kwds)
-{
- double x, y, radius;
- agg::trans_affine master_transform;
- PyObject *pathsobj;
- numpy::array_view<const double, 3> transforms;
- numpy::array_view<const double, 2> offsets;
- agg::trans_affine offset_trans;
- int filled;
- e_offset_position offset_position;
- std::vector<int> result;
-
- if (!PyArg_ParseTuple(args,
- "dddO&OO&O&O&iO&:point_in_path_collection",
- &x,
- &y,
- &radius,
- &convert_trans_affine,
- &master_transform,
- &pathsobj,
- &convert_transforms,
- &transforms,
- &convert_points,
- &offsets,
- &convert_trans_affine,
- &offset_trans,
- &filled,
- &convert_offset_position,
- &offset_position)) {
- return NULL;
- }
-
- try
- {
- py::PathGenerator paths(pathsobj);
-
- CALL_CPP("point_in_path_collection",
- (point_in_path_collection(x,
- y,
- radius,
- master_transform,
- paths,
- transforms,
- offsets,
- offset_trans,
- filled,
- offset_position,
- result)));
- }
- catch (const py::exception &)
- {
- return NULL;
- }
-
- npy_intp dims[] = {(npy_intp)result.size() };
- numpy::array_view<int, 1> pyresult(dims);
- if (result.size() > 0) {
- memcpy(pyresult.data(), &result[0], result.size() * sizeof(int));
- }
- return pyresult.pyobj();
-}
-
-const char *Py_path_in_path__doc__ = "path_in_path(path_a, trans_a, path_b, trans_b)";
-
-static PyObject *Py_path_in_path(PyObject *self, PyObject *args, PyObject *kwds)
-{
- py::PathIterator a;
- agg::trans_affine atrans;
- py::PathIterator b;
- agg::trans_affine btrans;
- bool result;
-
- if (!PyArg_ParseTuple(args,
- "O&O&O&O&:path_in_path",
- &convert_path,
- &a,
- &convert_trans_affine,
- &atrans,
- &convert_path,
- &b,
- &convert_trans_affine,
- &btrans)) {
- return NULL;
- }
-
- CALL_CPP("path_in_path", (result = path_in_path(a, atrans, b, btrans)));
-
- if (result) {
- Py_RETURN_TRUE;
- } else {
- Py_RETURN_FALSE;
- }
-}
-
-const char *Py_clip_path_to_rect__doc__ = "clip_path_to_rect(path, rect, inside)";
-
-static PyObject *Py_clip_path_to_rect(PyObject *self, PyObject *args, PyObject *kwds)
-{
- py::PathIterator path;
- agg::rect_d rect;
- int inside;
- std::vector<Polygon> result;
-
- if (!PyArg_ParseTuple(args,
- "O&O&i:clip_path_to_rect",
- &convert_path,
- &path,
- &convert_rect,
- &rect,
- &inside)) {
- return NULL;
- }
-
- CALL_CPP("clip_path_to_rect", (clip_path_to_rect(path, rect, inside, result)));
-
- return convert_polygon_vector(result);
-}
-
-const char *Py_affine_transform__doc__ = "affine_transform(points, trans)";
-
-static PyObject *Py_affine_transform(PyObject *self, PyObject *args, PyObject *kwds)
-{
- PyObject *vertices_obj;
- agg::trans_affine trans;
-
- if (!PyArg_ParseTuple(args,
- "OO&:affine_transform",
- &vertices_obj,
- &convert_trans_affine,
- &trans)) {
- return NULL;
- }
-
- try {
- numpy::array_view<double, 2> vertices(vertices_obj);
- npy_intp dims[] = { (npy_intp)vertices.size(), 2 };
- numpy::array_view<double, 2> result(dims);
- CALL_CPP("affine_transform", (affine_transform_2d(vertices, trans, result)));
- return result.pyobj();
- } catch (py::exception &) {
- PyErr_Clear();
- try {
- numpy::array_view<double, 1> vertices(vertices_obj);
- npy_intp dims[] = { (npy_intp)vertices.size() };
- numpy::array_view<double, 1> result(dims);
- CALL_CPP("affine_transform", (affine_transform_1d(vertices, trans, result)));
- return result.pyobj();
- } catch (py::exception &) {
- return NULL;
- }
- }
-}
-
-const char *Py_count_bboxes_overlapping_bbox__doc__ = "count_bboxes_overlapping_bbox(bbox, bboxes)";
-
-static PyObject *Py_count_bboxes_overlapping_bbox(PyObject *self, PyObject *args, PyObject *kwds)
-{
- agg::rect_d bbox;
- numpy::array_view<const double, 3> bboxes;
- int result;
-
- if (!PyArg_ParseTuple(args,
- "O&O&:count_bboxes_overlapping_bbox",
- &convert_rect,
- &bbox,
- &convert_bboxes,
- &bboxes)) {
- return NULL;
- }
-
- CALL_CPP("count_bboxes_overlapping_bbox",
- (result = count_bboxes_overlapping_bbox(bbox, bboxes)));
-
- return PyLong_FromLong(result);
-}
-
-const char *Py_path_intersects_path__doc__ = "path_intersects_path(path1, path2, filled=False)";
-
-static PyObject *Py_path_intersects_path(PyObject *self, PyObject *args, PyObject *kwds)
-{
- py::PathIterator p1;
- py::PathIterator p2;
- agg::trans_affine t1;
- agg::trans_affine t2;
- int filled = 0;
- const char *names[] = { "p1", "p2", "filled", NULL };
- bool result;
-
- if (!PyArg_ParseTupleAndKeywords(args,
- kwds,
- "O&O&i:path_intersects_path",
- (char **)names,
- &convert_path,
- &p1,
- &convert_path,
- &p2,
- &filled)) {
- return NULL;
- }
-
- CALL_CPP("path_intersects_path", (result = path_intersects_path(p1, p2)));
- if (filled) {
- if (!result) {
- CALL_CPP("path_intersects_path",
- (result = path_in_path(p1, t1, p2, t2)));
- }
- if (!result) {
- CALL_CPP("path_intersects_path",
- (result = path_in_path(p2, t1, p1, t2)));
- }
- }
-
- if (result) {
- Py_RETURN_TRUE;
- } else {
- Py_RETURN_FALSE;
- }
-}
-
-const char *Py_path_intersects_rectangle__doc__ = "path_intersects_rectangle(path, rect_x1, rect_y1, rect_x2, rect_y2, filled=False)";
-
-static PyObject *Py_path_intersects_rectangle(PyObject *self, PyObject *args, PyObject *kwds)
-{
- py::PathIterator path;
- double rect_x1, rect_y1, rect_x2, rect_y2;
- int filled = 0;
- const char *names[] = { "path", "rect_x1", "rect_y1", "rect_x2", "rect_y2", "filled", NULL };
- bool result;
-
- if (!PyArg_ParseTupleAndKeywords(args,
- kwds,
- "O&dddd|i:path_intersects_rectangle",
- (char **)names,
- &convert_path,
- &path,
- &rect_x1,
- &rect_y1,
- &rect_x2,
- &rect_y2,
- &filled)) {
- return NULL;
- }
-
- CALL_CPP("path_intersects_rectangle", (result = path_intersects_rectangle(path, rect_x1, rect_y1, rect_x2, rect_y2, filled)));
-
- if (result) {
- Py_RETURN_TRUE;
- } else {
- Py_RETURN_FALSE;
- }
-}
-
-const char *Py_convert_path_to_polygons__doc__ =
- "convert_path_to_polygons(path, trans, width=0, height=0)";
-
-static PyObject *Py_convert_path_to_polygons(PyObject *self, PyObject *args, PyObject *kwds)
-{
- py::PathIterator path;
- agg::trans_affine trans;
- double width = 0.0, height = 0.0;
- int closed_only = 1;
- std::vector<Polygon> result;
- const char *names[] = { "path", "transform", "width", "height", "closed_only", NULL };
-
- if (!PyArg_ParseTupleAndKeywords(args,
- kwds,
- "O&O&|ddi:convert_path_to_polygons",
- (char **)names,
- &convert_path,
- &path,
- &convert_trans_affine,
- &trans,
- &width,
- &height,
- &closed_only)) {
- return NULL;
- }
-
- CALL_CPP("convert_path_to_polygons",
- (convert_path_to_polygons(path, trans, width, height, closed_only, result)));
-
- return convert_polygon_vector(result);
-}
-
-const char *Py_cleanup_path__doc__ =
- "cleanup_path(path, trans, remove_nans, clip_rect, snap_mode, stroke_width, simplify, "
- "return_curves, sketch)";
-
-static PyObject *Py_cleanup_path(PyObject *self, PyObject *args, PyObject *kwds)
-{
- py::PathIterator path;
- agg::trans_affine trans;
- int remove_nans;
- agg::rect_d clip_rect;
- e_snap_mode snap_mode;
- double stroke_width;
- PyObject *simplifyobj;
- bool simplify = false;
- int return_curves;
- SketchParams sketch;
-
- if (!PyArg_ParseTuple(args,
- "O&O&iO&O&dOiO&:cleanup_path",
- &convert_path,
- &path,
- &convert_trans_affine,
- &trans,
- &remove_nans,
- &convert_rect,
- &clip_rect,
- &convert_snap,
- &snap_mode,
- &stroke_width,
- &simplifyobj,
- &return_curves,
- &convert_sketch_params,
- &sketch)) {
- return NULL;
- }
-
- if (simplifyobj == Py_None) {
- simplify = path.should_simplify();
- } else if (PyObject_IsTrue(simplifyobj)) {
- simplify = true;
- }
-
- bool do_clip = (clip_rect.x1 < clip_rect.x2 && clip_rect.y1 < clip_rect.y2);
-
- std::vector<double> vertices;
- std::vector<npy_uint8> codes;
-
- CALL_CPP("cleanup_path",
- (cleanup_path(path,
- trans,
- remove_nans,
- do_clip,
- clip_rect,
- snap_mode,
- stroke_width,
- simplify,
- return_curves,
- sketch,
- vertices,
- codes)));
-
- size_t length = codes.size();
-
- npy_intp vertices_dims[] = {(npy_intp)length, 2 };
- numpy::array_view<double, 2> pyvertices(vertices_dims);
-
- npy_intp codes_dims[] = {(npy_intp)length };
- numpy::array_view<unsigned char, 1> pycodes(codes_dims);
-
- memcpy(pyvertices.data(), &vertices[0], sizeof(double) * 2 * length);
- memcpy(pycodes.data(), &codes[0], sizeof(unsigned char) * length);
-
- return Py_BuildValue("NN", pyvertices.pyobj(), pycodes.pyobj());
-}
-
-const char *Py_convert_to_string__doc__ = "convert_to_string(path, trans, "
- "clip_rect, simplify, sketch, precision, codes, postfix)";
-
-static PyObject *Py_convert_to_string(PyObject *self, PyObject *args, PyObject *kwds)
-{
- py::PathIterator path;
- agg::trans_affine trans;
- agg::rect_d cliprect;
- PyObject *simplifyobj;
- bool simplify = false;
- SketchParams sketch;
- int precision;
- PyObject *codesobj;
- char *codes[5];
- int postfix;
- char *buffer = NULL;
- size_t buffersize;
- PyObject *result;
- int status;
-
- if (!PyArg_ParseTuple(args,
- "O&O&O&OO&iOi:convert_to_string",
- &convert_path,
- &path,
- &convert_trans_affine,
- &trans,
- &convert_rect,
- &cliprect,
- &simplifyobj,
- &convert_sketch_params,
- &sketch,
- &precision,
- &codesobj,
- &postfix)) {
- return NULL;
- }
-
- if (simplifyobj == Py_None) {
- simplify = path.should_simplify();
- } else if (PyObject_IsTrue(simplifyobj)) {
- simplify = true;
- }
-
- if (!PySequence_Check(codesobj)) {
- return NULL;
- }
- if (PySequence_Size(codesobj) != 5) {
- PyErr_SetString(
- PyExc_ValueError,
- "codes must be a 5-length sequence of byte strings");
- return NULL;
- }
- for (int i = 0; i < 5; ++i) {
- PyObject *item = PySequence_GetItem(codesobj, i);
- if (item == NULL) {
- return NULL;
- }
- codes[i] = PyBytes_AsString(item);
- if (codes[i] == NULL) {
- return NULL;
- }
- }
-
- CALL_CPP("convert_to_string",
- (status = convert_to_string(
- path, trans, cliprect, simplify, sketch,
- precision, codes, (bool)postfix, &buffer,
- &buffersize)));
-
- if (status) {
- free(buffer);
- if (status == 1) {
- PyErr_SetString(PyExc_MemoryError, "Memory error");
- } else if (status == 2) {
- PyErr_SetString(PyExc_ValueError, "Malformed path codes");
- }
- return NULL;
- }
-
- if (buffersize == 0) {
- result = PyBytes_FromString("");
- } else {
- result = PyBytes_FromStringAndSize(buffer, buffersize);
- }
-
- free(buffer);
-
- return result;
-}
-
-
-const char *Py_is_sorted__doc__ = "is_sorted(array)\n\n"
- "Returns True if 1-D array is monotonically increasing, ignoring NaNs\n";
-
-static PyObject *Py_is_sorted(PyObject *self, PyObject *obj)
-{
- npy_intp size;
- bool result;
-
- PyArrayObject *array = (PyArrayObject *)PyArray_FromAny(
- obj, NULL, 1, 1, 0, NULL);
-
- if (array == NULL) {
- return NULL;
- }
-
- size = PyArray_DIM(array, 0);
-
- if (size < 2) {
- Py_DECREF(array);
- Py_RETURN_TRUE;
- }
-
- /* Handle just the most common types here, otherwise coerce to
- double */
- switch(PyArray_TYPE(array)) {
- case NPY_INT:
- {
- _is_sorted_int<npy_int> is_sorted;
- result = is_sorted(array);
- }
- break;
-
- case NPY_LONG:
- {
- _is_sorted_int<npy_long> is_sorted;
- result = is_sorted(array);
- }
- break;
-
- case NPY_LONGLONG:
- {
- _is_sorted_int<npy_longlong> is_sorted;
- result = is_sorted(array);
- }
- break;
-
- case NPY_FLOAT:
- {
- _is_sorted<npy_float> is_sorted;
- result = is_sorted(array);
- }
- break;
-
- case NPY_DOUBLE:
- {
- _is_sorted<npy_double> is_sorted;
- result = is_sorted(array);
- }
- break;
-
- default:
- {
- Py_DECREF(array);
- array = (PyArrayObject *)PyArray_FromObject(obj, NPY_DOUBLE, 1, 1);
-
- if (array == NULL) {
- return NULL;
- }
-
- _is_sorted<npy_double> is_sorted;
- result = is_sorted(array);
- }
- }
-
- Py_DECREF(array);
-
- if (result) {
- Py_RETURN_TRUE;
- } else {
- Py_RETURN_FALSE;
- }
-}
-
-
-extern "C" {
-
- static PyMethodDef module_functions[] = {
- {"point_in_path", (PyCFunction)Py_point_in_path, METH_VARARGS, Py_point_in_path__doc__},
- {"points_in_path", (PyCFunction)Py_points_in_path, METH_VARARGS, Py_points_in_path__doc__},
- {"point_on_path", (PyCFunction)Py_point_on_path, METH_VARARGS, Py_point_on_path__doc__},
- {"points_on_path", (PyCFunction)Py_points_on_path, METH_VARARGS, Py_points_on_path__doc__},
- {"get_path_extents", (PyCFunction)Py_get_path_extents, METH_VARARGS, Py_get_path_extents__doc__},
- {"update_path_extents", (PyCFunction)Py_update_path_extents, METH_VARARGS, Py_update_path_extents__doc__},
- {"get_path_collection_extents", (PyCFunction)Py_get_path_collection_extents, METH_VARARGS, Py_get_path_collection_extents__doc__},
- {"point_in_path_collection", (PyCFunction)Py_point_in_path_collection, METH_VARARGS, Py_point_in_path_collection__doc__},
- {"path_in_path", (PyCFunction)Py_path_in_path, METH_VARARGS, Py_path_in_path__doc__},
- {"clip_path_to_rect", (PyCFunction)Py_clip_path_to_rect, METH_VARARGS, Py_clip_path_to_rect__doc__},
- {"affine_transform", (PyCFunction)Py_affine_transform, METH_VARARGS, Py_affine_transform__doc__},
- {"count_bboxes_overlapping_bbox", (PyCFunction)Py_count_bboxes_overlapping_bbox, METH_VARARGS, Py_count_bboxes_overlapping_bbox__doc__},
- {"path_intersects_path", (PyCFunction)Py_path_intersects_path, METH_VARARGS|METH_KEYWORDS, Py_path_intersects_path__doc__},
- {"path_intersects_rectangle", (PyCFunction)Py_path_intersects_rectangle, METH_VARARGS|METH_KEYWORDS, Py_path_intersects_rectangle__doc__},
- {"convert_path_to_polygons", (PyCFunction)Py_convert_path_to_polygons, METH_VARARGS|METH_KEYWORDS, Py_convert_path_to_polygons__doc__},
- {"cleanup_path", (PyCFunction)Py_cleanup_path, METH_VARARGS, Py_cleanup_path__doc__},
- {"convert_to_string", (PyCFunction)Py_convert_to_string, METH_VARARGS, Py_convert_to_string__doc__},
- {"is_sorted", (PyCFunction)Py_is_sorted, METH_O, Py_is_sorted__doc__},
- {NULL}
- };
-
-#if PY3K
- static struct PyModuleDef moduledef = {
- PyModuleDef_HEAD_INIT,
- "_path",
- NULL,
- 0,
- module_functions,
- NULL,
- NULL,
- NULL,
- NULL
- };
-
-#define INITERROR return NULL
- PyMODINIT_FUNC PyInit__path(void)
-#else
-#define INITERROR return
- PyMODINIT_FUNC init_path(void)
-#endif
- {
- PyObject *m;
-#if PY3K
- m = PyModule_Create(&moduledef);
-#else
- m = Py_InitModule3("_path", module_functions, NULL);
-#endif
-
- if (m == NULL) {
- INITERROR;
- }
-
- import_array();
-
-#if PY3K
- return m;
-#endif
- }
-}
diff --git a/contrib/python/matplotlib/py2/src/_png.cpp b/contrib/python/matplotlib/py2/src/_png.cpp
deleted file mode 100644
index ea7bf32efe..0000000000
--- a/contrib/python/matplotlib/py2/src/_png.cpp
+++ /dev/null
@@ -1,793 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-/* For linux, png.h must be imported before Python.h because
- png.h needs to be the one to define setjmp.
- Undefining _POSIX_C_SOURCE and _XOPEN_SOURCE stops a couple
- of harmless warnings.
-*/
-#define PY_SSIZE_T_CLEAN
-
-extern "C" {
-# include <png.h>
-# ifdef _POSIX_C_SOURCE
-# undef _POSIX_C_SOURCE
-# endif
-# ifndef _AIX
-# ifdef _XOPEN_SOURCE
-# undef _XOPEN_SOURCE
-# endif
-# endif
-}
-
-#include "numpy_cpp.h"
-#include "mplutils.h"
-#include "file_compat.h"
-
-# include <vector>
-# include "Python.h"
-
-
-// As reported in [3082058] build _png.so on aix
-#ifdef _AIX
-#undef jmpbuf
-#endif
-
-struct buffer_t {
- PyObject *str;
- size_t cursor;
- size_t size;
-};
-
-
-static void write_png_data_buffer(png_structp png_ptr, png_bytep data, png_size_t length)
-{
- buffer_t *buff = (buffer_t *)png_get_io_ptr(png_ptr);
- if (buff->cursor + length < buff->size) {
- memcpy(PyBytes_AS_STRING(buff->str) + buff->cursor, data, length);
- buff->cursor += length;
- }
-}
-
-static void flush_png_data_buffer(png_structp png_ptr)
-{
-
-}
-
-static void write_png_data(png_structp png_ptr, png_bytep data, png_size_t length)
-{
- PyObject *py_file_obj = (PyObject *)png_get_io_ptr(png_ptr);
- PyObject *write_method = PyObject_GetAttrString(py_file_obj, "write");
- PyObject *result = NULL;
- if (write_method) {
-#if PY3K
- result = PyObject_CallFunction(write_method, (char *)"y#", data, length);
-#else
- result = PyObject_CallFunction(write_method, (char *)"s#", data, length);
-#endif
- }
- Py_XDECREF(write_method);
- Py_XDECREF(result);
-}
-
-static void flush_png_data(png_structp png_ptr)
-{
- PyObject *py_file_obj = (PyObject *)png_get_io_ptr(png_ptr);
- PyObject *flush_method = PyObject_GetAttrString(py_file_obj, "flush");
- PyObject *result = NULL;
- if (flush_method) {
- result = PyObject_CallFunction(flush_method, (char *)"");
- }
- Py_XDECREF(flush_method);
- Py_XDECREF(result);
-}
-
-const char *Py_write_png__doc__ =
- "write_png(buffer, file, dpi=0, compression=6, filter=auto, metadata=None)\n"
- "\n"
- "Parameters\n"
- "----------\n"
- "buffer : numpy array of image data\n"
- " Must be an MxNxD array of dtype uint8.\n"
- " - if D is 1, the image is greyscale\n"
- " - if D is 3, the image is RGB\n"
- " - if D is 4, the image is RGBA\n"
- "\n"
- "file : str path, file-like object or None\n"
- " - If a str, must be a file path\n"
- " - If a file-like object, must write bytes\n"
- " - If None, a byte string containing the PNG data will be returned\n"
- "\n"
- "dpi : float\n"
- " The dpi to store in the file metadata.\n"
- "\n"
- "compression : int\n"
- " The level of lossless zlib compression to apply. 0 indicates no\n"
- " compression. Values 1-9 indicate low/fast through high/slow\n"
- " compression. Default is 6.\n"
- "\n"
- "filter : int\n"
- " Filter to apply. Must be one of the constants: PNG_FILTER_NONE,\n"
- " PNG_FILTER_SUB, PNG_FILTER_UP, PNG_FILTER_AVG, PNG_FILTER_PAETH.\n"
- " See the PNG standard for more information.\n"
- " If not provided, libpng will try to automatically determine the\n"
- " best filter on a line-by-line basis.\n"
- "\n"
- "metadata : dictionary\n"
- " The keyword-text pairs that are stored as comments in the image.\n"
- " Keys must be shorter than 79 chars. The only supported encoding\n"
- " for both keywords and values is Latin-1 (ISO 8859-1).\n"
- " Examples given in the PNG Specification are:\n"
- " - Title: Short (one line) title or caption for image\n"
- " - Author: Name of image's creator\n"
- " - Description: Description of image (possibly long)\n"
- " - Copyright: Copyright notice\n"
- " - Creation Time: Time of original image creation\n"
- " (usually RFC 1123 format, see below)\n"
- " - Software: Software used to create the image\n"
- " - Disclaimer: Legal disclaimer\n"
- " - Warning: Warning of nature of content\n"
- " - Source: Device used to create the image\n"
- " - Comment: Miscellaneous comment; conversion\n"
- " from other image format\n"
- "\n"
- "Returns\n"
- "-------\n"
- "buffer : bytes or None\n"
- " Byte string containing the PNG content if None was passed in for\n"
- " file, otherwise None is returned.\n";
-
-// this code is heavily adapted from
-// https://www.object-craft.com.au/projects/paint/ which licensed under the
-// (BSD compatible) LICENSE_PAINT which is included in this distribution.
-static PyObject *Py_write_png(PyObject *self, PyObject *args, PyObject *kwds)
-{
- numpy::array_view<unsigned char, 3> buffer;
- PyObject *filein;
- PyObject *metadata = NULL;
- PyObject *meta_key, *meta_val;
- png_text *text;
- Py_ssize_t pos = 0;
- int meta_pos = 0;
- Py_ssize_t meta_size;
- double dpi = 0;
- int compression = 6;
- int filter = -1;
- const char *names[] = { "buffer", "file", "dpi", "compression", "filter", "metadata", NULL };
-
- // We don't need strict contiguity, just for each row to be
- // contiguous, and libpng has special handling for getting RGB out
- // of RGBA, ARGB or BGR. But the simplest thing to do is to
- // enforce contiguity using array_view::converter_contiguous.
- if (!PyArg_ParseTupleAndKeywords(args,
- kwds,
- "O&O|diiO:write_png",
- (char **)names,
- &buffer.converter_contiguous,
- &buffer,
- &filein,
- &dpi,
- &compression,
- &filter,
- &metadata)) {
- return NULL;
- }
-
- png_uint_32 width = (png_uint_32)buffer.dim(1);
- png_uint_32 height = (png_uint_32)buffer.dim(0);
- int channels = buffer.dim(2);
- std::vector<png_bytep> row_pointers(height);
- for (png_uint_32 row = 0; row < (png_uint_32)height; ++row) {
- row_pointers[row] = (png_bytep)&buffer(row, 0, 0);
- }
-
- FILE *fp = NULL;
- mpl_off_t offset = 0;
- bool close_file = false;
- bool close_dup_file = false;
- PyObject *py_file = NULL;
-
- png_structp png_ptr = NULL;
- png_infop info_ptr = NULL;
- struct png_color_8_struct sig_bit;
- int png_color_type;
- buffer_t buff;
- buff.str = NULL;
-
- switch (channels) {
- case 1:
- png_color_type = PNG_COLOR_TYPE_GRAY;
- break;
- case 3:
- png_color_type = PNG_COLOR_TYPE_RGB;
- break;
- case 4:
- png_color_type = PNG_COLOR_TYPE_RGB_ALPHA;
- break;
- default:
- PyErr_SetString(PyExc_ValueError,
- "Buffer must be an NxMxD array with D in 1, 3, 4 "
- "(grayscale, RGB, RGBA)");
- goto exit;
- }
-
- if (compression < 0 || compression > 9) {
- PyErr_Format(PyExc_ValueError,
- "compression must be in range 0-9, got %d", compression);
- goto exit;
- }
-
- if (PyBytes_Check(filein) || PyUnicode_Check(filein)) {
- if ((py_file = mpl_PyFile_OpenFile(filein, (char *)"wb")) == NULL) {
- goto exit;
- }
- close_file = true;
- } else {
- py_file = filein;
- }
-
- if (filein == Py_None) {
- buff.size = width * height * 4 + 1024;
- buff.str = PyBytes_FromStringAndSize(NULL, buff.size);
- if (buff.str == NULL) {
- goto exit;
- }
- buff.cursor = 0;
- } else {
- #if PY3K
- if (close_file) {
- #else
- if (close_file || PyFile_Check(py_file)) {
- #endif
- fp = mpl_PyFile_Dup(py_file, (char *)"wb", &offset);
- }
-
- if (fp) {
- close_dup_file = true;
- } else {
- PyErr_Clear();
- PyObject *write_method = PyObject_GetAttrString(py_file, "write");
- if (!(write_method && PyCallable_Check(write_method))) {
- Py_XDECREF(write_method);
- PyErr_SetString(PyExc_TypeError,
- "Object does not appear to be a 8-bit string path or "
- "a Python file-like object");
- goto exit;
- }
- Py_XDECREF(write_method);
- }
- }
-
- png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
- if (png_ptr == NULL) {
- PyErr_SetString(PyExc_RuntimeError, "Could not create write struct");
- goto exit;
- }
-
- png_set_compression_level(png_ptr, compression);
- if (filter >= 0) {
- png_set_filter(png_ptr, 0, filter);
- }
-
- info_ptr = png_create_info_struct(png_ptr);
- if (info_ptr == NULL) {
- PyErr_SetString(PyExc_RuntimeError, "Could not create info struct");
- goto exit;
- }
-
- if (setjmp(png_jmpbuf(png_ptr))) {
- PyErr_SetString(PyExc_RuntimeError, "libpng signaled error");
- goto exit;
- }
-
- if (buff.str) {
- png_set_write_fn(png_ptr, (void *)&buff, &write_png_data_buffer, &flush_png_data_buffer);
- } else if (fp) {
- png_init_io(png_ptr, fp);
- } else {
- png_set_write_fn(png_ptr, (void *)py_file, &write_png_data, &flush_png_data);
- }
- png_set_IHDR(png_ptr,
- info_ptr,
- width,
- height,
- 8,
- png_color_type,
- PNG_INTERLACE_NONE,
- PNG_COMPRESSION_TYPE_BASE,
- PNG_FILTER_TYPE_BASE);
-
- // Save the dpi of the image in the file
- if (dpi > 0.0) {
- png_uint_32 dots_per_meter = (png_uint_32)(dpi / (2.54 / 100.0));
- png_set_pHYs(png_ptr, info_ptr, dots_per_meter, dots_per_meter, PNG_RESOLUTION_METER);
- }
-
-#ifdef PNG_TEXT_SUPPORTED
- // Save the metadata
- if (metadata != NULL) {
- meta_size = PyDict_Size(metadata);
- text = new png_text[meta_size];
-
- while (PyDict_Next(metadata, &pos, &meta_key, &meta_val)) {
- text[meta_pos].compression = PNG_TEXT_COMPRESSION_NONE;
-#if PY3K
- if (PyUnicode_Check(meta_key)) {
- PyObject *temp_key = PyUnicode_AsEncodedString(meta_key, "latin_1", "strict");
- if (temp_key != NULL) {
- text[meta_pos].key = PyBytes_AsString(temp_key);
- }
- } else if (PyBytes_Check(meta_key)) {
- text[meta_pos].key = PyBytes_AsString(meta_key);
- } else {
- char invalid_key[79];
- sprintf(invalid_key,"INVALID KEY %d", meta_pos);
- text[meta_pos].key = invalid_key;
- }
- if (PyUnicode_Check(meta_val)) {
- PyObject *temp_val = PyUnicode_AsEncodedString(meta_val, "latin_1", "strict");
- if (temp_val != NULL) {
- text[meta_pos].text = PyBytes_AsString(temp_val);
- }
- } else if (PyBytes_Check(meta_val)) {
- text[meta_pos].text = PyBytes_AsString(meta_val);
- } else {
- text[meta_pos].text = (char *)"Invalid value in metadata";
- }
-#else
- text[meta_pos].key = PyString_AsString(meta_key);
- text[meta_pos].text = PyString_AsString(meta_val);
-#endif
-#ifdef PNG_iTXt_SUPPORTED
- text[meta_pos].lang = NULL;
-#endif
- meta_pos++;
- }
- png_set_text(png_ptr, info_ptr, text, meta_size);
- delete[] text;
- }
-#endif
-
- sig_bit.alpha = 0;
- switch (png_color_type) {
- case PNG_COLOR_TYPE_GRAY:
- sig_bit.gray = 8;
- sig_bit.red = 0;
- sig_bit.green = 0;
- sig_bit.blue = 0;
- break;
- case PNG_COLOR_TYPE_RGB_ALPHA:
- sig_bit.alpha = 8;
- // fall through
- case PNG_COLOR_TYPE_RGB:
- sig_bit.gray = 0;
- sig_bit.red = 8;
- sig_bit.green = 8;
- sig_bit.blue = 8;
- break;
- default:
- PyErr_SetString(PyExc_RuntimeError, "internal error, bad png_color_type");
- goto exit;
- }
- png_set_sBIT(png_ptr, info_ptr, &sig_bit);
-
- png_write_info(png_ptr, info_ptr);
- png_write_image(png_ptr, &row_pointers[0]);
- png_write_end(png_ptr, info_ptr);
-
-exit:
-
- if (png_ptr && info_ptr) {
- png_destroy_write_struct(&png_ptr, &info_ptr);
- }
-
- if (close_dup_file) {
- mpl_PyFile_DupClose(py_file, fp, offset);
- }
-
- if (close_file) {
- mpl_PyFile_CloseFile(py_file);
- Py_DECREF(py_file);
- }
-
- if (PyErr_Occurred()) {
- Py_XDECREF(buff.str);
- return NULL;
- } else {
- if (buff.str) {
- _PyBytes_Resize(&buff.str, buff.cursor);
- return buff.str;
- }
- Py_RETURN_NONE;
- }
-}
-
-static void _read_png_data(PyObject *py_file_obj, png_bytep data, png_size_t length)
-{
- PyObject *read_method = PyObject_GetAttrString(py_file_obj, "read");
- PyObject *result = NULL;
- char *buffer;
- Py_ssize_t bufflen;
- if (read_method) {
- result = PyObject_CallFunction(read_method, (char *)"i", length);
- if (result) {
- if (PyBytes_AsStringAndSize(result, &buffer, &bufflen) == 0) {
- if (bufflen == (Py_ssize_t)length) {
- memcpy(data, buffer, length);
- } else {
- PyErr_SetString(PyExc_IOError, "read past end of file");
- }
- } else {
- PyErr_SetString(PyExc_IOError, "failed to copy buffer");
- }
- } else {
- PyErr_SetString(PyExc_IOError, "failed to read file");
- }
-
-
- }
- Py_XDECREF(read_method);
- Py_XDECREF(result);
-}
-
-static void read_png_data(png_structp png_ptr, png_bytep data, png_size_t length)
-{
- PyObject *py_file_obj = (PyObject *)png_get_io_ptr(png_ptr);
- _read_png_data(py_file_obj, data, length);
- if (PyErr_Occurred()) {
- png_error(png_ptr, "failed to read file");
- }
-
-}
-
-static PyObject *_read_png(PyObject *filein, bool float_result)
-{
- png_byte header[8]; // 8 is the maximum size that can be checked
- FILE *fp = NULL;
- mpl_off_t offset = 0;
- bool close_file = false;
- bool close_dup_file = false;
- PyObject *py_file = NULL;
- png_structp png_ptr = NULL;
- png_infop info_ptr = NULL;
- int num_dims;
- std::vector<png_bytep> row_pointers;
- png_uint_32 width = 0;
- png_uint_32 height = 0;
- int bit_depth;
- PyObject *result = NULL;
-
- // TODO: Remove direct calls to Numpy API here
-
- if (PyBytes_Check(filein) || PyUnicode_Check(filein)) {
- if ((py_file = mpl_PyFile_OpenFile(filein, (char *)"rb")) == NULL) {
- goto exit;
- }
- close_file = true;
- } else {
- py_file = filein;
- }
-
- #if PY3K
- if (close_file) {
- #else
- if (close_file || PyFile_Check(py_file)) {
- #endif
- fp = mpl_PyFile_Dup(py_file, (char *)"rb", &offset);
- }
-
- if (fp) {
- close_dup_file = true;
- if (fread(header, 1, 8, fp) != 8) {
- PyErr_SetString(PyExc_IOError, "error reading PNG header");
- goto exit;
- }
- } else {
- PyErr_Clear();
-
- PyObject *read_method = PyObject_GetAttrString(py_file, "read");
- if (!(read_method && PyCallable_Check(read_method))) {
- Py_XDECREF(read_method);
- PyErr_SetString(PyExc_TypeError,
- "Object does not appear to be a 8-bit string path or "
- "a Python file-like object");
- goto exit;
- }
- Py_XDECREF(read_method);
- _read_png_data(py_file, header, 8);
- if (PyErr_Occurred()) {
- goto exit;
- }
- }
-
- if (png_sig_cmp(header, 0, 8)) {
- PyErr_SetString(PyExc_ValueError, "invalid PNG header");
- goto exit;
- }
-
- /* initialize stuff */
- png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
-
- if (!png_ptr) {
- PyErr_SetString(PyExc_RuntimeError, "png_create_read_struct failed");
- goto exit;
- }
-
- info_ptr = png_create_info_struct(png_ptr);
- if (!info_ptr) {
- PyErr_SetString(PyExc_RuntimeError, "png_create_info_struct failed");
- goto exit;
- }
-
- if (setjmp(png_jmpbuf(png_ptr))) {
- if (!PyErr_Occurred()) {
- PyErr_SetString(PyExc_RuntimeError, "error setting jump");
- }
- goto exit;
- }
-
- if (fp) {
- png_init_io(png_ptr, fp);
- } else {
- png_set_read_fn(png_ptr, (void *)py_file, &read_png_data);
- }
- png_set_sig_bytes(png_ptr, 8);
- png_read_info(png_ptr, info_ptr);
-
- width = png_get_image_width(png_ptr, info_ptr);
- height = png_get_image_height(png_ptr, info_ptr);
-
- bit_depth = png_get_bit_depth(png_ptr, info_ptr);
-
- // Unpack 1, 2, and 4-bit images
- if (bit_depth < 8) {
- png_set_packing(png_ptr);
- }
-
- // If sig bits are set, shift data
- png_color_8p sig_bit;
- if ((png_get_color_type(png_ptr, info_ptr) != PNG_COLOR_TYPE_PALETTE) &&
- png_get_sBIT(png_ptr, info_ptr, &sig_bit)) {
- png_set_shift(png_ptr, sig_bit);
- }
-
-#if NPY_BYTE_ORDER == NPY_LITTLE_ENDIAN
- // Convert big endian to little
- if (bit_depth == 16) {
- png_set_swap(png_ptr);
- }
-#endif
-
- // Convert palletes to full RGB
- if (png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_PALETTE) {
- png_set_palette_to_rgb(png_ptr);
- bit_depth = 8;
- }
-
- // If there's an alpha channel convert gray to RGB
- if (png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_GRAY_ALPHA) {
- png_set_gray_to_rgb(png_ptr);
- }
-
- png_set_interlace_handling(png_ptr);
- png_read_update_info(png_ptr, info_ptr);
-
- row_pointers.resize(height);
- for (png_uint_32 row = 0; row < height; row++) {
- row_pointers[row] = new png_byte[png_get_rowbytes(png_ptr, info_ptr)];
- }
-
- png_read_image(png_ptr, &row_pointers[0]);
-
- npy_intp dimensions[3];
- dimensions[0] = height; // numrows
- dimensions[1] = width; // numcols
- if (png_get_color_type(png_ptr, info_ptr) & PNG_COLOR_MASK_ALPHA) {
- dimensions[2] = 4; // RGBA images
- } else if (png_get_color_type(png_ptr, info_ptr) & PNG_COLOR_MASK_COLOR) {
- dimensions[2] = 3; // RGB images
- } else {
- dimensions[2] = 1; // Greyscale images
- }
-
- if (float_result) {
- double max_value = (1 << bit_depth) - 1;
-
- numpy::array_view<float, 3> A(dimensions);
-
- for (png_uint_32 y = 0; y < height; y++) {
- png_byte *row = row_pointers[y];
- for (png_uint_32 x = 0; x < width; x++) {
- if (bit_depth == 16) {
- png_uint_16 *ptr = &reinterpret_cast<png_uint_16 *>(row)[x * dimensions[2]];
- for (png_uint_32 p = 0; p < (png_uint_32)dimensions[2]; p++) {
- A(y, x, p) = (float)(ptr[p]) / max_value;
- }
- } else {
- png_byte *ptr = &(row[x * dimensions[2]]);
- for (png_uint_32 p = 0; p < (png_uint_32)dimensions[2]; p++) {
- A(y, x, p) = (float)(ptr[p]) / max_value;
- }
- }
- }
- }
-
- result = A.pyobj();
- } else if (bit_depth == 16) {
- numpy::array_view<png_uint_16, 3> A(dimensions);
-
- for (png_uint_32 y = 0; y < height; y++) {
- png_byte *row = row_pointers[y];
- for (png_uint_32 x = 0; x < width; x++) {
- png_uint_16 *ptr = &reinterpret_cast<png_uint_16 *>(row)[x * dimensions[2]];
- for (png_uint_32 p = 0; p < (png_uint_32)dimensions[2]; p++) {
- A(y, x, p) = ptr[p];
- }
- }
- }
-
- result = A.pyobj();
- } else if (bit_depth == 8) {
- numpy::array_view<png_byte, 3> A(dimensions);
-
- for (png_uint_32 y = 0; y < height; y++) {
- png_byte *row = row_pointers[y];
- for (png_uint_32 x = 0; x < width; x++) {
- png_byte *ptr = &(row[x * dimensions[2]]);
- for (png_uint_32 p = 0; p < (png_uint_32)dimensions[2]; p++) {
- A(y, x, p) = ptr[p];
- }
- }
- }
-
- result = A.pyobj();
- } else {
- PyErr_SetString(PyExc_RuntimeError, "image has unknown bit depth");
- goto exit;
- }
-
- // free the png memory
- png_read_end(png_ptr, info_ptr);
-
- // For gray, return an x by y array, not an x by y by 1
- num_dims = (png_get_color_type(png_ptr, info_ptr) & PNG_COLOR_MASK_COLOR) ? 3 : 2;
-
- if (num_dims == 2) {
- PyArray_Dims dims = {dimensions, 2};
- PyObject *reshaped = PyArray_Newshape((PyArrayObject *)result, &dims, NPY_CORDER);
- Py_DECREF(result);
- result = reshaped;
- }
-
-exit:
- if (png_ptr && info_ptr) {
-#ifndef png_infopp_NULL
- png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
-#else
- png_destroy_read_struct(&png_ptr, &info_ptr, png_infopp_NULL);
-#endif
- }
-
- if (close_dup_file) {
- mpl_PyFile_DupClose(py_file, fp, offset);
- }
-
- if (close_file) {
- mpl_PyFile_CloseFile(py_file);
- Py_DECREF(py_file);
- }
-
- for (png_uint_32 row = 0; row < height; row++) {
- delete[] row_pointers[row];
- }
-
- if (PyErr_Occurred()) {
- Py_XDECREF(result);
- return NULL;
- } else {
- return result;
- }
-}
-
-const char *Py_read_png_float__doc__ =
- "read_png_float(file)\n"
- "\n"
- "Read in a PNG file, converting values to floating-point doubles\n"
- "in the range (0, 1)\n"
- "\n"
- "Parameters\n"
- "----------\n"
- "file : str path or file-like object\n";
-
-static PyObject *Py_read_png_float(PyObject *self, PyObject *args, PyObject *kwds)
-{
- return _read_png(args, true);
-}
-
-const char *Py_read_png_int__doc__ =
- "read_png_int(file)\n"
- "\n"
- "Read in a PNG file with original integer values.\n"
- "\n"
- "Parameters\n"
- "----------\n"
- "file : str path or file-like object\n";
-
-static PyObject *Py_read_png_int(PyObject *self, PyObject *args, PyObject *kwds)
-{
- return _read_png(args, false);
-}
-
-const char *Py_read_png__doc__ =
- "read_png(file)\n"
- "\n"
- "Read in a PNG file, converting values to floating-point doubles\n"
- "in the range (0, 1)\n"
- "\n"
- "Alias for read_png_float()\n"
- "\n"
- "Parameters\n"
- "----------\n"
- "file : str path or file-like object\n";
-
-static PyMethodDef module_methods[] = {
- {"write_png", (PyCFunction)Py_write_png, METH_VARARGS|METH_KEYWORDS, Py_write_png__doc__},
- {"read_png", (PyCFunction)Py_read_png_float, METH_O, Py_read_png__doc__},
- {"read_png_float", (PyCFunction)Py_read_png_float, METH_O, Py_read_png_float__doc__},
- {"read_png_int", (PyCFunction)Py_read_png_int, METH_O, Py_read_png_int__doc__},
- {NULL}
-};
-
-extern "C" {
-
-#if PY3K
- static struct PyModuleDef moduledef = {
- PyModuleDef_HEAD_INIT,
- "_png",
- NULL,
- 0,
- module_methods,
- NULL,
- NULL,
- NULL,
- NULL
- };
-
-#define INITERROR return NULL
-
- PyMODINIT_FUNC PyInit__png(void)
-
-#else
-#define INITERROR return
-
- PyMODINIT_FUNC init_png(void)
-#endif
-
- {
- PyObject *m;
-
-#if PY3K
- m = PyModule_Create(&moduledef);
-#else
- m = Py_InitModule3("_png", module_methods, NULL);
-#endif
-
- if (m == NULL) {
- INITERROR;
- }
-
- import_array();
-
- if (PyModule_AddIntConstant(m, "PNG_FILTER_NONE", PNG_FILTER_NONE) ||
- PyModule_AddIntConstant(m, "PNG_FILTER_SUB", PNG_FILTER_SUB) ||
- PyModule_AddIntConstant(m, "PNG_FILTER_UP", PNG_FILTER_UP) ||
- PyModule_AddIntConstant(m, "PNG_FILTER_AVG", PNG_FILTER_AVG) ||
- PyModule_AddIntConstant(m, "PNG_FILTER_PAETH", PNG_FILTER_PAETH)) {
- INITERROR;
- }
-
-
-#if PY3K
- return m;
-#endif
- }
-}
diff --git a/contrib/python/matplotlib/py2/src/_tkagg.cpp b/contrib/python/matplotlib/py2/src/_tkagg.cpp
deleted file mode 100644
index 106f1398b3..0000000000
--- a/contrib/python/matplotlib/py2/src/_tkagg.cpp
+++ /dev/null
@@ -1,475 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-/*
- * This code is derived from The Python Imaging Library and is covered
- * by the PIL license.
- *
- * See LICENSE/LICENSE.PIL for details.
- *
- */
-#define PY_SSIZE_T_CLEAN
-#include <Python.h>
-#include <cstdlib>
-#include <cstdio>
-#include <sstream>
-
-#include <agg_basics.h> // agg:int8u
-
-// Include our own excerpts from the Tcl / Tk headers
-#include "_tkmini.h"
-
-#if defined(_MSC_VER)
-# define IMG_FORMAT "%d %d %Iu"
-#else
-# define IMG_FORMAT "%d %d %zu"
-#endif
-#define BBOX_FORMAT "%f %f %f %f"
-
-typedef struct
-{
- PyObject_HEAD
- Tcl_Interp *interp;
-} TkappObject;
-
-// Global vars for Tcl / Tk functions. We load these symbols from the tkinter
-// extension module or loaded Tcl / Tk libraries at run-time.
-static Tcl_CreateCommand_t TCL_CREATE_COMMAND;
-static Tcl_AppendResult_t TCL_APPEND_RESULT;
-static Tk_MainWindow_t TK_MAIN_WINDOW;
-static Tk_FindPhoto_t TK_FIND_PHOTO;
-static Tk_PhotoPutBlock_NoComposite_t TK_PHOTO_PUT_BLOCK_NO_COMPOSITE;
-static Tk_PhotoBlank_t TK_PHOTO_BLANK;
-
-static int PyAggImagePhoto(ClientData clientdata, Tcl_Interp *interp, int
- argc, char **argv)
-{
- Tk_PhotoHandle photo;
- Tk_PhotoImageBlock block;
-
- // vars for blitting
-
- size_t pdata;
- int wdata, hdata, bbox_parse;
- float x1, x2, y1, y2;
- bool has_bbox;
- agg::int8u *destbuffer, *buffer;
- int destx, desty, destwidth, destheight, deststride;
-
- long mode;
- long nval;
- if (TK_MAIN_WINDOW(interp) == NULL) {
- // Will throw a _tkinter.TclError with "this isn't a Tk application"
- return TCL_ERROR;
- }
-
- if (argc != 5) {
- TCL_APPEND_RESULT(interp, "usage: ", argv[0], " destPhoto srcImage", (char *)NULL);
- return TCL_ERROR;
- }
-
- /* get Tcl PhotoImage handle */
- photo = TK_FIND_PHOTO(interp, argv[1]);
- if (photo == NULL) {
- TCL_APPEND_RESULT(interp, "destination photo must exist", (char *)NULL);
- return TCL_ERROR;
- }
- /* get buffer from str which is "height width ptr" */
- if (sscanf(argv[2], IMG_FORMAT, &hdata, &wdata, &pdata) != 3) {
- TCL_APPEND_RESULT(interp,
- "error reading data, expected height width ptr",
- (char *)NULL);
- return TCL_ERROR;
- }
- buffer = (agg::int8u*)pdata;
-
- /* get array mode (0=mono, 1=rgb, 2=rgba) */
- mode = atol(argv[3]);
- if ((mode != 0) && (mode != 1) && (mode != 2)) {
- TCL_APPEND_RESULT(interp, "illegal image mode", (char *)NULL);
- return TCL_ERROR;
- }
-
- /* check for bbox/blitting */
- bbox_parse = sscanf(argv[4], BBOX_FORMAT, &x1, &x2, &y1, &y2);
- if (bbox_parse == 4) {
- has_bbox = true;
- }
- else if ((bbox_parse == 1) && (x1 == 0)){
- has_bbox = false;
- } else {
- TCL_APPEND_RESULT(interp, "illegal bbox", (char *)NULL);
- return TCL_ERROR;
- }
-
- if (has_bbox) {
- int srcstride = wdata * 4;
- destx = (int)x1;
- desty = (int)(hdata - y2);
- destwidth = (int)(x2 - x1);
- destheight = (int)(y2 - y1);
- deststride = 4 * destwidth;
-
- destbuffer = new agg::int8u[deststride * destheight];
- if (destbuffer == NULL) {
- TCL_APPEND_RESULT(interp, "could not allocate memory", (char *)NULL);
- return TCL_ERROR;
- }
-
- for (int i = 0; i < destheight; ++i) {
- memcpy(destbuffer + (deststride * i),
- &buffer[(i + desty) * srcstride + (destx * 4)],
- deststride);
- }
- } else {
- destbuffer = NULL;
- destx = desty = destwidth = destheight = deststride = 0;
- }
-
- /* setup tkblock */
- block.pixelSize = 1;
- if (mode == 0) {
- block.offset[0] = block.offset[1] = block.offset[2] = 0;
- nval = 1;
- } else {
- block.offset[0] = 0;
- block.offset[1] = 1;
- block.offset[2] = 2;
- if (mode == 1) {
- block.offset[3] = 0;
- block.pixelSize = 3;
- nval = 3;
- } else {
- block.offset[3] = 3;
- block.pixelSize = 4;
- nval = 4;
- }
- }
-
- if (has_bbox) {
- block.width = destwidth;
- block.height = destheight;
- block.pitch = deststride;
- block.pixelPtr = destbuffer;
-
- TK_PHOTO_PUT_BLOCK_NO_COMPOSITE(photo, &block, destx, desty,
- destwidth, destheight);
- delete[] destbuffer;
-
- } else {
- block.width = wdata;
- block.height = hdata;
- block.pitch = (int)block.width * nval;
- block.pixelPtr = buffer;
-
- /* Clear current contents */
- TK_PHOTO_BLANK(photo);
- /* Copy opaque block to photo image, and leave the rest to TK */
- TK_PHOTO_PUT_BLOCK_NO_COMPOSITE(photo, &block, 0, 0, block.width,
- block.height);
- }
-
- return TCL_OK;
-}
-
-static PyObject *_tkinit(PyObject *self, PyObject *args)
-{
- Tcl_Interp *interp;
- TkappObject *app;
-
- PyObject *arg;
- int is_interp;
- if (!PyArg_ParseTuple(args, "Oi", &arg, &is_interp)) {
- return NULL;
- }
-
- if (is_interp) {
- interp = (Tcl_Interp *)PyLong_AsVoidPtr(arg);
- } else {
- /* Do it the hard way. This will break if the TkappObject
- layout changes */
- app = (TkappObject *)arg;
- interp = app->interp;
- }
-
- /* This will bomb if interp is invalid... */
-
- TCL_CREATE_COMMAND(interp,
- "PyAggImagePhoto",
- (Tcl_CmdProc *)PyAggImagePhoto,
- (ClientData)0,
- (Tcl_CmdDeleteProc *)NULL);
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-static PyMethodDef functions[] = {
- /* Tkinter interface stuff */
- { "tkinit", (PyCFunction)_tkinit, 1 },
- { NULL, NULL } /* sentinel */
-};
-
-// Functions to fill global TCL / Tk function pointers by dynamic loading
-#if defined(_WIN32) || defined(__WIN32__) || defined(WIN32)
-
-/*
- * On Windows, we can't load the tkinter module to get the TCL or Tk symbols,
- * because Windows does not load symbols into the library name-space of
- * importing modules. So, knowing that tkinter has already been imported by
- * Python, we scan all modules in the running process for the TCL and Tk
- * function names.
- */
-#include <windows.h>
-#define PSAPI_VERSION 1
-#include <psapi.h>
-// Must be linked with 'psapi' library
-
-FARPROC _dfunc(HMODULE lib_handle, const char *func_name)
-{
- // Load function `func_name` from `lib_handle`.
- // Set Python exception if we can't find `func_name` in `lib_handle`.
- // Returns function pointer or NULL if not present.
-
- char message[100];
-
- FARPROC func = GetProcAddress(lib_handle, func_name);
- if (func == NULL) {
- sprintf(message, "Cannot load function %s", func_name);
- PyErr_SetString(PyExc_RuntimeError, message);
- }
- return func;
-}
-
-int get_tcl(HMODULE hMod)
-{
- // Try to fill TCL global vars with function pointers. Return 0 for no
- // functions found, 1 for all functions found, -1 for some but not all
- // functions found.
- TCL_CREATE_COMMAND = (Tcl_CreateCommand_t)
- GetProcAddress(hMod, "Tcl_CreateCommand");
- if (TCL_CREATE_COMMAND == NULL) { // Maybe not TCL module
- return 0;
- }
- TCL_APPEND_RESULT = (Tcl_AppendResult_t) _dfunc(hMod,
- "Tcl_AppendResult");
- return (TCL_APPEND_RESULT == NULL) ? -1 : 1;
-}
-
-int get_tk(HMODULE hMod)
-{
- // Try to fill Tk global vars with function pointers. Return 0 for no
- // functions found, 1 for all functions found, -1 for some but not all
- // functions found.
- TK_MAIN_WINDOW = (Tk_MainWindow_t)
- GetProcAddress(hMod, "Tk_MainWindow");
- if (TK_MAIN_WINDOW == NULL) { // Maybe not Tk module
- return 0;
- }
- return ( // -1 if any remaining symbols are NULL
- ((TK_FIND_PHOTO = (Tk_FindPhoto_t)
- _dfunc(hMod, "Tk_FindPhoto")) == NULL) ||
- ((TK_PHOTO_PUT_BLOCK_NO_COMPOSITE = (Tk_PhotoPutBlock_NoComposite_t)
- _dfunc(hMod, "Tk_PhotoPutBlock_NoComposite")) == NULL) ||
- ((TK_PHOTO_BLANK = (Tk_PhotoBlank_t)
- _dfunc(hMod, "Tk_PhotoBlank")) == NULL))
- ? -1 : 1;
-}
-
-int load_tkinter_funcs(void)
-{
- // Load TCL and Tk functions by searching all modules in current process.
- // Return 0 for success, non-zero for failure.
-
- HMODULE hMods[1024];
- HANDLE hProcess;
- DWORD cbNeeded;
- unsigned int i;
- int found_tcl = 0;
- int found_tk = 0;
-
- // Returns pseudo-handle that does not need to be closed
- hProcess = GetCurrentProcess();
-
- // Iterate through modules in this process looking for TCL / Tk names
- if (EnumProcessModules(hProcess, hMods, sizeof(hMods), &cbNeeded)) {
- for (i = 0; i < (cbNeeded / sizeof(HMODULE)); i++) {
- if (!found_tcl) {
- found_tcl = get_tcl(hMods[i]);
- if (found_tcl == -1) {
- return 1;
- }
- }
- if (!found_tk) {
- found_tk = get_tk(hMods[i]);
- if (found_tk == -1) {
- return 1;
- }
- }
- if (found_tcl && found_tk) {
- return 0;
- }
- }
- }
-
- if (found_tcl == 0) {
- PyErr_SetString(PyExc_RuntimeError, "Could not find TCL routines");
- } else {
- PyErr_SetString(PyExc_RuntimeError, "Could not find Tk routines");
- }
- return 1;
-}
-
-#else // not Windows
-
-/*
- * On Unix, we can get the TCL and Tk synbols from the tkinter module, because
- * tkinter uses these symbols, and the symbols are therefore visible in the
- * tkinter dynamic library (module).
- */
-#if PY_MAJOR_VERSION >= 3
-#define TKINTER_PKG "tkinter"
-#define TKINTER_MOD "_tkinter"
-// From module __file__ attribute to char *string for dlopen.
-char *fname2char(PyObject *fname)
-{
- PyObject* bytes;
- bytes = PyUnicode_EncodeFSDefault(fname);
- if (bytes == NULL) {
- return NULL;
- }
- return PyBytes_AsString(bytes);
-}
-#else
-#define TKINTER_PKG "Tkinter"
-#define TKINTER_MOD "tkinter"
-// From module __file__ attribute to char *string for dlopen
-#define fname2char(s) (PyString_AsString(s))
-#endif
-
-#include <dlfcn.h>
-
-void *_dfunc(void *lib_handle, const char *func_name)
-{
- // Load function `func_name` from `lib_handle`.
- // Set Python exception if we can't find `func_name` in `lib_handle`.
- // Returns function pointer or NULL if not present.
-
- void* func;
- // Reset errors.
- dlerror();
- func = dlsym(lib_handle, func_name);
- if (func == NULL) {
- const char *error = dlerror();
- PyErr_SetString(PyExc_RuntimeError, error);
- }
- return func;
-}
-
-int _func_loader(void *lib)
-{
- // Fill global function pointers from dynamic lib.
- // Return 1 if any pointer is NULL, 0 otherwise.
- return (
- ((TCL_CREATE_COMMAND = (Tcl_CreateCommand_t)
- _dfunc(lib, "Tcl_CreateCommand")) == NULL) ||
- ((TCL_APPEND_RESULT = (Tcl_AppendResult_t)
- _dfunc(lib, "Tcl_AppendResult")) == NULL) ||
- ((TK_MAIN_WINDOW = (Tk_MainWindow_t)
- _dfunc(lib, "Tk_MainWindow")) == NULL) ||
- ((TK_FIND_PHOTO = (Tk_FindPhoto_t)
- _dfunc(lib, "Tk_FindPhoto")) == NULL) ||
- ((TK_PHOTO_PUT_BLOCK_NO_COMPOSITE = (Tk_PhotoPutBlock_NoComposite_t)
- _dfunc(lib, "Tk_PhotoPutBlock_NoComposite")) == NULL) ||
- ((TK_PHOTO_BLANK = (Tk_PhotoBlank_t)
- _dfunc(lib, "Tk_PhotoBlank")) == NULL));
-}
-
-int load_tkinter_funcs(void)
-{
- // Load tkinter global funcs from tkinter compiled module.
- // Return 0 for success, non-zero for failure.
- int ret = -1;
- void *main_program, *tkinter_lib;
- char *tkinter_libname;
- PyObject *pModule = NULL, *pSubmodule = NULL, *pString = NULL;
-
- // Try loading from the main program namespace first
- main_program = dlopen(NULL, RTLD_LAZY);
- if (_func_loader(main_program) == 0) {
- return 0;
- }
- // Clear exception triggered when we didn't find symbols above.
- PyErr_Clear();
-
- // Now try finding the tkinter compiled module
- pModule = PyImport_ImportModule(TKINTER_PKG);
- if (pModule == NULL) {
- goto exit;
- }
- pSubmodule = PyObject_GetAttrString(pModule, TKINTER_MOD);
- if (pSubmodule == NULL) {
- goto exit;
- }
- pString = PyObject_GetAttrString(pSubmodule, "__file__");
- if (pString == NULL) {
- goto exit;
- }
- tkinter_libname = fname2char(pString);
- if (tkinter_libname == NULL) {
- goto exit;
- }
- tkinter_lib = dlopen(tkinter_libname, RTLD_LAZY);
- if (tkinter_lib == NULL) {
- /* Perhaps it is a cffi module, like in PyPy? */
- pString = PyObject_GetAttrString(pSubmodule, "tklib_cffi");
- if (pString == NULL) {
- goto fail;
- }
- pString = PyObject_GetAttrString(pString, "__file__");
- if (pString == NULL) {
- goto fail;
- }
- tkinter_libname = fname2char(pString);
- if (tkinter_libname == NULL) {
- goto fail;
- }
- tkinter_lib = dlopen(tkinter_libname, RTLD_LAZY);
- }
- if (tkinter_lib == NULL) {
- goto fail;
- }
- ret = _func_loader(tkinter_lib);
- // dlclose probably safe because tkinter has been imported.
- dlclose(tkinter_lib);
- goto exit;
-fail:
- PyErr_SetString(PyExc_RuntimeError,
- "Cannot dlopen tkinter module file");
-exit:
- Py_XDECREF(pModule);
- Py_XDECREF(pSubmodule);
- Py_XDECREF(pString);
- return ret;
-}
-#endif // end not Windows
-
-#if PY_MAJOR_VERSION >= 3
-static PyModuleDef _tkagg_module = { PyModuleDef_HEAD_INIT, "_tkagg", "", -1, functions,
- NULL, NULL, NULL, NULL };
-
-PyMODINIT_FUNC PyInit__tkagg(void)
-{
- PyObject *m;
-
- m = PyModule_Create(&_tkagg_module);
-
- return (load_tkinter_funcs() == 0) ? m : NULL;
-}
-#else
-PyMODINIT_FUNC init_tkagg(void)
-{
- Py_InitModule("_tkagg", functions);
-
- load_tkinter_funcs();
-}
-#endif
diff --git a/contrib/python/matplotlib/py2/src/_tkmini.h b/contrib/python/matplotlib/py2/src/_tkmini.h
deleted file mode 100644
index 9b730b6c8c..0000000000
--- a/contrib/python/matplotlib/py2/src/_tkmini.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/* Small excerpts from the Tcl / Tk 8.6 headers
- *
- * License terms copied from:
- * http://www.tcl.tk/software/tcltk/license.html
- * as of 20 May 2016.
- *
- * Copyright (c) 1987-1994 The Regents of the University of California.
- * Copyright (c) 1993-1996 Lucent Technologies.
- * Copyright (c) 1994-1998 Sun Microsystems, Inc.
- * Copyright (c) 1998-2000 by Scriptics Corporation.
- * Copyright (c) 2002 by Kevin B. Kenny. All rights reserved.
- *
- * This software is copyrighted by the Regents of the University
- * of California, Sun Microsystems, Inc., Scriptics Corporation,
- * and other parties. The following terms apply to all files
- * associated with the software unless explicitly disclaimed in
- * individual files.
- *
- * The authors hereby grant permission to use, copy, modify,
- * distribute, and license this software and its documentation
- * for any purpose, provided that existing copyright notices are
- * retained in all copies and that this notice is included
- * verbatim in any distributions. No written agreement, license,
- * or royalty fee is required for any of the authorized uses.
- * Modifications to this software may be copyrighted by their
- * authors and need not follow the licensing terms described
- * here, provided that the new terms are clearly indicated on
- * the first page of each file where they apply.
- *
- * IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO
- * ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR
- * CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS
- * SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, EVEN
- * IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON
- * AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO
- * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
- * ENHANCEMENTS, OR MODIFICATIONS.
- *
- * GOVERNMENT USE: If you are acquiring this software on behalf
- * of the U.S. government, the Government shall have only
- * "Restricted Rights" in the software and related documentation
- * as defined in the Federal Acquisition Regulations (FARs) in
- * Clause 52.227.19 (c) (2). If you are acquiring the software
- * on behalf of the Department of Defense, the software shall be
- * classified as "Commercial Computer Software" and the
- * Government shall have only "Restricted Rights" as defined in
- * Clause 252.227-7013 (c) (1) of DFARs. Notwithstanding the
- * foregoing, the authors grant the U.S. Government and others
- * acting in its behalf permission to use and distribute the
- * software in accordance with the terms specified in this
- * license
- */
-
-/*
- * Unless otherwise noted, these definitions are stable from Tcl / Tk 8.5
- * through Tck / Tk master as of 21 May 2016
- */
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Tcl header excerpts */
-#define TCL_OK 0
-#define TCL_ERROR 1
-
-/*
- * Users of versions of Tcl >= 8.6 encouraged to tread Tcl_Interp as an opaque
- * pointer. The following definition results when TCL_NO_DEPRECATED defined.
- */
-typedef struct Tcl_Interp Tcl_Interp;
-
-typedef struct Tcl_Command_ *Tcl_Command;
-typedef void *ClientData;
-
-typedef int (Tcl_CmdProc) (ClientData clientData, Tcl_Interp
- *interp, int argc, const char *argv[]);
-typedef void (Tcl_CmdDeleteProc) (ClientData clientData);
-
-/* Typedefs derived from function signatures in Tcl header */
-/* Tcl_CreateCommand */
-typedef Tcl_Command (*Tcl_CreateCommand_t)(Tcl_Interp *interp,
- const char *cmdName, Tcl_CmdProc *proc,
- ClientData clientData,
- Tcl_CmdDeleteProc *deleteProc);
-/* Tcl_AppendResult */
-typedef void (*Tcl_AppendResult_t) (Tcl_Interp *interp, ...);
-
-/* Tk header excerpts */
-typedef struct Tk_Window_ *Tk_Window;
-
-typedef void *Tk_PhotoHandle;
-
-typedef struct Tk_PhotoImageBlock
-{
- unsigned char *pixelPtr;
- int width;
- int height;
- int pitch;
- int pixelSize;
- int offset[4];
-} Tk_PhotoImageBlock;
-
-/* Typedefs derived from function signatures in Tk header */
-/* Tk_MainWindow */
-typedef Tk_Window (*Tk_MainWindow_t) (Tcl_Interp *interp);
-typedef Tk_PhotoHandle (*Tk_FindPhoto_t) (Tcl_Interp *interp, const char
- *imageName);
-/* Tk_PhotoPutBLock_NoComposite typedef */
-typedef void (*Tk_PhotoPutBlock_NoComposite_t) (Tk_PhotoHandle handle,
- Tk_PhotoImageBlock *blockPtr, int x, int y,
- int width, int height);
-/* Tk_PhotoBlank */
-typedef void (*Tk_PhotoBlank_t) (Tk_PhotoHandle handle);
-
-/*
- * end block for C++
- */
-
-#ifdef __cplusplus
-}
-#endif
diff --git a/contrib/python/matplotlib/py2/src/_ttconv.cpp b/contrib/python/matplotlib/py2/src/_ttconv.cpp
deleted file mode 100644
index e18c8a53ca..0000000000
--- a/contrib/python/matplotlib/py2/src/_ttconv.cpp
+++ /dev/null
@@ -1,307 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-/*
- _ttconv.c
-
- Python wrapper for TrueType conversion library in ../ttconv.
- */
-#define PY_SSIZE_T_CLEAN
-#include "mplutils.h"
-
-#include <Python.h>
-#include "ttconv/pprdrv.h"
-#include "py_exceptions.h"
-#include <vector>
-#include <cassert>
-
-/**
- * An implementation of TTStreamWriter that writes to a Python
- * file-like object.
- */
-class PythonFileWriter : public TTStreamWriter
-{
- PyObject *_write_method;
-
- public:
- PythonFileWriter()
- {
- _write_method = NULL;
- }
-
- ~PythonFileWriter()
- {
- Py_XDECREF(_write_method);
- }
-
- void set(PyObject *write_method)
- {
- Py_XDECREF(_write_method);
- _write_method = write_method;
- Py_XINCREF(_write_method);
- }
-
- virtual void write(const char *a)
- {
- PyObject *result = NULL;
- if (_write_method) {
- PyObject *decoded = NULL;
- decoded = PyUnicode_DecodeLatin1(a, strlen(a), "");
- if (decoded == NULL) {
- throw py::exception();
- }
- result = PyObject_CallFunction(_write_method, (char *)"O", decoded);
- Py_DECREF(decoded);
- if (!result) {
- throw py::exception();
- }
- Py_DECREF(result);
- }
- }
-};
-
-int fileobject_to_PythonFileWriter(PyObject *object, void *address)
-{
- PythonFileWriter *file_writer = (PythonFileWriter *)address;
-
- PyObject *write_method = PyObject_GetAttrString(object, "write");
- if (write_method == NULL || !PyCallable_Check(write_method)) {
- PyErr_SetString(PyExc_TypeError, "Expected a file-like object with a write method.");
- return 0;
- }
-
- file_writer->set(write_method);
- Py_DECREF(write_method);
-
- return 1;
-}
-
-int pyiterable_to_vector_int(PyObject *object, void *address)
-{
- std::vector<int> *result = (std::vector<int> *)address;
-
- PyObject *iterator = PyObject_GetIter(object);
- if (!iterator) {
- return 0;
- }
-
- PyObject *item;
- while ((item = PyIter_Next(iterator))) {
-#if PY3K
- long value = PyLong_AsLong(item);
-#else
- long value = PyInt_AsLong(item);
-#endif
- Py_DECREF(item);
- if (value == -1 && PyErr_Occurred()) {
- return 0;
- }
- result->push_back((int)value);
- }
-
- Py_DECREF(iterator);
-
- return 1;
-}
-
-static PyObject *convert_ttf_to_ps(PyObject *self, PyObject *args, PyObject *kwds)
-{
- const char *filename;
- PythonFileWriter output;
- int fonttype;
- std::vector<int> glyph_ids;
-
- static const char *kwlist[] = { "filename", "output", "fonttype", "glyph_ids", NULL };
- if (!PyArg_ParseTupleAndKeywords(args,
- kwds,
-#if PY_MAJOR_VERSION == 3
- "yO&i|O&:convert_ttf_to_ps",
-#else
- "sO&i|O&:convert_ttf_to_ps",
-#endif
- (char **)kwlist,
- &filename,
- fileobject_to_PythonFileWriter,
- &output,
- &fonttype,
- pyiterable_to_vector_int,
- &glyph_ids)) {
- return NULL;
- }
-
- if (fonttype != 3 && fonttype != 42) {
- PyErr_SetString(PyExc_ValueError,
- "fonttype must be either 3 (raw Postscript) or 42 "
- "(embedded Truetype)");
- return NULL;
- }
-
- try
- {
- insert_ttfont(filename, output, (font_type_enum)fonttype, glyph_ids);
- }
- catch (TTException &e)
- {
- PyErr_SetString(PyExc_RuntimeError, e.getMessage());
- return NULL;
- }
- catch (const py::exception &)
- {
- return NULL;
- }
- catch (...)
- {
- PyErr_SetString(PyExc_RuntimeError, "Unknown C++ exception");
- return NULL;
- }
-
- Py_INCREF(Py_None);
- return Py_None;
-}
-
-class PythonDictionaryCallback : public TTDictionaryCallback
-{
- PyObject *_dict;
-
- public:
- PythonDictionaryCallback(PyObject *dict)
- {
- _dict = dict;
- }
-
- virtual void add_pair(const char *a, const char *b)
- {
- assert(a != NULL);
- assert(b != NULL);
- PyObject *value = PyBytes_FromString(b);
- if (!value) {
- throw py::exception();
- }
- if (PyDict_SetItemString(_dict, a, value)) {
- Py_DECREF(value);
- throw py::exception();
- }
- Py_DECREF(value);
- }
-};
-
-static PyObject *py_get_pdf_charprocs(PyObject *self, PyObject *args, PyObject *kwds)
-{
- const char *filename;
- std::vector<int> glyph_ids;
- PyObject *result;
-
- static const char *kwlist[] = { "filename", "glyph_ids", NULL };
- if (!PyArg_ParseTupleAndKeywords(args,
- kwds,
-#if PY_MAJOR_VERSION == 3
- "y|O&:get_pdf_charprocs",
-#else
- "s|O&:get_pdf_charprocs",
-#endif
- (char **)kwlist,
- &filename,
- pyiterable_to_vector_int,
- &glyph_ids)) {
- return NULL;
- }
-
- result = PyDict_New();
- if (!result) {
- return NULL;
- }
-
- PythonDictionaryCallback dict(result);
-
- try
- {
- ::get_pdf_charprocs(filename, glyph_ids, dict);
- }
- catch (TTException &e)
- {
- Py_DECREF(result);
- PyErr_SetString(PyExc_RuntimeError, e.getMessage());
- return NULL;
- }
- catch (const py::exception &)
- {
- Py_DECREF(result);
- return NULL;
- }
- catch (...)
- {
- Py_DECREF(result);
- PyErr_SetString(PyExc_RuntimeError, "Unknown C++ exception");
- return NULL;
- }
-
- return result;
-}
-
-static PyMethodDef ttconv_methods[] =
-{
- {
- "convert_ttf_to_ps", (PyCFunction)convert_ttf_to_ps, METH_VARARGS | METH_KEYWORDS,
- "convert_ttf_to_ps(filename, output, fonttype, glyph_ids)\n"
- "\n"
- "Converts the Truetype font into a Type 3 or Type 42 Postscript font, "
- "optionally subsetting the font to only the desired set of characters.\n"
- "\n"
- "filename is the path to a TTF font file.\n"
- "output is a Python file-like object with a write method that the Postscript "
- "font data will be written to.\n"
- "fonttype may be either 3 or 42. Type 3 is a \"raw Postscript\" font. "
- "Type 42 is an embedded Truetype font. Glyph subsetting is not supported "
- "for Type 42 fonts.\n"
- "glyph_ids (optional) is a list of glyph ids (integers) to keep when "
- "subsetting to a Type 3 font. If glyph_ids is not provided or is None, "
- "then all glyphs will be included. If any of the glyphs specified are "
- "composite glyphs, then the component glyphs will also be included."
- },
- {
- "get_pdf_charprocs", (PyCFunction)py_get_pdf_charprocs, METH_VARARGS | METH_KEYWORDS,
- "get_pdf_charprocs(filename, glyph_ids)\n"
- "\n"
- "Given a Truetype font file, returns a dictionary containing the PDF Type 3\n"
- "representation of its paths. Useful for subsetting a Truetype font inside\n"
- "of a PDF file.\n"
- "\n"
- "filename is the path to a TTF font file.\n"
- "glyph_ids is a list of the numeric glyph ids to include.\n"
- "The return value is a dictionary where the keys are glyph names and\n"
- "the values are the stream content needed to render that glyph. This\n"
- "is useful to generate the CharProcs dictionary in a PDF Type 3 font.\n"
- },
- {0, 0, 0, 0} /* Sentinel */
-};
-
-static const char *module_docstring =
- "Module to handle converting and subsetting TrueType "
- "fonts to Postscript Type 3, Postscript Type 42 and "
- "Pdf Type 3 fonts.";
-
-#if PY3K
-static PyModuleDef ttconv_module = {
- PyModuleDef_HEAD_INIT,
- "ttconv",
- module_docstring,
- -1,
- ttconv_methods,
- NULL, NULL, NULL, NULL
-};
-
-PyMODINIT_FUNC
-PyInit_ttconv(void)
-{
- PyObject* m;
-
- m = PyModule_Create(&ttconv_module);
-
- return m;
-}
-#else
-PyMODINIT_FUNC
-initttconv(void)
-{
- Py_InitModule3("ttconv", ttconv_methods, module_docstring);
-}
-#endif
diff --git a/contrib/python/matplotlib/py2/src/_windowing.cpp b/contrib/python/matplotlib/py2/src/_windowing.cpp
deleted file mode 100644
index 7a20baa0a3..0000000000
--- a/contrib/python/matplotlib/py2/src/_windowing.cpp
+++ /dev/null
@@ -1,64 +0,0 @@
-#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/agg_workaround.h b/contrib/python/matplotlib/py2/src/agg_workaround.h
deleted file mode 100644
index bfadf39284..0000000000
--- a/contrib/python/matplotlib/py2/src/agg_workaround.h
+++ /dev/null
@@ -1,85 +0,0 @@
-#ifndef __AGG_WORKAROUND_H__
-#define __AGG_WORKAROUND_H__
-
-#include "agg_pixfmt_rgba.h"
-
-/**********************************************************************
- WORKAROUND: This class is to workaround a bug in Agg SVN where the
- blending of RGBA32 pixels does not preserve enough precision
-*/
-
-template<class ColorT, class Order>
-struct fixed_blender_rgba_pre : agg::conv_rgba_pre<ColorT, Order>
-{
- typedef ColorT color_type;
- typedef Order order_type;
- typedef typename color_type::value_type value_type;
- typedef typename color_type::calc_type calc_type;
- typedef typename color_type::long_type long_type;
- enum base_scale_e
- {
- base_shift = color_type::base_shift,
- base_mask = color_type::base_mask
- };
-
- //--------------------------------------------------------------------
- static AGG_INLINE void blend_pix(value_type* p,
- value_type cr, value_type cg, value_type cb,
- value_type alpha, agg::cover_type cover)
- {
- blend_pix(p,
- color_type::mult_cover(cr, cover),
- color_type::mult_cover(cg, cover),
- color_type::mult_cover(cb, cover),
- color_type::mult_cover(alpha, cover));
- }
-
- //--------------------------------------------------------------------
- static AGG_INLINE void blend_pix(value_type* p,
- value_type cr, value_type cg, value_type cb,
- value_type alpha)
- {
- alpha = base_mask - alpha;
- p[Order::R] = (value_type)(((p[Order::R] * alpha) >> base_shift) + cr);
- p[Order::G] = (value_type)(((p[Order::G] * alpha) >> base_shift) + cg);
- p[Order::B] = (value_type)(((p[Order::B] * alpha) >> base_shift) + cb);
- p[Order::A] = (value_type)(base_mask - ((alpha * (base_mask - p[Order::A])) >> base_shift));
- }
-};
-
-
-template<class ColorT, class Order>
-struct fixed_blender_rgba_plain : agg::conv_rgba_plain<ColorT, Order>
-{
- typedef ColorT color_type;
- typedef Order order_type;
- typedef typename color_type::value_type value_type;
- typedef typename color_type::calc_type calc_type;
- typedef typename color_type::long_type long_type;
- enum base_scale_e { base_shift = color_type::base_shift };
-
- //--------------------------------------------------------------------
- static AGG_INLINE void blend_pix(value_type* p,
- value_type cr, value_type cg, value_type cb, value_type alpha, agg::cover_type cover)
- {
- blend_pix(p, cr, cg, cb, color_type::mult_cover(alpha, cover));
- }
-
- //--------------------------------------------------------------------
- static AGG_INLINE void blend_pix(value_type* p,
- value_type cr, value_type cg, value_type cb, value_type alpha)
- {
- if(alpha == 0) return;
- calc_type a = p[Order::A];
- calc_type r = p[Order::R] * a;
- calc_type g = p[Order::G] * a;
- calc_type b = p[Order::B] * a;
- a = ((alpha + a) << base_shift) - alpha * a;
- p[Order::A] = (value_type)(a >> base_shift);
- p[Order::R] = (value_type)((((cr << base_shift) - r) * alpha + (r << base_shift)) / a);
- p[Order::G] = (value_type)((((cg << base_shift) - g) * alpha + (g << base_shift)) / a);
- p[Order::B] = (value_type)((((cb << base_shift) - b) * alpha + (b << base_shift)) / a);
- }
-};
-
-#endif
diff --git a/contrib/python/matplotlib/py2/src/array.h b/contrib/python/matplotlib/py2/src/array.h
deleted file mode 100644
index 8056366a1c..0000000000
--- a/contrib/python/matplotlib/py2/src/array.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-/* Utilities to create scalars and empty arrays that behave like the
- Numpy array wrappers in numpy_cpp.h */
-
-#ifndef _SCALAR_H_
-#define _SCALAR_H_
-
-namespace array
-{
-
-template <typename T, int ND>
-class scalar
-{
- public:
- T m_value;
-
- scalar(const T value) : m_value(value)
- {
- }
-
- T &operator()(int i, int j = 0, int k = 0)
- {
- return m_value;
- }
-
- const T &operator()(int i, int j = 0, int k = 0) const
- {
- return m_value;
- }
-
- int dim(size_t i)
- {
- return 1;
- }
-
- size_t size()
- {
- return 1;
- }
-};
-
-template <typename T>
-class empty
-{
- public:
- typedef empty<T> sub_t;
-
- empty()
- {
- }
-
- T &operator()(int i, int j = 0, int k = 0)
- {
- throw std::runtime_error("Accessed empty array");
- }
-
- const T &operator()(int i, int j = 0, int k = 0) const
- {
- throw std::runtime_error("Accessed empty array");
- }
-
- sub_t operator[](int i) const
- {
- return empty<T>();
- }
-
- int dim(size_t i) const
- {
- return 0;
- }
-
- size_t size() const
- {
- return 0;
- }
-};
-}
-
-#endif
diff --git a/contrib/python/matplotlib/py2/src/file_compat.h b/contrib/python/matplotlib/py2/src/file_compat.h
deleted file mode 100644
index 114279fb1a..0000000000
--- a/contrib/python/matplotlib/py2/src/file_compat.h
+++ /dev/null
@@ -1,240 +0,0 @@
-#ifndef __FILE_COMPAT_H__
-#define __FILE_COMPAT_H__
-#define PY_SSIZE_T_CLEAN
-#include <Python.h>
-#include <stdio.h>
-#include "numpy/npy_common.h"
-#include "numpy/ndarrayobject.h"
-#include "mplutils.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-#if defined(_MSC_VER) && defined(_WIN64) && (_MSC_VER > 1400)
- #include <io.h>
- #define mpl_fseek _fseeki64
- #define mpl_ftell _ftelli64
- #define mpl_lseek _lseeki64
- #define mpl_off_t npy_int64
-
- #if NPY_SIZEOF_INT == 8
- #define MPL_OFF_T_PYFMT "i"
- #elif NPY_SIZEOF_LONG == 8
- #define MPL_OFF_T_PYFMT "l"
- #elif NPY_SIZEOF_LONGLONG == 8
- #define MPL_OFF_T_PYFMT "L"
- #else
- #error Unsupported size for type off_t
- #endif
-#else
- #define mpl_fseek fseek
- #define mpl_ftell ftell
- #define mpl_lseek lseek
- #define mpl_off_t off_t
-
- #if NPY_SIZEOF_INT == NPY_SIZEOF_SHORT
- #define MPL_OFF_T_PYFMT "h"
- #elif NPY_SIZEOF_INT == NPY_SIZEOF_INT
- #define MPL_OFF_T_PYFMT "i"
- #elif NPY_SIZEOF_INT == NPY_SIZEOF_LONG
- #define MPL_OFF_T_PYFMT "l"
- #elif NPY_SIZEOF_INT == NPY_SIZEOF_LONGLONG
- #define MPL_OFF_T_PYFMT "L"
- #else
- #error Unsupported size for type off_t
- #endif
-#endif
-
-/*
- * PyFile_* compatibility
- */
-#if PY3K | defined(PYPY_VERSION)
-
-/*
- * Get a FILE* handle to the file represented by the Python object
- */
-static NPY_INLINE FILE *mpl_PyFile_Dup(PyObject *file, char *mode, mpl_off_t *orig_pos)
-{
- int fd, fd2;
- PyObject *ret, *os;
- mpl_off_t pos;
- FILE *handle;
-
- if (mode[0] != 'r') {
- /* Flush first to ensure things end up in the file in the correct order */
- ret = PyObject_CallMethod(file, (char *)"flush", (char *)"");
- if (ret == NULL) {
- return NULL;
- }
- Py_DECREF(ret);
- }
-
- fd = PyObject_AsFileDescriptor(file);
- if (fd == -1) {
- return NULL;
- }
-
- /* The handle needs to be dup'd because we have to call fclose
- at the end */
- os = PyImport_ImportModule("os");
- if (os == NULL) {
- return NULL;
- }
- ret = PyObject_CallMethod(os, (char *)"dup", (char *)"i", fd);
- Py_DECREF(os);
- if (ret == NULL) {
- return NULL;
- }
- fd2 = PyNumber_AsSsize_t(ret, NULL);
- Py_DECREF(ret);
-
-/* Convert to FILE* handle */
-#ifdef _WIN32
- handle = _fdopen(fd2, mode);
-#else
- handle = fdopen(fd2, mode);
-#endif
- if (handle == NULL) {
- PyErr_SetString(PyExc_IOError, "Getting a FILE* from a Python file object failed");
- }
-
- /* Record the original raw file handle position */
- *orig_pos = mpl_ftell(handle);
- if (*orig_pos == -1) {
- // handle is a stream, so we don't have to worry about this
- return handle;
- }
-
- /* Seek raw handle to the Python-side position */
- ret = PyObject_CallMethod(file, (char *)"tell", (char *)"");
- if (ret == NULL) {
- fclose(handle);
- return NULL;
- }
- pos = PyNumber_AsSsize_t(ret, PyExc_OverflowError);
- Py_DECREF(ret);
- if (PyErr_Occurred()) {
- fclose(handle);
- return NULL;
- }
- if (mpl_fseek(handle, pos, SEEK_SET) == -1) {
- PyErr_SetString(PyExc_IOError, "seeking file failed");
- return NULL;
- }
- return handle;
-}
-
-/*
- * Close the dup-ed file handle, and seek the Python one to the current position
- */
-static NPY_INLINE int mpl_PyFile_DupClose(PyObject *file, FILE *handle, mpl_off_t orig_pos)
-{
- PyObject *exc_type = NULL, *exc_value = NULL, *exc_tb = NULL;
- PyErr_Fetch(&exc_type, &exc_value, &exc_tb);
-
- int fd;
- PyObject *ret;
- mpl_off_t position;
-
- position = mpl_ftell(handle);
-
- /* Close the FILE* handle */
- fclose(handle);
-
- /* Restore original file handle position, in order to not confuse
- Python-side data structures. Note that this would fail if an exception
- is currently set, which can happen as this function is called in cleanup
- code, so we need to carefully fetch and restore the exception state. */
- fd = PyObject_AsFileDescriptor(file);
- if (fd == -1) {
- goto fail;
- }
- if (mpl_lseek(fd, orig_pos, SEEK_SET) != -1) {
- if (position == -1) {
- PyErr_SetString(PyExc_IOError, "obtaining file position failed");
- goto fail;
- }
-
- /* Seek Python-side handle to the FILE* handle position */
- ret = PyObject_CallMethod(file, (char *)"seek", (char *)(MPL_OFF_T_PYFMT "i"), position, 0);
- if (ret == NULL) {
- goto fail;
- }
- Py_DECREF(ret);
- }
- PyErr_Restore(exc_type, exc_value, exc_tb);
- return 0;
-fail:
- Py_XDECREF(exc_type);
- Py_XDECREF(exc_value);
- Py_XDECREF(exc_tb);
- return -1;
-}
-
-static NPY_INLINE int mpl_PyFile_Check(PyObject *file)
-{
- int fd;
- fd = PyObject_AsFileDescriptor(file);
- if (fd == -1) {
- PyErr_Clear();
- return 0;
- }
- return 1;
-}
-
-#else
-
-static NPY_INLINE FILE *mpl_PyFile_Dup(PyObject *file, const char *mode, mpl_off_t *orig_pos)
-{
- return PyFile_AsFile(file);
-}
-
-static NPY_INLINE int mpl_PyFile_DupClose(PyObject *file, FILE *handle, mpl_off_t orig_pos)
-{
- // deliberately nothing
- return 0;
-}
-
-static NPY_INLINE int mpl_PyFile_Check(PyObject *file)
-{
- return PyFile_Check(file);
-}
-
-#endif
-
-static NPY_INLINE PyObject *mpl_PyFile_OpenFile(PyObject *filename, const char *mode)
-{
- PyObject *open;
- open = PyDict_GetItemString(PyEval_GetBuiltins(), "open");
- if (open == NULL) {
- return NULL;
- }
- return PyObject_CallFunction(open, (char *)"Os", filename, mode);
-}
-
-static NPY_INLINE int mpl_PyFile_CloseFile(PyObject *file)
-{
- PyObject *type, *value, *tb;
- PyErr_Fetch(&type, &value, &tb);
-
- PyObject *ret;
-
- ret = PyObject_CallMethod(file, (char *)"close", NULL);
- if (ret == NULL) {
- goto fail;
- }
- Py_DECREF(ret);
- PyErr_Restore(type, value, tb);
- return 0;
-fail:
- Py_XDECREF(type);
- Py_XDECREF(value);
- Py_XDECREF(tb);
- return -1;
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* ifndef __FILE_COMPAT_H__ */
diff --git a/contrib/python/matplotlib/py2/src/ft2font.cpp b/contrib/python/matplotlib/py2/src/ft2font.cpp
deleted file mode 100644
index 7245ca332a..0000000000
--- a/contrib/python/matplotlib/py2/src/ft2font.cpp
+++ /dev/null
@@ -1,808 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-#define NO_IMPORT_ARRAY
-
-#include <algorithm>
-#include <stdexcept>
-#include <string>
-
-#include "ft2font.h"
-#include "mplutils.h"
-
-#ifndef M_PI
-#define M_PI 3.14159265358979323846264338328
-#endif
-
-/**
- To improve the hinting of the fonts, this code uses a hack
- presented here:
-
- http://antigrain.com/research/font_rasterization/index.html
-
- The idea is to limit the effect of hinting in the x-direction, while
- preserving hinting in the y-direction. Since freetype does not
- support this directly, the dpi in the x-direction is set higher than
- in the y-direction, which affects the hinting grid. Then, a global
- transform is placed on the font to shrink it back to the desired
- size. While it is a bit surprising that the dpi setting affects
- hinting, whereas the global transform does not, this is documented
- behavior of FreeType, and therefore hopefully unlikely to change.
- The FreeType 2 tutorial says:
-
- NOTE: The transformation is applied to every glyph that is
- loaded through FT_Load_Glyph and is completely independent of
- any hinting process. This means that you won't get the same
- results if you load a glyph at the size of 24 pixels, or a glyph
- at the size at 12 pixels scaled by 2 through a transform,
- because the hints will have been computed differently (except
- you have disabled hints).
- */
-
-FT_Library _ft2Library;
-
-FT2Image::FT2Image() : m_dirty(true), m_buffer(NULL), m_width(0), m_height(0)
-{
-}
-
-FT2Image::FT2Image(unsigned long width, unsigned long height)
- : m_dirty(true), m_buffer(NULL), m_width(0), m_height(0)
-{
- resize(width, height);
-}
-
-FT2Image::~FT2Image()
-{
- delete[] m_buffer;
-}
-
-void FT2Image::resize(long width, long height)
-{
- if (width <= 0) {
- width = 1;
- }
- if (height <= 0) {
- height = 1;
- }
- size_t numBytes = width * height;
-
- if ((unsigned long)width != m_width || (unsigned long)height != m_height) {
- if (numBytes > m_width * m_height) {
- delete[] m_buffer;
- m_buffer = NULL;
- m_buffer = new unsigned char[numBytes];
- }
-
- m_width = (unsigned long)width;
- m_height = (unsigned long)height;
- }
-
- if (numBytes && m_buffer) {
- memset(m_buffer, 0, numBytes);
- }
-
- m_dirty = true;
-}
-
-void FT2Image::draw_bitmap(FT_Bitmap *bitmap, FT_Int x, FT_Int y)
-{
- FT_Int image_width = (FT_Int)m_width;
- FT_Int image_height = (FT_Int)m_height;
- FT_Int char_width = bitmap->width;
- FT_Int char_height = bitmap->rows;
-
- FT_Int x1 = CLAMP(x, 0, image_width);
- FT_Int y1 = CLAMP(y, 0, image_height);
- FT_Int x2 = CLAMP(x + char_width, 0, image_width);
- FT_Int y2 = CLAMP(y + char_height, 0, image_height);
-
- FT_Int x_start = MAX(0, -x);
- FT_Int y_offset = y1 - MAX(0, -y);
-
- if (bitmap->pixel_mode == FT_PIXEL_MODE_GRAY) {
- for (FT_Int i = y1; i < y2; ++i) {
- unsigned char *dst = m_buffer + (i * image_width + x1);
- unsigned char *src = bitmap->buffer + (((i - y_offset) * bitmap->pitch) + x_start);
- for (FT_Int j = x1; j < x2; ++j, ++dst, ++src)
- *dst |= *src;
- }
- } else if (bitmap->pixel_mode == FT_PIXEL_MODE_MONO) {
- for (FT_Int i = y1; i < y2; ++i) {
- unsigned char *dst = m_buffer + (i * image_width + x1);
- unsigned char *src = bitmap->buffer + ((i - y_offset) * bitmap->pitch);
- for (FT_Int j = x1; j < x2; ++j, ++dst) {
- int x = (j - x1 + x_start);
- int val = *(src + (x >> 3)) & (1 << (7 - (x & 0x7)));
- *dst = val ? 255 : *dst;
- }
- }
- } else {
- throw std::runtime_error("Unknown pixel mode");
- }
-
- m_dirty = true;
-}
-
-void FT2Image::draw_rect(unsigned long x0, unsigned long y0, unsigned long x1, unsigned long y1)
-{
- if (x0 > m_width || x1 > m_width || y0 > m_height || y1 > m_height) {
- throw std::runtime_error("Rect coords outside image bounds");
- }
-
- size_t top = y0 * m_width;
- size_t bottom = y1 * m_width;
- for (size_t i = x0; i < x1 + 1; ++i) {
- m_buffer[i + top] = 255;
- m_buffer[i + bottom] = 255;
- }
-
- for (size_t j = y0 + 1; j < y1; ++j) {
- m_buffer[x0 + j * m_width] = 255;
- m_buffer[x1 + j * m_width] = 255;
- }
-
- m_dirty = true;
-}
-
-void
-FT2Image::draw_rect_filled(unsigned long x0, unsigned long y0, unsigned long x1, unsigned long y1)
-{
- x0 = std::min(x0, m_width);
- y0 = std::min(y0, m_height);
- x1 = std::min(x1 + 1, m_width);
- y1 = std::min(y1 + 1, m_height);
-
- for (size_t j = y0; j < y1; j++) {
- for (size_t i = x0; i < x1; i++) {
- m_buffer[i + j * m_width] = 255;
- }
- }
-
- m_dirty = true;
-}
-
-inline double conv(long v)
-{
- return double(v) / 64.0;
-}
-
-int FT2Font::get_path_count()
-{
- // get the glyph as a path, a list of (COMMAND, *args) as described in matplotlib.path
- // this code is from agg's decompose_ft_outline with minor modifications
-
- if (!face->glyph) {
- throw std::runtime_error("No glyph loaded");
- }
-
- FT_Outline &outline = face->glyph->outline;
-
- FT_Vector v_last;
- FT_Vector v_control;
- FT_Vector v_start;
-
- FT_Vector *point;
- FT_Vector *limit;
- unsigned char *tags;
-
- int n; // index of contour in outline
- int first; // index of first point in contour
- char tag; // current point's state
- int count;
-
- count = 0;
- first = 0;
- for (n = 0; n < outline.n_contours; n++) {
- int last; // index of last point in contour
- bool starts_with_last;
-
- last = outline.contours[n];
- limit = outline.points + last;
-
- v_start = outline.points[first];
- v_last = outline.points[last];
-
- v_control = v_start;
-
- point = outline.points + first;
- tags = outline.tags + first;
- tag = FT_CURVE_TAG(tags[0]);
-
- // A contour cannot start with a cubic control point!
- if (tag == FT_CURVE_TAG_CUBIC) {
- throw std::runtime_error("A contour cannot start with a cubic control point");
- } else if (tag == FT_CURVE_TAG_CONIC) {
- starts_with_last = true;
- } else {
- starts_with_last = false;
- }
-
- count++;
-
- while (point < limit) {
- if (!starts_with_last) {
- point++;
- tags++;
- }
- starts_with_last = false;
-
- tag = FT_CURVE_TAG(tags[0]);
- switch (tag) {
- case FT_CURVE_TAG_ON: // emit a single line_to
- {
- count++;
- continue;
- }
-
- case FT_CURVE_TAG_CONIC: // consume conic arcs
- {
- Count_Do_Conic:
- if (point < limit) {
- point++;
- tags++;
- tag = FT_CURVE_TAG(tags[0]);
-
- if (tag == FT_CURVE_TAG_ON) {
- count += 2;
- continue;
- }
-
- if (tag != FT_CURVE_TAG_CONIC) {
- throw std::runtime_error("Invalid font");
- }
-
- count += 2;
-
- goto Count_Do_Conic;
- }
-
- count += 2;
-
- goto Count_Close;
- }
-
- default: // FT_CURVE_TAG_CUBIC
- {
- if (point + 1 > limit || FT_CURVE_TAG(tags[1]) != FT_CURVE_TAG_CUBIC) {
- throw std::runtime_error("Invalid font");
- }
-
- point += 2;
- tags += 2;
-
- if (point <= limit) {
- count += 3;
- continue;
- }
-
- count += 3;
-
- goto Count_Close;
- }
- }
- }
-
- Count_Close:
- count++;
- first = last + 1;
- }
-
- return count;
-}
-
-void FT2Font::get_path(double *outpoints, unsigned char *outcodes)
-{
- FT_Outline &outline = face->glyph->outline;
- bool flip_y = false; // todo, pass me as kwarg
-
- FT_Vector v_last;
- FT_Vector v_control;
- FT_Vector v_start;
-
- FT_Vector *point;
- FT_Vector *limit;
- unsigned char *tags;
-
- int n; // index of contour in outline
- int first; // index of first point in contour
- char tag; // current point's state
-
- first = 0;
- for (n = 0; n < outline.n_contours; n++) {
- int last; // index of last point in contour
- bool starts_with_last;
-
- last = outline.contours[n];
- limit = outline.points + last;
-
- v_start = outline.points[first];
- v_last = outline.points[last];
-
- v_control = v_start;
-
- point = outline.points + first;
- tags = outline.tags + first;
- tag = FT_CURVE_TAG(tags[0]);
-
- double x, y;
- if (tag != FT_CURVE_TAG_ON) {
- x = conv(v_last.x);
- y = flip_y ? -conv(v_last.y) : conv(v_last.y);
- starts_with_last = true;
- } else {
- x = conv(v_start.x);
- y = flip_y ? -conv(v_start.y) : conv(v_start.y);
- starts_with_last = false;
- }
-
- *(outpoints++) = x;
- *(outpoints++) = y;
- *(outcodes++) = MOVETO;
-
- while (point < limit) {
- if (!starts_with_last) {
- point++;
- tags++;
- }
- starts_with_last = false;
-
- tag = FT_CURVE_TAG(tags[0]);
- switch (tag) {
- case FT_CURVE_TAG_ON: // emit a single line_to
- {
- double x = conv(point->x);
- double y = flip_y ? -conv(point->y) : conv(point->y);
- *(outpoints++) = x;
- *(outpoints++) = y;
- *(outcodes++) = LINETO;
- continue;
- }
-
- case FT_CURVE_TAG_CONIC: // consume conic arcs
- {
- v_control.x = point->x;
- v_control.y = point->y;
-
- Do_Conic:
- if (point < limit) {
- FT_Vector vec;
- FT_Vector v_middle;
-
- point++;
- tags++;
- tag = FT_CURVE_TAG(tags[0]);
-
- vec.x = point->x;
- vec.y = point->y;
-
- if (tag == FT_CURVE_TAG_ON) {
- double xctl = conv(v_control.x);
- double yctl = flip_y ? -conv(v_control.y) : conv(v_control.y);
- double xto = conv(vec.x);
- double yto = flip_y ? -conv(vec.y) : conv(vec.y);
- *(outpoints++) = xctl;
- *(outpoints++) = yctl;
- *(outpoints++) = xto;
- *(outpoints++) = yto;
- *(outcodes++) = CURVE3;
- *(outcodes++) = CURVE3;
- continue;
- }
-
- v_middle.x = (v_control.x + vec.x) / 2;
- v_middle.y = (v_control.y + vec.y) / 2;
-
- double xctl = conv(v_control.x);
- double yctl = flip_y ? -conv(v_control.y) : conv(v_control.y);
- double xto = conv(v_middle.x);
- double yto = flip_y ? -conv(v_middle.y) : conv(v_middle.y);
- *(outpoints++) = xctl;
- *(outpoints++) = yctl;
- *(outpoints++) = xto;
- *(outpoints++) = yto;
- *(outcodes++) = CURVE3;
- *(outcodes++) = CURVE3;
-
- v_control = vec;
- goto Do_Conic;
- }
- double xctl = conv(v_control.x);
- double yctl = flip_y ? -conv(v_control.y) : conv(v_control.y);
- double xto = conv(v_start.x);
- double yto = flip_y ? -conv(v_start.y) : conv(v_start.y);
-
- *(outpoints++) = xctl;
- *(outpoints++) = yctl;
- *(outpoints++) = xto;
- *(outpoints++) = yto;
- *(outcodes++) = CURVE3;
- *(outcodes++) = CURVE3;
-
- goto Close;
- }
-
- default: // FT_CURVE_TAG_CUBIC
- {
- FT_Vector vec1, vec2;
-
- vec1.x = point[0].x;
- vec1.y = point[0].y;
- vec2.x = point[1].x;
- vec2.y = point[1].y;
-
- point += 2;
- tags += 2;
-
- if (point <= limit) {
- FT_Vector vec;
-
- vec.x = point->x;
- vec.y = point->y;
-
- double xctl1 = conv(vec1.x);
- double yctl1 = flip_y ? -conv(vec1.y) : conv(vec1.y);
- double xctl2 = conv(vec2.x);
- double yctl2 = flip_y ? -conv(vec2.y) : conv(vec2.y);
- double xto = conv(vec.x);
- double yto = flip_y ? -conv(vec.y) : conv(vec.y);
-
- (*outpoints++) = xctl1;
- (*outpoints++) = yctl1;
- (*outpoints++) = xctl2;
- (*outpoints++) = yctl2;
- (*outpoints++) = xto;
- (*outpoints++) = yto;
- (*outcodes++) = CURVE4;
- (*outcodes++) = CURVE4;
- (*outcodes++) = CURVE4;
- continue;
- }
-
- double xctl1 = conv(vec1.x);
- double yctl1 = flip_y ? -conv(vec1.y) : conv(vec1.y);
- double xctl2 = conv(vec2.x);
- double yctl2 = flip_y ? -conv(vec2.y) : conv(vec2.y);
- double xto = conv(v_start.x);
- double yto = flip_y ? -conv(v_start.y) : conv(v_start.y);
- (*outpoints++) = xctl1;
- (*outpoints++) = yctl1;
- (*outpoints++) = xctl2;
- (*outpoints++) = yctl2;
- (*outpoints++) = xto;
- (*outpoints++) = yto;
- (*outcodes++) = CURVE4;
- (*outcodes++) = CURVE4;
- (*outcodes++) = CURVE4;
-
- goto Close;
- }
- }
- }
-
- Close:
- (*outpoints++) = 0.0;
- (*outpoints++) = 0.0;
- (*outcodes++) = ENDPOLY;
- first = last + 1;
- }
-}
-
-FT2Font::FT2Font(FT_Open_Args &open_args, long hinting_factor_) : image(), face(NULL)
-{
- clear();
-
- int error = FT_Open_Face(_ft2Library, &open_args, 0, &face);
-
- if (error == FT_Err_Unknown_File_Format) {
- throw std::runtime_error("Can not load face. Unknown file format.");
- } else if (error == FT_Err_Cannot_Open_Resource) {
- throw std::runtime_error("Can not load face. Can not open resource.");
- } else if (error == FT_Err_Invalid_File_Format) {
- throw std::runtime_error("Can not load face. Invalid file format.");
- } else if (error) {
- throw std::runtime_error("Can not load face.");
- }
-
- // set a default fontsize 12 pt at 72dpi
- hinting_factor = hinting_factor_;
-
- error = FT_Set_Char_Size(face, 12 * 64, 0, 72 * (unsigned int)hinting_factor, 72);
- if (error) {
- FT_Done_Face(face);
- throw std::runtime_error("Could not set the fontsize");
- }
-
- if (open_args.stream != NULL) {
- face->face_flags |= FT_FACE_FLAG_EXTERNAL_STREAM;
- }
-
- FT_Matrix transform = { 65536 / hinting_factor, 0, 0, 65536 };
- FT_Set_Transform(face, &transform, 0);
-}
-
-FT2Font::~FT2Font()
-{
- for (size_t i = 0; i < glyphs.size(); i++) {
- FT_Done_Glyph(glyphs[i]);
- }
-
- if (face) {
- FT_Done_Face(face);
- }
-}
-
-void FT2Font::clear()
-{
- angle = 0.0;
-
- pen.x = 0;
- pen.y = 0;
-
- for (size_t i = 0; i < glyphs.size(); i++) {
- FT_Done_Glyph(glyphs[i]);
- }
-
- glyphs.clear();
-}
-
-void FT2Font::set_size(double ptsize, double dpi)
-{
- int error = FT_Set_Char_Size(
- face, (long)(ptsize * 64), 0, (unsigned int)(dpi * hinting_factor), (unsigned int)dpi);
- FT_Matrix transform = { 65536 / hinting_factor, 0, 0, 65536 };
- FT_Set_Transform(face, &transform, 0);
-
- if (error) {
- throw std::runtime_error("Could not set the fontsize");
- }
-}
-
-void FT2Font::set_charmap(int i)
-{
- if (i >= face->num_charmaps) {
- throw std::runtime_error("i exceeds the available number of char maps");
- }
- FT_CharMap charmap = face->charmaps[i];
- if (FT_Set_Charmap(face, charmap)) {
- throw std::runtime_error("Could not set the charmap");
- }
-}
-
-void FT2Font::select_charmap(unsigned long i)
-{
- if (FT_Select_Charmap(face, (FT_Encoding)i)) {
- throw std::runtime_error("Could not set the charmap");
- }
-}
-
-int FT2Font::get_kerning(FT_UInt left, FT_UInt right, FT_UInt mode)
-{
- if (!FT_HAS_KERNING(face)) {
- return 0;
- }
- FT_Vector delta;
-
- if (!FT_Get_Kerning(face, left, right, mode, &delta)) {
- return (int)(delta.x) / (hinting_factor << 6);
- } else {
- return 0;
- }
-}
-
-void FT2Font::set_text(
- size_t N, uint32_t *codepoints, double angle, FT_Int32 flags, std::vector<double> &xys)
-{
- angle = angle / 360.0 * 2 * M_PI;
-
- // this computes width and height in subpixels so we have to divide by 64
- matrix.xx = (FT_Fixed)(cos(angle) * 0x10000L);
- matrix.xy = (FT_Fixed)(-sin(angle) * 0x10000L);
- matrix.yx = (FT_Fixed)(sin(angle) * 0x10000L);
- matrix.yy = (FT_Fixed)(cos(angle) * 0x10000L);
-
- FT_Bool use_kerning = FT_HAS_KERNING(face);
- FT_UInt previous = 0;
-
- clear();
-
- bbox.xMin = bbox.yMin = 32000;
- bbox.xMax = bbox.yMax = -32000;
-
- for (unsigned int n = 0; n < N; n++) {
- std::string thischar("?");
- FT_UInt glyph_index;
- FT_BBox glyph_bbox;
- FT_Pos last_advance;
-
- glyph_index = FT_Get_Char_Index(face, codepoints[n]);
-
- // retrieve kerning distance and move pen position
- if (use_kerning && previous && glyph_index) {
- FT_Vector delta;
- FT_Get_Kerning(face, previous, glyph_index, FT_KERNING_DEFAULT, &delta);
- pen.x += (delta.x << 10) / (hinting_factor << 16);
- }
- error = FT_Load_Glyph(face, glyph_index, flags);
- if (error) {
- throw std::runtime_error("could not load glyph");
- }
- // ignore errors, jump to next glyph
-
- // extract glyph image and store it in our table
-
- FT_Glyph thisGlyph;
- error = FT_Get_Glyph(face->glyph, &thisGlyph);
-
- if (error) {
- throw std::runtime_error("could not get glyph");
- }
- // ignore errors, jump to next glyph
-
- last_advance = face->glyph->advance.x;
- FT_Glyph_Transform(thisGlyph, 0, &pen);
- FT_Glyph_Transform(thisGlyph, &matrix, 0);
- xys.push_back(pen.x);
- xys.push_back(pen.y);
-
- FT_Glyph_Get_CBox(thisGlyph, ft_glyph_bbox_subpixels, &glyph_bbox);
-
- bbox.xMin = std::min(bbox.xMin, glyph_bbox.xMin);
- bbox.xMax = std::max(bbox.xMax, glyph_bbox.xMax);
- bbox.yMin = std::min(bbox.yMin, glyph_bbox.yMin);
- bbox.yMax = std::max(bbox.yMax, glyph_bbox.yMax);
-
- pen.x += last_advance;
-
- previous = glyph_index;
- glyphs.push_back(thisGlyph);
- }
-
- FT_Vector_Transform(&pen, &matrix);
- advance = pen.x;
-
- if (bbox.xMin > bbox.xMax) {
- bbox.xMin = bbox.yMin = bbox.xMax = bbox.yMax = 0;
- }
-}
-
-void FT2Font::load_char(long charcode, FT_Int32 flags)
-{
- int error = FT_Load_Char(face, (unsigned long)charcode, flags);
-
- if (error) {
- throw std::runtime_error("Could not load charcode");
- }
-
- FT_Glyph thisGlyph;
- error = FT_Get_Glyph(face->glyph, &thisGlyph);
-
- if (error) {
- throw std::runtime_error("Could not get glyph");
- }
-
- glyphs.push_back(thisGlyph);
-}
-
-void FT2Font::load_glyph(FT_UInt glyph_index, FT_Int32 flags)
-{
- int error = FT_Load_Glyph(face, glyph_index, flags);
-
- if (error) {
- throw std::runtime_error("Could not load glyph");
- }
-
- FT_Glyph thisGlyph;
- error = FT_Get_Glyph(face->glyph, &thisGlyph);
-
- if (error) {
- throw std::runtime_error("Could not load glyph");
- }
-
- glyphs.push_back(thisGlyph);
-}
-
-void FT2Font::get_width_height(long *width, long *height)
-{
- *width = advance;
- *height = bbox.yMax - bbox.yMin;
-}
-
-long FT2Font::get_descent()
-{
- return -bbox.yMin;
-}
-
-void FT2Font::get_bitmap_offset(long *x, long *y)
-{
- *x = bbox.xMin;
- *y = 0;
-}
-
-void FT2Font::draw_glyphs_to_bitmap(bool antialiased)
-{
- size_t width = (bbox.xMax - bbox.xMin) / 64 + 2;
- size_t height = (bbox.yMax - bbox.yMin) / 64 + 2;
-
- image.resize(width, height);
-
- for (size_t n = 0; n < glyphs.size(); n++) {
- error = FT_Glyph_To_Bitmap(
- &glyphs[n], antialiased ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO, 0, 1);
- if (error) {
- throw std::runtime_error("Could not convert glyph to bitmap");
- }
-
- FT_BitmapGlyph bitmap = (FT_BitmapGlyph)glyphs[n];
- // now, draw to our target surface (convert position)
-
- // bitmap left and top in pixel, string bbox in subpixel
- FT_Int x = (FT_Int)(bitmap->left - (bbox.xMin / 64.));
- FT_Int y = (FT_Int)((bbox.yMax / 64.) - bitmap->top + 1);
-
- image.draw_bitmap(&bitmap->bitmap, x, y);
- }
-}
-
-void FT2Font::get_xys(bool antialiased, std::vector<double> &xys)
-{
- for (size_t n = 0; n < glyphs.size(); n++) {
-
- error = FT_Glyph_To_Bitmap(
- &glyphs[n], antialiased ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO, 0, 1);
- if (error) {
- throw std::runtime_error("Could not convert glyph to bitmap");
- }
-
- FT_BitmapGlyph bitmap = (FT_BitmapGlyph)glyphs[n];
-
- // bitmap left and top in pixel, string bbox in subpixel
- FT_Int x = (FT_Int)(bitmap->left - bbox.xMin / 64.);
- FT_Int y = (FT_Int)(bbox.yMax / 64. - bitmap->top + 1);
- // make sure the index is non-neg
- x = x < 0 ? 0 : x;
- y = y < 0 ? 0 : y;
- xys.push_back(x);
- xys.push_back(y);
- }
-}
-
-void FT2Font::draw_glyph_to_bitmap(FT2Image &im, int x, int y, size_t glyphInd, bool antialiased)
-{
- FT_Vector sub_offset;
- sub_offset.x = 0; // int((xd - (double)x) * 64.0);
- sub_offset.y = 0; // int((yd - (double)y) * 64.0);
-
- if (glyphInd >= glyphs.size()) {
- throw std::runtime_error("glyph num is out of range");
- }
-
- error = FT_Glyph_To_Bitmap(&glyphs[glyphInd],
- antialiased ? FT_RENDER_MODE_NORMAL : FT_RENDER_MODE_MONO,
- &sub_offset, // additional translation
- 1 // destroy image
- );
- if (error) {
- throw std::runtime_error("Could not convert glyph to bitmap");
- }
-
- FT_BitmapGlyph bitmap = (FT_BitmapGlyph)glyphs[glyphInd];
-
- im.draw_bitmap(&bitmap->bitmap, x + bitmap->left, y);
-}
-
-void FT2Font::get_glyph_name(unsigned int glyph_number, char *buffer)
-{
- if (!FT_HAS_GLYPH_NAMES(face)) {
- /* Note that this generated name must match the name that
- is generated by ttconv in ttfont_CharStrings_getname. */
- PyOS_snprintf(buffer, 128, "uni%08x", glyph_number);
- } else {
- if (FT_Get_Glyph_Name(face, glyph_number, buffer, 128)) {
- throw std::runtime_error("Could not get glyph names.");
- }
- }
-}
-
-long FT2Font::get_name_index(char *name)
-{
- return FT_Get_Name_Index(face, (FT_String *)name);
-}
diff --git a/contrib/python/matplotlib/py2/src/ft2font.h b/contrib/python/matplotlib/py2/src/ft2font.h
deleted file mode 100644
index 072428ceed..0000000000
--- a/contrib/python/matplotlib/py2/src/ft2font.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-/* A python interface to FreeType */
-#ifndef _FT2FONT_H
-#define _FT2FONT_H
-#include <vector>
-#include <stdint.h>
-
-extern "C" {
-#include <ft2build.h>
-#include FT_FREETYPE_H
-#include FT_GLYPH_H
-#include FT_SFNT_NAMES_H
-#include FT_TYPE1_TABLES_H
-#include FT_TRUETYPE_TABLES_H
-}
-
-/*
- By definition, FT_FIXED as 2 16bit values stored in a single long.
- */
-#define FIXED_MAJOR(val) (signed short)((val & 0xffff0000) >> 16)
-#define FIXED_MINOR(val) (unsigned short)(val & 0xffff)
-
-// the FreeType string rendered into a width, height buffer
-class FT2Image
-{
- public:
- FT2Image();
- FT2Image(unsigned long width, unsigned long height);
- virtual ~FT2Image();
-
- void resize(long width, long height);
- void draw_bitmap(FT_Bitmap *bitmap, FT_Int x, FT_Int y);
- void write_bitmap(FILE *fp) const;
- void draw_rect(unsigned long x0, unsigned long y0, unsigned long x1, unsigned long y1);
- void draw_rect_filled(unsigned long x0, unsigned long y0, unsigned long x1, unsigned long y1);
-
- unsigned char *get_buffer()
- {
- return m_buffer;
- }
- unsigned long get_width()
- {
- return m_width;
- }
- unsigned long get_height()
- {
- return m_height;
- }
-
- private:
- bool m_dirty;
- unsigned char *m_buffer;
- unsigned long m_width;
- unsigned long m_height;
-
- // prevent copying
- FT2Image(const FT2Image &);
- FT2Image &operator=(const FT2Image &);
-};
-
-extern FT_Library _ft2Library;
-
-class FT2Font
-{
-
- public:
- FT2Font(FT_Open_Args &open_args, long hinting_factor);
- virtual ~FT2Font();
- void clear();
- void set_size(double ptsize, double dpi);
- void set_charmap(int i);
- void select_charmap(unsigned long i);
- void set_text(
- size_t N, uint32_t *codepoints, double angle, FT_Int32 flags, std::vector<double> &xys);
- int get_kerning(FT_UInt left, FT_UInt right, FT_UInt mode);
- void load_char(long charcode, FT_Int32 flags);
- void load_glyph(FT_UInt glyph_index, FT_Int32 flags);
- void get_width_height(long *width, long *height);
- void get_bitmap_offset(long *x, long *y);
- long get_descent();
- // TODO: Since we know the size of the array upfront, we probably don't
- // need to dynamically allocate like this
- void get_xys(bool antialiased, std::vector<double> &xys);
- void draw_glyphs_to_bitmap(bool antialiased);
- void draw_glyph_to_bitmap(FT2Image &im, int x, int y, size_t glyphInd, bool antialiased);
- void get_glyph_name(unsigned int glyph_number, char *buffer);
- long get_name_index(char *name);
- int get_path_count();
- void get_path(double *outpoints, unsigned char *outcodes);
-
- FT_Face &get_face()
- {
- return face;
- }
- FT2Image &get_image()
- {
- return image;
- }
- FT_Glyph &get_last_glyph()
- {
- return glyphs.back();
- }
- size_t get_last_glyph_index()
- {
- return glyphs.size() - 1;
- }
- size_t get_num_glyphs()
- {
- return glyphs.size();
- }
- long get_hinting_factor()
- {
- return hinting_factor;
- }
-
- private:
- FT2Image image;
- FT_Face face;
- FT_Matrix matrix; /* transformation matrix */
- FT_Vector pen; /* untransformed origin */
- FT_Error error;
- std::vector<FT_Glyph> glyphs;
- std::vector<FT_Vector> pos;
- FT_BBox bbox;
- FT_Pos advance;
- double angle;
- double ptsize;
- double dpi;
- long hinting_factor;
-
- void set_scalable_attributes();
-
- // prevent copying
- FT2Font(const FT2Font &);
- FT2Font &operator=(const FT2Font &);
-};
-
-#endif
diff --git a/contrib/python/matplotlib/py2/src/ft2font_wrapper.cpp b/contrib/python/matplotlib/py2/src/ft2font_wrapper.cpp
deleted file mode 100644
index d0e516ad02..0000000000
--- a/contrib/python/matplotlib/py2/src/ft2font_wrapper.cpp
+++ /dev/null
@@ -1,1808 +0,0 @@
-#include "mplutils.h"
-#include "ft2font.h"
-#include "file_compat.h"
-#include "py_exceptions.h"
-#include "numpy_cpp.h"
-
-// From Python
-#include <structmember.h>
-
-#define STRINGIFY(s) XSTRINGIFY(s)
-#define XSTRINGIFY(s) #s
-
-static PyObject *convert_xys_to_array(std::vector<double> &xys)
-{
- npy_intp dims[] = {(npy_intp)xys.size() / 2, 2 };
- if (dims[0] > 0) {
- return PyArray_SimpleNewFromData(2, dims, NPY_DOUBLE, &xys[0]);
- } else {
- return PyArray_SimpleNew(2, dims, NPY_DOUBLE);
- }
-}
-
-/**********************************************************************
- * FT2Image
- * */
-
-typedef struct
-{
- PyObject_HEAD
- FT2Image *x;
- Py_ssize_t shape[2];
- Py_ssize_t strides[2];
- Py_ssize_t suboffsets[2];
-} PyFT2Image;
-
-static PyObject *PyFT2Image_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
- PyFT2Image *self;
- self = (PyFT2Image *)type->tp_alloc(type, 0);
- self->x = NULL;
- return (PyObject *)self;
-}
-
-static int PyFT2Image_init(PyFT2Image *self, PyObject *args, PyObject *kwds)
-{
- double width;
- double height;
-
- if (!PyArg_ParseTuple(args, "dd:FT2Image", &width, &height)) {
- return -1;
- }
-
- CALL_CPP_INIT("FT2Image", (self->x = new FT2Image(width, height)));
-
- return 0;
-}
-
-static void PyFT2Image_dealloc(PyFT2Image *self)
-{
- delete self->x;
- Py_TYPE(self)->tp_free((PyObject *)self);
-}
-
-const char *PyFT2Image_draw_rect__doc__ =
- "draw_rect(x0, y0, x1, y1)\n"
- "\n"
- "Draw a rect to the image.\n"
- "\n";
-
-static PyObject *PyFT2Image_draw_rect(PyFT2Image *self, PyObject *args, PyObject *kwds)
-{
- double x0, y0, x1, y1;
-
- if (!PyArg_ParseTuple(args, "dddd:draw_rect", &x0, &y0, &x1, &y1)) {
- return NULL;
- }
-
- CALL_CPP("draw_rect", (self->x->draw_rect(x0, y0, x1, y1)));
-
- Py_RETURN_NONE;
-}
-
-const char *PyFT2Image_draw_rect_filled__doc__ =
- "draw_rect_filled(x0, y0, x1, y1)\n"
- "\n"
- "Draw a filled rect to the image.\n"
- "\n";
-
-static PyObject *PyFT2Image_draw_rect_filled(PyFT2Image *self, PyObject *args, PyObject *kwds)
-{
- double x0, y0, x1, y1;
-
- if (!PyArg_ParseTuple(args, "dddd:draw_rect_filled", &x0, &y0, &x1, &y1)) {
- return NULL;
- }
-
- CALL_CPP("draw_rect_filled", (self->x->draw_rect_filled(x0, y0, x1, y1)));
-
- Py_RETURN_NONE;
-}
-
-const char *PyFT2Image_as_str__doc__ =
- "s = image.as_str()\n"
- "\n"
- "Return the image buffer as a string\n"
- "\n";
-
-static PyObject *PyFT2Image_as_str(PyFT2Image *self, PyObject *args, PyObject *kwds)
-{
- // TODO: Use a buffer to avoid the copy
- return PyBytes_FromStringAndSize((const char *)self->x->get_buffer(),
- self->x->get_width() * self->x->get_height());
-}
-
-const char *PyFT2Image_as_rgba_str__doc__ =
- "s = image.as_rgba_str()\n"
- "\n"
- "Return the image buffer as a RGBA string\n"
- "\n";
-
-static PyObject *PyFT2Image_as_rgba_str(PyFT2Image *self, PyObject *args, PyObject *kwds)
-{
- npy_intp dims[] = {(npy_intp)self->x->get_height(), (npy_intp)self->x->get_width(), 4 };
- numpy::array_view<unsigned char, 3> result(dims);
-
- unsigned char *src = self->x->get_buffer();
- unsigned char *end = src + (self->x->get_width() * self->x->get_height());
- unsigned char *dst = result.data();
-
- while (src != end) {
- *dst++ = 0;
- *dst++ = 0;
- *dst++ = 0;
- *dst++ = *src++;
- }
-
- return result.pyobj();
-}
-
-const char *PyFT2Image_as_array__doc__ =
- "x = image.as_array()\n"
- "\n"
- "Return the image buffer as a width x height numpy array of ubyte \n"
- "\n";
-
-static PyObject *PyFT2Image_as_array(PyFT2Image *self, PyObject *args, PyObject *kwds)
-{
- npy_intp dims[] = {(npy_intp)self->x->get_height(), (npy_intp)self->x->get_width() };
- return PyArray_SimpleNewFromData(2, dims, NPY_UBYTE, self->x->get_buffer());
-}
-
-static PyObject *PyFT2Image_get_width(PyFT2Image *self, PyObject *args, PyObject *kwds)
-{
- return PyLong_FromLong(self->x->get_width());
-}
-
-static PyObject *PyFT2Image_get_height(PyFT2Image *self, PyObject *args, PyObject *kwds)
-{
- return PyLong_FromLong(self->x->get_height());
-}
-
-static int PyFT2Image_get_buffer(PyFT2Image *self, Py_buffer *buf, int flags)
-{
- FT2Image *im = self->x;
-
- Py_INCREF(self);
- buf->obj = (PyObject *)self;
- buf->buf = im->get_buffer();
- buf->len = im->get_width() * im->get_height();
- buf->readonly = 0;
- buf->format = (char *)"B";
- buf->ndim = 2;
- self->shape[0] = im->get_height();
- self->shape[1] = im->get_width();
- buf->shape = self->shape;
- self->strides[0] = im->get_width();
- self->strides[1] = 1;
- buf->strides = self->strides;
- buf->suboffsets = NULL;
- buf->itemsize = 1;
- buf->internal = NULL;
-
- return 1;
-}
-
-static PyTypeObject PyFT2ImageType;
-
-static PyTypeObject *PyFT2Image_init_type(PyObject *m, PyTypeObject *type)
-{
- static PyMethodDef methods[] = {
- {"draw_rect", (PyCFunction)PyFT2Image_draw_rect, METH_VARARGS, PyFT2Image_draw_rect__doc__},
- {"draw_rect_filled", (PyCFunction)PyFT2Image_draw_rect_filled, METH_VARARGS, PyFT2Image_draw_rect_filled__doc__},
- {"as_str", (PyCFunction)PyFT2Image_as_str, METH_NOARGS, PyFT2Image_as_str__doc__},
- {"as_rgba_str", (PyCFunction)PyFT2Image_as_rgba_str, METH_NOARGS, PyFT2Image_as_rgba_str__doc__},
- {"as_array", (PyCFunction)PyFT2Image_as_array, METH_NOARGS, PyFT2Image_as_array__doc__},
- {"get_width", (PyCFunction)PyFT2Image_get_width, METH_NOARGS, NULL},
- {"get_height", (PyCFunction)PyFT2Image_get_height, METH_NOARGS, NULL},
- {NULL}
- };
-
- static PyBufferProcs buffer_procs;
- memset(&buffer_procs, 0, sizeof(PyBufferProcs));
- buffer_procs.bf_getbuffer = (getbufferproc)PyFT2Image_get_buffer;
-
- memset(type, 0, sizeof(PyTypeObject));
- type->tp_name = "matplotlib.ft2font.FT2Image";
- type->tp_basicsize = sizeof(PyFT2Image);
- type->tp_dealloc = (destructor)PyFT2Image_dealloc;
- type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_NEWBUFFER;
- type->tp_methods = methods;
- type->tp_new = PyFT2Image_new;
- type->tp_init = (initproc)PyFT2Image_init;
- type->tp_as_buffer = &buffer_procs;
-
- if (PyType_Ready(type) < 0) {
- return NULL;
- }
-
- if (PyModule_AddObject(m, "FT2Image", (PyObject *)type)) {
- return NULL;
- }
-
- return type;
-}
-
-/**********************************************************************
- * Glyph
- * */
-
-typedef struct
-{
- PyObject_HEAD
- size_t glyphInd;
- long width;
- long height;
- long horiBearingX;
- long horiBearingY;
- long horiAdvance;
- long linearHoriAdvance;
- long vertBearingX;
- long vertBearingY;
- long vertAdvance;
- FT_BBox bbox;
-} PyGlyph;
-
-static PyTypeObject PyGlyphType;
-
-static PyObject *
-PyGlyph_new(const FT_Face &face, const FT_Glyph &glyph, size_t ind, long hinting_factor)
-{
- PyGlyph *self;
- self = (PyGlyph *)PyGlyphType.tp_alloc(&PyGlyphType, 0);
-
- self->glyphInd = ind;
-
- FT_Glyph_Get_CBox(glyph, ft_glyph_bbox_subpixels, &self->bbox);
-
- self->width = face->glyph->metrics.width / hinting_factor;
- self->height = face->glyph->metrics.height;
- self->horiBearingX = face->glyph->metrics.horiBearingX / hinting_factor;
- self->horiBearingY = face->glyph->metrics.horiBearingY;
- self->horiAdvance = face->glyph->metrics.horiAdvance;
- self->linearHoriAdvance = face->glyph->linearHoriAdvance / hinting_factor;
- self->vertBearingX = face->glyph->metrics.vertBearingX;
- self->vertBearingY = face->glyph->metrics.vertBearingY;
- self->vertAdvance = face->glyph->metrics.vertAdvance;
-
- return (PyObject *)self;
-}
-
-static void PyGlyph_dealloc(PyGlyph *self)
-{
- Py_TYPE(self)->tp_free((PyObject *)self);
-}
-
-static PyObject *PyGlyph_get_bbox(PyGlyph *self, void *closure)
-{
- return Py_BuildValue(
- "llll", self->bbox.xMin, self->bbox.yMin, self->bbox.xMax, self->bbox.yMax);
-}
-
-static PyTypeObject *PyGlyph_init_type(PyObject *m, PyTypeObject *type)
-{
- static PyMemberDef members[] = {
- {(char *)"width", T_LONG, offsetof(PyGlyph, width), READONLY, (char *)""},
- {(char *)"height", T_LONG, offsetof(PyGlyph, height), READONLY, (char *)""},
- {(char *)"horiBearingX", T_LONG, offsetof(PyGlyph, horiBearingX), READONLY, (char *)""},
- {(char *)"horiBearingY", T_LONG, offsetof(PyGlyph, horiBearingY), READONLY, (char *)""},
- {(char *)"horiAdvance", T_LONG, offsetof(PyGlyph, horiAdvance), READONLY, (char *)""},
- {(char *)"linearHoriAdvance", T_LONG, offsetof(PyGlyph, linearHoriAdvance), READONLY, (char *)""},
- {(char *)"vertBearingX", T_LONG, offsetof(PyGlyph, vertBearingX), READONLY, (char *)""},
- {(char *)"vertBearingY", T_LONG, offsetof(PyGlyph, vertBearingY), READONLY, (char *)""},
- {(char *)"vertAdvance", T_LONG, offsetof(PyGlyph, vertAdvance), READONLY, (char *)""},
- {NULL}
- };
-
- static PyGetSetDef getset[] = {
- {(char *)"bbox", (getter)PyGlyph_get_bbox, NULL, NULL, NULL},
- {NULL}
- };
-
- memset(type, 0, sizeof(PyTypeObject));
- type->tp_name = "matplotlib.ft2font.Glyph";
- type->tp_basicsize = sizeof(PyGlyph);
- type->tp_dealloc = (destructor)PyGlyph_dealloc;
- type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE;
- type->tp_members = members;
- type->tp_getset = getset;
-
- if (PyType_Ready(type) < 0) {
- return NULL;
- }
-
- /* Don't need to add to module, since you can't create glyphs
- directly from Python */
-
- return type;
-}
-
-/**********************************************************************
- * FT2Font
- * */
-
-typedef struct
-{
- PyObject_HEAD
- FT2Font *x;
- PyObject *fname;
- PyObject *py_file;
- FILE *fp;
- int close_file;
- mpl_off_t offset;
- FT_StreamRec stream;
- FT_Byte *mem;
- size_t mem_size;
- Py_ssize_t shape[2];
- Py_ssize_t strides[2];
- Py_ssize_t suboffsets[2];
-} PyFT2Font;
-
-static unsigned long read_from_file_callback(FT_Stream stream,
- unsigned long offset,
- unsigned char *buffer,
- unsigned long count)
-{
-
- PyFT2Font *def = (PyFT2Font *)stream->descriptor.pointer;
-
- if (fseek(def->fp, offset, SEEK_SET) == -1) {
- return 0;
- }
-
- if (count > 0) {
- return fread(buffer, 1, count, def->fp);
- }
-
- return 0;
-}
-
-static void close_file_callback(FT_Stream stream)
-{
- PyFT2Font *def = (PyFT2Font *)stream->descriptor.pointer;
-
- if (mpl_PyFile_DupClose(def->py_file, def->fp, def->offset)) {
- throw std::runtime_error("Couldn't close file");
- }
-
- if (def->close_file) {
- mpl_PyFile_CloseFile(def->py_file);
- }
-
- Py_DECREF(def->py_file);
- def->py_file = NULL;
-}
-
-static int convert_open_args(PyFT2Font *self, PyObject *py_file_arg, FT_Open_Args *open_args)
-{
- PyObject *py_file = NULL;
- int close_file = 0;
- FILE *fp;
- PyObject *data = NULL;
- char *data_ptr;
- Py_ssize_t data_len;
- long file_size;
- FT_Byte *new_memory;
- mpl_off_t offset = 0;
-
- int result = 0;
-
- memset((void *)open_args, 0, sizeof(FT_Open_Args));
-
- if (PyBytes_Check(py_file_arg) || PyUnicode_Check(py_file_arg)) {
- if ((py_file = mpl_PyFile_OpenFile(py_file_arg, (char *)"rb")) == NULL) {
- goto exit;
- }
- close_file = 1;
- } else {
- Py_INCREF(py_file_arg);
- py_file = py_file_arg;
- }
-
- if ((fp = mpl_PyFile_Dup(py_file, (char *)"rb", &offset))) {
- Py_INCREF(py_file);
- self->py_file = py_file;
- self->close_file = close_file;
- self->fp = fp;
- self->offset = offset;
- fseek(fp, 0, SEEK_END);
- file_size = ftell(fp);
- fseek(fp, 0, SEEK_SET);
-
- self->stream.base = NULL;
- self->stream.size = (unsigned long)file_size;
- self->stream.pos = 0;
- self->stream.descriptor.pointer = self;
- self->stream.read = &read_from_file_callback;
- self->stream.close = &close_file_callback;
-
- open_args->flags = FT_OPEN_STREAM;
- open_args->stream = &self->stream;
- } else {
- if (PyObject_HasAttrString(py_file_arg, "read") &&
- (data = PyObject_CallMethod(py_file_arg, (char *)"read", (char *)""))) {
- if (PyBytes_AsStringAndSize(data, &data_ptr, &data_len)) {
- goto exit;
- }
-
- if (self->mem) {
- free(self->mem);
- }
- self->mem = (FT_Byte *)malloc((self->mem_size + data_len) * sizeof(FT_Byte));
- if (self->mem == NULL) {
- goto exit;
- }
- new_memory = self->mem + self->mem_size;
- self->mem_size += data_len;
-
- memcpy(new_memory, data_ptr, data_len);
- open_args->flags = FT_OPEN_MEMORY;
- open_args->memory_base = new_memory;
- open_args->memory_size = data_len;
- open_args->stream = NULL;
- } else {
- PyErr_SetString(PyExc_TypeError,
- "First argument must be a path or file object reading bytes");
- goto exit;
- }
- }
-
- result = 1;
-
-exit:
-
- Py_XDECREF(py_file);
- Py_XDECREF(data);
-
- return result;
-}
-
-static PyTypeObject PyFT2FontType;
-
-static PyObject *PyFT2Font_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
- PyFT2Font *self;
- self = (PyFT2Font *)type->tp_alloc(type, 0);
- self->x = NULL;
- self->fname = NULL;
- self->py_file = NULL;
- self->fp = NULL;
- self->close_file = 0;
- self->offset = 0;
- memset(&self->stream, 0, sizeof(FT_StreamRec));
- self->mem = 0;
- self->mem_size = 0;
- return (PyObject *)self;
-}
-
-const char *PyFT2Font_init__doc__ =
- "FT2Font(ttffile)\n"
- "\n"
- "Create a new FT2Font object\n"
- "The following global font attributes are defined:\n"
- " num_faces number of faces in file\n"
- " face_flags face flags (int type); see the ft2font constants\n"
- " style_flags style flags (int type); see the ft2font constants\n"
- " num_glyphs number of glyphs in the face\n"
- " family_name face family name\n"
- " style_name face style name\n"
- " num_fixed_sizes number of bitmap in the face\n"
- " scalable face is scalable\n"
- "\n"
- "The following are available, if scalable is true:\n"
- " bbox face global bounding box (xmin, ymin, xmax, ymax)\n"
- " units_per_EM number of font units covered by the EM\n"
- " ascender ascender in 26.6 units\n"
- " descender descender in 26.6 units\n"
- " height height in 26.6 units; used to compute a default\n"
- " line spacing (baseline-to-baseline distance)\n"
- " max_advance_width maximum horizontal cursor advance for all glyphs\n"
- " max_advance_height same for vertical layout\n"
- " underline_position vertical position of the underline bar\n"
- " underline_thickness vertical thickness of the underline\n"
- " postscript_name PostScript name of the font\n";
-
-static void PyFT2Font_fail(PyFT2Font *self)
-{
- free(self->mem);
- self->mem = NULL;
- Py_XDECREF(self->py_file);
- self->py_file = NULL;
-}
-
-static int PyFT2Font_init(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- PyObject *fname;
- FT_Open_Args open_args;
- long hinting_factor = 8;
- const char *names[] = { "filename", "hinting_factor", NULL };
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kwds, "O|l:FT2Font", (char **)names, &fname, &hinting_factor)) {
- return -1;
- }
-
- if (!convert_open_args(self, fname, &open_args)) {
- return -1;
- }
-
- CALL_CPP_FULL(
- "FT2Font", (self->x = new FT2Font(open_args, hinting_factor)), PyFT2Font_fail(self), -1);
-
- Py_INCREF(fname);
- self->fname = fname;
-
- return 0;
-}
-
-static void PyFT2Font_dealloc(PyFT2Font *self)
-{
- delete self->x;
- free(self->mem);
- Py_XDECREF(self->py_file);
- Py_XDECREF(self->fname);
- Py_TYPE(self)->tp_free((PyObject *)self);
-}
-
-const char *PyFT2Font_clear__doc__ =
- "clear()\n"
- "\n"
- "Clear all the glyphs, reset for a new set_text";
-
-static PyObject *PyFT2Font_clear(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- CALL_CPP("clear", (self->x->clear()));
-
- Py_RETURN_NONE;
-}
-
-const char *PyFT2Font_set_size__doc__ =
- "set_size(ptsize, dpi)\n"
- "\n"
- "Set the point size and dpi of the text.\n";
-
-static PyObject *PyFT2Font_set_size(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- double ptsize;
- double dpi;
-
- if (!PyArg_ParseTuple(args, "dd:set_size", &ptsize, &dpi)) {
- return NULL;
- }
-
- CALL_CPP("set_size", (self->x->set_size(ptsize, dpi)));
-
- Py_RETURN_NONE;
-}
-
-const char *PyFT2Font_set_charmap__doc__ =
- "set_charmap(i)\n"
- "\n"
- "Make the i-th charmap current\n";
-
-static PyObject *PyFT2Font_set_charmap(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- int i;
-
- if (!PyArg_ParseTuple(args, "i:set_charmap", &i)) {
- return NULL;
- }
-
- CALL_CPP("set_charmap", (self->x->set_charmap(i)));
-
- Py_RETURN_NONE;
-}
-
-const char *PyFT2Font_select_charmap__doc__ =
- "select_charmap(i)\n"
- "\n"
- "select charmap i where i is one of the FT_Encoding number\n";
-
-static PyObject *PyFT2Font_select_charmap(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- unsigned long i;
-
- if (!PyArg_ParseTuple(args, "k:select_charmap", &i)) {
- return NULL;
- }
-
- CALL_CPP("select_charmap", self->x->select_charmap(i));
-
- Py_RETURN_NONE;
-}
-
-const char *PyFT2Font_get_kerning__doc__ =
- "dx = get_kerning(left, right, mode)\n"
- "\n"
- "Get the kerning between left char and right glyph indices\n"
- "mode is a kerning mode constant\n"
- " KERNING_DEFAULT - Return scaled and grid-fitted kerning distances\n"
- " KERNING_UNFITTED - Return scaled but un-grid-fitted kerning distances\n"
- " KERNING_UNSCALED - Return the kerning vector in original font units\n";
-
-static PyObject *PyFT2Font_get_kerning(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- FT_UInt left, right, mode;
- int result;
-
- if (!PyArg_ParseTuple(args, "III:get_kerning", &left, &right, &mode)) {
- return NULL;
- }
-
- CALL_CPP("get_kerning", (result = self->x->get_kerning(left, right, mode)));
-
- return PyLong_FromLong(result);
-}
-
-const char *PyFT2Font_set_text__doc__ =
- "set_text(s, angle)\n"
- "\n"
- "Set the text string and angle.\n"
- "You must call this before draw_glyphs_to_bitmap\n"
- "A sequence of x,y positions is returned";
-
-static PyObject *PyFT2Font_set_text(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- PyObject *textobj;
- double angle = 0.0;
- FT_Int32 flags = FT_LOAD_FORCE_AUTOHINT;
- std::vector<double> xys;
- const char *names[] = { "string", "angle", "flags", NULL };
-
- /* This makes a technically incorrect assumption that FT_Int32 is
- int. In theory it can also be long, if the size of int is less
- than 32 bits. This is very unlikely on modern platforms. */
- if (!PyArg_ParseTupleAndKeywords(
- args, kwds, "O|di:set_text", (char **)names, &textobj, &angle, &flags)) {
- return NULL;
- }
-
- std::vector<uint32_t> codepoints;
- size_t size;
-
- if (PyUnicode_Check(textobj)) {
- size = PyUnicode_GET_SIZE(textobj);
- codepoints.resize(size);
- Py_UNICODE *unistr = PyUnicode_AsUnicode(textobj);
- for (size_t i = 0; i < size; ++i) {
- codepoints[i] = unistr[i];
- }
- } else if (PyBytes_Check(textobj)) {
- size = PyBytes_Size(textobj);
- codepoints.resize(size);
- char *bytestr = PyBytes_AsString(textobj);
- for (size_t i = 0; i < size; ++i) {
- codepoints[i] = bytestr[i];
- }
- } else {
- PyErr_SetString(PyExc_TypeError, "String must be unicode or bytes");
- return NULL;
- }
-
- uint32_t* codepoints_array = NULL;
- if (size > 0) {
- codepoints_array = &codepoints[0];
- }
- CALL_CPP("set_text", self->x->set_text(size, codepoints_array, angle, flags, xys));
-
- return convert_xys_to_array(xys);
-}
-
-const char *PyFT2Font_get_num_glyphs__doc__ =
- "get_num_glyphs()\n"
- "\n"
- "Return the number of loaded glyphs\n";
-
-static PyObject *PyFT2Font_get_num_glyphs(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- return PyLong_FromLong(self->x->get_num_glyphs());
-}
-
-const char *PyFT2Font_load_char__doc__ =
- "load_char(charcode, flags=LOAD_FORCE_AUTOHINT)\n"
- "\n"
- "Load character with charcode in current fontfile and set glyph.\n"
- "The flags argument can be a bitwise-or of the LOAD_XXX constants.\n"
- "Return value is a Glyph object, with attributes\n"
- " width # glyph width\n"
- " height # glyph height\n"
- " bbox # the glyph bbox (xmin, ymin, xmax, ymax)\n"
- " horiBearingX # left side bearing in horizontal layouts\n"
- " horiBearingY # top side bearing in horizontal layouts\n"
- " horiAdvance # advance width for horizontal layout\n"
- " vertBearingX # left side bearing in vertical layouts\n"
- " vertBearingY # top side bearing in vertical layouts\n"
- " vertAdvance # advance height for vertical layout\n";
-
-static PyObject *PyFT2Font_load_char(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- long charcode;
- FT_Int32 flags = FT_LOAD_FORCE_AUTOHINT;
- const char *names[] = { "charcode", "flags", NULL };
-
- /* This makes a technically incorrect assumption that FT_Int32 is
- int. In theory it can also be long, if the size of int is less
- than 32 bits. This is very unlikely on modern platforms. */
- if (!PyArg_ParseTupleAndKeywords(
- args, kwds, "l|i:load_char", (char **)names, &charcode, &flags)) {
- return NULL;
- }
-
- CALL_CPP("load_char", (self->x->load_char(charcode, flags)));
-
- return PyGlyph_new(self->x->get_face(),
- self->x->get_last_glyph(),
- self->x->get_last_glyph_index(),
- self->x->get_hinting_factor());
-}
-
-const char *PyFT2Font_load_glyph__doc__ =
- "load_glyph(glyphindex, flags=LOAD_FORCE_AUTOHINT)\n"
- "\n"
- "Load character with glyphindex in current fontfile and set glyph.\n"
- "The flags argument can be a bitwise-or of the LOAD_XXX constants.\n"
- "Return value is a Glyph object, with attributes\n"
- " width # glyph width\n"
- " height # glyph height\n"
- " bbox # the glyph bbox (xmin, ymin, xmax, ymax)\n"
- " horiBearingX # left side bearing in horizontal layouts\n"
- " horiBearingY # top side bearing in horizontal layouts\n"
- " horiAdvance # advance width for horizontal layout\n"
- " vertBearingX # left side bearing in vertical layouts\n"
- " vertBearingY # top side bearing in vertical layouts\n"
- " vertAdvance # advance height for vertical layout\n";
-
-static PyObject *PyFT2Font_load_glyph(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- FT_UInt glyph_index;
- FT_Int32 flags = FT_LOAD_FORCE_AUTOHINT;
- const char *names[] = { "glyph_index", "flags", NULL };
-
- /* This makes a technically incorrect assumption that FT_Int32 is
- int. In theory it can also be long, if the size of int is less
- than 32 bits. This is very unlikely on modern platforms. */
- if (!PyArg_ParseTupleAndKeywords(
- args, kwds, "I|i:load_glyph", (char **)names, &glyph_index, &flags)) {
- return NULL;
- }
-
- CALL_CPP("load_glyph", (self->x->load_glyph(glyph_index, flags)));
-
- return PyGlyph_new(self->x->get_face(),
- self->x->get_last_glyph(),
- self->x->get_last_glyph_index(),
- self->x->get_hinting_factor());
-}
-
-const char *PyFT2Font_get_width_height__doc__ =
- "w, h = get_width_height()\n"
- "\n"
- "Get the width and height in 26.6 subpixels of the current string set by set_text\n"
- "The rotation of the string is accounted for. To get width and height\n"
- "in pixels, divide these values by 64\n";
-
-static PyObject *PyFT2Font_get_width_height(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- long width, height;
-
- CALL_CPP("get_width_height", (self->x->get_width_height(&width, &height)));
-
- return Py_BuildValue("ll", width, height);
-}
-
-const char *PyFT2Font_get_bitmap_offset__doc__ =
- "x, y = get_bitmap_offset()\n"
- "\n"
- "Get the offset in 26.6 subpixels for the bitmap if ink hangs left or below (0, 0).\n"
- "Since matplotlib only supports left-to-right text, y is always 0.\n";
-
-static PyObject *PyFT2Font_get_bitmap_offset(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- long x, y;
-
- CALL_CPP("get_bitmap_offset", (self->x->get_bitmap_offset(&x, &y)));
-
- return Py_BuildValue("ll", x, y);
-}
-
-const char *PyFT2Font_get_descent__doc__ =
- "d = get_descent()\n"
- "\n"
- "Get the descent of the current string set by set_text in 26.6 subpixels.\n"
- "The rotation of the string is accounted for. To get the descent\n"
- "in pixels, divide this value by 64.\n";
-
-static PyObject *PyFT2Font_get_descent(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- long descent;
-
- CALL_CPP("get_descent", (descent = self->x->get_descent()));
-
- return PyLong_FromLong(descent);
-}
-
-const char *PyFT2Font_draw_glyphs_to_bitmap__doc__ =
- "draw_glyphs_to_bitmap()\n"
- "\n"
- "Draw the glyphs that were loaded by set_text to the bitmap\n"
- "The bitmap size will be automatically set to include the glyphs\n";
-
-static PyObject *PyFT2Font_draw_glyphs_to_bitmap(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- int antialiased = 1;
- const char *names[] = { "antialiased", NULL };
-
- if (!PyArg_ParseTupleAndKeywords(
- args, kwds, "|i:draw_glyphs_to_bitmap", (char **)names, &antialiased)) {
- return NULL;
- }
-
- CALL_CPP("draw_glyphs_to_bitmap", (self->x->draw_glyphs_to_bitmap(antialiased)));
-
- Py_RETURN_NONE;
-}
-
-const char *PyFT2Font_get_xys__doc__ =
- "get_xys()\n"
- "\n"
- "Get the xy locations of the current glyphs\n";
-
-static PyObject *PyFT2Font_get_xys(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- int antialiased = 1;
- std::vector<double> xys;
- const char *names[] = { "antialiased", NULL };
-
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "|i:get_xys", (char **)names, &antialiased)) {
- return NULL;
- }
-
- CALL_CPP("get_xys", (self->x->get_xys(antialiased, xys)));
-
- return convert_xys_to_array(xys);
-}
-
-const char *PyFT2Font_draw_glyph_to_bitmap__doc__ =
- "draw_glyph_to_bitmap(bitmap, x, y, glyph)\n"
- "\n"
- "Draw a single glyph to the bitmap at pixel locations x,y\n"
- "Note it is your responsibility to set up the bitmap manually\n"
- "with set_bitmap_size(w,h) before this call is made.\n"
- "\n"
- "If you want automatic layout, use set_text in combinations with\n"
- "draw_glyphs_to_bitmap. This function is intended for people who\n"
- "want to render individual glyphs at precise locations, eg, a\n"
- "a glyph returned by load_char\n";
-
-static PyObject *PyFT2Font_draw_glyph_to_bitmap(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- PyFT2Image *image;
- double xd, yd;
- PyGlyph *glyph;
- int antialiased = 1;
- const char *names[] = { "image", "x", "y", "glyph", "antialiased", NULL };
-
- if (!PyArg_ParseTupleAndKeywords(args,
- kwds,
- "O!ddO!|i:draw_glyph_to_bitmap",
- (char **)names,
- &PyFT2ImageType,
- &image,
- &xd,
- &yd,
- &PyGlyphType,
- &glyph,
- &antialiased)) {
- return NULL;
- }
-
- CALL_CPP("draw_glyph_to_bitmap",
- self->x->draw_glyph_to_bitmap(*(image->x), xd, yd, glyph->glyphInd, antialiased));
-
- Py_RETURN_NONE;
-}
-
-const char *PyFT2Font_get_glyph_name__doc__ =
- "get_glyph_name(index)\n"
- "\n"
- "Retrieves the ASCII name of a given glyph in a face.\n";
-
-static PyObject *PyFT2Font_get_glyph_name(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- unsigned int glyph_number;
- char buffer[128];
-
- if (!PyArg_ParseTuple(args, "I:get_glyph_name", &glyph_number)) {
- return NULL;
- }
-
- CALL_CPP("get_glyph_name", (self->x->get_glyph_name(glyph_number, buffer)));
-
- return PyUnicode_FromString(buffer);
-}
-
-const char *PyFT2Font_get_charmap__doc__ =
- "get_charmap()\n"
- "\n"
- "Returns a dictionary that maps the character codes of the selected charmap\n"
- "(Unicode by default) to their corresponding glyph indices.\n";
-
-static PyObject *PyFT2Font_get_charmap(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- PyObject *charmap;
-
- charmap = PyDict_New();
- if (charmap == NULL) {
- return NULL;
- }
-
- FT_UInt index;
- FT_ULong code = FT_Get_First_Char(self->x->get_face(), &index);
- while (index != 0) {
- PyObject *key;
- PyObject *val;
-
- key = PyLong_FromLong(code);
- if (key == NULL) {
- Py_DECREF(charmap);
- return NULL;
- }
-
- val = PyLong_FromLong(index);
- if (val == NULL) {
- Py_DECREF(key);
- Py_DECREF(charmap);
- return NULL;
- }
-
- if (PyDict_SetItem(charmap, key, val)) {
- Py_DECREF(key);
- Py_DECREF(val);
- Py_DECREF(charmap);
- return NULL;
- }
-
- Py_DECREF(key);
- Py_DECREF(val);
-
- code = FT_Get_Next_Char(self->x->get_face(), code, &index);
- }
-
- return charmap;
-}
-
-
-const char *PyFT2Font_get_char_index__doc__ =
- "get_char_index()\n"
- "\n"
- "Given a character code, returns a glyph index.\n";
-
-static PyObject *PyFT2Font_get_char_index(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- FT_UInt index;
- FT_ULong ccode;
-
- if (!PyArg_ParseTuple(args, "k:get_char_index", &ccode)) {
- return NULL;
- }
-
- index = FT_Get_Char_Index(self->x->get_face(), ccode);
-
- return PyLong_FromLong(index);
-}
-
-
-const char *PyFT2Font_get_sfnt__doc__ =
- "get_sfnt(name)\n"
- "\n"
- "Get all values from the SFNT names table. Result is a dictionary whose"
- "key is the platform-ID, ISO-encoding-scheme, language-code, and"
- "description.\n";
-
-static PyObject *PyFT2Font_get_sfnt(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- PyObject *names;
-
- if (!(self->x->get_face()->face_flags & FT_FACE_FLAG_SFNT)) {
- PyErr_SetString(PyExc_ValueError, "No SFNT name table");
- return NULL;
- }
-
- size_t count = FT_Get_Sfnt_Name_Count(self->x->get_face());
-
- names = PyDict_New();
- if (names == NULL) {
- return NULL;
- }
-
- for (FT_UInt j = 0; j < count; ++j) {
- FT_SfntName sfnt;
- FT_Error error = FT_Get_Sfnt_Name(self->x->get_face(), j, &sfnt);
-
- if (error) {
- Py_DECREF(names);
- PyErr_SetString(PyExc_ValueError, "Could not get SFNT name");
- return NULL;
- }
-
- PyObject *key = Py_BuildValue(
- "HHHH", sfnt.platform_id, sfnt.encoding_id, sfnt.language_id, sfnt.name_id);
- if (key == NULL) {
- Py_DECREF(names);
- return NULL;
- }
-
- PyObject *val = PyBytes_FromStringAndSize((const char *)sfnt.string, sfnt.string_len);
- if (val == NULL) {
- Py_DECREF(key);
- Py_DECREF(names);
- return NULL;
- }
-
- if (PyDict_SetItem(names, key, val)) {
- Py_DECREF(key);
- Py_DECREF(val);
- Py_DECREF(names);
- return NULL;
- }
-
- Py_DECREF(key);
- Py_DECREF(val);
- }
-
- return names;
-}
-
-const char *PyFT2Font_get_name_index__doc__ =
- "get_name_index(name)\n"
- "\n"
- "Returns the glyph index of a given glyph name.\n"
- "The glyph index 0 means `undefined character code'.\n";
-
-static PyObject *PyFT2Font_get_name_index(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- char *glyphname;
- long name_index;
-
- if (!PyArg_ParseTuple(args, "es:get_name_index", "ascii", &glyphname)) {
- return NULL;
- }
-
- CALL_CPP("get_name_index", name_index = self->x->get_name_index(glyphname));
-
- PyMem_Free(glyphname);
-
- return PyLong_FromLong(name_index);
-}
-
-const char *PyFT2Font_get_ps_font_info__doc__ =
- "get_ps_font_info()\n"
- "\n"
- "Return the information in the PS Font Info structure.\n";
-
-static PyObject *PyFT2Font_get_ps_font_info(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- PS_FontInfoRec fontinfo;
-
- FT_Error error = FT_Get_PS_Font_Info(self->x->get_face(), &fontinfo);
- if (error) {
- PyErr_SetString(PyExc_ValueError, "Could not get PS font info");
- return NULL;
- }
-
- return Py_BuildValue("ssssslbhH",
- fontinfo.version ? fontinfo.version : "",
- fontinfo.notice ? fontinfo.notice : "",
- fontinfo.full_name ? fontinfo.full_name : "",
- fontinfo.family_name ? fontinfo.family_name : "",
- fontinfo.weight ? fontinfo.weight : "",
- fontinfo.italic_angle,
- fontinfo.is_fixed_pitch,
- fontinfo.underline_position,
- fontinfo.underline_thickness);
-}
-
-const char *PyFT2Font_get_sfnt_table__doc__ =
- "get_sfnt_table(name)\n"
- "\n"
- "Return one of the following SFNT tables: head, maxp, OS/2, hhea, "
- "vhea, post, or pclt.\n";
-
-static PyObject *PyFT2Font_get_sfnt_table(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- char *tagname;
-
- if (!PyArg_ParseTuple(args, "es:get_sfnt_table", "ascii", &tagname)) {
- return NULL;
- }
-
- int tag;
- const char *tags[] = { "head", "maxp", "OS/2", "hhea", "vhea", "post", "pclt", NULL };
-
- for (tag = 0; tags[tag] != NULL; tag++) {
- if (strncmp(tagname, tags[tag], 5) == 0) {
- break;
- }
- }
-
- PyMem_Free(tagname);
-
- void *table = FT_Get_Sfnt_Table(self->x->get_face(), (FT_Sfnt_Tag)tag);
- if (!table) {
- Py_RETURN_NONE;
- }
-
- switch (tag) {
- case 0: {
- char head_dict[] =
- "{s:(h,H), s:(h,H), s:l, s:l, s:H, s:H,"
- "s:(l,l), s:(l,l), s:h, s:h, s:h, s:h, s:H, s:H, s:h, s:h, s:h}";
- TT_Header *t = (TT_Header *)table;
- return Py_BuildValue(head_dict,
- "version",
- FIXED_MAJOR(t->Table_Version),
- FIXED_MINOR(t->Table_Version),
- "fontRevision",
- FIXED_MAJOR(t->Font_Revision),
- FIXED_MINOR(t->Font_Revision),
- "checkSumAdjustment",
- t->CheckSum_Adjust,
- "magicNumber",
- t->Magic_Number,
- "flags",
- t->Flags,
- "unitsPerEm",
- t->Units_Per_EM,
- "created",
- t->Created[0],
- t->Created[1],
- "modified",
- t->Modified[0],
- t->Modified[1],
- "xMin",
- t->xMin,
- "yMin",
- t->yMin,
- "xMax",
- t->xMax,
- "yMax",
- t->yMax,
- "macStyle",
- t->Mac_Style,
- "lowestRecPPEM",
- t->Lowest_Rec_PPEM,
- "fontDirectionHint",
- t->Font_Direction,
- "indexToLocFormat",
- t->Index_To_Loc_Format,
- "glyphDataFormat",
- t->Glyph_Data_Format);
- }
- case 1: {
- char maxp_dict[] =
- "{s:(h,H), s:H, s:H, s:H, s:H, s:H, s:H,"
- "s:H, s:H, s:H, s:H, s:H, s:H, s:H, s:H}";
- TT_MaxProfile *t = (TT_MaxProfile *)table;
- return Py_BuildValue(maxp_dict,
- "version",
- FIXED_MAJOR(t->version),
- FIXED_MINOR(t->version),
- "numGlyphs",
- t->numGlyphs,
- "maxPoints",
- t->maxPoints,
- "maxContours",
- t->maxContours,
- "maxComponentPoints",
- t->maxCompositePoints,
- "maxComponentContours",
- t->maxCompositeContours,
- "maxZones",
- t->maxZones,
- "maxTwilightPoints",
- t->maxTwilightPoints,
- "maxStorage",
- t->maxStorage,
- "maxFunctionDefs",
- t->maxFunctionDefs,
- "maxInstructionDefs",
- t->maxInstructionDefs,
- "maxStackElements",
- t->maxStackElements,
- "maxSizeOfInstructions",
- t->maxSizeOfInstructions,
- "maxComponentElements",
- t->maxComponentElements,
- "maxComponentDepth",
- t->maxComponentDepth);
- }
- case 2: {
-#if PY3K
- char os_2_dict[] =
- "{s:H, s:h, s:H, s:H, s:H, s:h, s:h, s:h,"
- "s:h, s:h, s:h, s:h, s:h, s:h, s:h, s:h, s:y#, s:(kkkk),"
- "s:y#, s:H, s:H, s:H}";
-#else
- char os_2_dict[] =
- "{s:H, s:h, s:H, s:H, s:H, s:h, s:h, s:h,"
- "s:h, s:h, s:h, s:h, s:h, s:h, s:h, s:h, s:s#, s:(kkkk),"
- "s:s#, s:H, s:H, s:H}";
-#endif
- TT_OS2 *t = (TT_OS2 *)table;
- return Py_BuildValue(os_2_dict,
- "version",
- t->version,
- "xAvgCharWidth",
- t->xAvgCharWidth,
- "usWeightClass",
- t->usWeightClass,
- "usWidthClass",
- t->usWidthClass,
- "fsType",
- t->fsType,
- "ySubscriptXSize",
- t->ySubscriptXSize,
- "ySubscriptYSize",
- t->ySubscriptYSize,
- "ySubscriptXOffset",
- t->ySubscriptXOffset,
- "ySubscriptYOffset",
- t->ySubscriptYOffset,
- "ySuperscriptXSize",
- t->ySuperscriptXSize,
- "ySuperscriptYSize",
- t->ySuperscriptYSize,
- "ySuperscriptXOffset",
- t->ySuperscriptXOffset,
- "ySuperscriptYOffset",
- t->ySuperscriptYOffset,
- "yStrikeoutSize",
- t->yStrikeoutSize,
- "yStrikeoutPosition",
- t->yStrikeoutPosition,
- "sFamilyClass",
- t->sFamilyClass,
- "panose",
- t->panose,
- Py_ssize_t(10),
- "ulCharRange",
- t->ulUnicodeRange1,
- t->ulUnicodeRange2,
- t->ulUnicodeRange3,
- t->ulUnicodeRange4,
- "achVendID",
- t->achVendID,
- Py_ssize_t(4),
- "fsSelection",
- t->fsSelection,
- "fsFirstCharIndex",
- t->usFirstCharIndex,
- "fsLastCharIndex",
- t->usLastCharIndex);
- }
- case 3: {
- char hhea_dict[] =
- "{s:(h,H), s:h, s:h, s:h, s:H, s:h, s:h, s:h,"
- "s:h, s:h, s:h, s:h, s:H}";
- TT_HoriHeader *t = (TT_HoriHeader *)table;
- return Py_BuildValue(hhea_dict,
- "version",
- FIXED_MAJOR(t->Version),
- FIXED_MINOR(t->Version),
- "ascent",
- t->Ascender,
- "descent",
- t->Descender,
- "lineGap",
- t->Line_Gap,
- "advanceWidthMax",
- t->advance_Width_Max,
- "minLeftBearing",
- t->min_Left_Side_Bearing,
- "minRightBearing",
- t->min_Right_Side_Bearing,
- "xMaxExtent",
- t->xMax_Extent,
- "caretSlopeRise",
- t->caret_Slope_Rise,
- "caretSlopeRun",
- t->caret_Slope_Run,
- "caretOffset",
- t->caret_Offset,
- "metricDataFormat",
- t->metric_Data_Format,
- "numOfLongHorMetrics",
- t->number_Of_HMetrics);
- }
- case 4: {
- char vhea_dict[] =
- "{s:(h,H), s:h, s:h, s:h, s:H, s:h, s:h, s:h,"
- "s:h, s:h, s:h, s:h, s:H}";
- TT_VertHeader *t = (TT_VertHeader *)table;
- return Py_BuildValue(vhea_dict,
- "version",
- FIXED_MAJOR(t->Version),
- FIXED_MINOR(t->Version),
- "vertTypoAscender",
- t->Ascender,
- "vertTypoDescender",
- t->Descender,
- "vertTypoLineGap",
- t->Line_Gap,
- "advanceHeightMax",
- t->advance_Height_Max,
- "minTopSideBearing",
- t->min_Top_Side_Bearing,
- "minBottomSizeBearing",
- t->min_Bottom_Side_Bearing,
- "yMaxExtent",
- t->yMax_Extent,
- "caretSlopeRise",
- t->caret_Slope_Rise,
- "caretSlopeRun",
- t->caret_Slope_Run,
- "caretOffset",
- t->caret_Offset,
- "metricDataFormat",
- t->metric_Data_Format,
- "numOfLongVerMetrics",
- t->number_Of_VMetrics);
- }
- case 5: {
- char post_dict[] = "{s:(h,H), s:(h,H), s:h, s:h, s:k, s:k, s:k, s:k, s:k}";
- TT_Postscript *t = (TT_Postscript *)table;
- return Py_BuildValue(post_dict,
- "format",
- FIXED_MAJOR(t->FormatType),
- FIXED_MINOR(t->FormatType),
- "italicAngle",
- FIXED_MAJOR(t->italicAngle),
- FIXED_MINOR(t->italicAngle),
- "underlinePosition",
- t->underlinePosition,
- "underlineThickness",
- t->underlineThickness,
- "isFixedPitch",
- t->isFixedPitch,
- "minMemType42",
- t->minMemType42,
- "maxMemType42",
- t->maxMemType42,
- "minMemType1",
- t->minMemType1,
- "maxMemType1",
- t->maxMemType1);
- }
- case 6: {
- #if PY3K
- char pclt_dict[] =
- "{s:(h,H), s:k, s:H, s:H, s:H, s:H, s:H, s:H, s:y#, s:y#, s:b, "
- "s:b, s:b}";
- #else
- char pclt_dict[] =
- "{s:(h,H), s:k, s:H, s:H, s:H, s:H, s:H, s:H, s:s#, s:s#, s:b, "
- "s:b, s:b}";
- #endif
- TT_PCLT *t = (TT_PCLT *)table;
- return Py_BuildValue(pclt_dict,
- "version",
- FIXED_MAJOR(t->Version),
- FIXED_MINOR(t->Version),
- "fontNumber",
- t->FontNumber,
- "pitch",
- t->Pitch,
- "xHeight",
- t->xHeight,
- "style",
- t->Style,
- "typeFamily",
- t->TypeFamily,
- "capHeight",
- t->CapHeight,
- "symbolSet",
- t->SymbolSet,
- "typeFace",
- t->TypeFace,
- Py_ssize_t(16),
- "characterComplement",
- t->CharacterComplement,
- Py_ssize_t(8),
- "strokeWeight",
- t->StrokeWeight,
- "widthType",
- t->WidthType,
- "serifStyle",
- t->SerifStyle);
- }
- default:
- Py_RETURN_NONE;
- }
-}
-
-const char *PyFT2Font_get_path__doc__ =
- "get_path()\n"
- "\n"
- "Get the path data from the currently loaded glyph as a tuple of vertices, "
- "codes.\n";
-
-static PyObject *PyFT2Font_get_path(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- int count;
-
- CALL_CPP("get_path", (count = self->x->get_path_count()));
-
- npy_intp vertices_dims[2] = { count, 2 };
- numpy::array_view<double, 2> vertices(vertices_dims);
-
- npy_intp codes_dims[1] = { count };
- numpy::array_view<unsigned char, 1> codes(codes_dims);
-
- self->x->get_path(vertices.data(), codes.data());
-
- return Py_BuildValue("NN", vertices.pyobj(), codes.pyobj());
-}
-
-const char *PyFT2Font_get_image__doc__ =
- "get_image()\n"
- "\n"
- "Returns the underlying image buffer for this font object.\n";
-
-static PyObject *PyFT2Font_get_image(PyFT2Font *self, PyObject *args, PyObject *kwds)
-{
- FT2Image &im = self->x->get_image();
- npy_intp dims[] = {(npy_intp)im.get_height(), (npy_intp)im.get_width() };
- return PyArray_SimpleNewFromData(2, dims, NPY_UBYTE, im.get_buffer());
-}
-
-static PyObject *PyFT2Font_postscript_name(PyFT2Font *self, void *closure)
-{
- const char *ps_name = FT_Get_Postscript_Name(self->x->get_face());
- if (ps_name == NULL) {
- ps_name = "UNAVAILABLE";
- }
-
- return PyUnicode_FromString(ps_name);
-}
-
-static PyObject *PyFT2Font_num_faces(PyFT2Font *self, void *closure)
-{
- return PyLong_FromLong(self->x->get_face()->num_faces);
-}
-
-static PyObject *PyFT2Font_family_name(PyFT2Font *self, void *closure)
-{
- const char *name = self->x->get_face()->family_name;
- if (name == NULL) {
- name = "UNAVAILABLE";
- }
- return PyUnicode_FromString(name);
-}
-
-static PyObject *PyFT2Font_style_name(PyFT2Font *self, void *closure)
-{
- const char *name = self->x->get_face()->style_name;
- if (name == NULL) {
- name = "UNAVAILABLE";
- }
- return PyUnicode_FromString(name);
-}
-
-static PyObject *PyFT2Font_face_flags(PyFT2Font *self, void *closure)
-{
- return PyLong_FromLong(self->x->get_face()->face_flags);
-}
-
-static PyObject *PyFT2Font_style_flags(PyFT2Font *self, void *closure)
-{
- return PyLong_FromLong(self->x->get_face()->style_flags);
-}
-
-static PyObject *PyFT2Font_num_glyphs(PyFT2Font *self, void *closure)
-{
- return PyLong_FromLong(self->x->get_face()->num_glyphs);
-}
-
-static PyObject *PyFT2Font_num_fixed_sizes(PyFT2Font *self, void *closure)
-{
- return PyLong_FromLong(self->x->get_face()->num_fixed_sizes);
-}
-
-static PyObject *PyFT2Font_num_charmaps(PyFT2Font *self, void *closure)
-{
- return PyLong_FromLong(self->x->get_face()->num_charmaps);
-}
-
-static PyObject *PyFT2Font_scalable(PyFT2Font *self, void *closure)
-{
- if (FT_IS_SCALABLE(self->x->get_face())) {
- Py_RETURN_TRUE;
- }
- Py_RETURN_FALSE;
-}
-
-static PyObject *PyFT2Font_units_per_EM(PyFT2Font *self, void *closure)
-{
- return PyLong_FromLong(self->x->get_face()->units_per_EM);
-}
-
-static PyObject *PyFT2Font_get_bbox(PyFT2Font *self, void *closure)
-{
- FT_BBox *bbox = &(self->x->get_face()->bbox);
-
- return Py_BuildValue("llll",
- bbox->xMin, bbox->yMin, bbox->xMax, bbox->yMax);
-}
-
-static PyObject *PyFT2Font_ascender(PyFT2Font *self, void *closure)
-{
- return PyLong_FromLong(self->x->get_face()->ascender);
-}
-
-static PyObject *PyFT2Font_descender(PyFT2Font *self, void *closure)
-{
- return PyLong_FromLong(self->x->get_face()->descender);
-}
-
-static PyObject *PyFT2Font_height(PyFT2Font *self, void *closure)
-{
- return PyLong_FromLong(self->x->get_face()->height);
-}
-
-static PyObject *PyFT2Font_max_advance_width(PyFT2Font *self, void *closure)
-{
- return PyLong_FromLong(self->x->get_face()->max_advance_width);
-}
-
-static PyObject *PyFT2Font_max_advance_height(PyFT2Font *self, void *closure)
-{
- return PyLong_FromLong(self->x->get_face()->max_advance_height);
-}
-
-static PyObject *PyFT2Font_underline_position(PyFT2Font *self, void *closure)
-{
- return PyLong_FromLong(self->x->get_face()->underline_position);
-}
-
-static PyObject *PyFT2Font_underline_thickness(PyFT2Font *self, void *closure)
-{
- return PyLong_FromLong(self->x->get_face()->underline_thickness);
-}
-
-static PyObject *PyFT2Font_fname(PyFT2Font *self, void *closure)
-{
- if (self->fname) {
- Py_INCREF(self->fname);
- return self->fname;
- }
-
- Py_RETURN_NONE;
-}
-
-static int PyFT2Font_get_buffer(PyFT2Font *self, Py_buffer *buf, int flags)
-{
- FT2Image &im = self->x->get_image();
-
- Py_INCREF(self);
- buf->obj = (PyObject *)self;
- buf->buf = im.get_buffer();
- buf->len = im.get_width() * im.get_height();
- buf->readonly = 0;
- buf->format = (char *)"B";
- buf->ndim = 2;
- self->shape[0] = im.get_height();
- self->shape[1] = im.get_width();
- buf->shape = self->shape;
- self->strides[0] = im.get_width();
- self->strides[1] = 1;
- buf->strides = self->strides;
- buf->suboffsets = NULL;
- buf->itemsize = 1;
- buf->internal = NULL;
-
- return 1;
-}
-
-static PyTypeObject *PyFT2Font_init_type(PyObject *m, PyTypeObject *type)
-{
- static PyGetSetDef getset[] = {
- {(char *)"postscript_name", (getter)PyFT2Font_postscript_name, NULL, NULL, NULL},
- {(char *)"num_faces", (getter)PyFT2Font_num_faces, NULL, NULL, NULL},
- {(char *)"family_name", (getter)PyFT2Font_family_name, NULL, NULL, NULL},
- {(char *)"style_name", (getter)PyFT2Font_style_name, NULL, NULL, NULL},
- {(char *)"face_flags", (getter)PyFT2Font_face_flags, NULL, NULL, NULL},
- {(char *)"style_flags", (getter)PyFT2Font_style_flags, NULL, NULL, NULL},
- {(char *)"num_glyphs", (getter)PyFT2Font_num_glyphs, NULL, NULL, NULL},
- {(char *)"num_fixed_sizes", (getter)PyFT2Font_num_fixed_sizes, NULL, NULL, NULL},
- {(char *)"num_charmaps", (getter)PyFT2Font_num_charmaps, NULL, NULL, NULL},
- {(char *)"scalable", (getter)PyFT2Font_scalable, NULL, NULL, NULL},
- {(char *)"units_per_EM", (getter)PyFT2Font_units_per_EM, NULL, NULL, NULL},
- {(char *)"bbox", (getter)PyFT2Font_get_bbox, NULL, NULL, NULL},
- {(char *)"ascender", (getter)PyFT2Font_ascender, NULL, NULL, NULL},
- {(char *)"descender", (getter)PyFT2Font_descender, NULL, NULL, NULL},
- {(char *)"height", (getter)PyFT2Font_height, NULL, NULL, NULL},
- {(char *)"max_advance_width", (getter)PyFT2Font_max_advance_width, NULL, NULL, NULL},
- {(char *)"max_advance_height", (getter)PyFT2Font_max_advance_height, NULL, NULL, NULL},
- {(char *)"underline_position", (getter)PyFT2Font_underline_position, NULL, NULL, NULL},
- {(char *)"underline_thickness", (getter)PyFT2Font_underline_thickness, NULL, NULL, NULL},
- {(char *)"fname", (getter)PyFT2Font_fname, NULL, NULL, NULL},
- {NULL}
- };
-
- static PyMethodDef methods[] = {
- {"clear", (PyCFunction)PyFT2Font_clear, METH_NOARGS, PyFT2Font_clear__doc__},
- {"set_size", (PyCFunction)PyFT2Font_set_size, METH_VARARGS, PyFT2Font_set_size__doc__},
- {"set_charmap", (PyCFunction)PyFT2Font_set_charmap, METH_VARARGS, PyFT2Font_set_charmap__doc__},
- {"select_charmap", (PyCFunction)PyFT2Font_select_charmap, METH_VARARGS, PyFT2Font_select_charmap__doc__},
- {"get_kerning", (PyCFunction)PyFT2Font_get_kerning, METH_VARARGS, PyFT2Font_get_kerning__doc__},
- {"set_text", (PyCFunction)PyFT2Font_set_text, METH_VARARGS|METH_KEYWORDS, PyFT2Font_set_text__doc__},
- {"get_num_glyphs", (PyCFunction)PyFT2Font_get_num_glyphs, METH_NOARGS, PyFT2Font_get_num_glyphs__doc__},
- {"load_char", (PyCFunction)PyFT2Font_load_char, METH_VARARGS|METH_KEYWORDS, PyFT2Font_load_char__doc__},
- {"load_glyph", (PyCFunction)PyFT2Font_load_glyph, METH_VARARGS|METH_KEYWORDS, PyFT2Font_load_glyph__doc__},
- {"get_width_height", (PyCFunction)PyFT2Font_get_width_height, METH_NOARGS, PyFT2Font_get_width_height__doc__},
- {"get_bitmap_offset", (PyCFunction)PyFT2Font_get_bitmap_offset, METH_NOARGS, PyFT2Font_get_bitmap_offset__doc__},
- {"get_descent", (PyCFunction)PyFT2Font_get_descent, METH_NOARGS, PyFT2Font_get_descent__doc__},
- {"draw_glyphs_to_bitmap", (PyCFunction)PyFT2Font_draw_glyphs_to_bitmap, METH_VARARGS|METH_KEYWORDS, PyFT2Font_draw_glyphs_to_bitmap__doc__},
- {"get_xys", (PyCFunction)PyFT2Font_get_xys, METH_VARARGS|METH_KEYWORDS, PyFT2Font_get_xys__doc__},
- {"draw_glyph_to_bitmap", (PyCFunction)PyFT2Font_draw_glyph_to_bitmap, METH_VARARGS|METH_KEYWORDS, PyFT2Font_draw_glyph_to_bitmap__doc__},
- {"get_glyph_name", (PyCFunction)PyFT2Font_get_glyph_name, METH_VARARGS, PyFT2Font_get_glyph_name__doc__},
- {"get_charmap", (PyCFunction)PyFT2Font_get_charmap, METH_NOARGS, PyFT2Font_get_charmap__doc__},
- {"get_char_index", (PyCFunction)PyFT2Font_get_char_index, METH_VARARGS, PyFT2Font_get_char_index__doc__},
- {"get_sfnt", (PyCFunction)PyFT2Font_get_sfnt, METH_NOARGS, PyFT2Font_get_sfnt__doc__},
- {"get_name_index", (PyCFunction)PyFT2Font_get_name_index, METH_VARARGS, PyFT2Font_get_name_index__doc__},
- {"get_ps_font_info", (PyCFunction)PyFT2Font_get_ps_font_info, METH_NOARGS, PyFT2Font_get_ps_font_info__doc__},
- {"get_sfnt_table", (PyCFunction)PyFT2Font_get_sfnt_table, METH_VARARGS, PyFT2Font_get_sfnt_table__doc__},
- {"get_path", (PyCFunction)PyFT2Font_get_path, METH_NOARGS, PyFT2Font_get_path__doc__},
- {"get_image", (PyCFunction)PyFT2Font_get_image, METH_NOARGS, PyFT2Font_get_path__doc__},
- {NULL}
- };
-
- static PyBufferProcs buffer_procs;
- memset(&buffer_procs, 0, sizeof(PyBufferProcs));
- buffer_procs.bf_getbuffer = (getbufferproc)PyFT2Font_get_buffer;
-
- memset(type, 0, sizeof(PyTypeObject));
- type->tp_name = "matplotlib.ft2font.FT2Font";
- type->tp_doc = PyFT2Font_init__doc__;
- type->tp_basicsize = sizeof(PyFT2Font);
- type->tp_dealloc = (destructor)PyFT2Font_dealloc;
- type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_NEWBUFFER;
- type->tp_methods = methods;
- type->tp_getset = getset;
- type->tp_new = PyFT2Font_new;
- type->tp_init = (initproc)PyFT2Font_init;
- type->tp_as_buffer = &buffer_procs;
-
- if (PyType_Ready(type) < 0) {
- return NULL;
- }
-
- if (PyModule_AddObject(m, "FT2Font", (PyObject *)type)) {
- return NULL;
- }
-
- return type;
-}
-
-extern "C" {
-
-#if PY3K
-static struct PyModuleDef moduledef = {
- PyModuleDef_HEAD_INIT,
- "ft2font",
- NULL,
- 0,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL
-};
-
-#define INITERROR return NULL
-
-PyMODINIT_FUNC PyInit_ft2font(void)
-
-#else
-#define INITERROR return
-
-PyMODINIT_FUNC initft2font(void)
-#endif
-
-{
- PyObject *m;
-
-#if PY3K
- m = PyModule_Create(&moduledef);
-#else
- m = Py_InitModule3("ft2font", NULL, NULL);
-#endif
-
- if (m == NULL) {
- INITERROR;
- }
-
- if (!PyFT2Image_init_type(m, &PyFT2ImageType)) {
- INITERROR;
- }
-
- if (!PyGlyph_init_type(m, &PyGlyphType)) {
- INITERROR;
- }
-
- if (!PyFT2Font_init_type(m, &PyFT2FontType)) {
- INITERROR;
- }
-
- PyObject *d = PyModule_GetDict(m);
-
- if (add_dict_int(d, "SCALABLE", FT_FACE_FLAG_SCALABLE) ||
- add_dict_int(d, "FIXED_SIZES", FT_FACE_FLAG_FIXED_SIZES) ||
- add_dict_int(d, "FIXED_WIDTH", FT_FACE_FLAG_FIXED_WIDTH) ||
- add_dict_int(d, "SFNT", FT_FACE_FLAG_SFNT) ||
- add_dict_int(d, "HORIZONTAL", FT_FACE_FLAG_HORIZONTAL) ||
- add_dict_int(d, "VERTICAL", FT_FACE_FLAG_VERTICAL) ||
- add_dict_int(d, "KERNING", FT_FACE_FLAG_KERNING) ||
- add_dict_int(d, "FAST_GLYPHS", FT_FACE_FLAG_FAST_GLYPHS) ||
- add_dict_int(d, "MULTIPLE_MASTERS", FT_FACE_FLAG_MULTIPLE_MASTERS) ||
- add_dict_int(d, "GLYPH_NAMES", FT_FACE_FLAG_GLYPH_NAMES) ||
- add_dict_int(d, "EXTERNAL_STREAM", FT_FACE_FLAG_EXTERNAL_STREAM) ||
- add_dict_int(d, "ITALIC", FT_STYLE_FLAG_ITALIC) ||
- add_dict_int(d, "BOLD", FT_STYLE_FLAG_BOLD) ||
- add_dict_int(d, "KERNING_DEFAULT", FT_KERNING_DEFAULT) ||
- add_dict_int(d, "KERNING_UNFITTED", FT_KERNING_UNFITTED) ||
- add_dict_int(d, "KERNING_UNSCALED", FT_KERNING_UNSCALED) ||
- add_dict_int(d, "LOAD_DEFAULT", FT_LOAD_DEFAULT) ||
- add_dict_int(d, "LOAD_NO_SCALE", FT_LOAD_NO_SCALE) ||
- add_dict_int(d, "LOAD_NO_HINTING", FT_LOAD_NO_HINTING) ||
- add_dict_int(d, "LOAD_RENDER", FT_LOAD_RENDER) ||
- add_dict_int(d, "LOAD_NO_BITMAP", FT_LOAD_NO_BITMAP) ||
- add_dict_int(d, "LOAD_VERTICAL_LAYOUT", FT_LOAD_VERTICAL_LAYOUT) ||
- add_dict_int(d, "LOAD_FORCE_AUTOHINT", FT_LOAD_FORCE_AUTOHINT) ||
- add_dict_int(d, "LOAD_CROP_BITMAP", FT_LOAD_CROP_BITMAP) ||
- add_dict_int(d, "LOAD_PEDANTIC", FT_LOAD_PEDANTIC) ||
- add_dict_int(d, "LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH", FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH) ||
- add_dict_int(d, "LOAD_NO_RECURSE", FT_LOAD_NO_RECURSE) ||
- add_dict_int(d, "LOAD_IGNORE_TRANSFORM", FT_LOAD_IGNORE_TRANSFORM) ||
- add_dict_int(d, "LOAD_MONOCHROME", FT_LOAD_MONOCHROME) ||
- add_dict_int(d, "LOAD_LINEAR_DESIGN", FT_LOAD_LINEAR_DESIGN) ||
- add_dict_int(d, "LOAD_NO_AUTOHINT", (unsigned long)FT_LOAD_NO_AUTOHINT) ||
- add_dict_int(d, "LOAD_TARGET_NORMAL", (unsigned long)FT_LOAD_TARGET_NORMAL) ||
- add_dict_int(d, "LOAD_TARGET_LIGHT", (unsigned long)FT_LOAD_TARGET_LIGHT) ||
- add_dict_int(d, "LOAD_TARGET_MONO", (unsigned long)FT_LOAD_TARGET_MONO) ||
- add_dict_int(d, "LOAD_TARGET_LCD", (unsigned long)FT_LOAD_TARGET_LCD) ||
- add_dict_int(d, "LOAD_TARGET_LCD_V", (unsigned long)FT_LOAD_TARGET_LCD_V)) {
- INITERROR;
- }
-
- // initialize library
- int error = FT_Init_FreeType(&_ft2Library);
-
- if (error) {
- PyErr_SetString(PyExc_RuntimeError, "Could not initialize the freetype2 library");
- INITERROR;
- }
-
- {
- FT_Int major, minor, patch;
- char version_string[64];
-
- FT_Library_Version(_ft2Library, &major, &minor, &patch);
- sprintf(version_string, "%d.%d.%d", major, minor, patch);
- if (PyModule_AddStringConstant(m, "__freetype_version__", version_string)) {
- INITERROR;
- }
- }
-
- if (PyModule_AddStringConstant(m, "__freetype_build_type__", STRINGIFY(FREETYPE_BUILD_TYPE))) {
- INITERROR;
- }
-
- import_array();
-
-#if PY3K
- return m;
-#endif
-}
-
-} // extern "C"
diff --git a/contrib/python/matplotlib/py2/src/mplutils.cpp b/contrib/python/matplotlib/py2/src/mplutils.cpp
deleted file mode 100644
index bc09db52aa..0000000000
--- a/contrib/python/matplotlib/py2/src/mplutils.cpp
+++ /dev/null
@@ -1,21 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-#include "mplutils.h"
-
-int add_dict_int(PyObject *dict, const char *key, long val)
-{
- PyObject *valobj;
- valobj = PyLong_FromLong(val);
- if (valobj == NULL) {
- return 1;
- }
-
- if (PyDict_SetItemString(dict, (char *)key, valobj)) {
- Py_DECREF(valobj);
- return 1;
- }
-
- Py_DECREF(valobj);
-
- return 0;
-}
diff --git a/contrib/python/matplotlib/py2/src/mplutils.h b/contrib/python/matplotlib/py2/src/mplutils.h
deleted file mode 100644
index 4b59e08bbd..0000000000
--- a/contrib/python/matplotlib/py2/src/mplutils.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-/* Small utilities that are shared by most extension modules. */
-
-#ifndef _MPLUTILS_H
-#define _MPLUTILS_H
-#define PY_SSIZE_T_CLEAN
-
-#if defined(_MSC_VER) && _MSC_VER <= 1600
-typedef unsigned __int8 uint8_t;
-#else
-#include <stdint.h>
-#endif
-
-#ifdef _POSIX_C_SOURCE
-# undef _POSIX_C_SOURCE
-#endif
-#ifndef _AIX
-#ifdef _XOPEN_SOURCE
-# undef _XOPEN_SOURCE
-#endif
-#endif
-
-// Prevent multiple conflicting definitions of swab from stdlib.h and unistd.h
-#if defined(__sun) || defined(sun)
-#if defined(_XPG4)
-#undef _XPG4
-#endif
-#if defined(_XPG3)
-#undef _XPG3
-#endif
-#endif
-
-#include <Python.h>
-
-#if PY_MAJOR_VERSION >= 3
-#define PY3K 1
-#define Py_TPFLAGS_HAVE_NEWBUFFER 0
-#else
-#define PY3K 0
-#endif
-
-#undef CLAMP
-#define CLAMP(x, low, high) (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
-
-#undef MAX
-#define MAX(a, b) (((a) > (b)) ? (a) : (b))
-
-inline double mpl_round(double v)
-{
- return (double)(int)(v + ((v >= 0.0) ? 0.5 : -0.5));
-}
-
-enum {
- STOP = 0,
- MOVETO = 1,
- LINETO = 2,
- CURVE3 = 3,
- CURVE4 = 4,
- ENDPOLY = 0x4f
-};
-
-const size_t NUM_VERTICES[] = { 1, 1, 1, 2, 3, 1 };
-
-extern "C" int add_dict_int(PyObject *dict, const char *key, long val);
-
-#if defined(_MSC_VER) && (_MSC_VER < 1800)
-namespace std {
- inline bool isfinite(double num) { return _finite(num); }
-}
-#endif
-
-#endif
diff --git a/contrib/python/matplotlib/py2/src/numpy_cpp.h b/contrib/python/matplotlib/py2/src/numpy_cpp.h
deleted file mode 100644
index 75f773ee58..0000000000
--- a/contrib/python/matplotlib/py2/src/numpy_cpp.h
+++ /dev/null
@@ -1,569 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-#ifndef _NUMPY_CPP_H_
-#define _NUMPY_CPP_H_
-#define PY_SSIZE_T_CLEAN
-/***************************************************************************
- * This file is based on original work by Mark Wiebe, available at:
- *
- * http://github.com/mwiebe/numpy-cpp
- *
- * However, the needs of matplotlib wrappers, such as treating an
- * empty array as having the correct dimensions, have made this rather
- * matplotlib-specific, so it's no longer compatible with the
- * original.
- */
-
-#include "py_exceptions.h"
-
-#include <complex>
-
-#ifdef _POSIX_C_SOURCE
-# undef _POSIX_C_SOURCE
-#endif
-#ifndef _AIX
-#ifdef _XOPEN_SOURCE
-# undef _XOPEN_SOURCE
-#endif
-#endif
-
-// Prevent multiple conflicting definitions of swab from stdlib.h and unistd.h
-#if defined(__sun) || defined(sun)
-#if defined(_XPG4)
-#undef _XPG4
-#endif
-#if defined(_XPG3)
-#undef _XPG3
-#endif
-#endif
-
-#include <Python.h>
-#include <numpy/ndarrayobject.h>
-
-namespace numpy
-{
-
-// Type traits for the NumPy types
-template <typename T>
-struct type_num_of;
-
-/* Be careful with bool arrays as python has sizeof(npy_bool) == 1, but it is
- * not always the case that sizeof(bool) == 1. Using the array_view_accessors
- * is always fine regardless of sizeof(bool), so do this rather than using
- * array.data() and pointer arithmetic which will not work correctly if
- * sizeof(bool) != 1. */
-template <> struct type_num_of<bool>
-{
- enum {
- value = NPY_BOOL
- };
-};
-template <>
-struct type_num_of<npy_byte>
-{
- enum {
- value = NPY_BYTE
- };
-};
-template <>
-struct type_num_of<npy_ubyte>
-{
- enum {
- value = NPY_UBYTE
- };
-};
-template <>
-struct type_num_of<npy_short>
-{
- enum {
- value = NPY_SHORT
- };
-};
-template <>
-struct type_num_of<npy_ushort>
-{
- enum {
- value = NPY_USHORT
- };
-};
-template <>
-struct type_num_of<npy_int>
-{
- enum {
- value = NPY_INT
- };
-};
-template <>
-struct type_num_of<npy_uint>
-{
- enum {
- value = NPY_UINT
- };
-};
-template <>
-struct type_num_of<npy_long>
-{
- enum {
- value = NPY_LONG
- };
-};
-template <>
-struct type_num_of<npy_ulong>
-{
- enum {
- value = NPY_ULONG
- };
-};
-template <>
-struct type_num_of<npy_longlong>
-{
- enum {
- value = NPY_LONGLONG
- };
-};
-template <>
-struct type_num_of<npy_ulonglong>
-{
- enum {
- value = NPY_ULONGLONG
- };
-};
-template <>
-struct type_num_of<npy_float>
-{
- enum {
- value = NPY_FLOAT
- };
-};
-template <>
-struct type_num_of<npy_double>
-{
- enum {
- value = NPY_DOUBLE
- };
-};
-#if NPY_LONGDOUBLE != NPY_DOUBLE
-template <>
-struct type_num_of<npy_longdouble>
-{
- enum {
- value = NPY_LONGDOUBLE
- };
-};
-#endif
-template <>
-struct type_num_of<npy_cfloat>
-{
- enum {
- value = NPY_CFLOAT
- };
-};
-template <>
-struct type_num_of<std::complex<npy_float> >
-{
- enum {
- value = NPY_CFLOAT
- };
-};
-template <>
-struct type_num_of<npy_cdouble>
-{
- enum {
- value = NPY_CDOUBLE
- };
-};
-template <>
-struct type_num_of<std::complex<npy_double> >
-{
- enum {
- value = NPY_CDOUBLE
- };
-};
-#if NPY_CLONGDOUBLE != NPY_CDOUBLE
-template <>
-struct type_num_of<npy_clongdouble>
-{
- enum {
- value = NPY_CLONGDOUBLE
- };
-};
-template <>
-struct type_num_of<std::complex<npy_longdouble> >
-{
- enum {
- value = NPY_CLONGDOUBLE
- };
-};
-#endif
-template <>
-struct type_num_of<PyObject *>
-{
- enum {
- value = NPY_OBJECT
- };
-};
-template <typename T>
-struct type_num_of<T &>
-{
- enum {
- value = type_num_of<T>::value
- };
-};
-template <typename T>
-struct type_num_of<const T>
-{
- enum {
- value = type_num_of<T>::value
- };
-};
-
-template <typename T>
-struct is_const
-{
- enum {
- value = false
- };
-};
-template <typename T>
-struct is_const<const T>
-{
- enum {
- value = true
- };
-};
-
-namespace detail
-{
-template <template <typename, int> class AV, typename T, int ND>
-class array_view_accessors;
-
-template <template <typename, int> class AV, typename T>
-class array_view_accessors<AV, T, 1>
-{
- public:
- typedef AV<T, 1> AVC;
- typedef T sub_t;
-
- T &operator()(npy_intp i)
- {
- AVC *self = static_cast<AVC *>(this);
-
- return *reinterpret_cast<T *>(self->m_data + self->m_strides[0] * i);
- }
-
- const T &operator()(npy_intp i) const
- {
- const AVC *self = static_cast<const AVC *>(this);
-
- return *reinterpret_cast<const T *>(self->m_data + self->m_strides[0] * i);
- }
-
- T &operator[](npy_intp i)
- {
- AVC *self = static_cast<AVC *>(this);
-
- return *reinterpret_cast<T *>(self->m_data + self->m_strides[0] * i);
- }
-
- const T &operator[](npy_intp i) const
- {
- const AVC *self = static_cast<const AVC *>(this);
-
- return *reinterpret_cast<const T *>(self->m_data + self->m_strides[0] * i);
- }
-};
-
-template <template <typename, int> class AV, typename T>
-class array_view_accessors<AV, T, 2>
-{
- public:
- typedef AV<T, 2> AVC;
- typedef AV<T, 1> sub_t;
-
- T &operator()(npy_intp i, npy_intp j)
- {
- AVC *self = static_cast<AVC *>(this);
-
- return *reinterpret_cast<T *>(self->m_data + self->m_strides[0] * i +
- self->m_strides[1] * j);
- }
-
- const T &operator()(npy_intp i, npy_intp j) const
- {
- const AVC *self = static_cast<const AVC *>(this);
-
- return *reinterpret_cast<const T *>(self->m_data + self->m_strides[0] * i +
- self->m_strides[1] * j);
- }
-
- sub_t subarray(npy_intp i) const
- {
- const AVC *self = static_cast<const AVC *>(this);
-
- return sub_t(self->m_arr,
- self->m_data + self->m_strides[0] * i,
- self->m_shape + 1,
- self->m_strides + 1);
- }
-};
-
-template <template <typename, int> class AV, typename T>
-class array_view_accessors<AV, T, 3>
-{
- public:
- typedef AV<T, 3> AVC;
- typedef AV<T, 2> sub_t;
-
- T &operator()(npy_intp i, npy_intp j, npy_intp k)
- {
- AVC *self = static_cast<AVC *>(this);
-
- return *reinterpret_cast<T *>(self->m_data + self->m_strides[0] * i +
- self->m_strides[1] * j + self->m_strides[2] * k);
- }
-
- const T &operator()(npy_intp i, npy_intp j, npy_intp k) const
- {
- const AVC *self = static_cast<const AVC *>(this);
-
- return *reinterpret_cast<const T *>(self->m_data + self->m_strides[0] * i +
- self->m_strides[1] * j + self->m_strides[2] * k);
- }
-
- sub_t subarray(npy_intp i) const
- {
- const AVC *self = static_cast<const AVC *>(this);
-
- return sub_t(self->m_arr,
- self->m_data + self->m_strides[0] * i,
- self->m_shape + 1,
- self->m_strides + 1);
- }
-
-
-};
-
-// When adding instantiations of array_view_accessors, remember to add entries
-// to zeros[] below.
-
-}
-
-static npy_intp zeros[] = { 0, 0, 0 };
-
-template <typename T, int ND>
-class array_view : public detail::array_view_accessors<array_view, T, ND>
-{
- friend class detail::array_view_accessors<numpy::array_view, T, ND>;
-
- private:
- // Copies of the array data
- PyArrayObject *m_arr;
- npy_intp *m_shape;
- npy_intp *m_strides;
- char *m_data;
-
- public:
- typedef T value_type;
-
- enum {
- ndim = ND
- };
-
- array_view() : m_arr(NULL), m_data(NULL)
- {
- m_shape = zeros;
- m_strides = zeros;
- }
-
- array_view(PyObject *arr, bool contiguous = false) : m_arr(NULL), m_data(NULL)
- {
- if (!set(arr, contiguous)) {
- throw py::exception();
- }
- }
-
- array_view(const array_view &other) : m_arr(NULL), m_data(NULL)
- {
- m_arr = other.m_arr;
- Py_XINCREF(m_arr);
- m_data = other.m_data;
- m_shape = other.m_shape;
- m_strides = other.m_strides;
- }
-
- array_view(PyArrayObject *arr, char *data, npy_intp *shape, npy_intp *strides)
- {
- m_arr = arr;
- Py_XINCREF(arr);
- m_data = data;
- m_shape = shape;
- m_strides = strides;
- }
-
- array_view(npy_intp shape[ND]) : m_arr(NULL), m_shape(NULL), m_strides(NULL), m_data(NULL)
- {
- PyObject *arr = PyArray_SimpleNew(ND, shape, type_num_of<T>::value);
- if (arr == NULL) {
- throw py::exception();
- }
- if (!set(arr, true)) {
- Py_DECREF(arr);
- throw py::exception();
- }
- Py_DECREF(arr);
- }
-
- ~array_view()
- {
- Py_XDECREF(m_arr);
- }
-
- array_view& operator=(const array_view &other)
- {
- if (this != &other)
- {
- Py_XDECREF(m_arr);
- m_arr = other.m_arr;
- Py_XINCREF(m_arr);
- m_data = other.m_data;
- m_shape = other.m_shape;
- m_strides = other.m_strides;
- }
- return *this;
- }
-
- int set(PyObject *arr, bool contiguous = false)
- {
- PyArrayObject *tmp;
-
- if (arr == NULL || arr == Py_None) {
- Py_XDECREF(m_arr);
- m_arr = NULL;
- m_data = NULL;
- m_shape = zeros;
- m_strides = zeros;
- } else {
- if (contiguous) {
- tmp = (PyArrayObject *)PyArray_ContiguousFromAny(arr, type_num_of<T>::value, 0, ND);
- } else {
- tmp = (PyArrayObject *)PyArray_FromObject(arr, type_num_of<T>::value, 0, ND);
- }
- if (tmp == NULL) {
- return 0;
- }
-
- if (PyArray_NDIM(tmp) == 0 || PyArray_DIM(tmp, 0) == 0) {
- Py_XDECREF(m_arr);
- m_arr = NULL;
- m_data = NULL;
- m_shape = zeros;
- m_strides = zeros;
- if (PyArray_NDIM(tmp) == 0 && ND == 0) {
- m_arr = tmp;
- return 1;
- }
- }
- if (PyArray_NDIM(tmp) != ND) {
- PyErr_Format(PyExc_ValueError,
- "Expected %d-dimensional array, got %d",
- ND,
- PyArray_NDIM(tmp));
- Py_DECREF(tmp);
- return 0;
- }
-
- /* Copy some of the data to the view object for faster access */
- Py_XDECREF(m_arr);
- m_arr = tmp;
- m_shape = PyArray_DIMS(m_arr);
- m_strides = PyArray_STRIDES(m_arr);
- m_data = (char *)PyArray_BYTES(tmp);
- }
-
- return 1;
- }
-
- npy_intp dim(size_t i) const
- {
- if (i >= ND) {
- return 0;
- }
- return m_shape[i];
- }
-
- /*
- In most cases, code should use size() instead of dim(0), since
- size() == 0 when any dimension is 0.
- */
- size_t size() const
- {
- bool empty = (ND == 0);
- for (size_t i = 0; i < ND; i++) {
- if (m_shape[i] == 0) {
- empty = true;
- }
- }
- if (empty) {
- return 0;
- } else {
- return (size_t)dim(0);
- }
- }
-
- bool empty() const
- {
- return size() == 0;
- }
-
- // Do not use this for array_view<bool, ND>. See comment near top of file.
- const T *data() const
- {
- return (const T *)m_data;
- }
-
- // Do not use this for array_view<bool, ND>. See comment near top of file.
- T *data()
- {
- return (T *)m_data;
- }
-
- // Return a new reference.
- PyObject *pyobj()
- {
- Py_XINCREF(m_arr);
- return (PyObject *)m_arr;
- }
-
- // Steal a reference.
- PyObject *pyobj_steal()
- {
- return (PyObject *)m_arr;
- }
-
- static int converter(PyObject *obj, void *arrp)
- {
- array_view<T, ND> *arr = (array_view<T, ND> *)arrp;
-
- if (!arr->set(obj)) {
- return 0;
- }
-
- return 1;
- }
-
- static int converter_contiguous(PyObject *obj, void *arrp)
- {
- array_view<T, ND> *arr = (array_view<T, ND> *)arrp;
-
- if (!arr->set(obj, true)) {
- return 0;
- }
-
- return 1;
- }
-};
-
-} // namespace numpy
-
-
-#endif
diff --git a/contrib/python/matplotlib/py2/src/path_cleanup.cpp b/contrib/python/matplotlib/py2/src/path_cleanup.cpp
deleted file mode 100644
index f9f2213b3d..0000000000
--- a/contrib/python/matplotlib/py2/src/path_cleanup.cpp
+++ /dev/null
@@ -1,113 +0,0 @@
-/* -*- 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
deleted file mode 100644
index b481395aa5..0000000000
--- a/contrib/python/matplotlib/py2/src/path_cleanup.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/* -*- 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 */
diff --git a/contrib/python/matplotlib/py2/src/path_converters.h b/contrib/python/matplotlib/py2/src/path_converters.h
deleted file mode 100644
index db40c18d5a..0000000000
--- a/contrib/python/matplotlib/py2/src/path_converters.h
+++ /dev/null
@@ -1,1011 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-#ifndef __PATH_CONVERTERS_H__
-#define __PATH_CONVERTERS_H__
-
-#include <cmath>
-#include <stdint.h>
-#include "agg_path_storage.h"
-#include "agg_clip_liang_barsky.h"
-#include "mplutils.h"
-#include "agg_conv_segmentator.h"
-
-/*
- This file contains a number of vertex converters that modify
- paths. They all work as iterators, where the output is generated
- on-the-fly, and don't require a copy of the full data.
-
- Each class represents a discrete step in a "path-cleansing" pipeline.
- They are currently applied in the following order in the Agg backend:
-
- 1. Affine transformation (implemented in Agg, not here)
-
- 2. PathNanRemover: skips over segments containing non-finite numbers
- by inserting MOVETO commands
-
- 3. PathClipper: Clips line segments to a given rectangle. This is
- helpful for data reduction, and also to avoid a limitation in
- Agg where coordinates can not be larger than 24-bit signed
- integers.
-
- 4. PathSnapper: Rounds the path to the nearest center-pixels.
- This makes rectilinear curves look much better.
-
- 5. PathSimplifier: Removes line segments from highly dense paths
- that would not have an impact on their appearance. Speeds up
- rendering and reduces file sizes.
-
- 6. curve-to-line-segment conversion (implemented in Agg, not here)
-
- 7. stroking (implemented in Agg, not here)
- */
-
-/************************************************************
- This is a base class for vertex converters that need to queue their
- output. It is designed to be as fast as possible vs. the STL's queue
- which is more flexible.
- */
-template <int QueueSize>
-class EmbeddedQueue
-{
- protected:
- EmbeddedQueue() : m_queue_read(0), m_queue_write(0)
- {
- // empty
- }
-
- struct item
- {
- item()
- {
- }
-
- inline void set(const unsigned cmd_, const double x_, const double y_)
- {
- cmd = cmd_;
- x = x_;
- y = y_;
- }
- unsigned cmd;
- double x;
- double y;
- };
- int m_queue_read;
- int m_queue_write;
- item m_queue[QueueSize];
-
- inline void queue_push(const unsigned cmd, const double x, const double y)
- {
- m_queue[m_queue_write++].set(cmd, x, y);
- }
-
- inline bool queue_nonempty()
- {
- return m_queue_read < m_queue_write;
- }
-
- inline bool queue_pop(unsigned *cmd, double *x, double *y)
- {
- if (queue_nonempty()) {
- const item &front = m_queue[m_queue_read++];
- *cmd = front.cmd;
- *x = front.x;
- *y = front.y;
-
- return true;
- }
-
- m_queue_read = 0;
- m_queue_write = 0;
-
- return false;
- }
-
- inline void queue_clear()
- {
- m_queue_read = 0;
- m_queue_write = 0;
- }
-};
-
-/* Defines when path segment types have more than one vertex */
-static const size_t num_extra_points_map[] =
- {0, 0, 0, 1,
- 2, 0, 0, 0,
- 0, 0, 0, 0,
- 0, 0, 0, 0
- };
-
-/* An implementation of a simple linear congruential random number
- generator. This is a "classic" and fast RNG which works fine for
- our purposes of sketching lines, but should not be used for things
- that matter, like crypto. We are implementing this ourselves
- rather than using the C stdlib so that the seed state is not shared
- with other third-party code. There are recent C++ options, but we
- still require nothing later than C++98 for compatibility
- reasons. */
-class RandomNumberGenerator
-{
-private:
- /* These are the same constants from MS Visual C++, which
- has the nice property that the modulus is 2^32, thus
- saving an explicit modulo operation
- */
- static const uint32_t a = 214013;
- static const uint32_t c = 2531011;
- uint32_t m_seed;
-
-public:
- RandomNumberGenerator() : m_seed(0) {}
- RandomNumberGenerator(int seed) : m_seed(seed) {}
-
- void seed(int seed)
- {
- m_seed = seed;
- }
-
- double get_double()
- {
- m_seed = (a * m_seed + c);
- return (double)m_seed / (double)(1LL << 32);
- }
-};
-
-/*
- PathNanRemover is a vertex converter that removes non-finite values
- from the vertices list, and inserts MOVETO commands as necessary to
- skip over them. If a curve segment contains at least one non-finite
- value, the entire curve segment will be skipped.
- */
-template <class VertexSource>
-class PathNanRemover : protected EmbeddedQueue<4>
-{
- VertexSource *m_source;
- bool m_remove_nans;
- bool m_has_curves;
-
- public:
- /* has_curves should be true if the path contains bezier curve
- segments, as this requires a slower algorithm to remove the
- NaNs. When in doubt, set to true.
- */
- PathNanRemover(VertexSource &source, bool remove_nans, bool has_curves)
- : m_source(&source), m_remove_nans(remove_nans), m_has_curves(has_curves)
- {
- // empty
- }
-
- inline void rewind(unsigned path_id)
- {
- queue_clear();
- m_source->rewind(path_id);
- }
-
- inline unsigned vertex(double *x, double *y)
- {
- unsigned code;
-
- if (!m_remove_nans) {
- return m_source->vertex(x, y);
- }
-
- if (m_has_curves) {
- /* This is the slow method for when there might be curves. */
- if (queue_pop(&code, x, y)) {
- return code;
- }
-
- bool needs_move_to = false;
- while (true) {
- /* The approach here is to push each full curve
- segment into the queue. If any non-finite values
- are found along the way, the queue is emptied, and
- the next curve segment is handled. */
- code = m_source->vertex(x, y);
- if (code == agg::path_cmd_stop ||
- code == (agg::path_cmd_end_poly | agg::path_flags_close)) {
- return code;
- }
-
- if (needs_move_to) {
- queue_push(agg::path_cmd_move_to, *x, *y);
- }
-
- size_t num_extra_points = num_extra_points_map[code & 0xF];
- bool has_nan = (!(std::isfinite(*x) && std::isfinite(*y)));
- queue_push(code, *x, *y);
-
- /* Note: this test can not be short-circuited, since we need to
- advance through the entire curve no matter what */
- for (size_t i = 0; i < num_extra_points; ++i) {
- m_source->vertex(x, y);
- has_nan = has_nan || !(std::isfinite(*x) && std::isfinite(*y));
- queue_push(code, *x, *y);
- }
-
- if (!has_nan) {
- break;
- }
-
- queue_clear();
-
- /* If the last point is finite, we use that for the
- moveto, otherwise, we'll use the first vertex of
- the next curve. */
- if (std::isfinite(*x) && std::isfinite(*y)) {
- queue_push(agg::path_cmd_move_to, *x, *y);
- needs_move_to = false;
- } else {
- needs_move_to = true;
- }
- }
-
- if (queue_pop(&code, x, y)) {
- return code;
- } else {
- return agg::path_cmd_stop;
- }
- } else // !m_has_curves
- {
- /* This is the fast path for when we know we have no curves */
- code = m_source->vertex(x, y);
-
- if (code == agg::path_cmd_stop ||
- code == (agg::path_cmd_end_poly | agg::path_flags_close)) {
- return code;
- }
-
- if (!(std::isfinite(*x) && std::isfinite(*y))) {
- do {
- code = m_source->vertex(x, y);
- if (code == agg::path_cmd_stop ||
- code == (agg::path_cmd_end_poly | agg::path_flags_close)) {
- return code;
- }
- } while (!(std::isfinite(*x) && std::isfinite(*y)));
- return agg::path_cmd_move_to;
- }
-
- return code;
- }
- }
-};
-
-/************************************************************
- PathClipper uses the Liang-Barsky line clipping algorithm (as
- implemented in Agg) to clip the path to a given rectangle. Lines
- will never extend outside of the rectangle. Curve segments are not
- clipped, but are always included in their entirety.
- */
-template <class VertexSource>
-class PathClipper : public EmbeddedQueue<3>
-{
- VertexSource *m_source;
- bool m_do_clipping;
- agg::rect_base<double> m_cliprect;
- double m_lastX;
- double m_lastY;
- bool m_moveto;
- double m_initX;
- double m_initY;
- bool m_has_init;
-
- public:
- PathClipper(VertexSource &source, bool do_clipping, double width, double height)
- : m_source(&source),
- m_do_clipping(do_clipping),
- m_cliprect(-1.0, -1.0, width + 1.0, height + 1.0),
- m_moveto(true),
- m_has_init(false)
- {
- // empty
- }
-
- PathClipper(VertexSource &source, bool do_clipping, const agg::rect_base<double> &rect)
- : m_source(&source),
- m_do_clipping(do_clipping),
- m_cliprect(rect),
- m_moveto(true),
- m_has_init(false)
- {
- m_cliprect.x1 -= 1.0;
- m_cliprect.y1 -= 1.0;
- m_cliprect.x2 += 1.0;
- m_cliprect.y2 += 1.0;
- }
-
- inline void rewind(unsigned path_id)
- {
- m_has_init = false;
- m_moveto = true;
- m_source->rewind(path_id);
- }
-
- int draw_clipped_line(double x0, double y0, double x1, double y1)
- {
- unsigned moved = agg::clip_line_segment(&x0, &y0, &x1, &y1, m_cliprect);
- // moved >= 4 - Fully clipped
- // moved & 1 != 0 - First point has been moved
- // moved & 2 != 0 - Second point has been moved
- if (moved < 4) {
- if (moved & 1 || m_moveto) {
- queue_push(agg::path_cmd_move_to, x0, y0);
- }
- queue_push(agg::path_cmd_line_to, x1, y1);
-
- m_moveto = false;
- return 1;
- }
-
- return 0;
- }
-
- unsigned vertex(double *x, double *y)
- {
- unsigned code;
- bool emit_moveto = false;
-
- if (m_do_clipping) {
- /* This is the slow path where we actually do clipping */
-
- if (queue_pop(&code, x, y)) {
- return code;
- }
-
- while ((code = m_source->vertex(x, y)) != agg::path_cmd_stop) {
- emit_moveto = false;
-
- switch (code) {
- case (agg::path_cmd_end_poly | agg::path_flags_close):
- if (m_has_init) {
- draw_clipped_line(m_lastX, m_lastY, m_initX, m_initY);
- }
- queue_push(
- agg::path_cmd_end_poly | agg::path_flags_close,
- m_lastX, m_lastY);
- goto exit_loop;
-
- case agg::path_cmd_move_to:
-
- // was the last command a moveto (and we have
- // seen at least one command ?
- // if so, shove it in the queue if in clip box
- if (m_moveto && m_has_init &&
- m_lastX >= m_cliprect.x1 &&
- m_lastX <= m_cliprect.x2 &&
- m_lastY >= m_cliprect.y1 &&
- m_lastY <= m_cliprect.y2) {
- // push the last moveto onto the queue
- queue_push(agg::path_cmd_move_to, m_lastX, m_lastY);
- // flag that we need to emit it
- emit_moveto = true;
- }
- // update the internal state for this moveto
- m_initX = m_lastX = *x;
- m_initY = m_lastY = *y;
- m_has_init = true;
- m_moveto = true;
- // if the last command was moveto exit the loop to emit the code
- if (emit_moveto) {
- goto exit_loop;
- }
- // else, break and get the next point
- break;
-
- case agg::path_cmd_line_to:
- if (draw_clipped_line(m_lastX, m_lastY, *x, *y)) {
- m_lastX = *x;
- m_lastY = *y;
- goto exit_loop;
- }
- m_lastX = *x;
- m_lastY = *y;
- break;
-
- default:
- if (m_moveto) {
- queue_push(agg::path_cmd_move_to, m_lastX, m_lastY);
- m_moveto = false;
- }
-
- queue_push(code, *x, *y);
- m_lastX = *x;
- m_lastY = *y;
- goto exit_loop;
- }
- }
-
- exit_loop:
-
- if (queue_pop(&code, x, y)) {
- return code;
- }
-
- if (m_moveto &&
- m_lastX >= m_cliprect.x1 &&
- m_lastX <= m_cliprect.x2 &&
- m_lastY >= m_cliprect.y1 &&
- m_lastY <= m_cliprect.y2) {
- *x = m_lastX;
- *y = m_lastY;
- m_moveto = false;
- return agg::path_cmd_move_to;
- }
-
- return agg::path_cmd_stop;
- } else {
- // If not doing any clipping, just pass along the vertices
- // verbatim
- return m_source->vertex(x, y);
- }
- }
-};
-
-/************************************************************
- PathSnapper rounds vertices to their nearest center-pixels. This
- makes rectilinear paths (rectangles, horizontal and vertical lines
- etc.) look much cleaner.
-*/
-enum e_snap_mode {
- SNAP_AUTO,
- SNAP_FALSE,
- SNAP_TRUE
-};
-
-template <class VertexSource>
-class PathSnapper
-{
- private:
- VertexSource *m_source;
- bool m_snap;
- double m_snap_value;
-
- static bool should_snap(VertexSource &path, e_snap_mode snap_mode, unsigned total_vertices)
- {
- // If this contains only straight horizontal or vertical lines, it should be
- // snapped to the nearest pixels
- double x0 = 0, y0 = 0, x1 = 0, y1 = 0;
- unsigned code;
-
- switch (snap_mode) {
- case SNAP_AUTO:
- if (total_vertices > 1024) {
- return false;
- }
-
- code = path.vertex(&x0, &y0);
- if (code == agg::path_cmd_stop) {
- return false;
- }
-
- while ((code = path.vertex(&x1, &y1)) != agg::path_cmd_stop) {
- switch (code) {
- case agg::path_cmd_curve3:
- case agg::path_cmd_curve4:
- return false;
- case agg::path_cmd_line_to:
- if (!(fabs(x0 - x1) < 1e-4 || fabs(y0 - y1) < 1e-4)) {
- return false;
- }
- }
- x0 = x1;
- y0 = y1;
- }
-
- return true;
- case SNAP_FALSE:
- return false;
- case SNAP_TRUE:
- return true;
- }
-
- return false;
- }
-
- public:
- /*
- snap_mode should be one of:
- - SNAP_AUTO: Examine the path to determine if it should be snapped
- - SNAP_TRUE: Force snapping
- - SNAP_FALSE: No snapping
- */
- PathSnapper(VertexSource &source,
- e_snap_mode snap_mode,
- unsigned total_vertices = 15,
- double stroke_width = 0.0)
- : m_source(&source)
- {
- m_snap = should_snap(source, snap_mode, total_vertices);
-
- if (m_snap) {
- int is_odd = (int)mpl_round(stroke_width) % 2;
- m_snap_value = (is_odd) ? 0.5 : 0.0;
- }
-
- source.rewind(0);
- }
-
- inline void rewind(unsigned path_id)
- {
- m_source->rewind(path_id);
- }
-
- inline unsigned vertex(double *x, double *y)
- {
- unsigned code;
- code = m_source->vertex(x, y);
- if (m_snap && agg::is_vertex(code)) {
- *x = floor(*x + 0.5) + m_snap_value;
- *y = floor(*y + 0.5) + m_snap_value;
- }
- return code;
- }
-
- inline bool is_snapping()
- {
- return m_snap;
- }
-};
-
-/************************************************************
- PathSimplifier reduces the number of vertices in a dense path without
- changing its appearance.
-*/
-template <class VertexSource>
-class PathSimplifier : protected EmbeddedQueue<9>
-{
- public:
- /* Set simplify to true to perform simplification */
- PathSimplifier(VertexSource &source, bool do_simplify, double simplify_threshold)
- : m_source(&source),
- m_simplify(do_simplify),
- /* we square simplify_threshold so that we can compute
- norms without doing the square root every step. */
- m_simplify_threshold(simplify_threshold * simplify_threshold),
-
- m_moveto(true),
- m_after_moveto(false),
- m_clipped(false),
-
- // the x, y values from last iteration
- m_lastx(0.0),
- m_lasty(0.0),
-
- // the dx, dy comprising the original vector, used in conjunction
- // with m_currVecStart* to define the original vector.
- m_origdx(0.0),
- m_origdy(0.0),
-
- // the squared norm of the original vector
- m_origdNorm2(0.0),
-
- // maximum squared norm of vector in forward (parallel) direction
- m_dnorm2ForwardMax(0.0),
- // maximum squared norm of vector in backward (anti-parallel) direction
- m_dnorm2BackwardMax(0.0),
-
- // was the last point the furthest from lastWritten in the
- // forward (parallel) direction?
- m_lastForwardMax(false),
- // was the last point the furthest from lastWritten in the
- // backward (anti-parallel) direction?
- m_lastBackwardMax(false),
-
- // added to queue when _push is called
- m_nextX(0.0),
- m_nextY(0.0),
-
- // added to queue when _push is called if any backwards
- // (anti-parallel) vectors were observed
- m_nextBackwardX(0.0),
- m_nextBackwardY(0.0),
-
- // start of the current vector that is being simplified
- m_currVecStartX(0.0),
- m_currVecStartY(0.0)
- {
- // empty
- }
-
- inline void rewind(unsigned path_id)
- {
- queue_clear();
- m_moveto = true;
- m_source->rewind(path_id);
- }
-
- unsigned vertex(double *x, double *y)
- {
- unsigned cmd;
-
- /* The simplification algorithm doesn't support curves or compound paths
- so we just don't do it at all in that case... */
- if (!m_simplify) {
- return m_source->vertex(x, y);
- }
-
- /* idea: we can skip drawing many lines: we can combine
- sequential parallel lines into a
- single line instead of redrawing lines over the same
- points. The loop below works a bit like a state machine,
- where what it does depends on what it did in the last
- looping. To test whether sequential lines are close to
- parallel, I calculate the distance moved perpendicular to
- the last line. Once it gets too big, the lines cannot be
- combined. */
-
- /* This code was originally written by Allan Haldane and I
- have modified to work in-place -- meaning not creating an
- entirely new path list each time. In order to do that
- without too much additional code complexity, it keeps a
- small queue around so that multiple points can be emitted
- in a single call, and those points will be popped from the
- queue in subsequent calls. The following block will empty
- the queue before proceeding to the main loop below.
- -- Michael Droettboom */
-
- /* This code was originally written by Allan Haldane and
- updated by Michael Droettboom. I have modified it to
- handle anti-parallel vectors. This is done essentially
- the same way as parallel vectors, but requires a little
- additional book-keeping to track whether or not we have
- observed an anti-parallel vector during the current run.
- -- Kevin Rose */
-
- if (queue_pop(&cmd, x, y)) {
- return cmd;
- }
-
- /* The main simplification loop. The point is to consume only
- as many points as necessary until something has been added
- to the outbound queue, not to run through the entire path
- in one go. This eliminates the need to allocate and fill
- an entire additional path array on each draw. */
- while ((cmd = m_source->vertex(x, y)) != agg::path_cmd_stop) {
- /* if we are starting a new path segment, move to the first point
- + init */
-
- if (m_moveto || cmd == agg::path_cmd_move_to) {
- /* m_moveto check is not generally needed because
- m_source generates an initial moveto; but it is
- retained for safety in case circumstances arise
- where this is not true. */
- if (m_origdNorm2 != 0.0 && !m_after_moveto) {
- /* m_origdNorm2 is nonzero only if we have a
- vector; the m_after_moveto check ensures we
- push this vector to the queue only once. */
- _push(x, y);
- }
- m_after_moveto = true;
- m_lastx = *x;
- m_lasty = *y;
- m_moveto = false;
- m_origdNorm2 = 0.0;
- m_dnorm2BackwardMax = 0.0;
- m_clipped = true;
- if (queue_nonempty()) {
- /* If we did a push, empty the queue now. */
- break;
- }
- continue;
- }
- m_after_moveto = false;
-
- /* NOTE: We used to skip this very short segments, but if
- you have a lot of them cumulatively, you can miss
- maxima or minima in the data. */
-
- /* Don't render line segments less than one pixel long */
- /* if (fabs(*x - m_lastx) < 1.0 && fabs(*y - m_lasty) < 1.0) */
- /* { */
- /* continue; */
- /* } */
-
- /* if we have no orig vector, set it to this vector and
- continue. this orig vector is the reference vector we
- will build up the line to */
- if (m_origdNorm2 == 0.0) {
- if (m_clipped) {
- queue_push(agg::path_cmd_move_to, m_lastx, m_lasty);
- m_clipped = false;
- }
-
- m_origdx = *x - m_lastx;
- m_origdy = *y - m_lasty;
- m_origdNorm2 = m_origdx * m_origdx + m_origdy * m_origdy;
-
- // set all the variables to reflect this new orig vector
- m_dnorm2ForwardMax = m_origdNorm2;
- m_dnorm2BackwardMax = 0.0;
- m_lastForwardMax = true;
- m_lastBackwardMax = false;
-
- m_currVecStartX = m_lastx;
- m_currVecStartY = m_lasty;
- m_nextX = m_lastx = *x;
- m_nextY = m_lasty = *y;
- continue;
- }
-
- /* If got to here, then we have an orig vector and we just got
- a vector in the sequence. */
-
- /* Check that the perpendicular distance we have moved
- from the last written point compared to the line we are
- building is not too much. If o is the orig vector (we
- are building on), and v is the vector from the last
- written point to the current point, then the
- perpendicular vector is p = v - (o.v)o/(o.o)
- (here, a.b indicates the dot product of a and b). */
-
- /* get the v vector */
- double totdx = *x - m_currVecStartX;
- double totdy = *y - m_currVecStartY;
-
- /* get the dot product o.v */
- double totdot = m_origdx * totdx + m_origdy * totdy;
-
- /* get the para vector ( = (o.v)o/(o.o)) */
- double paradx = totdot * m_origdx / m_origdNorm2;
- double parady = totdot * m_origdy / m_origdNorm2;
-
- /* get the perp vector ( = v - para) */
- double perpdx = totdx - paradx;
- double perpdy = totdy - parady;
-
- /* get the squared norm of perp vector ( = p.p) */
- double perpdNorm2 = perpdx * perpdx + perpdy * perpdy;
-
- /* If the perpendicular vector is less than
- m_simplify_threshold pixels in size, then merge
- current x,y with the current vector */
- if (perpdNorm2 < m_simplify_threshold) {
- /* check if the current vector is parallel or
- anti-parallel to the orig vector. In either case,
- test if it is the longest of the vectors
- we are merging in that direction. If it is, then
- update the current vector in that direction. */
- double paradNorm2 = paradx * paradx + parady * parady;
-
- m_lastForwardMax = false;
- m_lastBackwardMax = false;
- if (totdot > 0.0) {
- if (paradNorm2 > m_dnorm2ForwardMax) {
- m_lastForwardMax = true;
- m_dnorm2ForwardMax = paradNorm2;
- m_nextX = *x;
- m_nextY = *y;
- }
- } else {
- if (paradNorm2 > m_dnorm2BackwardMax) {
- m_lastBackwardMax = true;
- m_dnorm2BackwardMax = paradNorm2;
- m_nextBackwardX = *x;
- m_nextBackwardY = *y;
- }
- }
-
- m_lastx = *x;
- m_lasty = *y;
- continue;
- }
-
- /* If we get here, then this vector was not similar enough to the
- line we are building, so we need to draw that line and start the
- next one. */
-
- /* If the line needs to extend in the opposite direction from the
- direction we are drawing in, move back to we start drawing from
- back there. */
- _push(x, y);
-
- break;
- }
-
- /* Fill the queue with the remaining vertices if we've finished the
- path in the above loop. */
- if (cmd == agg::path_cmd_stop) {
- if (m_origdNorm2 != 0.0) {
- queue_push((m_moveto || m_after_moveto) ? agg::path_cmd_move_to
- : agg::path_cmd_line_to,
- m_nextX,
- m_nextY);
- if (m_dnorm2BackwardMax > 0.0) {
- queue_push((m_moveto || m_after_moveto) ? agg::path_cmd_move_to
- : agg::path_cmd_line_to,
- m_nextBackwardX,
- m_nextBackwardY);
- }
- m_moveto = false;
- }
- queue_push((m_moveto || m_after_moveto) ? agg::path_cmd_move_to : agg::path_cmd_line_to,
- m_lastx,
- m_lasty);
- m_moveto = false;
- queue_push(agg::path_cmd_stop, 0.0, 0.0);
- }
-
- /* Return the first item in the queue, if any, otherwise
- indicate that we're done. */
- if (queue_pop(&cmd, x, y)) {
- return cmd;
- } else {
- return agg::path_cmd_stop;
- }
- }
-
- private:
- VertexSource *m_source;
- bool m_simplify;
- double m_simplify_threshold;
-
- bool m_moveto;
- bool m_after_moveto;
- bool m_clipped;
- double m_lastx, m_lasty;
-
- double m_origdx;
- double m_origdy;
- double m_origdNorm2;
- double m_dnorm2ForwardMax;
- double m_dnorm2BackwardMax;
- bool m_lastForwardMax;
- bool m_lastBackwardMax;
- double m_nextX;
- double m_nextY;
- double m_nextBackwardX;
- double m_nextBackwardY;
- double m_currVecStartX;
- double m_currVecStartY;
-
- inline void _push(double *x, double *y)
- {
- bool needToPushBack = (m_dnorm2BackwardMax > 0.0);
-
- /* If we observed any backward (anti-parallel) vectors, then
- we need to push both forward and backward vectors. */
- if (needToPushBack) {
- /* If the last vector seen was the maximum in the forward direction,
- then we need to push the forward after the backward. Otherwise,
- the last vector seen was the maximum in the backward direction,
- or somewhere in between, either way we are safe pushing forward
- before backward. */
- if (m_lastForwardMax) {
- queue_push(agg::path_cmd_line_to, m_nextBackwardX, m_nextBackwardY);
- queue_push(agg::path_cmd_line_to, m_nextX, m_nextY);
- } else {
- queue_push(agg::path_cmd_line_to, m_nextX, m_nextY);
- queue_push(agg::path_cmd_line_to, m_nextBackwardX, m_nextBackwardY);
- }
- } else {
- /* If we did not observe any backwards vectors, just push forward. */
- queue_push(agg::path_cmd_line_to, m_nextX, m_nextY);
- }
-
- /* If we clipped some segments between this line and the next line
- we are starting, we also need to move to the last point. */
- if (m_clipped) {
- queue_push(agg::path_cmd_move_to, m_lastx, m_lasty);
- } else if ((!m_lastForwardMax) && (!m_lastBackwardMax)) {
- /* If the last line was not the longest line, then move
- back to the end point of the last line in the
- sequence. Only do this if not clipped, since in that
- case lastx,lasty is not part of the line just drawn. */
-
- /* Would be move_to if not for the artifacts */
- queue_push(agg::path_cmd_line_to, m_lastx, m_lasty);
- }
-
- /* Now reset all the variables to get ready for the next line */
- m_origdx = *x - m_lastx;
- m_origdy = *y - m_lasty;
- m_origdNorm2 = m_origdx * m_origdx + m_origdy * m_origdy;
-
- m_dnorm2ForwardMax = m_origdNorm2;
- m_lastForwardMax = true;
- m_currVecStartX = m_queue[m_queue_write - 1].x;
- m_currVecStartY = m_queue[m_queue_write - 1].y;
- m_lastx = m_nextX = *x;
- m_lasty = m_nextY = *y;
- m_dnorm2BackwardMax = 0.0;
- m_lastBackwardMax = false;
-
- m_clipped = false;
- }
-};
-
-template <class VertexSource>
-class Sketch
-{
- public:
- /*
- scale: the scale of the wiggle perpendicular to the original
- line (in pixels)
-
- length: the base wavelength of the wiggle along the
- original line (in pixels)
-
- randomness: the factor that the sketch length will randomly
- shrink and expand.
- */
- Sketch(VertexSource &source, double scale, double length, double randomness)
- : m_source(&source),
- m_scale(scale),
- m_length(length),
- m_randomness(randomness),
- m_segmented(source),
- m_last_x(0.0),
- m_last_y(0.0),
- m_has_last(false),
- m_p(0.0),
- m_rand(0)
- {
- rewind(0);
- }
-
- unsigned vertex(double *x, double *y)
- {
- if (m_scale == 0.0) {
- return m_source->vertex(x, y);
- }
-
- unsigned code = m_segmented.vertex(x, y);
-
- if (code == agg::path_cmd_move_to) {
- m_has_last = false;
- m_p = 0.0;
- }
-
- if (m_has_last) {
- // We want the "cursor" along the sine wave to move at a
- // random rate.
- double d_rand = m_rand.get_double();
- double d_M_PI = 3.14159265358979323846;
- m_p += pow(m_randomness, d_rand * 2.0 - 1.0);
- double r = sin(m_p / (m_length / (d_M_PI * 2.0))) * m_scale;
- double den = m_last_x - *x;
- double num = m_last_y - *y;
- double len = num * num + den * den;
- m_last_x = *x;
- m_last_y = *y;
- if (len != 0) {
- len = sqrt(len);
- *x += r * num / len;
- *y += r * -den / len;
- }
- } else {
- m_last_x = *x;
- m_last_y = *y;
- }
-
- m_has_last = true;
-
- return code;
- }
-
- inline void rewind(unsigned path_id)
- {
- m_has_last = false;
- m_p = 0.0;
- if (m_scale != 0.0) {
- m_rand.seed(0);
- m_segmented.rewind(path_id);
- } else {
- m_source->rewind(path_id);
- }
- }
-
- private:
- VertexSource *m_source;
- double m_scale;
- double m_length;
- double m_randomness;
- agg::conv_segmentator<VertexSource> m_segmented;
- double m_last_x;
- double m_last_y;
- bool m_has_last;
- double m_p;
- RandomNumberGenerator m_rand;
-};
-
-#endif // __PATH_CONVERTERS_H__
diff --git a/contrib/python/matplotlib/py2/src/py_adaptors.h b/contrib/python/matplotlib/py2/src/py_adaptors.h
deleted file mode 100644
index 3d0dbdab45..0000000000
--- a/contrib/python/matplotlib/py2/src/py_adaptors.h
+++ /dev/null
@@ -1,251 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-#ifndef __PY_ADAPTORS_H__
-#define __PY_ADAPTORS_H__
-#define PY_SSIZE_T_CLEAN
-/***************************************************************************
- * This module contains a number of C++ classes that adapt Python data
- * structures to C++ and Agg-friendly interfaces.
- */
-
-#include <Python.h>
-
-#include "numpy/arrayobject.h"
-
-#include "py_exceptions.h"
-
-extern "C" {
-int convert_path(PyObject *obj, void *pathp);
-}
-
-namespace py
-{
-
-/************************************************************
- * py::PathIterator acts as a bridge between Numpy and Agg. Given a
- * pair of Numpy arrays, vertices and codes, it iterates over
- * those vertices and codes, using the standard Agg vertex source
- * interface:
- *
- * unsigned vertex(double* x, double* y)
- */
-class PathIterator
-{
- /* We hold references to the Python objects, not just the
- underlying data arrays, so that Python reference counting
- can work.
- */
- PyArrayObject *m_vertices;
- PyArrayObject *m_codes;
-
- unsigned m_iterator;
- unsigned m_total_vertices;
-
- /* This class doesn't actually do any simplification, but we
- store the value here, since it is obtained from the Python
- object.
- */
- bool m_should_simplify;
- double m_simplify_threshold;
-
- public:
- inline PathIterator()
- : m_vertices(NULL),
- m_codes(NULL),
- m_iterator(0),
- m_total_vertices(0),
- m_should_simplify(false),
- m_simplify_threshold(1.0 / 9.0)
- {
- }
-
- inline PathIterator(PyObject *vertices,
- PyObject *codes,
- bool should_simplify,
- double simplify_threshold)
- : m_vertices(NULL), m_codes(NULL), m_iterator(0)
- {
- if (!set(vertices, codes, should_simplify, simplify_threshold))
- throw py::exception();
- }
-
- inline PathIterator(PyObject *vertices, PyObject *codes)
- : m_vertices(NULL), m_codes(NULL), m_iterator(0)
- {
- if (!set(vertices, codes))
- throw py::exception();
- }
-
- inline PathIterator(const PathIterator &other)
- {
- Py_XINCREF(other.m_vertices);
- m_vertices = other.m_vertices;
-
- Py_XINCREF(other.m_codes);
- m_codes = other.m_codes;
-
- m_iterator = 0;
- m_total_vertices = other.m_total_vertices;
-
- m_should_simplify = other.m_should_simplify;
- m_simplify_threshold = other.m_simplify_threshold;
- }
-
- ~PathIterator()
- {
- Py_XDECREF(m_vertices);
- Py_XDECREF(m_codes);
- }
-
- inline int
- set(PyObject *vertices, PyObject *codes, bool should_simplify, double simplify_threshold)
- {
- m_should_simplify = should_simplify;
- m_simplify_threshold = simplify_threshold;
-
- Py_XDECREF(m_vertices);
- m_vertices = (PyArrayObject *)PyArray_FromObject(vertices, NPY_DOUBLE, 2, 2);
-
- if (!m_vertices || PyArray_DIM(m_vertices, 1) != 2) {
- PyErr_SetString(PyExc_ValueError, "Invalid vertices array");
- return 0;
- }
-
- Py_XDECREF(m_codes);
- m_codes = NULL;
-
- if (codes != NULL && codes != Py_None) {
- m_codes = (PyArrayObject *)PyArray_FromObject(codes, NPY_UINT8, 1, 1);
-
- if (!m_codes || PyArray_DIM(m_codes, 0) != PyArray_DIM(m_vertices, 0)) {
- PyErr_SetString(PyExc_ValueError, "Invalid codes array");
- return 0;
- }
- }
-
- m_total_vertices = (unsigned)PyArray_DIM(m_vertices, 0);
- m_iterator = 0;
-
- return 1;
- }
-
- inline int set(PyObject *vertices, PyObject *codes)
- {
- return set(vertices, codes, false, 0.0);
- }
-
- inline unsigned vertex(double *x, double *y)
- {
- if (m_iterator >= m_total_vertices) {
- *x = 0.0;
- *y = 0.0;
- return agg::path_cmd_stop;
- }
-
- const size_t idx = m_iterator++;
-
- char *pair = (char *)PyArray_GETPTR2(m_vertices, idx, 0);
- *x = *(double *)pair;
- *y = *(double *)(pair + PyArray_STRIDE(m_vertices, 1));
-
- if (m_codes != NULL) {
- return (unsigned)(*(char *)PyArray_GETPTR1(m_codes, idx));
- } else {
- return idx == 0 ? agg::path_cmd_move_to : agg::path_cmd_line_to;
- }
- }
-
- inline void rewind(unsigned path_id)
- {
- m_iterator = path_id;
- }
-
- inline unsigned total_vertices() const
- {
- return m_total_vertices;
- }
-
- inline bool should_simplify() const
- {
- return m_should_simplify;
- }
-
- inline double simplify_threshold() const
- {
- return m_simplify_threshold;
- }
-
- inline bool has_curves() const
- {
- return m_codes != NULL;
- }
-
- inline void *get_id()
- {
- return (void *)m_vertices;
- }
-};
-
-class PathGenerator
-{
- PyObject *m_paths;
- Py_ssize_t m_npaths;
-
- public:
- typedef PathIterator path_iterator;
-
- PathGenerator(PyObject *obj) : m_paths(NULL), m_npaths(0)
- {
- if (!set(obj)) {
- throw py::exception();
- }
- }
-
- ~PathGenerator()
- {
- Py_XDECREF(m_paths);
- }
-
- int set(PyObject *obj)
- {
- if (!PySequence_Check(obj)) {
- return 0;
- }
-
- m_paths = obj;
- Py_INCREF(m_paths);
-
- m_npaths = PySequence_Size(m_paths);
-
- return 1;
- }
-
- Py_ssize_t num_paths() const
- {
- return m_npaths;
- }
-
- Py_ssize_t size() const
- {
- return m_npaths;
- }
-
- path_iterator operator()(size_t i)
- {
- path_iterator path;
- PyObject *item;
-
- item = PySequence_GetItem(m_paths, i % m_npaths);
- if (item == NULL) {
- throw py::exception();
- }
- if (!convert_path(item, &path)) {
- throw py::exception();
- }
- Py_DECREF(item);
- return path;
- }
-};
-}
-
-#endif
diff --git a/contrib/python/matplotlib/py2/src/py_converters.cpp b/contrib/python/matplotlib/py2/src/py_converters.cpp
deleted file mode 100644
index 2d5d415a2c..0000000000
--- a/contrib/python/matplotlib/py2/src/py_converters.cpp
+++ /dev/null
@@ -1,619 +0,0 @@
-#define NO_IMPORT_ARRAY
-#define PY_SSIZE_T_CLEAN
-#include "py_converters.h"
-#include "numpy_cpp.h"
-
-#include "agg_basics.h"
-#include "agg_color_rgba.h"
-#include "agg_math_stroke.h"
-
-extern "C" {
-
-static int convert_string_enum(PyObject *obj, const char *name, const char **names, int *values, int *result)
-{
- PyObject *bytesobj;
- char *str;
-
- if (obj == NULL || obj == Py_None) {
- return 1;
- }
-
- if (PyUnicode_Check(obj)) {
- bytesobj = PyUnicode_AsASCIIString(obj);
- if (bytesobj == NULL) {
- return 0;
- }
- } else if (PyBytes_Check(obj)) {
- Py_INCREF(obj);
- bytesobj = obj;
- } else {
- PyErr_Format(PyExc_TypeError, "%s must be bytes or unicode", name);
- return 0;
- }
-
- str = PyBytes_AsString(bytesobj);
- if (str == NULL) {
- Py_DECREF(bytesobj);
- return 0;
- }
-
- for ( ; *names != NULL; names++, values++) {
- if (strncmp(str, *names, 64) == 0) {
- *result = *values;
- Py_DECREF(bytesobj);
- return 1;
- }
- }
-
- PyErr_Format(PyExc_ValueError, "invalid %s value", name);
- Py_DECREF(bytesobj);
- return 0;
-}
-
-int convert_from_method(PyObject *obj, const char *name, converter func, void *p)
-{
- PyObject *value;
-
- value = PyObject_CallMethod(obj, (char *)name, NULL);
- if (value == NULL) {
- if (!PyObject_HasAttrString(obj, (char *)name)) {
- PyErr_Clear();
- return 1;
- }
- return 0;
- }
-
- if (!func(value, p)) {
- Py_DECREF(value);
- return 0;
- }
-
- Py_DECREF(value);
- return 1;
-}
-
-int convert_from_attr(PyObject *obj, const char *name, converter func, void *p)
-{
- PyObject *value;
-
- value = PyObject_GetAttrString(obj, (char *)name);
- if (value == NULL) {
- if (!PyObject_HasAttrString(obj, (char *)name)) {
- PyErr_Clear();
- return 1;
- }
- return 0;
- }
-
- if (!func(value, p)) {
- Py_DECREF(value);
- return 0;
- }
-
- Py_DECREF(value);
- return 1;
-}
-
-int convert_double(PyObject *obj, void *p)
-{
- double *val = (double *)p;
-
- *val = PyFloat_AsDouble(obj);
- if (PyErr_Occurred()) {
- return 0;
- }
-
- return 1;
-}
-
-int convert_bool(PyObject *obj, void *p)
-{
- bool *val = (bool *)p;
-
- *val = PyObject_IsTrue(obj);
-
- return 1;
-}
-
-int convert_cap(PyObject *capobj, void *capp)
-{
- const char *names[] = {"butt", "round", "projecting", NULL};
- int values[] = {agg::butt_cap, agg::round_cap, agg::square_cap};
- int result = agg::butt_cap;
-
- if (!convert_string_enum(capobj, "capstyle", names, values, &result)) {
- return 0;
- }
-
- *(agg::line_cap_e *)capp = (agg::line_cap_e)result;
- return 1;
-}
-
-int convert_join(PyObject *joinobj, void *joinp)
-{
- const char *names[] = {"miter", "round", "bevel", NULL};
- int values[] = {agg::miter_join_revert, agg::round_join, agg::bevel_join};
- int result = agg::miter_join_revert;
-
- if (!convert_string_enum(joinobj, "joinstyle", names, values, &result)) {
- return 0;
- }
-
- *(agg::line_join_e *)joinp = (agg::line_join_e)result;
- return 1;
-}
-
-int convert_rect(PyObject *rectobj, void *rectp)
-{
- agg::rect_d *rect = (agg::rect_d *)rectp;
-
- if (rectobj == NULL || rectobj == Py_None) {
- rect->x1 = 0.0;
- rect->y1 = 0.0;
- rect->x2 = 0.0;
- rect->y2 = 0.0;
- } else {
- try
- {
- numpy::array_view<const double, 2> rect_arr(rectobj);
-
- if (rect_arr.dim(0) != 2 || rect_arr.dim(1) != 2) {
- PyErr_SetString(PyExc_ValueError, "Invalid bounding box");
- return 0;
- }
-
- rect->x1 = rect_arr(0, 0);
- rect->y1 = rect_arr(0, 1);
- rect->x2 = rect_arr(1, 0);
- rect->y2 = rect_arr(1, 1);
- }
- catch (py::exception &)
- {
- PyErr_Clear();
-
- try
- {
- numpy::array_view<const double, 1> rect_arr(rectobj);
-
- if (rect_arr.dim(0) != 4) {
- PyErr_SetString(PyExc_ValueError, "Invalid bounding box");
- return 0;
- }
-
- rect->x1 = rect_arr(0);
- rect->y1 = rect_arr(1);
- rect->x2 = rect_arr(2);
- rect->y2 = rect_arr(3);
- }
- catch (py::exception &)
- {
- return 0;
- }
- }
- }
-
- return 1;
-}
-
-int convert_rgba(PyObject *rgbaobj, void *rgbap)
-{
- agg::rgba *rgba = (agg::rgba *)rgbap;
-
- if (rgbaobj == NULL || rgbaobj == Py_None) {
- rgba->r = 0.0;
- rgba->g = 0.0;
- rgba->b = 0.0;
- rgba->a = 0.0;
- } else {
- rgba->a = 1.0;
- if (!PyArg_ParseTuple(
- rgbaobj, "ddd|d:rgba", &(rgba->r), &(rgba->g), &(rgba->b), &(rgba->a))) {
- return 0;
- }
- }
-
- return 1;
-}
-
-int convert_dashes(PyObject *dashobj, void *dashesp)
-{
- Dashes *dashes = (Dashes *)dashesp;
-
- if (dashobj == NULL && dashobj == Py_None) {
- return 1;
- }
-
- PyObject *dash_offset_obj = NULL;
- double dash_offset = 0.0;
- PyObject *dashes_seq = NULL;
- Py_ssize_t nentries;
-
- if (!PyArg_ParseTuple(dashobj, "OO:dashes", &dash_offset_obj, &dashes_seq)) {
- return 0;
- }
-
- if (dash_offset_obj != Py_None) {
- dash_offset = PyFloat_AsDouble(dash_offset_obj);
- if (PyErr_Occurred()) {
- return 0;
- }
- }
-
- if (dashes_seq == Py_None) {
- return 1;
- }
-
- if (!PySequence_Check(dashes_seq)) {
- PyErr_SetString(PyExc_TypeError, "Invalid dashes sequence");
- return 0;
- }
-
- nentries = PySequence_Size(dashes_seq);
- if (nentries % 2 != 0) {
- PyErr_Format(PyExc_ValueError, "dashes sequence must have an even number of elements");
- return 0;
- }
-
- for (Py_ssize_t i = 0; i < nentries; ++i) {
- PyObject *item;
- double length;
- double skip;
-
- item = PySequence_GetItem(dashes_seq, i);
- if (item == NULL) {
- return 0;
- }
- length = PyFloat_AsDouble(item);
- if (PyErr_Occurred()) {
- Py_DECREF(item);
- return 0;
- }
- Py_DECREF(item);
-
- ++i;
-
- item = PySequence_GetItem(dashes_seq, i);
- if (item == NULL) {
- return 0;
- }
- skip = PyFloat_AsDouble(item);
- if (PyErr_Occurred()) {
- Py_DECREF(item);
- return 0;
- }
- Py_DECREF(item);
-
- dashes->add_dash_pair(length, skip);
- }
-
- dashes->set_dash_offset(dash_offset);
-
- return 1;
-}
-
-int convert_dashes_vector(PyObject *obj, void *dashesp)
-{
- DashesVector *dashes = (DashesVector *)dashesp;
-
- if (!PySequence_Check(obj)) {
- return 0;
- }
-
- Py_ssize_t n = PySequence_Size(obj);
-
- for (Py_ssize_t i = 0; i < n; ++i) {
- PyObject *item;
- Dashes subdashes;
-
- item = PySequence_GetItem(obj, i);
- if (item == NULL) {
- return 0;
- }
-
- if (!convert_dashes(item, &subdashes)) {
- Py_DECREF(item);
- return 0;
- }
- Py_DECREF(item);
-
- dashes->push_back(subdashes);
- }
-
- return 1;
-}
-
-int convert_trans_affine(PyObject *obj, void *transp)
-{
- agg::trans_affine *trans = (agg::trans_affine *)transp;
-
- /** If None assume identity transform. */
- if (obj == NULL || obj == Py_None) {
- return 1;
- }
-
- try
- {
- numpy::array_view<const double, 2> matrix(obj);
-
- if (matrix.dim(0) == 3 && matrix.dim(1) == 3) {
- trans->sx = matrix(0, 0);
- trans->shx = matrix(0, 1);
- trans->tx = matrix(0, 2);
-
- trans->shy = matrix(1, 0);
- trans->sy = matrix(1, 1);
- trans->ty = matrix(1, 2);
-
- return 1;
- }
- }
- catch (py::exception &)
- {
- return 0;
- }
-
- PyErr_SetString(PyExc_ValueError, "Invalid affine transformation matrix");
- return 0;
-}
-
-int convert_path(PyObject *obj, void *pathp)
-{
- py::PathIterator *path = (py::PathIterator *)pathp;
-
- PyObject *vertices_obj = NULL;
- PyObject *codes_obj = NULL;
- PyObject *should_simplify_obj = NULL;
- PyObject *simplify_threshold_obj = NULL;
- bool should_simplify;
- double simplify_threshold;
-
- int status = 0;
-
- if (obj == NULL || obj == Py_None) {
- return 1;
- }
-
- vertices_obj = PyObject_GetAttrString(obj, "vertices");
- if (vertices_obj == NULL) {
- goto exit;
- }
-
- codes_obj = PyObject_GetAttrString(obj, "codes");
- if (codes_obj == NULL) {
- goto exit;
- }
-
- should_simplify_obj = PyObject_GetAttrString(obj, "should_simplify");
- if (should_simplify_obj == NULL) {
- goto exit;
- }
- should_simplify = PyObject_IsTrue(should_simplify_obj);
-
- simplify_threshold_obj = PyObject_GetAttrString(obj, "simplify_threshold");
- if (simplify_threshold_obj == NULL) {
- goto exit;
- }
- simplify_threshold = PyFloat_AsDouble(simplify_threshold_obj);
- if (PyErr_Occurred()) {
- goto exit;
- }
-
- if (!path->set(vertices_obj, codes_obj, should_simplify, simplify_threshold)) {
- goto exit;
- }
-
- status = 1;
-
-exit:
- Py_XDECREF(vertices_obj);
- Py_XDECREF(codes_obj);
- Py_XDECREF(should_simplify_obj);
- Py_XDECREF(simplify_threshold_obj);
-
- return status;
-}
-
-int convert_clippath(PyObject *clippath_tuple, void *clippathp)
-{
- ClipPath *clippath = (ClipPath *)clippathp;
- py::PathIterator path;
- agg::trans_affine trans;
-
- if (clippath_tuple != NULL && clippath_tuple != Py_None) {
- if (!PyArg_ParseTuple(clippath_tuple,
- "O&O&:clippath",
- &convert_path,
- &clippath->path,
- &convert_trans_affine,
- &clippath->trans)) {
- return 0;
- }
- }
-
- return 1;
-}
-
-int convert_snap(PyObject *obj, void *snapp)
-{
- e_snap_mode *snap = (e_snap_mode *)snapp;
-
- if (obj == NULL || obj == Py_None) {
- *snap = SNAP_AUTO;
- } else if (PyObject_IsTrue(obj)) {
- *snap = SNAP_TRUE;
- } else {
- *snap = SNAP_FALSE;
- }
-
- return 1;
-}
-
-int convert_sketch_params(PyObject *obj, void *sketchp)
-{
- SketchParams *sketch = (SketchParams *)sketchp;
-
- if (obj == NULL || obj == Py_None) {
- sketch->scale = 0.0;
- } else if (!PyArg_ParseTuple(obj,
- "ddd:sketch_params",
- &sketch->scale,
- &sketch->length,
- &sketch->randomness)) {
- return 0;
- }
-
- return 1;
-}
-
-int convert_gcagg(PyObject *pygc, void *gcp)
-{
- GCAgg *gc = (GCAgg *)gcp;
-
- if (!(convert_from_attr(pygc, "_linewidth", &convert_double, &gc->linewidth) &&
- convert_from_attr(pygc, "_alpha", &convert_double, &gc->alpha) &&
- convert_from_attr(pygc, "_forced_alpha", &convert_bool, &gc->forced_alpha) &&
- convert_from_attr(pygc, "_rgb", &convert_rgba, &gc->color) &&
- convert_from_attr(pygc, "_antialiased", &convert_bool, &gc->isaa) &&
- convert_from_attr(pygc, "_capstyle", &convert_cap, &gc->cap) &&
- convert_from_attr(pygc, "_joinstyle", &convert_join, &gc->join) &&
- convert_from_method(pygc, "get_dashes", &convert_dashes, &gc->dashes) &&
- convert_from_attr(pygc, "_cliprect", &convert_rect, &gc->cliprect) &&
- convert_from_method(pygc, "get_clip_path", &convert_clippath, &gc->clippath) &&
- convert_from_method(pygc, "get_snap", &convert_snap, &gc->snap_mode) &&
- convert_from_method(pygc, "get_hatch_path", &convert_path, &gc->hatchpath) &&
- convert_from_method(pygc, "get_hatch_color", &convert_rgba, &gc->hatch_color) &&
- convert_from_method(pygc, "get_hatch_linewidth", &convert_double, &gc->hatch_linewidth) &&
- convert_from_method(pygc, "get_sketch_params", &convert_sketch_params, &gc->sketch))) {
- return 0;
- }
-
- return 1;
-}
-
-int convert_offset_position(PyObject *obj, void *offsetp)
-{
- e_offset_position *offset = (e_offset_position *)offsetp;
- const char *names[] = {"data", NULL};
- int values[] = {OFFSET_POSITION_DATA};
- int result = (int)OFFSET_POSITION_FIGURE;
-
- if (!convert_string_enum(obj, "offset_position", names, values, &result)) {
- PyErr_Clear();
- }
-
- *offset = (e_offset_position)result;
-
- return 1;
-}
-
-int convert_face(PyObject *color, GCAgg &gc, agg::rgba *rgba)
-{
- if (!convert_rgba(color, rgba)) {
- return 0;
- }
-
- if (color != NULL && color != Py_None) {
- if (gc.forced_alpha || PySequence_Size(color) == 3) {
- rgba->a = gc.alpha;
- }
- }
-
- return 1;
-}
-
-int convert_points(PyObject *obj, void *pointsp)
-{
- numpy::array_view<double, 2> *points = (numpy::array_view<double, 2> *)pointsp;
-
- if (obj == NULL || obj == Py_None) {
- return 1;
- }
-
- points->set(obj);
-
- if (points->size() == 0) {
- return 1;
- }
-
- if (points->dim(1) != 2) {
- PyErr_Format(PyExc_ValueError,
- "Points must be Nx2 array, got %" NPY_INTP_FMT "x%" NPY_INTP_FMT,
- points->dim(0), points->dim(1));
- return 0;
- }
-
- return 1;
-}
-
-int convert_transforms(PyObject *obj, void *transp)
-{
- numpy::array_view<double, 3> *trans = (numpy::array_view<double, 3> *)transp;
-
- if (obj == NULL || obj == Py_None) {
- return 1;
- }
-
- trans->set(obj);
-
- if (trans->size() == 0) {
- return 1;
- }
-
- if (trans->dim(1) != 3 || trans->dim(2) != 3) {
- PyErr_Format(PyExc_ValueError,
- "Transforms must be Nx3x3 array, got %" NPY_INTP_FMT "x%" NPY_INTP_FMT "x%" NPY_INTP_FMT,
- trans->dim(0), trans->dim(1), trans->dim(2));
- return 0;
- }
-
- return 1;
-}
-
-int convert_bboxes(PyObject *obj, void *bboxp)
-{
- numpy::array_view<double, 3> *bbox = (numpy::array_view<double, 3> *)bboxp;
-
- if (obj == NULL || obj == Py_None) {
- return 1;
- }
-
- bbox->set(obj);
-
- if (bbox->size() == 0) {
- return 1;
- }
-
- if (bbox->dim(1) != 2 || bbox->dim(2) != 2) {
- PyErr_Format(PyExc_ValueError,
- "Bbox array must be Nx2x2 array, got %" NPY_INTP_FMT "x%" NPY_INTP_FMT "x%" NPY_INTP_FMT,
- bbox->dim(0), bbox->dim(1), bbox->dim(2));
- return 0;
- }
-
- return 1;
-}
-
-int convert_colors(PyObject *obj, void *colorsp)
-{
- numpy::array_view<double, 2> *colors = (numpy::array_view<double, 2> *)colorsp;
-
- if (obj == NULL || obj == Py_None) {
- return 1;
- }
-
- colors->set(obj);
-
- if (colors->size() == 0) {
- return 1;
- }
-
- if (colors->dim(1) != 4) {
- PyErr_Format(PyExc_ValueError,
- "Colors array must be Nx4 array, got %" NPY_INTP_FMT "x%" NPY_INTP_FMT,
- colors->dim(0), colors->dim(1));
- return 0;
- }
-
- return 1;
-}
-}
diff --git a/contrib/python/matplotlib/py2/src/py_converters.h b/contrib/python/matplotlib/py2/src/py_converters.h
deleted file mode 100644
index 02d84affe8..0000000000
--- a/contrib/python/matplotlib/py2/src/py_converters.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-#ifndef __PY_CONVERTERS_H__
-#define __PY_CONVERTERS_H__
-
-/***************************************************************************
- * This module contains a number of conversion functions from Python types
- * to C++ types. Most of them meet the Python "converter" signature:
- *
- * typedef int (*converter)(PyObject *, void *);
- *
- * and thus can be passed as conversion functions to PyArg_ParseTuple
- * and friends.
- */
-
-#include <Python.h>
-#include "numpy_cpp.h"
-#include "_backend_agg_basic_types.h"
-
-extern "C" {
-typedef int (*converter)(PyObject *, void *);
-
-int convert_from_attr(PyObject *obj, const char *name, converter func, void *p);
-int convert_from_method(PyObject *obj, const char *name, converter func, void *p);
-
-int convert_double(PyObject *obj, void *p);
-int convert_bool(PyObject *obj, void *p);
-int convert_cap(PyObject *capobj, void *capp);
-int convert_join(PyObject *joinobj, void *joinp);
-int convert_rect(PyObject *rectobj, void *rectp);
-int convert_rgba(PyObject *rgbaocj, void *rgbap);
-int convert_dashes(PyObject *dashobj, void *gcp);
-int convert_dashes_vector(PyObject *obj, void *dashesp);
-int convert_trans_affine(PyObject *obj, void *transp);
-int convert_path(PyObject *obj, void *pathp);
-int convert_clippath(PyObject *clippath_tuple, void *clippathp);
-int convert_snap(PyObject *obj, void *snapp);
-int convert_offset_position(PyObject *obj, void *offsetp);
-int convert_sketch_params(PyObject *obj, void *sketchp);
-int convert_gcagg(PyObject *pygc, void *gcp);
-int convert_points(PyObject *pygc, void *pointsp);
-int convert_transforms(PyObject *pygc, void *transp);
-int convert_bboxes(PyObject *pygc, void *bboxp);
-int convert_colors(PyObject *pygc, void *colorsp);
-
-int convert_face(PyObject *color, GCAgg &gc, agg::rgba *rgba);
-}
-
-#endif
diff --git a/contrib/python/matplotlib/py2/src/py_exceptions.h b/contrib/python/matplotlib/py2/src/py_exceptions.h
deleted file mode 100644
index 1ee2d51903..0000000000
--- a/contrib/python/matplotlib/py2/src/py_exceptions.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/* -*- mode: c++; c-basic-offset: 4 -*- */
-
-#ifndef __PY_EXCEPTIONS_H__
-#define __PY_EXCEPTIONS_H__
-
-#include <exception>
-#include <stdexcept>
-
-namespace py
-{
-class exception : public std::exception
-{
- public:
- const char *what() const throw()
- {
- return "python error has been set";
- }
-};
-}
-
-#define CALL_CPP_FULL(name, a, cleanup, errorcode) \
- try \
- { \
- a; \
- } \
- catch (const py::exception &) \
- { \
- { \
- cleanup; \
- } \
- return (errorcode); \
- } \
- catch (const std::bad_alloc &) \
- { \
- PyErr_Format(PyExc_MemoryError, "In %s: Out of memory", (name)); \
- { \
- cleanup; \
- } \
- return (errorcode); \
- } \
- catch (const std::overflow_error &e) \
- { \
- PyErr_Format(PyExc_OverflowError, "In %s: %s", (name), e.what()); \
- { \
- cleanup; \
- } \
- return (errorcode); \
- } \
- catch (const std::runtime_error &e) \
- { \
- PyErr_Format(PyExc_RuntimeError, "In %s: %s", (name), e.what()); \
- { \
- cleanup; \
- } \
- return (errorcode); \
- } \
- catch (...) \
- { \
- PyErr_Format(PyExc_RuntimeError, "Unknown exception in %s", (name)); \
- { \
- cleanup; \
- } \
- return (errorcode); \
- }
-
-#define CALL_CPP_CLEANUP(name, a, cleanup) CALL_CPP_FULL(name, a, cleanup, NULL)
-
-#define CALL_CPP(name, a) CALL_CPP_FULL(name, a, , NULL)
-
-#define CALL_CPP_INIT(name, a) CALL_CPP_FULL(name, a, , -1)
-
-#endif
diff --git a/contrib/python/matplotlib/py2/src/qhull_wrap.c b/contrib/python/matplotlib/py2/src/qhull_wrap.c
deleted file mode 100644
index 836a16c555..0000000000
--- a/contrib/python/matplotlib/py2/src/qhull_wrap.c
+++ /dev/null
@@ -1,378 +0,0 @@
-/*
- * Wrapper module for libqhull, providing Delaunay triangulation.
- *
- * This module's methods should not be accessed directly. To obtain a Delaunay
- * triangulation, construct an instance of the matplotlib.tri.Triangulation
- * class without specifying a triangles array.
- */
-#define PY_SSIZE_T_CLEAN
-#include "Python.h"
-#include "numpy/noprefix.h"
-#include "qhull_ra.h"
-#include <stdio.h>
-
-
-#if PY_MAJOR_VERSION >= 3
-#define PY3K 1
-#else
-#define PY3K 0
-#endif
-
-#ifndef MPL_DEVNULL
-#error "MPL_DEVNULL must be defined as the OS-equivalent of /dev/null"
-#endif
-
-#define STRINGIFY(x) STR(x)
-#define STR(x) #x
-
-static qhT qhData;
-static qhT* qh = &qhData;
-
-static const char* qhull_error_msg[6] = {
- "", /* 0 = qh_ERRnone */
- "input inconsistency", /* 1 = qh_ERRinput */
- "singular input data", /* 2 = qh_ERRsingular */
- "precision error", /* 3 = qh_ERRprec */
- "insufficient memory", /* 4 = qh_ERRmem */
- "internal error"}; /* 5 = qh_ERRqhull */
-
-
-/* Return the indices of the 3 vertices that comprise the specified facet (i.e.
- * triangle). */
-static void
-get_facet_vertices(const facetT* facet, int indices[3])
-{
- vertexT *vertex, **vertexp;
- FOREACHvertex_(facet->vertices)
- *indices++ = qh_pointid(qh, vertex->point);
-}
-
-/* Return the indices of the 3 triangles that are neighbors of the specified
- * facet (triangle). */
-static void
-get_facet_neighbours(const facetT* facet, const int* tri_indices,
- int indices[3])
-{
- facetT *neighbor, **neighborp;
- FOREACHneighbor_(facet)
- *indices++ = (neighbor->upperdelaunay ? -1 : tri_indices[neighbor->id]);
-}
-
-/* Return 1 if the specified points arrays contain at least 3 unique points,
- * or 0 otherwise. */
-static int
-at_least_3_unique_points(int npoints, const double* x, const double* y)
-{
- int i;
- const int unique1 = 0; /* First unique point has index 0. */
- int unique2 = 0; /* Second unique point index is 0 until set. */
-
- if (npoints < 3)
- return 0;
-
- for (i = 1; i < npoints; ++i) {
- if (unique2 == 0) {
- /* Looking for second unique point. */
- if (x[i] != x[unique1] || y[i] != y[unique1])
- unique2 = i;
- }
- else {
- /* Looking for third unique point. */
- if ( (x[i] != x[unique1] || y[i] != y[unique1]) &&
- (x[i] != x[unique2] || y[i] != y[unique2]) ) {
- /* 3 unique points found, with indices 0, unique2 and i. */
- return 1;
- }
- }
- }
-
- /* Run out of points before 3 unique points found. */
- return 0;
-}
-
-/* Delaunay implementation methyod. If hide_qhull_errors is 1 then qhull error
- * messages are discarded; if it is 0 then they are written to stderr. */
-static PyObject*
-delaunay_impl(int npoints, const double* x, const double* y,
- int hide_qhull_errors)
-{
- coordT* points = NULL;
- facetT* facet;
- int i, ntri, max_facet_id;
- FILE* error_file = NULL; /* qhull expects a FILE* to write errors to. */
- int exitcode; /* Value returned from qh_new_qhull(). */
- int* tri_indices = NULL; /* Maps qhull facet id to triangle index. */
- int indices[3];
- int curlong, totlong; /* Memory remaining after qh_memfreeshort. */
- PyObject* tuple; /* Return tuple (triangles, neighbors). */
- const int ndim = 2;
- npy_intp dims[2];
- PyArrayObject* triangles = NULL;
- PyArrayObject* neighbors = NULL;
- int* triangles_ptr;
- int* neighbors_ptr;
- double x_mean = 0.0;
- double y_mean = 0.0;
-
- QHULL_LIB_CHECK
-
- /* Allocate points. */
- points = (coordT*)malloc(npoints*ndim*sizeof(coordT));
- if (points == NULL) {
- PyErr_SetString(PyExc_MemoryError,
- "Could not allocate points array in qhull.delaunay");
- goto error_before_qhull;
- }
-
- /* Determine mean x, y coordinates. */
- for (i = 0; i < npoints; ++i) {
- x_mean += x[i];
- y_mean += y[i];
- }
- x_mean /= npoints;
- y_mean /= npoints;
-
- /* Prepare points array to pass to qhull. */
- for (i = 0; i < npoints; ++i) {
- points[2*i ] = x[i] - x_mean;
- points[2*i+1] = y[i] - y_mean;
- }
-
- /* qhull expects a FILE* to write errors to. */
- if (hide_qhull_errors) {
- /* qhull errors are ignored by writing to OS-equivalent of /dev/null.
- * Rather than have OS-specific code here, instead it is determined by
- * setupext.py and passed in via the macro MPL_DEVNULL. */
- error_file = fopen(STRINGIFY(MPL_DEVNULL), "w");
- if (error_file == NULL) {
- PyErr_SetString(PyExc_RuntimeError,
- "Could not open devnull in qhull.delaunay");
- goto error_before_qhull;
- }
- }
- else {
- /* qhull errors written to stderr. */
- error_file = stderr;
- }
-
- /* Perform Delaunay triangulation. */
- exitcode = qh_new_qhull(qh, ndim, npoints, points, False,
- "qhull d Qt Qbb Qc Qz", NULL, error_file);
- if (exitcode != qh_ERRnone) {
- PyErr_Format(PyExc_RuntimeError,
- "Error in qhull Delaunay triangulation calculation: %s (exitcode=%d)%s",
- qhull_error_msg[exitcode], exitcode,
- hide_qhull_errors ? "; use python verbose option (-v) to see original qhull error." : "");
- goto error;
- }
-
- /* Split facets so that they only have 3 points each. */
- qh_triangulate(qh);
-
- /* Determine ntri and max_facet_id.
- Note that libqhull uses macros to iterate through collections. */
- ntri = 0;
- FORALLfacets {
- if (!facet->upperdelaunay)
- ++ntri;
- }
-
- max_facet_id = qh->facet_id - 1;
-
- /* Create array to map facet id to triangle index. */
- tri_indices = (int*)malloc((max_facet_id+1)*sizeof(int));
- if (tri_indices == NULL) {
- PyErr_SetString(PyExc_MemoryError,
- "Could not allocate triangle map in qhull.delaunay");
- goto error;
- }
-
- /* Allocate python arrays to return. */
- dims[0] = ntri;
- dims[1] = 3;
- triangles = (PyArrayObject*)PyArray_SimpleNew(ndim, dims, NPY_INT);
- if (triangles == NULL) {
- PyErr_SetString(PyExc_MemoryError,
- "Could not allocate triangles array in qhull.delaunay");
- goto error;
- }
-
- neighbors = (PyArrayObject*)PyArray_SimpleNew(ndim, dims, NPY_INT);
- if (neighbors == NULL) {
- PyErr_SetString(PyExc_MemoryError,
- "Could not allocate neighbors array in qhull.delaunay");
- goto error;
- }
-
- triangles_ptr = (int*)PyArray_DATA(triangles);
- neighbors_ptr = (int*)PyArray_DATA(neighbors);
-
- /* Determine triangles array and set tri_indices array. */
- i = 0;
- FORALLfacets {
- if (!facet->upperdelaunay) {
- tri_indices[facet->id] = i++;
- get_facet_vertices(facet, indices);
- *triangles_ptr++ = (facet->toporient ? indices[0] : indices[2]);
- *triangles_ptr++ = indices[1];
- *triangles_ptr++ = (facet->toporient ? indices[2] : indices[0]);
- }
- else
- tri_indices[facet->id] = -1;
- }
-
- /* Determine neighbors array. */
- FORALLfacets {
- if (!facet->upperdelaunay) {
- get_facet_neighbours(facet, tri_indices, indices);
- *neighbors_ptr++ = (facet->toporient ? indices[2] : indices[0]);
- *neighbors_ptr++ = (facet->toporient ? indices[0] : indices[2]);
- *neighbors_ptr++ = indices[1];
- }
- }
-
- /* Clean up. */
- qh_freeqhull(qh, !qh_ALL);
- qh_memfreeshort(qh, &curlong, &totlong);
- if (curlong || totlong)
- PyErr_WarnEx(PyExc_RuntimeWarning,
- "Qhull could not free all allocated memory", 1);
- if (hide_qhull_errors)
- fclose(error_file);
- free(tri_indices);
- free(points);
-
- tuple = PyTuple_New(2);
- PyTuple_SetItem(tuple, 0, (PyObject*)triangles);
- PyTuple_SetItem(tuple, 1, (PyObject*)neighbors);
- return tuple;
-
-error:
- /* Clean up. */
- Py_XDECREF(triangles);
- Py_XDECREF(neighbors);
- qh_freeqhull(qh, !qh_ALL);
- qh_memfreeshort(qh, &curlong, &totlong);
- /* Don't bother checking curlong and totlong as raising error anyway. */
- if (hide_qhull_errors)
- fclose(error_file);
- free(tri_indices);
-
-error_before_qhull:
- free(points);
-
- return NULL;
-}
-
-/* Process python arguments and call Delaunay implementation method. */
-static PyObject*
-delaunay(PyObject *self, PyObject *args)
-{
- PyObject* xarg;
- PyObject* yarg;
- PyArrayObject* xarray;
- PyArrayObject* yarray;
- PyObject* ret;
- int npoints;
- const double* x;
- const double* y;
-
- if (!PyArg_ParseTuple(args, "OO", &xarg, &yarg)) {
- PyErr_SetString(PyExc_ValueError, "expecting x and y arrays");
- return NULL;
- }
-
- xarray = (PyArrayObject*)PyArray_ContiguousFromObject(xarg, NPY_DOUBLE,
- 1, 1);
- yarray = (PyArrayObject*)PyArray_ContiguousFromObject(yarg, NPY_DOUBLE,
- 1, 1);
- if (xarray == 0 || yarray == 0 ||
- PyArray_DIM(xarray,0) != PyArray_DIM(yarray, 0)) {
- Py_XDECREF(xarray);
- Py_XDECREF(yarray);
- PyErr_SetString(PyExc_ValueError,
- "x and y must be 1D arrays of the same length");
- return NULL;
- }
-
- npoints = PyArray_DIM(xarray, 0);
-
- if (npoints < 3) {
- Py_XDECREF(xarray);
- Py_XDECREF(yarray);
- PyErr_SetString(PyExc_ValueError,
- "x and y arrays must have a length of at least 3");
- return NULL;
- }
-
- x = (const double*)PyArray_DATA(xarray);
- y = (const double*)PyArray_DATA(yarray);
-
- if (!at_least_3_unique_points(npoints, x, y)) {
- Py_XDECREF(xarray);
- Py_XDECREF(yarray);
- PyErr_SetString(PyExc_ValueError,
- "x and y arrays must consist of at least 3 unique points");
- return NULL;
- }
-
- ret = delaunay_impl(npoints, x, y, Py_VerboseFlag == 0);
-
- Py_XDECREF(xarray);
- Py_XDECREF(yarray);
- return ret;
-}
-
-/* Return qhull version string for assistance in debugging. */
-static PyObject*
-version(void)
-{
- return PyBytes_FromString(qh_version);
-}
-
-static PyMethodDef qhull_methods[] = {
- {"delaunay", (PyCFunction)delaunay, METH_VARARGS, ""},
- {"version", (PyCFunction)version, METH_NOARGS, ""},
- {NULL, NULL, 0, NULL}
-};
-
-#if PY3K
-static struct PyModuleDef qhull_module = {
- PyModuleDef_HEAD_INIT,
- "qhull",
- "Computing Delaunay triangulations.\n",
- -1,
- qhull_methods,
- NULL, NULL, NULL, NULL
-};
-
-#define ERROR_RETURN return NULL
-
-PyMODINIT_FUNC
-PyInit__qhull(void)
-#else
-#define ERROR_RETURN return
-
-PyMODINIT_FUNC
-init_qhull(void)
-#endif
-{
- PyObject* m;
-
- #if PY3K
- m = PyModule_Create(&qhull_module);
- #else
- m = Py_InitModule3("_qhull", qhull_methods,
- "Computing Delaunay triangulations.\n");
- #endif
-
- if (m == NULL) {
- ERROR_RETURN;
- }
-
- import_array();
-
- #if PY3K
- return m;
- #endif
-}
diff --git a/contrib/python/matplotlib/py2/src/ya.make b/contrib/python/matplotlib/py2/src/ya.make
deleted file mode 100644
index 486bc04e49..0000000000
--- a/contrib/python/matplotlib/py2/src/ya.make
+++ /dev/null
@@ -1,68 +0,0 @@
-PY2_LIBRARY()
-
-VERSION(2.2.5)
-
-LICENSE(PSF-2.0)
-
-NO_COMPILER_WARNINGS()
-
-PEERDIR(
- ADDINCL contrib/libs/freetype
- ADDINCL contrib/libs/libpng
- ADDINCL contrib/python/numpy
- contrib/libs/qhull
- contrib/python/matplotlib/py2/extern/agg24-svn
- contrib/python/matplotlib/py2/extern/ttconv
-)
-
-ADDINCL(
- contrib/libs/qhull/libqhull_r
- contrib/python/matplotlib/py2
- contrib/python/matplotlib/py2/extern
- contrib/python/matplotlib/py2/extern/agg24-svn/include
-)
-
-CFLAGS(
- -D_MULTIARRAYMODULE
- -DFREETYPE_BUILD_TYPE=local
- -DNPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION
- -DMPL_DEVNULL=/dev/null
-)
-
-IF (OS_WINDOWS)
- LDFLAGS(
- Psapi.lib
- )
-ENDIF()
-
-PY_REGISTER(
- matplotlib._contour
- matplotlib._image # peerdir agg24-svn
- matplotlib._path # peerdir agg24-svn
- matplotlib._png
- matplotlib._qhull # peerdir libqhull
- matplotlib.backends._backend_agg # peerdir agg24-svn
- matplotlib.backends._tkagg
- matplotlib.ft2font
- matplotlib.ttconv # peerdir ttconv
-)
-
-SRCS(
- _backend_agg.cpp
- _backend_agg_wrapper.cpp
- _contour.cpp
- _contour_wrapper.cpp
- _image.cpp
- _image_wrapper.cpp
- _path_wrapper.cpp
- _png.cpp
- _tkagg.cpp
- _ttconv.cpp
- ft2font.cpp
- ft2font_wrapper.cpp
- mplutils.cpp
- py_converters.cpp
- qhull_wrap.c
-)
-
-END()