Esempio n. 1
0
static int get_bytes(DviContext *dvi, size_t n)
{	
	/* 
	 * caller wants to read `n' bytes from dvi->buffer + dvi->pos.
	 * Make sure there is enough data to satisfy the request 
	 */
	if(NEEDBYTES(dvi, n)) {
		size_t	required;
		int	newlen;
		
		if(dvi->buffer.frozen || dvi->in == NULL || feof(dvi->in)) {
			/* this is EOF */
			dviwarn(dvi, _("unexpected EOF\n"));
			return -1;
		}
		/* get more data */
		if(dvi->buffer.data == NULL) {
			/* first allocation */
			dvi->buffer.size = Max(DVI_BUFLEN, n);
			dvi->buffer.data = (Uchar *)mdvi_malloc(dvi->buffer.size);
			dvi->buffer.length = 0;
			dvi->buffer.frozen = 0;
		} else if(dvi->buffer.pos < dvi->buffer.length) {
			/* move whatever we want to keep */
			dvi->buffer.length -= dvi->buffer.pos;
			memmove(dvi->buffer.data,
				dvi->buffer.data + dvi->buffer.pos,
				dvi->buffer.length);
		} else {
			/* we can discard all the data in this buffer */
			dvi->buffer.length = 0;
		}

		required = n - dvi->buffer.length;
		if(required > dvi->buffer.size - dvi->buffer.length) {
			/* need to allocate more memory */
			dvi->buffer.size = dvi->buffer.length + required + 128;
			dvi->buffer.data = (Uchar *)xresize(dvi->buffer.data,
				char, dvi->buffer.size);
		}
		/* now read into the buffer */
		newlen = fread(dvi->buffer.data + dvi->buffer.length,
			1, dvi->buffer.size - dvi->buffer.length, dvi->in);
		if(newlen == -1) {
			mdvi_error("%s: %s\n", dvi->filename, strerror(errno));
			return -1;
		}
		dvi->buffer.length += newlen;
		dvi->buffer.pos = 0;
	}
Esempio n. 2
0
File: gf.c Progetto: 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;
}
Esempio n. 3
0
File: gf.c Progetto: 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;
}