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 "magick/studio.h"
00043 #include "magick/blob.h"
00044 #include "magick/client.h"
00045 #include "magick/configure.h"
00046 #include "magick/draw.h"
00047 #include "magick/exception.h"
00048 #include "magick/exception-private.h"
00049 #include "magick/hashmap.h"
00050 #include "magick/log.h"
00051 #include "magick/memory_.h"
00052 #include "magick/option.h"
00053 #include "magick/semaphore.h"
00054 #include "magick/splay-tree.h"
00055 #include "magick/string_.h"
00056 #include "magick/type.h"
00057 #include "magick/token.h"
00058 #include "magick/utility.h"
00059 #include "magick/xml-tree.h"
00060 #if defined(MAGICKCORE_FONTCONFIG_DELEGATE)
00061 # include "fontconfig/fontconfig.h"
00062 #if (FC_VERSION < 20209)
00063 #undef FC_WEIGHT_LIGHT
00064 #define FC_WIDTH                  "width"    /* Int */
00065 #define FC_WIDTH_ULTRACONDENSED    50
00066 #define FC_WIDTH_EXTRACONDENSED    63
00067 #define FC_WIDTH_CONDENSED         75
00068 #define FC_WIDTH_SEMICONDENSED     87
00069 #define FC_WIDTH_NORMAL            100
00070 #define FC_WIDTH_SEMIEXPANDED      113
00071 #define FC_WIDTH_EXPANDED          125
00072 #define FC_WIDTH_EXTRAEXPANDED     150
00073 #define FC_WIDTH_ULTRAEXPANDED     200
00074 
00075 #define FC_WEIGHT_THIN             0
00076 #define FC_WEIGHT_EXTRALIGHT       40
00077 #define FC_WEIGHT_ULTRALIGHT       FC_WEIGHT_EXTRALIGHT
00078 #define FC_WEIGHT_LIGHT            50
00079 #define FC_WEIGHT_BOOK             75
00080 #define FC_WEIGHT_REGULAR          80
00081 #define FC_WEIGHT_NORMAL           FC_WEIGHT_REGULAR
00082 #define FC_WEIGHT_MEDIUM           100
00083 #define FC_WEIGHT_DEMIBOLD         180
00084 #define FC_WEIGHT_SEMIBOLD         FC_WEIGHT_DEMIBOLD
00085 #define FC_WEIGHT_BOLD             200
00086 #define FC_WEIGHT_EXTRABOLD        205
00087 #define FC_WEIGHT_ULTRABOLD        FC_WEIGHT_EXTRABOLD
00088 #define FC_WEIGHT_BLACK            210
00089 #define FC_WEIGHT_HEAVY            FC_WEIGHT_BLACK
00090 #endif
00091 #endif
00092 #if defined(__WINDOWS__)
00093 # include "magick/nt-feature.h"
00094 #endif
00095 
00096 /*
00097   Define declarations.
00098 */
00099 #define MagickTypeFilename  "type.xml"
00100 
00101 /*
00102   Declare type map.
00103 */
00104 static const char
00105   *TypeMap = (const char *)
00106     "<?xml version=\"1.0\"?>"
00107     "<typemap>"
00108     "  <type stealth=\"True\" name=\"fixed\" family=\"helvetica\"/>"
00109     "  <type stealth=\"True\" name=\"helvetica\" family=\"helvetica\"/>"
00110     "</typemap>";
00111 
00112 /*
00113   Static declarations.
00114 */
00115 static SemaphoreInfo
00116   *type_semaphore = (SemaphoreInfo *) NULL;
00117 
00118 static volatile MagickBooleanType
00119   instantiate_type = MagickFalse;
00120 
00121 static SplayTreeInfo
00122   *type_list = (SplayTreeInfo *) NULL;
00123 
00124 /*
00125   Forward declarations.
00126 */
00127 static MagickBooleanType
00128   InitializeTypeList(ExceptionInfo *),
00129   LoadTypeLists(const char *,ExceptionInfo *);
00130 
00131 /*
00132 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00133 %                                                                             %
00134 %                                                                             %
00135 %                                                                             %
00136 +   G e t T y p e I n f o                                                     %
00137 %                                                                             %
00138 %                                                                             %
00139 %                                                                             %
00140 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00141 %
00142 %  GetTypeInfo searches the type list for the specified name and if found
00143 %  returns attributes for that type.
00144 %
00145 %  The format of the GetTypeInfo method is:
00146 %
00147 %      const TypeInfo *GetTypeInfo(const char *name,ExceptionInfo *exception)
00148 %
00149 %  A description of each parameter follows:
00150 %
00151 %    o name: the type name.
00152 %
00153 %    o exception: return any errors or warnings in this structure.
00154 %
00155 */
00156 MagickExport const TypeInfo *GetTypeInfo(const char *name,
00157   ExceptionInfo *exception)
00158 {
00159   assert(exception != (ExceptionInfo *) NULL);
00160   if ((type_list == (SplayTreeInfo *) NULL) ||
00161       (instantiate_type == MagickFalse))
00162     if (InitializeTypeList(exception) == MagickFalse)
00163       return((const TypeInfo *) NULL);
00164   if ((type_list == (SplayTreeInfo *) NULL) ||
00165       (GetNumberOfNodesInSplayTree(type_list) == 0))
00166     return((const TypeInfo *) NULL);
00167   if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
00168     {
00169       ResetSplayTreeIterator(type_list);
00170       return((const TypeInfo *) GetNextValueInSplayTree(type_list));
00171     }
00172   return((const TypeInfo *) GetValueFromSplayTree(type_list,name));
00173 }
00174 
00175 /*
00176 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00177 %                                                                             %
00178 %                                                                             %
00179 %                                                                             %
00180 +   G e t T y p e I n f o B y F a m i l y                                     %
00181 %                                                                             %
00182 %                                                                             %
00183 %                                                                             %
00184 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00185 %
00186 %  GetTypeInfoByFamily() searches the type list for the specified family and if
00187 %  found returns attributes for that type.
00188 %
00189 %  Type substitution and scoring algorithm contributed by Bob Friesenhahn.
00190 %
00191 %  The format of the GetTypeInfoByFamily method is:
00192 %
00193 %      const TypeInfo *GetTypeInfoByFamily(const char *family,
00194 %        const StyleType style,const StretchType stretch,
00195 %        const unsigned long weight,ExceptionInfo *exception)
00196 %
00197 %  A description of each parameter follows:
00198 %
00199 %    o family: the type family.
00200 %
00201 %    o style: the type style.
00202 %
00203 %    o stretch: the type stretch.
00204 %
00205 %    o weight: the type weight.
00206 %
00207 %    o exception: return any errors or warnings in this structure.
00208 %
00209 */
00210 
00211 static inline unsigned long MagickMax(const unsigned long x,
00212   const unsigned long y)
00213 {
00214   if (x > y)
00215     return(x);
00216   return(y);
00217 }
00218 
00219 static inline unsigned long MagickMin(const unsigned long x,
00220   const unsigned long y)
00221 {
00222   if (x < y)
00223     return(x);
00224   return(y);
00225 }
00226 
00227 MagickExport const TypeInfo *GetTypeInfoByFamily(const char *family,
00228   const StyleType style,const StretchType stretch,const unsigned long weight,
00229   ExceptionInfo *exception)
00230 {
00231   typedef struct _Fontmap
00232   {
00233     const char
00234       *name,
00235       *substitute;
00236   } Fontmap;
00237 
00238   const TypeInfo
00239     *type_info;
00240 
00241   long
00242     range;
00243 
00244   register const TypeInfo
00245     *p;
00246 
00247   register long
00248     i;
00249 
00250   static Fontmap
00251     fontmap[] =
00252     {
00253       { "fixed", "courier" },
00254       { "modern","courier" },
00255       { "monotype corsiva", "courier" },
00256       { "news gothic", "helvetica" },
00257       { "system", "courier" },
00258       { "terminal", "courier" },
00259       { "wingdings", "symbol" },
00260       { NULL, NULL }
00261     };
00262 
00263   unsigned long
00264     max_score,
00265     score;
00266 
00267   /*
00268     Check for an exact type match.
00269   */
00270   (void) GetTypeInfo("*",exception);
00271   if (type_list == (SplayTreeInfo *) NULL)
00272     return((TypeInfo *) NULL);
00273   (void) LockSemaphoreInfo(type_semaphore);
00274   ResetSplayTreeIterator(type_list);
00275   type_info=(const TypeInfo *) NULL;
00276   p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
00277   while (p != (const TypeInfo *) NULL)
00278   {
00279     if (p->family == (char *) NULL)
00280       {
00281         p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
00282         continue;
00283       }
00284     if (family == (const char *) NULL)
00285       {
00286         if ((LocaleCompare(p->family,"arial") != 0) &&
00287             (LocaleCompare(p->family,"helvetica") != 0))
00288           {
00289             p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
00290             continue;
00291           }
00292       }
00293     else
00294       if (LocaleCompare(p->family,family) != 0)
00295         {
00296           p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
00297           continue;
00298         }
00299     if ((style != UndefinedStyle) && (style != AnyStyle) && (p->style != style))
00300       {
00301         p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
00302         continue;
00303       }
00304     if ((stretch != UndefinedStretch) && (stretch != AnyStretch) &&
00305         (p->stretch != stretch))
00306       {
00307         p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
00308         continue;
00309       }
00310     if ((weight != 0) && (p->weight != weight))
00311       {
00312         p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
00313         continue;
00314       }
00315     type_info=p;
00316     break;
00317   }
00318   (void) UnlockSemaphoreInfo(type_semaphore);
00319   if (type_info != (const TypeInfo *) NULL)
00320     return(type_info);
00321   /*
00322     Check for types in the same family.
00323   */
00324   max_score=0;
00325   (void) LockSemaphoreInfo(type_semaphore);
00326   ResetSplayTreeIterator(type_list);
00327   p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
00328   while (p != (const TypeInfo *) NULL)
00329   {
00330     if (p->family == (char *) NULL)
00331       {
00332         p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
00333         continue;
00334       }
00335     if (family == (const char *) NULL)
00336       {
00337         if ((LocaleCompare(p->family,"arial") != 0) &&
00338             (LocaleCompare(p->family,"helvetica") != 0))
00339           {
00340             p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
00341             continue;
00342           }
00343       }
00344     else
00345       if (LocaleCompare(p->family,family) != 0)
00346         {
00347           p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
00348           continue;
00349         }
00350     score=0;
00351     if ((style == UndefinedStyle) || (style == AnyStyle) || (p->style == style))
00352       score+=32;
00353     else
00354       if (((style == ItalicStyle) || (style == ObliqueStyle)) &&
00355           ((p->style == ItalicStyle) || (p->style == ObliqueStyle)))
00356         score+=25;
00357     if (weight == 0)
00358       score+=16;
00359     else
00360       score+=(16*(800-((long) MagickMax(MagickMin(weight,900),p->weight)-
00361         (long) MagickMin(MagickMin(weight,900),p->weight))))/800;
00362     if ((stretch == UndefinedStretch) || (stretch == AnyStretch))
00363       score+=8;
00364     else
00365       {
00366         range=(long) UltraExpandedStretch-(long) NormalStretch;
00367         score+=(8*(range-((long) MagickMax(stretch,p->stretch)-
00368           (long) MagickMin(stretch,p->stretch))))/range;
00369       }
00370     if (score > max_score)
00371       {
00372         max_score=score;
00373         type_info=p;
00374       }
00375     p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
00376   }
00377   (void) UnlockSemaphoreInfo(type_semaphore);
00378   if (type_info != (const TypeInfo *) NULL)
00379     return(type_info);
00380   /*
00381     Check for table-based substitution match.
00382   */
00383   for (i=0; fontmap[i].name != (char *) NULL; i++)
00384   {
00385     if (family == (const char *) NULL)
00386       {
00387         if ((LocaleCompare(fontmap[i].name,"arial") != 0) &&
00388             (LocaleCompare(fontmap[i].name,"helvetica") != 0))
00389           continue;
00390       }
00391     else
00392       if (LocaleCompare(fontmap[i].name,family) != 0)
00393         continue;
00394     type_info=GetTypeInfoByFamily(fontmap[i].substitute,style,stretch,weight,
00395       exception);
00396     break;
00397   }
00398   if (type_info != (const TypeInfo *) NULL)
00399     {
00400       (void) ThrowMagickException(exception,GetMagickModule(),TypeError,
00401         "FontSubstitutionRequired","`%s'",type_info->family);
00402       return(type_info);
00403     }
00404   if (family != (const char *) NULL)
00405     type_info=GetTypeInfoByFamily((const char *) NULL,style,stretch,weight,
00406       exception);
00407   return(type_info);
00408 }
00409 
00410 /*
00411 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00412 %                                                                             %
00413 %                                                                             %
00414 %                                                                             %
00415 %   G e t T y p e I n f o L i s t                                             %
00416 %                                                                             %
00417 %                                                                             %
00418 %                                                                             %
00419 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00420 %
00421 %  GetTypeInfoList() returns any fonts that match the specified pattern.
00422 %
00423 %  The format of the GetTypeInfoList function is:
00424 %
00425 %      const TypeInfo **GetTypeInfoList(const char *pattern,
00426 %        unsigned long *number_fonts,ExceptionInfo *exception)
00427 %
00428 %  A description of each parameter follows:
00429 %
00430 %    o pattern: Specifies a pointer to a text string containing a pattern.
00431 %
00432 %    o number_fonts:  This integer returns the number of types in the list.
00433 %
00434 %    o exception: return any errors or warnings in this structure.
00435 %
00436 */
00437 
00438 #if defined(__cplusplus) || defined(c_plusplus)
00439 extern "C" {
00440 #endif
00441 
00442 static int TypeInfoCompare(const void *x,const void *y)
00443 {
00444   const TypeInfo
00445     **p,
00446     **q;
00447 
00448   p=(const TypeInfo **) x,
00449   q=(const TypeInfo **) y;
00450   if (LocaleCompare((*p)->path,(*q)->path) == 0)
00451     return(LocaleCompare((*p)->name,(*q)->name));
00452   return(LocaleCompare((*p)->path,(*q)->path));
00453 }
00454 
00455 #if defined(__cplusplus) || defined(c_plusplus)
00456 }
00457 #endif
00458 
00459 MagickExport const TypeInfo **GetTypeInfoList(const char *pattern,
00460   unsigned long *number_fonts,ExceptionInfo *exception)
00461 {
00462   const TypeInfo
00463     **fonts;
00464 
00465   register const TypeInfo
00466     *p;
00467 
00468   register long
00469     i;
00470 
00471   /*
00472     Allocate type list.
00473   */
00474   assert(pattern != (char *) NULL);
00475   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
00476   assert(number_fonts != (unsigned long *) NULL);
00477   *number_fonts=0;
00478   p=GetTypeInfo("*",exception);
00479   if (p == (const TypeInfo *) NULL)
00480     return((const TypeInfo **) NULL);
00481   fonts=(const TypeInfo **) AcquireQuantumMemory((size_t)
00482     GetNumberOfNodesInSplayTree(type_list)+1UL,sizeof(*fonts));
00483   if (fonts == (const TypeInfo **) NULL)
00484     return((const TypeInfo **) NULL);
00485   /*
00486     Generate type list.
00487   */
00488   (void) LockSemaphoreInfo(type_semaphore);
00489   ResetSplayTreeIterator(type_list);
00490   p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
00491   for (i=0; p != (const TypeInfo *) NULL; )
00492   {
00493     if ((p->stealth == MagickFalse) &&
00494         (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
00495       fonts[i++]=p;
00496     p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
00497   }
00498   (void) UnlockSemaphoreInfo(type_semaphore);
00499   qsort((void *) fonts,(size_t) i,sizeof(*fonts),TypeInfoCompare);
00500   fonts[i]=(TypeInfo *) NULL;
00501   *number_fonts=(unsigned long) i;
00502   return(fonts);
00503 }
00504 
00505 /*
00506 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00507 %                                                                             %
00508 %                                                                             %
00509 %                                                                             %
00510 %   G e t T y p e L i s t                                                     %
00511 %                                                                             %
00512 %                                                                             %
00513 %                                                                             %
00514 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00515 %
00516 %  GetTypeList() returns any fonts that match the specified pattern.
00517 %
00518 %  The format of the GetTypeList function is:
00519 %
00520 %      char **GetTypeList(const char *pattern,unsigned long *number_fonts,
00521 %        ExceptionInfo *exception)
00522 %
00523 %  A description of each parameter follows:
00524 %
00525 %    o pattern: Specifies a pointer to a text string containing a pattern.
00526 %
00527 %    o number_fonts:  This integer returns the number of fonts in the list.
00528 %
00529 %    o exception: return any errors or warnings in this structure.
00530 %
00531 */
00532 
00533 #if defined(__cplusplus) || defined(c_plusplus)
00534 extern "C" {
00535 #endif
00536 
00537 static int TypeCompare(const void *x,const void *y)
00538 {
00539   register const char
00540     **p,
00541     **q;
00542 
00543   p=(const char **) x;
00544   q=(const char **) y;
00545   return(LocaleCompare(*p,*q));
00546 }
00547 
00548 #if defined(__cplusplus) || defined(c_plusplus)
00549 }
00550 #endif
00551 
00552 MagickExport char **GetTypeList(const char *pattern,unsigned long *number_fonts,
00553   ExceptionInfo *exception)
00554 {
00555   char
00556     **fonts;
00557 
00558   register const TypeInfo
00559     *p;
00560 
00561   register long
00562     i;
00563 
00564   /*
00565     Allocate type list.
00566   */
00567   assert(pattern != (char *) NULL);
00568   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
00569   assert(number_fonts != (unsigned long *) NULL);
00570   *number_fonts=0;
00571   p=GetTypeInfo("*",exception);
00572   if (p == (const TypeInfo *) NULL)
00573     return((char **) NULL);
00574   fonts=(char **) AcquireQuantumMemory((size_t)
00575     GetNumberOfNodesInSplayTree(type_list)+1UL,sizeof(*fonts));
00576   if (fonts == (char **) NULL)
00577     return((char **) NULL);
00578   /*
00579     Generate type list.
00580   */
00581   (void) LockSemaphoreInfo(type_semaphore);
00582   ResetSplayTreeIterator(type_list);
00583   p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
00584   for (i=0; p != (const TypeInfo *) NULL; )
00585   {
00586     if ((p->stealth == MagickFalse) &&
00587         (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
00588       fonts[i++]=ConstantString(p->name);
00589     p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
00590   }
00591   (void) UnlockSemaphoreInfo(type_semaphore);
00592   qsort((void *) fonts,(size_t) i,sizeof(*fonts),TypeCompare);
00593   fonts[i]=(char *) NULL;
00594   *number_fonts=(unsigned long) i;
00595   return(fonts);
00596 }
00597 
00598 /*
00599 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00600 %                                                                             %
00601 %                                                                             %
00602 %                                                                             %
00603 +   I n i t i a l i z e T y p e L i s t                                       %
00604 %                                                                             %
00605 %                                                                             %
00606 %                                                                             %
00607 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00608 %
00609 %  InitializeTypeList() initializes the type list.
00610 %
00611 %  The format of the InitializeTypeList method is:
00612 %
00613 %      MagickBooleanType InitializeTypeList(ExceptionInfo *exception)
00614 %
00615 %  A description of each parameter follows.
00616 %
00617 %    o exception: return any errors or warnings in this structure.
00618 %
00619 */
00620 
00621 #if defined(MAGICKCORE_FONTCONFIG_DELEGATE)
00622 MagickExport MagickBooleanType LoadFontConfigFonts(SplayTreeInfo *type_list,
00623   ExceptionInfo *exception)
00624 {
00625   char
00626     extension[MaxTextExtent],
00627     name[MaxTextExtent];
00628 
00629   FcChar8
00630     *family,
00631     *file,
00632     *style;
00633 
00634   FcConfig
00635     *font_config;
00636 
00637   FcFontSet
00638     *font_set;
00639 
00640   FcObjectSet
00641     *object_set;
00642 
00643   FcPattern
00644     *pattern;
00645 
00646   FcResult
00647     status;
00648 
00649   int
00650     slant,
00651     width,
00652     weight;
00653 
00654   register long
00655     i;
00656 
00657   TypeInfo
00658     *type_info;
00659 
00660   /*
00661     Load system fonts.
00662   */
00663   (void) exception;
00664   font_config=FcInitLoadConfigAndFonts();
00665   if (font_config == (FcConfig *) NULL)
00666     return(MagickFalse);
00667   font_set=(FcFontSet *) NULL;
00668   object_set=FcObjectSetBuild(FC_FAMILY,FC_STYLE,FC_SLANT,FC_WIDTH,FC_WEIGHT,
00669     FC_FILE,(char *) NULL);
00670   if (object_set != (FcObjectSet *) NULL)
00671     {
00672       pattern=FcPatternCreate();
00673       if (pattern != (FcPattern *) NULL)
00674         {
00675           font_set=FcFontList(0,pattern,object_set);
00676           FcPatternDestroy(pattern);
00677         }
00678       FcObjectSetDestroy(object_set);
00679     }
00680   if (font_set == (FcFontSet *) NULL)
00681     {
00682       FcConfigDestroy(font_config);
00683       return(MagickFalse);
00684     }
00685   for (i=0; i < (long) font_set->nfont; i++)
00686   {
00687     status=FcPatternGetString(font_set->fonts[i],FC_FAMILY,0,&family);
00688     if (status != FcResultMatch)
00689       continue;
00690     status=FcPatternGetString(font_set->fonts[i],FC_FILE,0,&file);
00691     if (status != FcResultMatch)
00692       continue;
00693     *extension='\0';
00694     GetPathComponent((const char *) file,ExtensionPath,extension);
00695     if ((*extension != '\0') && (LocaleCompare(extension,"gz") == 0))
00696       continue;
00697     type_info=(TypeInfo *) AcquireMagickMemory(sizeof(*type_info));
00698     if (type_info == (TypeInfo *) NULL)
00699       continue;
00700     (void) ResetMagickMemory(type_info,0,sizeof(*type_info));
00701     type_info->path=ConstantString("System Fonts");
00702     type_info->signature=MagickSignature;
00703     (void) CopyMagickString(name,(const char *) family,MaxTextExtent);
00704     (void) ConcatenateMagickString(name," ",MaxTextExtent);
00705     status=FcPatternGetString(font_set->fonts[i],FC_STYLE,0,&style);
00706     if (status == FcResultMatch)
00707       (void) ConcatenateMagickString(name,(const char *) style,MaxTextExtent);
00708     type_info->name=ConstantString(name);
00709     (void) SubstituteString(&type_info->name," ","-");
00710     (void) SubstituteString(&type_info->name,"-L-","-");
00711     (void) SubstituteString(&type_info->name,"semicondensed","SemiCondensed");
00712     type_info->family=ConstantString((const char *) family);
00713     (void) SubstituteString(&type_info->family," L","");
00714     status=FcPatternGetInteger(font_set->fonts[i],FC_SLANT,0,&slant);
00715     type_info->style=NormalStyle;
00716     if (slant == FC_SLANT_ITALIC)
00717       type_info->style=ItalicStyle;
00718     if (slant == FC_SLANT_OBLIQUE)
00719       type_info->style=ObliqueStyle;
00720     status=FcPatternGetInteger(font_set->fonts[i],FC_WIDTH,0,&width);
00721     type_info->stretch=NormalStretch;
00722     if (width >= FC_WIDTH_ULTRACONDENSED)
00723       type_info->stretch=UltraCondensedStretch;
00724     if (width >= FC_WIDTH_EXTRACONDENSED)
00725       type_info->stretch=ExtraCondensedStretch;
00726     if (width >= FC_WIDTH_CONDENSED)
00727       type_info->stretch=CondensedStretch;
00728     if (width >= FC_WIDTH_SEMICONDENSED)
00729       type_info->stretch=SemiCondensedStretch;
00730     if (width >= FC_WIDTH_NORMAL)
00731       type_info->stretch=NormalStretch;
00732     if (width >= FC_WIDTH_SEMIEXPANDED)
00733       type_info->stretch=SemiExpandedStretch;
00734     if (width >= FC_WIDTH_EXPANDED)
00735       type_info->stretch=ExpandedStretch;
00736     if (width >= FC_WIDTH_EXTRAEXPANDED)
00737       type_info->stretch=ExtraExpandedStretch;
00738     if (width >= FC_WIDTH_ULTRAEXPANDED)
00739       type_info->stretch=UltraExpandedStretch;
00740     type_info->weight=400;
00741     status=FcPatternGetInteger(font_set->fonts[i],FC_WEIGHT,0,&weight);
00742     if (weight >= FC_WEIGHT_THIN)
00743       type_info->weight=100;
00744     if (weight >= FC_WEIGHT_EXTRALIGHT)
00745       type_info->weight=200;
00746     if (weight >= FC_WEIGHT_LIGHT)
00747       type_info->weight=300;
00748     if (weight >= FC_WEIGHT_NORMAL)
00749       type_info->weight=400;
00750     if (weight >= FC_WEIGHT_MEDIUM)
00751       type_info->weight=500;
00752     if (weight >= FC_WEIGHT_DEMIBOLD)
00753       type_info->weight=600;
00754     if (weight >= FC_WEIGHT_BOLD)
00755       type_info->weight=700;
00756     if (weight >= FC_WEIGHT_EXTRABOLD)
00757       type_info->weight=800;
00758     if (weight >= FC_WEIGHT_BLACK)
00759       type_info->weight=900;
00760     type_info->glyphs=ConstantString((const char *) file);
00761     (void) AddValueToSplayTree(type_list,type_info->name,type_info);
00762   }
00763   FcFontSetDestroy(font_set);
00764   FcConfigDestroy(font_config);
00765   return(MagickTrue);
00766 }
00767 #endif
00768 
00769 static MagickBooleanType InitializeTypeList(ExceptionInfo *exception)
00770 {
00771   if ((type_list == (SplayTreeInfo *) NULL) &&
00772       (instantiate_type == MagickFalse))
00773     {
00774       if (type_semaphore == (SemaphoreInfo *) NULL)
00775         AcquireSemaphoreInfo(&type_semaphore);
00776       (void) LockSemaphoreInfo(type_semaphore);
00777       if ((type_list == (SplayTreeInfo *) NULL) &&
00778           (instantiate_type == MagickFalse))
00779         {
00780           (void) LoadTypeLists(MagickTypeFilename,exception);
00781 #if defined(__WINDOWS__)
00782           (void) NTLoadTypeLists(type_list,exception);
00783 #endif
00784 #if defined(MAGICKCORE_FONTCONFIG_DELEGATE)
00785           (void) LoadFontConfigFonts(type_list,exception);
00786 #endif
00787           instantiate_type=MagickTrue;
00788         }
00789       (void) UnlockSemaphoreInfo(type_semaphore);
00790     }
00791   return(type_list != (SplayTreeInfo *) NULL ? MagickTrue : MagickFalse);
00792 }
00793 
00794 /*
00795 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00796 %                                                                             %
00797 %                                                                             %
00798 %                                                                             %
00799 %  L i s t T y p e I n f o                                                    %
00800 %                                                                             %
00801 %                                                                             %
00802 %                                                                             %
00803 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00804 %
00805 %  ListTypeInfo() lists the fonts to a file.
00806 %
00807 %  The format of the ListTypeInfo method is:
00808 %
00809 %      MagickBooleanType ListTypeInfo(FILE *file,ExceptionInfo *exception)
00810 %
00811 %  A description of each parameter follows.
00812 %
00813 %    o file:  An pointer to a FILE.
00814 %
00815 %    o exception: return any errors or warnings in this structure.
00816 %
00817 */
00818 MagickExport MagickBooleanType ListTypeInfo(FILE *file,ExceptionInfo *exception)
00819 {
00820   char
00821     weight[MaxTextExtent];
00822 
00823   const char
00824     *family,
00825     *glyphs,
00826     *name,
00827     *path,
00828     *stretch,
00829     *style;
00830 
00831   const TypeInfo
00832     **type_info;
00833 
00834   register long
00835     i;
00836 
00837   unsigned long
00838     number_fonts;
00839 
00840   if (file == (FILE *) NULL)
00841     file=stdout;
00842   number_fonts=0;
00843   type_info=GetTypeInfoList("*",&number_fonts,exception);
00844   if (type_info == (const TypeInfo **) NULL)
00845     return(MagickFalse);
00846   *weight='\0';
00847   path=(const char *) NULL;
00848   for (i=0; i < (long) number_fonts; i++)
00849   {
00850     if (type_info[i]->stealth != MagickFalse)
00851       continue;
00852     if (((path == (const char *) NULL) ||
00853          (LocaleCompare(path,type_info[i]->path) != 0)) &&
00854          (type_info[i]->path != (char *) NULL))
00855       (void) fprintf(file,"\nPath: %s\n",type_info[i]->path);
00856     path=type_info[i]->path;
00857     name="unknown";
00858     if (type_info[i]->name != (char *) NULL)
00859       name=type_info[i]->name;
00860     family="unknown";
00861     if (type_info[i]->family != (char *) NULL)
00862       family=type_info[i]->family;
00863     style=MagickOptionToMnemonic(MagickStyleOptions,type_info[i]->style);
00864     stretch=MagickOptionToMnemonic(MagickStretchOptions,type_info[i]->stretch);
00865     glyphs="unknown";
00866     if (type_info[i]->glyphs != (char *) NULL)
00867       glyphs=type_info[i]->glyphs;
00868     (void) FormatMagickString(weight,MaxTextExtent,"%lu",type_info[i]->weight);
00869     (void) fprintf(file,"  Font: %s\n",name);
00870     (void) fprintf(file,"    family: %s\n",family);
00871     (void) fprintf(file,"    style: %s\n",style);
00872     (void) fprintf(file,"    stretch: %s\n",stretch);
00873     (void) fprintf(file,"    weight: %s\n",weight);
00874     (void) fprintf(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 unsigned long 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 unsigned long 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(__WINDOWS__)
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=(unsigned long) atol(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(__WINDOWS__)
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               }
01155             type_info->glyphs=path;
01156             break;
01157           }
01158         break;
01159       }
01160       case 'M':
01161       case 'm':
01162       {
01163         if (LocaleCompare((char *) keyword,"metrics") == 0)
01164           {
01165             char
01166               *path;
01167 
01168             path=ConstantString(token);
01169 #if defined(__WINDOWS__)
01170             if (strchr(path,'@') != (char *) NULL)
01171               SubstituteString(&path,"@ghostscript_font_path@",font_path);
01172 #endif
01173             if (IsPathAccessible(path) == MagickFalse)
01174               {
01175                 /*
01176                   Relative path.
01177                 */
01178                 path=DestroyString(path);
01179                 GetPathComponent(filename,HeadPath,font_path);
01180                 (void) ConcatenateMagickString(font_path,DirectorySeparator,
01181                   MaxTextExtent);
01182                 (void) ConcatenateMagickString(font_path,token,MaxTextExtent);
01183                 path=ConstantString(font_path);
01184               }
01185             type_info->metrics=path;
01186             break;
01187           }
01188         break;
01189       }
01190       case 'N':
01191       case 'n':
01192       {
01193         if (LocaleCompare((char *) keyword,"name") == 0)
01194           {
01195             type_info->name=ConstantString(token);
01196             break;
01197           }
01198         break;
01199       }
01200       case 'S':
01201       case 's':
01202       {
01203         if (LocaleCompare((char *) keyword,"stealth") == 0)
01204           {
01205             type_info->stealth=IsMagickTrue(token);
01206             break;
01207           }
01208         if (LocaleCompare((char *) keyword,"stretch") == 0)
01209           {
01210             type_info->stretch=(StretchType) ParseMagickOption(
01211               MagickStretchOptions,MagickFalse,token);
01212             break;
01213           }
01214         if (LocaleCompare((char *) keyword,"style") == 0)
01215           {
01216             type_info->style=(StyleType) ParseMagickOption(MagickStyleOptions,
01217               MagickFalse,token);
01218             break;
01219           }
01220         break;
01221       }
01222       case 'W':
01223       case 'w':
01224       {
01225         if (LocaleCompare((char *) keyword,"weight") == 0)
01226           {
01227             type_info->weight=(unsigned long) atol(token);
01228             if (LocaleCompare(token,"bold") == 0)
01229               type_info->weight=700;
01230             if (LocaleCompare(token,"normal") == 0)
01231               type_info->weight=400;
01232             break;
01233           }
01234         break;
01235       }
01236       default:
01237         break;
01238     }
01239   }
01240   token=(char *) RelinquishMagickMemory(token);
01241   return(status);
01242 }
01243 
01244 /*
01245 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01246 %                                                                             %
01247 %                                                                             %
01248 %                                                                             %
01249 %  L o a d T y p e L i s t s                                                  %
01250 %                                                                             %
01251 %                                                                             %
01252 %                                                                             %
01253 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01254 %
01255 %  LoadTypeList() loads one or more type configuration files which provides a
01256 %  mapping between type attributes and a type name.
01257 %
01258 %  The format of the LoadTypeLists method is:
01259 %
01260 %      MagickBooleanType LoadTypeLists(const char *filename,
01261 %        ExceptionInfo *exception)
01262 %
01263 %  A description of each parameter follows:
01264 %
01265 %    o filename: the font file name.
01266 %
01267 %    o exception: return any errors or warnings in this structure.
01268 %
01269 */
01270 static MagickBooleanType LoadTypeLists(const char *filename,
01271   ExceptionInfo *exception)
01272 {
01273 #if defined(MAGICKCORE_EMBEDDABLE_SUPPORT)
01274   return(LoadTypeList(TypeMap,"built-in",0,exception));
01275 #else
01276   char
01277     *font_path,
01278     path[MaxTextExtent];
01279 
01280   const StringInfo
01281     *option;
01282 
01283   LinkedListInfo
01284     *options;
01285 
01286   MagickStatusType
01287     status;
01288 
01289   status=MagickFalse;
01290   *path='\0';
01291   options=GetConfigureOptions(filename,exception);
01292   option=(const StringInfo *) GetNextValueInLinkedList(options);
01293   while (option != (const StringInfo *) NULL)
01294   {
01295     (void) CopyMagickString(path,GetStringInfoPath(option),MaxTextExtent);
01296     status|=LoadTypeList((const char *) GetStringInfoDatum(option),
01297       GetStringInfoPath(option),0,exception);
01298     option=(const StringInfo *) GetNextValueInLinkedList(options);
01299   }
01300   options=DestroyConfigureOptions(options);
01301   font_path=GetEnvironmentValue("MAGICK_FONT_PATH");
01302   if (font_path != (char *) NULL)
01303     {
01304       char
01305         *option;
01306 
01307       /*
01308         Search MAGICK_FONT_PATH.
01309       */
01310       (void) FormatMagickString(path,MaxTextExtent,"%s%s%s",font_path,
01311         DirectorySeparator,filename);
01312       option=FileToString(path,~0,exception);
01313       if (option != (void *) NULL)
01314         {
01315           status|=LoadTypeList(option,path,0,exception);
01316           option=DestroyString(option);
01317         }
01318       font_path=DestroyString(font_path);
01319     }
01320   if ((type_list == (SplayTreeInfo *) NULL) ||
01321       (GetNumberOfNodesInSplayTree(type_list) == 0))
01322     status|=LoadTypeList(TypeMap,"built-in",0,exception);
01323   return(status != 0 ? MagickTrue : MagickFalse);
01324 #endif
01325 }
01326 
01327 /*
01328 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01329 %                                                                             %
01330 %                                                                             %
01331 %                                                                             %
01332 +   T y p e C o m p o n e n t G e n e s i s                                   %
01333 %                                                                             %
01334 %                                                                             %
01335 %                                                                             %
01336 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01337 %
01338 %  TypeComponentGenesis() instantiates the type component.
01339 %
01340 %  The format of the TypeComponentGenesis method is:
01341 %
01342 %      MagickBooleanType TypeComponentGenesis(void)
01343 %
01344 */
01345 MagickExport MagickBooleanType TypeComponentGenesis(void)
01346 {
01347   AcquireSemaphoreInfo(&type_semaphore);
01348   return(MagickTrue);
01349 }
01350 
01351 /*
01352 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01353 %                                                                             %
01354 %                                                                             %
01355 %                                                                             %
01356 +   T y p e C o m p o n e n t T e r m i n u s                                 %
01357 %                                                                             %
01358 %                                                                             %
01359 %                                                                             %
01360 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
01361 %
01362 %  TypeComponentTerminus() destroy type component.
01363 %
01364 %  The format of the TypeComponentTerminus method is:
01365 %
01366 %      void TypeComponentTerminus(void)
01367 %
01368 */
01369 MagickExport void TypeComponentTerminus(void)
01370 {
01371   if (type_semaphore == (SemaphoreInfo *) NULL)
01372     AcquireSemaphoreInfo(&type_semaphore);
01373   (void) LockSemaphoreInfo(type_semaphore);
01374   if (type_list != (SplayTreeInfo *) NULL)
01375     type_list=DestroySplayTree(type_list);
01376   instantiate_type=MagickFalse;
01377   (void) UnlockSemaphoreInfo(type_semaphore);
01378   DestroySemaphoreInfo(&type_semaphore);
01379 }

Generated on 19 Nov 2009 for MagickCore by  doxygen 1.6.1