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 "text_cluster_arginfo.h"
25 :
26 : zend_class_entry *ce_cairo_text_cluster;
27 :
28 : static zend_object_handlers cairo_text_cluster_object_handlers;
29 :
30 105 : cairo_text_cluster_object *cairo_text_cluster_fetch_object(zend_object *object)
31 : {
32 105 : return (cairo_text_cluster_object *) ((char*)(object) - XtOffsetOf(cairo_text_cluster_object, std));
33 : }
34 :
35 90 : static inline long cairo_text_cluster_get_property_default(zend_class_entry *ce, char * name) {
36 : zend_property_info *property_info;
37 90 : long value = 0;
38 90 : zend_string *key = zend_string_init(name, strlen(name), 0);
39 :
40 90 : property_info = zend_get_property_info(ce, key, 1);
41 90 : if (property_info) {
42 90 : zval *val = (zval*)((char*)ce->default_properties_table + property_info->offset - OBJ_PROP_TO_OFFSET(0));
43 90 : if (val) {
44 90 : value = zval_get_long(val);
45 : }
46 : }
47 : zend_string_release(key);
48 90 : return value;
49 : }
50 :
51 : #define CAIRO_ALLOC_TEXT_CLUSTER(text_cluster_value) if (!text_cluster_value) \
52 : { text_cluster_value = ecalloc(1, sizeof(cairo_text_cluster_t)); }
53 :
54 : #define CAIRO_VALUE_FROM_STRUCT(n) \
55 : if (strcmp(member->val, #n) == 0) { \
56 : value = text_cluster_object->text_cluster->n; \
57 : break; \
58 : }
59 :
60 : #define CAIRO_VALUE_TO_STRUCT(n) \
61 : if (strcmp(member->val, #n) == 0) { \
62 : text_cluster_object->text_cluster->n = zval_get_long(value); \
63 : break; \
64 : }
65 :
66 : #define CAIRO_ADD_STRUCT_VALUE(n) \
67 : ZVAL_LONG(&tmp, text_cluster_object->text_cluster->n); \
68 : zend_hash_str_update(props, #n, sizeof(#n)-1, &tmp);
69 :
70 : /* ----------------------------------------------------------------
71 : \Cairo\TextCluster C API
72 : ------------------------------------------------------------------*/
73 :
74 : /* {{{ */
75 6 : cairo_text_cluster_t *cairo_text_cluster_object_get_text_cluster(zval *zv)
76 : {
77 6 : cairo_text_cluster_object *text_cluster_object = Z_CAIRO_TEXT_CLUSTER_P(zv);
78 :
79 6 : return text_cluster_object->text_cluster;
80 : }
81 : /* }}} */
82 :
83 34 : zend_class_entry* php_cairo_get_text_cluster_ce()
84 : {
85 34 : return ce_cairo_text_cluster;
86 : }
87 :
88 : /* ----------------------------------------------------------------
89 : \Cairo\TextCluster Class API
90 : ------------------------------------------------------------------*/
91 :
92 : /* {{{ proto void __construct(int num_bytes, int num_glyphs)
93 : Creates a new text_cluster with the properties populated */
94 10 : PHP_METHOD(Cairo_TextCluster, __construct)
95 : {
96 : cairo_text_cluster_object *text_cluster_object;
97 :
98 : /* read defaults from object */
99 : zend_long num_bytes, num_glyphs;
100 :
101 : /* Now allow constructor to overwrite them if desired */
102 10 : ZEND_PARSE_PARAMETERS_START(2, 2)
103 14 : Z_PARAM_LONG(num_bytes)
104 12 : Z_PARAM_LONG(num_glyphs)
105 10 : ZEND_PARSE_PARAMETERS_END();
106 :
107 10 : text_cluster_object = Z_CAIRO_TEXT_CLUSTER_P(getThis());
108 :
109 5 : text_cluster_object->text_cluster->num_bytes = (int) num_bytes;
110 5 : text_cluster_object->text_cluster->num_glyphs = (int) num_glyphs;
111 : }
112 : /* }}} */
113 :
114 : /* ----------------------------------------------------------------
115 : \Cairo\TextCluster Object management
116 : ------------------------------------------------------------------*/
117 :
118 : /* {{{ */
119 45 : static void cairo_text_cluster_free_obj(zend_object *zobj)
120 : {
121 45 : cairo_text_cluster_object *intern = cairo_text_cluster_fetch_object(zobj);
122 :
123 45 : if (!intern) {
124 0 : return;
125 : }
126 :
127 45 : if (intern->text_cluster) {
128 45 : efree(intern->text_cluster);
129 45 : intern->text_cluster = NULL;
130 : }
131 :
132 45 : zend_object_std_dtor(&intern->std);
133 : }
134 : /* }}} */
135 :
136 : /* {{{ */
137 45 : static zend_object* cairo_text_cluster_obj_ctor(zend_class_entry *ce, cairo_text_cluster_object **intern)
138 : {
139 45 : cairo_text_cluster_object *object = ecalloc(1, sizeof(cairo_text_cluster_object) + zend_object_properties_size(ce));
140 45 : CAIRO_ALLOC_TEXT_CLUSTER(object->text_cluster);
141 :
142 45 : zend_object_std_init(&object->std, ce);
143 :
144 45 : object->std.handlers = &cairo_text_cluster_object_handlers;
145 45 : *intern = object;
146 :
147 : /* We need to read in any default values and set them if applicable */
148 45 : if (ce->default_properties_count) {
149 45 : object->text_cluster->num_bytes = cairo_text_cluster_get_property_default(ce, "num_bytes");
150 45 : object->text_cluster->num_glyphs = cairo_text_cluster_get_property_default(ce, "num_glyphs");
151 : }
152 :
153 45 : return &object->std;
154 : }
155 : /* }}} */
156 :
157 : /* {{{ */
158 44 : static zend_object* cairo_text_cluster_create_object(zend_class_entry *ce)
159 : {
160 44 : cairo_text_cluster_object *intern = NULL;
161 44 : zend_object *return_value = cairo_text_cluster_obj_ctor(ce, &intern);
162 :
163 44 : object_properties_init(&intern->std, ce);
164 44 : return return_value;
165 : }
166 : /* }}} */
167 :
168 : /* {{{ */
169 1 : static zend_object* cairo_text_cluster_clone_obj(zend_object *zobj)
170 : {
171 : cairo_text_cluster_object *new_text_cluster;
172 1 : cairo_text_cluster_object *old_text_cluster = cairo_text_cluster_fetch_object(zobj);
173 1 : zend_object *return_value = cairo_text_cluster_obj_ctor(zobj->ce, &new_text_cluster);
174 1 : CAIRO_ALLOC_TEXT_CLUSTER(new_text_cluster->text_cluster);
175 :
176 1 : new_text_cluster->text_cluster->num_bytes = old_text_cluster->text_cluster->num_bytes;
177 1 : new_text_cluster->text_cluster->num_glyphs = old_text_cluster->text_cluster->num_glyphs;
178 :
179 1 : zend_objects_clone_members(&new_text_cluster->std, &old_text_cluster->std);
180 :
181 1 : return return_value;
182 : }
183 : /* }}} */
184 :
185 : /* {{{ */
186 5 : static zval *cairo_text_cluster_object_read_property(zend_object *zobj, zend_string *member, int type, void **cache_slot, zval *rv)
187 : {
188 : zval *retval;
189 : long value;
190 5 : cairo_text_cluster_object *text_cluster_object = cairo_text_cluster_fetch_object(zobj);
191 :
192 5 : if (!text_cluster_object) {
193 0 : return rv;
194 : }
195 :
196 : do {
197 5 : CAIRO_VALUE_FROM_STRUCT(num_bytes);
198 3 : CAIRO_VALUE_FROM_STRUCT(num_glyphs);
199 :
200 : // not a struct member
201 1 : retval = (zend_get_std_object_handlers())->read_property(zobj, member, type, cache_slot, rv);
202 :
203 1 : return retval;
204 : } while(0);
205 :
206 4 : retval = rv;
207 4 : ZVAL_LONG(retval, value);
208 :
209 4 : return retval;
210 : }
211 : /* }}} */
212 :
213 : /* {{{ */
214 5 : static zval *cairo_text_cluster_object_write_property(zend_object *zobj, zend_string *member, zval *value, void **cache_slot)
215 : {
216 5 : cairo_text_cluster_object *text_cluster_object = cairo_text_cluster_fetch_object(zobj);
217 5 : zval *retval = NULL;
218 :
219 5 : if (!text_cluster_object) {
220 0 : return retval;
221 : }
222 :
223 : do {
224 7 : CAIRO_VALUE_TO_STRUCT(num_bytes);
225 5 : CAIRO_VALUE_TO_STRUCT(num_glyphs);
226 : } while(0);
227 :
228 : // not a struct member
229 5 : retval = (zend_get_std_object_handlers())->write_property(zobj, member, value, cache_slot);
230 :
231 5 : return retval;
232 : }
233 : /* }}} */
234 :
235 : /* {{{ */
236 4 : static HashTable *cairo_text_cluster_object_get_properties(zend_object *zobj)
237 : {
238 : HashTable *props;
239 : // used in CAIRO_ADD_STRUCT_VALUE below
240 : zval tmp;
241 4 : cairo_text_cluster_object *text_cluster_object = cairo_text_cluster_fetch_object(zobj);
242 :
243 4 : props = zend_std_get_properties(zobj);
244 :
245 4 : if (!text_cluster_object->text_cluster) {
246 0 : return props;
247 : }
248 :
249 4 : CAIRO_ADD_STRUCT_VALUE(num_bytes);
250 4 : CAIRO_ADD_STRUCT_VALUE(num_glyphs);
251 :
252 4 : return props;
253 : }
254 : /* }}} */
255 :
256 : /* ----------------------------------------------------------------
257 : \Cairo\TextCluster Definition and registration
258 : ------------------------------------------------------------------*/
259 :
260 : /* {{{ PHP_MINIT_FUNCTION */
261 433 : PHP_MINIT_FUNCTION(cairo_text_cluster)
262 : {
263 : zend_class_entry ce;
264 :
265 433 : memcpy(
266 : &cairo_text_cluster_object_handlers,
267 : zend_get_std_object_handlers(),
268 : sizeof(zend_object_handlers)
269 : );
270 :
271 433 : cairo_text_cluster_object_handlers.offset = XtOffsetOf(cairo_text_cluster_object, std);
272 433 : cairo_text_cluster_object_handlers.free_obj = cairo_text_cluster_free_obj;
273 433 : cairo_text_cluster_object_handlers.clone_obj = cairo_text_cluster_clone_obj;
274 433 : cairo_text_cluster_object_handlers.read_property = cairo_text_cluster_object_read_property;
275 433 : cairo_text_cluster_object_handlers.write_property = cairo_text_cluster_object_write_property;
276 433 : cairo_text_cluster_object_handlers.get_property_ptr_ptr = NULL;
277 433 : cairo_text_cluster_object_handlers.get_properties = cairo_text_cluster_object_get_properties;
278 :
279 433 : ce_cairo_text_cluster = register_class_Cairo_TextCluster();
280 433 : ce_cairo_text_cluster->create_object = cairo_text_cluster_create_object;
281 :
282 433 : return SUCCESS;
283 : }
284 : /* }}} */
|