18 #if wxART2D_USE_AGGDRAWER
20 #if wxART2D_USE_GRAPHICS_CONTEXT
24 #include "wx/window.h"
27 #include "wx/dialog.h"
29 #include "wx/bitmap.h"
30 #include "wx/dcmemory.h"
33 #include "wx/dcprint.h"
34 #include "wx/module.h"
37 #include "wx/aggdrawer/graphicagg.h"
42 #include "wx/graphics.h"
43 #include "wx/rawbmp.h"
45 #if wxART2D_USE_FREETYPE
50 #include <freetype/freetype.h>
51 #include <freetype/ftoutln.h>
54 #include FT_FREETYPE_H
67 const double RAD2DEG = 180.0 / M_PI;
73 static inline double dmin(
double a,
double b )
77 static inline double dmax(
double a,
double b )
82 static inline double DegToRad(
double deg )
84 return ( deg * M_PI ) / 180.0;
86 static inline double RadToDeg(
double deg )
88 return ( deg * 180.0 ) / M_PI;
99 #define max(a,b) (((a) > (b)) ? (a) : (b))
103 #define min(a,b) (((a) < (b)) ? (a) : (b))
110 template<
class PathT >
111 void a2dAggContext::_ras_add_stroked_path_xform( PathT& path,
const
112 agg::trans_affine& mtx )
123 typedef agg::conv_stroke< PathT > path_stroke_t;
124 typedef agg::conv_transform< path_stroke_t > path_stroke_trans_t;
126 path_stroke_t stroke( path );
127 path_stroke_trans_t trans_path( stroke, mtx );
128 stroke.line_join( m_join );
129 stroke.line_cap( m_cap );
130 if ( m_activestroke.GetPixelStroke() )
131 stroke.width( m_strokewidthDev );
133 stroke.width( m_strokewidth );
134 m_rasterizer.reset();
135 m_rasterizer.add_path( trans_path );
139 typedef agg::conv_transform<PathT> trans_t;
140 typedef agg::conv_stroke< trans_t > path_stroke_t;
142 trans_t trans_path( path, mtx );
143 path_stroke_t stroke( trans_path );
145 stroke.line_join( m_join );
146 stroke.line_cap( m_cap );
147 stroke.width( m_strokewidthDev );
148 m_rasterizer.reset();
149 m_rasterizer.add_path( stroke );
156 typedef agg::conv_dash< PathT > path_dash_t;
157 typedef agg::conv_stroke< path_dash_t > path_dashstroked_t;
158 typedef agg::conv_transform< path_dashstroked_t > path_transdash_t;
160 path_dash_t dash_path( path );
161 path_dashstroked_t stroke( dash_path );
162 path_transdash_t trans_path( stroke, mtx );
164 double scale = m_strokewidth;
165 if ( scale < 1.0 ) scale = 1.0;
170 dash_path.add_dash( 0.25 * scale, 1.5 * scale );
173 dash_path.add_dash( 0.25 * scale, 1.5 * scale );
174 dash_path.add_dash( 2.0 * scale, 2.0 * scale );
177 dash_path.add_dash( 2.0 * scale, 2.0 * scale );
180 dash_path.add_dash( 2.0 * scale, 2.0 * scale );
186 stroke.line_join( m_join );
187 stroke.line_cap( m_cap );
189 if ( m_activestroke.GetPixelStroke() )
190 stroke.width( m_strokewidthDev );
192 stroke.width( m_strokewidth );
193 m_rasterizer.reset();
194 m_rasterizer.add_path( trans_path );
198 typedef agg::conv_transform<PathT> trans_t;
199 typedef agg::conv_dash< trans_t > path_transdash_t;
200 typedef agg::conv_stroke< path_transdash_t > path_dashstroked_t;
202 trans_t trans_path( path, mtx );
203 path_transdash_t dash_path( trans_path );
204 path_dashstroked_t stroke( dash_path );
206 double scale = m_strokewidthDev;
207 if ( scale < 1.0 ) scale = 1.0;
212 dash_path.add_dash( 0.25 * scale, 1.5 * scale );
215 dash_path.add_dash( 0.25 * scale, 1.5 * scale );
216 dash_path.add_dash( 2.0 * scale, 2.0 * scale );
219 dash_path.add_dash( 2.0 * scale, 2.0 * scale );
222 dash_path.add_dash( 2.0 * scale, 2.0 * scale );
228 stroke.line_join( m_join );
229 stroke.line_cap( m_cap );
231 stroke.width( m_strokewidthDev );
232 m_rasterizer.reset();
233 m_rasterizer.add_path( stroke );
240 void a2dAggContext::_stipple_render_scanlines( agg::rasterizer_scanline_aa<>& ras,
241 agg::scanline_u8& sl,
243 agg::rendering_buffer pat,
246 unsigned offset_x = 0;
247 unsigned offset_y = 0;
251 typedef agg::wrap_mode_repeat wrap_x_type;
252 typedef agg::wrap_mode_repeat wrap_y_type;
254 typedef agg::image_accessor_wrap<PixFormat, wrap_x_type, wrap_y_type> img_source_type;
256 typedef agg::span_allocator<color_type> span_alloc_type;
258 typedef agg::renderer_scanline_aa<RendererBaseA, span_alloc_type, span_gen_type> renderer_type;
260 PixFormat img_pixf( pat );
261 img_source_type img_src( img_pixf );
262 span_gen_type sg( img_src, offset_x, offset_y );
264 sg.alpha( span_gen_type::value_type( alpha ) );
267 renderer_type rp( renb, sa, sg );
269 agg::render_scanlines( ras, sl, rp );
272 a2dAggContext::a2dAggContext( wxGraphicsRenderer* renderer,
const wxImage& drawable )
274 m_rendering_buffer(),
275 m_pixFormat( m_rendering_buffer ),
276 m_pixFormatComp( m_rendering_buffer ),
277 m_renBase( m_pixFormat ),
278 m_renBaseComp( m_pixFormatComp ),
279 m_renderer( m_renBase ),
280 m_renSolidComp( m_renBaseComp ),
284 m_fillGradientMatrix(),
285 m_lineGradientMatrix(),
286 m_fillGradientD1( 0.0 ),
287 m_lineGradientD1( 0.0 ),
288 m_fillGradientD2( 100.0 ),
289 m_lineGradientD2( 100.0 ),
290 m_fillGradientInterpolator( m_fillGradientMatrix ),
291 m_lineGradientInterpolator( m_lineGradientMatrix ),
292 m_linearGradientFunction(),
293 m_radialGradientFunction(),
294 a2dContext( renderer, drawable.GetWidth(), drawable.GetHeight() )
297 m_pdata = m_buffer->GetData();
298 m_rendering_buffer.attach( m_pdata, m_width, m_height, m_width * 4 );
303 a2dAggContext::a2dAggContext( wxGraphicsRenderer* renderer,
a2dImageRGBA* drawable )
305 m_rendering_buffer(),
306 m_pixFormat( m_rendering_buffer ),
307 m_pixFormatComp( m_rendering_buffer ),
308 m_renBase( m_pixFormat ),
309 m_renBaseComp( m_pixFormatComp ),
310 m_renderer( m_renBase ),
311 m_renSolidComp( m_renBaseComp ),
315 m_fillGradientMatrix(),
316 m_lineGradientMatrix(),
317 m_fillGradientD1( 0.0 ),
318 m_lineGradientD1( 0.0 ),
319 m_fillGradientD2( 100.0 ),
320 m_lineGradientD2( 100.0 ),
321 m_fillGradientInterpolator( m_fillGradientMatrix ),
322 m_lineGradientInterpolator( m_lineGradientMatrix ),
323 m_linearGradientFunction(),
324 m_radialGradientFunction(),
325 a2dContext( renderer, drawable->GetWidth(), drawable->GetHeight() )
328 m_pdata = m_buffer->GetData();
329 m_rendering_buffer.attach( m_pdata, m_width, m_height, m_width * 4 );
334 a2dAggContext::~a2dAggContext()
338 void a2dAggContext::Clip(
const wxRegion& region )
341 wxGraphicsPath path = GetRenderer()->CreatePath();
342 wxRegionIterator ri( region );
345 path.AddRectangle( ri.GetX(), ri.GetY(), ri.GetW(), ri.GetH() );
350 void a2dAggContext::Clip( wxDouble x, wxDouble y, wxDouble w, wxDouble h )
357 m_usertodevice.TransformPoint( x, y, dx, dy );
358 trpoints[0] = wxPoint( dx, dy );
359 m_usertodevice.TransformPoint( x, y + h, dx, dy );
360 trpoints[1] = wxPoint( dx, dy );
361 m_usertodevice.TransformPoint( x + w, y + h, dx, dy );
362 trpoints[2] = wxPoint( dx, dy );
363 m_usertodevice.TransformPoint( x + w, y, dx, dy );
364 trpoints[3] = wxPoint( dx, dy );
366 double xmin = trpoints[0].x;
367 double ymin = trpoints[0].y;
368 double xmax = trpoints[0].x;
369 double ymax = trpoints[0].y;
370 for (
int i = 1; i < 4; i ++ )
372 xmin = wxMin( xmin, trpoints[i].x );
373 xmax = wxMax( xmax, trpoints[i].x );
374 ymin = wxMin( ymin, trpoints[i].y );
375 ymax = wxMax( ymax, trpoints[i].y );
377 wxRect cliprect = wxRect( xmin, ymin, xmax - xmin, ymax - ymin );
378 m_clipboxdev = cliprect;
380 m_renBase.clip_box( xmin, ymin, xmax, ymax );
381 m_renBaseComp.clip_box( xmin, ymin, xmax, ymax );
382 m_rasterizer.clip_box( 0, 0, m_width, m_height );
387 void a2dAggContext::ResetClip()
389 m_clipboxdev = wxRect( 0, 0, m_width, m_height );
390 m_renBase.clip_box( 0, 0, m_width, m_height );
391 m_renBaseComp.clip_box( 0, 0, m_width, m_height );
392 m_rasterizer.clip_box( 0, 0, m_width, m_height );
395 void a2dAggContext::Render(
bool fillColor )
399 agg::rgba8 colorfill( m_colour1redFill, m_colour1greenFill, m_colour1blueFill, m_FillOpacityCol1 );
400 m_renderer.color( colorfill );
401 m_renSolidComp.color( colorfill );
405 agg::rgba8 colorstroke( m_colour1redStroke, m_colour1greenStroke, m_colour1blueStroke, m_StrokeOpacityCol1 );
406 m_renderer.color( colorstroke );
407 m_renSolidComp.color( colorstroke );
410 if( m_blendMode == agg::end_of_comp_op_e )
411 agg::render_scanlines( m_rasterizer, m_sl, m_renderer );
413 agg::render_scanlines( m_rasterizer, m_sl, m_renSolidComp );
416 void a2dAggContext::RenderGradient(
bool radial )
420 span_allocator_type aggallocator;
421 LinearGradientSpan span(
422 m_fillGradientInterpolator,
423 m_linearGradientFunction,
427 RendererLinearGradientA ren( m_renBase, aggallocator, span );
428 RendererLinearGradientComp renComp( m_renBaseComp, aggallocator, span );
430 if( m_blendMode == agg::end_of_comp_op_e )
431 agg::render_scanlines( m_rasterizer, m_sl, ren );
433 agg::render_scanlines( m_rasterizer, m_sl, renComp );
437 span_allocator_type aggallocator;
438 RadialGradientSpan span(
439 m_fillGradientInterpolator,
440 m_radialGradientFunction,
444 RendererRadialGradientA ren( m_renBase, aggallocator, span );
445 RendererRadialGradientComp renComp( m_renBaseComp, aggallocator, span );
447 if( m_blendMode == agg::end_of_comp_op_e )
448 agg::render_scanlines( m_rasterizer, m_sl, ren );
450 agg::render_scanlines( m_rasterizer, m_sl, renComp );
455 void a2dAggContext::RenderBitmapFill()
457 unsigned offset_x = 0;
458 unsigned offset_y = 0;
462 typedef agg::wrap_mode_repeat wrap_x_type;
463 typedef agg::wrap_mode_repeat wrap_y_type;
465 typedef agg::image_accessor_wrap<PixFormat, wrap_x_type, wrap_y_type> img_source_type;
467 typedef agg::span_allocator<color_type> span_alloc_type;
469 typedef agg::renderer_scanline_aa<RendererBaseA, span_alloc_type, span_gen_type> renderer_type;
471 PixFormat img_pixf( m_pattern_rbuf );
472 img_source_type img_src( img_pixf );
473 span_gen_type sg( img_src, offset_x, offset_y );
475 sg.alpha( span_gen_type::value_type( m_FillOpacityCol1 ) );
478 renderer_type rp( m_renBase, sa, sg );
480 agg::render_scanlines( m_rasterizer, m_sl, rp );
483 void a2dAggContext::Rotate( wxDouble angle )
485 m_usertodevice.Rotate( angle ) ;
488 void a2dAggContext::Translate( wxDouble dx , wxDouble dy )
490 m_usertodevice.Translate( dx, dy ) ;
493 void a2dAggContext::Scale( wxDouble xScale , wxDouble yScale )
495 m_usertodevice.Scale( xScale, yScale, 0, 0 ) ;
499 void a2dAggContext::ConcatTransform(
const wxGraphicsMatrix& matrix )
502 m_usertodevice *= *m;
506 void a2dAggContext::SetTransform(
const wxGraphicsMatrix& matrix )
513 wxGraphicsMatrix a2dAggContext::GetTransform()
const
515 wxGraphicsMatrix matrix = CreateMatrix();
521 #if wxCHECK_VERSION(2,9,0)
522 bool a2dAggContext::SetCompositionMode( wxCompositionMode op )
524 if ( m_composition == op )
531 case wxCOMPOSITION_CLEAR:
532 m_blendMode = agg::comp_op_clear;
534 case wxCOMPOSITION_SOURCE:
535 m_blendMode = agg::comp_op_src;
537 case wxCOMPOSITION_OVER:
538 m_blendMode = agg::comp_op_src_over;
540 case wxCOMPOSITION_IN:
541 m_blendMode = agg::comp_op_src_in;
543 case wxCOMPOSITION_OUT:
544 m_blendMode = agg::comp_op_src_out;
546 case wxCOMPOSITION_ATOP:
547 m_blendMode = agg::comp_op_src_atop;
549 case wxCOMPOSITION_DEST:
550 m_blendMode = agg::comp_op_dst;
552 case wxCOMPOSITION_DEST_OVER:
553 m_blendMode = agg::comp_op_dst_over;
555 case wxCOMPOSITION_DEST_IN:
556 m_blendMode = agg::comp_op_dst_in;
558 case wxCOMPOSITION_DEST_OUT:
559 m_blendMode = agg::comp_op_dst_out;
561 case wxCOMPOSITION_DEST_ATOP:
562 m_blendMode = agg::comp_op_dst_atop;
564 case wxCOMPOSITION_XOR:
565 m_blendMode = agg::comp_op_xor;
567 case wxCOMPOSITION_ADD:
568 m_blendMode = agg::comp_op_plus;
571 m_blendMode = agg::end_of_comp_op_e;
577 void a2dAggContext::SetDrawStyle(
a2dDrawStyle drawstyle )
579 m_drawstyle = drawstyle;
586 m_blendMode = agg::comp_op_invert;
592 m_blendMode = agg::end_of_comp_op_e;
598 m_blendMode = agg::end_of_comp_op_e;
604 m_blendMode = agg::comp_op_invert;
608 m_blendMode = agg::end_of_comp_op_e;
614 m_pixFormatComp.comp_op( m_blendMode );
617 bool a2dAggContext::SetLogicalFunction(
int function )
624 m_blendMode = agg::comp_op_invert;
628 m_blendMode = agg::end_of_comp_op_e;
632 m_pixFormatComp.comp_op( m_blendMode );
636 void a2dAggContext::DoSetActiveStroke()
641 m_strokewidthDev = 1;
645 switch( m_activestroke.GetStyle() )
653 m_style = m_activestroke.GetStyle();
679 m_strokewidth = m_activestroke.GetWidth();
684 m_strokewidthDev = 1;
686 m_join = agg::round_join;
687 m_cap = agg::round_cap;
691 switch ( m_activestroke.GetJoin() )
693 case wxJOIN_MITER: m_join = agg::miter_join;
695 case wxJOIN_ROUND: m_join = agg::round_join;
697 case wxJOIN_BEVEL: m_join = agg::bevel_join;
699 default: m_join = agg::round_join;
701 switch ( m_activestroke.GetCap() )
703 case wxCAP_BUTT: m_cap = agg::butt_cap;
705 case wxCAP_ROUND: m_cap = agg::round_cap;
707 case wxCAP_PROJECTING: m_cap = agg::square_cap;
709 default: m_cap = agg::round_cap;
712 if ( m_activestroke.GetPixelStroke() )
716 m_strokewidthDev = m_activestroke.GetWidth();
717 m_strokewidthDev = !m_strokewidthDev ? 1 : m_strokewidthDev;
722 m_strokewidth = m_activestroke.GetWidth();
723 m_strokewidthDev = m_usertodevice.TransformDistance( m_strokewidth );
724 if ( !m_strokewidthDev )
726 m_strokewidthDev = 1;
737 void a2dAggContext::DoSetActiveFill()
741 switch( m_activefill.GetStyle() )
748 m_pattern = wxImage( BDIAGONAL_HATCH_XPM );
751 m_pattern = wxImage( CROSSDIAG_HATCH_XPM );
754 m_pattern = wxImage( FDIAGONAL_HATCH_XPM );
757 m_pattern = wxImage( CROSS_HATCH_XPM );
760 m_pattern = wxImage( HORIZONTAL_HATCH_XPM );
763 m_pattern = wxImage( VERTICAL_HATCH_XPM );
767 if ( m_activefill.GetStyle() >= a2dFIRST_HATCH && m_activefill.GetStyle() <= a2dLAST_HATCH )
769 m_pattern.Replace( 0, 0, 0,
774 m_pattern_rbuf.attach( m_pattern.GetData(), m_pattern.GetWidth(), m_pattern.GetHeight(), m_pattern.GetWidth() * 3 );
779 bool nohatch =
false;
780 switch( m_activefill.GetStyle() )
783 m_pattern = wxImage( BDIAGONAL_HATCH_XPM );
786 m_pattern = wxImage( CROSSDIAG_HATCH_XPM );
789 m_pattern = wxImage( FDIAGONAL_HATCH_XPM );
792 m_pattern = wxImage( CROSS_HATCH_XPM );
795 m_pattern = wxImage( HORIZONTAL_HATCH_XPM );
798 m_pattern = wxImage( VERTICAL_HATCH_XPM );
804 m_pattern.Replace( 255, 255, 255,
809 m_pattern.Replace( 0, 0, 0,
814 m_pattern_rbuf.attach( m_pattern.GetData(), m_pattern.GetWidth(), m_pattern.GetHeight(), m_pattern.GetWidth() * 3 );
820 switch( m_activefill.GetStyle() )
826 static const int MASK_RED = 1;
827 static const int MASK_GREEN = 2;
828 static const int MASK_BLUE = 3;
830 m_pattern = m_activefill.GetStipple().ConvertToImage();
831 m_pattern.Replace( MASK_RED, MASK_GREEN, MASK_BLUE,
836 m_pattern_rbuf.attach( m_pattern.GetData(), m_pattern.GetWidth(), m_pattern.GetHeight(), m_pattern.GetWidth() * 3 );
851 double profile = 1.0;
853 double x1 = m_activefill.GetStart().m_x;
854 double y1 = m_activefill.GetStart().m_y;
855 double x2 = m_activefill.GetStop().m_x;
856 double y2 = m_activefill.GetStop().m_y;
857 color_type c1( m_colour1redFill, m_colour1greenFill, m_colour1blueFill, m_FillOpacityCol1 );
858 color_type c2( m_colour2redFill, m_colour2greenFill, m_colour2blueFill, m_FillOpacityCol2 );
859 int startGradient = 128 - int( profile * 128.0 );
860 int endGradient = 128 + int( profile * 128.0 );
861 if ( endGradient <= startGradient ) endGradient = startGradient + 1;
862 double k = 1.0 / double( endGradient - startGradient );
863 for ( i = 0; i < startGradient; i++ )
865 m_fillGradient[i] = c1;
867 for ( ; i < endGradient; i++ )
869 m_fillGradient[i] = c1.gradient( c2,
double( i - startGradient ) * k );
871 for ( ; i < 256; i++ )
873 m_fillGradient[i] = c2;
875 double angle = atan2( y2 - y1, x2 - x1 );
876 m_fillGradientMatrix.reset();
877 m_fillGradientMatrix *= agg::trans_affine_rotation( angle );
878 m_fillGradientMatrix *= agg::trans_affine_translation( x1, y1 );
879 m_fillGradientMatrix *= _get_agg_user_to_device_transform();
880 m_fillGradientMatrix.invert();
881 m_fillGradientD1 = 0;
882 m_fillGradientD2 = sqrt( ( x2 - x1 ) * ( x2 - x1 ) + ( y2 - y1 ) * ( y2 - y1 ) );
886 double profile = 1.0;
888 double xf = m_activefill.GetFocal().m_x;
889 double yf = m_activefill.GetFocal().m_y;
890 double x = m_activefill.GetCenter().m_x;
891 double y = m_activefill.GetCenter().m_y;
892 double r = m_activefill.GetRadius();
894 color_type c1( m_colour1redFill, m_colour1greenFill, m_colour1blueFill, m_FillOpacityCol1 );
895 color_type c2( m_colour2redFill, m_colour2greenFill, m_colour2blueFill, m_FillOpacityCol2 );
896 int startGradient = 128 - int( profile * 127.0 );
897 int endGradient = 128 + int( profile * 127.0 );
898 if ( endGradient <= startGradient ) endGradient = startGradient + 1;
899 double k = 1.0 / double( endGradient - startGradient );
900 for ( i = 0; i < startGradient; i++ )
902 m_fillGradient[i] = c1;
904 for ( ; i < endGradient; i++ )
906 m_fillGradient[i] = c1.gradient( c2,
double( i - startGradient ) * k );
908 for ( ; i < 256; i++ )
910 m_fillGradient[i] = c2;
912 m_fillGradientD2 = m_usertodevice.TransformDistance( r );
913 m_usertodevice.TransformPoint( x, y, x, y );
914 m_fillGradientMatrix.reset();
915 m_fillGradientMatrix *= agg::trans_affine_translation( x, y );
916 m_fillGradientMatrix.invert();
917 m_fillGradientD1 = 0;
921 #if wxCHECK_VERSION(2,9,0)
922 void a2dAggContext::DrawBitmap(
const wxGraphicsBitmap& bmp, wxDouble x, wxDouble y, wxDouble w, wxDouble h )
924 void a2dAggContext::DrawGraphicsBitmap(
const wxGraphicsBitmap& bmp, wxDouble x, wxDouble y, wxDouble w, wxDouble h )
927 a2dBitmapData* data =
static_cast<a2dBitmapData*
>( bmp.GetRefData() );
928 wxImage image = data->GetImage();
930 int imagew = image.GetWidth();
931 int imageh = image.GetHeight();
933 agg::trans_affine mtxi;
934 mtxi *= agg::trans_affine_scaling( w / imagew, h / imageh );
935 mtxi *= agg::trans_affine_translation( x - w / 2, y - h / 2 );
940 agg::trans_affine mtx = _get_agg_user_to_device_transform();
944 typedef agg::span_allocator<agg::rgba8> span_alloc_type;
947 typedef agg::image_accessor_clip<PixFormat> img_source_type;
948 typedef agg::span_interpolator_linear<> interpolator_type;
949 interpolator_type interpolator( mtxi );
951 typedef agg::span_image_filter_rgb_bilinear<img_source_type, interpolator_type> span_gen_type;
954 typedef agg::span_converter<span_gen_type, span_conv_const_alpha_rgba8> span_conv;
956 typedef agg::renderer_scanline_aa<RendererBaseA, span_alloc_type, span_conv> renderer_type_alpha;
958 typedef agg::renderer_scanline_bin<RendererBaseA, span_alloc_type, span_gen_type> renderer_type_normal;
960 agg::rendering_buffer image_buffer;
961 image_buffer.attach( image.GetData(), imagew, imageh, ( m_yaxis ) ? -imagew * 3 : imagew * 3 );
962 PixFormat img_pixf( image_buffer );
963 img_source_type img_src( img_pixf, agg::rgba( 1, 1, 1, 0 ) );
965 span_gen_type sg( img_src, interpolator );
983 agg::rounded_rect er( x - w / 2, y - h / 2 , x + w / 2, y + h / 2, 0 );
984 er.normalize_radius();
985 agg::conv_transform<agg::rounded_rect> tr( er, mtx );
986 m_rasterizer.reset();
987 m_rasterizer.add_path( tr );
990 if ( m_OpacityFactor != 255 )
992 span_conv_const_alpha_rgba8 color_alpha( m_OpacityFactor );
993 span_conv sc( sg, color_alpha );
994 renderer_type_alpha ri( m_renBase, sa, sc );
996 agg::render_scanlines( m_rasterizer, m_sl, ri );
1000 renderer_type_normal ri( m_renBase, sa, sg );
1001 agg::render_scanlines( m_rasterizer, m_sl, ri );
1007 void a2dAggContext::GetTextExtent(
const wxString& str, wxDouble* width, wxDouble* height,
1008 wxDouble* descent, wxDouble* externalLeading )
const
1012 void a2dAggContext::GetPartialTextExtents(
const wxString& text, wxArrayDouble& widths )
const
1016 void a2dAggContext::DrawCharDc( wxChar c )
1018 #if wxART2D_USE_FREETYPE && defined(__USE_WINAPI__)
1019 if ( m_a2dfont.GetType() == a2dFONT_WXDC && m_a2dfont.GetFreetypeFont().Ok() )
1022 m_a2dfont = m_a2dfont.GetFreetypeFont();
1023 DrawCharFreetype( c );
1024 m_a2dfont = oldfont;
1027 a2dContext::DrawCharDc( c );
1028 #else // wxART2D_USE_FREETYPE && defined(__USE_WINAPI__)
1029 a2dContext::DrawCharDc( c );
1030 #endif // wxART2D_USE_FREETYPE && defined(__USE_WINAPI__)
1034 void a2dAggContext::DrawTextDc(
const wxString& text,
double x,
double y )
1037 unsigned int fontsize;
1038 double dx = m_usertodevice.GetValue( 1, 0 );
1039 double dy = m_usertodevice.GetValue( 1, 1 );
1040 fontsize = (
unsigned int ) fabs( m_a2dfont.GetSize() * sqrt( dx * dx + dy * dy ) );
1043 m_a2dfont.GetFont().SetPointSize( fontsize );
1049 DrawTextGeneric( text, x, y, (
void ( a2dContext::* )( wxChar ) ) & a2dAggContext::DrawCharDc );
1052 void a2dAggContext::DrawCharStroke( wxChar c )
1054 agg::path_storage path;
1055 double size = m_a2dfont.GetSize();
1061 a2dVertexList::iterator iter = ( *ptr )->begin();
1062 if ( ( *ptr )->size() )
1065 path.move_to( point.m_x * size, point.m_y * size );
1068 while ( iter != ( *ptr )->end() )
1071 path.line_to( point.m_x * size, point.m_y * size );
1079 agg::trans_affine mtx = _get_agg_user_to_device_transform();
1080 agg::conv_transform< agg::path_storage > tr( path, mtx );
1081 agg::conv_stroke< agg::conv_transform< agg::path_storage > > stroke( tr );
1083 agg::rgba8 color( m_colour1redStroke, m_colour1greenStroke, m_colour1blueStroke, m_StrokeOpacityCol1 );
1084 stroke.line_join( m_join );
1085 stroke.line_cap( m_cap );
1086 stroke.width( m_a2dfont.GetStrokeWidth() );
1087 m_rasterizer.reset();
1088 m_rasterizer.add_path( stroke );
1089 m_renderer.color( color );
1090 m_renSolidComp.color( color );
1091 if( m_blendMode == agg::end_of_comp_op_e )
1092 agg::render_scanlines( m_rasterizer, m_sl, m_renderer );
1094 agg::render_scanlines( m_rasterizer, m_sl, m_renSolidComp );
1097 #if wxART2D_USE_FREETYPE
1098 extern FT_Library g_freetypeLibrary;
1111 static void a2dSpanFuncGray(
int y,
int count, FT_Span* spans,
a2dSpanData* user )
1113 unsigned int alpha, invalpha, len;
1115 unsigned int r, g, b, rpm, gpm, bpm;
1116 r = user->colour.Red();
1117 g = user->colour.Green();
1118 b = user->colour.Blue();
1120 unsigned char* buf, *buf2;
1121 buf = user->buf + ( user->ymax - y ) * user->stride - user->xmin * 3;
1124 buf2 = buf + spans->x * 3;
1126 alpha = spans->coverage;
1151 invalpha = 255 - alpha;
1157 buf2[0] = ( buf2[0] * invalpha + rpm ) / 255;
1158 buf2[1] = ( buf2[1] * invalpha + gpm ) / 255;
1159 buf2[2] = ( buf2[2] * invalpha + bpm ) / 255;
1161 buf2[0] = ( buf2[0] * invalpha + bpm ) / 255;
1162 buf2[1] = ( buf2[1] * invalpha + gpm ) / 255;
1163 buf2[2] = ( buf2[2] * invalpha + rpm ) / 255;
1176 void a2dAggContext::DrawCharFreetype( wxChar c )
1181 #if wxART2D_USE_FREETYPE
1182 y += m_a2dfont.GetDescent();
1184 agg::path_storage path;
1185 double scale = m_a2dfont.GetSize() / ( 64 * m_a2dfont.GetDeviceHeight() );
1187 FT_Glyph glyph = m_a2dfont.GetGlyphFreetype( c )->m_glyph;
1188 if ( glyph->format != FT_GLYPH_FORMAT_OUTLINE )
1190 FT_Outline& outline = ( ( FT_OutlineGlyph ) glyph )->outline;
1193 FT_Vector v_control;
1206 for( n = 0; n < outline.n_contours; n++ )
1210 last = outline.contours[n];
1211 limit = outline.points + last;
1213 v_start = outline.points[first];
1214 v_last = outline.points[last];
1216 v_control = v_start;
1218 point = outline.points + first;
1219 tags = outline.tags + first;
1220 tag = FT_CURVE_TAG( tags[0] );
1223 if( tag == FT_CURVE_TAG_CUBIC )
return;
1226 if( tag == FT_CURVE_TAG_CONIC )
1229 if( FT_CURVE_TAG( outline.tags[last] ) == FT_CURVE_TAG_ON )
1240 v_start.x = ( v_start.x + v_last.x ) / 2;
1241 v_start.y = ( v_start.y + v_last.y ) / 2;
1249 path.move_to( v_start.x, v_start.y );
1251 while( point < limit )
1256 tag = FT_CURVE_TAG( tags[0] );
1259 case FT_CURVE_TAG_ON:
1261 path.line_to( point->x, point->y );
1265 case FT_CURVE_TAG_CONIC:
1267 v_control.x = point->x;
1268 v_control.y = point->y;
1278 tag = FT_CURVE_TAG( tags[0] );
1283 if( tag == FT_CURVE_TAG_ON )
1285 path.curve3( v_control.x, v_control.y, vec.x, vec.y );
1289 if( tag != FT_CURVE_TAG_CONIC )
return;
1291 v_middle.x = ( v_control.x + vec.x ) / 2;
1292 v_middle.y = ( v_control.y + vec.y ) / 2;
1294 path.curve3( v_control.x, v_control.y, v_middle.x, v_middle.y );
1299 path.curve3( v_control.x, v_control.y, v_start.x, v_start.y );
1305 FT_Vector vec1, vec2;
1307 if( point + 1 > limit || FT_CURVE_TAG( tags[1] ) != FT_CURVE_TAG_CUBIC )
1312 vec1.x = point[0].x;
1313 vec1.y = point[0].y;
1314 vec2.x = point[1].x;
1315 vec2.y = point[1].y;
1320 if( point <= limit )
1327 path.curve4( vec1.x, vec1.y, vec2.x, vec2.y, vec.x, vec.y );
1331 path.curve4( vec1.x, vec1.y, vec2.x, vec2.y, v_start.x, v_start.y );
1337 path.close_polygon();
1345 affine.
Scale( scale );
1347 affine = m_usertodevice * affine;
1349 agg::trans_affine mtx( affine.GetValue( 0, 0 ), affine.GetValue( 0, 1 ),
1350 affine.GetValue( 1, 0 ), affine.GetValue( 1, 1 ),
1351 affine.GetValue( 2, 0 ), affine.GetValue( 2, 1 ) );
1352 agg::conv_transform< agg::path_storage > tr( path, mtx );
1353 agg::conv_curve< agg::conv_transform< agg::path_storage > > stroke( tr );
1355 agg::rgba8 color( m_colour1redStroke, m_colour1greenStroke, m_colour1blueStroke, m_StrokeOpacityCol1 );
1356 m_rasterizer.reset();
1357 m_rasterizer.add_path( stroke );
1358 m_renderer.color( color );
1359 m_renSolidComp.color( color );
1360 if( m_blendMode == agg::end_of_comp_op_e )
1361 agg::render_scanlines( m_rasterizer, m_sl, m_renderer );
1363 agg::render_scanlines( m_rasterizer, m_sl, m_renSolidComp );
1365 #else // wxART2D_USE_FREETYPE
1366 a2dContext::DrawCharFreetype( c );
1367 #endif // wxART2D_USE_FREETYPE
1370 void a2dAggContext::DrawRoundedRectangle( wxDouble x, wxDouble y, wxDouble width, wxDouble height, wxDouble radius )
1372 if ( width == 0 || height == 0 )
1375 if ( m_pen.IsNull() && m_brush.IsNull() )
1378 if ( !IsStrokeOnly() )
1380 agg::trans_affine mtx = _get_agg_user_to_device_transform();
1382 if ( fabs( radius ) <= 0.00000001 )
1385 agg::conv_transform<plain_rect> tr( r, mtx );
1386 m_rasterizer.reset();
1387 m_rasterizer.add_path( tr );
1391 agg::rounded_rect r( x, y, x + width, y + height, radius );
1392 r.normalize_radius();
1393 agg::conv_transform<agg::rounded_rect> tr( r, mtx );
1394 m_rasterizer.reset();
1395 m_rasterizer.add_path( tr );
1399 RenderGradient(
false );
1403 RenderGradient(
true );
1406 ( m_activefill.GetStyle() >= a2dFIRST_HATCH && m_activefill.GetStyle() <= a2dLAST_HATCH ) ||
1407 ( m_activefill.GetStyle() >= a2dFIRST_TWOCOL_HATCH && m_activefill.GetStyle() <= a2dLAST_TWOCOL_HATCH ) )
1419 if ( fabs( radius ) <= 0.00000001 )
1422 agg::trans_affine mtx = _get_agg_user_to_device_transform();
1423 m_rasterizer.reset();
1424 _ras_add_stroked_path_xform( r, mtx );
1428 m_rasterizer.reset();
1429 agg::rounded_rect r( x, y, x + width, y + height, radius );
1430 r.normalize_radius();
1431 agg::trans_affine mtx = _get_agg_user_to_device_transform();
1432 _ras_add_stroked_path_xform( r, mtx );
1438 void a2dAggContext::DrawEllipse( wxDouble x, wxDouble y, wxDouble w, wxDouble h )
1442 a2dContext::DrawEllipse( x, y, w, h );
1446 if ( m_pen.IsNull() && m_brush.IsNull() )
1450 unsigned int segments;
1453 double radiusDev = m_usertodevice.TransformDistance( wxMax( w, h ) );
1454 Aberration( m_displayaberration,
wxPI * 2, radiusDev , dphi, segments );
1456 agg::trans_affine mtx = _get_agg_user_to_device_transform();
1458 agg::rgba8 color( m_colour1redFill, m_colour1greenFill, m_colour1blueFill, m_FillOpacityCol1 );
1459 agg::ellipse ellipse( x + w / 2.0, y + h / 2.0, w / 2.0, h / 2.0, segments );
1461 agg::conv_transform<agg::ellipse> tr( ellipse, mtx );
1463 if ( !IsStrokeOnly() )
1465 m_path.remove_all();
1466 m_path.concat_path( tr, 0 );
1468 m_rasterizer.reset();
1469 m_rasterizer.add_path( m_path );
1473 RenderGradient(
false );
1477 RenderGradient(
true );
1480 ( m_activefill.GetStyle() >= a2dFIRST_HATCH && m_activefill.GetStyle() <= a2dLAST_HATCH ) ||
1481 ( m_activefill.GetStyle() >= a2dFIRST_TWOCOL_HATCH && m_activefill.GetStyle() <= a2dLAST_TWOCOL_HATCH ) )
1490 m_rasterizer.reset();
1491 _ras_add_stroked_path_xform( ellipse, mtx );
1496 void a2dAggContext::DrawPolygon(
const a2dVertexList* list, wxPolygonFillMode fillStyle )
1498 if ( m_pen.IsNull() && m_brush.IsNull() )
1501 int segments = ToAggPath( list,
false );
1503 if ( segments == 0 )
1506 agg::trans_affine mtx = _get_agg_user_to_device_transform();
1507 if ( IsStrokeOnly() )
1512 m_path.close_polygon();
1513 agg::conv_transform<agg::path_storage> tr( m_path, mtx );
1514 m_rasterizer.reset();
1515 m_rasterizer.add_path( tr );
1517 RenderGradient(
false );
1521 m_path.close_polygon();
1522 agg::conv_transform<agg::path_storage> tr( m_path, mtx );
1523 m_rasterizer.reset();
1524 m_rasterizer.add_path( tr );
1526 RenderGradient(
true );
1529 ( m_activefill.GetStyle() >= a2dFIRST_HATCH && m_activefill.GetStyle() <= a2dLAST_HATCH ) ||
1530 ( m_activefill.GetStyle() >= a2dFIRST_TWOCOL_HATCH && m_activefill.GetStyle() <= a2dLAST_TWOCOL_HATCH ) )
1532 m_path.close_polygon();
1533 agg::conv_transform<agg::path_storage> tr( m_path, mtx );
1534 m_rasterizer.reset();
1535 m_rasterizer.add_path( tr );
1541 m_path.close_polygon();
1542 agg::conv_transform<agg::path_storage> tr( m_path, mtx );
1543 m_rasterizer.reset();
1544 m_rasterizer.add_path( tr );
1551 m_rasterizer.reset();
1552 m_path.close_polygon();
1553 _ras_add_stroked_path_xform( m_path, mtx );
1561 if ( m_pen.IsNull() )
1564 int segments = ToAggPath( list,
false );
1566 if ( segments == 0 )
1569 agg::trans_affine mtx = _get_agg_user_to_device_transform();
1570 m_rasterizer.reset();
1571 _ras_add_stroked_path_xform( m_path, mtx );
1575 int a2dAggContext::ToAggPath(
a2dVertexArray* points,
bool transform )
1577 unsigned int segments = 0;
1579 m_path.remove_all();
1581 unsigned int count = 0;
1582 double x, y, lastx, lasty;
1584 for ( i = 0; i < points->size(); i++ )
1588 if ( !seg->GetArc() )
1591 m_usertodevice.TransformPoint( seg->
m_x, seg->
m_y, x, y );
1599 if( !count || fabs( x - lastx ) > 0.001 || fabs( y - lasty ) > 0.001 )
1602 m_path.move_to( x, y );
1604 m_path.line_to( x, y );
1614 double radius, center_x, center_y, beginrad, midrad, endrad, phit;
1616 if ( cseg->
CalcR( *( points->Item( i ? i - 1 : 0 ) ), radius, center_x, center_y, beginrad, midrad, endrad, phit ) )
1619 unsigned int segments;
1620 double radiusDev = m_usertodevice.TransformDistance( radius );
1621 Aberration( m_displayaberration, phit, radiusDev , dphi, segments );
1623 double theta = beginrad;
1627 for ( step = 0; step < segments + 1; step++ )
1630 m_usertodevice.TransformPoint( center_x + radius * cos ( theta ), center_y + radius * sin ( theta ), x, y );
1633 x = center_x + radius * cos ( theta );
1634 y = center_y + radius * sin ( theta );
1637 if( !count || fabs( x - lastx ) > 0.001 || fabs( y - lasty ) > 0.001 )
1640 m_path.move_to( x, y );
1642 m_path.line_to( x, y );
1648 theta = theta + dphi;
1655 m_usertodevice.TransformPoint( cseg->
m_x, cseg->
m_y, x, y );
1663 if( !count || fabs( x - lastx ) > 0.001 || fabs( y - lasty ) > 0.001 )
1666 m_path.move_to( x, y );
1668 m_path.line_to( x, y );
1680 int a2dAggContext::ToAggPath(
const a2dVertexList* list,
bool transform )
1682 unsigned int segments = 0;
1684 if ( list->empty() )
1687 m_path.remove_all();
1689 a2dVertexList::const_iterator iterprev = list->end();
1691 unsigned int count = 0;
1692 double x, y, lastx, lasty;
1693 iterprev = list->end();
1694 if ( iterprev != list->begin() )
1696 a2dVertexList::const_iterator iter = list->begin();
1697 iter = list->begin();
1698 while ( iter != list->end() )
1702 if ( !seg->GetArc() )
1705 m_usertodevice.TransformPoint( seg->
m_x, seg->
m_y, x, y );
1713 if( !count || fabs( x - lastx ) > 0.001 || fabs( y - lasty ) > 0.001 )
1716 m_path.move_to( x, y );
1718 m_path.line_to( x, y );
1728 double radius, center_x, center_y, beginrad, midrad, endrad, phit;
1730 if ( cseg->
CalcR( *( *iterprev ), radius, center_x, center_y, beginrad, midrad, endrad, phit ) )
1733 unsigned int segments;
1734 double radiusDev = m_usertodevice.TransformDistance( radius );
1735 Aberration( m_displayaberration, phit, radiusDev , dphi, segments );
1737 double theta = beginrad;
1741 for ( step = 0; step < segments + 1; step++ )
1744 m_usertodevice.TransformPoint( center_x + radius * cos ( theta ), center_y + radius * sin ( theta ), x, y );
1747 x = center_x + radius * cos ( theta );
1748 y = center_y + radius * sin ( theta );
1752 if( !count || fabs( x - lastx ) > 0.001 || fabs( y - lasty ) > 0.001 )
1755 m_path.move_to( x, y );
1757 m_path.line_to( x, y );
1762 theta = theta + dphi;
1769 m_usertodevice.TransformPoint( cseg->
m_x, cseg->
m_y, x, y );
1777 if( !count || fabs( x - lastx ) > 0.001 || fabs( y - lasty ) > 0.001 )
1780 m_path.move_to( x, y );
1782 m_path.line_to( x, y );
1798 IMPLEMENT_DYNAMIC_CLASS( a2dGcAggDrawer, a2dGcBaseDrawer )
1800 void a2dGcAggDrawer::InitContext()
1804 m_pdata = m_buffer.GetData();
1805 m_render =
new a2dRenderer();
1806 m_context =
new a2dAggContext( m_render, &m_buffer );
1809 a2dGcAggDrawer::a2dGcAggDrawer(
const wxSize& size ): a2dGcBaseDrawer( size.GetWidth(), size.GetHeight() )
1814 a2dGcAggDrawer::a2dGcAggDrawer(
int width,
int height ): a2dGcBaseDrawer( width, height )
1819 a2dGcAggDrawer::a2dGcAggDrawer(
const a2dGcAggDrawer& other )
1820 : a2dGcBaseDrawer( other )
1825 a2dGcAggDrawer::a2dGcAggDrawer(
const a2dDrawer2D& other )
1826 : a2dGcBaseDrawer( other )
1831 a2dGcAggDrawer::~a2dGcAggDrawer()
1837 void a2dGcAggDrawer::SetYaxis(
bool up )
1843 wxBitmap a2dGcAggDrawer::GetBuffer()
const
1845 return wxBitmap( m_buffer.GetImage() );
1848 void a2dGcAggDrawer::SetBufferSize(
int w,
int h )
1852 int old_pixelwidth = m_width * 4;
1853 int new_pixelwidth = w * 4;
1854 int pixelwidth = wxMin( w, m_width ) * 4;
1855 int minheight = wxMin( h, m_height );
1858 unsigned char* oldpdata = m_pdata;
1859 unsigned char* newpdata = newbuf.GetData();
1861 for (
int yp = 0; yp < minheight; yp++ )
1863 memcpy( newpdata, oldpdata, pixelwidth );
1864 oldpdata += old_pixelwidth;
1865 newpdata += new_pixelwidth;
1872 m_pdata = m_buffer.GetData();
1873 DestroyClippingRegion();
1875 m_context =
new a2dAggContext( m_render, &m_buffer );
1878 wxBitmap a2dGcAggDrawer::GetSubBitmap( wxRect rect )
const
1880 return wxBitmap( m_buffer.GetImage().GetSubImage( rect ) );
1883 void a2dGcAggDrawer::CopyIntoBuffer(
const wxBitmap& bitm )
1888 void a2dGcAggDrawer::BlitBuffer( wxDC* dc, wxRect rect,
const wxPoint& bufferpos )
1893 rect.width += rect.x;
1896 if ( rect.width <= 0 )
return;
1900 rect.height += rect.y;
1903 if ( rect.height <= 0 )
return;
1905 if ( rect.x + rect.width >= m_width )
1906 rect.width = m_width - rect.x;
1908 if ( rect.width <= 0 )
return;
1910 if ( rect.y + rect.height >= m_height )
1911 rect.height = m_height - rect.y;
1913 if ( rect.height <= 0 )
return;
1915 int xmax = rect.x + rect.width;
1916 int ymax = rect.y + rect.height;
1919 wxBitmap subbitmap = subImage->CreateBitmap();
1923 mdc.SelectObject( subbitmap );
1925 dc->Blit( rect.x - bufferpos.x, rect.y - bufferpos.y, xmax - rect.x, ymax - rect.y, &mdc, 0, 0, wxCOPY,
false );
1927 mdc.SelectObject( wxNullBitmap );
1930 void a2dGcAggDrawer::ShiftBuffer(
int dxy,
bool yshift )
1934 int pixelwidth = m_width * 4;
1936 if ( dxy > 0 && dxy < m_height )
1938 unsigned char* highline = m_pdata + ( m_height - dxy ) * pixelwidth ;
1939 unsigned char* lowline = m_pdata + m_height * pixelwidth ;
1941 for (
int yp = 0; yp < m_height - dxy; yp++ )
1943 highline -= pixelwidth;
1944 lowline -= pixelwidth;
1945 memcpy( lowline, highline, pixelwidth );
1948 else if ( dxy < 0 && dxy > -m_height )
1951 unsigned char* highline = m_pdata;
1952 unsigned char* lowline = m_pdata + dxy * pixelwidth ;
1954 for (
int yp = 0; yp < m_height - dxy ; yp++ )
1956 memcpy( highline, lowline, pixelwidth );
1957 highline += pixelwidth;
1958 lowline += pixelwidth;
1962 wxFAIL_MSG( wxT(
"you can only shift within height of buffer" ) );
1966 int pixelwidth = m_width * 4;
1967 if ( dxy > 0 && dxy < m_width )
1969 int subwidth = ( m_width - dxy ) * 4;
1970 unsigned char* low = m_pdata;
1971 unsigned char* high = m_pdata + dxy * 4 ;
1973 for (
int yp = 0; yp < m_height ; yp++ )
1975 memcpy( high, low, subwidth );
1980 else if ( dxy < 0 && dxy > -m_width )
1983 int subwidth = ( m_width - dxy ) * 4;
1984 unsigned char* low = m_pdata;
1985 unsigned char* high = m_pdata + dxy * 4 ;
1987 for (
int yp = 0; yp < m_height ; yp++ )
1989 memcpy( low, high, subwidth );
1995 wxFAIL_MSG( wxT(
"you can only shift within width of buffer" ) );
1999 void a2dGcAggDrawer::DoSetActiveStroke()
2005 a2dRenderer* render = ( a2dRenderer* ) m_render;
2006 a2dContext* context = ( a2dContext* ) m_context;
2007 wxGraphicsPen p = render->CreateStroke( m_activestroke );
2008 m_context->SetPen( p );
2012 a2dGcBaseDrawer::DoSetActiveStroke();
2016 void a2dGcAggDrawer::DoSetActiveFill()
2022 a2dRenderer* render = ( a2dRenderer* ) m_render;
2023 a2dContext* context = ( a2dContext* ) m_context;
2024 wxGraphicsBrush b = render->CreateFill( m_activefill );
2025 m_context->SetBrush( b );
2029 a2dGcBaseDrawer::DoSetActiveFill();
2033 void a2dGcAggDrawer::DoSetActiveFont(
const a2dFont& font )
2035 a2dContext* context = ( a2dContext* ) m_context;
2036 a2dRenderer* render = ( a2dRenderer* ) m_render;
2037 wxGraphicsFont f = render->CreateFont( font );
2038 context->SetFont( font );
2041 void a2dGcAggDrawer::DrawPoint(
double xc,
double yc )
2043 if ( m_disableDrawing )
2047 GetUserToDeviceTransform().TransformPoint( xc, yc, xt, yt );
2051 void a2dGcAggDrawer::DrawImage(
const wxImage& imagein,
double x,
double y,
double width,
double height, wxUint8 Opacity )
2053 if ( m_disableDrawing )
2060 affine.
Mirror(
true,
false );
2063 PushTransform( affine );
2065 a2dContext* context = ( a2dContext* ) m_context;
2066 a2dRenderer* render = ( a2dRenderer* ) m_render;
2067 wxGraphicsBitmap bitmap = render->CreateBitmap( imagein );
2068 #if wxCHECK_VERSION(2,9,0)
2069 m_context->DrawBitmap( bitmap, x, y, width, height );
2071 context->DrawGraphicsBitmap( bitmap, x, y, width, height );
2077 void a2dGcAggDrawer::DrawImage(
const a2dImageRGBA& image,
double x,
double y,
double width,
double height, wxUint8 Opacity )
2079 if ( m_disableDrawing )
2082 a2dContext* context = ( a2dContext* ) m_context;
2083 a2dRenderer* render = ( a2dRenderer* ) m_render;
2084 wxImage wximage = image.GetImage();
2085 wxGraphicsBitmap bitmap = render->CreateBitmap( wximage );
2086 #if wxCHECK_VERSION(2,9,0)
2087 m_context->DrawBitmap( bitmap, x - width / 2.0, y - height / 2.0, width, height );
2089 context->DrawGraphicsBitmap( bitmap, x - width / 2.0, y - height / 2.0, width, height );
2107 void a2dGcAggDrawer::DrawCharFreetype( wxChar c )
2109 wxGraphicsMatrix m = m_context->CreateMatrix();
2111 m_usertodevice( 0, 0), m_usertodevice( 0, 1),
2112 m_usertodevice( 1, 0), m_usertodevice( 1, 1),
2113 m_usertodevice( 2, 0), m_usertodevice( 2, 1) );
2114 m_context->SetTransform( m );
2115 static_cast<a2dAggContext*>(m_context)->DrawCharFreetype( c );
2120 #endif // wxART2D_USE_GRAPHICS_CONTEXT
2122 #endif //wxART2D_USE_AGGDRAWER
virtual void SetYaxis(bool up)
set if the Yaxis goes up or down
wxPoint2DDouble a2dPoint2D
this to define if coordinate numbers are integer or doubles
a2dAffineMatrix & Mirror(bool y=true, bool x=false)
mirror a matrix in x, y
const a2dStroke * a2dBLACK_STROKE
global a2dStroke stock object for BLACK stroking
Stroke and fill base classes.
Defines a font to be set to a2dDrawer2D or stored in a2dCanvsObject etc.
Arc Segment in a2dVertexList.
vertex array of line and arc segments.
vertex list of line and arc segments.
double TransformDistance(double distance) const
Transform a distance.
a2dDrawStyle
Define the manner in which a2dCanvasView draws to the device.
bool CalcR(const a2dLineSegment &prev, double &radius, double ¢er_x, double ¢er_y, double &beginrad, double &midrad, double &endrad, double &phit) const
Calculation of center for the Arc.
Drawing context abstraction.
Normal straight line segment in a2dVertexList and a2dVertexArray.
agg::renderer_base< PixFormatA > RendererBaseA
base rendering Agg
A 2x3 affine matrix class for 2D transformations.
agg::rgba8 color_type
color format in a2dAggDrawer
double m_x
x endpoint of line
used in freetype rendering
double m_y
y endpoint of line
void Aberration(double aber, double angle, double radius, double &dphi, unsigned int &segments)
calculate number of segments in an arc such that a certain accuracy is maintained ...
bool Scale(double scale)
Scale by scale (isotropic scaling i.e. the same in x and y):
bool Translate(double x, double y)
Translate by dx, dy:
bool Invert(void)
Invert matrix.
const double wxPI
defines PI
const a2dFill * a2dTRANSPARENT_FILL
global a2dFill stock object for TRANSPARENT filling