/src/graphicsmagick/coders/ttf.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | % Copyright (C) 2003-2020 GraphicsMagick Group |
3 | | % Copyright (C) 2002 ImageMagick Studio |
4 | | % Copyright 1991-1999 E. I. du Pont de Nemours and Company |
5 | | % |
6 | | % This program is covered by multiple licenses, which are described in |
7 | | % Copyright.txt. You should have received a copy of Copyright.txt with this |
8 | | % package; otherwise see http://www.graphicsmagick.org/www/Copyright.html. |
9 | | % |
10 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
11 | | % % |
12 | | % % |
13 | | % % |
14 | | % TTTTT TTTTT FFFFF % |
15 | | % T T F % |
16 | | % T T FFF % |
17 | | % T T F % |
18 | | % T T F % |
19 | | % % |
20 | | % % |
21 | | % Return A Preview For A TrueType or Postscript Font % |
22 | | % % |
23 | | % % |
24 | | % Software Design % |
25 | | % John Cristy % |
26 | | % July 1992 % |
27 | | % % |
28 | | % % |
29 | | % % |
30 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
31 | | % |
32 | | % |
33 | | */ |
34 | | |
35 | | /* |
36 | | Include declarations. |
37 | | */ |
38 | | #include "magick/studio.h" |
39 | | #include "magick/blob.h" |
40 | | #include "magick/pixel_cache.h" |
41 | | #include "magick/draw.h" |
42 | | #include "magick/magick.h" |
43 | | #include "magick/render.h" |
44 | | #include "magick/utility.h" |
45 | | #if defined(HasTTF) |
46 | | |
47 | | # if defined(__MINGW32__) |
48 | | # undef interface /* Remove interface define */ |
49 | | # endif |
50 | | |
51 | | # if defined(HAVE_FT2BUILD_H) |
52 | | /* |
53 | | Modern FreeType2 installs require that <ft2build.h> be included |
54 | | before including other FreeType2 headers. Including |
55 | | <ft2build.h> establishes definitions used by other FreeType2 |
56 | | headers. |
57 | | */ |
58 | | # include <ft2build.h> |
59 | | # include FT_FREETYPE_H |
60 | | # else |
61 | | /* |
62 | | Very old way to include FreeType2 |
63 | | */ |
64 | | # include <freetype/freetype.h> |
65 | | # endif /* defined(HAVE_FT2BUILD_H) */ |
66 | | |
67 | | #endif /* defined(HasTTF) */ |
68 | | |
69 | | /* |
70 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
71 | | % % |
72 | | % % |
73 | | % % |
74 | | % I s T T F % |
75 | | % % |
76 | | % % |
77 | | % % |
78 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
79 | | % |
80 | | % Method IsTTF returns True if the image format type, identified by the |
81 | | % magick string can be handled by this module. |
82 | | % |
83 | | % The format of the IsTTF method is: |
84 | | % |
85 | | % unsigned int IsTTF(const unsigned char *magick,const size_t length) |
86 | | % |
87 | | % A description of each parameter follows: |
88 | | % |
89 | | % o status: Method IsTTF returns True if the image format type can be |
90 | | % handled by this module. |
91 | | % |
92 | | % o magick: This string is generally the first few bytes of an image file |
93 | | % or blob. |
94 | | % |
95 | | % o length: Specifies the length of the magick string. |
96 | | % |
97 | | % |
98 | | */ |
99 | | |
100 | | static unsigned int IsPFA(const unsigned char *magick,const size_t length) |
101 | 0 | { |
102 | 0 | if (length < 14) |
103 | 0 | return(False); |
104 | 0 | if (LocaleNCompare((char *) magick,"%!PS-AdobeFont-1.0",14) == 0) |
105 | 0 | return(True); |
106 | 0 | return(False); |
107 | 0 | } |
108 | | |
109 | | static unsigned int IsTTF(const unsigned char *magick,const size_t length) |
110 | 0 | { |
111 | 0 | if (length < 5) |
112 | 0 | return(False); |
113 | 0 | if ((magick[0] == 0x00U) && (magick[1] == 0x01U) && (magick[2] == 0x00U) && |
114 | 0 | (magick[3] == 0x00U) && (magick[4] == 0x0U)) |
115 | 0 | return(True); |
116 | 0 | return(False); |
117 | 0 | } |
118 | | |
119 | | /* |
120 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
121 | | % % |
122 | | % % |
123 | | % % |
124 | | % R e a d T T F I m a g e % |
125 | | % % |
126 | | % % |
127 | | % % |
128 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
129 | | % |
130 | | % Method ReadTTFImage reads a TrueType font file and returns it. It |
131 | | % allocates the memory necessary for the new Image structure and returns a |
132 | | % pointer to the new image. |
133 | | % |
134 | | % The format of the ReadTTFImage method is: |
135 | | % |
136 | | % Image *ReadTTFImage(const ImageInfo *image_info,ExceptionInfo *exception) |
137 | | % |
138 | | % A description of each parameter follows: |
139 | | % |
140 | | % o image: Method ReadTTFImage returns a pointer to the image after |
141 | | % reading. A null image is returned if there is a memory shortage or |
142 | | % if the image cannot be read. |
143 | | % |
144 | | % o image_info: Specifies a pointer to a ImageInfo structure. |
145 | | % |
146 | | % o exception: return any errors or warnings in this structure. |
147 | | % |
148 | | % |
149 | | */ |
150 | | #if defined(HasTTF) |
151 | | static Image *ReadTTFImage(const ImageInfo *image_info,ExceptionInfo *exception) |
152 | 98 | { |
153 | 98 | char |
154 | 98 | buffer[MaxTextExtent]; |
155 | | |
156 | 98 | static const char |
157 | 98 | Text[] = |
158 | 98 | "ABCDEFGHIJKLMNOPQRSTUVWXYZ abcdefghijklmnopqrstuvwxyz\n0123456789 " |
159 | 98 | "\342\352\356\373\364\344\353\357\366\374\377\340\371\351\350\347\n" |
160 | 98 | "&#~\\\"\'(-`_^@)=+\260 $\243^\250*\265\371%!\247:/;.,?<>"; |
161 | | |
162 | 98 | DrawContext |
163 | 98 | context; |
164 | | |
165 | 98 | DrawInfo |
166 | 98 | *draw_info; |
167 | | |
168 | 98 | Image |
169 | 98 | *image; |
170 | | |
171 | 98 | long |
172 | 98 | y; |
173 | | |
174 | 98 | PixelPacket |
175 | 98 | background_color; |
176 | | |
177 | 98 | register long |
178 | 98 | i, |
179 | 98 | x; |
180 | | |
181 | 98 | register PixelPacket |
182 | 98 | *q; |
183 | | |
184 | 98 | unsigned int |
185 | 98 | status; |
186 | | |
187 | | /* |
188 | | Open image file. |
189 | | */ |
190 | 98 | assert(image_info != (const ImageInfo *) NULL); |
191 | 98 | assert(image_info->signature == MagickSignature); |
192 | 98 | assert(exception != (ExceptionInfo *) NULL); |
193 | 98 | assert(exception->signature == MagickSignature); |
194 | 98 | image=AllocateImage(image_info); |
195 | 98 | image->columns=800; |
196 | 98 | image->rows=480; |
197 | 98 | status=OpenBlob(image_info,image,ReadBinaryBlobMode,exception); |
198 | 98 | if (status == False) |
199 | 98 | ThrowReaderException(FileOpenError,UnableToOpenFile,image); |
200 | 98 | if (CheckImagePixelLimits(image, exception) != MagickPass) |
201 | 98 | ThrowReaderException(ResourceLimitError,ImagePixelLimitExceeded,image); |
202 | | /* |
203 | | Color canvas with background color |
204 | | */ |
205 | 98 | background_color=image_info->background_color; |
206 | 47.1k | for (y=0; y < (long) image->rows; y++) |
207 | 47.0k | { |
208 | 47.0k | q=SetImagePixels(image,0,y,image->columns,1); |
209 | 47.0k | if (q == (PixelPacket *) NULL) |
210 | 0 | break; |
211 | 37.6M | for (x=0; x < (long) image->columns; x++) |
212 | 37.6M | *q++=background_color; |
213 | 47.0k | if (!SyncImagePixelsEx(image,exception)) |
214 | 0 | break; |
215 | 47.0k | } |
216 | 98 | (void) strlcpy(image->magick,image_info->magick,MaxTextExtent); |
217 | 98 | (void) strlcpy(image->filename,image_info->filename,MaxTextExtent); |
218 | | /* |
219 | | Prepare drawing commands |
220 | | */ |
221 | 98 | y=20; |
222 | 98 | draw_info=CloneDrawInfo(image_info,(DrawInfo *) NULL); |
223 | 98 | draw_info->font=AllocateString(image->filename); |
224 | 98 | draw_info->fill=image_info->pen; |
225 | 98 | context=DrawAllocateContext(draw_info,image); |
226 | 98 | (void) DrawPushGraphicContext(context); |
227 | 98 | (void) DrawSetViewbox(context,0,0,image->columns,image->rows); |
228 | 98 | (void) DrawSetFont(context,image_info->filename); |
229 | 98 | (void) DrawSetFontSize(context,18); |
230 | 98 | (void) DrawAnnotation(context,10,y,(const unsigned char *) Text); |
231 | 98 | y+=20*MultilineCensus(Text)+20; |
232 | 784 | for (i=12; i <= 72; i+=6) |
233 | 686 | { |
234 | 686 | y+=i+12; |
235 | 686 | (void) DrawSetFontSize(context,18); |
236 | 686 | (void) FormatString(buffer,"%ld",i); |
237 | 686 | (void) DrawAnnotation(context,10,y,(const unsigned char *) buffer); |
238 | 686 | (void) DrawSetFontSize(context,i); |
239 | 686 | (void) DrawAnnotation(context,50,y,(const unsigned char *) |
240 | 686 | "That which does not destroy me, only makes me stronger."); |
241 | 686 | if (i >= 24) |
242 | 490 | i+=6; |
243 | 686 | } |
244 | 98 | (void) DrawPopGraphicContext(context); |
245 | 98 | (void) DrawRender(context); |
246 | | /* |
247 | | Free resources. |
248 | | */ |
249 | 98 | DestroyDrawInfo(draw_info); |
250 | 98 | DrawDestroyContext(context); |
251 | 98 | CloseBlob(image); |
252 | 98 | StopTimer(&image->timer); |
253 | 98 | return(image); |
254 | 98 | } |
255 | | #endif /* HasTTF */ |
256 | | |
257 | | /* |
258 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
259 | | % % |
260 | | % % |
261 | | % % |
262 | | % R e g i s t e r T T F I m a g e % |
263 | | % % |
264 | | % % |
265 | | % % |
266 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
267 | | % |
268 | | % Method RegisterTTFImage adds attributes for the TTF image format to |
269 | | % the list of supported formats. The attributes include the image format |
270 | | % tag, a method to read and/or write the format, whether the format |
271 | | % supports the saving of more than one frame to the same file or blob, |
272 | | % whether the format supports native in-memory I/O, and a brief |
273 | | % description of the format. |
274 | | % |
275 | | % The format of the RegisterTTFImage method is: |
276 | | % |
277 | | % RegisterTTFImage(void) |
278 | | % |
279 | | */ |
280 | | ModuleExport void RegisterTTFImage(void) |
281 | 5 | { |
282 | 5 | #if defined(FREETYPE_MAJOR) && defined(FREETYPE_MINOR) && defined(FREETYPE_PATCH) |
283 | | |
284 | 5 | static const char |
285 | 5 | version[] = "FreeType " DefineValueToString(FREETYPE_MAJOR) "." |
286 | 5 | DefineValueToString(FREETYPE_MINOR) "." DefineValueToString(FREETYPE_PATCH); |
287 | 5 | #define HAVE_TTF_VERSION 1 |
288 | 5 | #endif |
289 | | |
290 | 5 | MagickInfo |
291 | 5 | *entry; |
292 | | |
293 | | /* *version='\0'; */ |
294 | | /* #if defined(FREETYPE_MAJOR) && defined(FREETYPE_MINOR) && defined(FREETYPE_PATCH) */ |
295 | | /* FormatString(version,"FreeType %d.%d.%d",FREETYPE_MAJOR,FREETYPE_MINOR,FREETYPE_PATCH); */ |
296 | | /* #endif */ |
297 | | |
298 | 5 | entry=SetMagickInfo("TTF"); |
299 | 5 | #if defined(HasTTF) |
300 | 5 | entry->decoder=(DecoderHandler) ReadTTFImage; |
301 | 5 | #endif |
302 | 5 | entry->magick=(MagickHandler) IsTTF; |
303 | 5 | entry->adjoin=False; |
304 | 5 | entry->description="TrueType font"; |
305 | 5 | #if defined(HAVE_TTF_VERSION) |
306 | 5 | entry->version=version; |
307 | 5 | #endif |
308 | 5 | entry->module="TTF"; |
309 | 5 | entry->coder_class=PrimaryCoderClass; |
310 | 5 | (void) RegisterMagickInfo(entry); |
311 | | |
312 | 5 | entry=SetMagickInfo("PFA"); |
313 | 5 | #if defined(HasTTF) |
314 | 5 | entry->decoder=(DecoderHandler) ReadTTFImage; |
315 | 5 | #endif |
316 | 5 | entry->magick=(MagickHandler) IsPFA; |
317 | 5 | entry->adjoin=False; |
318 | 5 | entry->description="Postscript Type 1 font (ASCII)"; |
319 | 5 | #if defined(HAVE_TTF_VERSION) |
320 | 5 | entry->version=version; |
321 | 5 | #endif |
322 | 5 | entry->module="TTF"; |
323 | 5 | entry->coder_class=PrimaryCoderClass; |
324 | 5 | (void) RegisterMagickInfo(entry); |
325 | | |
326 | 5 | entry=SetMagickInfo("PFB"); |
327 | 5 | #if defined(HasTTF) |
328 | 5 | entry->decoder=(DecoderHandler) ReadTTFImage; |
329 | 5 | #endif |
330 | 5 | entry->magick=(MagickHandler) IsPFA; |
331 | 5 | entry->adjoin=False; |
332 | 5 | entry->description="Postscript Type 1 font (binary)"; |
333 | 5 | #if defined(HAVE_TTF_VERSION) |
334 | 5 | entry->version=version; |
335 | 5 | #endif |
336 | 5 | entry->module="TTF"; |
337 | 5 | entry->coder_class=PrimaryCoderClass; |
338 | 5 | (void) RegisterMagickInfo(entry); |
339 | 5 | } |
340 | | |
341 | | /* |
342 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
343 | | % % |
344 | | % % |
345 | | % % |
346 | | % U n r e g i s t e r T T F I m a g e % |
347 | | % % |
348 | | % % |
349 | | % % |
350 | | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |
351 | | % |
352 | | % Method UnregisterTTFImage removes format registrations made by the |
353 | | % TTF module from the list of supported formats. |
354 | | % |
355 | | % The format of the UnregisterTTFImage method is: |
356 | | % |
357 | | % UnregisterTTFImage(void) |
358 | | % |
359 | | */ |
360 | | ModuleExport void UnregisterTTFImage(void) |
361 | 0 | { |
362 | 0 | (void) UnregisterMagickInfo("TTF"); |
363 | 0 | (void) UnregisterMagickInfo("PFA"); |
364 | 0 | (void) UnregisterMagickInfo("PFB"); |
365 | 0 | } |