home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Meeting Pearls 3
/
Meeting_Pearls_III.iso
/
Pearls
/
texmf
/
source
/
driver
/
util
/
dospecia.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-06-04
|
16KB
|
666 lines
/*
** This file generated by localize 2.9 (AmigaDOS 2.1) from util/dospecia.c
*/
/* dospecial.c
*
* enthaelt:
* SkipDoSpecial() - ueberliest beliebig langen Special-Text
* DoSpecial() - liest den Special-Text, schneidet "vorne"/"hinten"
* Spaces/Ctrl-Zeichen ab und ruft
* CallDoSpecial()
* auf, in der dann der Text ausgewertet werden kann.
* ATARI-Teil:
* CallDoSpecial() - Auswertung von TPIC, Strunk-TeX und LindnerTeX
* Specials, anschliessend Auswertung wie dvips5.4x
*
* AMIGA-Teil:
* CallDoSpecial() - Protokoll fuer specialhost-Programm
* (zuvor sollte man noch die TPIC-specials heraus-
* filtern und erst, wenn tatsaechlich gezeichnet wird,
* die Punkte, Kreise, ... zu specialhost senden)
*/
#include "defines.h"
#include <stdio.h>
#include <ctype.h>
#include "globals.h"
#ifdef ANSI
# include <stddef.h>
# include <stdlib.h>
# include <string.h>
# include <math.h>
#endif
#include "bitmap.h"
#include "globals.i"
#ifndef AZTEC_C
# define fgetc(fp) getc(fp) /* Effizienz ? */
#endif
#ifdef AMIGA
# include <exec/types.h>
# include <exec/exec.h>
# include <exec/ports.h>
# include "fast_cp.i"
# include "special.h"
# include "dvihand.i"
#endif
#ifdef ATARI
extern int access(char *, int);
# include "atscreen.h"
#endif
#ifndef ANSI
char *strcpy();
#endif
/*
* Fuer die locale-Library:
*
* Hier duerfen *nur* die MSG_#? Nummern eingebunden werden!
* Achtung:
* Es muss/sollte 'multiple-include' erlaubt sein!
*/
#include "local.i"
#undef CATCOMP_ARRAY
#undef CATCOMP_BLOCK
#undef CATCOMP_STRINGS
#define CATCOMP_NUMBERS
#include "localstr.h"
extern long hh; /* current h on device */
extern long vv; /* current v on device */
#ifdef AMIGA
extern struct bitmap map;
extern long upper_limit;
extern long lower_limit;
#endif
static void CallDoSpecial(char *specialstring);
/*-->SkipDoSpecial*/
/*
* Wird beim Ueberlesen einer Seite aufgerufen.
* Evtl. sollten einige Specials, die global wirken, ausgefuehrt werden.
*/
void
SkipDoSpecial(DVIFILE *fp, unsigned long n)
{ char buffer[256];
unsigned long count;
while( n != 0L ) {
count = (n > 256) ? 256 : n;
if (DVIfread(buffer, 1L, count, fp) != count) {
Fatal(3, MSG_DVI_FILE_ERROR);
}
n -= count;
}
}
/*-->DoSpecial*/
/*********************************************************************/
/***************************** DoSpecial ***************************/
/*********************************************************************/
void
DoSpecial(DVIFILE *fp, unsigned long n)
{ static char *cmdbuffer = NULL;
static long cmdlen = -1L;
register char *p;
if( n == 0L ) /* before we forget this "special" case */
return;
/* If special is too long, write a message and skip over it... */
if( n > 65535L ) {
Logging(MSG_SPECIAL_TOO_LONG);
SkipDoSpecial(fp, n);
return;
}
/*
* Use old allocated buffer or
* allocate larger buffer for the special string
*/
if( cmdlen < (long)n ) {
if( cmdbuffer != NULL ) {
xfree(cmdbuffer);
cmdlen = -1L;
}
if( (cmdbuffer = malloc( n + 1 )) == NULL ) {
Logging(MSG_NO_MEM_FOR_SPECIAL);
SkipDoSpecial(fp, n);
return;
}
cmdlen = (long)n;
}
if( DVIfread(cmdbuffer, sizeof(char), (size_t)n, fp) != (size_t)n ) {
Fatal(3, MSG_DVI_FILE_ERROR);
return;
}
/* Trim the special string at both ends... */
while( n > 0 && cmdbuffer[n-1] <= ' ' )
n--; /* trim trailing blanks (and Ctrl-Chars) */
if( n == 0 )
return; /* all blanks is no-op */
/* Make sure that special string ends correctly with a \0 char */
cmdbuffer[n] = '\0';
p = cmdbuffer;
while( *p <= ' ' ) {
p++;
//n--;
}
/*
* Now the special string is null-terminated and trimmed
*/
CallDoSpecial(p);
/* If special buffer is too large, release allocated memory */
if( cmdlen > 256 ) {
xfree(cmdbuffer);
cmdlen = -1L;
}
}
/*----------------------------------------------------------------------*
*
* Site specific special treatment...
*
*----------------------------------------------------------------------*/
/*********************** A M I G A ********************************/
static void draw_border(struct special_map *bmap);
static int call_tpic_command(int tpic, char *p);
static int handle_tpic_command(int tpic, char *p);
static void draw_border(struct special_map *bmap)
{
long width,height;
long svv = vv, shh = hh;
width = (((long)(((double)bmap->width/(double)hconvresolution*1000/mag)*72.27+0.5))<<16) + (1<<15); /* *1000/mag : (hes) 2.6.95 */
height = (((long)(((double)bmap->height/(double)vconvresolution*1000/mag)*72.27+0.5))<<16) + (1<<15);
vv += bmap->voffset + ((1<<15) / vconv);
hh += bmap->hoffset - ((1<<15) / hconv);
SetRule(height, 1<<15, FALSE); /* 1<<15 == 0.5 pt */
SetRule(1<<15, width, FALSE);
vv -= (height + (vconv>>1) - (1<<15)) / vconv;
//vv -= bmap->height /*-vthickness*/;
SetRule(1<<15, width, FALSE);
vv += (height + (vconv>>1) - (1<<15)) / vconv;
//vv += bmap->height /*-vthickness*/;
hh += (width + (hconv>>1)) / hconv;
//hh += bmap->width /*-hthickness*/;
SetRule(height, 1<<15, FALSE);
vv = svv;
hh = shh;
}
static void CallDoSpecial(char *str)
{
struct special_map *bmap;
long x,y,width,height, xpos, ypos, pagewidth, xoff, shift, ystart;
long xstart, xend;
unsigned short *page, *image, it;
unsigned long copy, *insert;
FILE *iffile;
long buffer;
unsigned short *line;
long width_bit;
int tpic;
char *p;
/* TPIC specials: for tpic 2.0 */
tpic = TPIC_NO_TPIC;
p = str;
if (strncmp(p, "pn ", 3) == 0) { tpic = TPIC_PN; }
else if (strncmp(p, "pa ", 3) == 0) { tpic = TPIC_PA; }
else if (strcmp (p, "fp") == 0) { tpic = TPIC_FP; }
else if (strcmp (p, "ip") == 0) { tpic = TPIC_IP; } /* tpic 2.0 */
else if (strncmp(p, "da ", 3) == 0) { tpic = TPIC_DA; }
else if (strncmp(p, "dt ", 3) == 0) { tpic = TPIC_DT; }
else if (strcmp (p, "sp") == 0) { tpic = TPIC_SP; } /* tpic 2.0 */
else if (strncmp(p, "sp ", 3) == 0) { tpic = TPIC_SPB; } /* tpic 2.0 */
else if (strncmp(p, "ar ", 3) == 0) { tpic = TPIC_AR; } /* tpic 2.0 */
else if (strncmp(p, "ia ", 3) == 0) { tpic = TPIC_IA; } /* tpic 2.0 */
else if (strcmp (p, "sh") == 0) { tpic = TPIC_SH; } /* tpic 2.0 */
else if (strncmp(p, "sh ", 3) == 0) { tpic = TPIC_SHB; } /* tpic 2.0 */
else if (strcmp (p, "wh") == 0) { tpic = TPIC_WH; }
else if (strcmp (p, "bk") == 0) { tpic = TPIC_BK; }
else if (strncmp(p, "tx ", 3) == 0) { tpic = TPIC_TX; }
if (tpic != TPIC_NO_TPIC) {
(void)handle_tpic_command(tpic, p);
return;
}
/* else ... normaler \special-String */
bmap = send_special(str);
xstart = 0;
//xend = 0;
if (bmap != NULL) {
/* hh und vv enthalten die gerundete Pixel-Position links oben */
#ifdef OLD_NO_OFFSET_VARS
if (landscape) {
// wird spaeter noch gedreht, also jetzt etwas seltsame Offsets
x = hh + hconvresolution + bmap->hoffset; // plus 1 inch
y = vv + hoffset + bmap->voffset;
}
else {
x = hh + hoffset + bmap->hoffset;
y = vv + voffset + bmap->voffset;
}
// die rechte Seite wird direkt neben die linke gesetzt.
// Dazu wird der hoffset der rechten abgezogen, da dort kein Offset mehr benoetigt wird.
// hoffset gibt es wirklich nur am linken Rand. Ansonsten hat man ja den moffset.
if (twopage && !leftpage) x += paper_width + moffset - hoffset;
#else
x = hh + bmap->hoffset + OffsetBitmap_X;
y = vv + bmap->voffset + OffsetBitmap_Y;
#endif
if (x < 0) {
Warning(MSG_PICT_OUT_LEFT,x);
xstart = (15-x)/16; /* weglassen von Vielfachen von 16Bit (Word) */
x += xstart*16;
}
switch (bmap->where_is) {
case LOC_BITMAP:
case LOC_BITMAP_BORDER:
//copy = 0;
width = (bmap->width + 15) / 16; /* width in Words */
height = bmap->height;
y -= height;
xend = width;
if (x+width*16 > map.width) {
Warning(MSG_PICT_OUT_RIGHT);
xend = width - (((x+width*16-map.width)+15)/16);
}
xoff = x >> 4;
shift = x - (xoff << 4);
pagewidth = map.width >> 4;
/* Test ob Bild im sichtbaren Bereich */
if (y >= lower_limit || y + height < upper_limit) {
break;
}
/* Test oberer Rand */
if (y < upper_limit) {
ystart = upper_limit - y;
page = ((unsigned short *)map.pixptr) + xoff;
image = (unsigned short *)bmap->loc.map + xstart + (width*ystart);
}
else {
ystart = 0;
page = ((unsigned short *)map.pixptr) + (y-upper_limit) * pagewidth + xoff;
image = (unsigned short *)bmap->loc.map + xstart;
}
/* Test unterer Rand */
if (y + height >= lower_limit) {
height = lower_limit - y - 1;
/* height -= (lower_limit - y); that's a bug !! */
}
for (ypos = ystart; ypos < height; ypos++) {
for (xpos = xstart; xpos < xend; xpos++) {
it = *((unsigned short *)image+xpos);
copy = ((unsigned long)it) << 16;
insert = (unsigned long *)(page + xpos);
*insert |= (copy >> shift);
}
image += width;
page += pagewidth;
}
if (bmap->where_is == LOC_BITMAP_BORDER) {
draw_border(bmap);
}
break;
case LOC_FILE:
case LOC_FILE_BORDER:
if ((iffile = fopen(bmap->loc.filename,"r")) != NULL) {
if (fread((char *)&buffer,4,1,iffile) == 1 && buffer == MAGIC_WORD) {
(void)fread((char *)&buffer,4,1,iffile);
if (fread((char *)&buffer,4,1,iffile) == 1) {
width = (buffer+15) / 16; /* in words */
width_bit = buffer;
xend = width;
if (x+width*16 > map.width) {
Warning(MSG_PICT_OUT_RIGHT);
xend = width - (((x+width*16-map.width)+15)/16);
}
if (fread((char *)&buffer,4,1,iffile) == 1) {
height = buffer;
y -= height;
if ((line = xmalloc(width*2)) == NULL) {
Warning(MSG_NO_MEM_FOR_SPECIAL_BITMAP);
}
else {
xoff = x >> 4;
shift = x - (xoff << 4);
pagewidth = map.width >> 4;
/* Test on Bild im sichtbaren Bereich */
if (y > lower_limit || y + height < upper_limit) {
fclose(iffile);
break;
}
/* Test oberer Rand */
if (y < upper_limit) {
ystart = upper_limit - y;
page = ((unsigned short *)map.pixptr) + xoff;
fseek(iffile,width * 2 * ystart, 1); /* seek from actuall pos */
}
else {
page = ((unsigned short *)map.pixptr) + (y-upper_limit) * pagewidth + xoff;
ystart = 0;
}
/* Test unterer Rand */
if (y + height > lower_limit) {
height = lower_limit - y;
}
for (ypos = ystart; ypos < height; ypos++) {
if (fread((char *)line,2,width,iffile) == width) {
image = (unsigned short *)line+xstart;
for (xpos = xstart; xpos < xend; xpos++) {
it = *((unsigned short *)image+xpos);
copy = ((unsigned long)it) << 16;
insert = (unsigned long *)(page + xpos);
*insert |= (copy >> shift);
}
page += pagewidth;
}
}
xfree(line);
}
if (bmap->where_is == LOC_FILE_BORDER) {
bmap->width = width_bit;
bmap->height = height;
draw_border(bmap);
}
}
}
}
fclose(iffile);
}
break;
case LOC_BORDER:
draw_border(bmap);
break;
case LOC_RECTANGLE:
width = bmap->width; /* width in Bits */
height = bmap->height;
width = ((long)(((double)width/(double)hconvresolution)*72.27+0.5))<<16;
height = ((long)(((double)height/(double)vconvresolution)*72.27+0.5))<<16;
vv += bmap->voffset;
hh += bmap->hoffset;
SetRule(height, width, FALSE);
vv -= bmap->voffset;
hh -= bmap->hoffset;
break;
case LOC_NONE:
break;
default:
Warning(MSG_UNKNOWN_PICT_LOC);
break;
}
}
special_ok();
}
#define MAXPOINTS 300 /* Max points in a path */
#define TWOPI (3.14159265359*2.0)
static long xx[MAXPOINTS], yy[MAXPOINTS]; /* Path in milli-inches */
static long path_len = 0; /* # points in current path */
static char whiten = FALSE, blacken = FALSE;
static long pen_size = 0L;
static long shade; /* float *1000 */
static struct tpic_msg tp;
extern struct bitmap map;
extern long upper_limit;
extern long lower_limit;
static int handle_tpic_command(int tpic, char *p)
{
long ps;
long pathx, pathy;
float f;
int err = FALSE;
switch (tpic) {
case TPIC_PN : /* "pn " */
p += 2;
if (sscanf(p, "%ld", &ps) != 1) {
Warning(MSG_ILLEG_PS_COMM, p);
err = TRUE;
}
else {
pen_size = ps;
}
break;
case TPIC_PA : /* "pa " */
p += 2;
if (path_len >= MAXPOINTS-1) {
Warning(MSG_TOO_MANY_POINTS, p);
err = TRUE;
}
else {
if (sscanf(p, "%ld %ld", &pathx, &pathy) != 2) {
Warning(MSG_MALFORMED_PATH_COMM, p);
err = TRUE;
}
else {
path_len++; /* naja, beginen wir halt bei 1 (?) */
xx[path_len] = pathx;
yy[path_len] = pathy;
}
}
break;
case TPIC_FP : /* "fp" */
case TPIC_IP : /* "ip" */
err = call_tpic_command(tpic, p);
path_len = 0;
break;
case TPIC_DA : /* "da " */
case TPIC_DT : /* "dt " */
case TPIC_SP : /* "sp" */
case TPIC_SPB: /* "sp " */
p += 2;
err = call_tpic_command(tpic, p);
path_len = 0;
break;
case TPIC_AR : /* "ar " */
case TPIC_IA : /* "ia " */
p += 2;
err = call_tpic_command(tpic, p);
break;
case TPIC_SH : /* "sh" */
blacken = whiten = FALSE;
shade = 5000;
break;
case TPIC_SHB: /* "sh " */
p += 2;
blacken = whiten = FALSE; /* noch nicht ganz korrekt... */
if (sscanf(p, "%f", &f) != 1) {
Warning(MSG_ILLEG_PS_COMM, p);
err = TRUE;
}
else {
shade = (long)(f*10000.0);
}
break;
case TPIC_WH : /* "wh" */
whiten = TRUE;
blacken = FALSE;
shade = 0;
break;
case TPIC_BK : /* "bk" */
blacken = TRUE;
whiten = FALSE;
shade = 10000;
break;
case TPIC_TX : /* "tx" */
break;
}
return err;
}
static int call_tpic_command(int tpic, char *p)
{
int err = FALSE;
float f;
long t;
long x, y, rx, ry;
float s, e;
tp.tpic_com = tpic;
tp.whiten = whiten;
tp.blacken = blacken;
tp.shade = shade;
tp.pen_size = pen_size;
tp.path_len = path_len;
tp.xx = xx;
tp.yy = yy;
tp.opt_long[0] = tp.opt_long[1] = tp.opt_long[2] = tp.opt_long[3] = 0;
tp.opt_float[0][0] = tp.opt_float[1][0] = '\0';
switch (tpic) {
case TPIC_FP : /* "fp" */
case TPIC_IP : /* "ip" */
break;
case TPIC_DA : /* "da " */
case TPIC_DT : /* "dt " */
if (sscanf(p, "%f", &f) != 1) {
Warning(MSG_ILLEG_PS_COMM, p);
err = TRUE;
}
else {
sprintf(tp.opt_float[0], "%10.5g", f);
}
break;
case TPIC_SPB: /* "sp " */
if (sscanf(p, "%ld", &t) != 1) {
Warning(MSG_ILLEG_PS_COMM, p);
err = TRUE;
}
else {
tp.opt_long[0] = t;
}
break;
case TPIC_SP : /* "sp" */
tp.opt_long[0] = 0;
break;
case TPIC_AR : /* "ar " */
case TPIC_IA : /* "ia " */
if (sscanf(p, "%ld %ld %ld %ld %f %f", &x, &y, &rx, &ry, &s, &e) != 6) {
Warning(MSG_ILLEG_PS_COMM, p);
err = TRUE;
}
else {
tp.opt_long[0] = x;
tp.opt_long[1] = y;
tp.opt_long[2] = rx;
tp.opt_long[3] = ry;
sprintf(tp.opt_float[0], "%10.5g", s);
sprintf(tp.opt_float[1], "%10.5g", e);
}
break;
}
send_tpic(&tp);
return err;
}