X Tutup
Skip to content

Commit dee65fa

Browse files
committed
WIP: Add support for blend modes in Agg backend
1 parent 374c155 commit dee65fa

File tree

2 files changed

+66
-2
lines changed

2 files changed

+66
-2
lines changed

src/_backend_agg.h

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,8 @@ class RendererAgg
109109
{
110110
public:
111111

112-
typedef fixed_blender_rgba_plain<agg::rgba8, agg::order_rgba> fixed_blender_rgba32_plain;
113-
typedef agg::pixfmt_alpha_blend_rgba<fixed_blender_rgba32_plain, agg::rendering_buffer> pixfmt;
112+
typedef agg::comp_op_adaptor_rgba_plain<agg::rgba8, agg::order_rgba> comp_op_blender_plain;
113+
typedef agg::pixfmt_custom_blend_rgba<comp_op_blender_plain, agg::rendering_buffer> pixfmt;
114114
typedef agg::renderer_base<pixfmt> renderer_base;
115115
typedef agg::renderer_scanline_aa_solid<renderer_base> renderer_aa;
116116
typedef agg::renderer_scanline_bin_solid<renderer_base> renderer_bin;
@@ -461,6 +461,8 @@ RendererAgg::draw_path(GCAgg &gc, PathIterator &path, agg::trans_affine &trans,
461461
face = color;
462462
}
463463

464+
pixFmt.comp_op(gc.comp_op);
465+
464466
theRasterizer.reset_clipping();
465467
rendererBase.reset_clipping(true);
466468
set_clipbox(gc.cliprect, theRasterizer);
@@ -484,6 +486,8 @@ RendererAgg::draw_path(GCAgg &gc, PathIterator &path, agg::trans_affine &trans,
484486
sketch_t sketch(curve, gc.sketch.scale, gc.sketch.length, gc.sketch.randomness);
485487

486488
_draw_path(sketch, has_clippath, face, gc);
489+
490+
pixFmt.comp_op(agg::comp_op_src_over);
487491
}
488492

489493
template <class PathIterator>
@@ -571,6 +575,9 @@ inline void RendererAgg::draw_markers(GCAgg &gc,
571575
std::max(marker_size.x2, scanlines.max_x()),
572576
std::max(marker_size.y2, scanlines.max_y()));
573577

578+
579+
pixFmt.comp_op(gc.comp_op);
580+
574581
theRasterizer.reset_clipping();
575582
rendererBase.reset_clipping(true);
576583
set_clipbox(gc.cliprect, rendererBase);
@@ -658,6 +665,8 @@ inline void RendererAgg::draw_markers(GCAgg &gc,
658665

659666
theRasterizer.reset_clipping();
660667
rendererBase.reset_clipping(true);
668+
669+
pixFmt.comp_op(agg::comp_op_src_over);
661670
}
662671

663672
/**
@@ -714,6 +723,8 @@ inline void RendererAgg::draw_text_image(GCAgg &gc, ImageArray &image, int x, in
714723
typedef agg::renderer_scanline_aa<renderer_base, color_span_alloc_type, span_gen_type>
715724
renderer_type;
716725

726+
pixFmt.comp_op(gc.comp_op);
727+
717728
theRasterizer.reset_clipping();
718729
rendererBase.reset_clipping(true);
719730
if (angle != 0.0) {
@@ -782,6 +793,8 @@ inline void RendererAgg::draw_text_image(GCAgg &gc, ImageArray &image, int x, in
782793
}
783794
}
784795
}
796+
797+
pixFmt.comp_op(agg::comp_op_src_over);
785798
}
786799

787800
class span_conv_alpha
@@ -814,6 +827,7 @@ inline void RendererAgg::draw_image(GCAgg &gc,
814827
ImageArray &image)
815828
{
816829
double alpha = gc.alpha;
830+
pixFmt.comp_op(gc.comp_op);
817831

818832
theRasterizer.reset_clipping();
819833
rendererBase.reset_clipping(true);
@@ -878,6 +892,8 @@ inline void RendererAgg::draw_image(GCAgg &gc,
878892
}
879893

880894
rendererBase.reset_clipping(true);
895+
896+
pixFmt.comp_op(agg::comp_op_src_over);
881897
}
882898

883899
template <class PathIterator,
@@ -1042,6 +1058,7 @@ inline void RendererAgg::draw_path_collection(GCAgg &gc,
10421058
AntialiasedArray &antialiaseds,
10431059
ColorArray &hatchcolors)
10441060
{
1061+
pixFmt.comp_op(gc.comp_op);
10451062
_draw_path_collection_generic(gc,
10461063
master_transform,
10471064
gc.cliprect,
@@ -1059,6 +1076,7 @@ inline void RendererAgg::draw_path_collection(GCAgg &gc,
10591076
true,
10601077
true,
10611078
hatchcolors);
1079+
pixFmt.comp_op(agg::comp_op_src_over);
10621080
}
10631081

10641082
template <class CoordinateArray>
@@ -1154,6 +1172,7 @@ inline void RendererAgg::draw_quad_mesh(GCAgg &gc,
11541172
DashesVector linestyles;
11551173
ColorArray hatchcolors = py::array_t<double>().reshape({0, 4}).unchecked<double, 2>();
11561174

1175+
pixFmt.comp_op(gc.comp_op);
11571176
_draw_path_collection_generic(gc,
11581177
master_transform,
11591178
gc.cliprect,
@@ -1171,6 +1190,7 @@ inline void RendererAgg::draw_quad_mesh(GCAgg &gc,
11711190
true, // check_snap
11721191
false,
11731192
hatchcolors);
1193+
pixFmt.comp_op(agg::comp_op_src_over);
11741194
}
11751195

11761196
template <class PointArray, class ColorArray>
@@ -1248,6 +1268,8 @@ inline void RendererAgg::draw_gouraud_triangles(GCAgg &gc,
12481268
std::to_string(colors.shape(0)) + "colors");
12491269
}
12501270

1271+
pixFmt.comp_op(gc.comp_op);
1272+
12511273
theRasterizer.reset_clipping();
12521274
rendererBase.reset_clipping(true);
12531275
set_clipbox(gc.cliprect, theRasterizer);
@@ -1259,6 +1281,8 @@ inline void RendererAgg::draw_gouraud_triangles(GCAgg &gc,
12591281

12601282
_draw_gouraud_triangle(point, color, trans, has_clippath);
12611283
}
1284+
1285+
pixFmt.comp_op(agg::comp_op_src_over);
12621286
}
12631287

12641288
template <class R>

src/_backend_agg_basic_types.h

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
#include "agg_color_rgba.h"
1313
#include "agg_math_stroke.h"
14+
#include "agg_pixfmt_rgba.h"
1415
#include "agg_trans_affine.h"
1516
#include "path_converters.h"
1617

@@ -80,6 +81,7 @@ class GCAgg
8081
GCAgg()
8182
: linewidth(1.0),
8283
alpha(1.0),
84+
comp_op(agg::comp_op_src_over),
8385
cap(agg::butt_cap),
8486
join(agg::round_join),
8587
snap_mode(SNAP_FALSE)
@@ -93,6 +95,7 @@ class GCAgg
9395
double linewidth;
9496
double alpha;
9597
bool forced_alpha;
98+
agg::comp_op_e comp_op;
9699
agg::rgba color;
97100
bool isaa;
98101

@@ -125,6 +128,42 @@ class GCAgg
125128
};
126129

127130
namespace PYBIND11_NAMESPACE { namespace detail {
131+
template <> struct type_caster<agg::comp_op_e> {
132+
public:
133+
PYBIND11_TYPE_CASTER(agg::comp_op_e, const_name("comp_op_e"));
134+
135+
bool load(handle src, bool) {
136+
const std::unordered_map<std::string, agg::comp_op_e> enum_values = {
137+
{"clear", agg::comp_op_clear},
138+
{"source", agg::comp_op_src},
139+
//{"dest", agg::comp_op_dst},
140+
{"over", agg::comp_op_src_over},
141+
//{"dst_over", agg::comp_op_dst_over},
142+
{"in", agg::comp_op_src_in},
143+
//{"dst_in", agg::comp_op_dst_in},
144+
{"out", agg::comp_op_src_out},
145+
//{"dst_out", agg::comp_op_dst_out},
146+
{"atop", agg::comp_op_src_atop},
147+
//{"dst_atop", agg::comp_op_dst_atop},
148+
{"xor", agg::comp_op_xor},
149+
{"plus", agg::comp_op_plus},
150+
{"multiply", agg::comp_op_multiply},
151+
{"screen", agg::comp_op_screen},
152+
{"overlay", agg::comp_op_overlay},
153+
{"darken", agg::comp_op_darken},
154+
{"lighten", agg::comp_op_lighten},
155+
{"color_dodge", agg::comp_op_color_dodge},
156+
{"color_burn", agg::comp_op_color_burn},
157+
{"hard_light", agg::comp_op_hard_light},
158+
{"soft_light", agg::comp_op_soft_light},
159+
{"difference", agg::comp_op_difference},
160+
{"exclusion", agg::comp_op_exclusion},
161+
};
162+
value = enum_values.at(src.cast<std::string>());
163+
return true;
164+
}
165+
};
166+
128167
template <> struct type_caster<agg::line_cap_e> {
129168
public:
130169
PYBIND11_TYPE_CASTER(agg::line_cap_e, const_name("line_cap_e"));
@@ -234,6 +273,7 @@ namespace PYBIND11_NAMESPACE { namespace detail {
234273
value.linewidth = src.attr("_linewidth").cast<double>();
235274
value.alpha = src.attr("_alpha").cast<double>();
236275
value.forced_alpha = src.attr("_forced_alpha").cast<bool>();
276+
value.comp_op = src.attr("_blend_mode").cast<agg::comp_op_e>();
237277
value.color = src.attr("_rgb").cast<agg::rgba>();
238278
value.isaa = src.attr("_antialiased").cast<bool>();
239279
value.cap = src.attr("_capstyle").cast<agg::line_cap_e>();

0 commit comments

Comments
 (0)
X Tutup