2
/******************************************************************************
3
* MODULE : load_tex.cpp
4
* DESCRIPTION: simultaneously load pk and tfm file and
5
* generate them if they can't be found.
6
* COPYRIGHT : (C) 1999 Joris van der Hoeven
7
*******************************************************************************
8
* This software falls under the GNU general public license version 3 or later.
9
* It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
10
* in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
11
******************************************************************************/
13
#include "load_tex.hpp"
16
#include "Freetype/tt_file.hpp"
17
#include "Freetype/tt_face.hpp"
19
#include "data_cache.hpp"
26
mag (double dpi, double size, double dsize) {
27
if ((size>=100) && (dsize<100)) dsize *= 100;
28
if ((dsize>=100) && (size<100)) size *= 100;
29
return (int) (((size * dpi) / dsize) + 0.5);
32
/******************************************************************************
34
******************************************************************************/
37
try_tfm (string family, int size, int osize, tex_font_metric& tfm, bool make) {
38
// cout << "Try tfm " << family << size << " (" << osize << ")\n";
39
make= make && get_setting ("MAKETFM") != "false";
40
string name_tfm = family * as_string (osize) * ".tfm";
41
if (tex_font_metric::instances -> contains (name_tfm)) {
42
tfm= tex_font_metric (name_tfm);
45
string name= family * (size==0? string (""): as_string (size)) * ".tfm";
46
if (DEBUG_STD) cout << "TeXmacs] Try tfm " << name << "\n";
47
url u= resolve_tex (name);
49
if (exists (url ("$TEXMACS_HOME_PATH/fonts/error", name)))
52
system_wait ("Generating font file", name);
55
u= resolve_tex (name);
58
u= resolve_tex (name);
59
save_string (url ("$TEXMACS_HOME_PATH/fonts/error", name), "");
62
if (is_none (u)) return false;
64
// cout << "Tfm " << family << osize << " -> " << family << size << "\n";
65
tfm= load_tfm (u, family, osize);
67
cache_set ("font_cache.scm",
68
"tfm:" * family * as_string (osize), as_string (size));
71
if (DEBUG_STD) cout << "TeXmacs] Design size = " << size << "\n";
74
tfm->header[1]= mag (tfm->header[1], osize, size);
79
load_tex_tfm (string family, int size, int dsize, tex_font_metric& tfm,
82
//cout << "Load TeX tfm " << family << size << " (dsize= " << dsize << ")\n";
83
if (try_tfm (family, size, size, tfm, make))
86
return load_tex_tfm (family, (size+50)/100, dsize, tfm, make);
87
if (get_font_type () == 3) {
88
if ((size > 14) && try_tfm (family, 17, size, tfm, make)) return true;
89
if ((size > 12) && try_tfm (family, 12, size, tfm, make)) return true;
90
if ((size > 10) && try_tfm (family, 10, size, tfm, make)) return true;
91
if ((size < 5) && try_tfm (family, 5, size, tfm, make)) return true;
92
if ((size < 6) && try_tfm (family, 6, size, tfm, make)) return true;
93
if ((size < 7) && try_tfm (family, 7, size, tfm, make)) return true;
94
if ((size < 8) && try_tfm (family, 8, size, tfm, make)) return true;
95
if ((size < 9) && try_tfm (family, 9, size, tfm, make)) return true;
96
if ((size < 9) && try_tfm (family, 7, size, tfm, make)) return true;
97
if (try_tfm (family, 10, size, tfm, make)) return true;
98
if ((size > 14) && try_tfm (family, 1700, size, tfm, make)) return true;
99
if ((size > 12) && try_tfm (family, 1200, size, tfm, make)) return true;
100
if ((size < 5) && try_tfm (family, 500, size, tfm, make)) return true;
101
if ((size < 9) && try_tfm (family, 700, size, tfm, make)) return true;
102
if (try_tfm (family, 1000, size, tfm, make)) return true;
104
if (get_font_type () == 2) {
105
SI delta= (size<10? 1: -1);
106
if (try_tfm (family, size + delta, size, tfm, make)) return true;
107
if (try_tfm (family, size - delta, size, tfm, make)) return true;
108
if (try_tfm (family, size + 2*delta, size, tfm, make)) return true;
109
if (try_tfm (family, size - 2*delta, size, tfm, make)) return true;
110
if (try_tfm (family, 100 * size, size, tfm, make)) return true;
111
if (try_tfm (family, 100 * (size + delta), size, tfm, make)) return true;
112
if (try_tfm (family, 100 * (size - delta), size, tfm, make)) return true;
113
if (try_tfm (family, 100 * (size + 2*delta), size, tfm, make)) return true;
114
if (try_tfm (family, 100 * (size - 2*delta), size, tfm, make)) return true;
117
if (try_tfm (family, dsize, size, tfm, make))
119
if ((dsize != 10) && (size != 10))
120
if (try_tfm (family, 10, size, tfm, make))
126
load_tex_tfm (string family, int size, int dsize, tex_font_metric& tfm) {
127
string var= "tfm:" * family * as_string (size);
128
if (is_cached ("font_cache.scm", var))
129
if (try_tfm (family, as_int (cache_get ("font_cache.scm", var)->label),
132
if (get_font_type () >= 2 && get_setting ("MAKETFM") != "false")
133
if (load_tex_tfm (family, size ,dsize, tfm, false))
135
return load_tex_tfm (family, size ,dsize, tfm, true);
138
/******************************************************************************
139
* PK font glyphs with lazy parsing
140
******************************************************************************/
142
static glyph error_glyph;
144
struct pk_font_glyphs_rep: public font_glyphs_rep {
147
glyph* fng; // definitions of the characters
149
pk_font_glyphs_rep (string name, pk_loader*);
150
glyph& get (int char_code);
153
pk_font_glyphs_rep::pk_font_glyphs_rep(string name, pk_loader* pkl2)
154
:font_glyphs_rep (name), pkl (pkl2)
157
fng = pkl->load_pk ();
169
pk_font_glyphs_rep::get(int c)
171
if ((c<bc) || (c>ec)) return error_glyph;
172
if (pkl && !pkl->unpacked[c-bc]) {
173
pkl->input_pos = pkl->char_pos[c-bc];
174
pkl->flagbyte = pkl->char_flag[c-bc];
175
pkl->unpack(fng[c-bc]);
177
pkl->unpacked[c-bc] = true;
182
/******************************************************************************
184
******************************************************************************/
187
try_pk (string family, int size, int dpi, int dsize,
188
tex_font_metric& tfm, font_glyphs& pk)
190
// cout << "Try pk " << family << size << " at " << dpi << " dpi\n";
192
if (get_font_type () > 0) {
193
// Substitute by True Type font ?
194
int tt_size= size<333? size: (size+50)/100;
195
int tt_dpi = size<333? dpi : (size * dpi) / (100 * tt_size);
196
string tt_name= tt_find_name (family, tt_size);
198
if (font_glyphs::instances -> contains (tt_name))
199
pk= font_glyphs (tt_name);
200
else pk= tt_font_glyphs (tt_name, tt_size, tt_dpi);
204
#endif // USE_FREETYPE
206
// Open regular pk font
207
string name_pk= family * as_string (size) * "." * as_string (dpi) * "pk";
208
if (font_glyphs::instances -> contains (name_pk)) {
209
pk = font_glyphs (name_pk);
215
dpi = mag (dpi, old_size, size);
217
string size_name (dsize==0? string (""): as_string (size));
218
string name (family * size_name * "." * as_string (dpi) * "pk");
219
if (DEBUG_STD) cout << "TeXmacs] Open pk " << name << "\n";
220
url u= resolve_tex (name);
222
if (exists (url ("$TEXMACS_HOME_PATH/fonts/error", name)))
224
if (get_setting ("MAKEPK") != "false") {
225
system_wait ("Generating font file", name);
226
make_tex_pk (family * size_name, dpi, as_int (get_setting ("DPI")));
228
u= resolve_tex (name);
231
u= resolve_tex (name);
235
save_string (url ("$TEXMACS_HOME_PATH/fonts/error", name), "");
239
pk = font_glyphs (tm_new<pk_font_glyphs_rep> (name_pk,
240
tm_new<pk_loader> (u, tfm, dpi)));
245
load_tex_pk (string family, int size, int dpi, int dsize,
246
tex_font_metric& tfm, font_glyphs& pk) {
247
if (try_pk (family, size, dpi, dsize, tfm, pk)) return true;
248
if ((dsize != size) && (dsize != 0))
249
if (try_pk (family, dsize, mag (dpi, size, dsize), dsize, tfm, pk))
251
if ((dsize != 10) && (size != 10))
252
if (try_pk (family, 10, mag (dpi, size, 10), dsize, tfm, pk))
255
int sz= (size+50)/100;
256
return load_tex_pk (family, sz, mag (dpi, size, sz), dsize, tfm, pk);
261
/******************************************************************************
262
* Loading tfm and pk files
263
******************************************************************************/
266
rubber_status (glyph& gl, int st) {
272
rubber_fix (tex_font_metric tfm, font_glyphs& pk) {
273
// This routine is used so as to correct the anti-aliasing of
274
// rubber TeX characters (in the vertical direction).
276
for (c=tfm->bc; c<=tfm->ec; c++) {
277
if (tfm->tag (c)==3) {
278
if (tfm->bot(c)!=0) rubber_status (pk->get (tfm->bot (c)), 1);
279
if (tfm->top(c)!=0) rubber_status (pk->get (tfm->top (c)), 2);
280
if (tfm->mid(c)!=0) rubber_status (pk->get (tfm->mid (c)), 3);
281
if (tfm->rep(c)!=0) rubber_status (pk->get (tfm->rep (c)), 3);
287
load_tex (string family, int size, int dpi, int dsize,
288
tex_font_metric& tfm, font_glyphs& pk)
290
bench_start ("load tex font");
292
cout << "TeXmacs] loading " << family << size
293
<< " at " << dpi << " dpi\n";
294
if (load_tex_tfm (family, size, dsize, tfm) &&
295
load_tex_pk (family, size, dpi, dsize, tfm, pk))
297
bench_cumul ("load tex font");
298
rubber_fix (tfm, pk);
302
cout << "TeXmacs] font " << family << size
303
<< " at " << dpi << " dpi not found\n";
304
cout << "TeXmacs] loading ecrm" << size
305
<< " at " << dpi << " dpi instead\n";
307
if (load_tex_tfm ("ecrm", size, 10, tfm) &&
308
load_tex_pk ("ecrm", size, dpi, 10, tfm, pk))
310
bench_cumul ("load tex font");
315
string name= family * as_string (size) * "@" * as_string (dpi);
316
cerr << "\n\nCould not open font " << name << "\nLoading default" << LF;
317
cout << "Could not load font...\nLoading default" << LF;
319
if (load_tex_tfm ("ecrm", 10, 10, tfm) &&
320
load_tex_pk ("ecrm", 10, 600, 10, tfm, pk))
322
bench_cumul ("load tex font");
327
string name= family * as_string (size) * "@" * as_string (dpi);
328
cerr << "\n\nI could not open " << name << "\n";
329
FAILED ("Tex seems not to be installed properly");
330
bench_cumul ("load tex font");