00001 /*! \file wx/artbase/drawer2d.h 00002 \brief Contains graphical drawing context specific classes. 00003 a2dDrawer2D and derived classes are used for drawing primitives. 00004 00005 A drawing context which is wxDrawer2 derived, can be used to draw in general. 00006 Still it has special features in order to use it for drawing document containing a drawing. 00007 00008 \author Klaas Holwerda 00009 00010 Copyright: 2000-2004 (c) Klaas Holwerda 00011 00012 Licence: wxWidgets Licence 00013 00014 RCS-ID: $Id: drawer2d.h,v 1.53 2009/10/06 18:40:31 titato Exp $ 00015 */ 00016 00017 #ifndef __WXDRAWER2D_H__ 00018 #define __WXDRAWER2D_H__ 00019 00020 #ifndef WX_PRECOMP 00021 #include "wx/wx.h" 00022 #endif 00023 00024 00025 #include "wx/image.h" 00026 #include "wx/prntbase.h" 00027 #include <wx/module.h> 00028 00029 #include "wx/general/comevt.h" 00030 #include "wx/artbase/artglob.h" 00031 #include "wx/artbase/stylebase.h" 00032 #include "wx/artbase/liner.h" 00033 #include "wx/artbase/afmatrix.h" 00034 #include "wx/artbase/bbox.h" 00035 #include "wx/artbase/polyver.h" 00036 #include "wx/genart/imagergba.h" 00037 00038 #include <vector> 00039 00040 #ifdef Round 00041 #undef Round 00042 #endif 00043 #define Round( x ) (int) floor( (x) + 0.5 ) 00044 00045 #if wxCHECK_VERSION(2,7,1) 00046 # define WX_COLOUR_HAS_ALPHA 1 00047 #else 00048 # define WX_COLOUR_HAS_ALPHA 0 00049 #endif 00050 00051 //! Used for defining how a ClippingRegion defined as a polygon is combined with 00052 /*! the existing clipping region in a a2dCanvasView. 00053 \ingroup drawer 00054 */ 00055 enum a2dBooleanClip 00056 { 00057 a2dCLIP_AND, /*!< AND operation, the new region is the union/intersection with existing clipping region */ 00058 a2dCLIP_COPY, /*!< COPY operation, replaces existing clipping region */ 00059 a2dCLIP_DIFF, /*!< DIFF operation subtracts new region from the existing clipping region */ 00060 a2dCLIP_OR, /*!< OR operation, the new region is the merge of the given with the existing clipping region */ 00061 a2dCLIP_XOR /*!< XOR operation, the new region is the complement of the intersection with existing clipping region */ 00062 }; 00063 00064 00065 #include "wx/artbase/graphica.h" 00066 00067 //! Drawing context abstraction. 00068 /*! 00069 a2dDrawer2D presents a unified abstract view of underlying system-dependent 00070 drawing contexts. It provides a simple low-level interface for 00071 drawing rectangles and other basic primitives, and it also handles the 00072 mapping and transformations from world coordinates to device coordinates. 00073 00074 The current a2dFill and a2dStroke need to be set, those classes are always reference counted, 00075 and a2dDrawer2D will increment and decrement them when setting and releasing them. 00076 This means that if the reference count reaches zero it will actually be 00077 deleted. 00078 00079 Mapping from device to Logical/World coordinates needs to be set for a drawer. 00080 The Yaxis orientation can also be set via the SetYaxis() method. 00081 00082 \par About Transformations 00083 00084 There are three different coordinate systems used by a2dDrawer2D, and 00085 two transformations that map between them. These are referred to in a2d as 00086 - User coordinates 00087 - World coordinates 00088 - Device coordinates 00089 00090 User coordinates are the coordinates you give to drawing functions like 00091 DrawCircle(). User coordinates are transformed to World coordinates 00092 by the transformation returned from GetTransform(). 00093 The idea behind user coordinates is that one can draw in a relative coordinate system, 00094 which can be at a position, angle and scale relative to the world coordinates. 00095 The drawing context will correctly transform the relative coordinates, to world and device. 00096 This way of drawing especialy becomes important when working with canvas objects. 00097 Inside such object one can use drawing functions relative to the origin of that object, 00098 and one does not have to take into account how and where this object is placed in the world 00099 coordinate system. 00100 World coordinates are transformed to Device coordinates using the 00101 transformation returned by GetMappingMatrix(). One can draw 00102 in device coordinates without transformations by calling PushIdentityTransform(). 00103 PopTransform() will restore the previous transformation. 00104 As an example one can draw the vertexes in a plot as a circle in device 00105 coordinates (with a fixed radius in pixels that is), while the curve itself is draw in normal 00106 user coordinates. 00107 00108 Given an input point (x,y), the final location on the output device 00109 (e.g. screen) in device units (e.g. pixels) for any of the Draw*() methods 00110 is given by 00111 \code 00112 (devx,devy) = GetMappingMatrix() * GetTransform() * (x,y) 00113 \endcode 00114 The compound of the world-to-device mapping and user-to-world transform 00115 is also kept up-to-date. It can be obtained by calling 00116 GetUserToDeviceTransform(). 00117 So we can also say 00118 \code 00119 (devx,devy) = GetUserToDeviceTransform() * (x,y) 00120 \endcode 00121 00122 We can also depict this relationship as 00123 \verbatim 00124 User coordinates 00125 / \ 00126 [ GetTransform() ] | 00127 | | 00128 World coordinates [ GetUserToDeviceTransform() ] 00129 | | 00130 [ GetMappingMatrix() ] | 00131 \ / 00132 Device coordiantes 00133 \endverbatim 00134 00135 \par The Mapping Matrix 00136 00137 The mapping matrix returned by GetMappingMatrix() contains only translation 00138 and axis-aligned scaling. So an input of an axis-aligned rectangle is 00139 always transformed to another axis-aligned rectangle. This lets you have 00140 an unlimited virtual canvas (aka "world") and map different portions of 00141 it to the drawing surface. Additionally, some objects like fonts are 00142 aware of the orientation of the Y axis defined by the mapping, and will 00143 draw right-side up, even if the Y axis is mirrored in the mapping. 00144 00145 The mapping matrix can be manipulated using the following methods: 00146 - SetMappingUpp() 00147 - SetMappingDeviceRect() 00148 - SetMinX(), SetMinY() 00149 - SetUppX(), SetUppY() 00150 - SetMappingWidthHeight() 00151 - SetYaxis() 00152 00153 \par The User to World Transform Matrix 00154 00155 The user-to-world transform matrix returned by GetTransform() is a 2x3 00156 affine matrix that can contain translation, rotation, and scaling 00157 (including shearing and mirroring). 00158 00159 The relative transform can be manipulated with these methods: 00160 - SetTransform() 00161 - PushTransform() 00162 - PopTransform() 00163 - Transform() 00164 00165 00166 \par double buffering 00167 00168 A derived drawing context can be buffered or not. But this class is prepared as a 00169 buffered drawing context, so it assumes in certain member fucntions that one is drawing 00170 to a buffer. A drawing context which does not use a buffer needs to implement those 00171 pur virtual members and give assert. 00172 00173 \ingroup drawer docview style 00174 00175 \sa a2dDcDrawer, a2dMemDcDrawer, a2dAggDrawer 00176 00177 */ 00178 class A2DARTBASEDLLEXP a2dDrawer2D: public wxObject 00179 { 00180 #if defined(_DEBUG) && defined (SMART_POINTER_DEBUG) 00181 a2dInitCurrentSmartPointerOwner m_initCurrentSmartPointerOwner; 00182 #endif 00183 00184 public: 00185 00186 //!constructor 00187 /*! 00188 \remark 00189 Do not forget to call SetDocument() if used standalone 00190 (in a a2dDocumentCommandProcessor setting this is taken care of). 00191 */ 00192 a2dDrawer2D( int width = 0, int height = 0 ); 00193 00194 //!constructor 00195 /*! 00196 \remark 00197 Do not forget to call SetDocument() if used standalone 00198 (in a a2dDocumentCommandProcessor setting this is taken care of) 00199 */ 00200 a2dDrawer2D( const wxSize& size ); 00201 00202 //!copy constructor 00203 a2dDrawer2D( const a2dDrawer2D& other ); 00204 00205 //!destructor 00206 virtual ~a2dDrawer2D(); 00207 00208 //! the display 00209 void SetDisplay( wxWindow* window ) { m_display = window; } 00210 00211 //!set at what size to stop drawing 00212 inline void SetPrimitiveThreshold( wxUint16 pixels, bool asrect = true ) { m_drawingthreshold = pixels; m_asrectangle = asrect; } 00213 00214 //!get drawing threshold \sa SetDrawingThreshold 00215 inline wxUint16 GetPrimitiveThreshold() const { return m_drawingthreshold; } 00216 00217 //! underneath the threshold draw a rectangle instead of the real object. 00218 inline bool GetThresholdDrawRectangle() const { return m_asrectangle; } 00219 00220 //!set threshold at which polygon is drawn filled or only outline 00221 inline void SetPolygonFillThreshold( wxUint16 pixels ) { m_polygonFillThreshold = pixels; } 00222 00223 //!get threshold at which polygon is drawn filled or only outline 00224 inline wxUint16 GetPolygonFillThreshold() const { return m_polygonFillThreshold; } 00225 00226 //!get the DC that is used for rendering 00227 virtual wxDC* GetRenderDC() const { return NULL; } 00228 00229 //!get the DC that is used for rendering 00230 virtual wxDC* GetDeviceDC() const { return NULL; } 00231 00232 //! Set the display aberration of curved shapes 00233 /*! 00234 The drawing of curved shapes will not deviate more than this from the ideal curve. 00235 \remark the smaller the number the longer the drawing takes. 00236 00237 \param aber maximum deviation in device coordinates 00238 */ 00239 void SetDisplayAberration( double aber ) { m_displayaberration = aber; } 00240 00241 //! Returns the display aberration of curved shapes 00242 /*!, 00243 The drawing of curved shapes will not deviate more than this from the ideal curve. 00244 */ 00245 double GetDisplayAberration() const { return m_displayaberration; } 00246 00247 //! Return the buffer as a bitmap 00248 virtual wxBitmap GetBuffer() const = 0; 00249 00250 //!Change the buffer size 00251 /*! 00252 \remark 00253 SetMappingDeviceRect() is NOT reset. 00254 */ 00255 virtual void SetBufferSize( int w, int h ) = 0; 00256 00257 virtual void CopyIntoBuffer( const wxBitmap& bitm ) {}; 00258 00259 //! blit whole buffer to device 00260 void BlitBuffer(); 00261 00262 //! blit given rect contents within buffer to device 00263 void BlitBuffer( int x, int y, int width, int height, int xbuf = 0, int ybuf = 0 ); 00264 00265 //! blit given rect contents within buffer to device 00266 virtual void BlitBuffer( wxRect rect, const wxPoint& bufferpos = wxPoint( 0, 0 ) ) = 0; 00267 00268 //! used for blitting to a wxDC. 00269 virtual void BlitBuffer( wxDC* dc, wxRect rect, const wxPoint& bufferpos = wxPoint( 0, 0 ) ) = 0; 00270 00271 //! quick scroll over small distance 00272 virtual void ShiftBuffer( int WXUNUSED( dxy ), bool WXUNUSED( yshift ) ) {}; 00273 00274 //!A way to get parts form the buffer that is drawn into. 00275 /*! 00276 Used for freetype text at the moment since it mixes with the colors already there. 00277 */ 00278 virtual wxBitmap GetSubBitmap( wxRect sub_rect ) const = 0; 00279 00280 //!get y axis orientation 00281 inline bool GetYaxis() const { return m_yaxis; } 00282 00283 //!set if the Yaxis goes up or down 00284 virtual void SetYaxis( bool up ); 00285 00286 //! to change the default mapping (to the complete buffer). 00287 /*! 00288 By default the mapping from world coordinates to device coordinates is 00289 based on the size of the double buffer. 00290 For application where the a2dDrawer2D is used as a double buffered device context within 00291 a a2dCanvas window, it is better to oversize the buffer of the a2dDrawer2D. 00292 This prevents continuously reallocating/redrawing of the buffer after even the smallest resize. 00293 To still keep the mapping to what is visible on the window client window, one can 00294 independently from the buffer size set the mapping rectangle. 00295 Even a rectangle bigger then the buffer rectangle is possible, but of course the a2dDrawer2D 00296 will never draw outside the buffer eventually. 00297 00298 \param remap if true change mapping to 00299 */ 00300 void SetMappingDeviceRect( int mapx, int mapy, int mapWidth, int mapHeight, bool remap = false ); 00301 00302 //!Give the virtual size to be displayed, the mapping matrix will be calculated. 00303 /*! 00304 The current buffer size is used to calculate how to at least display all of the area given. 00305 00306 \see SetMappingDeviceRect to map to a different device/buffer rectangle. 00307 00308 \remark do not use during start up since window/buffer size is not well defined in that case resulting in 00309 00310 \remark bad settings for the mapping. 00311 00312 \param vx1: minimum x coordinate of display area 00313 \param vy1: minimum y coordinate of display area 00314 \param width: width of displayed area in world coordinates 00315 \param height: height of displayed area in world coordinates 00316 */ 00317 virtual void SetMappingWidthHeight( double vx1, double vy1, double width, double height ); 00318 00319 //!Give the virtual size to be displayed, the mapping matrix will be calculated. 00320 /*! 00321 The current buffer size is used to calculate how to at least display all of the area given. 00322 00323 \remark do not use during start up since window/buffer size is not well defined in that case resulting in 00324 00325 \remark bad settings for the mapping. 00326 00327 \see SetMappingDeviceRect to map to a different device/buffer rectangle. 00328 00329 \param box a boundingbox to set mapping 00330 */ 00331 void SetMappingWidthHeight( const a2dBoundingBox& box ); 00332 00333 //! Give the virtual size to be displayed, the mapping matrix will be calculated. 00334 /*! 00335 To display all of a drawing, set this here to the boundingbox of the root object 00336 of the canvas. 00337 00338 So vx1 and vx2 to the minimum x and y of the boundingbox. 00339 Calculate xpp and ypp in such a manner that it will show the whole drawing. 00340 00341 The buffer size or SetMappingDeviceRect() is used when setting the mapping with this function. 00342 00343 \remark when a user-to-world matrix SetTransform() is set, the m_usertodevice is recalculated to take 00344 the new mapping matrix and the already set user-to-world matrix into account. 00345 00346 \param vx1: minimum x coordinate of display area 00347 \param vy1: minimum y coordinate of display area 00348 \param xpp: Number of user units per pixel in x 00349 \param ypp: Number of user units per pixel in y 00350 */ 00351 void SetMappingUpp( double vx1, double vy1, double xpp, double ypp ); 00352 00353 //!return xpp Number of user units per pixel in x 00354 double GetUppX() const { return m_xpp; } 00355 00356 //!return ypp Number of user units per pixel in y 00357 double GetUppY() const { return m_ypp; } 00358 00359 //!Set Minimal X of the visible part in world coordinates 00360 void SetMinX( double x ); 00361 00362 //!Set Minimal Y of the visible part in world coordinates 00363 void SetMinY( double y ); 00364 00365 //!set world units per pixel in X 00366 void SetUppX( double x ); 00367 00368 //!set world units per pixel in Y 00369 void SetUppY( double y ); 00370 00371 //!if the virtual area has been set already return true else false. 00372 /*! 00373 Use this during initialization of an application. 00374 */ 00375 bool GetVirtualAreaSet() const { return m_virtualarea_set;} 00376 00377 //! when called a mapping change will result not result in a refresh of the m_display. 00378 /*! 00379 m_refreshDisplay is incremented, and EndRefreshDisplayDisable() does decrement it. 00380 When m_refreshDisplay > 0 no refresh is done when changing mapping. 00381 00382 Used to prevent looping and unneeded refresh when changing mapping several times within a function. 00383 */ 00384 void StartRefreshDisplayDisable() { m_refreshDisplay++; } 00385 00386 //! see StartRefreshDisplayDisable() 00387 void EndRefreshDisplayDisable() { m_refreshDisplay--; } 00388 00389 //! see StartRefreshDisplayDisable() 00390 bool GetRefreshDisplayDisable() const { return m_refreshDisplay > 0; } 00391 00392 //! get buffer/device width 00393 inline int GetWidth() const { return m_width; } 00394 00395 //! get buffer/device height 00396 inline int GetHeight() const { return m_height; } 00397 00398 //! get mapping to device width 00399 inline int GetMapWidth() const { return m_mapWidth; } 00400 00401 //! get mapping to device height 00402 inline int GetMapHeight() const { return m_mapHeight; } 00403 00404 //! X mapping position in device coordinates 00405 inline int GetMapX() const { return m_mapX; } 00406 00407 //! Y mapping position in device coordinates 00408 inline int GetMapY() const { return m_mapY; } 00409 00410 //!get Minimal X of the visible part in world coordinates 00411 double GetVisibleMinX() const; 00412 00413 //!get Minimal X of the visible part in world coordinates 00414 double GetVisibleMinY() const; 00415 00416 //!get Maximum X of the visible part in world coordinates 00417 virtual double GetVisibleMaxX() const; 00418 00419 //!get Maximum Y of the visible part in world coordinates 00420 virtual double GetVisibleMaxY() const; 00421 00422 //!get Width of visible part in world coordinates 00423 virtual double GetVisibleWidth() const; 00424 00425 //!get Height of visible part in world coordinates 00426 virtual double GetVisibleHeight() const; 00427 00428 //!get visible area as a boundingbox in world coordinates 00429 a2dBoundingBox GetVisibleBbox() const; 00430 00431 //!convert the bounding box in world coordinates to device coordinates and return that rectangle. 00432 wxRect ToDevice( const a2dBoundingBox& bbox ); 00433 00434 //!convert the rect in device coordinates to a bounding box in world coordinates and return that boundingbox. 00435 a2dBoundingBox ToWorld( const wxRect& rect ); 00436 00437 //! convert x from device to world coordinates 00438 inline double DeviceToWorldX( double x ) const { return ( x - m_worldtodevice.GetValue(2,0) ) / m_worldtodevice.GetValue(0,0); } 00439 //! convert y from device to world coordinates 00440 inline double DeviceToWorldY( double y ) const { return ( y - m_worldtodevice.GetValue(2,1) ) / m_worldtodevice.GetValue(1,1); } 00441 //! convert x relative from device to world coordinates 00442 /*! 00443 Use this to convert a length of a line for instance 00444 */ 00445 inline double DeviceToWorldXRel( double x ) const { return x / m_worldtodevice.GetValue(0,0); } 00446 //! convert y relative from device to world coordinates 00447 /*! 00448 Use this to convert a length of a line for instance 00449 */ 00450 inline double DeviceToWorldYRel( double y ) const { return y / m_worldtodevice.GetValue(1,1); } 00451 00452 00453 //! convert x from world to device coordinates 00454 inline int WorldToDeviceX( double x ) const { return ( int ) floor( m_worldtodevice.GetValue(0,0) * x + m_worldtodevice.GetValue(2,0) + 0.5 ); } 00455 //! convert y from world to device coordinates 00456 inline int WorldToDeviceY( double y ) const { return ( int ) floor( m_worldtodevice.GetValue(1,1) * y + m_worldtodevice.GetValue(2,1) + 0.5 ); } 00457 //! convert x relative from world to device coordinates 00458 /*! 00459 Use this to convert a length of a line for instance 00460 */ 00461 inline int WorldToDeviceXRel( double x ) const {return ( int ) floor( m_worldtodevice.GetValue(0,0) * x + 0.5 ); } 00462 //! convert y relative from world to device coordinates 00463 /*! 00464 Use this to convert a length of a line for instance 00465 */ 00466 inline int WorldToDeviceYRel( double y ) const {return ( int ) floor( m_worldtodevice.GetValue(1,1) * y + 0.5 ); } 00467 //! convert x relative from world to device coordinates (result not rounded to integer) 00468 /*! 00469 Use this to convert a length of a line for instance 00470 */ 00471 inline double WorldToDeviceXRelNoRnd( double x ) const {return m_worldtodevice.GetValue(0,0) * x; } 00472 //! convert y relative from world to device coordinates (result not rounded to integer) 00473 /*! 00474 Use this to convert a length of a line for instance 00475 */ 00476 inline double WorldToDeviceYRelNoRnd( double y ) const {return m_worldtodevice.GetValue(1,1) * y; } 00477 00478 //!get the world-to-device (aka mapping) matrix 00479 const a2dAffineMatrix& GetMappingMatrix() { return m_worldtodevice; } 00480 00481 //! set world to device matrix ( better use SetMappingWidthHeight() etc. ) 00482 //! Side ffect m_usertodevice is modified to m_worldtodevice * m_usertoworld 00483 void SetMappingMatrix( const a2dAffineMatrix& mapping ); 00484 00485 //!set user-to-world transform matrix. 00486 /*! 00487 Sets the current user-to-world transform matrix at the top of the 00488 transform stack. 00489 The user-to-world matrix transforms all drawing primitives from user 00490 coordinates to world coordinates. 00491 00492 \param userToWorld The matrix for transforming from user to world. 00493 */ 00494 virtual void SetTransform( const a2dAffineMatrix& userToWorld ); 00495 00496 //!get the user-to-world transform matrix. 00497 /*! 00498 The user-to-world matrix transforms all drawing primitives from user 00499 coordinates to world coordinates. 00500 */ 00501 inline const a2dAffineMatrix& GetTransform() const { return m_usertoworld; } 00502 00503 //! get matrix which transforms directly from user coordinates to device 00504 inline const a2dAffineMatrix& GetUserToDeviceTransform() const { return m_usertodevice; } 00505 00506 //! Save the current user-to-world transform on the affine stack. 00507 virtual void PushTransform(); 00508 00509 //! push no transform, to draw directly in device coordinates 00510 virtual void PushIdentityTransform(); 00511 00512 //! Save the current transform on the affine stack and then multiply it by the given affine. 00513 /*! This is a convenience function that is equivalent to calling 00514 \code 00515 PushTransform(); Transform(affine); 00516 \endcode 00517 */ 00518 virtual void PushTransform( const a2dAffineMatrix& affine ); 00519 00520 //! Recall the previously saved user-to-world transform off the matrix stack. 00521 virtual void PopTransform( void ); 00522 00523 //!Set the detail level for spline drawing 00524 /*! 00525 \param aber Accuracy in world coordinates 00526 */ 00527 void SetSplineAberration( double aber ); 00528 00529 //! set a pre-defined style reseting cashed values. 00530 /*! setting a style ( stroke fill ) for a a2dDrawer2D, 00531 takes into account the style that is currently set for it. 00532 If the style being set is equal to the current style, 00533 internal nothing is done for the underlying device. 00534 Of course this only works if everyone obeys the rules. 00535 Routines not using a2dDrawer2D as an entry to device, may fool 00536 this trick. Therefore to be sure to start with a proper a2dDrawer2D, 00537 first call this function. 00538 It will make the a2dDrawer2D style the actual style used on the device. 00539 */ 00540 virtual void ResetStyle(); 00541 00542 //!Used to set the current stroke. 00543 /*!The a2dStroke objects are reference counted, so passing a stroke pointer 00544 * allocated with 'new' to this function will not result in a leak. 00545 */ 00546 void SetDrawerStroke( const a2dStroke& stroke ); 00547 00548 //!get the current stroke 00549 a2dStroke GetDrawerStroke() const { return m_currentstroke; } 00550 00551 //!Used to set the current fill 00552 /*!The a2dFill objects are reference counted, so passing a fill pointer 00553 * allocated with 'new' to this function will not result in a leak. 00554 */ 00555 void SetDrawerFill( const a2dFill& fill ); 00556 00557 //!get the current fill 00558 a2dFill GetDrawerFill() const { return m_currentfill; } 00559 00560 //!set font to use for drawing text 00561 void SetFont( const a2dFont& font ); 00562 00563 //!get font used for drawing text 00564 a2dFont GetFont() const { return m_currentfont; } 00565 00566 //!Draw vector path in world coordinates 00567 virtual void DrawVpath( const a2dVpath* path ); 00568 00569 //! draw a list of polygons ( contour clockwise becomes hole ) 00570 virtual void DrawPolyPolygon( a2dListOfa2dVertexList polylist, wxPolygonFillMode fillStyle = wxODDEVEN_RULE ); 00571 00572 //!Draw polygon in world coordinates using pointarray 00573 virtual void DrawPolygon( a2dVertexArray* points, bool spline = false, wxPolygonFillMode fillStyle = wxODDEVEN_RULE ); 00574 00575 //!Draw polygon in world coordinates using pointlist 00576 virtual void DrawPolygon( const a2dVertexList* list, bool spline = false, wxPolygonFillMode fillStyle = wxODDEVEN_RULE ); 00577 00578 //!Draw polyline in world coordinates using pointarray 00579 virtual void DrawLines( a2dVertexArray* points, bool spline = false ); 00580 00581 //!Draw polyline in world coordinates using pointlist 00582 virtual void DrawLines( const a2dVertexList* list, bool spline = false ); 00583 00584 //!Draw line in world coordinates 00585 virtual void DrawLine( double x1, double y1, double x2, double y2 ); 00586 00587 //!Draw Arc in world coordinates 00588 virtual void DrawArc( double x1, double y1, double x2, double y2, double xc, double yc, bool chord ); 00589 00590 //!Draw Elliptic Arc in world coordinates 00591 virtual void DrawEllipticArc( double xc, double yc, double width, double height , double sa, double ea, bool chord ); 00592 00593 //!Draw RoundedRectangle in world coordinates 00594 virtual void DrawRoundedRectangle( double x, double y, double width, double height, double radius, bool pixelsize = false ); 00595 00596 //!Draw CenterRoundedRectangle in world coordinates 00597 /*! Draws a rounded rectangle centered at the point (xc,yc) in world 00598 coordinates. 00599 */ 00600 virtual void DrawCenterRoundedRectangle( double xc, double yc, double width, double height, double radius, bool pixelsize = false ); 00601 00602 //!Draw Circle in world coordinates 00603 /*! \remark circle gets rotates and scaled etc. in x and y when required.*/ 00604 virtual void DrawCircle( double x, double y, double radius ); 00605 00606 //!Draw Ellipse in world coordinates 00607 /*! \remark ellipse gets rotates and scaled etc. in x and y when required.*/ 00608 virtual void DrawEllipse( double x, double y, double width, double height ); 00609 00610 //! Draw wxImage in world coordinates 00611 /*! Draw the wxImage to the screen in such a manner that the 00612 image is mapped into the rectangle defined by 00613 points (x-width/2,y-width/2) and (x+width/2,y+height/2) in 00614 world coordinates, with the center of the image at (x,y). 00615 00616 \param image image to draw 00617 \param x world x position of center of image 00618 \param y world y position of center of image 00619 \param width width in world coordinates to map width of image to 00620 \param height height in world coordinates to map height of image to 00621 */ 00622 virtual void DrawImage( const wxImage& image, double x, double y, double width, double height, wxUint8 Opacity = 255 ) = 0; 00623 00624 virtual void DrawImage( const a2dImageRGBA& image, double x, double y, double width, double height, wxUint8 Opacity = 255 ) = 0; 00625 00626 //! Draw wxImage in world coordinates 00627 /*! Equivalent to calling 00628 DrawImage(image, x,y, image.GetWidth(),image.GetHeight()) 00629 00630 \param image image to draw 00631 \param x world x position of center of image 00632 \param y world y position of center of image 00633 */ 00634 void DrawImage( const wxImage& image, double x = 0, double y = 0, wxUint8 Opacity = 255 ) 00635 { DrawImage( image, x, y, image.GetWidth(), image.GetHeight(), Opacity ); } 00636 00637 //! draw a single point 00638 virtual void DrawPoint( double xc, double yc ) = 0; 00639 00640 //! If true use real scale else different scale by x and y 00641 void SetRealScale( bool realScale ) { m_realScale = realScale;} 00642 00643 //! Draw text in user coordinates. 00644 /*! Draws text at the given position in user coordinates. 00645 00646 Adding rotation etc. to the user transform matrix makes it possible 00647 to draw rotated text. 00648 \param text The text which should be drawn. 00649 \param x,y The position to draw at. 00650 \param alignment Use this to align the text (eg. wxLEFT | wxBOTTOM). See also ... 00651 \param Background with or without background rectangle 00652 \sa SetFont() 00653 */ 00654 virtual void DrawText( const wxString& text, double x, double y, int alignment = wxLEFT | wxTOP | wxBBOX, bool Background = true ); 00655 00656 //! text drawn in device coordinates 00657 virtual void DeviceDrawAnnotation( const wxString& WXUNUSED( text ), wxCoord WXUNUSED( x ), wxCoord WXUNUSED( y ), const wxFont& WXUNUSED( font ) ) {} 00658 00659 //! set drawstyle to use for drawing, 00660 /*! 00661 The draw style is used for drawing in a certain fashion. 00662 00663 The current fill, stroke are not changed while setting a diffrent drawstyle. 00664 Therefore first set the required fill and stroke. 00665 Setting a2dFIX_STYLE or a2dFIX_STYLE_INVERT can only be reset using ResetFixedStyle(). 00666 Still it can be temprarely overruled with OverRuleFixedStyle() to be restored with ReStoreFixedStyle(). 00667 00668 New settings for fill, stroke may or may not have effect in how is drawn, but do change the current fill are stroke, 00669 independent of the drawing style. 00670 This depends if it makes sense to have a different style when the drawstyle is in action. 00671 When drawstyle is set, the last set fill, stroke are made active when needed. 00672 00673 \param drawstyle one of the draw styles 00674 */ 00675 void SetDrawStyle( a2dDrawStyle drawstyle ); 00676 00677 //!get drawstyle used for drawing. 00678 a2dDrawStyle GetDrawStyle() const {return m_drawstyle;} 00679 00680 //! to modify drawing feature when used as context for printing 00681 void SetPrintMode( bool onOff ) { m_printingMode = onOff; } 00682 00683 //! id style is FIXED, saves current style and sets style to a2dFILLED 00684 void OverRuleFixedStyle(); 00685 00686 //! only way to reset style after SetDrawStyle( a2dFIXED*** ); 00687 void ResetFixedStyle(); 00688 00689 //! when fixed drawing style is set, it can be overruled. 00690 /*! 00691 The last fixed style stroke and fill are restored. 00692 */ 00693 void ReStoreFixedStyle(); 00694 00695 00696 //! when set, all drawing functions return immediately. 00697 /*! 00698 This can be used to render only nested parts of documents. The parent part or drawn from their 00699 a2dCanvasObjects, but in reality nothing will be drawn until drawing is enabled for the deeper nested objects. 00700 */ 00701 void SetDisableDrawing( bool disableDrawing ) { m_disableDrawing = disableDrawing; } 00702 00703 //! see SetDisableDrawing() 00704 bool GetDisableDrawing() { return m_disableDrawing; } 00705 00706 /* 00707 // clipping region 00708 */ 00709 00710 //!set clipping region from polygon to which everything drawn will be clipped. 00711 virtual void SetClippingRegion( a2dVertexList* points, bool spline = false, wxPolygonFillMode fillStyle = wxODDEVEN_RULE ) = 0; 00712 00713 //!extend clipping region with a polygon to which everything drawn will be clipped. 00714 virtual void ExtendClippingRegion( a2dVertexList* points, bool spline = false, wxPolygonFillMode fillStyle = wxODDEVEN_RULE, a2dBooleanClip clipoperation = a2dCLIP_AND ) = 0; 00715 00716 //! push on stack the current clipping region and extend clipping region 00717 /*! 00718 The clipping region will be extended with a polygon to which everything drawn will be clipped. 00719 */ 00720 virtual void ExtendAndPushClippingRegion( a2dVertexList* points, bool spline = false, wxPolygonFillMode fillStyle = wxODDEVEN_RULE, a2dBooleanClip clipoperation = a2dCLIP_AND ) = 0; 00721 00722 //!pop a previously pushed clipping region 00723 virtual void PopClippingRegion() = 0; 00724 00725 //!set clipping region using x y values in device coordinates 00726 virtual void SetClippingRegionDev( wxCoord minx, wxCoord miny, wxCoord maxx, wxCoord maxy ) = 0; 00727 00728 //!set clipping region using x y values in world coordinates 00729 virtual void SetClippingRegion( double minx, double miny, double maxx, double maxy ) = 0; 00730 00731 //!set clipping region off 00732 virtual void DestroyClippingRegion() = 0; 00733 00734 //!what is the current clipping region in world coordinates 00735 void GetClippingBox( double& x, double& y, double& w, double& h ) const; 00736 00737 //!what is the current clipping region in world coordinates 00738 a2dBoundingBox& GetClippingBox() { return m_clipboxworld; } 00739 00740 //!what is the current clipping region in world coordinates 00741 void GetClippingMinMax( double& xmin, double& ymin, double& xmax, double& ymax ) const; 00742 00743 //!what is the current clipping region in device coordinates 00744 wxRect& GetClippingBoxDev() { return m_clipboxdev; } 00745 00746 //!what is the current clipping region in device coordinates 00747 void GetClippingBoxDev( int& x, int& y, int& w, int& h ) const; 00748 00749 //! Initialize a drawer 00750 void Init(); 00751 00752 //!start to draw on this context (used to initialize a specific drawer) 00753 virtual void BeginDraw() = 0; 00754 00755 //!end drawing on this context (used to reset a specific drawer) 00756 virtual void EndDraw() = 0; 00757 00758 //! when enabling m_useOpacityFactor, this is how transparent 00759 /*! 00760 \param OpacityFactor Real opacity is set opacity * m_OpacityFactor/255 00761 */ 00762 void SetOpacityFactor( wxUint8 OpacityFactor ); 00763 00764 //! see SetOpacityFactor() 00765 wxUint8 GetOpacityFactor() { return m_OpacityFactor; } 00766 00767 //! does a derived drawer have alpha support or not 00768 virtual bool HasAlpha() { return false; } 00769 00770 protected: 00771 00772 //! sync with actual API graphical context 00773 /*! 00774 The stroke is set to the API that is doing the actual drawing. 00775 Depending on the API the m_drawStyle should be taken into account, if it does not already 00776 yield for any stroke set by SetDrawStyle() 00777 */ 00778 virtual void SetActiveStroke( const a2dStroke& stroke ); 00779 00780 //! sync with actual API graphical context 00781 /*! 00782 The fill is set to the API that is doing the actual drawing. 00783 Depending on the API the m_drawStyle should be taken into account, if it does not already 00784 yield for any stroke set by SetDrawStyle() 00785 */ 00786 virtual void SetActiveFill( const a2dFill& fill ); 00787 00788 virtual void DoSetDrawStyle( a2dDrawStyle drawstyle ) = 0; 00789 00790 //! per drawer implementation 00791 virtual void DoSetActiveStroke() = 0; 00792 00793 //! per drawer implementation 00794 virtual void DoSetActiveFill() = 0; 00795 00796 virtual void DoSetActiveFont( const a2dFont& font ) {}; 00797 00798 //! get active stroke as wxPen 00799 wxPen ConvertActiveToPen(); 00800 00801 //! get active fill as wxBrush 00802 wxBrush ConvertActiveToBrush(); 00803 00804 #if wxART2D_USE_GRAPHICS_CONTEXT 00805 wxGraphicsBrush ConvertActiveToGraphicsBrush( wxGraphicsContext* context ); 00806 wxGraphicsPen ConvertActiveToGraphicsPen( wxGraphicsContext* context ); 00807 #endif ///wxART2D_USE_GRAPHICS_CONTEXT 00808 00809 //! return true if the drawstyle in combination with the active stroke and fill, 00810 //! does not require filling 00811 inline bool IsStrokeOnly() 00812 { 00813 return ( m_drawstyle == a2dWIREFRAME || 00814 m_drawstyle == a2dWIREFRAME_ZERO_WIDTH || 00815 m_drawstyle == a2dWIREFRAME_INVERT || 00816 m_drawstyle == a2dWIREFRAME_INVERT_ZERO_WIDTH || 00817 m_activefill.IsNoFill() || 00818 m_activefill.GetStyle() == a2dFILL_TRANSPARENT 00819 ); 00820 } 00821 00822 //! return true if the the drawstyle in combination with the active stroke, 00823 //! does not require stroking 00824 inline bool IsStroked() 00825 { 00826 return !m_activestroke.IsNoStroke() && !m_activestroke.GetStyle() == a2dSTROKE_TRANSPARENT; 00827 } 00828 00829 00830 //! convert vertex array containing line and arc segments in user coordinates to device coordinate lines. 00831 int ToDeviceLines( a2dVertexArray* points, a2dBoundingBox& devbbox, bool& smallPoly, bool replaceByRectangle = false ); 00832 00833 //! convert vertex list containing line and arc segments in user coordinates to device coordinate lines. 00834 int ToDeviceLines( const a2dVertexList *list, a2dBoundingBox& devbbox, bool& smallPoly, bool replaceByRectangle = false ); 00835 00836 //!Given the rectangle in world coordinate to be displayed, update the mappingmatrix. 00837 /*! 00838 To display all of a drawing, set this to the bounding box of the root object 00839 of the canvas. 00840 00841 So vx1 and vx2 to the minimum x and y of the bounding box. 00842 Calculate xpp and ypp in such a manner that it will show the whole drawing. 00843 00844 The buffer size or SetMappingDeviceRect() or not used when setting the mapping with this function. 00845 In fact all other mapping functions in a2dDrawer2D use this function to set the mapping for the a2dDrawer2D in the end. 00846 00847 \remark when a relative world matrix SetTransform() is set, the m_usertodevice 00848 is recalculated to take the new mapping matrix and the already set 00849 user matrix into account. 00850 00851 \param x: map to device x (non zero if canvas window is smaller than drawer) 00852 \param y: map to device y (non zero if canvas window is smaller than drawer) 00853 \param wx: map to device of this size in x, normally same as width of buffer bitmap 00854 \param wy: map to device of this size in y, normally same as height of buffer bitmap 00855 \param vx1: minimum x coordinate of display area 00856 \param vy1: minimum y coordinate of display area 00857 \param xpp: Number of world units per pixel in x 00858 \param ypp: Number of world units per pixel in y 00859 */ 00860 void SetMappingUpp( double x, double y, double wx, double wy, double vx1, double vy1, double xpp, double ypp ); 00861 00862 //! converts internal device points array to spline. Returns new number of points. 00863 unsigned int ConvertSplinedPolygon2( unsigned int n ); 00864 00865 //! converts internal device points array to spline. Returns new number of points. 00866 unsigned int ConvertSplinedPolyline2( unsigned int n ); 00867 00868 //! clip lines 00869 bool Clipping( double &x1, double &y1, double &x2, double &y2 ); 00870 00871 //! clip code of a point 00872 int GetClipCode( double x, double y ); 00873 00874 //!Used for filling with Gradient fill style. 00875 void FillPolygon( int n, wxRealPoint points[] ); 00876 00877 //!Used for filling with Gradient fill style. 00878 bool MoveUp( int n, wxRealPoint points[] , double horline, int& index, int direction ); 00879 00880 //!Used for filling with Gradient fill style. 00881 void DetectCriticalPoints( int n, wxRealPoint points[] ); 00882 00883 // Core text drawing function. 00884 /*! This function will draw each character separately using the function drawchar. 00885 It will also advance and kern the characters, by adjusting the affine matrices. 00886 The character will also be checked against the clipbox. 00887 This function assumes (0,0) is the lowerleft bbox corner. 00888 This function will not draw the background fill. 00889 \param text The text to be drawn. 00890 \param x x-Position of the text. 00891 \param y y-Position of the text. 00892 \param drawchar A function which will draw a given character. 00893 */ 00894 void DrawTextGeneric( const wxString& text, double x, double y, void ( a2dDrawer2D::*drawchar )( wxChar ) ); 00895 00896 //! Draw a cross instead of a character. 00897 virtual void DrawCharUnknown( wxChar c ); 00898 00899 //! Draw a cross, indicating an unsupported font type for this drawer. 00900 /*! Draws text at the given position in user coordinates. 00901 Adding rotation etc. to that matrix makes it possible to draw rotated text. 00902 \param text draw unknown text 00903 \param x x position 00904 \param y y position 00905 \param words If false, draw a boxed cross for the whole line. 00906 If true, draw a piece of line for each word. 00907 */ 00908 virtual void DrawTextUnknown( const wxString& text, double x, double y, bool words = false ); 00909 00910 //! Draw a stroke character 00911 /*! This is an internal function, used by DrawTextStroke. 00912 This function assumes that the affine matrix has been set up by the calling function 00913 in such a way, that the (0,0) coordinate will match with the lowerleft bbox corner 00914 of the character. Also mirroring should be performed by the calling function. 00915 */ 00916 virtual void DrawCharStroke( wxChar c ); 00917 00918 //! Wrapper for DrawCharStroke 00919 /*! 00920 ISO C++ seems(?) to forbid directly calling the address of virtual member functions. 00921 Calling &a2dDrawer2D::DrawCharStroke refers to the actual function in a2dDrawer2D and 00922 does not refer to the virtual function. 00923 Calling &(this->DrawCharStroke) should refer to the virtual function and is accepted by 00924 some compilers (MSVC, gcc <3.3), but according to gcc 3.4 this is not allowed by ISO C++. 00925 Therefore the virtual function is called through this intermediate function 00926 */ 00927 void DrawCharStrokeCb( wxChar c ) { DrawCharStroke( c ); } 00928 00929 //! Draw text in user coordinates, based on a stroke font. 00930 /* The text will be drawn with (0,0) being the lowerleft bbox corner. 00931 The background fill and alignment positioning are handled by DrawText. 00932 */ 00933 virtual void DrawTextStroke( const wxString& text, double x, double y ) 00934 { DrawTextGeneric( text, x, y, &a2dDrawer2D::DrawCharStrokeCb ); } 00935 00936 //! Draw a freetype character 00937 /*! This is an internal function, used by DrawTextFreetype 00938 This function assumes that the affine matrix has been set up by the calling function 00939 in such a way, that the (0,0) coordinate will match with the lowerleft bbox corner 00940 of the character. Also mirroring should be performed by the calling function. 00941 */ 00942 virtual void DrawCharFreetype( wxChar c ) { DrawCharUnknown( c ); } 00943 00944 //! Wrapper for DrawCharFreetype 00945 /*! \sa DrawCharStrokeCb */ 00946 void DrawCharFreetypeCb( wxChar c ) { DrawCharFreetype( c ); } 00947 00948 //! Draw text in world coordinates, based on a freetype font . 00949 /* The text will be drawn with (0,0) being the lowerleft bbox corner. 00950 The background fill and alignment positioning are handled by DrawText. 00951 */ 00952 virtual void DrawTextFreetype( const wxString& text, double x, double y ) 00953 { DrawTextGeneric( text, x, y, &a2dDrawer2D::DrawCharFreetypeCb ); } 00954 00955 //! Draw a dc character 00956 /*! This is an internal function, used by DrawTextDc 00957 This function assumes that the affine matrix has been set up by the calling function 00958 in such a way, that the (0,0) coordinate will match with the lowerleft bbox corner 00959 of the character. Also mirroring should be performed by the calling function. 00960 */ 00961 virtual void DrawCharDc( wxChar c ) { DrawCharUnknown( c ); } 00962 00963 //! Wrapper for DrawCharDc 00964 /*! \sa DrawCharStrokeCb */ 00965 void DrawCharDcCb( wxChar c ) { DrawCharDc( c ); } 00966 00967 //! Draw text in user coordinates, based on a dc font . 00968 /* The text will be drawn with (0,0) being the lowerleft bbox corner. 00969 The background fill and alignment positioning are handled by DrawText. 00970 */ 00971 virtual void DrawTextDc( const wxString& text, double x, double y ) 00972 { DrawTextGeneric( text, x, y, &a2dDrawer2D::DrawCharDcCb ); } 00973 00974 //! Convert double points to integer coords in the point cache and return pointer. 00975 wxPoint* _convertToIntPointCache( int n, wxRealPoint *pts ); 00976 00977 //!buffer updating activity possible or not 00978 bool m_frozen; 00979 00980 //!enable/ disable mouse events handling by canvas 00981 bool m_mouseevents; 00982 00983 //!used while rendering 00984 a2dStroke m_currentstroke; 00985 00986 //!used while rendering 00987 a2dFill m_currentfill; 00988 00989 //!used while rendering 00990 a2dStroke m_activestroke; 00991 00992 //!used while rendering 00993 a2dFill m_activefill; 00994 00995 //!current font set 00996 a2dFont m_currentfont; 00997 00998 //!drawstyle (like invert mode) 00999 a2dDrawStyle m_drawstyle; 01000 01001 //! used to restore an overruled fix style 01002 a2dStroke m_fixStrokeRestore; 01003 01004 //! used to restore an overruled fix style 01005 a2dFill m_fixFillRestore; 01006 01007 //! used to restore an overruled fix style 01008 a2dDrawStyle m_fixDrawstyle; 01009 01010 //! up or down 01011 bool m_yaxis; 01012 01013 //! virtual coordinates box its miminum X 01014 double m_virt_minX; 01015 01016 //! virtual coordinates box its miminum Y 01017 double m_virt_minY; 01018 01019 //!user units per pixel in x 01020 double m_xpp; 01021 01022 //!user units per pixel in y 01023 double m_ypp; 01024 01025 //! keep track of this 01026 bool m_fixedStyledOverRuled; 01027 01028 private: 01029 01030 void ColourXYLinear( int x1, int x2, int y ); 01031 void ColourXYRadial( int x1, int x2, int y ); 01032 01033 //! gradient start stop 01034 double m_dx1, m_dy1, m_dx2, m_dy2, m_radiusd, m_length, m_max_x, m_min_x, m_max_y, m_min_y; 01035 a2dLine m_line; 01036 01037 protected: 01038 01039 //! draw an internal polygon in device coordinates 01040 virtual void DeviceDrawPolygon( unsigned int n, bool spline , wxPolygonFillMode fillStyle ); 01041 01042 //! draw an internal polyline in device coordinates 01043 virtual void DeviceDrawLines( unsigned int n, bool spline ); 01044 01045 //!draw in pixels 01046 virtual void DeviceDrawLine( double x1, double y1, double x2, double y2 ); 01047 01048 //! Draw a pixel-width, unstroked horizontal line in device (pixel) coordinates 01049 /*! This method is useful for implementing low level fill routines. 01050 01051 \param x1 x start of line 01052 \param x2 x end of line 01053 \param y1 y of line 01054 \param use_stroke_color If true, then use the current stroke color 01055 If false, then use the current fill color. 01056 */ 01057 virtual void DeviceDrawHorizontalLine( int x1, int y1, int x2, bool use_stroke_color ); 01058 01059 //! Draw a pixel-width, unstroked vertical line in device (pixel) coordinates 01060 /*! This method is useful for implementing low level fill routines. 01061 01062 \param x1 x of line 01063 \param y1 y start of line 01064 \param y2 y end of line 01065 \param use_stroke_color If true, then use the current stroke color 01066 If false, then use the current fill color. 01067 */ 01068 virtual void DeviceDrawVerticalLine( int x1, int y1, int y2, bool use_stroke_color ); 01069 01070 //!draw a single, unstroked pixel in device coordinates with the given color 01071 virtual void DeviceDrawPixel( int x1, int y1, unsigned char r, unsigned char g, unsigned char b, unsigned char a = 255 ); 01072 01073 //! active stroke alpha 01074 wxUint8 m_StrokeOpacityCol1; 01075 //! active stroke alpha 01076 wxUint8 m_StrokeOpacityCol2; 01077 //! active fill alpha 01078 wxUint8 m_FillOpacityCol1; 01079 //! active fill alpha 01080 wxUint8 m_FillOpacityCol2; 01081 01082 //! active stroke colours 01083 unsigned char m_colour1redStroke; 01084 //! active stroke colours 01085 unsigned char m_colour1greenStroke; 01086 //! active stroke colours 01087 unsigned char m_colour1blueStroke; 01088 01089 //! active fill colours 01090 unsigned char m_colour1redFill; 01091 //! active fill colours 01092 unsigned char m_colour1greenFill; 01093 //! active fill colours 01094 unsigned char m_colour1blueFill; 01095 01096 //! active fill colours 01097 unsigned char m_colour2redFill; 01098 //! active fill colours 01099 unsigned char m_colour2greenFill; 01100 //! active fill colours 01101 unsigned char m_colour2blueFill; 01102 01103 protected: 01104 01105 //!world to device coordinate mapping 01106 a2dAffineMatrix m_worldtodevice; 01107 01108 //!pointer to current user-to-world transform matrix 01109 a2dAffineMatrix m_usertoworld; 01110 01111 //!pointer to current user-to-device transform matrix ( so includes mapping matrix ) 01112 a2dAffineMatrix m_usertodevice; 01113 01114 //!is the virtual area set already (used during startup) 01115 bool m_virtualarea_set; 01116 01117 //! see SetRefreshDisplay() 01118 int m_refreshDisplay; 01119 01120 //!device size width 01121 int m_width; 01122 01123 //!device size height 01124 int m_height; 01125 01126 //! X mapping position in device coordinates 01127 int m_mapX; 01128 01129 //! Y mapping position in device coordinates 01130 int m_mapY; 01131 01132 //! width for mapping in device coordinates 01133 int m_mapWidth; 01134 01135 //! height for mapping in device coordinates 01136 int m_mapHeight; 01137 01138 //! critical point list for polygon 01139 a2dCriticalPointList m_CRlist; 01140 01141 //! scanline list of intersections with polygon 01142 a2dAETList m_AETlist; 01143 01144 //!cached array for containing transformed device coordinates (integer) 01145 std::vector<wxPoint> m_cpointsInt; 01146 01147 //!cached array for containing transformed device coordinates (double) 01148 std::vector<wxRealPoint> m_cpointsDouble; 01149 01150 //! accuracy of spline 01151 double m_splineaberration; 01152 01153 //! pushed clipping regions 01154 a2dClipRegionList m_clipregionlist; 01155 01156 //!accuracy of arc segment calculation etc. in device coordinates 01157 double m_displayaberration; 01158 01159 //! object smaller than this value will not be rendered 01160 wxUint16 m_drawingthreshold; 01161 01162 //! polygon smaller than this value will be rendered non filled. 01163 wxUint16 m_polygonFillThreshold; 01164 01165 //! underneath the threshold draw rectangles if true else nothing 01166 bool m_asrectangle; 01167 01168 //! current clipping area in world coordinates 01169 a2dBoundingBox m_clipboxworld; 01170 01171 //! current clipping area in device coordinates 01172 wxRect m_clipboxdev; 01173 01174 //! counter for BeginDraw EndDraw calls 01175 int m_beginDraw_endDraw; 01176 01177 //! view its window. 01178 wxWindow* m_display; 01179 01180 //! all drawing is disabled when this is true 01181 bool m_disableDrawing; 01182 01183 //! opacity will be the one set, derived by this 01184 wxUint8 m_OpacityFactor; 01185 01186 //! Affine transform stack. 01187 /*! The stack actually is a double stack, for both m_relativetransform and m_usertodevice 01188 This prevents some additional affine matrix multiplications. 01189 The stack is implemented as a 'fixed' array, preventing (slow) dynamic memory allocation. 01190 */ 01191 std::vector<a2dAffineMatrix> m_affineStack; 01192 01193 //! If true use real scale else different scale by x and y 01194 bool m_realScale; 01195 01196 //! can be used to modify drawing features when used as context for printing 01197 bool m_printingMode; 01198 01199 DECLARE_CLASS( a2dDrawer2D ) 01200 01201 public: 01202 01203 //! id for changed zoom 01204 //! sent from a2dDrawer2D to a2dEventDistributer when zoom has changed. 01205 const static wxEventType sm_changedZoom; 01206 01207 }; 01208 01209 //! class draws nothing, still can be used as a drawing context. 01210 /*! 01211 In cases where a drawing context is not really needed to draw, but 01212 one still wants to follow the same matrix multiplication as if drawn, 01213 this class can be used. 01214 It can simplifies the code a lot if there is a dummy drawer instead of non at all, 01215 which would require testing for that. 01216 A dummy drawer can be used in all cases where normally a real drawer is used. 01217 */ 01218 class A2DARTBASEDLLEXP a2dBlindDrawer2D : public a2dDrawer2D 01219 { 01220 public: 01221 01222 //! Drawer having a buffer of w pixel wide and h pixels heigh 01223 a2dBlindDrawer2D( int w = 100, int h = 100 ); 01224 01225 //! Drawer having a buffer of w pixel wide and h pixels height given by size 01226 a2dBlindDrawer2D( const wxSize& size ); 01227 01228 //!set buffer size to w pixel wide and h pixels heigh 01229 /*! 01230 \remark 01231 SetMappingDeviceRect() is NOT reset. 01232 */ 01233 void SetBufferSize( int w, int h ); 01234 01235 wxBitmap GetBuffer() const { return wxBitmap( 0, 0 ); } 01236 01237 //!get part of the buffer given a rect 01238 wxBitmap GetSubBitmap( wxRect sub_rect ) const; 01239 01240 //!destructor 01241 virtual ~a2dBlindDrawer2D(); 01242 01243 //!copy constructor 01244 a2dBlindDrawer2D( const a2dBlindDrawer2D& other ); 01245 01246 a2dBlindDrawer2D( const a2dDrawer2D& other ); 01247 01248 virtual void BlitBuffer( wxRect rect, const wxPoint& bufferpos = wxPoint( 0, 0 ) ); 01249 01250 virtual void BlitBuffer( wxDC* dc, wxRect rect, const wxPoint& bufferpos = wxPoint( 0, 0 ) ); 01251 01252 void ResetStyle(); 01253 01254 //!start to draw on this context (used to initialize a specific drawer) 01255 virtual void BeginDraw(); 01256 01257 //!end drawing on this context (used to reset a specific drawer) 01258 virtual void EndDraw(); 01259 01260 void SetClippingRegion( a2dVertexList* points, bool spline = false, wxPolygonFillMode fillStyle = wxODDEVEN_RULE ); 01261 01262 virtual void ExtendClippingRegion( a2dVertexList* points, bool spline = false, wxPolygonFillMode fillStyle = wxODDEVEN_RULE, a2dBooleanClip clipoperation = a2dCLIP_AND ); 01263 01264 virtual void ExtendAndPushClippingRegion( a2dVertexList* points, bool spline = false, wxPolygonFillMode fillStyle = wxODDEVEN_RULE, a2dBooleanClip clipoperation = a2dCLIP_AND ); 01265 01266 void PopClippingRegion(); 01267 01268 void SetClippingRegionDev( wxCoord minx, wxCoord miny, wxCoord width, wxCoord height ); 01269 void SetClippingRegion( double minx, double miny, double maxx, double maxy ); 01270 void DestroyClippingRegion(); 01271 01272 void DrawPolygon( a2dVertexArray* points, bool spline = false, wxPolygonFillMode fillStyle = wxODDEVEN_RULE ); 01273 01274 void DrawPolygon( const a2dVertexList* list, bool spline = false, wxPolygonFillMode fillStyle = wxODDEVEN_RULE ); 01275 01276 void DrawLines( a2dVertexArray* points, bool spline = false ); 01277 01278 void DrawLines( const a2dVertexList* list, bool spline = false ); 01279 01280 void DrawLine( double x1, double y1, double x2, double y2 ); 01281 01282 void DrawArc( double x1, double y1, double x2, double y2, double xc, double yc, bool chord ); 01283 01284 void DrawEllipticArc( double xc, double yc, double width, double height , double sa, double ea, bool chord ); 01285 01286 void DrawRoundedRectangle( double x, double y, double width, double height, double radius, bool pixelsize = false ); 01287 01288 void DrawCenterRoundedRectangle( double xc, double yc, double width, double height, double radius, bool pixelsize = false ); 01289 01290 void DrawCircle( double x, double y, double radius ); 01291 01292 void DrawEllipse( double x, double y, double width, double height ); 01293 01294 void DrawImage( const wxImage& image, double x, double y, double width, double height, wxUint8 Opacity = 255 ); 01295 01296 void DrawImage( const a2dImageRGBA& image, double x, double y, double width, double height, wxUint8 Opacity = 255 ); 01297 01298 //more speedy then base, by directly converting to device coordinates. 01299 void DrawVpath( const a2dVpath* path ); 01300 01301 void DrawPoint( double xc, double yc ); 01302 01303 void DeviceDrawAnnotation( const wxString& text, wxCoord x, wxCoord y, const wxFont& font ); 01304 01305 protected: 01306 01307 virtual void DoSetDrawStyle( a2dDrawStyle drawstyle ); 01308 01309 void DoSetActiveStroke(); 01310 01311 void DoSetActiveFill(); 01312 01313 private: 01314 01315 DECLARE_DYNAMIC_CLASS( a2dBlindDrawer2D ) 01316 }; 01317 01318 01319 #if wxART2D_USE_GRAPHICS_CONTEXT 01320 01321 //! wxGraphicsContext based drawing context derived from a2dDrawer2D 01322 /*! 01323 Use wxGraphicsContext from wxWidgets to draw. 01324 01325 \ingroup drawer 01326 */ 01327 class a2dGcBaseDrawer : public a2dDrawer2D 01328 { 01329 DECLARE_CLASS(a2dGcBaseDrawer) 01330 01331 public: 01332 01333 //! Drawer having a buffer of w pixel wide and h pixels heigh 01334 a2dGcBaseDrawer( int width = 0, int height = 0, wxGraphicsRenderer* render = NULL, wxGraphicsContext* context = NULL ); 01335 01336 //! copy constructor 01337 a2dGcBaseDrawer( const a2dGcBaseDrawer& other ); 01338 01339 a2dGcBaseDrawer( const a2dDrawer2D& other ); 01340 01341 virtual ~a2dGcBaseDrawer(); 01342 01343 virtual void SetTransform( const a2dAffineMatrix& userToWorld ); 01344 virtual void PushTransform(); 01345 virtual void PushIdentityTransform(); 01346 virtual void PushTransform( const a2dAffineMatrix& affine ); 01347 virtual void PopTransform( void ); 01348 01349 virtual void BeginDraw(); 01350 virtual void EndDraw(); 01351 01352 virtual void BlitBuffer( wxRect rect, const wxPoint& bufferpos ); 01353 01354 virtual void BlitBuffer( wxDC* dc, wxRect rect, const wxPoint& bufferpos = wxPoint( 0, 0 ) ) = 0; 01355 01356 void ResetStyle(); 01357 01358 void SetClippingRegion( a2dVertexList* points, bool spline = false, wxPolygonFillMode fillStyle = wxODDEVEN_RULE ); 01359 01360 virtual void ExtendClippingRegion( a2dVertexList* points, bool spline = false, wxPolygonFillMode fillStyle = wxODDEVEN_RULE, a2dBooleanClip clipoperation = a2dCLIP_AND ); 01361 01362 virtual void ExtendAndPushClippingRegion( a2dVertexList* points, bool spline = false, wxPolygonFillMode fillStyle = wxODDEVEN_RULE, a2dBooleanClip clipoperation = a2dCLIP_AND ); 01363 01364 void PopClippingRegion(); 01365 01366 void SetClippingRegionDev( wxCoord minx, wxCoord miny, wxCoord width, wxCoord height ); 01367 01368 void SetClippingRegion( double minx, double miny, double maxx, double maxy ); 01369 01370 void DestroyClippingRegion(); 01371 01372 virtual void DrawRoundedRectangle( double x, double y, double width, double height, double radius, bool pixelsize = false ); 01373 01374 virtual void DrawCircle( double x, double y, double radius ); 01375 01376 void DrawPoint( double xc, double yc ); 01377 01378 virtual void DrawEllipse( double x, double y, double width, double height); 01379 01380 virtual void DrawLines( const a2dVertexList* list, bool spline ); 01381 01382 virtual void DrawPolygon( a2dVertexArray* points, bool spline = false, wxPolygonFillMode fillStyle = wxODDEVEN_RULE ); 01383 01384 virtual void DrawPolygon( const a2dVertexList* list, bool spline = false, wxPolygonFillMode fillStyle = wxODDEVEN_RULE ); 01385 01386 virtual void DrawLines( a2dVertexArray* points, bool spline = false ); 01387 01388 void DrawLine( double x1, double y1, double x2, double y2 ); 01389 01390 void DrawImage( const wxImage& image, double x, double y, double width, double height, wxUint8 Opacity = 255 ); 01391 01392 void DrawImage( const a2dImageRGBA& image, double x, double y, double width, double height, wxUint8 Opacity = 255 ); 01393 01394 void DrawText( const wxString& text, double x, double y, int alignment = wxLEFT | wxTOP | wxBBOX, bool Background = true ); 01395 01396 protected: 01397 01398 virtual void DoSetDrawStyle( a2dDrawStyle drawstyle ); 01399 01400 void DoSetActiveStroke(); 01401 01402 void DoSetActiveFill(); 01403 01404 void DoSetActiveFont( const a2dFont& font ); 01405 01406 wxRegion m_clip; 01407 01408 wxGraphicsRenderer* m_render; 01409 wxGraphicsContext* m_context; 01410 }; 01411 01412 01413 //! wxGraphicsContext based drawing context derived from a2dDrawer2D 01414 /*! 01415 Use wxGraphicsContext from wxWidgets to draw. 01416 01417 \ingroup drawer 01418 */ 01419 class a2dNativeGcDrawer : public a2dGcBaseDrawer 01420 { 01421 DECLARE_DYNAMIC_CLASS(a2dNativeGcDrawer) 01422 01423 public: 01424 01425 //! Drawer having a buffer of w pixel wide and h pixels heigh 01426 a2dNativeGcDrawer( int width = 0, int height = 0 ); 01427 01428 //! Drawer having a buffer of w pixel wide and h pixels height given by size 01429 a2dNativeGcDrawer( const wxSize& size ); 01430 01431 //! bitmap is converted to image on which you can draw. 01432 //! Use GetBuffer() to get a bitmap back. 01433 a2dNativeGcDrawer( const wxBitmap& bitmap ); 01434 01435 //!return buffer as a bitmap 01436 wxBitmap GetBuffer() const; 01437 01438 //! copy constructor 01439 a2dNativeGcDrawer( const a2dNativeGcDrawer& other ); 01440 01441 a2dNativeGcDrawer( const a2dDrawer2D& other ); 01442 01443 //!set buffer size to w pixel wide and h pixels heigh 01444 void SetBufferSize( int w, int h ); 01445 01446 //!get part of the buffer given a rect 01447 wxBitmap GetSubBitmap( wxRect sub_rect ) const; 01448 01449 void CopyIntoBuffer( const wxBitmap& bitm ); 01450 01451 virtual ~a2dNativeGcDrawer(); 01452 01453 void InitContext(); 01454 01455 void BlitBuffer( wxDC* dc, wxRect rect, const wxPoint& bufferpos = wxPoint(0,0) ); 01456 01457 void ShiftBuffer( int dxy, bool yshift ); 01458 01459 void DrawPoint( double xc, double yc ); 01460 01461 protected: 01462 01463 //!the buffer that is used for rendering 01464 wxBitmap m_buffer; 01465 01466 //!Created at BeginDraw, and destoyed at EndDraw, used to actually draw 01467 wxMemoryDC m_memdc; 01468 }; 01469 #endif // wxART2D_USE_GRAPHICS_CONTEXT 01470 01471 #endif /* __WXDRAWER2D_H__ */ 01472