00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
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"
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
00098
00099 #define MagickTypeFilename "type.xml"
00100
00101
00102
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
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
00126
00127 static MagickBooleanType
00128 InitializeTypeList(ExceptionInfo *),
00129 LoadTypeLists(const char *,ExceptionInfo *);
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149 MagickExport void DestroyTypeList(void)
00150 {
00151 AcquireSemaphoreInfo(&type_semaphore);
00152 if (type_list != (SplayTreeInfo *) NULL)
00153 type_list=DestroySplayTree(type_list);
00154 instantiate_type=MagickFalse;
00155 RelinquishSemaphoreInfo(type_semaphore);
00156 DestroySemaphoreInfo(&type_semaphore);
00157 }
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184 MagickExport const TypeInfo *GetTypeInfo(const char *name,
00185 ExceptionInfo *exception)
00186 {
00187 assert(exception != (ExceptionInfo *) NULL);
00188 if ((type_list == (SplayTreeInfo *) NULL) ||
00189 (instantiate_type == MagickFalse))
00190 if (InitializeTypeList(exception) == MagickFalse)
00191 return((const TypeInfo *) NULL);
00192 if ((type_list == (SplayTreeInfo *) NULL) ||
00193 (GetNumberOfNodesInSplayTree(type_list) == 0))
00194 return((const TypeInfo *) NULL);
00195 if ((name == (const char *) NULL) || (LocaleCompare(name,"*") == 0))
00196 {
00197 ResetSplayTreeIterator(type_list);
00198 return((const TypeInfo *) GetNextValueInSplayTree(type_list));
00199 }
00200 return((const TypeInfo *) GetValueFromSplayTree(type_list,name));
00201 }
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239 static inline unsigned long MagickMax(const unsigned long x,
00240 const unsigned long y)
00241 {
00242 if (x > y)
00243 return(x);
00244 return(y);
00245 }
00246
00247 static inline unsigned long MagickMin(const unsigned long x,
00248 const unsigned long y)
00249 {
00250 if (x < y)
00251 return(x);
00252 return(y);
00253 }
00254
00255 MagickExport const TypeInfo *GetTypeInfoByFamily(const char *family,
00256 const StyleType style,const StretchType stretch,const unsigned long weight,
00257 ExceptionInfo *exception)
00258 {
00259 typedef struct _Fontmap
00260 {
00261 const char
00262 *name,
00263 *substitute;
00264 } Fontmap;
00265
00266 const TypeInfo
00267 *type_info;
00268
00269 long
00270 range;
00271
00272 register const TypeInfo
00273 *p;
00274
00275 register long
00276 i;
00277
00278 static Fontmap
00279 fontmap[] =
00280 {
00281 { "fixed", "courier" },
00282 { "modern","courier" },
00283 { "monotype corsiva", "courier" },
00284 { "news gothic", "helvetica" },
00285 { "system", "courier" },
00286 { "terminal", "courier" },
00287 { "wingdings", "symbol" },
00288 { NULL, NULL }
00289 };
00290
00291 unsigned long
00292 max_score,
00293 score;
00294
00295
00296
00297
00298 (void) GetTypeInfo("*",exception);
00299 if (type_list == (SplayTreeInfo *) NULL)
00300 return((TypeInfo *) NULL);
00301 AcquireSemaphoreInfo(&type_semaphore);
00302 ResetSplayTreeIterator(type_list);
00303 type_info=(const TypeInfo *) NULL;
00304 p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
00305 while (p != (const TypeInfo *) NULL)
00306 {
00307 if (p->family == (char *) NULL)
00308 {
00309 p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
00310 continue;
00311 }
00312 if (family == (const char *) NULL)
00313 {
00314 if ((LocaleCompare(p->family,"arial") != 0) &&
00315 (LocaleCompare(p->family,"helvetica") != 0))
00316 {
00317 p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
00318 continue;
00319 }
00320 }
00321 else
00322 if (LocaleCompare(p->family,family) != 0)
00323 {
00324 p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
00325 continue;
00326 }
00327 if ((style != UndefinedStyle) && (style != AnyStyle) && (p->style != style))
00328 {
00329 p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
00330 continue;
00331 }
00332 if ((stretch != UndefinedStretch) && (stretch != AnyStretch) &&
00333 (p->stretch != stretch))
00334 {
00335 p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
00336 continue;
00337 }
00338 if ((weight != 0) && (p->weight != weight))
00339 {
00340 p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
00341 continue;
00342 }
00343 type_info=p;
00344 break;
00345 }
00346 RelinquishSemaphoreInfo(type_semaphore);
00347 if (type_info != (const TypeInfo *) NULL)
00348 return(type_info);
00349
00350
00351
00352 max_score=0;
00353 AcquireSemaphoreInfo(&type_semaphore);
00354 ResetSplayTreeIterator(type_list);
00355 p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
00356 while (p != (const TypeInfo *) NULL)
00357 {
00358 if (p->family == (char *) NULL)
00359 {
00360 p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
00361 continue;
00362 }
00363 if (family == (const char *) NULL)
00364 {
00365 if ((LocaleCompare(p->family,"arial") != 0) &&
00366 (LocaleCompare(p->family,"helvetica") != 0))
00367 {
00368 p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
00369 continue;
00370 }
00371 }
00372 else
00373 if (LocaleCompare(p->family,family) != 0)
00374 {
00375 p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
00376 continue;
00377 }
00378 score=0;
00379 if ((style == UndefinedStyle) || (style == AnyStyle) || (p->style == style))
00380 score+=32;
00381 else
00382 if (((style == ItalicStyle) || (style == ObliqueStyle)) &&
00383 ((p->style == ItalicStyle) || (p->style == ObliqueStyle)))
00384 score+=25;
00385 if (weight == 0)
00386 score+=16;
00387 else
00388 score+=(16*(800-((long) MagickMax(MagickMin(weight,900),p->weight)-
00389 (long) MagickMin(MagickMin(weight,900),p->weight))))/800;
00390 if ((stretch == UndefinedStretch) || (stretch == AnyStretch))
00391 score+=8;
00392 else
00393 {
00394 range=(long) UltraExpandedStretch-(long) NormalStretch;
00395 score+=(8*(range-((long) MagickMax(stretch,p->stretch)-
00396 (long) MagickMin(stretch,p->stretch))))/range;
00397 }
00398 if (score > max_score)
00399 {
00400 max_score=score;
00401 type_info=p;
00402 }
00403 p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
00404 }
00405 RelinquishSemaphoreInfo(type_semaphore);
00406 if (type_info != (const TypeInfo *) NULL)
00407 return(type_info);
00408
00409
00410
00411 for (i=0; fontmap[i].name != (char *) NULL; i++)
00412 {
00413 if (family == (const char *) NULL)
00414 {
00415 if ((LocaleCompare(fontmap[i].name,"arial") != 0) &&
00416 (LocaleCompare(fontmap[i].name,"helvetica") != 0))
00417 continue;
00418 }
00419 else
00420 if (LocaleCompare(fontmap[i].name,family) != 0)
00421 continue;
00422 type_info=GetTypeInfoByFamily(fontmap[i].substitute,style,stretch,weight,
00423 exception);
00424 break;
00425 }
00426 if (type_info != (const TypeInfo *) NULL)
00427 {
00428 (void) ThrowMagickException(exception,GetMagickModule(),TypeError,
00429 "FontSubstitutionRequired","`%s'",type_info->family);
00430 return(type_info);
00431 }
00432 if (family != (const char *) NULL)
00433 type_info=GetTypeInfoByFamily((const char *) NULL,style,stretch,weight,
00434 exception);
00435 return(type_info);
00436 }
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466 #if defined(__cplusplus) || defined(c_plusplus)
00467 extern "C" {
00468 #endif
00469
00470 static int TypeInfoCompare(const void *x,const void *y)
00471 {
00472 const TypeInfo
00473 **p,
00474 **q;
00475
00476 p=(const TypeInfo **) x,
00477 q=(const TypeInfo **) y;
00478 if (LocaleCompare((*p)->path,(*q)->path) == 0)
00479 return(LocaleCompare((*p)->name,(*q)->name));
00480 return(LocaleCompare((*p)->path,(*q)->path));
00481 }
00482
00483 #if defined(__cplusplus) || defined(c_plusplus)
00484 }
00485 #endif
00486
00487 MagickExport const TypeInfo **GetTypeInfoList(const char *pattern,
00488 unsigned long *number_fonts,ExceptionInfo *exception)
00489 {
00490 const TypeInfo
00491 **fonts;
00492
00493 register const TypeInfo
00494 *p;
00495
00496 register long
00497 i;
00498
00499
00500
00501
00502 assert(pattern != (char *) NULL);
00503 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
00504 assert(number_fonts != (unsigned long *) NULL);
00505 *number_fonts=0;
00506 p=GetTypeInfo("*",exception);
00507 if (p == (const TypeInfo *) NULL)
00508 return((const TypeInfo **) NULL);
00509 fonts=(const TypeInfo **) AcquireQuantumMemory((size_t)
00510 GetNumberOfNodesInSplayTree(type_list)+1UL,sizeof(*fonts));
00511 if (fonts == (const TypeInfo **) NULL)
00512 return((const TypeInfo **) NULL);
00513
00514
00515
00516 AcquireSemaphoreInfo(&type_semaphore);
00517 ResetSplayTreeIterator(type_list);
00518 p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
00519 for (i=0; p != (const TypeInfo *) NULL; )
00520 {
00521 if ((p->stealth == MagickFalse) &&
00522 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
00523 fonts[i++]=p;
00524 p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
00525 }
00526 RelinquishSemaphoreInfo(type_semaphore);
00527 qsort((void *) fonts,(size_t) i,sizeof(*fonts),TypeInfoCompare);
00528 fonts[i]=(TypeInfo *) NULL;
00529 *number_fonts=(unsigned long) i;
00530 return(fonts);
00531 }
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561 #if defined(__cplusplus) || defined(c_plusplus)
00562 extern "C" {
00563 #endif
00564
00565 static int TypeCompare(const void *x,const void *y)
00566 {
00567 register const char
00568 **p,
00569 **q;
00570
00571 p=(const char **) x;
00572 q=(const char **) y;
00573 return(LocaleCompare(*p,*q));
00574 }
00575
00576 #if defined(__cplusplus) || defined(c_plusplus)
00577 }
00578 #endif
00579
00580 MagickExport char **GetTypeList(const char *pattern,unsigned long *number_fonts,
00581 ExceptionInfo *exception)
00582 {
00583 char
00584 **fonts;
00585
00586 register const TypeInfo
00587 *p;
00588
00589 register long
00590 i;
00591
00592
00593
00594
00595 assert(pattern != (char *) NULL);
00596 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",pattern);
00597 assert(number_fonts != (unsigned long *) NULL);
00598 *number_fonts=0;
00599 p=GetTypeInfo("*",exception);
00600 if (p == (const TypeInfo *) NULL)
00601 return((char **) NULL);
00602 fonts=(char **) AcquireQuantumMemory((size_t)
00603 GetNumberOfNodesInSplayTree(type_list)+1UL,sizeof(*fonts));
00604 if (fonts == (char **) NULL)
00605 return((char **) NULL);
00606
00607
00608
00609 AcquireSemaphoreInfo(&type_semaphore);
00610 ResetSplayTreeIterator(type_list);
00611 p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
00612 for (i=0; p != (const TypeInfo *) NULL; )
00613 {
00614 if ((p->stealth == MagickFalse) &&
00615 (GlobExpression(p->name,pattern,MagickFalse) != MagickFalse))
00616 fonts[i++]=ConstantString(p->name);
00617 p=(const TypeInfo *) GetNextValueInSplayTree(type_list);
00618 }
00619 RelinquishSemaphoreInfo(type_semaphore);
00620 qsort((void *) fonts,(size_t) i,sizeof(*fonts),TypeCompare);
00621 fonts[i]=(char *) NULL;
00622 *number_fonts=(unsigned long) i;
00623 return(fonts);
00624 }
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649 #if defined(MAGICKCORE_FONTCONFIG_DELEGATE)
00650 MagickExport MagickBooleanType LoadFontConfigFonts(SplayTreeInfo *type_list,
00651 ExceptionInfo *exception)
00652 {
00653 char
00654 extension[MaxTextExtent],
00655 name[MaxTextExtent];
00656
00657 FcChar8
00658 *family,
00659 *file,
00660 *style;
00661
00662 FcConfig
00663 *font_config;
00664
00665 FcFontSet
00666 *font_set;
00667
00668 FcObjectSet
00669 *object_set;
00670
00671 FcPattern
00672 *pattern;
00673
00674 FcResult
00675 status;
00676
00677 int
00678 slant,
00679 width,
00680 weight;
00681
00682 register long
00683 i;
00684
00685 TypeInfo
00686 *type_info;
00687
00688
00689
00690
00691 (void) exception;
00692 font_config=FcInitLoadConfigAndFonts();
00693 if (font_config == (FcConfig *) NULL)
00694 return(MagickFalse);
00695 font_set=(FcFontSet *) NULL;
00696 object_set=FcObjectSetBuild(FC_FAMILY,FC_STYLE,FC_SLANT,FC_WIDTH,FC_WEIGHT,
00697 FC_FILE,(char *) NULL);
00698 if (object_set != (FcObjectSet *) NULL)
00699 {
00700 pattern=FcPatternCreate();
00701 if (pattern != (FcPattern *) NULL)
00702 {
00703 font_set=FcFontList(0,pattern,object_set);
00704 FcPatternDestroy(pattern);
00705 }
00706 FcObjectSetDestroy(object_set);
00707 }
00708 if (font_set == (FcFontSet *) NULL)
00709 {
00710 FcConfigDestroy(font_config);
00711 return(MagickFalse);
00712 }
00713 for (i=0; i < (long) font_set->nfont; i++)
00714 {
00715 status=FcPatternGetString(font_set->fonts[i],FC_FAMILY,0,&family);
00716 if (status != FcResultMatch)
00717 continue;
00718 status=FcPatternGetString(font_set->fonts[i],FC_FILE,0,&file);
00719 if (status != FcResultMatch)
00720 continue;
00721 *extension='\0';
00722 GetPathComponent((const char *) file,ExtensionPath,extension);
00723 if ((*extension != '\0') && (LocaleCompare(extension,"gz") == 0))
00724 continue;
00725 type_info=(TypeInfo *) AcquireMagickMemory(sizeof(*type_info));
00726 if (type_info == (TypeInfo *) NULL)
00727 continue;
00728 (void) ResetMagickMemory(type_info,0,sizeof(*type_info));
00729 type_info->path=ConstantString("System Fonts");
00730 type_info->signature=MagickSignature;
00731 (void) CopyMagickString(name,(const char *) family,MaxTextExtent);
00732 (void) ConcatenateMagickString(name," ",MaxTextExtent);
00733 status=FcPatternGetString(font_set->fonts[i],FC_STYLE,0,&style);
00734 if (status == FcResultMatch)
00735 (void) ConcatenateMagickString(name,(const char *) style,MaxTextExtent);
00736 type_info->name=ConstantString(name);
00737 (void) SubstituteString(&type_info->name," ","-");
00738 (void) SubstituteString(&type_info->name,"-L-","-");
00739 (void) SubstituteString(&type_info->name,"semicondensed","SemiCondensed");
00740 type_info->family=ConstantString((const char *) family);
00741 (void) SubstituteString(&type_info->family," L","");
00742 status=FcPatternGetInteger(font_set->fonts[i],FC_SLANT,0,&slant);
00743 type_info->style=NormalStyle;
00744 if (slant == FC_SLANT_ITALIC)
00745 type_info->style=ItalicStyle;
00746 if (slant == FC_SLANT_OBLIQUE)
00747 type_info->style=ObliqueStyle;
00748 status=FcPatternGetInteger(font_set->fonts[i],FC_WIDTH,0,&width);
00749 type_info->stretch=NormalStretch;
00750 if (width >= FC_WIDTH_ULTRACONDENSED)
00751 type_info->stretch=UltraCondensedStretch;
00752 if (width >= FC_WIDTH_EXTRACONDENSED)
00753 type_info->stretch=ExtraCondensedStretch;
00754 if (width >= FC_WIDTH_CONDENSED)
00755 type_info->stretch=CondensedStretch;
00756 if (width >= FC_WIDTH_SEMICONDENSED)
00757 type_info->stretch=SemiCondensedStretch;
00758 if (width >= FC_WIDTH_NORMAL)
00759 type_info->stretch=NormalStretch;
00760 if (width >= FC_WIDTH_SEMIEXPANDED)
00761 type_info->stretch=SemiExpandedStretch;
00762 if (width >= FC_WIDTH_EXPANDED)
00763 type_info->stretch=ExpandedStretch;
00764 if (width >= FC_WIDTH_EXTRAEXPANDED)
00765 type_info->stretch=ExtraExpandedStretch;
00766 if (width >= FC_WIDTH_ULTRAEXPANDED)
00767 type_info->stretch=UltraExpandedStretch;
00768 type_info->weight=400;
00769 status=FcPatternGetInteger(font_set->fonts[i],FC_WEIGHT,0,&weight);
00770 if (weight >= FC_WEIGHT_THIN)
00771 type_info->weight=100;
00772 if (weight >= FC_WEIGHT_EXTRALIGHT)
00773 type_info->weight=200;
00774 if (weight >= FC_WEIGHT_LIGHT)
00775 type_info->weight=300;
00776 if (weight >= FC_WEIGHT_NORMAL)
00777 type_info->weight=400;
00778 if (weight >= FC_WEIGHT_MEDIUM)
00779 type_info->weight=500;
00780 if (weight >= FC_WEIGHT_DEMIBOLD)
00781 type_info->weight=600;
00782 if (weight >= FC_WEIGHT_BOLD)
00783 type_info->weight=700;
00784 if (weight >= FC_WEIGHT_EXTRABOLD)
00785 type_info->weight=800;
00786 if (weight >= FC_WEIGHT_BLACK)
00787 type_info->weight=900;
00788 type_info->glyphs=ConstantString((const char *) file);
00789 (void) AddValueToSplayTree(type_list,type_info->name,type_info);
00790 }
00791 FcFontSetDestroy(font_set);
00792 FcConfigDestroy(font_config);
00793 return(MagickTrue);
00794 }
00795 #endif
00796
00797 static MagickBooleanType InitializeTypeList(ExceptionInfo *exception)
00798 {
00799 if ((type_list == (SplayTreeInfo *) NULL) &&
00800 (instantiate_type == MagickFalse))
00801 {
00802 AcquireSemaphoreInfo(&type_semaphore);
00803 if ((type_list == (SplayTreeInfo *) NULL) &&
00804 (instantiate_type == MagickFalse))
00805 {
00806 (void) LoadTypeLists(MagickTypeFilename,exception);
00807 #if defined(__WINDOWS__)
00808 (void) NTLoadTypeLists(type_list,exception);
00809 #endif
00810 #if defined(MAGICKCORE_FONTCONFIG_DELEGATE)
00811 (void) LoadFontConfigFonts(type_list,exception);
00812 #endif
00813 instantiate_type=MagickTrue;
00814 }
00815 RelinquishSemaphoreInfo(type_semaphore);
00816 }
00817 return(type_list != (SplayTreeInfo *) NULL ? MagickTrue : MagickFalse);
00818 }
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844 MagickExport MagickBooleanType ListTypeInfo(FILE *file,ExceptionInfo *exception)
00845 {
00846 char
00847 weight[MaxTextExtent];
00848
00849 const char
00850 *family,
00851 *glyphs,
00852 *name,
00853 *path,
00854 *stretch,
00855 *style;
00856
00857 const TypeInfo
00858 **type_info;
00859
00860 register long
00861 i;
00862
00863 unsigned long
00864 number_fonts;
00865
00866 if (file == (FILE *) NULL)
00867 file=stdout;
00868 number_fonts=0;
00869 type_info=GetTypeInfoList("*",&number_fonts,exception);
00870 if (type_info == (const TypeInfo **) NULL)
00871 return(MagickFalse);
00872 *weight='\0';
00873 path=(const char *) NULL;
00874 for (i=0; i < (long) number_fonts; i++)
00875 {
00876 if (type_info[i]->stealth != MagickFalse)
00877 continue;
00878 if (((path == (const char *) NULL) ||
00879 (LocaleCompare(path,type_info[i]->path) != 0)) &&
00880 (type_info[i]->path != (char *) NULL))
00881 (void) fprintf(file,"\nPath: %s\n",type_info[i]->path);
00882 path=type_info[i]->path;
00883 name="unknown";
00884 if (type_info[i]->name != (char *) NULL)
00885 name=type_info[i]->name;
00886 family="unknown";
00887 if (type_info[i]->family != (char *) NULL)
00888 family=type_info[i]->family;
00889 style=MagickOptionToMnemonic(MagickStyleOptions,type_info[i]->style);
00890 stretch=MagickOptionToMnemonic(MagickStretchOptions,type_info[i]->stretch);
00891 glyphs="unknown";
00892 if (type_info[i]->glyphs != (char *) NULL)
00893 glyphs=type_info[i]->glyphs;
00894 (void) FormatMagickString(weight,MaxTextExtent,"%lu",type_info[i]->weight);
00895 (void) fprintf(file," Font: %s\n",name);
00896 (void) fprintf(file," family: %s\n",family);
00897 (void) fprintf(file," style: %s\n",style);
00898 (void) fprintf(file," stretch: %s\n",stretch);
00899 (void) fprintf(file," weight: %s\n",weight);
00900 (void) fprintf(file," glyphs: %s\n",glyphs);
00901 }
00902 (void) fflush(file);
00903 type_info=(const TypeInfo **) RelinquishMagickMemory((void *) type_info);
00904 return(MagickTrue);
00905 }
00906
00907
00908
00909
00910
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935
00936
00937
00938 static void *DestroyTypeNode(void *type_info)
00939 {
00940 register TypeInfo
00941 *p;
00942
00943 p=(TypeInfo *) type_info;
00944 if (p->path != (char *) NULL)
00945 p->path=DestroyString(p->path);
00946 if (p->name != (char *) NULL)
00947 p->name=DestroyString(p->name);
00948 if (p->description != (char *) NULL)
00949 p->description=DestroyString(p->description);
00950 if (p->family != (char *) NULL)
00951 p->family=DestroyString(p->family);
00952 if (p->encoding != (char *) NULL)
00953 p->encoding=DestroyString(p->encoding);
00954 if (p->foundry != (char *) NULL)
00955 p->foundry=DestroyString(p->foundry);
00956 if (p->format != (char *) NULL)
00957 p->format=DestroyString(p->format);
00958 if (p->metrics != (char *) NULL)
00959 p->metrics=DestroyString(p->metrics);
00960 if (p->glyphs != (char *) NULL)
00961 p->glyphs=DestroyString(p->glyphs);
00962 return(RelinquishMagickMemory(p));
00963 }
00964
00965 static MagickBooleanType LoadTypeList(const char *xml,const char *filename,
00966 const unsigned long depth,ExceptionInfo *exception)
00967 {
00968 char
00969 font_path[MaxTextExtent],
00970 keyword[MaxTextExtent],
00971 *token;
00972
00973 const char
00974 *q;
00975
00976 MagickBooleanType
00977 status;
00978
00979 TypeInfo
00980 *type_info;
00981
00982
00983
00984
00985 (void) LogMagickEvent(ConfigureEvent,GetMagickModule(),
00986 "Loading type configure file \"%s\" ...",filename);
00987 if (xml == (const char *) NULL)
00988 return(MagickFalse);
00989 if (type_list == (SplayTreeInfo *) NULL)
00990 {
00991 type_list=NewSplayTree(CompareSplayTreeString,(void *(*)(void *)) NULL,
00992 DestroyTypeNode);
00993 if (type_list == (SplayTreeInfo *) NULL)
00994 {
00995 ThrowFileException(exception,ResourceLimitError,
00996 "MemoryAllocationFailed",filename);
00997 return(MagickFalse);
00998 }
00999 }
01000 status=MagickTrue;
01001 type_info=(TypeInfo *) NULL;
01002 token=AcquireString(xml);
01003 #if defined(__WINDOWS__)
01004
01005
01006
01007 *font_path='\0';
01008 if (NTGhostscriptFonts(font_path,MaxTextExtent-2))
01009 (void) ConcatenateMagickString(font_path,DirectorySeparator,MaxTextExtent);
01010 #endif
01011 for (q=(char *) xml; *q != '\0'; )
01012 {
01013
01014
01015
01016 GetMagickToken(q,&q,token);
01017 if (*token == '\0')
01018 break;
01019 (void) CopyMagickString(keyword,token,MaxTextExtent);
01020 if (LocaleNCompare(keyword,"<!DOCTYPE",9) == 0)
01021 {
01022
01023
01024
01025 while ((LocaleNCompare(q,"]>",2) != 0) && (*q != '\0'))
01026 GetMagickToken(q,&q,token);
01027 continue;
01028 }
01029 if (LocaleNCompare(keyword,"<!--",4) == 0)
01030 {
01031
01032
01033
01034 while ((LocaleNCompare(q,"->",2) != 0) && (*q != '\0'))
01035 GetMagickToken(q,&q,token);
01036 continue;
01037 }
01038 if (LocaleCompare(keyword,"<include") == 0)
01039 {
01040
01041
01042
01043 while (((*token != '/') && (*(token+1) != '>')) && (*q != '\0'))
01044 {
01045 (void) CopyMagickString(keyword,token,MaxTextExtent);
01046 GetMagickToken(q,&q,token);
01047 if (*token != '=')
01048 continue;
01049 GetMagickToken(q,&q,token);
01050 if (LocaleCompare(keyword,"file") == 0)
01051