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