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" 49ba4ad2dfd3d5b883e8aa7d6e8b4e6f9613dc3c45Cristy#include "MagickCore/cache-private.h" 504c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/cache-view.h" 51c9afe1687cd4da5d2382a9ca3ca12f30d8baa96fcristy#include "MagickCore/channel.h" 524c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/client.h" 534c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/color.h" 544c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/color-private.h" 5554b92627b2e9657853beee431546d08234276477cristy#include "MagickCore/colorspace-private.h" 564c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/composite.h" 574c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/composite-private.h" 584c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/constitute.h" 594c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/draw.h" 604c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/draw-private.h" 613644bdf56f0081bcae1f4dbc69c2d06713f6203bcristy#include "MagickCore/enhance.h" 624c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/exception.h" 634c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/exception-private.h" 644c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/gem.h" 654c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/geometry.h" 664c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/image-private.h" 674c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/log.h" 684c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/quantum.h" 694c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/quantum-private.h" 704c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/pixel-accessor.h" 714c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/property.h" 724c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/resource_.h" 734c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/semaphore.h" 744c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/statistic.h" 754c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/string_.h" 7617f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy#include "MagickCore/token.h" 774c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/token-private.h" 7806f590165f0505d42005264893fe14a9e8a79986dirk#include "MagickCore/transform-private.h" 794c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/type.h" 804c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/utility.h" 81d1dd6e4fefa0810b9893e6ac9418f79c97c1b39acristy#include "MagickCore/utility-private.h" 82bcbda3fd7d9f3084869f5cebabceb0324c3b2cd7cristy#include "MagickCore/xwindow.h" 834c08aed51c5899665ade97263692328eea4af106cristy#include "MagickCore/xwindow-private.h" 843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_FREETYPE_DELEGATE) 8507a3cca00593c795eb8e0427f5bc4c2bcad3f0fbcristy#if defined(__MINGW32__) || defined(__MINGW64__) 863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# undef interface 873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif 8803f187ee83f1927717c93c57af06d5e030a194becristy#include <ft2build.h> 893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(FT_FREETYPE_H) 903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# include FT_FREETYPE_H 913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else 923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# include <freetype/freetype.h> 933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif 943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(FT_GLYPH_H) 953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# include FT_GLYPH_H 963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else 973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# include <freetype/ftglyph.h> 983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif 993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(FT_OUTLINE_H) 1003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# include FT_OUTLINE_H 1013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else 1023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# include <freetype/ftoutln.h> 1033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif 1043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(FT_BBOX_H) 1053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# include FT_BBOX_H 1063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else 1073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy# include <freetype/ftbbox.h> 1083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif /* defined(FT_BBOX_H) */ 1093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif 11017f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy#if defined(MAGICKCORE_RAQM_DELEGATE) 11169a0d3b5699c573f650e6b61f98ce4579d6f218cCristy#include <raqm.h> 112ea866ca14ef4019d49cf678d35b405512b210b85Cristy#endif 11317f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristytypedef struct _GraphemeInfo 11469a0d3b5699c573f650e6b61f98ce4579d6f218cCristy{ 11587dc5e4e6f9471304ba85f508de30e664b484d3aCristy size_t 11669a0d3b5699c573f650e6b61f98ce4579d6f218cCristy index, 11769a0d3b5699c573f650e6b61f98ce4579d6f218cCristy x_offset, 11869a0d3b5699c573f650e6b61f98ce4579d6f218cCristy x_advance, 11969a0d3b5699c573f650e6b61f98ce4579d6f218cCristy y_offset; 12069a0d3b5699c573f650e6b61f98ce4579d6f218cCristy 12187dc5e4e6f9471304ba85f508de30e664b484d3aCristy size_t 12269a0d3b5699c573f650e6b61f98ce4579d6f218cCristy cluster; 12317f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy} GraphemeInfo; 1245eb36084e86f5ab4a877c2b31c19880b0b0b02e3Cristy 1253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 126d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy Annotate semaphores. 127d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy*/ 128d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristystatic SemaphoreInfo 129d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy *annotate_semaphore = (SemaphoreInfo *) NULL; 130d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy 131d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy/* 1323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Forward declarations. 1333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 1343ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType 1355cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy RenderType(Image *,const DrawInfo *,const PointInfo *,TypeMetric *, 1365cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy ExceptionInfo *), 1375cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy RenderPostscript(Image *,const DrawInfo *,const PointInfo *,TypeMetric *, 1385cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy ExceptionInfo *), 1393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy RenderFreetype(Image *,const DrawInfo *,const char *,const PointInfo *, 1405cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy TypeMetric *,ExceptionInfo *), 1415cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy RenderX11(Image *,const DrawInfo *,const PointInfo *,TypeMetric *, 1425cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy ExceptionInfo *); 1433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 1453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 1463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 1473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 1483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 149d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy+ A n n o t a t e C o m p o n e n t G e n e s i s % 150d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% % 151d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% % 152d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% % 153d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 154d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% 155d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% AnnotateComponentGenesis() instantiates the annotate component. 156d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% 157d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% The format of the AnnotateComponentGenesis method is: 158d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% 159d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% MagickBooleanType AnnotateComponentGenesis(void) 160d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% 161d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy*/ 1625ff4eaf57b3cd47d0371f204f865cbba614674a0cristyMagickPrivate MagickBooleanType AnnotateComponentGenesis(void) 163d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy{ 1647c9770650f31145e0fe8811d10b2e0ecd47697c8cristy if (annotate_semaphore == (SemaphoreInfo *) NULL) 1657c9770650f31145e0fe8811d10b2e0ecd47697c8cristy annotate_semaphore=AcquireSemaphoreInfo(); 166d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy return(MagickTrue); 167d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy} 168d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy 169d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy/* 170d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 171d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% % 172d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% % 173d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% % 174d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy+ 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 % 175d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% % 176d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% % 177d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% % 178d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 179d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% 180d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% AnnotateComponentTerminus() destroys the annotate component. 181d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% 182d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% The format of the AnnotateComponentTerminus method is: 183d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% 184d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% AnnotateComponentTerminus(void) 185d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% 186d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy*/ 1875ff4eaf57b3cd47d0371f204f865cbba614674a0cristyMagickPrivate void AnnotateComponentTerminus(void) 188d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy{ 189d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy if (annotate_semaphore == (SemaphoreInfo *) NULL) 19004b11db5504ecdf205114ae7e9e68774a1ff0b9bcristy ActivateSemaphoreInfo(&annotate_semaphore); 1913d162a93f537cb7cbb6d9fa3b8e73e8f992a527acristy RelinquishSemaphoreInfo(&annotate_semaphore); 192d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy} 193d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy 194d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy/* 195d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 196d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% % 197d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% % 198d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy% % 1993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A n n o t a t e I m a g e % 2003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 2013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 2023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 2033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 2043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 2053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% AnnotateImage() annotates an image with text. Optionally you can include 2063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% any of the following bits of information about the image by embedding 2073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% the appropriate special characters: 2083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 209528127ac76bc2eda65c7e8407b11669b25513149cristy% \n newline 210528127ac76bc2eda65c7e8407b11669b25513149cristy% \r carriage return 211528127ac76bc2eda65c7e8407b11669b25513149cristy% < less-than character. 212528127ac76bc2eda65c7e8407b11669b25513149cristy% > greater-than character. 213528127ac76bc2eda65c7e8407b11669b25513149cristy% & ampersand character. 214528127ac76bc2eda65c7e8407b11669b25513149cristy% %% a percent sign 215528127ac76bc2eda65c7e8407b11669b25513149cristy% %b file size of image read in 216528127ac76bc2eda65c7e8407b11669b25513149cristy% %c comment meta-data property 217528127ac76bc2eda65c7e8407b11669b25513149cristy% %d directory component of path 218528127ac76bc2eda65c7e8407b11669b25513149cristy% %e filename extension or suffix 219528127ac76bc2eda65c7e8407b11669b25513149cristy% %f filename (including suffix) 220528127ac76bc2eda65c7e8407b11669b25513149cristy% %g layer canvas page geometry (equivalent to "%Wx%H%X%Y") 221528127ac76bc2eda65c7e8407b11669b25513149cristy% %h current image height in pixels 222528127ac76bc2eda65c7e8407b11669b25513149cristy% %i image filename (note: becomes output filename for "info:") 223528127ac76bc2eda65c7e8407b11669b25513149cristy% %k CALCULATED: number of unique colors 224528127ac76bc2eda65c7e8407b11669b25513149cristy% %l label meta-data property 225528127ac76bc2eda65c7e8407b11669b25513149cristy% %m image file format (file magic) 226528127ac76bc2eda65c7e8407b11669b25513149cristy% %n number of images in current image sequence 227528127ac76bc2eda65c7e8407b11669b25513149cristy% %o output filename (used for delegates) 228528127ac76bc2eda65c7e8407b11669b25513149cristy% %p index of image in current image list 229528127ac76bc2eda65c7e8407b11669b25513149cristy% %q quantum depth (compile-time constant) 230528127ac76bc2eda65c7e8407b11669b25513149cristy% %r image class and colorspace 231528127ac76bc2eda65c7e8407b11669b25513149cristy% %s scene number (from input unless re-assigned) 232528127ac76bc2eda65c7e8407b11669b25513149cristy% %t filename without directory or extension (suffix) 233528127ac76bc2eda65c7e8407b11669b25513149cristy% %u unique temporary filename (used for delegates) 234528127ac76bc2eda65c7e8407b11669b25513149cristy% %w current width in pixels 235528127ac76bc2eda65c7e8407b11669b25513149cristy% %x x resolution (density) 236528127ac76bc2eda65c7e8407b11669b25513149cristy% %y y resolution (density) 237528127ac76bc2eda65c7e8407b11669b25513149cristy% %z image depth (as read in unless modified, image save depth) 238528127ac76bc2eda65c7e8407b11669b25513149cristy% %A image transparency channel enabled (true/false) 239528127ac76bc2eda65c7e8407b11669b25513149cristy% %C image compression type 240528127ac76bc2eda65c7e8407b11669b25513149cristy% %D image GIF dispose method 241528127ac76bc2eda65c7e8407b11669b25513149cristy% %G original image size (%wx%h; before any resizes) 242528127ac76bc2eda65c7e8407b11669b25513149cristy% %H page (canvas) height 243528127ac76bc2eda65c7e8407b11669b25513149cristy% %M Magick filename (original file exactly as given, including read mods) 244528127ac76bc2eda65c7e8407b11669b25513149cristy% %O page (canvas) offset ( = %X%Y ) 245528127ac76bc2eda65c7e8407b11669b25513149cristy% %P page (canvas) size ( = %Wx%H ) 246528127ac76bc2eda65c7e8407b11669b25513149cristy% %Q image compression quality ( 0 = default ) 247528127ac76bc2eda65c7e8407b11669b25513149cristy% %S ?? scenes ?? 248528127ac76bc2eda65c7e8407b11669b25513149cristy% %T image time delay (in centi-seconds) 249528127ac76bc2eda65c7e8407b11669b25513149cristy% %U image resolution units 250528127ac76bc2eda65c7e8407b11669b25513149cristy% %W page (canvas) width 251528127ac76bc2eda65c7e8407b11669b25513149cristy% %X page (canvas) x offset (including sign) 252528127ac76bc2eda65c7e8407b11669b25513149cristy% %Y page (canvas) y offset (including sign) 253528127ac76bc2eda65c7e8407b11669b25513149cristy% %Z unique filename (used for delegates) 254528127ac76bc2eda65c7e8407b11669b25513149cristy% %@ CALCULATED: trim bounding box (without actually trimming) 255528127ac76bc2eda65c7e8407b11669b25513149cristy% %# CALCULATED: 'signature' hash of image values 2563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 2573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% The format of the AnnotateImage method is: 2583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 2595cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% MagickBooleanType AnnotateImage(Image *image,DrawInfo *draw_info, 2605cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% ExceptionInfo *exception) 2613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 2623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A description of each parameter follows: 2633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 2643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o image: the image. 2653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 2663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o draw_info: the draw info. 2673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 2685cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% o exception: return any errors or warnings in this structure. 2695cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% 2703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 2713ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport MagickBooleanType AnnotateImage(Image *image, 2725cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy const DrawInfo *draw_info,ExceptionInfo *exception) 2733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 2743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy char 275151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy primitive[MagickPathExtent], 2763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy **textlist; 2773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy DrawInfo 2793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *annotate, 2803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *annotate_info; 2813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy GeometryInfo 2833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy geometry_info; 2843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy MagickBooleanType 2863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy status; 2873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy PointInfo 2893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset; 2903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy RectangleInfo 2923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy geometry; 2933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 294bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy register ssize_t 2953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy i; 2963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy size_t 2983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy length; 2993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 3003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy TypeMetric 3013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics; 3023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 303bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy size_t 3045846039e7fade723e168819490eb771446e4b81fcristy height, 3053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy number_lines; 3063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 3073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image != (Image *) NULL); 308e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy assert(image->signature == MagickCoreSignature); 3093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->debug != MagickFalse) 3103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 3113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(draw_info != (DrawInfo *) NULL); 312e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy assert(draw_info->signature == MagickCoreSignature); 3133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (draw_info->text == (char *) NULL) 3143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(MagickFalse); 3153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (*draw_info->text == '\0') 3163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(MagickTrue); 3173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy textlist=StringToList(draw_info->text); 3183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (textlist == (char **) NULL) 3193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(MagickFalse); 3203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy length=strlen(textlist[0]); 3213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (i=1; textlist[i] != (char *) NULL; i++) 3223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (strlen(textlist[i]) > length) 3233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy length=strlen(textlist[i]); 324bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy number_lines=(size_t) i; 3253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate=CloneDrawInfo((ImageInfo *) NULL,draw_info); 3263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info=CloneDrawInfo((ImageInfo *) NULL,draw_info); 3273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy SetGeometry(image,&geometry); 3283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy SetGeometryInfo(&geometry_info); 3293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (annotate_info->geometry != (char *) NULL) 3303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 3313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) ParsePageGeometry(image,annotate_info->geometry,&geometry, 3325cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy exception); 3333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) ParseGeometry(annotate_info->geometry,&geometry_info); 3343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 3355cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy if (SetImageStorageClass(image,DirectClass,exception) == MagickFalse) 3363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(MagickFalse); 337a6400b1cfc3594644a0f02f3d77d920092f078eecristy if (IsGrayColorspace(image->colorspace) != MagickFalse) 3380c81d063030f7b30a97c7856e95534243cdc9e13cristy (void) SetImageColorspace(image,sRGBColorspace,exception); 3393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy status=MagickTrue; 3403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (i=0; textlist[i] != (char *) NULL; i++) 3413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 3423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 3433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Position text relative to image. 3443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 3453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.tx=geometry_info.xi-image->page.x; 3463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.ty=geometry_info.psi-image->page.y; 3473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) CloneString(&annotate->text,textlist[i]); 3485cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy (void) GetTypeMetrics(image,annotate,&metrics,exception); 349bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy height=(ssize_t) (metrics.ascent-metrics.descent+ 3505846039e7fade723e168819490eb771446e4b81fcristy draw_info->interline_spacing+0.5); 3513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy switch (annotate->gravity) 3523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 3533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case UndefinedGravity: 3543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy default: 3553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 3563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.x=annotate_info->affine.tx+i*annotate_info->affine.ry*height; 3573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.y=annotate_info->affine.ty+i*annotate_info->affine.sy*height; 3583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 3593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 3603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case NorthWestGravity: 3613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 3623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.x=(geometry.width == 0 ? -1.0 : 1.0)*annotate_info->affine.tx+i* 3633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.ry*height+annotate_info->affine.ry* 3643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (metrics.ascent+metrics.descent); 3653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.y=(geometry.height == 0 ? -1.0 : 1.0)*annotate_info->affine.ty+i* 3663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.sy*height+annotate_info->affine.sy* 3673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics.ascent; 3683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 3693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 3703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case NorthGravity: 3713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 3723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.x=(geometry.width == 0 ? -1.0 : 1.0)*annotate_info->affine.tx+ 3733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy geometry.width/2.0+i*annotate_info->affine.ry*height- 3743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.sx*(metrics.width+metrics.bounds.x1)/2.0+ 3753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.ry*(metrics.ascent+metrics.descent); 3763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.y=(geometry.height == 0 ? -1.0 : 1.0)*annotate_info->affine.ty+i* 3773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.sy*height+annotate_info->affine.sy* 3783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics.ascent-annotate_info->affine.rx*(metrics.width- 3793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics.bounds.x1)/2.0; 3803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 3813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 3823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case NorthEastGravity: 3833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 3843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.x=(geometry.width == 0 ? 1.0 : -1.0)*annotate_info->affine.tx+ 3853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy geometry.width+i*annotate_info->affine.ry*height- 3863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.sx*(metrics.width+metrics.bounds.x1)+ 3873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.ry*(metrics.ascent+metrics.descent)-1.0; 3883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.y=(geometry.height == 0 ? -1.0 : 1.0)*annotate_info->affine.ty+i* 3893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.sy*height+annotate_info->affine.sy* 3903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics.ascent-annotate_info->affine.rx*(metrics.width- 3913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics.bounds.x1); 3923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 3933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 3943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case WestGravity: 3953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 3963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.x=(geometry.width == 0 ? -1.0 : 1.0)*annotate_info->affine.tx+i* 3973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.ry*height+annotate_info->affine.ry* 3983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (metrics.ascent+metrics.descent-(number_lines-1.0)*height)/2.0; 3993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.y=(geometry.height == 0 ? -1.0 : 1.0)*annotate_info->affine.ty+ 4003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy geometry.height/2.0+i*annotate_info->affine.sy*height+ 4013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.sy*(metrics.ascent+metrics.descent- 402d4f277c15e3edbbeb2a4cc643a21b958cd8061dfCristy (number_lines-1.0)*height)/2.0; 4033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 4043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 4053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case CenterGravity: 4063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 4073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.x=(geometry.width == 0 ? -1.0 : 1.0)*annotate_info->affine.tx+ 4083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy geometry.width/2.0+i*annotate_info->affine.ry*height- 4093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.sx*(metrics.width+metrics.bounds.x1)/2.0+ 4103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.ry*(metrics.ascent+metrics.descent- 4116ad45e16bca2904129a25730316c9b4002055ea1Cristy (number_lines-1.0)*height)/2.0; 4123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.y=(geometry.height == 0 ? -1.0 : 1.0)*annotate_info->affine.ty+ 4133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy geometry.height/2.0+i*annotate_info->affine.sy*height- 4143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.rx*(metrics.width+metrics.bounds.x1)/2.0+ 4153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.sy*(metrics.ascent+metrics.descent- 416d4f277c15e3edbbeb2a4cc643a21b958cd8061dfCristy (number_lines-1.0)*height)/2.0; 4173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 4183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 4193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case EastGravity: 4203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 4213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.x=(geometry.width == 0 ? 1.0 : -1.0)*annotate_info->affine.tx+ 4223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy geometry.width+i*annotate_info->affine.ry*height- 4233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.sx*(metrics.width+metrics.bounds.x1)+ 4243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.ry*(metrics.ascent+metrics.descent- 4253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (number_lines-1.0)*height)/2.0-1.0; 4263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.y=(geometry.height == 0 ? -1.0 : 1.0)*annotate_info->affine.ty+ 4273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy geometry.height/2.0+i*annotate_info->affine.sy*height- 4283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.rx*(metrics.width+metrics.bounds.x1)+ 4293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.sy*(metrics.ascent+metrics.descent- 430d4f277c15e3edbbeb2a4cc643a21b958cd8061dfCristy (number_lines-1.0)*height)/2.0; 4313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 4323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 4333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case SouthWestGravity: 4343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 4353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.x=(geometry.width == 0 ? -1.0 : 1.0)*annotate_info->affine.tx+i* 4363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.ry*height-annotate_info->affine.ry* 4373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (number_lines-1.0)*height; 4383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.y=(geometry.height == 0 ? 1.0 : -1.0)*annotate_info->affine.ty+ 4393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy geometry.height+i*annotate_info->affine.sy*height- 4403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.sy*(number_lines-1.0)*height+metrics.descent; 4413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 4423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 4433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case SouthGravity: 4443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 4453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.x=(geometry.width == 0 ? -1.0 : 1.0)*annotate_info->affine.tx+ 4463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy geometry.width/2.0+i*annotate_info->affine.ry*height- 4473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.sx*(metrics.width+metrics.bounds.x1)/2.0- 4483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.ry*(number_lines-1.0)*height/2.0; 4493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.y=(geometry.height == 0 ? 1.0 : -1.0)*annotate_info->affine.ty+ 4503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy geometry.height+i*annotate_info->affine.sy*height- 4513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.rx*(metrics.width+metrics.bounds.x1)/2.0- 4523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.sy*(number_lines-1.0)*height+metrics.descent; 4533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 4543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 4553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case SouthEastGravity: 4563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 4573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.x=(geometry.width == 0 ? 1.0 : -1.0)*annotate_info->affine.tx+ 4583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy geometry.width+i*annotate_info->affine.ry*height- 4593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.sx*(metrics.width+metrics.bounds.x1)- 4603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.ry*(number_lines-1.0)*height-1.0; 4613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.y=(geometry.height == 0 ? 1.0 : -1.0)*annotate_info->affine.ty+ 4623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy geometry.height+i*annotate_info->affine.sy*height- 4633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.rx*(metrics.width+metrics.bounds.x1)- 4643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.sy*(number_lines-1.0)*height+metrics.descent; 4653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 4663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 4673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 4683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy switch (annotate->align) 4693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 4703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case LeftAlign: 4713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 4723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.x=annotate_info->affine.tx+i*annotate_info->affine.ry*height; 4733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.y=annotate_info->affine.ty+i*annotate_info->affine.sy*height; 4743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 4753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 4763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case CenterAlign: 4773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 4783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.x=annotate_info->affine.tx+i*annotate_info->affine.ry*height- 4793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.sx*(metrics.width+metrics.bounds.x1)/2.0; 4803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.y=annotate_info->affine.ty+i*annotate_info->affine.sy*height- 4813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.rx*(metrics.width+metrics.bounds.x1)/2.0; 4823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 4833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 4843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy case RightAlign: 4853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 4863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.x=annotate_info->affine.tx+i*annotate_info->affine.ry*height- 4873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.sx*(metrics.width+metrics.bounds.x1); 4883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.y=annotate_info->affine.ty+i*annotate_info->affine.sy*height- 4893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.rx*(metrics.width+metrics.bounds.x1); 4903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 4913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 4923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy default: 4933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 4943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 4954c08aed51c5899665ade97263692328eea4af106cristy if (draw_info->undercolor.alpha != TransparentAlpha) 4963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 4973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy DrawInfo 4983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *undercolor_info; 4993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 5003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 5013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Text box. 5023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 5033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy undercolor_info=CloneDrawInfo((ImageInfo *) NULL,(DrawInfo *) NULL); 5043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy undercolor_info->fill=draw_info->undercolor; 5053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy undercolor_info->affine=draw_info->affine; 5063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy undercolor_info->affine.tx=offset.x-draw_info->affine.ry*metrics.ascent; 5073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy undercolor_info->affine.ty=offset.y-draw_info->affine.sy*metrics.ascent; 508151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy (void) FormatLocaleString(primitive,MagickPathExtent, 509dcc02b0a70d924b55afa7ce2089c4c15b25f2e1fcristy "rectangle 0.0,0.0 %g,%g",metrics.origin.x,(double) height); 5103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) CloneString(&undercolor_info->primitive,primitive); 511018f07f7333b25743d0afff892450cebdb905c1acristy (void) DrawImage(image,undercolor_info,exception); 5123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) DestroyDrawInfo(undercolor_info); 5133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 5143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.tx=offset.x; 5153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.ty=offset.y; 516151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy (void) FormatLocaleString(primitive,MagickPathExtent,"stroke-width %g " 517a8549b176173db7680652304c372c64bb1a51737cristy "line 0,0 %g,0",metrics.underline_thickness,metrics.width); 5183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (annotate->decorate == OverlineDecoration) 5193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 5203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.ty-=(draw_info->affine.sy*(metrics.ascent+ 5213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics.descent-metrics.underline_position)); 5223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) CloneString(&annotate_info->primitive,primitive); 523018f07f7333b25743d0afff892450cebdb905c1acristy (void) DrawImage(image,annotate_info,exception); 5243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 5253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 5263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (annotate->decorate == UnderlineDecoration) 5273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 5283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.ty-=(draw_info->affine.sy* 5293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics.underline_position); 5303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) CloneString(&annotate_info->primitive,primitive); 531018f07f7333b25743d0afff892450cebdb905c1acristy (void) DrawImage(image,annotate_info,exception); 5323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 5333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 5343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Annotate image with text. 5353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 5365cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy status=RenderType(image,annotate,&offset,&metrics,exception); 5373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (status == MagickFalse) 5383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 5393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (annotate->decorate == LineThroughDecoration) 5403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 5413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->affine.ty-=(draw_info->affine.sy*(height+ 5423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics.underline_position+metrics.descent)/2.0); 5433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) CloneString(&annotate_info->primitive,primitive); 544018f07f7333b25743d0afff892450cebdb905c1acristy (void) DrawImage(image,annotate_info,exception); 5453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 5463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 5473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 5483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Relinquish resources. 5493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 5503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info=DestroyDrawInfo(annotate_info); 5513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate=DestroyDrawInfo(annotate); 5523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (i=0; textlist[i] != (char *) NULL; i++) 5533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy textlist[i]=DestroyString(textlist[i]); 5543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy textlist=(char **) RelinquishMagickMemory(textlist); 5553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(status); 5563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 5573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 5583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 5593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 5613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 5623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 5633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% F o r m a t M a g i c k C a p t i o n % 5643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 5653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 5663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 5673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 5683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 5693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% FormatMagickCaption() formats a caption so that it fits within the image 5703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% width. It returns the number of lines in the formatted caption. 5713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 5723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% The format of the FormatMagickCaption method is: 5733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 574bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy% ssize_t FormatMagickCaption(Image *image,DrawInfo *draw_info, 5755cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% const MagickBooleanType split,TypeMetric *metrics,char **caption, 5765cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% ExceptionInfo *exception) 5773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 5783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A description of each parameter follows. 5793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 5803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o image: The image. 5813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 5823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o draw_info: the draw info. 5833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 5846b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy% o split: when no convenient line breaks-- insert newline. 5856b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy% 5863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o metrics: Return the font metrics in this structure. 5873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 5886b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy% o caption: the caption. 5896b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy% 5905cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% o exception: return any errors or warnings in this structure. 5915cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% 5923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 593bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristyMagickExport ssize_t FormatMagickCaption(Image *image,DrawInfo *draw_info, 5945cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy const MagickBooleanType split,TypeMetric *metrics,char **caption, 5955cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy ExceptionInfo *exception) 5963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 59774966dbfe99011d1f7bea577e97a3d9a7b9836c7cristy char 59874966dbfe99011d1f7bea577e97a3d9a7b9836c7cristy *text; 59974966dbfe99011d1f7bea577e97a3d9a7b9836c7cristy 6003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy MagickBooleanType 60120aa2994f8d56f6f03a7a96b2a25d93b906989bcCristy digit, 6023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy status; 6033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 6043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy register char 6053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *p, 6063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *q, 6073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *s; 6083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 609bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy register ssize_t 6103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy i; 6113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 612bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy size_t 6133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy width; 6143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 6156193b86c0b59030b647a10c75f37ec82d73e3695cristy ssize_t 6166193b86c0b59030b647a10c75f37ec82d73e3695cristy n; 6176193b86c0b59030b647a10c75f37ec82d73e3695cristy 61820aa2994f8d56f6f03a7a96b2a25d93b906989bcCristy digit=MagickFalse; 61974966dbfe99011d1f7bea577e97a3d9a7b9836c7cristy text=AcquireString(draw_info->text); 6203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy q=draw_info->text; 6213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy s=(char *) NULL; 6223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (p=(*caption); GetUTFCode(p) != 0; p+=GetUTFOctets(p)) 6233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 62420aa2994f8d56f6f03a7a96b2a25d93b906989bcCristy if ((digit == MagickFalse) && (IsUTFSpace(GetUTFCode(p)) != MagickFalse)) 6253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy s=p; 62620aa2994f8d56f6f03a7a96b2a25d93b906989bcCristy digit=((GetUTFCode(p) >= 0x0030) && (GetUTFCode(p) <= 0x0039)) ? 62720aa2994f8d56f6f03a7a96b2a25d93b906989bcCristy MagickTrue : MagickFalse; 6282911f2d54257d36e1086061dbcc312fdad781070cristy if (GetUTFCode(p) == '\n') 629e2c81adf02cbe4bb92991389437a2a1daf8ed313cristy q=draw_info->text; 630bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (i=0; i < (ssize_t) GetUTFOctets(p); i++) 6313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *q++=(*(p+i)); 6323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *q='\0'; 6335cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy status=GetTypeMetrics(image,draw_info,metrics,exception); 6343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (status == MagickFalse) 6353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 63678fed5ea9a7f0a35e641ce3bc6f835fb099c4d20cristy width=(size_t) floor(metrics->width+draw_info->stroke_width+0.5); 63774966dbfe99011d1f7bea577e97a3d9a7b9836c7cristy if ((width <= image->columns) || (strcmp(text,draw_info->text) == 0)) 6386193b86c0b59030b647a10c75f37ec82d73e3695cristy continue; 63974966dbfe99011d1f7bea577e97a3d9a7b9836c7cristy (void) strcpy(text,draw_info->text); 6404aa314e7f9e09c30fcedcd112156b1dfb712b62dcristy if ((s != (char *) NULL) && (GetUTFOctets(s) == 1)) 6413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 6423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *s='\n'; 6433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy p=s; 6443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 6453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 6464aa314e7f9e09c30fcedcd112156b1dfb712b62dcristy if ((s != (char *) NULL) || (split != MagickFalse)) 6476b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy { 6486b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy char 6496b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy *target; 6503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 6516b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy /* 6526b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy No convenient line breaks-- insert newline. 6536b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy */ 6546b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy target=AcquireString(*caption); 6556b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy n=p-(*caption); 6566b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy CopyMagickString(target,*caption,n+1); 6576b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy ConcatenateMagickString(target,"\n",strlen(*caption)+1); 6586b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy ConcatenateMagickString(target,p,strlen(*caption)+2); 6596b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy (void) DestroyString(*caption); 6606b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy *caption=target; 6616b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy p=(*caption)+n; 6626b1d05e71aed91c7f85ff155dfad281e24d16fe5cristy } 6633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy q=draw_info->text; 6646193b86c0b59030b647a10c75f37ec82d73e3695cristy s=(char *) NULL; 6653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 66674966dbfe99011d1f7bea577e97a3d9a7b9836c7cristy text=DestroyString(text); 6676193b86c0b59030b647a10c75f37ec82d73e3695cristy n=0; 6683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (p=(*caption); GetUTFCode(p) != 0; p+=GetUTFOctets(p)) 6693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (GetUTFCode(p) == '\n') 6706193b86c0b59030b647a10c75f37ec82d73e3695cristy n++; 6716193b86c0b59030b647a10c75f37ec82d73e3695cristy return(n); 6723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 6733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 6743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 6753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 6773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 6783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 6793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% G e t M u l t i l i n e T y p e M e t r i c s % 6803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 6813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 6823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 6833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 6843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 6853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% GetMultilineTypeMetrics() returns the following information for the 6863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% specified font and text: 6873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 6883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% character width 6893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% character height 6903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% ascender 6913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% descender 6923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% text width 6933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% text height 6943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% maximum horizontal advance 6953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% bounds: x1 6963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% bounds: y1 6973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% bounds: x2 6983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% bounds: y2 6993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% origin: x 7003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% origin: y 7013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% underline position 7023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% underline thickness 7033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 7043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% This method is like GetTypeMetrics() but it returns the maximum text width 7053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% and height for multiple lines of text. 7063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 7073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% The format of the GetMultilineTypeMetrics method is: 7083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 7093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% MagickBooleanType GetMultilineTypeMetrics(Image *image, 7105cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% const DrawInfo *draw_info,TypeMetric *metrics,ExceptionInfo *exception) 7113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 7123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A description of each parameter follows: 7133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 7143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o image: the image. 7153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 7163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o draw_info: the draw info. 7173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 7183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o metrics: Return the font metrics in this structure. 7193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 7205cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% o exception: return any errors or warnings in this structure. 7215cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% 7223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 7233ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport MagickBooleanType GetMultilineTypeMetrics(Image *image, 7245cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy const DrawInfo *draw_info,TypeMetric *metrics,ExceptionInfo *exception) 7253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 7263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy char 7273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy **textlist; 7283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy DrawInfo 7303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *annotate_info; 7313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy MagickBooleanType 7333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy status; 7343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 735bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy register ssize_t 7363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy i; 7373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy TypeMetric 7393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy extent; 7403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image != (Image *) NULL); 742e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy assert(image->signature == MagickCoreSignature); 7433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->debug != MagickFalse) 7443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 7453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(draw_info != (DrawInfo *) NULL); 7463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(draw_info->text != (char *) NULL); 747e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy assert(draw_info->signature == MagickCoreSignature); 7483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (*draw_info->text == '\0') 7493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(MagickFalse); 7503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info=CloneDrawInfo((ImageInfo *) NULL,draw_info); 7513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->text=DestroyString(annotate_info->text); 7523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 7533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Convert newlines to multiple lines of text. 7543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 7553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy textlist=StringToList(draw_info->text); 7563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (textlist == (char **) NULL) 7573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(MagickFalse); 7583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->render=MagickFalse; 759024843f38984cd26602f0b3b28a0768dfa056bb5cristy annotate_info->direction=UndefinedDirection; 7603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) ResetMagickMemory(metrics,0,sizeof(*metrics)); 7613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) ResetMagickMemory(&extent,0,sizeof(extent)); 7623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 7633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Find the widest of the text lines. 7643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 7653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->text=textlist[0]; 7665cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy status=GetTypeMetrics(image,annotate_info,&extent,exception); 7673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *metrics=extent; 7683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (i=1; textlist[i] != (char *) NULL; i++) 7693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 7703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->text=textlist[i]; 7715cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy status=GetTypeMetrics(image,annotate_info,&extent,exception); 7723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (extent.width > metrics->width) 7733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *metrics=extent; 7743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 775e2c81adf02cbe4bb92991389437a2a1daf8ed313cristy metrics->height=(double) (i*(size_t) (metrics->ascent-metrics->descent+0.5)+ 776e2c81adf02cbe4bb92991389437a2a1daf8ed313cristy (i-1)*draw_info->interline_spacing); 7773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 7783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Relinquish resources. 7793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 7803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->text=(char *) NULL; 7813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info=DestroyDrawInfo(annotate_info); 7823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (i=0; textlist[i] != (char *) NULL; i++) 7833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy textlist[i]=DestroyString(textlist[i]); 7843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy textlist=(char **) RelinquishMagickMemory(textlist); 7853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(status); 7863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 7873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 7883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 7893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 7903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 7913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 7923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 7933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% G e t T y p e M e t r i c s % 7943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 7953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 7963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 7973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 7983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 7993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% GetTypeMetrics() returns the following information for the specified font 8003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% and text: 8013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 8023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% character width 8033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% character height 8043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% ascender 8053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% descender 8063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% text width 8073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% text height 8083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% maximum horizontal advance 8093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% bounds: x1 8103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% bounds: y1 8113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% bounds: x2 8123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% bounds: y2 8133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% origin: x 8143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% origin: y 8153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% underline position 8163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% underline thickness 8173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 8183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% The format of the GetTypeMetrics method is: 8193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 8203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% MagickBooleanType GetTypeMetrics(Image *image,const DrawInfo *draw_info, 8215cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% TypeMetric *metrics,ExceptionInfo *exception) 8223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 8233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A description of each parameter follows: 8243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 8253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o image: the image. 8263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 8273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o draw_info: the draw info. 8283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 8293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o metrics: Return the font metrics in this structure. 8303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 8315cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% o exception: return any errors or warnings in this structure. 8325cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% 8333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 8343ed852eea50f9d4cd633efb8c2b054b8e33c253cristyMagickExport MagickBooleanType GetTypeMetrics(Image *image, 8355cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy const DrawInfo *draw_info,TypeMetric *metrics,ExceptionInfo *exception) 8363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 8373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy DrawInfo 8383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *annotate_info; 8393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 8403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy MagickBooleanType 8413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy status; 8423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 8433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy PointInfo 8443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset; 8453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 8463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(image != (Image *) NULL); 847e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy assert(image->signature == MagickCoreSignature); 8483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->debug != MagickFalse) 8493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename); 8503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(draw_info != (DrawInfo *) NULL); 8513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy assert(draw_info->text != (char *) NULL); 852e1c94d9d25db6b0dd7a5028ffee31d1057855d73cristy assert(draw_info->signature == MagickCoreSignature); 8533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info=CloneDrawInfo((ImageInfo *) NULL,draw_info); 8543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->render=MagickFalse; 855024843f38984cd26602f0b3b28a0768dfa056bb5cristy annotate_info->direction=UndefinedDirection; 8563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) ResetMagickMemory(metrics,0,sizeof(*metrics)); 8573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.x=0.0; 8583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy offset.y=0.0; 8595cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy status=RenderType(image,annotate_info,&offset,metrics,exception); 8603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->debug != MagickFalse) 8613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) LogMagickEvent(AnnotateEvent,GetMagickModule(),"Metrics: text: %s; " 862e7f5109f30fc7242d04a26174a9138483dda5b6acristy "width: %g; height: %g; ascent: %g; descent: %g; max advance: %g; " 863a8549b176173db7680652304c372c64bb1a51737cristy "bounds: %g,%g %g,%g; origin: %g,%g; pixels per em: %g,%g; " 864e7f5109f30fc7242d04a26174a9138483dda5b6acristy "underline position: %g; underline thickness: %g",annotate_info->text, 8653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->width,metrics->height,metrics->ascent,metrics->descent, 8663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->max_advance,metrics->bounds.x1,metrics->bounds.y1, 8674c08aed51c5899665ade97263692328eea4af106cristy metrics->bounds.x2,metrics->bounds.y2,metrics->origin.x,metrics->origin.y, 8684c08aed51c5899665ade97263692328eea4af106cristy metrics->pixels_per_em.x,metrics->pixels_per_em.y, 8693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->underline_position,metrics->underline_thickness); 8703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info=DestroyDrawInfo(annotate_info); 8713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(status); 8723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 8733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 8743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 8753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 8763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 8773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 8783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 8793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy+ R e n d e r T y p e % 8803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 8813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 8823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 8833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 8843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 8853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% RenderType() renders text on the image. It also returns the bounding box of 8863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% the text relative to the image. 8873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 8883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% The format of the RenderType method is: 8893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 8903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% MagickBooleanType RenderType(Image *image,DrawInfo *draw_info, 8915cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% const PointInfo *offset,TypeMetric *metrics,ExceptionInfo *exception) 8923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 8933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A description of each parameter follows: 8943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 8953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o image: the image. 8963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 8973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o draw_info: the draw info. 8983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 8993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o offset: (x,y) location of text relative to image. 9003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 9013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o metrics: bounding box of text. 9023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 9035cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% o exception: return any errors or warnings in this structure. 9045cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% 9053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 9063ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType RenderType(Image *image,const DrawInfo *draw_info, 9075cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy const PointInfo *offset,TypeMetric *metrics,ExceptionInfo *exception) 9083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 9093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const TypeInfo 9103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *type_info; 9113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 9123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy DrawInfo 9133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *annotate_info; 9143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 9153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy MagickBooleanType 9163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy status; 9173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 9183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy type_info=(const TypeInfo *) NULL; 9193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (draw_info->font != (char *) NULL) 9203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 9213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (*draw_info->font == '@') 9223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 9233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy status=RenderFreetype(image,draw_info,draw_info->encoding,offset, 9245cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy metrics,exception); 9253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(status); 9263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 9273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (*draw_info->font == '-') 9285cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy return(RenderX11(image,draw_info,offset,metrics,exception)); 9293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (IsPathAccessible(draw_info->font) != MagickFalse) 9303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 9313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy status=RenderFreetype(image,draw_info,draw_info->encoding,offset, 9325cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy metrics,exception); 9333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(status); 9343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 9355cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy type_info=GetTypeInfo(draw_info->font,exception); 9363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (type_info == (const TypeInfo *) NULL) 9375cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy (void) ThrowMagickException(exception,GetMagickModule(),TypeWarning, 938efe601ce9ea5ad34ad0e8ad6e61d9be9b148b2a3cristy "UnableToReadFont","`%s'",draw_info->font); 9393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 9403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if ((type_info == (const TypeInfo *) NULL) && 9413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (draw_info->family != (const char *) NULL)) 9423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 9433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy type_info=GetTypeInfoByFamily(draw_info->family,draw_info->style, 9445cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy draw_info->stretch,draw_info->weight,exception); 9453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (type_info == (const TypeInfo *) NULL) 9465cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy (void) ThrowMagickException(exception,GetMagickModule(),TypeWarning, 947efe601ce9ea5ad34ad0e8ad6e61d9be9b148b2a3cristy "UnableToReadFont","`%s'",draw_info->family); 9483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 9493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (type_info == (const TypeInfo *) NULL) 950d984f27fbbb96073787c88f4c9409d7f836cedc5cristy type_info=GetTypeInfoByFamily("Arial",draw_info->style, 9515cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy draw_info->stretch,draw_info->weight,exception); 952d984f27fbbb96073787c88f4c9409d7f836cedc5cristy if (type_info == (const TypeInfo *) NULL) 953cbb34a4def108d6db032ca9631a433afd3ea5a5dcristy type_info=GetTypeInfoByFamily("Helvetica",draw_info->style, 9545cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy draw_info->stretch,draw_info->weight,exception); 9553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (type_info == (const TypeInfo *) NULL) 956704acaaebbfeec018847456e79de0ce301db126ecristy type_info=GetTypeInfoByFamily("Century Schoolbook",draw_info->style, 9575cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy draw_info->stretch,draw_info->weight,exception); 958704acaaebbfeec018847456e79de0ce301db126ecristy if (type_info == (const TypeInfo *) NULL) 9596193b86c0b59030b647a10c75f37ec82d73e3695cristy type_info=GetTypeInfoByFamily("Sans",draw_info->style, 9605cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy draw_info->stretch,draw_info->weight,exception); 9616193b86c0b59030b647a10c75f37ec82d73e3695cristy if (type_info == (const TypeInfo *) NULL) 9623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy type_info=GetTypeInfoByFamily((const char *) NULL,draw_info->style, 9635cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy draw_info->stretch,draw_info->weight,exception); 9643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (type_info == (const TypeInfo *) NULL) 9655cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy type_info=GetTypeInfo("*",exception); 966704acaaebbfeec018847456e79de0ce301db126ecristy if (type_info == (const TypeInfo *) NULL) 9673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 9685cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy status=RenderFreetype(image,draw_info,draw_info->encoding,offset,metrics, 9695cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy exception); 9703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(status); 9713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 9723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info=CloneDrawInfo((ImageInfo *) NULL,draw_info); 9733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->face=type_info->face; 9743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (type_info->metrics != (char *) NULL) 9753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) CloneString(&annotate_info->metrics,type_info->metrics); 9763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (type_info->glyphs != (char *) NULL) 9773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) CloneString(&annotate_info->font,type_info->glyphs); 9785cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy status=RenderFreetype(image,annotate_info,type_info->encoding,offset,metrics, 9795cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy exception); 9803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info=DestroyDrawInfo(annotate_info); 9813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(status); 9823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 9833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 9843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 9853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 9863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 9873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 9883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 9893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy+ R e n d e r F r e e t y p e % 9903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 9913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 9923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 9933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 9943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 9953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% RenderFreetype() renders text on the image with a Truetype font. It also 9963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% returns the bounding box of the text relative to the image. 9973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 9983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% The format of the RenderFreetype method is: 9993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 10003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% MagickBooleanType RenderFreetype(Image *image,DrawInfo *draw_info, 10015cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% const char *encoding,const PointInfo *offset,TypeMetric *metrics, 10025cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% ExceptionInfo *exception) 10033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 10043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A description of each parameter follows: 10053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 10063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o image: the image. 10073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 10083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o draw_info: the draw info. 10093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 10103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o encoding: the font encoding. 10113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 10123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o offset: (x,y) location of text relative to image. 10133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 10143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o metrics: bounding box of text. 10153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 10165cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% o exception: return any errors or warnings in this structure. 10175cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% 10183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 10193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 10203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(MAGICKCORE_FREETYPE_DELEGATE) 10212857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy 102287dc5e4e6f9471304ba85f508de30e664b484d3aCristystatic size_t ComplexTextLayout(const Image *image,const DrawInfo *draw_info, 102387dc5e4e6f9471304ba85f508de30e664b484d3aCristy const char *text,const size_t length,const FT_Face face,const FT_Int32 flags, 102487dc5e4e6f9471304ba85f508de30e664b484d3aCristy GraphemeInfo **grapheme,ExceptionInfo *exception) 102569a0d3b5699c573f650e6b61f98ce4579d6f218cCristy{ 102617f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy#if defined(MAGICKCORE_RAQM_DELEGATE) 10270d88ea3545d808eae9feeacdd57eec41db18d2baCristy const char 10280d88ea3545d808eae9feeacdd57eec41db18d2baCristy *features; 10290d88ea3545d808eae9feeacdd57eec41db18d2baCristy 103017f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy raqm_t 103117f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy *rq; 103217f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy 103317f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy raqm_glyph_t 103417f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy *glyphs; 103517f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy 103687dc5e4e6f9471304ba85f508de30e664b484d3aCristy register size_t 103787dc5e4e6f9471304ba85f508de30e664b484d3aCristy i; 103887dc5e4e6f9471304ba85f508de30e664b484d3aCristy 10396720ed7fdc6908b46f213f43c316fcccab53dbcdCristy size_t 10406720ed7fdc6908b46f213f43c316fcccab53dbcdCristy extent; 104187dc5e4e6f9471304ba85f508de30e664b484d3aCristy 10426720ed7fdc6908b46f213f43c316fcccab53dbcdCristy extent=0; 10430d88ea3545d808eae9feeacdd57eec41db18d2baCristy rq=raqm_create(); 104417f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy if (rq == (raqm_t *) NULL) 104517f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy goto cleanup; 10460d88ea3545d808eae9feeacdd57eec41db18d2baCristy if (raqm_set_text_utf8(rq,text,length) == 0) 104717f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy goto cleanup; 104887dc5e4e6f9471304ba85f508de30e664b484d3aCristy if (raqm_set_par_direction(rq,(raqm_direction_t) draw_info->direction) == 0) 104917f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy goto cleanup; 10500d88ea3545d808eae9feeacdd57eec41db18d2baCristy if (raqm_set_freetype_face(rq,face) == 0) 105117f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy goto cleanup; 10520d88ea3545d808eae9feeacdd57eec41db18d2baCristy features=GetImageProperty(image,"type:features",exception); 10530d88ea3545d808eae9feeacdd57eec41db18d2baCristy if (features != (const char *) NULL) 105417f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy { 105517f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy char 105617f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy breaker, 105717f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy quote, 105817f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy *token; 105917f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy 106017f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy int 106117f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy next, 106217f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy status_token; 106317f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy 106487dc5e4e6f9471304ba85f508de30e664b484d3aCristy TokenInfo 106587dc5e4e6f9471304ba85f508de30e664b484d3aCristy *token_info; 106687dc5e4e6f9471304ba85f508de30e664b484d3aCristy 106717f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy next=0; 106817f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy token_info=AcquireTokenInfo(); 106987dc5e4e6f9471304ba85f508de30e664b484d3aCristy token=AcquireString(""); 10700d88ea3545d808eae9feeacdd57eec41db18d2baCristy status_token=Tokenizer(token_info,0,token,50,features,"",",","",'\0', 10710d88ea3545d808eae9feeacdd57eec41db18d2baCristy &breaker,&next,"e); 107217f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy while (status_token == 0) 10730d88ea3545d808eae9feeacdd57eec41db18d2baCristy { 10740d88ea3545d808eae9feeacdd57eec41db18d2baCristy raqm_add_font_feature(rq,token,strlen(token)); 10750d88ea3545d808eae9feeacdd57eec41db18d2baCristy status_token=Tokenizer(token_info,0,token,50,features,"",",","",'\0', 10760d88ea3545d808eae9feeacdd57eec41db18d2baCristy &breaker,&next,"e); 10770d88ea3545d808eae9feeacdd57eec41db18d2baCristy } 107817f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy token_info=DestroyTokenInfo(token_info); 107917f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy token=DestroyString(token); 108017f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy } 10810d88ea3545d808eae9feeacdd57eec41db18d2baCristy if (raqm_layout(rq) == 0) 108217f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy goto cleanup; 10836720ed7fdc6908b46f213f43c316fcccab53dbcdCristy glyphs=raqm_get_glyphs(rq,&extent); 108417f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy if (glyphs == (raqm_glyph_t *) NULL) 108517f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy { 10866720ed7fdc6908b46f213f43c316fcccab53dbcdCristy extent=0; 108717f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy goto cleanup; 108817f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy } 10896720ed7fdc6908b46f213f43c316fcccab53dbcdCristy *grapheme=(GraphemeInfo *) AcquireQuantumMemory(extent,sizeof(**grapheme)); 109017f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy if (*grapheme == (GraphemeInfo *) NULL) 109117f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy { 10926720ed7fdc6908b46f213f43c316fcccab53dbcdCristy extent=0; 109317f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy goto cleanup; 109417f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy } 10956720ed7fdc6908b46f213f43c316fcccab53dbcdCristy for (i=0; i < (ssize_t) extent; i++) 10960d88ea3545d808eae9feeacdd57eec41db18d2baCristy { 10970d88ea3545d808eae9feeacdd57eec41db18d2baCristy (*grapheme)[i].index=glyphs[i].index; 10980d88ea3545d808eae9feeacdd57eec41db18d2baCristy (*grapheme)[i].x_offset=glyphs[i].x_offset; 10990d88ea3545d808eae9feeacdd57eec41db18d2baCristy (*grapheme)[i].x_advance=glyphs[i].x_advance; 11000d88ea3545d808eae9feeacdd57eec41db18d2baCristy (*grapheme)[i].y_offset=glyphs[i].y_offset; 11010d88ea3545d808eae9feeacdd57eec41db18d2baCristy (*grapheme)[i].cluster=glyphs[i].cluster; 11020d88ea3545d808eae9feeacdd57eec41db18d2baCristy } 110317f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy 110417f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristycleanup: 11050d88ea3545d808eae9feeacdd57eec41db18d2baCristy raqm_destroy(rq); 11066720ed7fdc6908b46f213f43c316fcccab53dbcdCristy return(extent); 110714c8ae4cf8fdcb1c1ed0f8fd1a5c3290414fe733Cristy#else 110887dc5e4e6f9471304ba85f508de30e664b484d3aCristy const char 110987dc5e4e6f9471304ba85f508de30e664b484d3aCristy *p; 111087dc5e4e6f9471304ba85f508de30e664b484d3aCristy 111169a0d3b5699c573f650e6b61f98ce4579d6f218cCristy FT_Error 111269a0d3b5699c573f650e6b61f98ce4579d6f218cCristy ft_status; 111369a0d3b5699c573f650e6b61f98ce4579d6f218cCristy 111469a0d3b5699c573f650e6b61f98ce4579d6f218cCristy register ssize_t 111569a0d3b5699c573f650e6b61f98ce4579d6f218cCristy i; 111669a0d3b5699c573f650e6b61f98ce4579d6f218cCristy 111769a0d3b5699c573f650e6b61f98ce4579d6f218cCristy ssize_t 111869a0d3b5699c573f650e6b61f98ce4579d6f218cCristy last_glyph; 111969a0d3b5699c573f650e6b61f98ce4579d6f218cCristy 1120751a6671c9b7480f3672a7ef6aa6e392f064b46ddirk magick_unreferenced(exception); 1121751a6671c9b7480f3672a7ef6aa6e392f064b46ddirk 112291c2741e03e3e692f6fe04eb02d059edbc0edb90Cristy /* 11239da9d9c28f5574cc630eb8d8a48186f4951c4e33Cristy Simple layout for bi-directional text (right-to-left or left-to-right). 112491c2741e03e3e692f6fe04eb02d059edbc0edb90Cristy */ 11250d88ea3545d808eae9feeacdd57eec41db18d2baCristy *grapheme=(GraphemeInfo *) AcquireQuantumMemory(length+1,sizeof(**grapheme)); 112617f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy if (*grapheme == (GraphemeInfo *) NULL) 112769a0d3b5699c573f650e6b61f98ce4579d6f218cCristy return(0); 112869a0d3b5699c573f650e6b61f98ce4579d6f218cCristy last_glyph=0; 1129d45bfbb9ef2f6b90eb038b56d1a416b59c68abe0shamsa p=text; 1130d45bfbb9ef2f6b90eb038b56d1a416b59c68abe0shamsa for (i=0; GetUTFCode(p) != 0; p+=GetUTFOctets(p), i++) 113169a0d3b5699c573f650e6b61f98ce4579d6f218cCristy { 113287dc5e4e6f9471304ba85f508de30e664b484d3aCristy (*grapheme)[i].index=(ssize_t) FT_Get_Char_Index(face,GetUTFCode(p)); 113391c2741e03e3e692f6fe04eb02d059edbc0edb90Cristy (*grapheme)[i].x_offset=0; 113491c2741e03e3e692f6fe04eb02d059edbc0edb90Cristy (*grapheme)[i].y_offset=0; 113591c2741e03e3e692f6fe04eb02d059edbc0edb90Cristy if (((*grapheme)[i].index != 0) && (last_glyph != 0)) 113669a0d3b5699c573f650e6b61f98ce4579d6f218cCristy { 113769a0d3b5699c573f650e6b61f98ce4579d6f218cCristy if (FT_HAS_KERNING(face)) 113869a0d3b5699c573f650e6b61f98ce4579d6f218cCristy { 113969a0d3b5699c573f650e6b61f98ce4579d6f218cCristy FT_Vector 114050d31568365a106c91ca4e827757fc2c806c6b16Cristy kerning; 114169a0d3b5699c573f650e6b61f98ce4579d6f218cCristy 114206d4a5a39532c883052f98c8e870d015be8db1ccCristy ft_status=FT_Get_Kerning(face,(FT_UInt) last_glyph,(FT_UInt) 114306d4a5a39532c883052f98c8e870d015be8db1ccCristy (*grapheme)[i].index,ft_kerning_default,&kerning); 114469a0d3b5699c573f650e6b61f98ce4579d6f218cCristy if (ft_status == 0) 114587dc5e4e6f9471304ba85f508de30e664b484d3aCristy (*grapheme)[i-1].x_advance+=(FT_Pos) ((draw_info->direction == 114687dc5e4e6f9471304ba85f508de30e664b484d3aCristy RightToLeftDirection ? -1.0 : 1.0)*kerning.x); 114769a0d3b5699c573f650e6b61f98ce4579d6f218cCristy } 114891c2741e03e3e692f6fe04eb02d059edbc0edb90Cristy } 114986bacded5c30fe8f40e3a992c3b07a7fd610cc12dirk ft_status=FT_Load_Glyph(face,(FT_UInt) (*grapheme)[i].index,flags); 115091c2741e03e3e692f6fe04eb02d059edbc0edb90Cristy (*grapheme)[i].x_advance=face->glyph->advance.x; 1151d45bfbb9ef2f6b90eb038b56d1a416b59c68abe0shamsa (*grapheme)[i].cluster=p-text; 115291c2741e03e3e692f6fe04eb02d059edbc0edb90Cristy last_glyph=(*grapheme)[i].index; 115369a0d3b5699c573f650e6b61f98ce4579d6f218cCristy } 115469a0d3b5699c573f650e6b61f98ce4579d6f218cCristy return((size_t) i); 115514c8ae4cf8fdcb1c1ed0f8fd1a5c3290414fe733Cristy#endif 115669a0d3b5699c573f650e6b61f98ce4579d6f218cCristy} 115769a0d3b5699c573f650e6b61f98ce4579d6f218cCristy 11583ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int TraceCubicBezier(FT_Vector *p,FT_Vector *q,FT_Vector *to, 11593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy DrawInfo *draw_info) 11603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 11613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy AffineMatrix 11623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy affine; 11633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 11643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy char 1165151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy path[MagickPathExtent]; 11663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 11673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy affine=draw_info->affine; 11689c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy (void) FormatLocaleString(path,MagickPathExtent,"C%g,%g %g,%g %g,%g", 11699c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy affine.tx+p->x/64.0,affine.ty-p->y/64.0,affine.tx+q->x/64.0,affine.ty- 11709c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy q->y/64.0,affine.tx+to->x/64.0,affine.ty-to->y/64.0); 11713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) ConcatenateString(&draw_info->primitive,path); 11723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(0); 11733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 11743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 11753ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int TraceLineTo(FT_Vector *to,DrawInfo *draw_info) 11763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 11773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy AffineMatrix 11783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy affine; 11793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 11803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy char 1181151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy path[MagickPathExtent]; 11823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 11833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy affine=draw_info->affine; 11849c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy (void) FormatLocaleString(path,MagickPathExtent,"L%g,%g",affine.tx+to->x/64.0, 11859c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy affine.ty-to->y/64.0); 11863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) ConcatenateString(&draw_info->primitive,path); 11873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(0); 11883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 11893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 11903ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int TraceMoveTo(FT_Vector *to,DrawInfo *draw_info) 11913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 11923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy AffineMatrix 11933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy affine; 11943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 11953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy char 1196151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy path[MagickPathExtent]; 11973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 11983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy affine=draw_info->affine; 11999c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy (void) FormatLocaleString(path,MagickPathExtent,"M%g,%g",affine.tx+to->x/64.0, 12009c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy affine.ty-to->y/64.0); 12013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) ConcatenateString(&draw_info->primitive,path); 12023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(0); 12033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 12043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12053ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic int TraceQuadraticBezier(FT_Vector *control,FT_Vector *to, 12063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy DrawInfo *draw_info) 12073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 12083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy AffineMatrix 12093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy affine; 12103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy char 1212151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy path[MagickPathExtent]; 12133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy affine=draw_info->affine; 12159c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy (void) FormatLocaleString(path,MagickPathExtent,"Q%g,%g %g,%g",affine.tx+ 12169c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy control->x/64.0,affine.ty-control->y/64.0,affine.tx+to->x/64.0,affine.ty- 12179c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy to->y/64.0); 12183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) ConcatenateString(&draw_info->primitive,path); 12193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(0); 12203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 12213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12223ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info, 12235cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy const char *encoding,const PointInfo *offset,TypeMetric *metrics, 12245cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy ExceptionInfo *exception) 12253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 12263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if !defined(FT_OPEN_PATHNAME) 12273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#define FT_OPEN_PATHNAME ft_open_pathname 12283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif 12293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy typedef struct _GlyphInfo 12313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 12323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy FT_UInt 12333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy id; 12343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy FT_Vector 12363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy origin; 12373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy FT_Glyph 12393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image; 12403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } GlyphInfo; 12413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const char 12433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *value; 12443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy DrawInfo 12463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *annotate_info; 12473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy FT_BBox 12493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy bounds; 12503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy FT_BitmapGlyph 12523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy bitmap; 12533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy FT_Encoding 12553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy encoding_type; 12563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy FT_Error 1258f8f295fde25dd8b1a50470d53b641d5265c0871fcristy ft_status; 12593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy FT_Face 12613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy face; 12623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy FT_Int32 12643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy flags; 12653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy FT_Library 12673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy library; 12683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy FT_Matrix 12703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy affine; 12713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy FT_Open_Args 12733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy args; 12743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy FT_Vector 12763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy origin; 12773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy GlyphInfo 12793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy glyph, 12803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy last_glyph; 12813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 128217f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy GraphemeInfo 128317f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy *grapheme; 128417f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy 1285f8f295fde25dd8b1a50470d53b641d5265c0871fcristy MagickBooleanType 1286f8f295fde25dd8b1a50470d53b641d5265c0871fcristy status; 1287f8f295fde25dd8b1a50470d53b641d5265c0871fcristy 12883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy PointInfo 12893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy point, 12903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy resolution; 12913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 12923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy register char 12933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *p; 12943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 129569a0d3b5699c573f650e6b61f98ce4579d6f218cCristy register ssize_t 129669a0d3b5699c573f650e6b61f98ce4579d6f218cCristy i; 129769a0d3b5699c573f650e6b61f98ce4579d6f218cCristy 129869a0d3b5699c573f650e6b61f98ce4579d6f218cCristy size_t 129969a0d3b5699c573f650e6b61f98ce4579d6f218cCristy length; 130069a0d3b5699c573f650e6b61f98ce4579d6f218cCristy 13019d314ff2c17a77996c05413c2013880387e50f0ecristy ssize_t 13029d314ff2c17a77996c05413c2013880387e50f0ecristy code, 13039d314ff2c17a77996c05413c2013880387e50f0ecristy y; 13049d314ff2c17a77996c05413c2013880387e50f0ecristy 13053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy static FT_Outline_Funcs 13063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy OutlineMethods = 13073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 13083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (FT_Outline_MoveTo_Func) TraceMoveTo, 13093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (FT_Outline_LineTo_Func) TraceLineTo, 13103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (FT_Outline_ConicTo_Func) TraceQuadraticBezier, 13113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (FT_Outline_CubicTo_Func) TraceCubicBezier, 13123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 0, 0 13133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy }; 13143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 13152857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy unsigned char 13162857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy *utf8; 13172857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy 13183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 13193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Initialize Truetype library. 13203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 1321f8f295fde25dd8b1a50470d53b641d5265c0871fcristy ft_status=FT_Init_FreeType(&library); 1322f8f295fde25dd8b1a50470d53b641d5265c0871fcristy if (ft_status != 0) 13233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ThrowBinaryException(TypeError,"UnableToInitializeFreetypeLibrary", 13243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy image->filename); 13253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy args.flags=FT_OPEN_PATHNAME; 13263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (draw_info->font == (char *) NULL) 13273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy args.pathname=ConstantString("helvetica"); 13283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 13293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (*draw_info->font != '@') 13303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy args.pathname=ConstantString(draw_info->font); 13313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 13323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy args.pathname=ConstantString(draw_info->font+1); 13333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy face=(FT_Face) NULL; 1334f8f295fde25dd8b1a50470d53b641d5265c0871fcristy ft_status=FT_Open_Face(library,&args,(long) draw_info->face,&face); 13353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy args.pathname=DestroyString(args.pathname); 1336f8f295fde25dd8b1a50470d53b641d5265c0871fcristy if (ft_status != 0) 13373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 13383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) FT_Done_FreeType(library); 13395cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy (void) ThrowMagickException(exception,GetMagickModule(),TypeError, 1340efe601ce9ea5ad34ad0e8ad6e61d9be9b148b2a3cristy "UnableToReadFont","`%s'",draw_info->font); 13415cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy return(RenderPostscript(image,draw_info,offset,metrics,exception)); 13423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 13433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if ((draw_info->metrics != (char *) NULL) && 13443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (IsPathAccessible(draw_info->metrics) != MagickFalse)) 13453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) FT_Attach_File(face,draw_info->metrics); 13463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy encoding_type=ft_encoding_unicode; 1347f8f295fde25dd8b1a50470d53b641d5265c0871fcristy ft_status=FT_Select_Charmap(face,encoding_type); 1348f8f295fde25dd8b1a50470d53b641d5265c0871fcristy if ((ft_status != 0) && (face->num_charmaps != 0)) 1349f8f295fde25dd8b1a50470d53b641d5265c0871fcristy ft_status=FT_Set_Charmap(face,face->charmaps[0]); 13503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (encoding != (const char *) NULL) 13513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 13523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(encoding,"AdobeCustom") == 0) 13533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy encoding_type=ft_encoding_adobe_custom; 13543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(encoding,"AdobeExpert") == 0) 13553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy encoding_type=ft_encoding_adobe_expert; 13563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(encoding,"AdobeStandard") == 0) 13573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy encoding_type=ft_encoding_adobe_standard; 13583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(encoding,"AppleRoman") == 0) 13593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy encoding_type=ft_encoding_apple_roman; 13603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(encoding,"BIG5") == 0) 13613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy encoding_type=ft_encoding_big5; 13623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(encoding,"GB2312") == 0) 13633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy encoding_type=ft_encoding_gb2312; 13643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(encoding,"Johab") == 0) 13653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy encoding_type=ft_encoding_johab; 13663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#if defined(ft_encoding_latin_1) 13673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(encoding,"Latin-1") == 0) 13683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy encoding_type=ft_encoding_latin_1; 13693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif 13703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(encoding,"Latin-2") == 0) 13713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy encoding_type=ft_encoding_latin_2; 13723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(encoding,"None") == 0) 13733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy encoding_type=ft_encoding_none; 13743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(encoding,"SJIScode") == 0) 13753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy encoding_type=ft_encoding_sjis; 13763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(encoding,"Symbol") == 0) 13773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy encoding_type=ft_encoding_symbol; 13783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(encoding,"Unicode") == 0) 13793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy encoding_type=ft_encoding_unicode; 13803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (LocaleCompare(encoding,"Wansung") == 0) 13813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy encoding_type=ft_encoding_wansung; 1382f8f295fde25dd8b1a50470d53b641d5265c0871fcristy ft_status=FT_Select_Charmap(face,encoding_type); 1383f8f295fde25dd8b1a50470d53b641d5265c0871fcristy if (ft_status != 0) 1384e3b2bb83e885eb35642c7029cedab50c5e1b263dcristy { 1385e3b2bb83e885eb35642c7029cedab50c5e1b263dcristy (void) FT_Done_Face(face); 1386e3b2bb83e885eb35642c7029cedab50c5e1b263dcristy (void) FT_Done_FreeType(library); 1387e3b2bb83e885eb35642c7029cedab50c5e1b263dcristy ThrowBinaryException(TypeError,"UnrecognizedFontEncoding",encoding); 1388e3b2bb83e885eb35642c7029cedab50c5e1b263dcristy } 13893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 13903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 13913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Set text size. 13923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 13933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy resolution.x=DefaultResolution; 13943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy resolution.y=DefaultResolution; 13953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (draw_info->density != (char *) NULL) 13963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 13973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy GeometryInfo 13983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy geometry_info; 13993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 14003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy MagickStatusType 140169a0d3b5699c573f650e6b61f98ce4579d6f218cCristy flags; 14023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 140369a0d3b5699c573f650e6b61f98ce4579d6f218cCristy flags=ParseGeometry(draw_info->density,&geometry_info); 14043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy resolution.x=geometry_info.rho; 14053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy resolution.y=geometry_info.sigma; 140669a0d3b5699c573f650e6b61f98ce4579d6f218cCristy if ((flags & SigmaValue) == 0) 14073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy resolution.y=resolution.x; 14083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 1409f8f295fde25dd8b1a50470d53b641d5265c0871fcristy ft_status=FT_Set_Char_Size(face,(FT_F26Dot6) (64.0*draw_info->pointsize), 14103ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (FT_F26Dot6) (64.0*draw_info->pointsize),(FT_UInt) resolution.x, 14113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (FT_UInt) resolution.y); 14122245bab833d2ab8dc9a2ec3389f5e1bd72ca9ec3Cristy if (ft_status != 0) 14132245bab833d2ab8dc9a2ec3389f5e1bd72ca9ec3Cristy { 14142245bab833d2ab8dc9a2ec3389f5e1bd72ca9ec3Cristy (void) FT_Done_Face(face); 14152245bab833d2ab8dc9a2ec3389f5e1bd72ca9ec3Cristy (void) FT_Done_FreeType(library); 14162245bab833d2ab8dc9a2ec3389f5e1bd72ca9ec3Cristy ThrowBinaryException(TypeError,"UnableToReadFont",draw_info->font); 14172245bab833d2ab8dc9a2ec3389f5e1bd72ca9ec3Cristy } 14183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->pixels_per_em.x=face->size->metrics.x_ppem; 14193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->pixels_per_em.y=face->size->metrics.y_ppem; 14203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->ascent=(double) face->size->metrics.ascender/64.0; 14213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->descent=(double) face->size->metrics.descender/64.0; 14223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->width=0; 14233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->origin.x=0; 14243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->origin.y=0; 14253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->height=(double) face->size->metrics.height/64.0; 14263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->max_advance=0.0; 14273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (face->size->metrics.max_advance > MagickEpsilon) 14283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->max_advance=(double) face->size->metrics.max_advance/64.0; 14293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->bounds.x1=0.0; 14303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->bounds.y1=metrics->descent; 14313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->bounds.x2=metrics->ascent+metrics->descent; 14323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->bounds.y2=metrics->ascent+metrics->descent; 14333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->underline_position=face->underline_position/64.0; 14343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->underline_thickness=face->underline_thickness/64.0; 143571709bfb884744dbf7c9030810cc8599600ab7d3cristy if ((draw_info->text == (char *) NULL) || (*draw_info->text == '\0')) 14363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 14373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) FT_Done_Face(face); 14383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) FT_Done_FreeType(library); 14393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(MagickTrue); 14403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 14413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 14423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Compute bounding box. 14433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 14443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->debug != MagickFalse) 14453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) LogMagickEvent(AnnotateEvent,GetMagickModule(),"Font %s; " 1446e7f5109f30fc7242d04a26174a9138483dda5b6acristy "font-encoding %s; text-encoding %s; pointsize %g", 14473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy draw_info->font != (char *) NULL ? draw_info->font : "none", 14483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy encoding != (char *) NULL ? encoding : "none", 14493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy draw_info->encoding != (char *) NULL ? draw_info->encoding : "none", 14503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy draw_info->pointsize); 14513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy flags=FT_LOAD_NO_BITMAP; 145255a804e2631f770f45d3a671076b0dfe29fdf188cristy if (draw_info->text_antialias == MagickFalse) 14534f9709e37140157c7845a03f3612534081a5b540cristy flags|=FT_LOAD_TARGET_MONO; 145455a804e2631f770f45d3a671076b0dfe29fdf188cristy else 145555a804e2631f770f45d3a671076b0dfe29fdf188cristy { 1456a89189d6e227db53ecff8624fb6b4388560d9b4acristy#if defined(FT_LOAD_TARGET_LIGHT) 145755a804e2631f770f45d3a671076b0dfe29fdf188cristy flags|=FT_LOAD_TARGET_LIGHT; 1458a89189d6e227db53ecff8624fb6b4388560d9b4acristy#elif defined(FT_LOAD_TARGET_LCD) 1459a89189d6e227db53ecff8624fb6b4388560d9b4acristy flags|=FT_LOAD_TARGET_LCD; 146055a804e2631f770f45d3a671076b0dfe29fdf188cristy#endif 146155a804e2631f770f45d3a671076b0dfe29fdf188cristy } 1462d15e65928aec551b7388c2863de3e3e628e2e0ddcristy value=GetImageProperty(image,"type:hinting",exception); 146333204240c3ef57786ee59c2692ffe8ffdce97bf9cristy if ((value != (const char *) NULL) && (LocaleCompare(value,"off") == 0)) 14643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy flags|=FT_LOAD_NO_HINTING; 14653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy glyph.id=0; 14663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy glyph.image=NULL; 14673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy last_glyph.id=0; 14683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy last_glyph.image=NULL; 14693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy origin.x=0; 14703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy origin.y=0; 14713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy affine.xx=65536L; 14723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy affine.yx=0L; 14733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy affine.xy=0L; 14743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy affine.yy=65536L; 14753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (draw_info->render != MagickFalse) 14763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 14773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy affine.xx=(FT_Fixed) (65536L*draw_info->affine.sx+0.5); 14783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy affine.yx=(FT_Fixed) (-65536L*draw_info->affine.rx+0.5); 14793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy affine.xy=(FT_Fixed) (-65536L*draw_info->affine.ry+0.5); 14803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy affine.yy=(FT_Fixed) (65536L*draw_info->affine.sy+0.5); 14813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 14823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info=CloneDrawInfo((ImageInfo *) NULL,draw_info); 14839c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy if (annotate_info->dash_pattern != (double *) NULL) 14849c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy annotate_info->dash_pattern[0]=0.0; 14853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) CloneString(&annotate_info->primitive,"path '"); 1486ba4ad2dfd3d5b883e8aa7d6e8b4e6f9613dc3c45Cristy status=MagickTrue; 14873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (draw_info->render != MagickFalse) 14883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 14893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->storage_class != DirectClass) 14905cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy (void) SetImageStorageClass(image,DirectClass,exception); 149117f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy if (image->alpha_trait == UndefinedPixelTrait) 1492a64d8007a138a0efeedc286de10538f2e8c7fe6bcristy (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception); 14933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 14943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy point.x=0.0; 14953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy point.y=0.0; 14963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy for (p=draw_info->text; GetUTFCode(p) != 0; p+=GetUTFOctets(p)) 1497bd51246ae63047fa139606f6c6862ff989ab1fbdcristy if (GetUTFCode(p) < 0) 1498bd51246ae63047fa139606f6c6862ff989ab1fbdcristy break; 14992857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy utf8=(unsigned char *) NULL; 1500d913ea1f524066a6a8bf3d046755a5c0f7eb471fcristy if (GetUTFCode(p) == 0) 15012857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy p=draw_info->text; 15022857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy else 1503bd51246ae63047fa139606f6c6862ff989ab1fbdcristy { 15042857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy utf8=ConvertLatin1ToUTF8((unsigned char *) draw_info->text); 15052857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy if (utf8 != (unsigned char *) NULL) 1506c9b129570a277337cf0e887229741497e2ead5cfcristy p=(char *) utf8; 15072857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy } 150817f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy grapheme=(GraphemeInfo *) NULL; 150987dc5e4e6f9471304ba85f508de30e664b484d3aCristy length=ComplexTextLayout(image,draw_info,p,strlen(p),face,flags,&grapheme, 15105eb36084e86f5ab4a877c2b31c19880b0b0b02e3Cristy exception); 151169a0d3b5699c573f650e6b61f98ce4579d6f218cCristy code=0; 151269a0d3b5699c573f650e6b61f98ce4579d6f218cCristy for (i=0; i < (ssize_t) length; i++) 15132857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy { 15142857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy /* 15152857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy Render UTF-8 sequence. 15162857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy */ 151786bacded5c30fe8f40e3a992c3b07a7fd610cc12dirk glyph.id=(FT_UInt) grapheme[i].index; 15182857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy if (glyph.id == 0) 15192857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy glyph.id=FT_Get_Char_Index(face,'?'); 15202857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy if ((glyph.id != 0) && (last_glyph.id != 0)) 152169a0d3b5699c573f650e6b61f98ce4579d6f218cCristy origin.x+=(FT_Pos) (64.0*draw_info->kerning); 15222857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy glyph.origin=origin; 152386bacded5c30fe8f40e3a992c3b07a7fd610cc12dirk glyph.origin.x+=(FT_Pos) grapheme[i].x_offset; 152486bacded5c30fe8f40e3a992c3b07a7fd610cc12dirk glyph.origin.y+=(FT_Pos) grapheme[i].y_offset; 1525f8f295fde25dd8b1a50470d53b641d5265c0871fcristy ft_status=FT_Load_Glyph(face,glyph.id,flags); 1526f8f295fde25dd8b1a50470d53b641d5265c0871fcristy if (ft_status != 0) 15272857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy continue; 1528f8f295fde25dd8b1a50470d53b641d5265c0871fcristy ft_status=FT_Get_Glyph(face->glyph,&glyph.image); 1529f8f295fde25dd8b1a50470d53b641d5265c0871fcristy if (ft_status != 0) 15302857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy continue; 1531f8f295fde25dd8b1a50470d53b641d5265c0871fcristy ft_status=FT_Outline_Get_BBox(&((FT_OutlineGlyph) glyph.image)->outline, 15322857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy &bounds); 1533f8f295fde25dd8b1a50470d53b641d5265c0871fcristy if (ft_status != 0) 15342857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy continue; 15352857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy if ((p == draw_info->text) || (bounds.xMin < metrics->bounds.x1)) 15368e1dd685b642e235234931b24d11045041254eafCristy if (bounds.xMin != 0) 15378e1dd685b642e235234931b24d11045041254eafCristy metrics->bounds.x1=(double) bounds.xMin; 15382857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy if ((p == draw_info->text) || (bounds.yMin < metrics->bounds.y1)) 15398e1dd685b642e235234931b24d11045041254eafCristy if (bounds.yMin != 0) 15408e1dd685b642e235234931b24d11045041254eafCristy metrics->bounds.y1=(double) bounds.yMin; 15412857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy if ((p == draw_info->text) || (bounds.xMax > metrics->bounds.x2)) 15428e1dd685b642e235234931b24d11045041254eafCristy if (bounds.xMax != 0) 15438e1dd685b642e235234931b24d11045041254eafCristy metrics->bounds.x2=(double) bounds.xMax; 15442857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy if ((p == draw_info->text) || (bounds.yMax > metrics->bounds.y2)) 15458e1dd685b642e235234931b24d11045041254eafCristy if (bounds.yMax != 0) 15468e1dd685b642e235234931b24d11045041254eafCristy metrics->bounds.y2=(double) bounds.yMax; 15479c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy if (((draw_info->stroke.alpha != TransparentAlpha) || 15489c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy (draw_info->stroke_pattern != (Image *) NULL)) && 15499c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy ((status != MagickFalse) && (draw_info->render != MagickFalse))) 1550f8f295fde25dd8b1a50470d53b641d5265c0871fcristy { 15519c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy /* 15529c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy Trace the glyph. 15539c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy */ 15549c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy annotate_info->affine.tx=glyph.origin.x/64.0; 155569a0d3b5699c573f650e6b61f98ce4579d6f218cCristy annotate_info->affine.ty=(-glyph.origin.y/64.0); 15569c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy (void) FT_Outline_Decompose(&((FT_OutlineGlyph) glyph.image)->outline, 15579c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy &OutlineMethods,annotate_info); 15589c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy } 15592857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy FT_Vector_Transform(&glyph.origin,&affine); 15602857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy (void) FT_Glyph_Transform(glyph.image,&affine,&glyph.origin); 1561f8f295fde25dd8b1a50470d53b641d5265c0871fcristy ft_status=FT_Glyph_To_Bitmap(&glyph.image,ft_render_mode_normal, 15622857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy (FT_Vector *) NULL,MagickTrue); 1563f8f295fde25dd8b1a50470d53b641d5265c0871fcristy if (ft_status != 0) 15642857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy continue; 15652857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy bitmap=(FT_BitmapGlyph) glyph.image; 15662857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy point.x=offset->x+bitmap->left; 15672f5b5c7c0813cc6f696a4dfc00aaf62e2dfb2a23cristy if (bitmap->bitmap.pixel_mode == ft_pixel_mode_mono) 15682f5b5c7c0813cc6f696a4dfc00aaf62e2dfb2a23cristy point.x=offset->x+(origin.x >> 6); 15692857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy point.y=offset->y-bitmap->top; 15702857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy if (draw_info->render != MagickFalse) 15712857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy { 15722857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy CacheView 15732857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy *image_view; 1574bd51246ae63047fa139606f6c6862ff989ab1fbdcristy 15752f5b5c7c0813cc6f696a4dfc00aaf62e2dfb2a23cristy register unsigned char 1576fa589d6096099562cbc2bc14e508931968a8c055dirk *r; 15772f5b5c7c0813cc6f696a4dfc00aaf62e2dfb2a23cristy 15782857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy /* 15792857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy Rasterize the glyph. 15802857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy */ 158146ff2676b1044ea4101ac7a59b83289cd8f6cfdacristy image_view=AcquireAuthenticCacheView(image,exception); 1582fa589d6096099562cbc2bc14e508931968a8c055dirk r=bitmap->bitmap.buffer; 1583bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (y=0; y < (ssize_t) bitmap->bitmap.rows; y++) 15842857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy { 158587dc5e4e6f9471304ba85f508de30e664b484d3aCristy double 158687dc5e4e6f9471304ba85f508de30e664b484d3aCristy fill_opacity; 158787dc5e4e6f9471304ba85f508de30e664b484d3aCristy 1588bd51246ae63047fa139606f6c6862ff989ab1fbdcristy MagickBooleanType 15892857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy active, 15902857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy sync; 1591bd51246ae63047fa139606f6c6862ff989ab1fbdcristy 1592101ab708b0574518ac5715da4d3915400e9df79acristy PixelInfo 15932857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy fill_color; 15942857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy 15954c08aed51c5899665ade97263692328eea4af106cristy register Quantum 159605d2ff7ebf21f659f5b11e45afb294e152f4330cdirk *magick_restrict q; 15972857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy 15988815806717c3b3e2b4f8700b4cc18b751bd3c23fcristy register ssize_t 15998815806717c3b3e2b4f8700b4cc18b751bd3c23fcristy x; 16008815806717c3b3e2b4f8700b4cc18b751bd3c23fcristy 160173ce31bc9ca5fc03ff0cef499e58ab2973add52ccristy ssize_t 16022f5b5c7c0813cc6f696a4dfc00aaf62e2dfb2a23cristy n, 160373ce31bc9ca5fc03ff0cef499e58ab2973add52ccristy x_offset, 160473ce31bc9ca5fc03ff0cef499e58ab2973add52ccristy y_offset; 160573ce31bc9ca5fc03ff0cef499e58ab2973add52ccristy 16062857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy if (status == MagickFalse) 16072857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy continue; 1608bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy x_offset=(ssize_t) ceil(point.x-0.5); 1609bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy y_offset=(ssize_t) ceil(point.y+y-0.5); 1610bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy if ((y_offset < 0) || (y_offset >= (ssize_t) image->rows)) 16112857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy continue; 16124c08aed51c5899665ade97263692328eea4af106cristy q=(Quantum *) NULL; 1613bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy if ((x_offset < 0) || (x_offset >= (ssize_t) image->columns)) 16142857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy active=MagickFalse; 16152857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy else 16162857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy { 16172857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy q=GetCacheViewAuthenticPixels(image_view,x_offset,y_offset, 16182857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy bitmap->bitmap.width,1,exception); 16194c08aed51c5899665ade97263692328eea4af106cristy active=q != (Quantum *) NULL ? MagickTrue : MagickFalse; 16202857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy } 1621854209afe797f1a6ecec8679889302af4d4b0faccristy n=y*bitmap->bitmap.pitch-1; 1622854209afe797f1a6ecec8679889302af4d4b0faccristy for (x=0; x < (ssize_t) bitmap->bitmap.width; x++) 1623bd51246ae63047fa139606f6c6862ff989ab1fbdcristy { 1624854209afe797f1a6ecec8679889302af4d4b0faccristy n++; 16252857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy x_offset++; 16262f5b5c7c0813cc6f696a4dfc00aaf62e2dfb2a23cristy if ((x_offset < 0) || (x_offset >= (ssize_t) image->columns)) 16273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 1628dcf8f73b2c558978add85031fe65f2607bbca057cristy if (q != (Quantum *) NULL) 1629dcf8f73b2c558978add85031fe65f2607bbca057cristy q+=GetPixelChannels(image); 16302857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy continue; 16313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 16322f5b5c7c0813cc6f696a4dfc00aaf62e2dfb2a23cristy if (bitmap->bitmap.pixel_mode != ft_pixel_mode_mono) 1633fa589d6096099562cbc2bc14e508931968a8c055dirk fill_opacity=(double) (r[n])/(bitmap->bitmap.num_grays-1); 16342f5b5c7c0813cc6f696a4dfc00aaf62e2dfb2a23cristy else 1635fa589d6096099562cbc2bc14e508931968a8c055dirk fill_opacity=((r[(x >> 3)+y*bitmap->bitmap.pitch] & 16362f5b5c7c0813cc6f696a4dfc00aaf62e2dfb2a23cristy (1 << (~x & 0x07)))) == 0 ? 0.0 : 1.0; 16372857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy if (draw_info->text_antialias == MagickFalse) 16382857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy fill_opacity=fill_opacity >= 0.5 ? 1.0 : 0.0; 16392857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy if (active == MagickFalse) 16402857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy q=GetCacheViewAuthenticPixels(image_view,x_offset,y_offset,1,1, 16412857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy exception); 16426193b86c0b59030b647a10c75f37ec82d73e3695cristy if (q == (Quantum *) NULL) 16439c5171c13c7186088b10ec322e199f60e455a7e1cristy continue; 1644ec061ec752ff58a96a5de680b18e43fb8beea7c0cristy GetPixelInfo(image,&fill_color); 164550be538de7d724dfbd0cba7d434d1404b49ce90ddirk GetFillColor(draw_info,x_offset,y_offset,&fill_color,exception); 16464c08aed51c5899665ade97263692328eea4af106cristy fill_opacity=fill_opacity*fill_color.alpha; 16474c08aed51c5899665ade97263692328eea4af106cristy CompositePixelOver(image,&fill_color,fill_opacity,q, 16484c08aed51c5899665ade97263692328eea4af106cristy GetPixelAlpha(image,q),q); 16492857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy if (active == MagickFalse) 16502857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy { 16512857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy sync=SyncCacheViewAuthenticPixels(image_view,exception); 16522857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy if (sync == MagickFalse) 16532857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy status=MagickFalse; 16542857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy } 1655ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy q+=GetPixelChannels(image); 16563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 16572857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy sync=SyncCacheViewAuthenticPixels(image_view,exception); 16582857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy if (sync == MagickFalse) 16592857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy status=MagickFalse; 16603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 16612857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy image_view=DestroyCacheView(image_view); 16629c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy if (((draw_info->stroke.alpha != TransparentAlpha) || 16639c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy (draw_info->stroke_pattern != (Image *) NULL)) && 16649c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy (status != MagickFalse)) 16659c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy { 16669c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy /* 16679c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy Draw text stroke. 16689c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy */ 16699c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy annotate_info->linejoin=RoundJoin; 16709c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy annotate_info->affine.tx=offset->x; 16719c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy annotate_info->affine.ty=offset->y; 16729c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy (void) ConcatenateString(&annotate_info->primitive,"'"); 16739c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy (void) DrawImage(image,annotate_info,exception); 16749c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy (void) CloneString(&annotate_info->primitive,"path '"); 16759c282cc8767db9a3fafe507398b52fbdd0c03d9fCristy } 16762857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy } 16772857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy if ((bitmap->left+bitmap->bitmap.width) > metrics->width) 16782857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy metrics->width=bitmap->left+bitmap->bitmap.width; 1679aa83c2c383e62bd5342c0d38dc5f6e746998bde8cristy if ((fabs(draw_info->interword_spacing) >= MagickEpsilon) && 168091c2741e03e3e692f6fe04eb02d059edbc0edb90Cristy (IsUTFSpace(GetUTFCode(p+grapheme[i].cluster)) != MagickFalse) && 16812857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy (IsUTFSpace(code) == MagickFalse)) 168269a0d3b5699c573f650e6b61f98ce4579d6f218cCristy origin.x+=(FT_Pos) (64.0*draw_info->interword_spacing); 16832857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy else 168491c2741e03e3e692f6fe04eb02d059edbc0edb90Cristy origin.x+=(FT_Pos) grapheme[i].x_advance; 1685aa83c2c383e62bd5342c0d38dc5f6e746998bde8cristy metrics->origin.x=(double) origin.x; 1686aa83c2c383e62bd5342c0d38dc5f6e746998bde8cristy metrics->origin.y=(double) origin.y; 1687bd5a96cd2b69f218f85a7adc306296a736f91a56cristy if (last_glyph.id != 0) 1688bd5a96cd2b69f218f85a7adc306296a736f91a56cristy FT_Done_Glyph(last_glyph.image); 16892857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy last_glyph=glyph; 169091c2741e03e3e692f6fe04eb02d059edbc0edb90Cristy code=GetUTFCode(p+grapheme[i].cluster); 16912857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy } 169217f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy if (grapheme != (GraphemeInfo *) NULL) 169317f8c7215fff88fc1362e9d98f4ccdffb6a74950Cristy grapheme=(GraphemeInfo *) RelinquishMagickMemory(grapheme); 16942857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy if (utf8 != (unsigned char *) NULL) 16952857ffcd46fc4d091060c7e8aa9804f4b4d6efaacristy utf8=(unsigned char *) RelinquishMagickMemory(utf8); 1696bd5a96cd2b69f218f85a7adc306296a736f91a56cristy if (last_glyph.id != 0) 1697bd5a96cd2b69f218f85a7adc306296a736f91a56cristy FT_Done_Glyph(last_glyph.image); 16983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 16993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Determine font metrics. 17003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 17013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy glyph.id=FT_Get_Char_Index(face,'_'); 17023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy glyph.origin=origin; 1703f8f295fde25dd8b1a50470d53b641d5265c0871fcristy ft_status=FT_Load_Glyph(face,glyph.id,flags); 1704f8f295fde25dd8b1a50470d53b641d5265c0871fcristy if (ft_status == 0) 17053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 1706f8f295fde25dd8b1a50470d53b641d5265c0871fcristy ft_status=FT_Get_Glyph(face->glyph,&glyph.image); 1707f8f295fde25dd8b1a50470d53b641d5265c0871fcristy if (ft_status == 0) 17083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 1709f8f295fde25dd8b1a50470d53b641d5265c0871fcristy ft_status=FT_Outline_Get_BBox(&((FT_OutlineGlyph) glyph.image)-> 1710f8f295fde25dd8b1a50470d53b641d5265c0871fcristy outline,&bounds); 1711f8f295fde25dd8b1a50470d53b641d5265c0871fcristy if (ft_status == 0) 17123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 17133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy FT_Vector_Transform(&glyph.origin,&affine); 17143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) FT_Glyph_Transform(glyph.image,&affine,&glyph.origin); 1715f8f295fde25dd8b1a50470d53b641d5265c0871fcristy ft_status=FT_Glyph_To_Bitmap(&glyph.image,ft_render_mode_normal, 17163ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (FT_Vector *) NULL,MagickTrue); 17173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy bitmap=(FT_BitmapGlyph) glyph.image; 17183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (bitmap->left > metrics->width) 17193ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->width=bitmap->left; 17203ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 17213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 1722e2c81adf02cbe4bb92991389437a2a1daf8ed313cristy FT_Done_Glyph(glyph.image); 17233ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 17243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->bounds.x1/=64.0; 17253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->bounds.y1/=64.0; 17263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->bounds.x2/=64.0; 17273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->bounds.y2/=64.0; 17283ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->origin.x/=64.0; 17293ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->origin.y/=64.0; 17303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 17313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Relinquish resources. 17323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 17333ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info=DestroyDrawInfo(annotate_info); 17343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) FT_Done_Face(face); 17353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) FT_Done_FreeType(library); 1736f8f295fde25dd8b1a50470d53b641d5265c0871fcristy return(status); 17373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 17383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#else 17393ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType RenderFreetype(Image *image,const DrawInfo *draw_info, 17403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy const char *magick_unused(encoding),const PointInfo *offset, 17415cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy TypeMetric *metrics,ExceptionInfo *exception) 17423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 17435cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy (void) ThrowMagickException(exception,GetMagickModule(), 1744e5b39652d8d21bc3940d83b8d6088d4070a8a34aanthony MissingDelegateWarning,"DelegateLibrarySupportNotBuiltIn","'%s' (Freetype)", 1745ee08182aae410ed78e712a845bee7e51eedf73f3cristy draw_info->font != (char *) NULL ? draw_info->font : "none"); 1746e3b062a2f84bdc16645c3ef9de153b2c6f44d04ccristy return(RenderPostscript(image,draw_info,offset,metrics,exception)); 17473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 17483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy#endif 17493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 17503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 17513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 17523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 17533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 17543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 17553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy+ R e n d e r P o s t s c r i p t % 17563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 17573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 17583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 17593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 17603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 17613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% RenderPostscript() renders text on the image with a Postscript font. It 17623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% also returns the bounding box of the text relative to the image. 17633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 17643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% The format of the RenderPostscript method is: 17653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 17663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% MagickBooleanType RenderPostscript(Image *image,DrawInfo *draw_info, 17675cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% const PointInfo *offset,TypeMetric *metrics,ExceptionInfo *exception) 17683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 17693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A description of each parameter follows: 17703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 17713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o image: the image. 17723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 17733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o draw_info: the draw info. 17743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 17753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o offset: (x,y) location of text relative to image. 17763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 17773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o metrics: bounding box of text. 17783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 17795cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% o exception: return any errors or warnings in this structure. 17805cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% 17813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 17823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 178334838f589a9c3dff858321d07926c66f7f7fa2f7Cristystatic char *EscapeParenthesis(const char *source) 17843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 17853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy char 178634838f589a9c3dff858321d07926c66f7f7fa2f7Cristy *destination; 17873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 17883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy register char 178934838f589a9c3dff858321d07926c66f7f7fa2f7Cristy *q; 17903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 179134838f589a9c3dff858321d07926c66f7f7fa2f7Cristy register const char 179234838f589a9c3dff858321d07926c66f7f7fa2f7Cristy *p; 17933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 17943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy size_t 179534838f589a9c3dff858321d07926c66f7f7fa2f7Cristy length; 17963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 179734838f589a9c3dff858321d07926c66f7f7fa2f7Cristy assert(source != (const char *) NULL); 179834838f589a9c3dff858321d07926c66f7f7fa2f7Cristy length=0; 179934838f589a9c3dff858321d07926c66f7f7fa2f7Cristy for (p=source; *p != '\0'; p++) 18003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 180134838f589a9c3dff858321d07926c66f7f7fa2f7Cristy if ((*p == '\\') || (*p == '(') || (*p == ')')) 18023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 180334838f589a9c3dff858321d07926c66f7f7fa2f7Cristy if (~length < 1) 180434838f589a9c3dff858321d07926c66f7f7fa2f7Cristy ThrowFatalException(ResourceLimitFatalError,"UnableToEscapeString"); 180534838f589a9c3dff858321d07926c66f7f7fa2f7Cristy length++; 18063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 180734838f589a9c3dff858321d07926c66f7f7fa2f7Cristy length++; 180834838f589a9c3dff858321d07926c66f7f7fa2f7Cristy } 180934838f589a9c3dff858321d07926c66f7f7fa2f7Cristy destination=(char *) NULL; 181034838f589a9c3dff858321d07926c66f7f7fa2f7Cristy if (~length >= (MagickPathExtent-1)) 181134838f589a9c3dff858321d07926c66f7f7fa2f7Cristy destination=(char *) AcquireQuantumMemory(length+MagickPathExtent, 181234838f589a9c3dff858321d07926c66f7f7fa2f7Cristy sizeof(*destination)); 181334838f589a9c3dff858321d07926c66f7f7fa2f7Cristy if (destination == (char *) NULL) 181434838f589a9c3dff858321d07926c66f7f7fa2f7Cristy ThrowFatalException(ResourceLimitFatalError,"UnableToEscapeString"); 181534838f589a9c3dff858321d07926c66f7f7fa2f7Cristy *destination='\0'; 181634838f589a9c3dff858321d07926c66f7f7fa2f7Cristy q=destination; 181734838f589a9c3dff858321d07926c66f7f7fa2f7Cristy for (p=source; *p != '\0'; p++) 181834838f589a9c3dff858321d07926c66f7f7fa2f7Cristy { 181934838f589a9c3dff858321d07926c66f7f7fa2f7Cristy if ((*p == '\\') || (*p == '(') || (*p == ')')) 182034838f589a9c3dff858321d07926c66f7f7fa2f7Cristy *q++='\\'; 182134838f589a9c3dff858321d07926c66f7f7fa2f7Cristy *q++=(*p); 18223ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 182334838f589a9c3dff858321d07926c66f7f7fa2f7Cristy *q='\0'; 182434838f589a9c3dff858321d07926c66f7f7fa2f7Cristy return(destination); 18253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 18263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 18273ed852eea50f9d4cd633efb8c2b054b8e33c253cristystatic MagickBooleanType RenderPostscript(Image *image, 18285cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy const DrawInfo *draw_info,const PointInfo *offset,TypeMetric *metrics, 18295cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy ExceptionInfo *exception) 18303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 18313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy char 1832151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy filename[MagickPathExtent], 1833151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy geometry[MagickPathExtent], 18343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *text; 18353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 18363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy FILE 18373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *file; 18383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 18393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Image 18403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *annotate_image; 18413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 18423ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ImageInfo 18433ed852eea50f9d4cd633efb8c2b054b8e33c253cristy *annotate_info; 18443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 18453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy int 18463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unique_file; 18473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 18483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy MagickBooleanType 18493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy identity; 18503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 18513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy PointInfo 18523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy extent, 18533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy point, 18543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy resolution; 18553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1856bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy register ssize_t 18573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy i; 18583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 185914d712974a2c2cd2aebf8db11c7ca686bb67596fcristy size_t 186014d712974a2c2cd2aebf8db11c7ca686bb67596fcristy length; 186114d712974a2c2cd2aebf8db11c7ca686bb67596fcristy 18629d314ff2c17a77996c05413c2013880387e50f0ecristy ssize_t 18639d314ff2c17a77996c05413c2013880387e50f0ecristy y; 18649d314ff2c17a77996c05413c2013880387e50f0ecristy 18653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 18663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Render label with a Postscript font. 18673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 18683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (image->debug != MagickFalse) 18693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) LogMagickEvent(AnnotateEvent,GetMagickModule(), 1870e7f5109f30fc7242d04a26174a9138483dda5b6acristy "Font %s; pointsize %g",draw_info->font != (char *) NULL ? 18713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy draw_info->font : "none",draw_info->pointsize); 18723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy file=(FILE *) NULL; 18733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy unique_file=AcquireUniqueFileResource(filename); 18743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (unique_file != -1) 18753ed852eea50f9d4cd633efb8c2b054b8e33c253cristy file=fdopen(unique_file,"wb"); 18763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if ((unique_file == -1) || (file == (FILE *) NULL)) 18773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 18785cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy ThrowFileException(exception,FileOpenError,"UnableToOpenFile",filename); 18793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(MagickFalse); 18803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 1881b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy (void) FormatLocaleFile(file,"%%!PS-Adobe-3.0\n"); 1882b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy (void) FormatLocaleFile(file,"/ReencodeType\n"); 1883b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy (void) FormatLocaleFile(file,"{\n"); 1884b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy (void) FormatLocaleFile(file," findfont dup length\n"); 1885b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy (void) FormatLocaleFile(file, 18863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy " dict begin { 1 index /FID ne {def} {pop pop} ifelse } forall\n"); 1887b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy (void) FormatLocaleFile(file, 18883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy " /Encoding ISOLatin1Encoding def currentdict end definefont pop\n"); 1889b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy (void) FormatLocaleFile(file,"} bind def\n"); 18903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 18913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Sample to compute bounding box. 18923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 1893aa83c2c383e62bd5342c0d38dc5f6e746998bde8cristy identity=(fabs(draw_info->affine.sx-draw_info->affine.sy) < MagickEpsilon) && 1894aa83c2c383e62bd5342c0d38dc5f6e746998bde8cristy (fabs(draw_info->affine.rx) < MagickEpsilon) && 1895aa83c2c383e62bd5342c0d38dc5f6e746998bde8cristy (fabs(draw_info->affine.ry) < MagickEpsilon) ? MagickTrue : MagickFalse; 18963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy extent.x=0.0; 18973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy extent.y=0.0; 189814d712974a2c2cd2aebf8db11c7ca686bb67596fcristy length=strlen(draw_info->text); 189914d712974a2c2cd2aebf8db11c7ca686bb67596fcristy for (i=0; i <= (ssize_t) (length+2); i++) 19003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 19013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy point.x=fabs(draw_info->affine.sx*i*draw_info->pointsize+ 19023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy draw_info->affine.ry*2.0*draw_info->pointsize); 19033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy point.y=fabs(draw_info->affine.rx*i*draw_info->pointsize+ 19043ed852eea50f9d4cd633efb8c2b054b8e33c253cristy draw_info->affine.sy*2.0*draw_info->pointsize); 19053ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (point.x > extent.x) 19063ed852eea50f9d4cd633efb8c2b054b8e33c253cristy extent.x=point.x; 19073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (point.y > extent.y) 19083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy extent.y=point.y; 19093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 1910b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy (void) FormatLocaleFile(file,"%g %g moveto\n",identity != MagickFalse ? 0.0 : 19113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy extent.x/2.0,extent.y/2.0); 1912b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy (void) FormatLocaleFile(file,"%g %g scale\n",draw_info->pointsize, 19133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy draw_info->pointsize); 19143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if ((draw_info->font == (char *) NULL) || (*draw_info->font == '\0') || 19153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (strchr(draw_info->font,'/') != (char *) NULL)) 1916b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy (void) FormatLocaleFile(file, 19173ed852eea50f9d4cd633efb8c2b054b8e33c253cristy "/Times-Roman-ISO dup /Times-Roman ReencodeType findfont setfont\n"); 19183ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 19191e604812fad85bb96f757a2393015ae3d061c39acristy (void) FormatLocaleFile(file, 19201e604812fad85bb96f757a2393015ae3d061c39acristy "/%s-ISO dup /%s ReencodeType findfont setfont\n",draw_info->font, 19211e604812fad85bb96f757a2393015ae3d061c39acristy draw_info->font); 1922b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy (void) FormatLocaleFile(file,"[%g %g %g %g 0 0] concat\n", 19238cd5b3193212b4aebce08c4e7afbb66b09778029cristy draw_info->affine.sx,-draw_info->affine.rx,-draw_info->affine.ry, 19248cd5b3193212b4aebce08c4e7afbb66b09778029cristy draw_info->affine.sy); 19253ed852eea50f9d4cd633efb8c2b054b8e33c253cristy text=EscapeParenthesis(draw_info->text); 19263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (identity == MagickFalse) 19271e604812fad85bb96f757a2393015ae3d061c39acristy (void) FormatLocaleFile(file,"(%s) stringwidth pop -0.5 mul -0.5 rmoveto\n", 19281e604812fad85bb96f757a2393015ae3d061c39acristy text); 1929b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy (void) FormatLocaleFile(file,"(%s) show\n",text); 19303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy text=DestroyString(text); 1931b51dff5c0d16a4c1b69ff683e786cb3b4c467694cristy (void) FormatLocaleFile(file,"showpage\n"); 19323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) fclose(file); 1933151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy (void) FormatLocaleString(geometry,MagickPathExtent,"%.20gx%.20g+0+0!", 1934e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy floor(extent.x+0.5),floor(extent.y+0.5)); 19353ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info=AcquireImageInfo(); 1936151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy (void) FormatLocaleString(annotate_info->filename,MagickPathExtent,"ps:%s", 19373ed852eea50f9d4cd633efb8c2b054b8e33c253cristy filename); 19383ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) CloneString(&annotate_info->page,geometry); 19393ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (draw_info->density != (char *) NULL) 19403ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) CloneString(&annotate_info->density,draw_info->density); 19413ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info->antialias=draw_info->text_antialias; 19425cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy annotate_image=ReadImage(annotate_info,exception); 19435cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy CatchException(exception); 19443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_info=DestroyImageInfo(annotate_info); 19453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy (void) RelinquishUniqueFileResource(filename); 19463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (annotate_image == (Image *) NULL) 19473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(MagickFalse); 194855cb9f15b804f98ac7d37615b8f5f8888fc792f4cristy (void) NegateImage(annotate_image,MagickFalse,exception); 19493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy resolution.x=DefaultResolution; 19503ed852eea50f9d4cd633efb8c2b054b8e33c253cristy resolution.y=DefaultResolution; 19513ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (draw_info->density != (char *) NULL) 19523ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 19533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy GeometryInfo 19543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy geometry_info; 19553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 19563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy MagickStatusType 19573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy flags; 19583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 19593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy flags=ParseGeometry(draw_info->density,&geometry_info); 19603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy resolution.x=geometry_info.rho; 19613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy resolution.y=geometry_info.sigma; 19623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if ((flags & SigmaValue) == 0) 19633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy resolution.y=resolution.x; 19643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 19653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (identity == MagickFalse) 1966e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy (void) TransformImage(&annotate_image,"0x0",(char *) NULL,exception); 19673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy else 19683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 19693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy RectangleInfo 19703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy crop_info; 19713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 19725cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy crop_info=GetImageBoundingBox(annotate_image,exception); 1973bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy crop_info.height=(size_t) ((resolution.y/DefaultResolution)* 19743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ExpandAffine(&draw_info->affine)*draw_info->pointsize+0.5); 1975bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy crop_info.y=(ssize_t) ceil((resolution.y/DefaultResolution)*extent.y/8.0- 197606609eef311d5af857f65f20ed3af6860c1994becristy 0.5); 1977151b66dffc9e3c2e8c4f8cdaca37ff987ca0f497cristy (void) FormatLocaleString(geometry,MagickPathExtent, 19786d8abbae64da926477182d86d5007bc2c5a8b979cristy "%.20gx%.20g%+.20g%+.20g",(double) crop_info.width,(double) 1979e8c25f9b4c9fb72cad6db08eeda58c7c5784014ecristy crop_info.height,(double) crop_info.x,(double) crop_info.y); 1980e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy (void) TransformImage(&annotate_image,geometry,(char *) NULL,exception); 19813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 19823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->pixels_per_em.x=(resolution.y/DefaultResolution)* 19833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ExpandAffine(&draw_info->affine)*draw_info->pointsize; 19843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->pixels_per_em.y=metrics->pixels_per_em.x; 19853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->ascent=metrics->pixels_per_em.x; 19863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->descent=metrics->pixels_per_em.y/-5.0; 19873ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->width=(double) annotate_image->columns/ 19883ed852eea50f9d4cd633efb8c2b054b8e33c253cristy ExpandAffine(&draw_info->affine); 19893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->height=1.152*metrics->pixels_per_em.x; 19903ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->max_advance=metrics->pixels_per_em.x; 19913ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->bounds.x1=0.0; 19923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->bounds.y1=metrics->descent; 19933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->bounds.x2=metrics->ascent+metrics->descent; 19943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->bounds.y2=metrics->ascent+metrics->descent; 19953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->underline_position=(-2.0); 19963ed852eea50f9d4cd633efb8c2b054b8e33c253cristy metrics->underline_thickness=1.0; 19973ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (draw_info->render == MagickFalse) 19983ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 19993ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_image=DestroyImage(annotate_image); 20003ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(MagickTrue); 20013ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 20024c08aed51c5899665ade97263692328eea4af106cristy if (draw_info->fill.alpha != TransparentAlpha) 20033ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 2004bd65948def60e897a2641d9503470945c304f46fcristy CacheView 2005bd65948def60e897a2641d9503470945c304f46fcristy *annotate_view; 2006bd65948def60e897a2641d9503470945c304f46fcristy 20073ed852eea50f9d4cd633efb8c2b054b8e33c253cristy MagickBooleanType 20083ed852eea50f9d4cd633efb8c2b054b8e33c253cristy sync; 20093ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2010101ab708b0574518ac5715da4d3915400e9df79acristy PixelInfo 20113ed852eea50f9d4cd633efb8c2b054b8e33c253cristy fill_color; 20123ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 20133ed852eea50f9d4cd633efb8c2b054b8e33c253cristy /* 20143ed852eea50f9d4cd633efb8c2b054b8e33c253cristy Render fill color. 20153ed852eea50f9d4cd633efb8c2b054b8e33c253cristy */ 201617f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy if (image->alpha_trait == UndefinedPixelTrait) 201763240888c3975789a09c2494a4654b523931df96cristy (void) SetImageAlphaChannel(image,OpaqueAlphaChannel,exception); 201817f11b056210f082a6d0e54ac5d68e6d72fa76b2cristy if (annotate_image->alpha_trait == UndefinedPixelTrait) 201963240888c3975789a09c2494a4654b523931df96cristy (void) SetImageAlphaChannel(annotate_image,OpaqueAlphaChannel, 202063240888c3975789a09c2494a4654b523931df96cristy exception); 20213ed852eea50f9d4cd633efb8c2b054b8e33c253cristy fill_color=draw_info->fill; 202246ff2676b1044ea4101ac7a59b83289cd8f6cfdacristy annotate_view=AcquireAuthenticCacheView(annotate_image,exception); 2023bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (y=0; y < (ssize_t) annotate_image->rows; y++) 20243ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 2025bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy register ssize_t 20263ed852eea50f9d4cd633efb8c2b054b8e33c253cristy x; 20273ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 20284c08aed51c5899665ade97263692328eea4af106cristy register Quantum 202905d2ff7ebf21f659f5b11e45afb294e152f4330cdirk *magick_restrict q; 20303ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 20313ed852eea50f9d4cd633efb8c2b054b8e33c253cristy q=GetCacheViewAuthenticPixels(annotate_view,0,y,annotate_image->columns, 20323ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 1,exception); 20336193b86c0b59030b647a10c75f37ec82d73e3695cristy if (q == (Quantum *) NULL) 20343ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 2035bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy for (x=0; x < (ssize_t) annotate_image->columns; x++) 20363ed852eea50f9d4cd633efb8c2b054b8e33c253cristy { 203750be538de7d724dfbd0cba7d434d1404b49ce90ddirk GetFillColor(draw_info,x,y,&fill_color,exception); 203855cb9f15b804f98ac7d37615b8f5f8888fc792f4cristy SetPixelAlpha(annotate_image,ClampToQuantum((((double) QuantumScale* 203955cb9f15b804f98ac7d37615b8f5f8888fc792f4cristy GetPixelIntensity(annotate_image,q)*fill_color.alpha))),q); 20404c08aed51c5899665ade97263692328eea4af106cristy SetPixelRed(annotate_image,fill_color.red,q); 20414c08aed51c5899665ade97263692328eea4af106cristy SetPixelGreen(annotate_image,fill_color.green,q); 20424c08aed51c5899665ade97263692328eea4af106cristy SetPixelBlue(annotate_image,fill_color.blue,q); 2043ed2315769b26818ed9d0c1291dc0457f0d8da0a4cristy q+=GetPixelChannels(annotate_image); 20443ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 20453ed852eea50f9d4cd633efb8c2b054b8e33c253cristy sync=SyncCacheViewAuthenticPixels(annotate_view,exception); 20463ed852eea50f9d4cd633efb8c2b054b8e33c253cristy if (sync == MagickFalse) 20473ed852eea50f9d4cd633efb8c2b054b8e33c253cristy break; 20483ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 20493ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_view=DestroyCacheView(annotate_view); 205039172408bad7ef2ef00a815fa9abf9979e7857cbcristy (void) CompositeImage(image,annotate_image,OverCompositeOp,MagickTrue, 2051bb50337b2a8a16ca7e903cc04ab195ff0fd47ae6cristy (ssize_t) ceil(offset->x-0.5),(ssize_t) ceil(offset->y-(metrics->ascent+ 2052e941a75fe8bf344bc5c06a7f74bb5173c87db115cristy metrics->descent)-0.5),exception); 20533ed852eea50f9d4cd633efb8c2b054b8e33c253cristy } 20543ed852eea50f9d4cd633efb8c2b054b8e33c253cristy annotate_image=DestroyImage(annotate_image); 20553ed852eea50f9d4cd633efb8c2b054b8e33c253cristy return(MagickTrue); 20563ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 20573ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 20583ed852eea50f9d4cd633efb8c2b054b8e33c253cristy/* 20593ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 20603ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 20613ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 20623ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 20633ed852eea50f9d4cd633efb8c2b054b8e33c253cristy+ R e n d e r X 1 1 % 20643ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 20653ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 20663ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% % 20673ed852eea50f9d4cd633efb8c2b054b8e33c253cristy%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 20683ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 20693ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% RenderX11() renders text on the image with an X11 font. It also returns the 20703ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% bounding box of the text relative to the image. 20713ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 20723ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% The format of the RenderX11 method is: 20733ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 20743ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% MagickBooleanType RenderX11(Image *image,DrawInfo *draw_info, 20755cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% const PointInfo *offset,TypeMetric *metrics,ExceptionInfo *exception) 20763ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 20773ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% A description of each parameter follows: 20783ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 20793ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o image: the image. 20803ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 20813ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o draw_info: the draw info. 20823ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 20833ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o offset: (x,y) location of text relative to image. 20843ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 20853ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% o metrics: bounding box of text. 20863ed852eea50f9d4cd633efb8c2b054b8e33c253cristy% 20875cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% o exception: return any errors or warnings in this structure. 20885cbc016effaa2d7ee617f46ca0a2371533d4ae17cristy% 20893ed852eea50f9d4cd633efb8c2b054b8e33c253cristy*/ 2090cc168c2dcad169c22f123761f2f53d867fb2f149cristystatic MagickBooleanType RenderX11(Image *image,const DrawInfo *draw_info, 2091cc168c2dcad169c22f123761f2f53d867fb2f149cristy const PointInfo *offset,TypeMetric *metrics,ExceptionInfo *exception) 20923ed852eea50f9d4cd633efb8c2b054b8e33c253cristy{ 20933ed852eea50f9d4cd633efb8c2b054b8e33c253cristy MagickBooleanType 20943ed852eea50f9d4cd633efb8c2b054b8e33c253cristy status; 20953ed852eea50f9d4cd633efb8c2b054b8e33c253cristy 2096d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy if (annotate_semaphore == (SemaphoreInfo *) NULL) 209704b11db5504ecdf205114ae7e9e68774a1ff0b9bcristy ActivateSemaphoreInfo(&annotate_semaphore); 2098d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy LockSemaphoreInfo(annotate_semaphore); 2099534d0a353b31242ce2f7b26c4eb4fe53f914d0f5cristy status=XRenderImage(image,draw_info,offset,metrics,exception); 2100d7ecaca521e2840f1308b758f7b3a3a9fd2dce38cristy UnlockSemaphoreInfo(annotate_semaphore); 2101534d0a353b31242ce2f7b26c4eb4fe53f914d0f5cristy return(status); 21023ed852eea50f9d4cd633efb8c2b054b8e33c253cristy} 2103