]> granicus.if.org Git - imagemagick/blob - coders/ttf.c
8729bb80f90b4deb98f4bc064ac4e2861ecb3abb
[imagemagick] / coders / ttf.c
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 %                                John Cristy                                  %
17 %                                 July 1992                                   %
18 %                                                                             %
19 %                                                                             %
20 %  Copyright 1999-2011 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 \f
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 #if defined(MAGICKCORE_HAVE_FT2BUILD_H)
61 #  include <ft2build.h>
62 #endif
63 #if defined(FT_FREETYPE_H)
64 #  include FT_FREETYPE_H
65 #else
66 #  include <freetype/freetype.h>
67 #endif
68 #endif
69 \f
70 /*
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 \f
105 /*
106 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
107 %                                                                             %
108 %                                                                             %
109 %                                                                             %
110 %   I s T T F                                                                 %
111 %                                                                             %
112 %                                                                             %
113 %                                                                             %
114 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
115 %
116 %  IsTTF()() returns MagickTrue if the image format type, identified by the
117 %  magick string, is TTF.
118 %
119 %  The format of the IsTTF method is:
120 %
121 %      MagickBooleanType IsTTF(const unsigned char *magick,const size_t length)
122 %
123 %  A description of each parameter follows:
124 %
125 %    o magick: compare image format pattern against these bytes.
126 %
127 %    o length: Specifies the length of the magick string.
128 %
129 %
130 */
131 static MagickBooleanType IsTTF(const unsigned char *magick,const size_t length)
132 {
133   if (length < 5)
134     return(MagickFalse);
135   if (((int) magick[0] == 0x00) && ((int) magick[1] == 0x01) &&
136       ((int) magick[2] == 0x00) && ((int) magick[3] == 0x00) &&
137       ((int) magick[4] == 0x00))
138     return(MagickTrue);
139   return(MagickFalse);
140 }
141 \f
142 #if defined(MAGICKCORE_FREETYPE_DELEGATE)
143 /*
144 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
145 %                                                                             %
146 %                                                                             %
147 %                                                                             %
148 %   R e a d T T F I m a g e                                                   %
149 %                                                                             %
150 %                                                                             %
151 %                                                                             %
152 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
153 %
154 %  ReadTTFImage() reads a TrueType font file and returns it.  It
155 %  allocates the memory necessary for the new Image structure and returns a
156 %  pointer to the new image.
157 %
158 %  The format of the ReadTTFImage method is:
159 %
160 %      Image *ReadTTFImage(const ImageInfo *image_info,ExceptionInfo *exception)
161 %
162 %  A description of each parameter follows:
163 %
164 %    o image_info: the image info.
165 %
166 %    o exception: return any errors or warnings in this structure.
167 %
168 */
169 static Image *ReadTTFImage(const ImageInfo *image_info,ExceptionInfo *exception)
170 {
171   char
172     buffer[MaxTextExtent],
173     *text;
174
175   const char
176     *Text = (char *)
177       "abcdefghijklmnopqrstuvwxyz\n"
178       "ABCDEFGHIJKLMNOPQRSTUVWXYZ\n"
179       "0123456789.:,;(*!?}^)#${%^&-+@\n",
180     *Phrase = (char *) "The quick onyx goblin jumps over the lazy dwarf!";
181         /* NOTE: These are Pangrams, which contain every letter in English
182            See http://www.artlebedev.ru/kovodstvo/sections/33/
183
184            "A quick brown fox jumps over the lazy dog.";
185            "Pack my box with five dozen liquor jugs.";
186            "The five boxing wizards jump quickly!";
187            "Grumpy wizards make toxic brew for the evil Queen and Jack.";
188
189            IMv6 used this well known phrase, but it is not a pangram!
190            "That which does not destroy me, only makes me stronger.";
191         */
192
193   const TypeInfo
194     *type_info;
195
196   DrawInfo
197     *draw_info;
198
199   Image
200     *image;
201
202   MagickBooleanType
203     status;
204
205   PixelInfo
206     background_color;
207
208   register ssize_t
209     i,
210     x;
211
212   register Quantum
213     *q;
214
215   ssize_t
216     y;
217
218   /*
219     Open image file.
220   */
221   assert(image_info != (const ImageInfo *) NULL);
222   assert(image_info->signature == MagickSignature);
223   if (image_info->debug != MagickFalse)
224     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",
225       image_info->filename);
226   assert(exception != (ExceptionInfo *) NULL);
227   assert(exception->signature == MagickSignature);
228   image=AcquireImage(image_info,exception);
229   image->columns=800;
230   image->rows=480;
231   type_info=GetTypeInfo(image_info->filename,exception);
232   if ((type_info != (const TypeInfo *) NULL) &&
233       (type_info->glyphs != (char *) NULL))
234     (void) CopyMagickString(image->filename,type_info->glyphs,MaxTextExtent);
235   status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception);
236   if (status == MagickFalse)
237     {
238       image=DestroyImageList(image);
239       return((Image *) NULL);
240     }
241   /*
242     Color canvas with background color
243   */
244   background_color=image_info->background_color;
245   for (y=0; y < (ssize_t) image->rows; y++)
246   {
247     q=QueueAuthenticPixels(image,0,y,image->columns,1,exception);
248     if (q == (Quantum *) NULL)
249       break;
250     for (x=0; x < (ssize_t) image->columns; x++)
251     {
252       SetPixelPixelInfo(image,&background_color,q);
253       q+=GetPixelChannels(image);
254     }
255     if (SyncAuthenticPixels(image,exception) == MagickFalse)
256       break;
257   }
258   (void) CopyMagickString(image->magick,image_info->magick,MaxTextExtent);
259   (void) CopyMagickString(image->filename,image_info->filename,MaxTextExtent);
260   /*
261     Prepare drawing commands
262   */
263   y=20;
264   draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL);
265   draw_info->font=AcquireString(image->filename);
266   ConcatenateString(&draw_info->primitive,"push graphic-context\n");
267   (void) FormatLocaleString(buffer,MaxTextExtent," viewbox 0 0 %.20g %.20g\n",
268     (double) image->columns,(double) image->rows);
269   ConcatenateString(&draw_info->primitive,buffer);
270   ConcatenateString(&draw_info->primitive," font-size 18\n");
271   (void) FormatLocaleString(buffer,MaxTextExtent," text 10,%.20g '",(double) y);
272   ConcatenateString(&draw_info->primitive,buffer);
273   text=EscapeString(Text,'"');
274   ConcatenateString(&draw_info->primitive,text);
275   text=DestroyString(text);
276   (void) FormatLocaleString(buffer,MaxTextExtent,"'\n");
277   ConcatenateString(&draw_info->primitive,buffer);
278   y+=12*(ssize_t) MultilineCensus((char *) Text);
279   /* FUTURE: A setting to specify the text to use */
280   for (i=4; i <= 72; )
281   {
282     y += (i>12) ? i : 12;  /* line spacing */
283     ConcatenateString(&draw_info->primitive," font-size 12\n");
284     (void) FormatLocaleString(buffer,MaxTextExtent," text 10,%.20g '%.20g'\n",
285       (double) y,(double) i);
286     ConcatenateString(&draw_info->primitive,buffer);
287     (void) FormatLocaleString(buffer,MaxTextExtent," font-size %.20g\n",
288       (double) i);
289     ConcatenateString(&draw_info->primitive,buffer);
290     (void) FormatLocaleString(buffer,MaxTextExtent," text 50,%.20g '%s'\n",
291          (double) y, Phrase);
292     ConcatenateString(&draw_info->primitive,buffer);
293     if (i < 8)
294       i++;
295     else if (i < 12)
296       i+=2;
297     else if (i < 24)
298       i+=6;
299     else
300       i+=12;
301   }
302   ConcatenateString(&draw_info->primitive,"pop graphic-context");
303   (void) DrawImage(image,draw_info,exception);
304   /*
305     Relinquish resources.
306   */
307   draw_info=DestroyDrawInfo(draw_info);
308   (void) CloseBlob(image);
309   return(GetFirstImageInList(image));
310 }
311 #endif /* MAGICKCORE_FREETYPE_DELEGATE */
312 \f
313 /*
314 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
315 %                                                                             %
316 %                                                                             %
317 %                                                                             %
318 %   R e g i s t e r T T F I m a g e                                           %
319 %                                                                             %
320 %                                                                             %
321 %                                                                             %
322 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
323 %
324 %  RegisterTTFImage() adds attributes for the TTF image format to
325 %  the list of supported formats.  The attributes include the image format
326 %  tag, a method to read and/or write the format, whether the format
327 %  supports the saving of more than one frame to the same file or blob,
328 %  whether the format supports native in-memory I/O, and a brief
329 %  description of the format.
330 %
331 %  The format of the RegisterTTFImage method is:
332 %
333 %      size_t RegisterTTFImage(void)
334 %
335 */
336 ModuleExport size_t RegisterTTFImage(void)
337 {
338   char
339     version[MaxTextExtent];
340
341   MagickInfo
342     *entry;
343
344   *version='\0';
345 #if defined(FREETYPE_MAJOR) && defined(FREETYPE_MINOR) && defined(FREETYPE_PATCH)
346   (void) FormatLocaleString(version,MaxTextExtent,"Freetype %d.%d.%d",
347     FREETYPE_MAJOR,FREETYPE_MINOR,FREETYPE_PATCH);
348 #endif
349   entry=SetMagickInfo("DFONT");
350 #if defined(MAGICKCORE_FREETYPE_DELEGATE)
351   entry->decoder=(DecodeImageHandler *) ReadTTFImage;
352 #endif
353   entry->magick=(IsImageFormatHandler *) IsTTF;
354   entry->adjoin=MagickFalse;
355   entry->description=ConstantString("Multi-face font package");
356   if (*version != '\0')
357     entry->version=ConstantString(version);
358   entry->module=ConstantString("TTF");
359   (void) RegisterMagickInfo(entry);
360   entry=SetMagickInfo("PFA");
361 #if defined(MAGICKCORE_FREETYPE_DELEGATE)
362   entry->decoder=(DecodeImageHandler *) ReadTTFImage;
363 #endif
364   entry->magick=(IsImageFormatHandler *) IsPFA;
365   entry->adjoin=MagickFalse;
366   entry->description=ConstantString("Postscript Type 1 font (ASCII)");
367   if (*version != '\0')
368     entry->version=ConstantString(version);
369   entry->module=ConstantString("TTF");
370   (void) RegisterMagickInfo(entry);
371   entry=SetMagickInfo("PFB");
372 #if defined(MAGICKCORE_FREETYPE_DELEGATE)
373   entry->decoder=(DecodeImageHandler *) ReadTTFImage;
374 #endif
375   entry->magick=(IsImageFormatHandler *) IsPFA;
376   entry->adjoin=MagickFalse;
377   entry->description=ConstantString("Postscript Type 1 font (binary)");
378   if (*version != '\0')
379     entry->version=ConstantString(version);
380   entry->module=ConstantString("TTF");
381   (void) RegisterMagickInfo(entry);
382   entry=SetMagickInfo("OTF");
383 #if defined(MAGICKCORE_FREETYPE_DELEGATE)
384   entry->decoder=(DecodeImageHandler *) ReadTTFImage;
385 #endif
386   entry->magick=(IsImageFormatHandler *) IsTTF;
387   entry->adjoin=MagickFalse;
388   entry->description=ConstantString("Open Type font");
389   if (*version != '\0')
390     entry->version=ConstantString(version);
391   entry->module=ConstantString("TTF");
392   (void) RegisterMagickInfo(entry);
393   entry=SetMagickInfo("TTC");
394 #if defined(MAGICKCORE_FREETYPE_DELEGATE)
395   entry->decoder=(DecodeImageHandler *) ReadTTFImage;
396 #endif
397   entry->magick=(IsImageFormatHandler *) IsTTF;
398   entry->adjoin=MagickFalse;
399   entry->description=ConstantString("TrueType font collection");
400   if (*version != '\0')
401     entry->version=ConstantString(version);
402   entry->module=ConstantString("TTF");
403   (void) RegisterMagickInfo(entry);
404   entry=SetMagickInfo("TTF");
405 #if defined(MAGICKCORE_FREETYPE_DELEGATE)
406   entry->decoder=(DecodeImageHandler *) ReadTTFImage;
407 #endif
408   entry->magick=(IsImageFormatHandler *) IsTTF;
409   entry->adjoin=MagickFalse;
410   entry->description=ConstantString("TrueType font");
411   if (*version != '\0')
412     entry->version=ConstantString(version);
413   entry->module=ConstantString("TTF");
414   (void) RegisterMagickInfo(entry);
415   return(MagickImageCoderSignature);
416 }
417 \f
418 /*
419 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
420 %                                                                             %
421 %                                                                             %
422 %                                                                             %
423 %   U n r e g i s t e r T T F I m a g e                                       %
424 %                                                                             %
425 %                                                                             %
426 %                                                                             %
427 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
428 %
429 %  UnregisterTTFImage() removes format registrations made by the
430 %  TTF module from the list of supported formats.
431 %
432 %  The format of the UnregisterTTFImage method is:
433 %
434 %      UnregisterTTFImage(void)
435 %
436 */
437 ModuleExport void UnregisterTTFImage(void)
438 {
439   (void) UnregisterMagickInfo("TTF");
440   (void) UnregisterMagickInfo("TTC");
441   (void) UnregisterMagickInfo("OTF");
442   (void) UnregisterMagickInfo("PFA");
443   (void) UnregisterMagickInfo("PFB");
444   (void) UnregisterMagickInfo("PFA");
445   (void) UnregisterMagickInfo("DFONT");
446 }