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