2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
6 % TTTTT Y Y PPPP EEEEE %
13 % MagickCore Image Type Methods %
20 % Copyright 1999-2007 ImageMagick Studio LLC, a non-profit organization %
21 % dedicated to making software imaging solutions freely available. %
23 % You may not use this file except in compliance with the License. You may %
24 % obtain a copy of the License at %
26 % http://www.imagemagick.org/script/license.php %
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. %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
42 #include "magick/studio.h"
43 #include "magick/blob.h"
44 #include "magick/client.h"
45 #include "magick/configure.h"
46 #include "magick/draw.h"
47 #include "magick/exception.h"
48 #include "magick/exception-private.h"
49 #include "magick/hashmap.h"
50 #include "magick/log.h"
51 #include "magick/memory_.h"
52 #include "magick/option.h"
53 #include "magick/semaphore.h"
54 #include "magick/splay-tree.h"
55 #include "magick/string_.h"
56 #include "magick/type.h"
57 #include "magick/token.h"
58 #include "magick/utility.h"
59 #include "magick/xml-tree.h"
60 #if defined(MAGICKCORE_FONTCONFIG_DELEGATE)
61 # include "fontconfig/fontconfig.h"
62 #if (FC_VERSION < 20209)
63 #undef FC_WEIGHT_LIGHT
64 #define FC_WIDTH "width" /* Int */
65 #define FC_WIDTH_ULTRACONDENSED 50
66 #define FC_WIDTH_EXTRACONDENSED 63
67 #define FC_WIDTH_CONDENSED 75
68 #define FC_WIDTH_SEMICONDENSED 87
69 #define FC_WIDTH_NORMAL 100
70 #define FC_WIDTH_SEMIEXPANDED 113
71 #define FC_WIDTH_EXPANDED 125
72 #define FC_WIDTH_EXTRAEXPANDED 150
73 #define FC_WIDTH_ULTRAEXPANDED 200
75 #define FC_WEIGHT_THIN 0
76 #define FC_WEIGHT_EXTRALIGHT 40
77 #define FC_WEIGHT_ULTRALIGHT FC_WEIGHT_EXTRALIGHT
78 #define FC_WEIGHT_LIGHT 50
79 #define FC_WEIGHT_BOOK 75
80 #define FC_WEIGHT_REGULAR 80
81 #define FC_WEIGHT_NORMAL FC_WEIGHT_REGULAR
82 #define FC_WEIGHT_MEDIUM 100
83 #define FC_WEIGHT_DEMIBOLD 180
84 #define FC_WEIGHT_SEMIBOLD FC_WEIGHT_DEMIBOLD
85 #define FC_WEIGHT_BOLD 200
86 #define FC_WEIGHT_EXTRABOLD 205
87 #define FC_WEIGHT_ULTRABOLD FC_WEIGHT_EXTRABOLD
88 #define FC_WEIGHT_BLACK 210
89 #define FC_WEIGHT_HEAVY FC_WEIGHT_BLACK
92 #if defined(__WINDOWS__)
93 # include "magick/nt-feature.h"
99 #define MagickTypeFilename "type.xml"
105 *TypeMap = (const char *)
106 "<?xml version=\"1.0\"?>"
108 " <type stealth=\"True\" name=\"fixed\" family=\"helvetica\"/>"
109 " <type stealth=\"True\" name=\"helvetica\" family=\"helvetica\"/>"
116 *type_semaphore = (SemaphoreInfo *) NULL;
118 static volatile MagickBooleanType
119 instantiate_type = MagickFalse;
122 *type_list = (SplayTreeInfo *) NULL;
125 Forward declarations.
127 static MagickBooleanType
128 InitializeTypeList(ExceptionInfo *),
129 LoadTypeLists(const char *,ExceptionInfo *);
132 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
136 + G e t T y p e I n f o %
140 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
142 % GetTypeInfo searches the type list for the specified name and if found
143 % returns attributes for that type.
145 % The format of the GetTypeInfo method is:
147 % const TypeInfo *GetTypeInfo(const char *name,ExceptionInfo *exception)
149 % A description of each parameter follows:
151 % o name: the type name.
153 % o exception: return any errors or warnings in this structure.
156 MagickExport const TypeInfo *GetTypeInfo(const char *name,
157 ExceptionInfo *exception)
159 assert(exception != (ExceptionInfo *) NULL);
160 if ((type_list == (SplayTreeInfo *) NULL) ||
161 (instantiate_type == MagickFalse))
162 if (InitializeTypeList(exception) == MagickFalse)
163 return((const TypeInfo *) NULL);
164 if ((type_list == (SplayTreeInfo *) NULL) ||
165 (GetNumberOfNodesInSplayTree(type_list) == 0))
166 return((const TypeInfo *) NULL);
167 if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
169 ResetSplayTreeIterator(type_list);
170 return((const TypeInfo *) GetNextValueInSplayTree(type_list));
172 return((const TypeInfo *) GetValueFromSplayTree(type_list,name));
176 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
180 + G e t T y p e I n f o B y F a m i l y %
184 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
186 % GetTypeInfoByFamily() searches the type list for the specified family and if
187 % found returns attributes for that type.
189 % Type substitution and scoring algorithm contributed by Bob Friesenhahn.
191 % The format of the GetTypeInfoByFamily method is:
193 % const TypeInfo *GetTypeInfoByFamily(const char *family,
194 % const StyleType style,const StretchType stretch,
195 % const unsigned long weight,ExceptionInfo *exception)
197 % A description of each parameter follows:
199 % o family: the type family.
201 % o style: the type style.
203 % o stretch: the type stretch.
205 % o weight: the type weight.
207 % o exception: return any errors or warnings in this structure.
211 static inline unsigned long MagickMax(const unsigned long x,
212 const unsigned long y)
219 static inline unsigned long MagickMin(const unsigned long x,
220 const unsigned long y)
227 MagickExport const TypeInfo *GetTypeInfoByFamily(const char *family,
228 const StyleType style,const StretchType stretch,const unsigned long weight,
229 ExceptionInfo *exception)
231 typedef struct _Fontmap
244 register const TypeInfo
253 { "fixed", "courier" },
254 { "modern","courier" },
255 { "monotype corsiva", "courier" },
256 { "news gothic", "helvetica" },
257 { "system", "courier" },
258 { "terminal", "courier" },
259 { "wingdings", "symbol" },
268 Check for an exact type match.
270 (void) GetTypeInfo("*",exception);
271 if (type_list == (SplayTreeInfo *) NULL)
272 return((TypeInfo *) NULL);
273 (void) LockSemaphoreInfo(type_semaphore);
274 ResetSplayTreeIterator(type_list);
275 type_info=(const TypeInfo *) NULL;
276 p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
277 while (p != (const TypeInfo *) NULL)
279 if (p->family == (char *) NULL)
281 p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
284 if (family == (const char *) NULL)
286 if ((LocaleCompare(p->family,"arial") != 0) &&
287 (LocaleCompare(p->family,"helvetica") != 0))
289 p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
294 if (LocaleCompare(p->family,family) != 0)
296 p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
299 if ((style != UndefinedStyle) && (style != AnyStyle) && (p->style != style))
301 p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
304 if ((stretch != UndefinedStretch) && (stretch != AnyStretch) &&
305 (p->stretch != stretch))
307 p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
310 if ((weight != 0) && (p->weight != weight))
312 p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
318 (void) UnlockSemaphoreInfo(type_semaphore);
319 if (type_info != (const TypeInfo *) NULL)
322 Check for types in the same family.
325 (void) LockSemaphoreInfo(type_semaphore);
326 ResetSplayTreeIterator(type_list);
327 p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
328 while (p != (const TypeInfo *) NULL)
330 if (p->family == (char *) NULL)
332 p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
335 if (family == (const char *) NULL)
337 if ((LocaleCompare(p->family,"arial") != 0) &&
338 (LocaleCompare(p->family,"helvetica") != 0))
340 p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
345 if (LocaleCompare(p->family,family) != 0)
347 p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
351 if ((style == UndefinedStyle) || (style == AnyStyle) || (p->style == style))
354 if (((style == ItalicStyle) || (style == ObliqueStyle)) &&
355 ((p->style == ItalicStyle) || (p->style == ObliqueStyle)))
360 score+=(16*(800-((long) MagickMax(MagickMin(weight,900),p->weight)-
361 (long) MagickMin(MagickMin(weight,900),p->weight))))/800;
362 if ((stretch == UndefinedStretch) || (stretch == AnyStretch))
366 range=(long) UltraExpandedStretch-(long) NormalStretch;
367 score+=(8*(range-((long) MagickMax(stretch,p->stretch)-
368 (long) MagickMin(stretch,p->stretch))))/range;
370 if (score > max_score)
375 p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
377 (void) UnlockSemaphoreInfo(type_semaphore);
378 if (type_info != (const TypeInfo *) NULL)
381 Check for table-based substitution match.
383 for (i=0; fontmap[i].name != (char *) NULL; i++)
385 if (family == (const char *) NULL)
387 if ((LocaleCompare(fontmap[i].name,"arial") != 0) &&
388 (LocaleCompare(fontmap[i].name,"helvetica") != 0))
392 if (LocaleCompare(fontmap[i].name,family) != 0)
394 type_info=GetTypeInfoByFamily(fontmap[i].substitute,style,stretch,weight,
398 if (type_info != (const TypeInfo *) NULL)
400 (void) ThrowMagickException(exception,GetMagickModule(),TypeError,
401 "FontSubstitutionRequired","`%s'",type_info->family);
404 if (family != (const char *) NULL)
405 type_info=GetTypeInfoByFamily((const char *) NULL,style,stretch,weight,
411 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
415 % G e t T y p e I n f o L i s t %
419 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
421 % GetTypeInfoList() returns any fonts that match the specified pattern.
423 % The format of the GetTypeInfoList function is:
425 % const TypeInfo **GetTypeInfoList(const char *pattern,
426 % unsigned long *number_fonts,ExceptionInfo *exception)
428 % A description of each parameter follows:
430 % o pattern: Specifies a pointer to a text string containing a pattern.
432 % o number_fonts: This integer returns the number of types in the list.
434 % o exception: return any errors or warnings in this structure.
438 #if defined(__cplusplus) || defined(c_plusplus)
442 static int TypeInfoCompare(const void *x,const void *y)
448 p=(const TypeInfo **) x,
449 q=(const TypeInfo **) y;
450 if (LocaleCompare((*p)->path,(*q)->path) == 0)
451 return(LocaleCompare((*p)->name,(*q)->name));
452 return(LocaleCompare((*p)->path,(*q)->path));
455 #if defined(__cplusplus) || defined(c_plusplus)
459 MagickExport const TypeInfo **GetTypeInfoList(const char *pattern,
460 unsigned long *number_fonts,ExceptionInfo *exception)
465 register const TypeInfo
474 assert(pattern != (char *) NULL);
475 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
476 assert(number_fonts != (unsigned long *) NULL);
478 p=GetTypeInfo("*",exception);
479 if (p == (const TypeInfo *) NULL)
480 return((const TypeInfo **) NULL);
481 fonts=(const TypeInfo **) AcquireQuantumMemory((size_t)
482 GetNumberOfNodesInSplayTree(type_list)+1UL,sizeof(*fonts));
483 if (fonts == (const TypeInfo **) NULL)
484 return((const TypeInfo **) NULL);
488 (void) LockSemaphoreInfo(type_semaphore);
489 ResetSplayTreeIterator(type_list);
490 p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
491 for (i=0; p != (const TypeInfo *) NULL; )
493 if ((p->stealth == MagickFalse) &&
494 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
496 p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
498 (void) UnlockSemaphoreInfo(type_semaphore);
499 qsort((void *) fonts,(size_t) i,sizeof(*fonts),TypeInfoCompare);
500 fonts[i]=(TypeInfo *) NULL;
501 *number_fonts=(unsigned long) i;
506 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
510 % G e t T y p e L i s t %
514 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
516 % GetTypeList() returns any fonts that match the specified pattern.
518 % The format of the GetTypeList function is:
520 % char **GetTypeList(const char *pattern,unsigned long *number_fonts,
521 % ExceptionInfo *exception)
523 % A description of each parameter follows:
525 % o pattern: Specifies a pointer to a text string containing a pattern.
527 % o number_fonts: This integer returns the number of fonts in the list.
529 % o exception: return any errors or warnings in this structure.
533 #if defined(__cplusplus) || defined(c_plusplus)
537 static int TypeCompare(const void *x,const void *y)
545 return(LocaleCompare(*p,*q));
548 #if defined(__cplusplus) || defined(c_plusplus)
552 MagickExport char **GetTypeList(const char *pattern,unsigned long *number_fonts,
553 ExceptionInfo *exception)
558 register const TypeInfo
567 assert(pattern != (char *) NULL);
568 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
569 assert(number_fonts != (unsigned long *) NULL);
571 p=GetTypeInfo("*",exception);
572 if (p == (const TypeInfo *) NULL)
573 return((char **) NULL);
574 fonts=(char **) AcquireQuantumMemory((size_t)
575 GetNumberOfNodesInSplayTree(type_list)+1UL,sizeof(*fonts));
576 if (fonts == (char **) NULL)
577 return((char **) NULL);
581 (void) LockSemaphoreInfo(type_semaphore);
582 ResetSplayTreeIterator(type_list);
583 p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
584 for (i=0; p != (const TypeInfo *) NULL; )
586 if ((p->stealth == MagickFalse) &&
587 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
588 fonts[i++]=ConstantString(p->name);
589 p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
591 (void) UnlockSemaphoreInfo(type_semaphore);
592 qsort((void *) fonts,(size_t) i,sizeof(*fonts),TypeCompare);
593 fonts[i]=(char *) NULL;
594 *number_fonts=(unsigned long) i;
599 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
603 + I n i t i a l i z e T y p e L i s t %
607 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
609 % InitializeTypeList() initializes the type list.
611 % The format of the InitializeTypeList method is:
613 % MagickBooleanType InitializeTypeList(ExceptionInfo *exception)
615 % A description of each parameter follows.
617 % o exception: return any errors or warnings in this structure.
621 #if defined(MAGICKCORE_FONTCONFIG_DELEGATE)
622 MagickExport MagickBooleanType LoadFontConfigFonts(SplayTreeInfo *type_list,
623 ExceptionInfo *exception)
626 extension[MaxTextExtent],
664 font_config=FcInitLoadConfigAndFonts();
665 if (font_config == (FcConfig *) NULL)
667 font_set=(FcFontSet *) NULL;
668 object_set=FcObjectSetBuild(FC_FAMILY,FC_STYLE,FC_SLANT,FC_WIDTH,FC_WEIGHT,
669 FC_FILE,(char *) NULL);
670 if (object_set != (FcObjectSet *) NULL)
672 pattern=FcPatternCreate();
673 if (pattern != (FcPattern *) NULL)
675 font_set=FcFontList(0,pattern,object_set);
676 FcPatternDestroy(pattern);
678 FcObjectSetDestroy(object_set);
680 if (font_set == (FcFontSet *) NULL)
682 FcConfigDestroy(font_config);
685 for (i=0; i < (long) font_set->nfont; i++)
687 status=FcPatternGetString(font_set->fonts[i],FC_FAMILY,0,&family);
688 if (status != FcResultMatch)
690 status=FcPatternGetString(font_set->fonts[i],FC_FILE,0,&file);
691 if (status != FcResultMatch)
694 GetPathComponent((const char *) file,ExtensionPath,extension);
695 if ((*extension != '\0') && (LocaleCompare(extension,"gz") == 0))
697 type_info=(TypeInfo *) AcquireMagickMemory(sizeof(*type_info));
698 if (type_info == (TypeInfo *) NULL)
700 (void) ResetMagickMemory(type_info,0,sizeof(*type_info));
701 type_info->path=ConstantString("System Fonts");
702 type_info->signature=MagickSignature;
703 (void) CopyMagickString(name,(const char *) family,MaxTextExtent);
704 (void) ConcatenateMagickString(name," ",MaxTextExtent);
705 status=FcPatternGetString(font_set->fonts[i],FC_STYLE,0,&style);
706 if (status == FcResultMatch)
707 (void) ConcatenateMagickString(name,(const char *) style,MaxTextExtent);
708 type_info->name=ConstantString(name);
709 (void) SubstituteString(&type_info->name," ","-");
710 (void) SubstituteString(&type_info->name,"-L-","-");
711 (void) SubstituteString(&type_info->name,"semicondensed","SemiCondensed");
712 type_info->family=ConstantString((const char *) family);
713 (void) SubstituteString(&type_info->family," L","");
714 status=FcPatternGetInteger(font_set->fonts[i],FC_SLANT,0,&slant);
715 type_info->style=NormalStyle;
716 if (slant == FC_SLANT_ITALIC)
717 type_info->style=ItalicStyle;
718 if (slant == FC_SLANT_OBLIQUE)
719 type_info->style=ObliqueStyle;
720 status=FcPatternGetInteger(font_set->fonts[i],FC_WIDTH,0,&width);
721 type_info->stretch=NormalStretch;
722 if (width >= FC_WIDTH_ULTRACONDENSED)
723 type_info->stretch=UltraCondensedStretch;
724 if (width >= FC_WIDTH_EXTRACONDENSED)
725 type_info->stretch=ExtraCondensedStretch;
726 if (width >= FC_WIDTH_CONDENSED)
727 type_info->stretch=CondensedStretch;
728 if (width >= FC_WIDTH_SEMICONDENSED)
729 type_info->stretch=SemiCondensedStretch;
730 if (width >= FC_WIDTH_NORMAL)
731 type_info->stretch=NormalStretch;
732 if (width >= FC_WIDTH_SEMIEXPANDED)
733 type_info->stretch=SemiExpandedStretch;
734 if (width >= FC_WIDTH_EXPANDED)
735 type_info->stretch=ExpandedStretch;
736 if (width >= FC_WIDTH_EXTRAEXPANDED)
737 type_info->stretch=ExtraExpandedStretch;
738 if (width >= FC_WIDTH_ULTRAEXPANDED)
739 type_info->stretch=UltraExpandedStretch;
740 type_info->weight=400;
741 status=FcPatternGetInteger(font_set->fonts[i],FC_WEIGHT,0,&weight);
742 if (weight >= FC_WEIGHT_THIN)
743 type_info->weight=100;
744 if (weight >= FC_WEIGHT_EXTRALIGHT)
745 type_info->weight=200;
746 if (weight >= FC_WEIGHT_LIGHT)
747 type_info->weight=300;
748 if (weight >= FC_WEIGHT_NORMAL)
749 type_info->weight=400;
750 if (weight >= FC_WEIGHT_MEDIUM)
751 type_info->weight=500;
752 if (weight >= FC_WEIGHT_DEMIBOLD)
753 type_info->weight=600;
754 if (weight >= FC_WEIGHT_BOLD)
755 type_info->weight=700;
756 if (weight >= FC_WEIGHT_EXTRABOLD)
757 type_info->weight=800;
758 if (weight >= FC_WEIGHT_BLACK)
759 type_info->weight=900;
760 type_info->glyphs=ConstantString((const char *) file);
761 (void) AddValueToSplayTree(type_list,type_info->name,type_info);
763 FcFontSetDestroy(font_set);
764 FcConfigDestroy(font_config);
769 static MagickBooleanType InitializeTypeList(ExceptionInfo *exception)
771 if ((type_list == (SplayTreeInfo *) NULL) &&
772 (instantiate_type == MagickFalse))
774 if (type_semaphore == (SemaphoreInfo *) NULL)
775 AcquireSemaphoreInfo(&type_semaphore);
776 (void) LockSemaphoreInfo(type_semaphore);
777 if ((type_list == (SplayTreeInfo *) NULL) &&
778 (instantiate_type == MagickFalse))
780 (void) LoadTypeLists(MagickTypeFilename,exception);
781 #if defined(__WINDOWS__)
782 (void) NTLoadTypeLists(type_list,exception);
784 #if defined(MAGICKCORE_FONTCONFIG_DELEGATE)
785 (void) LoadFontConfigFonts(type_list,exception);
787 instantiate_type=MagickTrue;
789 (void) UnlockSemaphoreInfo(type_semaphore);
791 return(type_list != (SplayTreeInfo *) NULL ? MagickTrue : MagickFalse);
795 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
799 % L i s t T y p e I n f o %
803 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
805 % ListTypeInfo() lists the fonts to a file.
807 % The format of the ListTypeInfo method is:
809 % MagickBooleanType ListTypeInfo(FILE *file,ExceptionInfo *exception)
811 % A description of each parameter follows.
813 % o file: An pointer to a FILE.
815 % o exception: return any errors or warnings in this structure.
818 MagickExport MagickBooleanType ListTypeInfo(FILE *file,ExceptionInfo *exception)
821 weight[MaxTextExtent];
840 if (file == (FILE *) NULL)
843 type_info=GetTypeInfoList("*",&number_fonts,exception);
844 if (type_info == (const TypeInfo **) NULL)
847 path=(const char *) NULL;
848 for (i=0; i < (long) number_fonts; i++)
850 if (type_info[i]->stealth != MagickFalse)
852 if (((path == (const char *) NULL) ||
853 (LocaleCompare(path,type_info[i]->path) != 0)) &&
854 (type_info[i]->path != (char *) NULL))
855 (void) fprintf(file,"\nPath: %s\n",type_info[i]->path);
856 path=type_info[i]->path;
858 if (type_info[i]->name != (char *) NULL)
859 name=type_info[i]->name;
861 if (type_info[i]->family != (char *) NULL)
862 family=type_info[i]->family;
863 style=MagickOptionToMnemonic(MagickStyleOptions,type_info[i]->style);
864 stretch=MagickOptionToMnemonic(MagickStretchOptions,type_info[i]->stretch);
866 if (type_info[i]->glyphs != (char *) NULL)
867 glyphs=type_info[i]->glyphs;
868 (void) FormatMagickString(weight,MaxTextExtent,"%lu",type_info[i]->weight);
869 (void) fprintf(file," Font: %s\n",name);
870 (void) fprintf(file," family: %s\n",family);
871 (void) fprintf(file," style: %s\n",style);
872 (void) fprintf(file," stretch: %s\n",stretch);
873 (void) fprintf(file," weight: %s\n",weight);
874 (void) fprintf(file," glyphs: %s\n",glyphs);
877 type_info=(const TypeInfo **) RelinquishMagickMemory((void *) type_info);
882 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
886 + L o a d T y p e L i s t %
890 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
892 % LoadTypeList() loads the type configuration file which provides a mapping
893 % between type attributes and a type name.
895 % The format of the LoadTypeList method is:
897 % MagickBooleanType LoadTypeList(const char *xml,const char *filename,
898 % const unsigned long depth,ExceptionInfo *exception)
900 % A description of each parameter follows:
902 % o xml: The type list in XML format.
904 % o filename: The type list filename.
906 % o depth: depth of <include /> statements.
908 % o exception: return any errors or warnings in this structure.
912 static void *DestroyTypeNode(void *type_info)
917 p=(TypeInfo *) type_info;
918 if (p->path != (char *) NULL)
919 p->path=DestroyString(p->path);
920 if (p->name != (char *) NULL)
921 p->name=DestroyString(p->name);
922 if (p->description != (char *) NULL)
923 p->description=DestroyString(p->description);
924 if (p->family != (char *) NULL)
925 p->family=DestroyString(p->family);
926 if (p->encoding != (char *) NULL)
927 p->encoding=DestroyString(p->encoding);
928 if (p->foundry != (char *) NULL)
929 p->foundry=DestroyString(p->foundry);
930 if (p->format != (char *) NULL)
931 p->format=DestroyString(p->format);
932 if (p->metrics != (char *) NULL)
933 p->metrics=DestroyString(p->metrics);
934 if (p->glyphs != (char *) NULL)
935 p->glyphs=DestroyString(p->glyphs);
936 return(RelinquishMagickMemory(p));
939 static MagickBooleanType LoadTypeList(const char *xml,const char *filename,
940 const unsigned long depth,ExceptionInfo *exception)
943 font_path[MaxTextExtent],
944 keyword[MaxTextExtent],
957 Load the type map file.
959 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
960 "Loading type configure file \"%s\" ...",filename);
961 if (xml == (const char *) NULL)
963 if (type_list == (SplayTreeInfo *) NULL)
965 type_list=NewSplayTree(CompareSplayTreeString,(void *(*)(void *)) NULL,
967 if (type_list == (SplayTreeInfo *) NULL)
969 ThrowFileException(exception,ResourceLimitError,
970 "MemoryAllocationFailed",filename);
975 type_info=(TypeInfo *) NULL;
976 token=AcquireString(xml);
977 #if defined(__WINDOWS__)
979 Determine the Ghostscript font path.
982 if (NTGhostscriptFonts(font_path,MaxTextExtent-2))
983 (void) ConcatenateMagickString(font_path,DirectorySeparator,MaxTextExtent);
985 for (q=(char *) xml; *q != '\0'; )
990 GetMagickToken(q,&q,token);
993 (void) CopyMagickString(keyword,token,MaxTextExtent);
994 if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
999 while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
1000 GetMagickToken(q,&q,token);
1003 if (LocaleNCompare(keyword,"<!--",4) == 0)
1008 while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
1009 GetMagickToken(q,&q,token);
1012 if (LocaleCompare(keyword,"<include") == 0)
1017 while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0'))
1019 (void) CopyMagickString(keyword,token,MaxTextExtent);
1020 GetMagickToken(q,&q,token);
1023 GetMagickToken(q,&q,token);
1024 if (LocaleCompare(keyword,"file") == 0)
1027 (void) ThrowMagickException(exception,GetMagickModule(),
1028 ConfigureError,"IncludeNodeNestedTooDeeply","`%s'",token);
1032 path[MaxTextExtent],
1039 GetPathComponent(filename,HeadPath,path);
1041 (void) ConcatenateMagickString(path,DirectorySeparator,
1043 if (*token == *DirectorySeparator)
1044 (void) CopyMagickString(path,token,MaxTextExtent);
1046 (void) ConcatenateMagickString(path,token,MaxTextExtent);
1047 sans_exception=AcquireExceptionInfo();
1048 xml=FileToString(path,~0,sans_exception);
1049 sans_exception=DestroyExceptionInfo(sans_exception);
1050 if (xml != (char *) NULL)
1052 status=LoadTypeList(xml,path,depth+1,exception);
1053 xml=(char *) RelinquishMagickMemory(xml);
1060 if (LocaleCompare(keyword,"<type") == 0)
1065 type_info=(TypeInfo *) AcquireMagickMemory(sizeof(*type_info));
1066 if (type_info == (TypeInfo *) NULL)
1067 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
1068 (void) ResetMagickMemory(type_info,0,sizeof(*type_info));
1069 type_info->path=ConstantString(filename);
1070 type_info->signature=MagickSignature;
1073 if (type_info == (TypeInfo *) NULL)
1075 if (LocaleCompare(keyword,"/>") == 0)
1077 status=AddValueToSplayTree(type_list,type_info->name,type_info);
1078 if (status == MagickFalse)
1079 (void) ThrowMagickException(exception,GetMagickModule(),
1080 ResourceLimitError,"MemoryAllocationFailed","`%s'",type_info->name);
1081 type_info=(TypeInfo *) NULL;
1083 GetMagickToken(q,(const char **) NULL,token);
1086 GetMagickToken(q,&q,token);
1087 GetMagickToken(q,&q,token);
1093 if (LocaleCompare((char *) keyword,"encoding") == 0)
1095 type_info->encoding=ConstantString(token);
1103 if (LocaleCompare((char *) keyword,"face") == 0)
1105 type_info->face=(unsigned long) atol(token);
1108 if (LocaleCompare((char *) keyword,"family") == 0)
1110 type_info->family=ConstantString(token);
1113 if (LocaleCompare((char *) keyword,"format") == 0)
1115 type_info->format=ConstantString(token);
1118 if (LocaleCompare((char *) keyword,"foundry") == 0)
1120 type_info->foundry=ConstantString(token);
1123 if (LocaleCompare((char *) keyword,"fullname") == 0)
1125 type_info->description=ConstantString(token);
1133 if (LocaleCompare((char *) keyword,"glyphs") == 0)
1138 path=ConstantString(token);
1139 #if defined(__WINDOWS__)
1140 if (strchr(path,'@') != (char *) NULL)
1141 SubstituteString(&path,"@ghostscript_font_path@",font_path);
1143 if (IsPathAccessible(path) == MagickFalse)
1148 path=DestroyString(path);
1149 GetPathComponent(filename,HeadPath,font_path);
1150 (void) ConcatenateMagickString(font_path,DirectorySeparator,
1152 (void) ConcatenateMagickString(font_path,token,MaxTextExtent);
1153 path=ConstantString(font_path);
1155 type_info->glyphs=path;
1163 if (LocaleCompare((char *) keyword,"metrics") == 0)
1168 path=ConstantString(token);
1169 #if defined(__WINDOWS__)
1170 if (strchr(path,'@') != (char *) NULL)
1171 SubstituteString(&path,"@ghostscript_font_path@",font_path);
1173 if (IsPathAccessible(path) == MagickFalse)
1178 path=DestroyString(path);
1179 GetPathComponent(filename,HeadPath,font_path);
1180 (void) ConcatenateMagickString(font_path,DirectorySeparator,
1182 (void) ConcatenateMagickString(font_path,token,MaxTextExtent);
1183 path=ConstantString(font_path);
1185 type_info->metrics=path;
1193 if (LocaleCompare((char *) keyword,"name") == 0)
1195 type_info->name=ConstantString(token);
1203 if (LocaleCompare((char *) keyword,"stealth") == 0)
1205 type_info->stealth=IsMagickTrue(token);
1208 if (LocaleCompare((char *) keyword,"stretch") == 0)
1210 type_info->stretch=(StretchType) ParseMagickOption(
1211 MagickStretchOptions,MagickFalse,token);
1214 if (LocaleCompare((char *) keyword,"style") == 0)
1216 type_info->style=(StyleType) ParseMagickOption(MagickStyleOptions,
1225 if (LocaleCompare((char *) keyword,"weight") == 0)
1227 type_info->weight=(unsigned long) atol(token);
1228 if (LocaleCompare(token,"bold") == 0)
1229 type_info->weight=700;
1230 if (LocaleCompare(token,"normal") == 0)
1231 type_info->weight=400;
1240 token=(char *) RelinquishMagickMemory(token);
1245 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1249 % L o a d T y p e L i s t s %
1253 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1255 % LoadTypeList() loads one or more type configuration files which provides a
1256 % mapping between type attributes and a type name.
1258 % The format of the LoadTypeLists method is:
1260 % MagickBooleanType LoadTypeLists(const char *filename,
1261 % ExceptionInfo *exception)
1263 % A description of each parameter follows:
1265 % o filename: the font file name.
1267 % o exception: return any errors or warnings in this structure.
1270 static MagickBooleanType LoadTypeLists(const char *filename,
1271 ExceptionInfo *exception)
1273 #if defined(MAGICKCORE_EMBEDDABLE_SUPPORT)
1274 return(LoadTypeList(TypeMap,"built-in",0,exception));
1278 path[MaxTextExtent];
1291 options=GetConfigureOptions(filename,exception);
1292 option=(const StringInfo *) GetNextValueInLinkedList(options);
1293 while (option != (const StringInfo *) NULL)
1295 (void) CopyMagickString(path,GetStringInfoPath(option),MaxTextExtent);
1296 status|=LoadTypeList((const char *) GetStringInfoDatum(option),
1297 GetStringInfoPath(option),0,exception);
1298 option=(const StringInfo *) GetNextValueInLinkedList(options);
1300 options=DestroyConfigureOptions(options);
1301 font_path=GetEnvironmentValue("MAGICK_FONT_PATH");
1302 if (font_path != (char *) NULL)
1308 Search MAGICK_FONT_PATH.
1310 (void) FormatMagickString(path,MaxTextExtent,"%s%s%s",font_path,
1311 DirectorySeparator,filename);
1312 option=FileToString(path,~0,exception);
1313 if (option != (void *) NULL)
1315 status|=LoadTypeList(option,path,0,exception);
1316 option=DestroyString(option);
1318 font_path=DestroyString(font_path);
1320 if ((type_list == (SplayTreeInfo *) NULL) ||
1321 (GetNumberOfNodesInSplayTree(type_list) == 0))
1322 status|=LoadTypeList(TypeMap,"built-in",0,exception);
1323 return(status != 0 ? MagickTrue : MagickFalse);
1328 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1332 + T y p e C o m p o n e n t G e n e s i s %
1336 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1338 % TypeComponentGenesis() instantiates the type component.
1340 % The format of the TypeComponentGenesis method is:
1342 % MagickBooleanType TypeComponentGenesis(void)
1345 MagickExport MagickBooleanType TypeComponentGenesis(void)
1347 assert(type_semaphore == (SemaphoreInfo *) NULL);
1348 type_semaphore=AllocateSemaphoreInfo();
1353 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1357 + T y p e C o m p o n e n t T e r m i n u s %
1361 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1363 % TypeComponentTerminus() destroy type component.
1365 % The format of the TypeComponentTerminus method is:
1367 % void TypeComponentTerminus(void)
1370 MagickExport void TypeComponentTerminus(void)
1372 if (type_semaphore == (SemaphoreInfo *) NULL)
1373 AcquireSemaphoreInfo(&type_semaphore);
1374 (void) LockSemaphoreInfo(type_semaphore);
1375 if (type_list != (SplayTreeInfo *) NULL)
1376 type_list=DestroySplayTree(type_list);
1377 instantiate_type=MagickFalse;
1378 (void) UnlockSemaphoreInfo(type_semaphore);
1379 DestroySemaphoreInfo(&type_semaphore);