Example #1
0
size_t	read_bcpl(FILE *in, char *buffer, size_t maxlen, size_t wanted)
{
	size_t	i;
	
	i = (int)fuget1(in);
	if(maxlen && i > maxlen)
		i = maxlen;
	if(fread(buffer, i, 1, in) != 1)
		return -1;
	buffer[i] = '\0';
	while(wanted-- > i)
		(void)fgetc(in);
	return i;
}
Example #2
0
char	*read_alloc_bcpl(FILE *in, size_t maxlen, size_t *size)
{
	size_t	i;
	char	*buffer;
	
	i = (size_t)fuget1(in);
	if(maxlen && i > maxlen)
		i = maxlen;
	buffer = (char *)malloc(i + 1);
	if(buffer == NULL)
		return NULL;
	if(fread(buffer, i, 1, in) != 1) {
		free(buffer);
		return NULL;
	}
	buffer[i] = '\0';
	if(size) *size = i;
	return buffer;
}
static DviContext *
mdvi_init_context (const char *file)
{
	FILE *p;
	gint32 arg;
	int op;
	int n;
	DviContext *dvi;
	char *filename;

	/*
	 * 1. Open the file and initialize the DVI context
	 */
	filename = opendvi (file);
	if (filename == NULL) {
		return NULL;
	}

	p = fopen (filename, "rb");
	if (p == NULL) {
		g_free (filename);
		return NULL;
	}

	dvi = g_new0 (DviContext, 1);
	dvi->filename = filename;
	dvi->in = p;

	/*
	 * 2. Read the preamble, extract scaling information
	 */
	if (fuget1 (p) != DVI_PRE) {
		goto error;
	}

	if ((arg = fuget1 (p)) != DVI_ID) {
		g_message ("Unsupported DVI format (version %u)", arg);
		goto error;
	}

	/* get dimensions */
	dvi->num = fuget4 (p);
	dvi->den = fuget4 (p);
	dvi->dvimag = fuget4 (p);

	/* check that these numbers make sense */
	if (!dvi->num || !dvi->den || !dvi->dvimag) {
		goto error;
	}

	/* get the comment from the preamble */
	n = fuget1 (p);
	dvi->fileid = g_malloc (n + 1);
	fread (dvi->fileid, 1, n, p);
	dvi->fileid[n] = 0;
	g_debug ("Preamble Comment: '%s'", dvi->fileid);

	/*
	 * 3. Read postamble, extract page information (number of
	 *    pages, dimensions) and stack depth.
	 */

	/* jump to the end of the file */
	if (fseek (p, (long) - 1, SEEK_END) == -1) {
		goto error;
	}

	for (n = 0; (op = fuget1 (p)) == DVI_TRAILER; n++) {
		if (fseek (p, (long) - 2, SEEK_CUR) < 0) {
			break;
		}
	}

	if (op != arg || n < 4) {
		goto error;
	}

	/* get the pointer to postamble */
	fseek (p, (long) - 5, SEEK_CUR);
	arg = fuget4 (p);

	/* jump to it */
	fseek (p, (long) arg, SEEK_SET);
	if (fuget1 (p) != DVI_POST) {
		goto error;
	}

	fuget4 (p); /* offset */
	if (dvi->num != fuget4 (p) ||
	    dvi->den != fuget4 (p) ||
	    dvi->dvimag != fuget4 (p)) {
		goto error;
	}
	dvi->dvi_page_h = fuget4 (p);
	dvi->dvi_page_w = fuget4 (p);
	dvi->stacksize = fuget2 (p);
	dvi->npages = fuget2 (p);

	g_debug ("Postamble: %d pages", dvi->npages);

	return dvi;

error:
	mdvi_destroy_context (dvi);
	return NULL;
}
Example #4
0
File: gf.c Project: 4eremuxa/evince
static int gf_read_bitmap(FILE *p, DviFontChar *ch)
{
	int	op;
	int	min_n, max_n;
	int	min_m, max_m;
	int	paint_switch;
	int	x, y;
	int	bpl;
	Int32	par;
	BmUnit	*line;
	BITMAP	*map;
	
	fseek(p, (long)ch->offset, SEEK_SET);
	op = fuget1(p);
	if(op == GF_BOC) {
		/* skip character code */
		fuget4(p);
		/* skip pointer */
		fuget4(p);
		min_m = fsget4(p);
		max_m = fsget4(p);
		min_n = fsget4(p);
		max_n = fsget4(p);
	} else if(op == GF_BOC1) {
		/* skip character code */
		fuget1(p);
		min_m = fuget1(p); /* this is max_m - min_m */
		max_m = fuget1(p);
		min_n = fuget1(p); /* this is max_n - min_n */
		max_n = fuget1(p); 
		min_m = max_m - min_m;
		min_n = max_n - min_n;
	} else {
		mdvi_error(_("GF: invalid opcode %d in character %d\n"),
			   op, ch->code);
		return -1;
	}

	ch->x = -min_m;
	ch->y = max_n;
	ch->width = max_m - min_m + 1;
	ch->height = max_n - min_n + 1;
	map = bitmap_alloc(ch->width, ch->height);

	ch->glyph.data = map;
	ch->glyph.x = ch->x;
	ch->glyph.y = ch->y;
	ch->glyph.w = ch->width;
	ch->glyph.h = ch->height;

#define COLOR(x)	((x) ? "BLACK" : "WHITE")

	paint_switch = WHITE;
	x = y = 0;
	line = map->data;
	bpl = map->stride;
	DEBUG((DBG_BITMAPS, "(gf) reading character %d\n", ch->code));
	while((op = fuget1(p)) != GF_EOC) {
		Int32	n;
		
		if(feof(p))
			break;
		if(op == GF_PAINT0) {
			DEBUG((DBG_BITMAPS, "(gf) Paint0 %s -> %s\n",
				COLOR(paint_switch), COLOR(!paint_switch)));	
			paint_switch = !paint_switch;
		} else if(op <= GF_PAINT3) {
			if(op < GF_PAINT1)
				par = op;
			else
				par = fugetn(p, op - GF_PAINT1 + 1);			
			if(y >= ch->height || x + par >= ch->width)
				goto toobig;
			/* paint everything between columns x and x + par - 1 */
			DEBUG((DBG_BITMAPS, "(gf) Paint %d %s from (%d,%d)\n",
				par, COLOR(paint_switch), x, y));
			if(paint_switch == BLACK)
				bitmap_paint_bits(line + (x / BITMAP_BITS),
					x % BITMAP_BITS, par);
			paint_switch = !paint_switch;
			x += par;
		} else if(op >= GF_NEW_ROW_0 && op <= GF_NEW_ROW_MAX) {
			y++; 
			line = bm_offset(line, bpl);
			x = op - GF_NEW_ROW_0;
			paint_switch = BLACK;
			DEBUG((DBG_BITMAPS, "(gf) new_row_%d\n", x));
		} else switch(op) {
			case GF_SKIP0:
				y++; 
				line = bm_offset(line, bpl);
				x = 0;
				paint_switch = WHITE;
				DEBUG((DBG_BITMAPS, "(gf) skip_0\n"));
				break;
			case GF_SKIP1:
			case GF_SKIP2:
			case GF_SKIP3:
				par = fugetn(p, op - GF_SKIP1 + 1);
				y += par + 1;
				line = bm_offset(line, (par + 1) * bpl);
				x = 0;
				paint_switch = WHITE;
				DEBUG((DBG_BITMAPS, "(gf) skip_%d\n", op - GF_SKIP1));
				break;
			case GF_XXX1:
			case GF_XXX2:
			case GF_XXX3:
			case GF_XXX4: {
#ifndef NODEBUG
				char	*s;

				s = read_string(p, op - GF_XXX1 + 1, NULL, 0);
				DEBUG((DBG_SPECIAL, "(gf) Character %d: Special \"%s\"\n",
					ch->code, s));
				mdvi_free(s);
#else
				n = fugetn(p, op - GF_XXX1 + 1);
				fseek(p, (long)n, SEEK_CUR);
#endif
				break;
			}
			case GF_YYY:
				n = fuget4(p);
				DEBUG((DBG_SPECIAL, "(gf) Character %d: MF special %u\n",
					ch->code, n));
				break;
			case GF_NOOP:
				DEBUG((DBG_BITMAPS, "(gf) no_op\n"));
				break;
			default:
				mdvi_error(_("(gf) Character %d: invalid opcode %d\n"),
					   ch->code, op);
				goto error;
		}
		/* chech that we're still inside the bitmap */
		if(x > ch->width || y > ch->height)
			goto toobig;
		DEBUG((DBG_BITMAPS, "(gf) curr_loc @ (%d,%d)\n", x, y));
	}

	if(op != GF_EOC)
		goto error;
	DEBUG((DBG_BITMAPS, "(gf) end of character %d\n", ch->code));
	return 0;

toobig:
	mdvi_error(_("(gf) character %d has an incorrect bounding box\n"),
		   ch->code);
error:
	bitmap_destroy(map);
	ch->glyph.data = NULL;
	return -1;
}
Example #5
0
File: gf.c Project: 4eremuxa/evince
static int gf_load_font(DviParams *unused, DviFont *font)
{
	int	i;
	int	n;
	int	loc;
	int	hic;
	FILE	*p;
	Int32	word;
	int	op;
	long	alpha, beta, z;
#ifndef NODEBUG
	char	s[256];
#endif

	p = font->in;

	/* check preamble */
	loc = fuget1(p); hic = fuget1(p);
	if(loc != GF_PRE || hic != GF_ID)
		goto badgf;
	loc = fuget1(p);
#ifndef NODEBUG
	for(i = 0; i < loc; i++)
		s[i] = fuget1(p);
	s[i] = 0;
	DEBUG((DBG_FONTS, "(gf) %s: %s\n", font->fontname, s));
#else
	fseek(p, (long)loc, SEEK_CUR);
#endif
	/* now read character locators in postamble */
	if(fseek(p, (long)-1, SEEK_END) == -1)
		return -1;
	
	n = 0;
	while((op = fuget1(p)) == GF_TRAILER) {
		if(fseek(p, (long)-2, SEEK_CUR) < 0)
			break;
		n++;
	}
	if(op != GF_ID || n < 4)
		goto badgf;
	/* get the pointer to the postamble */
	fseek(p, (long)-5, SEEK_CUR);
	op = fuget4(p);
	/* jump to it */
	fseek(p, (long)op, SEEK_SET);
	if(fuget1(p) != GF_POST)
		goto badgf;
	/* skip pointer to last EOC */
	fuget4(p);
	/* get the design size */
	font->design = fuget4(p);
	/* the checksum */
	word = fuget4(p);
	if(word && font->checksum && font->checksum != word) {
		mdvi_warning(_("%s: bad checksum (expected %u, found %u)\n"),
			     font->fontname, font->checksum, word);
	} else if(!font->checksum)
		font->checksum = word;
	/* skip pixels per point ratio */
	fuget4(p);
	fuget4(p);
	font->chars = xnalloc(DviFontChar, 256);
	for(loc = 0; loc < 256; loc++)
		font->chars[loc].offset = 0;
	/* skip glyph "bounding box" */
	fseek(p, (long)16, SEEK_CUR);
	loc = 256;
	hic = -1;
	TFMPREPARE(font->scale, z, alpha, beta);
	while((op = fuget1(p)) != GF_POST_POST) {
		DviFontChar *ch;
		int	cc;

		/* get the character code */		
		cc = fuget1(p);
		if(cc < loc)
			loc = cc;
		if(cc > hic)
			hic = cc;
		ch = &font->chars[cc];
		switch(op) {
		case GF_LOC:
			fsget4(p); /* skip dx */
			fsget4(p); /* skip dy */
			break;
		case GF_LOC0:
			fuget1(p); /* skip dx */
			           /* dy assumed 0 */
			break;
		default:
			mdvi_error(_("%s: junk in postamble\n"), font->fontname);
			goto error;
		}
		ch->code = cc;
		ch->tfmwidth = fuget4(p);
		ch->tfmwidth = TFMSCALE(ch->tfmwidth, z, alpha, beta);
		ch->offset = fuget4(p);
		if(ch->offset == -1)
			ch->offset = 0;
		/* initialize the rest of the glyph information */
		ch->x = 0;
		ch->y = 0;
		ch->width = 0;
		ch->height = 0;
		ch->glyph.data = NULL;
		ch->shrunk.data = NULL;
		ch->grey.data = NULL;
		ch->flags = 0;
		ch->loaded = 0;
	}	

	if(op != GF_POST_POST)
		goto badgf;
	
	if(loc > 0 || hic < 255) {
		/* shrink to optimal size */
		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;

badgf:
	mdvi_error(_("%s: File corrupted, or not a GF file\n"), font->fontname);
error:
	if(font->chars) {
		mdvi_free(font->chars);
		font->chars = NULL;
	}
	font->loc = font->hic = 0;
	return -1;
}