/* -*- mode: c++; c-basic-offset: 4 -*- */
#define NO_IMPORT_ARRAY
#include
#include "_backend_agg.h"
RendererAgg::RendererAgg(unsigned int width, unsigned int height, double dpi)
: width(width),
height(height),
dpi(dpi),
NUMBYTES((size_t)width * (size_t)height * 4),
pixBuffer(nullptr),
otherPixBuffer(nullptr),
renderingBuffer(),
alphaBuffer(nullptr),
alphaMaskRenderingBuffer(),
alphaMask(alphaMaskRenderingBuffer),
pixfmtAlphaMask(alphaMaskRenderingBuffer),
rendererBaseAlphaMask(),
rendererAlphaMask(),
scanlineAlphaMask(),
slineP8(),
slineBin(),
pixFmt(),
rendererBase(),
rendererAA(),
rendererBin(),
theRasterizer(32768),
lastclippath(nullptr),
_fill_color(agg::rgba(1, 1, 1, 0))
{
if (dpi = 1 = 1 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() == nullptr) {
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, nullptr, 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() == nullptr) {
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(mpl::PathIterator &clippath,
const agg::trans_affine &clippath_trans,
e_snap_mode snap_mode)
{
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));
auto transformed_clippath = agg::conv_transform{clippath, trans};
auto nan_removed_clippath = PathNanRemover{
transformed_clippath, true, clippath.has_codes()};
// Unlike normal Paths, the clip path cannot be clipped to the Figure
// bbox, because it needs to remain a complete closed path, so there is
// no PathClipper step after nan-removal.
auto snapped_clippath = PathSnapper{
nan_removed_clippath, snap_mode, clippath.total_vertices(), 0.0};
auto simplified_clippath = PathSimplifier{
snapped_clippath,
clippath.should_simplify() && !clippath.has_codes(),
clippath.simplify_threshold()};
auto curved_clippath = agg::conv_curve{simplified_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::clear()
{
//"clear the rendered buffer";
rendererBase.clear(_fill_color);
}