annotate.c revision 06f590165f0505d42005264893fe14a9e8a79986
13ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 23ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 33ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 43ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 53ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 63ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% AAA N N N N OOO TTTTT AAA TTTTT EEEEE % 73ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A A NN N NN N O O T A A T E % 83ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% AAAAA N N N N N N O O T AAAAA T EEE % 93ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A A N NN N NN O O T A A T E % 103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A A N N N N OOO T A A T EEEEE % 113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% MagickCore Image Annotation Methods % 143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% Software Design % 16de984cdc3631106b1cbbb8d3972b76a0fc27e8e8cristy% Cristy % 173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% July 1992 % 183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 207ce65e7125a4e1df1a274ce373c537a9df9c16cdCristy% Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization % 213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% dedicated to making software imaging solutions freely available. % 223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% You may not use this file except in compliance with the License. You may % 243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% obtain a copy of the License at % 253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% http://www.imagemagick.org/script/license.php % 273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% Unless required by applicable law or agreed to in writing, software % 293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% distributed under the License is distributed on an "AS IS" BASIS, % 303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % 313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% See the License for the specific language governing permissions and % 323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% limitations under the License. % 333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% Digital Applications (www.digapp.com) contributed the stroked text algorithm. 373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% It was written by Leonard Rosenthol. 383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Include declarations. 443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 454c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/studio.h" 464c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/annotate.h" 475ff4eaf57b3cd47d0371f204f865cbba614674a0cristy#include "MagickCore/annotate-private.h" 484c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/attribute.h" 494c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/cache-view.h" 50c9afe1687cd4da5d2382a9ca3ca12f30d8baa96fcristy#include "MagickCore/channel.h" 514c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/client.h" 524c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/color.h" 534c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/color-private.h" 5454b92627b2e9657853beee431546d08234276477cristy#include "MagickCore/colorspace-private.h" 554c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/composite.h" 564c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/composite-private.h" 574c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/constitute.h" 584c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/draw.h" 594c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/draw-private.h" 603644bdf56f0081bcae1f4dbc69c2d06713f6203bcristy#include "MagickCore/enhance.h" 614c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/exception.h" 624c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/exception-private.h" 634c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/gem.h" 644c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/geometry.h" 654c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/image-private.h" 664c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/log.h" 674c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/quantum.h" 684c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/quantum-private.h" 694c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/pixel-accessor.h" 704c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/property.h" 714c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/resource_.h" 724c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/semaphore.h" 734c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/statistic.h" 744c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/string_.h" 7517f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy#include "MagickCore/token.h" 764c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/token-private.h" 7706f590165f0505d42005264893fe14a9e8a79986dirk#include "MagickCore/transform-private.h" 784c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/type.h" 794c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/utility.h" 80d1dd6e4fefa0810b9893e6ac9418f79c97c1b39acristy#include "MagickCore/utility-private.h" 81bcbda3fd7d9f3084869f5cebabceb0324c3b2cd7cristy#include "MagickCore/xwindow.h" 824c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/xwindow-private.h" 833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_FREETYPE_DELEGATE) 8407a3cca00593c795eb8e0427f5bc4c2bcad3f0fbcristy#if defined(__MINGW32__) || defined(__MINGW64__) 853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# undef interface 863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif 8703f187ee83f1927717c93c57af06d5e030a194becristy#include <ft2build.h> 883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(FT_FREETYPE_H) 893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# include FT_FREETYPE_H 903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else 913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# include <freetype/freetype.h> 923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif 933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(FT_GLYPH_H) 943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# include FT_GLYPH_H 953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else 963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# include <freetype/ftglyph.h> 973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif 983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(FT_OUTLINE_H) 993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# include FT_OUTLINE_H 1003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else 1013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# include <freetype/ftoutln.h> 1023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif 1033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(FT_BBOX_H) 1043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# include FT_BBOX_H 1053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else 1063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# include <freetype/ftbbox.h> 1073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* defined(FT_BBOX_H) */ 1083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif 10917f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy#if defined(MAGICKCORE_RAQM_DELEGATE) 11069a0d3b5699c573f650e6b61f98ce4579d6f218cCristy#include <raqm.h> 111ea866ca14ef4019d49cf678d35b405512b210b85Cristy#endif 11217f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristytypedef struct _GraphemeInfo 11369a0d3b5699c573f650e6b61f98ce4579d6f218cCristy{ 11487dc5e4e6f9471304ba85f508de30e664b484d3aCristy size_t 11569a0d3b5699c573f650e6b61f98ce4579d6f218cCristy index, 11669a0d3b5699c573f650e6b61f98ce4579d6f218cCristy x_offset, 11769a0d3b5699c573f650e6b61f98ce4579d6f218cCristy x_advance, 11869a0d3b5699c573f650e6b61f98ce4579d6f218cCristy y_offset; 11969a0d3b5699c573f650e6b61f98ce4579d6f218cCristy 12087dc5e4e6f9471304ba85f508de30e664b484d3aCristy size_t 12169a0d3b5699c573f650e6b61f98ce4579d6f218cCristy cluster; 12217f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy} GraphemeInfo; 1235eb36084e86f5ab4a877c2b31c19880b0b0b02e3Cristy 1243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 125d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy Annotate semaphores. 126d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy*/ 127d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristystatic SemaphoreInfo 128d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy *annotate_semaphore = (SemaphoreInfo *) NULL; 129d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy 130d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy/* 1313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Forward declarations. 1323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 1333ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType 1345cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy RenderType(Image *,const DrawInfo *,const PointInfo *,TypeMetric *, 1355cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy ExceptionInfo *), 1365cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy RenderPostscript(Image *,const DrawInfo *,const PointInfo *,TypeMetric *, 1375cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy ExceptionInfo *), 1383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy RenderFreetype(Image *,const DrawInfo *,const char *,const PointInfo *, 1395cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy TypeMetric *,ExceptionInfo *), 1405cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy RenderX11(Image *,const DrawInfo *,const PointInfo *,TypeMetric *, 1415cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy ExceptionInfo *); 1423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 1443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 1463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 1473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 148d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy+ A n n o t a t e C o m p o n e n t G e n e s i s % 149d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% % 150d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% % 151d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% % 152d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 153d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% 154d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% AnnotateComponentGenesis() instantiates the annotate component. 155d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% 156d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% The format of the AnnotateComponentGenesis method is: 157d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% 158d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% MagickBooleanType AnnotateComponentGenesis(void) 159d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% 160d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy*/ 1615ff4eaf57b3cd47d0371f204f865cbba614674a0cristyMagickPrivate MagickBooleanType AnnotateComponentGenesis(void) 162d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy{ 1637c9770650f31145e0fe8811d10b2e0ecd47697c8cristy if (annotate_semaphore == (SemaphoreInfo *) NULL) 1647c9770650f31145e0fe8811d10b2e0ecd47697c8cristy annotate_semaphore=AcquireSemaphoreInfo(); 165d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy return(MagickTrue); 166d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy} 167d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy 168d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy/* 169d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 170d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% % 171d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% % 172d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% % 173d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy+ A n n o t a t e C o m p o n e n t T e r m i n u s % 174d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% % 175d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% % 176d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% % 177d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 178d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% 179d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% AnnotateComponentTerminus() destroys the annotate component. 180d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% 181d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% The format of the AnnotateComponentTerminus method is: 182d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% 183d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% AnnotateComponentTerminus(void) 184d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% 185d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy*/ 1865ff4eaf57b3cd47d0371f204f865cbba614674a0cristyMagickPrivate void AnnotateComponentTerminus(void) 187d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy{ 188d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy if (annotate_semaphore == (SemaphoreInfo *) NULL) 18904b11db5504ecdf205114ae7e9e68774a1ff0b9bcristy ActivateSemaphoreInfo(&annotate_semaphore); 1903d162a93f537cb7cbb6d9fa3b8e73e8f992a527acristy RelinquishSemaphoreInfo(&annotate_semaphore); 191d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy} 192d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy 193d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy/* 194d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 195d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% % 196d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% % 197d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% % 1983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A n n o t a t e I m a g e % 1993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 2003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 2013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 2023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 2043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% AnnotateImage() annotates an image with text. Optionally you can include 2053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% any of the following bits of information about the image by embedding 2063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% the appropriate special characters: 2073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 208528127ac76bc2eda65c7e8407b11669b25513149cristy% \n newline 209528127ac76bc2eda65c7e8407b11669b25513149cristy% \r carriage return 210528127ac76bc2eda65c7e8407b11669b25513149cristy% < less-than character. 211528127ac76bc2eda65c7e8407b11669b25513149cristy% > greater-than character. 212528127ac76bc2eda65c7e8407b11669b25513149cristy% & ampersand character. 213528127ac76bc2eda65c7e8407b11669b25513149cristy% %% a percent sign 214528127ac76bc2eda65c7e8407b11669b25513149cristy% %b file size of image read in 215528127ac76bc2eda65c7e8407b11669b25513149cristy% %c comment meta-data property 216528127ac76bc2eda65c7e8407b11669b25513149cristy% %d directory component of path 217528127ac76bc2eda65c7e8407b11669b25513149cristy% %e filename extension or suffix 218528127ac76bc2eda65c7e8407b11669b25513149cristy% %f filename (including suffix) 219528127ac76bc2eda65c7e8407b11669b25513149cristy% %g layer canvas page geometry (equivalent to "%Wx%H%X%Y") 220528127ac76bc2eda65c7e8407b11669b25513149cristy% %h current image height in pixels 221528127ac76bc2eda65c7e8407b11669b25513149cristy% %i image filename (note: becomes output filename for "info:") 222528127ac76bc2eda65c7e8407b11669b25513149cristy% %k CALCULATED: number of unique colors 223528127ac76bc2eda65c7e8407b11669b25513149cristy% %l label meta-data property 224528127ac76bc2eda65c7e8407b11669b25513149cristy% %m image file format (file magic) 225528127ac76bc2eda65c7e8407b11669b25513149cristy% %n number of images in current image sequence 226528127ac76bc2eda65c7e8407b11669b25513149cristy% %o output filename (used for delegates) 227528127ac76bc2eda65c7e8407b11669b25513149cristy% %p index of image in current image list 228528127ac76bc2eda65c7e8407b11669b25513149cristy% %q quantum depth (compile-time constant) 229528127ac76bc2eda65c7e8407b11669b25513149cristy% %r image class and colorspace 230528127ac76bc2eda65c7e8407b11669b25513149cristy% %s scene number (from input unless re-assigned) 231528127ac76bc2eda65c7e8407b11669b25513149cristy% %t filename without directory or extension (suffix) 232528127ac76bc2eda65c7e8407b11669b25513149cristy% %u unique temporary filename (used for delegates) 233528127ac76bc2eda65c7e8407b11669b25513149cristy% %w current width in pixels 234528127ac76bc2eda65c7e8407b11669b25513149cristy% %x x resolution (density) 235528127ac76bc2eda65c7e8407b11669b25513149cristy% %y y resolution (density) 236528127ac76bc2eda65c7e8407b11669b25513149cristy% %z image depth (as read in unless modified, image save depth) 237528127ac76bc2eda65c7e8407b11669b25513149cristy% %A image transparency channel enabled (true/false) 238528127ac76bc2eda65c7e8407b11669b25513149cristy% %C image compression type 239528127ac76bc2eda65c7e8407b11669b25513149cristy% %D image GIF dispose method 240528127ac76bc2eda65c7e8407b11669b25513149cristy% %G original image size (%wx%h; before any resizes) 241528127ac76bc2eda65c7e8407b11669b25513149cristy% %H page (canvas) height 242528127ac76bc2eda65c7e8407b11669b25513149cristy% %M Magick filename (original file exactly as given, including read mods) 243528127ac76bc2eda65c7e8407b11669b25513149cristy% %O page (canvas) offset ( = %X%Y ) 244528127ac76bc2eda65c7e8407b11669b25513149cristy% %P page (canvas) size ( = %Wx%H ) 245528127ac76bc2eda65c7e8407b11669b25513149cristy% %Q image compression quality ( 0 = default ) 246528127ac76bc2eda65c7e8407b11669b25513149cristy% %S ?? scenes ?? 247528127ac76bc2eda65c7e8407b11669b25513149cristy% %T image time delay (in centi-seconds) 248528127ac76bc2eda65c7e8407b11669b25513149cristy% %U image resolution units 249528127ac76bc2eda65c7e8407b11669b25513149cristy% %W page (canvas) width 250528127ac76bc2eda65c7e8407b11669b25513149cristy% %X page (canvas) x offset (including sign) 251528127ac76bc2eda65c7e8407b11669b25513149cristy% %Y page (canvas) y offset (including sign) 252528127ac76bc2eda65c7e8407b11669b25513149cristy% %Z unique filename (used for delegates) 253528127ac76bc2eda65c7e8407b11669b25513149cristy% %@ CALCULATED: trim bounding box (without actually trimming) 254528127ac76bc2eda65c7e8407b11669b25513149cristy% %# CALCULATED: 'signature' hash of image values 2553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 2563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% The format of the AnnotateImage method is: 2573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 2585cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% MagickBooleanType AnnotateImage(Image *image,DrawInfo *draw_info, 2595cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% ExceptionInfo *exception) 2603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 2613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A description of each parameter follows: 2623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 2633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o image: the image. 2643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 2653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o draw_info: the draw info. 2663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 2675cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% o exception: return any errors or warnings in this structure. 2685cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% 2693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 2703ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport MagickBooleanType AnnotateImage(Image *image, 2715cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy const DrawInfo *draw_info,ExceptionInfo *exception) 2723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 2733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy char 274151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy primitive[MagickPathExtent], 2753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy **textlist; 2763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy DrawInfo 2783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *annotate, 2793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *annotate_info; 2803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy GeometryInfo 2823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy geometry_info; 2833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy MagickBooleanType 2853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy status; 2863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy PointInfo 2883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset; 2893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy RectangleInfo 2913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy geometry; 2923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 293bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy register ssize_t 2943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy i; 2953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy size_t 2973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy length; 2983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy TypeMetric 3003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics; 3013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 302bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy size_t 3035846039e7fade723e168819490eb771446e4b81fcristy height, 3043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy number_lines; 3053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 3063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image != (Image *) NULL); 307e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy assert(image->signature == MagickCoreSignature); 3083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->debug != MagickFalse) 3093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 3103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(draw_info != (DrawInfo *) NULL); 311e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy assert(draw_info->signature == MagickCoreSignature); 3123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (draw_info->text == (char *) NULL) 3133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(MagickFalse); 3143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (*draw_info->text == '\0') 3153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(MagickTrue); 3163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy textlist=StringToList(draw_info->text); 3173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (textlist == (char **) NULL) 3183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(MagickFalse); 3193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy length=strlen(textlist[0]); 3203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (i=1; textlist[i] != (char *) NULL; i++) 3213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (strlen(textlist[i]) > length) 3223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy length=strlen(textlist[i]); 323bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy number_lines=(size_t) i; 3243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate=CloneDrawInfo((ImageInfo *) NULL,draw_info); 3253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info=CloneDrawInfo((ImageInfo *) NULL,draw_info); 3263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy SetGeometry(image,&geometry); 3273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy SetGeometryInfo(&geometry_info); 3283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (annotate_info->geometry != (char *) NULL) 3293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 3303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) ParsePageGeometry(image,annotate_info->geometry,&geometry, 3315cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy exception); 3323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) ParseGeometry(annotate_info->geometry,&geometry_info); 3333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 3345cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse) 3353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(MagickFalse); 336a6400b1cfc3594644a0f02f3d77d920092f078eecristy if (IsGrayColorspace(image->colorspace) != MagickFalse) 3370c81d063030f7b30a97c7856e95534243cdc9e13cristy (void) SetImageColorspace(image,sRGBColorspace,exception); 3383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy status=MagickTrue; 3393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (i=0; textlist[i] != (char *) NULL; i++) 3403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 3413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 3423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Position text relative to image. 3433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 3443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.tx=geometry_info.xi-image->page.x; 3453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.ty=geometry_info.psi-image->page.y; 3463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) CloneString(&annotate->text,textlist[i]); 3475cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy (void) GetTypeMetrics(image,annotate,&metrics,exception); 348bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy height=(ssize_t) (metrics.ascent-metrics.descent+ 3495846039e7fade723e168819490eb771446e4b81fcristy draw_info->interline_spacing+0.5); 3503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy switch (annotate->gravity) 3513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 3523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case UndefinedGravity: 3533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy default: 3543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 3553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.x=annotate_info->affine.tx+i*annotate_info->affine.ry*height; 3563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.y=annotate_info->affine.ty+i*annotate_info->affine.sy*height; 3573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 3583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 3593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case NorthWestGravity: 3603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 3613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.x=(geometry.width == 0 ? -1.0 : 1.0)*annotate_info->affine.tx+i* 3623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.ry*height+annotate_info->affine.ry* 3633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (metrics.ascent+metrics.descent); 3643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.y=(geometry.height == 0 ? -1.0 : 1.0)*annotate_info->affine.ty+i* 3653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.sy*height+annotate_info->affine.sy* 3663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics.ascent; 3673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 3683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 3693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case NorthGravity: 3703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 3713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.x=(geometry.width == 0 ? -1.0 : 1.0)*annotate_info->affine.tx+ 3723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy geometry.width/2.0+i*annotate_info->affine.ry*height- 3733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.sx*(metrics.width+metrics.bounds.x1)/2.0+ 3743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.ry*(metrics.ascent+metrics.descent); 3753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.y=(geometry.height == 0 ? -1.0 : 1.0)*annotate_info->affine.ty+i* 3763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.sy*height+annotate_info->affine.sy* 3773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics.ascent-annotate_info->affine.rx*(metrics.width- 3783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics.bounds.x1)/2.0; 3793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 3803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 3813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case NorthEastGravity: 3823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 3833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.x=(geometry.width == 0 ? 1.0 : -1.0)*annotate_info->affine.tx+ 3843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy geometry.width+i*annotate_info->affine.ry*height- 3853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.sx*(metrics.width+metrics.bounds.x1)+ 3863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.ry*(metrics.ascent+metrics.descent)-1.0; 3873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.y=(geometry.height == 0 ? -1.0 : 1.0)*annotate_info->affine.ty+i* 3883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.sy*height+annotate_info->affine.sy* 3893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics.ascent-annotate_info->affine.rx*(metrics.width- 3903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics.bounds.x1); 3913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 3923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 3933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case WestGravity: 3943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 3953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.x=(geometry.width == 0 ? -1.0 : 1.0)*annotate_info->affine.tx+i* 3963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.ry*height+annotate_info->affine.ry* 3973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (metrics.ascent+metrics.descent-(number_lines-1.0)*height)/2.0; 3983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.y=(geometry.height == 0 ? -1.0 : 1.0)*annotate_info->affine.ty+ 3993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy geometry.height/2.0+i*annotate_info->affine.sy*height+ 4003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.sy*(metrics.ascent+metrics.descent- 4017096f1cf18bfd18730112b4783146547a97854dacristy (number_lines-1.0)*height)/2.0+metrics.descent/2.0; 4023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 4033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 4043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case CenterGravity: 4053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 4063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.x=(geometry.width == 0 ? -1.0 : 1.0)*annotate_info->affine.tx+ 4073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy geometry.width/2.0+i*annotate_info->affine.ry*height- 4083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.sx*(metrics.width+metrics.bounds.x1)/2.0+ 4093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.ry*(metrics.ascent+metrics.descent- 4103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (number_lines-1)*height)/2.0; 4113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.y=(geometry.height == 0 ? -1.0 : 1.0)*annotate_info->affine.ty+ 4123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy geometry.height/2.0+i*annotate_info->affine.sy*height- 4133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.rx*(metrics.width+metrics.bounds.x1)/2.0+ 4143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.sy*(metrics.ascent+metrics.descent- 41570aa59ba920fd758a05dfd1e59a446638b3dd2a9Cristy (number_lines-1.0)*height)/2.0; 4163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 4173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 4183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case EastGravity: 4193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 4203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.x=(geometry.width == 0 ? 1.0 : -1.0)*annotate_info->affine.tx+ 4213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy geometry.width+i*annotate_info->affine.ry*height- 4223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.sx*(metrics.width+metrics.bounds.x1)+ 4233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.ry*(metrics.ascent+metrics.descent- 4243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (number_lines-1.0)*height)/2.0-1.0; 4253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.y=(geometry.height == 0 ? -1.0 : 1.0)*annotate_info->affine.ty+ 4263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy geometry.height/2.0+i*annotate_info->affine.sy*height- 4273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.rx*(metrics.width+metrics.bounds.x1)+ 4283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.sy*(metrics.ascent+metrics.descent- 4297096f1cf18bfd18730112b4783146547a97854dacristy (number_lines-1.0)*height)/2.0+metrics.descent/2.0; 4303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 4313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 4323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case SouthWestGravity: 4333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 4343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.x=(geometry.width == 0 ? -1.0 : 1.0)*annotate_info->affine.tx+i* 4353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.ry*height-annotate_info->affine.ry* 4363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (number_lines-1.0)*height; 4373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.y=(geometry.height == 0 ? 1.0 : -1.0)*annotate_info->affine.ty+ 4383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy geometry.height+i*annotate_info->affine.sy*height- 4393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.sy*(number_lines-1.0)*height+metrics.descent; 4403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 4413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 4423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case SouthGravity: 4433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 4443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.x=(geometry.width == 0 ? -1.0 : 1.0)*annotate_info->affine.tx+ 4453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy geometry.width/2.0+i*annotate_info->affine.ry*height- 4463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.sx*(metrics.width+metrics.bounds.x1)/2.0- 4473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.ry*(number_lines-1.0)*height/2.0; 4483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.y=(geometry.height == 0 ? 1.0 : -1.0)*annotate_info->affine.ty+ 4493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy geometry.height+i*annotate_info->affine.sy*height- 4503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.rx*(metrics.width+metrics.bounds.x1)/2.0- 4513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.sy*(number_lines-1.0)*height+metrics.descent; 4523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 4533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 4543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case SouthEastGravity: 4553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 4563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.x=(geometry.width == 0 ? 1.0 : -1.0)*annotate_info->affine.tx+ 4573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy geometry.width+i*annotate_info->affine.ry*height- 4583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.sx*(metrics.width+metrics.bounds.x1)- 4593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.ry*(number_lines-1.0)*height-1.0; 4603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.y=(geometry.height == 0 ? 1.0 : -1.0)*annotate_info->affine.ty+ 4613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy geometry.height+i*annotate_info->affine.sy*height- 4623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.rx*(metrics.width+metrics.bounds.x1)- 4633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.sy*(number_lines-1.0)*height+metrics.descent; 4643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 4653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 4663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 4673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy switch (annotate->align) 4683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 4693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case LeftAlign: 4703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 4713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.x=annotate_info->affine.tx+i*annotate_info->affine.ry*height; 4723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.y=annotate_info->affine.ty+i*annotate_info->affine.sy*height; 4733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 4743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 4753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case CenterAlign: 4763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 4773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.x=annotate_info->affine.tx+i*annotate_info->affine.ry*height- 4783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.sx*(metrics.width+metrics.bounds.x1)/2.0; 4793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.y=annotate_info->affine.ty+i*annotate_info->affine.sy*height- 4803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.rx*(metrics.width+metrics.bounds.x1)/2.0; 4813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 4823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 4833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case RightAlign: 4843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 4853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.x=annotate_info->affine.tx+i*annotate_info->affine.ry*height- 4863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.sx*(metrics.width+metrics.bounds.x1); 4873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.y=annotate_info->affine.ty+i*annotate_info->affine.sy*height- 4883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.rx*(metrics.width+metrics.bounds.x1); 4893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 4903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 4913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy default: 4923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 4933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 4944c08aed51c5899665ade97263692328eea4af106cristy if (draw_info->undercolor.alpha != TransparentAlpha) 4953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 4963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy DrawInfo 4973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *undercolor_info; 4983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 4993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 5003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Text box. 5013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 5023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy undercolor_info=CloneDrawInfo((ImageInfo *) NULL,(DrawInfo *) NULL); 5033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy undercolor_info->fill=draw_info->undercolor; 5043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy undercolor_info->affine=draw_info->affine; 5053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy undercolor_info->affine.tx=offset.x-draw_info->affine.ry*metrics.ascent; 5063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy undercolor_info->affine.ty=offset.y-draw_info->affine.sy*metrics.ascent; 507151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy (void) FormatLocaleString(primitive,MagickPathExtent, 508dcc02b0a70d924b55afa7ce2089c4c15b25f2e1fcristy "rectangle 0.0,0.0 %g,%g",metrics.origin.x,(double) height); 5093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) CloneString(&undercolor_info->primitive,primitive); 510018f07f7333b25743d0afff892450cebdb905c1acristy (void) DrawImage(image,undercolor_info,exception); 5113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) DestroyDrawInfo(undercolor_info); 5123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 5133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.tx=offset.x; 5143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.ty=offset.y; 515151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy (void) FormatLocaleString(primitive,MagickPathExtent,"stroke-width %g " 516a8549b176173db7680652304c372c64bb1a51737cristy "line 0,0 %g,0",metrics.underline_thickness,metrics.width); 5173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (annotate->decorate == OverlineDecoration) 5183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 5193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.ty-=(draw_info->affine.sy*(metrics.ascent+ 5203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics.descent-metrics.underline_position)); 5213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) CloneString(&annotate_info->primitive,primitive); 522018f07f7333b25743d0afff892450cebdb905c1acristy (void) DrawImage(image,annotate_info,exception); 5233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 5243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 5253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (annotate->decorate == UnderlineDecoration) 5263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 5273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.ty-=(draw_info->affine.sy* 5283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics.underline_position); 5293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) CloneString(&annotate_info->primitive,primitive); 530018f07f7333b25743d0afff892450cebdb905c1acristy (void) DrawImage(image,annotate_info,exception); 5313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 5323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 5333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Annotate image with text. 5343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 5355cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy status=RenderType(image,annotate,&offset,&metrics,exception); 5363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (status == MagickFalse) 5373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 5383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (annotate->decorate == LineThroughDecoration) 5393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 5403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.ty-=(draw_info->affine.sy*(height+ 5413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics.underline_position+metrics.descent)/2.0); 5423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) CloneString(&annotate_info->primitive,primitive); 543018f07f7333b25743d0afff892450cebdb905c1acristy (void) DrawImage(image,annotate_info,exception); 5443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 5453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 5463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 5473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Relinquish resources. 5483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 5493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info=DestroyDrawInfo(annotate_info); 5503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate=DestroyDrawInfo(annotate); 5513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (i=0; textlist[i] != (char *) NULL; i++) 5523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy textlist[i]=DestroyString(textlist[i]); 5533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy textlist=(char **) RelinquishMagickMemory(textlist); 5543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(status); 5553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 5563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 5573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 5583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 5603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 5613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 5623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% F o r m a t M a g i c k C a p t i o n % 5633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 5643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 5653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 5663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 5683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% FormatMagickCaption() formats a caption so that it fits within the image 5693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% width. It returns the number of lines in the formatted caption. 5703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 5713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% The format of the FormatMagickCaption method is: 5723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 573bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy% ssize_t FormatMagickCaption(Image *image,DrawInfo *draw_info, 5745cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% const MagickBooleanType split,TypeMetric *metrics,char **caption, 5755cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% ExceptionInfo *exception) 5763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 5773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A description of each parameter follows. 5783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 5793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o image: The image. 5803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 5813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o draw_info: the draw info. 5823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 5836b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy% o split: when no convenient line breaks-- insert newline. 5846b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy% 5853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o metrics: Return the font metrics in this structure. 5863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 5876b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy% o caption: the caption. 5886b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy% 5895cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% o exception: return any errors or warnings in this structure. 5905cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% 5913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 592bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristyMagickExport ssize_t FormatMagickCaption(Image *image,DrawInfo *draw_info, 5935cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy const MagickBooleanType split,TypeMetric *metrics,char **caption, 5945cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy ExceptionInfo *exception) 5953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 59674966dbfe99011d1f7bea577e97a3d9a7b9836c7cristy char 59774966dbfe99011d1f7bea577e97a3d9a7b9836c7cristy *text; 59874966dbfe99011d1f7bea577e97a3d9a7b9836c7cristy 5993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy MagickBooleanType 60020aa2994f8d56f6f03a7a96b2a25d93b906989bcCristy digit, 6013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy status; 6023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 6033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy register char 6043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *p, 6053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *q, 6063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *s; 6073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 608bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy register ssize_t 6093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy i; 6103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 611bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy size_t 6123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy width; 6133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 6146193b86c0b59030b647a10c75f37ec82d73e3695cristy ssize_t 6156193b86c0b59030b647a10c75f37ec82d73e3695cristy n; 6166193b86c0b59030b647a10c75f37ec82d73e3695cristy 61720aa2994f8d56f6f03a7a96b2a25d93b906989bcCristy digit=MagickFalse; 61874966dbfe99011d1f7bea577e97a3d9a7b9836c7cristy text=AcquireString(draw_info->text); 6193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy q=draw_info->text; 6203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy s=(char *) NULL; 6213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (p=(*caption); GetUTFCode(p) != 0; p+=GetUTFOctets(p)) 6223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 62320aa2994f8d56f6f03a7a96b2a25d93b906989bcCristy if ((digit == MagickFalse) && (IsUTFSpace(GetUTFCode(p)) != MagickFalse)) 6243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy s=p; 62520aa2994f8d56f6f03a7a96b2a25d93b906989bcCristy digit=((GetUTFCode(p) >= 0x0030) && (GetUTFCode(p) <= 0x0039)) ? 62620aa2994f8d56f6f03a7a96b2a25d93b906989bcCristy MagickTrue : MagickFalse; 6272911f2d54257d36e1086061dbcc312fdad781070cristy if (GetUTFCode(p) == '\n') 628e2c81adf02cbe4bb92991389437a2a1daf8ed313cristy q=draw_info->text; 629bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (i=0; i < (ssize_t) GetUTFOctets(p); i++) 6303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *q++=(*(p+i)); 6313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *q='\0'; 6325cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy status=GetTypeMetrics(image,draw_info,metrics,exception); 6333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (status == MagickFalse) 6343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 63578fed5ea9a7f0a35e641ce3bc6f835fb099c4d20cristy width=(size_t) floor(metrics->width+draw_info->stroke_width+0.5); 63674966dbfe99011d1f7bea577e97a3d9a7b9836c7cristy if ((width <= image->columns) || (strcmp(text,draw_info->text) == 0)) 6376193b86c0b59030b647a10c75f37ec82d73e3695cristy continue; 63874966dbfe99011d1f7bea577e97a3d9a7b9836c7cristy (void) strcpy(text,draw_info->text); 6394aa314e7f9e09c30fcedcd112156b1dfb712b62dcristy if ((s != (char *) NULL) && (GetUTFOctets(s) == 1)) 6403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 6413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *s='\n'; 6423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy p=s; 6433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 6443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 6454aa314e7f9e09c30fcedcd112156b1dfb712b62dcristy if ((s != (char *) NULL) || (split != MagickFalse)) 6466b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy { 6476b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy char 6486b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy *target; 6493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 6506b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy /* 6516b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy No convenient line breaks-- insert newline. 6526b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy */ 6536b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy target=AcquireString(*caption); 6546b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy n=p-(*caption); 6556b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy CopyMagickString(target,*caption,n+1); 6566b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy ConcatenateMagickString(target,"\n",strlen(*caption)+1); 6576b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy ConcatenateMagickString(target,p,strlen(*caption)+2); 6586b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy (void) DestroyString(*caption); 6596b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy *caption=target; 6606b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy p=(*caption)+n; 6616b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy } 6623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy q=draw_info->text; 6636193b86c0b59030b647a10c75f37ec82d73e3695cristy s=(char *) NULL; 6643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 66574966dbfe99011d1f7bea577e97a3d9a7b9836c7cristy text=DestroyString(text); 6666193b86c0b59030b647a10c75f37ec82d73e3695cristy n=0; 6673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (p=(*caption); GetUTFCode(p) != 0; p+=GetUTFOctets(p)) 6683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (GetUTFCode(p) == '\n') 6696193b86c0b59030b647a10c75f37ec82d73e3695cristy n++; 6706193b86c0b59030b647a10c75f37ec82d73e3695cristy return(n); 6713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 6723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 6733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 6743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 6763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 6773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 6783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% G e t M u l t i l i n e T y p e M e t r i c s % 6793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 6803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 6813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 6823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 6843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% GetMultilineTypeMetrics() returns the following information for the 6853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% specified font and text: 6863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 6873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% character width 6883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% character height 6893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% ascender 6903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% descender 6913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% text width 6923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% text height 6933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% maximum horizontal advance 6943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% bounds: x1 6953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% bounds: y1 6963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% bounds: x2 6973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% bounds: y2 6983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% origin: x 6993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% origin: y 7003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% underline position 7013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% underline thickness 7023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 7033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% This method is like GetTypeMetrics() but it returns the maximum text width 7043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% and height for multiple lines of text. 7053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 7063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% The format of the GetMultilineTypeMetrics method is: 7073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 7083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% MagickBooleanType GetMultilineTypeMetrics(Image *image, 7095cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% const DrawInfo *draw_info,TypeMetric *metrics,ExceptionInfo *exception) 7103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 7113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A description of each parameter follows: 7123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 7133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o image: the image. 7143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 7153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o draw_info: the draw info. 7163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 7173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o metrics: Return the font metrics in this structure. 7183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 7195cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% o exception: return any errors or warnings in this structure. 7205cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% 7213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 7223ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport MagickBooleanType GetMultilineTypeMetrics(Image *image, 7235cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy const DrawInfo *draw_info,TypeMetric *metrics,ExceptionInfo *exception) 7243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 7253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy char 7263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy **textlist; 7273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy DrawInfo 7293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *annotate_info; 7303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy MagickBooleanType 7323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy status; 7333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 734bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy register ssize_t 7353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy i; 7363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy TypeMetric 7383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy extent; 7393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image != (Image *) NULL); 741e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy assert(image->signature == MagickCoreSignature); 7423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->debug != MagickFalse) 7433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 7443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(draw_info != (DrawInfo *) NULL); 7453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(draw_info->text != (char *) NULL); 746e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy assert(draw_info->signature == MagickCoreSignature); 7473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (*draw_info->text == '\0') 7483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(MagickFalse); 7493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info=CloneDrawInfo((ImageInfo *) NULL,draw_info); 7503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->text=DestroyString(annotate_info->text); 7513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 7523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Convert newlines to multiple lines of text. 7533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 7543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy textlist=StringToList(draw_info->text); 7553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (textlist == (char **) NULL) 7563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(MagickFalse); 7573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->render=MagickFalse; 758024843f38984cd26602f0b3b28a0768dfa056bb5cristy annotate_info->direction=UndefinedDirection; 7593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) ResetMagickMemory(metrics,0,sizeof(*metrics)); 7603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) ResetMagickMemory(&extent,0,sizeof(extent)); 7613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 7623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Find the widest of the text lines. 7633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 7643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->text=textlist[0]; 7655cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy status=GetTypeMetrics(image,annotate_info,&extent,exception); 7663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *metrics=extent; 7673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (i=1; textlist[i] != (char *) NULL; i++) 7683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 7693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->text=textlist[i]; 7705cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy status=GetTypeMetrics(image,annotate_info,&extent,exception); 7713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (extent.width > metrics->width) 7723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *metrics=extent; 7733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 774e2c81adf02cbe4bb92991389437a2a1daf8ed313cristy metrics->height=(double) (i*(size_t) (metrics->ascent-metrics->descent+0.5)+ 775e2c81adf02cbe4bb92991389437a2a1daf8ed313cristy (i-1)*draw_info->interline_spacing); 7763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 7773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Relinquish resources. 7783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 7793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->text=(char *) NULL; 7803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info=DestroyDrawInfo(annotate_info); 7813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (i=0; textlist[i] != (char *) NULL; i++) 7823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy textlist[i]=DestroyString(textlist[i]); 7833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy textlist=(char **) RelinquishMagickMemory(textlist); 7843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(status); 7853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 7863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 7883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 7893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 7903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 7913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 7923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% G e t T y p e M e t r i c s % 7933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 7943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 7953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 7963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 7973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 7983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% GetTypeMetrics() returns the following information for the specified font 7993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% and text: 8003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 8013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% character width 8023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% character height 8033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% ascender 8043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% descender 8053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% text width 8063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% text height 8073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% maximum horizontal advance 8083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% bounds: x1 8093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% bounds: y1 8103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% bounds: x2 8113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% bounds: y2 8123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% origin: x 8133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% origin: y 8143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% underline position 8153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% underline thickness 8163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 8173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% The format of the GetTypeMetrics method is: 8183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 8193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% MagickBooleanType GetTypeMetrics(Image *image,const DrawInfo *draw_info, 8205cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% TypeMetric *metrics,ExceptionInfo *exception) 8213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 8223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A description of each parameter follows: 8233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 8243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o image: the image. 8253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 8263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o draw_info: the draw info. 8273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 8283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o metrics: Return the font metrics in this structure. 8293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 8305cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% o exception: return any errors or warnings in this structure. 8315cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% 8323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 8333ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport MagickBooleanType GetTypeMetrics(Image *image, 8345cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy const DrawInfo *draw_info,TypeMetric *metrics,ExceptionInfo *exception) 8353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 8363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy DrawInfo 8373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *annotate_info; 8383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 8393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy MagickBooleanType 8403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy status; 8413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 8423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy PointInfo 8433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset; 8443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 8453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image != (Image *) NULL); 846e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy assert(image->signature == MagickCoreSignature); 8473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->debug != MagickFalse) 8483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 8493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(draw_info != (DrawInfo *) NULL); 8503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(draw_info->text != (char *) NULL); 851e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy assert(draw_info->signature == MagickCoreSignature); 8523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info=CloneDrawInfo((ImageInfo *) NULL,draw_info); 8533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->render=MagickFalse; 854024843f38984cd26602f0b3b28a0768dfa056bb5cristy annotate_info->direction=UndefinedDirection; 8553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) ResetMagickMemory(metrics,0,sizeof(*metrics)); 8563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.x=0.0; 8573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.y=0.0; 8585cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy status=RenderType(image,annotate_info,&offset,metrics,exception); 8593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->debug != MagickFalse) 8603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) LogMagickEvent(AnnotateEvent,GetMagickModule(),"Metrics: text: %s; " 861e7f5109f30fc7242d04a26174a9138483dda5b6acristy "width: %g; height: %g; ascent: %g; descent: %g; max advance: %g; " 862a8549b176173db7680652304c372c64bb1a51737cristy "bounds: %g,%g %g,%g; origin: %g,%g; pixels per em: %g,%g; " 863e7f5109f30fc7242d04a26174a9138483dda5b6acristy "underline position: %g; underline thickness: %g",annotate_info->text, 8643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->width,metrics->height,metrics->ascent,metrics->descent, 8653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->max_advance,metrics->bounds.x1,metrics->bounds.y1, 8664c08aed51c5899665ade97263692328eea4af106cristy metrics->bounds.x2,metrics->bounds.y2,metrics->origin.x,metrics->origin.y, 8674c08aed51c5899665ade97263692328eea4af106cristy metrics->pixels_per_em.x,metrics->pixels_per_em.y, 8683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->underline_position,metrics->underline_thickness); 8693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info=DestroyDrawInfo(annotate_info); 8703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(status); 8713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 8723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 8733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 8743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 8753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 8763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 8773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 8783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy+ R e n d e r T y p e % 8793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 8803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 8813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 8823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 8833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 8843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% RenderType() renders text on the image. It also returns the bounding box of 8853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% the text relative to the image. 8863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 8873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% The format of the RenderType method is: 8883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 8893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% MagickBooleanType RenderType(Image *image,DrawInfo *draw_info, 8905cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% const PointInfo *offset,TypeMetric *metrics,ExceptionInfo *exception) 8913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 8923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A description of each parameter follows: 8933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 8943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o image: the image. 8953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 8963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o draw_info: the draw info. 8973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 8983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o offset: (x,y) location of text relative to image. 8993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 9003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o metrics: bounding box of text. 9013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 9025cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% o exception: return any errors or warnings in this structure. 9035cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% 9043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 9053ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType RenderType(Image *image,const DrawInfo *draw_info, 9065cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy const PointInfo *offset,TypeMetric *metrics,ExceptionInfo *exception) 9073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 9083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const TypeInfo 9093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *type_info; 9103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 9113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy DrawInfo 9123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *annotate_info; 9133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 9143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy MagickBooleanType 9153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy status; 9163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 9173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy type_info=(const TypeInfo *) NULL; 9183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (draw_info->font != (char *) NULL) 9193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 9203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (*draw_info->font == '@') 9213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 9223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy status=RenderFreetype(image,draw_info,draw_info->encoding,offset, 9235cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy metrics,exception); 9243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(status); 9253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 9263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (*draw_info->font == '-') 9275cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy return(RenderX11(image,draw_info,offset,metrics,exception)); 9283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (IsPathAccessible(draw_info->font) != MagickFalse) 9293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 9303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy status=RenderFreetype(image,draw_info,draw_info->encoding,offset, 9315cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy metrics,exception); 9323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(status); 9333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 9345cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy type_info=GetTypeInfo(draw_info->font,exception); 9353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (type_info == (const TypeInfo *) NULL) 9365cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy (void) ThrowMagickException(exception,GetMagickModule(),TypeWarning, 937efe601ce9ea5ad34ad0e8ad6e61d9be9b148b2a3cristy "UnableToReadFont","`%s'",draw_info->font); 9383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 9393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if ((type_info == (const TypeInfo *) NULL) && 9403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (draw_info->family != (const char *) NULL)) 9413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 9423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy type_info=GetTypeInfoByFamily(draw_info->family,draw_info->style, 9435cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy draw_info->stretch,draw_info->weight,exception); 9443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (type_info == (const TypeInfo *) NULL) 9455cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy (void) ThrowMagickException(exception,GetMagickModule(),TypeWarning, 946efe601ce9ea5ad34ad0e8ad6e61d9be9b148b2a3cristy "UnableToReadFont","`%s'",draw_info->family); 9473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 9483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (type_info == (const TypeInfo *) NULL) 949d984f27fbbb96073787c88f4c9409d7f836cedc5cristy type_info=GetTypeInfoByFamily("Arial",draw_info->style, 9505cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy draw_info->stretch,draw_info->weight,exception); 951d984f27fbbb96073787c88f4c9409d7f836cedc5cristy if (type_info == (const TypeInfo *) NULL) 952cbb34a4def108d6db032ca9631a433afd3ea5a5dcristy type_info=GetTypeInfoByFamily("Helvetica",draw_info->style, 9535cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy draw_info->stretch,draw_info->weight,exception); 9543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (type_info == (const TypeInfo *) NULL) 955704acaaebbfeec018847456e79de0ce301db126ecristy type_info=GetTypeInfoByFamily("Century Schoolbook",draw_info->style, 9565cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy draw_info->stretch,draw_info->weight,exception); 957704acaaebbfeec018847456e79de0ce301db126ecristy if (type_info == (const TypeInfo *) NULL) 9586193b86c0b59030b647a10c75f37ec82d73e3695cristy type_info=GetTypeInfoByFamily("Sans",draw_info->style, 9595cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy draw_info->stretch,draw_info->weight,exception); 9606193b86c0b59030b647a10c75f37ec82d73e3695cristy if (type_info == (const TypeInfo *) NULL) 9613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy type_info=GetTypeInfoByFamily((const char *) NULL,draw_info->style, 9625cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy draw_info->stretch,draw_info->weight,exception); 9633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (type_info == (const TypeInfo *) NULL) 9645cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy type_info=GetTypeInfo("*",exception); 965704acaaebbfeec018847456e79de0ce301db126ecristy if (type_info == (const TypeInfo *) NULL) 9663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 9675cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy status=RenderFreetype(image,draw_info,draw_info->encoding,offset,metrics, 9685cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy exception); 9693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(status); 9703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 9713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info=CloneDrawInfo((ImageInfo *) NULL,draw_info); 9723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->face=type_info->face; 9733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (type_info->metrics != (char *) NULL) 9743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) CloneString(&annotate_info->metrics,type_info->metrics); 9753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (type_info->glyphs != (char *) NULL) 9763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) CloneString(&annotate_info->font,type_info->glyphs); 9775cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy status=RenderFreetype(image,annotate_info,type_info->encoding,offset,metrics, 9785cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy exception); 9793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info=DestroyDrawInfo(annotate_info); 9803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(status); 9813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 9823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 9833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 9843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 9853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 9863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 9873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 9883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy+ R e n d e r F r e e t y p e % 9893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 9903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 9913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 9923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 9933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 9943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% RenderFreetype() renders text on the image with a Truetype font. It also 9953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% returns the bounding box of the text relative to the image. 9963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 9973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% The format of the RenderFreetype method is: 9983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 9993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% MagickBooleanType RenderFreetype(Image *image,DrawInfo *draw_info, 10005cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% const char *encoding,const PointInfo *offset,TypeMetric *metrics, 10015cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% ExceptionInfo *exception) 10023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 10033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A description of each parameter follows: 10043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 10053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o image: the image. 10063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 10073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o draw_info: the draw info. 10083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 10093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o encoding: the font encoding. 10103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 10113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o offset: (x,y) location of text relative to image. 10123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 10133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o metrics: bounding box of text. 10143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 10155cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% o exception: return any errors or warnings in this structure. 10165cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% 10173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 10183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 10193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_FREETYPE_DELEGATE) 10202857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy 102187dc5e4e6f9471304ba85f508de30e664b484d3aCristystatic size_t ComplexTextLayout(const Image *image,const DrawInfo *draw_info, 102287dc5e4e6f9471304ba85f508de30e664b484d3aCristy const char *text,const size_t length,const FT_Face face,const FT_Int32 flags, 102387dc5e4e6f9471304ba85f508de30e664b484d3aCristy GraphemeInfo **grapheme,ExceptionInfo *exception) 102469a0d3b5699c573f650e6b61f98ce4579d6f218cCristy{ 102517f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy#if defined(MAGICKCORE_RAQM_DELEGATE) 10260d88ea3545d808eae9feeacdd57eec41db18d2baCristy const char 10270d88ea3545d808eae9feeacdd57eec41db18d2baCristy *features; 10280d88ea3545d808eae9feeacdd57eec41db18d2baCristy 102917f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy raqm_t 103017f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy *rq; 103117f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy 103217f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy raqm_glyph_t 103317f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy *glyphs; 103417f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy 103587dc5e4e6f9471304ba85f508de30e664b484d3aCristy register size_t 103687dc5e4e6f9471304ba85f508de30e664b484d3aCristy i; 103787dc5e4e6f9471304ba85f508de30e664b484d3aCristy 10386720ed7fdc6908b46f213f43c316fcccab53dbcdCristy size_t 10396720ed7fdc6908b46f213f43c316fcccab53dbcdCristy extent; 104087dc5e4e6f9471304ba85f508de30e664b484d3aCristy 10416720ed7fdc6908b46f213f43c316fcccab53dbcdCristy extent=0; 10420d88ea3545d808eae9feeacdd57eec41db18d2baCristy rq=raqm_create(); 104317f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy if (rq == (raqm_t *) NULL) 104417f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy goto cleanup; 10450d88ea3545d808eae9feeacdd57eec41db18d2baCristy if (raqm_set_text_utf8(rq,text,length) == 0) 104617f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy goto cleanup; 104787dc5e4e6f9471304ba85f508de30e664b484d3aCristy if (raqm_set_par_direction(rq,(raqm_direction_t) draw_info->direction) == 0) 104817f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy goto cleanup; 10490d88ea3545d808eae9feeacdd57eec41db18d2baCristy if (raqm_set_freetype_face(rq,face) == 0) 105017f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy goto cleanup; 10510d88ea3545d808eae9feeacdd57eec41db18d2baCristy features=GetImageProperty(image,"type:features",exception); 10520d88ea3545d808eae9feeacdd57eec41db18d2baCristy if (features != (const char *) NULL) 105317f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy { 105417f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy char 105517f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy breaker, 105617f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy quote, 105717f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy *token; 105817f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy 105917f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy int 106017f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy next, 106117f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy status_token; 106217f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy 106387dc5e4e6f9471304ba85f508de30e664b484d3aCristy TokenInfo 106487dc5e4e6f9471304ba85f508de30e664b484d3aCristy *token_info; 106587dc5e4e6f9471304ba85f508de30e664b484d3aCristy 106617f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy next=0; 106717f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy token_info=AcquireTokenInfo(); 106887dc5e4e6f9471304ba85f508de30e664b484d3aCristy token=AcquireString(""); 10690d88ea3545d808eae9feeacdd57eec41db18d2baCristy status_token=Tokenizer(token_info,0,token,50,features,"",",","",'\0', 10700d88ea3545d808eae9feeacdd57eec41db18d2baCristy &breaker,&next,"e); 107117f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy while (status_token == 0) 10720d88ea3545d808eae9feeacdd57eec41db18d2baCristy { 10730d88ea3545d808eae9feeacdd57eec41db18d2baCristy raqm_add_font_feature(rq,token,strlen(token)); 10740d88ea3545d808eae9feeacdd57eec41db18d2baCristy status_token=Tokenizer(token_info,0,token,50,features,"",",","",'\0', 10750d88ea3545d808eae9feeacdd57eec41db18d2baCristy &breaker,&next,"e); 10760d88ea3545d808eae9feeacdd57eec41db18d2baCristy } 107717f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy token_info=DestroyTokenInfo(token_info); 107817f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy token=DestroyString(token); 107917f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy } 10800d88ea3545d808eae9feeacdd57eec41db18d2baCristy if (raqm_layout(rq) == 0) 108117f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy goto cleanup; 10826720ed7fdc6908b46f213f43c316fcccab53dbcdCristy glyphs=raqm_get_glyphs(rq,&extent); 108317f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy if (glyphs == (raqm_glyph_t *) NULL) 108417f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy { 10856720ed7fdc6908b46f213f43c316fcccab53dbcdCristy extent=0; 108617f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy goto cleanup; 108717f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy } 10886720ed7fdc6908b46f213f43c316fcccab53dbcdCristy *grapheme=(GraphemeInfo *) AcquireQuantumMemory(extent,sizeof(**grapheme)); 108917f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy if (*grapheme == (GraphemeInfo *) NULL) 109017f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy { 10916720ed7fdc6908b46f213f43c316fcccab53dbcdCristy extent=0; 109217f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy goto cleanup; 109317f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy } 10946720ed7fdc6908b46f213f43c316fcccab53dbcdCristy for (i=0; i < (ssize_t) extent; i++) 10950d88ea3545d808eae9feeacdd57eec41db18d2baCristy { 10960d88ea3545d808eae9feeacdd57eec41db18d2baCristy (*grapheme)[i].index=glyphs[i].index; 10970d88ea3545d808eae9feeacdd57eec41db18d2baCristy (*grapheme)[i].x_offset=glyphs[i].x_offset; 10980d88ea3545d808eae9feeacdd57eec41db18d2baCristy (*grapheme)[i].x_advance=glyphs[i].x_advance; 10990d88ea3545d808eae9feeacdd57eec41db18d2baCristy (*grapheme)[i].y_offset=glyphs[i].y_offset; 11000d88ea3545d808eae9feeacdd57eec41db18d2baCristy (*grapheme)[i].cluster=glyphs[i].cluster; 11010d88ea3545d808eae9feeacdd57eec41db18d2baCristy } 110217f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy 110317f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristycleanup: 11040d88ea3545d808eae9feeacdd57eec41db18d2baCristy raqm_destroy(rq); 11056720ed7fdc6908b46f213f43c316fcccab53dbcdCristy return(extent); 110614c8ae4cf8fdcb1c1ed0f8fd1a5c3290414fe733Cristy#else 110787dc5e4e6f9471304ba85f508de30e664b484d3aCristy const char 110887dc5e4e6f9471304ba85f508de30e664b484d3aCristy *p; 110987dc5e4e6f9471304ba85f508de30e664b484d3aCristy 111069a0d3b5699c573f650e6b61f98ce4579d6f218cCristy FT_Error 111169a0d3b5699c573f650e6b61f98ce4579d6f218cCristy ft_status; 111269a0d3b5699c573f650e6b61f98ce4579d6f218cCristy 111369a0d3b5699c573f650e6b61f98ce4579d6f218cCristy register ssize_t 111469a0d3b5699c573f650e6b61f98ce4579d6f218cCristy i; 111569a0d3b5699c573f650e6b61f98ce4579d6f218cCristy 111669a0d3b5699c573f650e6b61f98ce4579d6f218cCristy ssize_t 111769a0d3b5699c573f650e6b61f98ce4579d6f218cCristy last_glyph; 111869a0d3b5699c573f650e6b61f98ce4579d6f218cCristy 111991c2741e03e3e692f6fe04eb02d059edbc0edb90Cristy /* 11209da9d9c28f5574cc630eb8d8a48186f4951c4e33Cristy Simple layout for bi-directional text (right-to-left or left-to-right). 112191c2741e03e3e692f6fe04eb02d059edbc0edb90Cristy */ 11220d88ea3545d808eae9feeacdd57eec41db18d2baCristy *grapheme=(GraphemeInfo *) AcquireQuantumMemory(length+1,sizeof(**grapheme)); 112317f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy if (*grapheme == (GraphemeInfo *) NULL) 112469a0d3b5699c573f650e6b61f98ce4579d6f218cCristy return(0); 112569a0d3b5699c573f650e6b61f98ce4579d6f218cCristy last_glyph=0; 1126d45bfbb9ef2f6b90eb038b56d1a416b59c68abe0shamsa p=text; 1127d45bfbb9ef2f6b90eb038b56d1a416b59c68abe0shamsa for (i=0; GetUTFCode(p) != 0; p+=GetUTFOctets(p), i++) 112869a0d3b5699c573f650e6b61f98ce4579d6f218cCristy { 112987dc5e4e6f9471304ba85f508de30e664b484d3aCristy (*grapheme)[i].index=(ssize_t) FT_Get_Char_Index(face,GetUTFCode(p)); 113091c2741e03e3e692f6fe04eb02d059edbc0edb90Cristy (*grapheme)[i].x_offset=0; 113191c2741e03e3e692f6fe04eb02d059edbc0edb90Cristy (*grapheme)[i].y_offset=0; 113291c2741e03e3e692f6fe04eb02d059edbc0edb90Cristy if (((*grapheme)[i].index != 0) && (last_glyph != 0)) 113369a0d3b5699c573f650e6b61f98ce4579d6f218cCristy { 113469a0d3b5699c573f650e6b61f98ce4579d6f218cCristy if (FT_HAS_KERNING(face)) 113569a0d3b5699c573f650e6b61f98ce4579d6f218cCristy { 113669a0d3b5699c573f650e6b61f98ce4579d6f218cCristy FT_Vector 113750d31568365a106c91ca4e827757fc2c806c6b16Cristy kerning; 113869a0d3b5699c573f650e6b61f98ce4579d6f218cCristy 113906d4a5a39532c883052f98c8e870d015be8db1ccCristy ft_status=FT_Get_Kerning(face,(FT_UInt) last_glyph,(FT_UInt) 114006d4a5a39532c883052f98c8e870d015be8db1ccCristy (*grapheme)[i].index,ft_kerning_default,&kerning); 114169a0d3b5699c573f650e6b61f98ce4579d6f218cCristy if (ft_status == 0) 114287dc5e4e6f9471304ba85f508de30e664b484d3aCristy (*grapheme)[i-1].x_advance+=(FT_Pos) ((draw_info->direction == 114387dc5e4e6f9471304ba85f508de30e664b484d3aCristy RightToLeftDirection ? -1.0 : 1.0)*kerning.x); 114469a0d3b5699c573f650e6b61f98ce4579d6f218cCristy } 114591c2741e03e3e692f6fe04eb02d059edbc0edb90Cristy } 114691c2741e03e3e692f6fe04eb02d059edbc0edb90Cristy ft_status=FT_Load_Glyph(face,(*grapheme)[i].index,flags); 114791c2741e03e3e692f6fe04eb02d059edbc0edb90Cristy (*grapheme)[i].x_advance=face->glyph->advance.x; 1148d45bfbb9ef2f6b90eb038b56d1a416b59c68abe0shamsa (*grapheme)[i].cluster=p-text; 114991c2741e03e3e692f6fe04eb02d059edbc0edb90Cristy last_glyph=(*grapheme)[i].index; 115069a0d3b5699c573f650e6b61f98ce4579d6f218cCristy } 115169a0d3b5699c573f650e6b61f98ce4579d6f218cCristy return((size_t) i); 115214c8ae4cf8fdcb1c1ed0f8fd1a5c3290414fe733Cristy#endif 115369a0d3b5699c573f650e6b61f98ce4579d6f218cCristy} 115469a0d3b5699c573f650e6b61f98ce4579d6f218cCristy 11553ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int TraceCubicBezier(FT_Vector *p,FT_Vector *q,FT_Vector *to, 11563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy DrawInfo *draw_info) 11573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 11583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy AffineMatrix 11593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy affine; 11603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 11613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy char 1162151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy path[MagickPathExtent]; 11633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 11643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy affine=draw_info->affine; 11659c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy (void) FormatLocaleString(path,MagickPathExtent,"C%g,%g %g,%g %g,%g", 11669c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy affine.tx+p->x/64.0,affine.ty-p->y/64.0,affine.tx+q->x/64.0,affine.ty- 11679c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy q->y/64.0,affine.tx+to->x/64.0,affine.ty-to->y/64.0); 11683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) ConcatenateString(&draw_info->primitive,path); 11693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(0); 11703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 11713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 11723ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int TraceLineTo(FT_Vector *to,DrawInfo *draw_info) 11733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 11743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy AffineMatrix 11753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy affine; 11763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 11773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy char 1178151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy path[MagickPathExtent]; 11793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 11803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy affine=draw_info->affine; 11819c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy (void) FormatLocaleString(path,MagickPathExtent,"L%g,%g",affine.tx+to->x/64.0, 11829c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy affine.ty-to->y/64.0); 11833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) ConcatenateString(&draw_info->primitive,path); 11843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(0); 11853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 11863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 11873ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int TraceMoveTo(FT_Vector *to,DrawInfo *draw_info) 11883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 11893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy AffineMatrix 11903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy affine; 11913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 11923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy char 1193151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy path[MagickPathExtent]; 11943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 11953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy affine=draw_info->affine; 11969c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy (void) FormatLocaleString(path,MagickPathExtent,"M%g,%g",affine.tx+to->x/64.0, 11979c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy affine.ty-to->y/64.0); 11983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) ConcatenateString(&draw_info->primitive,path); 11993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(0); 12003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 12013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12023ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int TraceQuadraticBezier(FT_Vector *control,FT_Vector *to, 12033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy DrawInfo *draw_info) 12043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 12053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy AffineMatrix 12063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy affine; 12073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy char 1209151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy path[MagickPathExtent]; 12103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy affine=draw_info->affine; 12129c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy (void) FormatLocaleString(path,MagickPathExtent,"Q%g,%g %g,%g",affine.tx+ 12139c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy control->x/64.0,affine.ty-control->y/64.0,affine.tx+to->x/64.0,affine.ty- 12149c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy to->y/64.0); 12153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) ConcatenateString(&draw_info->primitive,path); 12163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(0); 12173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 12183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12193ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info, 12205cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy const char *encoding,const PointInfo *offset,TypeMetric *metrics, 12215cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy ExceptionInfo *exception) 12223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 12233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(FT_OPEN_PATHNAME) 12243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define FT_OPEN_PATHNAME ft_open_pathname 12253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif 12263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy typedef struct _GlyphInfo 12283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 12293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy FT_UInt 12303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy id; 12313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy FT_Vector 12333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy origin; 12343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy FT_Glyph 12363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image; 12373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } GlyphInfo; 12383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const char 12403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *value; 12413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy DrawInfo 12433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *annotate_info; 12443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy FT_BBox 12463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy bounds; 12473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy FT_BitmapGlyph 12493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy bitmap; 12503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy FT_Encoding 12523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy encoding_type; 12533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy FT_Error 1255f8f295fde25dd8b1a50470d53b641d5265c0871fcristy ft_status; 12563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy FT_Face 12583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy face; 12593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy FT_Int32 12613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy flags; 12623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy FT_Library 12643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy library; 12653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy FT_Matrix 12673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy affine; 12683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy FT_Open_Args 12703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy args; 12713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy FT_Vector 12733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy origin; 12743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy GlyphInfo 12763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy glyph, 12773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy last_glyph; 12783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 127917f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy GraphemeInfo 128017f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy *grapheme; 128117f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy 1282f8f295fde25dd8b1a50470d53b641d5265c0871fcristy MagickBooleanType 1283f8f295fde25dd8b1a50470d53b641d5265c0871fcristy status; 1284f8f295fde25dd8b1a50470d53b641d5265c0871fcristy 12853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy PointInfo 12863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy point, 12873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy resolution; 12883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy register char 12903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *p; 12913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 129269a0d3b5699c573f650e6b61f98ce4579d6f218cCristy register ssize_t 129369a0d3b5699c573f650e6b61f98ce4579d6f218cCristy i; 129469a0d3b5699c573f650e6b61f98ce4579d6f218cCristy 129569a0d3b5699c573f650e6b61f98ce4579d6f218cCristy size_t 129669a0d3b5699c573f650e6b61f98ce4579d6f218cCristy length; 129769a0d3b5699c573f650e6b61f98ce4579d6f218cCristy 12989d314ff2c17a77996c05413c2013880387e50f0ecristy ssize_t 12999d314ff2c17a77996c05413c2013880387e50f0ecristy code, 13009d314ff2c17a77996c05413c2013880387e50f0ecristy y; 13019d314ff2c17a77996c05413c2013880387e50f0ecristy 13023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy static FT_Outline_Funcs 13033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy OutlineMethods = 13043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 13053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (FT_Outline_MoveTo_Func) TraceMoveTo, 13063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (FT_Outline_LineTo_Func) TraceLineTo, 13073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (FT_Outline_ConicTo_Func) TraceQuadraticBezier, 13083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (FT_Outline_CubicTo_Func) TraceCubicBezier, 13093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 0, 0 13103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy }; 13113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 13122857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy unsigned char 13132857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy *utf8; 13142857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy 13153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 13163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Initialize Truetype library. 13173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 1318f8f295fde25dd8b1a50470d53b641d5265c0871fcristy ft_status=FT_Init_FreeType(&library); 1319f8f295fde25dd8b1a50470d53b641d5265c0871fcristy if (ft_status != 0) 13203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ThrowBinaryException(TypeError,"UnableToInitializeFreetypeLibrary", 13213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->filename); 13223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy args.flags=FT_OPEN_PATHNAME; 13233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (draw_info->font == (char *) NULL) 13243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy args.pathname=ConstantString("helvetica"); 13253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 13263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (*draw_info->font != '@') 13273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy args.pathname=ConstantString(draw_info->font); 13283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 13293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy args.pathname=ConstantString(draw_info->font+1); 13303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy face=(FT_Face) NULL; 1331f8f295fde25dd8b1a50470d53b641d5265c0871fcristy ft_status=FT_Open_Face(library,&args,(long) draw_info->face,&face); 13323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy args.pathname=DestroyString(args.pathname); 1333f8f295fde25dd8b1a50470d53b641d5265c0871fcristy if (ft_status != 0) 13343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 13353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) FT_Done_FreeType(library); 13365cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy (void) ThrowMagickException(exception,GetMagickModule(),TypeError, 1337efe601ce9ea5ad34ad0e8ad6e61d9be9b148b2a3cristy "UnableToReadFont","`%s'",draw_info->font); 13385cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy return(RenderPostscript(image,draw_info,offset,metrics,exception)); 13393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 13403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if ((draw_info->metrics != (char *) NULL) && 13413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (IsPathAccessible(draw_info->metrics) != MagickFalse)) 13423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) FT_Attach_File(face,draw_info->metrics); 13433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy encoding_type=ft_encoding_unicode; 1344f8f295fde25dd8b1a50470d53b641d5265c0871fcristy ft_status=FT_Select_Charmap(face,encoding_type); 1345f8f295fde25dd8b1a50470d53b641d5265c0871fcristy if ((ft_status != 0) && (face->num_charmaps != 0)) 1346f8f295fde25dd8b1a50470d53b641d5265c0871fcristy ft_status=FT_Set_Charmap(face,face->charmaps[0]); 13473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (encoding != (const char *) NULL) 13483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 13493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(encoding,"AdobeCustom") == 0) 13503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy encoding_type=ft_encoding_adobe_custom; 13513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(encoding,"AdobeExpert") == 0) 13523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy encoding_type=ft_encoding_adobe_expert; 13533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(encoding,"AdobeStandard") == 0) 13543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy encoding_type=ft_encoding_adobe_standard; 13553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(encoding,"AppleRoman") == 0) 13563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy encoding_type=ft_encoding_apple_roman; 13573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(encoding,"BIG5") == 0) 13583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy encoding_type=ft_encoding_big5; 13593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(encoding,"GB2312") == 0) 13603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy encoding_type=ft_encoding_gb2312; 13613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(encoding,"Johab") == 0) 13623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy encoding_type=ft_encoding_johab; 13633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(ft_encoding_latin_1) 13643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(encoding,"Latin-1") == 0) 13653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy encoding_type=ft_encoding_latin_1; 13663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif 13673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(encoding,"Latin-2") == 0) 13683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy encoding_type=ft_encoding_latin_2; 13693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(encoding,"None") == 0) 13703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy encoding_type=ft_encoding_none; 13713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(encoding,"SJIScode") == 0) 13723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy encoding_type=ft_encoding_sjis; 13733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(encoding,"Symbol") == 0) 13743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy encoding_type=ft_encoding_symbol; 13753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(encoding,"Unicode") == 0) 13763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy encoding_type=ft_encoding_unicode; 13773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(encoding,"Wansung") == 0) 13783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy encoding_type=ft_encoding_wansung; 1379f8f295fde25dd8b1a50470d53b641d5265c0871fcristy ft_status=FT_Select_Charmap(face,encoding_type); 1380f8f295fde25dd8b1a50470d53b641d5265c0871fcristy if (ft_status != 0) 1381e3b2bb83e885eb35642c7029cedab50c5e1b263dcristy { 1382e3b2bb83e885eb35642c7029cedab50c5e1b263dcristy (void) FT_Done_Face(face); 1383e3b2bb83e885eb35642c7029cedab50c5e1b263dcristy (void) FT_Done_FreeType(library); 1384e3b2bb83e885eb35642c7029cedab50c5e1b263dcristy ThrowBinaryException(TypeError,"UnrecognizedFontEncoding",encoding); 1385e3b2bb83e885eb35642c7029cedab50c5e1b263dcristy } 13863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 13873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 13883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Set text size. 13893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 13903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy resolution.x=DefaultResolution; 13913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy resolution.y=DefaultResolution; 13923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (draw_info->density != (char *) NULL) 13933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 13943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy GeometryInfo 13953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy geometry_info; 13963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 13973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy MagickStatusType 139869a0d3b5699c573f650e6b61f98ce4579d6f218cCristy flags; 13993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 140069a0d3b5699c573f650e6b61f98ce4579d6f218cCristy flags=ParseGeometry(draw_info->density,&geometry_info); 14013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy resolution.x=geometry_info.rho; 14023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy resolution.y=geometry_info.sigma; 140369a0d3b5699c573f650e6b61f98ce4579d6f218cCristy if ((flags & SigmaValue) == 0) 14043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy resolution.y=resolution.x; 14053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 1406f8f295fde25dd8b1a50470d53b641d5265c0871fcristy ft_status=FT_Set_Char_Size(face,(FT_F26Dot6) (64.0*draw_info->pointsize), 14073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (FT_F26Dot6) (64.0*draw_info->pointsize),(FT_UInt) resolution.x, 14083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (FT_UInt) resolution.y); 14092245bab833d2ab8dc9a2ec3389f5e1bd72ca9ec3Cristy if (ft_status != 0) 14102245bab833d2ab8dc9a2ec3389f5e1bd72ca9ec3Cristy { 14112245bab833d2ab8dc9a2ec3389f5e1bd72ca9ec3Cristy (void) FT_Done_Face(face); 14122245bab833d2ab8dc9a2ec3389f5e1bd72ca9ec3Cristy (void) FT_Done_FreeType(library); 14132245bab833d2ab8dc9a2ec3389f5e1bd72ca9ec3Cristy ThrowBinaryException(TypeError,"UnableToReadFont",draw_info->font); 14142245bab833d2ab8dc9a2ec3389f5e1bd72ca9ec3Cristy } 14153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->pixels_per_em.x=face->size->metrics.x_ppem; 14163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->pixels_per_em.y=face->size->metrics.y_ppem; 14173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->ascent=(double) face->size->metrics.ascender/64.0; 14183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->descent=(double) face->size->metrics.descender/64.0; 14193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->width=0; 14203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->origin.x=0; 14213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->origin.y=0; 14223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->height=(double) face->size->metrics.height/64.0; 14233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->max_advance=0.0; 14243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (face->size->metrics.max_advance > MagickEpsilon) 14253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->max_advance=(double) face->size->metrics.max_advance/64.0; 14263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->bounds.x1=0.0; 14273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->bounds.y1=metrics->descent; 14283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->bounds.x2=metrics->ascent+metrics->descent; 14293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->bounds.y2=metrics->ascent+metrics->descent; 14303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->underline_position=face->underline_position/64.0; 14313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->underline_thickness=face->underline_thickness/64.0; 143271709bfb884744dbf7c9030810cc8599600ab7d3cristy if ((draw_info->text == (char *) NULL) || (*draw_info->text == '\0')) 14333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 14343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) FT_Done_Face(face); 14353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) FT_Done_FreeType(library); 14363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(MagickTrue); 14373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 14383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 14393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Compute bounding box. 14403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 14413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->debug != MagickFalse) 14423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) LogMagickEvent(AnnotateEvent,GetMagickModule(),"Font %s; " 1443e7f5109f30fc7242d04a26174a9138483dda5b6acristy "font-encoding %s; text-encoding %s; pointsize %g", 14443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy draw_info->font != (char *) NULL ? draw_info->font : "none", 14453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy encoding != (char *) NULL ? encoding : "none", 14463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy draw_info->encoding != (char *) NULL ? draw_info->encoding : "none", 14473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy draw_info->pointsize); 14483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy flags=FT_LOAD_NO_BITMAP; 144955a804e2631f770f45d3a671076b0dfe29fdf188cristy if (draw_info->text_antialias == MagickFalse) 14504f9709e37140157c7845a03f3612534081a5b540cristy flags|=FT_LOAD_TARGET_MONO; 145155a804e2631f770f45d3a671076b0dfe29fdf188cristy else 145255a804e2631f770f45d3a671076b0dfe29fdf188cristy { 1453a89189d6e227db53ecff8624fb6b4388560d9b4acristy#if defined(FT_LOAD_TARGET_LIGHT) 145455a804e2631f770f45d3a671076b0dfe29fdf188cristy flags|=FT_LOAD_TARGET_LIGHT; 1455a89189d6e227db53ecff8624fb6b4388560d9b4acristy#elif defined(FT_LOAD_TARGET_LCD) 1456a89189d6e227db53ecff8624fb6b4388560d9b4acristy flags|=FT_LOAD_TARGET_LCD; 145755a804e2631f770f45d3a671076b0dfe29fdf188cristy#endif 145855a804e2631f770f45d3a671076b0dfe29fdf188cristy } 1459d15e65928aec551b7388c2863de3e3e628e2e0ddcristy value=GetImageProperty(image,"type:hinting",exception); 146033204240c3ef57786ee59c2692ffe8ffdce97bf9cristy if ((value != (const char *) NULL) && (LocaleCompare(value,"off") == 0)) 14613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy flags|=FT_LOAD_NO_HINTING; 14623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy glyph.id=0; 14633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy glyph.image=NULL; 14643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy last_glyph.id=0; 14653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy last_glyph.image=NULL; 14663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy origin.x=0; 14673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy origin.y=0; 14683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy affine.xx=65536L; 14693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy affine.yx=0L; 14703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy affine.xy=0L; 14713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy affine.yy=65536L; 14723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (draw_info->render != MagickFalse) 14733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 14743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy affine.xx=(FT_Fixed) (65536L*draw_info->affine.sx+0.5); 14753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy affine.yx=(FT_Fixed) (-65536L*draw_info->affine.rx+0.5); 14763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy affine.xy=(FT_Fixed) (-65536L*draw_info->affine.ry+0.5); 14773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy affine.yy=(FT_Fixed) (65536L*draw_info->affine.sy+0.5); 14783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 14793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info=CloneDrawInfo((ImageInfo *) NULL,draw_info); 14809c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy if (annotate_info->dash_pattern != (double *) NULL) 14819c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy annotate_info->dash_pattern[0]=0.0; 14823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) CloneString(&annotate_info->primitive,"path '"); 14833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (draw_info->render != MagickFalse) 14843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 14853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->storage_class != DirectClass) 14865cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy (void) SetImageStorageClass(image,DirectClass,exception); 148717f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy if (image->alpha_trait == UndefinedPixelTrait) 1488a64d8007a138a0efeedc286de10538f2e8c7fe6bcristy (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception); 14893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 14903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy point.x=0.0; 14913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy point.y=0.0; 14923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (p=draw_info->text; GetUTFCode(p) != 0; p+=GetUTFOctets(p)) 1493bd51246ae63047fa139606f6c6862ff989ab1fbdcristy if (GetUTFCode(p) < 0) 1494bd51246ae63047fa139606f6c6862ff989ab1fbdcristy break; 14952857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy utf8=(unsigned char *) NULL; 1496d913ea1f524066a6a8bf3d046755a5c0f7eb471fcristy if (GetUTFCode(p) == 0) 14972857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy p=draw_info->text; 14982857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy else 1499bd51246ae63047fa139606f6c6862ff989ab1fbdcristy { 15002857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy utf8=ConvertLatin1ToUTF8((unsigned char *) draw_info->text); 15012857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy if (utf8 != (unsigned char *) NULL) 1502c9b129570a277337cf0e887229741497e2ead5cfcristy p=(char *) utf8; 15032857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy } 1504f8f295fde25dd8b1a50470d53b641d5265c0871fcristy status=MagickTrue; 150517f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy grapheme=(GraphemeInfo *) NULL; 150687dc5e4e6f9471304ba85f508de30e664b484d3aCristy length=ComplexTextLayout(image,draw_info,p,strlen(p),face,flags,&grapheme, 15075eb36084e86f5ab4a877c2b31c19880b0b0b02e3Cristy exception); 150869a0d3b5699c573f650e6b61f98ce4579d6f218cCristy code=0; 150969a0d3b5699c573f650e6b61f98ce4579d6f218cCristy for (i=0; i < (ssize_t) length; i++) 15102857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy { 15112857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy /* 15122857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy Render UTF-8 sequence. 15132857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy */ 151491c2741e03e3e692f6fe04eb02d059edbc0edb90Cristy glyph.id=grapheme[i].index; 15152857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy if (glyph.id == 0) 15162857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy glyph.id=FT_Get_Char_Index(face,'?'); 15172857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy if ((glyph.id != 0) && (last_glyph.id != 0)) 151869a0d3b5699c573f650e6b61f98ce4579d6f218cCristy origin.x+=(FT_Pos) (64.0*draw_info->kerning); 15192857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy glyph.origin=origin; 152091c2741e03e3e692f6fe04eb02d059edbc0edb90Cristy glyph.origin.x+=grapheme[i].x_offset; 152191c2741e03e3e692f6fe04eb02d059edbc0edb90Cristy glyph.origin.y+=grapheme[i].y_offset; 1522f8f295fde25dd8b1a50470d53b641d5265c0871fcristy ft_status=FT_Load_Glyph(face,glyph.id,flags); 1523f8f295fde25dd8b1a50470d53b641d5265c0871fcristy if (ft_status != 0) 15242857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy continue; 1525f8f295fde25dd8b1a50470d53b641d5265c0871fcristy ft_status=FT_Get_Glyph(face->glyph,&glyph.image); 1526f8f295fde25dd8b1a50470d53b641d5265c0871fcristy if (ft_status != 0) 15272857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy continue; 1528f8f295fde25dd8b1a50470d53b641d5265c0871fcristy ft_status=FT_Outline_Get_BBox(&((FT_OutlineGlyph) glyph.image)->outline, 15292857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy &bounds); 1530f8f295fde25dd8b1a50470d53b641d5265c0871fcristy if (ft_status != 0) 15312857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy continue; 15322857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy if ((p == draw_info->text) || (bounds.xMin < metrics->bounds.x1)) 1533aa83c2c383e62bd5342c0d38dc5f6e746998bde8cristy metrics->bounds.x1=(double) bounds.xMin; 15342857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy if ((p == draw_info->text) || (bounds.yMin < metrics->bounds.y1)) 1535aa83c2c383e62bd5342c0d38dc5f6e746998bde8cristy metrics->bounds.y1=(double) bounds.yMin; 15362857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy if ((p == draw_info->text) || (bounds.xMax > metrics->bounds.x2)) 1537aa83c2c383e62bd5342c0d38dc5f6e746998bde8cristy metrics->bounds.x2=(double) bounds.xMax; 15382857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy if ((p == draw_info->text) || (bounds.yMax > metrics->bounds.y2)) 1539aa83c2c383e62bd5342c0d38dc5f6e746998bde8cristy metrics->bounds.y2=(double) bounds.yMax; 15409c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy if (((draw_info->stroke.alpha != TransparentAlpha) || 15419c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy (draw_info->stroke_pattern != (Image *) NULL)) && 15429c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy ((status != MagickFalse) && (draw_info->render != MagickFalse))) 1543f8f295fde25dd8b1a50470d53b641d5265c0871fcristy { 15449c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy /* 15459c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy Trace the glyph. 15469c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy */ 15479c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy annotate_info->affine.tx=glyph.origin.x/64.0; 154869a0d3b5699c573f650e6b61f98ce4579d6f218cCristy annotate_info->affine.ty=(-glyph.origin.y/64.0); 15499c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy (void) FT_Outline_Decompose(&((FT_OutlineGlyph) glyph.image)->outline, 15509c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy &OutlineMethods,annotate_info); 15519c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy } 15522857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy FT_Vector_Transform(&glyph.origin,&affine); 15532857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy (void) FT_Glyph_Transform(glyph.image,&affine,&glyph.origin); 1554f8f295fde25dd8b1a50470d53b641d5265c0871fcristy ft_status=FT_Glyph_To_Bitmap(&glyph.image,ft_render_mode_normal, 15552857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy (FT_Vector *) NULL,MagickTrue); 1556f8f295fde25dd8b1a50470d53b641d5265c0871fcristy if (ft_status != 0) 15572857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy continue; 15582857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy bitmap=(FT_BitmapGlyph) glyph.image; 15592857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy point.x=offset->x+bitmap->left; 15602f5b5c7c0813cc6f696a4dfc00aaf62e2dfb2a23cristy if (bitmap->bitmap.pixel_mode == ft_pixel_mode_mono) 15612f5b5c7c0813cc6f696a4dfc00aaf62e2dfb2a23cristy point.x=offset->x+(origin.x >> 6); 15622857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy point.y=offset->y-bitmap->top; 15632857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy if (draw_info->render != MagickFalse) 15642857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy { 15652857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy CacheView 15662857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy *image_view; 1567bd51246ae63047fa139606f6c6862ff989ab1fbdcristy 15682f5b5c7c0813cc6f696a4dfc00aaf62e2dfb2a23cristy register unsigned char 1569fa589d6096099562cbc2bc14e508931968a8c055dirk *r; 15702f5b5c7c0813cc6f696a4dfc00aaf62e2dfb2a23cristy 15712857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy /* 15722857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy Rasterize the glyph. 15732857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy */ 157446ff2676b1044ea4101ac7a59b83289cd8f6cfdacristy image_view=AcquireAuthenticCacheView(image,exception); 1575fa589d6096099562cbc2bc14e508931968a8c055dirk r=bitmap->bitmap.buffer; 1576bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (y=0; y < (ssize_t) bitmap->bitmap.rows; y++) 15772857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy { 157887dc5e4e6f9471304ba85f508de30e664b484d3aCristy double 157987dc5e4e6f9471304ba85f508de30e664b484d3aCristy fill_opacity; 158087dc5e4e6f9471304ba85f508de30e664b484d3aCristy 1581bd51246ae63047fa139606f6c6862ff989ab1fbdcristy MagickBooleanType 15822857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy active, 15832857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy sync; 1584bd51246ae63047fa139606f6c6862ff989ab1fbdcristy 1585101ab708b0574518ac5715da4d3915400e9df79acristy PixelInfo 15862857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy fill_color; 15872857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy 15884c08aed51c5899665ade97263692328eea4af106cristy register Quantum 158905d2ff7ebf21f659f5b11e45afb294e152f4330cdirk *magick_restrict q; 15902857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy 15918815806717c3b3e2b4f8700b4cc18b751bd3c23fcristy register ssize_t 15928815806717c3b3e2b4f8700b4cc18b751bd3c23fcristy x; 15938815806717c3b3e2b4f8700b4cc18b751bd3c23fcristy 159473ce31bc9ca5fc03ff0cef499e58ab2973add52ccristy ssize_t 15952f5b5c7c0813cc6f696a4dfc00aaf62e2dfb2a23cristy n, 159673ce31bc9ca5fc03ff0cef499e58ab2973add52ccristy x_offset, 159773ce31bc9ca5fc03ff0cef499e58ab2973add52ccristy y_offset; 159873ce31bc9ca5fc03ff0cef499e58ab2973add52ccristy 15992857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy if (status == MagickFalse) 16002857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy continue; 1601bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy x_offset=(ssize_t) ceil(point.x-0.5); 1602bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy y_offset=(ssize_t) ceil(point.y+y-0.5); 1603bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy if ((y_offset < 0) || (y_offset >= (ssize_t) image->rows)) 16042857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy continue; 16054c08aed51c5899665ade97263692328eea4af106cristy q=(Quantum *) NULL; 1606bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy if ((x_offset < 0) || (x_offset >= (ssize_t) image->columns)) 16072857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy active=MagickFalse; 16082857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy else 16092857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy { 16102857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy q=GetCacheViewAuthenticPixels(image_view,x_offset,y_offset, 16112857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy bitmap->bitmap.width,1,exception); 16124c08aed51c5899665ade97263692328eea4af106cristy active=q != (Quantum *) NULL ? MagickTrue : MagickFalse; 16132857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy } 1614854209afe797f1a6ecec8679889302af4d4b0faccristy n=y*bitmap->bitmap.pitch-1; 1615854209afe797f1a6ecec8679889302af4d4b0faccristy for (x=0; x < (ssize_t) bitmap->bitmap.width; x++) 1616bd51246ae63047fa139606f6c6862ff989ab1fbdcristy { 1617854209afe797f1a6ecec8679889302af4d4b0faccristy n++; 16182857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy x_offset++; 16192f5b5c7c0813cc6f696a4dfc00aaf62e2dfb2a23cristy if ((x_offset < 0) || (x_offset >= (ssize_t) image->columns)) 16203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 1621dcf8f73b2c558978add85031fe65f2607bbca057cristy if (q != (Quantum *) NULL) 1622dcf8f73b2c558978add85031fe65f2607bbca057cristy q+=GetPixelChannels(image); 16232857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy continue; 16243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 16252f5b5c7c0813cc6f696a4dfc00aaf62e2dfb2a23cristy if (bitmap->bitmap.pixel_mode != ft_pixel_mode_mono) 1626fa589d6096099562cbc2bc14e508931968a8c055dirk fill_opacity=(double) (r[n])/(bitmap->bitmap.num_grays-1); 16272f5b5c7c0813cc6f696a4dfc00aaf62e2dfb2a23cristy else 1628fa589d6096099562cbc2bc14e508931968a8c055dirk fill_opacity=((r[(x >> 3)+y*bitmap->bitmap.pitch] & 16292f5b5c7c0813cc6f696a4dfc00aaf62e2dfb2a23cristy (1 << (~x & 0x07)))) == 0 ? 0.0 : 1.0; 16302857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy if (draw_info->text_antialias == MagickFalse) 16312857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy fill_opacity=fill_opacity >= 0.5 ? 1.0 : 0.0; 16322857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy if (active == MagickFalse) 16332857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy q=GetCacheViewAuthenticPixels(image_view,x_offset,y_offset,1,1, 16342857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy exception); 16356193b86c0b59030b647a10c75f37ec82d73e3695cristy if (q == (Quantum *) NULL) 16369c5171c13c7186088b10ec322e199f60e455a7e1cristy continue; 1637ec061ec752ff58a96a5de680b18e43fb8beea7c0cristy GetPixelInfo(image,&fill_color); 16382ed42f6d7c2245432767ea446742977ee87e963ccristy (void) GetFillColor(draw_info,x_offset,y_offset,&fill_color, 16392ed42f6d7c2245432767ea446742977ee87e963ccristy exception); 16404c08aed51c5899665ade97263692328eea4af106cristy fill_opacity=fill_opacity*fill_color.alpha; 16414c08aed51c5899665ade97263692328eea4af106cristy CompositePixelOver(image,&fill_color,fill_opacity,q, 16424c08aed51c5899665ade97263692328eea4af106cristy GetPixelAlpha(image,q),q); 16432857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy if (active == MagickFalse) 16442857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy { 16452857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy sync=SyncCacheViewAuthenticPixels(image_view,exception); 16462857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy if (sync == MagickFalse) 16472857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy status=MagickFalse; 16482857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy } 1649ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy q+=GetPixelChannels(image); 16503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 16512857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy sync=SyncCacheViewAuthenticPixels(image_view,exception); 16522857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy if (sync == MagickFalse) 16532857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy status=MagickFalse; 16543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 16552857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy image_view=DestroyCacheView(image_view); 16569c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy if (((draw_info->stroke.alpha != TransparentAlpha) || 16579c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy (draw_info->stroke_pattern != (Image *) NULL)) && 16589c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy (status != MagickFalse)) 16599c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy { 16609c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy /* 16619c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy Draw text stroke. 16629c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy */ 16639c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy annotate_info->linejoin=RoundJoin; 16649c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy annotate_info->affine.tx=offset->x; 16659c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy annotate_info->affine.ty=offset->y; 16669c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy (void) ConcatenateString(&annotate_info->primitive,"'"); 16679c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy (void) DrawImage(image,annotate_info,exception); 16689c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy (void) CloneString(&annotate_info->primitive,"path '"); 16699c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy } 16702857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy } 16712857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy if ((bitmap->left+bitmap->bitmap.width) > metrics->width) 16722857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy metrics->width=bitmap->left+bitmap->bitmap.width; 1673aa83c2c383e62bd5342c0d38dc5f6e746998bde8cristy if ((fabs(draw_info->interword_spacing) >= MagickEpsilon) && 167491c2741e03e3e692f6fe04eb02d059edbc0edb90Cristy (IsUTFSpace(GetUTFCode(p+grapheme[i].cluster)) != MagickFalse) && 16752857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy (IsUTFSpace(code) == MagickFalse)) 167669a0d3b5699c573f650e6b61f98ce4579d6f218cCristy origin.x+=(FT_Pos) (64.0*draw_info->interword_spacing); 16772857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy else 167891c2741e03e3e692f6fe04eb02d059edbc0edb90Cristy origin.x+=(FT_Pos) grapheme[i].x_advance; 1679aa83c2c383e62bd5342c0d38dc5f6e746998bde8cristy metrics->origin.x=(double) origin.x; 1680aa83c2c383e62bd5342c0d38dc5f6e746998bde8cristy metrics->origin.y=(double) origin.y; 1681bd5a96cd2b69f218f85a7adc306296a736f91a56cristy if (last_glyph.id != 0) 1682bd5a96cd2b69f218f85a7adc306296a736f91a56cristy FT_Done_Glyph(last_glyph.image); 16832857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy last_glyph=glyph; 168491c2741e03e3e692f6fe04eb02d059edbc0edb90Cristy code=GetUTFCode(p+grapheme[i].cluster); 16852857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy } 168617f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy if (grapheme != (GraphemeInfo *) NULL) 168717f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy grapheme=(GraphemeInfo *) RelinquishMagickMemory(grapheme); 16882857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy if (utf8 != (unsigned char *) NULL) 16892857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy utf8=(unsigned char *) RelinquishMagickMemory(utf8); 1690bd5a96cd2b69f218f85a7adc306296a736f91a56cristy if (last_glyph.id != 0) 1691bd5a96cd2b69f218f85a7adc306296a736f91a56cristy FT_Done_Glyph(last_glyph.image); 16923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 16933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Determine font metrics. 16943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 16953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy glyph.id=FT_Get_Char_Index(face,'_'); 16963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy glyph.origin=origin; 1697f8f295fde25dd8b1a50470d53b641d5265c0871fcristy ft_status=FT_Load_Glyph(face,glyph.id,flags); 1698f8f295fde25dd8b1a50470d53b641d5265c0871fcristy if (ft_status == 0) 16993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 1700f8f295fde25dd8b1a50470d53b641d5265c0871fcristy ft_status=FT_Get_Glyph(face->glyph,&glyph.image); 1701f8f295fde25dd8b1a50470d53b641d5265c0871fcristy if (ft_status == 0) 17023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 1703f8f295fde25dd8b1a50470d53b641d5265c0871fcristy ft_status=FT_Outline_Get_BBox(&((FT_OutlineGlyph) glyph.image)-> 1704f8f295fde25dd8b1a50470d53b641d5265c0871fcristy outline,&bounds); 1705f8f295fde25dd8b1a50470d53b641d5265c0871fcristy if (ft_status == 0) 17063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 17073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy FT_Vector_Transform(&glyph.origin,&affine); 17083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) FT_Glyph_Transform(glyph.image,&affine,&glyph.origin); 1709f8f295fde25dd8b1a50470d53b641d5265c0871fcristy ft_status=FT_Glyph_To_Bitmap(&glyph.image,ft_render_mode_normal, 17103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (FT_Vector *) NULL,MagickTrue); 17113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy bitmap=(FT_BitmapGlyph) glyph.image; 17123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (bitmap->left > metrics->width) 17133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->width=bitmap->left; 17143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 17153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 1716e2c81adf02cbe4bb92991389437a2a1daf8ed313cristy FT_Done_Glyph(glyph.image); 17173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 171855cb9f15b804f98ac7d37615b8f5f8888fc792f4cristy metrics->width+=annotate_info->stroke_width; 17193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->bounds.x1/=64.0; 17203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->bounds.y1/=64.0; 17213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->bounds.x2/=64.0; 17223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->bounds.y2/=64.0; 17233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->origin.x/=64.0; 17243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->origin.y/=64.0; 17253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 17263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Relinquish resources. 17273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 17283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info=DestroyDrawInfo(annotate_info); 17293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) FT_Done_Face(face); 17303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) FT_Done_FreeType(library); 1731f8f295fde25dd8b1a50470d53b641d5265c0871fcristy return(status); 17323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 17333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else 17343ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info, 17353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const char *magick_unused(encoding),const PointInfo *offset, 17365cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy TypeMetric *metrics,ExceptionInfo *exception) 17373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 17385cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy (void) ThrowMagickException(exception,GetMagickModule(), 1739e5b39652d8d21bc3940d83b8d6088d4070a8a34aanthony MissingDelegateWarning,"DelegateLibrarySupportNotBuiltIn","'%s' (Freetype)", 1740ee08182aae410ed78e712a845bee7e51eedf73f3cristy draw_info->font != (char *) NULL ? draw_info->font : "none"); 1741e3b062a2f84bdc16645c3ef9de153b2c6f44d04ccristy return(RenderPostscript(image,draw_info,offset,metrics,exception)); 17423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 17433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif 17443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 17453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 17463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 17473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 17483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 17493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 17503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy+ R e n d e r P o s t s c r i p t % 17513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 17523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 17533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 17543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 17553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 17563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% RenderPostscript() renders text on the image with a Postscript font. It 17573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% also returns the bounding box of the text relative to the image. 17583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 17593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% The format of the RenderPostscript method is: 17603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 17613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% MagickBooleanType RenderPostscript(Image *image,DrawInfo *draw_info, 17625cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% const PointInfo *offset,TypeMetric *metrics,ExceptionInfo *exception) 17633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 17643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A description of each parameter follows: 17653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 17663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o image: the image. 17673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 17683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o draw_info: the draw info. 17693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 17703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o offset: (x,y) location of text relative to image. 17713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 17723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o metrics: bounding box of text. 17733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 17745cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% o exception: return any errors or warnings in this structure. 17755cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% 17763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 17773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 17783ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic char *EscapeParenthesis(const char *text) 17793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 17803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy char 17813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *buffer; 17823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 17833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy register char 17843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *p; 17853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1786bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy register ssize_t 17873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy i; 17883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 17893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy size_t 17903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy escapes; 17913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 17923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy escapes=0; 17933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy buffer=AcquireString(text); 17943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy p=buffer; 1795151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy for (i=0; i < (ssize_t) MagickMin(strlen(text),MagickPathExtent-escapes-1); i++) 17963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 17973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if ((text[i] == '(') || (text[i] == ')')) 17983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 17993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *p++='\\'; 18003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy escapes++; 18013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 18023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *p++=text[i]; 18033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 18043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *p='\0'; 18053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(buffer); 18063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 18073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 18083ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType RenderPostscript(Image *image, 18095cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy const DrawInfo *draw_info,const PointInfo *offset,TypeMetric *metrics, 18105cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy ExceptionInfo *exception) 18113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 18123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy char 1813151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy filename[MagickPathExtent], 1814151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy geometry[MagickPathExtent], 18153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *text; 18163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 18173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy FILE 18183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *file; 18193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 18203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Image 18213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *annotate_image; 18223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 18233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ImageInfo 18243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *annotate_info; 18253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 18263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy int 18273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unique_file; 18283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 18293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy MagickBooleanType 18303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy identity; 18313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 18323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy PointInfo 18333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy extent, 18343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy point, 18353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy resolution; 18363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1837bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy register ssize_t 18383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy i; 18393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 184014d712974a2c2cd2aebf8db11c7ca686bb67596fcristy size_t 184114d712974a2c2cd2aebf8db11c7ca686bb67596fcristy length; 184214d712974a2c2cd2aebf8db11c7ca686bb67596fcristy 18439d314ff2c17a77996c05413c2013880387e50f0ecristy ssize_t 18449d314ff2c17a77996c05413c2013880387e50f0ecristy y; 18459d314ff2c17a77996c05413c2013880387e50f0ecristy 18463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 18473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Render label with a Postscript font. 18483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 18493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->debug != MagickFalse) 18503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) LogMagickEvent(AnnotateEvent,GetMagickModule(), 1851e7f5109f30fc7242d04a26174a9138483dda5b6acristy "Font %s; pointsize %g",draw_info->font != (char *) NULL ? 18523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy draw_info->font : "none",draw_info->pointsize); 18533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy file=(FILE *) NULL; 18543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unique_file=AcquireUniqueFileResource(filename); 18553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (unique_file != -1) 18563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy file=fdopen(unique_file,"wb"); 18573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if ((unique_file == -1) || (file == (FILE *) NULL)) 18583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 18595cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy ThrowFileException(exception,FileOpenError,"UnableToOpenFile",filename); 18603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(MagickFalse); 18613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 1862b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy (void) FormatLocaleFile(file,"%%!PS-Adobe-3.0\n"); 1863b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy (void) FormatLocaleFile(file,"/ReencodeType\n"); 1864b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy (void) FormatLocaleFile(file,"{\n"); 1865b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy (void) FormatLocaleFile(file," findfont dup length\n"); 1866b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy (void) FormatLocaleFile(file, 18673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy " dict begin { 1 index /FID ne {def} {pop pop} ifelse } forall\n"); 1868b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy (void) FormatLocaleFile(file, 18693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy " /Encoding ISOLatin1Encoding def currentdict end definefont pop\n"); 1870b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy (void) FormatLocaleFile(file,"} bind def\n"); 18713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 18723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Sample to compute bounding box. 18733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 1874aa83c2c383e62bd5342c0d38dc5f6e746998bde8cristy identity=(fabs(draw_info->affine.sx-draw_info->affine.sy) < MagickEpsilon) && 1875aa83c2c383e62bd5342c0d38dc5f6e746998bde8cristy (fabs(draw_info->affine.rx) < MagickEpsilon) && 1876aa83c2c383e62bd5342c0d38dc5f6e746998bde8cristy (fabs(draw_info->affine.ry) < MagickEpsilon) ? MagickTrue : MagickFalse; 18773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy extent.x=0.0; 18783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy extent.y=0.0; 187914d712974a2c2cd2aebf8db11c7ca686bb67596fcristy length=strlen(draw_info->text); 188014d712974a2c2cd2aebf8db11c7ca686bb67596fcristy for (i=0; i <= (ssize_t) (length+2); i++) 18813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 18823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy point.x=fabs(draw_info->affine.sx*i*draw_info->pointsize+ 18833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy draw_info->affine.ry*2.0*draw_info->pointsize); 18843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy point.y=fabs(draw_info->affine.rx*i*draw_info->pointsize+ 18853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy draw_info->affine.sy*2.0*draw_info->pointsize); 18863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (point.x > extent.x) 18873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy extent.x=point.x; 18883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (point.y > extent.y) 18893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy extent.y=point.y; 18903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 1891b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy (void) FormatLocaleFile(file,"%g %g moveto\n",identity != MagickFalse ? 0.0 : 18923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy extent.x/2.0,extent.y/2.0); 1893b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy (void) FormatLocaleFile(file,"%g %g scale\n",draw_info->pointsize, 18943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy draw_info->pointsize); 18953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if ((draw_info->font == (char *) NULL) || (*draw_info->font == '\0') || 18963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (strchr(draw_info->font,'/') != (char *) NULL)) 1897b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy (void) FormatLocaleFile(file, 18983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy "/Times-Roman-ISO dup /Times-Roman ReencodeType findfont setfont\n"); 18993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 19001e604812fad85bb96f757a2393015ae3d061c39acristy (void) FormatLocaleFile(file, 19011e604812fad85bb96f757a2393015ae3d061c39acristy "/%s-ISO dup /%s ReencodeType findfont setfont\n",draw_info->font, 19021e604812fad85bb96f757a2393015ae3d061c39acristy draw_info->font); 1903b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy (void) FormatLocaleFile(file,"[%g %g %g %g 0 0] concat\n", 19048cd5b3193212b4aebce08c4e7afbb66b09778029cristy draw_info->affine.sx,-draw_info->affine.rx,-draw_info->affine.ry, 19058cd5b3193212b4aebce08c4e7afbb66b09778029cristy draw_info->affine.sy); 19063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy text=EscapeParenthesis(draw_info->text); 19073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (identity == MagickFalse) 19081e604812fad85bb96f757a2393015ae3d061c39acristy (void) FormatLocaleFile(file,"(%s) stringwidth pop -0.5 mul -0.5 rmoveto\n", 19091e604812fad85bb96f757a2393015ae3d061c39acristy text); 1910b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy (void) FormatLocaleFile(file,"(%s) show\n",text); 19113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy text=DestroyString(text); 1912b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy (void) FormatLocaleFile(file,"showpage\n"); 19133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) fclose(file); 1914151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy (void) FormatLocaleString(geometry,MagickPathExtent,"%.20gx%.20g+0+0!", 1915e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy floor(extent.x+0.5),floor(extent.y+0.5)); 19163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info=AcquireImageInfo(); 1917151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy (void) FormatLocaleString(annotate_info->filename,MagickPathExtent,"ps:%s", 19183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy filename); 19193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) CloneString(&annotate_info->page,geometry); 19203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (draw_info->density != (char *) NULL) 19213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) CloneString(&annotate_info->density,draw_info->density); 19223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->antialias=draw_info->text_antialias; 19235cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy annotate_image=ReadImage(annotate_info,exception); 19245cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy CatchException(exception); 19253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info=DestroyImageInfo(annotate_info); 19263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) RelinquishUniqueFileResource(filename); 19273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (annotate_image == (Image *) NULL) 19283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(MagickFalse); 192955cb9f15b804f98ac7d37615b8f5f8888fc792f4cristy (void) NegateImage(annotate_image,MagickFalse,exception); 19303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy resolution.x=DefaultResolution; 19313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy resolution.y=DefaultResolution; 19323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (draw_info->density != (char *) NULL) 19333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 19343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy GeometryInfo 19353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy geometry_info; 19363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 19373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy MagickStatusType 19383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy flags; 19393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 19403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy flags=ParseGeometry(draw_info->density,&geometry_info); 19413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy resolution.x=geometry_info.rho; 19423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy resolution.y=geometry_info.sigma; 19433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if ((flags & SigmaValue) == 0) 19443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy resolution.y=resolution.x; 19453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 19463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (identity == MagickFalse) 1947e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy (void) TransformImage(&annotate_image,"0x0",(char *) NULL,exception); 19483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 19493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 19503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy RectangleInfo 19513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy crop_info; 19523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 19535cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy crop_info=GetImageBoundingBox(annotate_image,exception); 1954bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy crop_info.height=(size_t) ((resolution.y/DefaultResolution)* 19553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ExpandAffine(&draw_info->affine)*draw_info->pointsize+0.5); 1956bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy crop_info.y=(ssize_t) ceil((resolution.y/DefaultResolution)*extent.y/8.0- 195706609eef311d5af857f65f20ed3af6860c1994becristy 0.5); 1958151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy (void) FormatLocaleString(geometry,MagickPathExtent, 19596d8abbae64da926477182d86d5007bc2c5a8b979cristy "%.20gx%.20g%+.20g%+.20g",(double) crop_info.width,(double) 1960e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy crop_info.height,(double) crop_info.x,(double) crop_info.y); 1961e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy (void) TransformImage(&annotate_image,geometry,(char *) NULL,exception); 19623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 19633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->pixels_per_em.x=(resolution.y/DefaultResolution)* 19643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ExpandAffine(&draw_info->affine)*draw_info->pointsize; 19653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->pixels_per_em.y=metrics->pixels_per_em.x; 19663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->ascent=metrics->pixels_per_em.x; 19673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->descent=metrics->pixels_per_em.y/-5.0; 19683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->width=(double) annotate_image->columns/ 19693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ExpandAffine(&draw_info->affine); 19703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->height=1.152*metrics->pixels_per_em.x; 19713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->max_advance=metrics->pixels_per_em.x; 19723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->bounds.x1=0.0; 19733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->bounds.y1=metrics->descent; 19743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->bounds.x2=metrics->ascent+metrics->descent; 19753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->bounds.y2=metrics->ascent+metrics->descent; 19763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->underline_position=(-2.0); 19773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->underline_thickness=1.0; 19783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (draw_info->render == MagickFalse) 19793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 19803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_image=DestroyImage(annotate_image); 19813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(MagickTrue); 19823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 19834c08aed51c5899665ade97263692328eea4af106cristy if (draw_info->fill.alpha != TransparentAlpha) 19843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 1985bd65948def60e897a2641d9503470945c304f46fcristy CacheView 1986bd65948def60e897a2641d9503470945c304f46fcristy *annotate_view; 1987bd65948def60e897a2641d9503470945c304f46fcristy 19883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy MagickBooleanType 19893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy sync; 19903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1991101ab708b0574518ac5715da4d3915400e9df79acristy PixelInfo 19923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy fill_color; 19933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 19943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 19953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Render fill color. 19963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 199717f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy if (image->alpha_trait == UndefinedPixelTrait) 199863240888c3975789a09c2494a4654b523931df96cristy (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception); 199917f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy if (annotate_image->alpha_trait == UndefinedPixelTrait) 200063240888c3975789a09c2494a4654b523931df96cristy (void) SetImageAlphaChannel(annotate_image,OpaqueAlphaChannel, 200163240888c3975789a09c2494a4654b523931df96cristy exception); 20023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy fill_color=draw_info->fill; 200346ff2676b1044ea4101ac7a59b83289cd8f6cfdacristy annotate_view=AcquireAuthenticCacheView(annotate_image,exception); 2004bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (y=0; y < (ssize_t) annotate_image->rows; y++) 20053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 2006bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy register ssize_t 20073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy x; 20083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 20094c08aed51c5899665ade97263692328eea4af106cristy register Quantum 201005d2ff7ebf21f659f5b11e45afb294e152f4330cdirk *magick_restrict q; 20113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 20123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy q=GetCacheViewAuthenticPixels(annotate_view,0,y,annotate_image->columns, 20133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1,exception); 20146193b86c0b59030b647a10c75f37ec82d73e3695cristy if (q == (Quantum *) NULL) 20153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 2016bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (x=0; x < (ssize_t) annotate_image->columns; x++) 20173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 20182ed42f6d7c2245432767ea446742977ee87e963ccristy (void) GetFillColor(draw_info,x,y,&fill_color,exception); 201955cb9f15b804f98ac7d37615b8f5f8888fc792f4cristy SetPixelAlpha(annotate_image,ClampToQuantum((((double) QuantumScale* 202055cb9f15b804f98ac7d37615b8f5f8888fc792f4cristy GetPixelIntensity(annotate_image,q)*fill_color.alpha))),q); 20214c08aed51c5899665ade97263692328eea4af106cristy SetPixelRed(annotate_image,fill_color.red,q); 20224c08aed51c5899665ade97263692328eea4af106cristy SetPixelGreen(annotate_image,fill_color.green,q); 20234c08aed51c5899665ade97263692328eea4af106cristy SetPixelBlue(annotate_image,fill_color.blue,q); 2024ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy q+=GetPixelChannels(annotate_image); 20253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 20263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy sync=SyncCacheViewAuthenticPixels(annotate_view,exception); 20273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (sync == MagickFalse) 20283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 20293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 20303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_view=DestroyCacheView(annotate_view); 203139172408bad7ef2ef00a815fa9abf9979e7857cbcristy (void) CompositeImage(image,annotate_image,OverCompositeOp,MagickTrue, 2032bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy (ssize_t) ceil(offset->x-0.5),(ssize_t) ceil(offset->y-(metrics->ascent+ 2033e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy metrics->descent)-0.5),exception); 20343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 20353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_image=DestroyImage(annotate_image); 20363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(MagickTrue); 20373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 20383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 20393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 20403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 20413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 20423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 20433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 20443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy+ R e n d e r X 1 1 % 20453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 20463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 20473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 20483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 20493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 20503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% RenderX11() renders text on the image with an X11 font. It also returns the 20513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% bounding box of the text relative to the image. 20523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 20533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% The format of the RenderX11 method is: 20543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 20553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% MagickBooleanType RenderX11(Image *image,DrawInfo *draw_info, 20565cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% const PointInfo *offset,TypeMetric *metrics,ExceptionInfo *exception) 20573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 20583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A description of each parameter follows: 20593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 20603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o image: the image. 20613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 20623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o draw_info: the draw info. 20633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 20643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o offset: (x,y) location of text relative to image. 20653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 20663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o metrics: bounding box of text. 20673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 20685cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% o exception: return any errors or warnings in this structure. 20695cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% 20703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 2071cc168c2dcad169c22f123761f2f53d867fb2f149cristystatic MagickBooleanType RenderX11(Image *image,const DrawInfo *draw_info, 2072cc168c2dcad169c22f123761f2f53d867fb2f149cristy const PointInfo *offset,TypeMetric *metrics,ExceptionInfo *exception) 20733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 20743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy MagickBooleanType 20753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy status; 20763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2077d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy if (annotate_semaphore == (SemaphoreInfo *) NULL) 207804b11db5504ecdf205114ae7e9e68774a1ff0b9bcristy ActivateSemaphoreInfo(&annotate_semaphore); 2079d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy LockSemaphoreInfo(annotate_semaphore); 2080534d0a353b31242ce2f7b26c4eb4fe53f914d0f5cristy status=XRenderImage(image,draw_info,offset,metrics,exception); 2081d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy UnlockSemaphoreInfo(annotate_semaphore); 2082534d0a353b31242ce2f7b26c4eb4fe53f914d0f5cristy return(status); 20833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 2084