Line data Source code
1 : /*
2 : +----------------------------------------------------------------------+
3 : | For PHP Version 8.2+ |
4 : +----------------------------------------------------------------------+
5 : | Copyright (c) The PHP Group |
6 : +----------------------------------------------------------------------+
7 : | This source file is subject to version 3.01 of the PHP license, |
8 : | that is bundled with this package in the file LICENSE, and is |
9 : | available through the world-wide-web at the following url: |
10 : | http://www.php.net/license/3_01.txt |
11 : | If you did not receive a copy of the PHP license and are unable to |
12 : | obtain it through the world-wide-web, please send a note to |
13 : | license@php.net so we can mail you a copy immediately. |
14 : +----------------------------------------------------------------------+
15 : | Authors: Michael Maclean <mgdm@php.net> |
16 : | Marcel Bolten <github@marcelbolten.de> |
17 : +----------------------------------------------------------------------+
18 : */
19 :
20 : #ifdef HAVE_CONFIG_H
21 : #include "config.h"
22 : #endif
23 :
24 : #include "php.h"
25 : #include "php_pango.h"
26 : #include "context_arginfo.h"
27 :
28 : zend_class_entry *pango_ce_pango_context;
29 : zend_class_entry *pango_ce_pango_direction;
30 : zend_class_entry *pango_ce_pango_gravity;
31 : zend_class_entry *pango_ce_pango_gravity_hint;
32 :
33 255 : PHP_PANGO_API zend_class_entry* php_pango_get_context_ce() {
34 255 : return pango_ce_pango_context;
35 : }
36 :
37 4 : PHP_PANGO_API zend_class_entry* php_pango_get_direction_ce() {
38 4 : return pango_ce_pango_direction;
39 : }
40 :
41 2 : PHP_PANGO_API zend_class_entry* php_pango_get_gravity_ce() {
42 2 : return pango_ce_pango_gravity;
43 : }
44 :
45 : static zend_object_handlers pango_context_object_handlers;
46 :
47 270 : pango_context_object *pango_context_fetch_object(zend_object *object)
48 : {
49 270 : return (pango_context_object *) ((char*)(object) - XtOffsetOf(pango_context_object, std));
50 : }
51 :
52 : /* {{{ Creates a new PangoContext initialized to default values. */
53 76 : PHP_METHOD(Pango_Context, __construct)
54 : {
55 : pango_context_object *context_object;
56 76 : zval *font_map_zv = NULL;
57 : pango_font_map_object *font_map_object;
58 :
59 76 : ZEND_PARSE_PARAMETERS_START(0, 1)
60 75 : Z_PARAM_OPTIONAL
61 137 : Z_PARAM_OBJECT_OF_CLASS_OR_NULL(font_map_zv, php_pango_get_font_map_ce())
62 137 : ZEND_PARSE_PARAMETERS_END();
63 :
64 148 : context_object = Z_PANGO_CONTEXT_P(getThis());
65 :
66 135 : if (font_map_zv && Z_TYPE_P(font_map_zv) != IS_NULL) {
67 61 : font_map_object = Z_PANGO_FONT_MAP_P(font_map_zv);
68 61 : context_object->context = pango_font_map_create_context(font_map_object->font_map);
69 :
70 : // keep a reference of the font map zval in the pango context object
71 61 : ZVAL_COPY(&context_object->font_map_zv, font_map_zv);
72 61 : return;
73 : }
74 :
75 13 : context_object->context = pango_context_new();
76 : }
77 :
78 : /* {{{ */
79 5 : PHP_METHOD(Pango_Context, getFontDescription)
80 : {
81 : pango_context_object *context_object;
82 :
83 5 : ZEND_PARSE_PARAMETERS_NONE();
84 :
85 8 : context_object = Z_PANGO_CONTEXT_P(getThis());
86 :
87 8 : if (Z_TYPE(context_object->font_description_zv) != IS_UNDEF) {
88 3 : RETURN_COPY(&context_object->font_description_zv);
89 : }
90 :
91 2 : RETURN_NULL();
92 : }
93 : /* }}} */
94 :
95 : /* {{{ */
96 5 : PHP_METHOD(Pango_Context, setFontDescription)
97 : {
98 : zval *font_desc_zv;
99 : pango_context_object *context_object;
100 5 : PangoFontDescription *font_description = NULL;
101 :
102 5 : ZEND_PARSE_PARAMETERS_START(1, 1);
103 6 : Z_PARAM_OBJECT_OF_CLASS_OR_NULL(font_desc_zv, php_pango_get_font_description_ce())
104 5 : ZEND_PARSE_PARAMETERS_END();
105 :
106 4 : context_object = Z_PANGO_CONTEXT_P(getThis());
107 2 : zval_ptr_dtor(&context_object->font_description_zv);
108 :
109 3 : if (font_desc_zv && Z_TYPE_P(font_desc_zv) != IS_NULL) {
110 1 : ZVAL_COPY(&context_object->font_description_zv, font_desc_zv);
111 1 : font_description = Z_PANGO_FONT_DESC_P(font_desc_zv)->font_description;
112 : } else {
113 1 : ZVAL_NULL(&context_object->font_description_zv);
114 : }
115 :
116 2 : pango_context_set_font_description(context_object->context, font_description);
117 : }
118 : /* }}} */
119 :
120 : /* {{{ */
121 4 : PHP_METHOD(Pango_Context, getFontMap)
122 : {
123 : pango_context_object *context_object;
124 :
125 4 : ZEND_PARSE_PARAMETERS_NONE();
126 :
127 4 : context_object = Z_PANGO_CONTEXT_P(getThis());
128 :
129 4 : if (Z_TYPE(context_object->font_map_zv) != IS_UNDEF) {
130 2 : RETURN_COPY(&context_object->font_map_zv);
131 : }
132 :
133 1 : RETURN_NULL();
134 : }
135 : /* }}} */
136 :
137 : // /* {{{ Sets the font map to be searched when fonts are looked-up in this context.
138 : // This is only for internal use by Pango backends, a PangoContext obtained
139 : // via one of the recommended methods should already have a suitable font map. */
140 : // PHP_METHOD(Pango_Context, setFontMap)
141 : // {
142 : // zval *font_map_zv = NULL;
143 :
144 : // ZEND_PARSE_PARAMETERS_START(0, 1);
145 : // Z_PARAM_OPTIONAL
146 : // Z_PARAM_OBJECT_OF_CLASS_OR_NULL(font_map_zv, php_pango_get_font_map_ce())
147 : // ZEND_PARSE_PARAMETERS_END();
148 : // }
149 : // /* }}} */
150 :
151 : /* {{{ */
152 2 : PHP_METHOD(Pango_Context, listFamilies)
153 : {
154 : pango_context_object *context_object;
155 : PangoFontFamily** families;
156 : int num_families;
157 : zval family_zv;
158 : pango_font_family_object *font_family_object;
159 :
160 2 : ZEND_PARSE_PARAMETERS_NONE();
161 :
162 2 : context_object = Z_PANGO_CONTEXT_P(getThis());
163 :
164 1 : pango_context_list_families(context_object->context, &families, &num_families);
165 :
166 1 : array_init(return_value);
167 29 : for (int i = 0; i < num_families; i++) {
168 28 : object_init_ex(&family_zv, php_pango_get_font_family_ce());
169 28 : font_family_object = Z_PANGO_FONT_FAMILY_P(&family_zv);
170 28 : font_family_object->font_family = g_object_ref(families[i]);
171 : add_next_index_zval(return_value, &family_zv);
172 : }
173 :
174 1 : g_free(families);
175 : }
176 : /* }}} */
177 :
178 :
179 : /* {{{ Retrieves the base direction for the context. */
180 4 : PHP_METHOD(Pango_Context, getBaseDir)
181 : {
182 : pango_context_object *context_object;
183 : zend_object *base_dir_case;
184 :
185 4 : ZEND_PARSE_PARAMETERS_NONE();
186 :
187 6 : context_object = Z_PANGO_CONTEXT_P(getThis());
188 :
189 3 : zend_enum_get_case_by_value(
190 : &base_dir_case, pango_ce_pango_direction,
191 3 : pango_context_get_base_dir(context_object->context),
192 : NULL, false
193 : );
194 :
195 6 : RETURN_OBJ_COPY(base_dir_case);
196 : }
197 : /* }}} */
198 :
199 : /* {{{ Gets the base gravity to be used to lay out the text. */
200 4 : PHP_METHOD(Pango_Context, getBaseGravity)
201 : {
202 : pango_context_object *context_object;
203 : zend_object *base_gravity_case;
204 :
205 4 : ZEND_PARSE_PARAMETERS_NONE();
206 :
207 6 : context_object = Z_PANGO_CONTEXT_P(getThis());
208 :
209 3 : zend_enum_get_case_by_value(
210 : &base_gravity_case, pango_ce_pango_gravity,
211 3 : pango_context_get_base_gravity(context_object->context),
212 : NULL, false
213 : );
214 :
215 6 : RETURN_OBJ_COPY(base_gravity_case);
216 : }
217 : /* }}} */
218 :
219 : /* {{{ Gets the gravity to be used to lay out the text */
220 2 : PHP_METHOD(Pango_Context, getGravity)
221 : {
222 : pango_context_object *context_object;
223 : zend_object *gravity_case;
224 :
225 2 : ZEND_PARSE_PARAMETERS_NONE();
226 :
227 2 : context_object = Z_PANGO_CONTEXT_P(getThis());
228 :
229 1 : zend_enum_get_case_by_value(
230 : &gravity_case, pango_ce_pango_gravity,
231 1 : pango_context_get_gravity(context_object->context),
232 : NULL, false
233 : );
234 :
235 2 : RETURN_OBJ_COPY(gravity_case);
236 : }
237 : /* }}} */
238 :
239 : /* {{{ Gets the gravity hint to be used to lay out the text */
240 4 : PHP_METHOD(Pango_Context, getGravityHint)
241 : {
242 : pango_context_object *context_object;
243 : zend_object *gravity_hint_case;
244 :
245 4 : ZEND_PARSE_PARAMETERS_NONE();
246 :
247 6 : context_object = Z_PANGO_CONTEXT_P(getThis());
248 :
249 3 : zend_enum_get_case_by_value(
250 : &gravity_hint_case, pango_ce_pango_gravity_hint,
251 3 : pango_context_get_gravity_hint(context_object->context),
252 : NULL, false
253 : );
254 :
255 6 : RETURN_OBJ_COPY(gravity_hint_case);
256 : }
257 : /* }}} */
258 :
259 : /* {{{ */
260 5 : PHP_METHOD(Pango_Context, getMatrix)
261 : {
262 : pango_context_object *context_object;
263 : const PangoMatrix *matrix_pango;
264 : PangoMatrix *matrix_php;
265 :
266 5 : ZEND_PARSE_PARAMETERS_NONE();
267 :
268 8 : context_object = Z_PANGO_CONTEXT_P(getThis());
269 4 : matrix_pango = pango_context_get_matrix(context_object->context);
270 :
271 : // start with a new identity matrix
272 4 : object_init_ex(return_value, php_pango_get_matrix_ce());
273 :
274 : // if the context has a matrix set, copy its values to the php matrix object
275 4 : if (matrix_pango != NULL) {
276 : // TODO: check if a copy is wanted here, perhaps just assign the pointer?
277 : // but the returned matrix is const so probably a copy is better
278 2 : matrix_php = pango_matrix_object_get_matrix(return_value);
279 2 : *matrix_php = *matrix_pango;
280 : }
281 : }
282 : /* }}} */
283 :
284 : /* {{{ Returns whether font rendering with this context should round glyph positions and widths. */
285 4 : PHP_METHOD(Pango_Context, getRoundGlyphPositions)
286 : {
287 : pango_context_object *context_object;
288 :
289 4 : ZEND_PARSE_PARAMETERS_NONE();
290 :
291 6 : context_object = Z_PANGO_CONTEXT_P(getThis());
292 :
293 3 : RETURN_BOOL(pango_context_get_round_glyph_positions(context_object->context));
294 : }
295 : /* }}} */
296 :
297 : /* {{{ Sets the base direction for the context. */
298 4 : PHP_METHOD(Pango_Context, setBaseDir)
299 : {
300 : pango_context_object *context_object;
301 : zend_object *base_dir;
302 :
303 4 : ZEND_PARSE_PARAMETERS_START(1, 1)
304 4 : Z_PARAM_OBJ_OF_CLASS(base_dir, pango_ce_pango_direction)
305 4 : ZEND_PARSE_PARAMETERS_END();
306 :
307 2 : context_object = Z_PANGO_CONTEXT_P(getThis());
308 1 : pango_context_set_base_dir(
309 : context_object->context,
310 2 : Z_LVAL_P(zend_enum_fetch_case_value(base_dir))
311 : );
312 : }
313 : /* }}} */
314 :
315 : /* {{{ Sets the base gravity to be used to lay out the text */
316 4 : PHP_METHOD(Pango_Context, setBaseGravity)
317 : {
318 : pango_context_object *context_object;
319 : zend_object *base_gravity;
320 :
321 4 : ZEND_PARSE_PARAMETERS_START(1, 1)
322 4 : Z_PARAM_OBJ_OF_CLASS(base_gravity, pango_ce_pango_gravity)
323 4 : ZEND_PARSE_PARAMETERS_END();
324 :
325 2 : context_object = Z_PANGO_CONTEXT_P(getThis());
326 1 : pango_context_set_base_gravity(
327 : context_object->context,
328 2 : Z_LVAL_P(zend_enum_fetch_case_value(base_gravity))
329 : );
330 : }
331 : /* }}} */
332 :
333 : /* {{{ Sets the gravity hint to be used to lay out the text */
334 4 : PHP_METHOD(Pango_Context, setGravityHint)
335 : {
336 : pango_context_object *context_object;
337 : zend_object *gravity_hint;
338 :
339 4 : ZEND_PARSE_PARAMETERS_START(1, 1)
340 4 : Z_PARAM_OBJ_OF_CLASS(gravity_hint, pango_ce_pango_gravity_hint)
341 4 : ZEND_PARSE_PARAMETERS_END();
342 :
343 2 : context_object = Z_PANGO_CONTEXT_P(getThis());
344 1 : pango_context_set_gravity_hint(
345 : context_object->context,
346 2 : Z_LVAL_P(zend_enum_fetch_case_value(gravity_hint))
347 : );
348 : }
349 : /* }}} */
350 :
351 : /* {{{ */
352 4 : PHP_METHOD(Pango_Context, setMatrix)
353 : {
354 : pango_context_object *context_object;
355 : zval *matrix_zval;
356 : PangoMatrix *matrix;
357 :
358 4 : ZEND_PARSE_PARAMETERS_START(1, 1)
359 4 : Z_PARAM_OBJECT_OF_CLASS_OR_NULL(matrix_zval, php_pango_get_matrix_ce())
360 4 : ZEND_PARSE_PARAMETERS_END();
361 :
362 2 : context_object = Z_PANGO_CONTEXT_P(getThis());
363 1 : matrix = pango_matrix_object_get_matrix(matrix_zval);
364 :
365 1 : pango_context_set_matrix(context_object->context, matrix);
366 : }
367 : /* }}} */
368 :
369 : /* {{{ Sets the round glyph positions for the context. */
370 4 : PHP_METHOD(Pango_Context, setRoundGlyphPositions)
371 : {
372 : pango_context_object *context_object;
373 : bool round;
374 :
375 4 : ZEND_PARSE_PARAMETERS_START(1, 1)
376 4 : Z_PARAM_BOOL(round)
377 4 : ZEND_PARSE_PARAMETERS_END();
378 :
379 2 : context_object = Z_PANGO_CONTEXT_P(getThis());
380 1 : pango_context_set_round_glyph_positions(context_object->context, round);
381 : }
382 : /* }}} */
383 :
384 :
385 : /* ----------------------------------------------------------------
386 : \Pango\Context Object management
387 : ------------------------------------------------------------------*/
388 :
389 : /* {{{ */
390 77 : static void pango_context_free_obj(zend_object *zobj)
391 : {
392 77 : pango_context_object *intern = pango_context_fetch_object(zobj);
393 :
394 77 : if (!intern) {
395 0 : return;
396 : }
397 :
398 77 : zval_ptr_dtor(&intern->font_map_zv);
399 77 : zval_ptr_dtor(&intern->font_options_zv);
400 77 : zval_ptr_dtor(&intern->font_description_zv);
401 77 : zval_ptr_dtor(&intern->cairo_context_zv);
402 :
403 77 : if (intern->context) {
404 75 : g_object_unref(intern->context);
405 : }
406 :
407 77 : zend_object_std_dtor(&intern->std);
408 : }
409 :
410 : /* {{{ */
411 77 : static zend_object* pango_context_obj_ctor(zend_class_entry *ce, pango_context_object **intern)
412 : {
413 77 : pango_context_object *object = ecalloc(1, sizeof(pango_context_object) + zend_object_properties_size(ce));
414 :
415 77 : object->context = NULL;
416 :
417 77 : ZVAL_UNDEF(&object->cairo_context_zv);
418 77 : ZVAL_UNDEF(&object->font_map_zv);
419 77 : ZVAL_UNDEF(&object->font_options_zv);
420 77 : ZVAL_UNDEF(&object->font_description_zv);
421 :
422 77 : zend_object_std_init(&object->std, ce);
423 :
424 77 : object->std.handlers = &pango_context_object_handlers;
425 77 : *intern = object;
426 :
427 77 : return &object->std;
428 : }
429 : /* }}} */
430 :
431 : /* {{{ */
432 77 : static zend_object* pango_context_create_object(zend_class_entry *ce)
433 : {
434 77 : pango_context_object *intern = NULL;
435 77 : zend_object *return_value = pango_context_obj_ctor(ce, &intern);
436 :
437 77 : object_properties_init(&intern->std, ce);
438 77 : return return_value;
439 : }
440 : /* }}} */
441 :
442 : /* {{{ PHP_MINIT_FUNCTION */
443 194 : PHP_MINIT_FUNCTION(pango_context)
444 : {
445 194 : memcpy(
446 : &pango_context_object_handlers,
447 : zend_get_std_object_handlers(),
448 : sizeof(zend_object_handlers)
449 : );
450 :
451 194 : pango_context_object_handlers.offset = XtOffsetOf(pango_context_object, std);
452 194 : pango_context_object_handlers.free_obj = pango_context_free_obj;
453 :
454 194 : pango_ce_pango_context = register_class_Pango_Context();
455 194 : pango_ce_pango_context->create_object = pango_context_create_object;
456 :
457 194 : pango_ce_pango_gravity = register_class_Pango_Gravity();
458 194 : pango_ce_pango_gravity_hint = register_class_Pango_GravityHint();
459 194 : pango_ce_pango_direction = register_class_Pango_Direction();
460 :
461 194 : return SUCCESS;
462 : }
463 : /* }}} */
|