diff options
author | shumkovnd <shumkovnd@yandex-team.com> | 2023-11-10 14:39:34 +0300 |
---|---|---|
committer | shumkovnd <shumkovnd@yandex-team.com> | 2023-11-10 16:42:24 +0300 |
commit | 77eb2d3fdcec5c978c64e025ced2764c57c00285 (patch) | |
tree | c51edb0748ca8d4a08d7c7323312c27ba1a8b79a /contrib/python/matplotlib/py2/src/_backend_agg.cpp | |
parent | dd6d20cadb65582270ac23f4b3b14ae189704b9d (diff) | |
download | ydb-77eb2d3fdcec5c978c64e025ced2764c57c00285.tar.gz |
KIKIMR-19287: add task_stats_drawing script
Diffstat (limited to 'contrib/python/matplotlib/py2/src/_backend_agg.cpp')
-rw-r--r-- | contrib/python/matplotlib/py2/src/_backend_agg.cpp | 234 |
1 files changed, 234 insertions, 0 deletions
diff --git a/contrib/python/matplotlib/py2/src/_backend_agg.cpp b/contrib/python/matplotlib/py2/src/_backend_agg.cpp new file mode 100644 index 0000000000..3dc35f6782 --- /dev/null +++ b/contrib/python/matplotlib/py2/src/_backend_agg.cpp @@ -0,0 +1,234 @@ +/* -*- 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 ®ion) +{ + 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 ®ion, 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); +} |