~ubuntu-branches/ubuntu/jaunty/luatex/jaunty

« back to all changes in this revision

Viewing changes to src/texk/web2c/luatexdir/font/pkin.c

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Preining
  • Date: 2007-09-24 12:56:11 UTC
  • Revision ID: james.westby@ubuntu.com-20070924125611-a8ge689azbptxvla
Tags: upstream-0.11.2
ImportĀ upstreamĀ versionĀ 0.11.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
Copyright (c) 1996-2002 Han The Thanh, <thanh@pdftex.org>
 
3
 
 
4
This file is part of pdfTeX.
 
5
 
 
6
pdfTeX is free software; you can redistribute it and/or modify
 
7
it under the terms of the GNU General Public License as published by
 
8
the Free Software Foundation; either version 2 of the License, or
 
9
(at your option) any later version.
 
10
 
 
11
pdfTeX is distributed in the hope that it will be useful,
 
12
but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
14
GNU General Public License for more details.
 
15
 
 
16
You should have received a copy of the GNU General Public License
 
17
along with pdfTeX; if not, write to the Free Software
 
18
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
19
 
 
20
$Id: //depot/Build/source.development/TeX/texk/web2c/pdftexdir/pkin.c#4 $
 
21
*/
 
22
 
 
23
/*
 
24
 * NAME
 
25
 * pkin.c - implementation of readchar()
 
26
 * DESCRIPTION
 
27
 * This implementation of readchar() uses parts of the program dvips
 
28
 * written by Tomas Rokicki--the inventor of the pkformat--(loadfont.c,
 
29
 * download.c and unpack.c). Dvips in turn is derived from pktype.
 
30
 * Pktype(TeX) is described in debt in ``The PKtype processor'',
 
31
 * which is available as pktype.weave as part of the METAFONTware.
 
32
 * What was needed to implement readchar() is rearranged in pkfile.c to
 
33
 * get more modularity in the style of MODULA2.
 
34
 * BUGFIXES
 
35
 *      May 1997: Eric Delaunay <delaunay@lix.polytechnique.fr> reports a
 
36
 *      problem with huge fonts (greater than 1008 DPI). The code for
 
37
 *      handling PK characters in `extended format' was wrongly derived
 
38
 *      from dvips. Made some minor improvements regarding error handling.
 
39
 * REDESIGN
 
40
 * Piet Tutelaers
 
41
 * rcpt@urc.tue.nl
 
42
 *
 
43
 *  Modified for use with pdftex by Han The Thanh <thanh@fi.muni.cz>.
 
44
 */
 
45
 
 
46
#include "ptexlib.h"
 
47
 
 
48
/*
 
49
 *   Now we have some routines to get stuff from the pk file.  pkbyte returns
 
50
 *   the next byte from the pk file.
 
51
 */
 
52
 
 
53
 
 
54
/*
 
55
static FILE *pkfile ;
 
56
*/
 
57
 
 
58
extern FILE *t3_file;
 
59
#define pkfile t3_file
 
60
 
 
61
static shalfword pkbyte(void)
 
62
{
 
63
    register shalfword i;
 
64
 
 
65
    if ((i = xgetc(pkfile)) == EOF)
 
66
        pdftex_fail("unexpected eof in pk file");
 
67
    return (i);
 
68
}
 
69
 
 
70
static integer pkduo(void)
 
71
{
 
72
    register integer i;
 
73
 
 
74
    i = pkbyte();
 
75
    if (i > 127)
 
76
        i -= 256;
 
77
    i = i * 256 + pkbyte();
 
78
    return (i);
 
79
}
 
80
 
 
81
static integer pktrio(void)
 
82
{
 
83
    register integer i;
 
84
 
 
85
    i = pkbyte();
 
86
    if (i > 127)
 
87
        i -= 256;
 
88
    i = i * 256 + pkbyte();
 
89
    i = i * 256 + pkbyte();
 
90
    return (i);
 
91
}
 
92
 
 
93
static integer pkquad(void)
 
94
{
 
95
    register integer i;
 
96
 
 
97
    i = pkbyte();
 
98
    if (i > 127)
 
99
        i -= 256;
 
100
    i = i * 256 + pkbyte();
 
101
    i = i * 256 + pkbyte();
 
102
    i = i * 256 + pkbyte();
 
103
    return (i);
 
104
}
 
105
 
 
106
/*
 
107
 *   The next part is devoted to unpacking the character data.
 
108
 */
 
109
 
 
110
/*
 
111
 *   We need procedures to get a nybble, bit, and packed word from the
 
112
 *   packed data structure.
 
113
 */
 
114
 
 
115
static halfword inputbyte, flagbyte;
 
116
static halfword bitweight;
 
117
static halfword dynf;
 
118
static halfword repeatcount;
 
119
 
 
120
static shalfword getnyb(void)
 
121
{
 
122
    halfword temp;
 
123
    if (bitweight == 0) {
 
124
        bitweight = 16;
 
125
        inputbyte = pkbyte();
 
126
        temp = inputbyte >> 4;
 
127
    } else {
 
128
        bitweight = 0;
 
129
        temp = inputbyte & 15;
 
130
    }
 
131
    return (temp);
 
132
}
 
133
 
 
134
static boolean getbit(void)
 
135
{
 
136
    bitweight >>= 1;
 
137
    if (bitweight == 0) {
 
138
        inputbyte = pkbyte();
 
139
        bitweight = 128;
 
140
    }
 
141
    return (inputbyte & bitweight);
 
142
}
 
143
 
 
144
static halfword(*realfunc) (void);
 
145
long pk_remainder;
 
146
static halfword handlehuge(halfword i, halfword k);
 
147
 
 
148
static halfword pkpackednum(void)
 
149
{
 
150
    register halfword i, j;
 
151
    i = getnyb();
 
152
    if (i == 0) {
 
153
        do {
 
154
            j = getnyb();
 
155
            i++;
 
156
        } while (!(j != 0));
 
157
        if (i > 3) {
 
158
/*
 
159
 *   Damn, we got a huge count!  We *fake* it by giving an artificially
 
160
 *   large repeat count.
 
161
 */
 
162
            return (handlehuge(i, j));
 
163
        } else {
 
164
            while (i > 0) {
 
165
                j = j * 16 + getnyb();
 
166
                i--;
 
167
            }
 
168
            return (j - 15 + (13 - dynf) * 16 + dynf);
 
169
        }
 
170
    } else if (i <= dynf)
 
171
        return (i);
 
172
    else if (i < 14)
 
173
        return ((i - dynf - 1) * 16 + getnyb() + dynf + 1);
 
174
    else {
 
175
        if (i == 14)
 
176
            repeatcount = pkpackednum();
 
177
        else
 
178
            repeatcount = 1;
 
179
#ifdef DEBUG
 
180
        printf("[%d]", (int) repeatcount);
 
181
#endif
 
182
        return ((*realfunc) ());
 
183
    }
 
184
}
 
185
 
 
186
static halfword rest(void)
 
187
{
 
188
    halfword i;
 
189
 
 
190
    if (pk_remainder < 0) {
 
191
        pk_remainder = -pk_remainder;
 
192
        return (0);
 
193
    } else if (pk_remainder > 0) {
 
194
        if (pk_remainder > 4000) {
 
195
            pk_remainder = 4000 - pk_remainder;
 
196
            return (4000);
 
197
        } else {
 
198
            i = pk_remainder;
 
199
            pk_remainder = 0;
 
200
            realfunc = pkpackednum;
 
201
            return (i);
 
202
        }
 
203
    } else {
 
204
        pdftex_fail("shouldn't happen");
 
205
        return 0;
 
206
     /*NOTREACHED*/}
 
207
}
 
208
 
 
209
static halfword handlehuge(halfword i, halfword k)
 
210
{
 
211
    register long j = k;
 
212
 
 
213
    while (i) {
 
214
        j = (j << 4L) + getnyb();
 
215
        i--;
 
216
    }
 
217
    pk_remainder = j - 15 + (13 - dynf) * 16 + dynf;
 
218
    realfunc = rest;
 
219
    return (rest());
 
220
}
 
221
 
 
222
/*
 
223
 *   And now we have our unpacking routine.
 
224
 */
 
225
 
 
226
static halfword gpower[17] = { 0, 1, 3, 7, 15, 31, 63, 127,
 
227
    255, 511, 1023, 2047, 4095, 8191, 16383, 32767, 65535
 
228
};
 
229
 
 
230
static void unpack(chardesc * cd)
 
231
{
 
232
    register integer i, j;
 
233
    register halfword word, wordweight;
 
234
    halfword *raster;
 
235
    shalfword rowsleft;
 
236
    boolean turnon;
 
237
    shalfword hbit;
 
238
    halfword count;
 
239
    shalfword wordwidth;
 
240
 
 
241
    wordwidth = (cd->cwidth + 15) / 16;
 
242
    i = 2 * cd->cheight * (long) wordwidth;
 
243
    if (i <= 0)
 
244
        i = 2;
 
245
    if (i > cd->rastersize) {
 
246
        xfree(cd->raster);
 
247
        cd->rastersize = i;
 
248
        cd->raster = xtalloc(cd->rastersize, halfword);
 
249
    }
 
250
    raster = cd->raster;
 
251
    realfunc = pkpackednum;
 
252
    dynf = flagbyte / 16;
 
253
    turnon = flagbyte & 8;
 
254
    if (dynf == 14) {
 
255
        bitweight = 0;
 
256
        for (i = 1; i <= cd->cheight; i++) {
 
257
            word = 0;
 
258
            wordweight = 32768;
 
259
            for (j = 1; j <= cd->cwidth; j++) {
 
260
                if (getbit())
 
261
                    word += wordweight;
 
262
                wordweight >>= 1;
 
263
                if (wordweight == 0) {
 
264
                    *raster++ = word;
 
265
                    word = 0;
 
266
                    wordweight = 32768;
 
267
                }
 
268
            }
 
269
            if (wordweight != 32768)
 
270
                *raster++ = word;
 
271
        }
 
272
    } else {
 
273
        rowsleft = cd->cheight;
 
274
        hbit = cd->cwidth;
 
275
        repeatcount = 0;
 
276
        wordweight = 16;
 
277
        word = 0;
 
278
        bitweight = 0;
 
279
        while (rowsleft > 0) {
 
280
            count = (*realfunc) ();
 
281
#ifdef DEBUG
 
282
            if (turnon)
 
283
                printf("(%d) ", (int) count);
 
284
            else
 
285
                printf("%d ", (int) count);
 
286
#endif
 
287
            while (count != 0) {
 
288
                if ((count < wordweight) && (count < hbit)) {
 
289
                    if (turnon)
 
290
                        word += gpower[wordweight] - gpower[wordweight - count];
 
291
                    hbit -= count;
 
292
                    wordweight -= count;
 
293
                    count = 0;
 
294
                } else if ((count >= hbit) && (hbit <= wordweight)) {
 
295
                    if (turnon)
 
296
                        word += gpower[wordweight] - gpower[wordweight - hbit];
 
297
                    *raster++ = word;
 
298
                    for (i = 1; i <= repeatcount; i++) {
 
299
                        for (j = 1; j <= wordwidth; j++) {
 
300
                            *raster = *(raster - wordwidth);
 
301
                            raster++;
 
302
                        }
 
303
                    }
 
304
                    rowsleft -= repeatcount + 1;
 
305
                    repeatcount = 0;
 
306
                    word = 0;
 
307
                    wordweight = 16;
 
308
                    count -= hbit;
 
309
                    hbit = cd->cwidth;
 
310
                } else {
 
311
                    if (turnon)
 
312
                        word += gpower[wordweight];
 
313
                    *raster++ = word;
 
314
                    word = 0;
 
315
                    count -= wordweight;
 
316
                    hbit -= wordweight;
 
317
                    wordweight = 16;
 
318
                }
 
319
            }
 
320
            turnon = !turnon;
 
321
        }
 
322
        if ((rowsleft != 0) || ((integer) hbit != cd->cwidth))
 
323
            pdftex_fail("error while unpacking; more bits than required");
 
324
    }
 
325
}
 
326
 
 
327
/*
 
328
 *   readchar(): the main routine
 
329
 *   Reads the character definition of character `c' into `cd' if available,
 
330
 *   return FALSE (0) otherwise.
 
331
 */
 
332
 
 
333
/*
 
334
 *   readchar(): the main routine
 
335
 *   check pk preamble if necessary,
 
336
 *   read the next character definition into `cd',
 
337
 *   return EOF if no character definition is available
 
338
 */
 
339
 
 
340
int readchar(boolean check_preamble, chardesc * cd)
 
341
{
 
342
    register shalfword i;
 
343
    register integer k;
 
344
    register integer length = 0;
 
345
 
 
346
/*
 
347
 *   Check the preamble of the pkfile
 
348
 */
 
349
    if (check_preamble) {
 
350
        if (pkbyte() != 247)
 
351
            pdftex_fail("bad pk file, expected pre");
 
352
        if (pkbyte() != 89)
 
353
            pdftex_fail("bad version of pk file");
 
354
        for (i = pkbyte(); i > 0; i--)  /* creator of pkfile */
 
355
            (void) pkbyte();
 
356
        (void) pkquad();        /* design size */
 
357
        k = pkquad();           /* checksum    */
 
358
        k = pkquad();           /* hppp        */
 
359
        k = pkquad();           /* vppp   */
 
360
    }
 
361
/*
 
362
 *   Now we skip to the desired character definition
 
363
 */
 
364
    while ((flagbyte = pkbyte()) != 245) {
 
365
        if (flagbyte < 240) {
 
366
            switch (flagbyte & 7) {
 
367
            case 0:
 
368
            case 1:
 
369
            case 2:
 
370
            case 3:
 
371
                length = (flagbyte & 7) * 256 + pkbyte() - 3;
 
372
                cd->charcode = pkbyte();
 
373
                (void) pktrio();        /* TFMwidth */
 
374
                cd->xescape = pkbyte(); /* pixel width */
 
375
                cd->cwidth = pkbyte();
 
376
                cd->cheight = pkbyte();
 
377
                cd->xoff = pkbyte();
 
378
                cd->yoff = pkbyte();
 
379
                if (cd->xoff > 127)
 
380
                    cd->xoff -= 256;
 
381
                if (cd->yoff > 127)
 
382
                    cd->yoff -= 256;
 
383
                break;
 
384
            case 4:
 
385
            case 5:
 
386
            case 6:
 
387
                length = (flagbyte & 3) * 65536L + pkbyte() * 256L;
 
388
                length = length + pkbyte() - 4L;
 
389
                cd->charcode = pkbyte();
 
390
                (void) pktrio();        /* TFMwidth */
 
391
                cd->xescape = pkduo();  /* pixelwidth */
 
392
                cd->cwidth = pkduo();
 
393
                cd->cheight = pkduo();
 
394
                cd->xoff = pkduo();
 
395
                cd->yoff = pkduo();
 
396
                break;
 
397
            case 7:
 
398
                length = pkquad() - 9L;
 
399
                cd->charcode = pkquad();
 
400
                (void) pkquad();        /* TFMwidth */
 
401
                cd->xescape = pkquad(); /* pixelwidth */
 
402
                k = pkquad();
 
403
                cd->cwidth = pkquad();
 
404
                cd->cheight = pkquad();
 
405
                cd->xoff = pkquad();
 
406
                cd->yoff = pkquad();
 
407
            }
 
408
            if (length <= 0)
 
409
                pdftex_fail("packet length (%i) too small", (int) length);
 
410
            unpack(cd);
 
411
            return 1;
 
412
        } else {
 
413
            k = 0;
 
414
            switch (flagbyte) {
 
415
            case 243:
 
416
                k = pkbyte();
 
417
                if (k > 127)
 
418
                    k -= 256;
 
419
            case 242:
 
420
                k = k * 256 + pkbyte();
 
421
            case 241:
 
422
                k = k * 256 + pkbyte();
 
423
            case 240:
 
424
                k = k * 256 + pkbyte();
 
425
                while (k-- > 0)
 
426
                    i = pkbyte();
 
427
                break;
 
428
            case 244:
 
429
                k = pkquad();
 
430
                break;
 
431
            case 246:
 
432
                break;
 
433
            default:
 
434
                pdftex_fail("unexpected command (%i)", (int) flagbyte);
 
435
            }
 
436
        }
 
437
    }
 
438
    return 0;                   /* character not found */
 
439
}