MagickCore  6.7.5
type.c
Go to the documentation of this file.
00001 /*
00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00003 %                                                                             %
00004 %                                                                             %
00005 %                                                                             %
00006 %                        TTTTT  Y   Y  PPPP   EEEEE                           %
00007 %                          T     Y Y   P   P  E                               %
00008 %                          T      Y    PPPP   EEE                             %
00009 %                          T      Y    P      E                               %
00010 %                          T      Y    P      EEEEE                           %
00011 %                                                                             %
00012 %                                                                             %
00013 %                       MagickCore Image Type Methods                         %
00014 %                                                                             %
00015 %                              Software Design                                %
00016 %                                John Cristy                                  %
00017 %                                 May 2001                                    %
00018 %                                                                             %
00019 %                                                                             %
00020 %  Copyright 1999-2007 ImageMagick Studio LLC, a non-profit organization      %
00021 %  dedicated to making software imaging solutions freely available.           %
00022 %                                                                             %
00023 %  You may not use this file except in compliance with the License.  You may  %
00024 %  obtain a copy of the License at                                            %
00025 %                                                                             %
00026 %    http://www.imagemagick.org/script/license.php                            %
00027 %                                                                             %
00028 %  Unless required by applicable law or agreed to in writing, software        %
00029 %  distributed under the License is distributed on an "AS IS" BASIS,          %
00030 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
00031 %  See the License for the specific language governing permissions and        %
00032 %  limitations under the License.                                             %
00033 %                                                                             %
00034 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00035 %
00036 %
00037 */
00038 
00039 /*
00040   Include declarations.
00041 */
00042 #include "MagickCore/studio.h"
00043 #include "MagickCore/blob.h"
00044 #include "MagickCore/client.h"
00045 #include "MagickCore/configure.h"
00046 #include "MagickCore/draw.h"
00047 #include "MagickCore/exception.h"
00048 #include "MagickCore/exception-private.h"
00049 #include "MagickCore/hashmap.h"
00050 #include "MagickCore/log.h"
00051 #include "MagickCore/memory_.h"
00052 #include "MagickCore/nt-base-private.h"
00053 #include "MagickCore/option.h"
00054 #include "MagickCore/semaphore.h"
00055 #include "MagickCore/splay-tree.h"
00056 #include "MagickCore/string_.h"
00057 #include "MagickCore/string-private.h"
00058 #include "MagickCore/type.h"
00059 #include "MagickCore/type-private.h"
00060 #include "MagickCore/token.h"
00061 #include "MagickCore/utility.h"
00062 #include "MagickCore/utility-private.h"
00063 #include "MagickCore/xml-tree.h"
00064 #if defined(MAGICKCORE_FONTCONFIG_DELEGATE)
00065 # include "fontconfig/fontconfig.h"
00066 #if (FC_VERSION < 20209)
00067 #undef FC_WEIGHT_LIGHT
00068 #define FC_WIDTH                  "width"    /* Int */
00069 #define FC_WIDTH_ULTRACONDENSED    50
00070 #define FC_WIDTH_EXTRACONDENSED    63
00071 #define FC_WIDTH_CONDENSED         75
00072 #define FC_WIDTH_SEMICONDENSED     87
00073 #define FC_WIDTH_NORMAL            100
00074 #define FC_WIDTH_SEMIEXPANDED      113
00075 #define FC_WIDTH_EXPANDED          125
00076 #define FC_WIDTH_EXTRAEXPANDED     150
00077 #define FC_WIDTH_ULTRAEXPANDED     200
00078 
00079 #define FC_WEIGHT_THIN             0
00080 #define FC_WEIGHT_EXTRALIGHT       40
00081 #define FC_WEIGHT_ULTRALIGHT       FC_WEIGHT_EXTRALIGHT
00082 #define FC_WEIGHT_LIGHT            50
00083 #define FC_WEIGHT_BOOK             75
00084 #define FC_WEIGHT_REGULAR          80
00085 #define FC_WEIGHT_NORMAL           FC_WEIGHT_REGULAR
00086 #define FC_WEIGHT_MEDIUM           100
00087 #define FC_WEIGHT_DEMIBOLD         180
00088 #define FC_WEIGHT_SEMIBOLD         FC_WEIGHT_DEMIBOLD
00089 #define FC_WEIGHT_BOLD             200
00090 #define FC_WEIGHT_EXTRABOLD        205
00091 #define FC_WEIGHT_ULTRABOLD        FC_WEIGHT_EXTRABOLD
00092 #define FC_WEIGHT_BLACK            210
00093 #define FC_WEIGHT_HEAVY            FC_WEIGHT_BLACK
00094 #endif
00095 #endif
00096 
00097 /*
00098   Define declarations.
00099 */
00100 #define MagickTypeFilename  "type.xml"
00101 
00102 /*
00103   Declare type map.
00104 */
00105 static const char
00106   *TypeMap = (const char *)
00107     "<?xml version=\"1.0\"?>"
00108     "<typemap>"
00109     "  <type stealth=\"True\" name=\"fixed\" family=\"helvetica\"/>"
00110     "  <type stealth=\"True\" name=\"helvetica\" family=\"helvetica\"/>"
00111     "</typemap>";
00112 
00113 /*
00114   Static declarations.
00115 */
00116 static SemaphoreInfo
00117   *type_semaphore = (SemaphoreInfo *) NULL;
00118 
00119 static volatile MagickBooleanType
00120   instantiate_type = MagickFalse;
00121 
00122 static SplayTreeInfo
00123   *type_list = (SplayTreeInfo *) NULL;
00124 
00125 /*
00126   Forward declarations.
00127 */
00128 static MagickBooleanType
00129   InitializeTypeList(ExceptionInfo *),
00130   LoadTypeLists(const char *,ExceptionInfo *);
00131 
00132 /*
00133 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00134 %                                                                             %
00135 %                                                                             %
00136 %                                                                             %
00137 +   G e t T y p e I n f o                                                     %
00138 %                                                                             %
00139 %                                                                             %
00140 %                                                                             %
00141 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00142 %
00143 %  GetTypeInfo searches the type list for the specified name and if found
00144 %  returns attributes for that type.
00145 %
00146 %  The format of the GetTypeInfo method is:
00147 %
00148 %      const TypeInfo *GetTypeInfo(const char *name,ExceptionInfo *exception)
00149 %
00150 %  A description of each parameter follows:
00151 %
00152 %    o name: the type name.
00153 %
00154 %    o exception: return any errors or warnings in this structure.
00155 %
00156 */
00157 MagickExport const TypeInfo *GetTypeInfo(const char *name,
00158   ExceptionInfo *exception)
00159 {
00160   assert(exception != (ExceptionInfo *) NULL);
00161   if ((type_list == (SplayTreeInfo *) NULL) ||
00162       (instantiate_type == MagickFalse))
00163     if (InitializeTypeList(exception) == MagickFalse)
00164       return((const TypeInfo *) NULL);
00165   if ((type_list == (SplayTreeInfo *) NULL) ||
00166       (GetNumberOfNodesInSplayTree(type_list) == 0))
00167     return((const TypeInfo *) NULL);
00168   if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
00169     {
00170       ResetSplayTreeIterator(type_list);
00171       return((const TypeInfo *) GetNextValueInSplayTree(type_list));
00172     }
00173   return((const TypeInfo *) GetValueFromSplayTree(type_list,name));
00174 }
00175 
00176 /*
00177 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00178 %                                                                             %
00179 %                                                                             %
00180 %                                                                             %
00181 +   G e t T y p e I n f o B y F a m i l y                                     %
00182 %                                                                             %
00183 %                                                                             %
00184 %                                                                             %
00185 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00186 %
00187 %  GetTypeInfoByFamily() searches the type list for the specified family and if
00188 %  found returns attributes for that type.
00189 %
00190 %  Type substitution and scoring algorithm contributed by Bob Friesenhahn.
00191 %
00192 %  The format of the GetTypeInfoByFamily method is:
00193 %
00194 %      const TypeInfo *GetTypeInfoByFamily(const char *family,
00195 %        const StyleType style,const StretchType stretch,
00196 %        const size_t weight,ExceptionInfo *exception)
00197 %
00198 %  A description of each parameter follows:
00199 %
00200 %    o family: the type family.
00201 %
00202 %    o style: the type style.
00203 %
00204 %    o stretch: the type stretch.
00205 %
00206 %    o weight: the type weight.
00207 %
00208 %    o exception: return any errors or warnings in this structure.
00209 %
00210 */
00211 
00212 static inline size_t MagickMax(const size_t x,const size_t y)
00213 {
00214   if (x > y)
00215     return(x);
00216   return(y);
00217 }
00218 
00219 static inline size_t MagickMin(const size_t x,const size_t y)
00220 {
00221   if (x < y)
00222     return(x);
00223   return(y);
00224 }
00225 
00226 MagickExport const TypeInfo *GetTypeInfoByFamily(const char *family,
00227   const StyleType style,const StretchType stretch,const size_t weight,
00228   ExceptionInfo *exception)
00229 {
00230   typedef struct _Fontmap
00231   {
00232     const char
00233       *name,
00234       *substitute;
00235   } Fontmap;
00236 
00237   const TypeInfo
00238     *type_info;
00239 
00240   register const TypeInfo
00241     *p;
00242 
00243   register ssize_t
00244     i;
00245 
00246   ssize_t
00247     range;
00248 
00249   static const Fontmap
00250     fontmap[] =
00251     {
00252       { "fixed", "courier" },
00253       { "modern","courier" },
00254       { "monotype corsiva", "courier" },
00255       { "news gothic", "helvetica" },
00256       { "system", "courier" },
00257       { "terminal", "courier" },
00258       { "wingdings", "symbol" },
00259       { NULL, NULL }
00260     };
00261 
00262   size_t
00263     max_score,
00264     score;
00265 
00266   /*
00267     Check for an exact type match.
00268   */
00269   (void) GetTypeInfo("*",exception);
00270   if (type_list == (SplayTreeInfo *) NULL)
00271     return((TypeInfo *) NULL);
00272   LockSemaphoreInfo(type_semaphore);
00273   ResetSplayTreeIterator(type_list);
00274   type_info=(const TypeInfo *) NULL;
00275   p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
00276   while (p != (const TypeInfo *) NULL)
00277   {
00278     if (p->family == (char *) NULL)
00279       {
00280         p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
00281         continue;
00282       }
00283     if (family == (const char *) NULL)
00284       {
00285         if ((LocaleCompare(p->family,"arial") != 0) &&
00286             (LocaleCompare(p->family,"helvetica") != 0))
00287           {
00288             p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
00289             continue;
00290           }
00291       }
00292     else
00293       if (LocaleCompare(p->family,family) != 0)
00294         {
00295           p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
00296           continue;
00297         }
00298     if ((style != UndefinedStyle) && (style != AnyStyle) && (p->style != style))
00299       {
00300         p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
00301         continue;
00302       }
00303     if ((stretch != UndefinedStretch) && (stretch != AnyStretch) &&
00304         (p->stretch != stretch))
00305       {
00306         p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
00307         continue;
00308       }
00309     if ((weight != 0) && (p->weight != weight))
00310       {
00311         p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
00312         continue;
00313       }
00314     type_info=p;
00315     break;
00316   }
00317   UnlockSemaphoreInfo(type_semaphore);
00318   if (type_info != (const TypeInfo *) NULL)
00319     return(type_info);
00320   /*
00321     Check for types in the same family.
00322   */
00323   max_score=0;
00324   LockSemaphoreInfo(type_semaphore);
00325   ResetSplayTreeIterator(type_list);
00326   p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
00327   while (p != (const TypeInfo *) NULL)
00328   {
00329     if (p->family == (char *) NULL)
00330       {
00331         p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
00332         continue;
00333       }
00334     if (family == (const char *) NULL)
00335       {
00336         if ((LocaleCompare(p->family,"arial") != 0) &&
00337             (LocaleCompare(p->family,"helvetica") != 0))
00338           {
00339             p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
00340             continue;
00341           }
00342       }
00343     else
00344       if (LocaleCompare(p->family,family) != 0)
00345         {
00346           p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
00347           continue;
00348         }
00349     score=0;
00350     if ((style == UndefinedStyle) || (style == AnyStyle) || (p->style == style))
00351       score+=32;
00352     else
00353       if (((style == ItalicStyle) || (style == ObliqueStyle)) &&
00354           ((p->style == ItalicStyle) || (p->style == ObliqueStyle)))
00355         score+=25;
00356     if (weight == 0)
00357       score+=16;
00358     else
00359       score+=(16*(800-((ssize_t) MagickMax(MagickMin(weight,900),p->weight)-
00360         (ssize_t) MagickMin(MagickMin(weight,900),p->weight))))/800;
00361     if ((stretch == UndefinedStretch) || (stretch == AnyStretch))
00362       score+=8;
00363     else
00364       {
00365         range=(ssize_t) UltraExpandedStretch-(ssize_t) NormalStretch;
00366         score+=(8*(range-((ssize_t) MagickMax(stretch,p->stretch)-
00367           (ssize_t) MagickMin(stretch,p->stretch))))/range;
00368       }
00369     if (score > max_score)
00370       {
00371         max_score=score;
00372         type_info=p;
00373       }
00374     p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
00375   }
00376   UnlockSemaphoreInfo(type_semaphore);
00377   if (type_info != (const TypeInfo *) NULL)
00378     return(type_info);
00379   /*
00380     Check for table-based substitution match.
00381   */
00382   for (i=0; fontmap[i].name != (char *) NULL; i++)
00383   {
00384     if (family == (const char *) NULL)
00385       {
00386         if ((LocaleCompare(fontmap[i].name,"arial") != 0) &&
00387             (LocaleCompare(fontmap[i].name,"helvetica") != 0))
00388           continue;
00389       }
00390     else
00391       if (LocaleCompare(fontmap[i].name,family) != 0)
00392         continue;
00393     type_info=GetTypeInfoByFamily(fontmap[i].substitute,style,stretch,weight,
00394       exception);
00395     break;
00396   }
00397   if (type_info != (const TypeInfo *) NULL)
00398     {
00399       (void) ThrowMagickException(exception,GetMagickModule(),TypeError,
00400         "FontSubstitutionRequired","`%s'",type_info->family);
00401       return(type_info);
00402     }
00403   if (family != (const char *) NULL)
00404     type_info=GetTypeInfoByFamily((const char *) NULL,style,stretch,weight,
00405       exception);
00406   return(type_info);
00407 }
00408 
00409 /*
00410 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00411 %                                                                             %
00412 %                                                                             %
00413 %                                                                             %
00414 %   G e t T y p e I n f o L i s t                                             %
00415 %                                                                             %
00416 %                                                                             %
00417 %                                                                             %
00418 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00419 %
00420 %  GetTypeInfoList() returns any fonts that match the specified pattern.
00421 %
00422 %  The format of the GetTypeInfoList function is:
00423 %
00424 %      const TypeInfo **GetTypeInfoList(const char *pattern,
00425 %        size_t *number_fonts,ExceptionInfo *exception)
00426 %
00427 %  A description of each parameter follows:
00428 %
00429 %    o pattern: Specifies a pointer to a text string containing a pattern.
00430 %
00431 %    o number_fonts:  This integer returns the number of types in the list.
00432 %
00433 %    o exception: return any errors or warnings in this structure.
00434 %
00435 */
00436 
00437 #if defined(__cplusplus) || defined(c_plusplus)
00438 extern "C" {
00439 #endif
00440 
00441 static int TypeInfoCompare(const void *x,const void *y)
00442 {
00443   const TypeInfo
00444     **p,
00445     **q;
00446 
00447   p=(const TypeInfo **) x,
00448   q=(const TypeInfo **) y;
00449   if (LocaleCompare((*p)->path,(*q)->path) == 0)
00450     return(LocaleCompare((*p)->name,(*q)->name));
00451   return(LocaleCompare((*p)->path,(*q)->path));
00452 }
00453 
00454 #if defined(__cplusplus) || defined(c_plusplus)
00455 }
00456 #endif
00457 
00458 MagickExport const TypeInfo **GetTypeInfoList(const char *pattern,
00459   size_t *number_fonts,ExceptionInfo *exception)
00460 {
00461   const TypeInfo
00462     **fonts;
00463 
00464   register const TypeInfo
00465     *p;
00466 
00467   register ssize_t
00468     i;
00469 
00470   /*
00471     Allocate type list.
00472   */
00473   assert(pattern != (char *) NULL);
00474   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
00475   assert(number_fonts != (size_t *) NULL);
00476   *number_fonts=0;
00477   p=GetTypeInfo("*",exception);
00478   if (p == (const TypeInfo *) NULL)
00479     return((const TypeInfo **) NULL);
00480   fonts=(const TypeInfo **) AcquireQuantumMemory((size_t)
00481     GetNumberOfNodesInSplayTree(type_list)+1UL,sizeof(*fonts));
00482   if (fonts == (const TypeInfo **) NULL)
00483     return((const TypeInfo **) NULL);
00484   /*
00485     Generate type list.
00486   */
00487   LockSemaphoreInfo(type_semaphore);
00488   ResetSplayTreeIterator(type_list);
00489   p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
00490   for (i=0; p != (const TypeInfo *) NULL; )
00491   {
00492     if ((p->stealth == MagickFalse) &&
00493         (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
00494       fonts[i++]=p;
00495     p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
00496   }
00497   UnlockSemaphoreInfo(type_semaphore);
00498   qsort((void *) fonts,(size_t) i,sizeof(*fonts),TypeInfoCompare);
00499   fonts[i]=(TypeInfo *) NULL;
00500   *number_fonts=(size_t) i;
00501   return(fonts);
00502 }
00503 
00504 /*
00505 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00506 %                                                                             %
00507 %                                                                             %
00508 %                                                                             %
00509 %   G e t T y p e L i s t                                                     %
00510 %                                                                             %
00511 %                                                                             %
00512 %                                                                             %
00513 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00514 %
00515 %  GetTypeList() returns any fonts that match the specified pattern.
00516 %
00517 %  The format of the GetTypeList function is:
00518 %
00519 %      char **GetTypeList(const char *pattern,size_t *number_fonts,
00520 %        ExceptionInfo *exception)
00521 %
00522 %  A description of each parameter follows:
00523 %
00524 %    o pattern: Specifies a pointer to a text string containing a pattern.
00525 %
00526 %    o number_fonts:  This integer returns the number of fonts in the list.
00527 %
00528 %    o exception: return any errors or warnings in this structure.
00529 %
00530 */
00531 
00532 #if defined(__cplusplus) || defined(c_plusplus)
00533 extern "C" {
00534 #endif
00535 
00536 static int TypeCompare(const void *x,const void *y)
00537 {
00538   register const char
00539     **p,
00540     **q;
00541 
00542   p=(const char **) x;
00543   q=(const char **) y;
00544   return(LocaleCompare(*p,*q));
00545 }
00546 
00547 #if defined(__cplusplus) || defined(c_plusplus)
00548 }
00549 #endif
00550 
00551 MagickExport char **GetTypeList(const char *pattern,size_t *number_fonts,
00552   ExceptionInfo *exception)
00553 {
00554   char
00555     **fonts;
00556 
00557   register const TypeInfo
00558     *p;
00559 
00560   register ssize_t
00561     i;
00562 
00563   /*
00564     Allocate type list.
00565   */
00566   assert(pattern != (char *) NULL);
00567   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
00568   assert(number_fonts != (size_t *) NULL);
00569   *number_fonts=0;
00570   p=GetTypeInfo("*",exception);
00571   if (p == (const TypeInfo *) NULL)
00572     return((char **) NULL);
00573   fonts=(char **) AcquireQuantumMemory((size_t)
00574     GetNumberOfNodesInSplayTree(type_list)+1UL,sizeof(*fonts));
00575   if (fonts == (char **) NULL)
00576     return((char **) NULL);
00577   /*
00578     Generate type list.
00579   */
00580   LockSemaphoreInfo(type_semaphore);
00581   ResetSplayTreeIterator(type_list);
00582   p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
00583   for (i=0; p != (const TypeInfo *) NULL; )
00584   {
00585     if ((p->stealth == MagickFalse) &&
00586         (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
00587       fonts[i++]=ConstantString(p->name);
00588     p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
00589   }
00590   UnlockSemaphoreInfo(type_semaphore);
00591   qsort((void *) fonts,(size_t) i,sizeof(*fonts),TypeCompare);
00592   fonts[i]=(char *) NULL;
00593   *number_fonts=(size_t) i;
00594   return(fonts);
00595 }
00596 
00597 /*
00598 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00599 %                                                                             %
00600 %                                                                             %
00601 %                                                                             %
00602 +   I n i t i a l i z e T y p e L i s t                                       %
00603 %                                                                             %
00604 %                                                                             %
00605 %                                                                             %
00606 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00607 %
00608 %  InitializeTypeList() initializes the type list.
00609 %
00610 %  The format of the InitializeTypeList method is:
00611 %
00612 %      MagickBooleanType InitializeTypeList(ExceptionInfo *exception)
00613 %
00614 %  A description of each parameter follows.
00615 %
00616 %    o exception: return any errors or warnings in this structure.
00617 %
00618 */
00619 
00620 #if defined(MAGICKCORE_FONTCONFIG_DELEGATE)
00621 MagickExport MagickBooleanType LoadFontConfigFonts(SplayTreeInfo *type_list,
00622   ExceptionInfo *exception)
00623 {
00624   char
00625     extension[MaxTextExtent],
00626     name[MaxTextExtent];
00627 
00628   FcChar8
00629     *family,
00630     *file,
00631     *style;
00632 
00633   FcConfig
00634     *font_config;
00635 
00636   FcFontSet
00637     *font_set;
00638 
00639   FcObjectSet
00640     *object_set;
00641 
00642   FcPattern
00643     *pattern;
00644 
00645   FcResult
00646     status;
00647 
00648   int
00649     slant,
00650     width,
00651     weight;
00652 
00653   register ssize_t
00654     i;
00655 
00656   TypeInfo
00657     *type_info;
00658 
00659   /*
00660     Load system fonts.
00661   */
00662   (void) exception;
00663   font_config=FcInitLoadConfigAndFonts();
00664   if (font_config == (FcConfig *) NULL)
00665     return(MagickFalse);
00666   font_set=(FcFontSet *) NULL;
00667   object_set=FcObjectSetBuild(FC_FAMILY,FC_STYLE,FC_SLANT,FC_WIDTH,FC_WEIGHT,
00668     FC_FILE,(char *) NULL);
00669   if (object_set != (FcObjectSet *) NULL)
00670     {
00671       pattern=FcPatternCreate();
00672       if (pattern != (FcPattern *) NULL)
00673         {
00674           font_set=FcFontList(0,pattern,object_set);
00675           FcPatternDestroy(pattern);
00676         }
00677       FcObjectSetDestroy(object_set);
00678     }
00679   if (font_set == (FcFontSet *) NULL)
00680     {
00681       FcConfigDestroy(font_config);
00682       return(MagickFalse);
00683     }
00684   for (i=0; i < (ssize_t) font_set->nfont; i++)
00685   {
00686     status=FcPatternGetString(font_set->fonts[i],FC_FAMILY,0,&family);
00687     if (status != FcResultMatch)
00688       continue;
00689     status=FcPatternGetString(font_set->fonts[i],FC_FILE,0,&file);
00690     if (status != FcResultMatch)
00691       continue;
00692     *extension='\0';
00693     GetPathComponent((const char *) file,ExtensionPath,extension);
00694     if ((*extension != '\0') && (LocaleCompare(extension,"gz") == 0))
00695       continue;
00696     type_info=(TypeInfo *) AcquireMagickMemory(sizeof(*type_info));
00697     if (type_info == (TypeInfo *) NULL)
00698       continue;
00699     (void) ResetMagickMemory(type_info,0,sizeof(*type_info));
00700     type_info->path=ConstantString("System Fonts");
00701     type_info->signature=MagickSignature;
00702     (void) CopyMagickString(name,(const char *) family,MaxTextExtent);
00703     (void) ConcatenateMagickString(name," ",MaxTextExtent);
00704     status=FcPatternGetString(font_set->fonts[i],FC_STYLE,0,&style);
00705     if (status == FcResultMatch)
00706       (void) ConcatenateMagickString(name,(const char *) style,MaxTextExtent);
00707     type_info->name=ConstantString(name);
00708     (void) SubstituteString(&type_info->name," ","-");
00709     (void) SubstituteString(&type_info->name,"-L-","-");
00710     (void) SubstituteString(&type_info->name,"semicondensed","SemiCondensed");
00711     type_info->family=ConstantString((const char *) family);
00712     (void) SubstituteString(&type_info->family," L","");
00713     status=FcPatternGetInteger(font_set->fonts[i],FC_SLANT,0,&slant);
00714     type_info->style=NormalStyle;
00715     if (slant == FC_SLANT_ITALIC)
00716       type_info->style=ItalicStyle;
00717     if (slant == FC_SLANT_OBLIQUE)
00718       type_info->style=ObliqueStyle;
00719     status=FcPatternGetInteger(font_set->fonts[i],FC_WIDTH,0,&width);
00720     type_info->stretch=NormalStretch;
00721     if (width >= FC_WIDTH_ULTRACONDENSED)
00722       type_info->stretch=UltraCondensedStretch;
00723     if (width >= FC_WIDTH_EXTRACONDENSED)
00724       type_info->stretch=ExtraCondensedStretch;
00725     if (width >= FC_WIDTH_CONDENSED)
00726       type_info->stretch=CondensedStretch;
00727     if (width >= FC_WIDTH_SEMICONDENSED)
00728       type_info->stretch=SemiCondensedStretch;
00729     if (width >= FC_WIDTH_NORMAL)
00730       type_info->stretch=NormalStretch;
00731     if (width >= FC_WIDTH_SEMIEXPANDED)
00732       type_info->stretch=SemiExpandedStretch;
00733     if (width >= FC_WIDTH_EXPANDED)
00734       type_info->stretch=ExpandedStretch;
00735     if (width >= FC_WIDTH_EXTRAEXPANDED)
00736       type_info->stretch=ExtraExpandedStretch;
00737     if (width >= FC_WIDTH_ULTRAEXPANDED)
00738       type_info->stretch=UltraExpandedStretch;
00739     type_info->weight=400;
00740     status=FcPatternGetInteger(font_set->fonts[i],FC_WEIGHT,0,&weight);
00741     if (weight >= FC_WEIGHT_THIN)
00742       type_info->weight=100;
00743     if (weight >= FC_WEIGHT_EXTRALIGHT)
00744       type_info->weight=200;
00745     if (weight >= FC_WEIGHT_LIGHT)
00746       type_info->weight=300;
00747     if (weight >= FC_WEIGHT_NORMAL)
00748       type_info->weight=400;
00749     if (weight >= FC_WEIGHT_MEDIUM)
00750       type_info->weight=500;
00751     if (weight >= FC_WEIGHT_DEMIBOLD)
00752       type_info->weight=600;
00753     if (weight >= FC_WEIGHT_BOLD)
00754       type_info->weight=700;
00755     if (weight >= FC_WEIGHT_EXTRABOLD)
00756       type_info->weight=800;
00757     if (weight >= FC_WEIGHT_BLACK)
00758       type_info->weight=900;
00759     type_info->glyphs=ConstantString((const char *) file);
00760     (void) AddValueToSplayTree(type_list,type_info->name,type_info);
00761   }
00762   FcFontSetDestroy(font_set);
00763   FcConfigDestroy(font_config);
00764   return(MagickTrue);
00765 }
00766 #endif
00767 
00768 static MagickBooleanType InitializeTypeList(ExceptionInfo *exception)
00769 {
00770   if ((type_list == (SplayTreeInfo *) NULL) &&
00771       (instantiate_type == MagickFalse))
00772     {
00773       if (type_semaphore == (SemaphoreInfo *) NULL)
00774         AcquireSemaphoreInfo(&type_semaphore);
00775       LockSemaphoreInfo(type_semaphore);
00776       if ((type_list == (SplayTreeInfo *) NULL) &&
00777           (instantiate_type == MagickFalse))
00778         {
00779           (void) LoadTypeLists(MagickTypeFilename,exception);
00780 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
00781           (void) NTLoadTypeLists(type_list,exception);
00782 #endif
00783 #if defined(MAGICKCORE_FONTCONFIG_DELEGATE)
00784           (void) LoadFontConfigFonts(type_list,exception);
00785 #endif
00786           instantiate_type=MagickTrue;
00787         }
00788       UnlockSemaphoreInfo(type_semaphore);
00789     }
00790   return(type_list != (SplayTreeInfo *) NULL ? MagickTrue : MagickFalse);
00791 }
00792 
00793 /*
00794 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00795 %                                                                             %
00796 %                                                                             %
00797 %                                                                             %
00798 %  L i s t T y p e I n f o                                                    %
00799 %                                                                             %
00800 %                                                                             %
00801 %                                                                             %
00802 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00803 %
00804 %  ListTypeInfo() lists the fonts to a file.
00805 %
00806 %  The format of the ListTypeInfo method is:
00807 %
00808 %      MagickBooleanType ListTypeInfo(FILE *file,ExceptionInfo *exception)
00809 %
00810 %  A description of each parameter follows.
00811 %
00812 %    o file:  An pointer to a FILE.
00813 %
00814 %    o exception: return any errors or warnings in this structure.
00815 %
00816 */
00817 MagickExport MagickBooleanType ListTypeInfo(FILE *file,ExceptionInfo *exception)
00818 {
00819   char
00820     weight[MaxTextExtent];
00821 
00822   const char
00823     *family,
00824     *glyphs,
00825     *name,
00826     *path,
00827     *stretch,
00828     *style;
00829 
00830   const TypeInfo
00831     **type_info;
00832 
00833   register ssize_t
00834     i;
00835 
00836   size_t
00837     number_fonts;
00838 
00839   if (file == (FILE *) NULL)
00840     file=stdout;
00841   number_fonts=0;
00842   type_info=GetTypeInfoList("*",&number_fonts,exception);
00843   if (type_info == (const TypeInfo **) NULL)
00844     return(MagickFalse);
00845   *weight='\0';
00846   path=(const char *) NULL;
00847   for (i=0; i < (ssize_t) number_fonts; i++)
00848   {
00849     if (type_info[i]->stealth != MagickFalse)
00850       continue;
00851     if (((path == (const char *) NULL) ||
00852          (LocaleCompare(path,type_info[i]->path) != 0)) &&
00853          (type_info[i]->path != (char *) NULL))
00854       (void) FormatLocaleFile(file,"\nPath: %s\n",type_info[i]->path);
00855     path=type_info[i]->path;
00856     name="unknown";
00857     if (type_info[i]->name != (char *) NULL)
00858       name=type_info[i]->name;
00859     family="unknown";
00860     if (type_info[i]->family != (char *) NULL)
00861       family=type_info[i]->family;
00862     style=CommandOptionToMnemonic(MagickStyleOptions,type_info[i]->style);
00863     stretch=CommandOptionToMnemonic(MagickStretchOptions,type_info[i]->stretch);
00864     glyphs="unknown";
00865     if (type_info[i]->glyphs != (char *) NULL)
00866       glyphs=type_info[i]->glyphs;
00867     (void) FormatLocaleString(weight,MaxTextExtent,"%.20g",(double)
00868       type_info[i]->weight);
00869     (void) FormatLocaleFile(file,"  Font: %s\n",name);
00870     (void) FormatLocaleFile(file,"    family: %s\n",family);
00871     (void) FormatLocaleFile(file,"    style: %s\n",style);
00872     (void) FormatLocaleFile(file,"    stretch: %s\n",stretch);
00873     (void) FormatLocaleFile(file,"    weight: %s\n",weight);
00874     (void) FormatLocaleFile(file,"    glyphs: %s\n",glyphs);
00875   }
00876   (void) fflush(file);
00877   type_info=(const TypeInfo **) RelinquishMagickMemory((void *) type_info);
00878   return(MagickTrue);
00879 }
00880 
00881 /*
00882 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00883 %                                                                             %
00884 %                                                                             %
00885 %                                                                             %
00886 +   L o a d T y p e L i s t                                                   %
00887 %                                                                             %
00888 %                                                                             %
00889 %                                                                             %
00890 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00891 %
00892 %  LoadTypeList() loads the type configuration file which provides a mapping
00893 %  between type attributes and a type name.
00894 %
00895 %  The format of the LoadTypeList method is:
00896 %
00897 %      MagickBooleanType LoadTypeList(const char *xml,const char *filename,
00898 %        const size_t depth,ExceptionInfo *exception)
00899 %
00900 %  A description of each parameter follows:
00901 %
00902 %    o xml:  The type list in XML format.
00903 %
00904 %    o filename:  The type list filename.
00905 %
00906 %    o depth: depth of <include /> statements.
00907 %
00908 %    o exception: return any errors or warnings in this structure.
00909 %
00910 */
00911 
00912 static void *DestroyTypeNode(void *type_info)
00913 {
00914   register TypeInfo
00915     *p;
00916 
00917   p=(TypeInfo *) type_info;
00918   if (p->path != (char *) NULL)
00919     p->path=DestroyString(p->path);
00920   if (p->name != (char *) NULL)
00921     p->name=DestroyString(p->name);
00922   if (p->description != (char *) NULL)
00923     p->description=DestroyString(p->description);
00924   if (p->family != (char *) NULL)
00925     p->family=DestroyString(p->family);
00926   if (p->encoding != (char *) NULL)
00927     p->encoding=DestroyString(p->encoding);
00928   if (p->foundry != (char *) NULL)
00929     p->foundry=DestroyString(p->foundry);
00930   if (p->format != (char *) NULL)
00931     p->format=DestroyString(p->format);
00932   if (p->metrics != (char *) NULL)
00933     p->metrics=DestroyString(p->metrics);
00934   if (p->glyphs != (char *) NULL)
00935     p->glyphs=DestroyString(p->glyphs);
00936   return(RelinquishMagickMemory(p));
00937 }
00938 
00939 static MagickBooleanType LoadTypeList(const char *xml,const char *filename,
00940   const size_t depth,ExceptionInfo *exception)
00941 {
00942   char
00943     font_path[MaxTextExtent],
00944     keyword[MaxTextExtent],
00945     *token;
00946 
00947   const char
00948     *q;
00949 
00950   MagickBooleanType
00951     status;
00952 
00953   TypeInfo
00954     *type_info;
00955 
00956   /*
00957     Load the type map file.
00958   */
00959   (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
00960     "Loading type configure file \"%s\" ...",filename);
00961   if (xml == (const char *) NULL)
00962     return(MagickFalse);
00963   if (type_list == (SplayTreeInfo *) NULL)
00964     {
00965       type_list=NewSplayTree(CompareSplayTreeString,(void *(*)(void *)) NULL,
00966         DestroyTypeNode);
00967       if (type_list == (SplayTreeInfo *) NULL)
00968         {
00969           ThrowFileException(exception,ResourceLimitError,
00970             "MemoryAllocationFailed",filename);
00971           return(MagickFalse);
00972         }
00973     }
00974   status=MagickTrue;
00975   type_info=(TypeInfo *) NULL;
00976   token=AcquireString(xml);
00977 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
00978   /*
00979     Determine the Ghostscript font path.
00980   */
00981   *font_path='\0';
00982   if (NTGhostscriptFonts(font_path,MaxTextExtent-2))
00983     (void) ConcatenateMagickString(font_path,DirectorySeparator,MaxTextExtent);
00984 #endif
00985   for (q=(char *) xml; *q != '\0'; )
00986   {
00987     /*
00988       Interpret XML.
00989     */
00990     GetMagickToken(q,&q,token);
00991     if (*token == '\0')
00992       break;
00993     (void) CopyMagickString(keyword,token,MaxTextExtent);
00994     if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
00995       {
00996         /*
00997           Doctype element.
00998         */
00999         while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
01000           GetMagickToken(q,&q,token);
01001         continue;
01002       }
01003     if (LocaleNCompare(keyword,"<!--",4) == 0)
01004       {
01005         /*
01006           Comment element.
01007         */
01008         while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
01009           GetMagickToken(q,&q,token);
01010         continue;
01011       }
01012     if (LocaleCompare(keyword,"<include") == 0)
01013       {
01014         /*
01015           Include element.
01016         */
01017         while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0'))
01018         {
01019           (void) CopyMagickString(keyword,token,MaxTextExtent);
01020           GetMagickToken(q,&q,token);
01021           if (*token != '=')
01022             continue;
01023           GetMagickToken(q,&q,token);
01024           if (LocaleCompare(keyword,"file") == 0)
01025             {
01026               if (depth > 200)
01027                 (void) ThrowMagickException(exception,GetMagickModule(),
01028                   ConfigureError,"IncludeNodeNestedTooDeeply","`%s'",token);
01029               else
01030                 {
01031                   char
01032                     path[MaxTextExtent],
01033                     *xml;
01034 
01035                   ExceptionInfo
01036                     *sans_exception;
01037 
01038                   *path='\0';
01039                   GetPathComponent(filename,HeadPath,path);
01040                   if (*path != '\0')
01041                     (void) ConcatenateMagickString(path,DirectorySeparator,
01042                       MaxTextExtent);
01043                   if (*token == *DirectorySeparator)
01044                     (void) CopyMagickString(path,token,MaxTextExtent);
01045                   else
01046                     (void) ConcatenateMagickString(path,token,MaxTextExtent);
01047                   sans_exception=AcquireExceptionInfo();
01048                   xml=FileToString(path,~0,sans_exception);
01049                   sans_exception=DestroyExceptionInfo(sans_exception);
01050                   if (xml != (char *) NULL)
01051                     {
01052                       status=LoadTypeList(xml,path,depth+1,exception);
01053                       xml=(char *) RelinquishMagickMemory(xml);
01054                     }
01055                 }
01056             }
01057         }
01058         continue;
01059       }
01060     if (LocaleCompare(keyword,"<type") == 0)
01061       {
01062         /*
01063           Type element.
01064         */
01065         type_info=(TypeInfo *) AcquireMagickMemory(sizeof(*type_info));
01066         if (type_info == (TypeInfo *) NULL)
01067           ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
01068         (void) ResetMagickMemory(type_info,0,sizeof(*type_info));
01069         type_info->path=ConstantString(filename);
01070         type_info->signature=MagickSignature;
01071         continue;
01072       }
01073     if (type_info == (TypeInfo *) NULL)
01074       continue;
01075     if (LocaleCompare(keyword,"/>") == 0)
01076       {
01077         status=AddValueToSplayTree(type_list,type_info->name,type_info);
01078         if (status == MagickFalse)
01079           (void) ThrowMagickException(exception,GetMagickModule(),
01080             ResourceLimitError,"MemoryAllocationFailed","`%s'",type_info->name);
01081         type_info=(TypeInfo *) NULL;
01082       }
01083     GetMagickToken(q,(const char **) NULL,token);
01084     if (*token != '=')
01085       continue;
01086     GetMagickToken(q,&q,token);
01087     GetMagickToken(q,&q,token);
01088     switch (*keyword)
01089     {
01090       case 'E':
01091       case 'e':
01092       {
01093         if (LocaleCompare((char *) keyword,"encoding") == 0)
01094           {
01095             type_info->encoding=ConstantString(token);
01096             break;
01097           }
01098         break;
01099       }
01100       case 'F':
01101       case 'f':
01102       {
01103         if (LocaleCompare((char *) keyword,"face") == 0)
01104           {
01105             type_info->face=StringToUnsignedLong(token);
01106             break;
01107           }
01108         if (LocaleCompare((char *) keyword,"family") == 0)
01109           {
01110             type_info->family=ConstantString(token);
01111             break;
01112           }
01113         if (LocaleCompare((char *) keyword,"format") == 0)
01114           {
01115             type_info->format=ConstantString(token);
01116             break;
01117           }
01118         if (LocaleCompare((char *) keyword,"foundry") == 0)
01119           {
01120             type_info->foundry=ConstantString(token);
01121             break;
01122           }
01123         if (LocaleCompare((char *) keyword,"fullname") == 0)
01124           {
01125             type_info->description=ConstantString(token);
01126             break;
01127           }
01128         break;
01129       }
01130       case 'G':
01131       case 'g':
01132       {
01133         if (LocaleCompare((char *) keyword,"glyphs") == 0)
01134           {
01135             char
01136               *path;
01137 
01138             path=ConstantString(token);
01139 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
01140             if (strchr(path,'@') != (char *) NULL)
01141               SubstituteString(&path,"@ghostscript_font_path@",font_path);
01142 #endif
01143             if (IsPathAccessible(path) == MagickFalse)
01144               {
01145                 /*
01146                   Relative path.
01147                 */
01148                 path=DestroyString(path);
01149                 GetPathComponent(filename,HeadPath,font_path);
01150                 (void) ConcatenateMagickString(font_path,DirectorySeparator,
01151                   MaxTextExtent);
01152                 (void) ConcatenateMagickString(font_path,token,MaxTextExtent);
01153                 path=ConstantString(font_path);
01154                 if (IsPathAccessible(path) == MagickFalse)
01155                   {
01156                     path=DestroyString(path);
01157                     path=ConstantString(token);
01158                   }
01159               }
01160             type_info->glyphs=path;
01161             break;
01162           }
01163         break;
01164       }
01165       case 'M':
01166       case 'm':
01167       {
01168         if (LocaleCompare((char *) keyword,"metrics") == 0)
01169           {
01170             char
01171               *path;
01172 
01173             path=ConstantString(token);
01174 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
01175             if (strchr(path,'@') != (char *) NULL)
01176               SubstituteString(&path,"@ghostscript_font_path@",font_path);
01177 #endif
01178             if (IsPathAccessible(path) == MagickFalse)
01179               {
01180                 /*
01181                   Relative path.
01182                 */
01183                 path=DestroyString(path);
01184                 GetPathComponent(filename,HeadPath,font_path);
01185                 (void) ConcatenateMagickString(font_path,DirectorySeparator,
01186                   MaxTextExtent);
01187                 (void) ConcatenateMagickString(font_path,token,MaxTextExtent);
01188                 path=ConstantString(font_path);
01189               }
01190             type_info->metrics=path;
01191             break;
01192           }
01193         break;
01194       }
01195       case 'N':
01196       case 'n':
01197       {
01198         if (LocaleCompare((char *) keyword,"name") == 0)
01199           {
01200             type_info->name=ConstantString(token);
01201             break;
01202           }
01203         break;
01204       }
01205       case 'S':
01206       case 's':
01207       {
01208         if (LocaleCompare((char *) keyword,"stealth") == 0)
01209           {
01210             type_info->stealth=IsMagickTrue(token);
01211             break;
01212           }
01213         if (LocaleCompare((char *) keyword,"stretch") == 0)
01214           {
01215             type_info->stretch=(StretchType) ParseCommandOption(
01216               MagickStretchOptions,MagickFalse,token);
01217             break;
01218           }
01219         if (LocaleCompare((char *) keyword,"style") == 0)
01220           {
01221             type_info->style=(StyleType) ParseCommandOption(MagickStyleOptions,
01222               MagickFalse,token);
01223             break;
01224           }
01225         break;
01226       }
01227       case 'W':
01228       case 'w':
01229       {
01230         if (LocaleCompare((char *) keyword,"weight") == 0)
01231           {
01232             type_info->weight=StringToUnsignedLong(token);
01233             if (LocaleCompare(token,"bold") == 0)
01234               type_info->weight=700;
01235             if (LocaleCompare(token,"normal") == 0)
01236               type_info->weight=400;
01237             break;
01238           }
01239         break;
01240       }
01241       default:
01242         break;
01243     }
01244   }
01245   token=(char *) RelinquishMagickMemory(token);
01246   return(status);
01247 }
01248 
01249 /*
01250 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01251 %                                                                             %
01252 %                                                                             %
01253 %                                                                             %
01254 %  L o a d T y p e L i s t s                                                  %
01255 %                                                                             %
01256 %                                                                             %
01257 %                                                                             %
01258 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01259 %
01260 %  LoadTypeList() loads one or more type configuration files which provides a
01261 %  mapping between type attributes and a type name.
01262 %
01263 %  The format of the LoadTypeLists method is:
01264 %
01265 %      MagickBooleanType LoadTypeLists(const char *filename,
01266 %        ExceptionInfo *exception)
01267 %
01268 %  A description of each parameter follows:
01269 %
01270 %    o filename: the font file name.
01271 %
01272 %    o exception: return any errors or warnings in this structure.
01273 %
01274 */
01275 static MagickBooleanType LoadTypeLists(const char *filename,
01276   ExceptionInfo *exception)
01277 {
01278 #if defined(MAGICKCORE_ZERO_CONFIGURATION_SUPPORT)
01279   return(LoadTypeList(TypeMap,"built-in",0,exception));
01280 #else
01281   char
01282     *font_path,
01283     path[MaxTextExtent];
01284 
01285   const StringInfo
01286     *option;
01287 
01288   LinkedListInfo
01289     *options;
01290 
01291   MagickStatusType
01292     status;
01293 
01294   status=MagickFalse;
01295   *path='\0';
01296   options=GetConfigureOptions(filename,exception);
01297   option=(const StringInfo *) GetNextValueInLinkedList(options);
01298   while (option != (const StringInfo *) NULL)
01299   {
01300     (void) CopyMagickString(path,GetStringInfoPath(option),MaxTextExtent);
01301     status|=LoadTypeList((const char *) GetStringInfoDatum(option),
01302       GetStringInfoPath(option),0,exception);
01303     option=(const StringInfo *) GetNextValueInLinkedList(options);
01304   }
01305   options=DestroyConfigureOptions(options);
01306   font_path=GetEnvironmentValue("MAGICK_FONT_PATH");
01307   if (font_path != (char *) NULL)
01308     {
01309       char
01310         *option;
01311 
01312       /*
01313         Search MAGICK_FONT_PATH.
01314       */
01315       (void) FormatLocaleString(path,MaxTextExtent,"%s%s%s",font_path,
01316         DirectorySeparator,filename);
01317       option=FileToString(path,~0,exception);
01318       if (option != (void *) NULL)
01319         {
01320           status|=LoadTypeList(option,path,0,exception);
01321           option=DestroyString(option);
01322         }
01323       font_path=DestroyString(font_path);
01324     }
01325   if ((type_list == (SplayTreeInfo *) NULL) ||
01326       (GetNumberOfNodesInSplayTree(type_list) == 0))
01327     status|=LoadTypeList(TypeMap,"built-in",0,exception);
01328   return(status != 0 ? MagickTrue : MagickFalse);
01329 #endif
01330 }
01331 
01332 /*
01333 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01334 %                                                                             %
01335 %                                                                             %
01336 %                                                                             %
01337 +   T y p e C o m p o n e n t G e n e s i s                                   %
01338 %                                                                             %
01339 %                                                                             %
01340 %                                                                             %
01341 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01342 %
01343 %  TypeComponentGenesis() instantiates the type component.
01344 %
01345 %  The format of the TypeComponentGenesis method is:
01346 %
01347 %      MagickBooleanType TypeComponentGenesis(void)
01348 %
01349 */
01350 MagickPrivate MagickBooleanType TypeComponentGenesis(void)
01351 {
01352   AcquireSemaphoreInfo(&type_semaphore);
01353   return(MagickTrue);
01354 }
01355 
01356 /*
01357 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01358 %                                                                             %
01359 %                                                                             %
01360 %                                                                             %
01361 +   T y p e C o m p o n e n t T e r m i n u s                                 %
01362 %                                                                             %
01363 %                                                                             %
01364 %                                                                             %
01365 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01366 %
01367 %  TypeComponentTerminus() destroy type component.
01368 %
01369 %  The format of the TypeComponentTerminus method is:
01370 %
01371 %      void TypeComponentTerminus(void)
01372 %
01373 */
01374 MagickPrivate void TypeComponentTerminus(void)
01375 {
01376   if (type_semaphore == (SemaphoreInfo *) NULL)
01377     AcquireSemaphoreInfo(&type_semaphore);
01378   LockSemaphoreInfo(type_semaphore);
01379   if (type_list != (SplayTreeInfo *) NULL)
01380     type_list=DestroySplayTree(type_list);
01381   instantiate_type=MagickFalse;
01382   UnlockSemaphoreInfo(type_semaphore);
01383   DestroySemaphoreInfo(&type_semaphore);
01384 }