~reviczky/luatex/luatex-svn

« back to all changes in this revision

Viewing changes to source/texk/web2c/luatexdir/pdf/pdffont.w

  • Committer: Adam Reviczky
  • Date: 2015-03-29 18:56:26 UTC
  • Revision ID: adam.reviczky@kclalumni.net-20150329185626-7j7tmwyfpa69lqwo
Revision 5213

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
% pdffont.w
 
2
%
 
3
% Copyright 2009-2014 Taco Hoekwater <taco@@luatex.org>
 
4
%
 
5
% This file is part of LuaTeX.
 
6
%
 
7
% LuaTeX is free software; you can redistribute it and/or modify it under
 
8
% the terms of the GNU General Public License as published by the Free
 
9
% Software Foundation; either version 2 of the License, or (at your
 
10
% option) any later version.
 
11
%
 
12
% LuaTeX is distributed in the hope that it will be useful, but WITHOUT
 
13
% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 
14
% FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 
15
% License for more details.
 
16
%
 
17
% You should have received a copy of the GNU General Public License along
 
18
% with LuaTeX; if not, see <http://www.gnu.org/licenses/>.
 
19
 
 
20
\def\pdfTeX{pdf\TeX}
 
21
 
 
22
@ @c
 
23
 
 
24
 
 
25
#include "ptexlib.h"
 
26
 
 
27
@ @c
 
28
#define font_id_text(A) cs_text(font_id_base+(A))       /* a frozen font identifier's name */
 
29
 
 
30
int pk_dpi;                     /* PK pixel density value from \.{texmf.cnf} */
 
31
 
 
32
 
 
33
@ As \pdfTeX{} should also act as a back-end driver, it needs to support virtual
 
34
fonts too. Information about virtual fonts can be found in the source of some
 
35
\.{DVI}-related programs.
 
36
 
 
37
Whenever we want to write out a character in a font to PDF output, we
 
38
should check whether the used character is a virtual or real character.
 
39
The |has_packet()| C macro checks for this condition.
 
40
 
 
41
 
 
42
@ The following code typesets a character to PDF output
 
43
 
 
44
@c
 
45
scaled_whd output_one_char(PDF pdf, halfword p)
 
46
{
 
47
    scaled_whd ci;              /* the real width, height and depth of the character */
 
48
    internal_font_number f = font(p);
 
49
    int c = character(p);
 
50
    int ex_glyph = ex_glyph(p)/1000;
 
51
    ci = get_charinfo_whd(f, c);
 
52
    if (!(char_exists(f,c))) {
 
53
        char_warning(f,c);
 
54
        return ci;
 
55
    }
 
56
    //ci.wd = round_xn_over_d(ci.wd, 1000 + ex_glyph, 1000);
 
57
    ci.wd = ext_xn_over_d(ci.wd, 1000000 + ex_glyph(p), 1000000);
 
58
    switch (pdf->posstruct->dir) {
 
59
    case dir_TLT:
 
60
        break;
 
61
    case dir_TRT:
 
62
        pos_left(ci.wd);
 
63
        break;
 
64
    case dir_LTL:
 
65
        pos_down(ci.ht);
 
66
        pos_left(ci.wd);
 
67
        break;
 
68
    case dir_RTT:
 
69
        pos_down(ci.ht);
 
70
        pos_left(ci.wd / 2);
 
71
        break;
 
72
    default:
 
73
        assert(0);
 
74
    }
 
75
    if (has_packet(f, c)) {
 
76
        do_vf_packet(pdf, f, c, ex_glyph);
 
77
    } else
 
78
        backend_out[glyph_node] (pdf, f, c, ex_glyph);  /* |pdf_place_glyph(pdf, f, c, ex_glyph);| */
 
79
    return ci;
 
80
}
 
81
 
 
82
@ Mark |f| as a used font; set |font_used(f)|, |font_size(f)| and |pdf_font_num(f)|
 
83
@c
 
84
static void pdf_use_font(internal_font_number f, int fontnum)
 
85
{
 
86
    set_font_used(f, true);
 
87
    assert((fontnum > 0) || ((fontnum < 0) && (pdf_font_num(-fontnum) > 0)));
 
88
    set_pdf_font_num(f, fontnum);
 
89
}
 
90
 
 
91
@ To set PDF font we need to find out fonts with the same name, because \TeX\
 
92
can load the same font several times for various sizes. For such fonts we
 
93
define only one font resource. The array |pdf_font_num| holds the object
 
94
number of font resource. A negative value of an entry of |pdf_font_num|
 
95
indicates that the corresponding font shares the font resource with the font
 
96
 
 
97
@c
 
98
#define same(n,f,k) (n(f) != NULL && n(k) != NULL && strcmp(n(f), n(k)) == 0)
 
99
 
 
100
static boolean font_shareable(internal_font_number f, internal_font_number k)
 
101
{
 
102
    int ret = 0;
 
103
    /* For some lua-loaded (for instance AFM) fonts, it is normal to have
 
104
       a zero cidregistry,  and such fonts do not have a fontmap entry yet
 
105
       at this point, so the test should use the other branch  */
 
106
    if (font_cidregistry(f) == NULL && font_cidregistry(k) == NULL &&
 
107
        font_encodingbytes(f) != 2 && font_encodingbytes(k) != 2) {
 
108
        if (font_map(k) != NULL &&
 
109
            font_map(f) != NULL && (same(font_name, k, f))) {
 
110
            ret = 1;
 
111
        }
 
112
    } else {
 
113
        if ((same(font_filename, k, f) && same(font_fullname, k, f))) {
 
114
            ret = 1;
 
115
        }
 
116
#ifdef DEBUG
 
117
        printf("\nfont_shareable(%d:%s:%s,%d:%s:%s): => %d\n",
 
118
               f, font_filename(f), font_fullname(f),
 
119
               k, font_filename(k), font_fullname(k), ret);
 
120
#endif
 
121
    }
 
122
    return ret;
 
123
}
 
124
 
 
125
@ create a font object
 
126
@c
 
127
void pdf_init_font(PDF pdf, internal_font_number f)
 
128
{
 
129
    internal_font_number k/*, b*/;
 
130
    fm_entry *fm;
 
131
    int i, l;
 
132
    assert(!font_used(f));
 
133
 
 
134
    ///* if |f| is auto expanded then ensure the base font is initialized */
 
135
    //
 
136
    //    if (font_auto_expand(f) && ((b = pdf_font_blink(f)) != null_font)) {
 
137
    //    if (!font_used(b))
 
138
    //        pdf_init_font(pdf, b);
 
139
    //    set_font_map(f, font_map(b));
 
140
    //    /* propagate slant and extend from unexpanded base font */
 
141
    //    set_font_slant(f, font_slant(b));
 
142
    //    set_font_extend(f, font_extend(b));
 
143
    //}
 
144
    /* check whether |f| can share the font object with some |k|: we have 2 cases
 
145
       here: 1) |f| and |k| have the same tfm name (so they have been loaded at
 
146
       different sizes, eg 'cmr10' and 'cmr10 at 11pt'); 2) |f| has been auto
 
147
       expanded from |k|
 
148
     */
 
149
 
 
150
    /* take over slant and extend from map entry, if not already set;
 
151
       this should also be the only place where getfontmap() may be called. */
 
152
 
 
153
    fm = getfontmap(font_name(f));
 
154
    if (font_map(f) == NULL && fm != NULL) {
 
155
        font_map(f) = fm;
 
156
        if (is_slantset(fm))
 
157
            font_slant(f) = fm->slant;
 
158
        if (is_extendset(fm))
 
159
            font_extend(f) = fm->extend;
 
160
    }
 
161
    i = pdf->head_tab[obj_type_font];
 
162
    while (i != 0) {
 
163
        k = obj_info(pdf, i);
 
164
        if (font_shareable(f, k)) {
 
165
            assert(pdf_font_num(k) != 0);
 
166
            if (pdf_font_num(k) < 0)
 
167
                pdf_use_font(f, pdf_font_num(k));
 
168
            else
 
169
                pdf_use_font(f, -k);
 
170
            return;
 
171
        }
 
172
        i = obj_link(pdf, i);
 
173
    }
 
174
    /* create a new font object for |f| */
 
175
    l = pdf_create_obj(pdf, obj_type_font, f);
 
176
    pdf_use_font(f, l);
 
177
}
 
178
 
 
179
@ set the actual font on PDF page
 
180
@c
 
181
internal_font_number pdf_set_font(PDF pdf, internal_font_number f)
 
182
{
 
183
    int ff;                     /* for use with |set_ff| */
 
184
    if (!font_used(f))
 
185
        pdf_init_font(pdf, f);
 
186
    /*
 
187
       set |ff| to the tfm number of the base font sharing the font object with |f|;
 
188
       |ff| is either |f| itself (then it is its own base font),
 
189
       or some font with the same tfm name at different size and/or expansion.
 
190
     */
 
191
    ff = pdf_font_num(f) < 0 ? -pdf_font_num(f) : f;    /* aka |set_ff(f)| */
 
192
    assert(pdf_font_num(ff) > 0);       /* base font object number */
 
193
    addto_page_resources(pdf, obj_type_font, pdf_font_num(ff));
 
194
    return ff;
 
195
}
 
196
 
 
197
@ Here come some subroutines to deal with expanded fonts for HZ-algorithm.
 
198
return 1 == identical
 
199
@c
 
200
static boolean cmp_font_name(int id, char *tt)
 
201
{
 
202
    char *tid;
 
203
    if (!is_valid_font(id))
 
204
        return 0;
 
205
    tid = font_name(id);
 
206
    if (tt == NULL && tid == NULL)
 
207
        return 1;
 
208
    if (tt == NULL || tid == NULL || strcmp(tid, tt) != 0)
 
209
        return 0;
 
210
    return 1;
 
211
}
 
212
 
 
213
@ @c
 
214
internal_font_number tfm_lookup(char *s, scaled fs)
 
215
{                               /* looks up for a TFM with name |s| loaded at |fs| size; if found then flushes |s| */
 
216
    internal_font_number k;
 
217
    if (fs != 0) {
 
218
        for (k = 1; k <= max_font_id(); k++) {
 
219
            if (cmp_font_name(k, s) && font_size(k) == fs) {
 
220
                return k;
 
221
            }
 
222
        }
 
223
    } else {
 
224
        for (k = 1; k <= max_font_id(); k++) {
 
225
            if (cmp_font_name(k, s)) {
 
226
                return k;
 
227
            }
 
228
        }
 
229
    }
 
230
    return null_font;
 
231
}
 
232
 
 
233
@ @c
 
234
int fix_expand_value(internal_font_number f, int e)
 
235
{                               /* return the multiple of |font_step(f)| that is nearest to |e| */
 
236
    int step;
 
237
    int max_expand;
 
238
    boolean neg;
 
239
    if (e == 0)
 
240
        return 0;
 
241
    if (e < 0) {
 
242
        e = -e;
 
243
        neg = true;
 
244
        max_expand = font_max_shrink(f);
 
245
    } else {
 
246
        neg = false;
 
247
        max_expand = font_max_stretch(f);
 
248
    }
 
249
    if (e > max_expand) {
 
250
        e = max_expand;
 
251
    } else {
 
252
        step = font_step(f);
 
253
        if (e % step > 0)
 
254
            e = step * round_xn_over_d(e, 1, step);
 
255
    }
 
256
    if (neg)
 
257
        e = -e;
 
258
    return e;
 
259
}
 
260
 
 
261
@ @c
 
262
void set_expand_params(internal_font_number f, boolean auto_expand,
 
263
                       int stretch_limit, int shrink_limit, int font_step)
 
264
{                               /* expand a font with given parameters */
 
265
    set_font_step(f, font_step);
 
266
    set_font_auto_expand(f, auto_expand);
 
267
    set_font_max_shrink(f, shrink_limit);
 
268
    set_font_max_stretch(f, stretch_limit);
 
269
}
 
270
 
 
271
@ @c
 
272
void read_expand_font(void)
 
273
{                               /* read font expansion spec and load expanded font */
 
274
    int shrink_limit, stretch_limit, font_step;
 
275
    internal_font_number f;
 
276
    boolean auto_expand;
 
277
    /* read font expansion parameters */
 
278
    scan_font_ident();
 
279
    f = cur_val;
 
280
    if (f == null_font)
 
281
        pdf_error("font expansion", "invalid font identifier");
 
282
    //if (pdf_font_blink(f) != null_font)
 
283
    //    pdf_error("font expansion",
 
284
    //              "\\pdffontexpand cannot be used this way (the base font has been expanded)");
 
285
    scan_optional_equals();
 
286
    scan_int();
 
287
    stretch_limit = fix_int(cur_val, 0, 1000);
 
288
    scan_int();
 
289
    shrink_limit = fix_int(cur_val, 0, 500);
 
290
    scan_int();
 
291
    font_step = fix_int(cur_val, 0, 100);
 
292
    if (font_step == 0)
 
293
        pdf_error("font expansion", "invalid step");
 
294
    stretch_limit = stretch_limit - stretch_limit % font_step;
 
295
    if (stretch_limit < 0)
 
296
        stretch_limit = 0;
 
297
    shrink_limit = shrink_limit - shrink_limit % font_step;
 
298
    if (shrink_limit < 0)
 
299
        shrink_limit = 0;
 
300
    if ((stretch_limit == 0) && (shrink_limit == 0))
 
301
        pdf_error("font expansion", "invalid limit(s)");
 
302
    auto_expand = false;
 
303
    if (scan_keyword("autoexpand")) {
 
304
        auto_expand = true;
 
305
        /* Scan an optional space */
 
306
        get_x_token();
 
307
        if (cur_cmd != spacer_cmd)
 
308
            back_input();
 
309
    }
 
310
 
 
311
    if (font_step(f) != 0) {
 
312
        /* this font has been expanded, ensure the expansion parameters are identical */
 
313
        if (font_step(f) != font_step)
 
314
            pdf_error("font expansion",
 
315
                      "font has been expanded with different expansion step");
 
316
 
 
317
        if (((font_max_stretch(f) == 0) && (stretch_limit != 0)) ||
 
318
            ((font_max_stretch(f) > 0)
 
319
             && (font_max_stretch(f) != stretch_limit)))
 
320
            pdf_error("font expansion",
 
321
                      "font has been expanded with different stretch limit");
 
322
 
 
323
        if (((font_max_shrink(f) == 0) && (shrink_limit != 0)) ||
 
324
            ((font_max_shrink(f) > 0)
 
325
             && (font_max_shrink(f) != shrink_limit)))
 
326
            pdf_error("font expansion",
 
327
                      "font has been expanded with different shrink limit");
 
328
 
 
329
        if (font_auto_expand(f) != auto_expand)
 
330
            pdf_error("font expansion",
 
331
                      "font has been expanded with different auto expansion value");
 
332
    } else {
 
333
        if (font_used(f))
 
334
            pdf_warning("font expansion",
 
335
                        "font should be expanded before its first use", true,
 
336
                        true);
 
337
        set_expand_params(f, auto_expand, stretch_limit, shrink_limit,
 
338
                          font_step);
 
339
    }
 
340
}
 
341
 
 
342
@ @c
 
343
void new_letterspaced_font(small_number a)
 
344
{                               /* letter-space a font by creating a virtual font */
 
345
    pointer u;                  /* user's font identifier */
 
346
    str_number t;               /* name for the frozen font identifier */
 
347
    internal_font_number f, k;
 
348
    boolean nolig = false;
 
349
    get_r_token();
 
350
    u = cur_cs;
 
351
    if (u >= hash_base)
 
352
        t = cs_text(u);
 
353
    else
 
354
        t = maketexstring("FONT");
 
355
    define(u, set_font_cmd, null_font);
 
356
    scan_optional_equals();
 
357
    scan_font_ident();
 
358
    k = cur_val;
 
359
    scan_int();
 
360
    if (scan_keyword("nolig"))
 
361
       nolig=true;
 
362
    f = letter_space_font(k, fix_int(cur_val, -1000, 1000), nolig);
 
363
    equiv(u) = f;
 
364
    eqtb[font_id_base + f] = eqtb[u];
 
365
    font_id_text(f) = t;
 
366
}
 
367
 
 
368
@ @c
 
369
void make_font_copy(small_number a)
 
370
{                               /* make a font copy for further use with font expansion */
 
371
    pointer u;                  /* user's font identifier */
 
372
    str_number t;               /* name for the frozen font identifier */
 
373
    internal_font_number f, k;
 
374
    get_r_token();
 
375
    u = cur_cs;
 
376
    if (u >= hash_base)
 
377
        t = cs_text(u);
 
378
    else
 
379
        t = maketexstring("FONT");
 
380
    define(u, set_font_cmd, null_font);
 
381
    scan_optional_equals();
 
382
    scan_font_ident();
 
383
    k = cur_val;
 
384
    f = copy_font_info(k);
 
385
    equiv(u) = f;
 
386
    eqtb[font_id_base + f] = eqtb[u];
 
387
    font_id_text(f) = t;
 
388
}
 
389
 
 
390
@ @c
 
391
void pdf_include_chars(PDF pdf)
 
392
{
 
393
    str_number s;
 
394
    unsigned char *k, *j;       /* running index */
 
395
    internal_font_number f;
 
396
    scan_font_ident();
 
397
    f = cur_val;
 
398
    if (f == null_font)
 
399
        pdf_error("font", "invalid font identifier");
 
400
    pdf_check_vf(cur_val);
 
401
    if (!font_used(f))
 
402
        pdf_init_font(pdf, f);
 
403
    scan_pdf_ext_toks();
 
404
    s = tokens_to_string(def_ref);
 
405
    delete_token_ref(def_ref);
 
406
    j = str_string(s) + str_length(s);
 
407
    for (k = str_string(s); k < j; k++) {
 
408
        pdf_mark_char(f, *k);
 
409
    }
 
410
    flush_str(s);
 
411
}
 
412
 
 
413
@ @c
 
414
void glyph_to_unicode(void)
 
415
{
 
416
    str_number s1, s2;
 
417
    scan_pdf_ext_toks();
 
418
    s1 = tokens_to_string(def_ref);
 
419
    delete_token_ref(def_ref);
 
420
    scan_pdf_ext_toks();
 
421
    s2 = tokens_to_string(def_ref);
 
422
    delete_token_ref(def_ref);
 
423
    def_tounicode(s1, s2);
 
424
    flush_str(s2);
 
425
    flush_str(s1);
 
426
}