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/image-private.h"
51#include "magick/log.h"
52#include "magick/memory_.h"
53#include "magick/nt-base-private.h"
54#include "magick/nt-feature.h"
55#include "magick/option.h"
56#include "magick/semaphore.h"
57#include "magick/splay-tree.h"
58#include "magick/string_.h"
59#include "magick/string-private.h"
60#include "magick/type.h"
61#include "magick/token.h"
62#include "magick/utility.h"
63#include "magick/xml-tree.h"
64#if defined(MAGICKCORE_FONTCONFIG_DELEGATE)
65# include "fontconfig/fontconfig.h"
66#if (FC_VERSION < 20209)
68#define FC_WIDTH "width"
69#define FC_WIDTH_ULTRACONDENSED 50
70#define FC_WIDTH_EXTRACONDENSED 63
71#define FC_WIDTH_CONDENSED 75
72#define FC_WIDTH_SEMICONDENSED 87
73#define FC_WIDTH_NORMAL 100
74#define FC_WIDTH_SEMIEXPANDED 113
75#define FC_WIDTH_EXPANDED 125
76#define FC_WIDTH_EXTRAEXPANDED 150
77#define FC_WIDTH_ULTRAEXPANDED 200
79#define FC_WEIGHT_THIN 0
80#define FC_WEIGHT_EXTRALIGHT 40
81#define FC_WEIGHT_ULTRALIGHT FC_WEIGHT_EXTRALIGHT
82#define FC_WEIGHT_LIGHT 50
83#define FC_WEIGHT_BOOK 75
84#define FC_WEIGHT_REGULAR 80
85#define FC_WEIGHT_NORMAL FC_WEIGHT_REGULAR
86#define FC_WEIGHT_MEDIUM 100
87#define FC_WEIGHT_DEMIBOLD 180
88#define FC_WEIGHT_SEMIBOLD FC_WEIGHT_DEMIBOLD
89#define FC_WEIGHT_BOLD 200
90#define FC_WEIGHT_EXTRABOLD 205
91#define FC_WEIGHT_ULTRABOLD FC_WEIGHT_EXTRABOLD
92#define FC_WEIGHT_BLACK 210
93#define FC_WEIGHT_HEAVY FC_WEIGHT_BLACK
96#if defined(MAGICKCORE_WINDOWS_SUPPORT)
97# include "magick/nt-feature.h"
103#define MagickTypeFilename "type.xml"
110 "<?xml version=\"1.0\"?>"
112 " <type stealth=\"True\" name=\"fixed\" family=\"helvetica\"/>"
113 " <type stealth=\"True\" name=\"helvetica\" family=\"helvetica\"/>"
128static MagickBooleanType
130 LoadTypeCache(
SplayTreeInfo *,
const char *,
const char *,
const size_t,
160static void *DestroyTypeNode(
void *type_info)
166 if (p->path != (
char *) NULL)
167 p->path=DestroyString(p->path);
168 if (p->name != (
char *) NULL)
169 p->name=DestroyString(p->name);
170 if (p->description != (
char *) NULL)
171 p->description=DestroyString(p->description);
172 if (p->family != (
char *) NULL)
173 p->family=DestroyString(p->family);
174 if (p->encoding != (
char *) NULL)
175 p->encoding=DestroyString(p->encoding);
176 if (p->foundry != (
char *) NULL)
177 p->foundry=DestroyString(p->foundry);
178 if (p->format != (
char *) NULL)
179 p->format=DestroyString(p->format);
180 if (p->metrics != (
char *) NULL)
181 p->metrics=DestroyString(p->metrics);
182 if (p->glyphs != (
char *) NULL)
183 p->glyphs=DestroyString(p->glyphs);
184 return(RelinquishMagickMemory(p));
196 cache=NewSplayTree(CompareSplayTreeString,(
void *(*)(
void *)) NULL,
199 ThrowFatalException(ResourceLimitFatalError,
"MemoryAllocationFailed");
201#if !MAGICKCORE_ZERO_CONFIGURATION_SUPPORT
214 options=GetConfigureOptions(filename,exception);
215 option=(
const StringInfo *) GetNextValueInLinkedList(options);
218 (void) CopyMagickString(path,GetStringInfoPath(option),MaxTextExtent);
219 status&=LoadTypeCache(cache,(
const char *) GetStringInfoDatum(option),
220 GetStringInfoPath(option),0,exception);
221 option=(
const StringInfo *) GetNextValueInLinkedList(options);
223 options=DestroyConfigureOptions(options);
224 font_path=GetEnvironmentValue(
"MAGICK_FONT_PATH");
225 if (font_path != (
char *) NULL)
233 (void) FormatLocaleString(path,MaxTextExtent,
"%s%s%s",font_path,
234 DirectorySeparator,filename);
235 option=FileToString(path,~0UL,exception);
236 if (option != (
void *) NULL)
238 status&=LoadTypeCache(cache,option,path,0,exception);
239 option=DestroyString(option);
241 font_path=DestroyString(font_path);
245 magick_unreferenced(filename);
247 if (GetNumberOfNodesInSplayTree(cache) == 0)
248 status&=LoadTypeCache(cache,TypeMap,
"built-in",0,exception);
249 if (status == MagickFalse)
279MagickExport
const TypeInfo *GetTypeInfo(
const char *name,
283 if (IsTypeTreeInstantiated(exception) == MagickFalse)
285 if ((name == (
const char *) NULL) || (LocaleCompare(name,
"*") == 0))
286 return((
const TypeInfo *) GetRootValueFromSplayTree(type_cache));
287 return((
const TypeInfo *) GetValueFromSplayTree(type_cache,name));
325MagickExport
const TypeInfo *GetTypeInfoByFamily(
const char *family,
326 const StyleType style,
const StretchType stretch,
const size_t weight,
329 typedef struct _Fontmap
351 {
"fixed",
"courier" },
352 {
"modern",
"courier" },
353 {
"monotype corsiva",
"courier" },
354 {
"news gothic",
"helvetica" },
355 {
"system",
"courier" },
356 {
"terminal",
"courier" },
357 {
"wingdings",
"symbol" }
368 (void) GetTypeInfo(
"*",exception);
371 font_weight=weight == 0 ? 400 : weight;
372 LockSemaphoreInfo(type_semaphore);
373 ResetSplayTreeIterator(type_cache);
375 p=(
const TypeInfo *) GetNextValueInSplayTree(type_cache);
376 while (p != (
const TypeInfo *) NULL)
378 if (p->family == (
char *) NULL)
380 p=(
const TypeInfo *) GetNextValueInSplayTree(type_cache);
383 if (family == (
const char *) NULL)
385 if ((LocaleCompare(p->family,
"arial") != 0) &&
386 (LocaleCompare(p->family,
"helvetica") != 0))
388 p=(
const TypeInfo *) GetNextValueInSplayTree(type_cache);
393 if (LocaleCompare(p->family,family) != 0)
395 p=(
const TypeInfo *) GetNextValueInSplayTree(type_cache);
398 if ((style != UndefinedStyle) && (style != AnyStyle) && (p->style != style))
400 p=(
const TypeInfo *) GetNextValueInSplayTree(type_cache);
403 if ((stretch != UndefinedStretch) && (stretch != AnyStretch) &&
404 (p->stretch != stretch))
406 p=(
const TypeInfo *) GetNextValueInSplayTree(type_cache);
409 if (p->weight != font_weight)
411 p=(
const TypeInfo *) GetNextValueInSplayTree(type_cache);
417 UnlockSemaphoreInfo(type_semaphore);
418 if (type_info != (
const TypeInfo *) NULL)
424 LockSemaphoreInfo(type_semaphore);
425 ResetSplayTreeIterator(type_cache);
426 p=(
const TypeInfo *) GetNextValueInSplayTree(type_cache);
427 while (p != (
const TypeInfo *) NULL)
429 if (p->family == (
char *) NULL)
431 p=(
const TypeInfo *) GetNextValueInSplayTree(type_cache);
434 if (family == (
const char *) NULL)
436 if ((LocaleCompare(p->family,
"arial") != 0) &&
437 (LocaleCompare(p->family,
"helvetica") != 0))
439 p=(
const TypeInfo *) GetNextValueInSplayTree(type_cache);
444 if (LocaleCompare(p->family,family) != 0)
446 p=(
const TypeInfo *) GetNextValueInSplayTree(type_cache);
450 if ((style == UndefinedStyle) || (style == AnyStyle) || (p->style == style))
453 if (((style == ItalicStyle) || (style == ObliqueStyle)) &&
454 ((p->style == ItalicStyle) || (p->style == ObliqueStyle)))
456 score+=(16*(800-((ssize_t) MagickMax(MagickMin(font_weight,900),p->weight)-
457 (ssize_t) MagickMin(MagickMin(font_weight,900),p->weight))))/800;
458 if ((stretch == UndefinedStretch) || (stretch == AnyStretch))
462 range=(ssize_t) UltraExpandedStretch-(ssize_t) NormalStretch;
463 score+=(8*(range-((ssize_t) MagickMax(stretch,p->stretch)-
464 (ssize_t) MagickMin(stretch,p->stretch))))/range;
466 if (score > max_score)
471 p=(
const TypeInfo *) GetNextValueInSplayTree(type_cache);
473 UnlockSemaphoreInfo(type_semaphore);
474 if (type_info != (
const TypeInfo *) NULL)
479 for (i=0; i < (ssize_t) (
sizeof(fontmap)/
sizeof(fontmap[0])); i++)
481 if (family == (
const char *) NULL)
483 if ((LocaleCompare(fontmap[i].name,
"arial") != 0) &&
484 (LocaleCompare(fontmap[i].name,
"helvetica") != 0))
488 if (LocaleCompare(fontmap[i].name,family) != 0)
490 type_info=GetTypeInfoByFamily(fontmap[i].substitute,style,stretch,weight,
494 if (type_info != (
const TypeInfo *) NULL)
496 (void) ThrowMagickException(exception,GetMagickModule(),TypeWarning,
497 "FontSubstitutionRequired",
"`%s'",type_info->family);
500 if (family != (
const char *) NULL)
501 type_info=GetTypeInfoByFamily((
const char *) NULL,style,stretch,weight,
534#if defined(__cplusplus) || defined(c_plusplus)
538static int TypeInfoCompare(
const void *x,
const void *y)
546 if (LocaleCompare((*p)->path,(*q)->path) == 0)
547 return(LocaleCompare((*p)->name,(*q)->name));
548 return(LocaleCompare((*p)->path,(*q)->path));
551#if defined(__cplusplus) || defined(c_plusplus)
555MagickExport
const TypeInfo **GetTypeInfoList(
const char *pattern,
570 assert(pattern != (
char *) NULL);
571 assert(number_fonts != (
size_t *) NULL);
572 if (IsEventLogging() != MagickFalse)
573 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",pattern);
575 p=GetTypeInfo(
"*",exception);
578 fonts=(
const TypeInfo **) AcquireQuantumMemory((
size_t)
579 GetNumberOfNodesInSplayTree(type_cache)+1UL,
sizeof(*fonts));
580 if (fonts == (
const TypeInfo **) NULL)
585 LockSemaphoreInfo(type_semaphore);
586 ResetSplayTreeIterator(type_cache);
587 p=(
const TypeInfo *) GetNextValueInSplayTree(type_cache);
588 for (i=0; p != (
const TypeInfo *) NULL; )
590 if ((p->stealth == MagickFalse) &&
591 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
593 p=(
const TypeInfo *) GetNextValueInSplayTree(type_cache);
595 UnlockSemaphoreInfo(type_semaphore);
596 qsort((
void *) fonts,(
size_t) i,
sizeof(*fonts),TypeInfoCompare);
598 *number_fonts=(size_t) i;
630#if defined(__cplusplus) || defined(c_plusplus)
634static int TypeCompare(
const void *x,
const void *y)
642 return(LocaleCompare(*p,*q));
645#if defined(__cplusplus) || defined(c_plusplus)
649MagickExport
char **GetTypeList(
const char *pattern,
size_t *number_fonts,
664 assert(pattern != (
char *) NULL);
665 assert(number_fonts != (
size_t *) NULL);
666 if (IsEventLogging() != MagickFalse)
667 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",pattern);
669 p=GetTypeInfo(
"*",exception);
671 return((
char **) NULL);
672 fonts=(
char **) AcquireQuantumMemory((
size_t)
673 GetNumberOfNodesInSplayTree(type_cache)+1UL,
sizeof(*fonts));
674 if (fonts == (
char **) NULL)
675 return((
char **) NULL);
679 LockSemaphoreInfo(type_semaphore);
680 ResetSplayTreeIterator(type_cache);
681 p=(
const TypeInfo *) GetNextValueInSplayTree(type_cache);
682 for (i=0; p != (
const TypeInfo *) NULL; )
684 if ((p->stealth == MagickFalse) &&
685 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
686 fonts[i++]=ConstantString(p->name);
687 p=(
const TypeInfo *) GetNextValueInSplayTree(type_cache);
689 UnlockSemaphoreInfo(type_semaphore);
690 qsort((
void *) fonts,(
size_t) i,
sizeof(*fonts),TypeCompare);
691 fonts[i]=(
char *) NULL;
692 *number_fonts=(size_t) i;
720#if defined(MAGICKCORE_FONTCONFIG_DELEGATE)
721MagickExport MagickBooleanType LoadFontConfigFonts(
SplayTreeInfo *type_cache,
724#if !defined(FC_FULLNAME)
725#define FC_FULLNAME "fullname"
729 extension[MaxTextExtent],
774 font_config=FcConfigGetCurrent();
775 if (font_config == (FcConfig *) NULL)
777 FcConfigSetRescanInterval(font_config,0);
778 font_set=(FcFontSet *) NULL;
779 object_set=FcObjectSetBuild(FC_FULLNAME,FC_FAMILY,FC_STYLE,FC_SLANT,
780 FC_WIDTH,FC_WEIGHT,FC_FILE,(
char *) NULL);
781 if (object_set != (FcObjectSet *) NULL)
783 pattern=FcPatternCreate();
784 if (pattern != (FcPattern *) NULL)
786 font_set=FcFontList(font_config,pattern,object_set);
787 FcPatternDestroy(pattern);
789 FcObjectSetDestroy(object_set);
791 if (font_set == (FcFontSet *) NULL)
793 FcConfigDestroy(font_config);
796 for (i=0; i < (ssize_t) font_set->nfont; i++)
798 status=FcPatternGetString(font_set->fonts[i],FC_FAMILY,0,&family);
799 if (status != FcResultMatch)
801 status=FcPatternGetString(font_set->fonts[i],FC_FILE,0,&file);
802 if (status != FcResultMatch)
805 GetPathComponent((
const char *) file,ExtensionPath,extension);
806 if ((*extension !=
'\0') && (LocaleCompare(extension,
"gz") == 0))
808 type_info=(
TypeInfo *) AcquireMagickMemory(
sizeof(*type_info));
811 (void) memset(type_info,0,
sizeof(*type_info));
812 type_info->path=ConstantString(
"System Fonts");
813 type_info->signature=MagickCoreSignature;
814 (void) CopyMagickString(name,
"Unknown",MaxTextExtent);
815 status=FcPatternGetString(font_set->fonts[i],FC_FULLNAME,0,&fullname);
816 if ((status == FcResultMatch) && (fullname != (FcChar8 *) NULL))
817 (void) CopyMagickString(name,(
const char *) fullname,MaxTextExtent);
820 if (family != (FcChar8 *) NULL)
821 (void) CopyMagickString(name,(
const char *) family,MaxTextExtent);
822 status=FcPatternGetString(font_set->fonts[i],FC_STYLE,0,&style);
823 if ((status == FcResultMatch) && (style != (FcChar8 *) NULL) &&
824 (LocaleCompare((
const char *) style,
"Regular") != 0))
826 (void) ConcatenateMagickString(name,
" ",MaxTextExtent);
827 (void) ConcatenateMagickString(name,(
const char *) style,
831 type_info->name=ConstantString(name);
832 (void) SubstituteString(&type_info->name,
" ",
"-");
833 type_info->family=ConstantString((
const char *) family);
834 status=FcPatternGetInteger(font_set->fonts[i],FC_SLANT,0,&slant);
835 type_info->style=NormalStyle;
836 if (slant == FC_SLANT_ITALIC)
837 type_info->style=ItalicStyle;
838 if (slant == FC_SLANT_OBLIQUE)
839 type_info->style=ObliqueStyle;
840 status=FcPatternGetInteger(font_set->fonts[i],FC_WIDTH,0,&width);
841 type_info->stretch=NormalStretch;
842 if (width >= FC_WIDTH_ULTRACONDENSED)
843 type_info->stretch=UltraCondensedStretch;
844 if (width >= FC_WIDTH_EXTRACONDENSED)
845 type_info->stretch=ExtraCondensedStretch;
846 if (width >= FC_WIDTH_CONDENSED)
847 type_info->stretch=CondensedStretch;
848 if (width >= FC_WIDTH_SEMICONDENSED)
849 type_info->stretch=SemiCondensedStretch;
850 if (width >= FC_WIDTH_NORMAL)
851 type_info->stretch=NormalStretch;
852 if (width >= FC_WIDTH_SEMIEXPANDED)
853 type_info->stretch=SemiExpandedStretch;
854 if (width >= FC_WIDTH_EXPANDED)
855 type_info->stretch=ExpandedStretch;
856 if (width >= FC_WIDTH_EXTRAEXPANDED)
857 type_info->stretch=ExtraExpandedStretch;
858 if (width >= FC_WIDTH_ULTRAEXPANDED)
859 type_info->stretch=UltraExpandedStretch;
860 type_info->weight=400;
861 status=FcPatternGetInteger(font_set->fonts[i],FC_WEIGHT,0,&weight);
862 if (weight >= FC_WEIGHT_THIN)
863 type_info->weight=100;
864 if (weight >= FC_WEIGHT_EXTRALIGHT)
865 type_info->weight=200;
866 if (weight >= FC_WEIGHT_LIGHT)
867 type_info->weight=300;
868 if (weight >= FC_WEIGHT_NORMAL)
869 type_info->weight=400;
870 if (weight >= FC_WEIGHT_MEDIUM)
871 type_info->weight=500;
872 if (weight >= FC_WEIGHT_DEMIBOLD)
873 type_info->weight=600;
874 if (weight >= FC_WEIGHT_BOLD)
875 type_info->weight=700;
876 if (weight >= FC_WEIGHT_EXTRABOLD)
877 type_info->weight=800;
878 if (weight >= FC_WEIGHT_BLACK)
879 type_info->weight=900;
880 type_info->glyphs=ConstantString((
const char *) file);
881 (void) AddValueToSplayTree(type_cache,type_info->name,type_info);
883 FcFontSetDestroy(font_set);
884 FcConfigDestroy(font_config);
889static MagickBooleanType IsTypeTreeInstantiated(
ExceptionInfo *exception)
894 ActivateSemaphoreInfo(&type_semaphore);
895 LockSemaphoreInfo(type_semaphore);
901 splay_tree=AcquireTypeCache(MagickTypeFilename,exception);
902#if defined(MAGICKCORE_WINDOWS_SUPPORT)
903 (void) NTAcquireTypeCache(splay_tree,exception);
905#if defined(MAGICKCORE_FONTCONFIG_DELEGATE)
906 (void) LoadFontConfigFonts(splay_tree,exception);
908 type_cache=splay_tree;
910 UnlockSemaphoreInfo(type_semaphore);
912 return(type_cache != (
SplayTreeInfo *) NULL ? MagickTrue : MagickFalse);
939MagickExport MagickBooleanType ListTypeInfo(FILE *file,
ExceptionInfo *exception)
942 weight[MaxTextExtent];
962 if (file == (FILE *) NULL)
965 type_info=GetTypeInfoList(
"*",&number_fonts,exception);
966 if (type_info == (
const TypeInfo **) NULL)
969 path=(
const char *) NULL;
970 for (i=0; i < (ssize_t) number_fonts; i++)
972 if (type_info[i]->stealth != MagickFalse)
974 if (((path == (
const char *) NULL) ||
975 (LocaleCompare(path,type_info[i]->path) != 0)) &&
976 (type_info[i]->path != (
char *) NULL))
977 (void) FormatLocaleFile(file,
"\nPath: %s\n",type_info[i]->path);
978 path=type_info[i]->path;
980 if (type_info[i]->name != (
char *) NULL)
981 name=type_info[i]->name;
982 family=
"not defined";
983 if (type_info[i]->family != (
char *) NULL)
984 family=type_info[i]->family;
985 style=CommandOptionToMnemonic(MagickStyleOptions,type_info[i]->style);
986 stretch=CommandOptionToMnemonic(MagickStretchOptions,type_info[i]->stretch);
987 metrics=
"not defined";
988 if (type_info[i]->metrics != (
char *) NULL)
989 metrics=type_info[i]->metrics;
990 glyphs=
"not defined";
991 if (type_info[i]->glyphs != (
char *) NULL)
992 glyphs=type_info[i]->glyphs;
993 (void) FormatLocaleString(weight,MaxTextExtent,
"%.20g",(
double)
994 type_info[i]->weight);
995 (void) FormatLocaleFile(file,
" Font: %s\n",name);
996 (void) FormatLocaleFile(file,
" family: %s\n",family);
997 (void) FormatLocaleFile(file,
" style: %s\n",style);
998 (void) FormatLocaleFile(file,
" stretch: %s\n",stretch);
999 (void) FormatLocaleFile(file,
" weight: %s\n",weight);
1000 (void) FormatLocaleFile(file,
" metrics: %s\n",metrics);
1001 (void) FormatLocaleFile(file,
" glyphs: %s\n",glyphs);
1003 (void) fflush(file);
1004 type_info=(
const TypeInfo **) RelinquishMagickMemory((
void *) type_info);
1038static inline MagickBooleanType SetTypeNodePath(
const char *filename,
1039 char *font_path,
const char *token,
char **target)
1044 path=ConstantString(token);
1045#if defined(MAGICKCORE_WINDOWS_SUPPORT)
1046 if (strchr(path,
'@') != (
char *) NULL)
1047 SubstituteString(&path,
"@ghostscript_font_path@",font_path);
1049 if (IsPathAccessible(path) == MagickFalse)
1054 path=DestroyString(path);
1055 GetPathComponent(filename,HeadPath,font_path);
1056 (void) ConcatenateMagickString(font_path,DirectorySeparator,
1058 (void) ConcatenateMagickString(font_path,token,MaxTextExtent);
1059 path=ConstantString(font_path);
1060#if defined(MAGICKCORE_WINDOWS_SUPPORT)
1061 if (strchr(path,
'@') != (
char *) NULL)
1062 SubstituteString(&path,
"@ghostscript_font_path@",
"");
1064 if (IsPathAccessible(path) == MagickFalse)
1066 path=DestroyString(path);
1067 return(MagickFalse);
1075static MagickBooleanType LoadTypeCache(
SplayTreeInfo *cache,
const char *xml,
1076 const char *filename,
const size_t depth,
ExceptionInfo *exception)
1079 font_path[MaxTextExtent],
1080 keyword[MaxTextExtent],
1098 if (IsEventLogging() != MagickFalse)
1099 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1100 "Loading type configure file \"%s\" ...",filename);
1101 if (xml == (
const char *) NULL)
1102 return(MagickFalse);
1105 token=AcquireString(xml);
1106 extent=strlen(token)+MaxTextExtent;
1107#if defined(MAGICKCORE_WINDOWS_SUPPORT)
1112 if (NTGhostscriptFonts(font_path,MaxTextExtent-2))
1113 (void) ConcatenateMagickString(font_path,DirectorySeparator,MaxTextExtent);
1115 for (q=(
char *) xml; *q !=
'\0'; )
1120 (void) GetNextToken(q,&q,extent,token);
1123 (void) CopyMagickString(keyword,token,MaxTextExtent);
1124 if (LocaleNCompare(keyword,
"<!DOCTYPE",9) == 0)
1129 while ((LocaleNCompare(q,
"]>",2) != 0) && (*q !=
'\0'))
1130 (void) GetNextToken(q,&q,extent,token);
1133 if (LocaleNCompare(keyword,
"<!--",4) == 0)
1138 while ((LocaleNCompare(q,
"->",2) != 0) && (*q !=
'\0'))
1139 (void) GetNextToken(q,&q,extent,token);
1142 if (LocaleCompare(keyword,
"<include") == 0)
1147 while (((*token !=
'/') && (*(token+1) !=
'>')) && (*q !=
'\0'))
1149 (void) CopyMagickString(keyword,token,MaxTextExtent);
1150 (void) GetNextToken(q,&q,extent,token);
1153 (void) GetNextToken(q,&q,extent,token);
1154 if (LocaleCompare(keyword,
"file") == 0)
1156 if (depth > MagickMaxRecursionDepth)
1157 (void) ThrowMagickException(exception,GetMagickModule(),
1158 ConfigureError,
"IncludeNodeNestedTooDeeply",
"`%s'",token);
1162 path[MaxTextExtent],
1169 GetPathComponent(filename,HeadPath,path);
1171 (void) ConcatenateMagickString(path,DirectorySeparator,
1173 if (*token == *DirectorySeparator)
1174 (void) CopyMagickString(path,token,MaxTextExtent);
1176 (
void) ConcatenateMagickString(path,token,MaxTextExtent);
1177 sans_exception=AcquireExceptionInfo();
1178 xml=FileToString(path,~0UL,sans_exception);
1179 sans_exception=DestroyExceptionInfo(sans_exception);
1180 if (xml != (
char *) NULL)
1182 status&=LoadTypeCache(cache,xml,path,depth+1,
1184 xml=(
char *) RelinquishMagickMemory(xml);
1191 if (LocaleCompare(keyword,
"<type") == 0)
1196 type_info=(
TypeInfo *) AcquireMagickMemory(
sizeof(*type_info));
1197 if (type_info == (
TypeInfo *) NULL)
1198 ThrowFatalException(ResourceLimitFatalError,
"MemoryAllocationFailed");
1199 (void) memset(type_info,0,
sizeof(*type_info));
1200 type_info->path=ConstantString(filename);
1201 type_info->signature=MagickCoreSignature;
1204 if (type_info == (
TypeInfo *) NULL)
1206 if ((LocaleCompare(keyword,
"/>") == 0) ||
1207 (LocaleCompare(keyword,
"</policy>") == 0))
1209 status=AddValueToSplayTree(cache,type_info->name,type_info);
1210 if (status == MagickFalse)
1211 (void) ThrowMagickException(exception,GetMagickModule(),
1212 ResourceLimitError,
"MemoryAllocationFailed",
"`%s'",type_info->name);
1216 (void) GetNextToken(q,(
const char **) NULL,extent,token);
1219 (void) GetNextToken(q,&q,extent,token);
1220 (void) GetNextToken(q,&q,extent,token);
1226 if (LocaleCompare((
char *) keyword,
"encoding") == 0)
1228 type_info->encoding=ConstantString(token);
1236 if (LocaleCompare((
char *) keyword,
"face") == 0)
1238 type_info->face=StringToUnsignedLong(token);
1241 if (LocaleCompare((
char *) keyword,
"family") == 0)
1243 type_info->family=ConstantString(token);
1246 if (LocaleCompare((
char *) keyword,
"format") == 0)
1248 type_info->format=ConstantString(token);
1251 if (LocaleCompare((
char *) keyword,
"foundry") == 0)
1253 type_info->foundry=ConstantString(token);
1256 if (LocaleCompare((
char *) keyword,
"fullname") == 0)
1258 type_info->description=ConstantString(token);
1266 if (LocaleCompare((
char *) keyword,
"glyphs") == 0)
1268 if (SetTypeNodePath(filename,font_path,token,&type_info->glyphs) == MagickFalse)
1269 type_info=(
TypeInfo *) DestroyTypeNode(type_info);
1277 if (LocaleCompare((
char *) keyword,
"metrics") == 0)
1279 if (SetTypeNodePath(filename,font_path,token,&type_info->metrics) == MagickFalse)
1280 type_info=(
TypeInfo *) DestroyTypeNode(type_info);
1288 if (LocaleCompare((
char *) keyword,
"name") == 0)
1290 type_info->name=ConstantString(token);
1298 if (LocaleCompare((
char *) keyword,
"stealth") == 0)
1300 type_info->stealth=IsMagickTrue(token);
1303 if (LocaleCompare((
char *) keyword,
"stretch") == 0)
1305 type_info->stretch=(StretchType) ParseCommandOption(
1306 MagickStretchOptions,MagickFalse,token);
1309 if (LocaleCompare((
char *) keyword,
"style") == 0)
1311 type_info->style=(StyleType) ParseCommandOption(MagickStyleOptions,
1320 if (LocaleCompare((
char *) keyword,
"weight") == 0)
1325 weight=ParseCommandOption(MagickWeightOptions,MagickFalse,token);
1327 weight=StringToUnsignedLong(token);
1328 type_info->weight=(size_t) weight;
1337 token=(
char *) RelinquishMagickMemory(token);
1338 return(status != 0 ? MagickTrue : MagickFalse);
1359MagickExport MagickBooleanType TypeComponentGenesis(
void)
1362 type_semaphore=AllocateSemaphoreInfo();
1384MagickExport
void TypeComponentTerminus(
void)
1387 ActivateSemaphoreInfo(&type_semaphore);
1388 LockSemaphoreInfo(type_semaphore);
1390 type_cache=DestroySplayTree(type_cache);
1391 UnlockSemaphoreInfo(type_semaphore);
1392 DestroySemaphoreInfo(&type_semaphore);