diff options
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/font/vfpacket.w')
-rw-r--r-- | Build/source/texk/web2c/luatexdir/font/vfpacket.w | 375 |
1 files changed, 375 insertions, 0 deletions
diff --git a/Build/source/texk/web2c/luatexdir/font/vfpacket.w b/Build/source/texk/web2c/luatexdir/font/vfpacket.w new file mode 100644 index 00000000000..eb28fcdcc4c --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/font/vfpacket.w @@ -0,0 +1,375 @@ +% vfpacket.w + +% Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org> +% Copyright 2006-2009 Taco Hoekwater <taco@@luatex.org> + +% This file is part of LuaTeX. + +% LuaTeX is free software; you can redistribute it and/or modify it under +% the terms of the GNU General Public License as published by the Free +% Software Foundation; either version 2 of the License, or (at your +% option) any later version. + +% LuaTeX is distributed in the hope that it will be useful, but WITHOUT +% ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +% FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public +% License for more details. + +% You should have received a copy of the GNU General Public License along +% with LuaTeX; if not, see <http://www.gnu.org/licenses/>. + +@ @c +#include "ptexlib.h" + +static const char _svn_version[] = + "$Id: vfpacket.w 3584 2010-04-02 17:45:55Z hhenkel $ " + "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/font/vfpacket.w $"; + + +@ The |do_vf_packet| procedure is called in order to interpret the + character packet for a virtual character. Such a packet may contain + the instruction to typeset a character from the same or an other + virtual font; in such cases |do_vf_packet| calls itself + recursively. The recursion level, i.e., the number of times this has + happened, is kept in the global variable |packet_cur_s| and should + not exceed |packet_max_recursion|. + +@c +#define packet_max_recursion 100 + +typedef unsigned char packet_stack_index; /* an index into the stack */ + +typedef struct packet_stack_record { + scaled stack_h; + scaled stack_v; +} packet_stack_record; + + +static packet_stack_index packet_cur_s = 0; /* current recursion level */ +static packet_stack_record packet_stack[packet_max_recursion]; +static packet_stack_index packet_stack_ptr = 0; /* pointer into |packet_stack| */ + + +@ Some macros for processing character packets. +@c +#define do_packet_byte() vf_packets[cur_packet_byte++] + +#define packet_number(fw) { \ + fw = do_packet_byte(); \ + fw = fw*256 + do_packet_byte(); \ + fw = fw*256 + do_packet_byte(); \ + fw = fw*256 + do_packet_byte(); } + +#define packet_scaled(a,fs) { int fw; \ + fw = do_packet_byte(); \ + if (fw>127) fw = fw - 256; \ + fw = fw*256 + do_packet_byte(); \ + fw = fw*256 + do_packet_byte(); \ + fw = fw*256 + do_packet_byte(); \ + a = store_scaled_f(fw, fs); } + + +@ count the number of bytes in a command packet +@c +int vf_packet_bytes(charinfo * co) +{ + eight_bits *vf_packets; + int cur_packet_byte; + unsigned k; + int cmd; + + vf_packets = get_charinfo_packets(co); + if (vf_packets == NULL) { + return 0; + } + cur_packet_byte = 0; + while ((cmd = vf_packets[cur_packet_byte]) != packet_end_code) { + cur_packet_byte++; + switch (cmd) { + case packet_char_code: + case packet_font_code: + case packet_right_code: + case packet_down_code: + case packet_node_code: + cur_packet_byte += 4; + break; + case packet_push_code: + case packet_pop_code: + break; + case packet_rule_code: + cur_packet_byte += 8; + break; + case packet_special_code: + packet_number(k); /* +4 */ + cur_packet_byte = (cur_packet_byte + (int) k); + break; + case packet_image_code: + cur_packet_byte += 4; + break; + case packet_nop_code: + break; + default: + pdf_error("vf", "invalid DVI command (1)"); + } + }; + return (cur_packet_byte + 1); +} + + +@ typeset the \.{DVI} commands in the + character packet for character |c| in current font |f| +@c +const char *packet_command_names[] = { + "char", "font", "pop", "push", "special", "image", + "right", "down", "rule", "node", "nop", "end", NULL +}; + + +void do_vf_packet(PDF pdf, internal_font_number vf_f, int c) +{ + internal_font_number lf; + charinfo *co; + scaledpos cur = { 0, 0 }, size; + eight_bits *vf_packets; + int cur_packet_byte; + int cmd, fs_f; + scaled i; + unsigned k; + str_number s; + + posstructure localpos; /* the position structure local within this function */ + posstructure *refpos; /* the list origin pos. on the page, provided by the caller */ + + lf = 0; /* for -Wall */ + packet_cur_s++; + if (packet_cur_s >= packet_max_recursion) + overflow("max level recursion of virtual fonts", packet_max_recursion); + co = get_charinfo(vf_f, c); + vf_packets = get_charinfo_packets(co); + if (vf_packets == NULL) { + packet_cur_s--; + return; + } + + refpos = pdf->posstruct; + pdf->posstruct = &localpos; /* use local structure for recursion */ + localpos.pos = refpos->pos; + localpos.dir = dir_TLT; /* invariably for vf */ + + cur_packet_byte = 0; + fs_f = font_size(vf_f); + while ((cmd = vf_packets[cur_packet_byte]) != packet_end_code) { + cur_packet_byte++; +#ifdef DEBUG + if (cmd>packet_end_code) { + fprintf(stdout, "do_vf_packet(%i,%i) command code = illegal \n", vf_f,c); + } else { + fprintf(stdout, "do_vf_packet(%i,%i) command code = %s\n",vf_f, c, packet_command_names[cmd]); + } +#endif + switch (cmd) { + case packet_font_code: + packet_number(lf); + break; + case packet_push_code: + packet_stack[packet_stack_ptr].stack_h = cur.h; + packet_stack[packet_stack_ptr].stack_v = cur.v; + packet_stack_ptr++; + break; + case packet_pop_code: + packet_stack_ptr--; + cur.h = packet_stack[packet_stack_ptr].stack_h; + cur.v = packet_stack[packet_stack_ptr].stack_v; + break; + case packet_char_code: + packet_number(k); + if (!char_exists(lf, (int) k)) { + char_warning(lf, (int) k); + } else { + if (has_packet(lf, (int) k)) + do_vf_packet(pdf, lf, (int) k); + else + pdf_place_glyph(pdf, lf, (int) k); + } + cur.h = cur.h + char_width(lf, (int) k); + break; + case packet_rule_code: + packet_scaled(size.v, fs_f); /* height (where is depth?) */ + packet_scaled(size.h, fs_f); + if (size.h > 0 && size.v > 0) + pdf_place_rule(pdf, 0, size); /* the 0 is unused */ + cur.h = cur.h + size.h; + break; + case packet_right_code: + packet_scaled(i, fs_f); + cur.h = cur.h + i; + break; + case packet_down_code: + packet_scaled(i, fs_f); + cur.v = cur.v + i; + break; + case packet_special_code: + packet_number(k); + str_room((unsigned) k); + while (k > 0) { + k--; + append_char(do_packet_byte()); + } + s = make_string(); + pdf_literal(pdf, s, scan_special, false); + flush_str(s); + break; + case packet_image_code: + packet_number(k); + vf_out_image(pdf, k); + break; + case packet_node_code: + packet_number(k); + hlist_out(pdf, (halfword) k); + break; + case packet_nop_code: + break; + default: + pdf_error("vf", "invalid DVI command (2)"); + } + synch_pos_with_cur(&localpos, refpos, cur); /* trivial case, always TLT */ + } + packet_cur_s--; + pdf->posstruct = refpos; +} + +@ @c +int *packet_local_fonts(internal_font_number f, int *num) +{ + int c, cmd, cur_packet_byte, lf, k, l, i; + int localfonts[256] = { 0 }; + int *lfs; + charinfo *co; + + eight_bits *vf_packets; + k = 0; + for (c = font_bc(f); c <= font_ec(f); c++) { + if (quick_char_exists(f, c)) { + co = get_charinfo(f, c); + vf_packets = get_charinfo_packets(co); + if (vf_packets == NULL) + continue; + cur_packet_byte = 0; + while ((cmd = vf_packets[cur_packet_byte]) != packet_end_code) { + cur_packet_byte++; + switch (cmd) { + case packet_font_code: + packet_number(lf); + for (l = 0; l < k; l++) { + if (localfonts[l] == lf) { + break; + } + } + if (l == k) { + localfonts[k++] = lf; + } + break; + case packet_push_code: + case packet_pop_code: + case packet_nop_code: + break; + case packet_char_code: + case packet_right_code: + case packet_down_code: + case packet_node_code: + cur_packet_byte += 4; + break; + case packet_rule_code: + cur_packet_byte += 8; + break; + case packet_special_code: + packet_number(i); + while (i-- > 0) + (void) do_packet_byte(); + break; + case packet_image_code: + cur_packet_byte += 4; + break; + default: + pdf_error("vf", "invalid DVI command (3)"); + } + } + } + } + *num = k; + if (k > 0) { + lfs = xmalloc((unsigned) ((unsigned) k * sizeof(int))); + memcpy(lfs, localfonts, (size_t) ((unsigned) k * sizeof(int))); + return lfs; + } + return NULL; +} + + +@ @c +void +replace_packet_fonts(internal_font_number f, int *old_fontid, + int *new_fontid, int count) +{ + int c, cmd, cur_packet_byte, lf, k, l; + charinfo *co; + eight_bits *vf_packets; + + k = 0; + for (c = font_bc(f); c <= font_ec(f); c++) { + if (quick_char_exists(f, c)) { + co = get_charinfo(f, c); + vf_packets = get_charinfo_packets(co); + if (vf_packets == NULL) + continue; + cur_packet_byte = 0; + while ((cmd = vf_packets[cur_packet_byte]) != packet_end_code) { + cur_packet_byte++; + switch (cmd) { + case packet_font_code: + packet_number(lf); + for (l = 0; l < count; l++) { + if (old_fontid[l] == lf) { + break; + } + } + if (l < count) { + k = new_fontid[l]; + vf_packets[(cur_packet_byte - 4)] = (eight_bits) + ((k & 0xFF000000) >> 24); + vf_packets[(cur_packet_byte - 3)] = (eight_bits) + ((k & 0x00FF0000) >> 16); + vf_packets[(cur_packet_byte - 2)] = (eight_bits) + ((k & 0x0000FF00) >> 8); + vf_packets[(cur_packet_byte - 1)] = + (eight_bits) (k & 0x000000FF); + } + break; + case packet_push_code: + case packet_pop_code: + case packet_nop_code: + break; + case packet_char_code: + case packet_right_code: + case packet_down_code: + case packet_node_code: + cur_packet_byte += 4; + break; + case packet_rule_code: + cur_packet_byte += 8; + break; + case packet_special_code: + packet_number(k); + while (k-- > 0) + (void) do_packet_byte(); + break; + case packet_image_code: + cur_packet_byte += 4; + break; + default: + pdf_error("vf", "invalid DVI command (4)"); + } + } + } + } +} |