1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 % %
4 % %
5 % %
6 % M M AAA GGGG IIIII CCCC K K %
7 % MM MM A A G I C K K %
8 % M M M AAAAA G GGG I C KKK %
9 % M M A A G G I C K K %
10 % M M A A GGGG IIIII CCCC K K %
11 % %
12 % W W AAA N N DDDD %
13 % W W A A NN N D D %
14 % W W W AAAAA N N N D D %
15 % WW WW A A N NN D D %
16 % W W A A N N DDDD %
17 % %
18 % %
19 % MagickWand Wand Methods %
20 % %
21 % Software Design %
22 % Cristy %
23 % August 2003 %
24 % %
25 % %
26 % Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization %
27 % dedicated to making software imaging solutions freely available. %
28 % %
29 % You may not use this file except in compliance with the License. You may %
30 % obtain a copy of the License at %
31 % %
32 % http://www.imagemagick.org/script/license.php %
33 % %
34 % Unless required by applicable law or agreed to in writing, software %
35 % distributed under the License is distributed on an "AS IS" BASIS, %
36 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
37 % See the License for the specific language governing permissions and %
38 % limitations under the License. %
39 % %
40 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
41 %
42 %
43 %
44 */
45
46 /*
47 Include declarations.
48 */
49 #include "MagickWand/studio.h"
50 #include "MagickWand/MagickWand.h"
51 #include "MagickWand/magick-wand-private.h"
52 #include "MagickWand/wand.h"
53
54 /*
55 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
56 % %
57 % %
58 % %
59 % C l e a r M a g i c k W a n d %
60 % %
61 % %
62 % %
63 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
64 %
65 % ClearMagickWand() clears resources associated with the wand, leaving the
66 % wand blank, and ready to be used for a new set of images.
67 %
68 % The format of the ClearMagickWand method is:
69 %
70 % void ClearMagickWand(MagickWand *wand)
71 %
72 % A description of each parameter follows:
73 %
74 % o wand: the magick wand.
75 %
76 */
ClearMagickWand(MagickWand * wand)77 WandExport void ClearMagickWand(MagickWand *wand)
78 {
79 assert(wand != (MagickWand *) NULL);
80 assert(wand->signature == MagickWandSignature);
81 if (wand->debug != MagickFalse)
82 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
83 wand->image_info=DestroyImageInfo(wand->image_info);
84 wand->images=DestroyImageList(wand->images);
85 wand->image_info=AcquireImageInfo();
86 wand->insert_before=MagickFalse;
87 wand->image_pending=MagickFalse;
88 ClearMagickException(wand->exception);
89 wand->debug=IsEventLogging();
90 }
91
92 /*
93 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
94 % %
95 % %
96 % %
97 % C l o n e M a g i c k W a n d %
98 % %
99 % %
100 % %
101 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
102 %
103 % CloneMagickWand() makes an exact copy of the specified wand.
104 %
105 % The format of the CloneMagickWand method is:
106 %
107 % MagickWand *CloneMagickWand(const MagickWand *wand)
108 %
109 % A description of each parameter follows:
110 %
111 % o wand: the magick wand.
112 %
113 */
CloneMagickWand(const MagickWand * wand)114 WandExport MagickWand *CloneMagickWand(const MagickWand *wand)
115 {
116 MagickWand
117 *clone_wand;
118
119 assert(wand != (MagickWand *) NULL);
120 assert(wand->signature == MagickWandSignature);
121 if (wand->debug != MagickFalse)
122 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
123 clone_wand=(MagickWand *) AcquireMagickMemory(sizeof(*clone_wand));
124 if (clone_wand == (MagickWand *) NULL)
125 ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
126 wand->name);
127 (void) ResetMagickMemory(clone_wand,0,sizeof(*clone_wand));
128 clone_wand->id=AcquireWandId();
129 (void) FormatLocaleString(clone_wand->name,MagickPathExtent,"%s-%.20g",
130 MagickWandId,(double) clone_wand->id);
131 clone_wand->exception=AcquireExceptionInfo();
132 InheritException(clone_wand->exception,wand->exception);
133 clone_wand->image_info=CloneImageInfo(wand->image_info);
134 clone_wand->images=CloneImageList(wand->images,clone_wand->exception);
135 clone_wand->insert_before=MagickFalse;
136 clone_wand->image_pending=MagickFalse;
137 clone_wand->debug=IsEventLogging();
138 if (clone_wand->debug != MagickFalse)
139 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",clone_wand->name);
140 clone_wand->signature=MagickWandSignature;
141 return(clone_wand);
142 }
143
144 /*
145 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
146 % %
147 % %
148 % %
149 % D e s t r o y M a g i c k W a n d %
150 % %
151 % %
152 % %
153 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
154 %
155 % DestroyMagickWand() deallocates memory associated with an MagickWand.
156 %
157 % The format of the DestroyMagickWand method is:
158 %
159 % MagickWand *DestroyMagickWand(MagickWand *wand)
160 %
161 % A description of each parameter follows:
162 %
163 % o wand: the magick wand.
164 %
165 */
DestroyMagickWand(MagickWand * wand)166 WandExport MagickWand *DestroyMagickWand(MagickWand *wand)
167 {
168 assert(wand != (MagickWand *) NULL);
169 assert(wand->signature == MagickWandSignature);
170 if (wand->debug != MagickFalse)
171 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
172 wand->images=DestroyImageList(wand->images);
173 if (wand->image_info != (ImageInfo *) NULL )
174 wand->image_info=DestroyImageInfo(wand->image_info);
175 if (wand->exception != (ExceptionInfo *) NULL )
176 wand->exception=DestroyExceptionInfo(wand->exception);
177 RelinquishWandId(wand->id);
178 wand->signature=(~MagickWandSignature);
179 wand=(MagickWand *) RelinquishMagickMemory(wand);
180 return(wand);
181 }
182
183 /*
184 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
185 % %
186 % %
187 % %
188 % I s M a g i c k W a n d %
189 % %
190 % %
191 % %
192 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
193 %
194 % IsMagickWand() returns MagickTrue if the wand is verified as a magick wand.
195 %
196 % The format of the IsMagickWand method is:
197 %
198 % MagickBooleanType IsMagickWand(const MagickWand *wand)
199 %
200 % A description of each parameter follows:
201 %
202 % o wand: the magick wand.
203 %
204 */
IsMagickWand(const MagickWand * wand)205 WandExport MagickBooleanType IsMagickWand(const MagickWand *wand)
206 {
207 if (wand == (const MagickWand *) NULL)
208 return(MagickFalse);
209 if (wand->signature != MagickWandSignature)
210 return(MagickFalse);
211 if (LocaleNCompare(wand->name,MagickWandId,strlen(MagickWandId)) != 0)
212 return(MagickFalse);
213 return(MagickTrue);
214 }
215
216 /*
217 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
218 % %
219 % %
220 % %
221 % M a g i c k C l e a r E x c e p t i o n %
222 % %
223 % %
224 % %
225 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
226 %
227 % MagickClearException() clears any exceptions associated with the wand.
228 %
229 % The format of the MagickClearException method is:
230 %
231 % MagickBooleanType MagickClearException(MagickWand *wand)
232 %
233 % A description of each parameter follows:
234 %
235 % o wand: the magick wand.
236 %
237 */
MagickClearException(MagickWand * wand)238 WandExport MagickBooleanType MagickClearException(MagickWand *wand)
239 {
240 assert(wand != (MagickWand *) NULL);
241 assert(wand->signature == MagickWandSignature);
242 if (wand->debug != MagickFalse)
243 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
244 ClearMagickException(wand->exception);
245 return(MagickTrue);
246 }
247
248 /*
249 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
250 % %
251 % %
252 % %
253 % M a g i c k G e t E x c e p t i o n %
254 % %
255 % %
256 % %
257 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
258 %
259 % MagickGetException() returns the severity, reason, and description of any
260 % error that occurs when using other methods in this API.
261 %
262 % The format of the MagickGetException method is:
263 %
264 % char *MagickGetException(const MagickWand *wand,ExceptionType *severity)
265 %
266 % A description of each parameter follows:
267 %
268 % o wand: the magick wand.
269 %
270 % o severity: the severity of the error is returned here.
271 %
272 */
MagickGetException(const MagickWand * wand,ExceptionType * severity)273 WandExport char *MagickGetException(const MagickWand *wand,
274 ExceptionType *severity)
275 {
276 char
277 *description;
278
279 assert(wand != (const MagickWand *) NULL);
280 assert(wand->signature == MagickWandSignature);
281 if (wand->debug != MagickFalse)
282 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
283 assert(severity != (ExceptionType *) NULL);
284 *severity=wand->exception->severity;
285 description=(char *) AcquireQuantumMemory(2UL*MagickPathExtent,
286 sizeof(*description));
287 if (description == (char *) NULL)
288 {
289 (void) ThrowMagickException(wand->exception,GetMagickModule(),WandError,
290 "MemoryAllocationFailed","`%s'",wand->name);
291 return((char *) NULL);
292 }
293 *description='\0';
294 if (wand->exception->reason != (char *) NULL)
295 (void) CopyMagickString(description,GetLocaleExceptionMessage(
296 wand->exception->severity,wand->exception->reason),MagickPathExtent);
297 if (wand->exception->description != (char *) NULL)
298 {
299 (void) ConcatenateMagickString(description," (",MagickPathExtent);
300 (void) ConcatenateMagickString(description,GetLocaleExceptionMessage(
301 wand->exception->severity,wand->exception->description),MagickPathExtent);
302 (void) ConcatenateMagickString(description,")",MagickPathExtent);
303 }
304 return(description);
305 }
306
307 /*
308 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
309 % %
310 % %
311 % %
312 % M a g i c k G e t E x c e p t i o n T y p e %
313 % %
314 % %
315 % %
316 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
317 %
318 % MagickGetExceptionType() returns the exception type associated with the
319 % wand. If no exception has occurred, UndefinedExceptionType is returned.
320 %
321 % The format of the MagickGetExceptionType method is:
322 %
323 % ExceptionType MagickGetExceptionType(const MagickWand *wand)
324 %
325 % A description of each parameter follows:
326 %
327 % o wand: the magick wand.
328 %
329 */
MagickGetExceptionType(const MagickWand * wand)330 WandExport ExceptionType MagickGetExceptionType(const MagickWand *wand)
331 {
332 assert(wand != (MagickWand *) NULL);
333 assert(wand->signature == MagickWandSignature);
334 if (wand->debug != MagickFalse)
335 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
336 return(wand->exception->severity);
337 }
338
339 /*
340 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
341 % %
342 % %
343 % %
344 % M a g i c k G e t I t e r a t o r I n d e x %
345 % %
346 % %
347 % %
348 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
349 %
350 % MagickGetIteratorIndex() returns the position of the iterator in the image
351 % list.
352 %
353 % The format of the MagickGetIteratorIndex method is:
354 %
355 % ssize_t MagickGetIteratorIndex(MagickWand *wand)
356 %
357 % A description of each parameter follows:
358 %
359 % o wand: the magick wand.
360 %
361 */
MagickGetIteratorIndex(MagickWand * wand)362 WandExport ssize_t MagickGetIteratorIndex(MagickWand *wand)
363 {
364 assert(wand != (MagickWand *) NULL);
365 assert(wand->signature == MagickWandSignature);
366 if (wand->debug != MagickFalse)
367 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
368 if (wand->images == (Image *) NULL)
369 {
370 (void) ThrowMagickException(wand->exception,GetMagickModule(),WandError,
371 "ContainsNoIterators","`%s'",wand->name);
372 return(-1);
373 }
374 return(GetImageIndexInList(wand->images));
375 }
376
377 /*
378 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
379 % %
380 % %
381 % %
382 % M a g i c k Q u e r y C o n f i g u r e O p t i o n %
383 % %
384 % %
385 % %
386 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
387 %
388 % MagickQueryConfigureOption() returns the value associated with the specified
389 % configure option.
390 %
391 % The format of the MagickQueryConfigureOption function is:
392 %
393 % char *MagickQueryConfigureOption(const char *option)
394 %
395 % A description of each parameter follows:
396 %
397 % o option: the option name.
398 %
399 */
MagickQueryConfigureOption(const char * option)400 WandExport char *MagickQueryConfigureOption(const char *option)
401 {
402 char
403 *value;
404
405 const ConfigureInfo
406 **configure_info;
407
408 ExceptionInfo
409 *exception;
410
411 size_t
412 number_options;
413
414 exception=AcquireExceptionInfo();
415 configure_info=GetConfigureInfoList(option,&number_options,exception);
416 exception=DestroyExceptionInfo(exception);
417 if (configure_info == (const ConfigureInfo **) NULL)
418 return((char *) NULL);
419 value=AcquireString(configure_info[0]->value);
420 configure_info=(const ConfigureInfo **)
421 RelinquishMagickMemory((void *) configure_info);
422 return(value);
423 }
424
425 /*
426 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
427 % %
428 % %
429 % %
430 % M a g i c k Q u e r y C o n f i g u r e O p t i o n s %
431 % %
432 % %
433 % %
434 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
435 %
436 % MagickQueryConfigureOptions() returns any configure options that match the
437 % specified pattern (e.g. "*" for all). Options include NAME, VERSION,
438 % LIB_VERSION, etc.
439 %
440 % The format of the MagickQueryConfigureOptions function is:
441 %
442 % char **MagickQueryConfigureOptions(const char *pattern,
443 % size_t *number_options)
444 %
445 % A description of each parameter follows:
446 %
447 % o pattern: Specifies a pointer to a text string containing a pattern.
448 %
449 % o number_options: Returns the number of configure options in the list.
450 %
451 %
452 */
MagickQueryConfigureOptions(const char * pattern,size_t * number_options)453 WandExport char **MagickQueryConfigureOptions(const char *pattern,
454 size_t *number_options)
455 {
456 char
457 **options;
458
459 ExceptionInfo
460 *exception;
461
462 exception=AcquireExceptionInfo();
463 options=GetConfigureList(pattern,number_options,exception);
464 exception=DestroyExceptionInfo(exception);
465 return(options);
466 }
467
468 /*
469 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
470 % %
471 % %
472 % %
473 % M a g i c k Q u e r y F o n t M e t r i c s %
474 % %
475 % %
476 % %
477 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
478 %
479 % MagickQueryFontMetrics() returns a 13 element array representing the
480 % following font metrics:
481 %
482 % Element Description
483 % -------------------------------------------------
484 % 0 character width
485 % 1 character height
486 % 2 ascender
487 % 3 descender
488 % 4 text width
489 % 5 text height
490 % 6 maximum horizontal advance
491 % 7 bounding box: x1
492 % 8 bounding box: y1
493 % 9 bounding box: x2
494 % 10 bounding box: y2
495 % 11 origin: x
496 % 12 origin: y
497 %
498 % The format of the MagickQueryFontMetrics method is:
499 %
500 % double *MagickQueryFontMetrics(MagickWand *wand,
501 % const DrawingWand *drawing_wand,const char *text)
502 %
503 % A description of each parameter follows:
504 %
505 % o wand: the Magick wand.
506 %
507 % o drawing_wand: the drawing wand.
508 %
509 % o text: the text.
510 %
511 */
MagickQueryFontMetrics(MagickWand * wand,const DrawingWand * drawing_wand,const char * text)512 WandExport double *MagickQueryFontMetrics(MagickWand *wand,
513 const DrawingWand *drawing_wand,const char *text)
514 {
515 double
516 *font_metrics;
517
518 DrawInfo
519 *draw_info;
520
521 MagickBooleanType
522 status;
523
524 TypeMetric
525 metrics;
526
527 assert(wand != (MagickWand *) NULL);
528 assert(wand->signature == MagickWandSignature);
529 if (wand->debug != MagickFalse)
530 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
531 assert(drawing_wand != (const DrawingWand *) NULL);
532 if (wand->images == (Image *) NULL)
533 {
534 (void) ThrowMagickException(wand->exception,GetMagickModule(),WandError,
535 "ContainsNoImages","`%s'",wand->name);
536 return((double *) NULL);
537 }
538 font_metrics=(double *) AcquireQuantumMemory(13UL,sizeof(*font_metrics));
539 if (font_metrics == (double *) NULL)
540 return((double *) NULL);
541 draw_info=PeekDrawingWand(drawing_wand);
542 if (draw_info == (DrawInfo *) NULL)
543 {
544 font_metrics=(double *) RelinquishMagickMemory(font_metrics);
545 return((double *) NULL);
546 }
547 (void) CloneString(&draw_info->text,text);
548 (void) ResetMagickMemory(&metrics,0,sizeof(metrics));
549 status=GetTypeMetrics(wand->images,draw_info,&metrics,wand->exception);
550 draw_info=DestroyDrawInfo(draw_info);
551 if (status == MagickFalse)
552 {
553 font_metrics=(double *) RelinquishMagickMemory(font_metrics);
554 return((double *) NULL);
555 }
556 font_metrics[0]=metrics.pixels_per_em.x;
557 font_metrics[1]=metrics.pixels_per_em.y;
558 font_metrics[2]=metrics.ascent;
559 font_metrics[3]=metrics.descent;
560 font_metrics[4]=metrics.width;
561 font_metrics[5]=metrics.height;
562 font_metrics[6]=metrics.max_advance;
563 font_metrics[7]=metrics.bounds.x1;
564 font_metrics[8]=metrics.bounds.y1;
565 font_metrics[9]=metrics.bounds.x2;
566 font_metrics[10]=metrics.bounds.y2;
567 font_metrics[11]=metrics.origin.x;
568 font_metrics[12]=metrics.origin.y;
569 return(font_metrics);
570 }
571
572 /*
573 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
574 % %
575 % %
576 % %
577 % M a g i c k Q u e r y M u l t i l i n e F o n t M e t r i c s %
578 % %
579 % %
580 % %
581 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
582 %
583 % MagickQueryMultilineFontMetrics() returns a 13 element array representing the
584 % following font metrics:
585 %
586 % Element Description
587 % -------------------------------------------------
588 % 0 character width
589 % 1 character height
590 % 2 ascender
591 % 3 descender
592 % 4 text width
593 % 5 text height
594 % 6 maximum horizontal advance
595 % 7 bounding box: x1
596 % 8 bounding box: y1
597 % 9 bounding box: x2
598 % 10 bounding box: y2
599 % 11 origin: x
600 % 12 origin: y
601 %
602 % This method is like MagickQueryFontMetrics() but it returns the maximum text
603 % width and height for multiple lines of text.
604 %
605 % The format of the MagickQueryFontMetrics method is:
606 %
607 % double *MagickQueryMultilineFontMetrics(MagickWand *wand,
608 % const DrawingWand *drawing_wand,const char *text)
609 %
610 % A description of each parameter follows:
611 %
612 % o wand: the Magick wand.
613 %
614 % o drawing_wand: the drawing wand.
615 %
616 % o text: the text.
617 %
618 */
MagickQueryMultilineFontMetrics(MagickWand * wand,const DrawingWand * drawing_wand,const char * text)619 WandExport double *MagickQueryMultilineFontMetrics(MagickWand *wand,
620 const DrawingWand *drawing_wand,const char *text)
621 {
622 double
623 *font_metrics;
624
625 DrawInfo
626 *draw_info;
627
628 MagickBooleanType
629 status;
630
631 TypeMetric
632 metrics;
633
634 assert(wand != (MagickWand *) NULL);
635 assert(wand->signature == MagickWandSignature);
636 if (wand->debug != MagickFalse)
637 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
638 assert(drawing_wand != (const DrawingWand *) NULL);
639 if (wand->images == (Image *) NULL)
640 {
641 (void) ThrowMagickException(wand->exception,GetMagickModule(),WandError,
642 "ContainsNoImages","`%s'",wand->name);
643 return((double *) NULL);
644 }
645 font_metrics=(double *) AcquireQuantumMemory(13UL,sizeof(*font_metrics));
646 if (font_metrics == (double *) NULL)
647 return((double *) NULL);
648 draw_info=PeekDrawingWand(drawing_wand);
649 if (draw_info == (DrawInfo *) NULL)
650 {
651 font_metrics=(double *) RelinquishMagickMemory(font_metrics);
652 return((double *) NULL);
653 }
654 (void) CloneString(&draw_info->text,text);
655 (void) ResetMagickMemory(&metrics,0,sizeof(metrics));
656 status=GetMultilineTypeMetrics(wand->images,draw_info,&metrics,
657 wand->exception);
658 draw_info=DestroyDrawInfo(draw_info);
659 if (status == MagickFalse)
660 {
661 font_metrics=(double *) RelinquishMagickMemory(font_metrics);
662 return((double *) NULL);
663 }
664 font_metrics[0]=metrics.pixels_per_em.x;
665 font_metrics[1]=metrics.pixels_per_em.y;
666 font_metrics[2]=metrics.ascent;
667 font_metrics[3]=metrics.descent;
668 font_metrics[4]=metrics.width;
669 font_metrics[5]=metrics.height;
670 font_metrics[6]=metrics.max_advance;
671 font_metrics[7]=metrics.bounds.x1;
672 font_metrics[8]=metrics.bounds.y1;
673 font_metrics[9]=metrics.bounds.x2;
674 font_metrics[10]=metrics.bounds.y2;
675 font_metrics[11]=metrics.origin.x;
676 font_metrics[12]=metrics.origin.y;
677 return(font_metrics);
678 }
679
680 /*
681 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
682 % %
683 % %
684 % %
685 % M a g i c k Q u e r y F o n t s %
686 % %
687 % %
688 % %
689 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
690 %
691 % MagickQueryFonts() returns any font that match the specified pattern (e.g.
692 % "*" for all).
693 %
694 % The format of the MagickQueryFonts function is:
695 %
696 % char **MagickQueryFonts(const char *pattern,size_t *number_fonts)
697 %
698 % A description of each parameter follows:
699 %
700 % o pattern: Specifies a pointer to a text string containing a pattern.
701 %
702 % o number_fonts: Returns the number of fonts in the list.
703 %
704 %
705 */
MagickQueryFonts(const char * pattern,size_t * number_fonts)706 WandExport char **MagickQueryFonts(const char *pattern,
707 size_t *number_fonts)
708 {
709 char
710 **fonts;
711
712 ExceptionInfo
713 *exception;
714
715 exception=AcquireExceptionInfo();
716 fonts=GetTypeList(pattern,number_fonts,exception);
717 exception=DestroyExceptionInfo(exception);
718 return(fonts);
719 }
720
721 /*
722 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
723 % %
724 % %
725 % %
726 % M a g i c k Q u e r y F o r m a t s %
727 % %
728 % %
729 % %
730 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
731 %
732 % MagickQueryFormats() returns any image formats that match the specified
733 % pattern (e.g. "*" for all).
734 %
735 % The format of the MagickQueryFormats function is:
736 %
737 % char **MagickQueryFormats(const char *pattern,size_t *number_formats)
738 %
739 % A description of each parameter follows:
740 %
741 % o pattern: Specifies a pointer to a text string containing a pattern.
742 %
743 % o number_formats: This integer returns the number of image formats in the
744 % list.
745 %
746 */
MagickQueryFormats(const char * pattern,size_t * number_formats)747 WandExport char **MagickQueryFormats(const char *pattern,
748 size_t *number_formats)
749 {
750 char
751 **formats;
752
753 ExceptionInfo
754 *exception;
755
756 exception=AcquireExceptionInfo();
757 formats=GetMagickList(pattern,number_formats,exception);
758 exception=DestroyExceptionInfo(exception);
759 return(formats);
760 }
761
762 /*
763 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
764 % %
765 % %
766 % %
767 % M a g i c k R e l i n q u i s h M e m o r y %
768 % %
769 % %
770 % %
771 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
772 %
773 % MagickRelinquishMemory() relinquishes memory resources returned by such
774 % methods as MagickIdentifyImage(), MagickGetException(), etc.
775 %
776 % The format of the MagickRelinquishMemory method is:
777 %
778 % void *MagickRelinquishMemory(void *resource)
779 %
780 % A description of each parameter follows:
781 %
782 % o resource: Relinquish the memory associated with this resource.
783 %
784 */
MagickRelinquishMemory(void * memory)785 WandExport void *MagickRelinquishMemory(void *memory)
786 {
787 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
788 return(RelinquishMagickMemory(memory));
789 }
790
791 /*
792 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
793 % %
794 % %
795 % %
796 % M a g i c k R e s e t I t e r a t o r %
797 % %
798 % %
799 % %
800 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
801 %
802 % MagickResetIterator() resets the wand iterator.
803 %
804 % It is typically used either before iterating though images, or before
805 % calling specific functions such as MagickAppendImages() to append all
806 % images together.
807 %
808 % Afterward you can use MagickNextImage() to iterate over all the images
809 % in a wand container, starting with the first image.
810 %
811 % Using this before MagickAddImages() or MagickReadImages() will cause
812 % new images to be inserted between the first and second image.
813 %
814 % The format of the MagickResetIterator method is:
815 %
816 % void MagickResetIterator(MagickWand *wand)
817 %
818 % A description of each parameter follows:
819 %
820 % o wand: the magick wand.
821 %
822 */
MagickResetIterator(MagickWand * wand)823 WandExport void MagickResetIterator(MagickWand *wand)
824 {
825 assert(wand != (MagickWand *) NULL);
826 assert(wand->signature == MagickWandSignature);
827 if (wand->debug != MagickFalse)
828 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
829 wand->images=GetFirstImageInList(wand->images);
830 wand->insert_before=MagickFalse; /* Insert/add after current (first) image */
831 wand->image_pending=MagickTrue; /* NextImage will set first image */
832 }
833
834 /*
835 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
836 % %
837 % %
838 % %
839 % M a g i c k S e t F i r s t I t e r a t o r %
840 % %
841 % %
842 % %
843 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
844 %
845 % MagickSetFirstIterator() sets the wand iterator to the first image.
846 %
847 % After using any images added to the wand using MagickAddImage() or
848 % MagickReadImage() will be prepended before any image in the wand.
849 %
850 % Also the current image has been set to the first image (if any) in the
851 % Magick Wand. Using MagickNextImage() will then set teh current image
852 % to the second image in the list (if present).
853 %
854 % This operation is similar to MagickResetIterator() but differs in how
855 % MagickAddImage(), MagickReadImage(), and MagickNextImage() behaves
856 % afterward.
857 %
858 % The format of the MagickSetFirstIterator method is:
859 %
860 % void MagickSetFirstIterator(MagickWand *wand)
861 %
862 % A description of each parameter follows:
863 %
864 % o wand: the magick wand.
865 %
866 */
MagickSetFirstIterator(MagickWand * wand)867 WandExport void MagickSetFirstIterator(MagickWand *wand)
868 {
869 assert(wand != (MagickWand *) NULL);
870 assert(wand->signature == MagickWandSignature);
871 if (wand->debug != MagickFalse)
872 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
873 wand->images=GetFirstImageInList(wand->images);
874 wand->insert_before=MagickTrue; /* Insert/add before the first image */
875 wand->image_pending=MagickFalse; /* NextImage will set next image */
876 }
877
878 /*
879 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
880 % %
881 % %
882 % %
883 % M a g i c k S e t I t e r a t o r I n d e x %
884 % %
885 % %
886 % %
887 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
888 %
889 % MagickSetIteratorIndex() set the iterator to the given position in the
890 % image list specified with the index parameter. A zero index will set
891 % the first image as current, and so on. Negative indexes can be used
892 % to specify an image relative to the end of the images in the wand, with
893 % -1 being the last image in the wand.
894 %
895 % If the index is invalid (range too large for number of images in wand)
896 % the function will return MagickFalse, but no 'exception' will be raised,
897 % as it is not actually an error. In that case the current image will not
898 % change.
899 %
900 % After using any images added to the wand using MagickAddImage() or
901 % MagickReadImage() will be added after the image indexed, regardless
902 % of if a zero (first image in list) or negative index (from end) is used.
903 %
904 % Jumping to index 0 is similar to MagickResetIterator() but differs in how
905 % MagickNextImage() behaves afterward.
906 %
907 % The format of the MagickSetIteratorIndex method is:
908 %
909 % MagickBooleanType MagickSetIteratorIndex(MagickWand *wand,
910 % const ssize_t index)
911 %
912 % A description of each parameter follows:
913 %
914 % o wand: the magick wand.
915 %
916 % o index: the scene number.
917 %
918 */
MagickSetIteratorIndex(MagickWand * wand,const ssize_t index)919 WandExport MagickBooleanType MagickSetIteratorIndex(MagickWand *wand,
920 const ssize_t index)
921 {
922 Image
923 *image;
924
925 assert(wand != (MagickWand *) NULL);
926 assert(wand->signature == MagickWandSignature);
927 if (wand->debug != MagickFalse)
928 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
929 if (wand->images == (Image *) NULL)
930 return(MagickFalse);
931 image=GetImageFromList(wand->images,index);
932 if (image == (Image *) NULL)
933 return(MagickFalse); /* this is not an exception! Just range error. */
934 wand->images=image;
935 wand->insert_before=MagickFalse; /* Insert/Add after (this) image */
936 wand->image_pending=MagickFalse; /* NextImage will set next image */
937 return(MagickTrue);
938 }
939 /*
940 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
941 % %
942 % %
943 % %
944 % M a g i c k S e t L a s t I t e r a t o r %
945 % %
946 % %
947 % %
948 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
949 %
950 % MagickSetLastIterator() sets the wand iterator to the last image.
951 %
952 % The last image is actually the current image, and the next use of
953 % MagickPreviousImage() will not change this allowing this function to be
954 % used to iterate over the images in the reverse direction. In this sense it
955 % is more like MagickResetIterator() than MagickSetFirstIterator().
956 %
957 % Typically this function is used before MagickAddImage(), MagickReadImage()
958 % functions to ensure new images are appended to the very end of wand's image
959 % list.
960 %
961 % The format of the MagickSetLastIterator method is:
962 %
963 % void MagickSetLastIterator(MagickWand *wand)
964 %
965 % A description of each parameter follows:
966 %
967 % o wand: the magick wand.
968 %
969 */
MagickSetLastIterator(MagickWand * wand)970 WandExport void MagickSetLastIterator(MagickWand *wand)
971 {
972 assert(wand != (MagickWand *) NULL);
973 assert(wand->signature == MagickWandSignature);
974 if (wand->debug != MagickFalse)
975 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
976 wand->images=GetLastImageInList(wand->images);
977 wand->insert_before=MagickFalse; /* Insert/add after current (last) image */
978 wand->image_pending=MagickTrue; /* PreviousImage will return last image */
979 }
980
981 /*
982 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
983 % %
984 % %
985 % %
986 % M a g i c k W a n d G e n e s i s %
987 % %
988 % %
989 % %
990 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
991 %
992 % MagickWandGenesis() initializes the MagickWand environment.
993 %
994 % The format of the MagickWandGenesis method is:
995 %
996 % void MagickWandGenesis(void)
997 %
998 */
MagickWandGenesis(void)999 WandExport void MagickWandGenesis(void)
1000 {
1001 if (IsMagickCoreInstantiated() == MagickFalse)
1002 MagickCoreGenesis((char *) NULL,MagickFalse);
1003 }
1004
1005 /*
1006 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1007 % %
1008 % %
1009 % %
1010 % M a g i c k W a n d T e r m i n u s %
1011 % %
1012 % %
1013 % %
1014 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1015 %
1016 % MagickWandTerminus() terminates the MagickWand environment.
1017 %
1018 % The format of the MaickWandTerminus method is:
1019 %
1020 % void MagickWandTerminus(void)
1021 %
1022 */
MagickWandTerminus(void)1023 WandExport void MagickWandTerminus(void)
1024 {
1025 DestroyWandIds();
1026 MagickCoreTerminus();
1027 }
1028
1029 /*
1030 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1031 % %
1032 % %
1033 % %
1034 % N e w M a g i c k W a n d %
1035 % %
1036 % %
1037 % %
1038 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1039 %
1040 % NewMagickWand() returns a wand required for all other methods in the API.
1041 % A fatal exception is thrown if there is not enough memory to allocate the
1042 % wand. Use DestroyMagickWand() to dispose of the wand when it is no longer
1043 % needed.
1044 %
1045 % The format of the NewMagickWand method is:
1046 %
1047 % MagickWand *NewMagickWand(void)
1048 %
1049 */
NewMagickWand(void)1050 WandExport MagickWand *NewMagickWand(void)
1051 {
1052 const char
1053 *quantum;
1054
1055 MagickWand
1056 *wand;
1057
1058 size_t
1059 depth;
1060
1061 depth=MAGICKCORE_QUANTUM_DEPTH;
1062 quantum=GetMagickQuantumDepth(&depth);
1063 if (depth != MAGICKCORE_QUANTUM_DEPTH)
1064 ThrowWandFatalException(WandError,"QuantumDepthMismatch",quantum);
1065 wand=(MagickWand *) AcquireMagickMemory(sizeof(*wand));
1066 if (wand == (MagickWand *) NULL)
1067 ThrowWandFatalException(ResourceLimitFatalError,"MemoryAllocationFailed",
1068 GetExceptionMessage(errno));
1069 (void) ResetMagickMemory(wand,0,sizeof(*wand));
1070 wand->id=AcquireWandId();
1071 (void) FormatLocaleString(wand->name,MagickPathExtent,"%s-%.20g",MagickWandId,
1072 (double) wand->id);
1073 wand->images=NewImageList();
1074 wand->image_info=AcquireImageInfo();
1075 wand->exception=AcquireExceptionInfo();
1076 wand->debug=IsEventLogging();
1077 if (wand->debug != MagickFalse)
1078 (void) LogMagickEvent(WandEvent,GetMagickModule(),"%s",wand->name);
1079 wand->signature=MagickWandSignature;
1080 return(wand);
1081 }
1082
1083 /*
1084 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1085 % %
1086 % %
1087 % %
1088 % N e w M a g i c k W a n d F r o m I m a g e %
1089 % %
1090 % %
1091 % %
1092 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1093 %
1094 % NewMagickWandFromImage() returns a wand with an image.
1095 %
1096 % The format of the NewMagickWandFromImage method is:
1097 %
1098 % MagickWand *NewMagickWandFromImage(const Image *image)
1099 %
1100 % A description of each parameter follows:
1101 %
1102 % o image: the image.
1103 %
1104 */
NewMagickWandFromImage(const Image * image)1105 WandExport MagickWand *NewMagickWandFromImage(const Image *image)
1106 {
1107 MagickWand
1108 *wand;
1109
1110 wand=NewMagickWand();
1111 wand->images=CloneImage(image,0,0,MagickTrue,wand->exception);
1112 return(wand);
1113 }
1114
1115 /*
1116 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1117 % %
1118 % %
1119 % %
1120 % I s M a g i c k W a n d I n s t a n t i a t e d %
1121 % %
1122 % %
1123 % %
1124 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1125 %
1126 % IsMagickWandInstantiated() returns MagickTrue if the ImageMagick environment
1127 % is currently instantiated-- that is, MagickWandGenesis() has been called but
1128 % MagickWandTerminus() has not.
1129 %
1130 % The format of the IsMagickWandInstantiated method is:
1131 %
1132 % MagickBooleanType IsMagickWandInstantiated(void)
1133 %
1134 */
IsMagickWandInstantiated(void)1135 MagickExport MagickBooleanType IsMagickWandInstantiated(void)
1136 {
1137 return(IsMagickCoreInstantiated());
1138 }
1139