beta-0.89.2
[luatex.git] / source / texk / web2c / luatexdir / tex / texdeffont.w
blob7fe5ae1e18c9da137d809757fc70b4964bb835d6
1 % texdeffont.w
3 % Copyright 2008-2010 Taco Hoekwater <taco@@luatex.org>
5 % This file is part of LuaTeX.
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.
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.
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/>.
20 @ @c
23 #include "ptexlib.h"
25 @ When the user defines \.{\\font\\f}, say, \TeX\ assigns an internal number
26 to the user's font~\.{\\f}. Adding this number to |font_id_base| gives the
27 |eqtb| location of a ``frozen'' control sequence that will always select
28 the font.
31 int font_bytes;
33 void set_cur_font(internal_font_number f)
35 int a = 0; /* never global */
36 define(cur_font_loc, data_cmd, f);
39 @ @c
40 static char *scaled_to_string(scaled s)
41 { /* prints scaled real, rounded to five digits */
42 static char result[16];
43 int n, k;
44 scaled delta; /* amount of allowable inaccuracy */
45 k = 0;
46 if (s < 0) {
47 result[k++] = '-';
48 s = -s; /* print the sign, if negative */
51 int l = 0;
52 char digs[8] = { 0 };
53 n = s / unity;
54 /* process the integer part */
55 do {
56 digs[l++] = (char) (n % 10);
57 n = n / 10;;
58 } while (n > 0);
59 while (l > 0) {
60 result[k++] = (char) (digs[--l] + '0');
63 result[k++] = '.';
64 s = 10 * (s % unity) + 5;
65 delta = 10;
66 do {
67 if (delta > unity)
68 s = s + 0100000 - 050000; /* round the last digit */
69 result[k++] = (char) ('0' + (s / unity));
70 s = 10 * (s % unity);
71 delta = delta * 10;
72 } while (s > delta);
74 result[k] = 0;
75 return (char *) result;
78 @ @c
79 void tex_def_font(small_number a)
81 pointer u; /* user's font identifier */
82 internal_font_number f; /* runs through existing fonts */
83 str_number t; /* name for the frozen font identifier */
84 int old_setting; /* holds |selector| setting */
85 scaled s = -1000; /* stated ``at'' size, or negative of scaled magnification */
86 int natural_dir = -1; /* the natural direction of the font */
87 char *fn;
88 if (job_name == 0)
89 open_log_file(); /* avoid confusing \.{texput} with the font name */
90 get_r_token();
91 u = cur_cs;
92 if (u >= null_cs)
93 t = cs_text(u);
94 else
95 t = maketexstring("FONT");
96 if (a >= 4) {
97 geq_define(u, set_font_cmd, null_font);
98 } else {
99 eq_define(u, set_font_cmd, null_font);
101 scan_optional_equals();
102 /* Get the next non-blank non-call token; */
103 do {
104 get_x_token();
105 } while ((cur_cmd == spacer_cmd) || (cur_cmd == relax_cmd));
107 if (cur_cmd != left_brace_cmd) {
108 back_input();
109 scan_file_name();
110 if (cur_area != get_nullstr() || cur_ext != get_nullstr()) {
111 /* Have to do some rescue-ing here, fonts only have a name,
112 no area nor extension */
113 old_setting = selector;
114 selector = new_string;
115 if (cur_area != get_nullstr()) {
116 print(cur_area);
118 if (cur_name != get_nullstr()) {
119 print(cur_name);
121 if (cur_ext != get_nullstr()) {
122 print(cur_ext);
124 selector = old_setting;
125 cur_name = make_string();
126 cur_ext = get_nullstr();
127 cur_area = get_nullstr();
129 } else {
130 back_input();
131 (void) scan_toks(false, true);
132 old_setting = selector;
133 selector = new_string;
134 token_show(def_ref);
135 selector = old_setting;
136 flush_list(def_ref);
137 /* |str_room(1)|; *//* what did that do ? */
138 cur_name = make_string();
139 cur_ext = get_nullstr();
140 cur_area = get_nullstr();
142 /* Scan the font size specification; */
143 name_in_progress = true; /* this keeps |cur_name| from being changed */
144 if (scan_keyword("at")) {
145 /* Put the positive `at' size into |s| */
146 scan_normal_dimen();
147 s = cur_val;
148 if ((s <= 0) || (s >= 01000000000)) {
149 char err[256];
150 const char *errhelp[] =
151 { "I can only handle fonts at positive sizes that are",
152 "less than 2048pt, so I've changed what you said to 10pt.",
153 NULL
155 snprintf(err, 255, "Improper `at' size (%spt), replaced by 10pt",
156 scaled_to_string(s));
157 tex_error(err, errhelp);
158 s = 10 * unity;
160 } else if (scan_keyword("scaled")) {
161 scan_int();
162 s = -cur_val;
163 if ((cur_val <= 0) || (cur_val > 32768)) {
164 char err[256];
165 const char *errhelp[] =
166 { "The magnification ratio must be between 1 and 32768.",
167 NULL
169 snprintf(err, 255,
170 "Illegal magnification has been changed to 1000 (%d)",
171 (int) cur_val);
172 tex_error(err, errhelp);
173 s = -1000;
176 if (scan_keyword("naturaldir")) {
177 scan_direction();
178 natural_dir = cur_val;
180 name_in_progress = false;
181 fn = makecstring(cur_name);
182 f = read_font_info(u, fn, s, natural_dir);
183 xfree(fn);
184 equiv(u) = f;
186 eqtb[font_id_base + f] = eqtb[u];
187 cs_text(font_id_base + f) = t;