summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/luatexdir/font/vfpacket.c
diff options
context:
space:
mode:
authorMartin Schröder <martin@oneiros.de>2008-03-24 15:47:15 +0000
committerMartin Schröder <martin@oneiros.de>2008-03-24 15:47:15 +0000
commit0b5550c241229764120d133af80a0cbab5937ddd (patch)
tree81309c18d6f0deba7407813cf15b9add2db375d1 /Build/source/texk/web2c/luatexdir/font/vfpacket.c
parent51f55df6a36ce376952a1f2b30bdb4dd0e06548d (diff)
First step of importing luatex (up to r1121)
git-svn-id: svn://tug.org/texlive/trunk@7124 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/font/vfpacket.c')
-rw-r--r--Build/source/texk/web2c/luatexdir/font/vfpacket.c377
1 files changed, 377 insertions, 0 deletions
diff --git a/Build/source/texk/web2c/luatexdir/font/vfpacket.c b/Build/source/texk/web2c/luatexdir/font/vfpacket.c
new file mode 100644
index 00000000000..4d8445f2227
--- /dev/null
+++ b/Build/source/texk/web2c/luatexdir/font/vfpacket.c
@@ -0,0 +1,377 @@
+/*
+Copyright (c) 1996-2002 Han The Thanh, <thanh@pdftex.org>
+
+This file is part of pdfTeX.
+
+pdfTeX 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.
+
+pdfTeX 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 General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with pdfTeX; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+$Id: vfpacket.c 1013 2008-02-14 00:09:02Z oneiros $
+*/
+
+#include "ptexlib.h"
+
+/*
+ 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|.
+*/
+
+#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. */
+
+#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) { integer 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 = sqxfw(fw, fs); }
+
+
+/* count the number of bytes in a command packet */
+int
+vf_packet_bytes (charinfo *co) {
+ real_eight_bits *vf_packets;
+ integer 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 += k;
+ break;
+ case packet_nop_code:
+ break;
+ default:
+ pdf_error("vf", "invalid DVI command");
+ }
+ };
+ return (cur_packet_byte +1);
+}
+
+
+/* typeset the \.{DVI} commands in the
+ character packet for character |c| in current font |f| */
+
+char *packet_command_names[] = {
+ "char", "font","pop", "push", "special",
+ "right","down","rule","node", "nop","end", NULL};
+
+
+void
+do_vf_packet (internal_font_number vf_f, integer c) {
+ internal_font_number lf;
+ charinfo *co;
+ scaled save_cur_h, save_cur_v;
+ real_eight_bits *vf_packets;
+ integer cur_packet_byte;
+ integer cmd, fs_f;
+ scaled i;
+ unsigned k;
+ str_number s;
+
+ packet_cur_s++;
+ if (packet_cur_s >= packet_max_recursion)
+ overflow_string("max level recursion of virtual fonts", packet_max_recursion);
+ save_cur_v = cur_v;
+ save_cur_h = cur_h;
+
+ lf = 0; /* for -Wall */
+ co = get_charinfo(vf_f,c);
+ vf_packets = get_charinfo_packets(co);
+ if (vf_packets == NULL) {
+ packet_cur_s--;
+ return ;
+ }
+ cur_packet_byte = 0;
+ fs_f = font_size(vf_f);
+ while ((cmd = vf_packets[cur_packet_byte]) != packet_end_code) {
+ cur_packet_byte++;
+ /*
+ 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]);
+ }
+ */
+ 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,k)) {
+ char_warning(lf, k);
+ } else {
+ output_one_char(lf, k);
+ }
+ cur_h = cur_h + char_width(lf,k);
+ break;
+ case packet_rule_code:
+ packet_scaled(rule_ht,fs_f);
+ packet_scaled(rule_wd,fs_f);
+ if ((rule_wd > 0) && (rule_ht > 0)) {
+ pdf_set_rule(cur_h, cur_v, rule_wd, rule_ht);
+ cur_h = cur_h + rule_wd;
+ }
+ 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);
+ string_room(k);
+ while (k > 0) {
+ k--;
+ append_pool_char(do_packet_byte());
+ }
+ s = make_string();
+ literal(s, scan_special, false);
+ flush_str(s);
+ break;
+ case packet_node_code:
+ packet_number(k);
+ temp_ptr = k;
+ pdf_hlist_out();
+ break;
+ case packet_nop_code:
+ break;
+ default:
+ pdf_error("vf", "invalid DVI command");
+ }
+ };
+ cur_h = save_cur_h;
+ cur_v = save_cur_v;
+ packet_cur_s--;
+}
+
+
+integer *packet_local_fonts(internal_font_number f, integer *num) {
+ int c, cmd, cur_packet_byte, lf, k,l, i;
+ integer localfonts[256] = {0};
+ integer *lfs;
+ charinfo *co;
+
+ real_eight_bits *vf_packets;
+ k = 0;
+ for (c = font_bc(f);c <= font_ec(f);c++) {
+ if (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;
+ default:
+ pdf_error("vf", "invalid DVI command");
+ }
+ }
+ }
+ }
+ *num = k;
+ if (k>0) {
+ lfs = xmalloc (k*sizeof(integer));
+ memcpy(lfs,localfonts,k*sizeof(integer));
+ return lfs;
+ }
+ return NULL;
+}
+
+
+void
+replace_packet_fonts(internal_font_number f, integer *old_fontid, integer *new_fontid, int count) {
+ int c, cmd, cur_packet_byte, lf, k,l;
+ charinfo *co;
+ real_eight_bits *vf_packets;
+
+ k = 0;
+ for (c = font_bc(f);c <= font_ec(f);c++) {
+ if (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)] = (k&0xFF000000)>>24;
+ vf_packets[(cur_packet_byte-3)] = (k&0x00FF0000)>>16;
+ vf_packets[(cur_packet_byte-2)] = (k&0x0000FF00)>>8;
+ vf_packets[(cur_packet_byte-1)] = (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;
+ default:
+ pdf_error("vf", "invalid DVI command");
+ }
+ }
+ }
+ }
+}
+
+/* this function was copied/borrowed/stolen from dvipdfm code */
+
+scaled sqxfw (scaled sq, integer fw)
+{
+ int sign = 1;
+ unsigned long a, b, c, d, ad, bd, bc, ac;
+ unsigned long e, f, g, h, i, j, k;
+ unsigned long result;
+ /* Make positive. */
+ if (sq < 0) {
+ sign = -sign;
+ sq = -sq;
+ }
+ if (fw < 0) {
+ sign = -sign;
+ fw = -fw;
+ }
+ a = ((unsigned long) sq) >> 16u;
+ b = ((unsigned long) sq) & 0xffffu;
+ c = ((unsigned long) fw) >> 16u;
+ d = ((unsigned long) fw) & 0xffffu;
+ ad = a*d; bd = b*d; bc = b*c; ac = a*c;
+ e = bd >> 16u;
+ f = ad >> 16u;
+ g = ad & 0xffffu;
+ h = bc >> 16u;
+ i = bc & 0xffffu;
+ j = ac >> 16u;
+ k = ac & 0xffffu;
+ result = (e+g+i + (1<<3)) >> 4u; /* 1<<3 is for rounding */
+ result += (f+h+k) << 12u;
+ result += j << 28u;
+ return (sign>0)?result:-result;
+}