Size: 4971
Comment:
|
← Revision 3 as of 2016-05-12 14:21:01 ⇥
Size: 5079
Comment:
|
Deletions are marked like this. | Additions are marked like this. |
Line 10: | Line 10: |
the native API for drawing, but be implemented in a way that catered for different drawing methods. So now it is a matter of implementing another derived drawing context in |
the native API for drawing. It is implemented in a way that implementing different drawing methods is easy. So now it is a matter of implementing another derived drawing context in |
Line 14: | Line 14: |
The relative here means that an affine transform can be set to the drawing | Relative here means that an affine transform can be set to the drawing |
Line 17: | Line 17: |
The style properties of primitives are pointer based, reference | The style properties of primitives are smart pointer based, reference |
Line 24: | Line 24: |
After a while I decided to build the <<Dox(a2dCanvas)>> and other classes on top | After a while I wanted to use the <<Dox(a2dCanvas)>> as part |
Line 26: | Line 26: |
the existing wxWidgets DocView classes. After a lot of developmet and experimentation the new revolutionary wxArt2D document/view/commandprocessor framework came to life. |
the existing wxWidgets DocView classes. After a lot of developent and experimentation the a new wxArt2D document/view/commandprocessor framework came to life. |
Line 33: | Line 33: |
data and consists of a display list of graphical primitives. Each Graphical | data and consists of a list of graphical primitives stored in one or more <<Dox(a2dDrawing)>>. Each Graphical |
Line 35: | Line 35: |
objects and properties. A document contains one root <<Dox(a2dCanvasObject)>>, and | objects and properties. A document contains one <<Dox(a2dDrawing)>>, and |
Line 37: | Line 37: |
children to this root object. Each <<Dox(a2dCanvasObject)>> has a transform matrix to | children to this root drawing. Each <<Dox(a2dCanvasObject)>> has a transform matrix to |
Line 42: | Line 42: |
The drawing context, which is a derived view, and the document, interact in such a manner that changed objects are redrawn automatically and efficiently. The key is bounding boxes which are maintained throughout the drawing hierarchy. |
The drawing context, is used to draw what is in a <<Dox(a2dDrawing)>>. Which part of the drawing will be visible in a canvas window, is defined in <<Dox(a2dDrawingPart)>>. Changed objects in the drawing are redrawn automatically and efficiently. The bounding boxes which are maintained throughout the drawing hierarchy, and used to optimize redraws. |
Line 50: | Line 51: |
Another required need was in being able to draw the same sub drawing in several places | Another requirement was to be able to draw the same sub drawing in several places, |
Line 52: | Line 53: |
to <<Dox(a2dCanvasObject)>>. In this way it is possible to add the same <<Dox(a2dCanvasObject)>> | to <<Dox(a2dCanvasObject)>>. Therefore it is possible to add the same <<Dox(a2dCanvasObject)>> |
Line 60: | Line 61: |
All style properties like colour for filling and stroking are implemented | All style properties like color for filling and stroking are implemented |
Line 73: | Line 74: |
Every <<Dox(a2dCanvas)>> which displays part of a document, can have tools plugged into it. The events are redirected from the canvas to the tools. There are a broad |
Every <<Dox(a2dCanvas)>> which displays part of a drawing, can have tools plugged into it. The events are redirected from the canvas to the tools. There is a broad |
Line 76: | Line 77: |
They are stacked based, making it possible to pan and zoom whilst busy drawing. | They are stack based, making it possible to pan and zoom while busy drawing. |
About wxArt2D
History and design
There was a great need for a canvas in the wxWidgets Library. Robert Roebling started something called wxCanvas and soon I took over. The original wxCanvas was pixel based and the idea was to render the primitives directly into an RGB buffer. However I realized that this path would be difficult to follow.
Abstract Drawing Context for vector drawings
I therefore decided to create an abstract Drawing Context that uses the native API for drawing. It is implemented in a way that implementing different drawing methods is easy. So now it is a matter of implementing another derived drawing context in order to draw to a different device, window or pixel buffer. The drawing context is specifically designed for drawing vectors in relative world coordinates. Relative here means that an affine transform can be set to the drawing context. Everything drawn will be transformed with that matrix first. To achieve speed, this is combined with the world to device coordinates transformation. The style properties of primitives are smart pointer based, reference counted and derived from abstract classes. This makes it easy to add new style types. More importantly style changes can be quickly compared, and updated if a change in style is required.
Multi Document Multi View
After a while I wanted to use the a2dCanvas as part of the wxWidgets DocView classes, but soon realized, I would not be able to do that with the existing wxWidgets DocView classes. After a lot of developent and experimentation the a new wxArt2D document/view/commandprocessor framework came to life. This change made it possible to add views like a2dCanvasView to a library, and let the user application display a desired View to a Window. Moreover, an extensive range of events are distributed, which help the application in having them handled within the framework. The main idea of the DocView framework, is that the drawing primitives are stored in a document and that several views can be created to view desired parts of the document. The a2dCanvasDocument is a document containing the graphical data and consists of a list of graphical primitives stored in one or more a2dDrawing. Each Graphical object is derived from a a2dCanvasObject class, and this class can have child objects and properties. A document contains one a2dDrawing, and the rest of the document's graphical content is included by adding nested children to this root drawing. Each a2dCanvasObject has a transform matrix to place itself in the world coordinate system relative to its parent object, with each child object placed relative to the object itself.
Updating
The drawing context, is used to draw what is in a a2dDrawing. Which part of the drawing will be visible in a canvas window, is defined in a2dDrawingPart. Changed objects in the drawing are redrawn automatically and efficiently. The bounding boxes which are maintained throughout the drawing hierarchy, and used to optimize redraws. Only objects overlapping the drawing boxes of the changed objects will be redrawn.
References
Another requirement was to be able to draw the same sub drawing in several places, without having to duplicate the drawing, this is achieved by reference counting pointers to a2dCanvasObject. Therefore it is possible to add the same a2dCanvasObject ( and its children) to two parent objects. During the rendering, paths from both parents will be followed and this will result in the same object being drawn at two positions.
Properties
The same reference counting system is used for properties to a2dCanvasObjects. All style properties like color for filling and stroking are implemented as dynamic properties, and objects that have no properties will not use memory space for them.
Layers
From the beginning, I wanted to be able to place objects on layers, and have the layers drawn in a set order. In this way the layer order defines how objects are stacked. All objects on a layer (and nested objects if desired) are drawn in a row, followed by the next layer etc.
Tools
Every a2dCanvas which displays part of a drawing, can have tools plugged into it. The events are redirected from the canvas to the tools. There is a broad range of tools to interactively draw primitives and change views. They are stack based, making it possible to pan and zoom while busy drawing.
Editing
Object can have editing implemented, all editing data needed is implemented using dynamic properties, and therefore only uses memory space when the object is being edited. Because of the stack based nature of the tools, editing tools can also recursively edit children of a2dCanvasObject. This makes it possible to implement editing of complex object like curves in a plot.