diff options
| -rw-r--r-- | dmagick/DrawingContext.d | 284 |
1 files changed, 279 insertions, 5 deletions
diff --git a/dmagick/DrawingContext.d b/dmagick/DrawingContext.d index 60c32d4..a409b3b 100644 --- a/dmagick/DrawingContext.d +++ b/dmagick/DrawingContext.d @@ -56,6 +56,15 @@ class DrawingContext } /** + * Specify if the text and stroke should be antialiased. + */ + void antialias(bool antialias) + { + strokeAntialias = antialias; + textAntialias = antialias; + } + + /** * Draws an arc within a rectangle. */ void arc(size_t startX, size_t startY, size_t endX, size_t endY, double startDegrees, double endDegrees) @@ -149,6 +158,9 @@ class DrawingContext */ void clipUnits(ClipPathUnits units) { + if ( units == ClipPathUnits.UndefinedPathUnits ) + throw new DrawException("Undefined Path Unit"); + operations ~= format( " clip-units %s", toLower(to!(string)(units)) ); } @@ -320,6 +332,30 @@ class DrawingContext operations ~= format(" fill %s", fillColor); } + ///ditto + alias fill fillColor; + + /** + * Pattern to use when filling drawn objects. + */ + void fill(size_t x, size_t y, size_t width, size_t height, void delegate(DrawingContext path) pattern) + { + operations ~= format(" fill url(#%s)", definePattern(x, y, width, height, pattern)); + } + + ///ditto + alias fill fillPattern; + + /** + * The gradient to use when filling drawn objects. + */ + void fill(Gradient gradient) + { + operations ~= gradient.defineGradient(); + + operations ~= format(" fill url(#%s)", gradient.id()); + } + /** * Specify the fill opacity. * @@ -670,6 +706,30 @@ class DrawingContext operations ~= format(" stroke %s", strokeColor); } + ///ditto + alias stroke strokeColor; + + /** + * Pattern to use when filling drawn objects. + */ + void stroke(size_t x, size_t y, size_t width, size_t height, void delegate(DrawingContext path) pattern) + { + operations ~= format(" stroke url(#%s)", definePattern(x, y, width, height, pattern)); + } + + ///ditto + alias stroke strokePattern; + + /** + * The gradient to use when filling drawn objects. + */ + void stroke(Gradient gradient) + { + operations ~= gradient.defineGradient(); + + operations ~= format(" stroke url(#%s)", gradient.id()); + } + /** * Specify if the stroke should be antialiased. */ @@ -821,6 +881,9 @@ class DrawingContext operations ~= format(" text-undercolor %s", color); } + ///ditto + alias textUnderColor boxColor; + /** * Specify a translation operation on the coordinate space. */ @@ -829,12 +892,23 @@ class DrawingContext operations ~= format(" translate %s,%s", x, y); } -//For gradients: -//gradient-units -//stop-color + /** + * Generate to operations for the profide pattern. + */ + private string definePattern(size_t x, size_t y, size_t width, size_t height, void delegate(DrawingContext path) pattern) + { + static size_t count; + count++; -//Does this do anything? -//offset + DrawingContext patt = new DrawingContext(); + pattern(patt); + + operations ~= format(" push defs push pattern patt%s %s,%s %s,%s push graphic-context", count, x, y, width, height); + operations ~= patt.operations; + operations ~= " pop graphic-context pop pattern pop defs"; + + return format("patt%s", count); + } /** * Escape the text so it can be added to the operations string. @@ -927,6 +1001,168 @@ class DrawingContext } /** + * + */ +struct Gradient +{ + private static size_t count; + private size_t currentCount; + + //Is the id to use this gradient already set. + private bool isDefined = false; + + GradientType type; + GradientUnits units; + double x1, y1, x2, y2, radius; + StopColor[] stopColors; + + /** + * Define a linear gradient. + * + * x1, y1, x2 and y2 define a gradient vector for the linear gradient. + * This gradient vector provides starting and ending points onto which + * the gradient stops are mapped. The values of x1, y1, x2 and y2 can + * be either numbers or percentages. + */ + static Gradient linear(double x1, double y1, double x2, double y2) + { + Gradient gradient; + + gradient.type = GradientType.LinearGradient; + + gradient.currentCount = count++; + gradient.x1 = x1; + gradient.y1 = y1; + gradient.x2 = x2; + gradient.y2 = y2; + + return gradient; + } + + /** + * Define a radial gradient. + * + * cx, cy and r define the largest (i.e., outermost) circle for the + * radial gradient. The gradient will be drawn such that the 100% + * gradient stop is mapped to the perimeter of this largest + * (i.e., outermost) circle. + * + * Params: + * xCenter = x coordinate for the center of the circle. + * yCenter = y coordinate for the center of the circle. + * xFocal = x coordinate the focal point for the radial gradient. + * The gradient will be drawn such that the 0% gradient + * stop is mapped to (xFocal, yFocal). + * yFocal = y coordinate the focal point + * radius = The radius of the gradient. A value of zero will cause + * the area to be painted as a single color using the + * color and opacity of the last gradient stop. + */ + static Gradient radial(double xCenter, double yCenter, double xFocal, double yFocal, double radius) + { + Gradient gradient; + + gradient.type = GradientType.RadialGradient; + + gradient.currentCount = count++; + gradient.x1 = xCenter; + gradient.y1 = yCenter; + gradient.x2 = xFocal; + gradient.y2 = yFocal; + gradient.radius = radius; + + return gradient; + } + + /** + * Define a radial gradient. + * + * The same as above but with the focal point at + * the center of the circle. + */ + static Gradient radial(double xCenter, double yCenter, double radius) + { + return radial(xCenter, yCenter, xCenter, yCenter, radius); + } + + /** + * Defines the coordinate system to use. + */ + Gradient gradientUnits(GradientUnits units) + { + this.units = units; + + return this; + } + + /** + * Define the color to use, and there offsets in the gradient. + * + * Params: + * color = The color to use at this stop. + * offset = For linear gradients, the offset attribute represents + * a location along the gradient vector. For radial + * gradients, it represents a percentage distance + * from (fx,fy) to the edge of the outermost/largest circle. + * offset should bwe between 0 and 1. + */ + Gradient stopColor(Color color, double offset) + { + stopColors ~= StopColor(color, offset); + + return this; + } + + /** + * Generate the string used to define this gradient. + */ + private string defineGradient() + { + if ( isDefined ) + return ""; + + string operations = " push defs"; + + if ( type == GradientType.LinearGradient ) + { + operations ~= format(" push gradient grad%s linear %s,%s %s,%s", + currentCount, x1, y1, x2, y2); + } + else + { + operations ~= format(" push gradient grad%s radial %s,%s %s,%s $s", + currentCount, x1, y1, x2, y2, radius); + } + + if ( units != GradientUnits.Undefined ) + operations ~= format(" gradient-units %s", units); + + foreach ( stop; stopColors ) + { + operations ~= format(" stop-color %s %s", stop.color, stop.offset); + } + + operations ~= " pop gradient pop defs"; + + return operations; + } + + /** + * If the gradient is defined, this id is neded to use it. + */ + private string id() + { + return format("grad%s", currentCount); + } + + private struct StopColor + { + Color color; + double offset; + } +} + +/** * This enumeration lists specific character repertories (i.e., charsets), * and not text encoding methods (e.g., UTF-8, UTF-16, etc.). */ @@ -960,3 +1196,41 @@ enum FontWeight : string Bolder = "bolder", /// Increases weight by 100. Lighter = "lighter", /// Decreases weight by 100. } + +/** + * Defines the coordinate system to use for Gradients. + */ +enum GradientUnits : string +{ + /** + * No coordinate systewm defined. + */ + Undefined = "", + + /** + * The values supplied to Gradient represent values in the coordinate + * system that results from taking the current user coordinate system + * in place at the time when the gradient element is referenced. + */ + UserSpace = "userSpace", + + /** + * The user coordinate system for the values supplied to Gradient is + * established using the bounding box of the element to which the + * gradient is applied. + */ + UserSpaceOnUse = "userSpaceOnUse", + + /** + * The normal of the linear gradient is perpendicular to the gradient + * vector in object bounding box space. When the object's bounding box + * is not square, the gradient normal which is initially perpendicular + * to the gradient vector within object bounding box space may render + * non-perpendicular relative to the gradient vector in user space. + * If the gradient vector is parallel to one of the axes of the bounding + * box, the gradient normal will remain perpendicular. + * This transformation is due to application of the non-uniform scaling + * transformation from bounding box space to user space. + */ + ObjectBoundingBox = "objectBoundingBox", +} |
