Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/dvi/mdvi-lib/pk.c
diff options
context:
space:
mode:
Diffstat (limited to 'dvi/mdvi-lib/pk.c')
-rw-r--r--dvi/mdvi-lib/pk.c569
1 files changed, 0 insertions, 569 deletions
diff --git a/dvi/mdvi-lib/pk.c b/dvi/mdvi-lib/pk.c
deleted file mode 100644
index 48da008..0000000
--- a/dvi/mdvi-lib/pk.c
+++ /dev/null
@@ -1,569 +0,0 @@
-
-/* Copyright (C) 2000, Matias Atria
- *
- * This program 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.
- *
- * This program 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 this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- */
-
-/*
- * History:
- *
- * 11/3/2000:
- * - First working version
- * 11/4/2000:
- * - FIXED: entirely white/black rows were missed.
- * 11/8/2000:
- * - TESTED: Glyphs are rendered correctly in different byte orders.
- * - Made bitmap code much more efficient and compact.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <math.h>
-
-#include "mdvi.h"
-#include "private.h"
-
-#define PK_ID 89
-#define PK_CMD_START 240
-#define PK_X1 240
-#define PK_X2 241
-#define PK_X3 242
-#define PK_X4 243
-#define PK_Y 244
-#define PK_POST 245
-#define PK_NOOP 246
-#define PK_PRE 247
-
-#define PK_DYN_F(x) (((x) >> 4) & 0xf)
-#define PK_PACKED(x) (PK_DYN_F(x) != 14)
-
-static int pk_load_font __PROTO((DviParams *, DviFont *));
-static int pk_font_get_glyph __PROTO((DviParams *, DviFont *, int));
-
-static int pk_auto_generate = 1; /* this is ON by default */
-
-typedef struct {
- char currbyte;
- char nybpos;
- int dyn_f;
-} pkread;
-
-static char *pk_lookup __PROTO((const char *, Ushort *, Ushort *));
-static char *pk_lookupn __PROTO((const char *, Ushort *, Ushort *));
-
-/* only symbols exported by this file */
-DviFontInfo pk_font_info = {
- "PK",
- 0, /* scaling not supported natively */
- pk_load_font,
- pk_font_get_glyph,
- mdvi_shrink_glyph,
- mdvi_shrink_glyph_grey,
- NULL, /* free */
- NULL, /* reset */
- pk_lookup, /* lookup */
- kpse_pk_format,
- NULL
-};
-
-DviFontInfo pkn_font_info = {
- "PKN",
- 0, /* scaling not supported natively */
- pk_load_font,
- pk_font_get_glyph,
- mdvi_shrink_glyph,
- mdvi_shrink_glyph_grey,
- NULL, /* free */
- NULL, /* reset */
- pk_lookupn, /* lookup */
- kpse_pk_format,
- NULL
-};
-
-static char *pk_lookup(const char *name, Ushort *hdpi, Ushort *vdpi)
-{
- kpse_glyph_file_type type;
- char *filename;
-
- if(pk_auto_generate == 0) {
- kpse_set_program_enabled(kpse_pk_format, 1, kpse_src_cmdline);
- pk_auto_generate = 1;
- }
- filename = kpse_find_glyph(name, Max(*hdpi, *vdpi),
- kpse_pk_format, &type);
- if(filename && type.source == kpse_glyph_source_fallback) {
- mdvi_free(filename);
- filename = NULL;
- } else if(filename) {
- *hdpi = *vdpi = type.dpi;
- }
- return filename;
-}
-
-static char *pk_lookupn(const char *name, Ushort *hdpi, Ushort *vdpi)
-{
- kpse_glyph_file_type type;
- char *filename;
-
- if(pk_auto_generate) {
- kpse_set_program_enabled(kpse_pk_format, 0, kpse_src_cmdline);
- pk_auto_generate = 0;
- }
- filename = kpse_find_glyph(name, Max(*hdpi, *vdpi),
- kpse_pk_format, &type);
- if(filename && type.source == kpse_glyph_source_fallback) {
- mdvi_free(filename);
- filename = NULL;
- } else if(filename) {
- *hdpi = *vdpi = type.dpi;
- }
- return filename;
-}
-
-static inline int pk_get_nyb(FILE *p, pkread *pk)
-{
- unsigned t;
- int nb;
- char c;
-
- t = c = pk->currbyte;
- nb = pk->nybpos;
-
- switch(nb) {
- case 0:
- c = pk->currbyte = fuget1(p);
- t = (c >> 4);
- break;
- case 1:
- t = c;
- break;
- }
- pk->nybpos = !nb;
- return (t & 0xf);
-}
-
-/*
- * this is a bit cumbersome because we have to pass around
- * the `pkread' data...
- */
-static int pk_packed_num(FILE *p, pkread *pkr, int *repeat)
-{
- int i, j;
- int dyn_f = pkr->dyn_f;
-
- i = pk_get_nyb(p, pkr);
- if(i == 0) {
- do {
- j = pk_get_nyb(p, pkr);
- i++;
- } while(j == 0);
- while(i-- > 0)
- j = (j << 4) + pk_get_nyb(p, pkr);
- return (j - 15 + ((13 - dyn_f) << 4) +
- dyn_f);
- } else if(i <= dyn_f)
- return i;
- else if(i < 14)
- return ((i - dyn_f - 1) << 4) +
- pk_get_nyb(p, pkr) + dyn_f + 1;
- else {
- *repeat = 1;
- if(i == 14)
- *repeat = pk_packed_num(p, pkr, repeat);
- return pk_packed_num(p, pkr, repeat);
- }
-}
-
-#define ROUND(x,y) (((x) + (y) - 1) / (y))
-
-static BITMAP *get_bitmap(FILE *p, int w, int h, int flags)
-{
- int i, j;
- BmUnit *ptr;
- BITMAP *bm;
- int bitpos;
- int currch;
-
- flags = 0; /* shut up that compiler */
- bitpos = -1;
- if((bm = bitmap_alloc(w, h)) == NULL)
- return NULL;
- DEBUG((DBG_BITMAPS, "get_bitmap(%d,%d,%d): reading raw bitmap\n",
- w, h, flags));
- ptr = bm->data;
- currch = 0;
- for(i = 0; i < h; i++) {
- BmUnit mask;
-
- mask = FIRSTMASK;
- for(j = 0; j < w; j++) {
- if(bitpos < 0) {
- currch = fuget1(p);
- bitpos = 7;
- }
- if(currch & (1 << bitpos))
- *ptr |= mask;
- bitpos--;
- if(mask == LASTMASK) {
- ptr++;
- mask = FIRSTMASK;
- } else
- NEXTMASK(mask);
- }
- ptr = bm_offset(ptr, bm->stride);
- }
- return bm;
-}
-
-static BITMAP *get_packed(FILE *p, int w, int h, int flags)
-{
- int inrow, count;
- int row;
- BITMAP *bm;
- int repeat_count;
- int paint;
- pkread pkr;
-
- pkr.nybpos = 0;
- pkr.currbyte = 0;
- pkr.dyn_f = PK_DYN_F(flags);
- paint = !!(flags & 0x8);
-
- repeat_count = 0;
- row = 0;
- inrow = w;
- if((bm = bitmap_alloc(w, h)) == NULL)
- return NULL;
- DEBUG((DBG_BITMAPS, "get_packed(%d,%d,%d): reading packed glyph\n",
- w, h, flags));
- while(row < h) {
- int i = 0;
-
- count = pk_packed_num(p, &pkr, &i);
- if(i > 0) {
- if(repeat_count)
- fprintf(stderr, "second repeat count for this row (had %d and got %d)\n",
- repeat_count, i);
- repeat_count = i;
- }
-
- if(count >= inrow) {
- Uchar *r, *t;
- BmUnit *a, mask;
-
- /* first finish current row */
- if(paint)
- bitmap_set_row(bm, row, w - inrow, inrow, paint);
- /* now copy it as many times as required */
- r = (Uchar *)bm->data + row * bm->stride;
- while(repeat_count-- > 0) {
- t = r + bm->stride;
- /* copy entire lines */
- memcpy(t, r, bm->stride);
- r = t;
- row++;
- }
- repeat_count = 0;
- /* count first row we drew */
- row++;
- /* update run count */
- count -= inrow;
- /* now r points to the beginning of the last row we finished */
- if(paint)
- mask = ~((BmUnit)0);
- else
- mask = 0;
- /* goto next row */
- a = (BmUnit *)(r + bm->stride);
- /* deal with entirely with/black rows */
- while(count >= w) {
- /* count number of atoms in a row */
- i = ROUND(w, BITMAP_BITS);
- while(i-- > 0)
- *a++ = mask;
- count -= w;
- row++;
- }
- inrow = w;
- }
- if(count > 0)
- bitmap_set_row(bm, row, w - inrow, count, paint);
- inrow -= count;
- paint = !paint;
- }
- if(row != h || inrow != w) {
- error(_("Bad PK file: More bits than required\n"));
- bitmap_destroy(bm);
- return NULL;
- }
- return bm;
-}
-
-static BITMAP *get_char(FILE *p, int w, int h, int flags)
-{
- /* check if dyn_f == 14 */
- if(((flags >> 4) & 0xf) == 14)
- return get_bitmap(p, w, h, flags);
- else
- return get_packed(p, w, h, flags);
-}
-
-/* supports any number of characters in a font */
-static int pk_load_font(DviParams *unused, DviFont *font)
-{
- int i;
- int flag_byte;
- int loc, hic, maxch;
- Int32 checksum;
- FILE *p;
-#ifndef NODEBUG
- char s[256];
-#endif
- long alpha, beta, z;
-
- font->chars = xnalloc(DviFontChar, 256);
- p = font->in;
- memzero(font->chars, 256 * sizeof(DviFontChar));
- for(i = 0; i < 256; i++)
- font->chars[i].offset = 0;
-
- /* check the preamble */
- loc = fuget1(p); hic = fuget1(p);
- if(loc != PK_PRE || hic != PK_ID)
- goto badpk;
- i = fuget1(p);
-#ifndef NODEBUG
- for(loc = 0; loc < i; loc++)
- s[loc] = fuget1(p);
- s[loc] = 0;
- DEBUG((DBG_FONTS, "(pk) %s: %s\n", font->fontname, s));
-#else
- fseek(in, (long)i, SEEK_CUR);
-#endif
- /* get the design size */
- font->design = fuget4(p);
- /* get the checksum */
- checksum = fuget4(p);
- if(checksum && font->checksum && font->checksum != checksum) {
- warning(_("%s: checksum mismatch (expected %u, got %u)\n"),
- font->fontname, font->checksum, checksum);
- } else if(!font->checksum)
- font->checksum = checksum;
- /* skip pixel per point ratios */
- fuget4(p);
- fuget4(p);
- if(feof(p))
- goto badpk;
-
- /* now start reading the font */
- loc = 256; hic = -1; maxch = 256;
-
- /* initialize alpha and beta for TFM width computation */
- TFMPREPARE(font->scale, z, alpha, beta);
-
- while((flag_byte = fuget1(p)) != PK_POST) {
- if(feof(p))
- break;
- if(flag_byte >= PK_CMD_START) {
- switch(flag_byte) {
- case PK_X1:
- case PK_X2:
- case PK_X3:
- case PK_X4: {
-#ifndef NODEBUG
- char *t;
- int n;
-
- i = fugetn(p, flag_byte - PK_X1 + 1);
- if(i < 256)
- t = &s[0];
- else
- t = mdvi_malloc(i + 1);
- for(n = 0; n < i; n++)
- t[n] = fuget1(p);
- t[n] = 0;
- DEBUG((DBG_SPECIAL, "(pk) %s: Special \"%s\"\n",
- font->fontname, t));
- if(t != &s[0])
- mdvi_free(t);
-#else
- i = fugetn(p, flag_byte - PK_X1 + 1);
- while(i-- > 0)
- fuget1(p);
-#endif
- break;
- }
- case PK_Y:
- i = fuget4(p);
- DEBUG((DBG_SPECIAL, "(pk) %s: MF special %u\n",
- font->fontname, (unsigned)i));
- break;
- case PK_POST:
- case PK_NOOP:
- break;
- case PK_PRE:
- error(_("%s: unexpected preamble\n"), font->fontname);
- goto error;
- }
- } else {
- int pl;
- int cc;
- int w, h;
- int x, y;
- int offset;
- long tfm;
-
- switch(flag_byte & 0x7) {
- case 7:
- pl = fuget4(p);
- cc = fuget4(p);
- offset = ftell(p) + pl;
- tfm = fuget4(p);
- fsget4(p); /* skip dx */
- fsget4(p); /* skip dy */
- w = fuget4(p);
- h = fuget4(p);
- x = fsget4(p);
- y = fsget4(p);
- break;
- case 4:
- case 5:
- case 6:
- pl = (flag_byte % 4) * 65536 + fuget2(p);
- cc = fuget1(p);
- offset = ftell(p) + pl;
- tfm = fuget3(p);
- fsget2(p); /* skip dx */
- /* dy assumed 0 */
- w = fuget2(p);
- h = fuget2(p);
- x = fsget2(p);
- y = fsget2(p);
- break;
- default:
- pl = (flag_byte % 4) * 256 + fuget1(p);
- cc = fuget1(p);
- offset = ftell(p) + pl;
- tfm = fuget3(p);
- fsget1(p); /* skip dx */
- /* dy assumed 0 */
- w = fuget1(p);
- h = fuget1(p);
- x = fsget1(p);
- y = fsget1(p);
- }
- if(feof(p))
- break;
- if(cc < loc)
- loc = cc;
- if(cc > hic)
- hic = cc;
- if(cc > maxch) {
- font->chars = xresize(font->chars,
- DviFontChar, cc + 16);
- for(i = maxch; i < cc + 16; i++)
- font->chars[i].offset = 0;
- maxch = cc + 16;
- }
- font->chars[cc].code = cc;
- font->chars[cc].flags = flag_byte;
- font->chars[cc].offset = ftell(p);
- font->chars[cc].width = w;
- font->chars[cc].height = h;
- font->chars[cc].glyph.data = NULL;
- font->chars[cc].x = x;
- font->chars[cc].y = y;
- font->chars[cc].glyph.x = x;
- font->chars[cc].glyph.y = y;
- font->chars[cc].glyph.w = w;
- font->chars[cc].glyph.h = h;
- font->chars[cc].grey.data = NULL;
- font->chars[cc].shrunk.data = NULL;
- font->chars[cc].tfmwidth = TFMSCALE(z, tfm, alpha, beta);
- font->chars[cc].loaded = 0;
- fseek(p, (long)offset, SEEK_SET);
- }
- }
- if(flag_byte != PK_POST) {
- error(_("%s: unexpected end of file (no postamble)\n"),
- font->fontname);
- goto error;
- }
- while((flag_byte = fuget1(p)) != EOF) {
- if(flag_byte != PK_NOOP) {
- error(_("invalid PK file! (junk in postamble)\n"));
- goto error;
- }
- }
-
- /* resize font char data */
- if(loc > 0 || hic < maxch-1) {
- memmove(font->chars, font->chars + loc,
- (hic - loc + 1) * sizeof(DviFontChar));
- font->chars = xresize(font->chars,
- DviFontChar, hic - loc + 1);
- }
- font->loc = loc;
- font->hic = hic;
- return 0;
-
-badpk:
- error(_("%s: File corrupted, or not a PK file\n"), font->fontname);
-error:
- mdvi_free(font->chars);
- font->chars = NULL;
- font->loc = font->hic = 0;
- return -1;
-}
-
-static int pk_font_get_glyph(DviParams *params, DviFont *font, int code)
-{
- DviFontChar *ch;
-
- if((ch = FONTCHAR(font, code)) == NULL)
- return -1;
-
- if(ch->offset == 0)
- return -1;
- DEBUG((DBG_GLYPHS, "(pk) loading glyph for character %d (%dx%d) in font `%s'\n",
- code, ch->width, ch->height, font->fontname));
- if(font->in == NULL && font_reopen(font) < 0)
- return -1;
- if(!ch->width || !ch->height) {
- /* this happens for ` ' (ASCII 32) in some fonts */
- ch->glyph.x = ch->x;
- ch->glyph.y = ch->y;
- ch->glyph.w = ch->width;
- ch->glyph.h = ch->height;
- ch->glyph.data = NULL;
- return 0;
- }
- if(fseek(font->in, ch->offset, SEEK_SET) == -1)
- return -1;
- ch->glyph.data = get_char(font->in,
- ch->width, ch->height, ch->flags);
- if(ch->glyph.data) {
- /* restore original settings */
- ch->glyph.x = ch->x;
- ch->glyph.y = ch->y;
- ch->glyph.w = ch->width;
- ch->glyph.h = ch->height;
- } else
- return -1;
- ch->loaded = 1;
- return 0;
-}