1/* 2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3% % 4% % 5% % 6% TTTTT TTTTT FFFFF % 7% T T F % 8% T T FFF % 9% T T F % 10% T T F % 11% % 12% % 13% Return A Preview For A TrueType or Postscript Font % 14% % 15% Software Design % 16% Cristy % 17% July 1992 % 18% % 19% % 20% Copyright 1999-2016 ImageMagick Studio LLC, a non-profit organization % 21% dedicated to making software imaging solutions freely available. % 22% % 23% You may not use this file except in compliance with the License. You may % 24% obtain a copy of the License at % 25% % 26% http://www.imagemagick.org/script/license.php % 27% % 28% Unless required by applicable law or agreed to in writing, software % 29% distributed under the License is distributed on an "AS IS" BASIS, % 30% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % 31% See the License for the specific language governing permissions and % 32% limitations under the License. % 33% % 34%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 35% 36% 37*/ 38 39/* 40 Include declarations. 41*/ 42#include "MagickCore/studio.h" 43#include "MagickCore/blob.h" 44#include "MagickCore/blob-private.h" 45#include "MagickCore/draw.h" 46#include "MagickCore/exception.h" 47#include "MagickCore/exception-private.h" 48#include "MagickCore/image.h" 49#include "MagickCore/image-private.h" 50#include "MagickCore/list.h" 51#include "MagickCore/magick.h" 52#include "MagickCore/memory_.h" 53#include "MagickCore/quantum-private.h" 54#include "MagickCore/static.h" 55#include "MagickCore/string_.h" 56#include "MagickCore/module.h" 57#include "MagickCore/type.h" 58#include "MagickWand/MagickWand.h" 59#if defined(MAGICKCORE_FREETYPE_DELEGATE) 60#include <ft2build.h> 61#if defined(FT_FREETYPE_H) 62# include FT_FREETYPE_H 63#else 64# include <freetype/freetype.h> 65#endif 66#endif 67 68/* 69%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 70% % 71% % 72% % 73% I s P F A % 74% % 75% % 76% % 77%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 78% 79% IsPFA()() returns MagickTrue if the image format type, identified by the 80% magick string, is PFA. 81% 82% The format of the IsPFA method is: 83% 84% MagickBooleanType IsPFA(const unsigned char *magick,const size_t length) 85% 86% A description of each parameter follows: 87% 88% o magick: compare image format pattern against these bytes. 89% 90% o length: Specifies the length of the magick string. 91% 92% 93*/ 94static MagickBooleanType IsPFA(const unsigned char *magick,const size_t length) 95{ 96 if (length < 14) 97 return(MagickFalse); 98 if (LocaleNCompare((char *) magick,"%!PS-AdobeFont",14) == 0) 99 return(MagickTrue); 100 return(MagickFalse); 101} 102 103/* 104%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 105% % 106% % 107% % 108% I s T T F % 109% % 110% % 111% % 112%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 113% 114% IsTTF()() returns MagickTrue if the image format type, identified by the 115% magick string, is TTF. 116% 117% The format of the IsTTF method is: 118% 119% MagickBooleanType IsTTF(const unsigned char *magick,const size_t length) 120% 121% A description of each parameter follows: 122% 123% o magick: compare image format pattern against these bytes. 124% 125% o length: Specifies the length of the magick string. 126% 127% 128*/ 129static MagickBooleanType IsTTF(const unsigned char *magick,const size_t length) 130{ 131 if (length < 5) 132 return(MagickFalse); 133 if (((int) magick[0] == 0x00) && ((int) magick[1] == 0x01) && 134 ((int) magick[2] == 0x00) && ((int) magick[3] == 0x00) && 135 ((int) magick[4] == 0x00)) 136 return(MagickTrue); 137 return(MagickFalse); 138} 139 140#if defined(MAGICKCORE_FREETYPE_DELEGATE) 141/* 142%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 143% % 144% % 145% % 146% R e a d T T F I m a g e % 147% % 148% % 149% % 150%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 151% 152% ReadTTFImage() reads a TrueType font file and returns it. It 153% allocates the memory necessary for the new Image structure and returns a 154% pointer to the new image. 155% 156% The format of the ReadTTFImage method is: 157% 158% Image *ReadTTFImage(const ImageInfo *image_info,ExceptionInfo *exception) 159% 160% A description of each parameter follows: 161% 162% o image_info: the image info. 163% 164% o exception: return any errors or warnings in this structure. 165% 166*/ 167static Image *ReadTTFImage(const ImageInfo *image_info,ExceptionInfo *exception) 168{ 169 char 170 buffer[MagickPathExtent], 171 *text; 172 173 const char 174 *Text = (char *) 175 "abcdefghijklmnopqrstuvwxyz\n" 176 "ABCDEFGHIJKLMNOPQRSTUVWXYZ\n" 177 "0123456789.:,;(*!?}^)#${%^&-+@\n"; 178 179 const TypeInfo 180 *type_info; 181 182 DrawInfo 183 *draw_info; 184 185 Image 186 *image; 187 188 MagickBooleanType 189 status; 190 191 PixelInfo 192 background_color; 193 194 register ssize_t 195 i, 196 x; 197 198 register Quantum 199 *q; 200 201 ssize_t 202 y; 203 204 /* 205 Open image file. 206 */ 207 assert(image_info != (const ImageInfo *) NULL); 208 assert(image_info->signature == MagickCoreSignature); 209 if (image_info->debug != MagickFalse) 210 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s", 211 image_info->filename); 212 assert(exception != (ExceptionInfo *) NULL); 213 assert(exception->signature == MagickCoreSignature); 214 image=AcquireImage(image_info,exception); 215 image->columns=800; 216 image->rows=480; 217 type_info=GetTypeInfo(image_info->filename,exception); 218 if ((type_info != (const TypeInfo *) NULL) && 219 (type_info->glyphs != (char *) NULL)) 220 (void) CopyMagickString(image->filename,type_info->glyphs,MagickPathExtent); 221 status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); 222 if (status == MagickFalse) 223 { 224 image=DestroyImageList(image); 225 return((Image *) NULL); 226 } 227 status=SetImageExtent(image,image->columns,image->rows,exception); 228 if (status == MagickFalse) 229 return(DestroyImageList(image)); 230 /* 231 Color canvas with background color 232 */ 233 background_color=image_info->background_color; 234 for (y=0; y < (ssize_t) image->rows; y++) 235 { 236 q=QueueAuthenticPixels(image,0,y,image->columns,1,exception); 237 if (q == (Quantum *) NULL) 238 break; 239 for (x=0; x < (ssize_t) image->columns; x++) 240 { 241 SetPixelViaPixelInfo(image,&background_color,q); 242 q+=GetPixelChannels(image); 243 } 244 if (SyncAuthenticPixels(image,exception) == MagickFalse) 245 break; 246 } 247 (void) CopyMagickString(image->magick,image_info->magick,MagickPathExtent); 248 (void) CopyMagickString(image->filename,image_info->filename,MagickPathExtent); 249 /* 250 Prepare drawing commands 251 */ 252 y=20; 253 draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL); 254 draw_info->font=AcquireString(image->filename); 255 ConcatenateString(&draw_info->primitive,"push graphic-context\n"); 256 (void) FormatLocaleString(buffer,MagickPathExtent," viewbox 0 0 %.20g %.20g\n", 257 (double) image->columns,(double) image->rows); 258 ConcatenateString(&draw_info->primitive,buffer); 259 ConcatenateString(&draw_info->primitive," font-size 18\n"); 260 (void) FormatLocaleString(buffer,MagickPathExtent," text 10,%.20g '",(double) y); 261 ConcatenateString(&draw_info->primitive,buffer); 262 text=EscapeString(Text,'"'); 263 ConcatenateString(&draw_info->primitive,text); 264 text=DestroyString(text); 265 (void) FormatLocaleString(buffer,MagickPathExtent,"'\n"); 266 ConcatenateString(&draw_info->primitive,buffer); 267 y+=20*(ssize_t) MultilineCensus((char *) Text)+20; 268 for (i=12; i <= 72; i+=6) 269 { 270 y+=i+12; 271 ConcatenateString(&draw_info->primitive," font-size 18\n"); 272 (void) FormatLocaleString(buffer,MagickPathExtent," text 10,%.20g '%.20g'\n", 273 (double) y,(double) i); 274 ConcatenateString(&draw_info->primitive,buffer); 275 (void) FormatLocaleString(buffer,MagickPathExtent," font-size %.20g\n", 276 (double) i); 277 ConcatenateString(&draw_info->primitive,buffer); 278 (void) FormatLocaleString(buffer,MagickPathExtent," text 50,%.20g " 279 "'That which does not destroy me, only makes me stronger.'\n",(double) y); 280 ConcatenateString(&draw_info->primitive,buffer); 281 if (i >= 24) 282 i+=6; 283 } 284 ConcatenateString(&draw_info->primitive,"pop graphic-context"); 285 (void) DrawImage(image,draw_info,exception); 286 /* 287 Relinquish resources. 288 */ 289 draw_info=DestroyDrawInfo(draw_info); 290 (void) CloseBlob(image); 291 return(GetFirstImageInList(image)); 292} 293#endif /* MAGICKCORE_FREETYPE_DELEGATE */ 294 295/* 296%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 297% % 298% % 299% % 300% R e g i s t e r T T F I m a g e % 301% % 302% % 303% % 304%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 305% 306% RegisterTTFImage() adds attributes for the TTF image format to 307% the list of supported formats. The attributes include the image format 308% tag, a method to read and/or write the format, whether the format 309% supports the saving of more than one frame to the same file or blob, 310% whether the format supports native in-memory I/O, and a brief 311% description of the format. 312% 313% The format of the RegisterTTFImage method is: 314% 315% size_t RegisterTTFImage(void) 316% 317*/ 318ModuleExport size_t RegisterTTFImage(void) 319{ 320 char 321 version[MagickPathExtent]; 322 323 MagickInfo 324 *entry; 325 326 *version='\0'; 327#if defined(FREETYPE_MAJOR) && defined(FREETYPE_MINOR) && defined(FREETYPE_PATCH) 328 (void) FormatLocaleString(version,MagickPathExtent,"Freetype %d.%d.%d", 329 FREETYPE_MAJOR,FREETYPE_MINOR,FREETYPE_PATCH); 330#endif 331 entry=AcquireMagickInfo("TTF","DFONT","Multi-face font package"); 332#if defined(MAGICKCORE_FREETYPE_DELEGATE) 333 entry->decoder=(DecodeImageHandler *) ReadTTFImage; 334#endif 335 entry->magick=(IsImageFormatHandler *) IsTTF; 336 entry->flags^=CoderAdjoinFlag; 337 if (*version != '\0') 338 entry->version=ConstantString(version); 339 (void) RegisterMagickInfo(entry); 340 entry=AcquireMagickInfo("TTF","PFA","Postscript Type 1 font (ASCII)"); 341#if defined(MAGICKCORE_FREETYPE_DELEGATE) 342 entry->decoder=(DecodeImageHandler *) ReadTTFImage; 343#endif 344 entry->magick=(IsImageFormatHandler *) IsPFA; 345 entry->flags^=CoderAdjoinFlag; 346 if (*version != '\0') 347 entry->version=ConstantString(version); 348 (void) RegisterMagickInfo(entry); 349 entry=AcquireMagickInfo("TTF","PFB","Postscript Type 1 font (binary)"); 350#if defined(MAGICKCORE_FREETYPE_DELEGATE) 351 entry->decoder=(DecodeImageHandler *) ReadTTFImage; 352#endif 353 entry->magick=(IsImageFormatHandler *) IsPFA; 354 entry->flags^=CoderAdjoinFlag; 355 if (*version != '\0') 356 entry->version=ConstantString(version); 357 (void) RegisterMagickInfo(entry); 358 entry=AcquireMagickInfo("TTF","OTF","Open Type font"); 359#if defined(MAGICKCORE_FREETYPE_DELEGATE) 360 entry->decoder=(DecodeImageHandler *) ReadTTFImage; 361#endif 362 entry->magick=(IsImageFormatHandler *) IsTTF; 363 entry->flags^=CoderAdjoinFlag; 364 if (*version != '\0') 365 entry->version=ConstantString(version); 366 (void) RegisterMagickInfo(entry); 367 entry=AcquireMagickInfo("TTF","TTC","TrueType font collection"); 368#if defined(MAGICKCORE_FREETYPE_DELEGATE) 369 entry->decoder=(DecodeImageHandler *) ReadTTFImage; 370#endif 371 entry->magick=(IsImageFormatHandler *) IsTTF; 372 entry->flags^=CoderAdjoinFlag; 373 if (*version != '\0') 374 entry->version=ConstantString(version); 375 (void) RegisterMagickInfo(entry); 376 entry=AcquireMagickInfo("TTF","TTF","TrueType font"); 377#if defined(MAGICKCORE_FREETYPE_DELEGATE) 378 entry->decoder=(DecodeImageHandler *) ReadTTFImage; 379#endif 380 entry->magick=(IsImageFormatHandler *) IsTTF; 381 entry->flags^=CoderAdjoinFlag; 382 if (*version != '\0') 383 entry->version=ConstantString(version); 384 (void) RegisterMagickInfo(entry); 385 return(MagickImageCoderSignature); 386} 387 388/* 389%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 390% % 391% % 392% % 393% U n r e g i s t e r T T F I m a g e % 394% % 395% % 396% % 397%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 398% 399% UnregisterTTFImage() removes format registrations made by the 400% TTF module from the list of supported formats. 401% 402% The format of the UnregisterTTFImage method is: 403% 404% UnregisterTTFImage(void) 405% 406*/ 407ModuleExport void UnregisterTTFImage(void) 408{ 409 (void) UnregisterMagickInfo("TTF"); 410 (void) UnregisterMagickInfo("TTC"); 411 (void) UnregisterMagickInfo("OTF"); 412 (void) UnregisterMagickInfo("PFA"); 413 (void) UnregisterMagickInfo("PFB"); 414 (void) UnregisterMagickInfo("PFA"); 415 (void) UnregisterMagickInfo("DFONT"); 416} 417