Line data Source code
1 : /*
2 : +----------------------------------------------------------------------+
3 : | For PHP Version 8 |
4 : +----------------------------------------------------------------------+
5 : | Copyright (c) 2022 Swen Zanon |
6 : +----------------------------------------------------------------------+
7 : | http://www.opensource.org/licenses/mit-license.php MIT License |
8 : | Also available in LICENSE |
9 : +----------------------------------------------------------------------+
10 : | Authors: Swen Zanon <swen.zanon@geoglis.de> |
11 : +----------------------------------------------------------------------+
12 : */
13 :
14 : #ifdef HAVE_CONFIG_H
15 : #include "config.h"
16 : #endif
17 :
18 : #include <cairo.h>
19 : #include <php.h>
20 : #include <zend_exceptions.h>
21 :
22 : #include "php_cairo.h"
23 : #include "php_cairo_internal.h"
24 : #include "glyph_arginfo.h"
25 :
26 : zend_class_entry *ce_cairo_glyph;
27 :
28 : static zend_object_handlers cairo_glyph_object_handlers;
29 :
30 144 : cairo_glyph_object *cairo_glyph_fetch_object(zend_object *object)
31 : {
32 144 : return (cairo_glyph_object *) ((char*)(object) - XtOffsetOf(cairo_glyph_object, std));
33 : }
34 :
35 : /*static inline double cairo_glyph_get_property_value(zend_object *object, char *name) {
36 : zval *prop, rv;
37 :
38 : prop = zend_read_property(object->ce, object, name, strlen(name), 1, &rv);
39 : return zval_get_double(prop);
40 : }*/
41 :
42 : #define CAIRO_ALLOC_GLYPH(glyph_value) if (!glyph_value) \
43 : { glyph_value = ecalloc(1, sizeof(cairo_glyph_t)); }
44 :
45 : #define CAIRO_VALUE_FROM_STRUCT(n) \
46 : if (strcmp(member->val, #n) == 0) { \
47 : value = glyph_object->glyph->n; \
48 : break; \
49 : }
50 :
51 : #define CAIRO_VALUE_TO_STRUCT(n) \
52 : if (strcmp(member->val, #n) == 0) { \
53 : if (Z_TYPE_P(value) == IS_LONG) { \
54 : glyph_object->glyph->n = zval_get_long(value); \
55 : } else { \
56 : glyph_object->glyph->n = zval_get_double(value); \
57 : } \
58 : break; \
59 : }
60 :
61 : #define CAIRO_ADD_STRUCT_VALUE(n) \
62 : if (strcmp(#n, "index") == 0) { \
63 : ZVAL_LONG(&tmp, glyph_object->glyph->n); \
64 : } else { \
65 : ZVAL_DOUBLE(&tmp, glyph_object->glyph->n); \
66 : } \
67 : zend_hash_str_update(props, #n, sizeof(#n)-1, &tmp);
68 :
69 : /* ----------------------------------------------------------------
70 : \Cairo\Glyph C API
71 : ------------------------------------------------------------------*/
72 :
73 : /* {{{ */
74 26 : cairo_glyph_t *cairo_glyph_object_get_glyph(zval *zv)
75 : {
76 26 : cairo_glyph_object *glyph_object = Z_CAIRO_GLYPH_P(zv);
77 :
78 26 : return glyph_object->glyph;
79 : }
80 : /* }}} */
81 :
82 42 : zend_class_entry* php_cairo_get_glyph_ce()
83 : {
84 42 : return ce_cairo_glyph;
85 : }
86 :
87 : /* ----------------------------------------------------------------
88 : \Cairo\Glyph Class API
89 : ------------------------------------------------------------------*/
90 :
91 : /* {{{ proto void __construct(int index [, float x, float y])
92 : Creates a new glyph with the properties populated */
93 10 : PHP_METHOD(Cairo_Glyph, __construct)
94 : {
95 : cairo_glyph_object *glyph_object;
96 :
97 : /* read defaults from object */
98 : unsigned long index; //cairo_glyph_get_property_value(Z_OBJ_P(getThis()), "index");
99 10 : double x = 0.0; //cairo_glyph_get_property_value(Z_OBJ_P(getThis()), "x");
100 10 : double y = 0.0; //cairo_glyph_get_property_value(Z_OBJ_P(getThis()), "y");
101 :
102 : /* Now allow constructor to overwrite them if desired */
103 10 : ZEND_PARSE_PARAMETERS_START(1, 3)
104 16 : Z_PARAM_LONG(index)
105 7 : Z_PARAM_OPTIONAL
106 14 : Z_PARAM_DOUBLE(x)
107 12 : Z_PARAM_DOUBLE(y)
108 10 : ZEND_PARSE_PARAMETERS_END();
109 :
110 10 : glyph_object = Z_CAIRO_GLYPH_P(getThis());
111 :
112 5 : glyph_object->glyph->index = index;
113 5 : glyph_object->glyph->x = x;
114 5 : glyph_object->glyph->y = y;
115 : }
116 : /* }}} */
117 :
118 : /* ----------------------------------------------------------------
119 : \Cairo\Glyph Object management
120 : ------------------------------------------------------------------*/
121 :
122 : /* {{{ */
123 53 : static void cairo_glyph_free_obj(zend_object *zobj)
124 : {
125 53 : cairo_glyph_object *intern = cairo_glyph_fetch_object(zobj);
126 :
127 53 : if (!intern) {
128 0 : return;
129 : }
130 :
131 53 : if (intern->glyph) {
132 53 : efree(intern->glyph);
133 53 : intern->glyph = NULL;
134 : }
135 :
136 53 : zend_object_std_dtor(&intern->std);
137 : }
138 : /* }}} */
139 :
140 : /* {{{ */
141 53 : static zend_object* cairo_glyph_obj_ctor(zend_class_entry *ce, cairo_glyph_object **intern)
142 : {
143 53 : cairo_glyph_object *object = ecalloc(1, sizeof(cairo_glyph_object) + zend_object_properties_size(ce));
144 53 : CAIRO_ALLOC_GLYPH(object->glyph);
145 :
146 53 : zend_object_std_init(&object->std, ce);
147 :
148 53 : object->std.handlers = &cairo_glyph_object_handlers;
149 53 : *intern = object;
150 :
151 53 : return &object->std;
152 : }
153 : /* }}} */
154 :
155 : /* {{{ */
156 52 : static zend_object* cairo_glyph_create_object(zend_class_entry *ce)
157 : {
158 52 : cairo_glyph_object *intern = NULL;
159 52 : zend_object *return_value = cairo_glyph_obj_ctor(ce, &intern);
160 :
161 52 : object_properties_init(&intern->std, ce);
162 52 : return return_value;
163 : }
164 : /* }}} */
165 :
166 : /* {{{ */
167 1 : static zend_object* cairo_glyph_clone_obj(zend_object *zobj)
168 : {
169 : cairo_glyph_object *new_glyph;
170 1 : cairo_glyph_object *old_glyph = cairo_glyph_fetch_object(zobj);
171 1 : zend_object *return_value = cairo_glyph_obj_ctor(zobj->ce, &new_glyph);
172 1 : CAIRO_ALLOC_GLYPH(new_glyph->glyph);
173 :
174 1 : new_glyph->glyph->index = old_glyph->glyph->index;
175 1 : new_glyph->glyph->x = old_glyph->glyph->x;
176 1 : new_glyph->glyph->y = old_glyph->glyph->y;
177 :
178 1 : zend_objects_clone_members(&new_glyph->std, &old_glyph->std);
179 :
180 1 : return return_value;
181 : }
182 : /* }}} */
183 :
184 : /* {{{ */
185 7 : static zval *cairo_glyph_object_read_property(zend_object *zobj, zend_string *member, int type, void **cache_slot, zval *rv)
186 : {
187 : zval *retval;
188 : double value;
189 7 : cairo_glyph_object *glyph_object = cairo_glyph_fetch_object(zobj);
190 :
191 7 : if (!glyph_object) {
192 0 : return rv;
193 : }
194 :
195 : do {
196 : // break if struct member
197 7 : CAIRO_VALUE_FROM_STRUCT(index);
198 5 : CAIRO_VALUE_FROM_STRUCT(x);
199 3 : CAIRO_VALUE_FROM_STRUCT(y);
200 :
201 : // not a struct member
202 1 : retval = (zend_get_std_object_handlers())->read_property(zobj, member, type, cache_slot, rv);
203 :
204 1 : return retval;
205 : } while(0);
206 :
207 6 : retval = rv;
208 6 : if (strcmp(member->val, "index") == 0) {
209 2 : ZVAL_LONG(retval, value);
210 : } else {
211 4 : ZVAL_DOUBLE(retval, value);
212 : }
213 :
214 6 : return retval;
215 : }
216 : /* }}} */
217 :
218 : /* {{{ */
219 5 : static zval *cairo_glyph_object_write_property(zend_object *zobj, zend_string *member, zval *value, void **cache_slot)
220 : {
221 5 : cairo_glyph_object *glyph_object = cairo_glyph_fetch_object(zobj);
222 5 : zval *retval = NULL;
223 :
224 5 : if (!glyph_object) {
225 0 : return retval;
226 : }
227 :
228 : do {
229 9 : CAIRO_VALUE_TO_STRUCT(index);
230 5 : CAIRO_VALUE_TO_STRUCT(x);
231 4 : CAIRO_VALUE_TO_STRUCT(y);
232 : } while(0);
233 :
234 : // not a struct member
235 5 : retval = (zend_get_std_object_handlers())->write_property(zobj, member, value, cache_slot);
236 :
237 5 : return retval;
238 : }
239 : /* }}} */
240 :
241 : /* {{{ */
242 5 : static HashTable *cairo_glyph_object_get_properties(zend_object *zobj)
243 : {
244 : HashTable *props;
245 : // used in CAIRO_ADD_STRUCT_VALUE below
246 : zval tmp;
247 5 : cairo_glyph_object *glyph_object = cairo_glyph_fetch_object(zobj);
248 :
249 5 : props = zend_std_get_properties(zobj);
250 :
251 5 : if (!glyph_object->glyph) {
252 0 : return props;
253 : }
254 :
255 5 : CAIRO_ADD_STRUCT_VALUE(index);
256 5 : CAIRO_ADD_STRUCT_VALUE(x);
257 5 : CAIRO_ADD_STRUCT_VALUE(y);
258 :
259 5 : return props;
260 : }
261 : /* }}} */
262 :
263 : /* ----------------------------------------------------------------
264 : \Cairo\Glyph Definition and registration
265 : ------------------------------------------------------------------*/
266 :
267 : /* {{{ PHP_MINIT_FUNCTION */
268 424 : PHP_MINIT_FUNCTION(cairo_glyph)
269 : {
270 424 : memcpy(
271 : &cairo_glyph_object_handlers,
272 : zend_get_std_object_handlers(),
273 : sizeof(zend_object_handlers)
274 : );
275 :
276 424 : cairo_glyph_object_handlers.offset = XtOffsetOf(cairo_glyph_object, std);
277 424 : cairo_glyph_object_handlers.free_obj = cairo_glyph_free_obj;
278 424 : cairo_glyph_object_handlers.clone_obj = cairo_glyph_clone_obj;
279 424 : cairo_glyph_object_handlers.read_property = cairo_glyph_object_read_property;
280 424 : cairo_glyph_object_handlers.write_property = cairo_glyph_object_write_property;
281 424 : cairo_glyph_object_handlers.get_property_ptr_ptr = NULL;
282 424 : cairo_glyph_object_handlers.get_properties = cairo_glyph_object_get_properties;
283 :
284 424 : ce_cairo_glyph = register_class_Cairo_Glyph();
285 424 : ce_cairo_glyph->create_object = cairo_glyph_create_object;
286 :
287 424 : return SUCCESS;
288 : }
289 : /* }}} */
|