root/trunk/cairo/cairooo/context.d

Revision 179, 29.5 kB (checked in by DRK, 5 years ago)

* Updated everything in cairo so that it compiles in the latest version of DMD. Also re-ran all the snippets, demos and tutorials, and checked that they worked.

Line 
1 /**
2     Context is the main class upon which you do your drawing operations.
3     It acts as an interface to the backing surface-specific routines that
4     actually do the drawing.
5
6     The typical way to draw on to a surface in cairo is to first create a
7     Surface object, wrap that in a Context, and then perform your drawing
8     operations on your Context.
9
10 Examples
11 ------------------------------------------------------------------------------
12 import cairooo.all;
13
14 void main()
15 {
16     Cairo.load();
17
18     auto Surface surface = new ImageSurface(Format.ARGB32, 256, 256);
19     auto Context cr = new Context(surface);
20
21     // Perform your drawing operations using cr...
22 }
23 ------------------------------------------------------------------------------
24 Authors: Daniel Keep
25 Copyright: 2006, Daniel Keep
26 License: BSD v2 (http://opensource.org/licenses/bsd-license.php).
27 **/
28 /**
29     Copyright © 2006 Daniel Keep
30     All rights reserved.
31     
32     Redistribution and use in source and binary forms, with or without
33     modification, are permitted provided that the following conditions are
34     met:
35     
36     * Redistributions of source code must retain the above copyright
37       notice, this list of conditions and the following disclaimer.
38       
39     * Redistributions in binary form must reproduce the above copyright
40       notice, this list of conditions and the following disclaimer in the
41       documentation and/or other materials provided with the distribution.
42     
43     * Neither the name of this software, nor the names of its contributors
44       may be used to endorse or promote products derived from this software
45       without specific prior written permission.
46     
47     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
48     "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
49     TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
50     PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
51     CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
52     EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
53     PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
54     PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
55     LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
56     NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
57     SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
58 **/
59 module cairooo.context;
60
61 private
62 {
63     import std.string;
64     import cairo.cairo;
65     import cairooo.enums;
66     import cairooo.exceptions;
67     import cairooo.fontextents;
68     import cairooo.fontface;
69     import cairooo.fontoptions;
70     import cairooo.glyph;
71     import cairooo.matrix;
72     import cairooo.path;
73     import cairooo.pattern;
74     import cairooo.surface;
75     import cairooo.textextents;
76 }
77
78 /**
79     The cairo drawing context.
80 **/
81 class Context
82 {
83 private:
84     cairo_t* _handle;
85
86 public:
87     /**
88         Creates a new drawing context from the specified surface.
89     **/
90     this(Surface surface)
91     {
92         this._handle = cairo_create(surface.handle);
93     }
94
95     /**
96         Wraps the low-level cairo context in a new object.  This method is most
97         useful for wrapping pointers returned from cairo api functions that are
98         not yet supported by the OO api.  Please note that this function is
99         slightly dangerous and can lead to memory leaks if misused (see below).
100         
101         Please note that it is $(I vitally) important that you use the takeref
102         parameter correctly.  If takeref is set to false, then the
103         object will $(I not) add to the handle's reference count.  This means
104         that if you do not pass the correct value for takeref, then you could
105         end up with handles either not being destroyed, or being destroyed too
106         early!
107         
108     Params:
109         handle      = Pointer to a cairo_t context.
110         takeref     = Should the object take a reference to this handle?
111     **/
112     this(cairo_t* handle, bool takeref)
113     {
114         checkStatus(handle);
115         this._handle = handle;
116         if( takeref )
117         {
118             cairo_reference(this.handle);
119             checkStatus(this.handle);
120         }
121     }
122
123     /**
124         Duplicates a context, providing a new, independant reference
125         to it.
126     **/
127     this(Context context)
128     {
129         this(context.handle, true);
130     }
131
132     ~this()
133     {
134         cairo_destroy(this.handle);
135     }
136
137     //
138     // cairo api members
139     //
140
141     /**
142         Makes a copy of the current state of the context, and places it on an
143         internal stack.  When the restore method is called, it restores the
144         context to the state stored at the top of this internal stack.
145
146         It is not neccecary to explicitly restore all the saved states on this
147         stack before the Context is destroyed.
148     **/
149     void
150     save()
151     {
152         scope(success) checkStatus();
153         cairo_save(this.handle);
154     }
155
156     /**
157         Restores a state stored by the save member.
158
159     See_Also: save
160     **/
161     void
162     restore()
163     {
164         scope(success) checkStatus();
165         cairo_restore(this.handle);
166     }
167
168     /**
169         Returns the surface which this context is performing operations on.
170     **/
171     Surface
172     target()
173     {
174         scope(success) checkStatus();
175         return Surface.rewrapSurfaceHandle(cairo_get_target(this.handle));
176     }
177
178     /**
179         Sets the current source pattern to the supplied opaque colour.
180         This colour will be used until a different pattern is set.
181
182     Params:
183         red     = Colour's red component.
184         green   = Colour's green component.
185         blue    = Colour's blue component.
186     **/
187     void
188     setSourceRGB(double red, double green, double blue)
189     {
190         scope(success) checkStatus();
191         cairo_set_source_rgb(this.handle, red, green, blue);
192     }
193
194     /+/// ditto
195     void
196     setSourceRGB(RGB color)
197     {
198         this.setSourceRGB(color.r, color.g, color.b);
199     }+/
200
201     /**
202         Sets the current source pattern to the supplied transparent colour.
203         This colour will be used until a different pattern is set.
204
205     Params:
206         red     = Colour's red component.
207         green   = Colour's green component.
208         blue    = Colour's blue component.
209         alpha   = Colour's alpha component.
210     **/
211     void
212     setSourceRGBA(double red, double green, double blue, double alpha)
213     {
214         scope(success) checkStatus();
215         cairo_set_source_rgba(this.handle, red, green, blue, alpha);
216     }
217
218     /+/// ditto
219     void
220     setSourceRGBA(RGBA color)
221     {
222         this.setSourceRGBA(color.r, color.g, color.b, color.a);
223     }+/
224
225     // NOTE: setSource/getSource are *not* implemented as getters/setters
226     // since they are overloaded, and the surface version takes extra
227     // arguments.
228
229     /**
230         Sets the source pattern for this context.  This pattern will be used
231         until a different pattern is set.
232
233     Params:
234         source = The pattern to use.
235     **/
236     void
237     setSource(Pattern source)
238     {
239         scope(success) checkStatus();
240         cairo_set_source(this.handle, source.handle);
241     }
242
243     /**
244         Sets the source pattern for this context to the given surface.  You
245         can also specify the user-space coordinates at which the surface will
246         appear at.  This pattern will be used until a different pattern is
247         set.
248
249     Params:
250         source =    The surface to display.
251         x =         The X user-space coordinate where the surface will appear.
252         y =         The Y user-space coordinate where the surface will appear.
253     **/
254     void
255     setSource(Surface source, double x, double y)
256     {
257         scope(success) checkStatus();
258         cairo_set_source_surface(this.handle, source.handle, x, y);
259     }
260
261     /+/// ditto
262     void
263     setSource(Surface source, Point offset)
264     {
265         this.setSource(source, offset.x, offset.y);
266     }+/
267
268     /**
269         Retrieves the current pattern being used by this context.
270
271         Please note that this function will return the pattern as an instance
272         of the base Pattern type, and not of a more specific type.
273
274     Returns: The current Pattern used by this Context.
275     **/
276     Pattern
277     getSource()
278     {
279         scope(success) checkStatus();
280         return new Pattern(cairo_get_source(this.handle), true);
281     }
282
283     /**
284         This property gives you access to the antialiasing scheme being used
285         by this context.
286     **/
287     Antialias
288     antialias()
289     {
290         scope(success) checkStatus();
291         return cast(Antialias) cairo_get_antialias(this.handle);
292     }
293
294     /// ditto
295     Antialias
296     antialias(Antialias value)
297     {
298         scope(success) checkStatus();
299         cairo_set_antialias(this.handle, cast(cairo_antialias_t) value);
300         return value;
301     }
302
303     /**
304         Sets the pattern of dashes which will be used by this context for
305         stroking paths.
306
307         The array describes the length of each alternating on/off segment of
308         the dash.  For example, if you wanted a dash that had visible segments
309         5 units in length and gaps 1 unit in length, you would pass an array
310         containing the values 5.0 and 1.0 to the dashes argument.
311
312     Params:
313         dashes =    Describes the length of each alternating on/off segment.
314         offset =    An offset into the dash pattern.
315     **/
316     void
317     setDash(double[] dashes, double offset)
318     {
319         scope(success) checkStatus();
320         cairo_set_dash(this.handle, dashes.ptr, dashes.length, offset);
321     }
322
323     /**
324         This property lets you access this context's current fill rule.
325     **/
326     FillRule
327     fillRule()
328     {
329         scope(success) checkStatus();
330         return cast(FillRule) cairo_get_fill_rule(this.handle);
331     }
332
333     /// ditto
334     FillRule
335     fillRule(FillRule value)
336     {
337         scope(success) checkStatus();
338         cairo_set_fill_rule(this.handle, cast(cairo_fill_rule_t) value);
339         return value;
340     }
341
342     /**
343         This property lets you access this context's current line cap style.
344     **/
345     LineCap
346     lineCap()
347     {
348         scope(success) checkStatus();
349         return cast(LineCap) cairo_get_line_cap(this.handle);
350     }
351
352     /// ditto
353     LineCap
354     lineCap(LineCap value)
355     {
356         scope(success) checkStatus();
357         cairo_set_line_cap(this.handle, cast(cairo_line_cap_t) value);
358         return value;
359     }
360
361     /**
362         This property lets you access this context's current line join style.
363     **/
364     LineJoin
365     lineJoin()
366     {
367         scope(success) checkStatus();
368         return cast(LineJoin) cairo_get_line_join(this.handle);
369     }
370
371     /// ditto
372     LineJoin
373     lineJoin(LineJoin value)
374     {
375         scope(success) checkStatus();
376         cairo_set_line_join(this.handle, cast(cairo_line_join_t) value);
377         return value;
378     }
379
380     /// This property lets you access this context's current line width.
381     double
382     lineWidth()
383     {
384         scope(success) checkStatus();
385         return cairo_get_line_width(this.handle);
386     }
387
388     /// ditto
389     double
390     lineWidth(double value)
391     {
392         scope(success) checkStatus();
393         cairo_set_line_width(this.handle, value);
394         return value;
395     }
396    
397     /// This property lets you access this context's current miter limit.
398     double
399     miterLimit()
400     {
401         scope(success) checkStatus();
402         return cairo_get_miter_limit(this.handle);
403     }
404
405     /// ditto
406     double
407     miterLimit(double value)
408     {
409         scope(success) checkStatus();
410         cairo_set_miter_limit(this.handle, value);
411         return value;
412     }
413
414     /// This property lets you access this context's current operator setting.
415     Operator
416     operator()
417     {
418         scope(success) checkStatus();
419         return cast(Operator) cairo_get_operator(this.handle);
420     }
421
422     /// ditto
423     Operator
424     operator(Operator value)
425     {
426         scope(success) checkStatus();
427         cairo_set_operator(this.handle, cast(cairo_operator_t) value);
428         return value;
429     }
430
431     /**
432         This property lets you access this context's current tolerance
433         setting.
434
435         This value is used when converting curved paths into line segments.
436         The curved path will be subdivided until the maximum deviation between
437         the original path and the straight line approximation is less than the
438         value of tolerance.
439
440         The default value is 0.1, and should be sufficient for most purposes.
441         Larger values will give better performance at the cost of jagged
442         curved.  Smaller values will give a smoother appearance to curved
443         paths at the cost of slower performance.
444         
445         Except in extreme
446         circumstances, reducing the value of tolerance from the default is
447         unlikely to significantly improve appearance.
448     **/
449     double
450     tolerance()
451     {
452         scope(success) checkStatus();
453         return cairo_get_tolerance(this.handle);
454     }
455
456     /// ditto
457     double
458     tolerance(double value)
459     {
460         scope(success) checkStatus();
461         cairo_set_tolerance(this.handle, value);
462         return value;
463     }
464
465     /**
466         Creates a new clip region by intersecting the current clip region with
467         the current Path as if it was filled by calling the fill method under
468         the current fill rule.
469
470         Calling clip can only make the clip region smaller, never larger.  If
471         you wish to reset the clip region, then you should call resetClip.
472         The clip region is also part of the context's state, and as such can
473         be managed using save/restore.
474
475         Calling this method consumes the current path.
476     **/
477     void
478     clip()
479     {
480         scope(success) checkStatus();
481         cairo_clip(this.handle);
482     }
483
484     /**
485         Creates a new clip region by intersecting the current clip region with
486         the current Path as if it was filled by calling the fill method under
487         the current fill rule.
488
489         Calling clip can only make the clip region smaller, never larger.  If
490         you wish to reset the clip region, then you should call resetClip.
491         The clip region is also part of the context's state, and as such can
492         be managed using save/restore.
493
494         Calling this method will not consume the current path.
495     **/
496     void
497     clipPreserve()
498     {
499         scope(success) checkStatus();
500         cairo_clip_preserve(this.handle);
501     }
502
503     /**
504         Resets the clip region to cover the entire surface.
505     **/
506     void
507     resetClip()
508     {
509         scope(success) checkStatus();
510         cairo_reset_clip(this.handle);
511     }
512
513     /**
514         Fills the active path with the current source, using the current fill
515         rule.
516
517         Calling this method will consume the current path.
518     **/
519     void
520     fill()
521     {
522         scope(success) checkStatus();
523         cairo_fill(this.handle);
524     }
525
526     /**
527         Fills the active path with the current source, using the current fill
528         rule.
529
530         Calling this method will not consume the current path.
531     **/
532     void
533     fillPreserve()
534     {
535         scope(success) checkStatus();
536         cairo_fill_preserve(this.handle);
537     }
538
539     /**
540         Computes the rectangle that contains the complete filled area of the
541         current path using the current fill rule.
542     **/
543     void
544     fillExtents(out double x1, out double y1, out double x2, out double y2)
545     {
546         scope(success) checkStatus();
547         cairo_fill_extents(this.handle, &x1, &y1, &x2, &y2);
548     }
549
550     /+/// ditto
551     Extent
552     fillExtents()
553     {
554         Extent result;
555         this.fillExtents(result.pt0.x, result.pt0.y, result.pt1.x,
556                 result.pt1.y);
557         return result;
558     }+/
559
560     /**
561         Determines if the specified point is inside the current path's filled
562         area.
563     **/
564     bool
565     inFill(double x, double y)
566     {
567         scope(success) checkStatus();
568         return cast(bool) cairo_in_fill(this.handle, x, y);
569     }
570
571     /+/// ditto
572     bool
573     inFill(Point pt)
574     {
575         return this.inFill(pt.x, pt.y);
576     }+/
577
578     /**
579         This paints the current source using the specified pattern's alpha
580         channel as a mask.
581     **/
582     void
583     mask(Pattern pattern)
584     {
585         scope(success) checkStatus();
586         cairo_mask(this.handle, pattern.handle);
587     }
588
589     /**
590         This paints the current source using the specified surface's alpha
591         channel as a mask.  The x and y coordinates have the same meaning as
592         for setSource(surface, x, y).
593     **/
594     void
595     maskSurface(Surface surface, double x, double y)
596     {
597         scope(success) checkStatus();
598         cairo_mask_surface(this.handle, surface.handle, x, y);
599     }
600
601     /+/// ditto
602     void
603     maskSurface(Surface surface, Point pt)
604     {
605         this.maskSurface(surface, pt.x, pt.y);
606     }+/
607
608     /**
609         This paints the current source everywhere on to the underlying
610         surface.
611     **/
612     void
613     paint()
614     {
615         scope(success) checkStatus();
616         cairo_paint(this.handle);
617     }
618
619     /**
620         This paints the current source everywhere on to the underlying
621         surface, using the specified alpha blending value.
622     **/
623     void
624     paintWithAlpha(double alpha)
625     {
626         scope(success) checkStatus();
627         cairo_paint_with_alpha(this.handle, alpha);
628     }
629
630     ///
631     void
632     stroke()
633     {
634         scope(success) checkStatus();
635         cairo_stroke(this.handle);
636     }
637
638     ///
639     void
640     strokePreserve()
641     {
642         scope(success) checkStatus();
643         cairo_stroke_preserve(this.handle);
644     }
645
646     ///
647     void
648     strokeExtents(out double x1, out double y1, out double x2, out double y2)
649     {
650         scope(success) checkStatus();
651         cairo_stroke_extents(this.handle, &x1, &y1, &x2, &y2);
652     }
653
654     /+/// ditto
655     Extent
656     strokeExtents()
657     {
658         Extent result;
659         this.strokeExtents(result.pt0.x, result.pt0.y, result.pt1.x,
660                 result.pt1.y);
661         return result;
662     }+/
663
664     ///
665     bool
666     inStroke(double x, double y)
667     {
668         scope(success) checkStatus();
669         return cast(bool) cairo_in_stroke(this.handle, x, y);
670     }
671
672     /+/// ditto
673     bool
674     inStroke(Point pt)
675     {
676         return this.inStroke(pt.x, pt.y);
677     }+/
678
679     ///
680     void
681     copyPage()
682     {
683         scope(success) checkStatus();
684         cairo_copy_page(this.handle);
685     }
686
687     ///
688     void
689     showPage()
690     {
691         scope(success) checkStatus();
692         cairo_show_page(this.handle);
693     }
694
695     ///
696     Path
697     copyPath()
698     {
699         scope(success) checkStatus();
700         return new Path(cairo_copy_path(this.handle));
701     }
702
703     ///
704     Path
705     copyPathFlat()
706     {
707         scope(success) checkStatus();
708         return new Path(cairo_copy_path_flat(this.handle));
709     }
710
711     //
712     // cairo path api members
713     //
714    
715     ///
716     void
717     appendPath(Path path)
718     {
719         scope(success) checkStatus();
720         cairo_append_path(this.handle, path.handle);
721     }
722
723     ///
724     void
725     getCurrentPoint(out double x, out double y)
726     {
727         scope(success) checkStatus();
728         cairo_get_current_point(this.handle, &x, &y);
729     }
730
731     /+/// ditto
732     Point
733     getCurrentPoint()
734     {
735         Point result;
736         this.getCurrentPoint(result.x, result.y);
737         return result;
738     }+/
739
740     ///
741     void
742     newPath()
743     {
744         scope(success) checkStatus();
745         cairo_new_path(this.handle);
746     }
747
748     ///
749     void
750     closePath()
751     {
752         scope(success) checkStatus();
753         cairo_close_path(this.handle);
754     }
755
756     ///
757     void
758     arc(double xc, double yc, double radius, double angle1, double angle2)
759     {
760         scope(success) checkStatus();
761         cairo_arc(this.handle, xc, yc, radius, angle1, angle2);
762     }
763
764     /+/// ditto
765     void
766     arc(Point center, double radius, double angle1, double angle2)
767     {
768         this.arc(center.x, center.y, radius, angle1, angle2);
769     }+/
770
771     ///
772     void
773     arcNegative(double xc, double yc, double radius, double angle1,
774             double angle2)
775     {
776         scope(success) checkStatus();
777         cairo_arc_negative(this.handle, xc, yc, radius, angle1, angle2);
778     }
779
780     /+/// ditto
781     void
782     arcNegative(Point center, double radius, double angle1, double angle2)
783     {
784         this.arcNegative(center.x, center.y, radius, angle1, angle2);
785     }+/
786
787     ///
788     void
789     curveTo(double x1, double y1, double x2, double y2,
790             double x3, double y3)
791     {
792         scope(success) checkStatus();
793         cairo_curve_to(this.handle, x1, y1, x2, y2, x3, y3);
794     }
795
796     /+/// ditto
797     void
798     curveTo(Point pt1, Point pt2, Point pt3)
799     {
800         this.curveTo(pt1.x, pt1.y, pt2.x, pt2.y, pt3.x, pt3.y);
801     }+/
802
803     ///
804     void
805     lineTo(double x, double y)
806     {
807         scope(success) checkStatus();
808         cairo_line_to(this.handle, x, y);
809     }
810
811     /+/// ditto
812     void
813     lineTo(Point pt)
814     {
815         this.lineTo(pt.x, pt.y);
816     }+/
817
818     ///
819     void
820     moveTo(double x, double y)
821     {
822         scope(success) checkStatus();
823         cairo_move_to(this.handle, x, y);
824     }
825
826     /+/// ditto
827     void
828     moveTo(Point pt)
829     {
830         this.moveTo(pt.x, pt.y);
831     }+/
832
833     ///
834     void
835     rectangle(double x, double y, double width, double height)
836     {
837         scope(success) checkStatus();
838         cairo_rectangle(this.handle, x, y, width, height);
839     }
840
841     /+/// ditto
842     void
843     rectangle(Rect rect)
844     {
845         this.rectangle(rect.origin.x, rect.origin.y, rect.size.w,
846                 rect.size.h);
847     }+/
848
849     ///
850     void
851     glyphPath(Glyph[] glyphs)
852     {
853         scope(success) checkStatus();
854         cairo_glyph_path(this.handle, cast(cairo_glyph_t*) glyphs.ptr,
855                 glyphs.length);
856     }
857
858     ///
859     void
860     textPath(char[] utf8)
861     {
862         scope(success) checkStatus();
863         cairo_text_path(this.handle, toStringz(utf8));
864     }
865
866     ///
867     void
868     relCurveTo(double dx1, double dy1, double dx2, double dy2,
869             double dx3, double dy3)
870     {
871         scope(success) checkStatus();
872         cairo_rel_curve_to(this.handle, dx1, dy1, dx2, dy2, dx3, dy3);
873     }
874
875     /+/// ditto
876     void
877     relCurveTo(Point dpt1, Point dpt2, Point dpt3)
878     {
879         this.relCurveTo(dpt1.x, dpt1.y, dpt2.x, dpt2.y, dpt3.x, dpt3.y);
880     }+/
881
882     ///
883     void
884     relLineTo(double dx, double dy)
885     {
886         scope(success) checkStatus();
887         cairo_rel_line_to(this.handle, dx, dy);
888     }
889
890     /+/// ditto
891     void
892     relLineTo(Point dpt)
893     {
894         this.relLineTo(dpt.x, dpt.y);
895     }+/
896
897     ///
898     void
899     relMoveTo(double dx, double dy)
900     {
901         scope(success) checkStatus();
902         cairo_rel_move_to(this.handle, dx, dy);
903     }
904
905     /+/// ditto
906     void
907     relMoveTo(Point dpt)
908     {
909         this.relMoveTo(dpt.x, dpt.y);
910     }+/
911
912     //
913     // cairo transformation api members
914     //
915
916     ///
917     void
918     translate(double tx, double ty)
919     {
920         scope(success) checkStatus();
921         cairo_translate(this.handle, tx, ty);
922     }
923
924     /+/// ditto
925     void
926     translate(Point dpt)
927     {
928         this.translate(dpt.x, dpt.y);
929     }+/
930
931     ///
932     void
933     scale(double sx, double sy)
934     {
935         scope(success) checkStatus();
936         cairo_scale(this.handle, sx, sy);
937     }
938
939     /+/// ditto
940     void
941     scale(Size sz)
942     {
943         this.scale(sz.w, sz.h);
944     }+/
945
946     ///
947     void
948     rotate(double angle)
949     {
950         scope(success) checkStatus();
951         cairo_rotate(this.handle, angle);
952     }
953
954     ///
955     void
956     transform(Matrix matrix)
957     {
958         scope(success) checkStatus();
959         cairo_transform(this.handle, matrix.toPtr);
960     }
961
962     ///
963     Matrix
964     matrix()
965     {
966         scope(success) checkStatus();
967         Matrix result;
968         cairo_get_matrix(this.handle, result.toPtr);
969         return result;
970     }
971
972     ///
973     Matrix
974     matrix(Matrix value)
975     {
976         scope(success) checkStatus();
977         cairo_set_matrix(this.handle, value.toPtr);
978         return value;
979     }
980
981     ///
982     void
983     identityMatrix()
984     {
985         scope(success) checkStatus();
986         cairo_identity_matrix(this.handle);
987     }
988
989     ///
990     void
991     userToDevice(inout double x, inout double y)
992     {
993         scope(success) checkStatus();
994         cairo_user_to_device(this.handle, &x, &y);
995     }
996
997     /+/// ditto
998     Point
999     userToDevice(Point pt)
1000     {
1001         Point result = pt;
1002         this.userToDevice(pt.x, pt.y);
1003         return result;
1004     }+/
1005
1006     ///
1007     void
1008     userToDeviceDistance(inout double dx, inout double dy)
1009     {
1010         scope(success) checkStatus();
1011         cairo_user_to_device_distance(this.handle, &dx, &dy);
1012     }
1013
1014     /+/// ditto
1015     Point
1016     userToDeviceDistance(Point dpt)
1017     {
1018         Point result = dpt;
1019         this.userToDeviceDistance(dpt.x, dpt.y);
1020         return result;
1021     }+/
1022
1023     ///
1024     void
1025     deviceToUser(inout double x, inout double y)
1026     {
1027         scope(success) checkStatus();
1028         cairo_device_to_user(this.handle, &x, &y);
1029     }
1030
1031     /+/// ditto
1032     Point
1033     deviceToUser(Point pt)
1034     {
1035         Point result = pt;
1036         this.deviceToUser(result.x, result.y);
1037         return result;
1038     }+/
1039
1040     ///
1041     void
1042     deviceToUserDistance(inout double dx, inout double dy)
1043     {
1044         scope(success) checkStatus();
1045         cairo_device_to_user_distance(this.handle, &dx, &dy);
1046     }
1047
1048     /+/// ditto
1049     Point
1050     deviceToUserDistance(Point dpt)
1051     {
1052         Point result = dpt;
1053         this.deviceToUserDistance(dpt.x, dpt.y);
1054         return result;
1055     }+/
1056
1057     //
1058     // cairo text api members
1059     //
1060
1061     ///
1062     void
1063     selectFontFace(char[] family, FontSlant slant, FontWeight weight)
1064     {
1065         scope(success) checkStatus();
1066         cairo_select_font_face(this.handle, .toStringz(family),
1067                 cast(cairo_font_slant_t) slant,
1068                 cast(cairo_font_weight_t) weight);
1069     }
1070
1071     ///
1072     void
1073     setFontSize(double size)
1074     {
1075         scope(success) checkStatus();
1076         cairo_set_font_size(this.handle, size);
1077     }
1078
1079     ///
1080     Matrix
1081     fontMatrix()
1082     {
1083         scope(success) checkStatus();
1084         Matrix result;
1085         cairo_get_font_matrix(this.handle, result.toPtr);
1086         return result;
1087     }
1088
1089     ///
1090     Matrix
1091     fontMatrix(Matrix value)
1092     {
1093         scope(success) checkStatus();
1094         cairo_set_font_matrix(this.handle, value.toPtr);
1095         return value;
1096     }
1097    
1098     ///
1099     FontOptions
1100     fontOptions()
1101     {
1102         scope(success) checkStatus();
1103         auto FontOptions temp = new FontOptions;
1104         cairo_get_font_options(this.handle, temp.handle);
1105         return temp.dup;
1106     }
1107
1108     ///
1109     FontOptions
1110     fontOptions(FontOptions value)
1111     {
1112         scope(success) checkStatus();
1113         cairo_set_font_options(this.handle, value.handle);
1114     }
1115
1116     ///
1117     void
1118     showText(char[] utf8)
1119     {
1120         scope(success) checkStatus();
1121         cairo_show_text(this.handle, toStringz(utf8));
1122     }
1123
1124     ///
1125     void
1126     showGlyphs(Glyph[] glyphs)
1127     {
1128         scope(success) checkStatus();
1129         cairo_show_glyphs(this.handle, cast(cairo_glyph_t*) glyphs.ptr,
1130                 glyphs.length);
1131     }
1132
1133     ///
1134     FontFace
1135     fontFace()
1136     {
1137         scope(success) checkStatus();
1138         return new FontFace(cairo_get_font_face(this.handle), true);
1139     }
1140
1141     ///
1142     FontFace
1143     fontFace(FontFace value)
1144     {
1145         scope(success) checkStatus();
1146         cairo_set_font_face(this.handle, value.handle);
1147     }
1148
1149     ///
1150     FontExtents
1151     fontExtents()
1152     {
1153         scope(success) checkStatus();
1154         FontExtents result;
1155         cairo_font_extents(this.handle, cast(cairo_font_extents_t*) &result);
1156         return result;
1157     }
1158
1159     ///
1160     TextExtents
1161     textExtents(char[] utf8)
1162     {
1163         scope(success) checkStatus();
1164         TextExtents result;
1165         cairo_text_extents(this.handle, .toStringz(utf8),
1166                 cast(cairo_text_extents_t*) &result);
1167         return result;
1168     }
1169
1170     ///
1171     TextExtents
1172     glyphExtents(Glyph[] glyphs)
1173     {
1174         scope(success) checkStatus();
1175         TextExtents result;
1176         cairo_glyph_extents(this.handle, cast(cairo_glyph_t*) glyphs.ptr,
1177                 glyphs.length, cast(cairo_text_extents_t*) &result);
1178         return result;
1179     }
1180    
1181     //
1182     // Extra members
1183     //
1184
1185     /**
1186      * Duplicates this context, providing a new, independant reference
1187      * to it.
1188      */
1189     Context
1190     dup()
1191     {
1192         return new Context(this);
1193     }
1194
1195     /**
1196      * Returns the underlying cairo handle.
1197      */
1198     cairo_t*
1199     handle()
1200     {
1201         return this._handle;
1202     }
1203
1204     ///
1205     int
1206     opEquals(Context other)
1207     {
1208         return this.handle == other.handle;
1209     }
1210
1211     //
1212     // Internal stuff
1213     //
1214 protected:
1215     void
1216     checkStatus()
1217     {
1218         .checkStatus(cairo_status(this._handle));
1219     }
1220
1221     void
1222     checkStatus(cairo_t* handle)
1223     {
1224         .checkStatus(cairo_status(handle));
1225     }
1226 }
Note: See TracBrowser for help on using the browser.