MagickCore  7.1.0
type.c
Go to the documentation of this file.
1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 % %
4 % %
5 % %
6 % TTTTT Y Y PPPP EEEEE %
7 % T Y Y P P E %
8 % T Y PPPP EEE %
9 % T Y P E %
10 % T Y P EEEEE %
11 % %
12 % %
13 % MagickCore Image Type Methods %
14 % %
15 % Software Design %
16 % Cristy %
17 % May 2001 %
18 % %
19 % %
20 % Copyright 1999-2021 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/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/client.h"
45 #include "MagickCore/configure.h"
46 #include "MagickCore/draw.h"
47 #include "MagickCore/exception.h"
50 #include "MagickCore/linked-list.h"
51 #include "MagickCore/log.h"
52 #include "MagickCore/memory_.h"
54 #include "MagickCore/nt-feature.h"
56 #include "MagickCore/option.h"
57 #include "MagickCore/semaphore.h"
58 #include "MagickCore/splay-tree.h"
59 #include "MagickCore/string_.h"
61 #include "MagickCore/type.h"
63 #include "MagickCore/token.h"
64 #include "MagickCore/utility.h"
66 #include "MagickCore/xml-tree.h"
67 #if defined(MAGICKCORE_FONTCONFIG_DELEGATE)
68 # include "fontconfig/fontconfig.h"
69 #if (FC_VERSION < 20209)
70 #undef FC_WEIGHT_LIGHT
71 #define FC_WIDTH "width" /* Int */
72 #define FC_WIDTH_ULTRACONDENSED 50
73 #define FC_WIDTH_EXTRACONDENSED 63
74 #define FC_WIDTH_CONDENSED 75
75 #define FC_WIDTH_SEMICONDENSED 87
76 #define FC_WIDTH_NORMAL 100
77 #define FC_WIDTH_SEMIEXPANDED 113
78 #define FC_WIDTH_EXPANDED 125
79 #define FC_WIDTH_EXTRAEXPANDED 150
80 #define FC_WIDTH_ULTRAEXPANDED 200
81 
82 #define FC_WEIGHT_THIN 0
83 #define FC_WEIGHT_EXTRALIGHT 40
84 #define FC_WEIGHT_ULTRALIGHT FC_WEIGHT_EXTRALIGHT
85 #define FC_WEIGHT_LIGHT 50
86 #define FC_WEIGHT_BOOK 75
87 #define FC_WEIGHT_REGULAR 80
88 #define FC_WEIGHT_NORMAL FC_WEIGHT_REGULAR
89 #define FC_WEIGHT_MEDIUM 100
90 #define FC_WEIGHT_DEMIBOLD 180
91 #define FC_WEIGHT_SEMIBOLD FC_WEIGHT_DEMIBOLD
92 #define FC_WEIGHT_BOLD 200
93 #define FC_WEIGHT_EXTRABOLD 205
94 #define FC_WEIGHT_ULTRABOLD FC_WEIGHT_EXTRABOLD
95 #define FC_WEIGHT_BLACK 210
96 #define FC_WEIGHT_HEAVY FC_WEIGHT_BLACK
97 #endif
98 #endif
99 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
100 # include "MagickCore/nt-feature.h"
101 #endif
102 
103 /*
104  Define declarations.
105 */
106 #define MagickTypeFilename "type.xml"
107 
108 /*
109  Declare type map.
110 */
111 static const char
113  "<?xml version=\"1.0\"?>"
114  "<typemap>"
115  " <type stealth=\"True\" name=\"fixed\" family=\"helvetica\"/>"
116  " <type stealth=\"True\" name=\"helvetica\" family=\"helvetica\"/>"
117  "</typemap>";
118 
119 /*
120  Static declarations.
121 */
122 static SemaphoreInfo
124 
125 static SplayTreeInfo
127 
128 /*
129  Forward declarations.
130 */
131 static MagickBooleanType
133  LoadTypeCache(SplayTreeInfo *,const char *,const char *,const size_t,
134  ExceptionInfo *);
135 
136 /*
137 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
138 % %
139 % %
140 % %
141 % A c q u i r e T y p e S p l a y T r e e %
142 % %
143 % %
144 % %
145 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
146 %
147 % AcquireTypeCache() caches one or more type configuration files which
148 % provides a mapping between type attributes and a type name.
149 %
150 % The format of the AcquireTypeCache method is:
151 %
152 % SplayTreeInfo *AcquireTypeCache(const char *filename,
153 % ExceptionInfo *exception)
154 %
155 % A description of each parameter follows:
156 %
157 % o filename: the font file name.
158 %
159 % o exception: return any errors or warnings in this structure.
160 %
161 */
162 
163 static void *DestroyTypeNode(void *type_info)
164 {
165  TypeInfo
166  *p;
167 
168  p=(TypeInfo *) type_info;
169  if (p->path != (char *) NULL)
170  p->path=DestroyString(p->path);
171  if (p->name != (char *) NULL)
172  p->name=DestroyString(p->name);
173  if (p->description != (char *) NULL)
175  if (p->family != (char *) NULL)
176  p->family=DestroyString(p->family);
177  if (p->encoding != (char *) NULL)
179  if (p->foundry != (char *) NULL)
181  if (p->format != (char *) NULL)
182  p->format=DestroyString(p->format);
183  if (p->metrics != (char *) NULL)
185  if (p->glyphs != (char *) NULL)
186  p->glyphs=DestroyString(p->glyphs);
187  return(RelinquishMagickMemory(p));
188 }
189 
190 static SplayTreeInfo *AcquireTypeCache(const char *filename,
191  ExceptionInfo *exception)
192 {
194  *cache;
195 
196  cache=NewSplayTree(CompareSplayTreeString,(void *(*)(void *)) NULL,
198 #if !MAGICKCORE_ZERO_CONFIGURATION_SUPPORT
199  {
200  char
201  *font_path,
202  path[MagickPathExtent];
203 
204  const StringInfo
205  *option;
206 
208  *options;
209 
210  *path='\0';
211  options=GetConfigureOptions(filename,exception);
212  option=(const StringInfo *) GetNextValueInLinkedList(options);
213  while (option != (const StringInfo *) NULL)
214  {
216  (void) LoadTypeCache(cache,(const char *)
217  GetStringInfoDatum(option),GetStringInfoPath(option),0,exception);
218  option=(const StringInfo *) GetNextValueInLinkedList(options);
219  }
220  options=DestroyConfigureOptions(options);
221  font_path=GetEnvironmentValue("MAGICK_FONT_PATH");
222  if (font_path != (char *) NULL)
223  {
224  char
225  *xml;
226 
227  /*
228  Search MAGICK_FONT_PATH.
229  */
230  (void) FormatLocaleString(path,MagickPathExtent,"%s%s%s",font_path,
231  DirectorySeparator,filename);
232  xml=FileToString(path,~0UL,exception);
233  if (xml != (void *) NULL)
234  {
235  (void) LoadTypeCache(cache,xml,path,0,exception);
236  xml=DestroyString(xml);
237  }
238  font_path=DestroyString(font_path);
239  }
240  }
241 #endif
242  if (GetNumberOfNodesInSplayTree(cache) == 0)
243  (void) LoadTypeCache(cache,TypeMap,"built-in",0,exception);
244  return(cache);
245 }
246 
247 /*
248 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
249 % %
250 % %
251 % %
252 + G e t T y p e I n f o %
253 % %
254 % %
255 % %
256 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
257 %
258 % GetTypeInfo searches the type list for the specified name and if found
259 % returns attributes for that type.
260 %
261 % The format of the GetTypeInfo method is:
262 %
263 % const TypeInfo *GetTypeInfo(const char *name,ExceptionInfo *exception)
264 %
265 % A description of each parameter follows:
266 %
267 % o name: the type name.
268 %
269 % o exception: return any errors or warnings in this structure.
270 %
271 */
272 MagickExport const TypeInfo *GetTypeInfo(const char *name,
273  ExceptionInfo *exception)
274 {
275  assert(exception != (ExceptionInfo *) NULL);
276  if (IsTypeTreeInstantiated(exception) == MagickFalse)
277  return((const TypeInfo *) NULL);
278  if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
279  return((const TypeInfo *) GetRootValueFromSplayTree(type_cache));
280  return((const TypeInfo *) GetValueFromSplayTree(type_cache,name));
281 }
282 
283 /*
284 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
285 % %
286 % %
287 % %
288 + G e t T y p e I n f o B y F a m i l y %
289 % %
290 % %
291 % %
292 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
293 %
294 % GetTypeInfoByFamily() searches the type list for the specified family and if
295 % found returns attributes for that type.
296 %
297 % Type substitution and scoring algorithm contributed by Bob Friesenhahn.
298 %
299 % The format of the GetTypeInfoByFamily method is:
300 %
301 % const TypeInfo *GetTypeInfoByFamily(const char *family,
302 % const StyleType style,const StretchType stretch,
303 % const size_t weight,ExceptionInfo *exception)
304 %
305 % A description of each parameter follows:
306 %
307 % o family: the type family.
308 %
309 % o style: the type style.
310 %
311 % o stretch: the type stretch.
312 %
313 % o weight: the type weight.
314 %
315 % o exception: return any errors or warnings in this structure.
316 %
317 */
318 MagickExport const TypeInfo *GetTypeInfoByFamily(const char *family,
319  const StyleType style,const StretchType stretch,const size_t weight,
320  ExceptionInfo *exception)
321 {
322  typedef struct _Fontmap
323  {
324  const char
325  name[17],
326  substitute[10];
327  } Fontmap;
328 
329  const TypeInfo
330  *type_info;
331 
332  const TypeInfo
333  *p;
334 
335  ssize_t
336  i;
337 
338  ssize_t
339  range;
340 
341  static const Fontmap
342  fontmap[] =
343  {
344  { "fixed", "courier" },
345  { "modern","courier" },
346  { "monotype corsiva", "courier" },
347  { "news gothic", "helvetica" },
348  { "system", "courier" },
349  { "terminal", "courier" },
350  { "wingdings", "symbol" }
351  };
352 
353  size_t
354  font_weight,
355  max_score,
356  score;
357 
358  /*
359  Check for an exact type match.
360  */
361  (void) GetTypeInfo("*",exception);
362  if (type_cache == (SplayTreeInfo *) NULL)
363  return((TypeInfo *) NULL);
364  font_weight=(size_t) (weight == 0 ? 400 : weight);
367  type_info=(const TypeInfo *) NULL;
369  while (p != (const TypeInfo *) NULL)
370  {
371  if (p->family == (char *) NULL)
372  {
374  continue;
375  }
376  if (family == (const char *) NULL)
377  {
378  if ((LocaleCompare(p->family,"arial") != 0) &&
379  (LocaleCompare(p->family,"helvetica") != 0))
380  {
382  continue;
383  }
384  }
385  else
386  if (LocaleCompare(p->family,family) != 0)
387  {
389  continue;
390  }
391  if ((style != UndefinedStyle) && (style != AnyStyle) && (p->style != style))
392  {
394  continue;
395  }
396  if ((stretch != UndefinedStretch) && (stretch != AnyStretch) &&
397  (p->stretch != stretch))
398  {
400  continue;
401  }
402  if (p->weight != font_weight)
403  {
405  continue;
406  }
407  type_info=p;
408  break;
409  }
411  if (type_info != (const TypeInfo *) NULL)
412  return(type_info);
413  /*
414  Check for types in the same family.
415  */
416  max_score=0;
420  while (p != (const TypeInfo *) NULL)
421  {
422  if (p->family == (char *) NULL)
423  {
425  continue;
426  }
427  if (family == (const char *) NULL)
428  {
429  if ((LocaleCompare(p->family,"arial") != 0) &&
430  (LocaleCompare(p->family,"helvetica") != 0))
431  {
433  continue;
434  }
435  }
436  else
437  if (LocaleCompare(p->family,family) != 0)
438  {
440  continue;
441  }
442  score=0;
443  if ((style == UndefinedStyle) || (style == AnyStyle) || (p->style == style))
444  score+=32;
445  else
446  if (((style == ItalicStyle) || (style == ObliqueStyle)) &&
447  ((p->style == ItalicStyle) || (p->style == ObliqueStyle)))
448  score+=25;
449  score+=(16*(800-((ssize_t) MagickMax(MagickMin(font_weight,900),p->weight)-
450  (ssize_t) MagickMin(MagickMin(font_weight,900),p->weight))))/800;
451  if ((stretch == UndefinedStretch) || (stretch == AnyStretch))
452  score+=8;
453  else
454  {
455  range=(ssize_t) UltraExpandedStretch-(ssize_t) NormalStretch;
456  score+=(8*(range-((ssize_t) MagickMax(stretch,p->stretch)-
457  (ssize_t) MagickMin(stretch,p->stretch))))/range;
458  }
459  if (score > max_score)
460  {
461  max_score=score;
462  type_info=p;
463  }
465  }
467  if (type_info != (const TypeInfo *) NULL)
468  return(type_info);
469  /*
470  Check for table-based substitution match.
471  */
472  for (i=0; i < (ssize_t) (sizeof(fontmap)/sizeof(fontmap[0])); i++)
473  {
474  if (family == (const char *) NULL)
475  {
476  if ((LocaleCompare(fontmap[i].name,"arial") != 0) &&
477  (LocaleCompare(fontmap[i].name,"helvetica") != 0))
478  continue;
479  }
480  else
481  if (LocaleCompare(fontmap[i].name,family) != 0)
482  continue;
483  type_info=GetTypeInfoByFamily(fontmap[i].substitute,style,stretch,weight,
484  exception);
485  break;
486  }
487  if (type_info != (const TypeInfo *) NULL)
488  {
490  "FontSubstitutionRequired","`%s'",type_info->family);
491  return(type_info);
492  }
493  if (family != (const char *) NULL)
494  type_info=GetTypeInfoByFamily((const char *) NULL,style,stretch,weight,
495  exception);
496  return(type_info);
497 }
498 
499 /*
500 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
501 % %
502 % %
503 % %
504 % G e t T y p e I n f o L i s t %
505 % %
506 % %
507 % %
508 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
509 %
510 % GetTypeInfoList() returns any fonts that match the specified pattern.
511 %
512 % The format of the GetTypeInfoList function is:
513 %
514 % const TypeInfo **GetTypeInfoList(const char *pattern,
515 % size_t *number_fonts,ExceptionInfo *exception)
516 %
517 % A description of each parameter follows:
518 %
519 % o pattern: Specifies a pointer to a text string containing a pattern.
520 %
521 % o number_fonts: This integer returns the number of types in the list.
522 %
523 % o exception: return any errors or warnings in this structure.
524 %
525 */
526 
527 #if defined(__cplusplus) || defined(c_plusplus)
528 extern "C" {
529 #endif
530 
531 static int TypeInfoCompare(const void *x,const void *y)
532 {
533  const TypeInfo
534  **p,
535  **q;
536 
537  p=(const TypeInfo **) x,
538  q=(const TypeInfo **) y;
539  if (LocaleCompare((*p)->path,(*q)->path) == 0)
540  return(LocaleCompare((*p)->name,(*q)->name));
541  return(LocaleCompare((*p)->path,(*q)->path));
542 }
543 
544 #if defined(__cplusplus) || defined(c_plusplus)
545 }
546 #endif
547 
548 MagickExport const TypeInfo **GetTypeInfoList(const char *pattern,
549  size_t *number_fonts,ExceptionInfo *exception)
550 {
551  const TypeInfo
552  **fonts;
553 
554  const TypeInfo
555  *p;
556 
557  ssize_t
558  i;
559 
560  /*
561  Allocate type list.
562  */
563  assert(pattern != (char *) NULL);
564  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
565  assert(number_fonts != (size_t *) NULL);
566  *number_fonts=0;
567  p=GetTypeInfo("*",exception);
568  if (p == (const TypeInfo *) NULL)
569  return((const TypeInfo **) NULL);
570  fonts=(const TypeInfo **) AcquireQuantumMemory((size_t)
571  GetNumberOfNodesInSplayTree(type_cache)+1UL,sizeof(*fonts));
572  if (fonts == (const TypeInfo **) NULL)
573  return((const TypeInfo **) NULL);
574  /*
575  Generate type list.
576  */
580  for (i=0; p != (const TypeInfo *) NULL; )
581  {
582  if ((p->stealth == MagickFalse) &&
583  (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
584  fonts[i++]=p;
586  }
588  qsort((void *) fonts,(size_t) i,sizeof(*fonts),TypeInfoCompare);
589  fonts[i]=(TypeInfo *) NULL;
590  *number_fonts=(size_t) i;
591  return(fonts);
592 }
593 
594 /*
595 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
596 % %
597 % %
598 % %
599 % G e t T y p e L i s t %
600 % %
601 % %
602 % %
603 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
604 %
605 % GetTypeList() returns any fonts that match the specified pattern.
606 %
607 % The format of the GetTypeList function is:
608 %
609 % char **GetTypeList(const char *pattern,size_t *number_fonts,
610 % ExceptionInfo *exception)
611 %
612 % A description of each parameter follows:
613 %
614 % o pattern: Specifies a pointer to a text string containing a pattern.
615 %
616 % o number_fonts: This integer returns the number of fonts in the list.
617 %
618 % o exception: return any errors or warnings in this structure.
619 %
620 */
621 
622 #if defined(__cplusplus) || defined(c_plusplus)
623 extern "C" {
624 #endif
625 
626 static int TypeCompare(const void *x,const void *y)
627 {
628  const char
629  **p,
630  **q;
631 
632  p=(const char **) x;
633  q=(const char **) y;
634  return(LocaleCompare(*p,*q));
635 }
636 
637 #if defined(__cplusplus) || defined(c_plusplus)
638 }
639 #endif
640 
641 MagickExport char **GetTypeList(const char *pattern,size_t *number_fonts,
642  ExceptionInfo *exception)
643 {
644  char
645  **fonts;
646 
647  const TypeInfo
648  *p;
649 
650  ssize_t
651  i;
652 
653  /*
654  Allocate type list.
655  */
656  assert(pattern != (char *) NULL);
657  (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
658  assert(number_fonts != (size_t *) NULL);
659  *number_fonts=0;
660  p=GetTypeInfo("*",exception);
661  if (p == (const TypeInfo *) NULL)
662  return((char **) NULL);
663  fonts=(char **) AcquireQuantumMemory((size_t)
664  GetNumberOfNodesInSplayTree(type_cache)+1UL,sizeof(*fonts));
665  if (fonts == (char **) NULL)
666  return((char **) NULL);
667  /*
668  Generate type list.
669  */
673  for (i=0; p != (const TypeInfo *) NULL; )
674  {
675  if ((p->stealth == MagickFalse) &&
676  (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
677  fonts[i++]=ConstantString(p->name);
679  }
681  qsort((void *) fonts,(size_t) i,sizeof(*fonts),TypeCompare);
682  fonts[i]=(char *) NULL;
683  *number_fonts=(size_t) i;
684  return(fonts);
685 }
686 
687 /*
688 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
689 % %
690 % %
691 % %
692 + I s T y p e T r e e I n s t a n t i a t e d %
693 % %
694 % %
695 % %
696 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
697 %
698 % IsTypeTreeInstantiated() determines if the type tree is instantiated. If
699 % not, it instantiates the tree and returns it.
700 %
701 % The format of the IsTypeInstantiated method is:
702 %
703 % MagickBooleanType IsTypeTreeInstantiated(ExceptionInfo *exception)
704 %
705 % A description of each parameter follows.
706 %
707 % o exception: return any errors or warnings in this structure.
708 %
709 */
710 
711 #if defined(MAGICKCORE_FONTCONFIG_DELEGATE)
713  ExceptionInfo *exception)
714 {
715 #if !defined(FC_FULLNAME)
716 #define FC_FULLNAME "fullname"
717 #endif
718 
719  char
720  extension[MagickPathExtent],
721  name[MagickPathExtent];
722 
723  FcBool
724  result;
725 
726  FcChar8
727  *family,
728  *file,
729  *fullname,
730  *style;
731 
732  FcConfig
733  *font_config;
734 
735  FcFontSet
736  *font_set;
737 
738  FcObjectSet
739  *object_set;
740 
741  FcPattern
742  *pattern;
743 
744  FcResult
745  status;
746 
747  int
748  slant,
749  width,
750  weight;
751 
752  ssize_t
753  i;
754 
755  TypeInfo
756  *type_info;
757 
758  /*
759  Load system fonts.
760  */
761  (void) exception;
762  result=FcInit();
763  if (result == 0)
764  return(MagickFalse);
765  font_config=FcConfigGetCurrent();
766  if (font_config == (FcConfig *) NULL)
767  return(MagickFalse);
768  FcConfigSetRescanInterval(font_config,0);
769  font_set=(FcFontSet *) NULL;
770  object_set=FcObjectSetBuild(FC_FULLNAME,FC_FAMILY,FC_STYLE,FC_SLANT,
771  FC_WIDTH,FC_WEIGHT,FC_FILE,(char *) NULL);
772  if (object_set != (FcObjectSet *) NULL)
773  {
774  pattern=FcPatternCreate();
775  if (pattern != (FcPattern *) NULL)
776  {
777  font_set=FcFontList(font_config,pattern,object_set);
778  FcPatternDestroy(pattern);
779  }
780  FcObjectSetDestroy(object_set);
781  }
782  if (font_set == (FcFontSet *) NULL)
783  {
784  FcConfigDestroy(font_config);
785  return(MagickFalse);
786  }
787  for (i=0; i < (ssize_t) font_set->nfont; i++)
788  {
789  status=FcPatternGetString(font_set->fonts[i],FC_FAMILY,0,&family);
790  if (status != FcResultMatch)
791  continue;
792  status=FcPatternGetString(font_set->fonts[i],FC_FILE,0,&file);
793  if (status != FcResultMatch)
794  continue;
795  *extension='\0';
796  GetPathComponent((const char *) file,ExtensionPath,extension);
797  if ((*extension != '\0') && (LocaleCompare(extension,"gz") == 0))
798  continue;
799  type_info=(TypeInfo *) AcquireMagickMemory(sizeof(*type_info));
800  if (type_info == (TypeInfo *) NULL)
801  continue;
802  (void) memset(type_info,0,sizeof(*type_info));
803  type_info->path=ConstantString("System Fonts");
804  type_info->signature=MagickCoreSignature;
805  (void) CopyMagickString(name,"Unknown",MagickPathExtent);
806  status=FcPatternGetString(font_set->fonts[i],FC_FULLNAME,0,&fullname);
807  if ((status == FcResultMatch) && (fullname != (FcChar8 *) NULL))
808  (void) CopyMagickString(name,(const char *) fullname,MagickPathExtent);
809  else
810  {
811  if (family != (FcChar8 *) NULL)
812  (void) CopyMagickString(name,(const char *) family,MagickPathExtent);
813  status=FcPatternGetString(font_set->fonts[i],FC_STYLE,0,&style);
814  if ((status == FcResultMatch) && (style != (FcChar8 *) NULL) &&
815  (LocaleCompare((const char *) style,"Regular") != 0))
816  {
817  (void) ConcatenateMagickString(name," ",MagickPathExtent);
818  (void) ConcatenateMagickString(name,(const char *) style,
820  }
821  }
822  type_info->name=ConstantString(name);
823  (void) SubstituteString(&type_info->name," ","-");
824  type_info->family=ConstantString((const char *) family);
825  status=FcPatternGetInteger(font_set->fonts[i],FC_SLANT,0,&slant);
826  type_info->style=NormalStyle;
827  if (slant == FC_SLANT_ITALIC)
828  type_info->style=ItalicStyle;
829  if (slant == FC_SLANT_OBLIQUE)
830  type_info->style=ObliqueStyle;
831  status=FcPatternGetInteger(font_set->fonts[i],FC_WIDTH,0,&width);
832  type_info->stretch=NormalStretch;
833  if (width >= FC_WIDTH_ULTRACONDENSED)
834  type_info->stretch=UltraCondensedStretch;
835  if (width >= FC_WIDTH_EXTRACONDENSED)
836  type_info->stretch=ExtraCondensedStretch;
837  if (width >= FC_WIDTH_CONDENSED)
838  type_info->stretch=CondensedStretch;
839  if (width >= FC_WIDTH_SEMICONDENSED)
840  type_info->stretch=SemiCondensedStretch;
841  if (width >= FC_WIDTH_NORMAL)
842  type_info->stretch=NormalStretch;
843  if (width >= FC_WIDTH_SEMIEXPANDED)
844  type_info->stretch=SemiExpandedStretch;
845  if (width >= FC_WIDTH_EXPANDED)
846  type_info->stretch=ExpandedStretch;
847  if (width >= FC_WIDTH_EXTRAEXPANDED)
848  type_info->stretch=ExtraExpandedStretch;
849  if (width >= FC_WIDTH_ULTRAEXPANDED)
850  type_info->stretch=UltraExpandedStretch;
851  type_info->weight=400;
852  status=FcPatternGetInteger(font_set->fonts[i],FC_WEIGHT,0,&weight);
853  if (weight >= FC_WEIGHT_THIN)
854  type_info->weight=100;
855  if (weight >= FC_WEIGHT_EXTRALIGHT)
856  type_info->weight=200;
857  if (weight >= FC_WEIGHT_LIGHT)
858  type_info->weight=300;
859  if (weight >= FC_WEIGHT_NORMAL)
860  type_info->weight=400;
861  if (weight >= FC_WEIGHT_MEDIUM)
862  type_info->weight=500;
863  if (weight >= FC_WEIGHT_DEMIBOLD)
864  type_info->weight=600;
865  if (weight >= FC_WEIGHT_BOLD)
866  type_info->weight=700;
867  if (weight >= FC_WEIGHT_EXTRABOLD)
868  type_info->weight=800;
869  if (weight >= FC_WEIGHT_BLACK)
870  type_info->weight=900;
871  type_info->glyphs=ConstantString((const char *) file);
872  (void) AddValueToSplayTree(type_cache,type_info->name,type_info);
873  }
874  FcFontSetDestroy(font_set);
875  FcConfigDestroy(font_config);
876  return(MagickTrue);
877 }
878 #endif
879 
881 {
882  if (type_cache == (SplayTreeInfo *) NULL)
883  {
884  if (type_semaphore == (SemaphoreInfo *) NULL)
887  if (type_cache == (SplayTreeInfo *) NULL)
888  {
890  *splay_tree;
891 
892  splay_tree=AcquireTypeCache(MagickTypeFilename,exception);
893 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
894  (void) NTAcquireTypeCache(splay_tree,exception);
895 #endif
896 #if defined(MAGICKCORE_FONTCONFIG_DELEGATE)
897  (void) LoadFontConfigFonts(splay_tree,exception);
898 #endif
899  type_cache=splay_tree;
900  }
902  }
903  return(type_cache != (SplayTreeInfo *) NULL ? MagickTrue : MagickFalse);
904 }
905 
906 /*
907 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
908 % %
909 % %
910 % %
911 % L i s t T y p e I n f o %
912 % %
913 % %
914 % %
915 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
916 %
917 % ListTypeInfo() lists the fonts to a file.
918 %
919 % The format of the ListTypeInfo method is:
920 %
921 % MagickBooleanType ListTypeInfo(FILE *file,ExceptionInfo *exception)
922 %
923 % A description of each parameter follows.
924 %
925 % o file: An pointer to a FILE.
926 %
927 % o exception: return any errors or warnings in this structure.
928 %
929 */
931 {
932  char
933  weight[MagickPathExtent];
934 
935  const char
936  *family,
937  *glyphs,
938  *name,
939  *path,
940  *stretch,
941  *style;
942 
943  const TypeInfo
944  **type_info;
945 
946  ssize_t
947  i;
948 
949  size_t
950  number_fonts;
951 
952  if (file == (FILE *) NULL)
953  file=stdout;
954  number_fonts=0;
955  type_info=GetTypeInfoList("*",&number_fonts,exception);
956  if (type_info == (const TypeInfo **) NULL)
957  return(MagickFalse);
958  *weight='\0';
959  path=(const char *) NULL;
960  for (i=0; i < (ssize_t) number_fonts; i++)
961  {
962  if (type_info[i]->stealth != MagickFalse)
963  continue;
964  if (((path == (const char *) NULL) ||
965  (LocaleCompare(path,type_info[i]->path) != 0)) &&
966  (type_info[i]->path != (char *) NULL))
967  (void) FormatLocaleFile(file,"\nPath: %s\n",type_info[i]->path);
968  path=type_info[i]->path;
969  name="unknown";
970  if (type_info[i]->name != (char *) NULL)
971  name=type_info[i]->name;
972  family="unknown";
973  if (type_info[i]->family != (char *) NULL)
974  family=type_info[i]->family;
975  style=CommandOptionToMnemonic(MagickStyleOptions,type_info[i]->style);
976  stretch=CommandOptionToMnemonic(MagickStretchOptions,type_info[i]->stretch);
977  glyphs="unknown";
978  if (type_info[i]->glyphs != (char *) NULL)
979  glyphs=type_info[i]->glyphs;
980  (void) FormatLocaleString(weight,MagickPathExtent,"%.20g",(double)
981  type_info[i]->weight);
982  (void) FormatLocaleFile(file," Font: %s\n",name);
983  (void) FormatLocaleFile(file," family: %s\n",family);
984  (void) FormatLocaleFile(file," style: %s\n",style);
985  (void) FormatLocaleFile(file," stretch: %s\n",stretch);
986  (void) FormatLocaleFile(file," weight: %s\n",weight);
987  (void) FormatLocaleFile(file," glyphs: %s\n",glyphs);
988  }
989  (void) fflush(file);
990  type_info=(const TypeInfo **) RelinquishMagickMemory((void *) type_info);
991  return(MagickTrue);
992 }
993 
994 /*
995 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
996 % %
997 % %
998 % %
999 + L o a d T y p e C a c h e %
1000 % %
1001 % %
1002 % %
1003 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1004 %
1005 % LoadTypeCache() loads the type configurations which provides a mapping
1006 % between type attributes and a type name.
1007 %
1008 % The format of the LoadTypeCache method is:
1009 %
1010 % MagickBooleanType LoadTypeCache(SplayTreeInfo *cache,const char *xml,
1011 % const char *filename,const size_t depth,ExceptionInfo *exception)
1012 %
1013 % A description of each parameter follows:
1014 %
1015 % o xml: The type list in XML format.
1016 %
1017 % o filename: The type list filename.
1018 %
1019 % o depth: depth of <include /> statements.
1020 %
1021 % o exception: return any errors or warnings in this structure.
1022 %
1023 */
1024 
1025 static inline MagickBooleanType SetTypeNodePath(const char *filename,
1026  char *font_path,const char *token,char **target)
1027 {
1028  char
1029  *path;
1030 
1031  path=ConstantString(token);
1032 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
1033  if (strchr(path,'@') != (char *) NULL)
1034  SubstituteString(&path,"@ghostscript_font_path@",font_path);
1035 #endif
1036  if (IsPathAccessible(path) == MagickFalse)
1037  {
1038  /*
1039  Relative path.
1040  */
1041  path=DestroyString(path);
1042  GetPathComponent(filename,HeadPath,font_path);
1045  (void) ConcatenateMagickString(font_path,token,MagickPathExtent);
1046  path=ConstantString(font_path);
1047 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
1048  if (strchr(path,'@') != (char *) NULL)
1049  SubstituteString(&path,"@ghostscript_font_path@","");
1050 #endif
1051  if (IsPathAccessible(path) == MagickFalse)
1052  {
1053  path=DestroyString(path);
1054  return(MagickFalse);
1055  }
1056  }
1057 
1058  *target=path;
1059  return(MagickTrue);
1060 }
1061 
1062 static MagickBooleanType LoadTypeCache(SplayTreeInfo *cache,const char *xml,
1063  const char *filename,const size_t depth,ExceptionInfo *exception)
1064 {
1065  char
1066  font_path[MagickPathExtent],
1067  keyword[MagickPathExtent],
1068  *token;
1069 
1070  const char
1071  *q;
1072 
1074  status;
1075 
1076  size_t
1077  extent;
1078 
1079  TypeInfo
1080  *type_info;
1081 
1082  /*
1083  Load the type map file.
1084  */
1086  "Loading type configure file \"%s\" ...",filename);
1087  if (xml == (const char *) NULL)
1088  return(MagickFalse);
1089  status=MagickTrue;
1090  type_info=(TypeInfo *) NULL;
1091  token=AcquireString(xml);
1092  extent=strlen(token)+MagickPathExtent;
1093 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
1094  /*
1095  Determine the Ghostscript font path.
1096  */
1097  *font_path='\0';
1098  if (NTGhostscriptFonts(font_path,MagickPathExtent-2))
1100 #endif
1101  for (q=(char *) xml; *q != '\0'; )
1102  {
1103  /*
1104  Interpret XML.
1105  */
1106  (void) GetNextToken(q,&q,extent,token);
1107  if (*token == '\0')
1108  break;
1109  (void) CopyMagickString(keyword,token,MagickPathExtent);
1110  if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
1111  {
1112  /*
1113  Doctype element.
1114  */
1115  while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
1116  (void) GetNextToken(q,&q,extent,token);
1117  continue;
1118  }
1119  if (LocaleNCompare(keyword,"<!--",4) == 0)
1120  {
1121  /*
1122  Comment element.
1123  */
1124  while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
1125  (void) GetNextToken(q,&q,extent,token);
1126  continue;
1127  }
1128  if (LocaleCompare(keyword,"<include") == 0)
1129  {
1130  /*
1131  Include element.
1132  */
1133  while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0'))
1134  {
1135  (void) CopyMagickString(keyword,token,MagickPathExtent);
1136  (void) GetNextToken(q,&q,extent,token);
1137  if (*token != '=')
1138  continue;
1139  (void) GetNextToken(q,&q,extent,token);
1140  if (LocaleCompare(keyword,"file") == 0)
1141  {
1142  if (depth > MagickMaxRecursionDepth)
1143  (void) ThrowMagickException(exception,GetMagickModule(),
1144  ConfigureError,"IncludeNodeNestedTooDeeply","`%s'",token);
1145  else
1146  {
1147  char
1148  path[MagickPathExtent],
1149  *file_xml;
1150 
1152  *sans_exception;
1153 
1154  *path='\0';
1155  GetPathComponent(filename,HeadPath,path);
1156  if (*path != '\0')
1159  if (*token == *DirectorySeparator)
1160  (void) CopyMagickString(path,token,MagickPathExtent);
1161  else
1162  (void) ConcatenateMagickString(path,token,MagickPathExtent);
1163  sans_exception=AcquireExceptionInfo();
1164  file_xml=FileToString(path,~0UL,sans_exception);
1165  sans_exception=DestroyExceptionInfo(sans_exception);
1166  if (file_xml != (char *) NULL)
1167  {
1168  status&=LoadTypeCache(cache,file_xml,path,depth+1,
1169  exception);
1170  file_xml=(char *) RelinquishMagickMemory(file_xml);
1171  }
1172  }
1173  }
1174  }
1175  continue;
1176  }
1177  if (LocaleCompare(keyword,"<type") == 0)
1178  {
1179  /*
1180  Type element.
1181  */
1182  type_info=(TypeInfo *) AcquireCriticalMemory(sizeof(*type_info));
1183  (void) memset(type_info,0,sizeof(*type_info));
1184  type_info->path=ConstantString(filename);
1185  type_info->signature=MagickCoreSignature;
1186  continue;
1187  }
1188  if (type_info == (TypeInfo *) NULL)
1189  continue;
1190  if ((LocaleCompare(keyword,"/>") == 0) ||
1191  (LocaleCompare(keyword,"</policy>") == 0))
1192  {
1193  status=AddValueToSplayTree(cache,type_info->name,type_info);
1194  if (status == MagickFalse)
1195  (void) ThrowMagickException(exception,GetMagickModule(),
1196  ResourceLimitError,"MemoryAllocationFailed","`%s'",type_info->name);
1197  type_info=(TypeInfo *) NULL;
1198  continue;
1199  }
1200  (void) GetNextToken(q,(const char **) NULL,extent,token);
1201  if (*token != '=')
1202  continue;
1203  (void) GetNextToken(q,&q,extent,token);
1204  (void) GetNextToken(q,&q,extent,token);
1205  switch (*keyword)
1206  {
1207  case 'E':
1208  case 'e':
1209  {
1210  if (LocaleCompare((char *) keyword,"encoding") == 0)
1211  {
1212  type_info->encoding=ConstantString(token);
1213  break;
1214  }
1215  break;
1216  }
1217  case 'F':
1218  case 'f':
1219  {
1220  if (LocaleCompare((char *) keyword,"face") == 0)
1221  {
1222  type_info->face=StringToUnsignedLong(token);
1223  break;
1224  }
1225  if (LocaleCompare((char *) keyword,"family") == 0)
1226  {
1227  type_info->family=ConstantString(token);
1228  break;
1229  }
1230  if (LocaleCompare((char *) keyword,"format") == 0)
1231  {
1232  type_info->format=ConstantString(token);
1233  break;
1234  }
1235  if (LocaleCompare((char *) keyword,"foundry") == 0)
1236  {
1237  type_info->foundry=ConstantString(token);
1238  break;
1239  }
1240  if (LocaleCompare((char *) keyword,"fullname") == 0)
1241  {
1242  type_info->description=ConstantString(token);
1243  break;
1244  }
1245  break;
1246  }
1247  case 'G':
1248  case 'g':
1249  {
1250  if (LocaleCompare((char *) keyword,"glyphs") == 0)
1251  {
1252  if (SetTypeNodePath(filename,font_path,token,&type_info->glyphs) ==
1253  MagickFalse)
1254  type_info=(TypeInfo *) DestroyTypeNode(type_info);
1255  break;
1256  }
1257  break;
1258  }
1259  case 'M':
1260  case 'm':
1261  {
1262  if (LocaleCompare((char *) keyword,"metrics") == 0)
1263  {
1264  if (SetTypeNodePath(filename,font_path,token,&type_info->metrics) ==
1265  MagickFalse)
1266  type_info=(TypeInfo *) DestroyTypeNode(type_info);
1267  break;
1268  }
1269  break;
1270  }
1271  case 'N':
1272  case 'n':
1273  {
1274  if (LocaleCompare((char *) keyword,"name") == 0)
1275  {
1276  type_info->name=ConstantString(token);
1277  break;
1278  }
1279  break;
1280  }
1281  case 'S':
1282  case 's':
1283  {
1284  if (LocaleCompare((char *) keyword,"stealth") == 0)
1285  {
1286  type_info->stealth=IsStringTrue(token);
1287  break;
1288  }
1289  if (LocaleCompare((char *) keyword,"stretch") == 0)
1290  {
1291  type_info->stretch=(StretchType) ParseCommandOption(
1293  break;
1294  }
1295  if (LocaleCompare((char *) keyword,"style") == 0)
1296  {
1298  MagickFalse,token);
1299  break;
1300  }
1301  break;
1302  }
1303  case 'W':
1304  case 'w':
1305  {
1306  if (LocaleCompare((char *) keyword,"weight") == 0)
1307  {
1308  ssize_t
1309  weight;
1310 
1312  if (weight == -1)
1313  weight=(ssize_t) StringToUnsignedLong(token);
1314  type_info->weight=(size_t) weight;
1315  break;
1316  }
1317  break;
1318  }
1319  default:
1320  break;
1321  }
1322  }
1323  token=(char *) RelinquishMagickMemory(token);
1324  return(status != 0 ? MagickTrue : MagickFalse);
1325 }
1326 
1327 /*
1328 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1329 % %
1330 % %
1331 % %
1332 + T y p e C o m p o n e n t G e n e s i s %
1333 % %
1334 % %
1335 % %
1336 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1337 %
1338 % TypeComponentGenesis() instantiates the type component.
1339 %
1340 % The format of the TypeComponentGenesis method is:
1341 %
1342 % MagickBooleanType TypeComponentGenesis(void)
1343 %
1344 */
1346 {
1347  if (type_semaphore == (SemaphoreInfo *) NULL)
1349  return(MagickTrue);
1350 }
1351 
1352 /*
1353 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1354 % %
1355 % %
1356 % %
1357 + T y p e C o m p o n e n t T e r m i n u s %
1358 % %
1359 % %
1360 % %
1361 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1362 %
1363 % TypeComponentTerminus() destroy type component.
1364 %
1365 % The format of the TypeComponentTerminus method is:
1366 %
1367 % void TypeComponentTerminus(void)
1368 %
1369 */
1371 {
1372  if (type_semaphore == (SemaphoreInfo *) NULL)
1375  if (type_cache != (SplayTreeInfo *) NULL)
1379 }
static SemaphoreInfo * type_semaphore
Definition: type.c:123
size_t face
Definition: type.h:53
#define MagickMaxRecursionDepth
Definition: studio.h:349
MagickExport MagickBooleanType AddValueToSplayTree(SplayTreeInfo *splay_tree, const void *key, const void *value)
Definition: splay-tree.c:154
StyleType
Definition: type.h:40
MagickExport size_t ConcatenateMagickString(char *magick_restrict destination, const char *magick_restrict source, const size_t length)
Definition: string.c:392
MagickExport void UnlockSemaphoreInfo(SemaphoreInfo *semaphore_info)
Definition: semaphore.c:449
static unsigned long StringToUnsignedLong(const char *magick_restrict value)
#define MagickTypeFilename
Definition: type.c:106
MagickExport ssize_t ParseCommandOption(const CommandOption option, const MagickBooleanType list, const char *options)
Definition: option.c:3055
MagickExport const TypeInfo * GetTypeInfo(const char *name, ExceptionInfo *exception)
Definition: type.c:272
char * description
Definition: type.h:56
char * metrics
Definition: type.h:71
MagickExport SemaphoreInfo * AcquireSemaphoreInfo(void)
Definition: semaphore.c:192
static SplayTreeInfo * type_cache
Definition: type.c:126
MagickPrivate MagickBooleanType TypeComponentGenesis(void)
Definition: type.c:1345
MagickExport MagickBooleanType ListTypeInfo(FILE *file, ExceptionInfo *exception)
Definition: type.c:930
static MagickBooleanType IsTypeTreeInstantiated(ExceptionInfo *)
Definition: type.c:880
MagickExport ExceptionInfo * AcquireExceptionInfo(void)
Definition: exception.c:115
MagickExport ssize_t FormatLocaleString(char *magick_restrict string, const size_t length, const char *magick_restrict format,...)
Definition: locale.c:463
MagickExport size_t CopyMagickString(char *magick_restrict destination, const char *magick_restrict source, const size_t length)
Definition: string.c:731
char * path
Definition: type.h:56
size_t weight
Definition: type.h:68
Definition: log.h:52
MagickExport char * FileToString(const char *filename, const size_t extent, ExceptionInfo *exception)
Definition: string.c:965
char * foundry
Definition: type.h:71
MagickExport void * GetNextValueInLinkedList(LinkedListInfo *list_info)
Definition: linked-list.c:305
static SplayTreeInfo * AcquireTypeCache(const char *filename, ExceptionInfo *exception)
Definition: type.c:190
MagickExport const void * GetNextValueInSplayTree(SplayTreeInfo *splay_tree)
Definition: splay-tree.c:823
MagickPrivate void TypeComponentTerminus(void)
Definition: type.c:1370
#define MagickCoreSignature
MagickExport void LockSemaphoreInfo(SemaphoreInfo *semaphore_info)
Definition: semaphore.c:293
MagickExport unsigned char * GetStringInfoDatum(const StringInfo *string_info)
Definition: string.c:1176
MagickExport char ** GetTypeList(const char *pattern, size_t *number_fonts, ExceptionInfo *exception)
Definition: type.c:641
MagickExport LinkedListInfo * GetConfigureOptions(const char *filename, ExceptionInfo *exception)
Definition: configure.c:642
MagickExport void GetPathComponent(const char *path, PathType type, char *component)
Definition: utility.c:1221
MagickExport ssize_t FormatLocaleFile(FILE *file, const char *magick_restrict format,...)
Definition: locale.c:368
MagickBooleanType
Definition: magick-type.h:165
#define DirectorySeparator
Definition: studio.h:264
unsigned int MagickStatusType
Definition: magick-type.h:125
MagickExport char * AcquireString(const char *source)
Definition: string.c:94
char * family
Definition: type.h:56
MagickExport MagickBooleanType GlobExpression(const char *magick_restrict expression, const char *magick_restrict pattern, const MagickBooleanType case_insensitive)
Definition: token.c:352
MagickExport const char * CommandOptionToMnemonic(const CommandOption option, const ssize_t type)
Definition: option.c:2764
MagickExport void * AcquireCriticalMemory(const size_t size)
Definition: memory.c:626
MagickExport void * AcquireQuantumMemory(const size_t count, const size_t quantum)
Definition: memory.c:665
MagickExport int LocaleNCompare(const char *p, const char *q, const size_t length)
Definition: locale.c:1523
StretchType stretch
Definition: type.h:65
MagickExport magick_hot_spot size_t GetNextToken(const char *magick_restrict start, const char **magick_restrict end, const size_t extent, char *magick_restrict token)
Definition: token.c:174
StretchType
Definition: type.h:25
MagickExport MagickBooleanType NTAcquireTypeCache(SplayTreeInfo *, ExceptionInfo *)
MagickExport SplayTreeInfo * DestroySplayTree(SplayTreeInfo *splay_tree)
Definition: splay-tree.c:682
#define MagickPathExtent
static void * DestroyTypeNode(void *type_info)
Definition: type.c:163
char * glyphs
Definition: type.h:71
MagickExport MagickBooleanType IsStringTrue(const char *value)
Definition: string.c:1386
Definition: type.h:50
static const char TypeMap[]
Definition: type.c:112
MagickExport SplayTreeInfo * NewSplayTree(int(*compare)(const void *, const void *), void *(*relinquish_key)(void *), void *(*relinquish_value)(void *))
Definition: splay-tree.c:1141
static MagickBooleanType SetTypeNodePath(const char *filename, char *font_path, const char *token, char **target)
Definition: type.c:1025
char * format
Definition: type.h:71
MagickExport MagickBooleanType ThrowMagickException(ExceptionInfo *exception, const char *module, const char *function, const size_t line, const ExceptionType severity, const char *tag, const char *format,...)
Definition: exception.c:1145
MagickExport MagickBooleanType LogMagickEvent(const LogEventType type, const char *module, const char *function, const size_t line, const char *format,...)
Definition: log.c:1660
MagickExport MagickBooleanType IsPathAccessible(const char *path)
Definition: utility.c:1492
MagickExport const TypeInfo * GetTypeInfoByFamily(const char *family, const StyleType style, const StretchType stretch, const size_t weight, ExceptionInfo *exception)
Definition: type.c:318
MagickExport MagickBooleanType SubstituteString(char **string, const char *search, const char *replace)
Definition: string.c:2583
MagickExport char * GetEnvironmentValue(const char *name)
Definition: string.c:1143
MagickBooleanType stealth
Definition: type.h:78
MagickExport const void * GetValueFromSplayTree(SplayTreeInfo *splay_tree, const void *key)
Definition: splay-tree.c:921
#define MagickMax(x, y)
Definition: image-private.h:36
MagickExport int LocaleCompare(const char *p, const char *q)
Definition: locale.c:1399
#define GetMagickModule()
Definition: log.h:28
MagickExport int CompareSplayTreeString(const void *target, const void *source)
Definition: splay-tree.c:412
MagickExport const char * GetStringInfoPath(const StringInfo *string_info)
Definition: string.c:1263
static int TypeInfoCompare(const void *x, const void *y)
Definition: type.c:531
static MagickBooleanType LoadTypeCache(SplayTreeInfo *, const char *, const char *, const size_t, ExceptionInfo *)
Definition: type.c:1062
MagickExport char * DestroyString(char *string)
Definition: string.c:788
MagickExport void * AcquireMagickMemory(const size_t size)
Definition: memory.c:552
MagickExport void ActivateSemaphoreInfo(SemaphoreInfo **semaphore_info)
Definition: semaphore.c:98
MagickExport const TypeInfo ** GetTypeInfoList(const char *pattern, size_t *number_fonts, ExceptionInfo *exception)
Definition: type.c:548
MagickExport const void * GetRootValueFromSplayTree(SplayTreeInfo *splay_tree)
Definition: splay-tree.c:877
#define MagickMin(x, y)
Definition: image-private.h:37
Definition: type.h:46
MagickExport void ResetSplayTreeIterator(SplayTreeInfo *splay_tree)
Definition: splay-tree.c:1472
MagickExport void * RelinquishMagickMemory(void *memory)
Definition: memory.c:1162
MagickExport size_t GetNumberOfNodesInSplayTree(const SplayTreeInfo *splay_tree)
Definition: splay-tree.c:976
static int TypeCompare(const void *x, const void *y)
Definition: type.c:626
char * encoding
Definition: type.h:71
size_t signature
Definition: type.h:81
#define MagickPrivate
#define MagickExport
StyleType style
Definition: type.h:62
MagickExport void RelinquishSemaphoreInfo(SemaphoreInfo **semaphore_info)
Definition: semaphore.c:351
MagickExport LinkedListInfo * DestroyConfigureOptions(LinkedListInfo *options)
Definition: configure.c:314
MagickExport char * ConstantString(const char *source)
Definition: string.c:678
char * name
Definition: type.h:56
MagickExport ExceptionInfo * DestroyExceptionInfo(ExceptionInfo *exception)
Definition: exception.c:418