diff options
author | Karl Berry <karl@freefriends.org> | 2006-01-17 21:41:51 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2006-01-17 21:41:51 +0000 |
commit | 487ca4806cc046076293cf6cc5fbba0db282bac7 (patch) | |
tree | 847b412ab5158dd7bdd7ed7e5a4cc3fbca94be32 /Build/source/texk/ps2pkm/pkin.c | |
parent | a3d3111bfe26b8e5f5bc6049dfb2a4ca2edc7881 (diff) |
texk 1
git-svn-id: svn://tug.org/texlive/trunk@1485 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Build/source/texk/ps2pkm/pkin.c')
-rw-r--r-- | Build/source/texk/ps2pkm/pkin.c | 454 |
1 files changed, 454 insertions, 0 deletions
diff --git a/Build/source/texk/ps2pkm/pkin.c b/Build/source/texk/ps2pkm/pkin.c new file mode 100644 index 00000000000..a539b1de5b0 --- /dev/null +++ b/Build/source/texk/ps2pkm/pkin.c @@ -0,0 +1,454 @@ +/* + * NAME + * pkin.c - implementation of readchar() + * DESCRIPTION + * This implementation of readchar() uses parts of the program dvips + * written by Tomas Rokicki--the inventor of the pkformat--(loadfont.c, + * download.c and unpack.c). Dvips in turn is derived from pktype. + * Pktype(TeX) is described in debt in ``The PKtype processor'', + * which is available as pktype.weave as part of the METAFONTware. + * What was needed to implement readchar() is rearranged in pkfile.c to + * get more modularity in the style of MODULA2. + * REDESIGN + * Piet Tutelaers + * rcpt@urc.tue.nl + */ + +#ifdef DEBUG +#include <stdio.h> +#endif + +#include <stdlib.h> /* malloc() */ +#include "basics.h" /* basic definitions */ +#include "pkin.h" + +/* + * Forward declaration + */ +static void error(); + +/* + * Now we have some routines to get stuff from the pk file. pkbyte returns + * the next byte from the pk file. + */ + +static FILE *pkfile ; + +static shalfword +pkbyte() +{ + register shalfword i ; + + if ((i=getc(pkfile))==EOF) + error("! unexpected eof in pk file") ; + return(i) ; +} + +static integer +pkquad() +{ + register integer i ; + + i = pkbyte() ; + if (i > 127) + i -= 256 ; + i = i * 256 + pkbyte() ; + i = i * 256 + pkbyte() ; + i = i * 256 + pkbyte() ; + return(i) ; +} + +static integer +pktrio() +{ + register integer i ; + + i = pkbyte() ; + i = i * 256 + pkbyte() ; + i = i * 256 + pkbyte() ; + return(i) ; +} + +static integer +pkpair() +{ + register integer i ; + + i = pkbyte() ; + i = i * 256 + pkbyte() ; + return (i); +} + +static integer +pkspair() +{ + register integer i ; + + i = pkbyte() ; + if (i > 127) + i -= 256; + i = i * 256 + pkbyte(); + return (i); +} + +static char errbuf[80] ; +/* + * pkopen opens the pk file. This is system dependent. + */ + +static Boolean +pkopen(name) + char name[] ; +{ + if ((pkfile=fopen(name, RB))==NULL) { + (void)sprintf(errbuf, "Could not open %s", name) ; + error(errbuf) ; + return(0) ; + } else + return(1) ; +} + +/* + * The next part is devoted to unpacking the character data. + */ + +/* + * We need procedures to get a nybble, bit, and packed word from the + * packed data structure. + */ + +static halfword inputbyte, flagbyte ; +static halfword bitweight ; +static halfword dynf ; +static halfword repeatcount ; + +static shalfword +getnyb () +{ halfword temp; + if ( bitweight == 0 ) + { bitweight = 16 ; + inputbyte = pkbyte(); + temp = inputbyte >> 4 ; + } else { + bitweight = 0 ; + temp = inputbyte & 15 ; + } + return(temp); +} + +static Boolean +getbit () +{ + bitweight >>= 1 ; + if ( bitweight == 0 ) + { inputbyte = pkbyte(); + bitweight = 128 ; + } + return(inputbyte & bitweight) ; +} + +static halfword (*realfunc)() ; +long PKremainder ; +static halfword handlehuge() ; + +static halfword pkpackednum () { +register halfword i, j ; + i = getnyb () ; + if ( i == 0 ) + { do { j = getnyb () ; + i++ ; + } while ( ! ( j != 0 ) ) ; + if ( i > 3 ) { +/* + * Damn, we got a huge count! We *fake* it by giving an artificially + * large repeat count. + */ + return( handlehuge ( i , j ) ) ; + } else { + while ( i > 0 ) + { j = j * 16 + getnyb () ; + i-- ; + } + return ( j - 15 + ( 13 - dynf ) * 16 + dynf ) ; + } + } + else if ( i <= dynf ) return ( i ) ; + else if ( i < 14 ) return ( ( i - dynf - 1 ) * 16 + getnyb () + dynf + 1 + ) ; + else + { if ( i == 14 ) repeatcount = pkpackednum () ; + else repeatcount = 1 ; +#ifdef DEBUG + printf("[%d]", repeatcount); +#endif + return ( (*realfunc)() ) ; + } + } + +static halfword rest () +{ + halfword i ; + + if (PKremainder < 0) { + PKremainder = - PKremainder ; + return ( 0 ) ; + } else if (PKremainder > 0) { + if (PKremainder > 4000) { + PKremainder = 4000 - PKremainder ; + return ( 4000 ) ; + } else { + i = PKremainder ; + PKremainder = 0 ; + realfunc = pkpackednum ; + return ( i ) ; + } + } else { + error("! shouldn't happen") ; + } + + /*NOTREACHED*/ + return 0; +} + +static halfword handlehuge ( i , k ) +halfword i , k ; +{ + register long j = k ; + + while (i) { + j = (j << 4L) + getnyb() ; + i-- ; + } + PKremainder = j - 15 + ( 13 - dynf ) * 16 + dynf ; + realfunc = rest ; + return ( rest() ) ; +} + +/* + * And now we have our unpacking routine. + */ + +static halfword gpower[17] = { 0 , 1 , 3 , 7 , 15 , 31 , 63 , 127 , + 255 , 511 , 1023 , 2047 , 4095 , 8191 , 16383 , 32767 , 65535 } ; + +static void +unpack(cd) +chardesc *cd; +{ + register integer i, j ; + register halfword word, wordweight ; + halfword *raster; + shalfword rowsleft ; + Boolean turnon ; + shalfword hbit ; + halfword count ; + shalfword wordwidth ; + + wordwidth = (cd->cwidth + 15) / 16 ; + i = 2 * cd->cheight * (long)wordwidth ; + if (i <= 0) + i = 2 ; + cd->raster = (halfword *)malloc((unsigned)i) ; + if (cd->raster == NULL) + error("! out of memory during allocation") ; + raster = cd->raster; + realfunc = pkpackednum ; + dynf = flagbyte / 16 ; + turnon = flagbyte & 8 ; + if ( dynf == 14 ) + { bitweight = 0 ; + for ( i = 1 ; i <= cd->cheight ; i ++ ) + { word = 0 ; + wordweight = 32768 ; + for ( j = 1 ; j <= cd->cwidth ; j ++ ) + { if ( getbit () ) word += wordweight ; + wordweight >>= 1 ; + if ( wordweight == 0 ) + { *raster++ = word ; + word = 0 ; + wordweight = 32768 ; + } + } + if ( wordweight != 32768 ) + *raster++ = word ; + } + } else { + rowsleft = cd->cheight ; + hbit = cd->cwidth ; + repeatcount = 0 ; + wordweight = 16 ; + word = 0 ; + bitweight = 0 ; + while ( rowsleft > 0 ) + { count = (*realfunc)() ; +#ifdef DEBUG + if (turnon) printf("(%d) ",count); + else printf("%d ",count); +#endif + while ( count != 0 ) + { if ( ( count < wordweight ) && ( count < hbit ) ) + { if ( turnon ) word += gpower [ wordweight ] - gpower + [ wordweight - count ] ; + hbit -= count ; + wordweight -= count ; + count = 0 ; + } + else if ( ( count >= hbit ) && ( hbit <= wordweight ) ) + { if ( turnon ) + word += gpower [ wordweight ] - gpower + [ wordweight - hbit ] ; + *raster++ = word ; + for ( i = 1 ; i <= repeatcount ; i ++ ) { + for ( j = 1 ; j <= wordwidth ; j ++ ) { + *raster = *(raster - wordwidth) ; + raster++ ; + } + } + rowsleft -= repeatcount + 1 ; + repeatcount = 0 ; + word = 0 ; + wordweight = 16 ; + count -= hbit ; + hbit = cd->cwidth ; + } + else + { if ( turnon ) word += gpower [ wordweight ] ; + *raster++ = word ; + word = 0 ; + count -= wordweight ; + hbit -= wordweight ; + wordweight = 16 ; + } + } + turnon = ! turnon ; + } + putchar('\n') ; + if ( ( rowsleft != 0 ) || ( hbit != cd->cwidth ) ) + error ( "! error while unpacking; more bits than required" ) ; + } +} + +/* + * readchar(): the main routine + * Reads the character definition of character `c' into `cd' if available, + * return FALSE (0) otherwise. + */ +int +readchar(name, c, cd) +char name[]; +shalfword c; +chardesc *cd; +{ + register shalfword i ; + register integer k ; + register integer length = 0; + + if (!pkopen(name)) return(0); +/* + * Check the preamble of the pkfile + */ + if (pkbyte()!=247) + error("! bad pk file, expected pre") ; + if (pkbyte()!=89) + error("! bad version of pk file") ; + for(i=pkbyte(); i>0; i--) /* creator of pkfile */ + (void)pkbyte() ; + (void)pkquad(); /* design size */ + k = pkquad() ; /* checksum */ + k = pkquad() ; /* hppp */ + k = pkquad() ; /* vppp */ +/* + * Now we skip to the desired character definition + */ + while ((flagbyte=pkbyte())!=245) { + if (flagbyte < 240) { + switch (flagbyte & 7) { +case 0: case 1: case 2: case 3: + length = (flagbyte & 7) * 256 + pkbyte() - 4 ; + cd->charcode = pkbyte() ; + (void) pktrio() ; /* TFMwidth */ + (void) pkbyte() ; /* pixel width */ + break ; +case 4: + length = pkbyte() * 256 ; + length = length + pkbyte() - 5 ; + cd->charcode = pkbyte() ; + (void) pktrio() ; /* TFMwidth */ + i = pkbyte() ; + i = i * 256 + pkbyte() ; /* pixelwidth */ + break ; +case 5: case 6: + error("! lost sync in pk file (character too big)") ; +case 7: + length = pkquad() - 12 ; + cd->charcode = pkquad() ; + (void) pkquad() ; /* TFMwidth */ +/* cd->pixelwidth = (pkquad() + 32768) >> 16 ; */ + (void) pkquad(); /* pixelwidth */ + k = pkquad() ; + } + if (cd->charcode == c) { + if (flagbyte & 4) { + if ((flagbyte & 7) == 7) { /* long format */ + cd->cwidth = pkquad() ; + cd->cheight = pkquad() ; + cd->xoff = pkquad() ; + cd->yoff = pkquad() ; + } else { /* extended format */ + cd->cwidth = pkpair(); ; + cd->cheight = pkpair() ; + cd->xoff = pkspair() ; + cd->yoff = pkspair() ; + } + } else { /* short format */ + cd->cwidth = pkbyte() ; + cd->cheight = pkbyte() ; + cd->xoff = pkbyte() ; + cd->yoff = pkbyte() ; + if (cd->xoff > 127) + cd->xoff -= 256 ; + if (cd->yoff > 127) + cd->yoff -= 256 ; + } + unpack(cd); + (void)fclose(pkfile) ; + return(1); + } + for (; length>0; length--) /* skip this character */ + (void) pkbyte() ; + } else { + k = 0 ; + switch (flagbyte) { +case 243: + k = pkbyte() ; + if (k > 127) + k -= 256 ; +case 242: + k = k * 256 + pkbyte() ; +case 241: + k = k * 256 + pkbyte() ; +case 240: + k = k * 256 + pkbyte() ; + while (k-- > 0) + i = pkbyte() ; + break ; +case 244: + k = pkquad() ; + break ; +case 246: + break ; +default: + error("! lost sync in pk file") ; + } + } + } + (void)fclose(pkfile) ; + return(0); /* character not found */ +} + +static void error(s) +char s[]; +{ + fprintf(stderr, "%s\n", s); + exit(1); +} |