xref: /imagick/imagickdraw_class.c (revision 3e8bdc15)
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", &degrees) == 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", &degrees) == 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", &param) == 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", &param) == 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", &param) == 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", &param_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", &degrees) == 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", &param) == 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