Updating built in Io code to use += instead of x = x + y
[io/quag.git] / addons / Cairo / source / IoCairoPathElement.c
blob1c756b39466082eeba1fc12e8524e32e3c191a68
1 /*#io
2 CairoPathElement ioDoc(
3 docCopyright("Daniel Rosengren", 2007)
4 docLicense("BSD revised")
5 docCategory("Graphics")
6 */
8 #include "IoCairoPathElement.h"
9 #include "IoCairoPath.h"
10 #include "IoNumber.h"
11 #include "tools.h"
12 #include <stdlib.h>
14 #define DATA(self) ((IoCairoPathElementData *)IoObject_dataPointer(self))
15 #define PATH_DATA(self) (DATA(self)->pathData)
17 static int IoCairoPathElement_pointCount(IoCairoPathElement *self);
20 static IoTag *IoCairoPathElement_newTag(void *state)
22 IoTag *tag = IoTag_newWithName_("CairoPathElement");
23 IoTag_state_(tag, state);
24 IoTag_cloneFunc_(tag, (IoTagCloneFunc *)IoCairoPathElement_rawClone);
25 IoTag_freeFunc_(tag, (IoTagFreeFunc *)IoCairoPathElement_free);
26 IoTag_markFunc_(tag, (IoTagFreeFunc *)IoCairoPathElement_mark);
27 return tag;
30 IoCairoPathElement *IoCairoPathElement_proto(void *state)
32 IoObject *self = IoObject_new(state);
33 IoObject_tag_(self, IoCairoPathElement_newTag(state));
35 IoState_registerProtoWithFunc_(state, self, IoCairoPathElement_proto);
38 IoMethodTable methodTable[] = {
39 {"kind", IoCairoPathElement_kind},
40 {"pointAt", IoCairoPathElement_pointAt},
42 {NULL, NULL},
45 IoObject_addMethodTable_(self, methodTable);
48 return self;
51 IoCairoPathElement *IoCairoPathElement_rawClone(IoCairoPathElement *proto)
53 IoObject *self = IoObject_rawClonePrimitive(proto);
54 return self;
57 IoCairoPathElement *IoCairoPathElement_newWithPath_dataOffset_(void *state, IoObject *path, int offset)
59 IoCairoPathElement *self = IOCLONE(IoState_protoWithInitFunction_(state, IoCairoPathElement_proto));
60 cairo_path_t *rawPath = ((IoCairoPathData *)IoObject_dataPointer(path))->path;
62 IoObject_setDataPointer_(self, malloc(sizeof(IoCairoPathElementData)));
63 DATA(self)->path = path;
64 PATH_DATA(self) = rawPath->data + offset;
65 return self;
68 void IoCairoPathElement_free(IoCairoPathElement *self)
70 if (DATA(self))
71 free(DATA(self));
74 void IoCairoPathElement_mark(IoCairoPathElement *self)
76 if (DATA(self))
77 IoObject_shouldMark(DATA(self)->path);
81 /* ------------------------------------------------------------------------------------------------*/
83 IoObject *IoCairoPathElement_kind(IoCairoPathElement *self, IoObject *locals, IoMessage *m)
85 return IONUMBER(PATH_DATA(self)->header.type);
88 IoObject *IoCairoPathElement_pointAt(IoCairoPathElement *self, IoObject *locals, IoMessage *m)
90 cairo_path_data_t *data = 0;
91 int pointCount = 0;
92 int i = 0;
94 if (!DATA(self)) return IONIL(self);
96 i = IoMessage_locals_intArgAt_(m, locals, 0);
97 pointCount = IoCairoPathElement_pointCount(self);
98 if (i < 0 || i >= pointCount) return IONIL(self);
100 data = PATH_DATA(self) + i + 1;
101 return IoSeq_newWithX_y_(IOSTATE, data->point.x, data->point.y);
105 /* ------------------------------------------------------------------------------------------------*/
106 /* Private */
108 static int IoCairoPathElement_pointCount(IoCairoPathElement *self)
110 switch (PATH_DATA(self)->header.type)
112 case CAIRO_PATH_MOVE_TO:
113 return 1;
114 case CAIRO_PATH_LINE_TO:
115 return 1;
116 case CAIRO_PATH_CURVE_TO:
117 return 3;
118 case CAIRO_PATH_CLOSE_PATH:
119 return 0;
121 return 0;