Updating built in Io code to use += instead of x = x + y
[io/quag.git] / addons / Cairo / source / IoCairoContext.c
blobb606b6633c3fec124446d67840702e1b39dfa8e5
1 /*#io
2 CairoContext ioDoc(
3 docCopyright("Daniel Rosengren", 2007)
4 docLicense("BSD revised")
5 docCategory("Graphics")
6 */
8 #include "IoCairoContext.h"
9 #include "IoCairoSurface.h"
10 #include "IoCairoPattern.h"
11 #include "IoCairoMatrix.h"
12 #include "IoCairoPath.h"
13 #include "IoCairoRectangle.h"
15 #include "IoCairoFontFace.h"
16 #include "IoCairoScaledFont.h"
17 #include "IoCairoFontExtents.h"
18 #include "IoCairoFontOptions.h"
19 #include "IoCairoTextExtents.h"
20 #include "IoCairoExtents.h"
21 #include "IoCairoGlyph.h"
23 #include "IoNumber.h"
24 #include "IoList.h"
25 #include "tools.h"
27 #define CONTEXT(self) ((cairo_t *)IoObject_dataPointer(self))
28 #define CHECK_STATUS(self) checkStatus_(IOSTATE, m, cairo_status(CONTEXT(self)))
31 static IoTag *IoCairoContext_newTag(void *state)
33 IoTag *tag = IoTag_newWithName_("CairoContext");
34 IoTag_state_(tag, state);
35 IoTag_cloneFunc_(tag, (IoTagCloneFunc *)IoCairoContext_rawClone);
36 IoTag_freeFunc_(tag, (IoTagFreeFunc *)IoCairoContext_free);
37 return tag;
40 IoCairoContext *IoCairoContext_proto(void *state)
42 IoObject *self = IoObject_new(state);
43 IoObject_tag_(self, IoCairoContext_newTag(state));
45 IoState_registerProtoWithFunc_(state, self, IoCairoContext_proto);
48 IoMethodTable methodTable[] = {
49 {"create", IoCairoContext_create},
51 {"save", IoCairoContext_save},
52 {"restore", IoCairoContext_restore},
54 {"getTarget", IoCairoContext_getTarget},
56 /* Groups */
58 {"pushGroup", IoCairoContext_pushGroup},
59 {"pushGroupWithContent", IoCairoContext_pushGroupWithContent},
60 {"popGroup", IoCairoContext_popGroup},
61 {"popGroupToSource", IoCairoContext_popGroupToSource},
62 {"getGroupTarget", IoCairoContext_getGroupTarget},
64 /* Source */
66 {"setSource", IoCairoContext_setSource},
67 {"setSourceRGB", IoCairoContext_setSourceRGB},
68 {"setSourceRGBA", IoCairoContext_setSourceRGBA},
69 {"setSourceSurface", IoCairoContext_setSourceSurface},
70 {"getSource", IoCairoContext_getSource},
72 /* Options / Properties */
74 {"setAntialias", IoCairoContext_setAntialias},
75 {"getAntialias", IoCairoContext_getAntialias},
77 {"setDash", IoCairoContext_setDash},
78 {"getDash", IoCairoContext_getDash},
79 {"getDashCount", IoCairoContext_getDashCount},
81 {"setFillRule", IoCairoContext_setFillRule},
82 {"getFillRule", IoCairoContext_getFillRule},
84 {"setLineCap", IoCairoContext_setLineCap},
85 {"getLineCap", IoCairoContext_getLineCap},
87 {"setLineJoin", IoCairoContext_setLineJoin},
88 {"getLineJoin", IoCairoContext_getLineJoin},
90 {"setLineWidth", IoCairoContext_setLineWidth},
91 {"getLineWidth", IoCairoContext_getLineWidth},
93 {"setMiterLimit", IoCairoContext_setMiterLimit},
94 {"getMiterLimit", IoCairoContext_getMiterLimit},
96 {"setOperator", IoCairoContext_setOperator},
97 {"getOperator", IoCairoContext_getOperator},
99 {"setTolerance", IoCairoContext_setTolerance},
100 {"getTolerance", IoCairoContext_getTolerance},
102 /* Paths */
104 {"newPath", IoCairoContext_newPath},
105 {"newSubPath", IoCairoContext_newSubPath},
106 {"closePath", IoCairoContext_closePath},
107 {"appendPath", IoCairoContext_appendPath},
108 {"copyPath", IoCairoContext_copyPath},
109 {"copyPathFlat", IoCairoContext_copyPathFlat},
110 {"getCurrentPoint", IoCairoContext_getCurrentPoint},
112 {"moveTo", IoCairoContext_moveTo},
113 {"lineTo", IoCairoContext_lineTo},
114 {"curveTo", IoCairoContext_curveTo},
115 {"relMoveTo", IoCairoContext_relMoveTo},
116 {"relCurveTo", IoCairoContext_relCurveTo},
117 {"relLineTo", IoCairoContext_relLineTo},
119 {"rectangle", IoCairoContext_rectangle},
120 {"arc", IoCairoContext_arc},
121 {"arcNegative", IoCairoContext_arcNegative},
123 {"textPath", IoCairoContext_textPath},
124 {"glyphPath", IoCairoContext_glyphPath},
126 /* Clipping */
128 {"clip", IoCairoContext_clip},
129 {"clipPreserve", IoCairoContext_clipPreserve},
130 {"clipExtents", IoCairoContext_clipExtents},
131 {"resetClip", IoCairoContext_resetClip},
132 {"copyClipRectangleList", IoCairoContext_copyClipRectangleList},
134 /* Drawing */
136 {"fill", IoCairoContext_fill},
137 {"fillPreserve", IoCairoContext_fillPreserve},
138 {"fillExtents", IoCairoContext_fillExtents},
139 {"inFill", IoCairoContext_inFill},
141 {"mask", IoCairoContext_mask},
142 {"maskSurface", IoCairoContext_maskSurface},
144 {"paint", IoCairoContext_paint},
145 {"paintWithAlpha", IoCairoContext_paintWithAlpha},
147 {"stroke", IoCairoContext_stroke},
148 {"strokePreserve", IoCairoContext_strokePreserve},
149 {"strokeExtents", IoCairoContext_strokeExtents},
150 {"inStroke", IoCairoContext_inStroke},
152 /* Transformations */
154 {"translate", IoCairoContext_translate},
155 {"scale", IoCairoContext_scale},
156 {"rotate", IoCairoContext_rotate},
157 {"transform", IoCairoContext_transform},
159 {"setMatrix", IoCairoContext_setMatrix},
160 {"getMatrix", IoCairoContext_getMatrix},
161 {"identityMatrix", IoCairoContext_identityMatrix},
163 {"userToDevice", IoCairoContext_userToDevice},
164 {"userToDeviceDistance", IoCairoContext_userToDeviceDistance},
165 {"deviceToUser", IoCairoContext_deviceToUser},
166 {"deviceToUserDistance", IoCairoContext_deviceToUserDistance},
168 /* Text */
170 {"selectFontFace", IoCairoContext_selectFontFace},
171 {"setFontFace", IoCairoContext_setFontFace},
172 {"getFontFace", IoCairoContext_getFontFace},
174 {"setFontSize", IoCairoContext_setFontSize},
176 {"fontExtents", IoCairoContext_fontExtents},
177 {"textExtents", IoCairoContext_textExtents},
178 {"glyphExtents", IoCairoContext_glyphExtents},
180 {"showText", IoCairoContext_showText},
181 {"showGlyphs", IoCairoContext_showGlyphs},
183 {"setScaledFont", IoCairoContext_setScaledFont},
184 {"getScaledFont", IoCairoContext_getScaledFont},
186 {"setFontOptions", IoCairoContext_setFontOptions},
187 {"getFontOptions", IoCairoContext_getFontOptions},
189 /* Pages */
191 {"copyPage", IoCairoContext_copyPage},
192 {"showPage", IoCairoContext_showPage},
194 {NULL, NULL},
196 IoObject_addMethodTable_(self, methodTable);
198 return self;
201 IoCairoContext *IoCairoContext_rawClone(IoCairoContext *proto)
203 IoObject *self = IoObject_rawClonePrimitive(proto);
204 if (CONTEXT(proto)) {
205 IoObject_setDataPointer_(self, cairo_reference(CONTEXT(proto)));
207 return self;
210 IoCairoContext *IoCairoContext_newWithSurface_(void *state, IoCairoImageSurface *surface)
212 IoCairoContext *self = IOCLONE(IoState_protoWithInitFunction_(state, IoCairoContext_proto));
213 cairo_t *rawContext = cairo_create(IoCairoSurface_rawSurface(surface));
214 checkStatus_(state, 0, cairo_status(rawContext));
215 IoObject_setDataPointer_(self, rawContext);
216 return self;
219 void IoCairoContext_free(IoCairoContext *self)
221 if (CONTEXT(self))
222 cairo_destroy(CONTEXT(self));
225 cairo_t *IoCairoContext_getRawContext(IoCairoContext *self)
227 return CONTEXT(self);
231 /* ------------------------------------------------------------------------------------------------*/
233 IoObject *IoCairoContext_create(IoCairoContext *self, IoObject *locals, IoMessage *m)
235 return IoCairoContext_newWithSurface_(IOSTATE, IoMessage_locals_valueArgAt_(m, locals, 0));
239 IoObject *IoCairoContext_save(IoCairoContext *self, IoObject *locals, IoMessage *m)
241 cairo_save(CONTEXT(self));
242 CHECK_STATUS(self);
243 return self;
246 IoObject *IoCairoContext_restore(IoCairoContext *self, IoObject *locals, IoMessage *m)
248 cairo_restore(CONTEXT(self));
249 CHECK_STATUS(self);
250 return self;
253 IoObject *IoCairoContext_getTarget(IoCairoContext *self, IoObject *locals, IoMessage *m)
255 cairo_surface_t *target = cairo_get_target(CONTEXT(self));
256 return IoCairoSurface_newWithRawSurface_(IOSTATE, m, cairo_surface_reference(target));
260 /* ------------------------------------------------------------------------------------------------*/
261 /* Source */
263 IoObject *IoCairoContext_setSource(IoCairoContext *self, IoObject *locals, IoMessage *m)
265 IoCairoPattern *pattern = IoMessage_locals_valueArgAt_(m, locals, 0);
266 cairo_set_source(CONTEXT(self), IoCairoPattern_rawPattern(pattern));
267 CHECK_STATUS(self);
268 return self;
271 IoObject *IoCairoContext_setSourceRGB(IoCairoContext *self, IoObject *locals, IoMessage *m)
273 double r = IoMessage_locals_doubleArgAt_(m, locals, 0);
274 double g = IoMessage_locals_doubleArgAt_(m, locals, 1);
275 double b = IoMessage_locals_doubleArgAt_(m, locals, 2);
277 cairo_set_source_rgb(CONTEXT(self), r, g, b);
278 CHECK_STATUS(self);
279 return self;
282 IoObject *IoCairoContext_setSourceRGBA(IoCairoContext *self, IoObject *locals, IoMessage *m)
284 double r = IoMessage_locals_doubleArgAt_(m, locals, 0);
285 double g = IoMessage_locals_doubleArgAt_(m, locals, 1);
286 double b = IoMessage_locals_doubleArgAt_(m, locals, 2);
287 double a = IoMessage_locals_doubleArgAt_(m, locals, 3);
289 cairo_set_source_rgba(CONTEXT(self), r, g, b, a);
290 CHECK_STATUS(self);
291 return self;
294 IoObject *IoCairoContext_setSourceSurface(IoCairoContext *self, IoObject *locals, IoMessage *m)
296 IoCairoSurface *surface = IoMessage_locals_valueArgAt_(m, locals, 0);
297 double x = IoMessage_locals_doubleArgAt_(m, locals, 1);
298 double y = IoMessage_locals_doubleArgAt_(m, locals, 2);
300 cairo_set_source_surface(CONTEXT(self), IoCairoSurface_rawSurface(surface), x, y);
301 CHECK_STATUS(self);
302 return self;
305 IoObject *IoCairoContext_getSource(IoCairoContext *self, IoObject *locals, IoMessage *m)
307 cairo_pattern_t *pattern = cairo_get_source(CONTEXT(self));
308 return IoCairoPattern_newWithRawPattern_(IOSTATE, m, cairo_pattern_reference(pattern));
312 /* ------------------------------------------------------------------------------------------------*/
313 /* Groups */
315 IoObject *IoCairoContext_pushGroup(IoCairoContext *self, IoObject *locals, IoMessage *m)
317 cairo_push_group(CONTEXT(self));
318 CHECK_STATUS(self);
319 return self;
322 IoObject *IoCairoContext_pushGroupWithContent(IoCairoContext *self, IoObject *locals, IoMessage *m)
324 cairo_push_group_with_content(CONTEXT(self), IoMessage_locals_intArgAt_(m, locals, 0));
325 CHECK_STATUS(self);
326 return self;
329 IoObject *IoCairoContext_popGroup(IoCairoContext *self, IoObject *locals, IoMessage *m)
331 cairo_pattern_t *pattern = cairo_pop_group(CONTEXT(self));
332 return IoCairoPattern_newWithRawPattern_(IOSTATE, m, cairo_pattern_reference(pattern));
335 IoObject *IoCairoContext_popGroupToSource(IoCairoContext *self, IoObject *locals, IoMessage *m)
337 cairo_pop_group_to_source(CONTEXT(self));
338 CHECK_STATUS(self);
339 return self;
342 IoObject *IoCairoContext_getGroupTarget(IoCairoContext *self, IoObject *locals, IoMessage *m)
344 cairo_surface_t *target = cairo_get_group_target(CONTEXT(self));
345 return IoCairoSurface_newWithRawSurface_(IOSTATE, m, cairo_surface_reference(target));
349 /* ------------------------------------------------------------------------------------------------*/
350 /* Options/Properties */
352 IoObject *IoCairoContext_setAntialias(IoCairoContext *self, IoObject *locals, IoMessage *m)
354 cairo_set_antialias(CONTEXT(self), IoMessage_locals_intArgAt_(m, locals, 0));
355 CHECK_STATUS(self);
356 return self;
359 IoObject *IoCairoContext_getAntialias(IoCairoContext *self, IoObject *locals, IoMessage *m)
361 return IONUMBER(cairo_get_antialias(CONTEXT(self)));
365 IoObject *IoCairoContext_setDash(IoCairoContext *self, IoObject *locals, IoMessage *m)
367 IoList *dashList = IoMessage_locals_valueArgAt_(m, locals, 0);
368 double offset = IoMessage_locals_doubleArgAt_(m, locals, 1);
369 List *list = 0;
370 int dashCount = 0;
371 double *dashes = 0;
373 if (!ISNIL(dashList)) {
374 list = IoList_rawList(dashList);
375 dashCount = List_size(list);
378 if (dashCount > 0)
380 dashes = malloc(sizeof(double) * dashCount);
381 LIST_FOREACH(list, i, number,
382 dashes[i] = IoNumber_asDouble(number);
386 cairo_set_dash(CONTEXT(self), dashes, dashCount, offset);
387 if (dashes)
388 free(dashes);
390 CHECK_STATUS(self);
391 return self;
394 IoObject *IoCairoContext_getDash(IoCairoContext *self, IoObject *locals, IoMessage *m)
396 IoList *list = IoList_new(IOSTATE);
397 IoList *dashList = IoList_new(IOSTATE);
398 int dashCount = cairo_get_dash_count(CONTEXT(self));
399 double *dashes = 0;
400 double offset = 0;
401 int i;
403 IoList_rawAppend_(list, dashList);
405 if (dashCount == 0)
407 IoList_rawAppend_(list, IONUMBER(0));
408 return list;
411 dashes = malloc(sizeof(double) * dashCount);
412 cairo_get_dash(CONTEXT(self), dashes, &offset);
413 for (i = 0; i < dashCount; i++)
414 IoList_rawAppend_(dashList, IONUMBER(dashes[i]));
415 free(dashes);
417 CHECK_STATUS(self);
418 IoList_rawAppend_(list, IONUMBER(offset));
419 return list;
422 IoObject *IoCairoContext_getDashCount(IoCairoContext *self, IoObject *locals, IoMessage *m)
424 return IONUMBER(cairo_get_dash_count(CONTEXT(self)));
428 IoObject *IoCairoContext_setFillRule(IoCairoContext *self, IoObject *locals, IoMessage *m)
430 cairo_set_fill_rule(CONTEXT(self), IoMessage_locals_intArgAt_(m, locals, 0));
431 CHECK_STATUS(self);
432 return self;
435 IoObject *IoCairoContext_getFillRule(IoCairoContext *self, IoObject *locals, IoMessage *m)
437 return IONUMBER(cairo_get_fill_rule(CONTEXT(self)));
441 IoObject *IoCairoContext_setLineCap(IoCairoContext *self, IoObject *locals, IoMessage *m)
443 cairo_set_line_cap(CONTEXT(self), IoMessage_locals_intArgAt_(m, locals, 0));
444 CHECK_STATUS(self);
445 return self;
448 IoObject *IoCairoContext_getLineCap(IoCairoContext *self, IoObject *locals, IoMessage *m)
450 return IONUMBER(cairo_get_line_cap(CONTEXT(self)));
454 IoObject *IoCairoContext_setLineJoin(IoCairoContext *self, IoObject *locals, IoMessage *m)
456 cairo_set_line_join(CONTEXT(self), IoMessage_locals_intArgAt_(m, locals, 0));
457 CHECK_STATUS(self);
458 return self;
461 IoObject *IoCairoContext_getLineJoin(IoCairoContext *self, IoObject *locals, IoMessage *m)
463 return IONUMBER(cairo_get_line_join(CONTEXT(self)));
467 IoObject *IoCairoContext_setLineWidth(IoCairoContext *self, IoObject *locals, IoMessage *m)
469 cairo_set_line_width(CONTEXT(self), IoMessage_locals_doubleArgAt_(m, locals, 0));
470 CHECK_STATUS(self);
471 return self;
474 IoObject *IoCairoContext_getLineWidth(IoCairoContext *self, IoObject *locals, IoMessage *m)
476 return IONUMBER(cairo_get_line_width(CONTEXT(self)));
480 IoObject *IoCairoContext_setMiterLimit(IoCairoContext *self, IoObject *locals, IoMessage *m)
482 cairo_set_miter_limit(CONTEXT(self), IoMessage_locals_doubleArgAt_(m, locals, 0));
483 CHECK_STATUS(self);
484 return self;
487 IoObject *IoCairoContext_getMiterLimit(IoCairoContext *self, IoObject *locals, IoMessage *m)
489 return IONUMBER(cairo_get_miter_limit(CONTEXT(self)));
493 IoObject *IoCairoContext_setOperator(IoCairoContext *self, IoObject *locals, IoMessage *m)
495 cairo_set_operator(CONTEXT(self), IoMessage_locals_intArgAt_(m, locals, 0));
496 CHECK_STATUS(self);
497 return self;
500 IoObject *IoCairoContext_getOperator(IoCairoContext *self, IoObject *locals, IoMessage *m)
502 return IONUMBER(cairo_get_operator(CONTEXT(self)));
506 IoObject *IoCairoContext_setTolerance(IoCairoContext *self, IoObject *locals, IoMessage *m)
508 cairo_set_tolerance(CONTEXT(self), IoMessage_locals_doubleArgAt_(m, locals, 0));
509 CHECK_STATUS(self);
510 return self;
513 IoObject *IoCairoContext_getTolerance(IoCairoContext *self, IoObject *locals, IoMessage *m)
515 return IONUMBER(cairo_get_tolerance(CONTEXT(self)));
519 /* ------------------------------------------------------------------------------------------------*/
520 /* Paths */
522 IoObject *IoCairoContext_newPath(IoCairoContext *self, IoObject *locals, IoMessage *m)
524 cairo_new_path(CONTEXT(self));
525 CHECK_STATUS(self);
526 return self;
529 IoObject *IoCairoContext_newSubPath(IoCairoContext *self, IoObject *locals, IoMessage *m)
531 cairo_new_sub_path(CONTEXT(self));
532 CHECK_STATUS(self);
533 return self;
536 IoObject *IoCairoContext_closePath(IoCairoContext *self, IoObject *locals, IoMessage *m)
538 cairo_close_path(CONTEXT(self));
539 CHECK_STATUS(self);
540 return self;
543 IoObject *IoCairoContext_appendPath(IoCairoContext *self, IoObject *locals, IoMessage *m)
545 IoCairoPath *path = IoMessage_locals_cairoPathArgAt_(m, locals, 0);
546 cairo_append_path(CONTEXT(self), IoCairoPath_rawPath(path));
547 CHECK_STATUS(self);
548 return self;
551 IoObject *IoCairoContext_copyPath(IoCairoContext *self, IoObject *locals, IoMessage *m)
553 return IoCairoPath_newWithRawPath_(IOSTATE, cairo_copy_path(CONTEXT(self)));
556 IoObject *IoCairoContext_copyPathFlat(IoCairoContext *self, IoObject *locals, IoMessage *m)
558 return IoCairoPath_newWithRawPath_(IOSTATE, cairo_copy_path_flat(CONTEXT(self)));
561 IoObject *IoCairoContext_getCurrentPoint(IoCairoContext *self, IoObject *locals, IoMessage *m)
563 double x = 0, y = 0;
564 cairo_get_current_point(CONTEXT(self), &x, &y);
565 return IoSeq_newWithX_y_(IOSTATE, x, y);
569 IoObject *IoCairoContext_moveTo(IoCairoContext *self, IoObject *locals, IoMessage *m)
571 double x = IoMessage_locals_doubleArgAt_(m, locals, 0);
572 double y = IoMessage_locals_doubleArgAt_(m, locals, 1);
574 cairo_move_to(CONTEXT(self), x, y);
575 CHECK_STATUS(self);
576 return self;
579 IoObject *IoCairoContext_lineTo(IoCairoContext *self, IoObject *locals, IoMessage *m)
581 double x = IoMessage_locals_doubleArgAt_(m, locals, 0);
582 double y = IoMessage_locals_doubleArgAt_(m, locals, 1);
584 cairo_line_to(CONTEXT(self), x, y);
585 CHECK_STATUS(self);
586 return self;
589 IoObject *IoCairoContext_curveTo(IoCairoContext *self, IoObject *locals, IoMessage *m)
591 double x1 = IoMessage_locals_doubleArgAt_(m, locals, 0);
592 double y1 = IoMessage_locals_doubleArgAt_(m, locals, 1);
593 double x2 = IoMessage_locals_doubleArgAt_(m, locals, 2);
594 double y2 = IoMessage_locals_doubleArgAt_(m, locals, 3);
595 double x3 = IoMessage_locals_doubleArgAt_(m, locals, 4);
596 double y3 = IoMessage_locals_doubleArgAt_(m, locals, 5);
598 cairo_curve_to(CONTEXT(self), x1, y1, x2, y2, x3, y3);
599 CHECK_STATUS(self);
600 return self;
603 IoObject *IoCairoContext_relMoveTo(IoCairoContext *self, IoObject *locals, IoMessage *m)
605 double dx = IoMessage_locals_doubleArgAt_(m, locals, 0);
606 double dy = IoMessage_locals_doubleArgAt_(m, locals, 1);
608 cairo_rel_move_to(CONTEXT(self), dx, dy);
609 CHECK_STATUS(self);
610 return self;
613 IoObject *IoCairoContext_relLineTo(IoCairoContext *self, IoObject *locals, IoMessage *m)
615 double dx = IoMessage_locals_doubleArgAt_(m, locals, 0);
616 double dy = IoMessage_locals_doubleArgAt_(m, locals, 1);
618 cairo_rel_line_to(CONTEXT(self), dx, dy);
619 CHECK_STATUS(self);
620 return self;
623 IoObject *IoCairoContext_relCurveTo(IoCairoContext *self, IoObject *locals, IoMessage *m)
625 double dx1 = IoMessage_locals_doubleArgAt_(m, locals, 0);
626 double dy1 = IoMessage_locals_doubleArgAt_(m, locals, 1);
627 double dx2 = IoMessage_locals_doubleArgAt_(m, locals, 2);
628 double dy2 = IoMessage_locals_doubleArgAt_(m, locals, 3);
629 double dx3 = IoMessage_locals_doubleArgAt_(m, locals, 4);
630 double dy3 = IoMessage_locals_doubleArgAt_(m, locals, 5);
632 cairo_rel_curve_to(CONTEXT(self), dx1, dy1, dx2, dy2, dx3, dy3);
633 CHECK_STATUS(self);
634 return self;
638 IoObject *IoCairoContext_arc(IoCairoContext *self, IoObject *locals, IoMessage *m)
640 double xc = IoMessage_locals_doubleArgAt_(m, locals, 0);
641 double yc = IoMessage_locals_doubleArgAt_(m, locals, 1);
642 double radius = IoMessage_locals_doubleArgAt_(m, locals, 2);
643 double angle1 = IoMessage_locals_doubleArgAt_(m, locals, 3);
644 double angle2 = IoMessage_locals_doubleArgAt_(m, locals, 4);
646 cairo_arc(CONTEXT(self), xc, yc, radius, angle1, angle2);
647 CHECK_STATUS(self);
648 return self;
651 IoObject *IoCairoContext_arcNegative(IoCairoContext *self, IoObject *locals, IoMessage *m)
653 double xc = IoMessage_locals_doubleArgAt_(m, locals, 0);
654 double yc = IoMessage_locals_doubleArgAt_(m, locals, 1);
655 double radius = IoMessage_locals_doubleArgAt_(m, locals, 2);
656 double angle1 = IoMessage_locals_doubleArgAt_(m, locals, 3);
657 double angle2 = IoMessage_locals_doubleArgAt_(m, locals, 4);
659 cairo_arc_negative(CONTEXT(self), xc, yc, radius, angle1, angle2);
660 CHECK_STATUS(self);
661 return self;
664 IoObject *IoCairoContext_rectangle(IoCairoContext *self, IoObject *locals, IoMessage *m)
666 double x = IoMessage_locals_doubleArgAt_(m, locals, 0);
667 double y = IoMessage_locals_doubleArgAt_(m, locals, 1);
668 double w = IoMessage_locals_doubleArgAt_(m, locals, 2);
669 double h = IoMessage_locals_doubleArgAt_(m, locals, 3);
671 cairo_rectangle(CONTEXT(self), x, y, w, h);
672 CHECK_STATUS(self);
673 return self;
676 IoObject *IoCairoContext_textPath(IoCairoContext *self, IoObject *locals, IoMessage *m)
678 cairo_text_path(CONTEXT(self), IoMessage_locals_UTF8ArgAt_(m, locals, 0));
679 CHECK_STATUS(self);
680 return self;
683 IoObject *IoCairoContext_glyphPath(IoCairoContext *self, IoObject *locals, IoMessage *m)
685 IoList *glyphList = IoMessage_locals_listArgAt_(m, locals, 0);
686 int glyphCount = 0;
687 cairo_glyph_t *glyphs = rawGlyphsFromList_count_(glyphList, &glyphCount);
689 if (!glyphs)
690 return self;
692 cairo_glyph_path(CONTEXT(self), glyphs, glyphCount);
693 free(glyphs);
694 CHECK_STATUS(self);
695 return self;
699 /* ------------------------------------------------------------------------------------------------*/
700 /* Clipping */
702 IoObject *IoCairoContext_clip(IoCairoContext *self, IoObject *locals, IoMessage *m)
704 cairo_clip(CONTEXT(self));
705 CHECK_STATUS(self);
706 return self;
709 IoObject *IoCairoContext_clipPreserve(IoCairoContext *self, IoObject *locals, IoMessage *m)
711 cairo_clip_preserve(CONTEXT(self));
712 CHECK_STATUS(self);
713 return self;
716 IoObject *IoCairoContext_clipExtents(IoCairoContext *self, IoObject *locals, IoMessage *m)
718 double x1, y1, x2, y2;
719 cairo_clip_extents(CONTEXT(self), &x1, &y1, &x2, &y2);
720 return IoCairoExtents_newSet(IOSTATE, x1, y1, x2, y2);
723 IoObject *IoCairoContext_resetClip(IoCairoContext *self, IoObject *locals, IoMessage *m)
725 cairo_reset_clip(CONTEXT(self));
726 CHECK_STATUS(self);
727 return self;
730 IoObject *IoCairoContext_copyClipRectangleList(IoCairoContext *self, IoObject *locals, IoMessage *m)
732 IoList *list = IoList_new(IOSTATE);
733 cairo_rectangle_list_t *rectList = cairo_copy_clip_rectangle_list(CONTEXT(self));
734 cairo_rectangle_t *rect = 0;
735 int i;
737 if (rectList->status != CAIRO_STATUS_SUCCESS)
738 IoState_error_(IOSTATE, m, "%s: cairo: %s", __func__, cairo_status_to_string(rectList->status));
740 rect = rectList->rectangles;
741 for (i = 0; i < rectList->num_rectangles; i++)
743 IoList_rawAppend_(list, IoCairoRectangle_newWithRawRectangle_(IOSTATE, rect));
744 rect++;
746 cairo_rectangle_list_destroy(rectList);
747 return list;
751 /* ------------------------------------------------------------------------------------------------*/
752 /* Drawing */
755 IoObject *IoCairoContext_fill(IoCairoContext *self, IoObject *locals, IoMessage *m)
757 cairo_fill(CONTEXT(self));
758 CHECK_STATUS(self);
759 return self;
762 IoObject *IoCairoContext_fillPreserve(IoCairoContext *self, IoObject *locals, IoMessage *m)
764 cairo_fill_preserve(CONTEXT(self));
765 CHECK_STATUS(self);
766 return self;
769 IoObject *IoCairoContext_fillExtents(IoCairoContext *self, IoObject *locals, IoMessage *m)
771 double x1, y1, x2, y2;
772 cairo_fill_extents(CONTEXT(self), &x1, &y1, &x2, &y2);
773 return IoCairoExtents_newSet(IOSTATE, x1, y1, x2, y2);
776 IoObject *IoCairoContext_inFill(IoCairoContext *self, IoObject *locals, IoMessage *m)
778 double x = IoMessage_locals_doubleArgAt_(m, locals, 0);
779 double y = IoMessage_locals_doubleArgAt_(m, locals, 1);
780 return IOBOOL(self, cairo_in_fill(CONTEXT(self), x, y));
784 IoObject *IoCairoContext_stroke(IoCairoContext *self, IoObject *locals, IoMessage *m)
786 cairo_stroke(CONTEXT(self));
787 CHECK_STATUS(self);
788 return self;
791 IoObject *IoCairoContext_strokePreserve(IoCairoContext *self, IoObject *locals, IoMessage *m)
793 cairo_stroke_preserve(CONTEXT(self));
794 CHECK_STATUS(self);
795 return self;
798 IoObject *IoCairoContext_strokeExtents(IoCairoContext *self, IoObject *locals, IoMessage *m)
800 double x1, y1, x2, y2;
801 cairo_stroke_extents(CONTEXT(self), &x1, &y1, &x2, &y2);
802 return IoCairoExtents_newSet(IOSTATE, x1, y1, x2, y2);
805 IoObject *IoCairoContext_inStroke(IoCairoContext *self, IoObject *locals, IoMessage *m)
807 double x = IoMessage_locals_doubleArgAt_(m, locals, 0);
808 double y = IoMessage_locals_doubleArgAt_(m, locals, 1);
809 return IOBOOL(self, cairo_in_stroke(CONTEXT(self), x, y));
813 IoObject *IoCairoContext_mask(IoCairoContext *self, IoObject *locals, IoMessage *m)
815 IoObject *pattern = IoMessage_locals_valueArgAt_(m, locals, 0);
816 cairo_mask(CONTEXT(self), IoCairoPattern_rawPattern(pattern));
817 CHECK_STATUS(self);
818 return self;
821 IoObject *IoCairoContext_maskSurface(IoCairoContext *self, IoObject *locals, IoMessage *m)
823 IoCairoSurface *surface = IoMessage_locals_valueArgAt_(m, locals, 0);
824 double x = IoMessage_locals_doubleArgAt_(m, locals, 1);
825 double y = IoMessage_locals_doubleArgAt_(m, locals, 2);
827 cairo_mask_surface(CONTEXT(self), IoCairoSurface_rawSurface(surface), x, y);
828 CHECK_STATUS(self);
829 return self;
833 IoObject *IoCairoContext_paint(IoCairoContext *self, IoObject *locals, IoMessage *m)
835 cairo_paint(CONTEXT(self));
836 CHECK_STATUS(self);
837 return self;
840 IoObject *IoCairoContext_paintWithAlpha(IoCairoContext *self, IoObject *locals, IoMessage *m)
842 cairo_paint_with_alpha(CONTEXT(self), IoMessage_locals_doubleArgAt_(m, locals, 0));
843 CHECK_STATUS(self);
844 return self;
848 /* ------------------------------------------------------------------------------------------------*/
849 /* Transformations */
851 IoObject *IoCairoContext_translate(IoCairoContext *self, IoObject *locals, IoMessage *m)
853 double tx = IoMessage_locals_doubleArgAt_(m, locals, 0);
854 double ty = IoMessage_locals_doubleArgAt_(m, locals, 1);
856 cairo_translate(CONTEXT(self), tx, ty);
857 CHECK_STATUS(self);
858 return self;
861 IoObject *IoCairoContext_scale(IoCairoContext *self, IoObject *locals, IoMessage *m)
863 double sx = IoMessage_locals_doubleArgAt_(m, locals, 0);
864 double sy = IoMessage_locals_doubleArgAt_(m, locals, 1);
866 cairo_scale(CONTEXT(self), sx, sy);
867 CHECK_STATUS(self);
868 return self;
871 IoObject *IoCairoContext_rotate(IoCairoContext *self, IoObject *locals, IoMessage *m)
873 cairo_rotate(CONTEXT(self), IoMessage_locals_doubleArgAt_(m, locals, 0));
874 CHECK_STATUS(self);
875 return self;
878 IoObject *IoCairoContext_transform(IoCairoContext *self, IoObject *locals, IoMessage *m)
880 IoCairoMatrix *matrix = IoMessage_locals_cairoMatrixArgAt_(m, locals, 0);
881 cairo_transform(CONTEXT(self), IoCairoMatrix_rawMatrix(matrix));
882 CHECK_STATUS(self);
883 return self;
887 IoObject *IoCairoContext_setMatrix(IoCairoContext *self, IoObject *locals, IoMessage *m)
889 IoCairoMatrix *matrix = IoMessage_locals_cairoMatrixArgAt_(m, locals, 0);
890 cairo_set_matrix(CONTEXT(self), IoCairoMatrix_rawMatrix(matrix));
891 CHECK_STATUS(self);
892 return self;
895 IoObject *IoCairoContext_getMatrix(IoCairoContext *self, IoObject *locals, IoMessage *m)
897 cairo_matrix_t matrix;
898 cairo_get_matrix(CONTEXT(self), &matrix);
899 return IoCairoMatrix_newWithRawMatrix_(IOSTATE, &matrix);
902 IoObject *IoCairoContext_identityMatrix(IoCairoContext *self, IoObject *locals, IoMessage *m)
904 cairo_identity_matrix(CONTEXT(self));
905 CHECK_STATUS(self);
906 return self;
910 IoObject *IoCairoContext_userToDevice(IoCairoContext *self, IoObject *locals, IoMessage *m)
912 double x = IoMessage_locals_doubleArgAt_(m, locals, 0);
913 double y = IoMessage_locals_doubleArgAt_(m, locals, 1);
915 cairo_user_to_device(CONTEXT(self), &x, &y);
916 CHECK_STATUS(self);
917 return IoSeq_newWithX_y_(IOSTATE, x, y);
920 IoObject *IoCairoContext_userToDeviceDistance(IoCairoContext *self, IoObject *locals, IoMessage *m)
922 double x = IoMessage_locals_doubleArgAt_(m, locals, 0);
923 double y = IoMessage_locals_doubleArgAt_(m, locals, 1);
925 cairo_user_to_device_distance(CONTEXT(self), &x, &y);
926 return IoSeq_newWithX_y_(IOSTATE, x, y);
929 IoObject *IoCairoContext_deviceToUser(IoCairoContext *self, IoObject *locals, IoMessage *m)
931 double x = IoMessage_locals_doubleArgAt_(m, locals, 0);
932 double y = IoMessage_locals_doubleArgAt_(m, locals, 1);
934 cairo_device_to_user(CONTEXT(self), &x, &y);
935 return IoSeq_newWithX_y_(IOSTATE, x, y);
938 IoObject *IoCairoContext_deviceToUserDistance(IoCairoContext *self, IoObject *locals, IoMessage *m)
940 double x = IoMessage_locals_doubleArgAt_(m, locals, 0);
941 double y = IoMessage_locals_doubleArgAt_(m, locals, 1);
943 cairo_device_to_user_distance(CONTEXT(self), &x, &y);
944 CHECK_STATUS(self);
945 return IoSeq_newWithX_y_(IOSTATE, x, y);
949 /* ------------------------------------------------------------------------------------------------*/
950 /* Text */
952 IoObject *IoCairoContext_setFontSize(IoCairoContext *self, IoObject *locals, IoMessage *m)
954 cairo_set_font_size(CONTEXT(self), IoMessage_locals_doubleArgAt_(m, locals, 0));
955 CHECK_STATUS(self);
956 return self;
960 IoObject *IoCairoContext_fontExtents(IoCairoContext *self, IoObject *locals, IoMessage *m)
962 cairo_font_extents_t extents;
963 cairo_font_extents(CONTEXT(self), &extents);
964 CHECK_STATUS(self);
965 return IoCairoFontExtents_newWithRawFontExtents(IOSTATE, &extents);
968 IoObject *IoCairoContext_textExtents(IoCairoContext *self, IoObject *locals, IoMessage *m)
970 const char *text = IoMessage_locals_UTF8ArgAt_(m, locals, 0);
971 cairo_text_extents_t extents;
973 cairo_text_extents(CONTEXT(self), text, &extents);
974 CHECK_STATUS(self);
975 return IoCairoTextExtents_newWithRawTextExtents(IOSTATE, &extents);
978 IoObject *IoCairoContext_glyphExtents(IoCairoContext *self, IoObject *locals, IoMessage *m)
980 IoList *glyphList = IoMessage_locals_listArgAt_(m, locals, 0);
981 int glyphCount = 0;
982 cairo_glyph_t *glyphs = rawGlyphsFromList_count_(glyphList, &glyphCount);
983 cairo_text_extents_t extents;
985 if (!glyphs)
986 return IONIL(self);
988 cairo_glyph_extents(CONTEXT(self), glyphs, glyphCount, &extents);
989 free(glyphs);
990 CHECK_STATUS(self);
991 return IoCairoTextExtents_newWithRawTextExtents(IOSTATE, &extents);
995 IoObject *IoCairoContext_showText(IoCairoContext *self, IoObject *locals, IoMessage *m)
997 cairo_show_text(CONTEXT(self), IoMessage_locals_UTF8ArgAt_(m, locals, 0));
998 CHECK_STATUS(self);
999 return self;
1002 IoObject *IoCairoContext_showGlyphs(IoCairoContext *self, IoObject *locals, IoMessage *m)
1004 IoList *glyphList = IoMessage_locals_listArgAt_(m, locals, 0);
1005 int glyphCount = 0;
1006 cairo_glyph_t *glyphs = rawGlyphsFromList_count_(glyphList, &glyphCount);
1008 if (!glyphs)
1009 return self;
1011 cairo_show_glyphs(CONTEXT(self), glyphs, glyphCount);
1012 free(glyphs);
1013 CHECK_STATUS(self);
1014 return self;
1018 IoObject *IoCairoContext_selectFontFace(IoCairoContext *self, IoObject *locals, IoMessage *m)
1020 char *family = CSTRING(IoMessage_locals_symbolArgAt_(m, locals, 0));
1021 cairo_font_slant_t slant = IoMessage_locals_intArgAt_(m, locals, 1);
1022 cairo_font_weight_t weight = IoMessage_locals_intArgAt_(m, locals, 2);
1024 cairo_select_font_face(CONTEXT(self), family, slant, weight);
1025 CHECK_STATUS(self);
1026 return self;
1029 IoObject *IoCairoContext_setFontFace(IoCairoContext *self, IoObject *locals, IoMessage *m)
1031 IoCairoFontFace *face = IoMessage_locals_cairoFontFaceArgAt_(m, locals, 0);
1032 cairo_set_font_face(CONTEXT(self), IoCairoFontFace_rawFontFace(face));
1033 CHECK_STATUS(self);
1034 return self;
1037 IoObject *IoCairoContext_getFontFace(IoCairoContext *self, IoObject *locals, IoMessage *m)
1039 cairo_font_face_t *face = cairo_get_font_face(CONTEXT(self));
1040 return IoCairoFontFace_newWithRawFontFace_(self, cairo_font_face_reference(face));
1044 IoObject *IoCairoContext_setScaledFont(IoCairoContext *self, IoObject *locals, IoMessage *m)
1046 IoCairoScaledFont *font = IoMessage_locals_cairoScaledFontArgAt_(m, locals, 0);
1047 cairo_set_scaled_font(CONTEXT(self), IoCairoScaledFont_rawScaledFont(font));
1048 CHECK_STATUS(self);
1049 return self;
1052 IoObject *IoCairoContext_getScaledFont(IoCairoContext *self, IoObject *locals, IoMessage *m)
1054 cairo_scaled_font_t *font = cairo_get_scaled_font(CONTEXT(self));
1055 return IoCairoScaledFont_newWithRawScaledFont_(IOSTATE, m, cairo_scaled_font_reference(font));
1059 IoObject *IoCairoContext_setFontOptions(IoCairoContext *self, IoObject *locals, IoMessage *m)
1061 IoCairoFontOptions *options = IoMessage_locals_cairoFontOptionsArgAt_(m, locals, 0);
1062 cairo_set_font_options(CONTEXT(self), IoCairoFontOptions_rawFontOptions(options));
1063 CHECK_STATUS(self);
1064 return self;
1067 IoObject *IoCairoContext_getFontOptions(IoCairoContext *self, IoObject *locals, IoMessage *m)
1069 cairo_font_options_t *options = cairo_font_options_create();
1070 cairo_get_font_options(CONTEXT(self), options);
1071 return IoCairoFontOptions_newWithRawFontOptions_(IOSTATE, m, options);
1075 /* ------------------------------------------------------------------------------------------------*/
1076 /* Pages */
1078 IoObject *IoCairoContext_copyPage(IoCairoContext *self, IoObject *locals, IoMessage *m)
1080 cairo_copy_page(CONTEXT(self));
1081 CHECK_STATUS(self);
1082 return self;
1085 IoObject *IoCairoContext_showPage(IoCairoContext *self, IoObject *locals, IoMessage *m)
1087 cairo_show_page(CONTEXT(self));
1088 CHECK_STATUS(self);
1089 return self;