1
2 /******************************************************************************
3 * MODULE : tt_file.cpp
4 * DESCRIPTION: Finding a True Type font
5 * COPYRIGHT : (C) 2003 Joris van der Hoeven
6 *******************************************************************************
7 * This software falls under the GNU general public license version 3 or later.
8 * It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
9 * in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
10 ******************************************************************************/
11
12 #include "tt_file.hpp"
13 #include "tt_tools.hpp"
14 #include "file.hpp"
15 #include "boot.hpp"
16 #include "analyze.hpp"
17 #include "hashmap.hpp"
18 #include "Metafont/tex_files.hpp"
19 #include "timer.hpp"
20 #include "data_cache.hpp"
21
22 static hashmap<string,string> tt_fonts ("no");
23
24 url
tt_font_path()25 tt_font_path () {
26 string xtt= get_env ("TEXMACS_FONT_PATH");
27 url xu= url_none ();
28 if (xtt != "") xu= search_sub_dirs (xtt);
29 return
30 xu |
31 search_sub_dirs ("$TEXMACS_HOME_PATH/fonts/truetype") |
32 search_sub_dirs ("$TEXMACS_PATH/fonts/truetype") |
33 #if defined __MINGW32__
34 search_sub_dirs ("$windir/Fonts");
35 #elif defined OS_MACOS
36 search_sub_dirs ("$HOME/Library/Fonts") |
37 search_sub_dirs ("/Library/Fonts") |
38 search_sub_dirs ("/System/Library/Fonts") |
39 search_sub_dirs ("/opt/local/share/texmf-texlive-dist/fonts/truetype");
40 #else
41 search_sub_dirs ("$HOME/.fonts") |
42 search_sub_dirs ("/usr/share/fonts/truetype") |
43 search_sub_dirs ("/usr/local/share/fonts/truetype");
44 #endif
45 }
46
47 static url
tt_locate(string name)48 tt_locate (string name) {
49 if (ends (name, ".pfb")) {
50 /*
51 if (starts (name, "rpag")) name= "uag" * name (4, N (name) - 4) * "8a.pfb";
52 if (starts (name, "rpbk")) name= "ubk" * name (4, N (name) - 4) * "8a.pfb";
53 if (starts (name, "rpcr")) name= "ucr" * name (4, N (name) - 4) * "8a.pfb";
54 if (starts (name, "rphv")) name= "uhv" * name (4, N (name) - 4) * "8a.pfb";
55 if (starts (name, "rpnc")) name= "unc" * name (4, N (name) - 4) * "8a.pfb";
56 if (starts (name, "rppl")) name= "upl" * name (4, N (name) - 4) * "8a.pfb";
57 if (starts (name, "rpsy")) name= "usy" * name (4, N (name));
58 if (starts (name, "rptm")) name= "utm" * name (4, N (name) - 4) * "8a.pfb";
59 if (starts (name, "rpzc")) name= "uzc" * name (4, N (name) - 4) * "8a.pfb";
60 if (starts (name, "rpzd")) name= "uzd" * name (4, N (name));
61 */
62 url u= resolve_tex (name);
63 //cout << "tt_locate: " << name << " -> " << u << "\n";
64 if (!is_none (u)) return u;
65 }
66 else if (use_locate &&
67 // NOTE: avoiding unnecessary locates can greatly improve timings
68 !starts (name, "ec") &&
69 !starts (name, "la") &&
70 !starts (name, "cm") &&
71 !starts (name, "msam") &&
72 !starts (name, "msbm") &&
73 !starts (name, "bbm") &&
74 !starts (name, "stmary") &&
75 !starts (name, "rsfs") &&
76 !starts (name, "grmn") &&
77 !starts (name, "mac-")
78 // FIXME: better caching of missed tt_locates would be better
79 )
80 {
81 string s= eval_system ("locate", "/" * name);
82 //cout << "locate " << name << " -> " << s << "\n";
83 int start, i, n= N(s);
84 for (start=0, i=0; i<n; i++)
85 if (s[i]=='\n') {
86 if (ends (s (start, i), name))
87 return url (s (start, i));
88 start= i+1;
89 }
90 }
91
92 url tt_path= tt_font_path ();
93 //cout << "Resolve " << name << " in " << tt_path << "\n";
94 return resolve (tt_path * name);
95 }
96
97 url
tt_font_find_sub(string name)98 tt_font_find_sub (string name) {
99 //cout << "tt_font_find " << name << "\n";
100 url u= tt_unpack (name);
101 if (!is_none (u)) return u;
102 u= tt_locate (name * ".pfb");
103 //if (!is_none (u)) cout << name << " -> " << u << "\n";
104 if (!is_none (u)) return u;
105 u= tt_locate (name * ".ttf");
106 //if (!is_none (u)) cout << name << " -> " << u << "\n";
107 //else cout << name << " -> ???\n";
108 if (!is_none (u)) return u;
109 u= tt_locate (name * ".ttc");
110 if (!is_none (u)) return u;
111 u= tt_locate (name * ".otf");
112 if (!is_none (u)) return u;
113 u= tt_locate (name * ".dfont");
114 return u;
115 }
116
117 url
tt_font_find(string name)118 tt_font_find (string name) {
119 string s= "ttf:" * name;
120 if (is_cached ("font_cache.scm", s)) {
121 string r= cache_get ("font_cache.scm", s) -> label;
122 if (r == "") return url_none ();
123 url u= url_system (r);
124 if (exists (u)) return u;
125 cache_reset ("font_cache.scm", s);
126 }
127
128 url r= tt_font_find_sub (name);
129 if (is_none (r)) cache_set ("font_cache.scm", s, "");
130 else cache_set ("font_cache.scm", s, as_string (r));
131 return r;
132 }
133
134 bool
tt_font_exists(string name)135 tt_font_exists (string name) {
136 //cout << "tt_font_exists? " << name << "\n";
137 if (tt_fonts->contains (name)) return tt_fonts[name] == "yes";
138 bool yes= !is_none (tt_font_find (name));
139 tt_fonts (name)= yes? string ("yes"): string ("no");
140 return yes;
141 }
142
143 string
tt_find_name_sub(string name,int size)144 tt_find_name_sub (string name, int size) {
145 if (size == 0) {
146 if (tt_font_exists (name)) return name;
147 else return "";
148 }
149 if (tt_font_exists (name * as_string (size)))
150 return name * as_string (size);
151 if (size > 333) size= (size+50)/100;
152 if (tt_font_exists (name * as_string (size)))
153 return name * as_string (size);
154
155 if ((size >= 15) && tt_font_exists (name * "17")) return name * "17";
156 if ((size > 12) && tt_font_exists (name * "12")) return name * "12";
157 if ((size < 5 ) && tt_font_exists (name * "5" )) return name * "5" ;
158 if ((size < 6 ) && tt_font_exists (name * "6" )) return name * "6" ;
159 if ((size < 7 ) && tt_font_exists (name * "7" )) return name * "7" ;
160 if ((size < 8 ) && tt_font_exists (name * "8" )) return name * "8" ;
161 if ((size < 9 ) && tt_font_exists (name * "9" )) return name * "9" ;
162 if ((size < 9 ) && tt_font_exists (name * "7" )) return name * "7" ;
163 if (tt_font_exists (name * "10")) return name * "10";
164 if ((size < 9 ) && tt_font_exists (name * "700" )) return name * "700" ;
165 if ((size >= 15) && tt_font_exists (name * "1700")) return name * "1700";
166 if (tt_font_exists (name * "1000")) return name * "1000";
167 if (tt_font_exists (name)) return name;
168 return "";
169 }
170
171 string
tt_find_name(string name,int size)172 tt_find_name (string name, int size) {
173 string s= "tt:" * name * as_string (size);
174 if (is_cached ("font_cache.scm", s)) {
175 string r= cache_get ("font_cache.scm", s) -> label;
176 if (tt_font_exists (r)) return r;
177 cache_reset ("font_cache.scm", s);
178 }
179
180 bench_start ("tt find name");
181 string r= tt_find_name_sub (name, size);
182 //cout << name << size << " -> " << r << "\n";
183 bench_cumul ("tt find name");
184
185 if (r != "") cache_set ("font_cache.scm", s, r);
186 return r;
187 }
188