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/web2c/pdftexdir/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/web2c/pdftexdir/pkin.c')
-rw-r--r-- | Build/source/texk/web2c/pdftexdir/pkin.c | 427 |
1 files changed, 427 insertions, 0 deletions
diff --git a/Build/source/texk/web2c/pdftexdir/pkin.c b/Build/source/texk/web2c/pdftexdir/pkin.c new file mode 100644 index 00000000000..3bece2124ad --- /dev/null +++ b/Build/source/texk/web2c/pdftexdir/pkin.c @@ -0,0 +1,427 @@ +/* +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: //depot/Build/source.development/TeX/texk/web2c/pdftexdir/pkin.c#4 $ +*/ + +/* + * 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. + * BUGFIXES + * May 1997: Eric Delaunay <delaunay@lix.polytechnique.fr> reports a + * problem with huge fonts (greater than 1008 DPI). The code for + * handling PK characters in `extended format' was wrongly derived + * from dvips. Made some minor improvements regarding error handling. + * REDESIGN + * Piet Tutelaers + * rcpt@urc.tue.nl + * + * Modified for use with pdftex by Han The Thanh <thanh@fi.muni.cz>. + */ + +#include "ptexlib.h" + +/* + * Now we have some routines to get stuff from the pk file. pkbyte returns + * the next byte from the pk file. + */ + + +/* +static FILE *pkfile ; +*/ + +extern FILE *t3_file; +#define pkfile t3_file + +static shalfword pkbyte(void) +{ + register shalfword i ; + + if ((i=xgetc(pkfile))==EOF) + pdftex_fail("unexpected eof in pk file") ; + return(i) ; +} + +static integer pkduo(void) +{ + register integer i ; + + i = pkbyte() ; + if (i > 127) + i -= 256 ; + i = i * 256 + pkbyte() ; + return(i) ; +} + +static integer pktrio(void) +{ + register integer i ; + + i = pkbyte() ; + if (i > 127) + i -= 256 ; + i = i * 256 + pkbyte() ; + i = i * 256 + pkbyte() ; + return(i) ; +} + +static integer pkquad(void) +{ + register integer i ; + + i = pkbyte() ; + if (i > 127) + i -= 256 ; + i = i * 256 + pkbyte() ; + i = i * 256 + pkbyte() ; + i = i * 256 + pkbyte() ; + return(i) ; +} + +/* + * 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(void) +{ halfword temp; + if ( bitweight == 0 ) + { bitweight = 16 ; + inputbyte = pkbyte(); + temp = inputbyte >> 4 ; + } else { + bitweight = 0 ; + temp = inputbyte & 15 ; + } + return(temp); +} + +static boolean getbit(void) +{ + bitweight >>= 1 ; + if ( bitweight == 0 ) + { inputbyte = pkbyte(); + bitweight = 128 ; + } + return(inputbyte & bitweight) ; +} + +static halfword (*realfunc)(void) ; +long pk_remainder ; +static halfword handlehuge(halfword i, halfword k); + +static halfword pkpackednum(void) { +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(void) +{ + halfword i ; + + if (pk_remainder < 0) { + pk_remainder = - pk_remainder ; + return ( 0 ) ; + } else if (pk_remainder > 0) { + if (pk_remainder > 4000) { + pk_remainder = 4000 - pk_remainder ; + return ( 4000 ) ; + } else { + i = pk_remainder ; + pk_remainder = 0 ; + realfunc = pkpackednum ; + return ( i ) ; + } + } else { + pdftex_fail("shouldn't happen") ; + return 0; /*NOTREACHED*/ + } +} + +static halfword handlehuge(halfword i, halfword k) +{ + register long j = k ; + + while (i) { + j = (j << 4L) + getnyb() ; + i-- ; + } + pk_remainder = 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(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 ; + if (i > cd->rastersize) { + xfree(cd->raster); + cd->rastersize = i; + cd->raster = xtalloc(cd->rastersize, halfword); + } + 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 ; + } + if ( ( rowsleft != 0 ) || ( (integer)hbit != cd->cwidth ) ) + pdftex_fail("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. + */ + +/* + * readchar(): the main routine + * check pk preamble if necessary, + * read the next character definition into `cd', + * return EOF if no character definition is available + */ + +int readchar(boolean check_preamble, chardesc *cd) +{ + register shalfword i ; + register integer k ; + register integer length=0 ; + +/* + * Check the preamble of the pkfile + */ + if (check_preamble) { + if (pkbyte()!=247) + pdftex_fail("bad pk file, expected pre") ; + if (pkbyte()!=89) + pdftex_fail("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() - 3; + cd->charcode = pkbyte() ; + (void) pktrio() ; /* TFMwidth */ + cd->xescape = pkbyte() ; /* pixel width */ + 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 ; + break ; +case 4: case 5: case 6: + length = (flagbyte & 3) * 65536L + pkbyte() * 256L ; + length = length + pkbyte() - 4L ; + cd->charcode = pkbyte() ; + (void) pktrio() ; /* TFMwidth */ + cd->xescape = pkduo() ; /* pixelwidth */ + cd->cwidth = pkduo() ; + cd->cheight = pkduo() ; + cd->xoff = pkduo() ; + cd->yoff = pkduo() ; + break ; +case 7: + length = pkquad() - 9L; + cd->charcode = pkquad(); + (void) pkquad() ; /* TFMwidth */ + cd->xescape = pkquad(); /* pixelwidth */ + k = pkquad() ; + cd->cwidth = pkquad(); + cd->cheight = pkquad(); + cd->xoff = pkquad(); + cd->yoff = pkquad(); + } + if (length <= 0) + pdftex_fail("packet length (%i) too small", (int)length) ; + unpack(cd); + return 1; + } 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: + pdftex_fail("unexpected command (%i)", (int)flagbyte) ; + } + } + } + return 0; /* character not found */ +} |