@@ -814,55 +814,99 @@ Py::Object
814814RendererAgg::draw_image (const Py::Tuple& args) {
815815 _VERBOSE (" RendererAgg::draw_image" );
816816
817- args.verify_length (4 );
817+ args.verify_length (4 , 7 ); // 7 if affine matrix if given
818818
819819 GCAgg gc (args[0 ], dpi);
820- double x = mpl_round (Py::Float (args[1 ]));
821- double y = mpl_round (Py::Float (args[2 ]));
822820 Image *image = static_cast <Image*>(args[3 ].ptr ());
823821 bool has_clippath = false ;
822+ agg::trans_affine affine_trans;
823+ bool has_affine = false ;
824+ double x, y, w, h;
825+
826+
827+ if (args.size () == 7 ) {
828+ has_affine = true ;
829+ x = Py::Float (args[1 ]);
830+ y = Py::Float (args[2 ]);
831+ w = Py::Float (args[4 ]);
832+ h = Py::Float (args[5 ]);
833+ affine_trans = py_to_agg_transformation_matrix (args[6 ].ptr ());
834+ } else {
835+ x = mpl_round (Py::Float (args[1 ]));
836+ y = mpl_round (Py::Float (args[2 ]));
837+ }
838+
824839
825840 theRasterizer.reset_clipping ();
826841 rendererBase.reset_clipping (true );
842+ set_clipbox (gc.cliprect , theRasterizer);
827843 has_clippath = render_clippath (gc.clippath , gc.clippath_trans );
828844
829845 Py::Tuple empty;
830846 image->flipud_out (empty);
831847 pixfmt pixf (*(image->rbufOut ));
832848
833- if (has_clippath) {
849+ if (has_affine | has_clippath) {
834850 agg::trans_affine mtx;
835- mtx *= agg::trans_affine_translation ((int )x, (int )(height-(y+image->rowsOut )));
836-
837851 agg::path_storage rect;
852+
853+ if (has_affine) {
854+ mtx *= agg::trans_affine_scaling (1 , -1 );
855+ mtx *= agg::trans_affine_translation (0 , image->rowsOut );
856+ mtx *= agg::trans_affine_scaling (w/(image->colsOut ), h/(image->rowsOut ));
857+ mtx *= agg::trans_affine_translation (x, y);
858+ mtx *= affine_trans;
859+ mtx *= agg::trans_affine_scaling (1.0 , -1.0 );
860+ mtx *= agg::trans_affine_translation (0.0 , (double ) height);
861+ } else {
862+ mtx *= agg::trans_affine_translation ((int )x, (int )(height-(y+image->rowsOut )));
863+ }
864+
838865 rect.move_to (0 , 0 );
839866 rect.line_to (image->colsOut , 0 );
840867 rect.line_to (image->colsOut , image->rowsOut );
841868 rect.line_to (0 , image->rowsOut );
842869 rect.line_to (0 , 0 );
870+
843871 agg::conv_transform<agg::path_storage> rect2 (rect, mtx);
844872
845873 agg::trans_affine inv_mtx (mtx);
846874 inv_mtx.invert ();
847875
876+
848877 typedef agg::span_allocator<agg::rgba8> color_span_alloc_type;
849- typedef agg::pixfmt_amask_adaptor<pixfmt, alpha_mask_type> pixfmt_amask_type;
850- typedef agg::renderer_base<pixfmt_amask_type> amask_ren_type;
851878 typedef agg::image_accessor_clip<agg::pixfmt_rgba32> image_accessor_type;
852879 typedef agg::span_interpolator_linear<> interpolator_type;
853880 typedef agg::span_image_filter_rgba_nn<image_accessor_type, interpolator_type> image_span_gen_type;
854- typedef agg::renderer_scanline_aa<amask_ren_type, color_span_alloc_type, image_span_gen_type> renderer_type;
881+
855882
856883 color_span_alloc_type sa;
857884 image_accessor_type ia (pixf, agg::rgba8 (0 , 0 , 0 , 0 ));
858885 interpolator_type interpolator (inv_mtx);
859886 image_span_gen_type image_span_generator (ia, interpolator);
860- pixfmt_amask_type pfa (pixFmt, alphaMask);
861- amask_ren_type r (pfa);
862- renderer_type ri (r, sa, image_span_generator);
863887
864- theRasterizer.add_path (rect2);
865- agg::render_scanlines (theRasterizer, slineP8, ri);
888+
889+ if (has_clippath) {
890+ typedef agg::pixfmt_amask_adaptor<pixfmt, alpha_mask_type> pixfmt_amask_type;
891+ typedef agg::renderer_base<pixfmt_amask_type> amask_ren_type;
892+ typedef agg::renderer_scanline_aa<amask_ren_type, color_span_alloc_type, image_span_gen_type> renderer_type_alpha;
893+
894+ pixfmt_amask_type pfa (pixFmt, alphaMask);
895+ amask_ren_type r (pfa);
896+ renderer_type_alpha ri (r, sa, image_span_generator);
897+
898+ theRasterizer.add_path (rect2);
899+ agg::render_scanlines (theRasterizer, slineP8, ri);
900+ } else {
901+ typedef agg::renderer_base<pixfmt> ren_type;
902+ typedef agg::renderer_scanline_aa<ren_type, color_span_alloc_type, image_span_gen_type> renderer_type;
903+ ren_type r (pixFmt);
904+ renderer_type ri (r, sa, image_span_generator);
905+
906+ theRasterizer.add_path (rect2);
907+ agg::render_scanlines (theRasterizer, slineP8, ri);
908+ }
909+
866910 } else {
867911 set_clipbox (gc.cliprect , rendererBase);
868912 rendererBase.blend_from (pixf, 0 , (int )x, (int )(height-(y+image->rowsOut )));
@@ -873,6 +917,9 @@ RendererAgg::draw_image(const Py::Tuple& args) {
873917 return Py::Object ();
874918}
875919
920+
921+
922+
876923template <class path_t >
877924void RendererAgg::_draw_path (path_t & path, bool has_clippath,
878925 const facepair_t & face, const GCAgg& gc) {
0 commit comments