1 /*
2 +----------------------------------------------------------------------+
3 | PHP Version 5 / Imagick |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 2006-2013 Mikko Koppanen, Scott MacVicar |
6 | ImageMagick (c) ImageMagick Studio LLC |
7 +----------------------------------------------------------------------+
8 | This source file is subject to version 3.01 of the PHP license, |
9 | that is bundled with this package in the file LICENSE, and is |
10 | available through the world-wide-web at the following url: |
11 | http://www.php.net/license/3_01.txt |
12 | If you did not receive a copy of the PHP license and are unable to |
13 | obtain it through the world-wide-web, please send a note to |
14 | license@php.net so we can mail you a copy immediately. |
15 +----------------------------------------------------------------------+
16 | Author: Mikko Kopppanen <mkoppanen@php.net> |
17 | Scott MacVicar <scottmac@php.net> |
18 +----------------------------------------------------------------------+
19 */
20
21 #include "php_imagick.h"
22 #include "php_imagick_defs.h"
23 #include "php_imagick_macros.h"
24 #include "php_imagick_helpers.h"
25
26 #if MagickLibVersion > 0x628
27 /* {{{ proto bool ImagickDraw::resetvectorgraphics()
28 Resets the vector graphics
29 */
PHP_METHOD(ImagickDraw,resetVectorGraphics)30 PHP_METHOD(ImagickDraw, resetVectorGraphics)
31 {
32 php_imagickdraw_object *internd;
33
34 if (zend_parse_parameters_none() == FAILURE) {
35 return;
36 }
37
38 internd = Z_IMAGICKDRAW_P(getThis());
39 DrawResetVectorGraphics(internd->drawing_wand);
40 RETURN_TRUE;
41 }
42 /* }}} */
43 #endif
44
45 #if MagickLibVersion > 0x649
46 /* {{{ proto bool ImagickDraw::getTextKerning()
47 Gets the text kerning
48 */
PHP_METHOD(ImagickDraw,getTextKerning)49 PHP_METHOD(ImagickDraw, getTextKerning)
50 {
51 php_imagickdraw_object *internd;
52
53 if (zend_parse_parameters_none() == FAILURE) {
54 return;
55 }
56
57 internd = Z_IMAGICKDRAW_P(getThis());;
58 RETURN_DOUBLE(DrawGetTextKerning(internd->drawing_wand));
59 }
60 /* }}} */
61
62 /* {{{ proto bool ImagickDraw::setTextKerning(float kerning)
63 Sets the text kerning
64 */
PHP_METHOD(ImagickDraw,setTextKerning)65 PHP_METHOD(ImagickDraw, setTextKerning)
66 {
67 php_imagickdraw_object *internd;
68 double kerning;
69
70 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &kerning) == FAILURE) {
71 return;
72 }
73
74 internd = Z_IMAGICKDRAW_P(getThis());;
75 DrawSetTextKerning(internd->drawing_wand, kerning);
76 RETURN_TRUE;
77 }
78 /* }}} */
79
80 /* {{{ proto bool ImagickDraw::getTextInterwordSpacing()
81 Gets the text interword spacing
82 */
PHP_METHOD(ImagickDraw,getTextInterwordSpacing)83 PHP_METHOD(ImagickDraw, getTextInterwordSpacing)
84 {
85 php_imagickdraw_object *internd;
86
87 if (zend_parse_parameters_none() == FAILURE) {
88 return;
89 }
90
91 internd = Z_IMAGICKDRAW_P(getThis());;
92 RETURN_DOUBLE(DrawGetTextInterwordSpacing(internd->drawing_wand));
93 }
94 /* }}} */
95
96 /* {{{ proto bool ImagickDraw::setTextInterwordSpacing(float spacing)
97 Sets the text interword spacing
98 */
PHP_METHOD(ImagickDraw,setTextInterwordSpacing)99 PHP_METHOD(ImagickDraw, setTextInterwordSpacing)
100 {
101 php_imagickdraw_object *internd;
102 double spacing;
103
104 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &spacing) == FAILURE) {
105 return;
106 }
107
108 internd = Z_IMAGICKDRAW_P(getThis());;
109 DrawSetTextInterwordSpacing(internd->drawing_wand, spacing);
110 RETURN_TRUE;
111 }
112 /* }}} */
113 #endif
114
115 #if MagickLibVersion > 0x655
116 /* {{{ proto bool ImagickDraw::getTextInterlineSpacing()
117 Gets the text interword spacing
118 */
PHP_METHOD(ImagickDraw,getTextInterlineSpacing)119 PHP_METHOD(ImagickDraw, getTextInterlineSpacing)
120 {
121 php_imagickdraw_object *internd;
122
123 if (zend_parse_parameters_none() == FAILURE) {
124 return;
125 }
126
127 internd = Z_IMAGICKDRAW_P(getThis());;
128 RETURN_DOUBLE(DrawGetTextInterlineSpacing(internd->drawing_wand));
129 }
130 /* }}} */
131
132 /* {{{ proto bool ImagickDraw::setTextInterlineSpacing(float spacing)
133 Sets the text interword spacing
134 */
PHP_METHOD(ImagickDraw,setTextInterlineSpacing)135 PHP_METHOD(ImagickDraw, setTextInterlineSpacing)
136 {
137 php_imagickdraw_object *internd;
138 double spacing;
139
140 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &spacing) == FAILURE) {
141 return;
142 }
143
144 internd = Z_IMAGICKDRAW_P(getThis());;
145 DrawSetTextInterlineSpacing(internd->drawing_wand, spacing);
146 RETURN_TRUE;
147 }
148 /* }}} */
149 #endif
150
151 /* {{{ proto ImagickDraw ImagickDraw::__construct()
152 The ImagickDraw constructor
153 */
PHP_METHOD(ImagickDraw,__construct)154 PHP_METHOD(ImagickDraw, __construct)
155 {
156 /* Empty constructor for possible future uses */
157
158 #if PHP_VERSION_ID >= 70000
159 // This suppresses an 'unused parameter' warning.
160 (void)execute_data;
161 (void)return_value;
162 #endif
163 }
164 /* }}} */
165
166 /* {{{ proto bool ImagickDraw::circle(float ox, float oy, float px, float py)
167 Draws a circle on the image.
168 */
PHP_METHOD(ImagickDraw,circle)169 PHP_METHOD(ImagickDraw, circle)
170 {
171 double ox, oy, px, py;
172 php_imagickdraw_object *internd;
173
174 /* Parse parameters given to function */
175 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "dddd", &ox, &oy, &px, &py) == FAILURE) {
176 return;
177 }
178
179 internd = Z_IMAGICKDRAW_P(getThis());;
180
181 DrawCircle(internd->drawing_wand, ox, oy, px, py);
182 RETURN_TRUE;
183 }
184 /* }}} */
185
186 /* {{{ proto bool ImagickDraw::rectangle(float x1, float y1, float x2, float y2)
187 Draws a rectangle given two coordinates and using the current stroke, stroke width, and fill settings.
188 */
PHP_METHOD(ImagickDraw,rectangle)189 PHP_METHOD(ImagickDraw, rectangle)
190 {
191 double x1, y1, x2, y2;
192 php_imagickdraw_object *internd;
193
194 /* Parse parameters given to function */
195 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "dddd", &x1, &y1, &x2, &y2) == FAILURE) {
196 return;
197 }
198
199 internd = Z_IMAGICKDRAW_P(getThis());;
200 DrawRectangle(internd->drawing_wand, x1, y1, x2, y2);
201
202 RETURN_TRUE;
203 }
204 /* }}} */
205
206 /* {{{ proto bool ImagickDraw::roundRectangle(float x1, float y1, float x2, float y2, float rx, float ry)
207 Draws a rounted rectangle given two coordinates, x & y corner radiuses and using the current stroke, stroke width, and fill settings.
208 */
PHP_METHOD(ImagickDraw,roundRectangle)209 PHP_METHOD(ImagickDraw, roundRectangle)
210 {
211 double x1, y1, x2, y2, rx, ry;
212 php_imagickdraw_object *internd;
213
214 /* Parse parameters given to function */
215 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "dddddd", &x1, &y1, &x2, &y2, &rx, &ry) == FAILURE) {
216 return;
217 }
218
219 internd = Z_IMAGICKDRAW_P(getThis());;
220
221 DrawRoundRectangle(internd->drawing_wand, x1, y1, x2, y2, rx, ry);
222 RETURN_TRUE;
223 }
224 /* }}} */
225
226 /* {{{ proto bool ImagickDraw::ellipse(float ox, float oy, float rx, float ry, float start, float end)
227 Draws an ellipse on the image.
228 */
PHP_METHOD(ImagickDraw,ellipse)229 PHP_METHOD(ImagickDraw, ellipse)
230 {
231 double ox, oy, rx, ry, start, end;
232 php_imagickdraw_object *internd;
233
234 /* Parse parameters given to function */
235 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "dddddd", &ox, &oy, &rx, &ry, &start, &end) == FAILURE) {
236 return;
237 }
238
239 internd = Z_IMAGICKDRAW_P(getThis());;
240
241 DrawEllipse(internd->drawing_wand, ox, oy, rx, ry, start, end);
242 RETURN_TRUE;
243 }
244 /* }}} */
245
246 /* {{{ proto bool ImagickDraw::skewX(float degrees)
247 Skews the current coordinate system in the horizontal direction.
248 */
PHP_METHOD(ImagickDraw,skewX)249 PHP_METHOD(ImagickDraw, skewX)
250 {
251 double degrees;
252 php_imagickdraw_object *internd;
253
254 /* Parse parameters given to function */
255 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", °rees) == FAILURE) {
256 return;
257 }
258
259 internd = Z_IMAGICKDRAW_P(getThis());;
260
261 DrawSkewX(internd->drawing_wand, degrees);
262 RETURN_TRUE;
263 }
264 /* }}} */
265
266 /* {{{ proto bool ImagickDraw::skewY(float degrees)
267 Skews the current coordinate system in the vertical direction.
268 */
PHP_METHOD(ImagickDraw,skewY)269 PHP_METHOD(ImagickDraw, skewY)
270 {
271 double degrees;
272 php_imagickdraw_object *internd;
273
274 /* Parse parameters given to function */
275 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", °rees) == FAILURE) {
276 return;
277 }
278
279 internd = Z_IMAGICKDRAW_P(getThis());;
280
281 DrawSkewY(internd->drawing_wand, degrees);
282 RETURN_TRUE;
283 }
284 /* }}} */
285
286 /* {{{ proto bool ImagickDraw::translate(float x, float y)
287 Applies a translation to the current coordinate system which moves the coordinate system origin to the specified coordinate.
288 */
PHP_METHOD(ImagickDraw,translate)289 PHP_METHOD(ImagickDraw, translate)
290 {
291 double x, y;
292 php_imagickdraw_object *internd;
293
294 /* Parse parameters given to function */
295 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "dd", &x, &y) == FAILURE) {
296 return;
297 }
298
299 internd = Z_IMAGICKDRAW_P(getThis());;
300
301 DrawTranslate(internd->drawing_wand, x, y);
302 RETURN_TRUE;
303 }
304 /* }}} */
305
306 /* {{{ proto bool ImagickDraw::setFillColor(PixelWand fill_wand)
307 Sets the fill color to be used for drawing filled objects.
308 */
PHP_METHOD(ImagickDraw,setFillColor)309 PHP_METHOD(ImagickDraw, setFillColor)
310 {
311 zval *param;
312 php_imagickdraw_object *internd;
313 PixelWand *color_wand;
314 zend_bool allocated;
315
316 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", ¶m) == FAILURE) {
317 return;
318 }
319
320 internd = Z_IMAGICKDRAW_P(getThis());;
321
322 color_wand = php_imagick_zval_to_pixelwand(param, IMAGICKDRAW_CLASS, &allocated TSRMLS_CC);
323 if (!color_wand)
324 return;
325
326 DrawSetFillColor(internd->drawing_wand, color_wand);
327 if (allocated)
328 color_wand = DestroyPixelWand (color_wand);
329
330 RETURN_TRUE;
331 }
332 /* }}} */
333
334 /* {{{ proto bool ImagickDraw::setResolution(float x, float y)
335 Sets the resolution
336 */
PHP_METHOD(ImagickDraw,setResolution)337 PHP_METHOD(ImagickDraw, setResolution)
338 {
339 char *density, *buf = NULL;
340 double x, y;
341 php_imagickdraw_object *internd;
342 DrawInfo *draw_info;
343 DrawingWand *d_wand;
344
345 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "dd", &x, &y) == FAILURE) {
346 return;
347 }
348
349 internd = Z_IMAGICKDRAW_P(getThis());
350
351 spprintf(&buf, 512, "%fx%f", x, y);
352 density = AcquireString(buf);
353 efree (buf);
354
355 if (!density) {
356 php_imagick_throw_exception(IMAGICKDRAW_CLASS, "Failed to allocate memory" TSRMLS_CC);
357 return;
358 }
359
360 draw_info = PeekDrawingWand(internd->drawing_wand);
361 draw_info->density = density;
362
363
364 #if MagickLibVersion >= 0x693
365 d_wand = AcquireDrawingWand(draw_info, NULL);
366 #else
367 d_wand = (DrawingWand *) DrawAllocateWand(draw_info, NULL);
368 #endif
369
370 if (!d_wand) {
371 php_imagick_throw_exception(IMAGICKDRAW_CLASS, "Failed to allocate new DrawingWand structure" TSRMLS_CC);
372 return;
373 }
374
375 php_imagick_replace_drawingwand(internd, d_wand);
376 RETURN_TRUE;
377 }
378 /* }}} */
379
380 /* {{{ proto bool ImagickDraw::setStrokeColor(PixelWand stroke_wand)
381 Sets the color used for stroking object outlines.
382 */
PHP_METHOD(ImagickDraw,setStrokeColor)383 PHP_METHOD(ImagickDraw, setStrokeColor)
384 {
385 zval *param;
386 php_imagickdraw_object *internd;
387 PixelWand *color_wand;
388 zend_bool allocated;
389
390 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", ¶m) == FAILURE) {
391 return;
392 }
393
394 internd = Z_IMAGICKDRAW_P(getThis());;
395
396 color_wand = php_imagick_zval_to_pixelwand (param, IMAGICKDRAW_CLASS, &allocated TSRMLS_CC);
397 if (!color_wand)
398 return;
399
400 DrawSetStrokeColor(internd->drawing_wand, color_wand);
401 if (allocated)
402 color_wand = DestroyPixelWand (color_wand);
403
404 RETURN_TRUE;
405 }
406 /* }}} */
407
408 /* {{{ proto bool ImagickDraw::setFillAlpha(float opacity)
409 Sets the opacity to use when drawing using the fill color or fill texture. Fully opaque is 1.0.
410 */
PHP_METHOD(ImagickDraw,setFillAlpha)411 PHP_METHOD(ImagickDraw, setFillAlpha)
412 {
413 php_imagickdraw_object *internd;
414 double opacity;
415
416 IMAGICK_METHOD_DEPRECATED("ImagickDraw", "setFillAlpha");
417
418 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &opacity) == FAILURE) {
419 return;
420 }
421
422 internd = Z_IMAGICKDRAW_P(getThis());;
423
424 #if MagickLibVersion >= 0x635
425 DrawSetFillOpacity(internd->drawing_wand, opacity);
426 #else
427 DrawSetFillAlpha(internd->drawing_wand, opacity);
428 #endif
429 RETURN_TRUE;
430 }
431 /* }}} */
432
433 /* {{{ proto bool ImagickDraw::settextantialias()
434 Returns the antialias property associated with the wand.
435 */
PHP_METHOD(ImagickDraw,setTextAntialias)436 PHP_METHOD(ImagickDraw, setTextAntialias)
437 {
438 php_imagickdraw_object *internd;
439 zend_bool antialias;
440
441 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &antialias) == FAILURE) {
442 return;
443 }
444
445 internd = Z_IMAGICKDRAW_P(getThis());;
446
447 DrawSetTextAntialias(internd->drawing_wand, antialias);
448 RETURN_TRUE;
449 }
450 /* }}} */
451
452 /* {{{ proto bool ImagickDraw::setTextEncoding(string encoding)
453 Specifies specifies the code set to use for text annotations.
454 The only character encoding which may be specified at this time is "UTF-8" for representing Unicode as a sequence of bytes.
455 Specify an empty string to set text encoding to the system's default.
456 Successful text annotation using Unicode may require fonts designed to support Unicode.
457 */
PHP_METHOD(ImagickDraw,setTextEncoding)458 PHP_METHOD(ImagickDraw, setTextEncoding)
459 {
460 php_imagickdraw_object *internd;
461 char *encoding;
462 IM_LEN_TYPE encoding_len;
463
464 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &encoding, &encoding_len) == FAILURE) {
465 return;
466 }
467
468 internd = Z_IMAGICKDRAW_P(getThis());;
469
470 DrawSetTextEncoding(internd->drawing_wand, encoding);
471 RETURN_TRUE;
472 }
473 /* }}} */
474
475 /* {{{ proto bool ImagickDraw::setStrokeAlpha(float opacity)
476 Specifies the opacity of stroked object outlines.
477 */
PHP_METHOD(ImagickDraw,setStrokeAlpha)478 PHP_METHOD(ImagickDraw, setStrokeAlpha)
479 {
480 php_imagickdraw_object *internd;
481 double opacity;
482
483 IMAGICK_METHOD_DEPRECATED("ImagickDraw", "setStrokeAlpha");
484
485 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &opacity) == FAILURE) {
486 return;
487 }
488
489 internd = Z_IMAGICKDRAW_P(getThis());;
490
491 #if MagickLibVersion >= 0x635
492 DrawSetStrokeOpacity(internd->drawing_wand, opacity);
493 #else
494 DrawSetStrokeAlpha(internd->drawing_wand, opacity);
495 #endif
496 RETURN_TRUE;
497 }
498 /* }}} */
499
500 /* {{{ proto bool ImagickDraw::setStrokeWidth(float stroke_width)
501 Sets the width of the stroke used to draw object outlines.
502 */
PHP_METHOD(ImagickDraw,setStrokeWidth)503 PHP_METHOD(ImagickDraw, setStrokeWidth)
504 {
505 php_imagickdraw_object *internd;
506 double width;
507
508 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &width) == FAILURE) {
509 return;
510 }
511
512 internd = Z_IMAGICKDRAW_P(getThis());;
513
514 DrawSetStrokeWidth(internd->drawing_wand, width);
515 RETURN_TRUE;
516 }
517 /* }}} */
518
519 /* {{{ proto bool ImagickDraw::setFont(string font_name)
520 Sets the fully-sepecified font to use when annotating with text.
521 */
PHP_METHOD(ImagickDraw,setFont)522 PHP_METHOD(ImagickDraw, setFont)
523 {
524 php_imagickdraw_object *internd;
525 char *font, *absolute;
526 IM_LEN_TYPE font_len;
527 MagickBooleanType status;
528 php_imagick_rw_result_t rc;
529
530 /* Parse parameters given to function */
531 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &font, &font_len) == FAILURE) {
532 return;
533 }
534
535 /* Check that no empty string is passed */
536 if (font_len == 0) {
537 php_imagick_throw_exception (IMAGICKDRAW_CLASS, "Can not set empty font" TSRMLS_CC);
538 return;
539 }
540
541 internd = Z_IMAGICKDRAW_P(getThis());;
542
543 /* And if it wasn't */
544 if (!php_imagick_check_font(font, font_len TSRMLS_CC)) {
545
546 if ((absolute = expand_filepath(font, NULL TSRMLS_CC)) == NULL) {
547 php_imagick_throw_exception (IMAGICKDRAW_CLASS, "Unable to set font, file path expansion failed" TSRMLS_CC);
548 return;
549 }
550
551 /* Do an access check for the font */
552 if ((rc = php_imagick_file_access_check (absolute TSRMLS_CC)) != IMAGICK_RW_OK) {
553 // Failed
554 php_imagick_imagickdraw_rw_fail_to_exception (internd->drawing_wand, rc, absolute TSRMLS_CC);
555 efree(absolute);
556 return;
557 }
558 status = DrawSetFont(internd->drawing_wand, absolute);
559 efree(absolute);
560
561 } else {
562 status = DrawSetFont(internd->drawing_wand, font);
563 }
564
565 if (status == MagickFalse) {
566 php_imagick_convert_imagickdraw_exception (internd->drawing_wand, "Unable to set font" TSRMLS_CC);
567 return;
568 }
569
570 RETURN_TRUE;
571 }
572 /* }}} */
573
574 /* {{{ proto bool ImagickDraw::setFontFamily(string font_family)
575 Sets the font family to use when annotating with text.
576 */
PHP_METHOD(ImagickDraw,setFontFamily)577 PHP_METHOD(ImagickDraw, setFontFamily)
578 {
579 php_imagickdraw_object *internd;
580 char *font_family;
581 IM_LEN_TYPE font_family_len;
582 MagickBooleanType status;
583
584 /* Parse parameters given to function */
585 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &font_family, &font_family_len) == FAILURE) {
586 return;
587 }
588
589 /* Check that no empty string is passed */
590 if (font_family_len == 0) {
591 php_imagick_throw_exception(IMAGICKDRAW_CLASS, "Can not set empty font family" TSRMLS_CC);
592 return;
593 }
594
595 if (!php_imagick_check_font(font_family, font_family_len TSRMLS_CC )) {
596 php_imagick_throw_exception(IMAGICKDRAW_CLASS, "Unable to set font family; parameter not found in the list of configured fonts" TSRMLS_CC);
597 return;
598 }
599
600 internd = Z_IMAGICKDRAW_P(getThis());;
601 status = DrawSetFontFamily(internd->drawing_wand, font_family);
602
603 if (status == MagickFalse) {
604 php_imagick_convert_imagickdraw_exception (internd->drawing_wand, "Unable to set font family" TSRMLS_CC);
605 return;
606 }
607
608 RETURN_TRUE;
609 }
610 /* }}} */
611
612 /* {{{ proto bool ImagickDraw::setFontSize(float pointsize)
613 Sets the font pointsize to use when annotating with text.
614 */
PHP_METHOD(ImagickDraw,setFontSize)615 PHP_METHOD(ImagickDraw, setFontSize)
616 {
617 php_imagickdraw_object *internd;
618 double font_size;
619
620 /* Parse parameters given to function */
621 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &font_size) == FAILURE) {
622 return;
623 }
624
625 internd = Z_IMAGICKDRAW_P(getThis());;
626
627 DrawSetFontSize(internd->drawing_wand, font_size);
628 RETURN_TRUE;
629 }
630 /* }}} */
631
632 /* {{{ proto bool ImagickDraw::setFontStyle(int style)
633 Sets the font style to use when annotating with text. The AnyStyle enumeration acts as a wild-card "don't care" option.
634 */
PHP_METHOD(ImagickDraw,setFontStyle)635 PHP_METHOD(ImagickDraw, setFontStyle)
636 {
637 php_imagickdraw_object *internd;
638 im_long style_id = AnyStyle;
639
640 /* Parse parameters given to function */
641 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &style_id) == FAILURE) {
642 return;
643 }
644
645 internd = Z_IMAGICKDRAW_P(getThis());;
646
647 DrawSetFontStyle(internd->drawing_wand, style_id);
648 RETURN_TRUE;
649 }
650 /* }}} */
651
652 /* {{{ proto bool ImagickDraw::setFontWeight(int font_weight)
653 Sets the font weight to use when annotating with text.
654 */
PHP_METHOD(ImagickDraw,setFontWeight)655 PHP_METHOD(ImagickDraw, setFontWeight)
656 {
657 php_imagickdraw_object *internd;
658 im_long weight;
659
660 /* Parse parameters given to function */
661 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &weight) == FAILURE) {
662 return;
663 }
664
665 if (weight >= 100 && weight <= 900) {
666 internd = Z_IMAGICKDRAW_P(getThis());;
667 DrawSetFontWeight(internd->drawing_wand, weight);
668 RETURN_TRUE;
669 }
670 php_imagick_throw_exception(IMAGICKDRAW_CLASS, "Font weight valid range is 100-900" TSRMLS_CC);
671 return;
672 }
673 /* }}} */
674
675 /* {{{ proto int ImagickDraw::getFontStretch(int fontStretch)
676 Gets the font stretch to use when annotating with text
677 */
PHP_METHOD(ImagickDraw,getFontStretch)678 PHP_METHOD(ImagickDraw, getFontStretch)
679 {
680 php_imagickdraw_object *internd;
681
682 internd = Z_IMAGICKDRAW_P(getThis());;
683 RETVAL_LONG(DrawGetFontStretch(internd->drawing_wand));
684 }
685 /* }}} */
686
687 /* {{{ proto bool ImagickDraw::setFontStretch(int fontStretch)
688 Sets the font stretch to use when annotating with text. The AnyStretch enumeration acts as a wild-card "don't care" option.
689 */
PHP_METHOD(ImagickDraw,setFontStretch)690 PHP_METHOD(ImagickDraw, setFontStretch)
691 {
692 php_imagickdraw_object *internd;
693 im_long stretch;
694
695 /* Parse parameters given to function */
696 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &stretch) == FAILURE) {
697 return;
698 }
699
700 internd = Z_IMAGICKDRAW_P(getThis());;
701
702 DrawSetFontStretch(internd->drawing_wand, stretch);
703 RETURN_TRUE;
704 }
705 /* }}} */
706
707 /* {{{ proto bool ImagickDraw::setStrokeAntialias(bool stroke_antialias)
708 Controls whether stroked outlines are antialiased. Stroked outlines are antialiased by default. When antialiasing is disabled stroked pixels are thresholded to determine if the stroke color or underlying canvas color should be used.
709 */
PHP_METHOD(ImagickDraw,setStrokeAntialias)710 PHP_METHOD(ImagickDraw, setStrokeAntialias)
711 {
712 php_imagickdraw_object *internd;
713 zend_bool antialias;
714
715 /* Parse parameters given to function */
716 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "b", &antialias) == FAILURE) {
717 return;
718 }
719
720 internd = Z_IMAGICKDRAW_P(getThis());;
721
722 DrawSetStrokeAntialias(internd->drawing_wand, antialias);
723 RETURN_TRUE;
724
725 }
726 /* }}} */
727
728 /* {{{ proto bool ImagickDraw::setTextAlignment(int alignment)
729 Specifies a text alignment to be applied when annotating with text.
730 */
PHP_METHOD(ImagickDraw,setTextAlignment)731 PHP_METHOD(ImagickDraw, setTextAlignment)
732 {
733 php_imagickdraw_object *internd;
734 im_long align;
735
736 /* Parse parameters given to function */
737 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &align) == FAILURE) {
738 return;
739 }
740
741 internd = Z_IMAGICKDRAW_P(getThis());;
742
743 DrawSetTextAlignment(internd->drawing_wand, align);
744 RETURN_TRUE;
745
746 }
747 /* }}} */
748
749 /* {{{ proto bool ImagickDraw::setTextDecoration(int decoration)
750 Specifies a decoration to be applied when annotating with text.
751 */
PHP_METHOD(ImagickDraw,setTextDecoration)752 PHP_METHOD(ImagickDraw, setTextDecoration)
753 {
754 php_imagickdraw_object *internd;
755 im_long decoration;
756
757 /* Parse parameters given to function */
758 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &decoration) == FAILURE) {
759 return;
760 }
761
762 internd = Z_IMAGICKDRAW_P(getThis());;
763
764 DrawSetTextDecoration(internd->drawing_wand, decoration);
765 RETURN_TRUE;
766 }
767 /* }}} */
768
769 /* {{{ proto bool ImagickDraw::setTextUnderColor(PixelWand under_wand)
770 Specifies the color of a background rectangle to place under text annotations.
771 */
PHP_METHOD(ImagickDraw,setTextUnderColor)772 PHP_METHOD(ImagickDraw, setTextUnderColor)
773 {
774 zval *param;
775 php_imagickdraw_object *internd;
776 PixelWand *color_wand;
777 zend_bool allocated;
778
779 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", ¶m) == FAILURE) {
780 return;
781 }
782
783 internd = Z_IMAGICKDRAW_P(getThis());;
784
785 color_wand = php_imagick_zval_to_pixelwand (param, IMAGICKDRAW_CLASS, &allocated TSRMLS_CC);
786 if (!color_wand)
787 return;
788
789 DrawSetTextUnderColor(internd->drawing_wand, color_wand);
790 if (allocated)
791 color_wand = DestroyPixelWand (color_wand);
792
793 RETURN_TRUE;
794 }
795 /* }}} */
796
797 /* {{{ proto bool ImagickDraw::setViewbox(float x1, float y1, float x2, float y2 )
798 Sets the overall canvas size to be recorded with the drawing vector data. Usually this will be specified using the same size as the canvas image. When the vector data is saved to SVG or MVG formats, the viewbox is use to specify the size of the canvas image that a viewer will render the vector data on.
799 */
PHP_METHOD(ImagickDraw,setViewbox)800 PHP_METHOD(ImagickDraw, setViewbox)
801 {
802 php_imagickdraw_object *internd;
803 im_long x1, y1, x2, y2;
804
805 /* Parse parameters given to function */
806 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "llll", &x1, &y1, &x2, &y2) == FAILURE) {
807 return;
808 }
809
810 internd = Z_IMAGICKDRAW_P(getThis());;
811
812 DrawSetViewbox(internd->drawing_wand, x1, y1, x2, y2);
813 RETURN_TRUE;
814 }
815
816 /* {{{ proto string ImagickDraw::getFont()
817 Returns a string specifying the font used when annotating with text
818 */
PHP_METHOD(ImagickDraw,getFont)819 PHP_METHOD(ImagickDraw, getFont)
820 {
821 php_imagickdraw_object *internd;
822 char *font;
823
824 if (zend_parse_parameters_none() == FAILURE) {
825 return;
826 }
827
828 internd = Z_IMAGICKDRAW_P(getThis());;
829
830 font = DrawGetFont(internd->drawing_wand);
831
832 if (!font) {
833 RETURN_FALSE;
834 } else {
835 IM_ZVAL_STRING(return_value, font);
836 IMAGICK_FREE_MAGICK_MEMORY(font);
837 return;
838 }
839 }
840 /* }}} */
841
842 /* {{{ proto string ImagickDraw::getFontFamily()
843 Returns the font family to use when annotating with text. The value returned must be freed by the user when it is no longer needed.
844 */
PHP_METHOD(ImagickDraw,getFontFamily)845 PHP_METHOD(ImagickDraw, getFontFamily)
846 {
847 php_imagickdraw_object *internd;
848 char *font_family;
849
850 if (zend_parse_parameters_none() == FAILURE) {
851 return;
852 }
853
854 internd = Z_IMAGICKDRAW_P(getThis());;
855
856 font_family = DrawGetFontFamily(internd->drawing_wand);
857 if (!font_family) {
858 RETURN_FALSE;
859 } else {
860 IM_ZVAL_STRING(return_value, font_family);
861 IMAGICK_FREE_MAGICK_MEMORY(font_family);
862 return;
863 }
864 }
865 /* }}} */
866
867 /* {{{ proto float ImagickDraw::getFontSize()
868 Returns the font pointsize used when annotating with text.
869 */
PHP_METHOD(ImagickDraw,getFontSize)870 PHP_METHOD(ImagickDraw, getFontSize)
871 {
872 php_imagickdraw_object *internd;
873 double font_size;
874
875 if (zend_parse_parameters_none() == FAILURE) {
876 return;
877 }
878
879 internd = Z_IMAGICKDRAW_P(getThis());
880
881 font_size = DrawGetFontSize(internd->drawing_wand);
882 ZVAL_DOUBLE(return_value, font_size);
883 return;
884 }
885 /* }}} */
886
887 /* {{{ proto int ImagickDraw::getFontStyle()
888 Returns the font style used when annotating with text.
889 */
PHP_METHOD(ImagickDraw,getFontStyle)890 PHP_METHOD(ImagickDraw, getFontStyle)
891 {
892 php_imagickdraw_object *internd;
893 long font_style;
894
895 if (zend_parse_parameters_none() == FAILURE) {
896 return;
897 }
898
899 internd = Z_IMAGICKDRAW_P(getThis());
900
901 font_style = DrawGetFontStyle(internd->drawing_wand);
902 ZVAL_LONG(return_value, font_style);
903 return;
904 }
905 /* }}} */
906
907 /* {{{ proto int ImagickDraw::getFontWeight()
908 Returns the font weight used when annotating with text.
909 */
PHP_METHOD(ImagickDraw,getFontWeight)910 PHP_METHOD(ImagickDraw, getFontWeight)
911 {
912 php_imagickdraw_object *internd;
913 long weight;
914
915 if (zend_parse_parameters_none() == FAILURE) {
916 return;
917 }
918
919 internd = Z_IMAGICKDRAW_P(getThis());;
920
921 weight = DrawGetFontWeight(internd->drawing_wand);
922 ZVAL_LONG(return_value, weight);
923 return;
924 }
925 /* }}} */
926
927 /* {{{ proto bool ImagickDraw::clear()
928 Clears a DrawingWand resource of any accumulated commands, and resets the settings it contains to their defaults.
929 */
PHP_METHOD(ImagickDraw,clear)930 PHP_METHOD(ImagickDraw, clear)
931 {
932 php_imagickdraw_object *internd;
933
934 if (zend_parse_parameters_none() == FAILURE) {
935 return;
936 }
937
938 internd = Z_IMAGICKDRAW_P(getThis());;
939 ClearDrawingWand(internd->drawing_wand);
940 RETURN_TRUE;
941 }
942 /* }}} */
943
944 /* {{{ proto int ImagickDraw::getTextDecoration()
945 Returns the decoration applied when annotating with text.
946 */
PHP_METHOD(ImagickDraw,getTextDecoration)947 PHP_METHOD(ImagickDraw, getTextDecoration)
948 {
949 php_imagickdraw_object *internd;
950 long decoration;
951
952 if (zend_parse_parameters_none() == FAILURE) {
953 return;
954 }
955
956 internd = Z_IMAGICKDRAW_P(getThis());;
957
958 decoration = DrawGetTextDecoration(internd->drawing_wand);
959 ZVAL_LONG(return_value, decoration);
960 return;
961 }
962 /* }}} */
963
964 /* {{{ proto string ImagickDraw::getTextEncoding()
965 Returns a null-terminated string which specifies the code set used for text annotations. The string must be freed by the user once it is no longer required.
966 */
PHP_METHOD(ImagickDraw,getTextEncoding)967 PHP_METHOD(ImagickDraw, getTextEncoding)
968 {
969 php_imagickdraw_object *internd;
970 char *encoding;
971
972 if (zend_parse_parameters_none() == FAILURE) {
973 return;
974 }
975
976 internd = Z_IMAGICKDRAW_P(getThis());;
977 encoding = DrawGetTextEncoding(internd->drawing_wand);
978
979 if (!encoding) {
980 RETURN_FALSE;
981 } else {
982 IM_ZVAL_STRING(return_value, encoding);
983 IMAGICK_FREE_MAGICK_MEMORY(encoding);
984 return;
985 }
986 }
987 /* }}} */
988
989 /* {{{ proto bool ImagickDraw::annotation(float x, float y, string *text)
990 Draws text on the image.
991 */
PHP_METHOD(ImagickDraw,annotation)992 PHP_METHOD(ImagickDraw, annotation)
993 {
994 php_imagickdraw_object *internd;
995 double x, y;
996 unsigned char *text;
997 IM_LEN_TYPE text_len;
998 #if MagickLibVersion < 0x632
999 char *font;
1000 #endif
1001
1002 /* Parse parameters given to function */
1003 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "dds", &x, &y, &text, &text_len) == FAILURE) {
1004 return;
1005 }
1006
1007 internd = Z_IMAGICKDRAW_P(getThis());;
1008 #if MagickLibVersion < 0x632
1009 font = DrawGetFont(internd->drawing_wand);
1010
1011 /* Fixes PECL Bug #11328 */
1012 if (!font) {
1013 php_imagick_throw_exception(IMAGICKDRAW_CLASS, "Font needs to be set before annotating an image" TSRMLS_CC);
1014 return;
1015 }
1016 #endif
1017
1018 DrawAnnotation(internd->drawing_wand, x, y, text);
1019 RETURN_TRUE;
1020 }
1021 /* }}} */
1022
1023 /* {{{ proto bool ImagickDraw::arc(float sx, float sy, float ex, float ey, float sd, float ed)
1024 Draws an arc falling within a specified bounding rectangle on the image.
1025 */
PHP_METHOD(ImagickDraw,arc)1026 PHP_METHOD(ImagickDraw, arc)
1027 {
1028 double sx, sy, ex, ey, sd, ed;
1029 php_imagickdraw_object *internd;
1030
1031 /* Parse parameters given to function */
1032 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "dddddd", &sx, &sy, &ex, &ey, &sd, &ed) == FAILURE) {
1033 return;
1034 }
1035
1036 internd = Z_IMAGICKDRAW_P(getThis());;
1037
1038 DrawArc(internd->drawing_wand, sx, sy, ex, ey, sd, ed);
1039 RETURN_TRUE;
1040 }
1041 /* }}} */
1042
1043
1044 #if MagickLibVersion < 0x700
1045 /* {{{ proto bool ImagickDraw::matte(float x, float y, int paintMethod)
1046 Paints on the image's opacity channel in order to set effected pixels to transparent. to influence the opacity of pixels. The available paint methods are:
1047 */
PHP_METHOD(ImagickDraw,matte)1048 PHP_METHOD(ImagickDraw, matte)
1049 {
1050 double x, y;
1051 php_imagickdraw_object *internd;
1052 im_long paint_method;
1053
1054 /* Parse parameters given to function */
1055 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ddl", &x, &y, &paint_method) == FAILURE) {
1056 return;
1057 }
1058
1059 internd = Z_IMAGICKDRAW_P(getThis());;
1060
1061 DrawMatte(internd->drawing_wand, x, y, paint_method);
1062 RETURN_TRUE;
1063 }
1064 /* }}} */
1065
1066 #else
1067
1068 /* {{{ proto bool ImagickDraw::alpha(float x, float y, int paintMethod)
1069 Paints on the image's alpha channel in order to set effected pixels to transparent. to influence the alpha of pixels. The available paint methods are:
1070 PointMethod: Select the target pixel
1071 ReplaceMethod: Select any pixel that matches the target pixel.
1072 FloodfillMethod: Select the target pixel and matching neighbors.
1073 FillToBorderMethod: Select the target pixel and neighbors not matching
1074 border color.
1075 ResetMethod: Select all pixels.
1076 */
PHP_METHOD(ImagickDraw,alpha)1077 PHP_METHOD(ImagickDraw, alpha)
1078 {
1079 double x, y;
1080 php_imagickdraw_object *internd;
1081 im_long paint_method;
1082
1083 /* Parse parameters given to function */
1084 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ddl", &x, &y, &paint_method) == FAILURE) {
1085 return;
1086 }
1087
1088 internd = Z_IMAGICKDRAW_P(getThis());;
1089
1090 DrawAlpha(internd->drawing_wand, x, y, paint_method);
1091 RETURN_TRUE;
1092 }
1093 /* }}} */
1094
1095 #endif
1096
1097
1098 /* {{{ proto bool ImagickDraw::polygon(array coordinates)
1099 Draws a polygon using the current stroke, stroke width, and fill color or texture, using the specified array of coordinates.
1100 */
PHP_METHOD(ImagickDraw,polygon)1101 PHP_METHOD(ImagickDraw, polygon)
1102 {
1103 zval *coordinate_array;
1104 php_imagickdraw_object *internd;
1105 PointInfo *coordinates;
1106 int num_elements = 0;
1107
1108 /* Parse parameters given to function */
1109 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &coordinate_array) == FAILURE) {
1110 return;
1111 }
1112
1113 coordinates = php_imagick_zval_to_pointinfo_array(coordinate_array, &num_elements TSRMLS_CC);
1114
1115 if (!coordinates) {
1116 php_imagick_throw_exception(IMAGICKDRAW_CLASS, "Unable to read coordinate array" TSRMLS_CC);
1117 return;
1118 }
1119
1120 internd = Z_IMAGICKDRAW_P(getThis());;
1121 DrawPolygon(internd->drawing_wand, num_elements, coordinates);
1122
1123 efree(coordinates);
1124
1125 RETURN_TRUE;
1126 }
1127 /* }}} */
1128
1129 /* {{{ proto bool ImagickDraw::bezier(array coordinates)
1130 Draws a bezier curve through a set of points on the image.
1131 */
PHP_METHOD(ImagickDraw,bezier)1132 PHP_METHOD(ImagickDraw, bezier)
1133 {
1134 zval *coordinate_array;
1135 php_imagickdraw_object *internd;
1136 PointInfo *coordinates;
1137 int num_elements = 0;
1138
1139 /* Parse parameters given to function */
1140 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &coordinate_array) == FAILURE) {
1141 return;
1142 }
1143
1144 coordinates = php_imagick_zval_to_pointinfo_array(coordinate_array, &num_elements TSRMLS_CC);
1145
1146 if (!coordinates) {
1147 php_imagick_throw_exception(IMAGICKDRAW_CLASS, "Unable to read coordinate array" TSRMLS_CC);
1148 return;
1149 }
1150
1151 internd = Z_IMAGICKDRAW_P(getThis());;
1152 DrawBezier(internd->drawing_wand, num_elements, coordinates);
1153
1154 efree(coordinates);
1155 RETURN_TRUE;
1156 }
1157 /* }}} */
1158
1159 /* {{{ proto bool ImagickDraw::point(float x, float y)
1160 Draws a point using the current stroke color and stroke thickness at the specified coordinates.
1161 */
PHP_METHOD(ImagickDraw,point)1162 PHP_METHOD(ImagickDraw, point)
1163 {
1164 php_imagickdraw_object *internd;
1165 double x, y;
1166
1167 /* Parse parameters given to function */
1168 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "dd", &x, &y) == FAILURE) {
1169 return;
1170 }
1171
1172 internd = Z_IMAGICKDRAW_P(getThis());;
1173 DrawPoint(internd->drawing_wand, x, y);
1174
1175 RETURN_TRUE;
1176 }
1177 /* }}} */
1178
1179 /* {{{ proto bool ImagickDraw::line(float sx, float sy, float ex, float ey)
1180 Draws a line on the image using the current stroke color, stroke opacity, and stroke width.
1181 */
PHP_METHOD(ImagickDraw,line)1182 PHP_METHOD(ImagickDraw, line)
1183 {
1184 php_imagickdraw_object *internd;
1185 double sx, sy, ex, ey;
1186
1187 /* Parse parameters given to function */
1188 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "dddd", &sx, &sy, &ex, &ey) == FAILURE) {
1189 return;
1190 }
1191
1192 internd = Z_IMAGICKDRAW_P(getThis());;
1193
1194 DrawLine(internd->drawing_wand, sx, sy, ex, ey);
1195 RETURN_TRUE;
1196 }
1197 /* }}} */
1198
1199 /* {{{ proto ImagickDraw ImagickDraw::clone()
1200 Makes an exact copy of the specified wand.
1201 */
PHP_METHOD(ImagickDraw,clone)1202 PHP_METHOD(ImagickDraw, clone)
1203 {
1204 php_imagickdraw_object *internd, *intern_return;
1205 DrawingWand *tmp_wand;
1206
1207 if (zend_parse_parameters_none() == FAILURE) {
1208 return;
1209 }
1210
1211 IMAGICK_METHOD_DEPRECATED("ImagickDraw", "clone");
1212
1213 internd = Z_IMAGICKDRAW_P(getThis());;
1214 tmp_wand = CloneDrawingWand(internd->drawing_wand);
1215
1216 if (!tmp_wand) {
1217 php_imagick_throw_exception (IMAGICK_CLASS, "Failed to allocate DrawingWand structure" TSRMLS_CC);
1218 return;
1219 }
1220
1221 object_init_ex(return_value, php_imagickdraw_sc_entry);
1222 intern_return = Z_IMAGICKDRAW_P(return_value);
1223 php_imagick_replace_drawingwand(intern_return, tmp_wand);
1224
1225 return;
1226 }
1227 /* }}} */
1228
1229 /* {{{ proto bool ImagickDraw::affine(array affine)
1230 Adjusts the current affine transformation matrix with the specified affine transformation matrix. Note that the current affine transform is adjusted rather than replaced.
1231 */
PHP_METHOD(ImagickDraw,affine)1232 PHP_METHOD(ImagickDraw, affine)
1233 {
1234 php_imagickdraw_object *internd;
1235 zval *affine_matrix;
1236
1237 #if PHP_VERSION_ID >= 70000
1238 zval *pzval;
1239 #else
1240 HashTable *affine;
1241 zval **ppzval;
1242 #endif
1243 char *matrix_elements[] = { "sx", "rx", "ry",
1244 "sy", "tx", "ty" };
1245 int i;
1246 double value;
1247 AffineMatrix matrix;
1248
1249 /* Parse parameters given to function */
1250 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &affine_matrix) == FAILURE) {
1251 return;
1252 }
1253
1254 #if PHP_VERSION_ID < 70000
1255 affine = Z_ARRVAL_P(affine_matrix);
1256 zend_hash_internal_pointer_reset_ex(affine, (HashPosition *) 0);
1257 #endif
1258
1259
1260 for (i = 0; i < 6 ; i++) {
1261 #if PHP_VERSION_ID >= 70000
1262 pzval = zend_hash_str_find(HASH_OF(affine_matrix), matrix_elements[i], 2);
1263 ZVAL_DEREF(pzval);
1264 if (pzval == NULL) {
1265 php_imagick_throw_exception(IMAGICKDRAW_CLASS, "AffineMatrix must contain keys: sx, rx, ry, sy, tx and ty" TSRMLS_CC);
1266 return;
1267 #else
1268 if (zend_hash_find(affine, matrix_elements[i], 3, (void**)&ppzval) == FAILURE) {
1269 php_imagick_throw_exception(IMAGICKDRAW_CLASS, "AffineMatrix must contain keys: sx, rx, ry, sy, tx and ty" TSRMLS_CC);
1270 return;
1271 #endif
1272 } else {
1273
1274 #if PHP_VERSION_ID >= 70000
1275 value = zval_get_double(pzval);
1276 #else
1277 zval tmp_zval, *tmp_pzval;
1278
1279 tmp_zval = **ppzval;
1280 zval_copy_ctor(&tmp_zval);
1281 tmp_pzval = &tmp_zval;
1282 convert_to_double(tmp_pzval);
1283 value = Z_DVAL(tmp_zval);
1284 #endif
1285 if (strcmp(matrix_elements[i], "sx") == 0) {
1286 matrix.sx = value;
1287 } else if (strcmp(matrix_elements[i], "rx") == 0) {
1288 matrix.rx = value;
1289 } else if (strcmp(matrix_elements[i], "ry") == 0) {
1290 matrix.ry = value;
1291 } else if (strcmp(matrix_elements[i], "sy") == 0) {
1292 matrix.sy = value;
1293 } else if (strcmp(matrix_elements[i], "tx") == 0) {
1294 matrix.tx = value;
1295 } else if (strcmp(matrix_elements[i], "ty") == 0) {
1296 matrix.ty = value;
1297 }
1298 }
1299 }
1300
1301 internd = Z_IMAGICKDRAW_P(getThis());
1302
1303 DrawAffine(internd->drawing_wand, &matrix);
1304
1305 RETURN_TRUE;
1306 }
1307 /* }}} */
1308
1309 /* {{{ proto bool ImagickDraw::composite(int compose, float x, float y, float width, float height, MagickWand magick_wand)
1310 Composites an image onto the current image, using the specified composition operator, specified position, and at the specified size.
1311 */
1312 PHP_METHOD(ImagickDraw, composite)
1313 {
1314 php_imagickdraw_object *internd;
1315 php_imagick_object *intern;
1316 zval *magick_obj;
1317 im_long compose;
1318 double x, y, width, height;
1319 MagickBooleanType status;
1320
1321 /* Parse parameters given to function */
1322 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "lddddO", &compose, &x, &y, &width, &height, &magick_obj, php_imagick_sc_entry) == FAILURE) {
1323 return;
1324 }
1325
1326 intern = Z_IMAGICK_P(magick_obj);
1327
1328 if (php_imagick_ensure_not_empty (intern->magick_wand) == 0)
1329 return;
1330
1331 internd = Z_IMAGICKDRAW_P(getThis());
1332 status = DrawComposite(internd->drawing_wand, compose, x, y, width, height, intern->magick_wand);
1333
1334 if (status == MagickFalse) {
1335 php_imagick_convert_imagickdraw_exception (internd->drawing_wand, "Compositing image failed" TSRMLS_CC);
1336 return;
1337 }
1338
1339 RETURN_TRUE;
1340 }
1341 /* }}} */
1342
1343 /* {{{ proto bool ImagickDraw::color(float x, float y, int paintMethod)
1344 Draws color on image using the current fill color, starting at specified position, and using specified paint method. The available paint methods are:
1345 */
1346 PHP_METHOD(ImagickDraw, color)
1347 {
1348 php_imagickdraw_object *internd;
1349 double x, y;
1350 im_long paint_method;
1351
1352 /* Parse parameters given to function */
1353 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ddl", &x, &y, &paint_method) == FAILURE) {
1354 return;
1355 }
1356
1357 internd = Z_IMAGICKDRAW_P(getThis());
1358
1359 DrawColor(internd->drawing_wand, x, y, paint_method);
1360 RETURN_TRUE;
1361 }
1362 /* }}} */
1363
1364 /* {{{ proto bool ImagickDraw::comment(string comment)
1365 Adds a comment to a vector output stream.
1366 */
1367 PHP_METHOD(ImagickDraw, comment)
1368 {
1369 php_imagickdraw_object *internd;
1370 char *comment;
1371 IM_LEN_TYPE comment_len;
1372
1373 /* Parse parameters given to function */
1374 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &comment, &comment_len) == FAILURE) {
1375 return;
1376 }
1377
1378 internd = Z_IMAGICKDRAW_P(getThis());
1379
1380 DrawComment(internd->drawing_wand, comment);
1381 RETURN_TRUE;
1382 }
1383 /* }}} */
1384
1385 /* {{{ proto string ImagickDraw::getClipPath()
1386 Obtains the current clipping path ID. The value returned must be deallocated by the user when it is no longer needed.
1387 */
1388 PHP_METHOD(ImagickDraw, getClipPath)
1389 {
1390 php_imagickdraw_object *internd;
1391 char *clip_path;
1392
1393 if (zend_parse_parameters_none() == FAILURE) {
1394 return;
1395 }
1396
1397 internd = Z_IMAGICKDRAW_P(getThis());;
1398 clip_path = DrawGetClipPath(internd->drawing_wand);
1399
1400 if (!clip_path) {
1401 RETURN_FALSE;
1402 } else {
1403 IM_ZVAL_STRING(return_value, clip_path);
1404 IMAGICK_FREE_MAGICK_MEMORY(clip_path);
1405 return;
1406 }
1407 }
1408 /* }}} */
1409
1410 /* {{{ proto int ImagickDraw::getClipRule()
1411 Returns the current polygon fill rule to be used by the clipping path.
1412 */
1413 PHP_METHOD(ImagickDraw, getClipRule)
1414 {
1415 php_imagickdraw_object *internd;
1416 long clip_rule;
1417
1418 if (zend_parse_parameters_none() == FAILURE) {
1419 return;
1420 }
1421
1422 internd = Z_IMAGICKDRAW_P(getThis());;
1423 clip_rule = DrawGetClipRule(internd->drawing_wand);
1424
1425 RETVAL_LONG(clip_rule);
1426 }
1427 /* }}} */
1428
1429 /* {{{ proto int ImagickDraw::getClipUnits()
1430 Returns the interpretation of clip path units.
1431 */
1432 PHP_METHOD(ImagickDraw, getClipUnits)
1433 {
1434 php_imagickdraw_object *internd;
1435 long units;
1436
1437 if (zend_parse_parameters_none() == FAILURE) {
1438 return;
1439 }
1440
1441 internd = Z_IMAGICKDRAW_P(getThis());;
1442 units = DrawGetClipUnits(internd->drawing_wand);
1443
1444 RETVAL_LONG(units);
1445 }
1446 /* }}} */
1447
1448 /* {{{ proto ImagickPixel ImagickDraw::getFillColor()
1449 Returns the fill color used for drawing filled objects.
1450 */
1451 PHP_METHOD(ImagickDraw, getFillColor)
1452 {
1453 php_imagickpixel_object *internp;
1454 php_imagickdraw_object *internd;
1455 PixelWand *tmp_wand;
1456
1457 if (zend_parse_parameters_none() == FAILURE) {
1458 return;
1459 }
1460
1461 internd = Z_IMAGICKDRAW_P(getThis());;
1462
1463 tmp_wand = NewPixelWand();
1464 DrawGetFillColor(internd->drawing_wand, tmp_wand);
1465
1466 object_init_ex(return_value, php_imagickpixel_sc_entry);
1467 internp = Z_IMAGICKPIXEL_P(return_value);
1468 php_imagick_replace_pixelwand(internp, tmp_wand);
1469
1470 return;
1471 }
1472 /* }}} */
1473
1474 /* {{{ proto float ImagickDraw::getFillOpacity()
1475 Returns the opacity used when drawing using the fill color or fill texture. Fully opaque is 1.0.
1476 */
1477 PHP_METHOD(ImagickDraw, getFillOpacity)
1478 {
1479 php_imagickdraw_object *internd;
1480 double opacity;
1481
1482 if (zend_parse_parameters_none() == FAILURE) {
1483 return;
1484 }
1485
1486 internd = Z_IMAGICKDRAW_P(getThis());;
1487 opacity = DrawGetFillOpacity(internd->drawing_wand);
1488
1489 RETVAL_DOUBLE(opacity);
1490 }
1491 /* }}} */
1492
1493 /* {{{ proto int ImagickDraw::getFillRule(const DrawingWand *wand)
1494 Returns the fill rule used while drawing polygons.
1495 */
1496 PHP_METHOD(ImagickDraw, getFillRule)
1497 {
1498 php_imagickdraw_object *internd;
1499 long fill_rule;
1500
1501 if (zend_parse_parameters_none() == FAILURE) {
1502 return;
1503 }
1504
1505 internd = Z_IMAGICKDRAW_P(getThis());;
1506 fill_rule = DrawGetFillRule(internd->drawing_wand);
1507
1508 RETVAL_LONG(fill_rule);
1509 }
1510 /* }}} */
1511
1512 /* {{{ proto int ImagickDraw::getGravity()
1513 Returns the text placement gravity used when annotating with text.
1514 */
1515 PHP_METHOD(ImagickDraw, getGravity)
1516 {
1517 php_imagickdraw_object *internd;
1518 long gravity;
1519
1520 if (zend_parse_parameters_none() == FAILURE) {
1521 return;
1522 }
1523
1524 internd = Z_IMAGICKDRAW_P(getThis());;
1525 gravity = DrawGetGravity(internd->drawing_wand);
1526
1527 RETVAL_LONG(gravity);
1528 }
1529 /* }}} */
1530
1531 /* {{{ proto bool ImagickDraw::getStrokeAntialias()
1532 Returns the current stroke antialias setting. Stroked outlines are antialiased by default. When antialiasing is disabled stroked pixels are thresholded to determine if the stroke color or underlying canvas color should be used.
1533 */
1534 PHP_METHOD(ImagickDraw, getStrokeAntialias)
1535 {
1536 php_imagickdraw_object *internd;
1537 MagickBooleanType status;
1538
1539 if (zend_parse_parameters_none() == FAILURE) {
1540 return;
1541 }
1542
1543 internd = Z_IMAGICKDRAW_P(getThis());;
1544 status = DrawGetStrokeAntialias(internd->drawing_wand);
1545
1546 if (status == MagickFalse) {
1547 RETURN_FALSE;
1548 } else {
1549 RETURN_TRUE;
1550 }
1551 }
1552 /* }}} */
1553
1554 /* {{{ proto ImagickPixel ImagickDraw::getStrokeColor(PixelWand stroke_color)
1555 Returns the color used for stroking object outlines.
1556 */
1557 PHP_METHOD(ImagickDraw, getStrokeColor)
1558 {
1559 php_imagickpixel_object *internp;
1560 php_imagickdraw_object *internd;
1561 PixelWand *tmp_wand;
1562
1563 if (zend_parse_parameters_none() == FAILURE) {
1564 return;
1565 }
1566
1567 internd = Z_IMAGICKDRAW_P(getThis());;
1568
1569 tmp_wand = NewPixelWand();
1570 DrawGetStrokeColor(internd->drawing_wand, tmp_wand);
1571
1572 object_init_ex(return_value, php_imagickpixel_sc_entry);
1573 internp = Z_IMAGICKPIXEL_P(return_value);
1574 php_imagick_replace_pixelwand(internp, tmp_wand);
1575
1576 return;
1577 }
1578 /* }}} */
1579
1580 /* {{{ proto array ImagickDraw::getStrokeDashArray()
1581 Returns an array representing the pattern of dashes and gaps used to stroke paths (see DrawSetStrokeDashArray). The array must be freed once it is no longer required by the user.
1582 */
1583 PHP_METHOD(ImagickDraw, getStrokeDashArray)
1584 {
1585 php_imagickdraw_object *internd;
1586 double *stroke_array;
1587 unsigned long i;
1588 size_t num_elements;
1589
1590 if (zend_parse_parameters_none() == FAILURE) {
1591 return;
1592 }
1593
1594 internd = Z_IMAGICKDRAW_P(getThis());;
1595
1596 stroke_array = DrawGetStrokeDashArray(internd->drawing_wand, &num_elements);
1597 array_init(return_value);
1598
1599 for (i = 0; i < num_elements ; i++) {
1600 add_next_index_double(return_value, stroke_array[i]);
1601 }
1602
1603 IMAGICK_FREE_MAGICK_MEMORY(stroke_array);
1604 return;
1605 }
1606 /* }}} */
1607
1608 /* {{{ proto bool ImagickDraw::setStrokeDashArray(array dashArray)
1609 Specifies the pattern of dashes and gaps used to stroke paths. The strokeDashArray represents an array of numbers that specify the lengths of alternating dashes and gaps in pixels. If an odd number of values is provided, then the list of values is repeated to yield an even number of values. To remove an existing dash array, pass a zero number_elements argument and null dash_array. A typical strokeDashArray_ array might contain the members 5 3 2.
1610 */
1611 PHP_METHOD(ImagickDraw, setStrokeDashArray)
1612 {
1613 zval *param_array;
1614 double *double_array;
1615 im_long elements;
1616 php_imagickdraw_object *internd;
1617
1618 /* Parse parameters given to function */
1619 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", ¶m_array) == FAILURE) {
1620 return;
1621 }
1622
1623 double_array = php_imagick_zval_to_double_array(param_array, &elements TSRMLS_CC);
1624
1625 if (!double_array) {
1626 php_imagick_throw_exception(IMAGICKDRAW_CLASS, "Cannot read stroke dash array parameter" TSRMLS_CC);
1627 return;
1628 }
1629
1630 internd = Z_IMAGICKDRAW_P(getThis());
1631
1632 DrawSetStrokeDashArray(internd->drawing_wand, elements, double_array);
1633 efree(double_array);
1634
1635 RETURN_TRUE;
1636 }
1637 /* }}} */
1638
1639 /* {{{ proto float ImagickDraw::getStrokeDashOffset()
1640 Returns the offset into the dash pattern to start the dash.
1641 */
1642 PHP_METHOD(ImagickDraw, getStrokeDashOffset)
1643 {
1644 php_imagickdraw_object *internd;
1645 double offset;
1646
1647 if (zend_parse_parameters_none() == FAILURE) {
1648 return;
1649 }
1650
1651 internd = Z_IMAGICKDRAW_P(getThis());;
1652 offset = DrawGetStrokeDashOffset(internd->drawing_wand);
1653
1654 RETVAL_DOUBLE(offset);
1655 }
1656 /* }}} */
1657
1658 /* {{{ proto int ImagickDraw::getStrokeLineCap()
1659 Returns the shape to be used at the end of open subpaths when they are stroked. Values of LineCap are UndefinedCap, ButtCap, RoundCap, and SquareCap.
1660 */
1661 PHP_METHOD(ImagickDraw, getStrokeLineCap)
1662 {
1663 php_imagickdraw_object *internd;
1664 long line_cap;
1665
1666 if (zend_parse_parameters_none() == FAILURE) {
1667 return;
1668 }
1669
1670 internd = Z_IMAGICKDRAW_P(getThis());;
1671 line_cap = DrawGetStrokeLineCap(internd->drawing_wand);
1672
1673 RETVAL_LONG(line_cap);
1674 }
1675 /* }}} */
1676
1677 /* {{{ proto int ImagickDraw::getStrokeLineJoin()
1678 Returns the shape to be used at the corners of paths (or other vector shapes) when they are stroked. Values of LineJoin are UndefinedJoin, MiterJoin, RoundJoin, and BevelJoin.
1679 */
1680 PHP_METHOD(ImagickDraw, getStrokeLineJoin)
1681 {
1682 php_imagickdraw_object *internd;
1683 long line_join;
1684
1685 if (zend_parse_parameters_none() == FAILURE) {
1686 return;
1687 }
1688
1689 internd = Z_IMAGICKDRAW_P(getThis());;
1690 line_join = DrawGetStrokeLineJoin(internd->drawing_wand);
1691
1692 RETVAL_LONG(line_join);
1693 }
1694 /* }}} */
1695
1696 /* {{{ proto int ImagickDraw::getStrokeMiterLimit()
1697 Returns the miter limit. When two line segments meet at a sharp angle and miter joins have been specified for 'lineJoin', it is possible for the miter to extend far beyond the thickness of the line stroking the path. The miterLimit' imposes a limit on the ratio of the miter length to the 'lineWidth'.
1698 */
1699 PHP_METHOD(ImagickDraw, getStrokeMiterLimit)
1700 {
1701 php_imagickdraw_object *internd;
1702 unsigned long miter_limit;
1703
1704 if (zend_parse_parameters_none() == FAILURE) {
1705 return;
1706 }
1707
1708 internd = Z_IMAGICKDRAW_P(getThis());;
1709 miter_limit = DrawGetStrokeMiterLimit(internd->drawing_wand);
1710
1711 RETVAL_LONG(miter_limit);
1712 }
1713 /* }}} */
1714
1715 /* {{{ proto float ImagickDraw::getStrokeOpacity()
1716 Returns the opacity of stroked object outlines.
1717 */
1718 PHP_METHOD(ImagickDraw, getStrokeOpacity)
1719 {
1720 php_imagickdraw_object *internd;
1721 double opacity;
1722
1723 if (zend_parse_parameters_none() == FAILURE) {
1724 return;
1725 }
1726
1727 internd = Z_IMAGICKDRAW_P(getThis());;
1728 opacity = DrawGetStrokeOpacity(internd->drawing_wand);
1729
1730 RETVAL_DOUBLE(opacity);
1731 }
1732 /* }}} */
1733
1734 /* {{{ proto float ImagickDraw::getStrokeWidth()
1735 Returns the width of the stroke used to draw object outlines.
1736 */
1737 PHP_METHOD(ImagickDraw, getStrokeWidth)
1738 {
1739 php_imagickdraw_object *internd;
1740 double width;
1741
1742 if (zend_parse_parameters_none() == FAILURE) {
1743 return;
1744 }
1745
1746 internd = Z_IMAGICKDRAW_P(getThis());;
1747 width = DrawGetStrokeWidth(internd->drawing_wand);
1748
1749 RETVAL_DOUBLE(width);
1750 }
1751 /* }}} */
1752
1753 /* {{{ proto int ImagickDraw::getTextAlignment()
1754 Returns the alignment applied when annotating with text.
1755 */
1756 PHP_METHOD(ImagickDraw, getTextAlignment)
1757 {
1758 php_imagickdraw_object *internd;
1759 long align_type;
1760
1761 if (zend_parse_parameters_none() == FAILURE) {
1762 return;
1763 }
1764
1765 internd = Z_IMAGICKDRAW_P(getThis());;
1766 align_type = DrawGetTextAlignment(internd->drawing_wand);
1767
1768 RETVAL_LONG(align_type);
1769 }
1770 /* }}} */
1771
1772 /* {{{ proto bool ImagickDraw::getTextAntialias()
1773 Returns the current text antialias setting, which determines whether text is antialiased. Text is antialiased by default.
1774 */
1775 PHP_METHOD(ImagickDraw, getTextAntialias)
1776 {
1777 php_imagickdraw_object *internd;
1778 MagickBooleanType status;
1779
1780 if (zend_parse_parameters_none() == FAILURE) {
1781 return;
1782 }
1783
1784 internd = Z_IMAGICKDRAW_P(getThis());;
1785 status = DrawGetTextAntialias(internd->drawing_wand);
1786
1787 if (status == MagickFalse) {
1788 RETURN_FALSE;
1789 } else {
1790 RETURN_TRUE;
1791 }
1792 }
1793 /* }}} */
1794
1795 /* {{{ proto string ImagickDraw::getVectorGraphics()
1796 Returns a null-terminated string which specifies the vector graphics generated by any graphics calls made since the wand was instantiated. The string must be freed by the user once it is no longer required.
1797 */
1798 PHP_METHOD(ImagickDraw, getVectorGraphics)
1799 {
1800 php_imagickdraw_object *internd;
1801 char *vector;
1802
1803 if (zend_parse_parameters_none() == FAILURE) {
1804 return;
1805 }
1806
1807 internd = Z_IMAGICKDRAW_P(getThis());;
1808 vector = DrawGetVectorGraphics(internd->drawing_wand);
1809
1810 IM_ZVAL_STRING(return_value, vector);
1811 IMAGICK_FREE_MAGICK_MEMORY(vector);
1812
1813 return;
1814 }
1815 /* }}} */
1816
1817 /* {{{ proto ImagickPixel ImagickDraw::getTextUnderColor(PixelWand under_color)
1818 Returns the color of a background rectangle to place under text annotations.
1819 */
1820 PHP_METHOD(ImagickDraw, getTextUnderColor)
1821 {
1822 php_imagickpixel_object *internp;
1823 php_imagickdraw_object *internd;
1824 PixelWand *tmp_wand;
1825
1826 if (zend_parse_parameters_none() == FAILURE) {
1827 return;
1828 }
1829
1830 internd = Z_IMAGICKDRAW_P(getThis());;
1831 tmp_wand = NewPixelWand();
1832
1833 if (!tmp_wand) {
1834 php_imagick_throw_exception(IMAGICKDRAW_CLASS, "Failed to allocate space for new PixelWand" TSRMLS_CC);
1835 return;
1836 }
1837
1838 DrawGetTextUnderColor(internd->drawing_wand, tmp_wand);
1839
1840 object_init_ex(return_value, php_imagickpixel_sc_entry);
1841 internp = Z_IMAGICKPIXEL_P(return_value);
1842 php_imagick_replace_pixelwand(internp, tmp_wand);
1843
1844 return;
1845 }
1846 /* }}} */
1847
1848 /* {{{ proto bool ImagickDraw::pathClose()
1849 Adds a path element to the current path which closes the current subpath by drawing a straight line from the current point to the current subpath's most recent starting point (usually, the most recent moveto point).
1850 */
1851 PHP_METHOD(ImagickDraw, pathClose)
1852 {
1853 php_imagickdraw_object *internd;
1854
1855 if (zend_parse_parameters_none() == FAILURE) {
1856 return;
1857 }
1858
1859 internd = Z_IMAGICKDRAW_P(getThis());;
1860 DrawPathClose(internd->drawing_wand);
1861 RETURN_TRUE;
1862 }
1863 /* }}} */
1864
1865 /* {{{ proto bool ImagickDraw::pathCurveToAbsolute(float x1, float y1, float x2, float y2, float x, float y)
1866 Draws a cubic Bezier curve from the current point to (x,y) using (x1,y1) as the control point at the beginning of the curve and (x2,y2) as the control point at the end of the curve using absolute coordinates. At the end of the command, the new current point becomes the final (x,y) coordinate pair used in the polybezier.
1867 */
1868 PHP_METHOD(ImagickDraw, pathCurveToAbsolute)
1869 {
1870 php_imagickdraw_object *internd;
1871 double x1, y1, x2, y2, x, y;
1872
1873 /* Parse parameters given to function */
1874 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "dddddd", &x1, &y1, &x2, &y2, &x, &y) == FAILURE) {
1875 return;
1876 }
1877
1878 internd = Z_IMAGICKDRAW_P(getThis());
1879
1880 DrawPathCurveToAbsolute(internd->drawing_wand, x1, y1, x2, y2, x, y);
1881 RETURN_TRUE;
1882 }
1883 /* }}} */
1884
1885 /* {{{ proto bool ImagickDraw::pathCurveToRelative(float x1, float y1, float x2, float y2, float x, float y)
1886 Draws a cubic Bezier curve from the current point to (x,y) using (x1,y1) as the control point at the beginning of the curve and (x2,y2) as the control point at the end of the curve using relative coordinates. At the end of the command, the new current point becomes the final (x,y) coordinate pair used in the polybezier.
1887 */
1888 PHP_METHOD(ImagickDraw, pathCurveToRelative)
1889 {
1890 php_imagickdraw_object *internd;
1891 double x1, y1, x2, y2, x, y;
1892
1893 /* Parse parameters given to function */
1894 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "dddddd", &x1, &y1, &x2, &y2, &x, &y) == FAILURE) {
1895 return;
1896 }
1897
1898 internd = Z_IMAGICKDRAW_P(getThis());
1899
1900 DrawPathCurveToRelative(internd->drawing_wand, x1, y1, x2, y2, x, y);
1901 RETURN_TRUE;
1902 }
1903 /* }}} */
1904
1905 /* {{{ proto bool ImagickDraw::pathCurveToQuadraticBezierAbsolute(float x1, float y1, float x, float y)
1906 Draws a quadratic Bezier curve from the current point to (x,y) using (x1,y1) as the control point using absolute coordinates. At the end of the command, the new current point becomes the final (x,y) coordinate pair used in the polybezier.
1907 */
1908 PHP_METHOD(ImagickDraw, pathCurveToQuadraticBezierAbsolute)
1909 {
1910 php_imagickdraw_object *internd;
1911 double x1, y1, x, y;
1912
1913 /* Parse parameters given to function */
1914 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "dddd", &x1, &y1, &x, &y) == FAILURE) {
1915 return;
1916 }
1917
1918 internd = Z_IMAGICKDRAW_P(getThis());
1919
1920 DrawPathCurveToQuadraticBezierAbsolute(internd->drawing_wand, x1, y1, x, y);
1921 RETURN_TRUE;
1922 }
1923 /* }}} */
1924
1925 /* {{{ proto bool ImagickDraw::pathCurveToQuadraticBezierRelative(float x1, float y1, float x, float y)
1926 Draws a quadratic Bezier curve from the current point to (x,y) using (x1,y1) as the control point using relative coordinates. At the end of the command, the new current point becomes the final (x,y) coordinate pair used in the polybezier.
1927 */
1928 PHP_METHOD(ImagickDraw, pathCurveToQuadraticBezierRelative)
1929 {
1930 php_imagickdraw_object *internd;
1931 double x1, y1, x, y;
1932
1933 /* Parse parameters given to function */
1934 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "dddd", &x1, &y1, &x, &y) == FAILURE) {
1935 return;
1936 }
1937
1938 internd = Z_IMAGICKDRAW_P(getThis());
1939
1940 DrawPathCurveToQuadraticBezierRelative(internd->drawing_wand, x1, y1, x, y);
1941 RETURN_TRUE;
1942 }
1943 /* }}} */
1944
1945 /* {{{ proto bool ImagickDraw::pathCurveToQuadraticBezierSmoothAbsolute(float x, float y)
1946 Draws a quadratic Bezier curve (using relative coordinates) from the current point to (x,y). The control point is assumed to be the reflection of the control point on the previous command relative to the current point. (If there is no previous command or if the previous command was not a DrawPathCurveToQuadraticBezierAbsolute, DrawPathCurveToQuadraticBezierRelative, DrawPathCurveToQuadraticBezierSmoothAbsolut or DrawPathCurveToQuadraticBezierSmoothRelative, assume the control point is coincident with the current point.). At the end of the command, the new current point becomes the final (x,y) coordinate pair used in the polybezier.
1947 */
1948 PHP_METHOD(ImagickDraw, pathCurveToQuadraticBezierSmoothAbsolute)
1949 {
1950 php_imagickdraw_object *internd;
1951 double x, y;
1952
1953 /* Parse parameters given to function */
1954 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "dd", &x, &y) == FAILURE) {
1955 return;
1956 }
1957
1958 internd = Z_IMAGICKDRAW_P(getThis());
1959
1960 DrawPathCurveToQuadraticBezierSmoothAbsolute(internd->drawing_wand, x, y);
1961 RETURN_TRUE;
1962 }
1963 /* }}} */
1964
1965 /* {{{ proto bool ImagickDraw::pathCurveToQuadraticBezierSmoothRelative(float x, float y)
1966 Draws a quadratic Bezier curve (using relative coordinates) from the current point to (x, y). The control point is assumed to be the reflection of the control point on the previous command relative to the current point. (If there is no previous command or if the previous command was not a DrawPathCurveToQuadraticBezierAbsolute, DrawPathCurveToQuadraticBezierRelative, DrawPathCurveToQuadraticBezierSmoothAbsolut or DrawPathCurveToQuadraticBezierSmoothRelative, assume the control point is coincident with the current point). At the end of the command, the new current point becomes the final (x, y) coordinate pair used in the polybezier.
1967 */
1968 PHP_METHOD(ImagickDraw, pathCurveToQuadraticBezierSmoothRelative)
1969 {
1970 php_imagickdraw_object *internd;
1971 double x, y;
1972
1973 /* Parse parameters given to function */
1974 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "dd", &x, &y) == FAILURE) {
1975 return;
1976 }
1977
1978 internd = Z_IMAGICKDRAW_P(getThis());
1979
1980 DrawPathCurveToQuadraticBezierSmoothRelative(internd->drawing_wand, x, y);
1981 RETURN_TRUE;
1982 }
1983 /* }}} */
1984
1985 /* {{{ proto bool ImagickDraw::pathCurveToSmoothAbsolute(float x2, float y2, float x, float y)
1986 Draws a cubic Bezier curve from the current point to (x,y) using absolute coordinates. The first control point is assumed to be the reflection of the second control point on the previous command relative to the current point. (If there is no previous command or if the previous command was not an DrawPathCurveToAbsolute, DrawPathCurveToRelative, DrawPathCurveToSmoothAbsolute or DrawPathCurveToSmoothRelative, assume the first control point is coincident with the current point.) (x2,y2) is the second control point (i.e., the control point at the end of the curve). At the end of the command, the new current point becomes the final (x,y) coordinate pair used in the polybezier.
1987 */
1988 PHP_METHOD(ImagickDraw, pathCurveToSmoothAbsolute)
1989 {
1990 php_imagickdraw_object *internd;
1991 double x1, y1, x, y;
1992
1993 /* Parse parameters given to function */
1994 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "dddd", &x1, &y1, &x, &y) == FAILURE) {
1995 return;
1996 }
1997
1998 internd = Z_IMAGICKDRAW_P(getThis());
1999
2000 DrawPathCurveToSmoothAbsolute(internd->drawing_wand, x1, y1, x, y);
2001 RETURN_TRUE;
2002 }
2003 /* }}} */
2004
2005 /* {{{ proto bool ImagickDraw::pathCurveToSmoothRelative(float x2, float y2, float x, float y)
2006 Draws a cubic Bezier curve from the current point to (x,y) using relative coordinates. The first control point is assumed to be the reflection of the second control point on the previous command relative to the current point. (If there is no previous command or if the previous command was not an DrawPathCurveToAbsolute, DrawPathCurveToRelative, DrawPathCurveToSmoothAbsolute or DrawPathCurveToSmoothRelative, assume the first control point is coincident with the current point.) (x2,y2) is the second control point (i.e., the control point at the end of the curve). At the end of the command, the new current point becomes the final (x,y) coordinate pair used in the polybezier.
2007 */
2008 PHP_METHOD(ImagickDraw, pathCurveToSmoothRelative)
2009 {
2010 php_imagickdraw_object *internd;
2011 double x1, y1, x, y;
2012
2013 /* Parse parameters given to function */
2014 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "dddd", &x1, &y1, &x, &y) == FAILURE) {
2015 return;
2016 }
2017
2018 internd = Z_IMAGICKDRAW_P(getThis());
2019
2020 DrawPathCurveToSmoothRelative(internd->drawing_wand, x1, y1, x, y);
2021 RETURN_TRUE;
2022 }
2023 /* }}} */
2024
2025 /* {{{ proto bool ImagickDraw::pathEllipticArcAbsolute(float rx, float ry, float x_axis_rotation, bool large_arc_flag, bool sweep_flag, float x, float y)
2026 Draws an elliptical arc from the current point to (x, y) using absolute coordinates. The size and orientation of the ellipse are defined by two radii (rx, ry) and an xAxisRotation, which indicates how the ellipse as a whole is rotated relative to the current coordinate system. The center (cx, cy) of the ellipse is calculated automatically to satisfy the constraints imposed by the other parameters. largeArcFlag and sweepFlag contribute to the automatic calculations and help determine how the arc is drawn. If largeArcFlag is true then draw the larger of the available arcs. If sweepFlag is true, then draw the arc matching a clock-wise rotation.
2027 */
2028 PHP_METHOD(ImagickDraw, pathEllipticArcAbsolute)
2029 {
2030 php_imagickdraw_object *internd;
2031 double rx, ry, x_axis_rotation, x, y;
2032 zend_bool large_arc, sweep;
2033
2034 /* Parse parameters given to function */
2035 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "dddbbdd", &rx, &ry, &x_axis_rotation, &large_arc, &sweep, &x, &y) == FAILURE) {
2036 return;
2037 }
2038
2039 internd = Z_IMAGICKDRAW_P(getThis());
2040 DrawPathEllipticArcAbsolute(internd->drawing_wand, rx, ry, x_axis_rotation, large_arc, sweep, x, y);
2041
2042 RETURN_TRUE;
2043 }
2044 /* }}} */
2045
2046 /* {{{ proto bool ImagickDraw::pathEllipticArcRelative(float rx, float ry, float x_axis_rotation, bool large_arc_flag, bool sweep_flag, float x, float y)
2047 Draws an elliptical arc from the current point to (x, y) using relative coordinates. The size and orientation of the ellipse are defined by two radii (rx, ry) and an xAxisRotation, which indicates how the ellipse as a whole is rotated relative to the current coordinate system. The center (cx, cy) of the ellipse is calculated automatically to satisfy the constraints imposed by the other parameters. largeArcFlag and sweepFlag contribute to the automatic calculations and help determine how the arc is drawn. If largeArcFlag is true then draw the larger of the available arcs. If sweepFlag is true, then draw the arc matching a clock-wise rotation.
2048 */
2049 PHP_METHOD(ImagickDraw, pathEllipticArcRelative)
2050 {
2051 php_imagickdraw_object *internd;
2052 double rx, ry, x_axis_rotation, x, y;
2053 zend_bool large_arc, sweep;
2054
2055 /* Parse parameters given to function */
2056 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "dddbbdd", &rx, &ry, &x_axis_rotation, &large_arc, &sweep, &x, &y) == FAILURE) {
2057 return;
2058 }
2059
2060 internd = Z_IMAGICKDRAW_P(getThis());
2061 DrawPathEllipticArcRelative(internd->drawing_wand, rx, ry, x_axis_rotation, large_arc, sweep, x, y);
2062
2063 RETURN_TRUE;
2064 }
2065 /* }}} */
2066
2067 /* {{{ proto bool ImagickDraw::pathFinish()
2068 Terminates the current path.
2069 */
2070 PHP_METHOD(ImagickDraw, pathFinish)
2071 {
2072 php_imagickdraw_object *internd;
2073
2074 if (zend_parse_parameters_none() == FAILURE) {
2075 return;
2076 }
2077
2078 internd = Z_IMAGICKDRAW_P(getThis());;
2079 DrawPathFinish(internd->drawing_wand);
2080 RETURN_TRUE;
2081 }
2082 /* }}} */
2083
2084 /* {{{ proto bool ImagickDraw::pathLineToAbsolute(float x, float y)
2085 Draws a line path from the current point to the given coordinate using absolute coordinates. The coordinate then becomes the new current point.
2086 */
2087 PHP_METHOD(ImagickDraw, pathLineToAbsolute)
2088 {
2089 php_imagickdraw_object *internd;
2090 double x, y;
2091
2092 /* Parse parameters given to function */
2093 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "dd", &x, &y) == FAILURE) {
2094 return;
2095 }
2096
2097 internd = Z_IMAGICKDRAW_P(getThis());
2098
2099 DrawPathLineToAbsolute(internd->drawing_wand, x, y);
2100 RETURN_TRUE;
2101 }
2102 /* }}} */
2103
2104 /* {{{ proto bool ImagickDraw::pathLineToRelative(float x, float y)
2105 Draws a line path from the current point to the given coordinate using relative coordinates. The coordinate then becomes the new current point.
2106 */
2107 PHP_METHOD(ImagickDraw, pathLineToRelative)
2108 {
2109 php_imagickdraw_object *internd;
2110 double x, y;
2111
2112 /* Parse parameters given to function */
2113 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "dd", &x, &y) == FAILURE) {
2114 return;
2115 }
2116
2117 internd = Z_IMAGICKDRAW_P(getThis());
2118
2119 DrawPathLineToRelative(internd->drawing_wand, x, y);
2120 RETURN_TRUE;
2121 }
2122 /* }}} */
2123
2124 /* {{{ proto bool ImagickDraw::pathLineToHorizontalAbsolute(float x)
2125 Draws a horizontal line path from the current point to the target point using absolute coordinates. The target point then becomes the new current point.
2126 */
2127 PHP_METHOD(ImagickDraw, pathLineToHorizontalAbsolute)
2128 {
2129 php_imagickdraw_object *internd;
2130 double y;
2131
2132 /* Parse parameters given to function */
2133 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &y) == FAILURE) {
2134 return;
2135 }
2136
2137 internd = Z_IMAGICKDRAW_P(getThis());
2138
2139 DrawPathLineToHorizontalAbsolute(internd->drawing_wand, y);
2140 RETURN_TRUE;
2141 }
2142 /* }}} */
2143
2144 /* {{{ proto bool ImagickDraw::pathLineToHorizontalRelative(float x)
2145 Draws a horizontal line path from the current point to the target point using relative coordinates. The target point then becomes the new current point.
2146 */
2147 PHP_METHOD(ImagickDraw, pathLineToHorizontalRelative)
2148 {
2149 php_imagickdraw_object *internd;
2150 double x;
2151
2152 /* Parse parameters given to function */
2153 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &x) == FAILURE) {
2154 return;
2155 }
2156
2157 internd = Z_IMAGICKDRAW_P(getThis());
2158
2159 DrawPathLineToHorizontalRelative(internd->drawing_wand, x);
2160 RETURN_TRUE;
2161 }
2162 /* }}} */
2163
2164 /* {{{ proto bool ImagickDraw::pathLineToVerticalAbsolute(float y)
2165 Draws a vertical line path from the current point to the target point using absolute coordinates. The target point then becomes the new current point.
2166 */
2167 PHP_METHOD(ImagickDraw, pathLineToVerticalAbsolute)
2168 {
2169 php_imagickdraw_object *internd;
2170 double y;
2171
2172 /* Parse parameters given to function */
2173 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &y) == FAILURE) {
2174 return;
2175 }
2176
2177 internd = Z_IMAGICKDRAW_P(getThis());
2178
2179 DrawPathLineToVerticalAbsolute(internd->drawing_wand, y);
2180 RETURN_TRUE;
2181 }
2182 /* }}} */
2183
2184 /* {{{ proto bool ImagickDraw::pathLineToVerticalRelative(float y)
2185 Draws a vertical line path from the current point to the target point using relative coordinates. The target point then becomes the new current point.
2186 */
2187 PHP_METHOD(ImagickDraw, pathLineToVerticalRelative)
2188 {
2189 php_imagickdraw_object *internd;
2190 double y;
2191
2192 /* Parse parameters given to function */
2193 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &y) == FAILURE) {
2194 return;
2195 }
2196
2197 internd = Z_IMAGICKDRAW_P(getThis());
2198
2199 DrawPathLineToVerticalRelative(internd->drawing_wand, y);
2200 RETURN_TRUE;
2201 }
2202 /* }}} */
2203
2204 /* {{{ proto bool ImagickDraw::pathMoveToAbsolute(float x, float y)
2205 Starts a new sub-path at the given coordinate using absolute coordinates. The current point then becomes the specified coordinate.
2206 */
2207 PHP_METHOD(ImagickDraw, pathMoveToAbsolute)
2208 {
2209 php_imagickdraw_object *internd;
2210 double x, y;
2211
2212 /* Parse parameters given to function */
2213 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "dd", &x, &y) == FAILURE) {
2214 return;
2215 }
2216
2217 internd = Z_IMAGICKDRAW_P(getThis());
2218
2219 DrawPathMoveToAbsolute(internd->drawing_wand, x, y);
2220 RETURN_TRUE;
2221 }
2222 /* }}} */
2223
2224 /* {{{ proto bool ImagickDraw::pathMoveToRelative(float x, float y)
2225 Starts a new sub-path at the given coordinate using relative coordinates. The current point then becomes the specified coordinate.
2226 */
2227 PHP_METHOD(ImagickDraw, pathMoveToRelative)
2228 {
2229 php_imagickdraw_object *internd;
2230 double x, y;
2231
2232 /* Parse parameters given to function */
2233 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "dd", &x, &y) == FAILURE) {
2234 return;
2235 }
2236
2237 internd = Z_IMAGICKDRAW_P(getThis());
2238
2239 DrawPathMoveToRelative(internd->drawing_wand, x, y);
2240 RETURN_TRUE;
2241 }
2242 /* }}} */
2243
2244 /* {{{ proto bool ImagickDraw::pathStart()
2245 Declares the start of a path drawing list which is terminated by a matching DrawPathFinish() command. All other DrawPath commands must be enclosed between a and a DrawPathFinish() command. This is because path drawing commands are subordinate commands and they do not function by themselves.
2246 */
2247 PHP_METHOD(ImagickDraw, pathStart)
2248 {
2249 php_imagickdraw_object *internd;
2250
2251 if (zend_parse_parameters_none() == FAILURE) {
2252 return;
2253 }
2254
2255 internd = Z_IMAGICKDRAW_P(getThis());;
2256 DrawPathStart(internd->drawing_wand);
2257 RETURN_TRUE;
2258 }
2259 /* }}} */
2260
2261 /* {{{ proto bool ImagickDraw::polyline(array coordinates)
2262 Draws a polyline using the current stroke, stroke width, and fill color or texture, using the specified array of coordinates.
2263 */
2264 PHP_METHOD(ImagickDraw, polyline)
2265 {
2266 zval *coordinate_array;
2267 php_imagickdraw_object *internd;
2268 PointInfo *coordinates;
2269 int num_elements = 0;
2270
2271 /* Parse parameters given to function */
2272 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "a", &coordinate_array) == FAILURE) {
2273 return;
2274 }
2275
2276 coordinates = php_imagick_zval_to_pointinfo_array(coordinate_array, &num_elements TSRMLS_CC);
2277
2278 if (!coordinates) {
2279 php_imagick_throw_exception(IMAGICKDRAW_CLASS, "Unable to read coordinate array" TSRMLS_CC);
2280 return;
2281 }
2282
2283 internd = Z_IMAGICKDRAW_P(getThis());;
2284 DrawPolyline(internd->drawing_wand, num_elements, coordinates);
2285
2286 efree(coordinates);
2287 RETURN_TRUE;
2288
2289 }
2290 /* }}} */
2291
2292 /* {{{ proto bool ImagickDraw::popClipPath()
2293 Terminates a clip path definition.
2294 */
2295 PHP_METHOD(ImagickDraw, popClipPath)
2296 {
2297 php_imagickdraw_object *internd;
2298
2299 if (zend_parse_parameters_none() == FAILURE) {
2300 return;
2301 }
2302
2303 internd = Z_IMAGICKDRAW_P(getThis());;
2304 DrawPopClipPath(internd->drawing_wand);
2305 RETURN_TRUE;
2306 }
2307 /* }}} */
2308
2309 /* {{{ proto bool ImagickDraw::popDefs()
2310 Terminates a definition list
2311 */
2312 PHP_METHOD(ImagickDraw, popDefs)
2313 {
2314 php_imagickdraw_object *internd;
2315
2316 if (zend_parse_parameters_none() == FAILURE) {
2317 return;
2318 }
2319
2320 internd = Z_IMAGICKDRAW_P(getThis());;
2321 DrawPopDefs(internd->drawing_wand);
2322 RETURN_TRUE;
2323 }
2324 /* }}} */
2325
2326 /* {{{ proto bool ImagickDraw::popPattern()
2327 Terminates a pattern definition.
2328 */
2329 PHP_METHOD(ImagickDraw, popPattern)
2330 {
2331 php_imagickdraw_object *internd;
2332 MagickBooleanType status;
2333
2334 if (zend_parse_parameters_none() == FAILURE) {
2335 return;
2336 }
2337 internd = Z_IMAGICKDRAW_P(getThis());;
2338 status = DrawPopPattern(internd->drawing_wand);
2339
2340 if (status == MagickFalse) {
2341 php_imagick_convert_imagickdraw_exception (internd->drawing_wand, "Unable to terminate the pattern definition" TSRMLS_CC);
2342 return;
2343 }
2344 RETURN_TRUE;
2345 }
2346 /* }}} */
2347
2348 /* {{{ proto bool ImagickDraw::pushClipPath(string clip_mask_id)
2349 Starts a clip path definition which is comprized of any number of drawing commands and terminated by a DrawPopClipPath() command.
2350 */
2351 PHP_METHOD(ImagickDraw, pushClipPath)
2352 {
2353 php_imagickdraw_object *internd;
2354 char *clip_mask;
2355 IM_LEN_TYPE clip_mask_len;
2356
2357 /* Parse parameters given to function */
2358 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &clip_mask, &clip_mask_len) == FAILURE) {
2359 return;
2360 }
2361
2362 internd = Z_IMAGICKDRAW_P(getThis());
2363
2364 DrawPushClipPath(internd->drawing_wand, clip_mask);
2365 RETURN_TRUE;
2366 }
2367 /* }}} */
2368
2369 /* {{{ proto bool ImagickDraw::pushDefs()
2370 Indicates that commands up to a terminating DrawPopDefs() command create named elements (e.g. clip-paths, textures, etc.) which may safely be processed earlier for the sake of efficiency.
2371 */
2372 PHP_METHOD(ImagickDraw, pushDefs)
2373 {
2374 php_imagickdraw_object *internd;
2375
2376 if (zend_parse_parameters_none() == FAILURE) {
2377 return;
2378 }
2379
2380 internd = Z_IMAGICKDRAW_P(getThis());;
2381 DrawPushDefs(internd->drawing_wand);
2382 RETURN_TRUE;
2383 }
2384 /* }}} */
2385
2386 /* {{{ proto bool ImagickDraw::pushPattern(string pattern_id, float x, float y, float width, float height)
2387 Indicates that subsequent commands up to a DrawPopPattern() command comprise the definition of a named pattern. The pattern space is assigned top left corner coordinates, a width and height, and becomes its own drawing space. Anything which can be drawn may be used in a pattern definition. Named patterns may be used as stroke or brush definitions.
2388 */
2389 PHP_METHOD(ImagickDraw, pushPattern)
2390 {
2391 php_imagickdraw_object *internd;
2392 char *pattern_id;
2393 IM_LEN_TYPE pattern_id_len;
2394 double x, y, width, height;
2395
2396 /* Parse parameters given to function */
2397 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sdddd", &pattern_id, &pattern_id_len, &x, &y, &width, &height) == FAILURE) {
2398 return;
2399 }
2400
2401 internd = Z_IMAGICKDRAW_P(getThis());
2402
2403 DrawPushPattern(internd->drawing_wand, pattern_id, x, y, width, height);
2404 RETURN_TRUE;
2405 }
2406 /* }}} */
2407
2408 /* {{{ proto bool ImagickDraw::render()
2409 Renders all preceding drawing commands.
2410 */
2411 PHP_METHOD(ImagickDraw, render)
2412 {
2413 php_imagickdraw_object *internd;
2414 MagickBooleanType status;
2415 char *old_locale;
2416
2417 if (zend_parse_parameters_none() == FAILURE) {
2418 return;
2419 }
2420
2421 internd = Z_IMAGICKDRAW_P(getThis());;
2422
2423 old_locale = php_imagick_set_locale (TSRMLS_C);
2424
2425 status = DrawRender(internd->drawing_wand);
2426
2427 php_imagick_restore_locale (old_locale);
2428
2429 if (old_locale)
2430 efree (old_locale);
2431
2432 if (status == MagickFalse) {
2433 php_imagick_convert_imagickdraw_exception (internd->drawing_wand, "Unable to render the drawing commands" TSRMLS_CC);
2434 return;
2435 }
2436 RETURN_TRUE;
2437 }
2438 /* }}} */
2439
2440 /* {{{ proto bool ImagickDraw::rotate(float degrees)
2441 Applies the specified rotation to the current coordinate space.
2442 */
2443 PHP_METHOD(ImagickDraw, rotate)
2444 {
2445 php_imagickdraw_object *internd;
2446 double degrees;
2447
2448 /* Parse parameters given to function */
2449 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", °rees) == FAILURE) {
2450 return;
2451 }
2452
2453 internd = Z_IMAGICKDRAW_P(getThis());
2454
2455 DrawRotate(internd->drawing_wand, degrees);
2456 RETURN_TRUE;
2457 }
2458 /* }}} */
2459
2460 /* {{{ proto bool ImagickDraw::scale(float x, float y)
2461 Adjusts the scaling factor to apply in the horizontal and vertical directions to the current coordinate space.
2462 */
2463 PHP_METHOD(ImagickDraw, scale)
2464 {
2465 php_imagickdraw_object *internd;
2466 double x, y;
2467
2468 /* Parse parameters given to function */
2469 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "dd", &x, &y) == FAILURE) {
2470 return;
2471 }
2472
2473 internd = Z_IMAGICKDRAW_P(getThis());
2474
2475 DrawScale(internd->drawing_wand, x, y);
2476 RETURN_TRUE;
2477 }
2478 /* }}} */
2479
2480 /* {{{ proto bool ImagickDraw::setClipPath(string clip_mask)
2481 Associates a named clipping path with the image. Only the areas drawn on by the clipping path will be modified as long as it remains in effect.
2482 */
2483 PHP_METHOD(ImagickDraw, setClipPath)
2484 {
2485 php_imagickdraw_object *internd;
2486 char *clip_mask;
2487 IM_LEN_TYPE clip_mask_len;
2488 MagickBooleanType status;
2489
2490 /* Parse parameters given to function */
2491 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &clip_mask, &clip_mask_len) == FAILURE) {
2492 return;
2493 }
2494
2495 internd = Z_IMAGICKDRAW_P(getThis());
2496 status = DrawSetClipPath(internd->drawing_wand, clip_mask);
2497
2498 if (status == MagickFalse) {
2499 php_imagick_convert_imagickdraw_exception (internd->drawing_wand, "Unable to set clipping path" TSRMLS_CC);
2500 return;
2501 }
2502 RETURN_TRUE;
2503 }
2504 /* }}} */
2505
2506 /* {{{ proto bool ImagickDraw::setClipRule(int fill_rule)
2507 Set the polygon fill rule to be used by the clipping path.
2508 */
2509 PHP_METHOD(ImagickDraw, setClipRule)
2510 {
2511 php_imagickdraw_object *internd;
2512 im_long fill_rule;
2513
2514 /* Parse parameters given to function */
2515 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &fill_rule) == FAILURE) {
2516 return;
2517 }
2518
2519 internd = Z_IMAGICKDRAW_P(getThis());
2520
2521 DrawSetClipRule(internd->drawing_wand, fill_rule);
2522 RETURN_TRUE;
2523 }
2524 /* }}} */
2525
2526 /* {{{ proto bool ImagickDraw::setClipUnits(int clip_units)
2527 Sets the interpretation of clip path units.
2528 */
2529 PHP_METHOD(ImagickDraw, setClipUnits)
2530 {
2531 php_imagickdraw_object *internd;
2532 im_long units;
2533
2534 /* Parse parameters given to function */
2535 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &units) == FAILURE) {
2536 return;
2537 }
2538
2539 internd = Z_IMAGICKDRAW_P(getThis());
2540
2541 DrawSetClipUnits(internd->drawing_wand, units);
2542 RETURN_TRUE;
2543 }
2544 /* }}} */
2545
2546 /* {{{ proto bool ImagickDraw::setFillOpacity(float fillOpacity)
2547 Sets the opacity to use when drawing using the fill color or fill texture. Fully opaque is 1.0.
2548 */
2549 PHP_METHOD(ImagickDraw, setFillOpacity)
2550 {
2551 php_imagickdraw_object *internd;
2552 double fillOpacity;
2553
2554 /* Parse parameters given to function */
2555 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &fillOpacity) == FAILURE) {
2556 return;
2557 }
2558
2559 internd = Z_IMAGICKDRAW_P(getThis());
2560
2561 DrawSetFillOpacity(internd->drawing_wand, fillOpacity);
2562 RETURN_TRUE;
2563 }
2564 /* }}} */
2565
2566 /* {{{ proto bool ImagickDraw::setFillPatternUrl(string fill_url)
2567 Sets the URL to use as a fill pattern for filling objects. Only local URLs ("#identifier") are supported at this time.
2568 These local URLs are normally created by defining a named fill pattern with DrawPushPattern/DrawPopPattern.
2569 */
2570 PHP_METHOD(ImagickDraw, setFillPatternUrl)
2571 {
2572 php_imagickdraw_object *internd;
2573 char *url;
2574 IM_LEN_TYPE url_len;
2575 MagickBooleanType status;
2576
2577 /* Parse parameters given to function */
2578 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &url, &url_len) == FAILURE) {
2579 return;
2580 }
2581
2582 internd = Z_IMAGICKDRAW_P(getThis());
2583 status = DrawSetFillPatternURL(internd->drawing_wand, url);
2584
2585 if (status == MagickFalse) {
2586 php_imagick_convert_imagickdraw_exception (internd->drawing_wand, "Unable to set fill pattern URL" TSRMLS_CC);
2587 return;
2588 }
2589 RETURN_TRUE;
2590 }
2591 /* }}} */
2592
2593 /* {{{ proto bool ImagickDraw::setFillRule(int fill_rule)
2594 Sets the fill rule to use while drawing polygons.
2595 */
2596 PHP_METHOD(ImagickDraw, setFillRule)
2597 {
2598 php_imagickdraw_object *internd;
2599 im_long fill_rule;
2600
2601 /* Parse parameters given to function */
2602 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &fill_rule) == FAILURE) {
2603 return;
2604 }
2605
2606 internd = Z_IMAGICKDRAW_P(getThis());
2607
2608 DrawSetFillRule(internd->drawing_wand, fill_rule);
2609 RETURN_TRUE;
2610 }
2611 /* }}} */
2612
2613 /* {{{ proto bool ImagickDraw::setGravity(int gravity)
2614 Sets the text placement gravity to use when annotating with text.
2615 */
2616 PHP_METHOD(ImagickDraw, setGravity)
2617 {
2618 php_imagickdraw_object *internd;
2619 im_long gravity;
2620
2621 /* Parse parameters given to function */
2622 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &gravity) == FAILURE) {
2623 return;
2624 }
2625
2626 internd = Z_IMAGICKDRAW_P(getThis());
2627
2628 DrawSetGravity(internd->drawing_wand, gravity);
2629 RETURN_TRUE;
2630 }
2631 /* }}} */
2632
2633 /* {{{ proto bool ImagickDraw::setStrokePatternUrl(string stroke_url)
2634 Sets the pattern used for stroking object outlines.
2635 */
2636 PHP_METHOD(ImagickDraw, setStrokePatternUrl)
2637 {
2638 php_imagickdraw_object *internd;
2639 char *url;
2640 IM_LEN_TYPE url_len;
2641 MagickBooleanType status;
2642
2643 /* Parse parameters given to function */
2644 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &url, &url_len) == FAILURE) {
2645 return;
2646 }
2647
2648 internd = Z_IMAGICKDRAW_P(getThis());
2649 status = DrawSetStrokePatternURL(internd->drawing_wand, url);
2650
2651 if (status == MagickFalse) {
2652 php_imagick_convert_imagickdraw_exception (internd->drawing_wand, "Unable to set stroke pattern URL" TSRMLS_CC);
2653 return;
2654 }
2655 RETURN_TRUE;
2656 }
2657 /* }}} */
2658
2659 /* {{{ proto bool ImagickDraw::setStrokeDashOffset(float dash_offset)
2660 Specifies the offset into the dash pattern to start the dash.
2661 */
2662 PHP_METHOD(ImagickDraw, setStrokeDashOffset)
2663 {
2664 php_imagickdraw_object *internd;
2665 double offset;
2666
2667 /* Parse parameters given to function */
2668 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &offset) == FAILURE) {
2669 return;
2670 }
2671
2672 internd = Z_IMAGICKDRAW_P(getThis());
2673
2674 DrawSetStrokeDashOffset(internd->drawing_wand, offset);
2675 RETURN_TRUE;
2676 }
2677 /* }}} */
2678
2679 /* {{{ proto bool ImagickDraw::setStrokeLineCap(int linecap)
2680 Specifies the shape to be used at the end of open subpaths when they are stroked. Values of LineCap are UndefinedCap, ButtCap, RoundCap, and SquareCap.
2681 */
2682 PHP_METHOD(ImagickDraw, setStrokeLineCap)
2683 {
2684 php_imagickdraw_object *internd;
2685 im_long line_cap;
2686
2687 /* Parse parameters given to function */
2688 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &line_cap) == FAILURE) {
2689 return;
2690 }
2691
2692 internd = Z_IMAGICKDRAW_P(getThis());
2693
2694 DrawSetStrokeLineCap(internd->drawing_wand, line_cap);
2695 RETURN_TRUE;
2696 }
2697 /* }}} */
2698
2699 /* {{{ proto bool ImagickDraw::setStrokeLineJoin(int linejoin)
2700 Specifies the shape to be used at the corners of paths (or other vector shapes) when they are stroked. Values of LineJoin are UndefinedJoin, MiterJoin, RoundJoin, and BevelJoin.
2701 */
2702 PHP_METHOD(ImagickDraw, setStrokeLineJoin)
2703 {
2704 php_imagickdraw_object *internd;
2705 im_long line_join;
2706
2707 /* Parse parameters given to function */
2708 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &line_join) == FAILURE) {
2709 return;
2710 }
2711
2712 internd = Z_IMAGICKDRAW_P(getThis());
2713
2714 DrawSetStrokeLineJoin(internd->drawing_wand, line_join);
2715 RETURN_TRUE;
2716 }
2717 /* }}} */
2718
2719 /* {{{ proto bool ImagickDraw::setStrokeMiterLimit(int miterlimit)
2720 Specifies the miter limit. When two line segments meet at a sharp angle and miter joins have been specified for 'lineJoin', it is possible for the miter to extend far beyond the thickness of the line stroking the path. The miterLimit' imposes a limit on the ratio of the miter length to the 'lineWidth'.
2721 */
2722 PHP_METHOD(ImagickDraw, setStrokeMiterLimit)
2723 {
2724 php_imagickdraw_object *internd;
2725 im_long miter_limit;
2726
2727 /* Parse parameters given to function */
2728 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &miter_limit) == FAILURE) {
2729 return;
2730 }
2731
2732 internd = Z_IMAGICKDRAW_P(getThis());
2733
2734 DrawSetStrokeMiterLimit(internd->drawing_wand, miter_limit);
2735 RETURN_TRUE;
2736 }
2737 /* }}} */
2738
2739 /* {{{ proto bool ImagickDraw::setStrokeOpacity(float stroke_opacity)
2740 Specifies the opacity of stroked object outlines.
2741 */
2742 PHP_METHOD(ImagickDraw, setStrokeOpacity)
2743 {
2744 php_imagickdraw_object *internd;
2745 double opacity;
2746
2747 /* Parse parameters given to function */
2748 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &opacity) == FAILURE) {
2749 return;
2750 }
2751
2752 internd = Z_IMAGICKDRAW_P(getThis());
2753
2754 DrawSetStrokeOpacity(internd->drawing_wand, opacity);
2755 RETURN_TRUE;
2756 }
2757 /* }}} */
2758
2759 /* {{{ proto bool ImagickDraw::setVectorGraphics(string xml)
2760 Sets the vector graphics associated with the specified wand. Use this method with DrawGetVectorGraphics() as a method to persist the vector graphics state.
2761 */
2762 PHP_METHOD(ImagickDraw, setVectorGraphics)
2763 {
2764 php_imagickdraw_object *internd;
2765 char *vector;
2766 IM_LEN_TYPE vector_len;
2767 MagickBooleanType status;
2768
2769 /* Parse parameters given to function */
2770 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &vector, &vector_len) == FAILURE) {
2771 return;
2772 }
2773
2774 internd = Z_IMAGICKDRAW_P(getThis());
2775 status = DrawSetVectorGraphics(internd->drawing_wand, vector);
2776
2777 if (status == MagickFalse) {
2778 php_imagick_convert_imagickdraw_exception (internd->drawing_wand, "Unable to set the vector graphics" TSRMLS_CC);
2779 return;
2780 }
2781 RETURN_TRUE;
2782 }
2783 /* }}} */
2784
2785 /* {{{ proto bool ImagickDraw::pop()
2786 Destroys the current DrawingWand in the stack, and returns to the previously pushed DrawingWand. Multiple DrawingWands may exist. It is an error to attempt to pop more DrawingWands than have been pushed, and it is proper form to pop all DrawingWands which have been pushed.
2787 */
2788 PHP_METHOD(ImagickDraw, pop)
2789 {
2790 php_imagickdraw_object *internd;
2791 MagickBooleanType status;
2792
2793 if (zend_parse_parameters_none() == FAILURE) {
2794 return;
2795 }
2796
2797 internd = Z_IMAGICKDRAW_P(getThis());;
2798 status = PopDrawingWand(internd->drawing_wand);
2799
2800 if (status == MagickFalse) {
2801 php_imagick_convert_imagickdraw_exception (internd->drawing_wand, "Unable to pop the current ImagickDraw object" TSRMLS_CC);
2802 return;
2803 }
2804 RETURN_TRUE;
2805 }
2806 /* }}} */
2807
2808 /* {{{ proto bool ImagickDraw::push()
2809 Clones the current DrawingWand to create a new DrawingWand, which is then added to the DrawingWand stack. The original drawing DrawingWand(s) may be returned to by invoking PopDrawingWand(). The DrawingWands are stored on a DrawingWand stack. For every Pop there must have already been an equivalent Push.
2810 */
2811 PHP_METHOD(ImagickDraw, push)
2812 {
2813 php_imagickdraw_object *internd;
2814 MagickBooleanType status;
2815
2816 if (zend_parse_parameters_none() == FAILURE) {
2817 return;
2818 }
2819
2820 internd = Z_IMAGICKDRAW_P(getThis());;
2821 status = PushDrawingWand(internd->drawing_wand);
2822
2823 if (status == MagickFalse) {
2824 php_imagick_convert_imagickdraw_exception (internd->drawing_wand, "Unable to push the current ImagickDraw object" TSRMLS_CC);
2825 return;
2826 }
2827 RETURN_TRUE;
2828 }
2829 /* }}} */
2830
2831 #if MagickLibVersion >= 0x693
2832 /* {{{ proto float ImagickDraw::getOpacity()
2833 Returns the opacity used when drawing with the fill or stroke color or texture. Fully opaque is 1.0.
2834 */
2835 PHP_METHOD(ImagickDraw, getOpacity)
2836 {
2837 php_imagickdraw_object *internd;
2838 double opacity;
2839
2840 if (zend_parse_parameters_none() == FAILURE) {
2841 return;
2842 }
2843
2844 internd = Z_IMAGICKDRAW_P(getThis());
2845 opacity = DrawGetOpacity(internd->drawing_wand);
2846
2847 RETURN_DOUBLE(opacity);
2848 }
2849 /* }}} */
2850
2851 /* {{{ proto bool ImagickDraw::setOpacity(float opacity)
2852 Sets the opacity to use when drawing using the fill or stroke color or texture. Fully opaque is 1.0.
2853 */
2854 PHP_METHOD(ImagickDraw, setOpacity)
2855 {
2856 php_imagickdraw_object *internd;
2857 double opacity;
2858
2859 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "d", &opacity) == FAILURE) {
2860 return;
2861 }
2862
2863 internd = Z_IMAGICKDRAW_P(getThis());;
2864 DrawSetOpacity(internd->drawing_wand, opacity);
2865
2866 RETURN_TRUE;
2867 }
2868 /* }}} */
2869 #endif //#if MagickLibVersion >= 0x693
2870
2871 #if MagickLibVersion >= 0x675
2872 /* {{{ proto array ImagickDraw::getFontResolution()
2873 Gets the image X and Y resolution.
2874 */
2875 PHP_METHOD(ImagickDraw, getFontResolution)
2876 {
2877 php_imagickdraw_object *internd;
2878 double x, y;
2879 MagickBooleanType status;
2880
2881 if (zend_parse_parameters_none() == FAILURE) {
2882 return;
2883 }
2884
2885 internd = Z_IMAGICKDRAW_P(getThis());
2886 status = DrawGetFontResolution(internd->drawing_wand, &x, &y);
2887
2888 if (status == MagickFalse) {
2889 php_imagick_convert_imagickdraw_exception (internd->drawing_wand, "Unable to push the current ImagickDraw object" TSRMLS_CC);
2890 return;
2891 }
2892
2893 array_init(return_value);
2894 add_assoc_double(return_value, "x", x);
2895 add_assoc_double(return_value, "y", y);
2896
2897 return;
2898 }
2899 /* }}} */
2900 #endif //#if MagickLibVersion >= 0x675
2901
2902
2903 #if MagickLibVersion >= 0x675
2904 /* {{{ proto bool ImagickDraw::setFontResolution(float x, float y)
2905 Sets the image font resolution.
2906 */
2907 PHP_METHOD(ImagickDraw, setFontResolution)
2908 {
2909 php_imagickdraw_object *internd;
2910 double x, y;
2911
2912 MagickBooleanType status;
2913
2914 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "dd", &x, &y) == FAILURE) {
2915 return;
2916 }
2917
2918 internd = Z_IMAGICKDRAW_P(getThis());;
2919 status = DrawSetFontResolution(internd->drawing_wand, x, y);
2920 if (status == MagickFalse) {
2921 php_imagick_convert_imagickdraw_exception (internd->drawing_wand, "Unable to push the current ImagickDraw object" TSRMLS_CC);
2922 return;
2923 }
2924
2925 RETURN_TRUE;
2926 }
2927 /* }}} */
2928 #endif //#if MagickLibVersion >= 0x675
2929
2930
2931 #if MagickLibVersion >= 0x675
2932 /* {{{ proto ImagickPixel ImagickDraw::getBorderColor()
2933 Returns the border color used for drawing bordered objects.
2934 */
2935 PHP_METHOD(ImagickDraw, getBorderColor)
2936 {
2937 php_imagickpixel_object *internp;
2938 php_imagickdraw_object *internd;
2939 PixelWand *tmp_wand;
2940
2941 if (zend_parse_parameters_none() == FAILURE) {
2942 return;
2943 }
2944
2945 internd = Z_IMAGICKDRAW_P(getThis());
2946
2947 tmp_wand = NewPixelWand();
2948 DrawGetBorderColor(internd->drawing_wand, tmp_wand);
2949
2950 object_init_ex(return_value, php_imagickpixel_sc_entry);
2951 internp = Z_IMAGICKPIXEL_P(return_value);
2952 php_imagick_replace_pixelwand(internp, tmp_wand);
2953 return;
2954 }
2955 /* }}} */
2956 #endif //#if MagickLibVersion >= 0x675
2957
2958
2959
2960 #if MagickLibVersion >= 0x675
2961 /* {{{ proto bool ImagickDraw::setBorderColor(ImagickPixel color)
2962 Sets the border color to be used for drawing bordered objects.
2963 */
2964 PHP_METHOD(ImagickDraw, setBorderColor)
2965 {
2966 zval *param;
2967 php_imagickdraw_object *internd;
2968 PixelWand *color_wand;
2969 zend_bool allocated;
2970
2971 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", ¶m) == FAILURE) {
2972 return;
2973 }
2974
2975 internd = Z_IMAGICKDRAW_P(getThis());;
2976
2977 color_wand = php_imagick_zval_to_pixelwand(param, IMAGICKDRAW_CLASS, &allocated TSRMLS_CC);
2978 if (!color_wand)
2979 return;
2980
2981 DrawSetBorderColor(internd->drawing_wand, color_wand);
2982 if (allocated)
2983 color_wand = DestroyPixelWand (color_wand);
2984
2985 RETURN_TRUE;
2986 }
2987 /* }}} */
2988 #endif //#if MagickLibVersion >= 0x675
2989
2990 #if MagickLibVersion >= 0x692
2991 /* {{{ proto integer ImagickDraw::getTextDirection()
2992 Returns the direction that will be used when annotating with text.
2993 */
2994 PHP_METHOD(ImagickDraw, getTextDirection)
2995 {
2996 php_imagickdraw_object *internd;
2997 im_long direction;
2998
2999 if (zend_parse_parameters_none() == FAILURE) {
3000 return;
3001 }
3002
3003 internd = Z_IMAGICKDRAW_P(getThis());
3004 direction = DrawGetTextDirection(internd->drawing_wand);
3005
3006 RETURN_LONG(direction);
3007 }
3008
3009 /* }}} */
3010
3011
3012 /* {{{ proto bool ImagickDraw::setTextDirection(int direction)
3013 Sets the font style to use when annotating with text. The AnyStyle enumeration acts as a wild-card "don't care" option.
3014 */
3015 PHP_METHOD(ImagickDraw, setTextDirection)
3016 {
3017 php_imagickdraw_object *internd;
3018 im_long direction;
3019
3020 /* Parse parameters given to function */
3021 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &direction) == FAILURE) {
3022 return;
3023 }
3024
3025 internd = Z_IMAGICKDRAW_P(getThis());
3026
3027 DrawSetTextDirection(internd->drawing_wand, direction);
3028 RETURN_TRUE;
3029 }
3030 /* }}} */
3031 #endif //#if MagickLibVersion >= 0x692
3032
3033 #if MagickLibVersion >= 0x692
3034 /* {{{ proto bool ImagickDraw::setDensity(string density_string)
3035 Sets the vertical and horizontal resolution.
3036 */
3037 PHP_METHOD(ImagickDraw, setDensity)
3038 {
3039 php_imagickdraw_object *internd;
3040 char *density;
3041 IM_LEN_TYPE density_len;
3042 MagickBooleanType status;
3043
3044 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &density, &density_len) == FAILURE) {
3045 return;
3046 }
3047
3048 internd = Z_IMAGICKDRAW_P(getThis());
3049 status = DrawSetDensity(internd->drawing_wand, density);
3050
3051 if (status == MagickFalse) {
3052 php_imagick_convert_imagickdraw_exception (internd->drawing_wand, "Unable to setdensity for ImagickDraw object" TSRMLS_CC);
3053 return;
3054 }
3055
3056 RETURN_TRUE;
3057 }
3058 /* }}} */
3059
3060
3061 /* {{{ proto string|null ImagickDraw::getDensity()
3062 Obtains the vertical and horizontal resolution.
3063 */
3064 PHP_METHOD(ImagickDraw, getDensity)
3065 {
3066 php_imagickdraw_object *internd;
3067 char *density;
3068
3069 if (zend_parse_parameters_none() == FAILURE) {
3070 return;
3071 }
3072
3073 internd = Z_IMAGICKDRAW_P(getThis());
3074 density = DrawGetDensity(internd->drawing_wand);
3075
3076 if (density == NULL) {
3077 RETURN_NULL();
3078 }
3079 else {
3080 IM_RETURN_STRING(density);
3081 }
3082 }
3083 /* }}} */
3084 #endif// #if MagickLibVersion >= 0x692
3085
3086
3087 /* END OF DRAWINGWAND METHODS */
3088