/* the general function to paint rows. Still used by the PK reader, but that * will change soon (The GF reader already uses bitmap_paint_bits()). */ void bitmap_set_row(BITMAP *bm, int row, int col, int count, int state) { BmUnit *ptr; ptr = __bm_unit_ptr(bm, col, row); if(state) bitmap_paint_bits(ptr, col & (BITMAP_BITS-1), count); else bitmap_clear_bits(ptr, col & (BITMAP_BITS-1), count); }
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; }