= a2dCanvasView and a2dDrawer2D = All rendering of a <> containing <>'s is achieved via a <> instance. <> in combination with <>, can be seen as a high level Device Context, specially designed to work with the wxArt2D library. The <> called <> has a <> which is used to do the real drawing. Specific <> implementation do have a double buffering mechanisms. They all understand how to draw basic primitives in relative world coordinates. You can set fills and strokes, a drawstyle, clipping regions, mapping matrixes etc. It has several optimizations to speed up the drawing of primitives. Most important is that the conversion from relative world to absolute world, followed by conversion to device coordinates. This action is done with one matrix calculation. The <> itself administrates the updating of rectangular areas within a drawing in a sufisticated manner. The clue is, to first assemble areas or objects that require to be redrawn, and when the time is right, really do redraw those areas at once in an optimized manner. This makes <> almost automatically redisplay modified objects or areas, without the user needing to bother about it. The modified object are in general part of the <>, but <> can have a <> set for it. And this <> can have tools which will draw object too. Therefor the whole update mechanism takes care of those objects inside tools also. A <> is just a base class, the idea is to derive classes from it which can really draw something. == Mapping and zooming == The mapping to device coordinates and visa versa, is under control of the <> class. <> is a kind of wxDC, it allows to draw all basic primitives like polygons, polylines, circles Arcs etc. in world coordinates, but applying a certain transform matrix first to that primitive. Transformation to device coordinates and first relative to absolute coordinates is done here. This means that if you have a <> which is a child of some other <>, the <> class will take care of drawing it at the right position in the <> its device. <> is setup independent of the <> and the <> that is used to display the data/drawing contained within the <>. Internally <> only uses a <> base pointer to display the objects. Any <> derived class can be used to display the drawing contained within the document to a device. A <> uses a <> to draw itself by drawing basic primitives, it first sets the accumulated matrix to the <>. This matrix takes care of transforming the basic primitives that represent the object from its relative position (towards its current parent object within the drawing) to an/the absolute position. One <> can be placed several times within a drawing, references to the object are used to do this. This means that an object does not have a unique absolute position within a drawing, and is defined only towards its parent object's. The accumulated matrix is calculated when recursively rendering a document. The accumulated matrix includes all transforms on the path to a certain <>. It is used to calculate the absolute coordinates which a <> at that position/path in the document has. The absolute coordinates are calculated within the <>, and in there combined in one matrix to directly go to the device coordinates also. Before really rendering an object, first the accumulated matrix is set for the <> that is used to render the document. This matrix is directly combined with a matrix which converts to device coordinates, the resulting matrix will be used to convert all primitives vertexes which will be drawn to an absolute position. Because the implementation of the drawing routines inside a <> are polygon based. Every basic primitive is converted to a polygon/polyline or set of polygons/polylines, the vertexes of those polygons will be converted to absolute and device coordinates. The resulting polygons will be rendered. This way we can have transformed circles, ellipses and arcs etc. So a relative drawn circle ( drawn by a <>) can eventually be drawn like an rotated ellipse. This would have bin impossible with just a wxDC based implementation. == Drawer types == There is a <> for printing a <>, which is used by <> to print a <>. It is possible to develop a a2dOpenGlCanvas and a a2dOpenGlDrawer. Since OpenGl will display 3D objects normally, in this case the <> layers can have thickness, so the result can be really 3D in a way. All objects drawn on a layer will get the same "z" coordinate based on the order the layers are drawn and the thickness of each layer. Special antialiased libraries do exist that can be used to draw into bitmaps, allowing alpha blending/compositing. The basic Fill and Stroke objects have a opacity member which is used to define the transparancy of the drawn primitives. Writing a <> based on those libraries, opens a new range possibilities, like new types of Strokes and Fills one can use. The current best implemented library is the Antigrain Library. A <> derived class like <> is used to do the drawing in world coordinates in a wxDc based fashion, but it does it double buffered. Internal it draws first to a bitmap buffer, which is later, in idle time, blitted to the window. The same <> is used internal in <>. Here it takes care of rendering a <> to a bitmap. A <> is a <> itself, and can be made part of a document like any other <>. It uses the <> its bitmap for the internal image to display it self as a <>. So indeed <> will be part of a <> structure in the end. The effect is that you can have a canvas which displays a2dRenderImages which contain data that you can/would/could normally display on a <> directly. As such it can be used in browser like programs to display one or more vector drawings on specific parts of the window. In a browser this might be used to display SVG content. == Printing a a2dCanvasView View == Printing part of a <> is seen as printing a view of the document. <> is used to simplify this task. The <> is used by the printing classes to extract the zoom of the view, and internal a <> is used to render the document to the printer. One can also print the whole document at once, and not only that part which is displayed on a view. For this there are two types of print, one for the view and one for the document (wxID_PRINT_VIEW wxID_PRINT_DOCUMENT). The following list shows some ways to draw/print a <> recursively while printing: * <>::OnCreatePrintout# based on this view its mapping * <>#render a canvas document through this class which is the drawer its a2dCanvasDocument * <> #render this document that contains a2dCanvasObjects * <> #render this object * <> #use this drawer in <> to draw it * printer #here is it drawn to and contains end result == Double buffer and updating == Some <>'s do have a backup buffer, that is used to render into. For the <> this is a bitmap that is drawn into. It depends on the implementation of <> derived classes how things are implemented. When used, the backup buffer is blitted to the real device when the rendering is finished. <> uses wxMemoryDc to draw into the buffer. <> has functions to draw basic primitives to a device, this device can be a buffer or a window are any other rectangular area. The primitive drawing functions are used inside <>'s to draw the object, and they are independent of the real device. This way the same <>'s can be displayed using different a2dDrawer2Ds. <>'s do have a <> set for it, and one <> from the document is set as the ShowObject. This object and all its nested children are displayed on the view. When a change in the document is detected, the <> will make sure that all <>'s using the document will be updated. <> has a <>, and this last class uses internal a <> with a bitmap having the same size as the client window. When rendering is complete the resulting bitmap is blitted to the <> window. This is done in Idle time, or when wanted by the user. The <> its bitmap buffer is also used to quickly repaint damaged parts caused by overlapping dialogs and other windows. But this task is part of <>. In those cases it will not render those parts again, only a simple blit is enough. Real re-rendering takes place when the mapping changes due to zooming in, scrolling, or resizing a window, and of course when the data in the document itself changes. This last one means re-rendering only those parts in the <> that really did change. When rendering the graphical data which is stored inside a <> as a2dCanvasObjects, all the <> using the document will be updated one by one. When updating and rendering part of a document to a view, the iteration context <> is used as a parameter to the rendering functions. The <> contains a pointer to the <> from where the renderings started. Via this <>, it has also access to the <> for that <>. All a2dCanvasObjects stored within a <> (nested also), have a pointer to the <> object to which they belong. This m_root pointer is used to notify the views on the document that there are pending objects. The document is check for changes in idle time, and sents update event to all views. This then result in the views bringing themselfs up to date. The <> itself knows the width and height of the device to render to. It might be a Window but also a bitmap being part of a window or some other type of device for which there is a <> available. It is very simular to wxDC in wxWidgets, only this one is dedicated to <> and alows to draw directly in world coordinates with a given placement matrix. <> is a <> derived class, and knows the <> it needs to view.. The same <> can be displayed with/on N <> objects at the same time. And all of them can display a different rectangular part of the same top <>. In case of nested data, the ShowObject which is displayed within all of the <> instances, can be different too. Updating objects that have changed in position or size etc. will be properly updated on all <> objects. This is under control of <>. When an object is changed, it sets a pending flag to indicate that, at the same time a flag is set in the <>. This flag is checked in idle time, so the document knows when there are changed objects. When there are changed objects, the document sents an update event to the central event distributer <> or a special set distributer class (e.g a <> in a single <> situation). This class then sents the event to all <>'s which are registrated to it. Because <> is derived from <>, it will get the update events. The <> now checks if the update event is sent from the document that it is meant to display, and if so starts updating its view. For a <> this means that the <> is traversed and all boundingboxes of the changed objects are added to the redraw list of the <>. The object that changed did not yet update their boundingbox, and therefore they still represent the boundingbox of the object before it was changed. As soon as all <>'s have assembled the boundingboxes of the previous state, <> recalculates the boundingboxes of the changed objects, and all that depend on it. Next it sent another update event, and this result once more in the <>s adding update areas of the new boundingboxes of the changed objects in the document. In the end all drawers have assembled all the areas changed in its view, all those areas will be redrawn. So when an object changes all it needs to do is report to the <> that it did change, which automatically results in updating the object on the <> devices. == Drawing methods == There or two ways to draw a <> using a <>. The direct way is to use the basic drawing features like drawpolygon, drawcircle etc., they draw the polygon or circle defined in relative world coordinates. Here the drawer does all the conversion from relative to absolute world coordinates (using the supplied matrix) and later to device coordinates. Clipping those polygons can be done in the drawer itself, first at the worldcoordinate level and later on device coordinate level. It uses the clippingregion set for the active drawer to do this. The advantage of this method of drawing is that many things like transformation and filling style routines can be concentrated in the drawer. Arrays containing converted device coordinates, can make use of one and the same array within <>. This type of cashing makes drawing much faster. Another method of drawing is to first ask the drawer for a part of the <> bitmap buffer. This bitmap will have the size of the clippingbox that is set to the <> when re-rendering an area. The canvasobject to draw, will retrieve that area from the backup buffer in <>, and add to it what it wants. The job of the <> its RenderFunction is to fill this bitmap in some way. Clearly the bitmap to fill is in device coordinates and therefore all transformations and conversion to device coordinates needs to be done within the render function itself. Still this can be the best way in cases where data needs to be cashed within the object in order to get acceptable speed. When the bitmap is filled it needs to be drawn back to the drawer its total bitmap buffer. This method allows cashing within the <> itself. For example, the <>, preserves the scalled image/bitmap. This cashed bitmap is used during redraws as long as the object itself or the mapping to device coordinates does not change. Of course very good for speed, bad for memory usage. == Updating the a2dCanvasView or a2dCanvas window == Updating means, redrawing/rerendering parts of a drawing that is stored within a <>, and it depends on the implementation of the <> how this is done. When using a <> for drawing, it renders and stores the result into a buffer first, and uses this buffer for quick blits to the real device, which is the <> window. This is called double buffering, and down here this type of <> is used for <>. Each <> displays part of the total drawing as set by its mapping. When the displayed part has changed, an update of this part is needed to reflect the changes on the <> its device and buffer. But also an update is needed when objects in the drawing change. The several <>'s on a <> which do display the changed objects will be partly updated in that case. === Requesting updating of an area === Requesting repainting areas of a drawing is done by <>::AddPendingUpdate members. Repainting the areas of all <>'s which display a certain <>, is done via the <> instance to which that <> belongs. A first way of requesting an area to update, is adding a rectangle to the updatelist of a <>. A second way is to give a pointer to a <> The area currently occupied by the object will be added to the updatelist of the <>. Those two methods make the programmer responsible for supplying the correct areas for updating on every <>. Often this method is used for interactive tools which directly manipulate the data in one <> view. Only in the end all other <>'s displaying the object are updated also. A third way of requesting updates is automatically arranged by the wxArt2D library. It requires to mark an object as pending, and everything will be taken care of. This is happening from within the <>, but it still uses <>::AddPendingUpdate to add areas to the updatelist within all <>'s of the document. === Updatelist within a2dCanvasView === Whatever method, they all eventually use the updatelist of every <>. The updatelist is in principle a list of rectangle's. Each update area has a two flag's. One to check if the area requested for update is already redrawn to the buffer and the other to check if that area is blitted to the screen also. The two action can be separated in time. When pending updates areas are added to the list within a <>, they are not directly updated/redrawn in the screen buffer, but only when idle, or in Onpaint. As soon as the buffer contains the redrawn areas, they can be blitted to the screen also. It depends on the action in progress if this is done directly or delayed. <>::RedrawPendingUpdateAreas() updates/redraws the areas in the updatelist to the buffer, flagging them for blit later. <>::BlitPendingUpdateAreas( wxDC & dc ) blits the areas that were updated to the screen in Onpaint or Onidle, or when needed. The blitted areas or directly deleted, resulting in having an empty updatelist. In some cases it is better to first redraw all update areas to the buffer, and delay the blitting to later. For instance while scrolling the window, where first the buffer is brought up to date, and the blitting to the screen is handled by shifting the whole buffer followed by a blit. So in those cases blitting the damaged parts is not needed. In the normal case the areas in the updatelist will be redrawn and the redrawn parts in the buffer will be blitted to the window in idle time, or when possible in Onpaint after a paint event. When adding areas to the updatelist, the new area is checked against the areas already there, and if there is overlap the two areas will be combined. This in the end means that there will be less areas to redraw. === Automatic updating === The third way of requesting an area to update, sets a <> it's pending flag and at the same time informs the <> that an object is pending for update. Many a2dCanvasObjects may be set pending at once. As soon as the program is Idle the Onidle member of the <>'s gets called. Here, via the <> of <>, the <> is checked for the pending <>'s flag. If the document has pending objects, the real updating will take place. The <> is traversed, searching for pending objects, and the previous and the current boundingbox of the object are added to each <> updatelist at all positions the object is placed (references included). All paths leading to the object will result in two rectangles being added to the updatelist of the <>'s. Since object area's can depend on the <> itself, in case of pixel extended objects, and also the object shown one each drawer may differ, the above is done for each <> seperately. When all <> updatelist's do contain the areas to update, those areas will be redrawn. Several areas may need an update, which means traversing the <> several times, in order to rerender each rectangular area. Therefore it is important to minimize the number of areas to update. Updating an object is inclusive references higher or lower in the datatree. Updating is initiated from <>. <> sents an update event as explained in Double buffer and updating. <> update areas (defined in pixels) can only be specified for a certain <> and only as seen from the current shown showobject in that view. This is because the mapping of the view/drawer and the <> shown on each <> can be different. The area occupied in pixels in a certain <> can be different for the same object displayed on another <>. <>::AddPending reports areas to be updated in world or device coordinates to the updatelist, the list itself is always in device/pixel coordinates. In case of world coordinates, it takes into account the <> its mapping to calculate the update area in device coordinates. The absolute position of the changed object its boundingbox as seen from top object shown on that <> is added to the update list. A <> can have more then one parent, if it is referenced more then once. Therefore the same relative object is displayed at several absolute locations. If such an object changes, several areas on the top level may need an update, since the same object is placed at several locations. Often the update areas are based on the relative boundingbox of objects. If an object has the pending flag set, the old boundingbox of the object, which was the area occupied before the change to the object was made, is added first. This is done for all pending objects in the whole document as seen from the seperate <>'s. The result is that all the absolute boundingboxes of all references to the object are added to the updatelist. After that the new boundingboxes are calculated for all pending objects, those new object areas are also added to the update list by traversing the <> once more. In the end all pending flag inside objects are reset. The complete render cycle, according to the following list of events: * Change several objects * set pending flags in changed objects and in the document * In Idle time or in Onpaint , the document pending flag triggers updating for all views. * The <> starts traversing the document via each <>. Traversing in each <>, starts at ShowObject. * While traversing, the accumulated matrix is used to calculate absolute boundingbox from the relative boundingbox of pending objects. This OLD boundingbox is added to the updatelist of the current <>. * The <> starts traversing the document to recalculate the relative boundingboxes of pending objects. * The <> starts traversing the document via each <>. Traversing in each <> starts at ShowObject. While traversing, the accumulated matrix is used to calculate absolute boundingbox from the relative boundingbox of pending objects. This time based on the NEW boundingbox that was calculated in the previous step. This boundingbox is added to the updatelist of the current <>. * document resets all pending object flag in the document itself and pending objects. * In idle time or Onpaint EACH <> sets itself as active drawer for the <> it belongs to. The <> renders each area in its update list, relative from its showobject within the <> it needs to display. <> its <> uses a wxMemoryDc to draw into a bitmap buffer. Only objects overlapping or within a specific area are re-rendered. Overlapping areas are clipped to the area. * a nested object renders itself and uses the <> its <> to do this. And therefore uses only basic drawing functionality offered by the base class <>. * The areas in the updatelist of each <> are blitted from the buffer to the device ( e.g. a <> window ). All areas are deleted from the update list. {{attachment:drawupdate.gif|width=753 height=1146}} === Updating All drawer or one === The area to update is always calculated for the current ShowObject in a certain <>. One object can be shown on several <> objects, but on a separate child level and also other references may exist in the same document. Therefore it is always necessary to update all areas occupied on all the <>/<> objects. Still it is up to the programmer to decide when to do it, taking into account speed etc. To give an example: when dragging an object using the mouse on a certain canvas, you may decide to only show the effect on the other non active canvas's when the dragging is finished. The programmer will freeze the automatic update mechanism until the dragging is finished. During the dragging action no <> will be updated as a result of pending objects. As soon as the drag tool releases the freeze setting, all changed objects will be updated. Still the programmer is responsible for adding the old boundingboxes to the updatelist's, before the drag changed the object. In special cases the updating of references is delayed. === Combining update areas === As soon as the application becomes Idle, it will start Redrawing all areas specified in the updatelist's of the <>'s. Several pending updates can be added before real redrawing/updating takes place. Changing or adding many <>'s in a row, which all had the pending flag set, will only result in one redraw action as soon as the application becomes idle. Also this redraw actions will be combined in as little redraw areas as possible, by combining redraw areas into one. Adding areas to the Updatelist of a <> is optimized, overlapping area's etc. are combined using filled tile rectangles. It is important to reduce the number of update rectangles, since each rectangle means render that area. Rendering means traversing the document, if areas do overlap the object in the overlapping part would be drawn twice. So i that case it is better to combine them. But combining two areas may also result in more things to be redrawn then is strictly needed. Think of L shaped structures. A technique to improve updating a bit more is called "micro tiling". This work as follows. The total area to draw on a <> is divided in small tiles. An object to be updated has, or generates a list of rectangles to be updated. Those rectangles overlap certain tiles and only those tiles will be flagged for update. In the end rendering the tiles needing an update will always be limited to the number of total tiles available. On top of this, it is possible to sub divide tiles. For instance in a tile is defined by a 4 byte long. This long contains the 8 bit integers to address the maximum and minimum x and y of a bounding box within the tile. The bounding box inside the tile is extended when an object overlaps that tile. And of course in such a manner that only the overlapping/intersecting part is reflected in the small bounding box of the tile. Again in the end updating would be limited to the maximum of tyles, but now the tiles to update will not always need to be totally redrawn. Only the part defined by the small bounding box inside the tile is really updated. The difficult part is calculating which and how tiles do overlap a <> which needs an update. For polygon and other filled shapes this means scanning with a certain grid. For polylines and other non filled shapes the trick is to divide the outline into segments. The segments are checked for overlap with tiles, taking into account thickness. Currently <> only reports the rectangular redraw area before and after it was changed. When a document has reported all changed rectangular areas, to its views, the views will be repainted. It takes the array of filled tiles, and first starts to combine as much connected tiles which need to be (partly) redrawn into bigger rectangles. The end result is a list of rectangles, which represent all the areas which must be redrawn. TODO Drawing of tile approach with a polygon divided over tiles in a <>. === Clipping to redraw areas === The clipping of <> to the rectangle to update/redraw, is another optimization. At this moment the API of wxWidgets is used to this, but in some cases it is better to do a pre-clip, in order to limit the number of things to transform and re-draw. Think of a polyline that has only one segment overlapping the update rectangle, and 1000 segments outside it. Clearly it is better to first reject the 1000 and only draw the one that overlaps. TODO Drawing of huge polyline, with only very small part displayed on <>.