Example #1
0
/* create a color table */
Ulong	*get_color_table(DviDevice *dev, 
			 int nlevels, Ulong fg, Ulong bg, double gamma, int density)
{
	ColorCache	*cc, *tofree;
	int		lohits;
	Ulong		*pixels;
	int		status;

	lohits = color_cache[0].hits;
	tofree = &color_cache[0];
	/* look in the cache and see if we have one that matches this request */
	for(cc = &color_cache[0]; cc < &color_cache[cc_entries]; cc++) {
		if(cc->hits < lohits) {
			lohits = cc->hits;
			tofree = cc;
		}
		if(cc->fg == fg && cc->bg == bg && cc->density == density &&
		   cc->nlevels == nlevels && fabs(cc->gamma - gamma) <= GAMMA_DIFF)
		   	break;
	}

	if(cc < &color_cache[cc_entries]) {
		cc->hits++;
		return cc->pixels;
	}

	DEBUG((DBG_DEVICE, "Adding color table to cache (fg=%lu, bg=%lu, n=%d)\n",
		fg, bg, nlevels));
		
	/* no entry was found in the cache, create a new one */
	if(cc_entries < CCSIZE) {
		cc = &color_cache[cc_entries++];
		cc->pixels = NULL;
	} else {
		cc = tofree;
		mdvi_free(cc->pixels);
	}
	pixels = xnalloc(Ulong, nlevels);
	status = dev->alloc_colors(dev->device_data, 
		pixels, nlevels, fg, bg, gamma, density);
	if(status < 0) {
		mdvi_free(pixels);
		return NULL;
	}
	cc->fg = fg;
	cc->bg = bg;
	cc->gamma = gamma;
	cc->density = density;
	cc->nlevels = nlevels;
	cc->pixels = pixels;
	cc->hits = 1;
	return pixels;	
}
Example #2
0
int	mdvi_unregister_special(const char *prefix)
{
	DviSpecial *sp;
	
	sp = find_special_prefix(prefix);	
	if(sp == NULL)
		return -1;
	mdvi_free(sp->prefix);
#ifdef WITH_REGEX_SPECIALS
	if(sp->has_reg)
		regfree(&sp->reg);
#endif
	listh_remove(&specials, LIST(sp));
	mdvi_free(sp);
	return 0;
}
Example #3
0
void    font_drop_one(DviFontRef *ref)
{
    DviFont *font;
    
    font = ref->ref;
    mdvi_free(ref);
    /* drop all children */
    for(ref = font->subfonts; ref; ref = ref->next) {
        /* just adjust the reference counts */
        ref->ref->links--;
    }
    if(--font->links == 0) {
        /* 
         * this font doesn't have any more references, but
         * we still keep it around in case a virtual font
         * requests it.
         */
        if(font->in) {
            fclose(font->in);
            font->in = NULL;
        }
        if(LIST(font) != fontlist.tail) {
            /* move it to the end of the list */
            listh_remove(&fontlist, LIST(font));
            listh_append(&fontlist, LIST(font));
        }
    }
    DEBUG((DBG_FONTS, "%s: reference dropped, %d more left\n",
        font->fontname, font->links));
}
Example #4
0
int	mdvi_register_special(const char *label, const char *prefix, 
	const char *regex, DviSpecialHandler handler, int replace)
{
	DviSpecial *sp;
	int	newsp = 0;

	if(!registered_builtins)
		register_builtin_specials();

	sp = find_special_prefix(prefix);
	if(sp == NULL) {
		sp = xalloc(DviSpecial);
		sp->prefix = mdvi_strdup(prefix);
		newsp = 1;
	} else if(!replace)
		return -1;
	else {
		mdvi_free(sp->label);
		sp->label = NULL;
	}

#ifdef WITH_REGEX_SPECIALS
	if(!newsp && sp->has_reg) {
		regfree(&sp->reg);
		sp->has_reg = 0;
	}
	if(regex && regcomp(&sp->reg, regex, REG_NOSUB) != 0) {
		if(newsp) {
			mdvi_free(sp->prefix);
			mdvi_free(sp);
		}
		return -1;
	}
	sp->has_reg = (regex != NULL);
#endif
	sp->handler = handler;
	sp->label = mdvi_strdup(label);
	sp->plen = strlen(prefix);
	if(newsp)
		listh_prepend(&specials, LIST(sp));		
	DEBUG((DBG_SPECIAL, 
		"New \\special handler `%s' with prefix `%s'\n", 
		label, prefix));
	return 0;
}
Example #5
0
void	mdvi_flush_specials(void)
{
	DviSpecial *sp, *list;
	
	
	for(list = (DviSpecial *)specials.head; (sp = list); ) {
		list = sp->next;
		if(sp->prefix) mdvi_free(sp->prefix);
		if(sp->label) mdvi_free(sp->label);
#ifdef WITH_REGEX_SPECIALS
		if(sp->has_reg)
			regfree(&sp->reg);
#endif
		mdvi_free(sp);
	}
	specials.head = NULL;
	specials.tail = NULL;
	specials.count = 0;
}
Example #6
0
void    bitmap_flip_rotate_counter_clockwise(BITMAP *bm)
{
    BITMAP    nb;
    BmUnit    *fptr, *tptr;
    BmUnit    fmask, tmask;
    int    w, h;
    
    nb.width = bm->height;
    nb.height = bm->width;
    nb.stride = BM_BYTES_PER_LINE(&nb);
    nb.data = mdvi_calloc(nb.height, nb.stride);
    
    fptr = bm->data;
    tptr = nb.data;
    tmask = FIRSTMASK;
    
    for(h = 0; h < bm->height; h++) {
        BmUnit    *fline, *tline;

        fmask = FIRSTMASK;
        fline = fptr;
        tline = tptr;
        for(w = 0; w < bm->width; w++) {
            if(*fline & fmask)
                *tline |= tmask;
            if(fmask == LASTMASK) {
                fmask = FIRSTMASK;
                fline++;
            } else
                NEXTMASK(fmask);
            /* go to next line */
            tline = bm_offset(tline, nb.stride);
        }
        fptr = bm_offset(fptr, bm->stride);
        if(tmask == LASTMASK) {
            tmask = FIRSTMASK;
            tptr++;
        } else
            NEXTMASK(tmask);
    }

    DEBUG((DBG_BITMAP_OPS, "flip_rotate_counter_clockwise (%d,%d) -> (%d,%d)\n",
        bm->width, bm->height, nb.width, nb.height));
    mdvi_free(bm->data);
    bm->data = nb.data;
    bm->width = nb.width;
    bm->height = nb.height;    
    bm->stride = nb.stride;
    if(SHOW_OP_DATA)
        bitmap_print(stderr, bm);
}
Example #7
0
int    font_free_unused(DviDevice *dev)
{
    DviFont    *font, *next;
    int    count = 0;

    DEBUG((DBG_FONTS, "destroying unused fonts\n"));    
    for(font = (DviFont *)fontlist.head; font; font = next) {
        DviFontRef *ref;
        
        next = font->next;
        if(font->links)
            continue;
        count++;
        DEBUG((DBG_FONTS, "removing unused %s font `%s'\n", 
            TYPENAME(font), font->fontname));
        listh_remove(&fontlist, LIST(font));
        if(font->in)
            fclose(font->in);
        /* get rid of subfonts (but can't use `drop_chain' here) */
        for(; (ref = font->subfonts); ) {
            font->subfonts = ref->next;
            mdvi_free(ref);
        }
        /* remove this font */
        font_reset_font_glyphs(dev, font, MDVI_FONTSEL_GLYPH);
        /* let the font destroy its private data */
        if(font->finfo->freedata)
            font->finfo->freedata(font);
        /* destroy characters */
        if(font->chars)
            mdvi_free(font->chars);
        mdvi_free(font->fontname);
        mdvi_free(font->filename);
        mdvi_free(font);
    }
    DEBUG((DBG_FONTS, "%d unused fonts removed\n", count));
    return count;
}
Example #8
0
char	*read_string(FILE *in, int s, char *buffer, size_t len)
{
	int	n;
	char	*str;
	
	n = fugetn(in, s ? s : 1);
	if((str = buffer) == NULL || n + 1 > len)
		str = mdvi_malloc(n + 1);
	if(fread(str, 1, n, in) != n) {
		if(str != buffer) mdvi_free(str);
		return NULL;
	}
	str[n] = 0;
	return str;
}
Example #9
0
void    bitmap_flip_diagonally(BITMAP *bm)
{
    BITMAP    nb;
    BmUnit    *fptr, *tptr;
    BmUnit    fmask, tmask;
    int    w, h;
    
    nb.width = bm->width;
    nb.height = bm->height;
    nb.stride = bm->stride;
    nb.data = mdvi_calloc(bm->height, bm->stride);
    
    fptr = bm->data;
    tptr = __bm_unit_ptr(&nb, nb.width-1, nb.height-1);
    for(h = 0; h < bm->height; h++) {
        BmUnit    *fline, *tline;
        
        fline = fptr; 
        tline = tptr;
        fmask = FIRSTMASK;
        tmask = FIRSTMASKAT(nb.width-1);
        for(w = 0; w < bm->width; w++) {
            if(*fline & fmask)
                *tline |= tmask;
            if(fmask == LASTMASK) {
                fmask = FIRSTMASK;
                fline++;
            } else
                NEXTMASK(fmask);
            if(tmask == FIRSTMASK) {
                tmask = LASTMASK;
                tline--;
            } else
                PREVMASK(tmask);
        }
        fptr = bm_offset(fptr, bm->stride);
        tptr = bm_offset(tptr, -nb.stride);
    }
    DEBUG((DBG_BITMAP_OPS, "flip_diagonally (%d,%d) -> (%d,%d)\n",
        bm->width, bm->height, nb.width, nb.height));
    mdvi_free(bm->data);
    bm->data = nb.data;
    if(SHOW_OP_DATA)
        bitmap_print(stderr, bm);
}
Example #10
0
void	buff_free(Buffer *buf)
{
	if(buf->data)
		mdvi_free(buf->data);
	buff_init(buf);	
}
Example #11
0
void    epsf_special(DviContext *dvi, char *prefix, char *arg)
{
    char    *file;
    char    *special;
    char    *psfile;
    char    *tmp;
    EpsfBox    box = {0, 0, 0, 0};
    int    x, y;
    int    w, h;
    double    xf, vf;
    struct stat buf;
    
    file = parse_epsf_special(&box, &special, prefix, arg);
    if (file != NULL)
        mdvi_free (special);

    xf = dvi->params.dpi * dvi->params.mag / (72.0 * dvi->params.hshrink);
    vf = dvi->params.vdpi * dvi->params.mag / (72.0 * dvi->params.vshrink);
    w = FROUND(box.bw * xf);
    h = FROUND(box.bh * vf);
    x = FROUND(box.ox * xf) + dvi->pos.hh;
    y = FROUND(box.oy * vf) + dvi->pos.vv - h + 1;

    if (!file || !dvi->device.draw_ps) {
        dvi->device.draw_rule (dvi, x, y, w, h, 0);
        return;
    }

    if (file[0] == '/') { /* Absolute path */
        if (stat (file, &buf) == 0)
            dvi->device.draw_ps (dvi, file, x, y, w, h);
        else
            dvi->device.draw_rule (dvi, x, y, w, h, 0);
        return;
    }

    tmp = mdvi_strrstr (dvi->filename, "/");
    if (tmp) { /* Document directory */
        int path_len = strlen (dvi->filename) - strlen (tmp + 1);
        int file_len = strlen (file);
        
        psfile = mdvi_malloc (path_len + file_len + 1);
        psfile[0] = '\0';
        strncat (psfile, dvi->filename, path_len);
        strncat (psfile, file, file_len);

        if (stat (psfile, &buf) == 0) {
            dvi->device.draw_ps (dvi, psfile, x, y, w, h);
            mdvi_free (psfile);

            return;
        }

        mdvi_free (psfile);
    }
            
    psfile = mdvi_build_path_from_cwd (file);
    if (stat (psfile, &buf) == 0) { /* Current working dir */
        dvi->device.draw_ps (dvi, psfile, x, y, w, h);
        mdvi_free (psfile);

        return;
    }

    mdvi_free (psfile);
    
    psfile = kpse_find_pict (file);
    if (psfile) { /* kpse */
        dvi->device.draw_ps (dvi, psfile, x, y, w, h);
    } else {
        dvi->device.draw_rule(dvi, x, y, w, h, 0);
    }

    free (psfile);
}
Example #12
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 #13
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;
}