summaryrefslogtreecommitdiff
path: root/Build/source/texk/web2c/pdftexdir/pkin.c
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2006-01-17 21:41:51 +0000
committerKarl Berry <karl@freefriends.org>2006-01-17 21:41:51 +0000
commit487ca4806cc046076293cf6cc5fbba0db282bac7 (patch)
tree847b412ab5158dd7bdd7ed7e5a4cc3fbca94be32 /Build/source/texk/web2c/pdftexdir/pkin.c
parenta3d3111bfe26b8e5f5bc6049dfb2a4ca2edc7881 (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.c427
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 */
+}