A figure is taken to be a chunck of dvi code enclosed between ‘+’ specials. They are to be translated to, for instance, gif code.
<..vars..>+
static BOOL dvi_flag = FALSE, dvi_page = FALSE;
static FILE *idv_file;
-_-_-
<..open idv file..>
job_name[job_name_n-1] = ’v’;
job_name[job_name_n-2] = ’d’;
job_name[job_name_n-3] = ’i’;
if( (idv_file = fopen(job_name, WRITE_BIN_FLAGS)) == NULL )
bad_in_file(job_name);
job_name[job_name_n-3] = ’\0’;
-_-_-
<..main’s vars..>+
long int eof_op_n, begin_postamble;
int dis_pages;
-_-_-
<..extract dvi chunks..>
job_name[job_name_n-3] = ’\0’;
<.extract preamble.>
page_n = 0;
<.start first idv page.>
while( dis_pages ){ <.extract pages.> }
<.error notice into lg.>
<.extract symbols.>
<.extract postamble.>
-_-_-
<..error notice into lg..>
if( errCode > 0 ){
(IGNORED) fprintf(log_file, "tex4ht.c error: %d\n", errCode);
}
-_-_-
<..vars..>+
static int errCode = 0;
-_-_-
We had ‘case ’+’: {;}’ before. However, this is wrong because we want to do nothing here with regarding to directives for the gif part.
<..ivd code in main pass..>
while( special_n-- > 0 ) (void) get_char();
-_-_-
<..extract preamble..>
file_n = 14;
(IGNORED) fseek(dvi_file, 0L, <.abs file addr.>);
do{ ch = get_char();
idv_char( ch );
file_n++;
}while( ch == <.no op.> );
<.idv version.>
for( i=12; i ; i-- ){ idv_char( get_char() ); }
i = get_char();
idv_char( (int) i ); while( i-- ) idv_copy();
-_-_-
<..idv version..>
ch = get_char();
if( id_version != -1 ){ ch = id_version; }
idv_char( ch );
-_-_-
<..idv version replacement num..>
{ U_CHAR *q;
q = p + 2;
id_version = 0;
while( *q != ’\0’ ){
if( id_version != -1 ){
if( (*q < ’0’) || (*q > ’9’) ){
id_version = -1;
warn_i(53);
}
id_version = id_version * 10 + *q - ’0’;
}
q++;
} }
-_-_-
<..vars..>+
static int id_version = -1;
-_-_-
<..extract postamble..>
idv_char(<.retrieve loc op.>); file_n += 2;
idv_char( <.end page op.> );
(IGNORED) fseek(dvi_file, begin_postamble, <.abs file addr.>);
begin_postamble = file_n;
idv_char( <.begin-postamble op.> ); file_n += 5;
idv_int( bop_addr ); (IGNORED) fseek(dvi_file, 5L, <.relative file addr.>);
for( i = 20; i; i-- ) idv_copy();
-_-_-
<..extract postamble..>+
i = (INTEGER) get_int(2) + 1; idv_char( (int) i >> 8 ); stack depth
idv_char( (int) i & 0xFF ); file_n += 2;
if( !page_n ) page_n++; idv_char( page_n >> 8 ); page number
idv_char( (int) page_n & 0xFF ); file_n += 2;
(IGNORED) fseek(dvi_file, 2L, <.relative file addr.>);
-_-_-
<..extract postamble..>+
eof_op_n -= 32; fonts
while( --eof_op_n ) idv_copy();
idv_int(begin_postamble); start postamble
(IGNORED) fseek(dvi_file, 4L, <.relative file addr.>); file_n += 4;
<.idv version.>
for( i = 8 - file_n % 4; i; i-- ) idv_char( <.eof op.> );
-_-_-
<..extract pages..>
if( (ch = get_char()) < 128 ) { visible_cnt = TRUE; cond_idv_char( ch );}
else switch( ch ){ <.chars for idv.> }
-_-_-
<..chars for idv..>
case 128: case 129: case 130: case 131: case 133:
case 134: case 135: case 136: {
visible_cnt = TRUE; cond_string( ch, (ch - (ch>132)) % 4 +1 );
break;
}
-_-_-
Why the ‘cond_string’ above?
<..chars for idv..>+
case <.start page op.>: {
x_val = 0; y_val = 0; stack_n = 0;
(IGNORED) fseek(dvi_file, 44L, <.relative file addr.>); break; }
case <.end page op.>: { dis_pages--; }
case <.no op.>: { break; }
-_-_-
<..chars for idv..>+
case <.mv hor dist dx.1.>: {
cond_idv_char( ch ); x_val += dx_1; break; }
case <.mv hor dist dx.2.>: {
cond_idv_char( ch ); x_val += dx_2; break; }
case <.mv ver dist dy.1.>: {
cond_idv_char( ch ); y_val += dy_1; break; }
case <.mv ver dist dy.2.>: {
cond_idv_char( ch ); y_val += dy_2; break; }
-_-_-
<..chars for idv..>+
case <.mv hor 1-byte.>: case <.mv hor 2-byte.>:
case <.mv hor 3-byte.>: case <.mv hor 4-byte.>: {
cond_idv_char( ch );
x_val += cond_int( ch - <.mv hor 1-byte.> + 1 ); break; }
case <.dx.1 store and mv hor 1-byte.>:
case <.dx.1 store and mv hor 2-byte.>:
case <.dx.1 store and mv hor 3-byte.>:
case <.dx.1 store and mv hor 4-byte.>: {
cond_idv_char( ch );
dx_1 = (INTEGER) cond_int( ch - <.dx.1 store and mv hor 1-byte.> + 1);
x_val += dx_1; break; }
case <.dx.2 store and mv hor 1-byte.>:
case <.dx.2 store and mv hor 2-byte.>:
case <.dx.2 store and mv hor 3-byte.>:
case <.dx.2 store and mv hor 4-byte.>: {
cond_idv_char( ch );
dx_2 = (INTEGER) cond_int( ch - <.dx.2 store and mv hor 1-byte.> + 1);
x_val += dx_2; break; }
-_-_-
<..chars for idv..>+
case <.mv ver 1-byte.>: case <.mv ver 2-byte.>:
case <.mv ver 3-byte.>: case <.mv ver 4-byte.>: {
cond_idv_char( ch );
y_val += cond_int( ch - <.mv ver 1-byte.> + 1);
break; }
case <.dy.1 store and mv ver 1-byte.>:
case <.dy.1 store and mv ver 2-byte.>:
case <.dy.1 store and mv ver 3-byte.>:
case <.dy.1 store and mv ver 4-byte.>: {
cond_idv_char( ch );
dy_1 = (INTEGER) cond_int( ch - <.dy.1 store and mv ver 1-byte.> + 1);
y_val += dy_1; break; }
case <.dy.2 store and mv ver 1-byte.>:
case <.dy.2 store and mv ver 2-byte.>:
case <.dy.2 store and mv ver 3-byte.>:
case <.dy.2 store and mv ver 4-byte.>: {
cond_idv_char( ch );
dy_2 = (INTEGER) cond_int( ch - <.dy.2 store and mv ver 1-byte.> + 1);
y_val += dy_2; break; }
-_-_-
<..chars for idv..>+
case <.insert rule + move op.>:{
visible_cnt = TRUE; cond_string( ch,4 ); x_val += cond_int(4);
break;
}
case <.insert rule + nomove op.>:{
visible_cnt = TRUE; cond_string( ch, 8 );
break;
}
-_-_-
Only ‘+’ tex4ht specials are significant here. The ones of the form ‘\special{t4ht++...}...\special{t4ht+}’ act as delimiters for segments of dvi code to be trasmitted to the dvi driver (probably dvips). The other ones of the form ‘\special{t4ht+...}’ are ignored outside such segments, and are replaced by sub-specilas ‘\special{...}’ within the segments. For instance, ‘\special{t4ht+ps:abc}’ translates to ‘\special{ps:abc}’ within these segments. That is, the latter ones are indirect transpoters for special code (why we need this transportes?).
The non-tex4ht specials are introduced into the idv code. Those that are parts of the picture environment, are included there (dvi_page=TRUE). Those that not, are included in separate pages. The latter ones might be definitions and directives for the pictures, as is the case for pstricks which sends them to dvips.
<..chars for idv..>+
case <.special 1.>: case <.special 2.>:
case <.special 3.>: case <.special 4.>: { long int i;
int special_nr;
special_nr = ch;
if( tex4ht_special( &ch, &i ) ){
if( ch == ’+’ ){
<.handle requests for dvi to gif code.> }
else while( i-- ) (void) get_char();
}else if( dvi_flag ){ <.insert non-t4ht special into picture.>
}else { <.insert non-t4ht special on non-picture page.> }
break;
}
-_-_-
<..insert non-t4ht special on non-picture page..>
if( dvi_page || !page_n ){ dvi_page = FALSE; <.advance idv page.> }
dvi_flag = TRUE;
<.insert non-t4ht special.>
dvi_flag = FALSE;
-_-_-
<..insert non-t4ht special on non-picture pageNO..>
while( i-- ) (IGNORED) get_char();
-_-_-
Replace the last piece with a seek! (IGNORED) fseek(dvi˙file, (long)i, ‘�relative file addr‘�);
<..insert non-t4ht special into picture..>
visible_cnt = TRUE; <.insert non-t4ht special.>
-_-_-
<..insert non-t4ht special..>
{
U_CHAR *ch;
int j;
ch = special_hd;
(IGNORED) putc( (unsigned) <.special 4.>, idv_file ); file_n++;
for(j=4; j--; ){ (IGNORED) putc( *ch, idv_file ); file_n++; ch++; }
while( *ch ){ (IGNORED) putc( *ch, idv_file ); file_n++; ch++; }
file_n += (int) i;
while( i-- ) (IGNORED) putc( get_char(), idv_file );
}
-_-_-
<..handle requests for dvi to gif code..>
if( i==0 ){ if( dvi_flag ){ dvi_flag = 0; <.end dvi page.> } }
else{
if( dvi_flag ){ <.make a special for dvi driver.> }
else switch( get_char() ){
case ’+’: { <.out gif filename.>
dvi_flag = TRUE; dvi_page = TRUE;
<.advance idv page.> break; }
case ’@’: { <.write to lg file.> break; }
default: { while( --i ) (void) get_char(); break; }
} }
-_-_-
<..write to lg file..>
while( --i ) (void) putc( get_char(), log_file );
(IGNORED) putc( ’\n’, log_file );
-_-_-
<..out gif filename..>
{ U_CHAR str[256], *ch;
ch = str; while( --i ) *(ch++) = get_char(); *ch = ’\0’;
script(font_gif, job_name ,page_n+1, str);
}
-_-_-
‘printf("%s", str);’— tooo much info for screen, and not that significant.
<..make a special for dvi driver..>
cond_idv_char( special_nr );
cond_idv_int( i, special_nr - <.special 1.> + 1 );
while( i-- ) cond_idv_char( get_char() );
visible_cnt = TRUE;
-_-_-
<..advance idv page..>
visible_cnt = FALSE;
bop_addr = advance_idv_page( bop_addr, cur_font );
stack_depth = 0;
set_loc( <.mv hor 1-byte.>, x_val );
set_loc( <.mv ver 1-byte.>, y_val );
-_-_-
<..idv vars..>
INTEGER bop_addr;
-_-_-
<..header functions..>+
static void set_loc( ARG_II(int, long int) );
-_-_-
<..functions..>+
static void set_loc( op, d )
int op;
long int d
;{
idv_char( op + 3 ); int_to_dvi( d, 4 ); file_n += 5;
}
-_-_-
<..chars for idv..>+
case <.sv loc op.>: {
push_stack();
stack_depth++;
cond_idv_char( ch );
break; }
case <.retrieve loc op.>: { INTEGER cur_x, cur_y;
stack_depth--;
cur_x = (INTEGER) x_val; cur_y = (INTEGER) y_val; pop_stack();
if( dvi_flag ){
if( stack_depth<0 ){ warn_i_int( 24, page_n );
<.push curr state.> }
cond_idv_char( ch );
}
break; }
-_-_-
<..push curr state..>
cond_idv_char( <.mv hor 4-byte.> );
idv_int( x_val - cur_x - dx_1 - dx_2 );
cond_idv_char( <.dx.1 store and mv hor 4-byte.> );
idv_int( dx_1 );
cond_idv_char( <.dx.2 store and mv hor 4-byte.> );
idv_int( dx_2 );
cond_idv_char( <.mv ver 4-byte.> );
idv_int( y_val - cur_y - dy_1 - dy_2 );
cond_idv_char( <.dy.1 store and mv ver 4-byte.> );
idv_int( dy_1 );
cond_idv_char( <.dy.2 store and mv ver 4-byte.> );
idv_int( dy_2 );
cond_idv_char( <.sv loc op.> ); file_n += 24;
-_-_-
<..end dvi page..>
if( !visible_cnt ) { U_CHAR str[256];
(IGNORED) sprintf(str, "--- empty picture --- %sidv[%d] ---\n",
job_name,page_n);
(IGNORED) printf("%s", str); (IGNORED) fprintf(log_file, "%s",str); }
while( stack_depth-- > 0 ){
idv_char(<.retrieve loc op.>); file_n++; }
-_-_-
<..idv vars..>+
int stack_depth=0;
-_-_-
<..chars for idv..>+
case <.def 4 byte font.>:
case <.def 3 byte font.>:
case <.def 2 byte font.>:
case <.def 1 byte font.>: { idv_char( ch ); file_n++;
for( i=14; i; i-- ){ ch = get_char(); idv_char( ch ); file_n++; }
i = ch; i += ch = get_char(); idv_char( ch ); file_n++;
while( i-- ){ idv_copy(); }
break; }
-_-_-
The following must be consisted with the usage ‘for( i=1; i<=cur_font[0]; i++ ){’.
<..chars for idv..>+
case <.font 1-byte.>:
case <.font 2-bytes.>:
case <.font 3-bytes.>:
case <.font int.>: { int i;
idv_char( ch ); file_n++;
cur_font[0] = ch - <.font 1-byte.> + 2;
cur_font[1] = ch;
for( i=2; i <= cur_font[0]; i++ ){
ch = get_char(); idv_char( ch );
cur_font[i] = ch; file_n++; }
break; }
-_-_-
<..chars for idv..>+
default: {
if( (ch < <.font 0.>) || (ch > <.font 63.>) ){
if( <.font defs for xdv’s idv?.> ){
<.xdv font def for idv.>
} else { err_i(23); }
}
else { idv_char( ch ); file_n++;
cur_font[0] = 1; cur_font[1] = ch; }
break;
}
-_-_-
<..idv vars..>+
char cur_font[6];
BOOL visible_cnt=FALSE;
-_-_-
<..extract symbols..>
{ int ch, i, mag;
U_CHAR str[256];
(IGNORED) fprintf(log_file, "%s", begin_char_gif);
dvi_flag = TRUE;
for( cur_fnt = font_tbl_size; cur_fnt--; ){
<.output to lg file.>
for( i = font_tbl[cur_fnt].char_l - font_tbl[cur_fnt].char_f + 1;
i--; )
if( get_bit( font_tbl[cur_fnt].gif_on, i) ){
bop_addr = advance_idv_page( bop_addr, cur_font );
set_loc( <.mv hor 1-byte.>, (long int) mid_page_x );
set_loc( <.mv ver 1-byte.>, (long int) mid_page_y );
<.get font of symbol.>
<.insert the char code.> }
}
(IGNORED) printf("Execute script ‘%slg’\n",
job_name);
(IGNORED) fclose( log_file );
}
-_-_-
<..insert the char code..>
if( (ch = i + font_tbl[cur_fnt].char_f) > 127 ) {
if( ch < 256 ) cond_idv_char(133); else warn_i(23); }
cond_idv_char( ch );
mag = (int) ((double) font_tbl[cur_fnt].scale /
font_tbl[cur_fnt].design_sz * 10 );
<.insert gif symbol to lg file.>
script(font_gif, job_name ,page_n, str);
-_-_-
‘printf("%s", str);’ — too mach info
<..open log file..>
{ U_CHAR str[256];
(IGNORED) strcpy((char *) str, (char *) job_name);
str[job_name_n-1] = ’\0’;
str[job_name_n-2] = ’g’;
str[job_name_n-3] = ’l’;
if( (log_file = fopen(str, WRITE_TEXT_FLAGS)) == NULL )
bad_in_file(str);
}
-_-_-
<..vars..>+
static FILE* log_file;
-_-_-
<..max page dimensions..>
mid_page_y = (INTEGER) get_unt(4) / 2;
mid_page_x = (INTEGER) get_unt(4) / 2;
-_-_-
<..vars..>+
static INTEGER mid_page_y, mid_page_x;
-_-_-
<..get font of symbol..>
{ INTEGER num;
num = font_tbl[cur_fnt].num;
if( num <= <.number of direct fonts.> )
cond_idv_char( (int) (num + <.font 0.>) );
else if( dvi_flag ){
if( (num < 0) || (num > 16777215L) ) idv_int(<.font int.>);
else if( num < 256 ) { idv_char(<.font 1-byte.>); file_n++; }
else if( num < 65536L ) int_to_dvi((long int) <.font 2-bytes.>,2);
else int_to_dvi((long int) <.font 3-bytes.>,3);
cond_idv_char( (int) num );
} }
-_-_-
The above seems to be incorrect for big numbers!!!!!!!!!!!!!!
<..header functions..>+
static void idv_char( ARG_I(int) );
-_-_-
<..functions..>+
static void idv_char( n ) int n
;{ (IGNORED) putc( n, idv_file ); }
-_-_-
<..header functions..>+
static void cond_idv_char( ARG_I(int) );
-_-_-
<..functions..>+
static void cond_idv_char( n ) int n
;{
if( dvi_flag ){ (IGNORED) putc( n, idv_file ); file_n++; }
}
-_-_-
<..header functions..>+
static void idv_copy( ARG_I(void) );
-_-_-
<..functions..>+
static void idv_copy( MYVOID )
{ idv_char( get_char() ); file_n++; }
-_-_-
<..defines..>+
#define idv_int(val) int_to_dvi((long int) val,4)
-_-_-
<..header functions..>+
static void cond_idv_int( ARG_II(long int, int) );
-_-_-
<..functions..>+
static void cond_idv_int( val, n ) long int val;
int n
;{
if( dvi_flag ){ int_to_dvi((long int) val, n ); file_n += n; }
}
-_-_-
<..header functions..>+
static void int_to_dvi( ARG_II(long int, int) );
-_-_-
<..functions..>+
static void int_to_dvi( val, n ) long int val;
int n
;{ unsigned U_CHAR ch2, ch3, ch4;
ch4 = (unsigned char) (val & 0xFF); val = val >> 8;
ch3 = (unsigned char) (val & 0xFF); val = val >> 8;
ch2 = (unsigned char) (val & 0xFF); val = val >> 8;
switch( n ){
case 4: idv_char( (int) val );
case 3: idv_char( ch2 );
case 2: idv_char( ch3 );
case 1: idv_char( ch4 ); }
if( val & 0x80 ) val -= 0x100;
}
-_-_-
<..header functions..>+
static void cond_string( ARG_II(int, int) );
-_-_-
<..functions..>+
static void cond_string(ch, n) int ch; int n
;{ cond_idv_char( ch );
while( n-- ) cond_idv_char( get_char() );
}
-_-_-
<..start first idv page..>
x_val = 0; y_val = 0; stack_n = 0;
idv_char( <.start page op.> );
idv_int( page_n + 1 ); for( i=36; i--; ) idv_char( 0);
idv_int( -1 ); bop_addr = file_n; file_n += 45;
idv_char(<.sv loc op.>); file_n++;
-_-_-
<..vars..>+
static int page_n, file_n;
-_-_-
<..header functions..>+
static INTEGER advance_idv_page( ARG_II( INTEGER,char*) );
-_-_-
<..functions..>+
static INTEGER advance_idv_page( bop_addr, cur_font )
INTEGER bop_addr;
char* cur_font
;{ int i;
if( page_n++ ){
idv_char(<.retrieve loc op.>); file_n++;
idv_char(<.end page op.>); file_n++;
idv_char( <.start page op.> );
idv_int( page_n ); for( i=36; i--; ) idv_char( 0);
idv_int( bop_addr ); bop_addr = file_n; file_n += 45;
idv_char(<.sv loc op.>); file_n++;
for( i=1; i<=cur_font[0]; i++ ){
idv_char( cur_font[i] ); file_n++;
} }
<.set dx-1, dx-2, dy-1, dy-2.>
return bop_addr;
}
-_-_-
What ‘cur_font[0]’ holds?
Dvips requires font definitions before the following code in the first dvi page.
<..set dx-1, dx-2, dy-1, dy-2..>
store_mv(<.dx.1 store and mv hor 4-byte.>, dx_1);
store_mv(<.dx.2 store and mv hor 4-byte.>, dx_2);
store_mv(<.dy.1 store and mv ver 4-byte.>, dy_1);
store_mv(<.dy.2 store and mv ver 4-byte.>, dy_2);
-_-_-
<..header functions..>+
static void store_mv( ARG_II( int, INTEGER) );
-_-_-
<..functionsNO-sep-9..>
static void store_mv(op, d) int op; INTEGER d
;{
cond_idv_char(op); cond_idv_int( (INTEGER) -d);
cond_idv_char(op); cond_idv_int( (INTEGER) d);
}
-_-_-
<..functions..>+
static void store_mv(op, d) int op; INTEGER d
;{
if( dvi_flag ){
cond_idv_char(op); idv_int( (INTEGER) -d);
cond_idv_char(op); idv_int( (INTEGER) d); file_n += 8; }
}
-_-_-