diff options
Diffstat (limited to 'Build/source/texk/web2c/luatexdir/font/pkin.w')
-rw-r--r-- | Build/source/texk/web2c/luatexdir/font/pkin.w | 434 |
1 files changed, 434 insertions, 0 deletions
diff --git a/Build/source/texk/web2c/luatexdir/font/pkin.w b/Build/source/texk/web2c/luatexdir/font/pkin.w new file mode 100644 index 00000000000..077680eb596 --- /dev/null +++ b/Build/source/texk/web2c/luatexdir/font/pkin.w @@ -0,0 +1,434 @@ +% pkin.w +% +% Copyright 1996-2006 Han The Thanh <thanh@@pdftex.org> +% Copyright 2006-2008 Taco Hoekwater <taco@@luatex.org> +% +% This file is part of LuaTeX. +% +% LuaTeX 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. +% +% LuaTeX 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 Lesser General Public +% License for more details. +% +% You should have received a copy of the GNU General Public License along +% with LuaTeX; if not, see <http://www.gnu.org/licenses/>. + +@ +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>. + +@c +#include "ptexlib.h" + +typedef short shalfword; + +static const char _svn_version[] = + "$Id: pkin.w 3584 2010-04-02 17:45:55Z hhenkel $" + "$URL: http://foundry.supelec.fr/svn/luatex/tags/beta-0.60.0/source/texk/web2c/luatexdir/font/pkin.w $"; + +@ +Now we have some routines to get stuff from the pk file. pkbyte returns +the next byte from the pk file. + +@c +static shalfword pkbyte(void) +{ + register shalfword i; + i = t3_getchar(); + if (t3_eof()) + pdftex_fail("unexpected eof in pk file"); + return (i); +} + +static int pkduo(void) +{ + register int i; + + i = pkbyte(); + if (i > 127) + i -= 256; + i = i * 256 + pkbyte(); + return (i); +} + +static int pktrio(void) +{ + register int i; + + i = pkbyte(); + if (i > 127) + i -= 256; + i = i * 256 + pkbyte(); + i = i * 256 + pkbyte(); + return (i); +} + +static int pkquad(void) +{ + register int 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. + +@c +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 (shalfword) (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 {\it 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]", (int) 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 = (halfword) 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. + +@c +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 int i, j; + register halfword word, wordweight; + halfword *raster; + shalfword rowsleft; + boolean turnon; + shalfword hbit; + halfword count; + shalfword wordwidth; + + wordwidth = (shalfword) ((cd->cwidth + 15) / 16); + i = (int) (2 * cd->cheight * (long) wordwidth); + if (i <= 0) + i = 2; + if (i > cd->rastersize) { + xfree(cd->raster); + cd->rastersize = i; + cd->raster = xtalloc((unsigned) 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 = (shalfword) cd->cheight; + hbit = (shalfword) cd->cwidth; + repeatcount = 0; + wordweight = 16; + word = 0; + bitweight = 0; + while (rowsleft > 0) { + count = (*realfunc) (); +#ifdef DEBUG + if (turnon) + printf("(%d) ", (int) count); + else + printf("%d ", (int) count); +#endif + while (count != 0) { + if ((count < wordweight) && (count < hbit)) { + if (turnon) + word += gpower[wordweight] - gpower[wordweight - count]; + hbit = (shalfword) (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 = (shalfword) (rowsleft - repeatcount - 1); + repeatcount = 0; + word = 0; + wordweight = 16; + count -= hbit; + hbit = (shalfword) cd->cwidth; + } else { + if (turnon) + word += gpower[wordweight]; + *raster++ = word; + word = 0; + count -= wordweight; + hbit = (shalfword) (hbit - wordweight); + wordweight = 16; + } + } + turnon = !turnon; + } + if ((rowsleft != 0) || ((int) hbit != cd->cwidth)) + pdftex_fail("error while unpacking; more bits than required"); + } +} + +@ +|readchar()|: the main routine +check pk preamble if necessary, +Reads the character definition of character `c' into `cd' if available, +return FALSE (0) otherwise. + +@c +int readchar(boolean check_preamble, chardesc * cd) +{ + register shalfword i; + register int k; + register int 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 = (int) ((flagbyte & 3) * 65536L + pkbyte() * 256L); + length = (int) (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 = (int) (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 */ +} |