/* %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % % % % % % L o a d T y p e L i s t s % % % % % % % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% % % LoadTypeList() loads one or more type configuration files which provides a % mapping between type attributes and a type name. % % The format of the LoadTypeLists method is: % % MagickBooleanType LoadTypeLists(const char *filename, % ExceptionInfo *exception) % % A description of each parameter follows: % % o filename: the font file name. % % o exception: return any errors or warnings in this structure. % */ static MagickBooleanType LoadTypeLists(const char *filename, ExceptionInfo *exception) { #if defined(MAGICKCORE_ZERO_CONFIGURATION_SUPPORT) return(LoadTypeList(TypeMap,"built-in",0,exception)); #else char *font_path, path[MaxTextExtent]; const StringInfo *option; LinkedListInfo *options; MagickStatusType status; status=MagickFalse; *path='\0'; options=GetConfigureOptions(filename,exception); option=(const StringInfo *) GetNextValueInLinkedList(options); while (option != (const StringInfo *) NULL) { (void) CopyMagickString(path,GetStringInfoPath(option),MaxTextExtent); status&=LoadTypeList((const char *) GetStringInfoDatum(option), GetStringInfoPath(option),0,exception); option=(const StringInfo *) GetNextValueInLinkedList(options); } options=DestroyConfigureOptions(options); font_path=GetEnvironmentValue("MAGICK_FONT_PATH"); if (font_path != (char *) NULL) { char *option; /* Search MAGICK_FONT_PATH. */ (void) FormatLocaleString(path,MaxTextExtent,"%s%s%s",font_path, DirectorySeparator,filename); option=FileToString(path,~0UL,exception); if (option != (void *) NULL) { status&=LoadTypeList(option,path,0,exception); option=DestroyString(option); } font_path=DestroyString(font_path); } if ((type_list == (SplayTreeInfo *) NULL) || (GetNumberOfNodesInSplayTree(type_list) == 0)) status&=LoadTypeList(TypeMap,"built-in",0,exception); return(status != 0 ? MagickTrue : MagickFalse); #endif }
static MagickBooleanType LoadTypeList(const char *xml,const char *filename, const size_t depth,ExceptionInfo *exception) { char font_path[MaxTextExtent], keyword[MaxTextExtent], *token; const char *q; MagickBooleanType status; TypeInfo *type_info; /* Load the type map file. */ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(), "Loading type configure file \"%s\" ...",filename); if (xml == (const char *) NULL) return(MagickFalse); if (type_list == (SplayTreeInfo *) NULL) { type_list=NewSplayTree(CompareSplayTreeString,(void *(*)(void *)) NULL, DestroyTypeNode); if (type_list == (SplayTreeInfo *) NULL) { ThrowFileException(exception,ResourceLimitError, "MemoryAllocationFailed",filename); return(MagickFalse); } } status=MagickTrue; type_info=(TypeInfo *) NULL; token=AcquireString(xml); #if defined(MAGICKCORE_WINDOWS_SUPPORT) /* Determine the Ghostscript font path. */ *font_path='\0'; if (NTGhostscriptFonts(font_path,MaxTextExtent-2)) (void) ConcatenateMagickString(font_path,DirectorySeparator,MaxTextExtent); #endif for (q=(char *) xml; *q != '\0'; ) { /* Interpret XML. */ GetMagickToken(q,&q,token); if (*token == '\0') break; (void) CopyMagickString(keyword,token,MaxTextExtent); if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0) { /* Doctype element. */ while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0')) GetMagickToken(q,&q,token); continue; } if (LocaleNCompare(keyword,"<!--",4) == 0) { /* Comment element. */ while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0')) GetMagickToken(q,&q,token); continue; } if (LocaleCompare(keyword,"<include") == 0) { /* Include element. */ while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0')) { (void) CopyMagickString(keyword,token,MaxTextExtent); GetMagickToken(q,&q,token); if (*token != '=') continue; GetMagickToken(q,&q,token); if (LocaleCompare(keyword,"file") == 0) { if (depth > 200) (void) ThrowMagickException(exception,GetMagickModule(), ConfigureError,"IncludeNodeNestedTooDeeply","`%s'",token); else { char path[MaxTextExtent], *xml; ExceptionInfo *sans_exception; *path='\0'; GetPathComponent(filename,HeadPath,path); if (*path != '\0') (void) ConcatenateMagickString(path,DirectorySeparator, MaxTextExtent); if (*token == *DirectorySeparator) (void) CopyMagickString(path,token,MaxTextExtent); else (void) ConcatenateMagickString(path,token,MaxTextExtent); sans_exception=AcquireExceptionInfo(); xml=FileToString(path,~0UL,sans_exception); sans_exception=DestroyExceptionInfo(sans_exception); if (xml != (char *) NULL) { status=LoadTypeList(xml,path,depth+1,exception); xml=(char *) RelinquishMagickMemory(xml); } } } } continue; } if (LocaleCompare(keyword,"<type") == 0) { /* Type element. */ type_info=(TypeInfo *) AcquireMagickMemory(sizeof(*type_info)); if (type_info == (TypeInfo *) NULL) ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); (void) ResetMagickMemory(type_info,0,sizeof(*type_info)); type_info->path=ConstantString(filename); type_info->signature=MagickSignature; continue; } if (type_info == (TypeInfo *) NULL) continue; if (LocaleCompare(keyword,"/>") == 0) { status=AddValueToSplayTree(type_list,type_info->name,type_info); if (status == MagickFalse) (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'",type_info->name); type_info=(TypeInfo *) NULL; } GetMagickToken(q,(const char **) NULL,token); if (*token != '=') continue; GetMagickToken(q,&q,token); GetMagickToken(q,&q,token); switch (*keyword) { case 'E': case 'e': { if (LocaleCompare((char *) keyword,"encoding") == 0) { type_info->encoding=ConstantString(token); break; } break; } case 'F': case 'f': { if (LocaleCompare((char *) keyword,"face") == 0) { type_info->face=StringToUnsignedLong(token); break; } if (LocaleCompare((char *) keyword,"family") == 0) { type_info->family=ConstantString(token); break; } if (LocaleCompare((char *) keyword,"format") == 0) { type_info->format=ConstantString(token); break; } if (LocaleCompare((char *) keyword,"foundry") == 0) { type_info->foundry=ConstantString(token); break; } if (LocaleCompare((char *) keyword,"fullname") == 0) { type_info->description=ConstantString(token); break; } break; } case 'G': case 'g': { if (LocaleCompare((char *) keyword,"glyphs") == 0) { char *path; path=ConstantString(token); #if defined(MAGICKCORE_WINDOWS_SUPPORT) if (strchr(path,'@') != (char *) NULL) SubstituteString(&path,"@ghostscript_font_path@",font_path); #endif if (IsPathAccessible(path) == MagickFalse) { /* Relative path. */ path=DestroyString(path); GetPathComponent(filename,HeadPath,font_path); (void) ConcatenateMagickString(font_path,DirectorySeparator, MaxTextExtent); (void) ConcatenateMagickString(font_path,token,MaxTextExtent); path=ConstantString(font_path); if (IsPathAccessible(path) == MagickFalse) { path=DestroyString(path); path=ConstantString(token); } } type_info->glyphs=path; break; } break; } case 'M': case 'm': { if (LocaleCompare((char *) keyword,"metrics") == 0) { char *path; path=ConstantString(token); #if defined(MAGICKCORE_WINDOWS_SUPPORT) if (strchr(path,'@') != (char *) NULL) SubstituteString(&path,"@ghostscript_font_path@",font_path); #endif if (IsPathAccessible(path) == MagickFalse) { /* Relative path. */ path=DestroyString(path); GetPathComponent(filename,HeadPath,font_path); (void) ConcatenateMagickString(font_path,DirectorySeparator, MaxTextExtent); (void) ConcatenateMagickString(font_path,token,MaxTextExtent); path=ConstantString(font_path); } type_info->metrics=path; break; } break; } case 'N': case 'n': { if (LocaleCompare((char *) keyword,"name") == 0) { type_info->name=ConstantString(token); break; } break; } case 'S': case 's': { if (LocaleCompare((char *) keyword,"stealth") == 0) { type_info->stealth=IsStringTrue(token); break; } if (LocaleCompare((char *) keyword,"stretch") == 0) { type_info->stretch=(StretchType) ParseCommandOption( MagickStretchOptions,MagickFalse,token); break; } if (LocaleCompare((char *) keyword,"style") == 0) { type_info->style=(StyleType) ParseCommandOption(MagickStyleOptions, MagickFalse,token); break; } break; } case 'W': case 'w': { if (LocaleCompare((char *) keyword,"weight") == 0) { type_info->weight=StringToUnsignedLong(token); if (LocaleCompare(token,"bold") == 0) type_info->weight=700; if (LocaleCompare(token,"normal") == 0) type_info->weight=400; break; } break; } default: break; } } token=(char *) RelinquishMagickMemory(token); return(status); }
static MagickBooleanType LoadTypeList(const char *xml,const char *filename, const unsigned long depth,ExceptionInfo *exception) { char font_path[MaxTextExtent]; const char *attribute; TypeInfo *type_info = (TypeInfo *) NULL; MagickBooleanType status; XMLTreeInfo *type, *type_map, *include; /* Load the type map file. */ (void) LogMagickEvent(ConfigureEvent,GetMagickModule(), "Loading type map \"%s\" ...",filename); if (xml == (const char *) NULL) return(MagickFalse); if (type_list == (SplayTreeInfo *) NULL) { type_list=NewSplayTree(CompareSplayTreeString,(void *(*)(void *)) NULL, DestroyTypeNode); if (type_list == (SplayTreeInfo *) NULL) { ThrowFileException(exception,ResourceLimitError, "MemoryAllocationFailed",filename); return(MagickFalse); } } type_map=NewXMLTree(xml,exception); if (type_map == (XMLTreeInfo *) NULL) return(MagickFalse); status=MagickTrue; include=GetXMLTreeChild(type_map,"include"); while (include != (XMLTreeInfo *) NULL) { /* Process include element. */ attribute=GetXMLTreeAttribute(include,"file"); if (attribute != (const char *) NULL) { if (depth > 200) (void) ThrowMagickException(exception,GetMagickModule(), ConfigureError,"IncludeElementNestedTooDeeply","`%s'",attribute); else { char path[MaxTextExtent], *xml; ExceptionInfo *sans_exception; GetPathComponent(filename,HeadPath,path); if (*path != '\0') (void) ConcatenateMagickString(path,DirectorySeparator, MaxTextExtent); (void) ConcatenateMagickString(path,attribute,MaxTextExtent); sans_exception=AcquireExceptionInfo(); xml=FileToString(path,~0,sans_exception); sans_exception=DestroyExceptionInfo(sans_exception); if (xml != (char *) NULL) { status=LoadTypeList(xml,path,depth+1,exception); xml=DestroyString(xml); } } } include=GetNextXMLTreeTag(include); } *font_path='\0'; #if defined(__WINDOWS__) if (NTGhostscriptFonts(font_path,MaxTextExtent-2)) (void) ConcatenateMagickString(font_path,DirectorySeparator,MaxTextExtent); #endif type=GetXMLTreeChild(type_map,"type"); while (type != (XMLTreeInfo *) NULL) { /* Process type element. */ type_info=(TypeInfo *) AcquireMagickMemory(sizeof(*type_info)); if (type_info == (TypeInfo *) NULL) ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed"); (void) ResetMagickMemory(type_info,0,sizeof(*type_info)); type_info->path=ConstantString(filename); type_info->signature=MagickSignature; attribute=GetXMLTreeAttribute(type,"encoding"); if (attribute != (const char *) NULL) type_info->encoding=ConstantString(attribute); attribute=GetXMLTreeAttribute(type,"face"); if (attribute != (const char *) NULL) type_info->face=(unsigned long) atol(attribute); attribute=GetXMLTreeAttribute(type,"family"); if (attribute != (const char *) NULL) type_info->family=ConstantString(attribute); attribute=GetXMLTreeAttribute(type,"format"); if (attribute != (const char *) NULL) type_info->format=ConstantString(attribute); attribute=GetXMLTreeAttribute(type,"foundry"); if (attribute != (const char *) NULL) type_info->foundry=ConstantString(attribute); attribute=GetXMLTreeAttribute(type,"fullname"); if (attribute != (const char *) NULL) type_info->description=ConstantString(attribute); attribute=GetXMLTreeAttribute(type,"glyphs"); if (attribute != (const char *) NULL) { char *path; path=ConstantString(attribute); #if defined(__WINDOWS__) if (strchr(path,'@') != (char *) NULL) (void) SubstituteString(&path,"@ghostscript_font_path@",font_path); #endif type_info->glyphs=path; } attribute=GetXMLTreeAttribute(type,"metrics"); if (attribute != (const char *) NULL) { char *path; path=ConstantString(attribute); #if defined(__WINDOWS__) if (strchr(path,'@') != (char *) NULL) (void) SubstituteString(&path,"@ghostscript_font_path@",font_path); #endif type_info->metrics=path; } attribute=GetXMLTreeAttribute(type,"name"); if (attribute != (const char *) NULL) type_info->name=ConstantString(attribute); attribute=GetXMLTreeAttribute(type,"stealth"); if (attribute != (const char *) NULL) type_info->stealth=IsMagickTrue(attribute); attribute=GetXMLTreeAttribute(type,"stretch"); if (attribute != (const char *) NULL) type_info->stretch=(StretchType) ParseMagickOption(MagickStretchOptions, MagickFalse,attribute); attribute=GetXMLTreeAttribute(type,"style"); if (attribute != (const char *) NULL) type_info->style=(StyleType) ParseMagickOption(MagickStyleOptions, MagickFalse,attribute); attribute=GetXMLTreeAttribute(type,"weight"); if (attribute != (const char *) NULL) { type_info->weight=(unsigned long) atol(attribute); if (LocaleCompare(attribute,"bold") == 0) type_info->weight=700; if (LocaleCompare(attribute,"normal") == 0) type_info->weight=400; } status=AddValueToSplayTree(type_list,type_info->name,type_info); if (status == MagickFalse) (void) ThrowMagickException(exception,GetMagickModule(), ResourceLimitError,"MemoryAllocationFailed","`%s'",filename); type=GetNextXMLTreeTag(type); } type_map=DestroyXMLTree(type_map); return(status); }