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 : | Author: Marcel Bolten <github@marcelbolten.de> |
16 : +----------------------------------------------------------------------+
17 : */
18 :
19 : #ifdef HAVE_CONFIG_H
20 : #include "config.h"
21 : #endif
22 :
23 : #include "php.h"
24 : #include "php_pango.h"
25 : #include "item_arginfo.h"
26 :
27 : #include <string.h>
28 : #include <glib.h>
29 : #include "zend_exceptions.h"
30 :
31 : zend_class_entry *pango_ce_pango_item;
32 :
33 : static zend_object_handlers pango_item_object_handlers;
34 :
35 13 : pango_item_object *pango_item_fetch_object(zend_object *object)
36 : {
37 13 : return (pango_item_object *) ((char*)(object) - XtOffsetOf(pango_item_object, std));
38 : }
39 :
40 : #define PANGO_VALUE_FROM_STRUCT(php_name, c_name) \
41 : if (strcmp(ZSTR_VAL(member), #php_name) == 0) { \
42 : zend_long value = 0; \
43 : value = item_object->item->c_name; \
44 : ZVAL_LONG(rv, value); \
45 : return rv; \
46 : }
47 :
48 : #define PANGO_ADD_STRUCT_VALUE(php_name, c_name) \
49 : ZVAL_LONG(&tmp, item_object->item->c_name); \
50 : zend_hash_str_update(props, #php_name, sizeof(#php_name)-1, &tmp);
51 :
52 :
53 4 : PHP_PANGO_API zend_class_entry* php_pango_get_item_ce()
54 : {
55 4 : return pango_ce_pango_item;
56 : }
57 :
58 : /* ----------------------------------------------------------------
59 : \Pango\Item Object management
60 : ------------------------------------------------------------------*/
61 :
62 : /* {{{ */
63 4 : static void pango_item_free_obj(zend_object *zobj)
64 : {
65 4 : pango_item_object *intern = pango_item_fetch_object(zobj);
66 :
67 4 : if (!intern) {
68 0 : return;
69 : }
70 :
71 4 : if (intern->item != NULL) {
72 4 : pango_item_free(intern->item);
73 4 : intern->item = NULL;
74 : }
75 :
76 4 : zval_ptr_dtor(&intern->glyph_item_zv);
77 :
78 4 : zend_object_std_dtor(&intern->std);
79 : }
80 : /* }}} */
81 :
82 : /* {{{ */
83 4 : static zend_object* pango_item_obj_ctor(zend_class_entry *ce, pango_item_object **intern)
84 : {
85 4 : pango_item_object *object = ecalloc(1, sizeof(pango_item_object) + zend_object_properties_size(ce));
86 :
87 4 : ZVAL_UNDEF(&object->glyph_item_zv);
88 :
89 4 : zend_object_std_init(&object->std, ce);
90 :
91 4 : object->std.handlers = &pango_item_object_handlers;
92 4 : *intern = object;
93 :
94 4 : return &object->std;
95 : }
96 : /* }}} */
97 :
98 : /* {{{ */
99 4 : static zend_object* pango_item_create_object(zend_class_entry *ce)
100 : {
101 4 : pango_item_object *intern = NULL;
102 4 : zend_object *return_value = pango_item_obj_ctor(ce, &intern);
103 :
104 4 : object_properties_init(&intern->std, ce);
105 4 : return return_value;
106 : }
107 : /* }}} */
108 :
109 : /* {{{ */
110 4 : static zval *pango_item_read_property(zend_object *zobj, zend_string *member, int type, void **cache_slot, zval *rv)
111 : {
112 4 : pango_item_object *item_object = pango_item_fetch_object(zobj);
113 :
114 4 : if (!item_object) {
115 0 : return rv;
116 : }
117 :
118 4 : if (strcmp(ZSTR_VAL(member), "analysis") == 0) {
119 1 : array_init(rv);
120 1 : add_assoc_long(rv, "bidiLevel", item_object->item->analysis.level);
121 :
122 : zend_object *gravity_case;
123 1 : zend_enum_get_case_by_value(
124 : &gravity_case, php_pango_get_gravity_ce(),
125 1 : item_object->item->analysis.gravity,
126 : NULL, false
127 : );
128 1 : GC_ADDREF(gravity_case);
129 1 : add_assoc_object(rv, "gravity", gravity_case);
130 :
131 : // add_assoc_long(rv, "flags", item_object->item->analysis.flags);
132 1 : add_assoc_bool(rv, "centeredBaseline", (item_object->item->analysis.flags & PANGO_ANALYSIS_FLAG_CENTERED_BASELINE) != 0);
133 1 : add_assoc_bool(rv, "isEllipsis", (item_object->item->analysis.flags & PANGO_ANALYSIS_FLAG_IS_ELLIPSIS) != 0);
134 1 : add_assoc_bool(rv, "needsHyphen", (item_object->item->analysis.flags & PANGO_ANALYSIS_FLAG_NEED_HYPHEN) != 0);
135 :
136 1 : guint32 script_code = GUINT32_TO_BE(g_unicode_script_to_iso15924((GUnicodeScript)item_object->item->analysis.script));
137 1 : char script_str[5] = {0};
138 1 : memcpy(script_str, &script_code, 4);
139 1 : script_str[4] = '\0';
140 : add_assoc_string(rv, "script", script_str);
141 :
142 1 : if (item_object->item->analysis.language != NULL) {
143 1 : const char* lang_str = pango_language_to_string(item_object->item->analysis.language);
144 : add_assoc_string(rv, "language", lang_str);
145 : } else {
146 : add_assoc_null(rv, "language");
147 : }
148 1 : return rv;
149 : }
150 :
151 3 : PANGO_VALUE_FROM_STRUCT(offset, offset);
152 2 : PANGO_VALUE_FROM_STRUCT(length, length);
153 1 : PANGO_VALUE_FROM_STRUCT(numChars, num_chars);
154 0 : }
155 : /* }}} */
156 :
157 : /* {{{ */
158 1 : static HashTable *pango_item_get_properties(zend_object *object)
159 : {
160 : HashTable *props;
161 : // used in PANGO_ADD_STRUCT_VALUE below
162 : zval tmp;
163 1 : pango_item_object *item_object = pango_item_fetch_object(object);
164 :
165 1 : props = zend_std_get_properties(object);
166 :
167 1 : if (!item_object->item) {
168 0 : return props;
169 : }
170 :
171 1 : array_init(&tmp);
172 1 : add_assoc_long(&tmp, "bidiLevel", item_object->item->analysis.level);
173 :
174 : zend_object *gravity_case;
175 1 : zend_enum_get_case_by_value(
176 : &gravity_case, php_pango_get_gravity_ce(),
177 1 : item_object->item->analysis.gravity,
178 : NULL, false
179 : );
180 1 : GC_ADDREF(gravity_case);
181 1 : add_assoc_object(&tmp, "gravity", gravity_case);
182 :
183 : // add_assoc_long(&tmp, "flags", item_object->item->analysis.flags);
184 1 : add_assoc_bool(&tmp, "centeredBaseline", (item_object->item->analysis.flags & PANGO_ANALYSIS_FLAG_CENTERED_BASELINE) != 0);
185 1 : add_assoc_bool(&tmp, "isEllipsis", (item_object->item->analysis.flags & PANGO_ANALYSIS_FLAG_IS_ELLIPSIS) != 0);
186 1 : add_assoc_bool(&tmp, "needsHyphen", (item_object->item->analysis.flags & PANGO_ANALYSIS_FLAG_NEED_HYPHEN) != 0);
187 :
188 1 : guint32 script_code = GUINT32_TO_BE(g_unicode_script_to_iso15924((GUnicodeScript)item_object->item->analysis.script));
189 1 : char script_str[5] = {0};
190 1 : memcpy(script_str, &script_code, 4);
191 1 : script_str[4] = '\0';
192 : add_assoc_string(&tmp, "script", script_str);
193 :
194 1 : if (item_object->item->analysis.language != NULL) {
195 1 : const char* lang_str = pango_language_to_string(item_object->item->analysis.language);
196 : add_assoc_string(&tmp, "language", lang_str);
197 : } else {
198 : add_assoc_null(&tmp, "language");
199 : }
200 1 : zend_hash_str_update(props, "analysis", sizeof("analysis")-1, &tmp);
201 :
202 1 : PANGO_ADD_STRUCT_VALUE(offset, offset);
203 1 : PANGO_ADD_STRUCT_VALUE(length, length);
204 1 : PANGO_ADD_STRUCT_VALUE(numChars, num_chars);
205 :
206 1 : return props;
207 : }
208 : /* }}} */
209 :
210 : /* {{{ PHP_MINIT_FUNCTION */
211 194 : PHP_MINIT_FUNCTION(pango_item)
212 : {
213 194 : memcpy(
214 : &pango_item_object_handlers,
215 : zend_get_std_object_handlers(),
216 : sizeof(zend_object_handlers)
217 : );
218 :
219 194 : pango_item_object_handlers.offset = XtOffsetOf(pango_item_object, std);
220 194 : pango_item_object_handlers.free_obj = pango_item_free_obj;
221 194 : pango_item_object_handlers.read_property = pango_item_read_property;
222 194 : pango_item_object_handlers.get_property_ptr_ptr = NULL;
223 194 : pango_item_object_handlers.get_properties = pango_item_get_properties;
224 :
225 194 : pango_ce_pango_item = register_class_Pango_Item();
226 194 : pango_ce_pango_item->create_object = pango_item_create_object;
227 :
228 194 : return SUCCESS;
229 : }
230 : /* }}} */
|