3 % Copyright
1996-2006 Han The Thanh
<thanh@@pdftex.org
>
4 % Copyright
2006-2013 Taco Hoekwater
<taco@@luatex.org
>
6 % This file is part of LuaTeX.
8 % LuaTeX is free software
; you can redistribute it and
/or modify it under
9 % the terms of the GNU General Public License as published by the Free
10 % Software Foundation
; either version
2 of the License
, or
(at your
11 % option
) any later version.
13 % LuaTeX is distributed in the hope that it will be useful
, but WITHOUT
14 % ANY WARRANTY
; without even the implied warranty of MERCHANTABILITY or
15 % FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16 % License for more details.
18 % You should have received a copy of the GNU General Public License along
19 % with LuaTeX
; if not
, see
<http
://www.gnu.org
/licenses
/>.
26 @ Some macros for processing character packets.
28 #define packet_number
(fw
) { \
30 fw
= fw
* 256 + *(vfp
++); \
31 fw
= fw
* 256 + *(vfp
++); \
32 fw
= fw
* 256 + *(vfp
++); \
35 #define packet_scaled
(a
, fs
) { \
40 fw
= fw
* 256 + *(vfp
++); \
41 fw
= fw
* 256 + *(vfp
++); \
42 fw
= fw
* 256 + *(vfp
++); \
43 a
= store_scaled_f
(fw
, fs
); \
47 vf_struct
*new_vfstruct
(void
)
49 vf_struct
*vp
= (vf_struct
*) xmalloc
(sizeof
(vf_struct
));
50 vp-
>packet_stack_level
= vp-
>packet_stack_minlevel
= 0;
52 (packet_stack_record
*) xmalloc
(packet_stack_size
*
53 sizeof
(packet_stack_record
));
62 @ Count the number of bytes in a command packet.
64 int vf_packet_bytes
(charinfo
* co
)
66 eight_bits
*vf_packets
, *vfp
;
70 vfp
= vf_packets
= get_charinfo_packets
(co
);
71 if
(vf_packets
== NULL) {
74 while
((cmd
= *(vfp
++)) != packet_end_code
) {
78 case packet_push_code
:
80 case packet_char_code
:
81 case packet_down_code
:
82 case packet_font_code
:
83 case packet_image_code
:
84 case packet_node_code
:
85 case packet_right_code
:
88 case packet_rule_code
:
91 case packet_special_code
:
92 packet_number
(k
); /* +4 */
96 normal_error
("vf", "invalid DVI command (1)");
99 return
(vfp
- vf_packets
);
102 @ Typeset the \.
{DVI
} commands in the character packet
103 for character |c| in current font |f|.
105 const char
*packet_command_names
[] = {
106 "char", "font", "pop", "push", "special", "image",
107 "right", "down", "rule", "node", "nop", "end", "scale", "lua", NULL
111 static float packet_float
(eight_bits
** vfpp
)
116 eight_bits b
[sizeof
(float
)];
118 eight_bits
*vfp
= *vfpp
;
119 for
(i
= 0; i
< sizeof
(float
); i
++)
125 @ The |do_vf_packet| procedure is called in order to interpret the
126 character packet for a virtual character. Such a packet may contain
127 the instruction to typeset a character from the same or an other
128 virtual font
; in such cases |do_vf_packet| calls itself
129 recursively. The recursion level
, i.e.
, the number of times this has
130 happened
, is kept in the global variable |packet_cur_s| and should
131 not exceed |packet_max_recursion|.
133 void do_vf_packet
(PDF pdf
, internal_font_number vf_f
, int c
, int ex_glyph
)
136 posstructure
*save_posstruct
, localpos
;
137 vf_struct
*save_vfstruct
, localvfstruct
, *vp
;
144 packet_stack_record
*mat_p
;
146 vfp
= get_charinfo_packets
(get_charinfo
(vf_f
, c
));
149 save_posstruct
= pdf-
>posstruct
;
150 pdf-
>posstruct
= &localpos; /* use local structure for recursion */
151 localpos.pos
= save_posstruct-
>pos
;
152 localpos.dir
= dir_TLT
; /* invariably for vf
*/
154 save_vfstruct
= pdf-
>vfstruct
;
155 vp
= pdf-
>vfstruct
= &localvfstruct;
156 localvfstruct
= *save_vfstruct
;
158 vp-
>packet_stack_minlevel
= ++(vp-
>packet_stack_level
);
160 vp-
>fs_f
= font_size
(vf_f
);
161 vp-
>ex_glyph
= ex_glyph
;
163 if
(vp-
>packet_cur_s
== packet_max_recursion
)
164 overflow
("max level recursion of virtual fonts", packet_max_recursion
);
165 vp-
>refpos
= save_posstruct
;
168 mat_p
= &(vp->packet_stack[vp->packet_stack_level]);
176 while
((cmd
= *(vfp
++)) != packet_end_code
) {
178 if
(cmd
> packet_end_code
) {
179 fprintf
(stdout
, "do_vf_packet(%i,%i) command code = illegal \n",
182 fprintf
(stdout
, "do_vf_packet(%i,%i) command code = %s\n", vf_f
, c
,
183 packet_command_names
[cmd
]);
187 case packet_font_code
:
188 packet_number
(vp-
>lf
);
190 case packet_push_code
:
191 vp-
>packet_stack_level
++;
192 if
(vp-
>packet_stack_level
== packet_stack_size
)
193 normal_error
("vf", "packet_stack_level overflow");
194 vp-
>packet_stack
[vp-
>packet_stack_level
] = *mat_p
;
195 mat_p
= &(vp->packet_stack[vp->packet_stack_level]);
197 case packet_pop_code
:
198 if
(vp-
>packet_stack_level
== vp-
>packet_stack_minlevel
)
199 normal_error
("vf", "packet_stack_level underflow");
200 vp-
>packet_stack_level--
;
201 mat_p
= &(vp->packet_stack[vp->packet_stack_level]);
203 case packet_char_code
:
205 if
(!char_exists
(vp-
>lf
, (int
) k
))
206 char_warning
(vp-
>lf
, (int
) k
);
208 if
(has_packet
(vp-
>lf
, (int
) k
))
209 do_vf_packet
(pdf
, vp-
>lf
, (int
) k
, ex_glyph
);
211 backend_out
[glyph_node
] (pdf
, vp-
>lf
, (int
) k
, ex_glyph
);
213 w
= char_width
(vp-
>lf
, (int
) k
);
214 mat_p-
>pos.h
+= round_xn_over_d
(w
, 1000 + ex_glyph
, 1000);
216 case packet_rule_code
:
217 packet_scaled
(size.v
, vp-
>fs_f
); /* height
(where is depth?
) */
218 packet_scaled
(size.h
, vp-
>fs_f
);
219 if
(size.h
> 0 && size.v > 0)
220 backend_out
[rule_node
](pdf
, 0, size
); /* the
0 is unused
*/
221 mat_p-
>pos.h
+= size.h
;
223 case packet_right_code
:
224 packet_scaled
(i
, vp-
>fs_f
);
227 case packet_down_code
:
228 packet_scaled
(i
, vp-
>fs_f
);
231 case packet_special_code
:
236 append_char
(*(vfp
++));
239 pdf_literal
(pdf
, s
, scan_special
, false
);
242 case packet_lua_code
:
246 (Luas
, (const char
*) vfp
, (size_t
) k
, "packet_lua_code")
247 || lua_pcall
(Luas
, 0, LUA_MULTRET
, 0))
252 case packet_image_code
:
254 vf_out_image
(pdf
, k
);
256 case packet_node_code
:
258 hlist_out
(pdf
, (halfword
) k
, 0);
260 case packet_nop_code
:
262 case packet_scale_code
:
263 f
= packet_float
(&vfp);
264 mat_p-
>c0
= mat_p-
>c0
* f
;
265 mat_p-
>c3
= mat_p-
>c3
* f
;
266 /* pdf-
>pstruct-
>scale
= f
; *//* scale is still NOP
*/
267 pdf-
>pstruct-
>need_tm
= true
;
268 pdf-
>pstruct-
>need_tf
= true
;
271 normal_error
("vf", "invalid DVI command (2)");
273 synch_pos_with_cur
(&localpos, save_posstruct, mat_p->pos); /* trivial case, always TLT */
275 pdf-
>posstruct
= save_posstruct
;
276 pdf-
>vfstruct
= save_vfstruct
;
280 int
*packet_local_fonts
(internal_font_number f
, int
*num
)
282 int c
, cmd
, lf
, k
, l
, i
;
283 int localfonts
[256] = { 0 };
287 eight_bits
*vf_packets
, *vfp
;
289 for
(c
= font_bc
(f
); c
<= font_ec
(f
); c
++) {
290 if
(quick_char_exists
(f
, c
)) {
291 co
= get_charinfo
(f
, c
);
292 vfp
= vf_packets
= get_charinfo_packets
(co
);
293 if
(vf_packets
== NULL)
295 while
((cmd
= *(vfp
++)) != packet_end_code
) {
297 case packet_font_code
:
299 for
(l
= 0; l
< k
; l
++) {
300 if
(localfonts
[l
] == lf
) {
305 localfonts
[k
++] = lf
;
308 case packet_nop_code
:
309 case packet_pop_code
:
310 case packet_push_code
:
312 case packet_char_code
:
313 case packet_down_code
:
314 case packet_image_code
:
315 case packet_node_code
:
316 case packet_right_code
:
319 case packet_rule_code
:
322 case packet_special_code
:
327 normal_error
("vf", "invalid DVI command (3)");
334 lfs
= xmalloc
((unsigned
) ((unsigned
) k
* sizeof
(int
)));
335 memcpy
(lfs
, localfonts
, (size_t
) ((unsigned
) k
* sizeof
(int
)));
343 replace_packet_fonts
(internal_font_number f
, int
*old_fontid
,
344 int
*new_fontid
, int count
)
346 int c
, cmd
, lf
, k
, l
;
348 eight_bits
*vf_packets
, *vfp
;
350 for
(c
= font_bc
(f
); c
<= font_ec
(f
); c
++) {
351 if
(quick_char_exists
(f
, c
)) {
352 co
= get_charinfo
(f
, c
);
353 vfp
= vf_packets
= get_charinfo_packets
(co
);
354 if
(vf_packets
== NULL)
356 while
((cmd
= *(vfp
++)) != packet_end_code
) {
358 case packet_font_code
:
360 for
(l
= 0; l
< count
; l
++) {
361 if
(old_fontid
[l
] == lf
) {
367 *(vfp
- 4) = (eight_bits
)
368 ((k
& 0xFF000000) >> 24);
369 *(vfp
- 3) = (eight_bits
)
370 ((k
& 0x00FF0000) >> 16);
371 *(vfp
- 2) = (eight_bits
)
372 ((k
& 0x0000FF00) >> 8);
373 *(vfp
- 1) = (eight_bits
) (k
& 0x000000FF);
376 case packet_nop_code
:
377 case packet_pop_code
:
378 case packet_push_code
:
380 case packet_char_code
:
381 case packet_down_code
:
382 case packet_image_code
:
383 case packet_node_code
:
384 case packet_right_code
:
387 case packet_rule_code
:
390 case packet_special_code
:
395 normal_error
("vf", "invalid DVI command (4)");