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"
48#include "MagickCore/exception-private.h"
49#include "MagickCore/image-private.h"
50#include "MagickCore/linked-list.h"
51#include "MagickCore/log.h"
52#include "MagickCore/memory_.h"
53#include "MagickCore/memory-private.h"
54#include "MagickCore/nt-feature.h"
55#include "MagickCore/nt-base-private.h"
56#include "MagickCore/option.h"
57#include "MagickCore/semaphore.h"
58#include "MagickCore/splay-tree.h"
59#include "MagickCore/string_.h"
60#include "MagickCore/string-private.h"
61#include "MagickCore/type.h"
62#include "MagickCore/type-private.h"
63#include "MagickCore/token.h"
64#include "MagickCore/utility.h"
65#include "MagickCore/utility-private.h"
66#include "MagickCore/xml-tree.h"
67#if defined(MAGICKCORE_FONTCONFIG_DELEGATE)
68# include "fontconfig/fontconfig.h"
69#if (FC_VERSION < 20209)
71#define FC_WIDTH "width"
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
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
99#if defined(MAGICKCORE_WINDOWS_SUPPORT)
100# include "MagickCore/nt-feature.h"
106#define MagickTypeFilename "type.xml"
113 "<?xml version=\"1.0\"?>"
115 " <type stealth=\"True\" name=\"fixed\" family=\"helvetica\"/>"
116 " <type stealth=\"True\" name=\"helvetica\" family=\"helvetica\"/>"
131static MagickBooleanType
133 LoadTypeCache(
SplayTreeInfo *,
const char *,
const char *,
const size_t,
163static void *DestroyTypeNode(
void *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)
174 p->description=DestroyString(p->description);
175 if (p->family != (
char *) NULL)
176 p->family=DestroyString(p->family);
177 if (p->encoding != (
char *) NULL)
178 p->encoding=DestroyString(p->encoding);
179 if (p->foundry != (
char *) NULL)
180 p->foundry=DestroyString(p->foundry);
181 if (p->format != (
char *) NULL)
182 p->format=DestroyString(p->format);
183 if (p->metrics != (
char *) NULL)
184 p->metrics=DestroyString(p->metrics);
185 if (p->glyphs != (
char *) NULL)
186 p->glyphs=DestroyString(p->glyphs);
187 return(RelinquishMagickMemory(p));
196 cache=NewSplayTree(CompareSplayTreeString,(
void *(*)(
void *)) NULL,
199 ThrowFatalException(ResourceLimitFatalError,
"MemoryAllocationFailed");
200#if !MAGICKCORE_ZERO_CONFIGURATION_SUPPORT
204 path[MagickPathExtent];
213 options=GetConfigureOptions(filename,exception);
214 option=(
const StringInfo *) GetNextValueInLinkedList(options);
217 (void) CopyMagickString(path,GetStringInfoPath(option),MagickPathExtent);
218 (void) LoadTypeCache(cache,(
const char *) GetStringInfoDatum(option),
219 GetStringInfoPath(option),0,exception);
220 option=(
const StringInfo *) GetNextValueInLinkedList(options);
222 options=DestroyConfigureOptions(options);
223 font_path=GetEnvironmentValue(
"MAGICK_FONT_PATH");
224 if (font_path != (
char *) NULL)
232 (void) FormatLocaleString(path,MagickPathExtent,
"%s%s%s",font_path,
233 DirectorySeparator,filename);
234 xml=FileToString(path,~0UL,exception);
235 if (xml != (
void *) NULL)
237 (void) LoadTypeCache(cache,xml,path,0,exception);
238 xml=DestroyString(xml);
240 font_path=DestroyString(font_path);
244 magick_unreferenced(filename);
246 if (GetNumberOfNodesInSplayTree(cache) == 0)
247 (void) LoadTypeCache(cache,TypeMap,
"built-in",0,exception);
276MagickExport
const TypeInfo *GetTypeInfo(
const char *name,
280 if (IsTypeTreeInstantiated(exception) == MagickFalse)
282 if ((name == (
const char *) NULL) || (LocaleCompare(name,
"*") == 0))
283 return((
const TypeInfo *) GetRootValueFromSplayTree(type_cache));
284 return((
const TypeInfo *) GetValueFromSplayTree(type_cache,name));
322MagickExport
const TypeInfo *GetTypeInfoByFamily(
const char *family,
323 const StyleType style,
const StretchType stretch,
const size_t weight,
326 typedef struct _Fontmap
349 {
"fixed",
"courier" },
350 {
"modern",
"courier" },
351 {
"monotype corsiva",
"courier" },
352 {
"news gothic",
"helvetica" },
353 {
"system",
"courier" },
354 {
"terminal",
"courier" },
355 {
"wingdings",
"symbol" }
361 (void) GetTypeInfo(
"*",exception);
364 font_weight=(size_t) (weight == 0 ? 400 : weight);
365 LockSemaphoreInfo(type_semaphore);
366 ResetSplayTreeIterator(type_cache);
368 p=(
const TypeInfo *) GetNextValueInSplayTree(type_cache);
369 while (p != (
const TypeInfo *) NULL)
371 if (p->family == (
char *) NULL)
373 p=(
const TypeInfo *) GetNextValueInSplayTree(type_cache);
376 if (family == (
const char *) NULL)
378 if ((LocaleCompare(p->family,
"arial") != 0) &&
379 (LocaleCompare(p->family,
"helvetica") != 0))
381 p=(
const TypeInfo *) GetNextValueInSplayTree(type_cache);
386 if (LocaleCompare(p->family,family) != 0)
388 p=(
const TypeInfo *) GetNextValueInSplayTree(type_cache);
391 if ((style != UndefinedStyle) && (style != AnyStyle) && (p->style != style))
393 p=(
const TypeInfo *) GetNextValueInSplayTree(type_cache);
396 if ((stretch != UndefinedStretch) && (stretch != AnyStretch) &&
397 (p->stretch != stretch))
399 p=(
const TypeInfo *) GetNextValueInSplayTree(type_cache);
402 if (p->weight != font_weight)
404 p=(
const TypeInfo *) GetNextValueInSplayTree(type_cache);
410 UnlockSemaphoreInfo(type_semaphore);
411 if (type_info != (
const TypeInfo *) NULL)
417 LockSemaphoreInfo(type_semaphore);
418 ResetSplayTreeIterator(type_cache);
419 p=(
const TypeInfo *) GetNextValueInSplayTree(type_cache);
420 while (p != (
const TypeInfo *) NULL)
422 if (p->family == (
char *) NULL)
424 p=(
const TypeInfo *) GetNextValueInSplayTree(type_cache);
427 if (family == (
const char *) NULL)
429 if ((LocaleCompare(p->family,
"arial") != 0) &&
430 (LocaleCompare(p->family,
"helvetica") != 0))
432 p=(
const TypeInfo *) GetNextValueInSplayTree(type_cache);
437 if (LocaleCompare(p->family,family) != 0)
439 p=(
const TypeInfo *) GetNextValueInSplayTree(type_cache);
443 if ((style == UndefinedStyle) || (style == AnyStyle) || (p->style == style))
446 if (((style == ItalicStyle) || (style == ObliqueStyle)) &&
447 ((p->style == ItalicStyle) || (p->style == ObliqueStyle)))
449 score+=(size_t) ((16L*(800L-((ssize_t) MagickMax(MagickMin(font_weight,900),
450 p->weight)-(ssize_t) MagickMin(MagickMin(font_weight,900),p->weight))))/
452 if ((stretch == UndefinedStretch) || (stretch == AnyStretch))
456 range=(ssize_t) UltraExpandedStretch-(ssize_t) NormalStretch;
457 score+=(size_t) ((ssize_t) (8L*(range-((ssize_t) MagickMax(stretch,
458 p->stretch)-(ssize_t) MagickMin(stretch,p->stretch))))/range);
460 if (score > max_score)
465 p=(
const TypeInfo *) GetNextValueInSplayTree(type_cache);
467 UnlockSemaphoreInfo(type_semaphore);
468 if (type_info != (
const TypeInfo *) NULL)
473 for (i=0; i < (ssize_t) (
sizeof(fontmap)/
sizeof(fontmap[0])); i++)
475 if (family == (
const char *) NULL)
477 if ((LocaleCompare(fontmap[i].name,
"arial") != 0) &&
478 (LocaleCompare(fontmap[i].name,
"helvetica") != 0))
482 if (LocaleCompare(fontmap[i].name,family) != 0)
484 type_info=GetTypeInfoByFamily(fontmap[i].substitute,style,stretch,weight,
488 if (type_info != (
const TypeInfo *) NULL)
490 (void) ThrowMagickException(exception,GetMagickModule(),TypeWarning,
491 "FontSubstitutionRequired",
"`%s'",type_info->family);
494 if (family != (
const char *) NULL)
495 type_info=GetTypeInfoByFamily((
const char *) NULL,style,stretch,weight,
528#if defined(__cplusplus) || defined(c_plusplus)
532static int TypeInfoCompare(
const void *x,
const void *y)
540 if (LocaleCompare((*p)->path,(*q)->path) == 0)
541 return(LocaleCompare((*p)->name,(*q)->name));
542 return(LocaleCompare((*p)->path,(*q)->path));
545#if defined(__cplusplus) || defined(c_plusplus)
549MagickExport
const TypeInfo **GetTypeInfoList(
const char *pattern,
564 assert(pattern != (
char *) NULL);
565 assert(number_fonts != (
size_t *) NULL);
566 if (IsEventLogging() != MagickFalse)
567 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",pattern);
569 p=GetTypeInfo(
"*",exception);
572 fonts=(
const TypeInfo **) AcquireQuantumMemory((
size_t)
573 GetNumberOfNodesInSplayTree(type_cache)+1UL,
sizeof(*fonts));
574 if (fonts == (
const TypeInfo **) NULL)
579 LockSemaphoreInfo(type_semaphore);
580 ResetSplayTreeIterator(type_cache);
581 p=(
const TypeInfo *) GetNextValueInSplayTree(type_cache);
582 for (i=0; p != (
const TypeInfo *) NULL; )
584 if ((p->stealth == MagickFalse) &&
585 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
587 p=(
const TypeInfo *) GetNextValueInSplayTree(type_cache);
589 UnlockSemaphoreInfo(type_semaphore);
590 qsort((
void *) fonts,(
size_t) i,
sizeof(*fonts),TypeInfoCompare);
592 *number_fonts=(size_t) i;
624#if defined(__cplusplus) || defined(c_plusplus)
628static int TypeCompare(
const void *x,
const void *y)
636 return(LocaleCompare(*p,*q));
639#if defined(__cplusplus) || defined(c_plusplus)
643MagickExport
char **GetTypeList(
const char *pattern,
size_t *number_fonts,
658 assert(pattern != (
char *) NULL);
659 assert(number_fonts != (
size_t *) NULL);
660 if (IsEventLogging() != MagickFalse)
661 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",pattern);
663 p=GetTypeInfo(
"*",exception);
665 return((
char **) NULL);
666 fonts=(
char **) AcquireQuantumMemory((
size_t)
667 GetNumberOfNodesInSplayTree(type_cache)+1UL,
sizeof(*fonts));
668 if (fonts == (
char **) NULL)
669 return((
char **) NULL);
673 LockSemaphoreInfo(type_semaphore);
674 ResetSplayTreeIterator(type_cache);
675 p=(
const TypeInfo *) GetNextValueInSplayTree(type_cache);
676 for (i=0; p != (
const TypeInfo *) NULL; )
678 if ((p->stealth == MagickFalse) &&
679 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
680 fonts[i++]=ConstantString(p->name);
681 p=(
const TypeInfo *) GetNextValueInSplayTree(type_cache);
683 UnlockSemaphoreInfo(type_semaphore);
684 qsort((
void *) fonts,(
size_t) i,
sizeof(*fonts),TypeCompare);
685 fonts[i]=(
char *) NULL;
686 *number_fonts=(size_t) i;
714#if defined(MAGICKCORE_FONTCONFIG_DELEGATE)
715MagickExport MagickBooleanType LoadFontConfigFonts(
SplayTreeInfo *type_cache,
718#if !defined(FC_FULLNAME)
719#define FC_FULLNAME "fullname"
723 extension[MagickPathExtent],
724 name[MagickPathExtent];
769 font_config=FcConfigGetCurrent();
770 if (font_config == (FcConfig *) NULL)
772 FcConfigSetRescanInterval(font_config,0);
773 font_set=(FcFontSet *) NULL;
774 object_set=FcObjectSetBuild(FC_FULLNAME,FC_FAMILY,FC_STYLE,FC_SLANT,
775 FC_WIDTH,FC_WEIGHT,FC_FILE,FC_INDEX,(
char *) NULL);
776 if (object_set != (FcObjectSet *) NULL)
778 pattern=FcPatternCreate();
779 if (pattern != (FcPattern *) NULL)
781 font_set=FcFontList(font_config,pattern,object_set);
782 FcPatternDestroy(pattern);
784 FcObjectSetDestroy(object_set);
786 if (font_set == (FcFontSet *) NULL)
788 FcConfigDestroy(font_config);
791 for (i=0; i < (ssize_t) font_set->nfont; i++)
793 status=FcPatternGetString(font_set->fonts[i],FC_FAMILY,0,&family);
794 if (status != FcResultMatch)
796 status=FcPatternGetString(font_set->fonts[i],FC_FILE,0,&file);
797 if (status != FcResultMatch)
800 GetPathComponent((
const char *) file,ExtensionPath,extension);
801 if ((*extension !=
'\0') && (LocaleCompare(extension,
"gz") == 0))
803 type_info=(
TypeInfo *) AcquireMagickMemory(
sizeof(*type_info));
806 (void) memset(type_info,0,
sizeof(*type_info));
807 type_info->path=ConstantString(
"System Fonts");
808 type_info->signature=MagickCoreSignature;
809 (void) CopyMagickString(name,
"Unknown",MagickPathExtent);
810 status=FcPatternGetString(font_set->fonts[i],FC_FULLNAME,0,&fullname);
811 if ((status == FcResultMatch) && (fullname != (FcChar8 *) NULL))
812 (void) CopyMagickString(name,(
const char *) fullname,MagickPathExtent);
815 if (family != (FcChar8 *) NULL)
816 (void) CopyMagickString(name,(
const char *) family,MagickPathExtent);
817 status=FcPatternGetString(font_set->fonts[i],FC_STYLE,0,&style);
818 if ((status == FcResultMatch) && (style != (FcChar8 *) NULL) &&
819 (LocaleCompare((
const char *) style,
"Regular") != 0))
821 (void) ConcatenateMagickString(name,
" ",MagickPathExtent);
822 (void) ConcatenateMagickString(name,(
const char *) style,
826 type_info->name=ConstantString(name);
827 (void) SubstituteString(&type_info->name,
" ",
"-");
828 type_info->family=ConstantString((
const char *) family);
829 status=FcPatternGetInteger(font_set->fonts[i],FC_INDEX,0,&index);
830 if (status == FcResultMatch)
831 type_info->face=(size_t) index;
832 status=FcPatternGetInteger(font_set->fonts[i],FC_SLANT,0,&slant);
833 type_info->style=NormalStyle;
834 if (slant == FC_SLANT_ITALIC)
835 type_info->style=ItalicStyle;
836 if (slant == FC_SLANT_OBLIQUE)
837 type_info->style=ObliqueStyle;
838 status=FcPatternGetInteger(font_set->fonts[i],FC_WIDTH,0,&width);
839 type_info->stretch=NormalStretch;
840 if (width >= FC_WIDTH_ULTRACONDENSED)
841 type_info->stretch=UltraCondensedStretch;
842 if (width >= FC_WIDTH_EXTRACONDENSED)
843 type_info->stretch=ExtraCondensedStretch;
844 if (width >= FC_WIDTH_CONDENSED)
845 type_info->stretch=CondensedStretch;
846 if (width >= FC_WIDTH_SEMICONDENSED)
847 type_info->stretch=SemiCondensedStretch;
848 if (width >= FC_WIDTH_NORMAL)
849 type_info->stretch=NormalStretch;
850 if (width >= FC_WIDTH_SEMIEXPANDED)
851 type_info->stretch=SemiExpandedStretch;
852 if (width >= FC_WIDTH_EXPANDED)
853 type_info->stretch=ExpandedStretch;
854 if (width >= FC_WIDTH_EXTRAEXPANDED)
855 type_info->stretch=ExtraExpandedStretch;
856 if (width >= FC_WIDTH_ULTRAEXPANDED)
857 type_info->stretch=UltraExpandedStretch;
858 type_info->weight=400;
859 status=FcPatternGetInteger(font_set->fonts[i],FC_WEIGHT,0,&weight);
860 if (weight >= FC_WEIGHT_THIN)
861 type_info->weight=100;
862 if (weight >= FC_WEIGHT_EXTRALIGHT)
863 type_info->weight=200;
864 if (weight >= FC_WEIGHT_LIGHT)
865 type_info->weight=300;
866 if (weight >= FC_WEIGHT_NORMAL)
867 type_info->weight=400;
868 if (weight >= FC_WEIGHT_MEDIUM)
869 type_info->weight=500;
870 if (weight >= FC_WEIGHT_DEMIBOLD)
871 type_info->weight=600;
872 if (weight >= FC_WEIGHT_BOLD)
873 type_info->weight=700;
874 if (weight >= FC_WEIGHT_EXTRABOLD)
875 type_info->weight=800;
876 if (weight >= FC_WEIGHT_BLACK)
877 type_info->weight=900;
878 type_info->glyphs=ConstantString((
const char *) file);
879 (void) AddValueToSplayTree(type_cache,type_info->name,type_info);
881 FcFontSetDestroy(font_set);
882 FcConfigDestroy(font_config);
887static MagickBooleanType IsTypeTreeInstantiated(
ExceptionInfo *exception)
892 ActivateSemaphoreInfo(&type_semaphore);
893 LockSemaphoreInfo(type_semaphore);
899 splay_tree=AcquireTypeCache(MagickTypeFilename,exception);
900#if defined(MAGICKCORE_WINDOWS_SUPPORT)
901 (void) NTAcquireTypeCache(splay_tree,exception);
903#if defined(MAGICKCORE_FONTCONFIG_DELEGATE)
904 (void) LoadFontConfigFonts(splay_tree,exception);
906 type_cache=splay_tree;
908 UnlockSemaphoreInfo(type_semaphore);
910 return(type_cache != (
SplayTreeInfo *) NULL ? MagickTrue : MagickFalse);
937MagickExport MagickBooleanType ListTypeInfo(FILE *file,
ExceptionInfo *exception)
956 if (file == (FILE *) NULL)
959 type_info=GetTypeInfoList(
"*",&number_fonts,exception);
960 if (type_info == (
const TypeInfo **) NULL)
962 path=(
const char *) NULL;
963 for (i=0; i < (ssize_t) number_fonts; i++)
965 if (type_info[i]->stealth != MagickFalse)
967 if (((path == (
const char *) NULL) ||
968 (LocaleCompare(path,type_info[i]->path) != 0)) &&
969 (type_info[i]->path != (
char *) NULL))
970 (void) FormatLocaleFile(file,
"\nPath: %s\n",type_info[i]->path);
971 path=type_info[i]->path;
973 if (type_info[i]->name != (
char *) NULL)
974 name=type_info[i]->name;
976 if (type_info[i]->family != (
char *) NULL)
977 family=type_info[i]->family;
978 style=CommandOptionToMnemonic(MagickStyleOptions,type_info[i]->style);
979 stretch=CommandOptionToMnemonic(MagickStretchOptions,type_info[i]->stretch);
981 if (type_info[i]->glyphs != (
char *) NULL)
982 glyphs=type_info[i]->glyphs;
983 (void) FormatLocaleFile(file,
" Font: %s\n",name);
984 (void) FormatLocaleFile(file,
" family: %s\n",family);
985 (void) FormatLocaleFile(file,
" style: %s\n",style);
986 (void) FormatLocaleFile(file,
" stretch: %s\n",stretch);
987 (void) FormatLocaleFile(file,
" weight: %.20g\n",(
double)
988 type_info[i]->weight);
989 (void) FormatLocaleFile(file,
" glyphs: %s\n",glyphs);
990 (void) FormatLocaleFile(file,
" index: %d\n",(
int)
994 type_info=(
const TypeInfo **) RelinquishMagickMemory((
void *) type_info);
1029static inline MagickBooleanType SetTypeNodePath(
const char *filename,
1030 char *font_path,
const char *token,
char **target)
1035 path=ConstantString(token);
1036#if defined(MAGICKCORE_WINDOWS_SUPPORT)
1037 if (strchr(path,
'@') != (
char *) NULL)
1038 SubstituteString(&path,
"@ghostscript_font_path@",font_path);
1040 if (IsPathAccessible(path) == MagickFalse)
1045 path=DestroyString(path);
1046 GetPathComponent(filename,HeadPath,font_path);
1047 (void) ConcatenateMagickString(font_path,DirectorySeparator,
1049 (void) ConcatenateMagickString(font_path,token,MagickPathExtent);
1050 path=ConstantString(font_path);
1051#if defined(MAGICKCORE_WINDOWS_SUPPORT)
1052 if (strchr(path,
'@') != (
char *) NULL)
1053 SubstituteString(&path,
"@ghostscript_font_path@",
"");
1055 if (IsPathAccessible(path) == MagickFalse)
1057 path=DestroyString(path);
1058 return(MagickFalse);
1066static MagickBooleanType LoadTypeCache(
SplayTreeInfo *cache,
const char *xml,
1067 const char *filename,
const size_t depth,
ExceptionInfo *exception)
1070 font_path[MagickPathExtent],
1071 keyword[MagickPathExtent],
1089 if (IsEventLogging() != MagickFalse)
1090 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
1091 "Loading type configure file \"%s\" ...",filename);
1092 if (xml == (
const char *) NULL)
1093 return(MagickFalse);
1096 token=AcquireString(xml);
1097 extent=strlen(token)+MagickPathExtent;
1098#if defined(MAGICKCORE_WINDOWS_SUPPORT)
1103 if (NTGhostscriptFonts(font_path,MagickPathExtent-2) != MagickFalse)
1104 (void) ConcatenateMagickString(font_path,DirectorySeparator,
1107 for (q=(
char *) xml; *q !=
'\0'; )
1112 (void) GetNextToken(q,&q,extent,token);
1115 (void) CopyMagickString(keyword,token,MagickPathExtent);
1116 if (LocaleNCompare(keyword,
"<!DOCTYPE",9) == 0)
1121 while ((LocaleNCompare(q,
"]>",2) != 0) && (*q !=
'\0'))
1122 (void) GetNextToken(q,&q,extent,token);
1125 if (LocaleNCompare(keyword,
"<!--",4) == 0)
1130 while ((LocaleNCompare(q,
"->",2) != 0) && (*q !=
'\0'))
1131 (void) GetNextToken(q,&q,extent,token);
1134 if (LocaleCompare(keyword,
"<include") == 0)
1139 while (((*token !=
'/') && (*(token+1) !=
'>')) && (*q !=
'\0'))
1141 (void) CopyMagickString(keyword,token,MagickPathExtent);
1142 (void) GetNextToken(q,&q,extent,token);
1145 (void) GetNextToken(q,&q,extent,token);
1146 if (LocaleCompare(keyword,
"file") == 0)
1148 if (depth > MagickMaxRecursionDepth)
1149 (void) ThrowMagickException(exception,GetMagickModule(),
1150 ConfigureError,
"IncludeNodeNestedTooDeeply",
"`%s'",token);
1154 path[MagickPathExtent],
1161 GetPathComponent(filename,HeadPath,path);
1163 (void) ConcatenateMagickString(path,DirectorySeparator,
1165 if (*token == *DirectorySeparator)
1166 (void) CopyMagickString(path,token,MagickPathExtent);
1168 (
void) ConcatenateMagickString(path,token,MagickPathExtent);
1169 sans_exception=AcquireExceptionInfo();
1170 file_xml=FileToString(path,~0UL,sans_exception);
1171 sans_exception=DestroyExceptionInfo(sans_exception);
1172 if (file_xml != (
char *) NULL)
1174 status&=(MagickStatusType) LoadTypeCache(cache,file_xml,
1175 path,depth+1,exception);
1176 file_xml=(
char *) RelinquishMagickMemory(file_xml);
1183 if (LocaleCompare(keyword,
"<type") == 0)
1188 type_info=(
TypeInfo *) AcquireCriticalMemory(
sizeof(*type_info));
1189 (void) memset(type_info,0,
sizeof(*type_info));
1190 type_info->path=ConstantString(filename);
1191 type_info->signature=MagickCoreSignature;
1194 if (type_info == (
TypeInfo *) NULL)
1196 if ((LocaleCompare(keyword,
"/>") == 0) ||
1197 (LocaleCompare(keyword,
"</policy>") == 0))
1199 status=AddValueToSplayTree(cache,type_info->name,type_info);
1200 if (status == MagickFalse)
1201 (void) ThrowMagickException(exception,GetMagickModule(),
1202 ResourceLimitError,
"MemoryAllocationFailed",
"`%s'",type_info->name);
1206 (void) GetNextToken(q,(
const char **) NULL,extent,token);
1209 (void) GetNextToken(q,&q,extent,token);
1210 (void) GetNextToken(q,&q,extent,token);
1216 if (LocaleCompare((
char *) keyword,
"encoding") == 0)
1218 type_info->encoding=ConstantString(token);
1226 if (LocaleCompare((
char *) keyword,
"face") == 0)
1228 type_info->face=StringToUnsignedLong(token);
1231 if (LocaleCompare((
char *) keyword,
"family") == 0)
1233 type_info->family=ConstantString(token);
1236 if (LocaleCompare((
char *) keyword,
"format") == 0)
1238 type_info->format=ConstantString(token);
1241 if (LocaleCompare((
char *) keyword,
"foundry") == 0)
1243 type_info->foundry=ConstantString(token);
1246 if (LocaleCompare((
char *) keyword,
"fullname") == 0)
1248 type_info->description=ConstantString(token);
1256 if (LocaleCompare((
char *) keyword,
"glyphs") == 0)
1258 if (SetTypeNodePath(filename,font_path,token,&type_info->glyphs) ==
1260 type_info=(
TypeInfo *) DestroyTypeNode(type_info);
1268 if (LocaleCompare((
char *) keyword,
"metrics") == 0)
1270 if (SetTypeNodePath(filename,font_path,token,&type_info->metrics) ==
1272 type_info=(
TypeInfo *) DestroyTypeNode(type_info);
1280 if (LocaleCompare((
char *) keyword,
"name") == 0)
1282 type_info->name=ConstantString(token);
1290 if (LocaleCompare((
char *) keyword,
"stealth") == 0)
1292 type_info->stealth=IsStringTrue(token);
1295 if (LocaleCompare((
char *) keyword,
"stretch") == 0)
1297 type_info->stretch=(StretchType) ParseCommandOption(
1298 MagickStretchOptions,MagickFalse,token);
1301 if (LocaleCompare((
char *) keyword,
"style") == 0)
1303 type_info->style=(StyleType) ParseCommandOption(MagickStyleOptions,
1312 if (LocaleCompare((
char *) keyword,
"weight") == 0)
1317 weight=ParseCommandOption(MagickWeightOptions,MagickFalse,token);
1319 weight=(ssize_t) StringToUnsignedLong(token);
1320 type_info->weight=(size_t) weight;
1329 token=(
char *) RelinquishMagickMemory(token);
1330 return(status != 0 ? MagickTrue : MagickFalse);
1351MagickPrivate MagickBooleanType TypeComponentGenesis(
void)
1354 type_semaphore=AcquireSemaphoreInfo();
1376MagickPrivate
void TypeComponentTerminus(
void)
1379 ActivateSemaphoreInfo(&type_semaphore);
1380 LockSemaphoreInfo(type_semaphore);
1382 type_cache=DestroySplayTree(type_cache);
1383 UnlockSemaphoreInfo(type_semaphore);
1384 RelinquishSemaphoreInfo(&type_semaphore);