Back to index

texmacs  1.0.7.15
tt_file.cpp
Go to the documentation of this file.
00001 
00002 /******************************************************************************
00003 * MODULE     : tt_file.cpp
00004 * DESCRIPTION: Finding a True Type font
00005 * COPYRIGHT  : (C) 2003  Joris van der Hoeven
00006 *******************************************************************************
00007 * This software falls under the GNU general public license version 3 or later.
00008 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
00009 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
00010 ******************************************************************************/
00011 
00012 #include "tt_file.hpp"
00013 #include "file.hpp"
00014 #include "boot.hpp"
00015 #include "analyze.hpp"
00016 #include "hashmap.hpp"
00017 #include "Metafont/tex_files.hpp"
00018 #include "timer.hpp"
00019 #include "data_cache.hpp"
00020 
00021 static hashmap<string,string> tt_fonts ("no");
00022 
00023 static url
00024 search_sub_dirs (url root) {
00025   url dirs= complete (root * url_wildcard (), "dr");
00026   return expand (dirs);
00027 }
00028 
00029 static url
00030 tt_locate (string name) {
00031   if (ends (name, ".pfb")) {
00032     /*
00033     if (starts (name, "rpag")) name= "uag" * name (4, N (name) - 4) * "8a.pfb";
00034     if (starts (name, "rpbk")) name= "ubk" * name (4, N (name) - 4) * "8a.pfb";
00035     if (starts (name, "rpcr")) name= "ucr" * name (4, N (name) - 4) * "8a.pfb";
00036     if (starts (name, "rphv")) name= "uhv" * name (4, N (name) - 4) * "8a.pfb";
00037     if (starts (name, "rpnc")) name= "unc" * name (4, N (name) - 4) * "8a.pfb";
00038     if (starts (name, "rppl")) name= "upl" * name (4, N (name) - 4) * "8a.pfb";
00039     if (starts (name, "rpsy")) name= "usy" * name (4, N (name));
00040     if (starts (name, "rptm")) name= "utm" * name (4, N (name) - 4) * "8a.pfb";
00041     if (starts (name, "rpzc")) name= "uzc" * name (4, N (name) - 4) * "8a.pfb";
00042     if (starts (name, "rpzd")) name= "uzd" * name (4, N (name));
00043     */
00044     url u= resolve_tex (name);
00045     //cout << "tt_locate: " << name << " -> " << u << "\n";
00046     if (!is_none (u)) return u;
00047   }
00048   else if (use_locate &&
00049           // NOTE: avoiding unnecessary locates can greatly improve timings
00050           !starts (name, "ec") &&
00051           !starts (name, "la") &&
00052           !starts (name, "cm") &&
00053           !starts (name, "msam") &&
00054           !starts (name, "msbm") &&
00055           !starts (name, "bbm") &&
00056           !starts (name, "stmary") &&
00057           !starts (name, "rsfs") &&
00058           !starts (name, "grmn") &&
00059           !starts (name, "mac-")
00060           // FIXME: better caching of missed tt_locates would be better
00061           )
00062     {
00063       string s= eval_system ("locate", "/" * name);
00064       //cout << "locate " << name << " -> " << s << "\n";
00065       int start, i, n= N(s);
00066       for (start=0, i=0; i<n; i++)
00067        if (s[i]=='\n') {
00068          if (ends (s (start, i), name))
00069            return url (s (start, i));
00070          start= i+1;
00071        }
00072     }
00073 
00074   url tt_path=
00075     search_sub_dirs ("$TEXMACS_HOME_PATH/fonts/truetype") |
00076 #if defined __MINGW32__
00077     search_sub_dirs ("$windir/Fonts");
00078 #elif defined OS_MACOS
00079     search_sub_dirs ("$HOME/Library/Fonts") |
00080     search_sub_dirs ("/Library/Fonts") |
00081     search_sub_dirs ("/System/Library/Fonts");
00082 #else
00083     search_sub_dirs ("/usr/share/fonts/truetype") |
00084     search_sub_dirs ("/usr/local/share/fonts/truetype");
00085 #endif
00086   //cout << "Resolve " << name << " in " << tt_path << "\n";
00087   return resolve (tt_path * name);
00088 }
00089 
00090 url
00091 tt_font_find_sub (string name) {
00092   //cout << "tt_font_find " << name << "\n";
00093   url u= tt_locate (name * ".pfb");
00094   //if (!is_none (u)) cout << name << " -> " << u << "\n";
00095   if (!is_none (u)) return u;
00096   u= tt_locate (name * ".ttf");
00097   //if (!is_none (u)) cout << name << " -> " << u << "\n";
00098   //else cout << name << " -> ???\n";
00099   if (!is_none (u)) return u;
00100   u= tt_locate (name * ".ttc");
00101   if (!is_none (u)) return u;
00102   u= tt_locate (name * ".otf");
00103   if (!is_none (u)) return u;
00104   u= tt_locate (name * ".dfont");
00105   return u;
00106 }
00107 
00108 url
00109 tt_font_find (string name) {
00110   string s= "ttf:" * name;
00111   if (is_cached ("font_cache.scm", s)) {
00112     string r= cache_get ("font_cache.scm", s) -> label;
00113     if (r == "") return url_none ();
00114     url u= url_system (r);
00115     if (exists (u)) return u;
00116     cache_reset ("font_cache.scm", s);
00117   }
00118 
00119   url r= tt_font_find_sub (name);
00120   if (is_none (r)) cache_set ("font_cache.scm", s, "");
00121   else cache_set ("font_cache.scm", s, as_string (r));
00122   return r;
00123 }
00124 
00125 bool
00126 tt_font_exists (string name) {
00127   //cout << "tt_font_exists? " << name << "\n";
00128   if (tt_fonts->contains (name)) return tt_fonts[name] == "yes";
00129   bool yes= !is_none (tt_font_find (name));
00130   tt_fonts (name)= yes? string ("yes"): string ("no");
00131   return yes;
00132 }
00133 
00134 string
00135 tt_find_name_sub (string name, int size) {
00136   if (size == 0) {
00137     if (tt_font_exists (name)) return name;
00138     else return "";
00139   }
00140   if (tt_font_exists (name * as_string (size)))
00141     return name * as_string (size);
00142   if (size > 333) size= (size+50)/100;
00143   if (tt_font_exists (name * as_string (size)))
00144     return name * as_string (size);
00145 
00146   if ((size >= 15) && tt_font_exists (name * "17")) return name * "17";
00147   if ((size >  12) && tt_font_exists (name * "12")) return name * "12";
00148   if ((size <  5 ) && tt_font_exists (name * "5" )) return name * "5" ;
00149   if ((size <  6 ) && tt_font_exists (name * "6" )) return name * "6" ;
00150   if ((size <  7 ) && tt_font_exists (name * "7" )) return name * "7" ;
00151   if ((size <  8 ) && tt_font_exists (name * "8" )) return name * "8" ;
00152   if ((size <  9 ) && tt_font_exists (name * "9" )) return name * "9" ;
00153   if ((size <  9 ) && tt_font_exists (name * "7" )) return name * "7" ;
00154   if (tt_font_exists (name * "10")) return name * "10";
00155   if ((size <  9 ) && tt_font_exists (name * "700" )) return name * "700" ;
00156   if ((size >= 15) && tt_font_exists (name * "1700")) return name * "1700";
00157   if (tt_font_exists (name * "1000")) return name * "1000";
00158   if (tt_font_exists (name)) return name;
00159   return "";
00160 }
00161 
00162 string
00163 tt_find_name (string name, int size) {
00164   string s= "tt:" * name * as_string (size);
00165   if (is_cached ("font_cache.scm", s)) {
00166     string r= cache_get ("font_cache.scm", s) -> label;
00167     if (tt_font_exists (r)) return r;
00168     cache_reset ("font_cache.scm", s);
00169   }
00170 
00171   bench_start ("tt find name");
00172   string r= tt_find_name_sub (name, size);
00173   //cout << name << size << " -> " << r << "\n";
00174   bench_cumul ("tt find name");
00175 
00176   if (r != "") cache_set ("font_cache.scm", s, r);
00177   return r;
00178 }