示例#1
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);
}
示例#2
0
/*
 * Count the number of non-zero bits in a box of dimensions w x h, starting
 * at column `step' in row `data'.
 * 
 * Shamelessly stolen from xdvi.
 */
static int do_sample(BmUnit *data, int stride, int step, int w, int h)
{
    BmUnit    *ptr, *end, *cp;
    int    shift, n;
    int    bits_left;
    int    wid;
    
    ptr = data + step / BITMAP_BITS;
    end = bm_offset(data, h * stride);
    shift = FIRSTSHIFTAT(step);
    bits_left = w;
    n = 0;
    while(bits_left) {
#ifndef WORD_BIG_ENDIAN
        wid = BITMAP_BITS - shift;
#else
        wid = shift;
#endif
        if(wid > bits_left)
            wid = bits_left;
        if(wid > 8)
            wid = 8;
#ifdef WORD_BIG_ENDIAN
        shift -= wid;
#endif
        for(cp = ptr; cp < end; cp = bm_offset(cp, stride))
            n += sample_count[(*cp >> shift) & bit_masks[wid]];
#ifndef WORD_BIG_ENDIAN
        shift += wid;
#endif
#ifdef WORD_BIG_ENDIAN
        if(shift == 0) {
            shift = BITMAP_BITS;
            ptr++;
        }
#else
        if(shift == BITMAP_BITS) {
            shift = 0;
            ptr++;
        }
#endif
        bits_left -= wid;
    }
    return n;
}
示例#3
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);
}
示例#4
0
void bitmap_set_col(BITMAP *bm, int row, int col, int count, int state)
{
    BmUnit    *ptr;
    BmUnit    mask;
    
    ptr = __bm_unit_ptr(bm, col, row);
    mask = FIRSTMASKAT(col);
    
    while(count-- > 0) {
        if(state)
            *ptr |= mask;
        else
            *ptr &= ~mask;
        /* move to next row */
        ptr = bm_offset(ptr, bm->stride);
    }
}
示例#5
0
文件: gf.c 项目: 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;
}
示例#6
0
void    mdvi_shrink_glyph_grey(DviContext *dvi, DviFont *font,
    DviFontChar *pk, DviGlyph *dest)
{
    int    rows_left, rows;
    int    cols_left, cols, init_cols;
    long    sampleval, samplemax;
    BmUnit    *old_ptr;
    void    *image;
    int    w, h;
    int    x, y;
    DviGlyph *glyph;
    BITMAP     *map;
    Ulong    *pixels;
    int    npixels;
    Ulong    colortab[2];
    int    hs, vs;
    DviDevice *dev;

    hs = dvi->params.hshrink;
    vs = dvi->params.vshrink;
    dev = &dvi->device;
    
    glyph = &pk->glyph;
    map = (BITMAP *)glyph->data;
    
    x = (int)glyph->x / hs;
    init_cols = (int)glyph->x - x * hs;
    if(init_cols <= 0)
        init_cols += hs;
    else
        x++;
    w = x + ROUND((int)glyph->w - glyph->x, hs);

    cols = (int)glyph->y + 1;
    y = cols / vs;
    rows = cols - y * vs;
    if(rows <= 0) {
        rows += vs;
        y--;
    }
    h = y + ROUND((int)glyph->h - cols, vs) + 1;
    ASSERT(w && h);
    
    /* before touching anything, do this */
    image = dev->create_image(dev->device_data, w, h, BITMAP_BITS);
    if(image == NULL) {
        mdvi_shrink_glyph(dvi, font, pk, dest);
        return;
    }
    
    /* save these colors */
    pk->fg = MDVI_CURRFG(dvi);
    pk->bg = MDVI_CURRBG(dvi);
    
    samplemax = vs * hs;
    npixels = samplemax + 1;
    pixels = get_color_table(&dvi->device, npixels, pk->fg, pk->bg,
            dvi->params.gamma, dvi->params.density);
    if(pixels == NULL) {
        npixels = 2;
        colortab[0] = pk->fg;
        colortab[1] = pk->bg;
        pixels = &colortab[0];
    }
    
    /* setup the new glyph */
    dest->data = image;
    dest->x = x;
    dest->y = glyph->y / vs;
    dest->w = w;
    dest->h = h;

    y = 0;
    old_ptr = map->data;
    rows_left = glyph->h;

    while(rows_left && y < h) {
        x = 0;
        if(rows > rows_left)
            rows = rows_left;
        cols_left = glyph->w;
        cols = init_cols;
        while(cols_left && x < w) {
            if(cols > cols_left)
                cols = cols_left;
            sampleval = do_sample(old_ptr, map->stride,
                glyph->w - cols_left, cols, rows);
            /* scale the sample value by the number of grey levels */
            if(npixels - 1 != samplemax)
                sampleval = ((npixels-1) * sampleval) / samplemax;
            ASSERT(sampleval < npixels);
            dev->put_pixel(image, x, y, pixels[sampleval]);
            cols_left -= cols;
            cols = hs;
            x++;
        }
        for(; x < w; x++)
            dev->put_pixel(image, x, y, pixels[0]);
        old_ptr = bm_offset(old_ptr, rows * map->stride);
        rows_left -= rows;
        rows = vs;
        y++;
    }
    
    for(; y < h; y++) {
        for(x = 0; x < w; x++)
            dev->put_pixel(image, x, y, pixels[0]);
    }

        dev->image_done(image);
    DEBUG((DBG_BITMAPS, "shrink_glyph_grey: (%dw,%dh,%dx,%dy) -> (%dw,%dh,%dx,%dy)\n",
        glyph->w, glyph->h, glyph->x, glyph->y,
        dest->w, dest->h, dest->x, dest->y));
}
示例#7
0
void    mdvi_shrink_glyph(DviContext *dvi, DviFont *font,
    DviFontChar *pk, DviGlyph *dest)
{
    int    rows_left, rows, init_cols;
    int    cols_left, cols;
    BmUnit    *old_ptr, *new_ptr;
    BITMAP    *oldmap, *newmap;
    BmUnit    m, *cp;
    DviGlyph *glyph;
    int    sample, min_sample;
    int    old_stride;
    int    new_stride;
    int    x, y;
    int    w, h;
    int    hs, vs;
    
    hs = dvi->params.hshrink;
    vs = dvi->params.vshrink;
    
    min_sample = vs * hs * dvi->params.density / 100;

    glyph = &pk->glyph;
    oldmap = (BITMAP *)glyph->data;
        
    x = (int)glyph->x / hs;
    init_cols = (int)glyph->x - x * hs;
    if(init_cols <= 0)
        init_cols += hs;
    else
        x++;
    w = x + ROUND((int)glyph->w - glyph->x, hs);

    cols = (int)glyph->y + 1;
    y = cols / vs;
    rows = cols - y * vs;
    if(rows <= 0) {
        rows += vs;
        y--;
    }
    h = y + ROUND((int)glyph->h - cols, vs) + 1;

    /* create the new glyph */
    newmap = bitmap_alloc(w, h);
    dest->data = newmap;
    dest->x = x;
    dest->y = glyph->y / vs;
    dest->w = w;
    dest->h = h;

    old_ptr = oldmap->data;
    old_stride = oldmap->stride;
    new_ptr = newmap->data;
    new_stride = newmap->stride;
    rows_left = glyph->h;

    while(rows_left) {
        if(rows > rows_left)
            rows = rows_left;
        cols_left = glyph->w;
        m = FIRSTMASK;
        cp = new_ptr;
        cols = init_cols;
        while(cols_left > 0) {
            if(cols > cols_left)
                cols = cols_left;
            sample = do_sample(old_ptr, old_stride,
                glyph->w - cols_left, cols, rows);
            if(sample >= min_sample)
                *cp |= m;
            if(m == LASTMASK) {
                m = FIRSTMASK;
                cp++;
            } else
                NEXTMASK(m);
            cols_left -= cols;
            cols = hs;
        }
        new_ptr = bm_offset(new_ptr, new_stride);
        old_ptr = bm_offset(old_ptr, rows * old_stride);
        rows_left -= rows;
        rows = vs;
    }    
    DEBUG((DBG_BITMAPS, "shrink_glyph: (%dw,%dh,%dx,%dy) -> (%dw,%dh,%dx,%dy)\n",
        glyph->w, glyph->h, glyph->x, glyph->y,
        dest->w, dest->h, dest->x, dest->y));
    if(DEBUGGING(BITMAP_DATA))
        bitmap_print(stderr, newmap);
}