|
MagickCore
6.7.5
|
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 }