Magick::Drawable

Drawable provides a convenient interface for preparing vector, image, or text arguments for the Image::draw() method. Each instance of a Drawable sub-class represents a single drawable object. Drawable objects may be drawn "one-by-one" via multiple invocations of the Image draw() method, or may be drawn "all-at-once" by passing a list of Drawable objects to the Image draw() method. The one-by-one approach is convenient for simple drawings, while the list-based approach is appropriate for drawings which require more sophistication.

The following is an example using the Drawable subclasses with a one-by-one approach to draw the following figure:

#include <string> #include <iostream> #include <Magick++.h> using namespace std; using namespace Magick; int main(int /*argc*/,char **argv) { try { InitializeMagick(*argv); // Create base image (white image of 300 by 200 pixels) Image image( Geometry(300,200), Color("white") ); // Set draw options image.strokeColor("red"); // Outline color image.fillColor("green"); // Fill color image.strokeWidth(5); // Draw a circle image.draw( DrawableCircle(100,100, 50,100) ); // Draw a rectangle image.draw( DrawableRectangle(200,200, 270,170) ); // Display the result image.display( ); } catch( exception & error_ ) { cout << "Caught exception: " << error_.what() << endl; return 1; } return 0; }

Since Drawable is an object it may be saved in an array or a list for later (perhaps repeated) use. The following example shows how to draw the same figure using the list-based approach:

#include <string> #include <iostream> #include <list> #include <Magick++.h> using namespace std; using namespace Magick; int main(int /*argc*/,char **/*argv*/) { try { InitializeMagick(*argv); // Create base image (white image of 300 by 200 pixels) Image image( Geometry(300,200), Color("white") ); // Construct drawing list std::list<Magick::Drawable> drawList; // Add some drawing options to drawing list drawList.push_back(DrawableStrokeColor("red")); // Outline color drawList.push_back(DrawableStrokeWidth(5)); // Stroke width drawList.push_back(DrawableFillColor("green")); // Fill color // Add a Circle to drawing list drawList.push_back(DrawableCircle(100,100, 50,100)); // Add a Rectangle to drawing list drawList.push_back(DrawableRectangle(200,100, 270,170)); // Draw everything using completed drawing list image.draw(drawList); // Display the result image.display( ); } catch( exception & error_ ) { cout << "Caught exception: " << error_.what() << endl; return 1; } return 0; }

Drawable depends on the simple Coordinate structure which represents a pair of x,y coodinates. The methods provided by the Coordinate structure are shown in the following table:

Coordinate Structure Methods

The Drawable classes are shown in the following table. Only constructor signatures are documented here. Each Drawable class also provides methods by which each individual parameter may be adjusted.

Drawable Classes

Vector Path Classes

The vector paths supported by Magick++ are based on those supported by the SVG XML specification. Vector paths are not directly drawable, they must first be supplied as a constructor argument to the DrawablePath class in order to create a drawable object. The DrawablePath class effectively creates a drawable compound component which may be replayed as desired. If the drawable compound component consists only of vector path objects using relative coordinates then the object may be positioned on the image by preceding it with a DrawablePath which sets the current drawing coordinate. Alternatively coordinate transforms may be used to translate the origin in order to position the object, rotate it, skew it, or scale it.

The "moveto" commands

The "moveto" commands establish a new current point. The effect is as if the "pen" were lifted and moved to a new location. A path data segment must begin with either one of the "moveto" commands or one of the "arc" commands. Subsequent "moveto" commands (i.e., when the "moveto" is not the first command) represent the start of a new subpath:

Moveto Classes

The "closepath" command

The "closepath" command causes an automatic straight line to be drawn from the current point to the initial point of the current subpath:

Closepath Classes

The "lineto" commands

The various "lineto" commands draw straight lines from the current point to a new point:

Lineto Classes

The curve commands

These three groups of commands draw curves:

The cubic Bézier curve commands

The cubic Bézier commands depend on the PathCurvetoArgs argument class, which has the constructor signature

  PathCurvetoArgs( double x1_, double y1_, 
                   double x2_, double y2_, 
                   double x_, double y_ );

The commands are as follows:

Cubic Bézier Curve Classes

The quadratic Bézier curve commands

The quadratic Bézier commands depend on the PathQuadraticCurvetoArgs argument class, which has the constructor signature:

  PathQuadraticCurvetoArgs( double x1_, double y1_, 
                            double x_, double y_ );

The quadratic Bézier commands are as follows:

Quadratic Bézier Curve Classes

The elliptical arc curve commands

The elliptical arc curve commands depend on the PathArcArgs argument class, which has the constructor signature:

   PathArcArgs( double radiusX_, double radiusY_, 
                double xAxisRotation_, bool largeArcFlag_, 
                bool sweepFlag_, double x_, double y_ );

The elliptical arc commands are as follows:

Elliptical Arc Curve Classes