1 /**
2  * This module contains wrappers for most of cairo's fuctionality.
3  * Additional wrappers for subsets of cairo are available in the
4  * cairo.* modules.
5  *
6  * Note:
7  * Most cairoD functions could throw an OutOfMemoryError. This is therefore not
8  * explicitly stated in the functions' api documenation.
9  *
10  * See_Also:
11  * $(LINK http://cairographics.org/documentation/)
12  *
13  * License:
14  * $(TABLE
15  *   $(TR $(TD cairoD wrapper/bindings)
16  *     $(TD $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)))
17  *   $(TR $(TD $(LINK2 http://cgit.freedesktop.org/cairo/tree/COPYING, _cairo))
18  *     $(TD $(LINK2 http://cgit.freedesktop.org/cairo/tree/COPYING-LGPL-2.1, LGPL 2.1) /
19  *     $(LINK2 http://cgit.freedesktop.org/cairo/plain/COPYING-MPL-1.1, MPL 1.1)))
20  * )
21  * Authors:
22  * $(TABLE
23  *   $(TR $(TD Johannes Pfau) $(TD cairoD))
24  *   $(TR $(TD Andrej Mitrovic) $(TD cairoD))
25  *   $(TR $(TD $(LINK2 http://cairographics.org, _cairo team)) $(TD _cairo))
26  * )
27  */
28 /*
29  * Distributed under the Boost Software License, Version 1.0.
30  *    (See accompanying file LICENSE_1_0.txt or copy at
31  *          http://www.boost.org/LICENSE_1_0.txt)
32  */
33 module cairo.cairo;
34 
35 import cairo.c.cairo;
36 import cairo.util;
37 
38 import core.exception;
39 import std.algorithm;
40 import std.conv;
41 import std.format : formattedWrite;
42 import std.string;
43 import std.traits;
44 import std.typecons;
45 
46 debug(RefCounted)
47 {
48     import std.stdio;
49 }
50 
51 /**
52  * Mainly used internally by cairoD.
53  * If status is CAIRO_STATUS_NO_MEMORY a OutOfMemoryError is thrown.
54  * If status is  CAIRO_STATUS_SUCCESS nothing happens.
55  * For all other statuses, this functions throws
56  * a $(D CairoException) with the status value.
57  */
58 void throwError(cairo_status_t status, string file = __FILE__, int line = __LINE__)
59 {
60     switch(status)
61     {
62         case cairo_status_t.CAIRO_STATUS_SUCCESS:
63             return;
64         case cairo_status_t.CAIRO_STATUS_NO_MEMORY:
65             throw new OutOfMemoryError(file, line);
66         default:
67             throw new CairoException(status, file, line);
68     }
69 }
70 
71 /**
72  * Convert a size_t as given from a D arrays .length property
73  * to a cairo count type (int).
74  *
75  * In debug mode an exception is thrown if the size_t value does
76  * not fit into the int type. In release mode all checks are
77  * removed!
78  */
79 private int toCairoCount(size_t length)
80 {
81     debug
82     {
83         import std.conv;
84         return to!int(length);
85     }
86     else
87     {
88         return cast(int)length;
89     }
90 }
91 
92 unittest
93 {
94     assert(toCairoCount(int.max) == int.max);
95     assert(toCairoCount(0) == 0);
96     assert(toCairoCount(42) == 42);
97     debug
98     {
99         import std.exception;
100         assertThrown(toCairoCount(int.max + 1));
101     }
102 }
103 
104 /**
105  * Exception thrown by cairoD if an error occurs.
106  */
107 public class CairoException : Exception
108 {
109     public:
110         /**
111          * Cairo's error status.
112          * Gives further information about the error.
113          */
114         cairo_status_t status;
115 
116         ///
117         this(cairo_status_t stat, string file = __FILE__, int line = __LINE__)
118         {
119             this.status = stat;
120             super(format("%s: %s", this.status,  to!string(cairo_status_to_string(this.status))));
121         }
122 }
123 
124 /**
125  * Aliases for simple cairo enums and structs.
126  * Theses aliases provide D-like names when
127  * using the cairoD API.
128  */
129 public alias cairo_content_t Content;
130 public alias cairo_antialias_t AntiAlias; ///ditto
131 public alias cairo_subpixel_order_t SubpixelOrder; ///ditto
132 public alias cairo_hint_style_t HintStyle; ///ditto
133 public alias cairo_hint_metrics_t HintMetrics; ///ditto
134 public alias cairo_surface_type_t SurfaceType; ///ditto
135 public alias cairo_format_t Format; ///ditto
136 public alias cairo_extend_t Extend; ///ditto
137 public alias cairo_filter_t Filter; ///ditto
138 public alias cairo_pattern_type_t PatternType; ///ditto
139 public alias cairo_fill_rule_t FillRule; ///ditto
140 public alias cairo_line_cap_t LineCap; ///ditto
141 public alias cairo_line_join_t LineJoin; ///ditto
142 public alias cairo_operator_t Operator; ///ditto
143 public alias cairo_path_data_type_t PathElementType; ///ditto
144 public alias cairo_font_extents_t FontExtents; ///ditto
145 public alias cairo_text_extents_t TextExtents; ///ditto
146 public alias cairo_glyph_t Glyph; ///ditto
147 public alias cairo_text_cluster_t TextCluster; ///ditto
148 public alias cairo_text_cluster_flags_t TextClusterFlags; ///ditto
149 public alias cairo_font_slant_t FontSlant; ///ditto
150 public alias cairo_font_weight_t FontWeight; ///ditto
151 public alias cairo_device_type_t DeviceType; ///ditto
152 public alias cairo_font_type_t FontType; ///ditto
153 public alias cairo_region_overlap_t RegionOverlap; ///ditto
154 
155 /**
156  * A simple struct to store the coordinates of a point as
157  * doubles or integers.
158  */
159 public struct Point(T) if(isOneOf!(T, int, double))
160 {
161     ///
162     public this(T x, T y)
163     {
164         this.x = x;
165         this.y = y;
166     }
167 
168     ///
169     T x;
170     ///
171     T y;
172 }
173 
174 ///
175 unittest
176 {
177     auto p = Point!double(10, 10);  //Type Point!double
178     auto p2 = point(10.0, 10.0);    //Type Point!double
179     auto p3 = Point!int(10, 10);    //Type Point!int
180     auto p4 = point(10, 10);        //Type Point!int
181     assert(p == p2);
182     assert(p3 == p4);
183 }
184 
185 /**
186  * Convenience function to create a $(D Point!int) or $(D Point!double).
187  */
188 auto point(T)(T x, T y) if(is(T == int) || is(T == double))
189 {
190     return Point!T(x,y);
191 }
192 
193 /**
194  * A simple struct representing a rectangle with $(D int) or $(D double) values
195  */
196 public struct Rectangle(T) if(isOneOf!(T, int, double))
197 {
198     ///
199     public this(Point!T point, T width, T height)
200     {
201         this.point = point;
202         this.width = width;
203         this.height = height;
204     }
205 
206     ///ditto
207     public this(T x, T y, T width, T height)
208     {
209         this.point.x = x;
210         this.point.y = y;
211         this.width = width;
212         this.height = height;
213     }
214 
215     ///TOP-LEFT point of the rectangle
216     Point!T point;
217     ///
218     T width;
219     ///
220     T height;
221 }
222 
223 /**
224  * Convenience function to create a $(D Rectangle!int) or $(D Rectangle!double).
225  */
226 auto rectangle(T)(T x, T y, T width, T height) if(isOneOf!(T, int, double))
227 {
228     return Rectangle!(T)(x, y, width, height);
229 }
230 
231 ///ditto
232 auto rectangle(T)(Point!T point, T width, T height) if(isOneOf!(T, int, double))
233 {
234     return Rectangle!(T)(point, width, height);
235 }
236 
237 ///
238 unittest
239 {
240     auto a = rectangle(1, 1, 4, 4);
241     Rectangle!int rectInt = a;
242     auto b = rectangle(0.99, 0.99, 3.99, 3.99);
243     Rectangle!double rectDouble = b;
244 }
245 
246 /**
247  * A simple struct representing a size with only $(D int) or $(D double) values
248  */
249 public struct Size(T) if(is(T == int) || is(T == double))
250 {
251     ///
252     public this(T width, T height)
253     {
254         this.width = width;
255         this.height = height;
256     }
257 
258     ///
259     T width, height;
260 }
261 
262 ///
263 unittest
264 {
265     auto a = Size!int(10, 10);
266     auto a2 = size(10, 10);
267     auto b = Size!double(5, 5);
268     auto b2 = size(5.0, 5.0);
269     assert(a == a2);
270     assert(b == b2);
271 }
272 
273 /**
274  * Convenience function to create a $(D Size!int) or $(D Size!double).
275  */
276 auto size(T)(T width, T height) if(isOneOf!(T, int, double))
277 {
278     return Size!(T)(width, height);
279 }
280 
281 /**
282  * A simple struct representing a box.
283  * Used for Extents.
284  */
285 public struct Box
286 {
287     ///
288     public this(Point!double point1, Point!double point2)
289     {
290         this.point1 = point1;
291         this.point2 = point2;
292     }
293     ///
294     public this(double x1, double y1, double x2, double y2)
295     {
296         this.point1.x = x1;
297         this.point1.y = y1;
298         this.point2.x = x2;
299         this.point2.y = y2;
300     }
301     ///Top-left point
302     Point!double point1;
303     ///Bottom-right point
304     Point!double point2;
305 }
306 
307 /**
308  * A simple struct representing a resolution
309  */
310 public struct Resolution
311 {
312     ///
313     public this(double resX, double resY)
314     {
315         this.x = resX;
316         this.y = resY;
317     }
318 
319     ///In pixels per inch
320     double x, y;
321 }
322 
323 /**
324  * Struct representing a RGBA color
325  */
326 public struct RGBA
327 {
328     ///
329     public this(double red, double green, double blue, double alpha)
330     {
331         this.red = red;
332         this.green = green;
333         this.blue = blue;
334         this.alpha = alpha;
335     }
336     ///
337     public double red, green, blue, alpha;
338 
339     ///convert RGBA struct to RGB struct. Alpha is discarded
340     public RGB opCast(RGB)()
341     {
342         return RGB(red, green, blue);
343     }
344 }
345 
346 /**
347  * Struct representing a RGB color
348  */
349 public struct RGB
350 {
351     ///
352     public this(double red, double green, double blue)
353     {
354         this.red = red;
355         this.green = green;
356         this.blue = blue;
357     }
358     ///
359     public double red, green, blue;
360 
361     ///convert RGBA struct to RGB struct. Alpha is set to '1.0'
362     public RGBA opCast(RGBA)()
363     {
364         return RGBA(red, green, blue, 1.0);
365     }
366 }
367 
368 unittest
369 {
370     auto rgb1 = RGB(0.1, 0.2, 0.3);
371     auto rgba1 = cast(RGBA)rgb1;
372     assert(rgba1.red == rgb1.red);
373     assert(rgba1.green == rgb1.green);
374     assert(rgba1.blue == rgb1.blue);
375     assert(rgba1.alpha == 1.0);
376 
377     auto rgba2 = RGBA(0.3, 0.2, 0.1, 0.5);
378     auto rgb2 = cast(RGB)rgba2;
379     assert(rgba2.red == rgb2.red);
380     assert(rgba2.green == rgb2.green);
381     assert(rgba2.blue == rgb2.blue);
382 }
383 
384 /* From cairo binding documentation:
385  * You should not present an API for mutating or for creating new cairo_path_t
386  * objects. In the future, these guidelines may be extended to present an API
387  * for creating a cairo_path_t from scratch for use with cairo_append_path()
388  * but the current expectation is that cairo_append_path() will mostly be
389  * used with paths from cairo_copy_path().*/
390  /**
391   * Reference counted wrapper around $(D cairo_path_t).
392   * This struct can only be obtained from cairoD. It cannot be created
393   * manually.
394   */
395 public struct Path
396 {
397     private:
398         struct Payload
399         {
400             cairo_path_t* _payload;
401             this(cairo_path_t* h)
402             {
403                 _payload = h;
404             }
405             ~this()
406             {
407                 if(_payload)
408                 {
409                     cairo_path_destroy(_payload);
410                     _payload = null;
411                 }
412             }
413 
414             // Should never perform these operations
415             this(this) { assert(false); }
416             void opAssign(Path.Payload rhs) { assert(false); }
417         }
418         alias RefCounted!(Payload, RefCountedAutoInitialize.no) Data;
419         Data _data;
420 
421         @property cairo_status_t status()
422         {
423             return nativePointer.status;
424         }
425 
426         @property cairo_path_data_t* data()
427         {
428             return nativePointer.data;
429         }
430 
431         @property int num_data()
432         {
433             return nativePointer.num_data;
434         }
435 
436     public:
437         // @BUG@: Can't pass as range if default ctor is disabled
438         // @disable this();
439 
440         /**
441          * Create a Path from a existing $(D cairo_path_t*).
442          * Path is a reference-counted type. It will call $(D cairo_path_destroy)
443          * when there are no more references to the path.
444          *
445          * This means you should not destroy the $(D cairo_path_t*) manually
446          * and you should not use $(D cairo_path_t*) anymore after you created a Path
447          * with this constructor.
448          *
449          * Warning:
450          * $(RED Only use this if you know what your doing!
451          * This function should not be needed for standard cairoD usage.)
452          */
453         this(cairo_path_t* path)
454         {
455             throwError(path.status);
456             _data = Data(path);
457         }
458 
459         /**
460          * The underlying $(D cairo_path_t*) handle
461          */
462         @property cairo_path_t* nativePointer()
463         {
464             return _data._payload;
465         }
466 
467         version(D_Ddoc)
468         {
469             /**
470              * Enable / disable memory management debugging for this Path
471              * instance. Only available if both cairoD and the cairoD user
472              * code were compiled with "debug=RefCounted"
473              *
474              * Output is written to stdout, see
475              * $(LINK https://github.com/jpf91/cairoD/wiki/Memory-Management#debugging)
476              * for more information
477              */
478             @property bool debugging();
479             ///ditto
480             @property void debugging(bool value);
481         }
482         else debug(RefCounted)
483         {
484             @property bool debugging()
485             {
486                 return _data.RefCounted.debugging;
487             }
488 
489             @property void debugging(bool value)
490             {
491                 _data.RefCounted.debugging = value;
492             }
493         }
494 
495         /**
496          * Get a $(D PathRange) for this path to iterate the paths
497          * elements.
498          */
499         PathRange opSlice()
500         {
501             return PathRange(this);
502         }
503         ///
504         unittest
505         {
506             import std.math, std.stdio, std.array;
507             //Let's create a context first and draw some lines
508             auto surf = new ImageSurface(Format.CAIRO_FORMAT_ARGB32, 100, 100);
509             auto ctx = Context(surf);
510             ctx.moveTo(0.0, 0.0);
511             ctx.lineTo(10.0, 10.0);
512             surf.writeToPNG("test2.png");
513 
514             auto path = ctx.copyPath();
515             foreach(element; path[])
516             {
517                 switch(element.type)
518                 {
519                     case PathElementType.CAIRO_PATH_MOVE_TO:
520                         auto destination = element[0];
521                         writefln("Move to %s:%s", destination.x, destination.y);
522                         break;
523                     default:
524                 }
525             }
526         }
527 
528         unittest
529         {
530             import std.math, std.stdio, std.array;
531             //Let's create a context first and draw some lines
532             auto surf = new ImageSurface(Format.CAIRO_FORMAT_ARGB32, 100, 100);
533             auto ctx = Context(surf);
534             ctx.moveTo(0.0, 0.0);
535             ctx.lineTo(10.0, 10.0);
536             ctx.curveTo(5, 5, 7, 6, 0, 0);
537             ctx.lineTo(10.0, 0.0);
538 
539             auto path = ctx.copyPath();
540             auto pathArray = ctx.copyPath()[].array;
541             assert(pathArray[0].type == PathElementType.CAIRO_PATH_MOVE_TO);
542             assert(pathArray[0][0] == Point!double(0, 0));
543             assert(pathArray[1].type == PathElementType.CAIRO_PATH_LINE_TO);
544             assert(pathArray[1][0] == Point!double(10, 10));
545             assert(pathArray[2].type == PathElementType.CAIRO_PATH_CURVE_TO);
546             assert(pathArray[2][0] == Point!double(5, 5));
547             assert(pathArray[2][1] == Point!double(7, 6));
548             assert(pathArray[2][2] == Point!double(0, 0));
549             assert(pathArray[3].type == PathElementType.CAIRO_PATH_LINE_TO);
550             assert(pathArray[3][0] == Point!double(10, 0));
551         }
552 }
553 
554 /**
555  * ForwardRange to iterate a cairo path.
556  * This range keeps a reference to its $(D Path) object,
557  * so it can be passed around without thinking about memory management.
558  */
559 public struct PathRange
560 {
561     private:
562         Path path;
563         int pos = 0;
564         this(Path path, int pos)
565         {
566             this.path = path;
567             this.pos = pos;
568         }
569 
570     public:
571         /**
572          * Constructor to get a PathRange for a $(D Path) object.
573          * You should usually use $(D Path)'s opSlice method insted, see
574          * the $(D Path) documentation for an example.
575          */
576         this(Path path)
577         {
578             this.path = path;
579         }
580 
581         ///ForwardRange implementation
582         @property PathRange save()
583         {
584             return PathRange(path, pos);
585         }
586 
587         ///ditto
588         @property bool empty()
589         {
590             assert(pos <= path.num_data);
591             return (pos == path.num_data);
592         }
593 
594         ///ditto
595         void popFront()
596         {
597             pos += path.data[pos].header.length;
598             assert(pos <= path.num_data);
599         }
600 
601         ///ditto
602         @property PathElement front()
603         {
604             return PathElement(this, &path.data[pos]);
605         }
606 }
607 
608 unittest
609 {
610     import std.range;
611     static assert(isForwardRange!PathRange);
612 }
613 
614 unittest
615 {
616     import std.array, std.range;
617     //Let's create a context first and draw some lines
618     auto surf = new ImageSurface(Format.CAIRO_FORMAT_ARGB32, 100, 100);
619     auto ctx = Context(surf);
620     ctx.moveTo(0.0, 0.0);
621     ctx.lineTo(10.0, 10.0);
622     ctx.curveTo(5, 5, 7, 6, 0, 0);
623     ctx.lineTo(10.0, 0.0);
624 
625     auto path = ctx.copyPath();
626     auto pathRange = path[];
627     auto pathRange2 = pathRange.save;
628     pathRange.popFront();
629     auto pathRange3 = pathRange.save;
630 
631     auto pathArray1 = pathRange.array;
632     auto pathArray2 = pathRange2.array;
633     auto pathArray3 = pathRange3.array;
634     assert(pathArray2[0].type == PathElementType.CAIRO_PATH_MOVE_TO);
635     assert(pathArray2[0][0] == Point!double(0, 0));
636     assert(pathArray2[1].type == PathElementType.CAIRO_PATH_LINE_TO);
637     assert(pathArray2[1][0] == Point!double(10, 10));
638     assert(pathArray2[2].type == PathElementType.CAIRO_PATH_CURVE_TO);
639     assert(pathArray2[2][0] == Point!double(5, 5));
640     assert(pathArray2[2][1] == Point!double(7, 6));
641     assert(pathArray2[2][2] == Point!double(0, 0));
642     assert(pathArray2[3].type == PathElementType.CAIRO_PATH_LINE_TO);
643     assert(pathArray2[3][0] == Point!double(10, 0));
644 
645     assert(pathArray1 == pathArray3);
646     assert(pathArray2.drop(1) == pathArray1);
647 }
648 
649 /**
650  * An element of a cairo $(D Path) and the objects iterated by a
651  * $(D PathRange).
652  */
653 public struct PathElement
654 {
655     private:
656         cairo_path_data_t* data;
657         PathRange range;
658 
659         this(PathRange range, cairo_path_data_t* data)
660         {
661             this.data = data;
662             this.range = range;
663         }
664     public:
665         ///The type of this element.
666         @property PathElementType type() const
667         {
668             return data.header.type;
669         }
670 
671         /**
672          * Get a point from this element.
673          * Index is zero-based. The number of available points
674          * depends on the elements $(D type):
675          * --------------------
676          *     CAIRO_PATH_MOVE_TO:     1 point
677          *     CAIRO_PATH_LINE_TO:     1 point
678          *     CAIRO_PATH_CURVE_TO:    3 points
679          *     CAIRO_PATH_CLOSE_PATH:  0 points
680          * --------------------
681          */
682         Point!double getPoint(int index) const
683         {
684             //length = 1 + number of points, index 0 based
685             if(index > (data.header.length - 2))
686             {
687                 throw new RangeError(__FILE__, __LINE__);
688             }
689             Point!double p;
690             p.x = data[index+1].point.x;
691             p.y = data[index+1].point.y;
692             return p;
693         }
694 
695         ///Convenience operator overload.
696         alias getPoint opIndex;
697 
698         void toString(scope void delegate(const(char)[]) sink) const
699         {
700             final switch(type)
701             {
702                 case PathElementType.CAIRO_PATH_CLOSE_PATH:
703                     sink("(CAIRO_PATH_CLOSE_PATH)");
704                     break;
705                 case PathElementType.CAIRO_PATH_CURVE_TO:
706                     sink("(CAIRO_PATH_CURVE_TO(");
707                     formattedWrite(sink, "%s", this[0]);
708                     sink(",");
709                     formattedWrite(sink, "%s", this[1]);
710                     sink(",");
711                     formattedWrite(sink, "%s", this[2]);
712                     sink("))");
713                     break;
714                 case PathElementType.CAIRO_PATH_LINE_TO:
715                     sink("(CAIRO_PATH_LINE_TO(");
716                     formattedWrite(sink, "%s", this[0]);
717                     sink("))");
718                     break;
719                 case PathElementType.CAIRO_PATH_MOVE_TO:
720                     sink("(CAIRO_PATH_MOVE_TO(");
721                     formattedWrite(sink, "%s", this[0]);
722                     sink("))");
723                     break;
724             }
725         }
726 }
727 
728 /**
729  * Wrapper for cairo's $(D cairo_matrix_t).
730  * A $(D cairo_matrix_t) holds an affine transformation, such as a scale,
731  * rotation, shear, or a combination of those. The transformation of
732  * a point (x, y) is given by:
733  * --------------------------------------
734  *     x_new = xx * x + xy * y + x0;
735  *     y_new = yx * x + yy * y + y0;
736  * --------------------------------------
737  **/
738 public struct Matrix
739 {
740     public:
741         /**
742          * Cairo's $(D cairo_matrix_t) struct
743          */
744         cairo_matrix_t nativeMatrix;
745         /**
746          * Alias, so that $(D cairo_matrix_t) members also work
747          * with this $(D Matrix) struct
748          */
749         alias nativeMatrix this;
750 
751         /**
752          * Sets matrix to be the affine transformation given by xx, yx, xy, yy, x0, y0.
753          * The transformation is given by:
754          * ----------------------
755          *  x_new = xx * x + xy * y + x0;
756          *  y_new = yx * x + yy * y + y0;
757          * ----------------------
758          *
759          * Params:
760          * xx = xx component of the affine transformation
761          * yx = yx component of the affine transformation
762          * xy = xy component of the affine transformation
763          * yy = yy component of the affine transformation
764          * x0 = X translation component of the affine transformation
765          * y0 = Y translation component of the affine transformation
766          */
767         this(double xx, double yx, double xy, double yy,
768             double x0, double y0)
769         {
770             cairo_matrix_init(&this.nativeMatrix, xx, yx, xy, yy, x0, y0);
771         }
772 
773         /**
774          * Modifies matrix to be an identity transformation.
775          */
776         void initIdentity()
777         {
778             cairo_matrix_init_identity(&this.nativeMatrix);
779         }
780 
781         /**
782          * Initializes matrix to a transformation that translates by tx
783          * and ty in the X and Y dimensions, respectively.
784          *
785          * Params:
786          * tx = amount to translate in the X direction
787          * ty = amount to translate in the Y direction
788          */
789         void initTranslate(double tx, double ty)
790         {
791             cairo_matrix_init_translate(&this.nativeMatrix, tx, ty);
792         }
793 
794         /**
795          * nitializes matrix to a transformation that scales by sx and sy
796          * in the X and Y dimensions, respectively.
797          *
798          * Params:
799          * sx = scale factor in the X direction
800          * sy = scale factor in the Y direction
801          */
802         void initScale(double sx, double sy)
803         {
804             cairo_matrix_init_scale(&this.nativeMatrix, sx, sy);
805         }
806 
807         ///ditto
808         void initScale(Point!double point)
809         {
810             initScale(point.x, point.y);
811         }
812 
813         /**
814          * Initialized matrix to a transformation that rotates by radians.
815          *
816          * Params:
817          * radians = angle of rotation, in radians. The direction of
818          *     rotation is defined such that positive angles rotate in
819          *     the direction from the positive X axis toward the positive
820          *     Y axis. With the default axis orientation of cairo,
821          *     positive angles rotate in a clockwise direction
822          */
823         void initRotate(double radians)
824         {
825             cairo_matrix_init_rotate(&this.nativeMatrix, radians);
826         }
827 
828         /**
829          * Applies a translation by tx, ty to the transformation in matrix.
830          * The effect of the new transformation is to first translate the
831          * coordinates by tx and ty, then apply the original transformation
832          * to the coordinates.
833          *
834          * Params:
835          * tx = amount to translate in the X direction
836          * ty = amount to translate in the Y direction
837          */
838         void translate(double tx, double ty)
839         {
840             cairo_matrix_translate(&this.nativeMatrix, tx, ty);
841         }
842 
843         /**
844          * Applies scaling by sx, sy to the transformation in matrix.
845          * The effect of the new transformation is to first scale the
846          * coordinates by sx and sy, then apply the original transformation
847          * to the coordinates.
848          *
849          * Params:
850          * sx = scale factor in the X direction
851          * sy = scale factor in the Y direction
852          */
853         void scale(double sx, double sy)
854         {
855             cairo_matrix_scale(&this.nativeMatrix, sx, sy);
856         }
857 
858         ///ditto
859         void scale(Point!double point)
860         {
861             scale(point.x, point.y);
862         }
863 
864         /**
865          * Applies rotation by radians to the transformation in matrix.
866          * The effect of the new transformation is to first rotate the
867          * coordinates by radians, then apply the original transformation
868          * to the coordinates.
869          *
870          * Params:
871          * radians = angle of rotation, in radians. The direction of
872          * rotation is defined such that positive angles rotate in the
873          * direction from the positive X axis toward the positive Y axis.
874          * With the default axis orientation of cairo, positive angles
875          * rotate in a clockwise direction.
876          */
877         void rotate(double radians)
878         {
879             cairo_matrix_rotate(&this.nativeMatrix, radians);
880         }
881 
882         /**
883          * Changes matrix to be the inverse of its original value.
884          * Not all transformation matrices have inverses; if the matrix
885          * collapses points together (it is degenerate), then it has no
886          * inverse and this function will fail.
887          *
888          * Throws:
889          * If matrix has an inverse, modifies matrix to be the inverse matrix.
890          * Otherwise, throws a cairo exception
891          * with CAIRO_STATUS_INVALID_MATRIX type.
892          */
893         void invert()
894         {
895             throwError(cairo_matrix_invert(&this.nativeMatrix));
896         }
897 
898         /**
899          * Multiplies the affine transformations in a and b together and
900          * returns the result. The effect of the resulting transformation
901          * is to first apply the transformation in a to the coordinates
902          * and then apply the transformation in b to the coordinates.
903          *
904          * It is allowable for result to be identical to either a or b.
905          */
906         Matrix opBinary(string op)(Matrix rhs) if(op == "*")
907         {
908             Matrix result;
909             cairo_matrix_multiply(&result.nativeMatrix, &this.nativeMatrix, &rhs.nativeMatrix);
910             return result;
911         }
912 
913         /**
914          * Transforms the distance vector (dx,dy) by matrix. This is similar
915          * to $(D transformPoint) except that the translation
916          * components of the transformation are ignored. The calculation
917          * of the returned vector is as follows:
918          * ------------------
919          * dx2 = dx1 * a + dy1 * c;
920          * dy2 = dx1 * b + dy1 * d;
921          * ------------------
922          */
923         Point!double transformDistance(Point!double dist)
924         {
925             cairo_matrix_transform_distance(&this.nativeMatrix, &dist.x, &dist.y);
926             return dist;
927         }
928 
929         /**
930          * Transforms the point (x, y) by matrix.
931          */
932         Point!double transformPoint(Point!double point)
933         {
934             cairo_matrix_transform_point(&this.nativeMatrix, &point.x, &point.y);
935             return point;
936         }
937 }
938 
939 /**
940  * A $(D Pattern) represents a source when drawing onto a
941  * $(D Surface). There are different subtypes of $(D Pattern),
942  * for different types of sources; for example,
943  * $(D SolidPattern.fromRGB) creates a pattern for a solid
944  * opaque color.
945  *
946  * Other than various $(D Pattern) subclasses,
947  * some of the pattern types can be implicitly created
948  * using various $(D Context.setSource) functions;
949  * for example $(D Context.setSourceRGB).
950  *
951  * The C type of a pattern can be queried with $(D getType()),
952  * although D polymorphism features also work.
953  *
954  * Memory management of $(D Pattern) can be done with the $(D dispose())
955  * method, see $(LINK https://github.com/jpf91/cairoD/wiki/Memory-Management#3-RC-class)
956  *
957  * Note:
958  * This class uses the $(D CairoCountedClass) mixin, so all it's members
959  * are also available in $(D Pattern) classes, although they do not show
960  * up in the documentation because of a limitation in ddoc.
961  **/
962 public class Pattern
963 {
964     ///
965     mixin CairoCountedClass!(cairo_pattern_t*, "cairo_pattern_");
966 
967     protected:
968         /**
969          * Method for use in subclasses.
970          * Calls $(D cairo_pattern_status(nativePointer)) and throws
971          * an exception if the status isn't CAIRO_STATUS_SUCCESS
972          */
973         final void checkError()
974         {
975             throwError(cairo_pattern_status(nativePointer));
976         }
977 
978     public:
979         /**
980          * Create a $(D Pattern) from a existing $(D cairo_pattern_t*).
981          * Pattern is a garbage collected class. It will call $(D cairo_pattern_destroy)
982          * when it gets collected by the GC or when $(D dispose()) is called.
983          *
984          * Warning:
985          * $(D ptr)'s reference count is not increased by this function!
986          * Adjust reference count before calling it if necessary
987          *
988          * $(RED Only use this if you know what your doing!
989          * This function should not be needed for standard cairoD usage.)
990          */
991         this(cairo_pattern_t* ptr)
992         {
993             this.nativePointer = ptr;
994             if(!ptr)
995             {
996                 throw new CairoException(cairo_status_t.CAIRO_STATUS_NULL_POINTER);
997             }
998             checkError();
999         }
1000 
1001         /**
1002          * The createFromNative method for the Pattern classes.
1003          * See $(LINK https://github.com/jpf91/cairoD/wiki/Memory-Management#createFromNative)
1004          * for more information.
1005          *
1006          * Warning:
1007          * $(RED Only use this if you know what your doing!
1008          * This function should not be needed for standard cairoD usage.)
1009          */
1010         static Pattern createFromNative(cairo_pattern_t* ptr, bool adjRefCount = true)
1011         {
1012             if(!ptr)
1013             {
1014                 throw new CairoException(cairo_status_t.CAIRO_STATUS_NULL_POINTER);
1015             }
1016             throwError(cairo_pattern_status(ptr));
1017             //Adjust reference count
1018             if(adjRefCount)
1019                 cairo_pattern_reference(ptr);
1020             switch(cairo_pattern_get_type(ptr))
1021             {
1022                 case cairo_pattern_type_t.CAIRO_PATTERN_TYPE_LINEAR:
1023                     return new LinearGradient(ptr);
1024                 case cairo_pattern_type_t.CAIRO_PATTERN_TYPE_RADIAL:
1025                     return new RadialGradient(ptr);
1026                 case cairo_pattern_type_t.CAIRO_PATTERN_TYPE_SOLID:
1027                     return new SolidPattern(ptr);
1028                 case cairo_pattern_type_t.CAIRO_PATTERN_TYPE_SURFACE:
1029                     return new SurfacePattern(ptr);
1030                 default:
1031                     return new Pattern(ptr);
1032             }
1033         }
1034 
1035         /**
1036          * Sets the mode to be used for drawing outside the area of a pattern.
1037          * See $(D Extend) for details on the semantics of each extend strategy.
1038          * The default extend mode is CAIRO_EXTEND_NONE for surface patterns
1039          * and CAIRO_EXTEND_PAD for gradient patterns.
1040          */
1041         void setExtend(Extend ext)
1042         {
1043             cairo_pattern_set_extend(this.nativePointer, ext);
1044             checkError();
1045         }
1046 
1047         /**
1048          * Gets the current extend mode for a pattern. See $(D Extend)
1049          * for details on the semantics of each extend strategy.
1050          */
1051         Extend getExtend()
1052         {
1053             scope(exit)
1054                 checkError();
1055             return cairo_pattern_get_extend(this.nativePointer);
1056         }
1057 
1058         /**
1059          * Sets the filter to be used for resizing when using this pattern.
1060          * See $(D Filter) for details on each filter.
1061          *
1062          * Note:
1063          * You might want to control filtering even when you do not have
1064          * an explicit cairo_pattern_t object, (for example when using
1065          * $(D context.setSourceSourface())). In these cases, it is convenient
1066          * to use $(D Context.getSource()) to get access to the pattern
1067          * that cairo creates implicitly.
1068          * For example:
1069          * ------------------------
1070          * context.setSourceSurface(image, x, y);
1071          * context.getSource().setFilter(Filter.CAIRO_FILTER_NEAREST);
1072          * ------------------------
1073          */
1074         void setFilter(Filter fil)
1075         {
1076             cairo_pattern_set_filter(this.nativePointer, fil);
1077             checkError();
1078         }
1079 
1080         /**
1081          * Gets the current filter for a pattern. See $(D Filter) for details on each filter.
1082          */
1083         Filter getFilter()
1084         {
1085             scope(exit)
1086                 checkError();
1087             return cairo_pattern_get_filter(this.nativePointer);
1088         }
1089 
1090         ///Convenience property
1091         void filter(Filter fil)
1092         {
1093             setFilter(fil);
1094         }
1095 
1096         ///ditto
1097         Filter filter()
1098         {
1099             return getFilter();
1100         }
1101 
1102         /**
1103          * Sets the pattern's transformation matrix to matrix.
1104          * This matrix is a transformation from user space to pattern space.
1105          *
1106          * When a pattern is first created it always has the identity matrix
1107          * for its transformation matrix, which means that pattern space
1108          * is initially identical to user space.
1109          * Important: Please note that the direction of this transformation
1110          * matrix is from user space to pattern space. This means that if
1111          * you imagine the flow from a pattern to user space (and on to
1112          * device space), then coordinates in that flow will be transformed
1113          * by the inverse of the pattern matrix.
1114          *
1115          * For example, if you want to make a pattern appear twice as large
1116          * as it does by default the correct code to use is:
1117          * -------------------
1118          * Matrix matrix;
1119          * matrix.initScale(0.5, 0.5);
1120          * pattern.setMatrix(matrix);
1121          * -------------------
1122          * Meanwhile, using values of 2.0 rather than 0.5 in the code above
1123          * would cause the pattern to appear at half of its default size.
1124          *
1125          * Also, please note the discussion of the user-space locking semantics
1126          * of $(D Context.setSource()).
1127          */
1128         void setMatrix(Matrix mat)
1129         {
1130             cairo_pattern_set_matrix(this.nativePointer, &mat.nativeMatrix);
1131             checkError();
1132         }
1133 
1134         /**
1135          * Returns the pattern's transformation matrix.
1136          */
1137         Matrix getMatrix()
1138         {
1139             Matrix ma;
1140             cairo_pattern_get_matrix(this.nativePointer, &ma.nativeMatrix);
1141             checkError();
1142             return ma;
1143         }
1144 
1145         ///Convenience property
1146         @property void matrix(Matrix mat)
1147         {
1148             setMatrix(mat);
1149         }
1150 
1151         ///ditto
1152         @property Matrix matrix()
1153         {
1154             return getMatrix();
1155         }
1156 
1157         /**
1158          * This function returns the C type of a pattern. See $(D PatternType)
1159          * for available types.
1160          */
1161         PatternType getType()
1162         {
1163             scope(exit)
1164                 checkError();
1165             return cairo_pattern_get_type(this.nativePointer);
1166         }
1167 
1168         ///Convenience property
1169         @property PatternType type()
1170         {
1171             return getType();
1172         }
1173 
1174         //Cairo binding guidelines say we shouldn't wrap these
1175         /*
1176         void setUserData(const cairo_user_data_key_t* key, void* data, cairo_destroy_func_t destroy)
1177         {
1178             cairo_pattern_set_user_data(this.nativePointer, key, data, destroy);
1179             checkError();
1180         }
1181 
1182         void* getUserData(const cairo_user_data_key_t* key)
1183         {
1184             scope(exit)
1185                 checkError();
1186             return cairo_pattern_get_user_data(this.nativePointer, key);
1187         }*/
1188 }
1189 
1190 /**
1191  * A solid pattern.
1192  *
1193  * Use the $(D fromRGB) and $(D fromRGBA) methods to create an
1194  * instance.
1195  */
1196 public class SolidPattern : Pattern
1197 {
1198     public:
1199         /**
1200          * Create a $(D SolidPattern) from a existing $(D cairo_pattern_t*).
1201          * SolidPattern is a garbage collected class. It will call $(D cairo_pattern_destroy)
1202          * when it gets collected by the GC or when $(D dispose()) is called.
1203          *
1204          * Warning:
1205          * $(D ptr)'s reference count is not increased by this function!
1206          * Adjust reference count before calling it if necessary
1207          *
1208          * $(RED Only use this if you know what your doing!
1209          * This function should not be needed for standard cairoD usage.)
1210          */
1211         this(cairo_pattern_t* ptr)
1212         {
1213             super(ptr);
1214         }
1215 
1216         /**
1217          * Creates a new $(D SolidPattern) corresponding to an opaque color.
1218          * The color components are floating point numbers in the range 0
1219          * to 1. If the values passed in are outside that range, they will
1220          * be clamped.
1221          */
1222         static SolidPattern fromRGB(double red, double green, double blue)
1223         {
1224             return new SolidPattern(cairo_pattern_create_rgb(red, green, blue));
1225         }
1226 
1227         ///ditto
1228         static SolidPattern fromRGB(RGB rgb)
1229         {
1230             return new SolidPattern(cairo_pattern_create_rgb(rgb.red, rgb.green, rgb.blue));
1231         }
1232 
1233         /**
1234          * Creates a new $(D SolidPattern) corresponding to a translucent color.
1235          * The color components are floating point numbers in the range 0 to 1.
1236          * If the values passed in are outside that range, they will be clamped.
1237          */
1238         static SolidPattern fromRGBA(double red, double green, double blue, double alpha)
1239         {
1240             return new SolidPattern(cairo_pattern_create_rgba(red, green, blue, alpha));
1241         }
1242 
1243         ///ditto
1244         static SolidPattern fromRGBA(RGBA rgba)
1245         {
1246             return new SolidPattern(cairo_pattern_create_rgba(rgba.red,rgba. green, rgba.blue, rgba.alpha));
1247         }
1248 
1249         /**
1250          * Gets the solid color for a solid color pattern.
1251          */
1252         RGBA getRGBA()
1253         {
1254             RGBA col;
1255             cairo_pattern_get_rgba(this.nativePointer, &col.red, &col.green, &col.blue, &col.alpha);
1256             checkError();
1257             return col;
1258         }
1259 
1260         ///Convenience property (todo: dubious due to lowercase requirement)
1261         @property RGBA rgba()
1262         {
1263             return getRGBA();
1264         }
1265 }
1266 
1267 /**
1268  * A surface pattern.
1269  *
1270  * Use the $(this(Surface)) constructor to create an
1271  * instance.
1272  */
1273 public class SurfacePattern : Pattern
1274 {
1275     public:
1276         /**
1277          * Create a $(D SurfacePattern) from a existing $(D cairo_pattern_t*).
1278          * SurfacePattern is a garbage collected class. It will call $(D cairo_pattern_destroy)
1279          * when it gets collected by the GC or when $(D dispose()) is called.
1280          *
1281          * Warning:
1282          * $(D ptr)'s reference count is not increased by this function!
1283          * Adjust reference count before calling it if necessary
1284          *
1285          * $(RED Only use this if you know what your doing!
1286          * This function should not be needed for standard cairoD usage.)
1287          */
1288         this(cairo_pattern_t* ptr)
1289         {
1290             super(ptr);
1291         }
1292 
1293         /**
1294          * Create a new $(D SurfacePattern) for the given surface.
1295          */
1296         this(Surface surface)
1297         {
1298             super(cairo_pattern_create_for_surface(surface.nativePointer));
1299         }
1300 
1301         /**
1302          * Gets the $(D Surface) of a SurfacePattern.
1303          */
1304         Surface getSurface()
1305         {
1306             cairo_surface_t* ptr;
1307             throwError(cairo_pattern_get_surface(this.nativePointer, &ptr));
1308             return Surface.createFromNative(ptr);
1309         }
1310 
1311         ///Convenience property
1312         @property Surface surface()
1313         {
1314             return getSurface();
1315         }
1316 }
1317 
1318 /**
1319  * Base class for $(D LinearGradient) and $(D RadialGradient).
1320  *
1321  * It's not possible to create instances of this class.
1322  */
1323 public class Gradient : Pattern
1324 {
1325     public:
1326         /**
1327          * Create a $(D Gradient) from a existing $(D cairo_pattern_t*).
1328          * Gradient is a garbage collected class. It will call $(D cairo_pattern_destroy)
1329          * when it gets collected by the GC or when $(D dispose()) is called.
1330          *
1331          * Warning:
1332          * $(D ptr)'s reference count is not increased by this function!
1333          * Adjust reference count before calling it if necessary
1334          *
1335          * $(RED Only use this if you know what your doing!
1336          * This function should not be needed for standard cairoD usage.)
1337          */
1338         this(cairo_pattern_t* ptr)
1339         {
1340             super(ptr);
1341         }
1342 
1343         /**
1344          * Adds an opaque color stop to a gradient pattern. The offset
1345          * specifies the location along the gradient's control vector.
1346          * For example, a $(D LinearGradient)'s control vector is from
1347          * (x0,y0) to (x1,y1) while a $(D RadialGradient)'s control vector is
1348          * from any point on the start circle to the corresponding point
1349          * on the end circle.
1350          *
1351          * The color is specified in the same way as in $(D context.setSourceRGB()).
1352          *
1353          * If two (or more) stops are specified with identical offset
1354          * values, they will be sorted according to the order in which the
1355          * stops are added, (stops added earlier will compare less than
1356          * stops added later). This can be useful for reliably making sharp
1357          * color transitions instead of the typical blend.
1358          *
1359          * Params:
1360          * offset = an offset in the range [0.0 .. 1.0]
1361          *
1362          * Note: If the pattern is not a gradient pattern, (eg. a linear
1363          * or radial pattern), then the pattern will be put into an error
1364          * status with a status of CAIRO_STATUS_PATTERN_TYPE_MISMATCH.
1365          */
1366         void addColorStopRGB(double offset, RGB color)
1367         {
1368             cairo_pattern_add_color_stop_rgb(this.nativePointer, offset,
1369                 color.red, color.green, color.blue);
1370             checkError();
1371         }
1372 
1373         ///ditto
1374         void addColorStopRGB(double offset, double red, double green, double blue)
1375         {
1376             cairo_pattern_add_color_stop_rgb(this.nativePointer, offset,
1377                 red, green, blue);
1378             checkError();
1379         }
1380 
1381         /**
1382          * Adds a translucent color stop to a gradient pattern. The offset
1383          * specifies the location along the gradient's control vector. For
1384          * example, a linear gradient's control vector is from (x0,y0) to
1385          * (x1,y1) while a radial gradient's control vector is from any point
1386          * on the start circle to the corresponding point on the end circle.
1387          *
1388          * The color is specified in the same way as in
1389          * $(D context.setSourceRGBA()).
1390          *
1391          * If two (or more) stops are specified with identical offset values,
1392          * they will be sorted according to the order in which the stops are added,
1393          * (stops added earlier will compare less than stops added later).
1394          * This can be useful for reliably making sharp color transitions
1395          * instead of the typical blend.
1396          *
1397          * Params:
1398          * offset = an offset in the range [0.0 .. 1.0]
1399          *
1400          * Note: If the pattern is not a gradient pattern, (eg. a linear
1401          * or radial pattern), then the pattern will be put into an error
1402          * status with a status of CAIRO_STATUS_PATTERN_TYPE_MISMATCH.
1403          */
1404         void addColorStopRGBA(double offset, RGBA color)
1405         {
1406             cairo_pattern_add_color_stop_rgba(this.nativePointer, offset,
1407                 color.red, color.green, color.blue, color.alpha);
1408             checkError();
1409         }
1410 
1411         ///ditto
1412         void addColorStopRGBA(double offset, double red, double green,
1413             double blue, double alpha)
1414         {
1415             cairo_pattern_add_color_stop_rgba(this.nativePointer, offset,
1416                 red, green, blue, alpha);
1417             checkError();
1418         }
1419 
1420         /**
1421          * Gets the number of color stops specified in the given gradient pattern.
1422          */
1423         int getColorStopCount()
1424         {
1425             int tmp;
1426             cairo_pattern_get_color_stop_count(this.nativePointer, &tmp);
1427             checkError();
1428             return tmp;
1429         }
1430 
1431         ///Convenience alias
1432         alias getColorStopCount colorStopCount;
1433 
1434         /**
1435          * Gets the color and offset information at the given index for a
1436          * gradient pattern. Values of index are 0 to 1 less than the number
1437          * returned by $(D getColorStopCount()).
1438          *
1439          * Params:
1440          * index = index of the stop to return data for
1441          * offset = output: Returns the offset of the color stop
1442          * color = output: Returns the color of the color stop
1443          *
1444          * TODO: Array/Range - like interface?
1445          */
1446         void getColorStopRGBA(int index, out double offset, out RGBA color)
1447         {
1448             throwError(cairo_pattern_get_color_stop_rgba(this.nativePointer, index, &offset,
1449                 &color.red, &color.green, &color.blue, &color.alpha));
1450         }
1451 }
1452 
1453 /**
1454  * A linear gradient.
1455  *
1456  * Use the $(D this(Point!double p1, Point!double p2)) constructor to create an
1457  * instance.
1458  */
1459 public class LinearGradient : Gradient
1460 {
1461     public:
1462         /**
1463          * Create a $(D LinearGradient) from a existing $(D cairo_pattern_t*).
1464          * LinearGradient is a garbage collected class. It will call $(D cairo_pattern_destroy)
1465          * when it gets collected by the GC or when $(D dispose()) is called.
1466          *
1467          * Warning:
1468          * $(D ptr)'s reference count is not increased by this function!
1469          * Adjust reference count before calling it if necessary
1470          *
1471          * $(RED Only use this if you know what your doing!
1472          * This function should not be needed for standard cairoD usage.)
1473          */
1474         this(cairo_pattern_t* ptr)
1475         {
1476             super(ptr);
1477         }
1478 
1479         /**
1480          * Create a new linear gradient $(D Pattern) along the line defined
1481          * by p1 and p2. Before using the gradient pattern, a number of
1482          * color stops should be defined using $(D Gradient.addColorStopRGB())
1483          * or  $(D Gradient.addColorStopRGBA()).
1484          *
1485          * Params:
1486          * p1 = the start point
1487          * p2 = the end point
1488          *
1489          * Note: The coordinates here are in pattern space. For a new pattern,
1490          * pattern space is identical to user space, but the relationship
1491          * between the spaces can be changed with $(D Pattern.setMatrix()).
1492          */
1493         this(Point!double p1, Point!double p2)
1494         {
1495             super(cairo_pattern_create_linear(p1.x, p1.y, p2.x, p2.y));
1496         }
1497         ///ditto
1498         this(double x1, double y1, double x2, double y2)
1499         {
1500             super(cairo_pattern_create_linear(x1, y1, x2, y2));
1501         }
1502 
1503         /**
1504          * Gets the gradient endpoints for a linear gradient.
1505          *
1506          * Returns:
1507          * Point[0] = the first point
1508          *
1509          * Point[1] = the second point
1510          */
1511         Point!(double)[2] getLinearPoints()
1512         {
1513             Point!(double)[2] tmp;
1514             throwError(cairo_pattern_get_linear_points(this.nativePointer, &tmp[0].x, &tmp[0].y,
1515                 &tmp[1].x, &tmp[1].y));
1516             return tmp;
1517         }
1518 
1519         ///Convenience alias
1520         alias getLinearPoints linearPoints;
1521 }
1522 
1523 /**
1524  * A radial gradient.
1525  *
1526  * Use the $(D this(Point!double c0, double radius0, Point!double c1, double radius1))
1527  * constructor to create an instance.
1528  */
1529 public class RadialGradient : Gradient
1530 {
1531     public:
1532         /**
1533          * Create a $(D RadialGradient) from a existing $(D cairo_pattern_t*).
1534          * RadialGradient is a garbage collected class. It will call $(D cairo_pattern_destroy)
1535          * when it gets collected by the GC or when $(D dispose()) is called.
1536          *
1537          * Warning:
1538          * $(D ptr)'s reference count is not increased by this function!
1539          * Adjust reference count before calling it if necessary
1540          *
1541          * $(RED Only use this if you know what your doing!
1542          * This function should not be needed for standard cairoD usage.)
1543          */
1544         this(cairo_pattern_t* ptr)
1545         {
1546             super(ptr);
1547         }
1548 
1549         /**
1550          * Creates a new radial gradient $(D pattern) between the two
1551          * circles defined by (c0, radius0) and (c1, radius1). Before
1552          * using the gradient pattern, a number of color stops should
1553          * be defined using $(D Pattern.addColorStopRGB()) or
1554          * $(D Pattern.addColorStopRGBA()).
1555          *
1556          * Params:
1557          * c0 = center of the start circle
1558          * radius0 = radius of the start circle
1559          * c1 = center of the end circle
1560          * radius1 = radius of the end circle
1561          *
1562          * Note: The coordinates here are in pattern space. For a new pattern,
1563          * pattern space is identical to user space, but the relationship
1564          * between the spaces can be changed with $(D Pattern.setMatrix()).
1565          */
1566         this(Point!double c0, double radius0, Point!double c1, double radius1)
1567         {
1568             super(cairo_pattern_create_radial(c0.x, c0.y, radius0, c1.x, c1.y, radius1));
1569         }
1570         ///ditto
1571         this(double c0x, double c0y, double radius0, double c1x, double c1y, double radius1)
1572         {
1573             super(cairo_pattern_create_radial(c0x, c0y, radius0, c1x, c1y, radius1));
1574         }
1575 
1576         /**
1577          * Gets the gradient endpoint circles for a radial gradient,
1578          * each specified as a center coordinate and a radius.
1579          */
1580         void getRadialCircles(out Point!double c0, out Point!double c1, out double radius0, out double radius1)
1581         {
1582             throwError(cairo_pattern_get_radial_circles(this.nativePointer, &c0.x, &c0.y, &radius0,
1583                 &c1.x, &c1.y, &radius1));
1584         }
1585 }
1586 
1587 /**
1588  * Devices are the abstraction Cairo employs for the rendering system used
1589  * by a $(D Surface). You can get the device of a surface using
1590  * $(D Surface.getDevice()).
1591  *
1592  * Devices are created using custom functions specific to the rendering
1593  * system you want to use. See the documentation for the surface types
1594  * for those functions.
1595  *
1596  * An important function that devices fulfill is sharing access to the
1597  * rendering system between Cairo and your application. If you want to access
1598  * a device directly that you used to draw to with Cairo, you must first
1599  * call $(D Device.flush()) to ensure that Cairo finishes all operations
1600  * on the device and resets it to a clean state.
1601  *
1602  * Cairo also provides the functions $(D Device.acquire()) and
1603  * $(D Device.release()) to synchronize access to the rendering system
1604  * in a multithreaded environment. This is done internally, but can also
1605  * be used by applications.
1606  *
1607  * Note:
1608  * Please refer to the documentation of each backend for additional usage
1609  * requirements, guarantees provided, and interactions with existing surface
1610  * API of the device functions for surfaces of that type.
1611  *
1612  * Examples:
1613  * -------------------------
1614  * void my_device_modifying_function(Device device)
1615  * {
1616  *     // Ensure the device is properly reset
1617  *     device.flush();
1618  *     try
1619  *     {
1620  *         // Try to acquire the device
1621  *         device.acquire();
1622  *     }
1623  *     catch(CairoException e)
1624  *     {
1625  *         writeln("");
1626  *     }
1627  *
1628  *     // Release the device when done.
1629  *     scope(exit)
1630  *         device.release();
1631  *
1632  *     // Do the custom operations on the device here.
1633  *     // But do not call any Cairo functions that might acquire devices.
1634  *
1635  * }
1636  * -------------------------
1637 */
1638 public class Device
1639 {
1640     ///
1641     mixin CairoCountedClass!(cairo_device_t*, "cairo_device_");
1642 
1643     protected:
1644         /**
1645          * Method for use in subclasses.
1646          * Calls $(D cairo_device_status(nativePointer)) and throws
1647          * an exception if the status isn't CAIRO_STATUS_SUCCESS
1648          */
1649         final void checkError()
1650         {
1651             throwError(cairo_device_status(nativePointer));
1652         }
1653 
1654     public:
1655         /**
1656          * Create a $(D Device) from a existing $(D cairo_device_t*).
1657          * Device is a garbage collected class. It will call $(D cairo_pattern_destroy)
1658          * when it gets collected by the GC or when $(D dispose()) is called.
1659          *
1660          * Warning:
1661          * $(D ptr)'s reference count is not increased by this function!
1662          * Adjust reference count before calling it if necessary
1663          *
1664          * $(RED Only use this if you know what your doing!
1665          * This function should not be needed for standard cairoD usage.)
1666          */
1667         this(cairo_device_t* ptr)
1668         {
1669             this.nativePointer = ptr;
1670             if(!ptr)
1671             {
1672                 throw new CairoException(cairo_status_t.CAIRO_STATUS_NULL_POINTER);
1673             }
1674             checkError();
1675         }
1676 
1677         /**
1678          * This function finishes the device and drops all references to
1679          * external resources. All surfaces, fonts and other objects created
1680          * for this device will be finished, too. Further operations on
1681          * the device will not affect the device but will instead trigger
1682          * a CAIRO_STATUS_DEVICE_FINISHED exception.
1683          *
1684          * When the reference count reaches zero, cairo will call $(D finish())
1685          * if it hasn't been called already, before freeing the resources
1686          * associated with the device.
1687          *
1688          * This function may acquire devices.
1689          *
1690          * BUGS: How does "All surfaces, fonts and other objects created
1691          * for this device will be finished" interact with the cairoD?
1692          */
1693         void finish()
1694         {
1695             cairo_device_finish(this.nativePointer);
1696             checkError();
1697         }
1698 
1699         /**
1700          * Finish any pending operations for the device and also restore
1701          * any temporary modifications cairo has made to the device's state.
1702          * This function must be called before switching from using the
1703          * device with Cairo to operating on it directly with native APIs.
1704          * If the device doesn't support direct access, then this function does nothing.
1705          *
1706          * This function may acquire devices.
1707          */
1708         void flush()
1709         {
1710             cairo_device_flush(this.nativePointer);
1711             checkError();
1712         }
1713 
1714         /**
1715          * This function returns the C type of a Device. See $(D DeviceType)
1716          * for available types.
1717          */
1718         DeviceType getType()
1719         {
1720             auto tmp = cairo_device_get_type(this.nativePointer);
1721             checkError();
1722             return tmp;
1723         }
1724 
1725         ///Convenience alias
1726         alias getType type;
1727 
1728         /**
1729          * Acquires the device for the current thread. This function will
1730          * block until no other thread has acquired the device.
1731          *
1732          * If no Exception is thrown, you successfully
1733          * acquired the device. From now on your thread owns the device
1734          * and no other thread will be able to acquire it until a matching
1735          * call to $(D Device.release()). It is allowed to recursively
1736          * acquire the device multiple times from the same thread.
1737          *
1738          * Note:
1739          * You must never acquire two different devices at the same time
1740          * unless this is explicitly allowed. Otherwise the possibility
1741          * of deadlocks exist.
1742          *
1743          * As various Cairo functions can acquire devices when called,
1744          * these functions may also cause deadlocks when you call them
1745          * with an acquired device. So you must not have a device acquired
1746          * when calling them. These functions are marked in the documentation.
1747          *
1748          * Throws:
1749          * An exception if the device is in an error state and could not
1750          * be acquired. After a successful call to acquire, a matching call
1751          * to $(D Device.release()) is required.
1752          */
1753         void acquire()
1754         {
1755             cairo_device_acquire(this.nativePointer);
1756             checkError();
1757         }
1758 
1759         /**
1760          * Releases a device previously acquired using $(D Device.acquire()).
1761          * See that function for details.
1762          */
1763         void release()
1764         {
1765             cairo_device_release(this.nativePointer);
1766             checkError();
1767         }
1768 }
1769 
1770 /**
1771  * Surface is the abstract type representing all different drawing targets
1772  * that cairo can render to. The actual drawings are performed using a cairo context.
1773  *
1774  * A cairo surface is created by using backend-specific classes,
1775  * typically of the form $(D BackendSurface).
1776  *
1777  * Most surface types allow accessing the surface without using Cairo
1778  * functions. If you do this, keep in mind that it is mandatory that
1779  * you call $(D Surface.flush()) before reading from or writing to the
1780  * surface and that you must use $(D Surface.markDirty()) after modifying it.
1781  */
1782 public class Surface
1783 {
1784     ///
1785     mixin CairoCountedClass!(cairo_surface_t*, "cairo_surface_");
1786 
1787     protected:
1788         /**
1789          * Method for use in subclasses.
1790          * Calls $(D cairo_surface_status(nativePointer)) and throws
1791          * an exception if the status isn't CAIRO_STATUS_SUCCESS
1792          */
1793         final void checkError()
1794         {
1795             throwError(cairo_surface_status(nativePointer));
1796         }
1797 
1798     public:
1799         /**
1800          * Create a $(D Surface) from a existing $(D cairo_surface_t*).
1801          * Surface is a garbage collected class. It will call $(D cairo_surface_destroy)
1802          * when it gets collected by the GC or when $(D dispose()) is called.
1803          *
1804          * Warning:
1805          * $(D ptr)'s reference count is not increased by this function!
1806          * Adjust reference count before calling it if necessary
1807          *
1808          * $(RED Only use this if you know what your doing!
1809          * This function should not be needed for standard cairoD usage.)
1810          */
1811         this(cairo_surface_t* ptr)
1812         {
1813             this.nativePointer = ptr;
1814             if(!ptr)
1815             {
1816                 throw new CairoException(cairo_status_t.CAIRO_STATUS_NULL_POINTER);
1817             }
1818             checkError();
1819         }
1820 
1821         /**
1822          * The createFromNative method for the Surface classes.
1823          * See $(LINK https://github.com/jpf91/cairoD/wiki/Memory-Management#createFromNative)
1824          * for more information.
1825          *
1826          * Warning:
1827          * $(RED Only use this if you know what your doing!
1828          * This function should not be needed for standard cairoD usage.)
1829          */
1830         static Surface createFromNative(cairo_surface_t* ptr, bool adjRefCount = true)
1831         {
1832             if(!ptr)
1833             {
1834                 throw new CairoException(cairo_status_t.CAIRO_STATUS_NULL_POINTER);
1835             }
1836             throwError(cairo_surface_status(ptr));
1837             //Adjust reference count
1838             if(adjRefCount)
1839                 cairo_surface_reference(ptr);
1840             switch(cairo_surface_get_type(ptr))
1841             {
1842                 case cairo_surface_type_t.CAIRO_SURFACE_TYPE_IMAGE:
1843                     return new ImageSurface(ptr);
1844                 static if(CAIRO_HAS_PS_SURFACE)
1845                 {
1846                     import cairo.ps;
1847                     case cairo_surface_type_t.CAIRO_SURFACE_TYPE_PS:
1848                         return new PSSurface(ptr);
1849                 }
1850                 static if(CAIRO_HAS_PDF_SURFACE)
1851                 {
1852                     import cairo.pdf;
1853                     case cairo_surface_type_t.CAIRO_SURFACE_TYPE_PDF:
1854                         return new PDFSurface(ptr);
1855                 }
1856                 static if(CAIRO_HAS_SVG_SURFACE)
1857                 {
1858                     import cairo.svg;
1859                     case cairo_surface_type_t.CAIRO_SURFACE_TYPE_SVG:
1860                         return new SVGSurface(ptr);
1861                 }
1862                 static if(CAIRO_HAS_WIN32_SURFACE)
1863                 {
1864                     import cairo.win32;
1865                     case cairo_surface_type_t.CAIRO_SURFACE_TYPE_WIN32:
1866                         return new Win32Surface(ptr);
1867                     case cairo_surface_type_t.CAIRO_SURFACE_TYPE_WIN32_PRINTING:
1868                         return new Win32Surface(ptr);
1869                 }
1870                 static if(CAIRO_HAS_XCB_SURFACE)
1871                 {
1872                     import cairo.xcb;
1873                     case cairo_surface_type_t.CAIRO_SURFACE_TYPE_XCB:
1874                         return new XCBSurface(ptr);
1875                 }
1876                 static if(CAIRO_HAS_DIRECTFB_SURFACE)
1877                 {
1878                     import cairo.directfb;
1879                     case cairo_surface_type_t.CAIRO_SURFACE_TYPE_DIRECTFB:
1880                         return new DirectFBSurface(ptr);
1881                 }
1882                 static if(CAIRO_HAS_XLIB_SURFACE)
1883                 {
1884                     import cairo.xlib;
1885                     case cairo_surface_type_t.CAIRO_SURFACE_TYPE_XLIB:
1886                         return new XlibSurface(ptr);
1887                 }
1888                 default:
1889                     return new Surface(ptr);
1890             }
1891         }
1892 
1893         /**
1894          * Create a new surface that is as compatible as possible with
1895          * an existing surface. For example the new surface will have the
1896          * same fallback resolution and font options as other. Generally,
1897          * the new surface will also use the same backend as other, unless
1898          * that is not possible for some reason. The type of the returned
1899          * surface may be examined with $(D Surface.getType()).
1900          *
1901          * Initially the surface contents are all 0 (transparent if
1902          * contents have transparency, black otherwise.)
1903          *
1904          * Params:
1905          * other = an existing surface used to select the backend of the new surface
1906          * content = the content for the new surface
1907          * width = width of the new surface, (in device-space units)
1908          * height = height of the new surface (in device-space units)
1909          */
1910         static Surface createSimilar(Surface other, Content content, int width, int height)
1911         {
1912             return createFromNative(cairo_surface_create_similar(other.nativePointer, content, width, height), false);
1913         }
1914 
1915         /**
1916          * Create a new surface that is a rectangle within the target surface.
1917          * All operations drawn to this surface are then clipped and translated
1918          * onto the target surface. Nothing drawn via this sub-surface
1919          * outside of its bounds is drawn onto the target surface,
1920          * making this a useful method for passing constrained child
1921          * surfaces to library routines that draw directly onto the parent
1922          * surface, i.e. with no further backend allocations, double
1923          * buffering or copies.
1924          *
1925          * Note:
1926          * The semantics of subsurfaces have not been finalized yet unless
1927          * the rectangle is in full device units, is contained within
1928          * the extents of the target surface, and the target or
1929          * subsurface's device transforms are not changed.
1930          *
1931          * Params:
1932          * target = an existing surface for which the sub-surface will point to
1933          * rect = location of the subsurface
1934          */
1935         static Surface createForRectangle(Surface target, Rectangle!double rect)
1936         {
1937             return createFromNative(cairo_surface_create_for_rectangle(target.nativePointer,
1938                 rect.point.x, rect.point.y, rect.width, rect.height), false);
1939         }
1940 
1941         /**
1942          * This function finishes the surface and drops all references
1943          * to external resources. For example, for the Xlib backend it
1944          * means that cairo will no longer access the drawable, which
1945          * can be freed. After calling $(D Surface.finish()) the only
1946          * valid operations on a surface are getting and setting user,
1947          * referencing and destroying, and flushing and finishing it.
1948          *
1949          * Further drawing to the surface will not affect the surface
1950          * but will instead trigger a CAIRO_STATUS_SURFACE_FINISHED exception.
1951          *
1952          * When the reference count id decreased to zero, cairo will call
1953          * $(D Surface.finish()) if it hasn't been called already, before
1954          * freeing the resources associated with the surface.
1955          */
1956         void finish()
1957         {
1958             cairo_surface_finish(this.nativePointer);
1959             checkError();
1960         }
1961 
1962         /**
1963          * Do any pending drawing for the surface and also restore any temporary
1964          * modifications cairo has made to the surface's state. This function
1965          * must be called before switching from drawing on the surface
1966          * with cairo to drawing on it directly with native APIs. If the
1967          * surface doesn't support direct access, then this function does
1968          * nothing.
1969          */
1970         void flush()
1971         {
1972             cairo_surface_flush(this.nativePointer);
1973             checkError();
1974         }
1975 
1976         /**
1977          * This function returns the device for a surface. See $(D Device).
1978          */
1979         Device getDevice()
1980         {
1981             auto ptr = cairo_surface_get_device(this.nativePointer);
1982             if(!ptr)
1983                 return null;
1984             cairo_device_reference(ptr);
1985             return new Device(ptr);
1986         }
1987 
1988         ///Convenience alias
1989         alias getDevice device;
1990 
1991         /**
1992          * Retrieves the default font rendering options for the surface.
1993          * This allows display surfaces to report the correct subpixel
1994          * order for rendering on them, print surfaces to disable hinting
1995          * of metrics and so forth. The result can then be used with
1996          * $(new ScaledFont()).
1997          */
1998         FontOptions getFontOptions()
1999         {
2000             FontOptions fo = FontOptions.create();
2001             cairo_surface_get_font_options(this.nativePointer, fo._data._payload);
2002             fo.checkError();
2003             return fo;
2004         }
2005 
2006         ///Convenience alias
2007         alias getFontOptions fontOptions;
2008 
2009         /**
2010          * This function returns the content type of surface which indicates
2011          * whether the surface contains color and/or alpha information.
2012          * See $(D Content).
2013          */
2014         Content getContent()
2015         {
2016             scope(exit)
2017                 checkError();
2018             return cairo_surface_get_content(this.nativePointer);
2019         }
2020 
2021         ///Convenience alias
2022         alias getContent content;
2023 
2024         /**
2025          * Tells cairo that drawing has been done to surface using means
2026          * other than cairo, and that cairo should reread any cached areas.
2027          * Note that you must call $(D Surface.flush()) before doing such drawing.
2028          */
2029         void markDirty()
2030         {
2031             cairo_surface_mark_dirty(this.nativePointer);
2032             checkError();
2033         }
2034 
2035         /**
2036          * Like $(D Surface.markDirty()), but drawing has been done only
2037          * to the specified rectangle, so that cairo can retain cached
2038          * contents for other parts of the surface.
2039          *
2040          * Any cached clip set on the surface will be reset by this function,
2041          * to make sure that future cairo calls have the clip set that they expect.
2042          */
2043         void markDirtyRectangle(int x, int y, int width, int height)
2044         {
2045             cairo_surface_mark_dirty_rectangle(this.nativePointer, x, y, width, height);
2046             checkError();
2047         }
2048 
2049         ///ditto
2050         void markDirtyRectangle(Rectangle!int rect)
2051         {
2052             cairo_surface_mark_dirty_rectangle(this.nativePointer, rect.point.x,
2053                 rect.point.y, rect.width, rect.height);
2054             checkError();
2055         }
2056 
2057         /**
2058          * Sets an offset that is added to the device coordinates determined
2059          * by the CTM when drawing to surface. One use case for this function
2060          * is when we want to create a $(D Surface) that redirects drawing
2061          * for a portion of an onscreen surface to an offscreen surface
2062          * in a way that is completely invisible to the user of the cairo API.
2063          * Setting a transformation via $(D Context.translate()) isn't sufficient
2064          * to do this, since functions like $(D Context.deviceToUser()) will
2065          * expose the hidden offset.
2066          *
2067          * Note:
2068          * the offset affects drawing to the surface as well as using the
2069          * surface in a source pattern.
2070          *
2071          * Params:
2072          * x_offset = the offset in the X direction, in device units
2073          * y_offset = the offset in the Y direction, in device units
2074          */
2075         void setDeviceOffset(double x_offset, double y_offset)
2076         {
2077             cairo_surface_set_device_offset(this.nativePointer, x_offset, y_offset);
2078             checkError();
2079         }
2080         ///ditto
2081         void setDeviceOffset(Point!double offset)
2082         {
2083             cairo_surface_set_device_offset(this.nativePointer, offset.x, offset.y);
2084             checkError();
2085         }
2086 
2087         /**
2088          * This function returns the previous device offset set
2089          * by $(D Surface.setDeviceOffset()).
2090          *
2091          * Returns:
2092          * Offset in device units
2093          */
2094         Point!double getDeviceOffset()
2095         {
2096             Point!double tmp;
2097             cairo_surface_get_device_offset(this.nativePointer, &tmp.x, &tmp.y);
2098             checkError();
2099             return tmp;
2100         }
2101 
2102         ///Convenience property function
2103         // todo: enable when new D tuples are implemented
2104         /+@property void deviceOffset(double x_offset, double y_offset)
2105         {
2106             setDeviceOffset(x_offset, y_offset);
2107         }+/
2108 
2109         ///ditto
2110         @property void deviceOffset(Point!double offset)
2111         {
2112             setDeviceOffset(offset);
2113         }
2114 
2115         ///ditto
2116         @property Point!double deviceOffset()
2117         {
2118             return getDeviceOffset();
2119         }
2120 
2121         /**
2122          * Set the horizontal and vertical resolution for image fallbacks.
2123          *
2124          * When certain operations aren't supported natively by a backend,
2125          * cairo will fallback by rendering operations to an image and
2126          * then overlaying that image onto the output. For backends that
2127          * are natively vector-oriented, this function can be used to set
2128          * the resolution used for these image fallbacks, (larger values
2129          * will result in more detailed images, but also larger file sizes).
2130          *
2131          * Some examples of natively vector-oriented backends are the ps,
2132          * pdf, and svg backends.
2133          *
2134          * For backends that are natively raster-oriented, image fallbacks
2135          * are still possible, but they are always performed at the native
2136          * device resolution. So this function has no effect on those backends.
2137          *
2138          * Note:
2139          * The fallback resolution only takes effect at the time of
2140          * completing a page (with $(D Context.showPage()) or $(D Context.copyPage()))
2141          * so there is currently no way to have more than one fallback
2142          * resolution in effect on a single page.
2143          *
2144          * The default fallback resoultion is 300 pixels per inch in both
2145          * dimensions.
2146          */
2147         void setFallbackResolution(Resolution res)
2148         {
2149             cairo_surface_set_fallback_resolution(this.nativePointer, res.x, res.y);
2150             checkError();
2151         }
2152 
2153         /**
2154          * This function returns the previous fallback resolution set
2155          * by $(D setFallbackResolution()), or default
2156          * fallback resolution if never set.
2157          */
2158         Resolution getFallbackResolution()
2159         {
2160             Resolution res;
2161             cairo_surface_get_fallback_resolution(this.nativePointer, &res.x, &res.y);
2162             checkError();
2163             return res;
2164         }
2165 
2166         ///Convenience property function
2167         @property void fallbackResolution(Resolution res)
2168         {
2169             setFallbackResolution(res);
2170         }
2171 
2172         ///ditto
2173         @property Resolution fallbackResolution()
2174         {
2175             return getFallbackResolution();
2176         }
2177 
2178         /**
2179          * This function returns the C type of a Surface. See $(D SurfaceType)
2180          * for available types.
2181          */
2182         SurfaceType getType()
2183         {
2184             auto tmp = cairo_surface_get_type(this.nativePointer);
2185             checkError();
2186             return tmp;
2187         }
2188 
2189         ///convenience alias
2190         alias getType type;
2191 
2192         /*
2193         void setUserData(const cairo_user_data_key_t* key, void* data, cairo_destroy_func_t destroy)
2194         {
2195             cairo_surface_set_user_data(this.nativePointer, key, data, destroy);
2196             checkError();
2197         }
2198 
2199         void* getUserData(const cairo_user_data_key_t* key)
2200         {
2201             scope(exit)
2202                 checkError();
2203             return cairo_surface_get_user_data(this.nativePointer, key);
2204         }*/
2205 
2206         /**
2207          * Emits the current page for backends that support multiple pages,
2208          * but doesn't clear it, so that the contents of the current page
2209          * will be retained for the next page. Use $(D Surface.showPage())
2210          * if you want to get an empty page after the emission.
2211          *
2212          * There is a convenience function for this that can be called on
2213          * a $(D Context), namely $(D Context.copyPage()).
2214          */
2215         void copyPage()
2216         {
2217             cairo_surface_copy_page(this.nativePointer);
2218             checkError();
2219         }
2220 
2221         /**
2222          * Emits and clears the current page for backends that support
2223          * multiple pages. Use $(D Surface.copyPage()) if you don't
2224          * want to clear the page.
2225          *
2226          * There is a convenience function for this that can be called on
2227          * a $(D Context), namely $(D Context.showPage()).
2228          */
2229         void showPage()
2230         {
2231             cairo_surface_show_page(this.nativePointer);
2232             checkError();
2233         }
2234 
2235         /**
2236          * Returns whether the surface supports sophisticated $(D showTextGlyphs())
2237          * operations. That is, whether it actually uses the provided text
2238          * and cluster data to a $(D showTextGlyphs()) call.
2239          *
2240          * Note:
2241          * Even if this function returns false, a $(D showTextGlyphs())
2242          * operation targeted at surface will still succeed. It just will
2243          * act like a $(D showGlyphs()) operation. Users can use this
2244          * function to avoid computing UTF-8 text and cluster mapping
2245          * if the target surface does not use it.
2246          *
2247          * Returns:
2248          * true if surface supports $(D showTextGlyphs()), false otherwise
2249          */
2250         bool hasShowTextGlyphs()
2251         {
2252             scope(exit)
2253                 checkError();
2254             return cairo_surface_has_show_text_glyphs(this.nativePointer) ? true : false;
2255         }
2256 
2257         /**
2258          * Attach an image in the format mime_type to surface. To remove
2259          * the data from a surface, call this function with same mime
2260          * type and NULL for data.
2261          *
2262          * The attached image (or filename) data can later be used by
2263          * backends which support it (currently: PDF, PS, SVG and Win32
2264          * Printing surfaces) to emit this data instead of making a snapshot
2265          * of the surface. This approach tends to be faster and requires
2266          * less memory and disk space.
2267          *
2268          * The recognized MIME types are the following: CAIRO_MIME_TYPE_JPEG,
2269          * CAIRO_MIME_TYPE_PNG, CAIRO_MIME_TYPE_JP2, CAIRO_MIME_TYPE_URI.
2270          *
2271          * See corresponding backend surface docs for details about which
2272          * MIME types it can handle.
2273          *
2274          * Caution: the associated MIME data will be discarded if you draw
2275          * on the surface afterwards. Use this function with care.
2276          *
2277          * Params:
2278          * mime_type = the MIME type of the image data
2279          * data = the image data to attach to the surface
2280          * length = the length of the image data
2281          * destroy = a cairo_destroy_func_t which will be called when the
2282          *     surface is destroyed or when new image data is attached using
2283          *     the same mime type.
2284          * closure = the data to be passed to the destroy notifier
2285          *
2286          * Throws:
2287          * OutOfMemoryError if a slot could not be allocated for the user data.
2288          *
2289          * TODO: More D-like API
2290          *
2291          * Note:
2292          * $(RED Only use this if you know what your doing! Make sure you get
2293          * memory management of the passed in data right!)
2294          */
2295         void setMimeData(string type, ubyte* data, ulong length, cairo_destroy_func_t destroy, void* closure)
2296         {
2297             throwError(cairo_surface_set_mime_data(this.nativePointer, toStringz(type),
2298                 data, length, destroy, closure));
2299         }
2300 
2301         /**
2302          * Return mime data previously attached to surface using the
2303          * specified mime type. If no data has been attached with the given
2304          * mime type, data is set null.
2305          *
2306          * Params:
2307          * type = the mime type of the image data
2308          *
2309          * TODO: More D-like API
2310          *
2311          * Note:
2312          * $(RED Only use this if you know what your doing! Make sure you get
2313          * memory management of the data right!)
2314          */
2315         void getMimeData(string type, out ubyte* data, out ulong length)
2316         {
2317             cairo_surface_get_mime_data(this.nativePointer, toStringz(type), &data, &length);
2318             checkError();
2319         }
2320 }
2321 
2322 /**
2323  * This function provides a stride value that will respect all alignment
2324  * requirements of the accelerated image-rendering code within cairo.
2325  *
2326  * Examples:
2327  * -----------------------------------
2328  * int stride;
2329  * ubyte[] data;
2330  * Surface surface;
2331  *
2332  * stride = formatStrideForWidth(format, width);
2333  * data = new ubyte[](stride * height); //could also use malloc
2334  * surface = new ImageSurface(data, format, width, height, stride);
2335  * -----------------------------------
2336  *
2337  * Params:
2338  * format = The desired Format of an image surface to be created
2339  * width = The desired width of an image surface to be created
2340  *
2341  * Returns:
2342  * the appropriate stride to use given the desired format and width, or
2343  * -1 if either the format is invalid or the width too large.
2344  */
2345 int formatStrideForWidth(Format format, int width)
2346 {
2347     return cairo_format_stride_for_width(format, width);
2348 }
2349 
2350 /**
2351  * Image Surfaces — Rendering to memory buffers
2352  *
2353  * Image surfaces provide the ability to render to memory buffers either
2354  * allocated by cairo or by the calling code. The supported image
2355  * formats are those defined in $(D Format).
2356  */
2357 public class ImageSurface : Surface
2358 {
2359     public:
2360         /**
2361          * Create a $(D ImageSurface) from a existing $(D cairo_surface_t*).
2362          * ImageSurface is a garbage collected class. It will call $(D cairo_surface_destroy)
2363          * when it gets collected by the GC or when $(D dispose()) is called.
2364          *
2365          * Warning:
2366          * $(D ptr)'s reference count is not increased by this function!
2367          * Adjust reference count before calling it if necessary
2368          *
2369          * $(RED Only use this if you know what your doing!
2370          * This function should not be needed for standard cairoD usage.)
2371          */
2372         this(cairo_surface_t* ptr)
2373         {
2374             super(ptr);
2375         }
2376 
2377         /**
2378          * Creates an image surface of the specified format and dimensions.
2379          * Initially the surface contents are all 0. (Specifically, within
2380          * each pixel, each color or alpha channel belonging to format will
2381          * be 0. The contents of bits within a pixel, but not belonging
2382          * to the given format are undefined).
2383          *
2384          * Params:
2385          * format = format of pixels in the surface to create
2386          * width = width of the surface, in pixels
2387          * height = height of the surface, in pixels
2388          */
2389         this(Format format, int width, int height)
2390         {
2391             super(cairo_image_surface_create(format, width, height));
2392         }
2393 
2394         /**
2395          * Creates an image surface for the provided pixel data.
2396          * $(RED The output buffer must be kept around until the $(D Surface)
2397          * is destroyed or $(D Surface.finish()) is called on the surface.)
2398          * The initial contents of data will be used as the initial image
2399          * contents; you must explicitly clear the buffer, using, for
2400          * example, $(D Context.rectangle()) and $(D Context.fill()) if you
2401          * want it cleared.
2402          *
2403          * Note that the stride may be larger than width*bytes_per_pixel
2404          * to provide proper alignment for each pixel and row.
2405          * This alignment is required to allow high-performance rendering
2406          * within cairo. The correct way to obtain a legal stride value is
2407          * to call $(D formatStrideForWidth) with the desired format and
2408          * maximum image width value, and then use the resulting stride
2409          * value to allocate the data and to create the image surface.
2410          * See $(D formatStrideForWidth) for example code.
2411          *
2412          * Params:
2413          * data = a pointer to a buffer supplied by the application in
2414          *     which to write contents. This pointer must be suitably aligned
2415          *     for any kind of variable, (for example, a pointer returned by malloc).
2416          * format = the format of pixels in the buffer
2417          * width = the width of the image to be stored in the buffer
2418          * height = the height of the image to be stored in the buffer
2419          * stride = the number of bytes between the start of rows in the
2420          *     buffer as allocated. This value should always be computed
2421          *     by $(D formatStrideForWidth) before allocating
2422          *     the data buffer.
2423          */
2424         this(ubyte[] data, Format format, int width, int height, int stride)
2425         {
2426             super(cairo_image_surface_create_for_data(data.ptr, format, width, height, stride));
2427         }
2428 
2429         /**
2430          * Get a pointer to the data of the image surface,
2431          * for direct inspection or modification.
2432          *
2433          * Warning: There's no way to get the size of the buffer from
2434          * cairo, so you'll only get a $(D ubyte*). Be careful!
2435          */
2436         ubyte* getData()
2437         {
2438             scope(exit)
2439                 checkError();
2440             return cairo_image_surface_get_data(this.nativePointer);
2441         }
2442 
2443         ///convenience alias
2444         alias getData data;
2445 
2446         /**
2447          * Get the format of the surface.
2448          */
2449         Format getFormat()
2450         {
2451             scope(exit)
2452                 checkError();
2453             return cairo_image_surface_get_format(this.nativePointer);
2454         }
2455 
2456         ///convenience alias
2457         alias getFormat format;
2458 
2459         /**
2460          * Get the width of the image surface in pixels.
2461          */
2462         int getWidth()
2463         {
2464             scope(exit)
2465                 checkError();
2466             return cairo_image_surface_get_width(this.nativePointer);
2467         }
2468 
2469         ///convenience alias
2470         alias getWidth width;
2471 
2472         /**
2473          * Get the height of the image surface in pixels.
2474          */
2475         int getHeight()
2476         {
2477             scope(exit)
2478                 checkError();
2479             return cairo_image_surface_get_height(this.nativePointer);
2480         }
2481 
2482         ///convenience alias
2483         alias getHeight height;
2484 
2485         /**
2486          * Get the stride of the image surface in bytes.
2487          */
2488         int getStride()
2489         {
2490             scope(exit)
2491                 checkError();
2492             return cairo_image_surface_get_stride(this.nativePointer);
2493         }
2494 
2495         ///convenience alias
2496         alias getStride stride;
2497 
2498         version(D_Ddoc)
2499         {
2500             /**
2501              * Creates a new image surface and initializes the contents to the given PNG file.
2502              *
2503              * Params:
2504              * file = name of PNG file to load
2505              *
2506              * Note:
2507              * Only available if cairo, cairoD and the cairoD user
2508              * code were compiled with "version=CAIRO_HAS_PNG_FUNCTIONS"
2509              */
2510             static ImageSurface fromPng(string file);
2511             //TODO: fromPNGStream when phobos gets new streaming api
2512             /**
2513              * Writes the contents of surface to a new file filename as a PNG image.
2514              *
2515              * Params:
2516              * file = the name of a file to write to
2517              *
2518              * Note:
2519              * Only available if cairo, cairoD and the cairoD user
2520              * code were compiled with "version=CAIRO_HAS_PNG_FUNCTIONS"
2521              */
2522             void writeToPNG(string file);
2523             //TODO: toPNGStream when phobos gets new streaming api
2524         }
2525         else static if(CAIRO_HAS_PNG_FUNCTIONS)
2526         {
2527             static ImageSurface fromPng(string file)
2528             {
2529                 return new ImageSurface(cairo_image_surface_create_from_png(toStringz(file)));
2530             }
2531             //TODO: fromPNGStream when phobos gets new streaming api
2532             void writeToPNG(string file)
2533             {
2534                 throwError(cairo_surface_write_to_png(this.nativePointer, toStringz(file)));
2535             }
2536             //TODO: toPNGStream when phobos gets new streaming api
2537         }
2538 }
2539 
2540 /**
2541  * The cairo drawing context
2542  *
2543  * $(D Context) is the main object used when drawing with cairo. To draw
2544  * with cairo, you create a $(D Context), set the target surface, and drawing
2545  * options for the $(D Context), create shapes with functions like $(D Context.moveTo())
2546  * and $(D Context.lineTo()), and then draw shapes with $(D Context.stroke())
2547  * or $(D Context.fill()).
2548  *
2549  * $(D Context)'s can be pushed to a stack via $(D Context.save()).
2550  * They may then safely be changed, without loosing the current state.
2551  * Use $(D Context.restore()) to restore to the saved state.
2552  */
2553 public struct Context
2554 {
2555     /*---------------------------Reference counting stuff---------------------------*/
2556     protected:
2557         @property uint _count()
2558         {
2559             return cairo_get_reference_count(this.nativePointer);
2560         }
2561 
2562         void _reference()
2563         {
2564             cairo_reference(this.nativePointer);
2565         }
2566 
2567         void _dereference()
2568         {
2569             cairo_destroy(this.nativePointer);
2570         }
2571 
2572     public:
2573         /**
2574          * The underlying $(D cairo_t*) handle
2575          */
2576         cairo_t* nativePointer;
2577         version(D_Ddoc)
2578         {
2579              /**
2580              * Enable / disable memory management debugging for this Context
2581              * instance. Only available if both cairoD and the cairoD user
2582              * code were compiled with "debug=RefCounted"
2583              *
2584              * Output is written to stdout, see
2585              * $(LINK https://github.com/jpf91/cairoD/wiki/Memory-Management#debugging)
2586              * for more information
2587              */
2588              bool debugging = false;
2589         }
2590         else debug(RefCounted)
2591         {
2592             bool debugging = false;
2593         }
2594 
2595         /**
2596          * Constructor that tracks the reference count appropriately. If $(D
2597          * !refCountedIsInitialized), does nothing.
2598          */
2599         this(this)
2600         {
2601             if (this.nativePointer is null)
2602                 return;
2603             this._reference();
2604             debug(RefCounted)
2605                 if (this.debugging)
2606             {
2607                      writeln(typeof(this).stringof,
2608                     "@", cast(void*) this.nativePointer, ": bumped refcount to ",
2609                     this._count);
2610             }
2611         }
2612 
2613         ~this()
2614         {
2615             this.dispose();
2616         }
2617 
2618         /**
2619          * Explicitly drecrease the reference count.
2620          *
2621          * See $(LINK https://github.com/jpf91/cairoD/wiki/Memory-Management#2.1-structs)
2622          * for more information.
2623          */
2624         void dispose()
2625         {
2626             if (this.nativePointer is null)
2627                 return;
2628             assert(this._count > 0);
2629             if (this._count > 1)
2630             {
2631                 debug(RefCounted)
2632                     if (this.debugging)
2633                 {
2634                          writeln(typeof(this).stringof,
2635                         "@", cast(void*)this.nativePointer,
2636                         ": decrement refcount to ", this._count - 1);
2637                 }
2638                 this._dereference();
2639                 this.nativePointer = null;
2640                 return;
2641             }
2642             debug(RefCounted)
2643                 if (this.debugging)
2644             {
2645                 write(typeof(this).stringof,
2646                         "@", cast(void*)this.nativePointer, ": freeing... ");
2647                 stdout.flush();
2648             }
2649             //Done, deallocate is done by cairo
2650             this._dereference();
2651             this.nativePointer = null;
2652             debug(RefCounted) if (this.debugging) writeln("done!");
2653         }
2654         /**
2655          * Assignment operator
2656          */
2657         void opAssign(typeof(this) rhs)
2658         {
2659             //Black magic?
2660             swap(this.nativePointer, rhs.nativePointer);
2661             debug(RefCounted)
2662                 this.debugging = rhs.debugging;
2663         }
2664     /*------------------------End of Reference counting stuff-----------------------*/
2665 
2666 
2667     protected:
2668         final void checkError()
2669         {
2670             throwError(cairo_status(nativePointer));
2671         }
2672 
2673 
2674     public:
2675         /**
2676          * Creates a new $(D Context) with all graphics state parameters set
2677          * to default values and with target as a target surface. The
2678          * target surface should be constructed with a backend-specific
2679          * function such as $(D new ImageSurface()).
2680          *
2681          * This function references target, so you can immediately call
2682          * $(D Surface.dispose()) on it if you don't need to maintain
2683          * a separate reference to it.
2684          */
2685         this(Surface target)
2686         {
2687             //cairo_create already references the pointer, so _reference
2688             //isn't necessary
2689             nativePointer = cairo_create(target.nativePointer);
2690             throwError(cairo_status(nativePointer));
2691         }
2692 
2693         /**
2694          * Create a $(D Context) from a existing $(D cairo_t*).
2695          * Context is a garbage collected class. It will call $(D cairo_destroy)
2696          * when it gets collected by the GC or when $(D dispose()) is called.
2697          *
2698          * Warning:
2699          * $(D ptr)'s reference count is not increased by this function!
2700          * Adjust reference count before calling it if necessary
2701          *
2702          * $(RED Only use this if you know what your doing!
2703          * This function should not be needed for standard cairoD usage.)
2704          */
2705         this(cairo_t* ptr)
2706         {
2707             this.nativePointer = ptr;
2708             if(!ptr)
2709             {
2710                 throw new CairoException(cairo_status_t.CAIRO_STATUS_NULL_POINTER);
2711             }
2712             checkError();
2713         }
2714 
2715         /**
2716          * Makes a copy of the current state of cr and saves it on an
2717          * internal stack of saved states for cr. When $(D Context.restore())
2718          * is called, cr will be restored to the saved state. Multiple
2719          * calls to $(D Context.save()) and  $(D Context.restore()) can be nested; each
2720          * call to  $(D Context.restore()) restores the state from the matching
2721          * paired $(D Context.save()).
2722          *
2723          * It isn't necessary to clear all saved states before a $(D Context)
2724          * is freed. If the reference count of a $(D Context) drops to zero
2725          * , any saved states will be freed along with the $(D Context).
2726          */
2727         void save()
2728         {
2729             cairo_save(this.nativePointer);
2730             checkError();
2731         }
2732 
2733         /**
2734          * Restores cr to the state saved by a preceding call to
2735          * $(D Context.save()) and removes that state from the stack of
2736          * saved states.
2737          */
2738         void restore()
2739         {
2740             cairo_restore(this.nativePointer);
2741             checkError();
2742         }
2743 
2744         /**
2745          * Gets the target surface for the cairo context as passed to
2746          * the constructor.
2747          */
2748         Surface getTarget()
2749         {
2750             return Surface.createFromNative(cairo_get_target(this.nativePointer));
2751         }
2752 
2753         ///convenience alias
2754         alias getTarget target;
2755 
2756         /**
2757          * Temporarily redirects drawing to an intermediate surface known
2758          * as a group. The redirection lasts until the group is completed
2759          * by a call to $(D Context.popGroup()) or $(D Context.popGroupToSource()).
2760          * These calls provide the result of any drawing to the group
2761          * as a pattern, (either as an explicit object, or set as the
2762          * source pattern).
2763          *
2764          * This group functionality can be convenient for performing
2765          * intermediate compositing. One common use of a group is to render
2766          * objects as opaque within the group, (so that they occlude each other),
2767          * and then blend the result with translucence onto the destination.
2768          *
2769          * Groups can be nested arbitrarily deep by making balanced calls
2770          * to $(D Context.pushGgroup())/$(D Context.popGroup()). Each call pushes/pops
2771          * the new target group onto/from a stack.
2772          *
2773          * The $(D Context.pushGroup()) function calls $(D Context.save()) so that any
2774          * changes to the graphics state will not be visible outside the
2775          * group, (the $(D Context.popGroup) functions call $(D Context.restore())).
2776          *
2777          * By default the intermediate group will have a content type of
2778          * CAIRO_CONTENT_COLOR_ALPHA. Other content types can be chosen
2779          * for the group by using $(D Context.pushGroup(Content)) instead.
2780          *
2781          * As an example, here is how one might fill and stroke a path with
2782          * translucence, but without any portion of the fill being visible
2783          * under the stroke:
2784          * -------------------------------
2785          * cr.pushGroup();
2786          * cr.setSource(fill_pattern);
2787          * cr.fillPreserve();
2788          * cr.setSource(stroke_pattern);
2789          * cr.stroke();
2790          * cr.popGroupToSource();
2791          * cr.paintWithAlpha(alpha);
2792          * -------------------------------
2793          */
2794         void pushGroup()
2795         {
2796             cairo_push_group(this.nativePointer);
2797             checkError();
2798         }
2799 
2800         /**
2801          * Temporarily redirects drawing to an intermediate surface known
2802          * as a group. The redirection lasts until the group is completed
2803          * by a call to $(D Context.popGroup()) or $(D Context.popGroupToSource()).
2804          * These calls provide the result of any drawing to the group as
2805          * a pattern, (either as an explicit object, or set as the source
2806          * pattern).
2807          *
2808          * The group will have a content type of content. The ability to
2809          * control this content type is the only distinction between this
2810          * function and $(D Context.pushGroup()) which you should see for a more
2811          * detailed description of group rendering.
2812          */
2813         void pushGroup(Content cont)
2814         {
2815             cairo_push_group_with_content(this.nativePointer, cont);
2816             checkError();
2817         }
2818 
2819         /**
2820          * Terminates the redirection begun by a call to $(D Context.pushGroup())
2821          * or $(D Context.pushGroup(Content)) and returns a new pattern
2822          * containing the results of all drawing operations performed to
2823          * the group.
2824          *
2825          * The $(D Context.popGroup()) function calls $(D Context.restore()), (balancing
2826          * a call to $(D Context.save()) by the $(D Context.pushGroup()) function), so that any
2827          * changes to the graphics state will not be visible outside the group.
2828          */
2829         Pattern popGroup()
2830         {
2831             auto ptr = cairo_pop_group(this.nativePointer);
2832             return Pattern.createFromNative(ptr, false);
2833         }
2834 
2835         /**
2836          * Terminates the redirection begun by a call to $(D Context.pushGroup())
2837          * or $(D Context.pushGroup(Content)) and installs the resulting
2838          * pattern as the source pattern in the given cairo context.
2839          *
2840          * The behavior of this function is equivalent to the sequence
2841          * of operations:
2842          * -----------------------
2843          * Pattern group = cr.popGroup();
2844          * cr.setSource(group);
2845          * group.dispose();
2846          * -----------------------
2847          * but is more convenient as their is no need for a variable to
2848          * store the short-lived pointer to the pattern.
2849          *
2850          * The $(D Context.popGroup()) function calls $(D Context.restore()),
2851          * (balancing a call to $(D Context.save()) by the $(D Context.pushGroup()) function),
2852          * so that any changes to the graphics state will not be
2853          * visible outside the group.
2854          */
2855         void popGroupToSource()
2856         {
2857             cairo_pop_group_to_source(this.nativePointer);
2858             checkError();
2859         }
2860 
2861         /**
2862          * Gets the current destination surface for the context.
2863          * This is either the original target surface as passed to
2864          * the Context constructor or the target surface for the current
2865          * group as started by the most recent call to
2866          *  $(D Context.pushGroup()) or  $(D Context.pushGroup(Content)).
2867          */
2868         Surface getGroupTarget()
2869         {
2870             return Surface.createFromNative(cairo_get_group_target(this.nativePointer));
2871         }
2872 
2873         ///convenience alias
2874         alias getGroupTarget groupTarget;
2875 
2876         /**
2877          * Sets the source pattern within cr to an opaque color.
2878          * This opaque color will then be used for any subsequent
2879          * drawing operation until a new source pattern is set.
2880          *
2881          * The color components are floating point numbers in the range
2882          * 0 to 1. If the values passed in are outside that range,
2883          * they will be clamped.
2884          *
2885          * The default source pattern is opaque black,
2886          * (that is, it is equivalent to setSourceRGB(0.0, 0.0, 0.0)).
2887          */
2888         void setSourceRGB(double red, double green, double blue)
2889         {
2890             cairo_set_source_rgb(this.nativePointer, red, green, blue);
2891             checkError();
2892         }
2893 
2894         ///ditto
2895         void setSourceRGB(RGB rgb)
2896         {
2897             cairo_set_source_rgb(this.nativePointer, rgb.red, rgb.green, rgb.blue);
2898             checkError();
2899         }
2900 
2901         /**
2902          * Sets the source pattern within cr to a translucent color.
2903          * This color will then be used for any subsequent drawing
2904          * operation until a new source pattern is set.
2905          *
2906          * The color and alpha components are floating point numbers in
2907          * the range 0 to 1. If the values passed in are outside that
2908          * range, they will be clamped.
2909          *
2910          * The default source pattern is opaque black, (that is, it is
2911          * equivalent to setSourceRGBA(0.0, 0.0, 0.0, 1.0)).
2912          */
2913         void setSourceRGBA(double red, double green, double blue, double alpha)
2914         {
2915             cairo_set_source_rgba(this.nativePointer, red, green, blue, alpha);
2916             checkError();
2917         }
2918 
2919         ///ditto
2920         void setSourceRGBA(RGBA rgba)
2921         {
2922             cairo_set_source_rgba(this.nativePointer, rgba.red, rgba.green, rgba.blue, rgba.alpha);
2923             checkError();
2924         }
2925 
2926         /**
2927          * Sets the source pattern within cr to source. This pattern will
2928          * then be used for any subsequent drawing operation until
2929          * a new source pattern is set.
2930          *
2931          * Note: The pattern's transformation matrix will be locked to
2932          * the user space in effect at the time of setSource(). This
2933          * means that further modifications of the current transformation
2934          * matrix will not affect the source pattern.
2935          * See $(D Pattern.setMatrix()).
2936          *
2937          * The default source pattern is a solid pattern that is opaque
2938          * black, (that is, it is equivalent
2939          * to setSourceRGB(0.0, 0.0, 0.0)).
2940          */
2941         void setSource(Pattern pat)
2942         {
2943             cairo_set_source(this.nativePointer, pat.nativePointer);
2944             checkError();
2945         }
2946 
2947         /**
2948          * Gets the current source pattern for cr.
2949          */
2950         Pattern getSource()
2951         {
2952             return Pattern.createFromNative(cairo_get_source(this.nativePointer));
2953         }
2954 
2955         ///Convenience property
2956         @property void source(Pattern pat)
2957         {
2958             setSource(pat);
2959         }
2960 
2961         ///ditto
2962         @property Pattern source()
2963         {
2964             return getSource();
2965         }
2966 
2967         /**
2968          * This is a convenience function for creating a pattern from
2969          * surface and setting it as the source in cr with $(D Context.setSource()).
2970          *
2971          * The x and y parameters give the user-space coordinate at
2972          * which the surface origin should appear. (The surface origin
2973          * is its upper-left corner before any transformation has been
2974          * applied.) The x and y parameters are negated and then set
2975          * as translation values in the pattern matrix.
2976          *
2977          * Other than the initial translation pattern matrix,
2978          * as described above, all other pattern attributes,
2979          * (such as its extend mode), are set to the default values as
2980          * in $(D new SurfacePattern()). The resulting pattern can be
2981          * queried with $(D Context.getSource()) so that these
2982          * attributes can be modified if desired, (eg. to create a
2983          * repeating pattern with $(D Pattern.setExtend())).
2984          *
2985          * Params:
2986          * x = User-space X coordinate for surface origin
2987          * y = User-space Y coordinate for surface origin
2988          */
2989         void setSourceSurface(Surface sur, double x, double y)
2990         {
2991             cairo_set_source_surface(this.nativePointer, sur.nativePointer, x, y);
2992             checkError();
2993         }
2994         ///ditto
2995         void setSourceSurface(Surface sur, Point!double p1)
2996         {
2997             cairo_set_source_surface(this.nativePointer, sur.nativePointer, p1.x, p1.y);
2998             checkError();
2999         }
3000 
3001         /**
3002          * Set the antialiasing mode of the rasterizer used for
3003          * drawing shapes. This value is a hint, and a particular
3004          * backend may or may not support a particular value. At
3005          * the current time, no backend supports CAIRO_ANTIALIAS_SUBPIXEL
3006          * when drawing shapes.
3007          *
3008          * Note that this option does not affect text rendering,
3009          * instead see $(D FontOptions.setAntialias()).
3010          */
3011         void setAntiAlias(AntiAlias antialias)
3012         {
3013             cairo_set_antialias(this.nativePointer, antialias);
3014             checkError();
3015         }
3016 
3017         /**
3018          * Gets the current shape antialiasing mode, as set by $(D setAntiAlias).
3019          */
3020         AntiAlias getAntiAlias()
3021         {
3022             scope(exit)
3023                 checkError();
3024             return cairo_get_antialias(this.nativePointer);
3025         }
3026 
3027         ///Convenience property
3028         @property void antiAlias(AntiAlias aa)
3029         {
3030             setAntiAlias(aa);
3031         }
3032 
3033         ///ditto
3034         @property AntiAlias antiAlias()
3035         {
3036             return getAntiAlias();
3037         }
3038 
3039         /**
3040          * Sets the dash pattern to be used by $(D stroke()). A dash
3041          * pattern is specified by dashes, an array of positive values.
3042          * Each value provides the length of alternate "on" and
3043          * "off" portions of the stroke. The offset specifies an offset
3044          * into the pattern at which the stroke begins.
3045          *
3046          * Each "on" segment will have caps applied as if the segment
3047          * were a separate sub-path. In particular, it is valid to use
3048          * an "on" length of 0.0 with CAIRO_LINE_CAP_ROUND or
3049          * CAIRO_LINE_CAP_SQUARE in order to distributed dots
3050          * or squares along a path.
3051          *
3052          * Note: The length values are in user-space units as
3053          * evaluated at the time of stroking. This is not necessarily
3054          * the same as the user space at the time of $(D setDash()).
3055          *
3056          * If dashes is empty dashing is disabled.
3057          *
3058          * If dashes.length is 1 a symmetric pattern is assumed with alternating
3059          * on and off portions of the size specified by the single value
3060          * in dashes.
3061          *
3062          * If any value in dashes is negative, or if all values are 0, then
3063          * cr will be put into an error state with a
3064          * status of CAIRO_STATUS_INVALID_DASH.
3065          *
3066          * Params:
3067          * dashes = an array specifying alternate lengths of on and off stroke portions
3068          * offset = an offset into the dash pattern at which the stroke should start
3069          */
3070         void setDash(const(double[]) dashes, double offset)
3071         {
3072             cairo_set_dash(this.nativePointer, dashes.ptr, dashes.length.toCairoCount(), offset);
3073             checkError();
3074         }
3075 
3076         /**
3077          * Gets the current dash array.
3078          */
3079         double[] getDash(out double offset)
3080         {
3081             double[] dashes = new double[](this.getDashCount());
3082             cairo_get_dash(this.nativePointer, dashes.ptr, &offset);
3083             checkError();
3084             return dashes;
3085         }
3086 
3087         /**
3088          * This function returns the length of the dash array in cr
3089          * (0 if dashing is not currently in effect).
3090          */
3091         int getDashCount()
3092         {
3093             scope(exit)
3094                 checkError();
3095             return cairo_get_dash_count(this.nativePointer);
3096         }
3097 
3098         /**
3099          * Set the current fill rule within the cairo context. The fill
3100          * rule is used to determine which regions are inside or outside
3101          * a complex (potentially self-intersecting) path. The current
3102          * fill rule affects both $(D fill()) and $(D clip()). See
3103          * $(D FillRule) for details on the semantics of each
3104          * available fill rule.
3105          *
3106          * The default fill rule is CAIRO_FILL_RULE_WINDING.
3107          */
3108         void setFillRule(FillRule rule)
3109         {
3110             cairo_set_fill_rule(this.nativePointer, rule);
3111             checkError();
3112         }
3113 
3114         /**
3115          * Gets the current fill rule, as set by $(D setFillRule).
3116          */
3117         FillRule getFillRule()
3118         {
3119             scope(exit)
3120                 checkError();
3121             return cairo_get_fill_rule(this.nativePointer);
3122         }
3123 
3124         ///Convenience property
3125         @property void fillRule(FillRule rule)
3126         {
3127             setFillRule(rule);
3128         }
3129 
3130         ///ditto
3131         @property FillRule fillRule()
3132         {
3133             return getFillRule();
3134         }
3135 
3136         /**
3137          * Sets the current line cap style within the cairo context.
3138          * See $(D LineCap) for details about how the available
3139          * line cap styles are drawn.
3140          *
3141          * As with the other stroke parameters, the current line cap
3142          * style is examined by $(D stroke()), $(D strokeExtents())
3143          * and $(D strokeToPath()), but does not have any
3144          * effect during path construction.
3145          *
3146          * The default line cap style is CAIRO_LINE_CAP_BUTT.
3147          */
3148         void setLineCap(LineCap cap)
3149         {
3150             cairo_set_line_cap(this.nativePointer, cap);
3151             checkError();
3152         }
3153 
3154         /**
3155          * Gets the current line cap style, as set by $(D setLineCap()).
3156          */
3157         LineCap getLineCap()
3158         {
3159             scope(exit)
3160                 checkError();
3161             return cairo_get_line_cap(this.nativePointer);
3162         }
3163 
3164         ///Convenience property
3165         @property void lineCap(LineCap cap)
3166         {
3167             setLineCap(cap);
3168         }
3169 
3170         ///ditto
3171         @property LineCap lineCap()
3172         {
3173             return getLineCap();
3174         }
3175 
3176         /**
3177          * Sets the current line join style within the cairo context.
3178          * See $(D LineJoin) for details about how the available
3179          * line join styles are drawn.
3180          *
3181          * As with the other stroke parametes, the current line join
3182          * style is examined by $(D stroke()), $(D strokeExtents())
3183          * and $(D strokeToPath()), but does not have any effect
3184          * during path construction.
3185          *
3186          * The default line join style is CAIRO_LINE_JOIN_MITER.
3187          */
3188         void setLineJoin(LineJoin join)
3189         {
3190             cairo_set_line_join(this.nativePointer, join);
3191             checkError();
3192         }
3193 
3194         /**
3195          * Gets the current line join style, as set by $(D setLineJoin)
3196          */
3197         LineJoin getLineJoin()
3198         {
3199             scope(exit)
3200                 checkError();
3201             return cairo_get_line_join(this.nativePointer);
3202         }
3203 
3204         ///Convenience property
3205         @property void lineJoin(LineJoin join)
3206         {
3207             setLineJoin(join);
3208         }
3209 
3210         ///ditto
3211         @property LineJoin lineJoin()
3212         {
3213             return getLineJoin();
3214         }
3215 
3216         /**
3217          * Sets the current line width within the cairo context. The line
3218          * width value specifies the diameter of a pen that is circular
3219          * in user space, (though device-space pen may be an ellipse
3220          * in general due to scaling/shear/rotation of the CTM).
3221          *
3222          * Note: When the description above refers to user space and CTM
3223          * it refers to the user space and CTM in effect at the time
3224          * of the stroking operation, not the user space and CTM in
3225          * effect at the time of the call to $(D setLineWidth()).
3226          * The simplest usage makes both of these spaces identical.
3227          * That is, if there is no change to the CTM between a call to
3228          * $(D setLineWidth()) and the stroking operation, then one
3229          * can just pass user-space values to $(D setLineWidth()) and
3230          * ignore this note.
3231          *
3232          * As with the other stroke parameters, the current line width is
3233          * examined by $(D stroke()), $(D strokeExtents())
3234          * and $(D strokeToPath()), but does not have any effect during
3235          * path construction.
3236          *
3237          * The default line width value is 2.0.
3238          */
3239         void setLineWidth(double width)
3240         {
3241             cairo_set_line_width(this.nativePointer, width);
3242             checkError();
3243         }
3244 
3245         /**
3246          * This function returns the current line width value exactly
3247          * as set by cairo_set_line_width(). Note that the value is
3248          * unchanged even if the CTM has changed between the calls
3249          * to $(D setLineWidth()) and $(D getLineWidth()).
3250          */
3251         double getLineWidth()
3252         {
3253             scope(exit)
3254                 checkError();
3255             return cairo_get_line_width(this.nativePointer);
3256         }
3257 
3258         ///Convenience property
3259         @property void lineWidth(double width)
3260         {
3261             setLineWidth(width);
3262         }
3263 
3264         ///ditto
3265         @property double lineWidth()
3266         {
3267             return getLineWidth();
3268         }
3269 
3270         /**
3271          * Sets the current miter limit within the cairo context.
3272          *
3273          * If the current line join style is set to
3274          * CAIRO_LINE_JOIN_MITER (see cairo_set_line_join()), the miter
3275          * limit is used to determine whether the lines should be joined
3276          * with a bevel instead of a miter. Cairo divides the length of
3277          * the miter by the line width. If the result is greater than the
3278          * miter limit, the style is converted to a bevel.
3279          *
3280          * As with the other stroke parameters, the current line miter
3281          * limit is examined by $(D stroke()), $(D strokeExtents())
3282          * and $(D strokeToPath()), but does not have any effect
3283          * during path construction.
3284          *
3285          * The default miter limit value is 10.0, which will convert
3286          * joins with interior angles less than 11 degrees to bevels
3287          * instead of miters. For reference, a miter limit of 2.0 makes
3288          * the miter cutoff at 60 degrees, and a miter limit of 1.414
3289          * makes the cutoff at 90 degrees.
3290          *
3291          * A miter limit for a desired angle can be computed as: miter
3292          * limit = 1/sin(angle/2)
3293          */
3294         void setMiterLimit(double limit)
3295         {
3296             cairo_set_miter_limit(this.nativePointer, limit);
3297             checkError();
3298         }
3299 
3300         /**
3301          * Gets the current miter limit, as set by $(D setMiterLimit)
3302          */
3303         double getMiterLimit()
3304         {
3305             scope(exit)
3306                 checkError();
3307             return cairo_get_miter_limit(this.nativePointer);
3308         }
3309 
3310         ///Convenience property
3311         @property void miterLimit(double limit)
3312         {
3313             setMiterLimit(limit);
3314         }
3315 
3316         ///ditto
3317         @property double miterLimit()
3318         {
3319             return getMiterLimit();
3320         }
3321 
3322         /**
3323          * Sets the compositing operator to be used for all
3324          * drawing operations. See $(D Operator) for details on
3325          * the semantics of each available compositing operator.
3326          *
3327          * The default operator is CAIRO_OPERATOR_OVER.
3328          */
3329         void setOperator(Operator op)
3330         {
3331             cairo_set_operator(this.nativePointer, op);
3332             checkError();
3333         }
3334 
3335         /**
3336          * Gets the current compositing operator for a cairo context.
3337          */
3338         Operator getOperator()
3339         {
3340             scope(exit)
3341                 checkError();
3342             return cairo_get_operator(this.nativePointer);
3343         }
3344 
3345         ///Convenience property
3346         @property void operator(Operator op)
3347         {
3348             setOperator(op);
3349         }
3350 
3351         ///ditto
3352         @property Operator operator()
3353         {
3354             return getOperator();
3355         }
3356 
3357         /**
3358          * Sets the tolerance used when converting paths into trapezoids.
3359          * Curved segments of the path will be subdivided until the maximum
3360          * deviation between the original path and the polygonal
3361          * approximation is less than tolerance. The default value
3362          * is 0.1. A larger value will give better performance, a smaller
3363          * value, better appearance. (Reducing the value from the
3364          * default value of 0.1 is unlikely to improve appearance
3365          * significantly.) The accuracy of paths within Cairo is limited
3366          * by the precision of its internal arithmetic, and the prescribed
3367          * tolerance is restricted to the smallest representable
3368          * internal value.
3369          */
3370         void setTolerance(double tolerance)
3371         {
3372             cairo_set_tolerance(this.nativePointer, tolerance);
3373             checkError();
3374         }
3375 
3376         /**
3377          * Gets the current tolerance value, as set by $(D setTolerance)
3378          */
3379         double getTolerance()
3380         {
3381             scope(exit)
3382                 checkError();
3383             return cairo_get_tolerance(this.nativePointer);
3384         }
3385 
3386         ///Convenience property
3387         @property void tolerance(double tolerance)
3388         {
3389             setTolerance(tolerance);
3390         }
3391 
3392         ///ditto
3393         @property double tolerance()
3394         {
3395             return getTolerance();
3396         }
3397 
3398         /**
3399          * Establishes a new clip region by intersecting the current
3400          * clip region with the current path as it would be filled by
3401          * $(D fill()) and according to the current
3402          * fill rule (see $(D setFillRule())).
3403          *
3404          * After $(D clip()), the current path will be cleared from the
3405          * cairo context.
3406          *
3407          * The current clip region affects all drawing operations by
3408          * effectively masking out any changes to the surface that are
3409          * outside the current clip region.
3410          *
3411          * Calling $(D clip()) can only make the clip region smaller,
3412          * never larger. But the current clip is part of the graphics state,
3413          * so a temporary restriction of the clip region can be achieved
3414          * by calling $(D clip()) within a $(D save())/$(D restore())
3415          * pair. The only other means of increasing the size of the clip
3416          * region is $(D resetClip()).
3417          */
3418         void clip()
3419         {
3420             cairo_clip(this.nativePointer);
3421             checkError();
3422         }
3423 
3424         /**
3425          * Establishes a new clip region by intersecting the current clip
3426          * region with the current path as it would be filled by
3427          * $(D fill()) and according to the current fill rule
3428          * (see $(D setFillRule())).
3429          *
3430          * Unlike $(D clip()), $(D clipPreserve()) preserves the
3431          * path within the cairo context.
3432          *
3433          * The current clip region affects all drawing operations by
3434          * effectively masking out any changes to the surface that are
3435          * outside the current clip region.
3436          *
3437          * Calling $(D clipPreserve()) can only make the clip region
3438          * smaller, never larger. But the current clip is part of the
3439          * graphics state, so a temporary restriction of the clip region
3440          * can be achieved by calling $(D clip()) within a $(D save())/$(D restore())
3441          * pair. The only other means of increasing the size of the clip
3442          * region is $(D resetClip()).
3443          */
3444         void clipPreserve()
3445         {
3446             cairo_clip_preserve(this.nativePointer);
3447             checkError();
3448         }
3449 
3450         /**
3451          * Computes a bounding box in user coordinates covering the area
3452          * inside the current clip.
3453          */
3454         Box clipExtents()
3455         {
3456             Box tmp;
3457             cairo_clip_extents(this.nativePointer, &tmp.point1.x, &tmp.point1.y, &tmp.point2.x, &tmp.point2.y);
3458             checkError();
3459             return tmp;
3460         }
3461 
3462         /**
3463          * Tests whether the given point is inside the area that would
3464          * be visible through the current clip, i.e. the area that
3465          * would be filled by a cairo_paint() operation.
3466          *
3467          * See $(D clip()), and $(D clipPreserve()).
3468          */
3469         bool inClip(Point!double point)
3470         {
3471             scope(exit)
3472                 checkError();
3473             return cairo_in_clip(this.nativePointer, point.x, point.y) ? true : false;
3474         }
3475 
3476         /**
3477          * Reset the current clip region to its original, unrestricted
3478          * state. That is, set the clip region to an infinitely
3479          * large shape containing the target surface. Equivalently,
3480          * if infinity is too hard to grasp, one can imagine the clip
3481          * region being reset to the exact bounds of the target surface.
3482          *
3483          * Note that code meant to be reusable should not call
3484          * $(D resetClip()) as it will cause results unexpected by
3485          * higher-level code which calls $(D clip()). Consider using
3486          * $(D save()) and $(D restore()) around $(D clip()) as a
3487          * more robust means of temporarily restricting the clip region.
3488          */
3489         void resetClip()
3490         {
3491             cairo_reset_clip(this.nativePointer);
3492             checkError();
3493         }
3494 
3495         /**
3496          * Gets the current clip region as a list of rectangles in user
3497          * coordinates.
3498          */
3499         Rectangle!(double)[] copyClipRectangles()
3500         {
3501             Rectangle!(double)[] list;
3502             auto nList = cairo_copy_clip_rectangle_list(this.nativePointer);
3503             scope(exit)
3504                 cairo_rectangle_list_destroy(nList);
3505             throwError(nList.status);
3506             list.length = nList.num_rectangles;
3507             for(int i = 0; i < list.length; i++)
3508             {
3509                 list[i].point.x = nList.rectangles[i].x;
3510                 list[i].point.y = nList.rectangles[i].y;
3511                 list[i].width = nList.rectangles[i].width;
3512                 list[i].height = nList.rectangles[i].height;
3513             }
3514             return list;
3515         }
3516 
3517         /**
3518          * A drawing operator that fills the current path according to
3519          * the current fill rule, (each sub-path is implicitly closed
3520          * before being filled). After c$(D fill()), the current
3521          * path will be cleared from the cairo context. See
3522          * $(D setFillRule()) and $(D fillPreserve()).
3523          */
3524         void fill()
3525         {
3526             cairo_fill(this.nativePointer);
3527             checkError();
3528         }
3529 
3530         /**
3531          * A drawing operator that fills the current path according to
3532          * the current fill rule, (each sub-path is implicitly closed
3533          * before being filled). Unlike $(D fill()), $(D fillPreserve())
3534          * preserves the path within the cairo context.
3535          */
3536         void fillPreserve()
3537         {
3538             cairo_fill_preserve(this.nativePointer);
3539             checkError();
3540         }
3541 
3542         /**
3543          * Computes a bounding box in user coordinates covering the area
3544          * that would be affected, (the "inked" area), by a
3545          * $(D fill()) operation given the current path and fill parameters.
3546          * If the current path is empty, returns an empty rectangle
3547          * ((0,0), (0,0)). Surface dimensions and clipping are not
3548          * taken into account.
3549          *
3550          * Contrast with $(D pathExtents()), which is similar, but
3551          * returns non-zero extents for some paths with no inked area,
3552          * (such as a simple line segment).
3553          *
3554          * Note that $(D fillExtents()) must necessarily do more work
3555          * to compute the precise inked areas in light of the fill rule,
3556          * so $(D pathExtents()) may be more desirable for sake of
3557          * performance if the non-inked path extents are desired.
3558          *
3559          * See $(D fill()), $(D setFillRule()) and $(D fillPreserve()).
3560          */
3561         Box fillExtends()
3562         {
3563             Box tmp;
3564             cairo_fill_extents(this.nativePointer, &tmp.point1.x, &tmp.point1.y, &tmp.point2.x, &tmp.point2.y);
3565             checkError();
3566             return tmp;
3567         }
3568 
3569         /**
3570          * Tests whether the given point is inside the area that would
3571          * be affected by a cairo_fill() operation given the current path
3572          * and filling parameters. Surface dimensions and clipping are not
3573          * taken into account.
3574          *
3575          * See $(D fill()), $(D setFillRule()) and $(D fillPreserve()).
3576          */
3577         bool inFill(Point!double point)
3578         {
3579             scope(exit)
3580                 checkError();
3581             return cairo_in_fill(this.nativePointer, point.x, point.y) ? true : false;
3582         }
3583 
3584         /**
3585          * A drawing operator that paints the current source using the
3586          * alpha channel of pattern as a mask. (Opaque areas of pattern
3587          * are painted with the source, transparent areas are not painted.)
3588          */
3589         void mask(Pattern pattern)
3590         {
3591             cairo_mask(this.nativePointer, pattern.nativePointer);
3592             checkError();
3593         }
3594 
3595         /**
3596          * A drawing operator that paints the current source using
3597          * the alpha channel of surface as a mask. (Opaque areas of
3598          * surface are painted with the source, transparent areas
3599          * are not painted.)
3600          *
3601          * Params:
3602          * location = coordinates at which to place the origin of surface
3603          */
3604         void maskSurface(Surface surface, Point!double location)
3605         {
3606             cairo_mask_surface(this.nativePointer, surface.nativePointer, location.x, location.y);
3607             checkError();
3608         }
3609         ///ditto
3610         void maskSurface(Surface surface, double x, double y)
3611         {
3612             cairo_mask_surface(this.nativePointer, surface.nativePointer, x, y);
3613             checkError();
3614         }
3615 
3616         /**
3617          * A drawing operator that paints the current source everywhere
3618          * within the current clip region.
3619          */
3620         void paint()
3621         {
3622             cairo_paint(this.nativePointer);
3623             checkError();
3624         }
3625 
3626         /**
3627          * A drawing operator that paints the current source everywhere
3628          * within the current clip region using a mask of constant alpha
3629          * value alpha. The effect is similar to $(D paint()), but
3630          * the drawing is faded out using the alpha value.
3631          */
3632         void paintWithAlpha(double alpha)
3633         {
3634             cairo_paint_with_alpha(this.nativePointer, alpha);
3635             checkError();
3636         }
3637 
3638         /**
3639          * A drawing operator that strokes the current path according to
3640          * the current line width, line join, line cap, and dash settings.
3641          * After $(D stroke()), the current path will be cleared from
3642          * the cairo context. See $(D setLineWidth()),
3643          * $(D setLineJoin()), $(D setLineCap()), $(D setDash()),
3644          * and $(D strokePreserve()).
3645          *
3646          * Note: Degenerate segments and sub-paths are treated specially
3647          * and provide a useful result. These can result in two
3648          * different situations:
3649          *
3650          * 1. Zero-length "on" segments set in cairo_set_dash(). If the
3651          * cap style is CAIRO_LINE_CAP_ROUND or CAIRO_LINE_CAP_SQUARE
3652          * then these segments will be drawn as circular dots or squares
3653          * respectively. In the case of CAIRO_LINE_CAP_SQUARE, the
3654          * orientation of the squares is determined by the direction
3655          * of the underlying path.
3656          *
3657          * 2. A sub-path created by $(D moveTo()) followed by either a
3658          * $(D closePath()) or one or more calls to $(D lineTo()) to
3659          * the same coordinate as the $(D moveTo()). If the cap style
3660          * is CAIRO_LINE_CAP_ROUND then these sub-paths will be drawn as
3661          * circular dots. Note that in the case of CAIRO_LINE_CAP_SQUARE
3662          * a degenerate sub-path will not be drawn at all, (since the
3663          * correct orientation is indeterminate).
3664          *
3665          * In no case will a cap style of CAIRO_LINE_CAP_BUTT cause
3666          * anything to be drawn in the case of either degenerate
3667          * segments or sub-paths.
3668          */
3669         void stroke()
3670         {
3671             cairo_stroke(this.nativePointer);
3672             checkError();
3673         }
3674 
3675         /**
3676          * A drawing operator that strokes the current path according to
3677          * the current line width, line join, line cap, and dash settings.
3678          * Unlike $(D stroke()), $(D strokePreserve()) preserves
3679          * the path within the cairo context.
3680          *
3681          * See $(D setLineWidth()), $(D setLineJoin()),
3682          * $(D setLineCap()), $(D set_dash()), and $(D strokePreserve()).
3683          */
3684         void strokePreserve()
3685         {
3686             cairo_stroke_preserve(this.nativePointer);
3687             checkError();
3688         }
3689 
3690         /**
3691          * Computes a bounding box in user coordinates covering the area
3692          * that would be affected, (the "inked" area), by a $(D stroke())
3693          * operation given the current path and stroke parameters. If the
3694          * current path is empty, returns an empty rectangle ((0,0), (0,0)).
3695          * Surface dimensions and clipping are not taken into account.
3696          *
3697          * Note that if the line width is set to exactly zero, then
3698          * $(D strokeExtents()) will return an empty rectangle.
3699          * Contrast with $(D pathExtents()) which can be used to
3700          * compute the non-empty bounds as the line width approaches zero.
3701          *
3702          * Note that $(D strokeExtents()) must necessarily do more
3703          * work to compute the precise inked areas in light of the
3704          * stroke parameters, so $(D pathExtents()) may be more
3705          * desirable for sake of performance if non-inked path extents
3706          * are desired.
3707          *
3708          * See $(D stroke()), $(D setLineWidth()), $(D setLineJoin()),
3709          * $(D setLineCap()), $(D set_dash()), and $(D strokePreserve()).
3710          */
3711         Box strokeExtends()
3712         {
3713             Box tmp;
3714             cairo_stroke_extents(this.nativePointer, &tmp.point1.x, &tmp.point1.y, &tmp.point2.x, &tmp.point2.y);
3715             checkError();
3716             return tmp;
3717         }
3718 
3719         /**
3720          * Tests whether the given point is inside the area that would be
3721          * affected by a cairo_stroke() operation given the current path
3722          * and stroking parameters. Surface dimensions and clipping are
3723          * not taken into account.
3724          *
3725          * See $(D stroke()), $(D setLineWidth()), $(D setLineJoin()),
3726          * $(D setLineCap()), $(D set_dash()), and $(D strokePreserve()).
3727          */
3728         bool inStroke(Point!double point)
3729         {
3730             scope(exit)
3731                 checkError();
3732             return cairo_in_stroke(this.nativePointer, point.x, point.y) ? true : false;
3733         }
3734         ///ditto
3735         bool inStroke(double x, double y)
3736         {
3737             scope(exit)
3738                 checkError();
3739             return cairo_in_stroke(this.nativePointer, x, y) ? true : false;
3740         }
3741 
3742         /**
3743          * Emits the current page for backends that support multiple
3744          * pages, but doesn't clear it, so, the contents of the current
3745          * page will be retained for the next page too.
3746          * Use $(D showPage()) if you want to get an empty page after
3747          * the emission.
3748          *
3749          * This is a convenience function that simply calls $(D Surface.copyPage())
3750          * on this's target.
3751          */
3752         void copyPage()
3753         {
3754             cairo_copy_page(this.nativePointer);
3755             checkError();
3756         }
3757 
3758         /**
3759          * Emits and clears the current page for backends that support
3760          * multiple pages. Use $(D copyPage()) if you don't want to
3761          * clear the page.
3762          *
3763          * This is a convenience function that simply calls
3764          * $(D Surface.showPage()) on this's target.
3765          */
3766         void showPage()
3767         {
3768             cairo_show_page(this.nativePointer);
3769             checkError();
3770         }
3771 
3772         /*
3773         void setUserData(const cairo_user_data_key_t* key, void* data, cairo_destroy_func_t destroy)
3774         {
3775             cairo_set_user_data(this.nativePointer, key, data, destroy);
3776             checkError();
3777         }
3778 
3779         void* getUserData(const cairo_user_data_key_t* key)
3780         {
3781             scope(exit)
3782                 checkError();
3783             return cairo_get_user_data(this.nativePointer, key);
3784         }
3785         */
3786 
3787         /**
3788          * Creates a copy of the current path and returns it to the user
3789          * as a $(D Path). See $(D PathRange) for hints on how to
3790          * iterate over the returned data structure.
3791          */
3792         Path copyPath()
3793         {
3794             return Path(cairo_copy_path(this.nativePointer));
3795         }
3796 
3797         /**
3798          * Gets a flattened copy of the current path and returns it to
3799          * the user as a $(D Path). See $(D PathRange) for hints
3800          * on how to iterate over the returned data structure.
3801          *
3802          * This function is like $(D copyPath()) except that any
3803          * curves in the path will be approximated with piecewise-linear
3804          * approximations, (accurate to within the current tolerance value).
3805          * That is, the result is guaranteed to not have any elements of
3806          * type CAIRO_PATH_CURVE_TO which will instead be replaced by
3807          * a series of CAIRO_PATH_LINE_TO elements.
3808          */
3809         Path copyPathFlat()
3810         {
3811             return Path(cairo_copy_path_flat(this.nativePointer));
3812         }
3813 
3814         /**
3815          * Append the path onto the current path. The path may be
3816          * the return value from one of $(D copyPath()) or $(D copyPathFlat()).
3817          */
3818         void appendPath(Path p)
3819         {
3820             cairo_append_path(this.nativePointer, p.nativePointer);
3821             checkError();
3822         }
3823 
3824         /**
3825          * appendPath for user created paths. There is no high level API
3826          * for user defined paths. Use $(D appendPath(Path p)) for paths
3827          * which were obtained from cairo.
3828          *
3829          * See $(D cairo_path_t) for details
3830          * on how the path data structure should be initialized,
3831          * and note that path.status must be initialized to CAIRO_STATUS_SUCCESS.
3832          *
3833          * Warning:
3834          * $(RED Only use this if you know what your doing!
3835          * This function should not be needed for standard cairoD usage.)
3836          */
3837         void appendPath(cairo_path_t* path)
3838         {
3839             cairo_append_path(this.nativePointer, path);
3840             checkError();
3841         }
3842 
3843         /**
3844          * Returns whether a current point is defined on the current path.
3845          * See $(D getCurrentPoint()) for details on the current point.
3846          */
3847         bool hasCurrentPoint()
3848         {
3849             scope(exit)
3850                 checkError();
3851             return cairo_has_current_point(this.nativePointer) ? true : false;
3852         }
3853 
3854         /**
3855          * Gets the current point of the current path, which is conceptually
3856          * the final point reached by the path so far.
3857          *
3858          * The current point is returned in the user-space coordinate system.
3859          * If there is no defined current point or if cr is in an error status,
3860          * x and y will both be set to 0.0. It is possible to check
3861          * this in advance with $(D hasCurrentPoint()).
3862          *
3863          * Most path construction functions alter the current point. See
3864          * the following for details on how they affect the current point:
3865          * $(D newPath()), $(D newSubPath()), $(D appendPath()),
3866          * $(D closePath()), $(D moveTo()), $(D lineTo()),
3867          * $(D curveTo()), $(D relMoveTo()), $(D relLineTo()),
3868          * $(D relCurveTo()), $(D arc()), $(D arcNegative()),
3869          * $(D rectangle()), $(D textPath()), $(D glyphPath()),
3870          * $(D strokeToPath()).
3871          *
3872          * Some functions use and alter the current point but do not
3873          * otherwise change current path: $(D showText()).
3874          *
3875          * Some functions unset the current path and as a result,
3876          * current point: $(D fill()), $(D stroke()).
3877          */
3878         Point!double getCurrentPoint()
3879         {
3880             Point!double tmp;
3881             cairo_get_current_point(this.nativePointer, &tmp.x, &tmp.y);
3882             checkError();
3883             return tmp;
3884         }
3885 
3886         ///convenience alias
3887         alias getCurrentPoint currentPoint;
3888 
3889         /**
3890          * Clears the current path. After this call there will be no path
3891          * and no current point.
3892          */
3893         void newPath()
3894         {
3895             cairo_new_path(this.nativePointer);
3896             checkError();
3897         }
3898 
3899         /**
3900          * Begin a new sub-path. Note that the existing path is not affected.
3901          * After this call there will be no current point.
3902          *
3903          * In many cases, this call is not needed since new sub-paths are
3904          * frequently started with cairo_move_to().
3905          *
3906          * A call to $(D newSubPath()) is particularly useful when
3907          * beginning a new sub-path with one of the $(D arc()) calls.
3908          * This makes things easier as it is no longer necessary to
3909          * manually compute the arc's initial coordinates for a call
3910          * to $(D moveTo()).
3911          */
3912         void newSubPath()
3913         {
3914             cairo_new_sub_path(this.nativePointer);
3915             checkError();
3916         }
3917 
3918         /**
3919          * Adds a line segment to the path from the current point to
3920          * the beginning of the current sub-path, (the most recent
3921          * point passed to $(D moveTo())), and closes this sub-path.
3922          * After this call the current point will be at the joined
3923          * endpoint of the sub-path.
3924          *
3925          * The behavior of $(D closePath()) is distinct from simply
3926          * calling $(D lineTo()) with the equivalent coordinate in
3927          * the case of stroking. When a closed sub-path is stroked,
3928          * there are no caps on the ends of the sub-path. Instead,
3929          * there is a line join connecting the final and initial
3930          * segments of the sub-path.
3931          *
3932          * If there is no current point before the call to $(D closePath()),
3933          * this function will have no effect.
3934          *
3935          * Note: As of cairo version 1.2.4 any call to $(D closePath())
3936          * will place an explicit MOVE_TO element into the path immediately
3937          * after the CLOSE_PATH element, (which can be seen in
3938          * $(D copyPath()) for example). This can simplify path processing
3939          * in some cases as it may not be necessary to save the "last
3940          * move_to point" during processing as the MOVE_TO immediately
3941          * after the CLOSE_PATH will provide that point.
3942          */
3943         void closePath()
3944         {
3945             cairo_close_path(this.nativePointer);
3946             checkError();
3947         }
3948 
3949         /**
3950          * Adds a circular arc of the given radius to the current path.
3951          * The arc is centered at center, begins at angle1 and proceeds in
3952          * the direction of increasing angles to end at angle2.
3953          * If angle2 is less than angle1 it will be progressively
3954          * increased by 2*PI until it is greater than angle1.
3955          *
3956          * If there is a current point, an initial line segment will be
3957          * added to the path to connect the current point to the beginning
3958          * of the arc. If this initial line is undesired, it can be
3959          * avoided by calling $(D newSubPath()) before calling $(D arc()).
3960          *
3961          * Angles are measured in radians. An angle of 0.0 is in the
3962          * direction of the positive X axis (in user space). An angle
3963          * of PI/2.0 radians (90 degrees) is in the direction of the
3964          * positive Y axis (in user space). Angles increase in the
3965          * direction from the positive X axis toward the positive Y
3966          * axis. So with the default transformation matrix, angles
3967          * increase in a clockwise direction.
3968          *
3969          * (To convert from degrees to radians, use degrees * (PI / 180))
3970          *
3971          * This function gives the arc in the direction of increasing angles;
3972          * see $(D arcNegative()) to get the arc in the direction of decreasing angles.
3973          *
3974          * The arc is circular in user space. To achieve an elliptical arc,
3975          * you can scale the current transformation matrix by different
3976          * amounts in the X and Y directions. For example, to draw an
3977          * ellipse in the box given by x, y, width, height:
3978          * -------------------
3979          * cr.save();
3980          * cr.translate(x + width / 2, y + height / 2);
3981          * cr.scale(width / 2, height / 2);
3982          * cr.arc(Point(0, 0), 1, 0, 2 * PI);
3983          * cr.restore();
3984          * -------------------
3985          * Params:
3986          * radius = the radius of the arc
3987          * angle1 = the start angle, in radians
3988          * angle2 = the end angle, in radians
3989          */
3990         void arc(Point!double center, double radius, double angle1, double angle2)
3991         {
3992             cairo_arc(this.nativePointer, center.x, center.y, radius, angle1, angle2);
3993             checkError();
3994         }
3995         ///ditto
3996         void arc(double centerX, double centerY, double radius, double angle1, double angle2)
3997         {
3998             cairo_arc(this.nativePointer, centerX, centerY, radius, angle1, angle2);
3999             checkError();
4000         }
4001 
4002         /**
4003          * Adds a circular arc of the given radius to the current path.
4004          * The arc is centered at center, begins at angle1 and proceeds
4005          * in the direction of decreasing angles to end at angle2.
4006          * If angle2 is greater than angle1 it will be progressively
4007          * decreased by 2*PI until it is less than angle1.
4008          *
4009          * See $(D arc()) for more details. This function differs only
4010          * in the direction of the arc between the two angles.
4011          *
4012          * Params:
4013          * radius = the radius of the arc
4014          * angle1 = the start angle, in radians
4015          * angle2 = the end angle, in radians
4016          */
4017         void arcNegative(Point!double center, double radius, double angle1, double angle2)
4018         {
4019             cairo_arc_negative(this.nativePointer, center.x, center.y, radius, angle1, angle2);
4020             checkError();
4021         }
4022         ///ditto
4023         void arcNegative(double centerX, double centerY, double radius, double angle1, double angle2)
4024         {
4025             cairo_arc_negative(this.nativePointer, centerX, centerY, radius, angle1, angle2);
4026             checkError();
4027         }
4028 
4029         /**
4030          * Adds a cubic Bézier spline to the path from the current
4031          * point to position p3 in user-space coordinates, using p1 and p2
4032          * as the control points. After this call the current point will be p3.
4033          *
4034          * If there is no current point before the call to $(D curveTo())
4035          * this function will behave as if preceded by a call to
4036          * $(D moveTo(p1)).
4037          *
4038          * Params:
4039          * p1 = First control point
4040          * p2 = Second control point
4041          * p3 = End of the curve
4042          */
4043         void curveTo(Point!double p1, Point!double p2, Point!double p3)
4044         {
4045             cairo_curve_to(this.nativePointer, p1.x, p1.y, p2.x, p2.y, p3.x, p3.y);
4046             checkError();
4047         }
4048         ///ditto
4049         void curveTo(double p1x, double p1y, double p2x, double p2y,
4050             double p3x, double p3y)
4051         {
4052             cairo_curve_to(this.nativePointer, p1x, p1y, p2x, p2y, p3x, p3y);
4053             checkError();
4054         }
4055 
4056         /**
4057          * Adds a line to the path from the current point to position p1
4058          * in user-space coordinates. After this call the current point
4059          * will be p1.
4060          *
4061          * If there is no current point before the call to $(D lineTo())
4062          * this function will behave as $(D moveTo(p1)).
4063          *
4064          * Params:
4065          * p1 = End of the line
4066          */
4067         void lineTo(Point!double p1)
4068         {
4069             cairo_line_to(this.nativePointer, p1.x, p1.y);
4070             checkError();
4071         }
4072         ///ditto
4073         void lineTo(double x, double y)
4074         {
4075             cairo_line_to(this.nativePointer, x, y);
4076             checkError();
4077         }
4078 
4079         /**
4080          * Begin a new sub-path. After this call the current point will be p1.
4081          */
4082         void moveTo(Point!double p1)
4083         {
4084             cairo_move_to(this.nativePointer, p1.x, p1.y);
4085             checkError();
4086         }
4087         ///ditto
4088         void moveTo(double x, double y)
4089         {
4090             cairo_move_to(this.nativePointer, x, y);
4091             checkError();
4092         }
4093 
4094         /**
4095          * Adds a closed sub-path rectangle of the given size to the
4096          * current path at position r.point in user-space coordinates.
4097          * This function is logically equivalent to:
4098          * ---------------------
4099          * cr.moveTo(r.point);
4100          * cr.relLineTo(r.width, 0);
4101          * cr.relLineTo(0, r.height);
4102          * cr.relLineTo(-r.width, 0);
4103          * cr.closePath();
4104          * ---------------------
4105          */
4106         void rectangle(Rectangle!double r)
4107         {
4108             cairo_rectangle(this.nativePointer, r.point.x, r.point.y, r.width, r.height);
4109             checkError();
4110         }
4111         ///ditto
4112         void rectangle(double x, double y, double width, double height)
4113         {
4114             cairo_rectangle(this.nativePointer, x, y, width, height);
4115             checkError();
4116         }
4117 
4118         /**
4119          * Adds closed paths for the glyphs to the current path.
4120          * The generated path if filled, achieves an effect
4121          * similar to that of $(D showGlyphs()).
4122          */
4123         void glyphPath(Glyph[] glyphs)
4124         {
4125             cairo_glyph_path(this.nativePointer, glyphs.ptr, glyphs.length.toCairoCount());
4126             checkError();
4127         }
4128 
4129         /**
4130          * Adds closed paths for text to the current path. The generated
4131          * path if filled, achieves an effect similar to that of
4132          * $(D showText()).
4133          *
4134          * Text conversion and positioning is done similar to $(D showText()).
4135          *
4136          * Like $(D showText()), After this call the current point is moved
4137          * to the origin of where the next glyph would be placed in this
4138          * same progression. That is, the current point will be at the
4139          * origin of the final glyph offset by its advance values. This
4140          * allows for chaining multiple calls to to $(D textPath())
4141          * without having to set current point in between.
4142          *
4143          * Note: The $(D textPath()) function call is part of what the
4144          * cairo designers call the "toy" text API. It is convenient for
4145          * short demos and simple programs, but it is not expected
4146          * to be adequate for serious text-using applications. See
4147          * $(D glyphPath()) for the "real" text path API in cairo.
4148          */
4149         void textPath(string text)
4150         {
4151             cairo_text_path(this.nativePointer, toStringz(text));
4152             checkError();
4153         }
4154 
4155         /**
4156          * Relative-coordinate version of $(D curveTo()).
4157          * All offsets are relative to the current point. Adds a
4158          * cubic Bézier spline to the path from the current point
4159          * to a point offset from the current point by rp3,
4160          * using points offset by rp1 and rp2 as the
4161          * control points. After this call the current point will
4162          * be offset by rp3.
4163          *
4164          * Given a current point of (x, y),
4165          * cairo_rel_curve_to(cr, dx1, dy1, dx2, dy2, dx3, dy3) is logically
4166          * equivalent to
4167          * cairo_curve_to(cr, x+dx1, y+dy1, x+dx2, y+dy2, x+dx3, y+dy3).
4168          *
4169          * It is an error to call this function with no current point.
4170          * Doing so will cause an CairoException with a
4171          * status of CAIRO_STATUS_NO_CURRENT_POINT.
4172          *
4173          * Params:
4174          * rp1 = First control point
4175          * rp2 = Second control point
4176          * rp3 = offset to the end of the curve
4177          */
4178         void relCurveTo(Point!double rp1, Point!double rp2, Point!double rp3)
4179         {
4180             cairo_rel_curve_to(this.nativePointer, rp1.x, rp1.y, rp2.x, rp2.y, rp3.x, rp3.y);
4181             checkError();
4182         }
4183         ///ditto
4184         void relCurveTo(double rp1x, double rp1y, double rp2x, double rp2y,
4185             double rp3x, double rp3y)
4186         {
4187             cairo_rel_curve_to(this.nativePointer, rp1x, rp1y, rp2x, rp2y, rp3x, rp3y);
4188             checkError();
4189         }
4190 
4191         /**
4192          * Relative-coordinate version of $(D lineTo()). Adds a line
4193          * to the path from the current point to a point that is
4194          * offset from the current point by rp1 in user space.
4195          * After this call the current point will be offset by rp1.
4196          *
4197          * Given a current point of (x, y), cairo_rel_line_to(cr, dx, dy)
4198          * is logically equivalent to cairo_line_to(cr, x + dx, y + dy).
4199          *
4200          * It is an error to call this function with no current point.
4201          * Doing so will cause an CairoException with a
4202          * status of CAIRO_STATUS_NO_CURRENT_POINT.
4203          */
4204         void relLineTo(Point!double rp1)
4205         {
4206             cairo_rel_line_to(this.nativePointer, rp1.x, rp1.y);
4207             checkError();
4208         }
4209         ///ditto
4210         void relLineTo(double x, double y)
4211         {
4212             cairo_rel_line_to(this.nativePointer, x, y);
4213             checkError();
4214         }
4215 
4216         /**
4217          * Begin a new sub-path. After this call the current point will
4218          * offset by rp1.
4219          *
4220          * Given a current point of (x, y), cairo_rel_move_to(cr, dx, dy)
4221          * is logically equivalent to cairo_move_to(cr, x + dx, y + dy).
4222          *
4223          * It is an error to call this function with no current point.
4224          * Doing so will cause an CairoException with a status of
4225          * CAIRO_STATUS_NO_CURRENT_POINT.
4226          */
4227         void relMoveTo(Point!double rp1)
4228         {
4229             cairo_rel_move_to(this.nativePointer, rp1.x, rp1.y);
4230             checkError();
4231         }
4232         ///ditto
4233         void relMoveTo(double x, double y)
4234         {
4235             cairo_rel_move_to(this.nativePointer, x, y);
4236             checkError();
4237         }
4238 
4239         /**
4240          * Computes a bounding box in user-space coordinates covering
4241          * the points on the current path. If the current path is empty,
4242          * returns an empty Box ((0,0), (0,0)). Stroke parameters,
4243          * fill rule, surface dimensions and clipping are not taken
4244          * into account.
4245          *
4246          * Contrast with $(D fillExtents()) and $(D strokeExtents())
4247          * which return the extents of only the area that would be "inked"
4248          * by the corresponding drawing operations.
4249          *
4250          * The result of $(D pathExtents()) is defined as equivalent
4251          * to the limit of $(D strokeExtents()) with CAIRO_LINE_CAP_ROUND
4252          * as the line width approaches 0.0, (but never reaching the
4253          * empty-rectangle returned by $(D strokeExtents()) for a
4254          * line width of 0.0).
4255          *
4256          * Specifically, this means that zero-area sub-paths such as
4257          * $(D moveTo());$(D lineTo()) segments, (even degenerate
4258          * cases where the coordinates to both calls are identical),
4259          * will be considered as contributing to the extents. However,
4260          * a lone $(D moveTo()) will not contribute to the
4261          * results of $(D pathExtents()).
4262          */
4263         Box pathExtends()
4264         {
4265             Box tmp;
4266             cairo_path_extents(this.nativePointer, &tmp.point1.x, &tmp.point1.y, &tmp.point2.x, &tmp.point2.y);
4267             checkError();
4268             return tmp;
4269         }
4270 
4271         /**
4272          * Modifies the current transformation matrix (CTM) by translating
4273          * the user-space origin by (tx, ty). This offset is interpreted
4274          * as a user-space coordinate according to the CTM in place
4275          * before the new call to $(D translate()). In other words,
4276          * the translation of the user-space origin takes place
4277          * after any existing transformation.
4278          *
4279          * Params:
4280          * tx = amount to translate in the X direction
4281          * ty = amount to translate in the Y direction
4282          */
4283         void translate(double tx, double ty)
4284         {
4285             cairo_translate(this.nativePointer, tx, ty);
4286             checkError();
4287         }
4288 
4289         /**
4290          * Modifies the current transformation matrix (CTM) by scaling
4291          * the X and Y user-space axes by sx and sy respectively.
4292          * The scaling of the axes takes place after any existing
4293          * transformation of user space.
4294          *
4295          * Params:
4296          * sx = scale factor for the X dimension
4297          * sy = scale factor for the Y dimension
4298          */
4299         void scale(double sx, double sy)
4300         {
4301             cairo_scale(this.nativePointer, sx, sy);
4302             checkError();
4303         }
4304 
4305         ///ditto
4306         void scale(Point!double point)
4307         {
4308             scale(point.x, point.y);
4309         }
4310 
4311         /**
4312          * Modifies the current transformation matrix (CTM) by rotating
4313          * the user-space axes by angle radians. The rotation of the
4314          * axes takes places after any existing transformation of user
4315          * space. The rotation direction for positive angles is from
4316          * the positive X axis toward the positive Y axis.
4317          *
4318          * Params:
4319          * angle = angle (in radians) by which the user-space axes will be rotated
4320          */
4321         void rotate(double angle)
4322         {
4323             cairo_rotate(this.nativePointer, angle);
4324             checkError();
4325         }
4326 
4327         /**
4328          * Modifies the current transformation matrix (CTM) by applying
4329          * matrix as an additional transformation. The new
4330          * transformation of user space takes place after any
4331          * existing transformation.
4332          *
4333          * Params:
4334          * matrix = a transformation to be applied to the user-space axes
4335          */
4336         void transform(const Matrix matrix)
4337         {
4338             cairo_transform(this.nativePointer, &matrix.nativeMatrix);
4339             checkError();
4340         }
4341 
4342         /**
4343          * Modifies the current transformation matrix (CTM) by setting it
4344          * equal to matrix.
4345          *
4346          * Params:
4347          * Matrix = a transformation matrix from user space to device space
4348          */
4349         void setMatrix(const Matrix matrix)
4350         {
4351             cairo_set_matrix(this.nativePointer, &matrix.nativeMatrix);
4352             checkError();
4353         }
4354 
4355         /**
4356          * Returns the current transformation matrix (CTM)
4357          */
4358         Matrix getMatrix()
4359         {
4360             Matrix m;
4361             cairo_get_matrix(this.nativePointer, &m.nativeMatrix);
4362             checkError();
4363             return m;
4364         }
4365 
4366         ///Convenience property
4367         @property void matrix(const Matrix matrix)
4368         {
4369             setMatrix(matrix);
4370         }
4371 
4372         ///ditto
4373         @property Matrix matrix()
4374         {
4375             return getMatrix();
4376         }
4377 
4378         /**
4379          * Resets the current transformation matrix (CTM) by setting it
4380          * equal to the identity matrix. That is, the user-space and
4381          * device-space axes will be aligned and one user-space unit
4382          * will transform to one device-space unit.
4383          */
4384         void identityMatrix()
4385         {
4386             cairo_identity_matrix(this.nativePointer);
4387             checkError();
4388         }
4389 
4390         /**
4391          * Transform a coordinate from user space to device space by
4392          * multiplying the given point by the current
4393          * transformation matrix (CTM).
4394          */
4395         Point!double userToDevice(Point!double inp)
4396         {
4397             cairo_user_to_device(this.nativePointer, &inp.x, &inp.y);
4398             checkError();
4399             return inp;
4400         }
4401 
4402         /**
4403          * Transform a distance vector from user space to device space.
4404          * This function is similar to $(D userToDevice()) except that
4405          * the translation components of the CTM will be ignored when
4406          * transforming inp.
4407          */
4408         Point!double userToDeviceDistance(Point!double inp)
4409         {
4410             cairo_user_to_device_distance(this.nativePointer, &inp.x, &inp.y);
4411             checkError();
4412             return inp;
4413         }
4414 
4415         /**
4416          * Transform a coordinate from device space to user space by
4417          * multiplying the given point by the inverse of the current
4418          * transformation matrix (CTM).
4419          */
4420         Point!double deviceToUser(Point!double inp)
4421         {
4422             cairo_device_to_user(this.nativePointer, &inp.x, &inp.y);
4423             checkError();
4424             return inp;
4425         }
4426 
4427         /**
4428          * Transform a distance vector from device space to user space.
4429          * This function is similar to $(D deviceToUser()) except that
4430          * the translation components of the inverse CTM will be ignored
4431          * when transforming inp.
4432          */
4433         Point!double deviceToUserDistance(Point!double inp)
4434         {
4435             cairo_device_to_user_distance(this.nativePointer, &inp.x, &inp.y);
4436             checkError();
4437             return inp;
4438         }
4439 
4440         /**
4441          * Note: The $(D selectFontFace()) function call is part of
4442          * what the cairo designers call the "toy" text API. It
4443          * is convenient for short demos and simple programs, but
4444          * it is not expected to be adequate for serious text-using
4445          * applications.
4446          *
4447          * Selects a family and style of font from a simplified description
4448          * as a family name, slant and weight. Cairo provides no
4449          * operation to list available family names on the system
4450          * (this is a "toy", remember), but the standard CSS2 generic
4451          * family names, ("serif", "sans-serif", "cursive", "fantasy",
4452          * "monospace"), are likely to work as expected.
4453          *
4454          * If family starts with the string "cairo:", or if no native
4455          * font backends are compiled in, cairo will use an internal
4456          * font family. The internal font family recognizes many
4457          * modifiers in the family string, most notably, it recognizes
4458          * the string "monospace". That is, the family name
4459          * "cairo:monospace" will use the monospace version of the
4460          * internal font family.
4461          *
4462          * For "real" font selection, see the font-backend-specific
4463          * $(D FontFace) classes for the font backend you are using.
4464          * (For example, if you are using the freetype-based cairo-ft
4465          * font backend, see $(D FTFontFace))
4466          *
4467          * The resulting font face could then be used
4468          * with $(D ScaledFont) and $(D Context.setScaledFont()).
4469          *
4470          * Similarly, when using the "real" font support, you can call
4471          * directly into the underlying font system, (such as
4472          * fontconfig or freetype), for operations such as listing
4473          * available fonts, etc.
4474          *
4475          * It is expected that most applications will need to use a more
4476          * comprehensive font handling and text layout library,
4477          * (for example, pango), in conjunction with cairo.
4478          *
4479          * If text is drawn without a call to $(D selectFontFace()),
4480          * (nor $(D setFontFace()) nor $(D setScaledFont())),
4481          * the default family is platform-specific, but is essentially
4482          * "sans-serif". Default slant is CAIRO_FONT_SLANT_NORMAL,
4483          * and default weight is CAIRO_FONT_WEIGHT_NORMAL.
4484          *
4485          * This function is equivalent to a call to
4486          * $(D toyFontFaceCreate()) followed by $(D setFontFace()).
4487          *
4488          * Params:
4489          * family = a font family name, encoded in UTF-8
4490          * slant = the slant for the font
4491          * weight = the weight for the font
4492          */
4493         void selectFontFace(string family, FontSlant slant, FontWeight weight)
4494         {
4495             cairo_select_font_face(this.nativePointer, toStringz(family), slant, weight);
4496             checkError();
4497         }
4498 
4499         /**
4500          * Sets the current font matrix to a scale by a factor of size,
4501          * replacing any font matrix previously set with $(D setFontSize())
4502          * or $(D setFontMatrix()). This results in a font size of
4503          * size user space units. (More precisely, this matrix will
4504          * result in the font's em-square being a size by size
4505          * square in user space.)
4506          *
4507          * If text is drawn without a call to $(D setFontSize()),
4508          * (nor $(D setFontMatrix()) nor $(D setScaledFont())),
4509          * the default font size is 10.0.
4510          *
4511          * Params:
4512          * size = the new font size, in user space units
4513          */
4514         void setFontSize(double size)
4515         {
4516             cairo_set_font_size(this.nativePointer, size);
4517             checkError();
4518         }
4519 
4520         /**
4521          * Sets the current font matrix to matrix. The font matrix gives
4522          * a transformation from the design space of the font (in this
4523          * space, the em-square is 1 unit by 1 unit) to user space.
4524          * Normally, a simple scale is used (see $(D setFontSize())),
4525          * but a more complex font matrix can be used to shear the font
4526          * or stretch it unequally along the two axes
4527          *
4528          * Params:
4529          * matrix = a $(D Matrix) describing a transform to be applied
4530          * to the current font.
4531          */
4532         void setFontMatrix(Matrix matrix)
4533         {
4534             cairo_set_font_matrix(this.nativePointer, &matrix.nativeMatrix);
4535             checkError();
4536         }
4537 
4538         /**
4539          * Returns the current font matrix. See $(D setFontMatrix).
4540          */
4541         Matrix getFontMatrix()
4542         {
4543             Matrix res;
4544             cairo_get_font_matrix(this.nativePointer, &res.nativeMatrix);
4545             checkError();
4546             return res;
4547         }
4548 
4549         ///Convenience property
4550         @property void fontMatrix(Matrix matrix)
4551         {
4552             setFontMatrix(matrix);
4553         }
4554 
4555         ///ditto
4556         @property Matrix fontMatrix()
4557         {
4558             return getFontMatrix();
4559         }
4560 
4561         /**
4562          * Sets a set of custom font rendering options for the
4563          * $(D Context). Rendering options are derived by merging these
4564          * options with the options derived from underlying surface;
4565          * if the value in options has a default value (like CAIRO_ANTIALIAS_DEFAULT),
4566          * then the value from the surface is used.
4567          */
4568         void setFontOptions(FontOptions options)
4569         {
4570             cairo_set_font_options(this.nativePointer, options.nativePointer);
4571             checkError();
4572         }
4573 
4574         /**
4575          * Retrieves font rendering options set via $(D setFontOptions()).
4576          * Note that the returned options do not include any options
4577          * derived from the underlying surface; they are literally
4578          * the options passed to $(D setFontOptions()).
4579          */
4580         FontOptions getFontOptions()
4581         {
4582             auto opt = FontOptions.create();
4583             cairo_get_font_options(this.nativePointer, opt.nativePointer);
4584             checkError();
4585             return opt;
4586         }
4587 
4588         ///Convenience property
4589         @property void fontOptions(FontOptions options)
4590         {
4591             setFontOptions(options);
4592         }
4593 
4594         ///ditto
4595         @property FontOptions fontOptions()
4596         {
4597             return getFontOptions();
4598         }
4599 
4600         /**
4601          * Replaces the current $(D FontFace) object in the $(D Context)
4602          * with font_face. The replaced font face in the $(D Context) will
4603          * be destroyed if there are no other references to it.
4604          */
4605         void setFontFace(FontFace font_face)
4606         {
4607             cairo_set_font_face(this.nativePointer, font_face.nativePointer);
4608             checkError();
4609         }
4610 
4611         /**
4612          * Replaces the current $(D FontFace) object in the $(D Context)
4613          * with the default font.
4614          */
4615         void setFontFace()
4616         {
4617             cairo_set_font_face(this.nativePointer, null);
4618             checkError();
4619         }
4620 
4621         // todo: setFontFace should be renamed to resetFontFace, using alias
4622         // instead for backwards-compatibility.
4623         ///convenience alias
4624         alias setFontFace resetFontFace;
4625 
4626         /**
4627          * Gets the current font face for a $(D Context).
4628          */
4629         FontFace getFontFace()
4630         {
4631             return FontFace.createFromNative(cairo_get_font_face(this.nativePointer));
4632         }
4633 
4634         ///Convenience property
4635         @property void fontFace(FontFace font_face)
4636         {
4637             setFontFace(font_face);
4638         }
4639 
4640         ///ditto
4641         @property FontFace fontFace()
4642         {
4643             return getFontFace();
4644         }
4645 
4646         /**
4647          * Replaces the current font face, font matrix, and font options
4648          * in the $(D Context) with those of the $(D ScaledFont). Except
4649          * for some translation, the current CTM of the cairo_t should be
4650          * the same as that of the $(D ScaledFont), which can be
4651          * accessed using $(D ScaledFont.getCTM()).
4652          */
4653         void setScaledFont(ScaledFont scaled_font)
4654         {
4655             cairo_set_scaled_font(this.nativePointer, scaled_font.nativePointer);
4656             checkError();
4657         }
4658 
4659         /**
4660          * Gets the current scaled font for a $(D Context).
4661          */
4662         ScaledFont getScaledFont()
4663         {
4664             return ScaledFont.createFromNative(cairo_get_scaled_font(this.nativePointer));
4665         }
4666 
4667         ///Convenience property
4668         @property void scaledFont(ScaledFont scaled_font)
4669         {
4670             setScaledFont(scaled_font);
4671         }
4672 
4673         ///ditto
4674         @property ScaledFont scaledFont()
4675         {
4676             return getScaledFont();
4677         }
4678 
4679         /**
4680          * A drawing operator that generates the shape from a string of
4681          * UTF-8 characters, rendered according to the current
4682          * fontFace, fontSize (fontMatrix), and fontOptions.
4683          *
4684          * This function first computes a set of glyphs for the string
4685          * of text. The first glyph is placed so that its origin is
4686          * at the current point. The origin of each subsequent glyph
4687          * is offset from that of the previous glyph by the advance
4688          * values of the previous glyph.
4689          *
4690          * After this call the current point is moved to the origin
4691          * of where the next glyph would be placed in this same
4692          * progression. That is, the current point will be at the
4693          * origin of the final glyph offset by its advance values.
4694          * This allows for easy display of a single logical string
4695          * with multiple calls to $(D showText()).
4696          *
4697          * Note: The $(D showText()) function call is part of
4698          * what the cairo designers call the "toy" text API. It
4699          * is convenient for short demos and simple programs, but
4700          * it is not expected to be adequate for serious text-using
4701          * applications. See $(D showGlyphs()) for the "real" text
4702          * display API in cairo.
4703          */
4704         void showText(string text)
4705         {
4706             cairo_show_text(this.nativePointer, toStringz(text));
4707             checkError();
4708         }
4709 
4710         /**
4711          * A drawing operator that generates the shape from an array of
4712          * glyphs, rendered according to the current fontFace,
4713          * fontSize (fontMatrix), and font options.
4714          */
4715         void showGlyphs(Glyph[] glyphs)
4716         {
4717             cairo_show_glyphs(this.nativePointer, glyphs.ptr, glyphs.length.toCairoCount());
4718             checkError();
4719         }
4720 
4721         /**
4722          * This operation has rendering effects similar to $(D showGlyphs())
4723          * but, if the target surface supports it, uses the provided
4724          * text and cluster mapping to embed the text for the glyphs
4725          * shown in the output. If the target does not support the
4726          * extended attributes, this function acts like the basic
4727          * $(D showGlyphs()).
4728          */
4729         void showTextGlyphs(TextGlyph glyph)
4730         {
4731             cairo_show_text_glyphs(this.nativePointer, glyph.text.ptr,
4732                 glyph.text.length.toCairoCount(), glyph.glyphs.ptr, glyph.glyphs.length.toCairoCount(),
4733                 glyph.cluster.ptr, glyph.cluster.length.toCairoCount(), glyph.flags);
4734             checkError();
4735         }
4736 
4737         /**
4738          * Gets the font extents for the currently selected font.
4739          */
4740         FontExtents fontExtents()
4741         {
4742             FontExtents res;
4743             cairo_font_extents(this.nativePointer, &res);
4744             checkError();
4745             return res;
4746         }
4747 
4748         /**
4749          * Gets the extents for a string of text. The extents describe
4750          * a user-space rectangle that encloses the "inked"
4751          * portion of the text, (as it would be drawn by $(D showText())).
4752          * Additionally, the x_advance and y_advance values indicate
4753          * the amount by which the current point would be advanced
4754          * by $(D showText()).
4755          *
4756          * Note that whitespace characters do not directly contribute
4757          * to the size of the rectangle (extents.width and extents.height).
4758          * They do contribute indirectly by changing the position of
4759          * non-whitespace characters. In particular, trailing whitespace
4760          * characters are likely to not affect the size of the rectangle,
4761          * though they will affect the x_advance and y_advance values.
4762          */
4763         TextExtents textExtents(string text)
4764         {
4765             TextExtents res;
4766             cairo_text_extents(this.nativePointer, toStringz(text), &res);
4767             checkError();
4768             return res;
4769         }
4770 
4771         /**
4772          * Gets the extents for an array of glyphs. The extents describe
4773          * a user-space rectangle that encloses the "inked" portion of
4774          * the glyphs, (as they would be drawn by $(D showGlyphs())).
4775          * Additionally, the x_advance and y_advance values indicate
4776          * the amount by which the current point would be advanced by
4777          * $(D showGlyphs()).
4778          *
4779          * Note that whitespace glyphs do not contribute to the size of
4780          * the rectangle (extents.width and extents.height).
4781          */
4782         TextExtents glyphExtents(Glyph[] glyphs)
4783         {
4784             TextExtents res;
4785             cairo_glyph_extents(this.nativePointer, glyphs.ptr, glyphs.length.toCairoCount(), &res);
4786             checkError();
4787             return res;
4788         }
4789 }
4790 
4791 /* ------------------------------- Fonts ------------------------------ */
4792 
4793 /**
4794  * $(D FontOptions) - How a font should be rendered
4795  *
4796  * The font options specify how fonts should be rendered. Most of the
4797  * time the font options implied by a surface are just right and do
4798  * not need any changes, but for pixel-based targets tweaking font
4799  * options may result in superior output on a particular display.
4800  *
4801  * Warning: Instances must be created with the create static member function!
4802  * --------
4803  * auto options = FontOptions.create(); //Correct
4804  * options.toHash();
4805  * --------
4806  *
4807  * --------
4808  * FontOptions options; //Wrong
4809  * options.toHash();
4810  * --------
4811  *
4812  * --------
4813  * FontOptions options;
4814  * options = FontOptions.create(); //Correct
4815  * options.toHash();
4816  * --------
4817  */
4818 public struct FontOptions
4819 {
4820     private:
4821         struct Payload
4822         {
4823             cairo_font_options_t* _payload;
4824             this(cairo_font_options_t* h)
4825             {
4826                 _payload = h;
4827             }
4828             ~this()
4829             {
4830                 if(_payload)
4831                 {
4832                     cairo_font_options_destroy(_payload);
4833                     _payload = null;
4834                 }
4835             }
4836 
4837             // Should never perform these operations
4838             this(this) { assert(false); }
4839             void opAssign(FontOptions.Payload rhs) { assert(false); }
4840         }
4841 
4842         alias RefCounted!(Payload, RefCountedAutoInitialize.no) Data;
4843         Data _data;
4844 
4845     protected:
4846         final void checkError()
4847         {
4848             throwError(cairo_font_options_status(nativePointer));
4849         }
4850 
4851     public:
4852         /**
4853          * The underlying $(D cairo_font_options_t*) handle
4854          */
4855         @property cairo_font_options_t* nativePointer()
4856         {
4857             return _data._payload;
4858         }
4859 
4860         version(D_Ddoc)
4861         {
4862             /**
4863              * Enable / disable memory management debugging for this FontOptions
4864              * instance. Only available if both cairoD and the cairoD user
4865              * code were compiled with "debug=RefCounted"
4866              *
4867              * Output is written to stdout, see
4868              * $(LINK https://github.com/jpf91/cairoD/wiki/Memory-Management#debugging)
4869              * for more information
4870              */
4871             @property bool debugging();
4872             ///ditto
4873             @property void debugging(bool value);
4874         }
4875         else debug(RefCounted)
4876         {
4877             @property bool debugging()
4878             {
4879                 return _data.RefCounted.debugging;
4880             }
4881 
4882             @property void debugging(bool value)
4883             {
4884                 _data.RefCounted.debugging = value;
4885             }
4886         }
4887 
4888         /**
4889          * Allocates a new font options object with all
4890          * options initialized to default values.
4891          */
4892         static FontOptions create()
4893         {
4894             FontOptions opt;
4895             auto ptr = cairo_font_options_create();
4896             throwError(cairo_font_options_status(ptr));
4897             opt._data = Data(ptr);
4898             return opt;
4899         }
4900 
4901         /**
4902          * Create $(D FontOptions) from a existing $(D cairo_font_options_t*).
4903          * FontOptions is a reference counted struct. It will call
4904          * $(D cairo_font_options_destroy) when it's reference count is 0.
4905          * See $(LINK https://github.com/jpf91/cairoD/wiki/Memory-Management#2.2-structs)
4906          * for more information.
4907          *
4908          * Warning:
4909          * $(RED Only use this if you know what your doing!
4910          * This function should not be needed for standard cairoD usage.)
4911          */
4912         this(cairo_font_options_t* ptr)
4913         {
4914             if(!ptr)
4915             {
4916                 throw new CairoException(cairo_status_t.CAIRO_STATUS_NULL_POINTER);
4917             }
4918             throwError(cairo_font_options_status(ptr));
4919             _data = Data(ptr);
4920         }
4921 
4922         /**
4923          * Allocates a new font options object copying the option values
4924          * from original.
4925          *
4926          * This new object's reference counting is independent from the
4927          * current object's.
4928          */
4929         FontOptions copy()
4930         {
4931             return FontOptions(cairo_font_options_copy(nativePointer));
4932         }
4933 
4934         /**
4935          * Merges non-default options from other into this object,
4936          * replacing existing values. This operation can be thought
4937          * of as somewhat similar to compositing other onto options
4938          * with the operation of CAIRO_OPERATION_OVER.
4939          */
4940         void merge(FontOptions other)
4941         {
4942             cairo_font_options_merge(nativePointer, other.nativePointer);
4943             checkError();
4944         }
4945 
4946         /**
4947          * Compute a hash for the font options object; this value
4948          * will be useful when storing an object containing a
4949          * FontOptions in a hash table.
4950          */
4951         /*
4952          * Cairo docs say hash can be casted to a 32bit value, if needed
4953          */
4954         size_t toHash()
4955         {
4956             auto hash = cast(size_t)cairo_font_options_hash(nativePointer);
4957             checkError();
4958             return hash;
4959         }
4960 
4961         /**
4962          * Compares two font options objects for equality.
4963          *
4964          * Returns:
4965          * true if all fields of the two font options objects match.
4966          * Note that this function will return false if either object is
4967          * in error.
4968          */
4969         const bool opEquals(ref const(FontOptions) other)
4970         {
4971             return cairo_font_options_equal((cast(FontOptions)this).nativePointer,
4972                 (cast(FontOptions)other).nativePointer) ? true : false;
4973         }
4974 
4975         /**
4976          * Sets the antialiasing mode for the font options object. This
4977          * specifies the type of antialiasing to do when rendering text.
4978          */
4979         void setAntiAlias(AntiAlias antialias)
4980         {
4981             cairo_font_options_set_antialias(nativePointer, antialias);
4982             checkError();
4983         }
4984 
4985         /**
4986          * Gets the antialiasing mode for the font options object.
4987          */
4988         AntiAlias getAntiAlias()
4989         {
4990             scope(exit)
4991                 checkError();
4992             return cairo_font_options_get_antialias(nativePointer);
4993         }
4994 
4995         ///Convenience property
4996         @property void antiAlias(AntiAlias aa)
4997         {
4998             setAntiAlias(aa);
4999         }
5000 
5001         ///ditto
5002         @property AntiAlias antiAlias()
5003         {
5004             return getAntiAlias();
5005         }
5006 
5007         /**
5008          * Sets the subpixel order for the font options object.
5009          * The subpixel order specifies the order of color elements
5010          * within each pixel on the display device when rendering with
5011          * an antialiasing mode of CAIRO_ANTIALIAS_SUBPIXEL.
5012          * See the documentation for $(D SubpixelOrder) for full details.
5013          */
5014         void setSubpixelOrder(SubpixelOrder order)
5015         {
5016             cairo_font_options_set_subpixel_order(nativePointer, order);
5017             checkError();
5018         }
5019 
5020         /**
5021          * Gets the subpixel order for the font options object.
5022          * See the documentation for $(D SubpixelOrder) for full details.
5023          */
5024         SubpixelOrder getSubpixelOrder()
5025         {
5026             scope(exit)
5027                 checkError();
5028             return cairo_font_options_get_subpixel_order(nativePointer);
5029         }
5030 
5031         ///convenience alias
5032         alias getSubpixelOrder subpixelOrder;
5033 
5034         /**
5035          * Sets the hint style for font outlines for the font options object.
5036          * This controls whether to fit font outlines to the pixel grid,
5037          * and if so, whether to optimize for fidelity or contrast.
5038          * See the documentation for $(D HintStyle) for full details.
5039          */
5040         void setHintStyle(HintStyle style)
5041         {
5042             cairo_font_options_set_hint_style(nativePointer, style);
5043             checkError();
5044         }
5045 
5046         /**
5047          * Gets the hint style for font outlines for the font options object.
5048          * See the documentation for $(D HintStyle) for full details.
5049          */
5050         HintStyle getHintStyle()
5051         {
5052             scope(exit)
5053                 checkError();
5054             return cairo_font_options_get_hint_style(nativePointer);
5055         }
5056 
5057         ///Convenience property
5058         @property void hintStyle(HintStyle style)
5059         {
5060             setHintStyle(style);
5061         }
5062 
5063         ///ditto
5064         @property HintStyle hintStyle()
5065         {
5066             return getHintStyle();
5067         }
5068 
5069         /**
5070          * Sets the metrics hinting mode for the font options object.
5071          * This controls whether metrics are quantized to integer
5072          * values in device units. See the documentation for
5073          * $(D HintMetrics) for full details.
5074          */
5075         void setHintMetrics(HintMetrics metrics)
5076         {
5077             cairo_font_options_set_hint_metrics(nativePointer, metrics);
5078             checkError();
5079         }
5080 
5081         /**
5082          * Gets the metrics hinting mode for the font options object.
5083          * See the documentation for $(D HintMetrics) for full details.
5084          */
5085         HintMetrics getHintMetrics()
5086         {
5087             scope(exit)
5088                 checkError();
5089             return cairo_font_options_get_hint_metrics(nativePointer);
5090         }
5091 
5092         ///Convenience property
5093         @property void hintMetrics(HintMetrics metrics)
5094         {
5095             setHintMetrics(metrics);
5096         }
5097 
5098         ///ditto
5099         @property HintMetrics hintMetrics()
5100         {
5101             return getHintMetrics();
5102         }
5103 }
5104 
5105 /**
5106  * The mapping between utf8 and glyphs is provided by an array
5107  * of clusters. Each cluster covers a number of text bytes and
5108  * glyphs, and neighboring clusters cover neighboring areas of
5109  * utf8 and glyphs. The clusters should collectively cover
5110  * utf8 and glyphs in entirety.
5111  *
5112  * The first cluster always covers bytes from the beginning of
5113  * utf8. If cluster_flags do not have the
5114  * CAIRO_TEXT_CLUSTER_FLAG_BACKWARD set, the first cluster also
5115  * covers the beginning of glyphs, otherwise it covers the end
5116  * of the glyphs array and following clusters move backward.
5117  *
5118  * See cairo_text_cluster_t for constraints on valid clusters.
5119  */
5120 public struct TextGlyph
5121 {
5122     public:
5123         ///array of glyphs
5124         Glyph[] glyphs;
5125         ///array of cluster mapping information
5126         TextCluster[] cluster;
5127         ///a string of text encoded in UTF-8
5128         string text;
5129         ///cluster mapping flags
5130         TextClusterFlags flags;
5131 }
5132 
5133 /**
5134  * Font face at particular size and options
5135  *
5136  * $(D ScaledFont) represents a realization of a font face at a particular
5137  * size and transformation and a certain set of font options.
5138  */
5139 public class ScaledFont
5140 {
5141     ///
5142     mixin CairoCountedClass!(cairo_scaled_font_t*, "cairo_scaled_font_");
5143 
5144     protected:
5145         /**
5146          * Method for use in subclasses.
5147          * Calls $(D cairo_scaled_font_status(nativePointer)) and throws
5148          * an exception if the status isn't CAIRO_STATUS_SUCCESS
5149          */
5150         final void checkError()
5151         {
5152             throwError(cairo_scaled_font_status(nativePointer));
5153         }
5154 
5155     public:
5156         /**
5157          * Create a $(D ScaledFont) from a existing $(D cairo_scaled_font_t*).
5158          * ScaledFont is a garbage collected class. It will call $(D cairo_scaled_font_destroy)
5159          * when it gets collected by the GC or when $(D dispose()) is called.
5160          *
5161          * Warning:
5162          * $(D ptr)'s reference count is not increased by this function!
5163          * Adjust reference count before calling it if necessary
5164          *
5165          * $(RED Only use this if you know what your doing!
5166          * This function should not be needed for standard cairoD usage.)
5167          */
5168         this(cairo_scaled_font_t* ptr)
5169         {
5170             this.nativePointer = ptr;
5171             checkError();
5172         }
5173 
5174         /**
5175          * Creates a $(D ScaledFont) object from a font face and
5176          * matrices that describe the size of the font and the
5177          * environment in which it will be used.
5178          *
5179          * Params:
5180          * font_matrix = font space to user space transformation matrix
5181          *   for the font. In the simplest case of a N point font, this
5182          *   matrix is just a scale by N, but it can also be used to
5183          *   shear the font or stretch it unequally along the two axes.
5184          *   See $(D Context.setFontMatrix()).
5185          * ctm = user to device transformation matrix with which
5186          *   the font will be used.
5187          */
5188         this(FontFace font_face, Matrix font_matrix, Matrix ctm,
5189              FontOptions options)
5190         {
5191             this(cairo_scaled_font_create(font_face.nativePointer,
5192                 &font_matrix.nativeMatrix, &ctm.nativeMatrix, options.nativePointer));
5193         }
5194 
5195         /**
5196          * The createFromNative method for the ScaledFont classes.
5197          * See $(LINK https://github.com/jpf91/cairoD/wiki/Memory-Management#createFromNative)
5198          * for more information.
5199          *
5200          * Warning:
5201          * $(RED Only use this if you know what your doing!
5202          * This function should not be needed for standard cairoD usage.)
5203          */
5204         static ScaledFont createFromNative(cairo_scaled_font_t* ptr, bool adjRefCount = true)
5205         {
5206             if(!ptr)
5207             {
5208                 throw new CairoException(cairo_status_t.CAIRO_STATUS_NULL_POINTER);
5209             }
5210             throwError(cairo_scaled_font_status(ptr));
5211             //Adjust reference count
5212             if(adjRefCount)
5213                 cairo_scaled_font_reference(ptr);
5214             switch(cairo_scaled_font_get_type(ptr))
5215             {
5216                 static if(CAIRO_HAS_WIN32_FONT)
5217                 {
5218                     import cairo.win32;
5219                     case cairo_font_type_t.CAIRO_FONT_TYPE_WIN32:
5220                         return new Win32ScaledFont(ptr);
5221                 }
5222                 static if(CAIRO_HAS_FT_FONT)
5223                 {
5224                     import cairo.ft;
5225                     case cairo_font_type_t.CAIRO_FONT_TYPE_FT:
5226                         return new FTScaledFont(ptr);
5227                 }
5228                 default:
5229                     return new ScaledFont(ptr);
5230             }
5231         }
5232 
5233         /**
5234          * Gets the metrics for a $(D ScaledFont).
5235          */
5236         FontExtents extents()
5237         {
5238             FontExtents res;
5239             cairo_scaled_font_extents(this.nativePointer, &res);
5240             checkError();
5241             return res;
5242         }
5243 
5244         /**
5245          * Gets the extents for a string of text. The extents describe a
5246          * user-space rectangle that encloses the "inked" portion of the
5247          * text drawn at the origin (0,0) (as it would be drawn by
5248          * $(D Context.showText()) if the cairo graphics state were set
5249          * to the same fontFace, fontMatrix, ctm, and fontOptions
5250          * as $(D ScaledFont)). Additionally, the x_advance and y_advance
5251          * values indicate the amount by which the current point would
5252          * be advanced by $(D Context.showText()).
5253          *
5254          * Note that whitespace characters do not directly contribute
5255          * to the size of the rectangle (extents.width and extents.height).
5256          * They do contribute indirectly by changing the position of
5257          * non-whitespace characters. In particular, trailing whitespace
5258          * characters are likely to not affect the size of the
5259          * rectangle, though they will affect the x_advance
5260          * and y_advance values.
5261          */
5262         TextExtents textExtents(string text)
5263         {
5264             TextExtents res;
5265             cairo_scaled_font_text_extents(this.nativePointer, toStringz(text),
5266                 &res);
5267             checkError();
5268             return res;
5269         }
5270 
5271         /**
5272          * Gets the extents for an array of glyphs. The extents describe
5273          * a user-space rectangle that encloses the "inked" portion
5274          * of the glyphs, (as they would be drawn by $(D Context.showGlyphs())
5275          * if the cairo graphics state were set to the same fontFace,
5276          * fontMatrix, ctm, and fontOptions as scaled_font). Additionally,
5277          * the x_advance and y_advance values indicate the amount by
5278          * which the current point would be advanced by $(D Context.showGlyphs()).
5279          *
5280          * Note that whitespace glyphs do not contribute to the size
5281          * of the rectangle (extents.width and extents.height).
5282          */
5283         TextExtents glyphExtents(Glyph[] glyphs)
5284         {
5285             TextExtents res;
5286             cairo_scaled_font_glyph_extents(this.nativePointer, glyphs.ptr,
5287                 glyphs.length.toCairoCount(), &res);
5288             checkError();
5289             return res;
5290         }
5291 
5292         /**
5293          * Converts UTF-8 text to an array of glyphs, optionally with
5294          * cluster mapping, that can be used to render later using ScaledFont.
5295          *
5296          * If glyphBuffer initially points to a non-empty array, that array is
5297          * used as a glyph buffer. If the provided glyph array is too
5298          * short for the conversion, a new glyph array is allocated and returned.
5299          *
5300          * If clusterBuffer is not empty a cluster mapping will be computed.
5301          * The semantics of how cluster array allocation works is similar to the glyph array.
5302          * That is, if clusterBuffer initially points to a non-empty array,
5303          * that array is used as a cluster buffer.
5304          * If the provided cluster array is too short for the conversion,
5305          * a new cluster array is allocated and returned.
5306          *
5307          * In the simplest case, glyphs and clusters can be omitted
5308          * or set to an empty array and a suitable array will be allocated.
5309          * In code
5310          * -----------------
5311          * auto glyphs = scaled_font.textToTextGlyph(x, y, text);
5312          * cr.showTextGlyphs(glyphs);
5313          * -----------------
5314          * If no cluster mapping is needed
5315          * -----------------
5316          * auto glyphs = scaled_font.textToGlyphs(x, y, text);
5317          * cr.showGlyphs(glyphs);
5318          * -----------------
5319          * If stack-based glyph and cluster arrays are to be used for small arrays
5320          * -----------------
5321          * Glyph[40] stack_glyphs;
5322          * TextCluster[40] stack_clusters;
5323          * auto glyphs = scaled_font.textToTextGlyph(x, y, text, stack_glyphs, stack_clusters);
5324          * cr.showTextGlyphs(glyphs);
5325          * -----------------
5326          *
5327          * The output values can be readily passed to $(D Context.showTextGlyphs())
5328          * $(D Context.showGlyphs()), or related functions, assuming that
5329          * the exact same ScaledFont is used for the operation.
5330          *
5331          * Params:
5332          * x = X position to place first glyph
5333          * y = Y position to place first glyph
5334          */
5335         Glyph[] textToGlyphs(double x, double y, string text, Glyph[] glyphBuffer = [])
5336         {
5337             Glyph* gPtr = null;
5338             int gLen = 0;
5339             if(glyphBuffer.length != 0)
5340             {
5341                 gPtr = glyphBuffer.ptr;
5342                 gLen = glyphBuffer.length.toCairoCount();
5343             }
5344 
5345             throwError(cairo_scaled_font_text_to_glyphs(this.nativePointer, x, y,
5346                 text.ptr, text.length.toCairoCount(), &gPtr, &gLen, null, null, null));
5347 
5348             if(gPtr == glyphBuffer.ptr)
5349             {
5350                 return glyphBuffer[0 .. gLen];
5351             }
5352             else
5353             {
5354                 Glyph[] gCopy = gPtr[0 .. gLen].dup;
5355                 cairo_glyph_free(gPtr);
5356                 return gCopy;
5357             }
5358         }
5359         ///ditto
5360         Glyph[] textToGlyphs(Point!double p1, string text, Glyph[] glyphBuffer = [])
5361         {
5362             return textToGlyphs(p1.x, p1.y, text, glyphBuffer);
5363         }
5364         ///ditto
5365         TextGlyph textToTextGlyph(double x, double y, string text, Glyph[] glyphBuffer = [],
5366             TextCluster[] clusterBuffer = [])
5367         {
5368             TextGlyph res;
5369 
5370             Glyph* gPtr = null;
5371             int gLen = 0;
5372             TextCluster* cPtr = null;
5373             int cLen = 0;
5374             TextClusterFlags cFlags;
5375             if(glyphBuffer.length != 0)
5376             {
5377                 gPtr = glyphBuffer.ptr;
5378                 gLen = glyphBuffer.length.toCairoCount();
5379             }
5380             if(clusterBuffer.length != 0)
5381             {
5382                 cPtr = clusterBuffer.ptr;
5383                 cLen = clusterBuffer.length.toCairoCount();
5384             }
5385 
5386             throwError(cairo_scaled_font_text_to_glyphs(this.nativePointer, x, y,
5387                 text.ptr, text.length.toCairoCount(), &gPtr, &gLen, &cPtr, &cLen, &cFlags));
5388 
5389             if(gPtr == glyphBuffer.ptr)
5390             {
5391                 res.glyphs = glyphBuffer[0 .. gLen];
5392             }
5393             else
5394             {
5395                 res.glyphs = gPtr[0 .. gLen].dup;
5396                 cairo_glyph_free(gPtr);
5397             }
5398             if(cPtr == clusterBuffer.ptr)
5399             {
5400                 res.cluster = clusterBuffer[0 .. cLen];
5401             }
5402             else
5403             {
5404                 res.cluster = cPtr[0 .. cLen].dup;
5405                 cairo_text_cluster_free(cPtr);
5406             }
5407 
5408             res.text = text;
5409             res.flags = cFlags;
5410             return res;
5411         }
5412         ///ditto
5413         TextGlyph textToTextGlyph(Point!double p1, string text, Glyph[] glyphBuffer = [],
5414             TextCluster[] clusterBuffer = [])
5415         {
5416             return textToTextGlyph(p1.x, p1.y, text, glyphBuffer, clusterBuffer);
5417         }
5418 
5419         /**
5420          * Gets the font face that this scaled font uses. This is the
5421          * font face passed to $(D new ScaledFont()).
5422          */
5423         FontFace getFontFace()
5424         {
5425             auto face = cairo_scaled_font_get_font_face(this.nativePointer);
5426             checkError();
5427             return FontFace.createFromNative(face);
5428         }
5429 
5430         ///convenience alias
5431         alias getFontFace fontFace;
5432 
5433         /**
5434          * Returns the font options with which ScaledFont
5435          * was created.
5436          */
5437         FontOptions getFontOptions()
5438         {
5439             //TODO: verify if this is correct
5440             FontOptions fo = FontOptions.create();
5441             cairo_scaled_font_get_font_options(this.nativePointer, fo.nativePointer);
5442             checkError();
5443             return fo;
5444         }
5445 
5446         ///convenience alias
5447         alias getFontOptions fontOptions;
5448 
5449         /**
5450          * Returns the font matrix with which ScaledFont
5451          * was created.
5452          */
5453         Matrix getFontMatrix()
5454         {
5455             Matrix mat;
5456             cairo_scaled_font_get_font_matrix(this.nativePointer, &mat.nativeMatrix);
5457             checkError();
5458             return mat;
5459         }
5460 
5461         ///convenience alias
5462         alias getFontMatrix fontMatrix;
5463 
5464         /**
5465          * Returns the CTM with which ScaledFont was created.
5466          * Note that the translation offsets (x0, y0) of the CTM are
5467          * ignored by $(D new ScaledFont()). So, the matrix this function
5468          * returns always has 0,0 as x0,y0.
5469          */
5470         Matrix getCTM()
5471         {
5472             Matrix mat;
5473             cairo_scaled_font_get_ctm(this.nativePointer, &mat.nativeMatrix);
5474             checkError();
5475             return mat;
5476         }
5477 
5478         ///convenience alias
5479         alias getCTM CTM;
5480 
5481         /**
5482          * Returns the scale matrix of ScaledFont.
5483          * The scale matrix is product of the font matrix and the
5484          * ctm associated with the scaled font, and hence is the
5485          * matrix mapping from font space to device space.
5486          */
5487         Matrix getScaleMatrix()
5488         {
5489             Matrix mat;
5490             cairo_scaled_font_get_scale_matrix(this.nativePointer, &mat.nativeMatrix);
5491             checkError();
5492             return mat;
5493         }
5494 
5495         ///convenience alias
5496         alias getScaleMatrix scaleMatrix;
5497 
5498         /**
5499          * This function returns the C type of a ScaledFont. See $(D FontType)
5500          * for available types.
5501          */
5502         FontType getType()
5503         {
5504             auto tmp = cairo_scaled_font_get_type(this.nativePointer);
5505             checkError();
5506             return tmp;
5507         }
5508 
5509         ///convenience alias
5510         alias getType type;
5511 }
5512 
5513 /**
5514  * Base class for font faces
5515  *
5516  * $(D FontFace) represents a particular font at a particular weight,
5517  * slant, and other characteristic but no size, transformation, or size.
5518  *
5519  * Font faces are created using font-backend-specific classes,
5520  * typically of the form $(D *FontFace), or implicitly
5521  * using the toy text API by way of $(D Context.selectFontFace()). The
5522  * resulting face can be accessed using $(D Context.getFontFace()).
5523  */
5524 public class FontFace
5525 {
5526     ///
5527     mixin CairoCountedClass!(cairo_font_face_t*, "cairo_font_face_");
5528 
5529     protected:
5530         /**
5531          * Method for use in subclasses.
5532          * Calls $(D cairo_font_face_status(nativePointer)) and throws
5533          * an exception if the status isn't CAIRO_STATUS_SUCCESS
5534          */
5535         final void checkError()
5536         {
5537             throwError(cairo_font_face_status(nativePointer));
5538         }
5539 
5540     public:
5541         /**
5542          * Create a $(D FontFace) from a existing $(D cairo_font_face_t*).
5543          * FontFace is a garbage collected class. It will call $(D cairo_font_face_destroy)
5544          * when it gets collected by the GC or when $(D dispose()) is called.
5545          *
5546          * Warning:
5547          * $(D ptr)'s reference count is not increased by this function!
5548          * Adjust reference count before calling it if necessary
5549          *
5550          * $(RED Only use this if you know what your doing!
5551          * This function should not be needed for standard cairoD usage.)
5552          */
5553         this(cairo_font_face_t* ptr)
5554         {
5555             this.nativePointer = ptr;
5556             checkError();
5557         }
5558 
5559         /**
5560          * The createFromNative method for the FontFace classes.
5561          * See $(LINK https://github.com/jpf91/cairoD/wiki/Memory-Management#createFromNative)
5562          * for more information.
5563          *
5564          * Warning:
5565          * $(RED Only use this if you know what your doing!
5566          * This function should not be needed for standard cairoD usage.)
5567          */
5568         static FontFace createFromNative(cairo_font_face_t* ptr, bool adjRefCount = true)
5569         {
5570             if(!ptr)
5571             {
5572                 throw new CairoException(cairo_status_t.CAIRO_STATUS_NULL_POINTER);
5573             }
5574             throwError(cairo_font_face_status(ptr));
5575             //Adjust reference count
5576             if(adjRefCount)
5577                 cairo_font_face_reference(ptr);
5578             switch(cairo_font_face_get_type(ptr))
5579             {
5580                 case cairo_font_type_t.CAIRO_FONT_TYPE_TOY:
5581                     return new ToyFontFace(ptr);
5582                 static if(CAIRO_HAS_WIN32_FONT)
5583                 {
5584                     import cairo.win32;
5585                     case cairo_font_type_t.CAIRO_FONT_TYPE_WIN32:
5586                         return new Win32FontFace(ptr);
5587                 }
5588                 static if(CAIRO_HAS_FT_FONT)
5589                 {
5590                     import cairo.ft;
5591                     case cairo_font_type_t.CAIRO_FONT_TYPE_FT:
5592                         return new FTFontFace(ptr);
5593                 }
5594                 default:
5595                     return new FontFace(ptr);
5596             }
5597         }
5598 
5599         /**
5600          * This function returns the C type of a FontFace. See $(D FontType)
5601          * for available types.
5602          */
5603         FontType getType()
5604         {
5605             auto tmp = cairo_font_face_get_type(this.nativePointer);
5606             checkError();
5607             return tmp;
5608         }
5609 
5610         ///convenience alias
5611         alias getType type;
5612 }
5613 
5614 /**
5615  * Cairo toy font api's FontFace
5616  */
5617 public class ToyFontFace : FontFace
5618 {
5619     public:
5620         /**
5621          * Create a $(D ToyFontFace) from a existing $(D cairo_font_face_t*).
5622          * ToyFontFace is a garbage collected class. It will call $(D cairo_surface_destroy)
5623          * when it gets collected by the GC or when $(D dispose()) is called.
5624          *
5625          * Warning:
5626          * $(D ptr)'s reference count is not increased by this function!
5627          * Adjust reference count before calling it if necessary
5628          *
5629          * $(RED Only use this if you know what your doing!
5630          * This function should not be needed for standard cairoD usage.)
5631          */
5632         this(cairo_font_face_t* ptr)
5633         {
5634             super(ptr);
5635         }
5636 
5637         /**
5638          * Creates a font face from a triplet of family, slant, and weight.
5639          * These font faces are used in implementation of the the cairo "toy" font API.
5640          *
5641          * If family is the zero-length string "", the platform-specific
5642          * default family is assumed. The default family then
5643          * can be queried using $(D getFamily()).
5644          *
5645          * The $(D Context.selectFontFace()) function uses this to create
5646          * font faces. See that function for limitations and
5647          * other details of toy font faces.
5648          */
5649         this(string family, FontSlant slant, FontWeight weight)
5650         {
5651             super(cairo_toy_font_face_create(toStringz(family), slant, weight));
5652         }
5653 
5654         /**
5655          * Gets the familly name of a toy font.
5656          */
5657         string getFamily()
5658         {
5659             auto ptr = cairo_toy_font_face_get_family(this.nativePointer);
5660             checkError();
5661             return to!string(ptr);
5662         }
5663 
5664         ///convenience alias
5665         alias getFamily family;
5666 
5667         /**
5668          * Gets the slant a toy font.
5669          */
5670         FontSlant getSlant()
5671         {
5672             auto res = cairo_toy_font_face_get_slant(this.nativePointer);
5673             checkError();
5674             return res;
5675         }
5676 
5677         ///convenience alias
5678         alias getSlant slant;
5679 
5680         /**
5681          * Gets the weight of a toy font.
5682          */
5683         FontWeight getWeight()
5684         {
5685             auto res = cairo_toy_font_face_get_weight(this.nativePointer);
5686             checkError();
5687             return res;
5688         }
5689 
5690         ///convenience alias
5691         alias getWeight weight;
5692 }
5693 
5694 /**
5695  * Cairo version information
5696  */
5697 public struct Version
5698 {
5699     public:
5700         ///Major, Minor and Micro versions
5701         uint major;
5702         uint minor; ///ditto
5703         uint micro; ///ditto
5704 
5705         /**
5706          * Construct a version object from a encoded version.
5707          */
5708         this(ulong encoded)
5709         {
5710             this.major = cast(uint)(encoded / 10000);
5711             this.minor = cast(uint)((encoded % 10000) / 100);
5712             this.micro = cast(uint)((encoded % 10000) % 100);
5713         }
5714 
5715         /**
5716          * Construct a version object from version components.
5717          */
5718         this(uint major, uint minor, uint micro)
5719         {
5720             this.major = major;
5721             this.minor = minor;
5722             this.micro = micro;
5723         }
5724 
5725         /**
5726          * Return the (runtime) version of the used cairo
5727          * library.
5728          */
5729         static @property Version cairoVersion()
5730         {
5731             return Version(cairo_version());
5732         }
5733 
5734         /**
5735          * Returns the (compile time) version of this binding / wrapper.
5736          */
5737         static @property Version bindingVersion()
5738         {
5739             return Version(CAIRO_VERSION_MAJOR, CAIRO_VERSION_MINOR,
5740                 CAIRO_VERSION_MICRO);
5741         }
5742 
5743         /**
5744          * Returns the version in encoded form.
5745          */
5746         ulong encode()
5747         {
5748             return CAIRO_VERSION_ENCODE(major, minor, micro);
5749         }
5750 
5751         /**
5752          * toString implementation
5753          */
5754         string toString()
5755         {
5756             return CAIRO_VERSION_STRINGIZE(major, minor, micro);
5757         }
5758 }
5759 
5760 
5761 /**
5762  * RandomAccessRange to iterate or index into Clips of a Cairo Region.
5763  * This range keeps a reference to its $(D Region) object,
5764  * so it can be passed around without thinking about memory management.
5765  */
5766 public struct ClipRange
5767 {
5768     private Region _outer;
5769     private int _a, _b;
5770 
5771     this(Region data)
5772     {
5773         _outer = data;
5774         _b = _outer.numRectangles();
5775     }
5776 
5777     this(Region data, int a, int b)
5778     {
5779         _outer = data;
5780         _a = a;
5781         _b = b;
5782     }
5783 
5784     @property bool empty() // const
5785     {
5786         assert(_outer.numRectangles() >= _b);
5787         return _a >= _b;
5788     }
5789 
5790     @property typeof(this) save()
5791     {
5792         return this;
5793     }
5794 
5795     @property Rectangle!int front()
5796     {
5797         assert(!empty);
5798         return _outer.getRectangle(_a);
5799     }
5800 
5801     @property Rectangle!int back()
5802     {
5803         assert(!empty);
5804         return _outer.getRectangle(_b - 1);
5805     }
5806 
5807     void popFront()
5808     {
5809         assert(!empty);
5810         ++_a;
5811     }
5812 
5813     void popBack()
5814     {
5815         assert(!empty);
5816         --_b;
5817     }
5818 
5819     Rectangle!int opIndex(int i)
5820     {
5821         i += _a;
5822         assert(i < _b && _b <= _outer.numRectangles);
5823         return _outer.getRectangle(i);
5824     }
5825 
5826     typeof(this) opSlice()
5827     {
5828         return this;
5829     }
5830 
5831     typeof(this) opSlice(int a, int b)
5832     {
5833         return typeof(this)(_outer, a + _a, b + _a);
5834     }
5835 
5836     @property size_t length() const {
5837         return _b - _a;
5838     }
5839 }
5840 
5841 unittest
5842 {
5843     import std.range;
5844     static assert(isRandomAccessRange!ClipRange);
5845 }
5846 
5847 unittest
5848 {
5849     import std.array, std.range;
5850     auto rect1 = Rectangle!int(0, 0, 100, 100);
5851     auto rect2 = Rectangle!int(200, 200, 100, 100);
5852 
5853     static assert(!hasLvalueElements!ClipRange);
5854 
5855     auto region = Region(rect1);
5856     region.unionWith(rect2);
5857 
5858     assert(region.getRectangles().length == 2);
5859     assert(region.getRectangles()[].length == 2);
5860     assert(array(region.getRectangles()) == [rect1, rect2]);
5861 
5862     assert(region.getRectangles()[1..2].length == 1);
5863     assert(region.getRectangles()[1..2][0] == rect2);
5864 
5865     assert(region.getRectangles()[0] == rect1);
5866     assert(region.getRectangles()[1] == rect2);
5867 
5868     foreach (int i, clip; [rect1, rect2])
5869     {
5870         assert(region.getRectangles()[i] == clip);
5871     }
5872 
5873     /* @BUG@ Access Violation */
5874     //foreach (regRect, oldRect; lockstep(region.getRectangles(), region.getRectangles()))
5875     auto oldRects = [rect1, rect2];
5876     size_t i = 0;
5877     foreach (Rectangle!int regRect; region.getRectangles())
5878     {
5879         assert(regRect == oldRects[i++]);
5880     }
5881 }
5882 
5883 
5884 public struct Region
5885 {
5886     /*---------------------------Reference counting stuff---------------------------*/
5887     protected:
5888         void _reference()
5889         {
5890             cairo_region_reference(this.nativePointer);
5891         }
5892 
5893         void _dereference()
5894         {
5895             cairo_region_destroy(this.nativePointer);
5896         }
5897 
5898     public:
5899         /**
5900          * The underlying $(D cairo_t*) handle
5901          */
5902         cairo_region_t* nativePointer;
5903         version(D_Ddoc)
5904         {
5905              /**
5906              * Enable / disable memory management debugging for this Context
5907              * instance. Only available if both cairoD and the cairoD user
5908              * code were compiled with "debug=RefCounted"
5909              *
5910              * Output is written to stdout, see
5911              * $(LINK https://github.com/jpf91/cairoD/wiki/Memory-Management#debugging)
5912              * for more information
5913              */
5914              bool debugging = false;
5915         }
5916         else debug(RefCounted)
5917         {
5918             bool debugging = false;
5919         }
5920 
5921         /**
5922          * Constructor that tracks the reference count appropriately. If $(D
5923          * !refCountedIsInitialized), does nothing.
5924          */
5925         this(this)
5926         {
5927             if (this.nativePointer is null)
5928                 return;
5929             this._reference();
5930             debug(RefCounted)
5931                 if (this.debugging)
5932             {
5933                      writeln(typeof(this).stringof,
5934                     "@", cast(void*) this.nativePointer, ": bumped refcount.");
5935             }
5936         }
5937 
5938         ~this()
5939         {
5940             this.dispose();
5941         }
5942 
5943         /**
5944          * Explicitly drecrease the reference count.
5945          *
5946          * See $(LINK https://github.com/jpf91/cairoD/wiki/Memory-Management#2.1-structs)
5947          * for more information.
5948          */
5949         void dispose()
5950         {
5951            if (this.nativePointer is null)
5952                 return;
5953 
5954             debug(RefCounted)
5955                 if (this.debugging)
5956             {
5957                      writeln(typeof(this).stringof,
5958                     "@", cast(void*)this.nativePointer,
5959                     ": decrement refcount");
5960             }
5961             this._dereference();
5962             this.nativePointer = null;
5963         }
5964 
5965         /**
5966          * Assignment operator
5967          */
5968         void opAssign(Region rhs)
5969         {
5970             this.nativePointer = cairo_region_copy(rhs.nativePointer);
5971             debug(RefCounted)
5972                 this.debugging = rhs.debugging;
5973         }
5974     /*------------------------End of Reference counting-----------------------*/
5975 
5976     public:
5977         this(Region region)
5978         {
5979             this(cairo_region_copy(region.nativePointer));
5980             debug(RefCounted)
5981                 this.debugging = region.debugging;
5982         }
5983 
5984         /**
5985          * Create a $(D Region) from a existing $(D cairo_region_t*).
5986          * Context is a garbage collected class. It will call $(D cairo_region_destroy)
5987          * when it gets collected by the GC or when $(D dispose()) is called.
5988          *
5989          * Warning:
5990          * $(D ptr)'s reference count is not increased by this function!
5991          * Adjust reference count before calling it if necessary
5992          *
5993          * $(RED Only use this if you know what your doing!
5994          * This function should not be needed for standard cairoD usage.)
5995          */
5996         this(cairo_region_t* ptr)
5997         {
5998             this.nativePointer = ptr;
5999             if(!ptr)
6000             {
6001                 throw new CairoException(cairo_status_t.CAIRO_STATUS_NULL_POINTER);
6002             }
6003             checkError();
6004         }
6005 
6006     protected:
6007         /**
6008          * Method for use in subclasses.
6009          * Calls $(D cairo_region_status(nativePointer)) and throws
6010          * an exception if the status isn't CAIRO_STATUS_SUCCESS
6011          */
6012         final void checkError()
6013         {
6014             throwError(cairo_region_status(nativePointer));
6015         }
6016 
6017     public:
6018         /**
6019          * Create a new, empty region
6020          *
6021          * Note: The Region constructors can be used to create a new Region with Rectangles
6022          */
6023         static Region create()
6024         {
6025             return Region(cairo_region_create());
6026         }
6027 
6028         /**
6029          *
6030          */
6031         Region copy()
6032         {
6033             return Region(cairo_region_copy(this.nativePointer));
6034         }
6035 
6036         /**
6037          *
6038          */
6039         this(Rectangle!int rect)
6040         {
6041             this(cairo_region_create_rectangle(cast(cairo_rectangle_int_t*)&rect));
6042         }
6043 
6044         /**
6045          *
6046          */
6047         this(Rectangle!int[] rects)
6048         {
6049             this(cairo_region_create_rectangles(cast(cairo_rectangle_int_t*)rects.ptr, rects.length.toCairoCount()));
6050         }
6051 
6052         /**
6053          *
6054          */
6055         Rectangle!int getExtents()
6056         {
6057             Rectangle!int extents;
6058             cairo_region_get_extents(this.nativePointer, cast(cairo_rectangle_int_t*)&extents);
6059             checkError();
6060             return extents;
6061         }
6062 
6063         /**
6064          *
6065          */
6066         int numRectangles()
6067         {
6068             return cairo_region_num_rectangles(this.nativePointer);
6069         }
6070 
6071         /**
6072          *
6073          */
6074         Rectangle!int getRectangle(int index)
6075         {
6076             Rectangle!int rect;
6077             cairo_region_get_rectangle(this.nativePointer, index, cast(cairo_rectangle_int_t*)&rect);
6078             checkError();
6079             return rect;
6080         }
6081 
6082         /**
6083          *
6084          */
6085         auto getRectangles()
6086         {
6087             return ClipRange(this);
6088         }
6089 
6090         /**
6091          *
6092          */
6093         bool isEmpty()
6094         {
6095             return cast(bool)cairo_region_is_empty(this.nativePointer);
6096         }
6097 
6098         /**
6099          *
6100          */
6101         RegionOverlap containsRectangle(Rectangle!int rect)
6102         {
6103             return cairo_region_contains_rectangle(this.nativePointer, cast(cairo_rectangle_int_t*)&rect);
6104         }
6105 
6106         /**
6107          *
6108          */
6109         bool containsPoint(Point!int point)
6110         {
6111             return cast(bool)cairo_region_contains_point(this.nativePointer, point.x, point.y);
6112         }
6113 
6114         /**
6115          *
6116          */
6117         const bool opEquals(ref const(Region) other)
6118         {
6119             return cast(bool)cairo_region_equal(this.nativePointer, other.nativePointer);
6120         }
6121 
6122         /**
6123          *
6124          */
6125         void translate(int dx, int dy)
6126         {
6127             cairo_region_translate(this.nativePointer, dx, dy);
6128             checkError();
6129         }
6130 
6131         /**
6132          *
6133          */
6134         void intersect(Region other)
6135         {
6136             throwError(cairo_region_intersect(this.nativePointer, other.nativePointer));
6137         }
6138         /**
6139          *
6140          */
6141         void intersect(Rectangle!int other)
6142         {
6143             throwError(cairo_region_intersect_rectangle(this.nativePointer, cast(cairo_rectangle_int_t*)&other));
6144         }
6145 
6146         /**
6147          *
6148          */
6149         void subtract(Region other)
6150         {
6151             throwError(cairo_region_subtract_rectangle(this.nativePointer, cast(cairo_rectangle_int_t*)&other));
6152         }
6153 
6154         /**
6155          *
6156          */
6157         void subtract(Rectangle!int other)
6158         {
6159             throwError(cairo_region_subtract_rectangle(this.nativePointer, cast(cairo_rectangle_int_t*)&other));
6160         }
6161 
6162         /**
6163          *
6164          */
6165         void unionWith(Region other)
6166         {
6167             throwError(cairo_region_union(this.nativePointer, other.nativePointer));
6168         }
6169 
6170         /**
6171          *
6172          */
6173         void unionWith(Rectangle!int other)
6174         {
6175             throwError(cairo_region_union_rectangle(this.nativePointer, cast(cairo_rectangle_int_t*)&other));
6176         }
6177 
6178         /**
6179          *
6180          */
6181         void xor(Region other)
6182         {
6183             throwError(cairo_region_xor(this.nativePointer, other.nativePointer));
6184         }
6185 
6186         /**
6187          *
6188          */
6189         void xor(Rectangle!int other)
6190         {
6191             throwError(cairo_region_xor_rectangle(this.nativePointer, cast(cairo_rectangle_int_t*)&other));
6192         }
6193 }
6194 
6195 unittest
6196 {
6197     auto rect1 = Rectangle!int(0, 0, 100, 100);
6198     auto region = Region(rect1);
6199 
6200     assert(region.numRectangles == 1);
6201     assert(!region.isEmpty());
6202 
6203     assert(region.containsPoint(Point!int(50, 0)));
6204     assert(!region.containsPoint(Point!int(100, 0)));  // 100 is over the range of 0 .. 100 (99 is max)
6205 
6206     region.translate(10, 0);
6207     assert(region.containsPoint(Point!int(100, 0)));   // range is now 10 .. 110
6208     assert(!region.containsPoint(Point!int(0, 0)));    // 0 is below the minimum of 10
6209 
6210     region.xor(region);  // xor, 1 ^ 1 == 0 :)
6211     assert(region.isEmpty());
6212 
6213     auto rect2 = Rectangle!int(99, 0, 100, 100);
6214     region = Region([rect1, rect2]);
6215     assert(region.numRectangles == 1);  // note: cairo merges the two rectangles as they
6216                                         // form a closed rectangle path.
6217 
6218     rect2.point.x = 120;
6219     region = Region([rect1, rect2]);
6220     assert(region.numRectangles == 2);  // now they can't be merged
6221 
6222     region = Region(rect1);
6223     region.unionWith(rect2);
6224     assert(region.numRectangles == 2);  // same thing when using a union
6225 
6226     rect2.point.x += 10;
6227     region.subtract(rect2);
6228     assert(region.numRectangles == 2);  // still two rectangles due to extra edge
6229 
6230     rect2.point.x -= 10;
6231     region.subtract(rect2);
6232     assert(region.numRectangles == 1);  // and now the second rectangle is completely gone
6233 
6234     region.subtract(rect1);
6235     assert(region.isEmpty);             // first rectangle also gone, region is empty
6236 
6237     auto region1 = Region(rect1);
6238     auto region2 = Region(rect1);
6239     assert(region1 == region2);
6240 }
6241 
6242 unittest
6243 {
6244     auto surface = new ImageSurface(Format.CAIRO_FORMAT_ARGB32, 100, 100);
6245     auto ctx = Context(surface);
6246 
6247     ctx.rectangle(10, 20, 100, 100);
6248     auto path = ctx.copyPath();
6249 
6250     size_t index;
6251     foreach (element; path[])
6252     {
6253         switch (element.type)
6254         {
6255              case PathElementType.CAIRO_PATH_MOVE_TO:
6256              {
6257                  assert(element[0].x == 10 && element[0].y == 20);
6258                  break;
6259              }
6260              case PathElementType.CAIRO_PATH_LINE_TO:
6261              {
6262                  if (index == 1)
6263                      assert(element[0].x == 110 && element[0].y == 20);
6264                  else if (index == 2)
6265                      assert(element[0].x == 110 && element[0].y == 120);
6266                  else if (index == 3)
6267                      assert(element[0].x == 10 && element[0].y == 120);
6268                  break;
6269              }
6270              default:
6271         }
6272         index++;
6273     }
6274 }