Line data Source code
1 : /*
2 : +----------------------------------------------------------------------+
3 : | For PHP Version 8.2+ |
4 : +----------------------------------------------------------------------+
5 : | Copyright (c) 2015 Elizabeth M Smith |
6 : +----------------------------------------------------------------------+
7 : | http://www.opensource.org/licenses/mit-license.php MIT License |
8 : +----------------------------------------------------------------------+
9 : | Authors: Elizabeth M Smith <auroraeosrose@gmail.com> |
10 : | Swen Zanon <swen.zanon@geoglis.de> |
11 : | Marcel Bolten <github@marcelbolten.de> |
12 : +----------------------------------------------------------------------+
13 : */
14 :
15 : #ifdef HAVE_CONFIG_H
16 : #include "config.h"
17 : #endif
18 :
19 : #include <php.h>
20 : #include <zend_exceptions.h>
21 :
22 : #include "php_pango.h"
23 : #include "rectangle_arginfo.h"
24 :
25 : zend_class_entry *ce_pango_rectangle;
26 : zend_class_entry *ce_pango_rounding_mode;
27 :
28 : static zend_object_handlers pango_rectangle_object_handlers;
29 :
30 112 : pango_rectangle_object *pango_rectangle_fetch_object(zend_object *object)
31 : {
32 112 : return (pango_rectangle_object *) ((char*)(object) - XtOffsetOf(pango_rectangle_object, std));
33 : }
34 :
35 : #define PANGO_ALLOC_RECT(rect_value) if (!rect_value) \
36 : { rect_value = ecalloc(1, sizeof(PangoRectangle)); }
37 :
38 : #define PANGO_VALUE_FROM_STRUCT(n) \
39 : if (strcmp(member->val, #n) == 0) { \
40 : ZVAL_LONG(rv, rectangle_object->rect->n); \
41 : return rv; \
42 : }
43 :
44 : #define PANGO_MACRO_VALUE_FROM_STRUCT(n, macro) \
45 : if (strcmp(member->val, #n) == 0) { \
46 : ZVAL_LONG(rv, macro((*rectangle_object->rect))); \
47 : return rv; \
48 : }
49 :
50 : #define PANGO_ADD_STRUCT_VALUE(n) \
51 : ZVAL_LONG(&tmp, rectangle_object->rect->n); \
52 : zend_hash_str_update(props, #n, sizeof(#n)-1, &tmp)
53 :
54 : #define PANGO_MACRO_ADD_STRUCT_VALUE(n, macro) \
55 : ZVAL_LONG(&tmp, macro((*rectangle_object->rect))); \
56 : zend_hash_str_update(props, #n, sizeof(#n)-1, &tmp)
57 :
58 : /* ----------------------------------------------------------------
59 : \Pango\Rectangle C API
60 : ------------------------------------------------------------------*/
61 :
62 : /* {{{ */
63 28 : PangoRectangle *pango_rectangle_object_get_rectangle(zval *zv)
64 : {
65 28 : pango_rectangle_object *rect_object = Z_PANGO_RECTANGLE_P(zv);
66 :
67 28 : return rect_object->rect;
68 : }
69 : /* }}} */
70 :
71 28 : zend_class_entry* php_pango_get_rectangle_ce()
72 : {
73 28 : return ce_pango_rectangle;
74 : }
75 :
76 : /* ----------------------------------------------------------------
77 : \Pango\Rectangle Class API
78 : ------------------------------------------------------------------*/
79 :
80 : /* {{{ Creates a new rectangle with the properties populated */
81 16 : PHP_METHOD(Pango_Rectangle, __construct)
82 : {
83 : zend_long x;
84 : zend_long y;
85 : zend_long width;
86 : zend_long height;
87 : pango_rectangle_object *rectangle_object;
88 :
89 16 : ZEND_PARSE_PARAMETERS_START(4, 4)
90 22 : Z_PARAM_LONG(x)
91 20 : Z_PARAM_LONG(y)
92 18 : Z_PARAM_LONG(width)
93 16 : Z_PARAM_LONG(height)
94 16 : ZEND_PARSE_PARAMETERS_END();
95 :
96 14 : rectangle_object = pango_rectangle_fetch_object(Z_OBJ_P(getThis()));
97 7 : *rectangle_object->rect = (PangoRectangle){(int)x, (int)y, (int)width, (int)height};
98 : }
99 : /* }}} */
100 :
101 : /* {{{ Converts extents from Pango units to device units and rounds based on rounding mode. */
102 7 : PHP_METHOD(Pango_Rectangle, extentsToPixels)
103 : {
104 : zval *rectangle_zv;
105 7 : zend_object *rounding_mode_case = NULL;
106 : // Default rounding mode is inclusive
107 7 : bool use_inclusive = true;
108 : PangoRectangle rect;
109 :
110 7 : ZEND_PARSE_PARAMETERS_START(1, 2)
111 10 : Z_PARAM_OBJECT_OF_CLASS(rectangle_zv, ce_pango_rectangle)
112 4 : Z_PARAM_OPTIONAL
113 7 : Z_PARAM_OBJ_OF_CLASS(rounding_mode_case, ce_pango_rounding_mode)
114 7 : ZEND_PARSE_PARAMETERS_END();
115 :
116 3 : if (rounding_mode_case) {
117 4 : zend_string *name = Z_STR_P(zend_enum_fetch_case_name(rounding_mode_case));
118 :
119 2 : if (zend_string_equals_literal(name, "Nearest")) {
120 1 : use_inclusive = false;
121 : }
122 : // "Inclusive" is the default, so no need to check explicitly
123 : }
124 :
125 3 : rect = *pango_rectangle_object_get_rectangle(rectangle_zv);
126 :
127 : // Call with inclusive rounding
128 3 : if (use_inclusive) {
129 2 : pango_extents_to_pixels(&rect, NULL);
130 : }
131 : // Call with nearest rounding
132 : else {
133 1 : pango_extents_to_pixels(NULL, &rect);
134 : }
135 :
136 3 : object_init_ex(return_value, ce_pango_rectangle);
137 3 : *pango_rectangle_object_get_rectangle(return_value) = rect;
138 : }
139 : /* }}} */
140 :
141 : /* ----------------------------------------------------------------
142 : \Pango\Rectangle Object management
143 : ------------------------------------------------------------------*/
144 :
145 : /* {{{ */
146 39 : static void pango_rectangle_free_obj(zend_object *object)
147 : {
148 39 : pango_rectangle_object *intern = pango_rectangle_fetch_object(object);
149 :
150 39 : if (!intern) {
151 0 : return;
152 : }
153 :
154 39 : if (intern->rect) {
155 39 : efree(intern->rect);
156 39 : intern->rect = NULL;
157 : }
158 :
159 39 : zend_object_std_dtor(&intern->std);
160 : }
161 : /* }}} */
162 :
163 : /* {{{ */
164 39 : static zend_object* pango_rectangle_obj_ctor(zend_class_entry *ce, pango_rectangle_object **intern)
165 : {
166 39 : pango_rectangle_object *object = ecalloc(1, sizeof(pango_rectangle_object) + zend_object_properties_size(ce));
167 39 : PANGO_ALLOC_RECT(object->rect);
168 :
169 39 : zend_object_std_init(&object->std, ce);
170 :
171 39 : object->std.handlers = &pango_rectangle_object_handlers;
172 39 : *intern = object;
173 :
174 39 : return &object->std;
175 : }
176 : /* }}} */
177 :
178 : /* {{{ */
179 38 : static zend_object* pango_rectangle_create_object(zend_class_entry *ce)
180 : {
181 38 : pango_rectangle_object *intern = NULL;
182 38 : zend_object *return_value = pango_rectangle_obj_ctor(ce, &intern);
183 :
184 38 : object_properties_init(&intern->std, ce);
185 38 : return return_value;
186 : }
187 : /* }}} */
188 :
189 : /* {{{ */
190 1 : static zend_object* pango_rectangle_clone_obj(zend_object *zobj)
191 : {
192 : pango_rectangle_object *new_rectangle;
193 1 : pango_rectangle_object *old_rectangle = pango_rectangle_fetch_object(zobj);
194 1 : zend_object *return_value = pango_rectangle_obj_ctor(zobj->ce, &new_rectangle);
195 1 : PANGO_ALLOC_RECT(new_rectangle->rect);
196 :
197 1 : *new_rectangle->rect = *old_rectangle->rect;
198 :
199 1 : zend_objects_clone_members(&new_rectangle->std, &old_rectangle->std);
200 :
201 1 : return return_value;
202 : }
203 : /* }}} */
204 :
205 : /* {{{ */
206 8 : static zval *pango_rectangle_object_read_property(zend_object *object, zend_string *member, int type, void **cache_slot, zval *rv)
207 : {
208 8 : pango_rectangle_object *rectangle_object = pango_rectangle_fetch_object(object);
209 :
210 8 : if (!rectangle_object) {
211 0 : return rv;
212 : }
213 :
214 8 : PANGO_VALUE_FROM_STRUCT(x);
215 7 : PANGO_VALUE_FROM_STRUCT(y);
216 6 : PANGO_VALUE_FROM_STRUCT(width);
217 5 : PANGO_VALUE_FROM_STRUCT(height);
218 4 : PANGO_MACRO_VALUE_FROM_STRUCT(ascent, PANGO_ASCENT);
219 3 : PANGO_MACRO_VALUE_FROM_STRUCT(descent, PANGO_DESCENT);
220 2 : PANGO_MACRO_VALUE_FROM_STRUCT(leftBearing, PANGO_LBEARING);
221 1 : PANGO_MACRO_VALUE_FROM_STRUCT(rightBearing, PANGO_RBEARING);
222 :
223 0 : return rv;
224 : }
225 : /* }}} */
226 :
227 : /* {{{ */
228 29 : static HashTable *pango_rectangle_object_get_properties(zend_object *object)
229 : {
230 : HashTable *props;
231 : // used in macros below
232 : zval tmp;
233 29 : pango_rectangle_object *rectangle_object = pango_rectangle_fetch_object(object);
234 :
235 29 : props = zend_std_get_properties(object);
236 :
237 29 : if (!rectangle_object->rect) {
238 0 : return props;
239 : }
240 :
241 29 : PANGO_ADD_STRUCT_VALUE(x);
242 29 : PANGO_ADD_STRUCT_VALUE(y);
243 29 : PANGO_ADD_STRUCT_VALUE(width);
244 29 : PANGO_ADD_STRUCT_VALUE(height);
245 29 : PANGO_MACRO_ADD_STRUCT_VALUE(ascent, PANGO_ASCENT);
246 29 : PANGO_MACRO_ADD_STRUCT_VALUE(descent, PANGO_DESCENT);
247 29 : PANGO_MACRO_ADD_STRUCT_VALUE(leftBearing, PANGO_LBEARING);
248 29 : PANGO_MACRO_ADD_STRUCT_VALUE(rightBearing, PANGO_RBEARING);
249 :
250 29 : return props;
251 : }
252 : /* }}} */
253 :
254 : /* ----------------------------------------------------------------
255 : \Pango\Rectangle Definition and registration
256 : ------------------------------------------------------------------*/
257 :
258 : /* {{{ PHP_MINIT_FUNCTION */
259 194 : PHP_MINIT_FUNCTION(pango_rectangle)
260 : {
261 194 : memcpy(
262 : &pango_rectangle_object_handlers,
263 : zend_get_std_object_handlers(),
264 : sizeof(zend_object_handlers)
265 : );
266 :
267 194 : pango_rectangle_object_handlers.offset = XtOffsetOf(pango_rectangle_object, std);
268 194 : pango_rectangle_object_handlers.free_obj = pango_rectangle_free_obj;
269 194 : pango_rectangle_object_handlers.clone_obj = pango_rectangle_clone_obj;
270 194 : pango_rectangle_object_handlers.read_property = pango_rectangle_object_read_property;
271 : // pango_rectangle_object_handlers.write_property = pango_rectangle_object_write_property;
272 194 : pango_rectangle_object_handlers.get_property_ptr_ptr = NULL;
273 194 : pango_rectangle_object_handlers.get_properties = pango_rectangle_object_get_properties;
274 :
275 194 : ce_pango_rectangle = register_class_Pango_Rectangle();
276 194 : ce_pango_rectangle->create_object = pango_rectangle_create_object;
277 :
278 : // Pango\RoundingMode enum
279 194 : ce_pango_rounding_mode = register_class_Pango_RoundingMode();
280 :
281 194 : return SUCCESS;
282 : }
283 : /* }}} */
|