示例#1
0
/*
 * Get any character by its code.
 */
static int
gf_get_char (gf_font_t *font, gf_char_t *sym, unsigned char charcode)
{
	gf_locator_t *loc;
	unsigned char c, col_delta, row_delta;
	long lcode, back_pointer;

	loc = &font->char_loc [charcode];
	if (loc->char_pointer == -1)
		return 0;

	sym->font = font;
	sym->h_escapement = loc->h_escapement;
	sym->tfm_width = loc->tfm_width;

	if (fseek (font->input_file, loc->char_pointer, SEEK_SET) < 0) {
		fprintf (stderr, "%s: seek error\n", font->input_filename);
		return 0;
	}

	/* This reads the character starting from the current position
	 * (but some specials might come first).
	 */
	skip_specials (font);

	c = get_byte (font);
	switch (c) {
	case BOC:
		/* If the back pointer actually points somewhere,
		 * this character is a ``residue'', and the font
		 * is probably too big.
		 */
		lcode = (long) get_four (font);
		if (lcode < 0 || lcode > 255) {
			/* Someone is trying to use a font with character codes
			 * that are out of our range. */
			fprintf (stderr, "%s: invalid character code %ld (expected %d)\n",
				font->input_filename, lcode, charcode);
			return 0;
		}
		sym->charcode = lcode;

		back_pointer = (long) get_four (font);
		if (back_pointer != -1)
			fprintf (stderr, "%s: warning: character %u has a non-null back pointer (to %#lx)\n",
				font->input_filename, sym->charcode, back_pointer);

		sym->bbox_min_col = (long) get_four (font);
		sym->bbox_max_col = (long) get_four (font);
		sym->bbox_min_row = (long) get_four (font);
		sym->bbox_max_row = (long) get_four (font);
		break;

	case BOC1:
		sym->charcode = get_byte (font);

		col_delta = get_byte (font);
		sym->bbox_max_col = get_byte (font);
		sym->bbox_min_col = sym->bbox_max_col - col_delta;

		row_delta = get_byte (font);
		sym->bbox_max_row = get_byte (font);
		sym->bbox_min_row = sym->bbox_max_row - row_delta;
		break;

	case POST:
		return 0;

	default:
		fprintf (stderr, "%s: error reading character (found %u)\n",
			font->input_filename, c);
		return 0;
	}
	if (sym->charcode != charcode) {
		fprintf (stderr, "%s: warning: character code mismatch, %d != %d\n",
			font->input_filename, sym->charcode, charcode);
	}

	get_character_bitmap (sym);

	deblank (sym);
	return 1;
}
示例#2
0
void InitPK(struct font_entry * tfontp)
{
  unsigned char* position;
  struct char_entry *tcharptr; /* temporary char_entry pointer  */
  uint32_t    hppp, vppp, packet_length;
  uint32_t    c;

  DEBUG_PRINT((DEBUG_DVI|DEBUG_PK),("\n  OPEN FONT:\t'%s'", tfontp->name));
  Message(BE_VERBOSE,"<%s>", tfontp->name);
  if (MmapFile(tfontp->name,&(tfontp->fmmap)))
    Fatal("font file %s unusable", tfontp->name);
  position=(unsigned char*)tfontp->fmmap.data;
  if (tfontp->fmmap.size < 2 || tfontp->fmmap.size < 3+*(position+2)+16)
    Fatal("PK file %s ends prematurely",tfontp->name);
  if (*position++ != PK_PRE)
    Fatal("unknown font format in file %s",tfontp->name);
  if (*position++ != PK_ID)
    Fatal( "wrong version %d of PK file %s (should be 89)",
	   (int)*(position-1),tfontp->name);
  DEBUG_PRINT(DEBUG_PK,("\n  PK_PRE:\t'%.*s'",(int)*position, position+1));
  position += *position + 1;

  tfontp->designsize = UNumRead(position, 4);
  DEBUG_PRINT(DEBUG_PK,(" %d", tfontp->designsize));
  tfontp->type = FONT_TYPE_PK;

  c = UNumRead(position+4, 4);
  DEBUG_PRINT(DEBUG_PK,(" %d", c));
  CheckChecksum (tfontp->c, c, tfontp->name);

  hppp = UNumRead(position+8, 4);
  vppp = UNumRead(position+12, 4);
  DEBUG_PRINT(DEBUG_PK,(" %d %d", hppp,vppp));
  if (hppp != vppp)
    Warning("aspect ratio is %d:%d (should be 1:1)", hppp, vppp);
  tfontp->magnification = (uint32_t)((uint64_t)hppp * 7227 * 5 / 65536l + 50)/100;
  position+=16;
  /* Read char definitions */
  position = skip_specials(position);
  while (*position != PK_POST) {
    DEBUG_PRINT(DEBUG_PK,("\n  @%ld PK CHAR:\t%d",
			  (long)((char *)position - tfontp->fmmap.data), *position));
    if ((tcharptr = malloc(sizeof(struct char_entry))) == NULL)
      Fatal("cannot allocate space for char_entry");
    tcharptr->flag_byte = *position;
    tcharptr->data = NULL;
    tcharptr->tfmw = 0;
    if ((*position & 7) == 7) {
      packet_length = UNumRead(position+1,4);
      c = UNumRead(position+5, 4);
      position += 9;
    } else if (*position & 4) {
      packet_length = (*position & 3) * 65536l +
	UNumRead(position+1, 2);
      c = UNumRead(position+3, 1);
      position += 4;
    } else {
      packet_length = (*position & 3) * 256 +
	UNumRead(position+1, 1);
      c = UNumRead(position+2, 1);
      position += 3;
    }
  DEBUG_PRINT(DEBUG_PK,(" %d %d",packet_length,c));
  if (c > (LASTFNTCHAR))
    Fatal("PK font %s exceeds char numbering limit",tfontp->name);
  tcharptr->length = packet_length;
  tcharptr->pkdata = position;
  tfontp->chr[c]=tcharptr;
  position += packet_length;
  position = skip_specials(position);
  }
}
示例#3
0
/*
 * The ``bitmap'' is a sequence of commands that describe it in terms of
 * run-length encoding.
 *
 * GF's row and column numbers are the lower left corner of a pixel.
 * GF (0,0) is the Cartesian unit square: 0 <= x (col) <= 1,
 * 0 <= y (row) <= 1.  Yes, it's <=, not <.  What does this mean for
 * the maxes and mins?  Let's take the height first:  if a character has
 * min_row = 0 and max_row = 10, we start the ``current'' y at 10,
 * (possibly) paint some pixels on that row, ..., and end up with it at
 * zero, (possibly) painting some pixels on that row.  Thus, there are
 * 11 (10 - 0 + 1) rows in which we might paint pixels.  Now the width:
 * if a character has min_row = 0 and max_row = 4, the current x starts
 * at zero, we paint four pixels (let's say), and now the current x is
 * four (the max possible), so we cannot paint any more.  Thus there are
 * four (4 - 0) columns in which we might paint pixels.
 *
 * Weird, huh?
 */
static void
get_character_bitmap (gf_char_t *sym)
{
	unsigned char c;

	/* We expect these to be >= 0, but if the GF file is improper,
	 * they might turn to be negative.
	 */
	int height, width, painting_black = 0;
	int cur_x, cur_y;		/* This will be the GF position. */

	cur_x = sym->bbox_min_col;
	cur_y = sym->bbox_max_row;

	width = sym->bbox_max_col - sym->bbox_min_col;
	height = sym->bbox_max_row - sym->bbox_min_row + 1;

	/* If the character has zero or negative extent in either dimension,
	 * it's not going to have a bitmap.  (If this happens, the GF file is
	 * incorrect; but the discrepancy isn't serious, so we may as well not
	 * bomb out when it happens, especially since PKtoGF has a bug that
	 * produces such a bounding box when the character is all blank.)
	 */
	if (width <= 0 || height <= 0) {
		sym->height = 0;
		sym->width = 0;
		sym->bitmap = 0;

		/* The next non-NO_OP byte should be EOC. */
		while ((c = get_byte (sym->font)) == NO_OP)
			continue;	/* do nothing */
		if (c != EOC) {
			fprintf (stderr, "%s: expected eoc (for a blank character), found %u\n",
				sym->font->input_filename, c);
			exit (-1);
		}
		return;
	}

	sym->height = height;
	sym->width = width;
	sym->bitmap = calloc (width, height);
	if (! sym->bitmap) {
		fprintf (stderr, "%s: out of memory\n",
			sym->font->input_filename);
		exit (-1);
	}

	for (;;) {
		c = get_byte (sym->font);
		if (c == EOC)
			break;

		if (/* PAINT_0 <= c && */ c <= PAINT3) {
			/* No need to test if `PAINT_0 <= c'; it must be,
			 * since PAINT_0 is zero and `c' is unsigned.
			 */
			/* The paint commands come in two varieties -- either
			 * with the length implicitly part of the command,
			 * or where it is specified as a separate parameter. */
			unsigned length;

			if (/* PAINT_0 <= c && */ c <= PAINT_63)
				length = c - PAINT_0;
			else {
				switch (c) {
				case PAINT1:
					length = get_byte (sym->font);
					break;
				case PAINT2:
					length = get_two (sym->font);
					break;
				case PAINT3:
					length = get_three (sym->font);
					break;
				default:
					fprintf (stderr, "%s: invalid painting command %u\n",
						sym->font->input_filename, c);
					exit (-1);
				}
			}

			/* We have to translate from Cartesian to
			 * C coordinates.  That means the x's are the same,
			 * but the y's are flipped. */
			if (painting_black) {
				unsigned matrix_x, matrix_y;

				matrix_y = sym->bbox_max_row - cur_y;
				for (; length != 0; length--) {
					matrix_x = cur_x - sym->bbox_min_col;

					PIXEL (sym, matrix_y, matrix_x) = 255;
					cur_x++;
				}
			} else {
				cur_x += length;
			}
			painting_black = ! painting_black;

		} else if (SKIP0 <= c && c <= SKIP3) {
			/* Skip commands move down in the GF character,
			 * leaving blank rows. */
			unsigned rows_to_skip;

			switch (c) {
			case SKIP0:
				rows_to_skip = 0;
				break;
			case SKIP1:
				rows_to_skip = get_byte (sym->font);
				break;
			case SKIP2:
				rows_to_skip = get_two (sym->font);
				break;
			case SKIP3:
				rows_to_skip = get_three (sym->font);
				break;
			default:
				fprintf (stderr, "%s: invalid skip command %u\n",
					sym->font->input_filename, c);
				exit (-1);
			}
			cur_y -= rows_to_skip + 1;
			cur_x = sym->bbox_min_col;
			painting_black = 0;

		} else if (NEW_ROW_0 <= c && c <= NEW_ROW_164) {
			/* `new_row' commands move to the next line down
			 * and then over. */
			cur_y--;
			cur_x = sym->bbox_min_col + c - NEW_ROW_0;
			painting_black = 1;

		} else if (c == NO_OP) {
			/* do nothing */

		} else if ((XXX1 <= c && c <= XXX4) || c == YYY) {
			skip_specials (sym->font);

		} else {
			fprintf (stderr, "%s: expected paint or skip or new_row, found %u\n",
				sym->font->input_filename, c);
			exit (-1);
		}
	}
}