Line data Source code
1 : /*
2 : +----------------------------------------------------------------------+
3 : | For PHP Version 8 |
4 : +----------------------------------------------------------------------+
5 : | Copyright (c) 2015 Elizabeth M Smith |
6 : +----------------------------------------------------------------------+
7 : | http://www.opensource.org/licenses/mit-license.php MIT License |
8 : | Also available in LICENSE |
9 : +----------------------------------------------------------------------+
10 : | Authors: Elizabeth M Smith <auroraeosrose@gmail.com> |
11 : | Swen Zanon <swen.zanon@geoglis.de> |
12 : +----------------------------------------------------------------------+
13 : */
14 :
15 : #ifdef HAVE_CONFIG_H
16 : #include "config.h"
17 : #endif
18 :
19 : #include <cairo.h>
20 : #include <php.h>
21 : #include <zend_exceptions.h>
22 :
23 : #include "php_cairo.h"
24 : #include "php_cairo_internal.h"
25 :
26 : #if CAIRO_HAS_PS_SURFACE
27 : #include <cairo-ps.h>
28 : #include "ps_surface_arginfo.h"
29 :
30 : zend_class_entry *ce_cairo_pssurface;
31 : zend_class_entry *ce_cairo_pslevel;
32 :
33 : /* ----------------------------------------------------------------
34 : Cairo\Surface\Ps Class API
35 : ------------------------------------------------------------------*/
36 :
37 : /* {{{ proto void CairoPsSurface->__construct(string|resource file, int|float width, int|float height)
38 : Creates a PS surface of the specified size in points to be written to filename. */
39 17 : PHP_METHOD(Cairo_Surface_Ps, __construct)
40 : {
41 17 : zval *stream_zval = NULL;
42 : stream_closure *closure;
43 17 : php_stream *stream = NULL;
44 : double width, height;
45 17 : bool owned_stream = false;
46 : cairo_surface_object *surface_object;
47 :
48 17 : ZEND_PARSE_PARAMETERS_START(3, 3)
49 13 : Z_PARAM_ZVAL(stream_zval)
50 26 : Z_PARAM_DOUBLE(width)
51 24 : Z_PARAM_DOUBLE(height)
52 17 : ZEND_PARSE_PARAMETERS_END();
53 :
54 22 : surface_object = Z_CAIRO_SURFACE_P(getThis());
55 11 : if (!surface_object) {
56 0 : RETURN_NULL();
57 : }
58 :
59 : /* special case - a NULL file is like an "in memory" surface
60 : notice it uses the regular create cairo method, not create for stream */
61 22 : if (Z_TYPE_P(stream_zval) == IS_NULL) {
62 8 : surface_object->surface = cairo_ps_surface_create(NULL, width, height);
63 : }
64 : /* Otherwise it can be a filename or a PHP stream */
65 : else {
66 6 : if (Z_TYPE_P(stream_zval) == IS_STRING) {
67 1 : stream = php_stream_open_wrapper(Z_STRVAL_P(stream_zval), "w+b", REPORT_ERRORS, NULL);
68 1 : owned_stream = 1;
69 4 : } else if (Z_TYPE_P(stream_zval) == IS_RESOURCE) {
70 1 : php_stream_from_zval(stream, stream_zval);
71 : } else {
72 1 : zend_throw_exception(zend_ce_type_error, "Cairo\\Surface\\Ps::__construct() expects parameter 1 to be null, a string, or a stream resource", 0);
73 1 : RETURN_THROWS();
74 : }
75 :
76 : /* Pack stream into struct */
77 2 : closure = ecalloc(1, sizeof(stream_closure));
78 2 : closure->stream = stream;
79 2 : closure->owned_stream = owned_stream;
80 :
81 2 : surface_object->closure = closure;
82 2 : surface_object->surface = cairo_ps_surface_create_for_stream(php_cairo_write_func, (void *)closure, width, height);
83 : }
84 :
85 10 : if (php_cairo_throw_exception(cairo_surface_status(surface_object->surface))) {
86 0 : RETURN_THROWS();
87 : }
88 : }
89 : /* }}} */
90 :
91 : /* {{{ proto void CairoPsSurface->setSize(double width, double height)
92 : Changes the size of a PS surface for the current (and subsequent) pages.
93 : This should be called before any drawing takes place on the surface */
94 6 : PHP_METHOD(Cairo_Surface_Ps, setSize)
95 : {
96 6 : double width = 0.0, height = 0.0;
97 : cairo_surface_object *surface_object;
98 :
99 6 : ZEND_PARSE_PARAMETERS_START(2, 2)
100 6 : Z_PARAM_DOUBLE(width)
101 4 : Z_PARAM_DOUBLE(height)
102 6 : ZEND_PARSE_PARAMETERS_END();
103 :
104 2 : surface_object = cairo_surface_object_get(getThis());
105 1 : if (!surface_object) {
106 0 : RETURN_THROWS();
107 : }
108 :
109 1 : cairo_ps_surface_set_size(surface_object->surface, width, height);
110 :
111 1 : if (php_cairo_throw_exception(cairo_surface_status(surface_object->surface))) {
112 0 : RETURN_THROWS();
113 : }
114 : }
115 : /* }}} */
116 :
117 : /* {{{ proto void CairoPsSurface->restrictToLevel(int level)
118 : Restricts the generated PostScript file to level. */
119 4 : PHP_METHOD(Cairo_Surface_Ps, restrictToLevel)
120 : {
121 : cairo_surface_object *surface_object;
122 4 : zval *level = NULL;
123 :
124 4 : ZEND_PARSE_PARAMETERS_START(0, 1)
125 3 : Z_PARAM_OPTIONAL
126 5 : Z_PARAM_OBJECT_OF_CLASS(level, ce_cairo_pslevel)
127 4 : ZEND_PARSE_PARAMETERS_END();
128 :
129 4 : surface_object = cairo_surface_object_get(getThis());
130 2 : if (!surface_object) {
131 0 : RETURN_THROWS();
132 : }
133 :
134 2 : cairo_ps_surface_restrict_to_level(
135 : surface_object->surface,
136 : level
137 3 : ? Z_LVAL_P(zend_enum_fetch_case_value(Z_OBJ_P(level)))
138 : : CAIRO_PS_LEVEL_2
139 : );
140 :
141 2 : if (php_cairo_throw_exception(cairo_surface_status(surface_object->surface))) {
142 0 : RETURN_THROWS();
143 : }
144 : }
145 : /* }}} */
146 :
147 : /* {{{ proto void CairoPsSurface->setEps(boolean eps)
148 : If eps is TRUE, the PostScript surface will output Encapsulated PostScript. */
149 4 : PHP_METHOD(Cairo_Surface_Ps, setEps)
150 : {
151 4 : bool eps = false;
152 : cairo_surface_object *surface_object;
153 :
154 4 : ZEND_PARSE_PARAMETERS_START(1, 1)
155 4 : Z_PARAM_BOOL(eps)
156 4 : ZEND_PARSE_PARAMETERS_END();
157 :
158 2 : surface_object = cairo_surface_object_get(getThis());
159 1 : if (!surface_object) {
160 0 : RETURN_THROWS();
161 : }
162 :
163 1 : cairo_ps_surface_set_eps(surface_object->surface, eps);
164 :
165 1 : if (php_cairo_throw_exception(cairo_surface_status(surface_object->surface))) {
166 0 : RETURN_THROWS();
167 : }
168 : }
169 : /* }}} */
170 :
171 : /* {{{ proto boolean CairoPsSurface->getEps(void)
172 : Check whether the PostScript surface will output Encapsulated PostScript. */
173 2 : PHP_METHOD(Cairo_Surface_Ps, getEps)
174 : {
175 : cairo_surface_object *surface_object;
176 :
177 2 : ZEND_PARSE_PARAMETERS_NONE();
178 :
179 2 : surface_object = cairo_surface_object_get(getThis());
180 1 : if (!surface_object) {
181 0 : RETURN_THROWS();
182 : }
183 :
184 1 : RETURN_BOOL(cairo_ps_surface_get_eps(surface_object->surface));
185 : }
186 : /* }}} */
187 :
188 : /* {{{ proto void CairoPsSurface->dscBeginSetup(void)
189 : This function indicates that subsequent calls to cairo_ps_surface_dsc_comment() should
190 : direct comments to the Setup section of the PostScript output. */
191 2 : PHP_METHOD(Cairo_Surface_Ps, dscBeginSetup)
192 : {
193 : cairo_surface_object *surface_object;
194 :
195 2 : ZEND_PARSE_PARAMETERS_NONE();
196 :
197 2 : surface_object = cairo_surface_object_get(getThis());
198 1 : if (!surface_object) {
199 0 : RETURN_THROWS();
200 : }
201 :
202 1 : cairo_ps_surface_dsc_begin_setup(surface_object->surface);
203 : }
204 : /* }}} */
205 :
206 : /* {{{ proto void CairoPsSurface->dscBeginPageSetup(void)
207 : This indicates that subsequent calls to cairo_ps_surface_dsc_comment()
208 : should direct comments to the PageSetup section of the PostScript output.
209 :
210 : This function call is only needed for the first page of a surface.
211 : It should be called after any call to cairo_ps_surface_dsc_begin_setup()
212 : and before any drawing is performed to the surface. */
213 2 : PHP_METHOD(Cairo_Surface_Ps, dscBeginPageSetup)
214 : {
215 : cairo_surface_object *surface_object;
216 :
217 2 : ZEND_PARSE_PARAMETERS_NONE();
218 :
219 2 : surface_object = cairo_surface_object_get(getThis());
220 1 : if (!surface_object) {
221 0 : RETURN_THROWS();
222 : }
223 :
224 1 : cairo_ps_surface_dsc_begin_page_setup(surface_object->surface);
225 : }
226 : /* }}} */
227 :
228 : /* {{{ proto void CairoPsSurface->dscComment(string comment)
229 : Emit a comment into the PostScript output for the given surface. */
230 4 : PHP_METHOD(Cairo_Surface_Ps, dscComment)
231 : {
232 : cairo_surface_object *surface_object;
233 : char *comment, *cairo_comment;
234 : size_t comment_len;
235 :
236 4 : ZEND_PARSE_PARAMETERS_START(1, 1)
237 4 : Z_PARAM_STRING(comment, comment_len)
238 4 : ZEND_PARSE_PARAMETERS_END();
239 :
240 2 : surface_object = cairo_surface_object_get(getThis());
241 1 : if (!surface_object) {
242 0 : RETURN_THROWS();
243 : }
244 :
245 1 : cairo_comment = estrdup(comment);
246 1 : cairo_ps_surface_dsc_comment(surface_object->surface, cairo_comment);
247 1 : efree(cairo_comment);
248 :
249 1 : if (php_cairo_throw_exception(cairo_surface_status(surface_object->surface))) {
250 0 : RETURN_THROWS();
251 : }
252 : }
253 : /* }}} */
254 :
255 : /* {{{ proto array CairoPsSurface::getLevels(void)
256 : Used to retrieve the list of supported levels. See cairo_ps_surface_restrict_to_level(). */
257 2 : PHP_METHOD(Cairo_Surface_Ps, getLevels)
258 : {
259 : const cairo_ps_level_t *levels;
260 : int num_levels, i;
261 : zval ps_level_case;
262 :
263 2 : ZEND_PARSE_PARAMETERS_NONE();
264 :
265 1 : cairo_ps_get_levels(&levels, &num_levels);
266 :
267 1 : array_init(return_value);
268 3 : for (i = 0; i < num_levels; i++) {
269 2 : ps_level_case = php_enum_from_cairo_c_enum(ce_cairo_pslevel, levels[i]);
270 : add_next_index_zval(return_value, &ps_level_case);
271 : }
272 : }
273 : /* }}} */
274 :
275 : /* {{{ proto string \Cairo\Surface\Ps::levelToString(Cairo\Surface\Ps\Level level)
276 : Get the string representation of the given level id. */
277 4 : PHP_METHOD(Cairo_Surface_Ps, levelToString)
278 : {
279 : zval *level;
280 :
281 4 : ZEND_PARSE_PARAMETERS_START(1, 1)
282 4 : Z_PARAM_OBJECT_OF_CLASS(level, ce_cairo_pslevel)
283 4 : ZEND_PARSE_PARAMETERS_END();
284 :
285 3 : RETURN_STRING(cairo_ps_level_to_string(Z_LVAL_P(zend_enum_fetch_case_value(Z_OBJ_P(level)))));
286 : }
287 : /* }}} */
288 :
289 : /* ----------------------------------------------------------------
290 : Cairo\Surface\ps Definition and registration
291 : ------------------------------------------------------------------*/
292 :
293 : /* {{{ PHP_MINIT_FUNCTION */
294 424 : PHP_MINIT_FUNCTION(cairo_ps_surface)
295 : {
296 : zend_class_entry pssurface_ce;
297 :
298 424 : ce_cairo_pssurface = register_class_Cairo_Surface_Ps(ce_cairo_surface);
299 :
300 : /* Ps Level */
301 424 : ce_cairo_pslevel = register_class_Cairo_Surface_Ps_Level();
302 :
303 424 : return SUCCESS;
304 : }
305 :
306 : #endif
|